NFC: Merge branch 'caf/github-nxpnfc/master' into nfc.lnx.3.1

* caf/github-nxpnfc/master:
  SEAccessKit_AR8.3.0_OpnSrc
  Update README.md
  SEAccessKit_AR8.3.0_OpnSrc
  SEAccessKit_AR8.2.3_OpnSrc
  SEAccessKit_AR8.2.0_OpnSrc

Change-Id: Ie6032f88e072e412e4b4a12216d6c6d66817d3c0
diff --git a/Android.mk b/Android.mk
index 989f207..dc58037 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,33 +1,140 @@
-# 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
-
-
+ifeq ($(strip $(TARGET_USES_NQ_NFC)),true)
 LOCAL_PATH:= $(call my-dir)
-D_CFLAGS += -DNXP_LDR_SVC_VER_2=TRUE
-######################################
-# Build shared library system/lib/libp61-jcop-kit.so for stack code.
-
 include $(CLEAR_VARS)
-LOCAL_PRELINK_MODULE := false
-LOCAL_ARM_MODE := arm
-LOCAL_MODULE := libp61-jcop-kit
-LOCAL_MODULE_TAGS := optional
-LOCAL_SHARED_LIBRARIES := libhardware_legacy libcutils liblog libdl libhardware
-LOCAL_CFLAGS := $(D_CFLAGS)
-LOCAL_C_INCLUDES := \
-    $(LOCAL_PATH)/include/ \
-    $(LOCAL_PATH)/inc/
-LOCAL_SRC_FILES := \
-    $(call all-c-files-under, src) \
-    $(call all-cpp-files-under, src)
+NFA := src/nfa
+NFC := src/nfc
+HAL := src/hal
+UDRV := src/udrv
 
+D_CFLAGS := -DANDROID -DBUILDCFG=1 \
+    -Wno-deprecated-register \
+    -Wno-unused-parameter \
+
+#Enable NXP Specific
+D_CFLAGS += -DNXP_EXTNS=TRUE
+D_CFLAGS += -DNFC_NXP_STAT_DUAL_UICC_EXT_SWITCH=FALSE
+D_CFLAGS += -DNFC_NXP_AID_MAX_SIZE_DYN=TRUE
+
+#Enable HCE-F specific
+D_CFLAGS += -DNXP_NFCC_HCE_F=TRUE
+
+#variables for NFC_NXP_CHIP_TYPE
+PN547C2 := 1
+PN548C2 := 2
+PN551   := 3
+PN553   := 4
+PN557   := 5
+
+ifeq ($(PN547C2),1)
+D_CFLAGS += -DPN547C2=1
+endif
+ifeq ($(PN548C2),2)
+D_CFLAGS += -DPN548C2=2
+endif
+ifeq ($(PN551),3)
+D_CFLAGS += -DPN551=3
+endif
+ifeq ($(PN553),4)
+D_CFLAGS += -DPN553=4
+endif
+ifeq ($(PN557),5)
+D_CFLAGS += -DPN557=5
+endif
+
+#### Select the JCOP OS Version ####
+JCOP_VER_3_1 := 1
+JCOP_VER_3_2 := 2
+JCOP_VER_3_3 := 3
+JCOP_VER_4_0 := 4
+
+LOCAL_CFLAGS += -DJCOP_VER_3_1=$(JCOP_VER_3_1)
+LOCAL_CFLAGS += -DJCOP_VER_3_2=$(JCOP_VER_3_2)
+LOCAL_CFLAGS += -DJCOP_VER_3_3=$(JCOP_VER_3_3)
+LOCAL_CFLAGS += -DJCOP_VER_4_0=$(JCOP_VER_4_0)
+
+NFC_NXP_ESE:= TRUE
+ifeq ($(NFC_NXP_ESE),TRUE)
+LOCAL_CFLAGS += -DNFC_NXP_ESE=TRUE
+LOCAL_CFLAGS += -DNFC_NXP_ESE_VER=$(JCOP_VER_4_0)
+else
+LOCAL_CFLAGS += -DNFC_NXP_ESE=FALSE
+endif
+
+ifeq ($(call is-board-platform-in-list,msm8909w msm8916 msm8994 msm8909 msm8996 msm8992 msm8952 msm8937 msm8953 msm8998),true)
+D_CFLAGS += -DNQ_NFC_DUAL_UICC=FALSE
+else
+D_CFLAGS += -DNQ_NFC_DUAL_UICC=TRUE
+endif
+
+#### Select the CHIP ####
+ifeq ($(strip $(NQ3XX_PRESENT)),true)
+NXP_CHIP_TYPE := $(PN553)
+else
+NXP_CHIP_TYPE := $(PN548C2)
+endif
+
+ifeq ($(NXP_CHIP_TYPE),$(PN547C2))
+D_CFLAGS += -DNFC_NXP_CHIP_TYPE=PN547C2
+else ifeq ($(NXP_CHIP_TYPE),$(PN548C2))
+D_CFLAGS += -DNFC_NXP_CHIP_TYPE=PN548C2
+else ifeq ($(NXP_CHIP_TYPE),$(PN551))
+D_CFLAGS += -DNFC_NXP_CHIP_TYPE=PN551
+else ifeq ($(NXP_CHIP_TYPE),$(PN553))
+D_CFLAGS += -DNFC_NXP_CHIP_TYPE=PN553
+else ifeq ($(NXP_CHIP_TYPE),$(PN557))
+D_CFLAGS += -DNFC_NXP_CHIP_TYPE=PN557
+endif
+
+#Gemalto SE support
+D_CFLAGS += -DGEMALTO_SE_SUPPORT
+D_CFLAGS += -DNXP_UICC_ENABLE
+ifeq ($(NXP_CHIP_TYPE),$(PN553))
+D_CFLAGS += -DJCOP_WA_ENABLE=FALSE
+else
+D_CFLAGS += -DJCOP_WA_ENABLE=TRUE
+endif
+
+#Routing Entries optimization
+D_CFLAGS += -DNFC_NXP_LISTEN_ROUTE_TBL_OPTIMIZATION=TRUE
+######################################
+# Build shared library system/lib/libnfc-nci.so for stack code.
+
+LOCAL_ARM_MODE := arm
+ifeq (true,$(TARGET_IS_64_BIT))
+LOCAL_MULTILIB := 64
+else
+LOCAL_MULTILIB := 32
+endif
+LOCAL_MODULE := libnqnfc-nci
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_OWNER := nxp
+LOCAL_SHARED_LIBRARIES := libhardware_legacy libcutils liblog libdl libhardware
+LOCAL_CFLAGS += $(D_CFLAGS)
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/src/include \
+    $(LOCAL_PATH)/src/gki/ulinux \
+    $(LOCAL_PATH)/src/gki/common \
+    $(LOCAL_PATH)/$(NFA)/include \
+    $(LOCAL_PATH)/$(NFA)/int \
+    $(LOCAL_PATH)/$(NFC)/include \
+    $(LOCAL_PATH)/$(NFC)/int \
+    $(LOCAL_PATH)/src/hal/include \
+    $(LOCAL_PATH)/src/hal/int \
+    $(LOCAL_PATH)/$(HALIMPL)/include \
+    system/libhwbinder/include
+
+# Treble configuration
+LOCAL_SHARED_LIBRARIES += libhidlbase libhidltransport libhwbinder libutils android.hardware.nfc@1.0 vendor.nxp.hardware.nfc@1.0
+LOCAL_SRC_FILES := \
+    $(call all-c-files-under, $(NFA)/ce $(NFA)/dm $(NFA)/ee) \
+    $(call all-c-files-under, $(NFA)/hci $(NFA)/int $(NFA)/p2p $(NFA)/rw $(NFA)/sys) \
+    $(call all-c-files-under, $(NFC)/int $(NFC)/llcp $(NFC)/nci $(NFC)/ndef $(NFC)/nfc $(NFC)/tags) \
+    $(call all-c-files-under, src/adaptation) \
+    $(call all-cpp-files-under, src/adaptation) \
+    $(call all-c-files-under, src/gki) \
+    src/nfca_version.c
 include $(BUILD_SHARED_LIBRARY)
 
 
 ######################################
 include $(call all-makefiles-under,$(LOCAL_PATH))
+endif
diff --git a/CleanSpec.mk b/CleanSpec.mk
new file mode 100644
index 0000000..cf3a247
--- /dev/null
+++ b/CleanSpec.mk
@@ -0,0 +1,50 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# If you don't need to do a full clean build but would like to touch
+# a file or delete some intermediate files, add a clean step to the end
+# of the list.  These steps will only be run once, if they haven't been
+# run before.
+#
+# E.g.:
+#     $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
+#     $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
+#
+# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
+# files that are missing or have been moved.
+#
+# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
+# Use $(OUT_DIR) to refer to the "out" directory.
+#
+# If you need to re-do something that's already mentioned, just copy
+# the command and add it to the bottom of the list.  E.g., if a change
+# that you made last week required touching a file and a change you
+# made today requires touching the same file, just copy the old
+# touch step and add it to the end of the list.
+#
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
+
+# For example:
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
+#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
+#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libnqnfc-nci_intermediates)
+
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_APACHE2
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/README.md b/README.md
index 01eeb1c..5dbc62f 100644
--- a/README.md
+++ b/README.md
@@ -1,30 +1,44 @@
-# NXPNFC_P61_JCOP_Kit
+#NFC_NCIHAL_libnfc-nci
 
 ####Git Repository
 
 | DESCRIPTION        | CHECKOUT COMMAND          |
-| :-------------: |:-------------:| 
-| NXPNFC_P61_JCOP_Kit    |  git clone https://github.com/NXPNFCProject/NXPNFC_P61_JCOP_Kit.git |
+|:-------------:|:-------------:|
+| NFC_NCIHAL_libnfc-nci     |  git clone https://github.com/NXPNFCProject/NFC_NCIHAL_libnfc-nci.git |
 
-####Supported Android Versions
+####Supported Versions on "master" Branch
 
 | Android Version        | NXP Release          | NXP Tag  |
 | :-------------: |:-------------:| :-----:|
-| android-6.0.0_r1                     |  3.1.0_M (PN547C2/PN548C2) |  SEAccessKit_AR3.1.0_OpnSrc |
-| android-6.0.0_r1                     |  3.2.0_M (PN547C2/PN548C2) |  SEAccessKit_AR3.2.0_OpnSrc |
-| android-6.0.1_r17                    |  3.3.0_M (PN551/PN548C2)   |  SEAccessKit_AR3.3.0_OpnSrc |
-| android-6.0.1_r17                    |  3.5.0_M (PN553)   |  SEAccessKit_AR3.5.0_OpnSrc |
-| android-7.0.0_r4                     |  3.5.2 (PN553)   |  SEAccessKit_AR3.5.2_OpnSrc |
-| android-6.0.1_r17                    |  3.6.0_M (PN551/PN548C2)   |  SEAccessKit_AR3.6.0_OpnSrc |
-| android-7.0.0_r12                     |  7.0.3_N (PN548C2/PN551/PN553) |  SEAccessKit_AR7.0.3_OpnSrc |
-| android-7.0.0_r12                     |  7.1.0_N (PN553) |  SEAccessKit_AR7.1.0_OpnSrc |
-| android-7.0.0_r12                     |  7.2.0_N (PN553) |  SEAccessKit_AR7.2.0_OpnSrc |
-| android-7.1.1_r1                     |  7.3.0_N (PN548C2/PN551) |  SEAccessKit_AR7.3.0_OpnSrc |
-| android-7.1.1_r1                     |  7.4.0_N (PN553) |  SEAccessKit_AR7.4.0_OpnSrc |
-| android-o-preview2                     |  8.0.9_O (PN553/PN557) |  SEAccessKit_AR8.0.9_OpnSrc |
-| android-o-preview2                     |  8.0.C_O (PN553/PN557) |  SEAccessKit_AR8.0.C_OpnSrc |
-| android-o-preview2                     |  8.0.13_O (PN553/PN557) |  SEAccessKit_AR8.0.13_OpnSrc |
-| android-8.0.0_r4               |  8.1.0_O (PN553) |  SEAccessKit_AR8.1.0_OpnSrc |
-| android-8.0.0_r4               |  8.2.0_O (PN557) |  SEAccessKit_AR8.2.0_OpnSrc |
-| android-8.0.0_r4               |  8.2.3_O (PN557) |  SEAccessKit_AR8.2.3_OpnSrc |
-| android-8.0.0_r4               |  8.3.0_O (PN548C2/PN551/PN553) |  SEAccessKit_AR8.3.0_OpnSrc |
+| android-5.0.0_r1/android5.1.0_r1     |  3.5.0_L (PN547C2/PN548C2) |  NFC_NCIHALx_AR0F.3.5.0_L_OpnSrc |
+
+####Supported Versions on "br_android_ncihalx_m" Branch
+
+| Android Version        | NXP Release          | NXP Tag  |
+| :-------------: |:-------------:| :-----:|
+| android-6.0.0_r1                     |  4.2.0_M (PN547C2/PN548C2) |  NFC_NCIHALx_AR0F.4.2.0_M_OpnSrc |
+| android-6.0.0_r1                     |  4.3.0_M (PN547C2/PN548C2) |  NFC_NCIHALx_AR0F.4.3.0_M_OpnSrc |
+| android-6.0.1_r17                    |  4.5.0_M (PN551/PN548C2)   |  NFC_NCIHALx_AR3C.4.5.0_M_OpnSrc |
+| android-6.0.1_r17                    |  4.7.0_M (PN553)   |  NFC_NCIHALx_ARC0.4.7.0_M_OpnSrc |
+| android-6.0.1_r17                    |  4.8.0_M (PN551/PN548C2)   |  NFC_NCIHALx_AR3C.4.8.0_M_OpnSrc |
+
+####Supported Versions on "br_android_ncihalx_n" Branch
+
+| Android Version        | NXP Release          | NXP Tag  |
+| :-------------: |:-------------:| :-----:|
+| android-7.0.0_r1                     |  7.0.3_N (PN548C2/PN551) |  NFC_NCIHALx_AR3C.7.0.3_N_OpnSrc |
+| android-7.0.0_r4                     |  7.0.4_N (PN553) |  NFC_NCIHALx_ARC0.7.0.4_N_OpnSrc |
+| android-7.0.0_r12                     |  7.1.0_N (PN548C2/PN551/PN553) |  NFC_NCIHALx_ARFC.7.1.0_N_OpnSrc |
+| android-7.0.0_r12                     |  7.2.0_N (PN553) |  NFC_NCIHALx_ARC0.7.2.0_N_OpnSrc |
+| android-7.0.0_r12                     |  7.3.0_N (PN553) |  NFC_NCIHALx_ARC0.7.3.0_N_OpnSrc |
+| android-7.1.1_r1                     |  7.4.0_N (PN548C2/PN551) |  NFC_NCIHALx_AR3C.7.4.0_N_OpnSrc |
+| android-7.1.1_r1                     |  7.5.0_N (PN553) |  NFC_NCIHALx_ARC0.7.5.0_N_OpnSrc |
+
+####Supported Versions on "br_android_ncihalx_o" Branch
+
+| Android Version        | NXP Release          | NXP Tag  |
+| :-------------: |:-------------:| :-----:|
+| android-o-preview2                     |  8.0.9_O (PN553/PN557) |  NFC_NCIHALx_AR1800.8.0.9_O_OpnSrc |
+| android-o-preview2                     |  8.0.C_O (PN553/PN557) |  NFC_NCIHALx_AR1800.8.0.C_O_OpnSrc |
+| android-o-preview2                     |  8.0.13_O (PN553/PN557) |  NFC_NCIHALx_AR18C0.8.0.13_O_OpnSrc |
+| android-8.0.0_r4               |  8.1.0_O (PN553) |  NFC_NCIHALx_AR00C0.8.1.0_O_OpnSrc |
diff --git a/README.md~ b/README.md~
new file mode 100644
index 0000000..ffa039d
--- /dev/null
+++ b/README.md~
@@ -0,0 +1,29 @@
+#NFC_NCIHAL_libnfc-nci
+
+####Git Repository
+
+| DESCRIPTION        | CHECKOUT COMMAND          |
+|:-------------:|:-------------:| 
+| NFC_NCIHAL_libnfc-nci     |  git clone https://github.com/NXPNFCProject/NFC_NCIHAL_libnfc-nci.git |
+
+####Supported Versions on "master" Branch
+
+| Android Version        | NXP Release          | NXP Tag  |
+| :-------------: |:-------------:| :-----:|
+| android-5.0.0_r1/android5.1.0_r1     |  3.5.0_L (PN547C2/PN548C2) |  NFC_NCIHALx_AR0F.3.5.0_L_OpnSrc |
+
+####Supported Versions on "br_android_ncihalx_m" Branch
+
+| Android Version        | NXP Release          | NXP Tag  |
+| :-------------: |:-------------:| :-----:|
+| android-6.0.0_r1                     |  4.2.0_M (PN547C2/PN548C2) |  NFC_NCIHALx_AR0F.4.2.0_M_OpnSrc |
+| android-6.0.0_r1                     |  4.3.0_M (PN547C2/PN548C2) |  NFC_NCIHALx_AR0F.4.3.0_M_OpnSrc |
+| android-6.0.1_r17                    |  4.5.0_M (PN551/PN548C2)   |  NFC_NCIHALx_AR3C.4.5.0_M_OpnSrc |
+| android-6.0.1_r17                    |  4.7.0_M (PN553)   |  NFC_NCIHALx_ARC0.4.7.0_M_OpnSrc |
+
+####Supported Versions on "br_android_ncihalx_n" Branch
+
+| Android Version        | NXP Release          | NXP Tag  |
+| :-------------: |:-------------:| :-----:|
+| android-7.0.0_r1                     |  7.0.3_N (PN548C2/PN551) |  NFC_NCIHALx_AR3C.7.0.3_N_OpnSrc |
+| android-7.0.0_r4                     |  7.0.4_N (PN553) |  NFC_NCIHALx_AR3C.7.0.4_N_OpnSrc |
diff --git a/halimpl/Android.mk b/halimpl/Android.mk
new file mode 100644
index 0000000..cfd03be
--- /dev/null
+++ b/halimpl/Android.mk
@@ -0,0 +1,2 @@
+LOCAL_PATH:= $(call my-dir)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/halimpl/bcm2079x/adaptation/CondVar.cpp b/halimpl/bcm2079x/adaptation/CondVar.cpp
new file mode 100644
index 0000000..c2dacdc
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/CondVar.cpp
@@ -0,0 +1,149 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Encapsulate a condition variable for thread synchronization.
+ *
+ ******************************************************************************/
+#define LOG_TAG "NfcNciHal"
+#include "OverrideLog.h"
+#include "CondVar.h"
+#include <errno.h>
+#include <string.h>
+
+
+/*******************************************************************************
+**
+** Function:        CondVar
+**
+** Description:     Initialize member variables.
+**
+** Returns:         None.
+**
+*******************************************************************************/
+CondVar::CondVar ()
+{
+    pthread_condattr_t attr;
+    pthread_condattr_init(&attr);
+    pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
+    memset (&mCondition, 0, sizeof(mCondition));
+    int const res = pthread_cond_init (&mCondition, &attr);
+    if (res)
+    {
+        ALOGE ("CondVar::CondVar: fail init; error=0x%X", res);
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function:        ~CondVar
+**
+** Description:     Cleanup all resources.
+**
+** Returns:         None.
+**
+*******************************************************************************/
+CondVar::~CondVar ()
+{
+    int const res = pthread_cond_destroy (&mCondition);
+    if (res)
+    {
+        ALOGE ("CondVar::~CondVar: fail destroy; error=0x%X", res);
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function:        wait
+**
+** Description:     Block the caller and wait for a condition.
+**
+** Returns:         None.
+**
+*******************************************************************************/
+void CondVar::wait (Mutex& mutex)
+{
+    int const res = pthread_cond_wait (&mCondition, mutex.nativeHandle());
+    if (res)
+    {
+        ALOGE ("CondVar::wait: fail wait; error=0x%X", res);
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function:        wait
+**
+** Description:     Block the caller and wait for a condition.
+**                  millisec: Timeout in milliseconds.
+**
+** Returns:         True if wait is successful; false if timeout occurs.
+**
+*******************************************************************************/
+bool CondVar::wait (Mutex& mutex, long millisec)
+{
+    bool retVal = false;
+    struct timespec absoluteTime;
+
+    if (clock_gettime (CLOCK_MONOTONIC, &absoluteTime) == -1)
+    {
+        ALOGE ("CondVar::wait: fail get time; errno=0x%X", errno);
+    }
+    else
+    {
+        absoluteTime.tv_sec += millisec / 1000;
+        long ns = absoluteTime.tv_nsec + ((millisec % 1000) * 1000000);
+        if (ns > 1000000000)
+        {
+            absoluteTime.tv_sec++;
+            absoluteTime.tv_nsec = ns - 1000000000;
+        }
+        else
+            absoluteTime.tv_nsec = ns;
+    }
+
+    int waitResult = pthread_cond_timedwait (&mCondition, mutex.nativeHandle(), &absoluteTime);
+    if ((waitResult != 0) && (waitResult != ETIMEDOUT))
+        ALOGE ("CondVar::wait: fail timed wait; error=0x%X", waitResult);
+    retVal = (waitResult == 0); //waited successfully
+    return retVal;
+}
+
+
+/*******************************************************************************
+**
+** Function:        notifyOne
+**
+** Description:     Unblock the waiting thread.
+**
+** Returns:         None.
+**
+*******************************************************************************/
+void CondVar::notifyOne ()
+{
+    int const res = pthread_cond_signal (&mCondition);
+    if (res)
+    {
+        ALOGE ("CondVar::notifyOne: fail signal; error=0x%X", res);
+    }
+}
+
diff --git a/halimpl/bcm2079x/adaptation/CondVar.h b/halimpl/bcm2079x/adaptation/CondVar.h
new file mode 100644
index 0000000..afa3fbf
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/CondVar.h
@@ -0,0 +1,95 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Encapsulate a condition variable for thread synchronization.
+ *
+ ******************************************************************************/
+
+#pragma once
+#include <pthread.h>
+#include "Mutex.h"
+
+
+class CondVar
+{
+public:
+    /*******************************************************************************
+    **
+    ** Function:        CondVar
+    **
+    ** Description:     Initialize member variables.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    CondVar ();
+
+
+    /*******************************************************************************
+    **
+    ** Function:        ~CondVar
+    **
+    ** Description:     Cleanup all resources.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    ~CondVar ();
+
+
+    /*******************************************************************************
+    **
+    ** Function:        wait
+    **
+    ** Description:     Block the caller and wait for a condition.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    void wait (Mutex& mutex);
+
+
+    /*******************************************************************************
+    **
+    ** Function:        wait
+    **
+    ** Description:     Block the caller and wait for a condition.
+    **                  millisec: Timeout in milliseconds.
+    **
+    ** Returns:         True if wait is successful; false if timeout occurs.
+    **
+    *******************************************************************************/
+    bool wait (Mutex& mutex, long millisec);
+
+
+    /*******************************************************************************
+    **
+    ** Function:        notifyOne
+    **
+    ** Description:     Unblock the waiting thread.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    void notifyOne ();
+
+private:
+    pthread_cond_t mCondition;
+};
diff --git a/halimpl/bcm2079x/adaptation/HalAdaptation.cpp b/halimpl/bcm2079x/adaptation/HalAdaptation.cpp
new file mode 100644
index 0000000..92e86b8
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/HalAdaptation.cpp
@@ -0,0 +1,415 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  HAL Adaptation Interface (HAI). This interface regulates the interaction
+ *  between standard Android HAL and Broadcom-specific HAL.  It adapts
+ *  Broadcom-specific features to the Android framework.
+ *
+ ******************************************************************************/
+#define LOG_TAG "NfcNciHal"
+#include "OverrideLog.h"
+#include "HalAdaptation.h"
+#include "SyncEvent.h"
+#include "config.h"
+#include "nfc_hal_int.h"
+#include "nfc_hal_post_reset.h"
+#include <errno.h>
+#include <pthread.h>
+#include <cutils/properties.h>
+#include "buildcfg.h"
+#include "android_logmsg.h"
+extern void delete_hal_non_volatile_store (bool forceDelete);
+extern void verify_hal_non_volatile_store ();
+extern void resetConfig ();
+extern "C"
+{
+#include "userial.h"
+}
+
+extern void configureCrystalFrequency ();
+
+///////////////////////////////////////
+// private declaration, definition
+
+
+static nfc_stack_callback_t* gAndroidHalCallback = NULL;
+static nfc_stack_data_callback_t* gAndroidHalDataCallback = NULL;
+static SyncEvent gOpenCompletedEvent;
+static SyncEvent gPostInitCompletedEvent;
+static SyncEvent gCloseCompletedEvent;
+
+UINT32 ScrProtocolTraceFlag = SCR_PROTO_TRACE_ALL; //0x017F00;
+
+static void BroadcomHalCallback (UINT8 event, tHAL_NFC_STATUS status);
+static void BroadcomHalDataCallback (UINT16 data_len, UINT8* p_data);
+
+static bool isColdBoot = true;
+
+extern tNFC_HAL_CFG *p_nfc_hal_cfg;
+extern const UINT8  nfca_version_string [];
+extern const UINT8  nfa_version_string [];
+
+tNFC_HAL_DM_PRE_SET_MEM nfc_hal_pre_set_mem_20795a1 [] =
+{
+    {0x0016403c,    0x00000008},
+    {0x0016403c,    0x00000000},
+    {0x0014008c,    0x00000001},
+    {0,         0}
+};
+
+extern tNFC_HAL_DM_PRE_SET_MEM *p_nfc_hal_dm_pre_set_mem;
+
+///////////////////////////////////////
+
+
+int HaiInitializeLibrary (const bcm2079x_dev_t* device)
+{
+    ALOGD ("%s: enter", __FUNCTION__);
+    ALOGE ("%s: ver=%s nfa=%s", __FUNCTION__, nfca_version_string, nfa_version_string);
+    int retval = EACCES;
+    unsigned long freq = 0;
+    unsigned long num = 0;
+    char temp[120];
+    int8_t prop_value;
+    UINT8 logLevel = 0;
+
+    logLevel = InitializeGlobalAppLogLevel ();
+
+    if ( GetNumValue ( NAME_GLOBAL_RESET, &num, sizeof ( num ) ) )
+    {
+        if (num == 1)
+        {
+            // Send commands to disable boc
+            p_nfc_hal_dm_pre_set_mem = nfc_hal_pre_set_mem_20795a1;
+        }
+    }
+
+    configureCrystalFrequency ();
+    verify_hal_non_volatile_store ();
+    if ( GetNumValue ( NAME_PRESERVE_STORAGE, (char*)&num, sizeof ( num ) ) &&
+            (num == 1) )
+        ALOGD ("%s: preserve HAL NV store", __FUNCTION__);
+    else
+    {
+        delete_hal_non_volatile_store (false);
+    }
+
+    if ( GetNumValue ( NAME_USE_RAW_NCI_TRACE, &num, sizeof ( num ) ) )
+    {
+        if (num == 1)
+        {
+            // display protocol traces in raw format
+            ProtoDispAdapterUseRawOutput (TRUE);
+        }
+    }
+
+    // Initialize protocol logging level
+    InitializeProtocolLogLevel ();
+
+    tUSERIAL_OPEN_CFG cfg;
+    struct tUART_CONFIG  uart;
+
+    if ( GetStrValue ( NAME_UART_PARITY, temp, sizeof ( temp ) ) )
+    {
+        if ( strcmp ( temp, "even" ) == 0 )
+            uart.m_iParity = USERIAL_PARITY_EVEN;
+        else if ( strcmp ( temp, "odd" ) == 0 )
+            uart.m_iParity = USERIAL_PARITY_ODD;
+        else if ( strcmp ( temp, "none" ) == 0 )
+            uart.m_iParity = USERIAL_PARITY_NONE;
+    }
+    else
+        uart.m_iParity = USERIAL_PARITY_NONE;
+
+    if ( GetStrValue ( NAME_UART_STOPBITS, temp, sizeof ( temp ) ) )
+    {
+        if ( strcmp ( temp, "1" ) == 0 )
+            uart.m_iStopbits = USERIAL_STOPBITS_1;
+        else if ( strcmp ( temp, "2" ) == 0 )
+            uart.m_iStopbits = USERIAL_STOPBITS_2;
+        else if ( strcmp ( temp, "1.5" ) == 0 )
+            uart.m_iStopbits = USERIAL_STOPBITS_1_5;
+    }
+    else if ( GetNumValue ( NAME_UART_STOPBITS, &num, sizeof ( num ) ) )
+    {
+        if ( num == 1 )
+            uart.m_iStopbits = USERIAL_STOPBITS_1;
+        else if ( num == 2 )
+            uart.m_iStopbits = USERIAL_STOPBITS_2;
+    }
+    else
+        uart.m_iStopbits = USERIAL_STOPBITS_1;
+
+    if ( GetNumValue ( NAME_UART_DATABITS, &num, sizeof ( num ) ) )
+    {
+        if ( 5 <= num && num <= 8 )
+            uart.m_iDatabits = ( 1 << ( num + 1 ) );
+    }
+    else
+        uart.m_iDatabits = USERIAL_DATABITS_8;
+
+    if ( GetNumValue ( NAME_UART_BAUD, &num, sizeof ( num ) ) )
+    {
+        if ( num == 300 ) uart.m_iBaudrate = USERIAL_BAUD_300;
+        else if ( num == 600 ) uart.m_iBaudrate = USERIAL_BAUD_600;
+        else if ( num == 1200 ) uart.m_iBaudrate = USERIAL_BAUD_1200;
+        else if ( num == 2400 ) uart.m_iBaudrate = USERIAL_BAUD_2400;
+        else if ( num == 9600 ) uart.m_iBaudrate = USERIAL_BAUD_9600;
+        else if ( num == 19200 ) uart.m_iBaudrate = USERIAL_BAUD_19200;
+        else if ( num == 57600 ) uart.m_iBaudrate = USERIAL_BAUD_57600;
+        else if ( num == 115200 ) uart.m_iBaudrate = USERIAL_BAUD_115200;
+        else if ( num == 230400 ) uart.m_iBaudrate = USERIAL_BAUD_230400;
+        else if ( num == 460800 ) uart.m_iBaudrate = USERIAL_BAUD_460800;
+        else if ( num == 921600 ) uart.m_iBaudrate = USERIAL_BAUD_921600;
+    }
+    else if ( GetStrValue ( NAME_UART_BAUD, temp, sizeof ( temp ) ) )
+    {
+        if ( strcmp ( temp, "auto" ) == 0 )
+            uart.m_iBaudrate = USERIAL_BAUD_AUTO;
+    }
+    else
+        uart.m_iBaudrate = USERIAL_BAUD_115200;
+
+    memset (&cfg, 0, sizeof(tUSERIAL_OPEN_CFG));
+    cfg.fmt = uart.m_iDatabits | uart.m_iParity | uart.m_iStopbits;
+    cfg.baud = uart.m_iBaudrate;
+
+    ALOGD ("%s: uart config=0x%04x, %d\n", __func__, cfg.fmt, cfg.baud);
+    USERIAL_Init(&cfg);
+
+    if ( GetNumValue ( NAME_NFCC_ENABLE_TIMEOUT, &num, sizeof ( num ) ) )
+    {
+        p_nfc_hal_cfg->nfc_hal_nfcc_enable_timeout = num;
+    }
+
+    if ( GetNumValue ( NAME_NFA_MAX_EE_SUPPORTED, &num, sizeof ( num ) ) && num == 0 )
+    {
+        // Since NFA_MAX_EE_SUPPORTED is explicetly set to 0, no UICC support is needed.
+        p_nfc_hal_cfg->nfc_hal_hci_uicc_support = 0;
+    }
+
+    prop_value = property_get_bool("nfc.bcm2079x.isColdboot", 0);
+    if (prop_value) {
+        isColdBoot = true;
+        property_set("nfc.bcm2079x.isColdboot", "0");
+    }
+    // Set 'first boot' flag based on static variable that will get set to false
+    // after the stack has first initialized the EE.
+    p_nfc_hal_cfg->nfc_hal_first_boot = isColdBoot ? TRUE : FALSE;
+
+    HAL_NfcInitialize ();
+    HAL_NfcSetTraceLevel (logLevel); // Initialize HAL's logging level
+
+    retval = 0;
+    ALOGD ("%s: exit %d", __FUNCTION__, retval);
+    return retval;
+}
+
+
+int HaiTerminateLibrary ()
+{
+    int retval = EACCES;
+    ALOGD ("%s: enter", __FUNCTION__);
+
+    HAL_NfcTerminate ();
+    gAndroidHalCallback = NULL;
+    gAndroidHalDataCallback = NULL;
+    GKI_shutdown ();
+    resetConfig ();
+    retval = 0;
+    ALOGD ("%s: exit %d", __FUNCTION__, retval);
+    return retval;
+}
+
+
+int HaiOpen (const bcm2079x_dev_t* device, nfc_stack_callback_t* halCallbackFunc, nfc_stack_data_callback_t* halDataCallbackFunc)
+{
+    ALOGD ("%s: enter", __FUNCTION__);
+    int retval = EACCES;
+
+    gAndroidHalCallback = halCallbackFunc;
+    gAndroidHalDataCallback = halDataCallbackFunc;
+
+    SyncEventGuard guard (gOpenCompletedEvent);
+    HAL_NfcOpen (BroadcomHalCallback, BroadcomHalDataCallback);
+    gOpenCompletedEvent.wait ();
+
+    retval = 0;
+    ALOGD ("%s: exit %d", __FUNCTION__, retval);
+    return retval;
+}
+
+
+void BroadcomHalCallback (UINT8 event, tHAL_NFC_STATUS status)
+{
+    ALOGD ("%s: enter; event=0x%X", __FUNCTION__, event);
+    switch (event)
+    {
+    case HAL_NFC_OPEN_CPLT_EVT:
+        {
+            ALOGD ("%s: HAL_NFC_OPEN_CPLT_EVT; status=0x%X", __FUNCTION__, status);
+            SyncEventGuard guard (gOpenCompletedEvent);
+            gOpenCompletedEvent.notifyOne ();
+            break;
+        }
+
+    case HAL_NFC_POST_INIT_CPLT_EVT:
+        {
+            ALOGD ("%s: HAL_NFC_POST_INIT_CPLT_EVT", __FUNCTION__);
+            SyncEventGuard guard (gPostInitCompletedEvent);
+            gPostInitCompletedEvent.notifyOne ();
+            break;
+        }
+
+    case HAL_NFC_CLOSE_CPLT_EVT:
+        {
+            ALOGD ("%s: HAL_NFC_CLOSE_CPLT_EVT", __FUNCTION__);
+            SyncEventGuard guard (gCloseCompletedEvent);
+            gCloseCompletedEvent.notifyOne ();
+            break;
+        }
+
+    case HAL_NFC_ERROR_EVT:
+        {
+            ALOGD ("%s: HAL_NFC_ERROR_EVT", __FUNCTION__);
+            {
+                SyncEventGuard guard (gOpenCompletedEvent);
+                gOpenCompletedEvent.notifyOne ();
+            }
+            {
+                SyncEventGuard guard (gPostInitCompletedEvent);
+                gPostInitCompletedEvent.notifyOne ();
+            }
+            {
+                SyncEventGuard guard (gCloseCompletedEvent);
+                gCloseCompletedEvent.notifyOne ();
+            }
+            break;
+        }
+    }
+    gAndroidHalCallback (event, status);
+    ALOGD ("%s: exit; event=0x%X", __FUNCTION__, event);
+}
+
+
+void BroadcomHalDataCallback (UINT16 data_len, UINT8* p_data)
+{
+    ALOGD ("%s: enter; len=%u", __FUNCTION__, data_len);
+    gAndroidHalDataCallback (data_len, p_data);
+}
+
+
+int HaiClose (const bcm2079x_dev_t* device)
+{
+    ALOGD ("%s: enter", __FUNCTION__);
+    int retval = EACCES;
+
+    SyncEventGuard guard (gCloseCompletedEvent);
+    HAL_NfcClose ();
+    gCloseCompletedEvent.wait ();
+    retval = 0;
+    ALOGD ("%s: exit %d", __FUNCTION__, retval);
+    return retval;
+}
+
+
+int HaiCoreInitialized (const bcm2079x_dev_t* device, uint8_t* coreInitResponseParams)
+{
+    ALOGD ("%s: enter", __FUNCTION__);
+    int retval = EACCES;
+
+    SyncEventGuard guard (gPostInitCompletedEvent);
+    HAL_NfcCoreInitialized (0, coreInitResponseParams);
+    gPostInitCompletedEvent.wait ();
+    retval = 0;
+    ALOGD ("%s: exit %d", __FUNCTION__, retval);
+    return retval;
+}
+
+
+int HaiWrite (const bcm2079x_dev_t* dev, uint16_t dataLen, const uint8_t* data)
+{
+    ALOGD ("%s: enter; len=%u", __FUNCTION__, dataLen);
+    int retval = EACCES;
+
+    HAL_NfcWrite (dataLen, const_cast<UINT8*> (data));
+    retval = 0;
+    ALOGD ("%s: exit %d", __FUNCTION__, retval);
+    return retval;
+}
+
+
+int HaiPreDiscover (const bcm2079x_dev_t* device)
+{
+    ALOGD ("%s: enter", __FUNCTION__);
+    int retval = EACCES;
+
+    // This function is a clear indication that the stack is initializing
+    // EE.  So we can reset the cold-boot flag here.
+    isColdBoot = false;
+    retval = HAL_NfcPreDiscover () ? 1 : 0;
+    ALOGD ("%s: exit %d", __FUNCTION__, retval);
+    return retval;
+}
+
+
+int HaiControlGranted (const bcm2079x_dev_t* device)
+{
+    ALOGD ("%s: enter", __FUNCTION__);
+    int retval = EACCES;
+
+    HAL_NfcControlGranted ();
+    retval = 0;
+    ALOGD ("%s: exit %d", __FUNCTION__, retval);
+    return retval;
+}
+
+
+int HaiPowerCycle (const bcm2079x_dev_t* device)
+{
+    ALOGD ("%s: enter", __FUNCTION__);
+    int retval = EACCES;
+
+    HAL_NfcPowerCycle ();
+    retval = 0;
+    ALOGD ("%s: exit %d", __FUNCTION__, retval);
+    return retval;
+}
+
+
+int HaiGetMaxNfcee (const bcm2079x_dev_t* device, uint8_t* maxNfcee)
+{
+    ALOGD ("%s: enter", __FUNCTION__);
+    int retval = EACCES;
+
+    // This function is a clear indication that the stack is initializing
+    // EE.  So we can reset the cold-boot flag here.
+    isColdBoot = false;
+
+    if ( maxNfcee )
+    {
+        *maxNfcee = HAL_NfcGetMaxNfcee ();
+        ALOGD("%s: max_ee from HAL to use %d", __FUNCTION__, *maxNfcee);
+        retval = 0;
+    }
+    ALOGD ("%s: exit %d", __FUNCTION__, retval);
+    return retval;
+}
+
diff --git a/halimpl/bcm2079x/adaptation/Mutex.cpp b/halimpl/bcm2079x/adaptation/Mutex.cpp
new file mode 100644
index 0000000..f931493
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/Mutex.cpp
@@ -0,0 +1,142 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Encapsulate a mutex for thread synchronization.
+ *
+ ******************************************************************************/
+
+#define LOG_TAG "NfcNciHal"
+#include "OverrideLog.h"
+#include "Mutex.h"
+#include <errno.h>
+#include <string.h>
+
+/*******************************************************************************
+**
+** Function:        Mutex
+**
+** Description:     Initialize member variables.
+**
+** Returns:         None.
+**
+*******************************************************************************/
+Mutex::Mutex ()
+{
+    memset (&mMutex, 0, sizeof(mMutex));
+    int res = pthread_mutex_init (&mMutex, NULL);
+    if (res != 0)
+    {
+        ALOGE ("Mutex::Mutex: fail init; error=0x%X", res);
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function:        ~Mutex
+**
+** Description:     Cleanup all resources.
+**
+** Returns:         None.
+**
+*******************************************************************************/
+Mutex::~Mutex ()
+{
+    int res = pthread_mutex_destroy (&mMutex);
+    if (res != 0)
+    {
+        ALOGE ("Mutex::~Mutex: fail destroy; error=0x%X", res);
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function:        lock
+**
+** Description:     Block the thread and try lock the mutex.
+**
+** Returns:         None.
+**
+*******************************************************************************/
+void Mutex::lock ()
+{
+    int res = pthread_mutex_lock (&mMutex);
+    if (res != 0)
+    {
+        ALOGE ("Mutex::lock: fail lock; error=0x%X", res);
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function:        unlock
+**
+** Description:     Unlock a mutex to unblock a thread.
+**
+** Returns:         None.
+**
+*******************************************************************************/
+void Mutex::unlock ()
+{
+    int res = pthread_mutex_unlock (&mMutex);
+    if (res != 0)
+    {
+        ALOGE ("Mutex::unlock: fail unlock; error=0x%X", res);
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function:        tryLock
+**
+** Description:     Try to lock the mutex.
+**
+** Returns:         True if the mutex is locked.
+**
+*******************************************************************************/
+bool Mutex::tryLock ()
+{
+    int res = pthread_mutex_trylock (&mMutex);
+    if ((res != 0) && (res != EBUSY))
+    {
+        ALOGE ("Mutex::tryLock: error=0x%X", res);
+    }
+    return res == 0;
+}
+
+
+/*******************************************************************************
+**
+** Function:        nativeHandle
+**
+** Description:     Get the handle of the mutex.
+**
+** Returns:         Handle of the mutex.
+**
+*******************************************************************************/
+pthread_mutex_t* Mutex::nativeHandle ()
+{
+    return &mMutex;
+}
+
+
diff --git a/halimpl/bcm2079x/adaptation/Mutex.h b/halimpl/bcm2079x/adaptation/Mutex.h
new file mode 100644
index 0000000..5091894
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/Mutex.h
@@ -0,0 +1,106 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Encapsulate a mutex for thread synchronization.
+ *
+ ******************************************************************************/
+
+#pragma once
+#include <pthread.h>
+
+
+class Mutex
+{
+public:
+    /*******************************************************************************
+    **
+    ** Function:        Mutex
+    **
+    ** Description:     Initialize member variables.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    Mutex ();
+
+
+    /*******************************************************************************
+    **
+    ** Function:        ~Mutex
+    **
+    ** Description:     Cleanup all resources.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    ~Mutex ();
+
+
+    /*******************************************************************************
+    **
+    ** Function:        lock
+    **
+    ** Description:     Block the thread and try lock the mutex.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    void lock ();
+
+
+    /*******************************************************************************
+    **
+    ** Function:        unlock
+    **
+    ** Description:     Unlock a mutex to unblock a thread.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    void unlock ();
+
+
+    /*******************************************************************************
+    **
+    ** Function:        tryLock
+    **
+    ** Description:     Try to lock the mutex.
+    **
+    ** Returns:         True if the mutex is locked.
+    **
+    *******************************************************************************/
+    bool tryLock ();
+
+
+    /*******************************************************************************
+    **
+    ** Function:        nativeHandle
+    **
+    ** Description:     Get the handle of the mutex.
+    **
+    ** Returns:         Handle of the mutex.
+    **
+    *******************************************************************************/
+    pthread_mutex_t* nativeHandle ();
+
+private:
+    pthread_mutex_t mMutex;
+};
+
diff --git a/halimpl/bcm2079x/adaptation/NonVolatileStore.cpp b/halimpl/bcm2079x/adaptation/NonVolatileStore.cpp
new file mode 100644
index 0000000..f921f99
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/NonVolatileStore.cpp
@@ -0,0 +1,275 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "OverrideLog.h"
+#define LOG_TAG "NfcNciHal"
+#include "gki.h"
+extern "C"
+{
+    #include "nfc_hal_target.h"
+    #include "nfc_hal_nv_ci.h"
+}
+#include "config.h"
+#include "CrcChecksum.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string>
+
+
+//directory of HAL's non-volatile storage
+static const char* default_location = "/data/nfc";
+static const char* filename_prefix = "/halStorage.bin";
+static const std::string get_storage_location ();
+void delete_hal_non_volatile_store (bool forceDelete);
+void verify_hal_non_volatile_store ();
+
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nv_co_read
+**
+** Description      This function is called by NFA to read in data from the
+**                  previously opened file.
+**
+** Parameters       p_buf   - buffer to read the data into.
+**                  nbytes  - number of bytes to read into the buffer.
+**
+** Returns          void
+**
+**                  Note: Upon completion of the request, nfc_hal_nv_ci_read () is
+**                        called with the buffer of data, along with the number
+**                        of bytes read into the buffer, and a status.  The
+**                        call-in function should only be called when ALL requested
+**                        bytes have been read, the end of file has been detected,
+**                        or an error has occurred.
+**
+*******************************************************************************/
+void nfc_hal_nv_co_read (UINT8 *p_buf, UINT16 nbytes, UINT8 block)
+{
+    std::string fn = get_storage_location();
+    char filename[256];
+
+    fn.append (filename_prefix);
+    if (fn.length() > 200)
+    {
+        ALOGE ("%s: filename too long", __FUNCTION__);
+        return;
+    }
+    snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), block);
+
+    ALOGD ("%s: buffer len=%u; file=%s", __FUNCTION__, nbytes, filename);
+    int fileStream = open (filename, O_RDONLY);
+    if (fileStream >= 0)
+    {
+        unsigned short checksum = 0;
+        size_t actualReadCrc = read (fileStream, &checksum, sizeof(checksum));
+        size_t actualReadData = read (fileStream, p_buf, nbytes);
+        close (fileStream);
+        if (actualReadData > 0)
+        {
+            ALOGD ("%s: data size=%u", __FUNCTION__, actualReadData);
+            nfc_hal_nv_ci_read (actualReadData, NFC_HAL_NV_CO_OK, block);
+        }
+        else
+        {
+            ALOGE ("%s: fail to read", __FUNCTION__);
+            nfc_hal_nv_ci_read (0, NFC_HAL_NV_CO_FAIL, block);
+        }
+    }
+    else
+    {
+        ALOGD ("%s: fail to open", __FUNCTION__);
+        nfc_hal_nv_ci_read (0, NFC_HAL_NV_CO_FAIL, block);
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nv_co_write
+**
+** Description      This function is called by io to send file data to the
+**                  phone.
+**
+** Parameters       p_buf   - buffer to read the data from.
+**                  nbytes  - number of bytes to write out to the file.
+**
+** Returns          void
+**
+**                  Note: Upon completion of the request, nfc_hal_nv_ci_write () is
+**                        called with the file descriptor and the status.  The
+**                        call-in function should only be called when ALL requested
+**                        bytes have been written, or an error has been detected,
+**
+*******************************************************************************/
+void nfc_hal_nv_co_write (const UINT8 *p_buf, UINT16 nbytes, UINT8 block)
+{
+    std::string fn = get_storage_location();
+    char filename[256];
+    int fileStream = 0;
+
+    fn.append (filename_prefix);
+    if (fn.length() > 200)
+    {
+        ALOGE ("%s: filename too long", __FUNCTION__);
+        return;
+    }
+    snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), block);
+    ALOGD ("%s: bytes=%u; file=%s", __FUNCTION__, nbytes, filename);
+
+    fileStream = open (filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
+    if (fileStream >= 0)
+    {
+        unsigned short checksum = crcChecksumCompute (p_buf, nbytes);
+        size_t actualWrittenCrc = write (fileStream, &checksum, sizeof(checksum));
+        size_t actualWrittenData = write (fileStream, p_buf, nbytes);
+        ALOGD ("%s: %d bytes written", __FUNCTION__, actualWrittenData);
+        if ((actualWrittenData == nbytes) && (actualWrittenCrc == sizeof(checksum)))
+        {
+            nfc_hal_nv_ci_write (NFC_HAL_NV_CO_OK);
+        }
+        else
+        {
+            ALOGE ("%s: fail to write", __FUNCTION__);
+            nfc_hal_nv_ci_write (NFC_HAL_NV_CO_FAIL);
+        }
+        close (fileStream);
+    }
+    else
+    {
+        ALOGE ("%s: fail to open, error = %d", __FUNCTION__, errno);
+        nfc_hal_nv_ci_write (NFC_HAL_NV_CO_FAIL);
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         get_storage_location
+**
+** Description      Get the absolute directory path of the HAL's storage location.
+**
+** Parameters       none
+**
+** Returns          Absolute path.
+**
+*******************************************************************************/
+const std::string get_storage_location ()
+{
+    char buffer [100];
+    memset (buffer, 0, sizeof(buffer));
+    if (!GetStrValue (NAME_NFA_STORAGE, buffer, sizeof(buffer)))
+        return default_location;
+    else
+        return std::string (buffer);
+}
+
+
+/*******************************************************************************
+**
+** Function         delete_hal_non_volatile_store
+**
+** Description      Delete all the content of the HAL's storage location.
+**
+** Parameters       forceDelete: unconditionally delete the storage.
+**
+** Returns          none
+**
+*******************************************************************************/
+void delete_hal_non_volatile_store (bool forceDelete)
+{
+    static bool firstTime = true;
+    std::string fn = get_storage_location();
+    char filename[256];
+    int stat = 0;
+
+    if ((firstTime == false) && (forceDelete == false))
+        return;
+    firstTime = false;
+
+    ALOGD ("%s", __FUNCTION__);
+
+    fn.append (filename_prefix);
+    if (fn.length() > 200)
+    {
+        ALOGE ("%s: filename too long", __FUNCTION__);
+        return;
+    }
+
+    snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), DH_NV_BLOCK);
+    remove (filename);
+    snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F3_NV_BLOCK);
+    remove (filename);
+    snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F4_NV_BLOCK);
+    remove (filename);
+    snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F2_NV_BLOCK);
+    remove (filename);
+    snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F5_NV_BLOCK);
+    remove (filename);
+}
+
+
+/*******************************************************************************
+**
+** Function         verify_hal_non_volatile_store
+**
+** Description      Verify the content of all non-volatile store.
+**
+** Parameters       none
+**
+** Returns          none
+**
+*******************************************************************************/
+void verify_hal_non_volatile_store ()
+{
+    ALOGD ("%s", __FUNCTION__);
+    std::string fn = get_storage_location();
+    char filename[256];
+    bool isValid = false;
+
+    fn.append (filename_prefix);
+    if (fn.length() > 200)
+    {
+        ALOGE ("%s: filename too long", __FUNCTION__);
+        return;
+    }
+
+    snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), DH_NV_BLOCK);
+    if (crcChecksumVerifyIntegrity (filename))
+    {
+        snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F3_NV_BLOCK);
+        if (crcChecksumVerifyIntegrity (filename))
+        {
+            snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F4_NV_BLOCK);
+            if (crcChecksumVerifyIntegrity (filename))
+            {
+                snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F2_NV_BLOCK);
+                if (crcChecksumVerifyIntegrity (filename))
+                {
+                    snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F5_NV_BLOCK);
+                    if (crcChecksumVerifyIntegrity (filename))
+                        isValid = true;
+                }
+            }
+        }
+    }
+
+    if (isValid == false)
+        delete_hal_non_volatile_store (true);
+}
diff --git a/halimpl/bcm2079x/adaptation/OverrideLog.cpp b/halimpl/bcm2079x/adaptation/OverrideLog.cpp
new file mode 100644
index 0000000..ce40d8a
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/OverrideLog.cpp
@@ -0,0 +1,102 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Override the ALOGD(), ALOGE(), and other logging macros from
+ *  /system/core/include/cutils/log.h
+ *
+ ******************************************************************************/
+#include "OverrideLog.h"
+#include <cutils/properties.h>
+#include <string.h>
+#include "config.h"
+#include "android_logmsg.h"
+#define LOG_TAG "NfcNciHal"
+
+
+unsigned char appl_trace_level = BT_TRACE_LEVEL_DEBUG;
+
+/*******************************************************************************
+**
+** Function:        InitializeGlobalAppLogLevel
+**
+** Description:     Initialize and get global logging level from
+**                  Android property nfc.app_log_level.
+**
+** Returns:         Global log level:
+**                  BT_TRACE_LEVEL_NONE    0        * No trace messages to be generated
+**                  BT_TRACE_LEVEL_ERROR   1        * Error condition trace messages
+**                  BT_TRACE_LEVEL_WARNING 2        * Warning condition trace messages
+**                  BT_TRACE_LEVEL_API     3        * API traces
+**                  BT_TRACE_LEVEL_EVENT   4        * Debug messages for events
+**                  BT_TRACE_LEVEL_DEBUG   5        * Debug messages (general)
+**
+*******************************************************************************/
+unsigned char InitializeGlobalAppLogLevel ()
+{
+    unsigned long num = 0;
+    char valueStr [PROPERTY_VALUE_MAX] = {0};
+
+    num = 1;
+    if (GetNumValue (NAME_APPL_TRACE_LEVEL, &num, sizeof(num)))
+        appl_trace_level = (unsigned char) num;
+
+    int len = property_get ("nfc.app_log_level", valueStr, "");
+    if (len > 0)
+    {
+        //let Android property override default value
+        sscanf (valueStr, "%lu", &num);
+        appl_trace_level = (unsigned char) num;
+    }
+
+    //0xFF is a special value used by the stack to query the current
+    //trace level; it does not change any trace level
+    if (appl_trace_level == 0xFF)
+        appl_trace_level = BT_TRACE_LEVEL_DEBUG;
+    ALOGD ("%s: level=%u", __FUNCTION__, appl_trace_level);
+
+    if (appl_trace_level < BT_TRACE_LEVEL_DEBUG)
+    {
+        //display protocol traces in raw format
+        ProtoDispAdapterUseRawOutput (TRUE);
+    }
+    return appl_trace_level;
+}
+
+UINT32 InitializeProtocolLogLevel () {
+    UINT32 num = 0;
+    char valueStr [PROPERTY_VALUE_MAX] = {0};
+
+    if ( GetNumValue ( NAME_PROTOCOL_TRACE_LEVEL, &num, sizeof ( num ) ) )
+        ScrProtocolTraceFlag = num;
+
+    int len = property_get ("nfc.enable_protocol_log", valueStr, "");
+    if (len > 0)
+    {
+        if (strncmp("0", valueStr, 1) == 0)
+        {
+            ScrProtocolTraceFlag = 0;
+        } else {
+            ScrProtocolTraceFlag = ~0;
+        }
+    }
+
+    return ScrProtocolTraceFlag;
+}
+
diff --git a/halimpl/bcm2079x/adaptation/StartupConfig.cpp b/halimpl/bcm2079x/adaptation/StartupConfig.cpp
new file mode 100644
index 0000000..f296763
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/StartupConfig.cpp
@@ -0,0 +1,155 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ * Construct a buffer that contains multiple Type-Length-Value contents
+ * that is used by the HAL in a CORE_SET_CONFIG NCI command.
+ ******************************************************************************/
+
+#define LOG_TAG "NfcNciHal"
+#include "OverrideLog.h"
+#include "StartupConfig.h"
+
+
+const UINT8 StartupConfig::mMaxLength = 255;
+
+
+/*******************************************************************************
+**
+** Function:        initialize
+**
+** Description:     Initialize all member variables.
+**
+** Returns:         None
+**
+*******************************************************************************/
+StartupConfig::StartupConfig ()
+{
+    //set first byte to 0, which is length of payload
+    mBuffer.append ((uint8_string::size_type) 1, (uint8_string::value_type) 0);
+}
+
+
+/*******************************************************************************
+**
+** Function:        initialize
+**
+** Description:     Reset all member variables.
+**
+** Returns:         None
+**
+*******************************************************************************/
+void StartupConfig::initialize ()
+{
+    mBuffer.clear ();
+    //set first byte to 0, which is length of payload
+    mBuffer.append ((uint8_string::size_type) 1, (uint8_string::value_type) 0);
+}
+
+
+/*******************************************************************************
+**
+** Function:        getInternalBuffer
+**
+** Description:     Get the pointer to buffer that contains multiple
+**                  Type-Length-Value contents.
+**
+** Returns:         Pointer to buffer.
+**
+*******************************************************************************/
+const UINT8* StartupConfig::getInternalBuffer ()
+{
+    return mBuffer.data ();
+}
+
+
+/*******************************************************************************
+**
+** Function:        append
+**
+** Description:     Append new config data to internal buffer.
+**                  newContent: buffer containing new content; newContent[0] is
+**                          payload length; newContent[1..end] is payload.
+**                  newContentLen: total length of newContent.
+**
+** Returns:         True if ok.
+**
+*******************************************************************************/
+bool StartupConfig::append (const UINT8* newContent, UINT8 newContentLen)
+{
+    static const char fn [] = "StartupConfig::append";
+    if ((newContentLen+mBuffer.size()) > mMaxLength)
+    {
+        ALOGE ("%s: exceed max length", fn);
+        return false;
+    }
+
+    ALOGD ("%s: try append %u bytes", fn, (uint8_string::size_type) (newContentLen));
+    //append new payload into private buffer
+    mBuffer.append (newContent+1, (uint8_string::size_type) (newContentLen-1));
+    //increase size counter of payload in private buffer
+    mBuffer[0] = mBuffer[0] + newContentLen-1;
+    ALOGD ("%s: new size %u bytes", fn, mBuffer[0]);
+    return true;
+};
+
+
+/*******************************************************************************
+**
+** Function:        disableSecureElement
+**
+** Description:     Adjust a TLV to disable secure element(s).  The TLV's type is 0xC2.
+**                  bitmask: 0xC0 = do not detect any secure element.
+**                           0x40 = do not detect secure element in slot 0.
+**                           0x80 = do not detect secure element in slot 1.
+**
+** Returns:         True if ok.
+**
+*******************************************************************************/
+bool StartupConfig::disableSecureElement (UINT8 bitmask)
+{
+    const UINT8 maxLen = mBuffer[0];
+    UINT8 index = 1, tlvType = 0, tlvLen = 0;
+    bool found0xC2 = false;
+
+    while (true)
+    {
+        if (index > maxLen)
+            break;
+        tlvType = mBuffer [index];
+        index++;
+        tlvLen = mBuffer [index];
+        index++;
+        if (tlvType == 0xC2) //this TLV controls secure elements
+        {
+            index++; //index of second byte in TLV's value
+            mBuffer [index] = mBuffer [index] | bitmask; //turn on certain bits
+            found0xC2 = true;
+        }
+        else
+            index += tlvLen;
+    }
+
+    if (found0xC2 == false)
+    {
+        UINT8 tlv [] = {0x04, 0xC2, 0x02, 0x61, 0x00};
+        tlv [4] = tlv [4] | bitmask;
+        found0xC2 = append (tlv, 5);
+    }
+    return found0xC2;
+}
diff --git a/halimpl/bcm2079x/adaptation/SyncEvent.h b/halimpl/bcm2079x/adaptation/SyncEvent.h
new file mode 100644
index 0000000..2a56aca
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/SyncEvent.h
@@ -0,0 +1,175 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Synchronize two or more threads using a condition variable and a mutex.
+ *
+ ******************************************************************************/
+#pragma once
+#include "CondVar.h"
+#include "Mutex.h"
+
+
+class SyncEvent
+{
+public:
+    /*******************************************************************************
+    **
+    ** Function:        ~SyncEvent
+    **
+    ** Description:     Cleanup all resources.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    ~SyncEvent ()
+    {
+    }
+
+
+    /*******************************************************************************
+    **
+    ** Function:        start
+    **
+    ** Description:     Start a synchronization operation.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    void start ()
+    {
+        mMutex.lock ();
+    }
+
+
+    /*******************************************************************************
+    **
+    ** Function:        wait
+    **
+    ** Description:     Block the thread and wait for the event to occur.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    void wait ()
+    {
+        mCondVar.wait (mMutex);
+    }
+
+
+    /*******************************************************************************
+    **
+    ** Function:        wait
+    **
+    ** Description:     Block the thread and wait for the event to occur.
+    **                  millisec: Timeout in milliseconds.
+    **
+    ** Returns:         True if wait is successful; false if timeout occurs.
+    **
+    *******************************************************************************/
+    bool wait (long millisec)
+    {
+        bool retVal = mCondVar.wait (mMutex, millisec);
+        return retVal;
+    }
+
+
+    /*******************************************************************************
+    **
+    ** Function:        notifyOne
+    **
+    ** Description:     Notify a blocked thread that the event has occured. Unblocks it.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    void notifyOne ()
+    {
+        mCondVar.notifyOne ();
+    }
+
+
+    /*******************************************************************************
+    **
+    ** Function:        end
+    **
+    ** Description:     End a synchronization operation.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    void end ()
+    {
+        mMutex.unlock ();
+    }
+
+private:
+    CondVar mCondVar;
+    Mutex mMutex;
+};
+
+
+/*****************************************************************************/
+/*****************************************************************************/
+
+
+/*****************************************************************************
+**
+**  Name:           SyncEventGuard
+**
+**  Description:    Automatically start and end a synchronization event.
+**
+*****************************************************************************/
+class SyncEventGuard
+{
+public:
+    /*******************************************************************************
+    **
+    ** Function:        SyncEventGuard
+    **
+    ** Description:     Start a synchronization operation.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    SyncEventGuard (SyncEvent& event)
+    :   mEvent (event)
+    {
+        event.start (); //automatically start operation
+    };
+
+
+    /*******************************************************************************
+    **
+    ** Function:        ~SyncEventGuard
+    **
+    ** Description:     End a synchronization operation.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    ~SyncEventGuard ()
+    {
+        mEvent.end (); //automatically end operation
+    };
+
+private:
+    SyncEvent& mEvent;
+};
+
diff --git a/halimpl/bcm2079x/adaptation/android_logmsg.cpp b/halimpl/bcm2079x/adaptation/android_logmsg.cpp
new file mode 100644
index 0000000..86fc9b8
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/android_logmsg.cpp
@@ -0,0 +1,360 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "OverrideLog.h"
+#include "android_logmsg.h"
+#include "nfc_target.h"
+#include "buildcfg.h"
+#include <cutils/log.h>
+
+
+extern UINT32 ScrProtocolTraceFlag;
+#define MAX_NCI_PACKET_SIZE 259
+#define BTE_LOG_BUF_SIZE 1024
+#define BTE_LOG_MAX_SIZE (BTE_LOG_BUF_SIZE - 12)
+#define MAX_LOGCAT_LINE 4096
+#define PRINT(s) __android_log_write (ANDROID_LOG_DEBUG, "BrcmNci", s)
+static char log_line [MAX_LOGCAT_LINE];
+static const char* sTable = "0123456789abcdef";
+static BOOLEAN sIsUseRaw = FALSE;
+static void ToHex (const UINT8* data, UINT16 len, char* hexString, UINT16 hexStringSize);
+static void dumpbin (const char* data, int size, UINT32 trace_layer, UINT32 trace_type);
+static inline void word2hex (const char* data, char** hex);
+static inline void byte2char (const char* data, char** str);
+static inline void byte2hex (const char* data, char** str);
+
+
+void BTDISP_LOCK_LOG()
+{
+}
+
+
+void BTDISP_UNLOCK_LOG()
+{
+}
+
+
+void BTDISP_INIT_LOCK()
+{
+}
+
+
+void BTDISP_UNINIT_LOCK()
+{
+}
+
+
+void ProtoDispAdapterUseRawOutput (BOOLEAN isUseRaw)
+{
+    sIsUseRaw = isUseRaw;
+}
+
+
+void ProtoDispAdapterDisplayNciPacket (UINT8 *nciPacket, UINT16 nciPacketLen, BOOLEAN is_recv)
+{
+    //Protocol decoder is not available, so decode NCI packet into hex numbers.
+    if (!(ScrProtocolTraceFlag & SCR_PROTO_TRACE_NCI))
+        return;
+    char line_buf [(MAX_NCI_PACKET_SIZE*2)+1];
+    ToHex (nciPacket, nciPacketLen, line_buf, sizeof(line_buf));
+    __android_log_write (ANDROID_LOG_DEBUG, (is_recv) ? "BrcmNciR": "BrcmNciX", line_buf);
+}
+
+
+void ToHex (const UINT8* data, UINT16 len, char* hexString, UINT16 hexStringSize)
+{
+    int i=0, j=0;
+    for(i = 0, j = 0; i < len && j < hexStringSize-3; i++)
+    {
+        hexString [j++] = sTable [(*data >> 4) & 0xf];
+        hexString [j++] = sTable [*data & 0xf];
+        data++;
+    }
+    hexString [j] = '\0';
+}
+
+
+//Protodisp code calls ScrLog() to print decoded texts.
+void ScrLog (UINT32 trace_set_mask, const char *fmt_str, ...)
+{
+    static char buffer [BTE_LOG_BUF_SIZE];
+    va_list ap;
+
+    va_start (ap, fmt_str);
+    vsnprintf (buffer, BTE_LOG_MAX_SIZE, fmt_str, ap);
+    va_end (ap);
+    __android_log_write(ANDROID_LOG_INFO, "BrcmNci", buffer);
+}
+
+
+UINT8 *scru_dump_hex (UINT8 *p, char *pTitle, UINT32 len, UINT32 layer, UINT32 type)
+{
+    if(pTitle && *pTitle)
+        PRINT(pTitle);
+    dumpbin((char*) p, len, layer, type);
+    return p;
+}
+
+
+void dumpbin(const char* data, int size, UINT32 trace_layer, UINT32 trace_type)
+{
+    char line_buff[256];
+    char *line;
+    int i, j, addr;
+    const int width = 16;
+    if(size <= 0)
+        return;
+    for(i = 0; i < size / width; i++)
+    {
+        line = line_buff;
+        //write address:
+        addr = i*width;
+        word2hex((const char*)&addr, &line);
+        *line++ = ':'; *line++ = ' ';
+        //write hex of data
+        for(j = 0; j < width; j++)
+        {
+            byte2hex(&data[j], &line);
+            *line++ = ' ';
+        }
+        //write char of data
+        for(j = 0; j < width; j++)
+            byte2char(data++, &line);
+        //wirte the end of line
+        *line = 0;
+        //output the line
+        PRINT(line_buff);
+    }
+    //last line of left over if any
+    int leftover = size % width;
+    if(leftover > 0)
+    {
+        line = line_buff;
+        //write address:
+        addr = i*width;
+        word2hex((const char*)&addr, &line);
+        *line++ = ':'; *line++ = ' ';
+        //write hex of data
+        for(j = 0; j < leftover; j++)
+        {
+            byte2hex(&data[j], &line);
+            *line++ = ' ';
+        }
+        //write hex padding
+        for(; j < width; j++)
+        {
+            *line++ = ' ';
+            *line++ = ' ';
+            *line++ = ' ';
+        }
+        //write char of data
+        for(j = 0; j < leftover; j++)
+            byte2char(data++, &line);
+        //write the end of line
+        *line = 0;
+        //output the line
+        PRINT(line_buff);
+    }
+}
+
+
+inline void word2hex (const char* data, char** hex)
+{
+    byte2hex(&data[1], hex);
+    byte2hex(&data[0], hex);
+}
+
+
+inline void byte2char (const char* data, char** str)
+{
+    **str = *data < ' ' ? '.' : *data > '~' ? '.' : *data;
+    ++(*str);
+}
+
+
+inline void byte2hex (const char* data, char** str)
+{
+    **str = sTable[(*data >> 4) & 0xf];
+    ++*str;
+    **str = sTable[*data & 0xf];
+    ++*str;
+}
+
+
+    //Decode a few Bluetooth HCI packets into hex numbers.
+    void DispHciCmd (BT_HDR *p_buf)
+    {
+        UINT32 nBytes = ((BT_HDR_SIZE + p_buf->offset + p_buf->len)*2)+1;
+        UINT8* data = (UINT8*) p_buf;
+        int data_len = BT_HDR_SIZE + p_buf->offset + p_buf->len;
+
+        if (appl_trace_level < BT_TRACE_LEVEL_DEBUG)
+            return;
+
+        if (nBytes > sizeof(log_line))
+            return;
+
+        ToHex (data, data_len, log_line, sizeof(log_line));
+        __android_log_write (ANDROID_LOG_DEBUG, "BrcmHciX", log_line);
+    }
+
+
+    //Decode a few Bluetooth HCI packets into hex numbers.
+    void DispHciEvt (BT_HDR *p_buf)
+    {
+        UINT32 nBytes = ((BT_HDR_SIZE + p_buf->offset + p_buf->len)*2)+1;
+        UINT8* data = (UINT8*) p_buf;
+        int data_len = BT_HDR_SIZE + p_buf->offset + p_buf->len;
+
+        if (appl_trace_level < BT_TRACE_LEVEL_DEBUG)
+            return;
+
+        if (nBytes > sizeof(log_line))
+            return;
+
+        ToHex (data, data_len, log_line, sizeof(log_line));
+        __android_log_write (ANDROID_LOG_DEBUG, "BrcmHciR", log_line);
+    }
+
+
+    /*******************************************************************************
+    **
+    ** Function         DispLLCP
+    **
+    ** Description      Log LLCP packet as hex-ascii bytes.
+    **
+    ** Returns          None.
+    **
+    *******************************************************************************/
+    void DispLLCP (BT_HDR *p_buf, BOOLEAN is_recv)
+    {
+        UINT32 nBytes = ((BT_HDR_SIZE + p_buf->offset + p_buf->len)*2)+1;
+        UINT8 * data = (UINT8*) p_buf;
+        int data_len = BT_HDR_SIZE + p_buf->offset + p_buf->len;
+
+        if (appl_trace_level < BT_TRACE_LEVEL_DEBUG)
+            return;
+
+        if (nBytes > sizeof(log_line))
+            return;
+
+        ToHex (data, data_len, log_line, sizeof(log_line));
+        __android_log_write (ANDROID_LOG_DEBUG, (is_recv) ? "BrcmLlcpR": "BrcmLlcpX", log_line);
+    }
+
+
+    /*******************************************************************************
+    **
+    ** Function         DispHcp
+    **
+    ** Description      Log raw HCP packet as hex-ascii bytes
+    **
+    ** Returns          None.
+    **
+    *******************************************************************************/
+    void DispHcp (UINT8 *data, UINT16 len, BOOLEAN is_recv)
+    {
+        UINT32 nBytes = (len*2)+1;
+
+        if (appl_trace_level < BT_TRACE_LEVEL_DEBUG)
+            return;
+
+        // Only trace HCP if we're tracing HCI as well
+        if (!(ScrProtocolTraceFlag & SCR_PROTO_TRACE_HCI_SUMMARY))
+            return;
+
+        if (nBytes > sizeof(log_line))
+            return;
+
+        ToHex (data, len, log_line, sizeof(log_line));
+        __android_log_write (ANDROID_LOG_DEBUG, (is_recv) ? "BrcmHcpR": "BrcmHcpX", log_line);
+    }
+
+
+    void DispSNEP (UINT8 local_sap, UINT8 remote_sap, BT_HDR *p_buf, BOOLEAN is_first, BOOLEAN is_rx) {}
+    void DispCHO (UINT8 *pMsg, UINT32 MsgLen, BOOLEAN is_rx) {}
+    void DispT3TagMessage(BT_HDR *p_msg, BOOLEAN is_rx) {}
+    void DispRWT4Tags (BT_HDR *p_buf, BOOLEAN is_rx) {}
+    void DispCET4Tags (BT_HDR *p_buf, BOOLEAN is_rx) {}
+    void DispRWI93Tag (BT_HDR *p_buf, BOOLEAN is_rx, UINT8 command_to_respond) {}
+    void DispNDEFMsg (UINT8 *pMsg, UINT32 MsgLen, BOOLEAN is_recv) {}
+
+
+/*******************************************************************************
+**
+** Function:        LogMsg
+**
+** Description:     Print messages from NFC stack.
+**
+** Returns:         None.
+**
+*******************************************************************************/
+void LogMsg (UINT32 trace_set_mask, const char *fmt_str, ...)
+{
+    static char buffer [BTE_LOG_BUF_SIZE];
+    va_list ap;
+    UINT32 trace_type = trace_set_mask & 0x07; //lower 3 bits contain trace type
+    int android_log_type = ANDROID_LOG_INFO;
+
+    va_start (ap, fmt_str);
+    vsnprintf (buffer, BTE_LOG_MAX_SIZE, fmt_str, ap);
+    va_end (ap);
+    if (trace_type == TRACE_TYPE_ERROR)
+        android_log_type = ANDROID_LOG_ERROR;
+    __android_log_write (android_log_type, LOGMSG_TAG_NAME, buffer);
+}
+
+
+void LogMsg_0 (UINT32 maskTraceSet, const char *p_str)
+{
+    LogMsg (maskTraceSet, p_str);
+}
+
+
+void LogMsg_1 (UINT32 maskTraceSet, const char *fmt_str, UINT32 p1)
+{
+    LogMsg (maskTraceSet, fmt_str, p1);
+}
+
+
+void LogMsg_2 (UINT32 maskTraceSet, const char *fmt_str, UINT32 p1, UINT32 p2)
+{
+    LogMsg (maskTraceSet, fmt_str, p1, p2);
+}
+
+
+void LogMsg_3 (UINT32 maskTraceSet, const char *fmt_str, UINT32 p1, UINT32 p2, UINT32 p3)
+{
+    LogMsg (maskTraceSet, fmt_str, p1, p2, p3);
+}
+
+
+void LogMsg_4 (UINT32 maskTraceSet, const char *fmt_str, UINT32 p1, UINT32 p2, UINT32 p3, UINT32 p4)
+{
+    LogMsg (maskTraceSet, fmt_str, p1, p2, p3, p4);
+}
+
+void LogMsg_5 (UINT32 maskTraceSet, const char *fmt_str, UINT32 p1, UINT32 p2, UINT32 p3, UINT32 p4, UINT32 p5)
+{
+    LogMsg (maskTraceSet, fmt_str, p1, p2, p3, p4, p5);
+}
+
+
+void LogMsg_6 (UINT32 maskTraceSet, const char *fmt_str, UINT32 p1, UINT32 p2, UINT32 p3, UINT32 p4, UINT32 p5, UINT32 p6)
+{
+    LogMsg (maskTraceSet, fmt_str, p1, p2, p3, p4, p5, p6);
+}
diff --git a/halimpl/bcm2079x/adaptation/config.cpp b/halimpl/bcm2079x/adaptation/config.cpp
new file mode 100644
index 0000000..7889a52
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/config.cpp
@@ -0,0 +1,763 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2011-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "OverrideLog.h"
+#include "config.h"
+#include <sys/stat.h>
+#include <stdio.h>
+#include <string>
+#include <vector>
+#include <list>
+
+#define LOG_TAG "NfcNciHal"
+
+const char* transport_config_paths[] = {"/odm/etc/", "/vendor/etc/", "/etc/"};
+const int transport_config_path_size =
+    (sizeof(transport_config_paths) / sizeof(transport_config_paths[0]));
+
+#define config_name             "libnfc-brcm.conf"
+#define extra_config_base       "libnfc-brcm-"
+#define extra_config_ext        ".conf"
+#define     IsStringValue       0x80000000
+
+using namespace::std;
+
+class CNfcParam : public string
+{
+public:
+    CNfcParam();
+    CNfcParam(const char* name, const string& value);
+    CNfcParam(const char* name, unsigned long value);
+    virtual ~CNfcParam();
+    unsigned long numValue() const {return m_numValue;}
+    const char*   str_value() const {return m_str_value.c_str();}
+    size_t        str_len() const   {return m_str_value.length();}
+private:
+    string          m_str_value;
+    unsigned long   m_numValue;
+};
+
+class CNfcConfig : public vector<const CNfcParam*>
+{
+public:
+    virtual ~CNfcConfig();
+    static CNfcConfig& GetInstance();
+    friend void readOptionalConfig(const char* optional);
+
+    bool    getValue(const char* name, char* pValue, size_t& len) const;
+    bool    getValue(const char* name, unsigned long& rValue) const;
+    bool    getValue(const char* name, unsigned short & rValue) const;
+    const CNfcParam*    find(const char* p_name) const;
+    void    clean();
+private:
+    CNfcConfig();
+    bool    readConfig(const char* name, bool bResetContent);
+    void    moveFromList();
+    void    moveToList();
+    void    add(const CNfcParam* pParam);
+    list<const CNfcParam*> m_list;
+    bool    mValidFile;
+
+    unsigned long   state;
+
+    inline bool Is(unsigned long f) {return (state & f) == f;}
+    inline void Set(unsigned long f) {state |= f;}
+    inline void Reset(unsigned long f) {state &= ~f;}
+};
+
+/*******************************************************************************
+**
+** Function:    isPrintable()
+**
+** Description: detremine if a char is printable
+**
+** Returns:     none
+**
+*******************************************************************************/
+inline bool isPrintable(char c)
+{
+    return  (c >= 'A' && c <= 'Z') ||
+            (c >= 'a' && c <= 'z') ||
+            (c >= '0' && c <= '9') ||
+            c == '/' || c == '_' || c == '-' || c == '.';
+}
+
+/*******************************************************************************
+**
+** Function:    isDigit()
+**
+** Description: detremine if a char is numeral digit
+**
+** Returns:     none
+**
+*******************************************************************************/
+inline bool isDigit(char c, int base)
+{
+    if ('0' <= c && c <= '9')
+        return true;
+    if (base == 16)
+    {
+        if (('A' <= c && c <= 'F') ||
+            ('a' <= c && c <= 'f') )
+            return true;
+    }
+    return false;
+}
+
+/*******************************************************************************
+**
+** Function:    getDigitValue()
+**
+** Description: return numercal value of a char
+**
+** Returns:     none
+**
+*******************************************************************************/
+inline int getDigitValue(char c, int base)
+{
+    if ('0' <= c && c <= '9')
+        return c - '0';
+    if (base == 16)
+    {
+        if ('A' <= c && c <= 'F')
+            return c - 'A' + 10;
+        else if ('a' <= c && c <= 'f')
+            return c - 'a' + 10;
+    }
+    return 0;
+}
+
+/*******************************************************************************
+**
+** Function:    findConfigFilePathFromTransportConfigPaths()
+**
+** Description: find a config file path with a given config name from transport
+**              config paths
+**
+** Returns:     none
+**
+*******************************************************************************/
+void findConfigFilePathFromTransportConfigPaths(const string& configName,
+                                                string& filePath) {
+  for (int i = 0; i < transport_config_path_size - 1; i++) {
+    filePath.assign(transport_config_paths[i]);
+    filePath += configName;
+    struct stat file_stat;
+    if (stat(filePath.c_str(), &file_stat) == 0 && S_ISREG(file_stat.st_mode)) {
+      return;
+    }
+  }
+  filePath.assign(transport_config_paths[transport_config_path_size - 1]);
+  filePath += configName;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::readConfig()
+**
+** Description: read Config settings and parse them into a linked list
+**              move the element from linked list to a array at the end
+**
+** Returns:     none
+**
+*******************************************************************************/
+bool CNfcConfig::readConfig(const char* name, bool bResetContent)
+{
+    enum {
+        BEGIN_LINE = 1,
+        TOKEN,
+        STR_VALUE,
+        NUM_VALUE,
+        BEGIN_HEX,
+        BEGIN_QUOTE,
+        END_LINE
+    };
+
+    FILE*   fd = NULL;
+    string  token;
+    string  strValue;
+    unsigned long    numValue = 0;
+    CNfcParam* pParam = NULL;
+    int     i = 0;
+    int     base = 0;
+    char    c = 0;
+
+    state = BEGIN_LINE;
+    /* open config file, read it into a buffer */
+    if ((fd = fopen(name, "rb")) == NULL)
+    {
+        ALOGD("%s Cannot open config file %s\n", __func__, name);
+        if (bResetContent)
+        {
+            ALOGD("%s Using default value for all settings\n", __func__);
+        mValidFile = false;
+        }
+        return false;
+    }
+    ALOGD("%s Opened %s config %s\n", __func__, (bResetContent ? "base" : "optional"), name);
+
+    mValidFile = true;
+    if (size() > 0)
+    {
+        if (bResetContent)
+        clean();
+        else
+            moveToList();
+    }
+
+    while (!feof(fd) && fread(&c, 1, 1, fd) == 1)
+    {
+        switch (state & 0xff)
+        {
+        case BEGIN_LINE:
+            if (c == '#')
+                state = END_LINE;
+            else if (isPrintable(c))
+            {
+                i = 0;
+                token.erase();
+                strValue.erase();
+                state = TOKEN;
+                token.push_back(c);
+            }
+            break;
+        case TOKEN:
+            if (c == '=')
+            {
+                token.push_back('\0');
+                state = BEGIN_QUOTE;
+            }
+            else if (isPrintable(c))
+                token.push_back(c);
+            else
+                state = END_LINE;
+            break;
+        case BEGIN_QUOTE:
+            if (c == '"')
+            {
+                state = STR_VALUE;
+                base = 0;
+            }
+            else if (c == '0')
+                state = BEGIN_HEX;
+            else if (isDigit(c, 10))
+            {
+                state = NUM_VALUE;
+                base = 10;
+                numValue = getDigitValue(c, base);
+                i = 0;
+            }
+            else if (c == '{')
+            {
+                state = NUM_VALUE;
+                base = 16;
+                i = 0;
+                Set(IsStringValue);
+            }
+            else
+                state = END_LINE;
+            break;
+        case BEGIN_HEX:
+            if (c == 'x' || c == 'X')
+            {
+                state = NUM_VALUE;
+                base = 16;
+                numValue = 0;
+                i = 0;
+                break;
+            }
+            else if (isDigit(c, 10))
+            {
+                state = NUM_VALUE;
+                base = 10;
+                numValue = getDigitValue(c, base);
+                break;
+            }
+            else if (c != '\n' && c != '\r')
+            {
+                state = END_LINE;
+                break;
+            }
+            // fal through to numValue to handle numValue
+
+        case NUM_VALUE:
+            if (isDigit(c, base))
+            {
+                numValue *= base;
+                numValue += getDigitValue(c, base);
+                ++i;
+            }
+            else if (base == 16 && (c == ':' || c == '-' || c == ' ' || c == '}'))
+            {
+                if (i > 0)
+                {
+                    int n = (i+1) / 2;
+                    while (n-- > 0)
+                    {
+                        unsigned char c = (numValue >> (n * 8))  & 0xFF;
+                        strValue.push_back(c);
+                    }
+                }
+                Set(IsStringValue);
+                numValue = 0;
+                i = 0;
+            }
+            else
+            {
+                if (c == '\n' || c == '\r')
+                    state = BEGIN_LINE;
+                else
+                    state = END_LINE;
+                if (Is(IsStringValue) && base == 16 && i > 0)
+                {
+                    int n = (i+1) / 2;
+                    while (n-- > 0)
+                        strValue.push_back(((numValue >> (n * 8))  & 0xFF));
+                }
+                if (strValue.length() > 0)
+                    pParam = new CNfcParam(token.c_str(), strValue);
+                else
+                    pParam = new CNfcParam(token.c_str(), numValue);
+                add(pParam);
+                strValue.erase();
+                numValue = 0;
+            }
+            break;
+        case STR_VALUE:
+            if (c == '"')
+            {
+                strValue.push_back('\0');
+                state = END_LINE;
+                pParam = new CNfcParam(token.c_str(), strValue);
+                add(pParam);
+            }
+            else if (isPrintable(c))
+                strValue.push_back(c);
+            break;
+        case END_LINE:
+            if (c == '\n' || c == '\r')
+                state = BEGIN_LINE;
+            break;
+        default:
+            break;
+        }
+    }
+
+    fclose(fd);
+
+    moveFromList();
+    return size() > 0;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::CNfcConfig()
+**
+** Description: class constructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcConfig::CNfcConfig() :
+    mValidFile(true)
+{
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::~CNfcConfig()
+**
+** Description: class destructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcConfig::~CNfcConfig()
+{
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::GetInstance()
+**
+** Description: get class singleton object
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcConfig& CNfcConfig::GetInstance()
+{
+    static CNfcConfig theInstance;
+
+    if (theInstance.size() == 0 && theInstance.mValidFile)
+    {
+        string strPath;
+        findConfigFilePathFromTransportConfigPaths(config_name, strPath);
+        theInstance.readConfig(strPath.c_str(), true);
+    }
+
+    return theInstance;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::getValue()
+**
+** Description: get a string value of a setting
+**
+** Returns:     true if setting exists
+**              false if setting does not exist
+**
+*******************************************************************************/
+bool CNfcConfig::getValue(const char* name, char* pValue, size_t& len) const
+{
+    const CNfcParam* pParam = find(name);
+    if (pParam == NULL)
+        return false;
+
+    if (pParam->str_len() > 0)
+    {
+        memset(pValue, 0, len);
+        if (len > pParam->str_len())
+            len  = pParam->str_len();
+        memcpy(pValue, pParam->str_value(), len);
+        return true;
+    }
+    return false;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::getValue()
+**
+** Description: get a long numerical value of a setting
+**
+** Returns:     true if setting exists
+**              false if setting does not exist
+**
+*******************************************************************************/
+bool CNfcConfig::getValue(const char* name, unsigned long& rValue) const
+{
+    const CNfcParam* pParam = find(name);
+    if (pParam == NULL)
+        return false;
+
+    if (pParam->str_len() == 0)
+    {
+        rValue = static_cast<unsigned long>(pParam->numValue());
+        return true;
+    }
+    return false;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::getValue()
+**
+** Description: get a short numerical value of a setting
+**
+** Returns:     true if setting exists
+**              false if setting does not exist
+**
+*******************************************************************************/
+bool CNfcConfig::getValue(const char* name, unsigned short& rValue) const
+{
+    const CNfcParam* pParam = find(name);
+    if (pParam == NULL)
+        return false;
+
+    if (pParam->str_len() == 0)
+    {
+        rValue = static_cast<unsigned short>(pParam->numValue());
+        return true;
+    }
+    return false;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::find()
+**
+** Description: search if a setting exist in the setting array
+**
+** Returns:     pointer to the setting object
+**
+*******************************************************************************/
+const CNfcParam* CNfcConfig::find(const char* p_name) const
+{
+    if (size() == 0)
+        return NULL;
+
+    for (const_iterator it = begin(), itEnd = end(); it != itEnd; ++it)
+    {
+        if (**it < p_name)
+            continue;
+        else if (**it == p_name)
+        {
+            if((*it)->str_len() > 0)
+                ALOGD("%s found %s=%s\n", __func__, p_name, (*it)->str_value());
+            else
+                ALOGD("%s found %s=(0x%lX)\n", __func__, p_name, (*it)->numValue());
+            return *it;
+        }
+        else
+            break;
+    }
+    return NULL;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::clean()
+**
+** Description: reset the setting array
+**
+** Returns:     none
+**
+*******************************************************************************/
+void CNfcConfig::clean()
+{
+    if (size() == 0)
+        return;
+
+    for (iterator it = begin(), itEnd = end(); it != itEnd; ++it)
+        delete *it;
+    clear();
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::Add()
+**
+** Description: add a setting object to the list
+**
+** Returns:     none
+**
+*******************************************************************************/
+void CNfcConfig::add(const CNfcParam* pParam)
+{
+    if (m_list.size() == 0)
+    {
+        m_list.push_back(pParam);
+        return;
+    }
+    for (list<const CNfcParam*>::iterator it = m_list.begin(), itEnd = m_list.end(); it != itEnd; ++it)
+    {
+        if (**it < pParam->c_str())
+            continue;
+        m_list.insert(it, pParam);
+        return;
+    }
+    m_list.push_back(pParam);
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::moveFromList()
+**
+** Description: move the setting object from list to array
+**
+** Returns:     none
+**
+*******************************************************************************/
+void CNfcConfig::moveFromList()
+{
+    if (m_list.size() == 0)
+        return;
+
+    for (list<const CNfcParam*>::iterator it = m_list.begin(), itEnd = m_list.end(); it != itEnd; ++it)
+        push_back(*it);
+    m_list.clear();
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::moveToList()
+**
+** Description: move the setting object from array to list
+**
+** Returns:     none
+**
+*******************************************************************************/
+void CNfcConfig::moveToList()
+{
+    if (m_list.size() != 0)
+        m_list.clear();
+
+    for (iterator it = begin(), itEnd = end(); it != itEnd; ++it)
+        m_list.push_back(*it);
+    clear();
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcParam::CNfcParam()
+**
+** Description: class constructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcParam::CNfcParam() :
+    m_numValue(0)
+{
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcParam::~CNfcParam()
+**
+** Description: class destructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcParam::~CNfcParam()
+{
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcParam::CNfcParam()
+**
+** Description: class copy constructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcParam::CNfcParam(const char* name,  const string& value) :
+    string(name),
+    m_str_value(value),
+    m_numValue(0)
+{
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcParam::CNfcParam()
+**
+** Description: class copy constructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcParam::CNfcParam(const char* name,  unsigned long value) :
+    string(name),
+    m_numValue(value)
+{
+}
+
+/*******************************************************************************
+**
+** Function:    GetStrValue
+**
+** Description: API function for getting a string value of a setting
+**
+** Returns:     none
+**
+*******************************************************************************/
+extern "C" int GetStrValue(const char* name, char* pValue, unsigned long l)
+{
+    size_t len = l;
+    CNfcConfig& rConfig = CNfcConfig::GetInstance();
+
+    bool b = rConfig.getValue(name, pValue, len);
+    return b ? len : 0;
+}
+
+/*******************************************************************************
+**
+** Function:    GetNumValue
+**
+** Description: API function for getting a numerical value of a setting
+**
+** Returns:     none
+**
+*******************************************************************************/
+extern "C" int GetNumValue(const char* name, void* pValue, unsigned long len)
+{
+    if (!pValue)
+        return false;
+
+    CNfcConfig& rConfig = CNfcConfig::GetInstance();
+    const CNfcParam* pParam = rConfig.find(name);
+
+    if (pParam == NULL)
+        return false;
+    unsigned long v = pParam->numValue();
+    if (v == 0 && pParam->str_len() > 0 && pParam->str_len() < 4)
+    {
+        const unsigned char* p = (const unsigned char*)pParam->str_value();
+        for (size_t i = 0 ; i < pParam->str_len(); ++i)
+        {
+            v *= 256;
+            v += *p++;
+        }
+    }
+    switch (len)
+    {
+    case sizeof(unsigned long):
+        *(static_cast<unsigned long*>(pValue)) = (unsigned long)v;
+        break;
+    case sizeof(unsigned short):
+        *(static_cast<unsigned short*>(pValue)) = (unsigned short)v;
+        break;
+    case sizeof(unsigned char):
+        *(static_cast<unsigned char*> (pValue)) = (unsigned char)v;
+        break;
+    default:
+        return false;
+    }
+    return true;
+}
+
+/*******************************************************************************
+**
+** Function:    resetConfig
+**
+** Description: reset settings array
+**
+** Returns:     none
+**
+*******************************************************************************/
+extern void resetConfig()
+{
+    CNfcConfig& rConfig = CNfcConfig::GetInstance();
+
+    rConfig.clean();
+}
+
+/*******************************************************************************
+**
+** Function:    readOptionalConfig()
+**
+** Description: read Config settings from an optional conf file
+**
+** Returns:     none
+**
+*******************************************************************************/
+void readOptionalConfig(const char* extra)
+{
+    string strPath;
+    string configName(extra_config_base);
+    configName += extra;
+    configName += extra_config_ext;
+
+    findConfigFilePathFromTransportConfigPaths(configName, strPath);
+    CNfcConfig::GetInstance().readConfig(strPath.c_str(), false);
+}
+
diff --git a/halimpl/bcm2079x/adaptation/patchram.cpp b/halimpl/bcm2079x/adaptation/patchram.cpp
new file mode 100644
index 0000000..76947b9
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/patchram.cpp
@@ -0,0 +1,621 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "OverrideLog.h"
+#include "config.h"
+#include "nfc_hal_int.h"
+#include "userial.h"
+extern "C"
+{
+    #include "nfc_hal_post_reset.h"
+}
+#include <malloc.h>
+#include <string>
+#include <cutils/properties.h>
+#include "spdhelper.h"
+#include "StartupConfig.h"
+
+#define LOG_TAG "NfcNciHal"
+
+#define FW_PRE_PATCH                        "FW_PRE_PATCH"
+#define FW_PATCH                            "FW_PATCH"
+#define MAX_RF_DATA_CREDITS                 "MAX_RF_DATA_CREDITS"
+
+#define MAX_BUFFER      (512)
+static char sPrePatchFn[MAX_BUFFER+1];
+static char sPatchFn[MAX_BUFFER+1];
+static void * sPrmBuf = NULL;
+static void * sI2cFixPrmBuf = NULL;
+
+#define CONFIG_MAX_LEN 256
+static UINT8 sConfig [CONFIG_MAX_LEN];
+static StartupConfig sStartupConfig;
+static StartupConfig sLptdConfig;
+static StartupConfig sPreDiscoveryConfig;
+static StartupConfig sXtalCustomParam;
+extern UINT8 *p_nfc_hal_dm_start_up_cfg; //defined in the HAL
+static UINT8 nfa_dm_start_up_vsc_cfg[CONFIG_MAX_LEN];
+extern UINT8 *p_nfc_hal_dm_start_up_vsc_cfg; //defined in the HAL
+extern UINT8 *p_nfc_hal_dm_lptd_cfg; //defined in the HAL
+static UINT8 sDontSendLptd[] = { 0 };
+extern UINT8 *p_nfc_hal_pre_discover_cfg; //defined in the HAL
+extern UINT8 *p_nfc_hal_dm_xtal_params_cfg; //defined in HAL
+
+extern tSNOOZE_MODE_CONFIG gSnoozeModeCfg;
+extern tNFC_HAL_CFG *p_nfc_hal_cfg;
+static void mayDisableSecureElement (StartupConfig& config);
+
+/* Default patchfile (in NCD format) */
+#ifndef NFA_APP_DEFAULT_PATCHFILE_NAME
+#define NFA_APP_DEFAULT_PATCHFILE_NAME      "\0"
+#endif
+
+/* Default patchfile (in NCD format) */
+#ifndef NFA_APP_DEFAULT_I2C_PATCHFILE_NAME
+#define NFA_APP_DEFAULT_I2C_PATCHFILE_NAME  "\0"
+#endif
+
+tNFC_POST_RESET_CB nfc_post_reset_cb =
+{
+    /* Default Patch & Pre-Patch */
+    NFA_APP_DEFAULT_PATCHFILE_NAME,
+    NULL,
+    NFA_APP_DEFAULT_I2C_PATCHFILE_NAME,
+    NULL,
+
+    /* Default UART baud rate */
+    NFC_HAL_DEFAULT_BAUD,
+
+    /* Default tNFC_HAL_DEV_INIT_CFG (flags, num_xtal_cfg, {brcm_hw_id, xtal-freq, xtal-index} ) */
+    {
+        2, /* number of valid entries */
+        {
+            {0x43341000, 37400, NFC_HAL_XTAL_INDEX_37400},      // All revisions of 43341 use 37,400
+            {0x20795000, 26000, NFC_HAL_XTAL_INDEX_26000},
+            {0, 0, 0},
+            {0, 0, 0},
+            {0, 0, 0},
+        }
+    },
+
+    /* Default low power mode settings */
+    NFC_HAL_LP_SNOOZE_MODE_NONE,    /* Snooze Mode          */
+    NFC_HAL_LP_IDLE_THRESHOLD_HOST, /* Idle Threshold Host  */
+    NFC_HAL_LP_IDLE_THRESHOLD_HC,   /* Idle Threshold HC    */
+    NFC_HAL_LP_ACTIVE_LOW,          /* NFC_WAKE Active Mode */
+    NFC_HAL_LP_ACTIVE_HIGH,         /* DH_WAKE Active Mode  */
+
+    NFA_APP_MAX_NUM_REINIT,         /* max retry to get NVM type */
+    0,                              /* current retry count */
+    TRUE,                           /* debug mode for downloading patchram */
+    FALSE                           /* skip downloading patchram after reinit because of patch download failure */
+};
+
+
+/*******************************************************************************
+**
+** Function         getFileLength
+**
+** Description      return the size of a file
+**
+** Returns          file size in number of bytes
+**
+*******************************************************************************/
+static long getFileLength(FILE* fp)
+{
+    long sz;
+    fseek(fp, 0L, SEEK_END);
+    sz = ftell(fp);
+    fseek(fp, 0L, SEEK_SET);
+
+    return (sz > 0) ? sz : 0;
+}
+
+/*******************************************************************************
+**
+** Function         isFileExist
+**
+** Description      Check if file name exists (android does not support fexists)
+**
+** Returns          TRUE if file exists
+**
+*******************************************************************************/
+static BOOLEAN isFileExist(const char *pFilename)
+{
+    FILE *pf;
+
+    if ((pf = fopen(pFilename, "r")) != NULL)
+    {
+        fclose(pf);
+        return TRUE;
+    }
+    return FALSE;
+}
+
+/*******************************************************************************
+**
+** Function         findPatchramFile
+**
+** Description      Find the patchram file name specified in the .conf
+**
+** Returns          pointer to the file name
+**
+*******************************************************************************/
+static const char* findPatchramFile(const char * pConfigName, char * pBuffer, int bufferLen)
+{
+    ALOGD("%s: config=%s", __FUNCTION__, pConfigName);
+
+    if (pConfigName == NULL)
+    {
+        ALOGD("%s No patchfile defined\n", __FUNCTION__);
+        return NULL;
+    }
+
+    if (GetStrValue(pConfigName, &pBuffer[0], bufferLen))
+    {
+        ALOGD("%s found patchfile %s\n", __FUNCTION__, pBuffer);
+        return (pBuffer[0] == '\0') ? NULL : pBuffer;
+    }
+
+    ALOGD("%s Cannot find patchfile '%s'\n", __FUNCTION__, pConfigName);
+    return NULL;
+}
+
+/*******************************************************************************
+**
+** Function:    continueAfterSetSnoozeMode
+**
+** Description: Called after Snooze Mode is enabled.
+**
+** Returns:     none
+**
+*******************************************************************************/
+static void continueAfterSetSnoozeMode(tHAL_NFC_STATUS status)
+{
+    ALOGD("%s: status=%u", __FUNCTION__, status);
+    //let stack download firmware during next initialization
+    nfc_post_reset_cb.spd_skip_on_power_cycle = FALSE;
+    if (status == NCI_STATUS_OK)
+        HAL_NfcPreInitDone (HAL_NFC_STATUS_OK);
+    else
+        HAL_NfcPreInitDone (HAL_NFC_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function:    postDownloadPatchram
+**
+** Description: Called after patch download
+**
+** Returns:     none
+**
+*******************************************************************************/
+static void postDownloadPatchram(tHAL_NFC_STATUS status)
+{
+    ALOGD("%s: status=%i", __FUNCTION__, status);
+    GetStrValue (NAME_SNOOZE_MODE_CFG, (char*)&gSnoozeModeCfg, sizeof(gSnoozeModeCfg));
+    if (status != HAL_NFC_STATUS_OK)
+    {
+        ALOGE("%s: Patch download failed", __FUNCTION__);
+        if (status == HAL_NFC_STATUS_REFUSED)
+        {
+            SpdHelper::setPatchAsBad();
+        }
+        else
+            SpdHelper::incErrorCount();
+
+        /* If in SPD Debug mode, fail immediately and obviously */
+        if (SpdHelper::isSpdDebug())
+            HAL_NfcPreInitDone (HAL_NFC_STATUS_FAILED);
+        else
+        {
+            /* otherwise, power cycle the chip and let the stack startup normally */
+            ALOGD("%s: re-init; don't download firmware", __FUNCTION__);
+            //stop stack from downloading firmware during next initialization
+            nfc_post_reset_cb.spd_skip_on_power_cycle = TRUE;
+            USERIAL_PowerupDevice(0);
+            HAL_NfcReInit ();
+        }
+    }
+    /* Set snooze mode here */
+    else if (gSnoozeModeCfg.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE)
+    {
+        status = HAL_NfcSetSnoozeMode(gSnoozeModeCfg.snooze_mode,
+                                       gSnoozeModeCfg.idle_threshold_dh,
+                                       gSnoozeModeCfg.idle_threshold_nfcc,
+                                       gSnoozeModeCfg.nfc_wake_active_mode,
+                                       gSnoozeModeCfg.dh_wake_active_mode,
+                                       continueAfterSetSnoozeMode);
+        if (status != NCI_STATUS_OK)
+        {
+            ALOGE("%s: Setting snooze mode failed, status=%i", __FUNCTION__, status);
+            HAL_NfcPreInitDone(HAL_NFC_STATUS_FAILED);
+        }
+    }
+    else
+    {
+        ALOGD("%s: Not using Snooze Mode", __FUNCTION__);
+        HAL_NfcPreInitDone(HAL_NFC_STATUS_OK);
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function:    prmCallback
+**
+** Description: Patchram callback (for static patchram mode)
+**
+** Returns:     none
+**
+*******************************************************************************/
+void prmCallback(UINT8 event)
+{
+    ALOGD("%s: event=0x%x", __FUNCTION__, event);
+    switch (event)
+    {
+    case NFC_HAL_PRM_CONTINUE_EVT:
+        /* This event does not occur if static patchram buf is used */
+        break;
+
+    case NFC_HAL_PRM_COMPLETE_EVT:
+        postDownloadPatchram(HAL_NFC_STATUS_OK);
+        break;
+
+    case NFC_HAL_PRM_ABORT_EVT:
+        postDownloadPatchram(HAL_NFC_STATUS_FAILED);
+        break;
+
+    case NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT:
+        ALOGD("%s: invalid patch...skipping patch download", __FUNCTION__);
+        postDownloadPatchram(HAL_NFC_STATUS_REFUSED);
+        break;
+
+    case NFC_HAL_PRM_ABORT_BAD_SIGNATURE_EVT:
+        ALOGD("%s: patch authentication failed", __FUNCTION__);
+        postDownloadPatchram(HAL_NFC_STATUS_REFUSED);
+        break;
+
+    case NFC_HAL_PRM_ABORT_NO_NVM_EVT:
+        ALOGD("%s: No NVM detected", __FUNCTION__);
+        HAL_NfcPreInitDone(HAL_NFC_STATUS_FAILED);
+        break;
+
+    default:
+        ALOGD("%s: not handled event=0x%x", __FUNCTION__, event);
+        break;
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         getNfaValues
+**
+** Description      Get configuration values needed by NFA layer
+**
+** Returns:         None
+**
+*******************************************************************************/
+static void getNfaValues (UINT32 chipid)
+{
+    unsigned long num = 0;
+    int actualLen = 0;
+
+    sStartupConfig.initialize ();
+    sLptdConfig.initialize ();
+    sPreDiscoveryConfig.initialize();
+
+    actualLen = GetStrValue (NAME_NFA_DM_START_UP_CFG, (char*)sConfig, sizeof(sConfig));
+    if (actualLen)
+        sStartupConfig.append (sConfig, actualLen);
+
+    // Set antenna tuning configuration if configured.
+    actualLen = GetStrValue(NAME_PREINIT_DSP_CFG, (char*)sConfig, sizeof(sConfig));
+    if (actualLen)
+        sStartupConfig.append (sConfig, actualLen);
+
+    if ( GetStrValue ( NAME_NFA_DM_START_UP_VSC_CFG, (char*)nfa_dm_start_up_vsc_cfg, sizeof (nfa_dm_start_up_vsc_cfg) ) )
+    {
+        p_nfc_hal_dm_start_up_vsc_cfg = &nfa_dm_start_up_vsc_cfg[0];
+        ALOGD ( "START_UP_VSC_CFG[0] = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+                                                                            nfa_dm_start_up_vsc_cfg[0],
+                                                                            nfa_dm_start_up_vsc_cfg[1],
+                                                                            nfa_dm_start_up_vsc_cfg[2],
+                                                                            nfa_dm_start_up_vsc_cfg[3],
+                                                                            nfa_dm_start_up_vsc_cfg[4],
+                                                                            nfa_dm_start_up_vsc_cfg[5],
+                                                                            nfa_dm_start_up_vsc_cfg[6],
+                                                                            nfa_dm_start_up_vsc_cfg[7] );
+    }
+
+    actualLen = GetStrValue(NAME_LPTD_CFG, (char*)sConfig, sizeof(sConfig));
+    if (actualLen)
+    {
+        sLptdConfig.append (sConfig, actualLen);
+        p_nfc_hal_dm_lptd_cfg = const_cast<UINT8*> (sLptdConfig.getInternalBuffer ());
+    }
+    else
+    {
+        // Default to not sending any LPTD setting.
+        p_nfc_hal_dm_lptd_cfg = sDontSendLptd;
+    }
+
+    mayDisableSecureElement (sStartupConfig);
+    p_nfc_hal_dm_start_up_cfg = const_cast<UINT8*> (sStartupConfig.getInternalBuffer ());
+
+    actualLen = GetStrValue(NAME_NFA_DM_PRE_DISCOVERY_CFG, (char*)sConfig, sizeof(sConfig));
+    if (actualLen)
+    {
+        sPreDiscoveryConfig.append (sConfig, actualLen);
+        mayDisableSecureElement (sPreDiscoveryConfig);
+        p_nfc_hal_pre_discover_cfg = const_cast<UINT8*> (sPreDiscoveryConfig.getInternalBuffer ());
+    }
+
+    //configure how many secure elements are available for each type of chip
+    if (p_nfc_hal_cfg->nfc_hal_hci_uicc_support > 0)
+    {
+        if ((chipid & BRCM_NFC_GEN_MASK) == BRCM_NFC_20791_GEN)
+        {
+            nfc_hal_cb.max_ee = BRCM_NFC_20791_GEN_MAX_EE;
+            p_nfc_hal_cfg->nfc_hal_hci_uicc_support = HAL_NFC_HCI_UICC0_HOST | HAL_NFC_HCI_UICC1_HOST;
+        }
+        else if ((chipid & BRCM_NFC_GEN_MASK) == BRCM_NFC_43341_GEN)
+        {
+            nfc_hal_cb.max_ee = BRCM_NFC_43341_GEN_MAX_EE;
+            p_nfc_hal_cfg->nfc_hal_hci_uicc_support = HAL_NFC_HCI_UICC0_HOST | HAL_NFC_HCI_UICC1_HOST;
+        }
+        else if ((chipid & BRCM_NFC_GEN_MASK) == BRCM_NFC_20795_GEN)
+        {
+            nfc_hal_cb.max_ee = BRCM_NFC_20795_GEN_MAX_EE;
+            p_nfc_hal_cfg->nfc_hal_hci_uicc_support = HAL_NFC_HCI_UICC0_HOST | HAL_NFC_HCI_UICC1_HOST | HAL_NFC_HCI_UICC2_HOST;
+        }
+
+        //let .conf variable determine how many EE's to discover
+        if (GetNumValue(NAME_NFA_MAX_EE_SUPPORTED, &num, sizeof(num)))
+            nfc_hal_cb.max_ee = num;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         StartPatchDownload
+**
+** Description      Reads configuration settings, and begins the download
+**                  process if patch files are configured.
+**
+** Returns:         None
+**
+*******************************************************************************/
+static void StartPatchDownload(UINT32 chipid)
+{
+    ALOGD ("%s: chipid=%lx",__FUNCTION__, chipid);
+
+    char chipID[30];
+    sprintf(chipID, "%lx", chipid);
+    ALOGD ("%s: chidId=%s", __FUNCTION__, chipID);
+
+    readOptionalConfig(chipID);     // Read optional chip specific settings
+    readOptionalConfig("fime");     // Read optional FIME specific settings
+    getNfaValues(chipid);                 // Get NFA configuration values into variables
+
+    findPatchramFile(FW_PATCH, sPatchFn, sizeof(sPatchFn));
+    findPatchramFile(FW_PRE_PATCH, sPrePatchFn, sizeof(sPatchFn));
+
+    {
+        FILE *fd;
+        /* If an I2C fix patch file was specified, then tell the stack about it */
+        if (sPrePatchFn[0] != '\0')
+        {
+            if ((fd = fopen(sPrePatchFn, "rb")) != NULL)
+            {
+                UINT32 lenPrmBuffer = getFileLength(fd);
+
+                if ((sI2cFixPrmBuf = malloc(lenPrmBuffer)) != NULL)
+                {
+                    size_t actualLen = fread(sI2cFixPrmBuf, 1, lenPrmBuffer, fd);
+                    if (actualLen == lenPrmBuffer)
+                    {
+                        ALOGD("%s Setting I2C fix to %s (size: %lu)", __FUNCTION__, sPrePatchFn, lenPrmBuffer);
+                        HAL_NfcPrmSetI2cPatch((UINT8*)sI2cFixPrmBuf, (UINT16)lenPrmBuffer, 0);
+                    }
+                    else
+                        ALOGE("%s fail reading i2c fix; actual len=%u; expected len=%lu", __FUNCTION__, actualLen, lenPrmBuffer);
+                }
+                else
+                {
+                    ALOGE("%s Unable to get buffer to i2c fix (%lu bytes)", __FUNCTION__, lenPrmBuffer);
+                }
+
+                fclose(fd);
+            }
+            else
+            {
+                ALOGE("%s Unable to open i2c fix patchfile %s", __FUNCTION__, sPrePatchFn);
+            }
+        }
+    }
+
+    {
+        FILE *fd;
+
+        /* If a patch file was specified, then download it now */
+        if (sPatchFn[0] != '\0')
+        {
+            UINT32 bDownloadStarted = false;
+
+            /* open patchfile, read it into a buffer */
+            if ((fd = fopen(sPatchFn, "rb")) != NULL)
+            {
+                UINT32 lenPrmBuffer = getFileLength(fd);
+                ALOGD("%s Downloading patchfile %s (size: %lu) format=%u", __FUNCTION__, sPatchFn, lenPrmBuffer, NFC_HAL_PRM_FORMAT_NCD);
+                if ((sPrmBuf = malloc(lenPrmBuffer)) != NULL)
+                {
+                    size_t actualLen = fread(sPrmBuf, 1, lenPrmBuffer, fd);
+                    if (actualLen == lenPrmBuffer)
+                    {
+                        if (!SpdHelper::isPatchBad((UINT8*)sPrmBuf, lenPrmBuffer))
+                        {
+                            /* Download patch using static memeory mode */
+                            HAL_NfcPrmDownloadStart(NFC_HAL_PRM_FORMAT_NCD, 0, (UINT8*)sPrmBuf, lenPrmBuffer, 0, prmCallback);
+                            bDownloadStarted = true;
+                        }
+                    }
+                    else
+                        ALOGE("%s fail reading patchram", __FUNCTION__);
+                }
+                else
+                    ALOGE("%s Unable to buffer to hold patchram (%lu bytes)", __FUNCTION__, lenPrmBuffer);
+
+                fclose(fd);
+            }
+            else
+                ALOGE("%s Unable to open patchfile %s", __FUNCTION__, sPatchFn);
+
+            /* If the download never got started */
+            if (!bDownloadStarted)
+            {
+                /* If debug mode, fail in an obvious way, otherwise try to start stack */
+                postDownloadPatchram(SpdHelper::isSpdDebug() ? HAL_NFC_STATUS_FAILED :
+                        HAL_NFC_STATUS_OK);
+            }
+        }
+        else
+        {
+            ALOGE("%s: No patchfile specified or disabled. Proceeding to post-download procedure...", __FUNCTION__);
+            postDownloadPatchram(HAL_NFC_STATUS_OK);
+        }
+    }
+
+    ALOGD ("%s: exit", __FUNCTION__);
+}
+
+/*******************************************************************************
+**
+** Function:    nfc_hal_post_reset_init
+**
+** Description: Called by the NFC HAL after controller has been reset.
+**              Begin to download firmware patch files.
+**
+** Returns:     none
+**
+*******************************************************************************/
+void nfc_hal_post_reset_init (UINT32 brcm_hw_id, UINT8 nvm_type)
+{
+    ALOGD("%s: brcm_hw_id=0x%lx, nvm_type=%d", __FUNCTION__, brcm_hw_id, nvm_type);
+    tHAL_NFC_STATUS stat = HAL_NFC_STATUS_FAILED;
+    UINT8 max_credits = 1, allow_no_nvm=0;
+
+    p_nfc_hal_cfg->nfc_hal_prm_nvm_required = TRUE; //don't download firmware if controller cannot detect EERPOM
+
+    if (nvm_type == NCI_SPD_NVM_TYPE_NONE)
+    {
+        GetNumValue(NAME_ALLOW_NO_NVM, &allow_no_nvm, sizeof(allow_no_nvm));
+        if (allow_no_nvm == 0)
+        {
+        ALOGD("%s: No NVM detected, FAIL the init stage to force a retry", __FUNCTION__);
+        USERIAL_PowerupDevice (0);
+        stat = HAL_NfcReInit ();
+            return;
+        }
+
+        p_nfc_hal_cfg->nfc_hal_prm_nvm_required = FALSE; //allow download firmware if controller cannot detect EERPOM
+    }
+
+        /* Start downloading the patch files */
+        StartPatchDownload(brcm_hw_id);
+
+        if (GetNumValue(MAX_RF_DATA_CREDITS, &max_credits, sizeof(max_credits)) && (max_credits > 0))
+        {
+            ALOGD("%s : max_credits=%d", __FUNCTION__, max_credits);
+            HAL_NfcSetMaxRfDataCredits(max_credits);
+        }
+    }
+
+
+/*******************************************************************************
+**
+** Function:        mayDisableSecureElement
+**
+** Description:     Optionally adjust a TLV to disable secure element.  This feature
+**                  is enabled by setting the system property
+**                  nfc.disable_secure_element to a bit mask represented by a hex
+**                  octet: C0 = do not detect any secure element.
+**                         40 = do not detect secure element in slot 0.
+**                         80 = do not detect secure element in slot 1.
+**
+**                  config: a sequence of TLV's.
+**
+*******************************************************************************/
+void mayDisableSecureElement (StartupConfig& config)
+{
+    unsigned int bitmask = 0;
+    char valueStr [PROPERTY_VALUE_MAX] = {0};
+    int len = property_get ("nfc.disable_secure_element", valueStr, "");
+    if (len > 0)
+    {
+        sscanf (valueStr, "%x", &bitmask); //read system property as a hex octet
+        ALOGD ("%s: disable 0x%02X", __FUNCTION__, (UINT8) bitmask);
+        config.disableSecureElement ((UINT8) (bitmask & 0xC0));
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function:    configureCrystalFrequency
+**
+** Description: Configure controller's crystal frequency by reading values from
+**              .conf file.  If .conf file does not define any value, then use
+**              default values defined in struct nfc_post_reset_cb.
+**
+** Returns:     none
+**
+*******************************************************************************/
+void configureCrystalFrequency ()
+{
+    unsigned long num = 0;
+    UINT32 hwId = 0;
+    UINT16 xtalFreq = 0;
+    UINT8 xtalIndex = 0;
+    int actualLen = 0;
+
+    if (GetNumValue (NAME_XTAL_HARDWARE_ID, &num, sizeof(num)))
+        hwId = num;
+
+    if (GetNumValue (NAME_XTAL_FREQUENCY, &num, sizeof(num)))
+        xtalFreq = (UINT16) num;
+
+    if (GetNumValue (NAME_XTAL_FREQ_INDEX, &num, sizeof(num)))
+        xtalIndex = (UINT8) num;
+
+    actualLen = GetStrValue (NAME_XTAL_PARAMS_CFG, (char*)sConfig, sizeof(sConfig));
+    if (actualLen && (xtalIndex == NFC_HAL_XTAL_INDEX_SPECIAL)) //whether to use custom crystal frequency
+    {
+        sXtalCustomParam.append (sConfig, actualLen);
+        p_nfc_hal_dm_xtal_params_cfg = const_cast<UINT8*> (sXtalCustomParam.getInternalBuffer ());
+    }
+
+    if ((hwId == 0) && (xtalFreq == 0) && (xtalIndex == 0))
+        return;
+
+    ALOGD ("%s: hwId=0x%lX; freq=%u; index=%u", __FUNCTION__, hwId, xtalFreq, xtalIndex);
+    nfc_post_reset_cb.dev_init_config.xtal_cfg[0].brcm_hw_id = (hwId & BRCM_NFC_GEN_MASK);
+    nfc_post_reset_cb.dev_init_config.xtal_cfg[0].xtal_freq  = xtalFreq;
+    nfc_post_reset_cb.dev_init_config.xtal_cfg[0].xtal_index = xtalIndex;
+    nfc_post_reset_cb.dev_init_config.num_xtal_cfg = 1;
+}
diff --git a/halimpl/bcm2079x/adaptation/spdhelper.cpp b/halimpl/bcm2079x/adaptation/spdhelper.cpp
new file mode 100644
index 0000000..3d87e0e
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/spdhelper.cpp
@@ -0,0 +1,108 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#define LOG_TAG "NfcNciHal"
+#include "OverrideLog.h"
+#include "spdhelper.h"
+#include "config.h"
+
+void SpdHelper::setPatchAsBad()
+{
+    getInstance().setPatchAsBadImpl();
+}
+
+void SpdHelper::incErrorCount()
+{
+    getInstance().incErrorCountImpl();
+}
+
+bool SpdHelper::isPatchBad(UINT8* prm, UINT32 len)
+{
+    return getInstance().isPatchBadImpl(prm, len);
+}
+
+bool SpdHelper::isSpdDebug()
+{
+    bool b = getInstance().isSpdDebugImpl();
+    ALOGD("%s SpdDebug is %s", __func__, (b ? "TRUE" : "FALSE"));
+    return b;
+}
+
+void SpdHelper::incErrorCountImpl()
+{
+    if (++mErrorCount >= mMaxErrorCount)
+    {
+        setPatchAsBadImpl();
+    }
+}
+
+void SpdHelper::setPatchAsBadImpl()
+{
+    mIsPatchBad = true;
+}
+
+inline const char * toHex(UINT8 b)
+{
+    static char hex[] = "0123456789ABCDEF";
+    static char c[3];
+    c[0] = hex[((b >> 4) & 0x0F)];
+    c[1] = hex[((b >> 0) & 0x0F)];
+    c[2] = '\0';
+    return &c[0];
+}
+
+bool SpdHelper::isPatchBadImpl(UINT8* prm, UINT32 len)
+{
+    string strNew;
+
+    // Get the patch ID from the prm data.
+    for (int i = 0; i < 8 && i < len; ++i)
+        strNew.append(toHex(*prm++));
+
+    // If it is not the same patch as before, then reset things.
+    if ( strNew != mPatchId )
+    {
+        mPatchId = strNew;
+        mErrorCount = 0;
+        mIsPatchBad = false;
+    }
+
+    // Otherwise the 'mIsPatchBad' will tell if its bad or not.
+    ALOGD("%s '%s' (%d) is %sa known bad patch file", __func__, mPatchId.c_str(), mErrorCount, (mIsPatchBad ? "" : "not "));
+
+    return mIsPatchBad;
+}
+
+SpdHelper& SpdHelper::getInstance()
+{
+    static SpdHelper* theInstance = NULL;
+    if (theInstance == NULL)
+        theInstance= new SpdHelper;
+    return *theInstance;
+}
+
+SpdHelper::SpdHelper()
+{
+    mErrorCount = 0;
+    mPatchId.erase();
+    if(!GetNumValue((char*)NAME_SPD_MAXRETRYCOUNT, &mMaxErrorCount, sizeof(mMaxErrorCount)))
+        mMaxErrorCount = DEFAULT_SPD_MAXRETRYCOUNT;
+    mIsPatchBad = false;
+    if (!GetNumValue((char*)NAME_SPD_DEBUG, &mSpdDebug, sizeof(mSpdDebug)))
+        mSpdDebug = false;
+}
diff --git a/halimpl/bcm2079x/adaptation/userial_linux.c b/halimpl/bcm2079x/adaptation/userial_linux.c
new file mode 100644
index 0000000..f41f296
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/userial_linux.c
@@ -0,0 +1,1795 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#include "OverrideLog.h"
+#include <string.h>
+#include "gki.h"
+#include "nfc_hal_api.h"
+#include "nfc_hal_int.h"
+#include "userial.h"
+#include "nfc_target.h"
+
+#include <pthread.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <gki_int.h>
+#include "hcidefs.h"
+#include <poll.h>
+#include "upio.h"
+#include "bcm2079x.h"
+#include "config.h"
+
+#define HCISU_EVT                           EVENT_MASK(APPL_EVT_0)
+#define MAX_ERROR                           10
+#define default_transport                   "/dev/bcm2079x"
+
+#define NUM_RESET_ATTEMPTS                  5
+#define NFC_WAKE_ASSERTED_ON_POR            UPIO_OFF
+
+#ifndef BTE_APPL_MAX_USERIAL_DEV_NAME
+#define BTE_APPL_MAX_USERIAL_DEV_NAME           (256)
+#endif
+extern UINT8 appl_trace_level;
+
+
+/* Mapping of USERIAL_PORT_x to linux */
+extern UINT32 ScrProtocolTraceFlag;
+static tUPIO_STATE current_nfc_wake_state = UPIO_OFF;
+int uart_port  = 0;
+int isLowSpeedTransport = 0;
+int nfc_wake_delay = 0;
+int nfc_write_delay = 0;
+int gPowerOnDelay = 300;
+static int gPrePowerOffDelay = 0;    // default value
+static int gPostPowerOffDelay = 0;     // default value
+static pthread_mutex_t close_thread_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+char userial_dev[BTE_APPL_MAX_USERIAL_DEV_NAME+1];
+char power_control_dev[BTE_APPL_MAX_USERIAL_DEV_NAME+1];
+tSNOOZE_MODE_CONFIG gSnoozeModeCfg = {
+    NFC_HAL_LP_SNOOZE_MODE_SPI_I2C,     /* Sleep Mode (0=Disabled 1=UART 8=SPI/I2C) */
+    NFC_HAL_LP_IDLE_THRESHOLD_HOST,     /* Idle Threshold Host */
+    NFC_HAL_LP_IDLE_THRESHOLD_HC,       /* Idle Threshold HC */
+    NFC_HAL_LP_ACTIVE_LOW,              /* NFC Wake active mode (0=ActiveLow 1=ActiveHigh) */
+    NFC_HAL_LP_ACTIVE_HIGH              /* Host Wake active mode (0=ActiveLow 1=ActiveHigh) */
+};
+
+UINT8 bcmi2cnfc_client_addr = 0;
+UINT8 bcmi2cnfc_read_multi_packets = 0;
+
+#define USERIAL_Debug_verbose     ((ScrProtocolTraceFlag & 0x80000000) == 0x80000000)
+
+#include <sys/socket.h>
+
+#define LOG_TAG "USERIAL_LINUX"
+
+static UINT8 spi_negotiation[10] = { 0xF0, /* CMD */
+                                    0x00, /* SPI PARM Negotiation */
+                                    0x01, /* SPI Version */
+                                    0x00, /* SPI Mode:0, SPI_INT active low */
+                                    0x00, /* 8Bit, MSB first, Little Endian byte order */
+                                    0x00, /* Reserved */
+                                    0xFF, /* Sleep timeout Lower Byte */
+                                    0xFF, /* Sleep timeout Upper Byte */
+                                    0x00, /* Reserved */
+                                    0x00 /* Reserved */
+};
+static UINT8 spi_nego_res[20];
+
+/* Modes used when powering off (independent
+   of what the stack/jni has configured */
+#define POM_NORMAL          (0)     /* Normal */
+#define POM_CE3SO           (1)     /* Go to CE3-SO */
+#define POM_NFC_OFF         (2)     /* Set NFC Off bit */
+
+static int gPowerOffMode = POM_NORMAL;
+
+static UINT8 ce3_so_cmd[10] = { 0x10,
+                                0x2F, /* CMD */
+                                0x08,
+                                0x06, /* size of cmd */
+                                0x02, /* CE3 power-level */
+                                0xF3, /* LpmUicc */
+                                0x01, /* LpmListenTech */
+                                0x01, /* Param */
+                                0x00, /* Forced */
+                                0x00  /* Debug */
+};
+
+static UINT8 set_nfc_off_cmd[5] = {
+                                0x10,
+                                0x2F, /* CMD */
+                                0x38,
+                                0x01, /* size of cmd */
+                                0x01  /* setNfcOff */
+};
+
+#include <ctype.h>
+
+#define USING_BRCM_USB TRUE
+
+/* use tc interface to change baudrate instead of close/open sequence which can fail on some platforms
+ * due to tx line movement when opeing/closing the UART. the 43xx do not like this. */
+#ifndef USERIAL_USE_TCIO_BAUD_CHANGE
+#define USERIAL_USE_TCIO_BAUD_CHANGE FALSE
+#endif
+
+#ifndef USERIAL_USE_IO_BT_WAKE
+#define USERIAL_USE_IO_BT_WAKE FALSE
+#endif
+
+/* this are the ioctl values used for bt_wake ioctl via UART driver. you may need to redefine at for
+ * you platform! Logically they need to be unique and not colide with existing uart ioctl's.
+ */
+#ifndef USERIAL_IO_BT_WAKE_ASSERT
+#define USERIAL_IO_BT_WAKE_ASSERT   0x8003
+#endif
+#ifndef USERIAL_IO_BT_WAKE_DEASSERT
+#define USERIAL_IO_BT_WAKE_DEASSERT 0x8004
+#endif
+#ifndef USERIAL_IO_BT_WAKE_GET_ST
+#define USERIAL_IO_BT_WAKE_GET_ST   0x8005
+#endif
+
+/* the read limit in this current implementation depends on the GKI_BUF3_SIZE
+ * It would be better to use some ring buffer from the USERIAL_Read() is reading
+ * instead of putting it into GKI buffers.
+ */
+#define READ_LIMIT (USERIAL_POOL_BUF_SIZE-BT_HDR_SIZE)
+/*
+ * minimum buffer size requirement to read a full sized packet from NFCC = 255 + 4 byte header
+ */
+#define MIN_BUFSIZE 259
+#define     POLL_TIMEOUT    1000
+/* priority of the reader thread */
+#define USERIAL_READ_TRHEAD_PRIO 90
+/* time (ms) to wait before trying to allocate again a GKI buffer */
+#define NO_GKI_BUFFER_RECOVER_TIME 100
+#define MAX_SERIAL_PORT (USERIAL_PORT_15 + 1)
+
+extern void dumpbin(const char* data, int size);
+extern UINT8 *scru_dump_hex (UINT8 *p, char *p_title, UINT32 len, UINT32 trace_layer, UINT32 trace_type);
+
+static pthread_t      worker_thread1 = 0;
+
+typedef struct  {
+    volatile unsigned long bt_wake_state;
+    int             sock;
+    tUSERIAL_CBACK      *ser_cb;
+    UINT16      baud;
+    UINT8       data_bits;
+    UINT16      parity;
+    UINT8       stop_bits;
+    UINT8       port;
+    tUSERIAL_OPEN_CFG open_cfg;
+    int         sock_power_control;
+    int         client_device_address;
+    struct timespec write_time;
+} tLINUX_CB;
+
+static tLINUX_CB linux_cb;  /* case of multipel port support use array : [MAX_SERIAL_PORT] */
+
+void userial_close_thread(UINT32 params);
+
+static UINT8 device_name[BTE_APPL_MAX_USERIAL_DEV_NAME+1];
+static int   bSerialPortDevice = FALSE;
+static int _timeout = POLL_TIMEOUT;
+static BOOLEAN is_close_thread_is_waiting = FALSE;
+
+static int change_client_addr(int addr);
+
+int   perf_log_every_count = 0;
+typedef struct {
+    const char* label;
+    long    lapse;
+    long    bytes;
+    long    count;
+    long    overhead;
+} tPERF_DATA;
+
+/*******************************************************************************
+**
+** Function         perf_reset
+**
+** Description      reset performance measurement data
+**
+** Returns          none
+**
+*******************************************************************************/
+void perf_reset(tPERF_DATA* t)
+{
+    t->count =
+    t->bytes =
+    t->lapse = 0;
+}
+
+/*******************************************************************************
+**
+** Function         perf_log
+**
+** Description      produce a log entry of cvurrent performance data
+**
+** Returns          none
+**
+*******************************************************************************/
+void perf_log(tPERF_DATA* t)
+{
+    // round to nearest ms
+    // t->lapse += 500;
+    // t->lapse /= 1000;
+    if (t->lapse)
+    {
+        if (t->bytes)
+            ALOGD( "%s:%s, bytes=%ld, lapse=%ld (%d.%02d kbps) (bus data rate %d.%02d kbps) overhead %d(%d percent)\n",
+                    __func__,
+                    t->label, t->bytes, t->lapse,
+                    (int)(8 * t->bytes / t->lapse), (int)(800 * t->bytes / (t->lapse)) % 100,
+                    (int)(9 * (t->bytes + t->count * t->overhead) / t->lapse), (int)(900 * (t->bytes + t->count * t->overhead) / (t->lapse)) % 100,
+                    (int)(t->count * t->overhead), (int)(t->count * t->overhead * 100 / t->bytes)
+                    );
+        else
+            ALOGD( "%s:%s, lapse=%ld (average %ld)\n", __func__,
+                    t->label, t->lapse, (int)t->lapse / t->count
+                    );
+    }
+    perf_reset(t);
+}
+
+/*******************************************************************************
+**
+** Function         perf_update
+**
+** Description      update perforamnce measurement data
+**
+** Returns          none
+**
+*******************************************************************************/
+void perf_update(tPERF_DATA* t, long lapse, long bytes)
+{
+    if (!perf_log_every_count)
+        return;
+    // round to nearest ms
+    lapse += 500;
+    lapse /= 1000;
+    t->count++;
+    t->bytes += bytes;
+    t->lapse += lapse;
+    if (t->count == perf_log_every_count)
+        perf_log(t);
+}
+
+static tPERF_DATA   perf_poll = {"USERIAL_Poll", 0, 0, 0, 0};
+static tPERF_DATA   perf_read = {"USERIAL_Read", 0, 0, 0, 9};
+static tPERF_DATA   perf_write = {"USERIAL_Write", 0, 0, 0, 3};
+static tPERF_DATA   perf_poll_2_poll = {"USERIAL_Poll_to_Poll", 0, 0, 0, 0};
+static clock_t      _poll_t0 = 0;
+
+static UINT32 userial_baud_tbl[] =
+{
+    300,        /* USERIAL_BAUD_300          0 */
+    600,        /* USERIAL_BAUD_600          1 */
+    1200,       /* USERIAL_BAUD_1200         2 */
+    2400,       /* USERIAL_BAUD_2400         3 */
+    9600,       /* USERIAL_BAUD_9600         4 */
+    19200,      /* USERIAL_BAUD_19200        5 */
+    57600,      /* USERIAL_BAUD_57600        6 */
+    115200,     /* USERIAL_BAUD_115200       7 */
+    230400,     /* USERIAL_BAUD_230400       8 */
+    460800,     /* USERIAL_BAUD_460800       9 */
+    921600,     /* USERIAL_BAUD_921600       10 */
+    1000000,    /* USERIAL_BAUD_1M           11 */
+    1500000,    /* USERIAL_BAUD_1_5M         12 */
+    2000000,    /* USERIAL_BAUD_2M           13 */
+    3000000,    /* USERIAL_BAUD_3M           14 */
+    4000000     /* USERIAL_BAUD_4M           15 */
+};
+
+/*******************************************************************************
+**
+** Function         wake_state
+**
+** Description      return current state of NFC_WAKE gpio
+**
+** Returns          GPIO value to wake NFCC
+**
+*******************************************************************************/
+static inline int wake_state()
+{
+    return ((gSnoozeModeCfg.nfc_wake_active_mode == NFC_HAL_LP_ACTIVE_HIGH) ? UPIO_ON : UPIO_OFF);
+}
+
+/*******************************************************************************
+**
+** Function         sleep_state
+**
+** Description      return current state of NFC_WAKE gpio
+**
+** Returns          GPIO value to allow NFCC to goto sleep
+**
+*******************************************************************************/
+static inline int sleep_state()
+{
+    return ((gSnoozeModeCfg.nfc_wake_active_mode == NFC_HAL_LP_ACTIVE_HIGH) ? UPIO_OFF : UPIO_ON);
+}
+
+/*******************************************************************************
+**
+** Function         isWake
+**
+** Description      return current state of NFC_WAKE gpio based on the active mode setting
+**
+** Returns          asserted_state if it's awake, deasserted_state if it's allowed to sleep
+**
+*******************************************************************************/
+static inline int isWake(int state)
+{
+    int     asserted_state = ((gSnoozeModeCfg.nfc_wake_active_mode == NFC_HAL_LP_ACTIVE_HIGH) ? UPIO_ON : UPIO_OFF);
+    return (state != -1) ?
+        state == asserted_state :
+        current_nfc_wake_state == asserted_state;
+}
+
+/*******************************************************************************
+**
+** Function           setWriteDelay
+**
+** Description        Record a delay for the next write operation
+**
+** Input Parameter    delay in milliseconds
+**
+** Comments           use this function to register a delay before next write,
+**                    This is used in three instances: power up delay, wake delay
+**                    and write delay
+**
+*******************************************************************************/
+static void setWriteDelay(int delay)
+{
+    if (delay <= 0) {
+        // Set a minimum delay of 5ms between back-to-back writes
+        delay = 5;
+    }
+
+    clock_gettime(CLOCK_MONOTONIC, &linux_cb.write_time);
+    if (delay > 1000)
+    {
+        linux_cb.write_time.tv_sec += delay / 1000;
+        delay %= 1000;
+    }
+    unsigned long write_delay = delay * 1000 * 1000;
+    linux_cb.write_time.tv_nsec += write_delay;
+    if (linux_cb.write_time.tv_nsec > 1000*1000*1000)
+    {
+        linux_cb.write_time.tv_nsec -= 1000*1000*1000;
+        linux_cb.write_time.tv_sec++;
+    }
+}
+
+/*******************************************************************************
+**
+** Function           doWriteDelay
+**
+** Description        Execute a delay as registered in setWriteDelay()
+**
+** Output Parameter   none
+**
+** Returns            none
+**
+** Comments           This function calls GKI_Delay to execute a delay to fulfill
+**                    the delay registered earlier.
+**
+*******************************************************************************/
+static void doWriteDelay()
+{
+    struct timespec now;
+    clock_gettime(CLOCK_MONOTONIC, &now);
+    long delay = 0;
+
+    if (now.tv_sec > linux_cb.write_time.tv_sec)
+        return;
+    else if (now.tv_sec == linux_cb.write_time.tv_sec)
+    {
+        if (now.tv_nsec > linux_cb.write_time.tv_nsec)
+            return;
+        delay = (linux_cb.write_time.tv_nsec - now.tv_nsec) / 1000000;
+    }
+    else
+        delay = (linux_cb.write_time.tv_sec - now.tv_sec) * 1000 + linux_cb.write_time.tv_nsec / 1000000 - now.tv_nsec / 1000000;
+
+    if (delay > 0 && delay < 1000)
+    {
+        ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "doWriteDelay() delay %ld ms", delay);
+        GKI_delay(delay);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         create_signal_fds
+**
+** Description      create a socketpair for read thread to use
+**
+** Returns          file descriptor
+**
+*******************************************************************************/
+
+static int signal_fds[2];
+static inline int create_signal_fds(struct pollfd* set)
+{
+    if (signal_fds[0] == 0 && socketpair(AF_UNIX, SOCK_STREAM, 0, signal_fds) < 0)
+    {
+        ALOGE("%s create_signal_sockets:socketpair failed, errno: %d", __func__, errno);
+        return -1;
+    }
+    set->fd = signal_fds[0];
+    return signal_fds[0];
+}
+
+/*******************************************************************************
+**
+** Function         close_signal_fds
+**
+** Description      close the socketpair
+**
+** Returns          none
+**
+*******************************************************************************/
+static inline void close_signal_fds()
+{
+    int stat = 0;
+
+    stat = close(signal_fds[0]);
+    if (stat == -1)
+        ALOGE ("%s, fail close index 0; errno=%d", __FUNCTION__, errno);
+    signal_fds[0] = 0;
+
+    stat = close(signal_fds[1]);
+    if (stat == -1)
+        ALOGE ("%s, fail close index 1; errno=%d", __FUNCTION__, errno);
+    signal_fds[1] = 0;
+}
+
+/*******************************************************************************
+**
+** Function         send_wakeup_signal
+**
+** Description      send a one byte data to the socket as signal to the read thread
+**                  for it to stop
+**
+** Returns          number of bytes sent, or error no
+**
+*******************************************************************************/
+static inline int send_wakeup_signal()
+{
+    char sig_on = 1;
+    ALOGD("%s: Sending signal to %d", __func__, signal_fds[1]);
+    return send(signal_fds[1], &sig_on, sizeof(sig_on), 0);
+}
+
+/*******************************************************************************
+**
+** Function         reset_signal
+**
+** Description      read the one byte data from the socket
+**
+** Returns          received data
+**
+*******************************************************************************/
+static inline int reset_signal()
+{
+    char sig_recv = 0;
+    ALOGD("%s: Receiving signal from %d", __func__, signal_fds[0]);
+    recv(signal_fds[0], &sig_recv, sizeof(sig_recv), MSG_WAITALL);
+    return (int)sig_recv;
+}
+
+/*******************************************************************************
+**
+** Function         is_signaled
+**
+** Description      test if there's data waiting on the socket
+**
+** Returns          TRUE is data is available
+**
+*******************************************************************************/
+static inline int is_signaled(struct pollfd* set)
+{
+    return ((set->revents & POLLIN) == POLLIN) || ((set->revents & POLLRDNORM) == POLLRDNORM) ;
+}
+
+/******************************************************************************/
+
+typedef unsigned char uchar;
+
+BUFFER_Q Userial_in_q;
+
+/*******************************************************************************
+ **
+ ** Function           USERIAL_GetLineSpeed
+ **
+ ** Description        This function convert USERIAL baud to line speed.
+ **
+ ** Output Parameter   None
+ **
+ ** Returns            line speed
+ **
+ *******************************************************************************/
+UDRV_API extern UINT32 USERIAL_GetLineSpeed(UINT8 baud)
+{
+    return (baud <= USERIAL_BAUD_4M) ?
+            userial_baud_tbl[baud-USERIAL_BAUD_300] : 0;
+}
+
+/*******************************************************************************
+ **
+ ** Function           USERIAL_GetBaud
+ **
+ ** Description        This function convert line speed to USERIAL baud.
+ **
+ ** Output Parameter   None
+ **
+ ** Returns            line speed
+ **
+ *******************************************************************************/
+UDRV_API extern UINT8 USERIAL_GetBaud(UINT32 line_speed)
+{
+    UINT8 i;
+    for (i = USERIAL_BAUD_300; i <= USERIAL_BAUD_921600; i++)
+    {
+        if (userial_baud_tbl[i-USERIAL_BAUD_300] == line_speed)
+            return i;
+    }
+
+    return USERIAL_BAUD_AUTO;
+}
+
+/*******************************************************************************
+**
+** Function           USERIAL_Init
+**
+** Description        This function initializes the  serial driver.
+**
+** Output Parameter   None
+**
+** Returns            Nothing
+**
+*******************************************************************************/
+
+UDRV_API void    USERIAL_Init(void * p_cfg)
+{
+    ALOGI(__FUNCTION__);
+
+    //if userial_close_thread() is waiting to run; let it go first;
+    //let it finish; then continue this function
+    while (TRUE)
+    {
+        pthread_mutex_lock(&close_thread_mutex);
+        if (is_close_thread_is_waiting)
+        {
+            pthread_mutex_unlock(&close_thread_mutex);
+            ALOGI("USERIAL_Init(): wait for close-thread");
+            sleep (1);
+        }
+        else
+            break;
+    }
+
+    memset(&linux_cb, 0, sizeof(linux_cb));
+    linux_cb.sock = -1;
+    linux_cb.ser_cb = NULL;
+    linux_cb.sock_power_control = -1;
+    linux_cb.client_device_address = 0;
+    GKI_init_q(&Userial_in_q);
+    pthread_mutex_unlock(&close_thread_mutex);
+}
+
+/*******************************************************************************
+ **
+ ** Function           my_read
+ **
+ ** Description        This function read a packet from driver.
+ **
+ ** Output Parameter   None
+ **
+ ** Returns            number of bytes in the packet or error code
+ **
+ *******************************************************************************/
+int my_read(int fd, uchar *pbuf, int len)
+{
+    struct pollfd fds[2];
+
+    int n = 0;
+    int ret = 0;
+    int count = 0;
+    int offset = 0;
+    clock_t t1, t2;
+
+    if (!isLowSpeedTransport && _timeout != POLL_TIMEOUT)
+        ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: enter, pbuf=%lx, len = %d\n", __func__, (unsigned long)pbuf, len);
+    memset(pbuf, 0, len);
+    /* need to use select in order to avoid collistion between read and close on same fd */
+    /* Initialize the input set */
+    fds[0].fd = fd;
+    fds[0].events = POLLIN | POLLERR | POLLRDNORM;
+    fds[0].revents = 0;
+
+    create_signal_fds(&fds[1]);
+    fds[1].events = POLLIN | POLLERR | POLLRDNORM;
+    fds[1].revents = 0;
+    t1 = clock();
+    n = poll(fds, 2, _timeout);
+    t2 = clock();
+    perf_update(&perf_poll, t2 - t1, 0);
+    if (_poll_t0)
+        perf_update(&perf_poll_2_poll, t2 - _poll_t0, 0);
+
+    _poll_t0 = t2;
+    /* See if there was an error */
+    if (n < 0)
+    {
+        ALOGD( "select failed; errno = %d\n", errno);
+        return -errno;
+    }
+    else if (n == 0)
+        return -EAGAIN;
+
+    if (is_signaled(&fds[1]))
+    {
+        ALOGD( "%s: exit signal received\n", __func__);
+        reset_signal();
+        return -1;
+    }
+    if (!bSerialPortDevice || len < MIN_BUFSIZE)
+        count = len;
+    else
+        count = 1;
+    do {
+        t2 = clock();
+        ret = read(fd, pbuf+offset, (size_t)count);
+        if (ret > 0)
+            perf_update(&perf_read, clock()-t2, ret);
+
+        if (ret <= 0 || !bSerialPortDevice || len < MIN_BUFSIZE)
+            break;
+
+        if (isLowSpeedTransport)
+            goto done;
+
+        if (offset == 0)
+        {
+            if (pbuf[offset] == HCIT_TYPE_NFC)
+                count = 3;
+            else if (pbuf[offset] == HCIT_TYPE_EVENT)
+                count = 2;
+            else
+            {
+                ALOGD( "%s: unknown HCIT type header pbuf[%d] = %x\n", __func__, offset, pbuf[offset]);
+                break;
+            }
+            offset = 1;
+        }
+        else if (offset == 1)
+        {
+            offset += count;
+            count = pbuf[offset-1];
+            if (count > (len - offset)) //if (count > (remaining buffer size))
+                count = len - offset; //only read what the remaining buffer size can hold
+        }
+        else
+        {
+            offset += ret;
+            count -= ret;
+        }
+        if (count == 0)
+        {
+            ret = offset;
+            break;
+        }
+    } while (count > 0);
+
+
+ #if VALIDATE_PACKET
+/*
+ * vallidate the packet structure
+ */
+    if (ret > 0 && len >= MIN_BUFSIZE)
+    {
+        count = 0;
+        while (count < ret)
+        {
+            if (pbuf[count] == HCIT_TYPE_NFC)
+            {
+                if (USERIAL_Debug_verbose)
+                    scru_dump_hex(pbuf+count, NULL, pbuf[count+3]+4, 0, 0);
+                count += pbuf[count+3]+4;
+            }
+            else if (pbuf[count] == HCIT_TYPE_EVENT)
+            {
+                if (USERIAL_Debug_verbose)
+                    scru_dump_hex(pbuf+count, NULL, pbuf[count+2]+3, 0, 0);
+                count += pbuf[count+2]+3;
+            }
+            else
+            {
+                ALOGD( "%s: unknown HCIT type header pbuf[%d] = %x, remain %d bytes\n", __func__, count, pbuf[count], ret-count);
+                scru_dump_hex(pbuf+count, NULL, ret - count, 0, 0);
+                break;
+            }
+        } /* while*/
+    }
+#endif
+done:
+    if (!isLowSpeedTransport)
+        ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: return %d(0x%x) bytes, errno=%d count=%d, n=%d, timeout=%d\n", __func__,
+            ret, ret, errno, count, n, _timeout);
+    if (_timeout == POLL_TIMEOUT)
+        _timeout = -1;
+    return ret;
+}
+extern BOOLEAN gki_chk_buf_damage(void *p_buf);
+static int sRxLength = 0;
+
+/*******************************************************************************
+ **
+ ** Function           userial_read_thread
+ **
+ ** Description        entry point of read thread.
+ **
+ ** Output Parameter   None
+ **
+ ** Returns            0
+ **
+ *******************************************************************************/
+UINT32 userial_read_thread(UINT32 arg)
+{
+    int rx_length;
+    int error_count = 0;
+    int bErrorReported = 0;
+    int iMaxError = MAX_ERROR;
+    BT_HDR *p_buf = NULL;
+
+    worker_thread1 = pthread_self();
+
+    ALOGD( "start userial_read_thread, id=%lx", worker_thread1);
+    _timeout = POLL_TIMEOUT;
+
+    for (;linux_cb.sock > 0;)
+    {
+        BT_HDR *p_buf;
+        UINT8 *current_packet;
+
+        if ((p_buf = (BT_HDR *) GKI_getpoolbuf( USERIAL_POOL_ID ) )!= NULL)
+        {
+            p_buf->offset = 0;
+            p_buf->layer_specific = 0;
+
+            current_packet = (UINT8 *) (p_buf + 1);
+            rx_length = my_read(linux_cb.sock, current_packet, READ_LIMIT);
+
+        }
+        else
+        {
+            ALOGE( "userial_read_thread(): unable to get buffer from GKI p_buf = %p poolid = %d\n", p_buf, USERIAL_POOL_ID);
+            rx_length = 0;  /* paranoia setting */
+            GKI_delay( NO_GKI_BUFFER_RECOVER_TIME );
+            continue;
+        }
+        if (rx_length > 0)
+        {
+            bErrorReported = 0;
+            error_count = 0;
+            iMaxError = 3;
+            if (rx_length > sRxLength)
+                sRxLength = rx_length;
+            p_buf->len = (UINT16)rx_length;
+            GKI_enqueue(&Userial_in_q, p_buf);
+            if (!isLowSpeedTransport)
+                ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "userial_read_thread(): enqueued p_buf=%p, count=%d, length=%d\n",
+                            p_buf, Userial_in_q.count, rx_length);
+
+            if (linux_cb.ser_cb != NULL)
+                (*linux_cb.ser_cb)(linux_cb.port, USERIAL_RX_READY_EVT, (tUSERIAL_EVT_DATA *)p_buf);
+
+            GKI_send_event(USERIAL_HAL_TASK, HCISU_EVT);
+        }
+        else
+        {
+            GKI_freebuf( p_buf );
+            if (rx_length == -EAGAIN)
+                continue;
+            else if (rx_length == -1)
+            {
+                ALOGD( "userial_read_thread(): exiting\n");
+                break;
+            }
+            else if (rx_length == 0 && !isWake(-1))
+                continue;
+            ++error_count;
+            if (rx_length <= 0 && ((error_count > 0) && ((error_count % iMaxError) == 0)))
+            {
+                if (bErrorReported == 0)
+                {
+                    ALOGE( "userial_read_thread(): my_read returned (%d) error count = %d, errno=%d return USERIAL_ERR_EVT\n",
+                            rx_length, error_count, errno);
+                    if (linux_cb.ser_cb != NULL)
+                        (*linux_cb.ser_cb)(linux_cb.port, USERIAL_ERR_EVT, (tUSERIAL_EVT_DATA *)p_buf);
+
+                    GKI_send_event(USERIAL_HAL_TASK, HCISU_EVT);
+                    ++bErrorReported;
+                }
+                if (sRxLength == 0)
+                {
+                    ALOGE( "userial_read_thread(): my_read returned (%d) error count = %d, errno=%d exit read thread\n",
+                            rx_length, error_count, errno);
+                    break;
+                }
+            }
+        }
+    } /* for */
+
+    ALOGD( "userial_read_thread(): freeing GKI_buffers\n");
+    while ((p_buf = (BT_HDR *) GKI_dequeue (&Userial_in_q)) != NULL)
+    {
+        GKI_freebuf(p_buf);
+        ALOGD("userial_read_thread: dequeued buffer from Userial_in_q\n");
+    }
+
+    GKI_exit_task (GKI_get_taskid ());
+    ALOGD( "USERIAL READ: EXITING TASK\n");
+
+    return 0;
+}
+
+/*******************************************************************************
+ **
+ ** Function           userial_to_tcio_baud
+ **
+ ** Description        helper function converts USERIAL baud rates into TCIO conforming baud rates
+ **
+ ** Output Parameter   None
+ **
+ ** Returns            TRUE - success
+ **                    FALSE - unsupported baud rate, default of 115200 is used
+ **
+ *******************************************************************************/
+BOOLEAN userial_to_tcio_baud(UINT8 cfg_baud, UINT32 * baud)
+{
+    if (cfg_baud == USERIAL_BAUD_600)
+        *baud = B600;
+    else if (cfg_baud == USERIAL_BAUD_1200)
+        *baud = B1200;
+    else if (cfg_baud == USERIAL_BAUD_9600)
+        *baud = B9600;
+    else if (cfg_baud == USERIAL_BAUD_19200)
+        *baud = B19200;
+    else if (cfg_baud == USERIAL_BAUD_57600)
+        *baud = B57600;
+    else if (cfg_baud == USERIAL_BAUD_115200)
+        *baud = B115200 | CBAUDEX;
+    else if (cfg_baud == USERIAL_BAUD_230400)
+        *baud = B230400;
+    else if (cfg_baud == USERIAL_BAUD_460800)
+        *baud = B460800;
+    else if (cfg_baud == USERIAL_BAUD_921600)
+        *baud = B921600;
+    else if (cfg_baud == USERIAL_BAUD_1M)
+        *baud = B1000000;
+    else if (cfg_baud == USERIAL_BAUD_2M)
+        *baud = B2000000;
+    else if (cfg_baud == USERIAL_BAUD_3M)
+        *baud = B3000000;
+    else if (cfg_baud == USERIAL_BAUD_4M)
+        *baud = B4000000;
+    else
+    {
+        ALOGE( "userial_to_tcio_baud: unsupported baud idx %i", cfg_baud );
+        *baud = B115200;
+        return FALSE;
+    }
+    return TRUE;
+}
+
+#if (USERIAL_USE_IO_BT_WAKE==TRUE)
+/*******************************************************************************
+ **
+ ** Function           userial_io_init_bt_wake
+ **
+ ** Description        helper function to set the open state of the bt_wake if ioctl
+ **                    is used. it should not hurt in the rfkill case but it might
+ **                    be better to compile it out.
+ **
+ ** Returns            none
+ **
+ *******************************************************************************/
+void userial_io_init_bt_wake( int fd, unsigned long * p_wake_state )
+{
+    /* assert BT_WAKE for ioctl. should NOT hurt on rfkill version */
+    ioctl( fd, USERIAL_IO_BT_WAKE_ASSERT, NULL);
+    ioctl( fd, USERIAL_IO_BT_WAKE_GET_ST, p_wake_state );
+    if ( *p_wake_state == 0)
+        ALOGI("\n***userial_io_init_bt_wake(): Ooops, asserted BT_WAKE signal, but still got BT_WAKE state == to %d\n",
+             *p_wake_state );
+
+    *p_wake_state = 1;
+}
+#endif
+
+/*******************************************************************************
+**
+** Function           USERIAL_Open
+**
+** Description        Open the indicated serial port with the given configuration
+**
+** Output Parameter   None
+**
+** Returns            Nothing
+**
+*******************************************************************************/
+UDRV_API void USERIAL_Open(tUSERIAL_PORT port, tUSERIAL_OPEN_CFG *p_cfg, tUSERIAL_CBACK *p_cback)
+{
+    UINT32 baud = 0;
+    UINT8 data_bits = 0;
+    UINT16 parity = 0;
+    UINT8 stop_bits = 0;
+    struct termios termios;
+    const char ttyusb[] = "/dev/ttyUSB";
+    const char devtty[] = "/dev/tty";
+    unsigned long num = 0;
+    int     ret = 0;
+
+    ALOGI("USERIAL_Open(): enter");
+
+    //if userial_close_thread() is waiting to run; let it go first;
+    //let it finish; then continue this function
+    while (TRUE)
+    {
+        pthread_mutex_lock(&close_thread_mutex);
+        if (is_close_thread_is_waiting)
+        {
+            pthread_mutex_unlock(&close_thread_mutex);
+            ALOGI("USERIAL_Open(): wait for close-thread");
+            sleep (1);
+        }
+        else
+            break;
+    }
+
+    // restore default power off delay settings incase they were changed in userial_set_poweroff_delays()
+    gPrePowerOffDelay = 0;
+    gPostPowerOffDelay = 0;
+
+    if ( !GetStrValue ( NAME_TRANSPORT_DRIVER, userial_dev, sizeof ( userial_dev ) ) )
+        strcpy ( userial_dev, default_transport );
+    if ( GetNumValue ( NAME_UART_PORT, &num, sizeof ( num ) ) )
+        uart_port = num;
+    if ( GetNumValue ( NAME_LOW_SPEED_TRANSPORT, &num, sizeof ( num ) ) )
+        isLowSpeedTransport = num;
+    if ( GetNumValue ( NAME_NFC_WAKE_DELAY, &num, sizeof ( num ) ) )
+        nfc_wake_delay = num;
+    if ( GetNumValue ( NAME_NFC_WRITE_DELAY, &num, sizeof ( num ) ) )
+        nfc_write_delay = num;
+    if ( GetNumValue ( NAME_PERF_MEASURE_FREQ, &num, sizeof ( num ) ) )
+        perf_log_every_count = num;
+    if ( GetNumValue ( NAME_POWER_ON_DELAY, &num, sizeof ( num ) ) )
+        gPowerOnDelay = num;
+    if ( GetNumValue ( NAME_PRE_POWER_OFF_DELAY, &num, sizeof ( num ) ) )
+        gPrePowerOffDelay = num;
+    if ( GetNumValue ( NAME_POST_POWER_OFF_DELAY, &num, sizeof ( num ) ) )
+        gPostPowerOffDelay = num;
+    if ( GetNumValue ( NAME_POWER_OFF_MODE, &num, sizeof ( num ) ) )
+        gPowerOffMode = num;
+    ALOGI("USERIAL_Open() device: %s port=%d, uart_port=%d WAKE_DELAY(%d) WRITE_DELAY(%d) POWER_ON_DELAY(%d) PRE_POWER_OFF_DELAY(%d) POST_POWER_OFF_DELAY(%d)",
+            (char*)userial_dev, port, uart_port, nfc_wake_delay, nfc_write_delay, gPowerOnDelay, gPrePowerOffDelay,
+            gPostPowerOffDelay);
+
+    strcpy((char*)device_name, (char*)userial_dev);
+    sRxLength = 0;
+    _poll_t0 = 0;
+
+    if ((strncmp(userial_dev, ttyusb, sizeof(ttyusb)-1) == 0) ||
+        (strncmp(userial_dev, devtty, sizeof(devtty)-1) == 0) )
+    {
+        if (uart_port >= MAX_SERIAL_PORT)
+        {
+            ALOGD( "Port > MAX_SERIAL_PORT\n");
+            goto done_open;
+        }
+        bSerialPortDevice = TRUE;
+        sprintf((char*)device_name, "%s%d", (char*)userial_dev, uart_port);
+        ALOGI("USERIAL_Open() using device_name: %s ", (char*)device_name);
+        if (!userial_to_tcio_baud(p_cfg->baud, &baud))
+            goto done_open;
+
+        if (p_cfg->fmt & USERIAL_DATABITS_8)
+            data_bits = CS8;
+        else if (p_cfg->fmt & USERIAL_DATABITS_7)
+            data_bits = CS7;
+        else if (p_cfg->fmt & USERIAL_DATABITS_6)
+            data_bits = CS6;
+        else if (p_cfg->fmt & USERIAL_DATABITS_5)
+            data_bits = CS5;
+        else
+            goto done_open;
+
+        if (p_cfg->fmt & USERIAL_PARITY_NONE)
+            parity = 0;
+        else if (p_cfg->fmt & USERIAL_PARITY_EVEN)
+            parity = PARENB;
+        else if (p_cfg->fmt & USERIAL_PARITY_ODD)
+            parity = (PARENB | PARODD);
+        else
+            goto done_open;
+
+        if (p_cfg->fmt & USERIAL_STOPBITS_1)
+            stop_bits = 0;
+        else if (p_cfg->fmt & USERIAL_STOPBITS_2)
+            stop_bits = CSTOPB;
+        else
+            goto done_open;
+    }
+    else
+        strcpy((char*)device_name, (char*)userial_dev);
+
+    {
+        ALOGD("%s Opening %s\n",  __FUNCTION__, device_name);
+        if ((linux_cb.sock = open((char*)device_name, O_RDWR | O_NOCTTY )) == -1)
+        {
+            ALOGI("%s unable to open %s",  __FUNCTION__, device_name);
+            GKI_send_event(NFC_HAL_TASK, NFC_HAL_TASK_EVT_TERMINATE);
+            goto done_open;
+        }
+        ALOGD( "%s sock = %d\n", __FUNCTION__, linux_cb.sock);
+        if (GetStrValue ( NAME_POWER_CONTROL_DRIVER, power_control_dev, sizeof ( power_control_dev ) ) &&
+            power_control_dev[0] != '\0')
+        {
+            if (strcmp(power_control_dev, userial_dev) == 0)
+                linux_cb.sock_power_control = linux_cb.sock;
+            else
+            {
+                if ((linux_cb.sock_power_control = open((char*)power_control_dev, O_RDWR | O_NOCTTY )) == -1)
+                {
+                    ALOGI("%s unable to open %s",  __FUNCTION__, power_control_dev);
+                }
+            }
+        }
+        if ( bSerialPortDevice )
+        {
+            tcflush(linux_cb.sock, TCIOFLUSH);
+            tcgetattr(linux_cb.sock, &termios);
+
+            termios.c_cflag &= ~(CSIZE | PARENB);
+            termios.c_cflag = CLOCAL|CREAD|data_bits|stop_bits|parity;
+            if (!parity)
+                termios.c_cflag |= IGNPAR;
+            // termios.c_cflag &= ~CRTSCTS;
+            termios.c_oflag = 0;
+            termios.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
+            termios.c_iflag &= ~(BRKINT | ICRNL | INLCR | ISTRIP | IXON | IGNBRK | PARMRK | INPCK);
+            termios.c_lflag = 0;
+            termios.c_iflag = 0;
+            cfsetospeed(&termios, baud);
+            cfsetispeed(&termios, baud);
+
+            termios.c_cc[VTIME] = 0;
+            termios.c_cc[VMIN] = 1;
+            tcsetattr(linux_cb.sock, TCSANOW, &termios);
+
+            tcflush(linux_cb.sock, TCIOFLUSH);
+
+#if (USERIAL_USE_IO_BT_WAKE==TRUE)
+            userial_io_init_bt_wake( linux_cb.sock, &linux_cb.bt_wake_state );
+#endif
+            GKI_delay(gPowerOnDelay);
+        }
+        else
+        {
+            USERIAL_PowerupDevice(port);
+        }
+    }
+
+    linux_cb.ser_cb     = p_cback;
+    linux_cb.port = port;
+    memcpy(&linux_cb.open_cfg, p_cfg, sizeof(tUSERIAL_OPEN_CFG));
+    GKI_create_task ((TASKPTR)userial_read_thread, USERIAL_HAL_TASK, (INT8*)"USERIAL_HAL_TASK", 0, 0, (pthread_cond_t*)NULL, NULL);
+
+
+#if (defined USERIAL_DEBUG) && (USERIAL_DEBUG == TRUE)
+    ALOGD( "Leaving USERIAL_Open\n");
+#endif
+
+#if (SERIAL_AMBA == TRUE)
+    /* give 20ms time for reader thread */
+    GKI_delay(20);
+#endif
+
+done_open:
+    pthread_mutex_unlock(&close_thread_mutex);
+    ALOGI("USERIAL_Open(): exit");
+    return;
+}
+
+/*******************************************************************************
+**
+** Function           USERIAL_Read
+**
+** Description        Read data from a serial port using byte buffers.
+**
+** Output Parameter   None
+**
+** Returns            Number of bytes actually read from the serial port and
+**                    copied into p_data.  This may be less than len.
+**
+*******************************************************************************/
+
+static BT_HDR *pbuf_USERIAL_Read = NULL;
+
+UDRV_API UINT16  USERIAL_Read(tUSERIAL_PORT port, UINT8 *p_data, UINT16 len)
+{
+    UINT16 total_len = 0;
+    UINT16 copy_len = 0;
+    UINT8 * current_packet = NULL;
+
+#if (defined USERIAL_DEBUG) && (USERIAL_DEBUG == TRUE)
+    ALOGD( "%s ++ len=%d pbuf_USERIAL_Read=%p, p_data=%p\n", __func__, len, pbuf_USERIAL_Read, p_data);
+#endif
+    do
+    {
+        if (pbuf_USERIAL_Read != NULL)
+        {
+            current_packet = ((UINT8 *)(pbuf_USERIAL_Read + 1)) + (pbuf_USERIAL_Read->offset);
+
+            if ((pbuf_USERIAL_Read->len) <= (len - total_len))
+                copy_len = pbuf_USERIAL_Read->len;
+            else
+                copy_len = (len - total_len);
+
+            memcpy((p_data + total_len), current_packet, copy_len);
+
+            total_len += copy_len;
+
+            pbuf_USERIAL_Read->offset += copy_len;
+            pbuf_USERIAL_Read->len -= copy_len;
+
+            if (pbuf_USERIAL_Read->len == 0)
+            {
+                GKI_freebuf(pbuf_USERIAL_Read);
+                pbuf_USERIAL_Read = NULL;
+            }
+        }
+
+        if (pbuf_USERIAL_Read == NULL && (total_len < len))
+            pbuf_USERIAL_Read = (BT_HDR *)GKI_dequeue(&Userial_in_q);
+
+    } while ((pbuf_USERIAL_Read != NULL) && (total_len < len));
+
+#if (defined USERIAL_DEBUG) && (USERIAL_DEBUG == TRUE)
+    ALOGD( "%s: returned %d bytes", __func__, total_len);
+#endif
+    return total_len;
+}
+
+/*******************************************************************************
+**
+** Function           USERIAL_Readbuf
+**
+** Description        Read data from a serial port using GKI buffers.
+**
+** Output Parameter   Pointer to a GKI buffer which contains the data.
+**
+** Returns            Nothing
+**
+** Comments           The caller of this function is responsible for freeing the
+**                    GKI buffer when it is finished with the data.  If there is
+**                    no data to be read, the value of the returned pointer is
+**                    NULL.
+**
+*******************************************************************************/
+
+UDRV_API void    USERIAL_ReadBuf(tUSERIAL_PORT port, BT_HDR **p_buf)
+{
+
+}
+
+/*******************************************************************************
+**
+** Function           USERIAL_WriteBuf
+**
+** Description        Write data to a serial port using a GKI buffer.
+**
+** Output Parameter   None
+**
+** Returns            TRUE  if buffer accepted for write.
+**                    FALSE if there is already a buffer being processed.
+**
+** Comments           The buffer will be freed by the serial driver.  Therefore,
+**                    the application calling this function must not free the
+**                    buffer.
+**
+*******************************************************************************/
+
+UDRV_API BOOLEAN USERIAL_WriteBuf(tUSERIAL_PORT port, BT_HDR *p_buf)
+{
+    return FALSE;
+}
+
+/*******************************************************************************
+**
+** Function           USERIAL_Write
+**
+** Description        Write data to a serial port using a byte buffer.
+**
+** Output Parameter   None
+**
+** Returns            Number of bytes actually written to the transport.  This
+**                    may be less than len.
+**
+*******************************************************************************/
+UDRV_API UINT16  USERIAL_Write(tUSERIAL_PORT port, UINT8 *p_data, UINT16 len)
+{
+    int ret = 0, total = 0;
+    int i = 0;
+    clock_t t;
+
+    ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "USERIAL_Write: (%d bytes)", len);
+    pthread_mutex_lock(&close_thread_mutex);
+
+    doWriteDelay();
+    t = clock();
+    while (len != 0 && linux_cb.sock != -1)
+    {
+        ret = write(linux_cb.sock, p_data + total, len);
+        if (ret < 0)
+        {
+            ALOGE("USERIAL_Write len = %d, ret = %d, errno = %d", len, ret, errno);
+            break;
+        }
+        else
+        {
+            ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "USERIAL_Write len = %d, ret = %d", len, ret);
+        }
+
+        total += ret;
+        len -= ret;
+    }
+    perf_update(&perf_write, clock() - t, total);
+
+    /* register a delay for next write */
+    setWriteDelay(total * nfc_write_delay / 1000);
+
+    pthread_mutex_unlock(&close_thread_mutex);
+
+    return ((UINT16)total);
+}
+
+/*******************************************************************************
+**
+** Function           userial_change_rate
+**
+** Description        change naud rate
+**
+** Output Parameter   None
+**
+** Returns            None
+**
+*******************************************************************************/
+void userial_change_rate(UINT8 baud)
+{
+#if defined (USING_BRCM_USB) && (USING_BRCM_USB == FALSE)
+    struct termios termios;
+#endif
+#if (USERIAL_USE_TCIO_BAUD_CHANGE==TRUE)
+    UINT32 tcio_baud;
+#endif
+
+#if defined (USING_BRCM_USB) && (USING_BRCM_USB == FALSE)
+    tcflush(linux_cb.sock, TCIOFLUSH);
+
+    tcgetattr(linux_cb.sock, &termios);
+
+    cfmakeraw(&termios);
+    cfsetospeed(&termios, baud);
+    cfsetispeed(&termios, baud);
+
+    termios.c_cflag |= (CLOCAL | CREAD | CRTSCTS | stop_bits);
+
+    tcsetattr(linux_cb.sock, TCSANOW, &termios);
+    tcflush(linux_cb.sock, TCIOFLUSH);
+
+#else
+#if (USERIAL_USE_TCIO_BAUD_CHANGE==FALSE)
+    fprintf(stderr, "userial_change_rate: Closing UART Port\n");
+    ALOGI("userial_change_rate: Closing UART Port\n");
+    USERIAL_Close(linux_cb.port);
+
+    GKI_delay(50);
+
+    /* change baud rate in settings - leave everything else the same  */
+    linux_cb.open_cfg.baud = baud;
+
+    ALOGD( "userial_change_rate: Attempting to reopen the UART Port at 0x%08x\n", (unsigned int)USERIAL_GetLineSpeed(baud));
+    ALOGI("userial_change_rate: Attempting to reopen the UART Port at %i\n", (unsigned int)USERIAL_GetLineSpeed(baud));
+
+    USERIAL_Open(linux_cb.port, &linux_cb.open_cfg, linux_cb.ser_cb);
+#else /* amba uart */
+    fprintf(stderr, "userial_change_rate(): changeing baud rate via TCIO \n");
+    ALOGI( "userial_change_rate: (): changeing baud rate via TCIO \n");
+    /* change baud rate in settings - leave everything else the same  */
+    linux_cb.open_cfg.baud = baud;
+    if (!userial_to_tcio_baud(linux_cb.open_cfg.baud, &tcio_baud))
+        return;
+
+    tcflush(linux_cb.sock, TCIOFLUSH);
+
+    /* get current settings. they should be fine besides baud rate we want to change */
+    tcgetattr(linux_cb.sock, &termios);
+
+    /* set input/output baudrate */
+    cfsetospeed(&termios, tcio_baud);
+    cfsetispeed(&termios, tcio_baud);
+    tcsetattr(linux_cb.sock, TCSANOW, &termios);
+
+    tcflush(linux_cb.sock, TCIOFLUSH);
+#endif
+#endif   /* USING_BRCM_USB  */
+}
+
+/*******************************************************************************
+**
+** Function           userial_close_port
+**
+** Description        close the transport driver
+**
+** Returns            Nothing
+**
+*******************************************************************************/
+void userial_close_port( void )
+{
+    USERIAL_Close(linux_cb.port);
+}
+
+/*******************************************************************************
+**
+** Function           USERIAL_Ioctl
+**
+** Description        Perform an operation on a serial port.
+**
+** Output Parameter   The p_data parameter is either an input or output depending
+**                    on the operation.
+**
+** Returns            Nothing
+**
+*******************************************************************************/
+
+UDRV_API void    USERIAL_Ioctl(tUSERIAL_PORT port, tUSERIAL_OP op, tUSERIAL_IOCTL_DATA *p_data)
+{
+#if (defined LINUX_OS) && (LINUX_OS == TRUE)
+    USB_SCO_CONTROL ioctl_data;
+
+    /* just ignore port parameter as we are using USB in this case  */
+#endif
+
+    switch (op)
+    {
+    case USERIAL_OP_FLUSH:
+        break;
+    case USERIAL_OP_FLUSH_RX:
+        break;
+    case USERIAL_OP_FLUSH_TX:
+        break;
+    case USERIAL_OP_BAUD_WR:
+        ALOGI( "USERIAL_Ioctl: Received USERIAL_OP_BAUD_WR on port: %d, ioctl baud%i\n", port, p_data->baud);
+        linux_cb.port = port;
+        userial_change_rate(p_data->baud);
+        break;
+
+    default:
+        break;
+    }
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         USERIAL_SetPowerOffDelays
+**
+** Description      Set power off delays used during USERIAL_Close().  The
+**                  values in the conf. file setting override these if set.
+**
+** Returns          None.
+**
+*******************************************************************************/
+UDRV_API void USERIAL_SetPowerOffDelays(int pre_poweroff_delay, int post_poweroff_delay)
+{
+    gPrePowerOffDelay = pre_poweroff_delay;
+    gPostPowerOffDelay = post_poweroff_delay;
+}
+
+/*******************************************************************************
+**
+** Function           USERIAL_Close
+**
+** Description        Close a serial port
+**
+** Output Parameter   None
+**
+** Returns            Nothing
+**
+*******************************************************************************/
+UDRV_API void    USERIAL_Close(tUSERIAL_PORT port)
+{
+    pthread_attr_t attr;
+    pthread_t      close_thread;
+    UINT8          res[10];
+    UINT32         delay = 100;
+
+    ALOGD ("%s: enter; gPowerOffMode=%d", __FUNCTION__, gPowerOffMode);
+
+    /* Do we need to put NFCC into certain mode before switching off?... */
+    if (gPowerOffMode != POM_NORMAL)
+    {
+        switch (gPowerOffMode)
+        {
+        case POM_CE3SO:
+            ALOGD ("%s: Sending Set_PwrLevel cmd to go to CE3-SO mode", __FUNCTION__);
+            USERIAL_Write(port, ce3_so_cmd, sizeof (ce3_so_cmd));
+            delay = 1000;
+            break;
+
+        case POM_NFC_OFF:
+            ALOGD ("%s: Sending Set_NfcOff cmd", __FUNCTION__);
+            USERIAL_Write(port, set_nfc_off_cmd, sizeof (set_nfc_off_cmd));
+            break;
+        }
+
+        USERIAL_Read(port, res, sizeof ( res ));
+        GKI_delay(delay);
+    }
+
+    // check to see if thread is already running
+    if (pthread_mutex_trylock(&close_thread_mutex) == 0)
+    {
+        // mutex aquired so thread is not running
+        is_close_thread_is_waiting = TRUE;
+        pthread_mutex_unlock(&close_thread_mutex);
+
+        // close transport in a new thread so we don't block the caller
+        // make thread detached, no other thread will join
+        pthread_attr_init(&attr);
+        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+        pthread_create( &close_thread, &attr, (void *)userial_close_thread, NULL);
+        pthread_attr_destroy(&attr);
+    }
+    else
+    {
+        // mutex not aquired to thread is already running
+        ALOGD( "USERIAL_Close(): already closing \n");
+    }
+    ALOGD ("%s: exit", __FUNCTION__);
+}
+
+
+/*******************************************************************************
+**
+** Function         userial_close_thread
+**
+** Description      Thread to close USERIAL
+**
+** Returns          None.
+**
+*******************************************************************************/
+void userial_close_thread(UINT32 params)
+{
+    BT_HDR                  *p_buf = NULL;
+    int result;
+
+    ALOGD( "%s: closing transport (%d)\n", __FUNCTION__, linux_cb.sock);
+    pthread_mutex_lock(&close_thread_mutex);
+    is_close_thread_is_waiting = FALSE;
+
+    if (linux_cb.sock <= 0)
+    {
+        ALOGD( "%s: already closed (%d)\n", __FUNCTION__, linux_cb.sock);
+        pthread_mutex_unlock(&close_thread_mutex);
+        return;
+    }
+
+    send_wakeup_signal();
+    result = pthread_join( worker_thread1, NULL );
+    if ( result < 0 )
+        ALOGE( "%s: pthread_join() FAILED: result: %d", __FUNCTION__, result );
+    else
+        ALOGD( "%s: pthread_join() joined: result: %d", __FUNCTION__, result );
+
+    if (linux_cb.sock_power_control > 0)
+    {
+        result = ioctl(linux_cb.sock_power_control, BCMNFC_WAKE_CTL, sleep_state());
+        ALOGD("%s: Delay %dms before turning off the chip", __FUNCTION__, gPrePowerOffDelay);
+        GKI_delay(gPrePowerOffDelay);
+        result = ioctl(linux_cb.sock_power_control, BCMNFC_POWER_CTL, 0);
+        ALOGD("%s: Delay %dms after turning off the chip", __FUNCTION__, gPostPowerOffDelay);
+        GKI_delay(gPostPowerOffDelay);
+    }
+    result = close(linux_cb.sock);
+    if (result == -1)
+        ALOGE("%s: fail close linux_cb.sock; errno=%d", __FUNCTION__, errno);
+
+    if (linux_cb.sock_power_control > 0 && linux_cb.sock_power_control != linux_cb.sock)
+    result = close(linux_cb.sock_power_control);
+    if (result == -1)
+        ALOGE("%s: fail close linux_cb.sock_power_control; errno=%d", __FUNCTION__, errno);
+
+    linux_cb.sock_power_control = -1;
+    linux_cb.sock = -1;
+
+    close_signal_fds();
+    pthread_mutex_unlock(&close_thread_mutex);
+    ALOGD("%s: exiting", __FUNCTION__);
+}
+
+/*******************************************************************************
+**
+** Function           USERIAL_Feature
+**
+** Description        Check whether a feature of the serial API is supported.
+**
+** Output Parameter   None
+**
+** Returns            TRUE  if the feature is supported
+**                    FALSE if the feature is not supported
+**
+*******************************************************************************/
+
+UDRV_API BOOLEAN USERIAL_Feature(tUSERIAL_FEATURE feature)
+{
+    switch (feature)
+    {
+    case USERIAL_FEAT_PORT_1:
+    case USERIAL_FEAT_PORT_2:
+    case USERIAL_FEAT_PORT_3:
+    case USERIAL_FEAT_PORT_4:
+
+    case USERIAL_FEAT_BAUD_600:
+    case USERIAL_FEAT_BAUD_1200:
+    case USERIAL_FEAT_BAUD_9600:
+    case USERIAL_FEAT_BAUD_19200:
+    case USERIAL_FEAT_BAUD_57600:
+    case USERIAL_FEAT_BAUD_115200:
+
+    case USERIAL_FEAT_STOPBITS_1:
+    case USERIAL_FEAT_STOPBITS_2:
+
+    case USERIAL_FEAT_PARITY_NONE:
+    case USERIAL_FEAT_PARITY_EVEN:
+    case USERIAL_FEAT_PARITY_ODD:
+
+    case USERIAL_FEAT_DATABITS_5:
+    case USERIAL_FEAT_DATABITS_6:
+    case USERIAL_FEAT_DATABITS_7:
+    case USERIAL_FEAT_DATABITS_8:
+
+    case USERIAL_FEAT_FC_HW:
+    case USERIAL_FEAT_BUF_BYTE:
+
+    case USERIAL_FEAT_OP_FLUSH_RX:
+    case USERIAL_FEAT_OP_FLUSH_TX:
+        return TRUE;
+    default:
+        return FALSE;
+    }
+
+    return FALSE;
+}
+
+/*****************************************************************************
+**
+** Function         UPIO_Set
+**
+** Description
+**      This function sets one or more GPIO devices to the given state.
+**      Multiple GPIOs of the same type can be masked together to set more
+**      than one GPIO. This function can only be used on types UPIO_LED and
+**      UPIO_GENERAL.
+**
+** Input Parameters:
+**      type    The type of device.
+**      pio     Indicates the particular GPIOs.
+**      state   The desired state.
+**
+** Output Parameter:
+**      None.
+**
+** Returns:
+**      None.
+**
+*****************************************************************************/
+UDRV_API void UPIO_Set(tUPIO_TYPE type, tUPIO pio, tUPIO_STATE new_state)
+{
+    int     ret;
+    if (type == UPIO_GENERAL)
+    {
+        if (pio == NFC_HAL_LP_NFC_WAKE_GPIO)
+        {
+            if (new_state == UPIO_ON || new_state == UPIO_OFF)
+            {
+                if (linux_cb.sock_power_control > 0)
+                {
+                    ALOGD("%s: ioctl, state=%d", __func__, new_state);
+                    ret = ioctl(linux_cb.sock_power_control, BCMNFC_WAKE_CTL, new_state);
+                    if (isWake(new_state) && nfc_wake_delay > 0 && new_state != current_nfc_wake_state)
+                    {
+                        ALOGD("%s: ioctl, old state=%d, insert delay for %d ms", __func__, current_nfc_wake_state, nfc_wake_delay);
+                        setWriteDelay(nfc_wake_delay);
+                    }
+                    current_nfc_wake_state = new_state;
+                }
+            }
+        }
+    }
+}
+
+/*****************************************************************************
+**
+** Function         setReadPacketSize
+**
+** Description
+**      This function sets the packetSize to the driver.
+**      this enables faster read operation of NCI/HCI responses
+**
+** Input Parameters:
+**      len     number of bytes to read per operation.
+**
+** Output Parameter:
+**      None.
+**
+** Returns:
+**      None.
+**
+*****************************************************************************/
+void setReadPacketSize(int len)
+{
+    int ret;
+    ALOGD("%s: ioctl, len=%d", __func__, len);
+    ret = ioctl(linux_cb.sock, BCMNFC_READ_FULL_PACKET, len);
+}
+
+
+UDRV_API BOOLEAN USERIAL_IsClosed()
+{
+    return (linux_cb.sock == -1) ? TRUE : FALSE;
+}
+
+UDRV_API void USERIAL_PowerupDevice(tUSERIAL_PORT port)
+{
+    int ret = -1;
+    unsigned long num = 0;
+    unsigned int resetSuccess = 0;
+    unsigned int numTries = 0;
+    unsigned char spi_negotiation[64];
+    int delay = gPowerOnDelay;
+    ALOGD("%s: enter", __FUNCTION__);
+
+    if ( GetNumValue ( NAME_READ_MULTI_PACKETS, &num, sizeof ( num ) ) )
+        bcmi2cnfc_read_multi_packets = num;
+
+    if (bcmi2cnfc_read_multi_packets > 0)
+        ioctl(linux_cb.sock, BCMNFC_READ_MULTI_PACKETS, bcmi2cnfc_read_multi_packets);
+
+    while (!resetSuccess && numTries < NUM_RESET_ATTEMPTS) {
+        if (numTries++ > 0) {
+            ALOGW("BCM2079x: retrying reset, attempt %d/%d", numTries, NUM_RESET_ATTEMPTS);
+        }
+        if (linux_cb.sock_power_control > 0)
+        {
+            current_nfc_wake_state = NFC_WAKE_ASSERTED_ON_POR;
+            ioctl(linux_cb.sock_power_control, BCMNFC_WAKE_CTL, NFC_WAKE_ASSERTED_ON_POR);
+            ioctl(linux_cb.sock_power_control, BCMNFC_POWER_CTL, 0);
+            GKI_delay(10);
+            ret = ioctl(linux_cb.sock_power_control, BCMNFC_POWER_CTL, 1);
+        }
+
+        ret = GetStrValue ( NAME_SPI_NEGOTIATION, (char*)spi_negotiation, sizeof ( spi_negotiation ) );
+        if (ret > 0 && spi_negotiation[0] > 0 && spi_negotiation[0] < sizeof ( spi_negotiation ) - 1)
+        {
+            int len = spi_negotiation[0];
+            /* Wake control is not available: Start SPI negotiation*/
+            USERIAL_Write(port, &spi_negotiation[1], len);
+            USERIAL_Read(port, spi_nego_res, sizeof ( spi_nego_res ));
+        }
+
+        if ( GetNumValue ( NAME_CLIENT_ADDRESS, &num, sizeof ( num ) ) )
+            bcmi2cnfc_client_addr = num & 0xFF;
+        if (bcmi2cnfc_client_addr != 0 &&
+            0x07 < bcmi2cnfc_client_addr &&
+            bcmi2cnfc_client_addr < 0x78)
+        {
+            /* Delay needed after turning on chip */
+            GKI_delay(delay);
+            ALOGD( "Change client address to %x\n", bcmi2cnfc_client_addr);
+            ret = change_client_addr(bcmi2cnfc_client_addr);
+            if (!ret) {
+                resetSuccess = 1;
+                linux_cb.client_device_address = bcmi2cnfc_client_addr;
+                /* Delay long enough for address change */
+                /* MACO xxx this needs to be at least 200 ms for BCM2079x B3 */
+                delay = 200;
+            }
+        } else {
+            resetSuccess = 1;
+        }
+    }
+
+    if (!resetSuccess) {
+        ALOGE("BCM2079x: failed to initialize NFC controller");
+    }
+
+    GKI_delay(delay);
+    ALOGD("%s: exit", __FUNCTION__);
+}
+
+#define DEFAULT_CLIENT_ADDRESS 0x77
+#define ALIAS_CLIENT_ADDRESS   0x79
+static int change_client_addr(int addr)
+{
+    int ret;
+    int i;
+    char addr_data[] = {
+        0xFA, 0xF2, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x2A
+    };
+    int size = sizeof(addr_data) - 1;
+
+    addr_data[5] = addr & 0xFF;
+
+    /* set the checksum */
+    ret = 0;
+    for (i = 1; i < size; ++i)
+        ret += addr_data[i];
+    addr_data[size] = (ret & 0xFF);
+    ALOGD( "change_client_addr() change addr from 0x%x to 0x%x\n", DEFAULT_CLIENT_ADDRESS, addr);
+    /* ignore the return code from IOCTL */
+    /* always revert back to the default client address */
+    ioctl(linux_cb.sock, BCMNFC_SET_CLIENT_ADDR, DEFAULT_CLIENT_ADDRESS);
+    /* Send address change command (skipping first byte) */
+    ret = write(linux_cb.sock, &addr_data[1], size);
+
+    /* If it fails, it is likely a B3 we are talking to */
+    if (ret != size) {
+        ALOGD( "change_client_addr() change addr to 0x%x by setting BSP address to 0x%x\n", addr, ALIAS_CLIENT_ADDRESS);
+        /* legacy kernel */
+        /* MACO xxx commented out code below only works with new kernel driver,
+         * but Mako/Manta ship with old one */
+        ret = ioctl(linux_cb.sock, BCMNFC_CHANGE_ADDR, addr);
+        return ret;
+        /*
+        ret = ioctl(linux_cb.sock, BCMNFC_SET_CLIENT_ADDR, ALIAS_CLIENT_ADDRESS);
+        size++;
+        ret = write(linux_cb.sock, addr_data, size);
+        */
+    }
+
+    if (ret == size) {
+        ALOGD( "change_client_addr() set client address 0x%x to client driver\n", addr);
+        ret = ioctl(linux_cb.sock, BCMNFC_SET_CLIENT_ADDR, addr);
+    }
+    else {
+        ret = -EIO;
+    }
+    return ret;
+}
diff --git a/halimpl/bcm2079x/gki/common/gki.h b/halimpl/bcm2079x/gki/common/gki.h
new file mode 100644
index 0000000..f2e6f1a
--- /dev/null
+++ b/halimpl/bcm2079x/gki/common/gki.h
@@ -0,0 +1,517 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef GKI_H
+#define GKI_H
+
+#ifdef BUILDCFG
+#if (!defined(NFC_HAL_TARGET) || (NFC_HAL_TARGET == FALSE))
+    #include "buildcfg.h"
+#else
+    /* Build config when building HAL */
+    #include "buildcfg_hal.h"
+#endif
+#endif
+
+/* Include platform-specific over-rides */
+#if (defined(NFC_STANDALONE) && (NFC_STANDALONE == TRUE))
+    #include "gki_target.h"
+    #include "bt_types.h"
+#elif (defined(NFC_HAL_TARGET) && (NFC_HAL_TARGET == TRUE))
+    /* If building NFC HAL, then use hal target file */
+    #include "gki_hal_target.h"
+    #include "nfc_types.h"
+#else
+    /* For non-nfc_standalone, include Bluetooth definitions */
+    #include "bt_target.h"
+    #include "bt_types.h"
+#endif
+
+/* Uncomment this line for verbose GKI debugging and buffer tracking */
+/*#define GKI_BUFFER_DEBUG   TRUE*/
+
+
+/* Error codes */
+#define GKI_SUCCESS         0x00
+#define GKI_FAILURE         0x01
+#define GKI_INVALID_TASK    0xF0
+#define GKI_INVALID_POOL    0xFF
+
+
+/************************************************************************
+** Mailbox definitions. Each task has 4 mailboxes that are used to
+** send buffers to the task.
+*/
+#define TASK_MBOX_0    0
+#define TASK_MBOX_1    1
+#define TASK_MBOX_2    2
+#define TASK_MBOX_3    3
+
+#define NUM_TASK_MBOX  4
+
+/************************************************************************
+** Event definitions.
+**
+** There are 4 reserved events used to signal messages rcvd in task mailboxes.
+** There are 4 reserved events used to signal timeout events.
+** There are 8 general purpose events available for applications.
+*/
+#define MAX_EVENTS              16
+
+#define TASK_MBOX_0_EVT_MASK   0x0001
+#define TASK_MBOX_1_EVT_MASK   0x0002
+#define TASK_MBOX_2_EVT_MASK   0x0004
+#define TASK_MBOX_3_EVT_MASK   0x0008
+
+
+#define TIMER_0             0
+#define TIMER_1             1
+#define TIMER_2             2
+#define TIMER_3             3
+
+#define TIMER_0_EVT_MASK    0x0010
+#define TIMER_1_EVT_MASK    0x0020
+#define TIMER_2_EVT_MASK    0x0040
+#define TIMER_3_EVT_MASK    0x0080
+
+#define APPL_EVT_0          8
+#define APPL_EVT_1          9
+#define APPL_EVT_2          10
+#define APPL_EVT_3          11
+#define APPL_EVT_4          12
+#define APPL_EVT_5          13
+#define APPL_EVT_6          14
+#define APPL_EVT_7          15
+
+#define EVENT_MASK(evt)       ((UINT16)(0x0001 << (evt)))
+
+/************************************************************************
+**  Max Time Queue
+**/
+#ifndef GKI_MAX_TIMER_QUEUES
+#define GKI_MAX_TIMER_QUEUES    3
+#endif
+
+
+/************************************************************************
+**  Macro to determine the pool buffer size based on the GKI POOL ID at compile time.
+**  Pool IDs index from 0 to GKI_NUM_FIXED_BUF_POOLS - 1
+*/
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 1)
+
+#ifndef GKI_POOL_ID_0
+#define GKI_POOL_ID_0                0
+#endif /* ifndef GKI_POOL_ID_0 */
+
+#ifndef GKI_BUF0_SIZE
+#define GKI_BUF0_SIZE                0
+#endif /* ifndef GKI_BUF0_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 1 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 2)
+
+#ifndef GKI_POOL_ID_1
+#define GKI_POOL_ID_1                0
+#endif /* ifndef GKI_POOL_ID_1 */
+
+#ifndef GKI_BUF1_SIZE
+#define GKI_BUF1_SIZE                0
+#endif /* ifndef GKI_BUF1_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 2 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 3)
+
+#ifndef GKI_POOL_ID_2
+#define GKI_POOL_ID_2                0
+#endif /* ifndef GKI_POOL_ID_2 */
+
+#ifndef GKI_BUF2_SIZE
+#define GKI_BUF2_SIZE                0
+#endif /* ifndef GKI_BUF2_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 3 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 4)
+
+#ifndef GKI_POOL_ID_3
+#define GKI_POOL_ID_3                0
+#endif /* ifndef GKI_POOL_ID_4 */
+
+#ifndef GKI_BUF3_SIZE
+#define GKI_BUF3_SIZE                0
+#endif /* ifndef GKI_BUF3_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 4 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 5)
+
+#ifndef GKI_POOL_ID_4
+#define GKI_POOL_ID_4                0
+#endif /* ifndef GKI_POOL_ID_4 */
+
+#ifndef GKI_BUF4_SIZE
+#define GKI_BUF4_SIZE                0
+#endif /* ifndef GKI_BUF4_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 5 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 6)
+
+#ifndef GKI_POOL_ID_5
+#define GKI_POOL_ID_5                0
+#endif /* ifndef GKI_POOL_ID_5 */
+
+#ifndef GKI_BUF5_SIZE
+#define GKI_BUF5_SIZE                0
+#endif /* ifndef GKI_BUF5_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 6 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 7)
+
+#ifndef GKI_POOL_ID_6
+#define GKI_POOL_ID_6                0
+#endif /* ifndef GKI_POOL_ID_6 */
+
+#ifndef GKI_BUF6_SIZE
+#define GKI_BUF6_SIZE                0
+#endif /* ifndef GKI_BUF6_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 7 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 8)
+
+#ifndef GKI_POOL_ID_7
+#define GKI_POOL_ID_7                0
+#endif /* ifndef GKI_POOL_ID_7 */
+
+#ifndef GKI_BUF7_SIZE
+#define GKI_BUF7_SIZE                0
+#endif /* ifndef GKI_BUF7_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 8 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 9)
+
+#ifndef GKI_POOL_ID_8
+#define GKI_POOL_ID_8                0
+#endif /* ifndef GKI_POOL_ID_8 */
+
+#ifndef GKI_BUF8_SIZE
+#define GKI_BUF8_SIZE                0
+#endif /* ifndef GKI_BUF8_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 9 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 10)
+
+#ifndef GKI_POOL_ID_9
+#define GKI_POOL_ID_9                0
+#endif /* ifndef GKI_POOL_ID_9 */
+
+#ifndef GKI_BUF9_SIZE
+#define GKI_BUF9_SIZE                0
+#endif /* ifndef GKI_BUF9_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 10 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 11)
+
+#ifndef GKI_POOL_ID_10
+#define GKI_POOL_ID_10                0
+#endif /* ifndef GKI_POOL_ID_10 */
+
+#ifndef GKI_BUF10_SIZE
+#define GKI_BUF10_SIZE                0
+#endif /* ifndef GKI_BUF10_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 11 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 12)
+
+#ifndef GKI_POOL_ID_11
+#define GKI_POOL_ID_11                0
+#endif /* ifndef GKI_POOL_ID_11 */
+
+#ifndef GKI_BUF11_SIZE
+#define GKI_BUF11_SIZE                0
+#endif /* ifndef GKI_BUF11_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 12 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 13)
+
+#ifndef GKI_POOL_ID_12
+#define GKI_POOL_ID_12                0
+#endif /* ifndef GKI_POOL_ID_12 */
+
+#ifndef GKI_BUF12_SIZE
+#define GKI_BUF12_SIZE                0
+#endif /* ifndef GKI_BUF12_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 13 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 14)
+
+#ifndef GKI_POOL_ID_13
+#define GKI_POOL_ID_13                0
+#endif /* ifndef GKI_POOL_ID_13 */
+
+#ifndef GKI_BUF13_SIZE
+#define GKI_BUF13_SIZE                0
+#endif /* ifndef GKI_BUF13_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 14 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 15)
+
+#ifndef GKI_POOL_ID_14
+#define GKI_POOL_ID_14                0
+#endif /* ifndef GKI_POOL_ID_14 */
+
+#ifndef GKI_BUF14_SIZE
+#define GKI_BUF14_SIZE                0
+#endif /* ifndef GKI_BUF14_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 15 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 16)
+
+#ifndef GKI_POOL_ID_15
+#define GKI_POOL_ID_15                0
+#endif /* ifndef GKI_POOL_ID_15 */
+
+#ifndef GKI_BUF15_SIZE
+#define GKI_BUF15_SIZE                0
+#endif /* ifndef GKI_BUF15_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 16 */
+
+
+/* Timer list entry callback type
+*/
+typedef void (TIMER_CBACK)(void *p_tle);
+#ifndef TIMER_PARAM_TYPE
+#ifdef  WIN2000
+#define TIMER_PARAM_TYPE    void *
+#else
+#define TIMER_PARAM_TYPE    UINT32
+#endif
+#endif
+/* Define a timer list entry
+*/
+typedef struct _tle
+{
+    struct _tle  *p_next;
+    struct _tle  *p_prev;
+    TIMER_CBACK  *p_cback;
+    INT32         ticks;
+    TIMER_PARAM_TYPE   param;
+    UINT16        event;
+    UINT8         in_use;
+} TIMER_LIST_ENT;
+
+/* Define a timer list queue
+*/
+typedef struct
+{
+    TIMER_LIST_ENT   *p_first;
+    TIMER_LIST_ENT   *p_last;
+    INT32             last_ticks;
+} TIMER_LIST_Q;
+
+
+/***********************************************************************
+** This queue is a general purpose buffer queue, for application use.
+*/
+typedef struct
+{
+    void    *p_first;
+    void    *p_last;
+    UINT16   count;
+} BUFFER_Q;
+
+#define GKI_IS_QUEUE_EMPTY(p_q) ((p_q)->count == 0)
+
+/* Task constants
+*/
+#ifndef TASKPTR
+typedef void (*TASKPTR)(UINT32);
+#endif
+
+
+#define GKI_PUBLIC_POOL         0       /* General pool accessible to GKI_getbuf() */
+#define GKI_RESTRICTED_POOL     1       /* Inaccessible pool to GKI_getbuf() */
+
+/***********************************************************************
+** Function prototypes
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Task management
+*/
+GKI_API extern UINT8   GKI_create_task (TASKPTR, UINT8, INT8 *, UINT16 *, UINT16, void*, void*);
+GKI_API extern void    GKI_exit_task(UINT8);
+GKI_API extern UINT8   GKI_get_taskid(void);
+GKI_API extern void    GKI_init(void);
+GKI_API extern UINT8   *GKI_map_taskname(UINT8);
+GKI_API extern UINT8   GKI_resume_task(UINT8);
+GKI_API extern void    GKI_run(void *);
+GKI_API extern void    GKI_stop(void);
+GKI_API extern UINT8   GKI_suspend_task(UINT8);
+GKI_API extern UINT8   GKI_is_task_running(UINT8);
+GKI_API extern void    GKI_shutdown(void);
+
+/* memory management
+*/
+GKI_API extern void GKI_shiftdown (UINT8 *p_mem, UINT32 len, UINT32 shift_amount);
+GKI_API extern void GKI_shiftup (UINT8 *p_dest, UINT8 *p_src, UINT32 len);
+
+/* To send buffers and events between tasks
+*/
+GKI_API extern UINT8   GKI_isend_event (UINT8, UINT16);
+GKI_API extern void    GKI_isend_msg (UINT8, UINT8, void *);
+GKI_API extern void   *GKI_read_mbox  (UINT8);
+GKI_API extern void    GKI_send_msg   (UINT8, UINT8, void *);
+GKI_API extern UINT8   GKI_send_event (UINT8, UINT16);
+
+
+/* To get and release buffers, change owner and get size
+*/
+GKI_API extern void    GKI_change_buf_owner (void *, UINT8);
+GKI_API extern UINT8   GKI_create_pool (UINT16, UINT16, UINT8, void *);
+GKI_API extern void    GKI_delete_pool (UINT8);
+GKI_API extern void   *GKI_find_buf_start (void *);
+GKI_API extern void    GKI_freebuf (void *);
+#if GKI_BUFFER_DEBUG
+#define GKI_getbuf(size)    GKI_getbuf_debug(size, __FUNCTION__, __LINE__)
+GKI_API extern void   *GKI_getbuf_debug (UINT16, const char *, int);
+#else
+GKI_API extern void   *GKI_getbuf (UINT16);
+#endif
+GKI_API extern UINT16  GKI_get_buf_size (void *);
+#if GKI_BUFFER_DEBUG
+#define GKI_getpoolbuf(id)    GKI_getpoolbuf_debug(id, __FUNCTION__, __LINE__)
+GKI_API extern void   *GKI_getpoolbuf_debug (UINT8, const char *, int);
+#else
+GKI_API extern void   *GKI_getpoolbuf (UINT8);
+#endif
+
+GKI_API extern UINT16  GKI_poolcount (UINT8);
+GKI_API extern UINT16  GKI_poolfreecount (UINT8);
+GKI_API extern UINT16  GKI_poolutilization (UINT8);
+GKI_API extern void    GKI_register_mempool (void *p_mem);
+GKI_API extern UINT8   GKI_set_pool_permission(UINT8, UINT8);
+
+
+/* User buffer queue management
+*/
+GKI_API extern void   *GKI_dequeue  (BUFFER_Q *);
+GKI_API extern void    GKI_enqueue (BUFFER_Q *, void *);
+GKI_API extern void    GKI_enqueue_head (BUFFER_Q *, void *);
+GKI_API extern void   *GKI_getfirst (BUFFER_Q *);
+GKI_API extern void   *GKI_getlast (BUFFER_Q *);
+GKI_API extern void   *GKI_getnext (void *);
+GKI_API extern void    GKI_init_q (BUFFER_Q *);
+GKI_API extern BOOLEAN GKI_queue_is_empty(BUFFER_Q *);
+GKI_API extern void   *GKI_remove_from_queue (BUFFER_Q *, void *);
+GKI_API extern UINT16  GKI_get_pool_bufsize (UINT8);
+
+/* Timer management
+*/
+GKI_API extern void    GKI_add_to_timer_list (TIMER_LIST_Q *, TIMER_LIST_ENT  *);
+GKI_API extern void    GKI_delay(UINT32);
+GKI_API extern UINT32  GKI_get_tick_count(void);
+GKI_API extern INT8   *GKI_get_time_stamp(INT8 *);
+GKI_API extern void    GKI_init_timer_list (TIMER_LIST_Q *);
+GKI_API extern void    GKI_init_timer_list_entry (TIMER_LIST_ENT  *);
+GKI_API extern INT32   GKI_ready_to_sleep (void);
+GKI_API extern void    GKI_remove_from_timer_list (TIMER_LIST_Q *, TIMER_LIST_ENT  *);
+GKI_API extern void    GKI_start_timer(UINT8, INT32, BOOLEAN);
+GKI_API extern void    GKI_stop_timer (UINT8);
+GKI_API extern void    GKI_timer_update(INT32);
+GKI_API extern UINT16  GKI_update_timer_list (TIMER_LIST_Q *, INT32);
+GKI_API extern UINT32  GKI_get_remaining_ticks (TIMER_LIST_Q *, TIMER_LIST_ENT  *);
+GKI_API extern UINT16  GKI_wait(UINT16, UINT32);
+
+/* Start and Stop system time tick callback
+ * true for start system tick if time queue is not empty
+ * false to stop system tick if time queue is empty
+*/
+typedef void (SYSTEM_TICK_CBACK)(BOOLEAN);
+
+/* Time queue management for system ticks
+*/
+GKI_API extern BOOLEAN GKI_timer_queue_empty (void);
+GKI_API extern void    GKI_timer_queue_register_callback(SYSTEM_TICK_CBACK *);
+
+/* Disable Interrupts, Enable Interrupts
+*/
+GKI_API extern void    GKI_enable(void);
+GKI_API extern void    GKI_disable(void);
+GKI_API extern void    GKI_sched_lock(void);
+GKI_API extern void    GKI_sched_unlock(void);
+
+/* Allocate (Free) memory from an OS
+*/
+GKI_API extern void     *GKI_os_malloc (UINT32);
+GKI_API extern void      GKI_os_free (void *);
+
+/* os timer operation */
+GKI_API extern UINT32 GKI_get_os_tick_count(void);
+
+/* Exception handling
+*/
+GKI_API extern void    GKI_exception (UINT16, char *);
+
+#if GKI_DEBUG == TRUE
+GKI_API extern void    GKI_PrintBufferUsage(UINT8 *p_num_pools, UINT16 *p_cur_used);
+GKI_API extern void    GKI_PrintBuffer(void);
+GKI_API extern void    GKI_print_task(void);
+#else
+#undef GKI_PrintBufferUsage
+#define GKI_PrintBuffer() NULL
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+
diff --git a/halimpl/bcm2079x/gki/common/gki_buffer.c b/halimpl/bcm2079x/gki/common/gki_buffer.c
new file mode 100644
index 0000000..555bc4b
--- /dev/null
+++ b/halimpl/bcm2079x/gki/common/gki_buffer.c
@@ -0,0 +1,1559 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "gki_int.h"
+#include <stdio.h>
+
+#if (GKI_NUM_TOTAL_BUF_POOLS > 16)
+#error Number of pools out of range (16 Max)!
+#endif
+
+#if (!defined(BTU_STACK_LITE_ENABLED) || BTU_STACK_LITE_ENABLED == FALSE)
+static void gki_add_to_pool_list(UINT8 pool_id);
+static void gki_remove_from_pool_list(UINT8 pool_id);
+#endif /*  BTU_STACK_LITE_ENABLED == FALSE */
+
+#if GKI_BUFFER_DEBUG
+#define LOG_TAG "GKI_DEBUG"
+#include <android/log.h>
+#include <cutils/log.h>
+#define LOGD(format, ...)  LogMsg (TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_GENERIC, format, ## __VA_ARGS__)
+#endif
+/*******************************************************************************
+**
+** Function         gki_init_free_queue
+**
+** Description      Internal function called at startup to initialize a free
+**                  queue. It is called once for each free queue.
+**
+** Returns          void
+**
+*******************************************************************************/
+static void gki_init_free_queue (UINT8 id, UINT16 size, UINT16 total, void *p_mem)
+{
+    UINT16           i;
+    UINT16           act_size;
+    BUFFER_HDR_T    *hdr;
+    BUFFER_HDR_T    *hdr1 = NULL;
+    UINT32          *magic;
+    INT32            tempsize = size;
+    tGKI_COM_CB     *p_cb = &gki_cb.com;
+
+    /* Ensure an even number of longwords */
+    tempsize = (INT32)ALIGN_POOL(size);
+    act_size = (UINT16)(tempsize + BUFFER_PADDING_SIZE);
+
+    /* Remember pool start and end addresses */
+    if(p_mem)
+    {
+        p_cb->pool_start[id] = (UINT8 *)p_mem;
+        p_cb->pool_end[id]   = (UINT8 *)p_mem + (act_size * total);
+    }
+
+    p_cb->pool_size[id]  = act_size;
+
+    p_cb->freeq[id].size      = (UINT16) tempsize;
+    p_cb->freeq[id].total     = total;
+    p_cb->freeq[id].cur_cnt   = 0;
+    p_cb->freeq[id].max_cnt   = 0;
+
+#if GKI_BUFFER_DEBUG
+    LOGD("gki_init_free_queue() init pool=%d, size=%d (aligned=%d) total=%d start=%p", id, size, tempsize, total, p_mem);
+#endif
+
+    /* Initialize  index table */
+    if(p_mem)
+    {
+        hdr = (BUFFER_HDR_T *)p_mem;
+        p_cb->freeq[id].p_first = hdr;
+        for (i = 0; i < total; i++)
+        {
+            hdr->task_id = GKI_INVALID_TASK;
+            hdr->q_id    = id;
+            hdr->status  = BUF_STATUS_FREE;
+            magic        = (UINT32 *)((UINT8 *)hdr + BUFFER_HDR_SIZE + tempsize);
+            *magic       = MAGIC_NO;
+            hdr1         = hdr;
+            hdr          = (BUFFER_HDR_T *)((UINT8 *)hdr + act_size);
+            hdr1->p_next = hdr;
+        }
+        hdr1->p_next = NULL;
+        p_cb->freeq[id].p_last = hdr1;
+    }
+    return;
+}
+
+#ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS
+static BOOLEAN gki_alloc_free_queue(UINT8 id)
+{
+    FREE_QUEUE_T  *Q;
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+    #if GKI_BUFFER_DEBUG
+        ALOGD("\ngki_alloc_free_queue in, id:%d \n", id);
+    #endif
+
+    Q = &p_cb->freeq[p_cb->pool_list[id]];
+
+    if(Q->p_first == 0)
+    {
+        void* p_mem = GKI_os_malloc((Q->size + BUFFER_PADDING_SIZE) * Q->total);
+        if(p_mem)
+        {
+            //re-initialize the queue with allocated memory
+            #if GKI_BUFFER_DEBUG
+                ALOGD("\ngki_alloc_free_queue calling  gki_init_free_queue, id:%d  size:%d, totol:%d\n", id, Q->size, Q->total);
+            #endif
+            gki_init_free_queue(id, Q->size, Q->total, p_mem);
+            #if GKI_BUFFER_DEBUG
+                ALOGD("\ngki_alloc_free_queue ret OK, id:%d  size:%d, totol:%d\n", id, Q->size, Q->total);
+            #endif
+            return TRUE;
+        }
+        GKI_exception (GKI_ERROR_BUF_SIZE_TOOBIG, "gki_alloc_free_queue: Not enough memory");
+    }
+    #if GKI_BUFFER_DEBUG
+        ALOGD("\ngki_alloc_free_queue out failed, id:%d\n", id);
+    #endif
+    return FALSE;
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         gki_buffer_init
+**
+** Description      Called once internally by GKI at startup to initialize all
+**                  buffers and free buffer pools.
+**
+** Returns          void
+**
+*******************************************************************************/
+void gki_buffer_init(void)
+{
+    UINT8   i, tt, mb;
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+
+    /* Initialize mailboxes */
+    for (tt = 0; tt < GKI_MAX_TASKS; tt++)
+    {
+        for (mb = 0; mb < NUM_TASK_MBOX; mb++)
+        {
+            p_cb->OSTaskQFirst[tt][mb] = NULL;
+            p_cb->OSTaskQLast [tt][mb] = NULL;
+        }
+    }
+
+    for (tt = 0; tt < GKI_NUM_TOTAL_BUF_POOLS; tt++)
+    {
+        p_cb->pool_start[tt] = NULL;
+        p_cb->pool_end[tt]   = NULL;
+        p_cb->pool_size[tt]  = 0;
+
+        p_cb->freeq[tt].p_first = 0;
+        p_cb->freeq[tt].p_last  = 0;
+        p_cb->freeq[tt].size    = 0;
+        p_cb->freeq[tt].total   = 0;
+        p_cb->freeq[tt].cur_cnt = 0;
+        p_cb->freeq[tt].max_cnt = 0;
+    }
+
+    /* Use default from target.h */
+    p_cb->pool_access_mask = GKI_DEF_BUFPOOL_PERM_MASK;
+
+#if (!defined GKI_USE_DEFERED_ALLOC_BUF_POOLS && (GKI_USE_DYNAMIC_BUFFERS == TRUE))
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 0)
+    p_cb->bufpool0 = (UINT8 *)GKI_os_malloc ((GKI_BUF0_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF0_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 1)
+    p_cb->bufpool1 = (UINT8 *)GKI_os_malloc ((GKI_BUF1_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF1_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 2)
+    p_cb->bufpool2 = (UINT8 *)GKI_os_malloc ((GKI_BUF2_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF2_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 3)
+    p_cb->bufpool3 = (UINT8 *)GKI_os_malloc ((GKI_BUF3_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF3_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 4)
+    p_cb->bufpool4 = (UINT8 *)GKI_os_malloc ((GKI_BUF4_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF4_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 5)
+    p_cb->bufpool5 = (UINT8 *)GKI_os_malloc ((GKI_BUF5_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF5_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 6)
+    p_cb->bufpool6 = (UINT8 *)GKI_os_malloc ((GKI_BUF6_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF6_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 7)
+    p_cb->bufpool7 = (UINT8 *)GKI_os_malloc ((GKI_BUF7_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF7_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 8)
+    p_cb->bufpool8 = (UINT8 *)GKI_os_malloc ((GKI_BUF8_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF8_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 9)
+    p_cb->bufpool9 = (UINT8 *)GKI_os_malloc ((GKI_BUF9_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF9_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 10)
+    p_cb->bufpool10 = (UINT8 *)GKI_os_malloc ((GKI_BUF10_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF10_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 11)
+    p_cb->bufpool11 = (UINT8 *)GKI_os_malloc ((GKI_BUF11_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF11_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 12)
+    p_cb->bufpool12 = (UINT8 *)GKI_os_malloc ((GKI_BUF12_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF12_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 13)
+    p_cb->bufpool13 = (UINT8 *)GKI_os_malloc ((GKI_BUF13_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF13_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 14)
+    p_cb->bufpool14 = (UINT8 *)GKI_os_malloc ((GKI_BUF14_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF14_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 15)
+    p_cb->bufpool15 = (UINT8 *)GKI_os_malloc ((GKI_BUF15_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF15_MAX);
+#endif
+
+#endif
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 0)
+    gki_init_free_queue(0, GKI_BUF0_SIZE, GKI_BUF0_MAX, p_cb->bufpool0);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 1)
+    gki_init_free_queue(1, GKI_BUF1_SIZE, GKI_BUF1_MAX, p_cb->bufpool1);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 2)
+    gki_init_free_queue(2, GKI_BUF2_SIZE, GKI_BUF2_MAX, p_cb->bufpool2);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 3)
+    gki_init_free_queue(3, GKI_BUF3_SIZE, GKI_BUF3_MAX, p_cb->bufpool3);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 4)
+    gki_init_free_queue(4, GKI_BUF4_SIZE, GKI_BUF4_MAX, p_cb->bufpool4);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 5)
+    gki_init_free_queue(5, GKI_BUF5_SIZE, GKI_BUF5_MAX, p_cb->bufpool5);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 6)
+    gki_init_free_queue(6, GKI_BUF6_SIZE, GKI_BUF6_MAX, p_cb->bufpool6);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 7)
+    gki_init_free_queue(7, GKI_BUF7_SIZE, GKI_BUF7_MAX, p_cb->bufpool7);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 8)
+    gki_init_free_queue(8, GKI_BUF8_SIZE, GKI_BUF8_MAX, p_cb->bufpool8);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 9)
+    gki_init_free_queue(9, GKI_BUF9_SIZE, GKI_BUF9_MAX, p_cb->bufpool9);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 10)
+    gki_init_free_queue(10, GKI_BUF10_SIZE, GKI_BUF10_MAX, p_cb->bufpool10);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 11)
+    gki_init_free_queue(11, GKI_BUF11_SIZE, GKI_BUF11_MAX, p_cb->bufpool11);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 12)
+    gki_init_free_queue(12, GKI_BUF12_SIZE, GKI_BUF12_MAX, p_cb->bufpool12);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 13)
+    gki_init_free_queue(13, GKI_BUF13_SIZE, GKI_BUF13_MAX, p_cb->bufpool13);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 14)
+    gki_init_free_queue(14, GKI_BUF14_SIZE, GKI_BUF14_MAX, p_cb->bufpool14);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 15)
+    gki_init_free_queue(15, GKI_BUF15_SIZE, GKI_BUF15_MAX, p_cb->bufpool15);
+#endif
+
+    /* add pools to the pool_list which is arranged in the order of size */
+    for(i=0; i < GKI_NUM_FIXED_BUF_POOLS ; i++)
+    {
+        p_cb->pool_list[i] = i;
+    }
+
+    p_cb->curr_total_no_of_pools = GKI_NUM_FIXED_BUF_POOLS;
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_init_q
+**
+** Description      Called by an application to initialize a buffer queue.
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_init_q (BUFFER_Q *p_q)
+{
+    p_q->p_first = p_q->p_last = NULL;
+    p_q->count = 0;
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_getbuf
+**
+** Description      Called by an application to get a free buffer which
+**                  is of size greater or equal to the requested size.
+**
+**                  Note: This routine only takes buffers from public pools.
+**                        It will not use any buffers from pools
+**                        marked GKI_RESTRICTED_POOL.
+**
+** Parameters       size - (input) number of bytes needed.
+**
+** Returns          A pointer to the buffer, or NULL if none available
+**
+*******************************************************************************/
+#if GKI_BUFFER_DEBUG
+void *GKI_getbuf_debug (UINT16 size, const char * _function_, int _line_)
+#else
+void *GKI_getbuf (UINT16 size)
+#endif
+{
+    UINT8         i;
+    FREE_QUEUE_T  *Q;
+    BUFFER_HDR_T  *p_hdr;
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+#if GKI_BUFFER_DEBUG
+    UINT8         x;
+#endif
+
+    if (size == 0)
+    {
+        GKI_exception (GKI_ERROR_BUF_SIZE_ZERO, "getbuf: Size is zero");
+        return (NULL);
+    }
+
+#if GKI_BUFFER_DEBUG
+    LOGD("GKI_getbuf() requesting %d func:%s(line=%d)", size, _function_, _line_);
+#endif
+    /* Find the first buffer pool that is public that can hold the desired size */
+    for (i=0; i < p_cb->curr_total_no_of_pools; i++)
+    {
+        if ( size <= p_cb->freeq[p_cb->pool_list[i]].size )
+            break;
+    }
+
+    if(i == p_cb->curr_total_no_of_pools)
+    {
+        GKI_exception (GKI_ERROR_BUF_SIZE_TOOBIG, "getbuf: Size is too big");
+        return (NULL);
+    }
+
+    /* Make sure the buffers aren't disturbed til finished with allocation */
+    GKI_disable();
+
+    /* search the public buffer pools that are big enough to hold the size
+     * until a free buffer is found */
+    for ( ; i < p_cb->curr_total_no_of_pools; i++)
+    {
+        /* Only look at PUBLIC buffer pools (bypass RESTRICTED pools) */
+        if (((UINT16)1 << p_cb->pool_list[i]) & p_cb->pool_access_mask)
+            continue;
+
+        Q = &p_cb->freeq[p_cb->pool_list[i]];
+        if(Q->cur_cnt < Q->total)
+        {
+        #ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS
+            if(Q->p_first == 0 && gki_alloc_free_queue(i) != TRUE)
+            {
+                GKI_TRACE_ERROR_0("GKI_getbuf() out of buffer");
+                GKI_enable();
+                return NULL;
+            }
+        #endif
+
+            if(Q->p_first == 0)
+            {
+                /* gki_alloc_free_queue() failed to alloc memory */
+                GKI_TRACE_ERROR_0("GKI_getbuf() fail alloc free queue");
+                GKI_enable();
+                return NULL;
+            }
+
+            p_hdr = Q->p_first;
+            Q->p_first = p_hdr->p_next;
+
+            if (!Q->p_first)
+                Q->p_last = NULL;
+
+            if(++Q->cur_cnt > Q->max_cnt)
+                Q->max_cnt = Q->cur_cnt;
+
+            GKI_enable();
+
+            p_hdr->task_id = GKI_get_taskid();
+
+            p_hdr->status  = BUF_STATUS_UNLINKED;
+            p_hdr->p_next  = NULL;
+            p_hdr->Type    = 0;
+#if GKI_BUFFER_DEBUG
+            LOGD("GKI_getbuf() allocated, %x, %x (%d of %d used) %d", (UINT8*)p_hdr + BUFFER_HDR_SIZE, p_hdr, Q->cur_cnt, Q->total, p_cb->freeq[i].total);
+
+            strncpy(p_hdr->_function, _function_, _GKI_MAX_FUNCTION_NAME_LEN);
+            p_hdr->_function[_GKI_MAX_FUNCTION_NAME_LEN] = '\0';
+            p_hdr->_line = _line_;
+#endif
+            return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
+        }
+    }
+
+    GKI_TRACE_ERROR_0("GKI_getbuf() unable to allocate buffer!!!!!");
+#if GKI_BUFFER_DEBUG
+    LOGD("GKI_getbuf() unable to allocate buffer!!!!!");
+    LOGD("******************** GKI Memory Pool Dump ********************");
+
+    p_cb = &gki_cb.com;
+
+    LOGD("Dumping total of %d buffer pools", p_cb->curr_total_no_of_pools);
+
+    for (i=0 ; i < p_cb->curr_total_no_of_pools; i++)
+    {
+        p_hdr = (BUFFER_HDR_T *)p_cb->pool_start[i];
+
+        LOGD("pool %d has a total of %d buffers (start=%p)", i, p_cb->freeq[i].total, p_hdr);
+
+        for (x=0; p_hdr && x < p_cb->freeq[i].total; x++)
+        {
+            if (p_hdr->status != BUF_STATUS_FREE)
+            {
+                LOGD("pool:%d, buf[%d]:%x, hdr:%x status=%d func:%s(line=%d)", i, x, (UINT8*)p_hdr + BUFFER_HDR_SIZE, p_hdr, p_hdr->status, p_hdr->_function, p_hdr->_line);
+            }
+
+            p_hdr = (BUFFER_HDR_T *)((UINT8 *)p_hdr + p_cb->pool_size[i]);
+        }
+    }
+    LOGD("**************************************************************");
+#endif
+
+    GKI_TRACE_ERROR_0("Failed to allocate GKI buffer");
+
+    GKI_enable();
+
+    return (NULL);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_getpoolbuf
+**
+** Description      Called by an application to get a free buffer from
+**                  a specific buffer pool.
+**
+**                  Note: If there are no more buffers available from the pool,
+**                        the public buffers are searched for an available buffer.
+**
+** Parameters       pool_id - (input) pool ID to get a buffer out of.
+**
+** Returns          A pointer to the buffer, or NULL if none available
+**
+*******************************************************************************/
+#if GKI_BUFFER_DEBUG
+void *GKI_getpoolbuf_debug (UINT8 pool_id, const char * _function_, int _line_)
+#else
+void *GKI_getpoolbuf (UINT8 pool_id)
+#endif
+{
+    FREE_QUEUE_T  *Q;
+    BUFFER_HDR_T  *p_hdr;
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+
+    if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
+        return (NULL);
+
+#if GKI_BUFFER_DEBUG
+    LOGD("GKI_getpoolbuf() requesting from %d func:%s(line=%d)", pool_id, _function_, _line_);
+#endif
+    /* Make sure the buffers aren't disturbed til finished with allocation */
+    GKI_disable();
+
+    Q = &p_cb->freeq[pool_id];
+    if(Q->cur_cnt < Q->total)
+    {
+#ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS
+        if(Q->p_first == 0 && gki_alloc_free_queue(pool_id) != TRUE)
+            return NULL;
+#endif
+
+        if(Q->p_first == 0)
+        {
+            /* gki_alloc_free_queue() failed to alloc memory */
+            GKI_TRACE_ERROR_0("GKI_getpoolbuf() fail alloc free queue");
+            return NULL;
+        }
+
+        p_hdr = Q->p_first;
+        Q->p_first = p_hdr->p_next;
+
+        if (!Q->p_first)
+            Q->p_last = NULL;
+
+        if(++Q->cur_cnt > Q->max_cnt)
+            Q->max_cnt = Q->cur_cnt;
+
+        GKI_enable();
+
+
+        p_hdr->task_id = GKI_get_taskid();
+
+        p_hdr->status  = BUF_STATUS_UNLINKED;
+        p_hdr->p_next  = NULL;
+        p_hdr->Type    = 0;
+
+#if GKI_BUFFER_DEBUG
+        LOGD("GKI_getpoolbuf() allocated, %x, %x (%d of %d used) %d", (UINT8*)p_hdr + BUFFER_HDR_SIZE, p_hdr, Q->cur_cnt, Q->total, p_cb->freeq[pool_id].total);
+
+        strncpy(p_hdr->_function, _function_, _GKI_MAX_FUNCTION_NAME_LEN);
+        p_hdr->_function[_GKI_MAX_FUNCTION_NAME_LEN] = '\0';
+        p_hdr->_line = _line_;
+#endif
+        return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
+    }
+
+    /* If here, no buffers in the specified pool */
+    GKI_enable();
+
+#if GKI_BUFFER_DEBUG
+    /* try for free buffers in public pools */
+    return (GKI_getbuf_debug(p_cb->freeq[pool_id].size, _function_, _line_));
+#else
+    /* try for free buffers in public pools */
+    return (GKI_getbuf(p_cb->freeq[pool_id].size));
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         GKI_freebuf
+**
+** Description      Called by an application to return a buffer to the free pool.
+**
+** Parameters       p_buf - (input) address of the beginning of a buffer.
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_freebuf (void *p_buf)
+{
+    FREE_QUEUE_T    *Q;
+    BUFFER_HDR_T    *p_hdr;
+
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
+    if (!p_buf || gki_chk_buf_damage(p_buf))
+    {
+        GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Free - Buf Corrupted");
+        return;
+    }
+#endif
+
+    p_hdr = (BUFFER_HDR_T *) ((UINT8 *)p_buf - BUFFER_HDR_SIZE);
+
+#if GKI_BUFFER_DEBUG
+    LOGD("GKI_freebuf() freeing, %x, %x, func:%s(line=%d)", p_buf, p_hdr, p_hdr->_function, p_hdr->_line);
+#endif
+
+    if (p_hdr->status != BUF_STATUS_UNLINKED)
+    {
+        GKI_exception(GKI_ERROR_FREEBUF_BUF_LINKED, "Freeing Linked Buf");
+        return;
+    }
+
+    if (p_hdr->q_id >= GKI_NUM_TOTAL_BUF_POOLS)
+    {
+        GKI_exception(GKI_ERROR_FREEBUF_BAD_QID, "Bad Buf QId");
+        return;
+    }
+
+    GKI_disable();
+
+    /*
+    ** Release the buffer
+    */
+    Q  = &gki_cb.com.freeq[p_hdr->q_id];
+    if (Q->p_last)
+        Q->p_last->p_next = p_hdr;
+    else
+        Q->p_first = p_hdr;
+
+    Q->p_last      = p_hdr;
+    p_hdr->p_next  = NULL;
+    p_hdr->status  = BUF_STATUS_FREE;
+    p_hdr->task_id = GKI_INVALID_TASK;
+    if (Q->cur_cnt > 0)
+        Q->cur_cnt--;
+
+    GKI_enable();
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_get_buf_size
+**
+** Description      Called by an application to get the size of a buffer.
+**
+** Parameters       p_buf - (input) address of the beginning of a buffer.
+**
+** Returns          the size of the buffer
+**
+*******************************************************************************/
+UINT16 GKI_get_buf_size (void *p_buf)
+{
+    BUFFER_HDR_T    *p_hdr;
+
+    p_hdr = (BUFFER_HDR_T *)((UINT8 *) p_buf - BUFFER_HDR_SIZE);
+
+    if ((UINT32)p_hdr & 1)
+        return (0);
+
+    if (p_hdr->q_id < GKI_NUM_TOTAL_BUF_POOLS)
+    {
+        return (gki_cb.com.freeq[p_hdr->q_id].size);
+    }
+
+    return (0);
+}
+
+/*******************************************************************************
+**
+** Function         gki_chk_buf_damage
+**
+** Description      Called internally by OSS to check for buffer corruption.
+**
+** Returns          TRUE if there is a problem, else FALSE
+**
+*******************************************************************************/
+BOOLEAN gki_chk_buf_damage(void *p_buf)
+{
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
+
+    UINT32 *magic;
+    magic  = (UINT32 *)((UINT8 *) p_buf + GKI_get_buf_size(p_buf));
+
+    if ((UINT32)magic & 1)
+        return (TRUE);
+
+    if (*magic == MAGIC_NO)
+        return (FALSE);
+
+    return (TRUE);
+
+#else
+
+    return (FALSE);
+
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         GKI_send_msg
+**
+** Description      Called by applications to send a buffer to a task
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void GKI_send_msg (UINT8 task_id, UINT8 mbox, void *msg)
+{
+    BUFFER_HDR_T    *p_hdr;
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+
+    /* If task non-existant or not started, drop buffer */
+    if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX) || (p_cb->OSRdyTbl[task_id] == TASK_DEAD))
+    {
+        GKI_exception(GKI_ERROR_SEND_MSG_BAD_DEST, "Sending to unknown dest");
+        GKI_freebuf (msg);
+        return;
+    }
+
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
+    if (gki_chk_buf_damage(msg))
+    {
+        GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Send - Buffer corrupted");
+        return;
+    }
+#endif
+
+    p_hdr = (BUFFER_HDR_T *) ((UINT8 *) msg - BUFFER_HDR_SIZE);
+
+    if (p_hdr->status != BUF_STATUS_UNLINKED)
+    {
+        GKI_exception(GKI_ERROR_SEND_MSG_BUF_LINKED, "Send - buffer linked");
+        return;
+    }
+
+    GKI_disable();
+
+    if (p_cb->OSTaskQFirst[task_id][mbox])
+        p_cb->OSTaskQLast[task_id][mbox]->p_next = p_hdr;
+    else
+        p_cb->OSTaskQFirst[task_id][mbox] = p_hdr;
+
+    p_cb->OSTaskQLast[task_id][mbox] = p_hdr;
+
+    p_hdr->p_next = NULL;
+    p_hdr->status = BUF_STATUS_QUEUED;
+    p_hdr->task_id = task_id;
+
+
+    GKI_enable();
+
+    GKI_send_event(task_id, (UINT16)EVENT_MASK(mbox));
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_read_mbox
+**
+** Description      Called by applications to read a buffer from one of
+**                  the task mailboxes.  A task can only read its own mailbox.
+**
+** Parameters:      mbox  - (input) mailbox ID to read (0, 1, 2, or 3)
+**
+** Returns          NULL if the mailbox was empty, else the address of a buffer
+**
+*******************************************************************************/
+void *GKI_read_mbox (UINT8 mbox)
+{
+    UINT8           task_id = GKI_get_taskid();
+    void            *p_buf = NULL;
+    BUFFER_HDR_T    *p_hdr;
+
+    if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX))
+        return (NULL);
+
+    GKI_disable();
+
+    if (gki_cb.com.OSTaskQFirst[task_id][mbox])
+    {
+        p_hdr = gki_cb.com.OSTaskQFirst[task_id][mbox];
+        gki_cb.com.OSTaskQFirst[task_id][mbox] = p_hdr->p_next;
+
+        p_hdr->p_next = NULL;
+        p_hdr->status = BUF_STATUS_UNLINKED;
+
+        p_buf = (UINT8 *)p_hdr + BUFFER_HDR_SIZE;
+    }
+
+    GKI_enable();
+
+    return (p_buf);
+}
+
+
+
+/*******************************************************************************
+**
+** Function         GKI_enqueue
+**
+** Description      Enqueue a buffer at the tail of the queue
+**
+** Parameters:      p_q  -  (input) pointer to a queue.
+**                  p_buf - (input) address of the buffer to enqueue
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_enqueue (BUFFER_Q *p_q, void *p_buf)
+{
+    BUFFER_HDR_T    *p_hdr;
+
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
+    if (gki_chk_buf_damage(p_buf))
+    {
+        GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Enqueue - Buffer corrupted");
+        return;
+    }
+#endif
+
+    p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
+
+    if (p_hdr->status != BUF_STATUS_UNLINKED)
+    {
+        GKI_exception(GKI_ERROR_ENQUEUE_BUF_LINKED, "Eneueue - buf already linked");
+        return;
+    }
+
+    GKI_disable();
+
+    /* Since the queue is exposed (C vs C++), keep the pointers in exposed format */
+    if (p_q->p_first)
+    {
+        BUFFER_HDR_T *p_last_hdr = (BUFFER_HDR_T *)((UINT8 *)p_q->p_last - BUFFER_HDR_SIZE);
+        p_last_hdr->p_next = p_hdr;
+    }
+    else
+        p_q->p_first = p_buf;
+
+    p_q->p_last = p_buf;
+    p_q->count++;
+
+    p_hdr->p_next = NULL;
+    p_hdr->status = BUF_STATUS_QUEUED;
+
+    GKI_enable();
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_enqueue_head
+**
+** Description      Enqueue a buffer at the head of the queue
+**
+** Parameters:      p_q  -  (input) pointer to a queue.
+**                  p_buf - (input) address of the buffer to enqueue
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_enqueue_head (BUFFER_Q *p_q, void *p_buf)
+{
+    BUFFER_HDR_T    *p_hdr;
+
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
+    if (gki_chk_buf_damage(p_buf))
+    {
+        GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Enqueue - Buffer corrupted");
+        return;
+    }
+#endif
+
+    p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
+
+    if (p_hdr->status != BUF_STATUS_UNLINKED)
+    {
+        GKI_exception(GKI_ERROR_ENQUEUE_BUF_LINKED, "Eneueue head - buf already linked");
+        return;
+    }
+
+    GKI_disable();
+
+    if (p_q->p_first)
+    {
+        p_hdr->p_next = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE);
+        p_q->p_first = p_buf;
+    }
+    else
+    {
+        p_q->p_first = p_buf;
+        p_q->p_last  = p_buf;
+        p_hdr->p_next = NULL;
+    }
+    p_q->count++;
+
+    p_hdr->status = BUF_STATUS_QUEUED;
+
+    GKI_enable();
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_dequeue
+**
+** Description      Dequeues a buffer from the head of a queue
+**
+** Parameters:      p_q  - (input) pointer to a queue.
+**
+** Returns          NULL if queue is empty, else buffer
+**
+*******************************************************************************/
+void *GKI_dequeue (BUFFER_Q *p_q)
+{
+    BUFFER_HDR_T    *p_hdr;
+
+    GKI_disable();
+
+    if (!p_q || !p_q->count)
+    {
+        GKI_enable();
+        return (NULL);
+    }
+
+    p_hdr = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE);
+
+    /* Keep buffers such that GKI header is invisible
+    */
+    if (p_hdr->p_next)
+        p_q->p_first = ((UINT8 *)p_hdr->p_next + BUFFER_HDR_SIZE);
+    else
+    {
+        p_q->p_first = NULL;
+        p_q->p_last  = NULL;
+    }
+
+    p_q->count--;
+
+    p_hdr->p_next = NULL;
+    p_hdr->status = BUF_STATUS_UNLINKED;
+
+    GKI_enable();
+
+    return ((UINT8 *)p_hdr + BUFFER_HDR_SIZE);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_remove_from_queue
+**
+** Description      Dequeue a buffer from the middle of the queue
+**
+** Parameters:      p_q  - (input) pointer to a queue.
+**                  p_buf - (input) address of the buffer to enqueue
+**
+** Returns          NULL if queue is empty, else buffer
+**
+*******************************************************************************/
+void *GKI_remove_from_queue (BUFFER_Q *p_q, void *p_buf)
+{
+    BUFFER_HDR_T    *p_prev;
+    BUFFER_HDR_T    *p_buf_hdr;
+
+    GKI_disable();
+
+    if (p_buf == p_q->p_first)
+    {
+        GKI_enable();
+        return (GKI_dequeue (p_q));
+    }
+
+    p_buf_hdr = (BUFFER_HDR_T *)((UINT8 *)p_buf - BUFFER_HDR_SIZE);
+    p_prev    = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE);
+
+    for ( ; p_prev; p_prev = p_prev->p_next)
+    {
+        /* If the previous points to this one, move the pointers around */
+        if (p_prev->p_next == p_buf_hdr)
+        {
+            p_prev->p_next = p_buf_hdr->p_next;
+
+            /* If we are removing the last guy in the queue, update p_last */
+            if (p_buf == p_q->p_last)
+                p_q->p_last = p_prev + 1;
+
+            /* One less in the queue */
+            p_q->count--;
+
+            /* The buffer is now unlinked */
+            p_buf_hdr->p_next = NULL;
+            p_buf_hdr->status = BUF_STATUS_UNLINKED;
+
+            GKI_enable();
+            return (p_buf);
+        }
+    }
+
+    GKI_enable();
+    return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_getfirst
+**
+** Description      Return a pointer to the first buffer in a queue
+**
+** Parameters:      p_q  - (input) pointer to a queue.
+**
+** Returns          NULL if queue is empty, else buffer address
+**
+*******************************************************************************/
+void *GKI_getfirst (BUFFER_Q *p_q)
+{
+    return (p_q->p_first);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_getlast
+**
+** Description      Return a pointer to the last buffer in a queue
+**
+** Parameters:      p_q  - (input) pointer to a queue.
+**
+** Returns          NULL if queue is empty, else buffer address
+**
+*******************************************************************************/
+void *GKI_getlast (BUFFER_Q *p_q)
+{
+    return (p_q->p_last);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_getnext
+**
+** Description      Return a pointer to the next buffer in a queue
+**
+** Parameters:      p_buf  - (input) pointer to the buffer to find the next one from.
+**
+** Returns          NULL if no more buffers in the queue, else next buffer address
+**
+*******************************************************************************/
+void *GKI_getnext (void *p_buf)
+{
+    BUFFER_HDR_T    *p_hdr;
+
+    p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
+
+    if (p_hdr->p_next)
+        return ((UINT8 *)p_hdr->p_next + BUFFER_HDR_SIZE);
+    else
+        return (NULL);
+}
+
+
+
+/*******************************************************************************
+**
+** Function         GKI_queue_is_empty
+**
+** Description      Check the status of a queue.
+**
+** Parameters:      p_q  - (input) pointer to a queue.
+**
+** Returns          TRUE if queue is empty, else FALSE
+**
+*******************************************************************************/
+BOOLEAN GKI_queue_is_empty(BUFFER_Q *p_q)
+{
+    return ((BOOLEAN) (p_q->count == 0));
+}
+
+/*******************************************************************************
+**
+** Function         GKI_find_buf_start
+**
+** Description      This function is called with an address inside a buffer,
+**                  and returns the start address ofthe buffer.
+**
+**                  The buffer should be one allocated from one of GKI's pools.
+**
+** Parameters:      p_user_area - (input) address of anywhere in a GKI buffer.
+**
+** Returns          void * - Address of the beginning of the specified buffer if successful,
+**                          otherwise NULL if unsuccessful
+**
+*******************************************************************************/
+void *GKI_find_buf_start (void *p_user_area)
+{
+    UINT16       xx, size;
+    UINT32       yy;
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+    UINT8       *p_ua = (UINT8 *)p_user_area;
+
+    for (xx = 0; xx < GKI_NUM_TOTAL_BUF_POOLS; xx++)
+    {
+        if ((p_ua > p_cb->pool_start[xx]) && (p_ua < p_cb->pool_end[xx]))
+        {
+            yy = (UINT32)(p_ua - p_cb->pool_start[xx]);
+
+            size = p_cb->pool_size[xx];
+
+            yy = (yy / size) * size;
+
+            return ((void *) (p_cb->pool_start[xx] + yy + sizeof(BUFFER_HDR_T)) );
+        }
+    }
+
+    /* If here, invalid address - not in one of our buffers */
+    GKI_exception (GKI_ERROR_BUF_SIZE_ZERO, "GKI_get_buf_start:: bad addr");
+
+    return (NULL);
+}
+
+
+/********************************************************
+* The following functions are not needed for light stack
+*********************************************************/
+#if (!defined(BTU_STACK_LITE_ENABLED) || BTU_STACK_LITE_ENABLED == FALSE)
+
+/*******************************************************************************
+**
+** Function         GKI_set_pool_permission
+**
+** Description      This function is called to set or change the permissions for
+**                  the specified pool ID.
+**
+** Parameters       pool_id -       (input) pool ID to be set or changed
+**                  permission -    (input) GKI_PUBLIC_POOL or GKI_RESTRICTED_POOL
+**
+** Returns          GKI_SUCCESS if successful
+**                  GKI_INVALID_POOL if unsuccessful
+**
+*******************************************************************************/
+UINT8 GKI_set_pool_permission(UINT8 pool_id, UINT8 permission)
+{
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+
+    if (pool_id < GKI_NUM_TOTAL_BUF_POOLS)
+    {
+        if (permission == GKI_RESTRICTED_POOL)
+            p_cb->pool_access_mask = (UINT16)(p_cb->pool_access_mask | (1 << pool_id));
+
+        else    /* mark the pool as public */
+            p_cb->pool_access_mask = (UINT16)(p_cb->pool_access_mask & ~(1 << pool_id));
+
+        return (GKI_SUCCESS);
+    }
+    else
+        return (GKI_INVALID_POOL);
+}
+
+/*******************************************************************************
+**
+** Function         gki_add_to_pool_list
+**
+** Description      Adds pool to the pool list which is arranged in the
+**                  order of size
+**
+** Returns          void
+**
+*******************************************************************************/
+static void gki_add_to_pool_list(UINT8 pool_id)
+{
+
+    INT32 i, j;
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+
+     /* Find the position where the specified pool should be inserted into the list */
+    for(i=0; i < p_cb->curr_total_no_of_pools; i++)
+    {
+
+        if(p_cb->freeq[pool_id].size <= p_cb->freeq[ p_cb->pool_list[i] ].size)
+            break;
+    }
+
+    /* Insert the new buffer pool ID into the list of pools */
+    for(j = p_cb->curr_total_no_of_pools; j > i; j--)
+    {
+        p_cb->pool_list[j] = p_cb->pool_list[j-1];
+    }
+
+    p_cb->pool_list[i] = pool_id;
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         gki_remove_from_pool_list
+**
+** Description      Removes pool from the pool list. Called when a pool is deleted
+**
+** Returns          void
+**
+*******************************************************************************/
+static void gki_remove_from_pool_list(UINT8 pool_id)
+{
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+    UINT8 i;
+
+    for(i=0; i < p_cb->curr_total_no_of_pools; i++)
+    {
+        if(pool_id == p_cb->pool_list[i])
+            break;
+    }
+
+    while (i < (p_cb->curr_total_no_of_pools - 1))
+    {
+        p_cb->pool_list[i] = p_cb->pool_list[i+1];
+        i++;
+    }
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_igetpoolbuf
+**
+** Description      Called by an interrupt service routine to get a free buffer from
+**                  a specific buffer pool.
+**
+** Parameters       pool_id - (input) pool ID to get a buffer out of.
+**
+** Returns          A pointer to the buffer, or NULL if none available
+**
+*******************************************************************************/
+void *GKI_igetpoolbuf (UINT8 pool_id)
+{
+    FREE_QUEUE_T  *Q;
+    BUFFER_HDR_T  *p_hdr;
+
+    if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
+        return (NULL);
+
+
+    Q = &gki_cb.com.freeq[pool_id];
+    if(Q->cur_cnt < Q->total)
+    {
+        p_hdr = Q->p_first;
+        Q->p_first = p_hdr->p_next;
+
+        if (!Q->p_first)
+            Q->p_last = NULL;
+
+        if(++Q->cur_cnt > Q->max_cnt)
+            Q->max_cnt = Q->cur_cnt;
+
+        p_hdr->task_id = GKI_get_taskid();
+
+        p_hdr->status  = BUF_STATUS_UNLINKED;
+        p_hdr->p_next  = NULL;
+        p_hdr->Type    = 0;
+
+        return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
+    }
+
+    return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_poolcount
+**
+** Description      Called by an application to get the total number of buffers
+**                  in the specified buffer pool.
+**
+** Parameters       pool_id - (input) pool ID to get the free count of.
+**
+** Returns          the total number of buffers in the pool
+**
+*******************************************************************************/
+UINT16 GKI_poolcount (UINT8 pool_id)
+{
+    if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
+        return (0);
+
+    return (gki_cb.com.freeq[pool_id].total);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_poolfreecount
+**
+** Description      Called by an application to get the number of free buffers
+**                  in the specified buffer pool.
+**
+** Parameters       pool_id - (input) pool ID to get the free count of.
+**
+** Returns          the number of free buffers in the pool
+**
+*******************************************************************************/
+UINT16 GKI_poolfreecount (UINT8 pool_id)
+{
+    FREE_QUEUE_T  *Q;
+
+    if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
+        return (0);
+
+    Q  = &gki_cb.com.freeq[pool_id];
+
+    return ((UINT16)(Q->total - Q->cur_cnt));
+}
+
+/*******************************************************************************
+**
+** Function         GKI_change_buf_owner
+**
+** Description      Called to change the task ownership of a buffer.
+**
+** Parameters:      p_buf   - (input) pointer to the buffer
+**                  task_id - (input) task id to change ownership to
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_change_buf_owner (void *p_buf, UINT8 task_id)
+{
+    BUFFER_HDR_T    *p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
+
+    p_hdr->task_id = task_id;
+
+    return;
+}
+
+#if (defined(GKI_SEND_MSG_FROM_ISR) &&  GKI_SEND_MSG_FROM_ISR == TRUE)
+/*******************************************************************************
+**
+** Function         GKI_isend_msg
+**
+** Description      Called from interrupt context to send a buffer to a task
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void GKI_isend_msg (UINT8 task_id, UINT8 mbox, void *msg)
+{
+    BUFFER_HDR_T    *p_hdr;
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+
+    /* If task non-existant or not started, drop buffer */
+    if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX) || (p_cb->OSRdyTbl[task_id] == TASK_DEAD))
+    {
+        GKI_exception(GKI_ERROR_SEND_MSG_BAD_DEST, "Sending to unknown dest");
+        GKI_freebuf (msg);
+        return;
+    }
+
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
+    if (gki_chk_buf_damage(msg))
+    {
+        GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Send - Buffer corrupted");
+        return;
+    }
+#endif
+
+#if (GKI_ENABLE_OWNER_CHECK == TRUE)
+    if (gki_chk_buf_owner(msg))
+    {
+        GKI_exception(GKI_ERROR_NOT_BUF_OWNER, "Send by non-owner");
+        return;
+    }
+#endif
+
+    p_hdr = (BUFFER_HDR_T *) ((UINT8 *) msg - BUFFER_HDR_SIZE);
+
+    if (p_hdr->status != BUF_STATUS_UNLINKED)
+    {
+        GKI_exception(GKI_ERROR_SEND_MSG_BUF_LINKED, "Send - buffer linked");
+        return;
+    }
+
+    if (p_cb->OSTaskQFirst[task_id][mbox])
+        p_cb->OSTaskQLast[task_id][mbox]->p_next = p_hdr;
+    else
+        p_cb->OSTaskQFirst[task_id][mbox] = p_hdr;
+
+    p_cb->OSTaskQLast[task_id][mbox] = p_hdr;
+
+    p_hdr->p_next = NULL;
+    p_hdr->status = BUF_STATUS_QUEUED;
+    p_hdr->task_id = task_id;
+
+    GKI_isend_event(task_id, (UINT16)EVENT_MASK(mbox));
+
+    return;
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         GKI_create_pool
+**
+** Description      Called by applications to create a buffer pool.
+**
+** Parameters:      size        - (input) length (in bytes) of each buffer in the pool
+**                  count       - (input) number of buffers to allocate for the pool
+**                  permission  - (input) restricted or public access?
+**                                        (GKI_PUBLIC_POOL or GKI_RESTRICTED_POOL)
+**                  p_mem_pool  - (input) pointer to an OS memory pool, NULL if not provided
+**
+** Returns          the buffer pool ID, which should be used in calls to
+**                  GKI_getpoolbuf(). If a pool could not be created, this
+**                  function returns 0xff.
+**
+*******************************************************************************/
+UINT8 GKI_create_pool (UINT16 size, UINT16 count, UINT8 permission, void *p_mem_pool)
+{
+    UINT8        xx;
+    UINT32       mem_needed;
+    INT32        tempsize = size;
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+
+    /* First make sure the size of each pool has a valid size with room for the header info */
+    if (size > MAX_USER_BUF_SIZE)
+        return (GKI_INVALID_POOL);
+
+    /* First, look for an unused pool */
+    for (xx = 0; xx < GKI_NUM_TOTAL_BUF_POOLS; xx++)
+    {
+        if (!p_cb->pool_start[xx])
+            break;
+    }
+
+    if (xx == GKI_NUM_TOTAL_BUF_POOLS)
+        return (GKI_INVALID_POOL);
+
+    /* Ensure an even number of longwords */
+    tempsize = (INT32)ALIGN_POOL(size);
+
+    mem_needed = (tempsize + BUFFER_PADDING_SIZE) * count;
+
+    if (!p_mem_pool)
+        p_mem_pool = GKI_os_malloc(mem_needed);
+
+    if (p_mem_pool)
+    {
+        /* Initialize the new pool */
+        gki_init_free_queue (xx, size, count, p_mem_pool);
+        gki_add_to_pool_list(xx);
+        (void) GKI_set_pool_permission (xx, permission);
+        p_cb->curr_total_no_of_pools++;
+
+        return (xx);
+    }
+    else
+        return (GKI_INVALID_POOL);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_delete_pool
+**
+** Description      Called by applications to delete a buffer pool.  The function
+**                  calls the operating specific function to free the actual memory.
+**                  An exception is generated if an error is detected.
+**
+** Parameters:      pool_id - (input) Id of the poll being deleted.
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_delete_pool (UINT8 pool_id)
+{
+    FREE_QUEUE_T    *Q;
+    tGKI_COM_CB     *p_cb = &gki_cb.com;
+
+    if ((pool_id >= GKI_NUM_TOTAL_BUF_POOLS) || (!p_cb->pool_start[pool_id]))
+        return;
+
+    GKI_disable();
+    Q  = &p_cb->freeq[pool_id];
+
+    if (!Q->cur_cnt)
+    {
+        Q->size      = 0;
+        Q->total     = 0;
+        Q->cur_cnt   = 0;
+        Q->max_cnt   = 0;
+        Q->p_first   = NULL;
+        Q->p_last    = NULL;
+
+        GKI_os_free (p_cb->pool_start[pool_id]);
+
+        p_cb->pool_start[pool_id] = NULL;
+        p_cb->pool_end[pool_id]   = NULL;
+        p_cb->pool_size[pool_id]  = 0;
+
+        gki_remove_from_pool_list(pool_id);
+        p_cb->curr_total_no_of_pools--;
+    }
+    else
+        GKI_exception(GKI_ERROR_DELETE_POOL_BAD_QID, "Deleting bad pool");
+
+    GKI_enable();
+
+    return;
+}
+
+#endif /*  BTU_STACK_LITE_ENABLED == FALSE */
+
+/*******************************************************************************
+**
+** Function         GKI_get_pool_bufsize
+**
+** Description      Called by an application to get the size of buffers in a pool
+**
+** Parameters       Pool ID.
+**
+** Returns          the size of buffers in the pool
+**
+*******************************************************************************/
+UINT16 GKI_get_pool_bufsize (UINT8 pool_id)
+{
+    if (pool_id < GKI_NUM_TOTAL_BUF_POOLS)
+        return (gki_cb.com.freeq[pool_id].size);
+
+    return (0);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_poolutilization
+**
+** Description      Called by an application to get the buffer utilization
+**                  in the specified buffer pool.
+**
+** Parameters       pool_id - (input) pool ID to get the free count of.
+**
+** Returns          % of buffers used from 0 to 100
+**
+*******************************************************************************/
+UINT16 GKI_poolutilization (UINT8 pool_id)
+{
+    FREE_QUEUE_T  *Q;
+
+    if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
+        return (100);
+
+    Q  = &gki_cb.com.freeq[pool_id];
+
+    if (Q->total == 0)
+        return (100);
+
+    return ((Q->cur_cnt * 100) / Q->total);
+}
+
diff --git a/halimpl/bcm2079x/gki/common/gki_common.h b/halimpl/bcm2079x/gki/common/gki_common.h
new file mode 100644
index 0000000..2bd9f8f
--- /dev/null
+++ b/halimpl/bcm2079x/gki/common/gki_common.h
@@ -0,0 +1,393 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef GKI_COMMON_H
+#define GKI_COMMON_H
+
+#include "gki.h"
+#include "dyn_mem.h"
+
+#ifndef GKI_DEBUG
+#define GKI_DEBUG	FALSE
+#endif
+
+/* Task States: (For OSRdyTbl) */
+#define TASK_DEAD       0   /* b0000 */
+#define TASK_READY      1   /* b0001 */
+#define TASK_WAIT       2   /* b0010 */
+#define TASK_DELAY      4   /* b0100 */
+#define TASK_SUSPEND    8   /* b1000 */
+
+
+/********************************************************************
+**  Internal Error codes
+*********************************************************************/
+#define GKI_ERROR_BUF_CORRUPTED         0xFFFF
+#define GKI_ERROR_NOT_BUF_OWNER         0xFFFE
+#define GKI_ERROR_FREEBUF_BAD_QID       0xFFFD
+#define GKI_ERROR_FREEBUF_BUF_LINKED    0xFFFC
+#define GKI_ERROR_SEND_MSG_BAD_DEST     0xFFFB
+#define GKI_ERROR_SEND_MSG_BUF_LINKED   0xFFFA
+#define GKI_ERROR_ENQUEUE_BUF_LINKED    0xFFF9
+#define GKI_ERROR_DELETE_POOL_BAD_QID   0xFFF8
+#define GKI_ERROR_BUF_SIZE_TOOBIG       0xFFF7
+#define GKI_ERROR_BUF_SIZE_ZERO         0xFFF6
+#define GKI_ERROR_ADDR_NOT_IN_BUF       0xFFF5
+
+
+/********************************************************************
+**  Misc constants
+*********************************************************************/
+
+#define GKI_MAX_INT32           (0x7fffffffL)
+#define GKI_MAX_TIMESTAMP       (0xffffffffL)
+
+/********************************************************************
+**  Buffer Management Data Structures
+*********************************************************************/
+
+typedef struct _buffer_hdr
+{
+    struct _buffer_hdr *p_next;   /* next buffer in the queue */
+    UINT8   q_id;                 /* id of the queue */
+    UINT8   task_id;              /* task which allocated the buffer*/
+    UINT8   status;               /* FREE, UNLINKED or QUEUED */
+    UINT8   Type;
+
+#if GKI_BUFFER_DEBUG
+    /* for tracking who allocated the buffer */
+    #define _GKI_MAX_FUNCTION_NAME_LEN   (50)
+    char    _function[_GKI_MAX_FUNCTION_NAME_LEN+1];
+    int     _line;
+#endif
+
+} BUFFER_HDR_T;
+
+typedef struct _free_queue
+{
+    BUFFER_HDR_T *p_first;      /* first buffer in the queue */
+    BUFFER_HDR_T *p_last;       /* last buffer in the queue */
+    UINT16          size;          /* size of the buffers in the pool */
+    UINT16          total;         /* toatal number of buffers */
+    UINT16          cur_cnt;       /* number of  buffers currently allocated */
+    UINT16          max_cnt;       /* maximum number of buffers allocated at any time */
+} FREE_QUEUE_T;
+
+
+/* Buffer related defines
+*/
+#define ALIGN_POOL(pl_size)  ( (((pl_size) + 3) / sizeof(UINT32)) * sizeof(UINT32))
+#define BUFFER_HDR_SIZE     (sizeof(BUFFER_HDR_T))                  /* Offset past header */
+#define BUFFER_PADDING_SIZE (sizeof(BUFFER_HDR_T) + sizeof(UINT32)) /* Header + Magic Number */
+#define MAX_USER_BUF_SIZE   ((UINT16)0xffff - BUFFER_PADDING_SIZE)  /* pool size must allow for header */
+#define MAGIC_NO            0xDDBADDBA
+
+#define BUF_STATUS_FREE     0
+#define BUF_STATUS_UNLINKED 1
+#define BUF_STATUS_QUEUED   2
+
+#define GKI_USE_DEFERED_ALLOC_BUF_POOLS
+
+/* Exception related structures (Used in debug mode only)
+*/
+#if (GKI_DEBUG == TRUE)
+typedef struct
+{
+    UINT16  type;
+    UINT8   taskid;
+    UINT8   msg[GKI_MAX_EXCEPTION_MSGLEN];
+} EXCEPTION_T;
+#endif
+
+
+/* Put all GKI variables into one control block
+*/
+typedef struct
+{
+    /* Task management variables
+    */
+    /* The stack and stack size are not used on Windows
+    */
+#if (!defined GKI_USE_DEFERED_ALLOC_BUF_POOLS && (GKI_USE_DYNAMIC_BUFFERS == FALSE))
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 0)
+    UINT8 bufpool0[(ALIGN_POOL(GKI_BUF0_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF0_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 1)
+    UINT8 bufpool1[(ALIGN_POOL(GKI_BUF1_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF1_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 2)
+    UINT8 bufpool2[(ALIGN_POOL(GKI_BUF2_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF2_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 3)
+    UINT8 bufpool3[(ALIGN_POOL(GKI_BUF3_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF3_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 4)
+    UINT8 bufpool4[(ALIGN_POOL(GKI_BUF4_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF4_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 5)
+    UINT8 bufpool5[(ALIGN_POOL(GKI_BUF5_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF5_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 6)
+    UINT8 bufpool6[(ALIGN_POOL(GKI_BUF6_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF6_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 7)
+    UINT8 bufpool7[(ALIGN_POOL(GKI_BUF7_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF7_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 8)
+    UINT8 bufpool8[(ALIGN_POOL(GKI_BUF8_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF8_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 9)
+    UINT8 bufpool9[(ALIGN_POOL(GKI_BUF9_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF9_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 10)
+    UINT8 bufpool10[(ALIGN_POOL(GKI_BUF10_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF10_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 11)
+    UINT8 bufpool11[(ALIGN_POOL(GKI_BUF11_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF11_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 12)
+    UINT8 bufpool12[(ALIGN_POOL(GKI_BUF12_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF12_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 13)
+    UINT8 bufpool13[(ALIGN_POOL(GKI_BUF13_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF13_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 14)
+    UINT8 bufpool14[(ALIGN_POOL(GKI_BUF14_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF14_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 15)
+    UINT8 bufpool15[(ALIGN_POOL(GKI_BUF15_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF15_MAX];
+#endif
+
+#else
+/* Definitions for dynamic buffer use */
+#if (GKI_NUM_FIXED_BUF_POOLS > 0)
+    UINT8 *bufpool0;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 1)
+    UINT8 *bufpool1;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 2)
+    UINT8 *bufpool2;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 3)
+    UINT8 *bufpool3;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 4)
+    UINT8 *bufpool4;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 5)
+    UINT8 *bufpool5;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 6)
+    UINT8 *bufpool6;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 7)
+    UINT8 *bufpool7;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 8)
+    UINT8 *bufpool8;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 9)
+    UINT8 *bufpool9;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 10)
+    UINT8 *bufpool10;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 11)
+    UINT8 *bufpool11;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 12)
+    UINT8 *bufpool12;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 13)
+    UINT8 *bufpool13;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 14)
+    UINT8 *bufpool14;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 15)
+    UINT8 *bufpool15;
+#endif
+
+#endif
+
+    UINT8  *OSStack[GKI_MAX_TASKS];         /* pointer to beginning of stack */
+    UINT16  OSStackSize[GKI_MAX_TASKS];     /* stack size available to each task */
+
+
+    INT8   *OSTName[GKI_MAX_TASKS];         /* name of the task */
+
+    UINT8   OSRdyTbl[GKI_MAX_TASKS];        /* current state of the task */
+    UINT16  OSWaitEvt[GKI_MAX_TASKS];       /* events that have to be processed by the task */
+    UINT16  OSWaitForEvt[GKI_MAX_TASKS];    /* events the task is waiting for*/
+
+    UINT32  OSTicks;                        /* system ticks from start */
+    UINT32  OSIdleCnt;                      /* idle counter */
+    INT16   OSDisableNesting;               /* counter to keep track of interrupt disable nesting */
+    INT16   OSLockNesting;                  /* counter to keep track of sched lock nesting */
+    INT16   OSIntNesting;                   /* counter to keep track of interrupt nesting */
+
+    /* Timer related variables
+    */
+    INT32   OSTicksTilExp;      /* Number of ticks till next timer expires */
+#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
+    UINT32  OSTicksTilStop;     /* inactivity delay timer; OS Ticks till stopping system tick */
+#endif
+    INT32   OSNumOrigTicks;     /* Number of ticks between last timer expiration to the next one */
+
+    INT32   OSWaitTmr   [GKI_MAX_TASKS];  /* ticks the task has to wait, for specific events */
+
+    /* Only take up space timers used in the system (GKI_NUM_TIMERS defined in target.h) */
+#if (GKI_NUM_TIMERS > 0)
+    INT32   OSTaskTmr0  [GKI_MAX_TASKS];
+    INT32   OSTaskTmr0R [GKI_MAX_TASKS];
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+    INT32   OSTaskTmr1  [GKI_MAX_TASKS];
+    INT32   OSTaskTmr1R [GKI_MAX_TASKS];
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+    INT32   OSTaskTmr2  [GKI_MAX_TASKS];
+    INT32   OSTaskTmr2R [GKI_MAX_TASKS];
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+    INT32   OSTaskTmr3  [GKI_MAX_TASKS];
+    INT32   OSTaskTmr3R [GKI_MAX_TASKS];
+#endif
+
+
+
+    /* Buffer related variables
+    */
+    BUFFER_HDR_T    *OSTaskQFirst[GKI_MAX_TASKS][NUM_TASK_MBOX]; /* array of pointers to the first event in the task mailbox */
+    BUFFER_HDR_T    *OSTaskQLast [GKI_MAX_TASKS][NUM_TASK_MBOX]; /* array of pointers to the last event in the task mailbox */
+
+    /* Define the buffer pool management variables
+    */
+    FREE_QUEUE_T    freeq[GKI_NUM_TOTAL_BUF_POOLS];
+
+    UINT16   pool_buf_size[GKI_NUM_TOTAL_BUF_POOLS];
+    UINT16   pool_max_count[GKI_NUM_TOTAL_BUF_POOLS];
+    UINT16   pool_additions[GKI_NUM_TOTAL_BUF_POOLS];
+
+    /* Define the buffer pool start addresses
+    */
+    UINT8   *pool_start[GKI_NUM_TOTAL_BUF_POOLS];   /* array of pointers to the start of each buffer pool */
+    UINT8   *pool_end[GKI_NUM_TOTAL_BUF_POOLS];     /* array of pointers to the end of each buffer pool */
+    UINT16   pool_size[GKI_NUM_TOTAL_BUF_POOLS];    /* actual size of the buffers in a pool */
+
+    /* Define the buffer pool access control variables */
+    void        *p_user_mempool;                    /* User O/S memory pool */
+    UINT16      pool_access_mask;                   /* Bits are set if the corresponding buffer pool is a restricted pool */
+    UINT8       pool_list[GKI_NUM_TOTAL_BUF_POOLS]; /* buffer pools arranged in the order of size */
+    UINT8       curr_total_no_of_pools;             /* number of fixed buf pools + current number of dynamic pools */
+
+    BOOLEAN     timer_nesting;                      /* flag to prevent timer interrupt nesting */
+
+    /* Time queue arrays */
+    TIMER_LIST_Q *timer_queues[GKI_MAX_TIMER_QUEUES];
+    /* System tick callback */
+    SYSTEM_TICK_CBACK *p_tick_cb;
+    BOOLEAN     system_tick_running;                /* TRUE if system tick is running. Valid only if p_tick_cb is not NULL */
+
+#if (GKI_DEBUG == TRUE)
+    UINT16      ExceptionCnt;                       /* number of GKI exceptions that have happened */
+    EXCEPTION_T Exception[GKI_MAX_EXCEPTION];
+#endif
+
+} tGKI_COM_CB;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Internal GKI function prototypes
+*/
+GKI_API extern BOOLEAN   gki_chk_buf_damage(void *);
+extern BOOLEAN   gki_chk_buf_owner(void *);
+extern void      gki_buffer_init (void);
+extern void      gki_timers_init(void);
+extern void      gki_adjust_timer_count (INT32);
+
+extern void    OSStartRdy(void);
+extern void	   OSCtxSw(void);
+extern void	   OSIntCtxSw(void);
+extern void    OSSched(void);
+extern void    OSIntEnter(void);
+extern void    OSIntExit(void);
+
+
+/* Debug aids
+*/
+typedef void  (*FP_PRINT)(char *, ...);
+
+#if (GKI_DEBUG == TRUE)
+
+typedef void  (*PKT_PRINT)(UINT8 *, UINT16);
+
+extern void gki_print_task(FP_PRINT);
+extern void gki_print_exception(FP_PRINT);
+extern void gki_print_timer(FP_PRINT);
+extern void gki_print_stack(FP_PRINT);
+extern void gki_print_buffer(FP_PRINT);
+extern void gki_print_buffer_statistics(FP_PRINT, INT16);
+GKI_API extern void gki_print_used_bufs (FP_PRINT, UINT8);
+extern void gki_dump(UINT8 *, UINT16, FP_PRINT);
+extern void gki_dump2(UINT16 *, UINT16, FP_PRINT);
+extern void gki_dump4(UINT32 *, UINT16, FP_PRINT);
+
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/halimpl/bcm2079x/gki/common/gki_debug.c b/halimpl/bcm2079x/gki/common/gki_debug.c
new file mode 100644
index 0000000..481ba16
--- /dev/null
+++ b/halimpl/bcm2079x/gki/common/gki_debug.c
@@ -0,0 +1,353 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "gki_int.h"
+
+#if (GKI_DEBUG == TRUE)
+
+const INT8 * const OSTaskStates[] =
+{
+    (INT8 *)"DEAD",  /* 0 */
+    (INT8 *)"REDY",  /* 1 */
+    (INT8 *)"WAIT",  /* 2 */
+    (INT8 *)"",
+    (INT8 *)"DELY",  /* 4 */
+    (INT8 *)"",
+    (INT8 *)"",
+    (INT8 *)"",
+    (INT8 *)"SUSP",  /* 8 */
+};
+
+
+/*******************************************************************************
+**
+** Function         GKI_PrintBufferUsage
+**
+** Description      Displays Current Buffer Pool summary
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_PrintBufferUsage(UINT8 *p_num_pools, UINT16 *p_cur_used)
+{
+    int i;
+    FREE_QUEUE_T    *p;
+    UINT8   num = gki_cb.com.curr_total_no_of_pools;
+    UINT16   cur[GKI_NUM_TOTAL_BUF_POOLS];
+
+    GKI_TRACE_0("");
+    GKI_TRACE_0("--- GKI Buffer Pool Summary (R - restricted, P - public) ---");
+
+    GKI_TRACE_0("POOL     SIZE  USED  MAXU  TOTAL");
+    GKI_TRACE_0("------------------------------");
+    for (i = 0; i < gki_cb.com.curr_total_no_of_pools; i++)
+    {
+        p = &gki_cb.com.freeq[i];
+        if ((1 << i) & gki_cb.com.pool_access_mask)
+        {
+            GKI_TRACE_5("%02d: (R), %4d, %3d, %3d, %3d",
+                        i, p->size, p->cur_cnt, p->max_cnt, p->total);
+        }
+        else
+        {
+            GKI_TRACE_5("%02d: (P), %4d, %3d, %3d, %3d",
+                        i, p->size, p->cur_cnt, p->max_cnt, p->total);
+        }
+        cur[i] = p->cur_cnt;
+    }
+    if (p_num_pools)
+        *p_num_pools = num;
+    if (p_cur_used)
+        memcpy(p_cur_used, cur, num*2);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_PrintBuffer
+**
+** Description      Called internally by OSS to print the buffer pools
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_PrintBuffer(void)
+{
+    UINT16 i;
+    for(i=0; i<GKI_NUM_TOTAL_BUF_POOLS; i++)
+    {
+        GKI_TRACE_5("pool:%4u free %4u cur %3u max %3u  total%3u", i, gki_cb.com.freeq[i].size,
+                    gki_cb.com.freeq[i].cur_cnt, gki_cb.com.freeq[i].max_cnt, gki_cb.com.freeq[i].total);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         gki_calc_stack
+**
+** Description      This function tries to calculate the amount of
+**                  stack used by looking non magic num. Magic num is consider
+**                  the first byte in the stack.
+**
+** Returns          the number of unused byte on the stack. 4 in case of stack overrun
+**
+*******************************************************************************/
+UINT16 gki_calc_stack (UINT8 task)
+{
+    int    j, stacksize;
+    UINT32 MagicNum;
+    UINT32 *p;
+
+    stacksize = (int) gki_cb.com.OSStackSize[task];
+    p = (UINT32 *)gki_cb.com.OSStack[task]; /* assume stack is aligned, */
+    MagicNum = *p;
+
+    for(j = 0; j < stacksize; j++)
+    {
+        if(*p++ != MagicNum) break;
+    }
+
+    return (j * sizeof(UINT32));
+}
+
+/*******************************************************************************
+**
+** Function         GKI_print_task
+**
+** Description      Print task stack usage.
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_print_task(void)
+{
+#ifdef _BT_WIN32
+	GKI_TRACE_0("Service not available under insight");
+#else
+    UINT8 TaskId;
+
+    GKI_TRACE_0("TID TASKNAME STATE FREE_STACK  STACK");
+    for(TaskId=0; TaskId < GKI_MAX_TASKS; TaskId++)
+    {
+        if (gki_cb.com.OSRdyTbl[TaskId] != TASK_DEAD)
+        {
+            GKI_TRACE_5("%2u   %-8s %-5s  0x%04X     0x%04X Bytes",
+                (UINT16)TaskId,  gki_cb.com.OSTName[TaskId],
+                OSTaskStates[gki_cb.com.OSRdyTbl[TaskId]],
+                gki_calc_stack(TaskId), gki_cb.com.OSStackSize[TaskId]);
+
+        }
+    }
+#endif
+}
+
+
+/*******************************************************************************
+**
+** Function         gki_print_buffer_statistics
+**
+** Description      Called internally by OSS to print the buffer pools statistics
+**
+** Returns          void
+**
+*******************************************************************************/
+void gki_print_buffer_statistics(FP_PRINT print, INT16 pool)
+{
+    UINT16           i;
+    BUFFER_HDR_T    *hdr;
+    UINT16           size,act_size,maxbuffs;
+    UINT32           *magic;
+
+    if (pool > GKI_NUM_TOTAL_BUF_POOLS || pool < 0)
+    {
+        print("Not a valid Buffer pool\n");
+        return;
+    }
+
+    size = gki_cb.com.freeq[pool].size;
+    maxbuffs = gki_cb.com.freeq[pool].total;
+    act_size = size + BUFFER_PADDING_SIZE;
+    print("Buffer Pool[%u] size=%u cur_cnt=%u max_cnt=%u  total=%u\n",
+        pool, gki_cb.com.freeq[pool].size,
+        gki_cb.com.freeq[pool].cur_cnt, gki_cb.com.freeq[pool].max_cnt, gki_cb.com.freeq[pool].total);
+
+    print("      Owner  State    Sanity\n");
+    print("----------------------------\n");
+    hdr = (BUFFER_HDR_T *)(gki_cb.com.pool_start[pool]);
+    for(i=0; i<maxbuffs; i++)
+    {
+        magic = (UINT32 *)((UINT8 *)hdr + BUFFER_HDR_SIZE + size);
+        print("%3d: 0x%02x %4d %10s\n", i, hdr->task_id, hdr->status, (*magic == MAGIC_NO)?"OK":"CORRUPTED");
+        hdr          = (BUFFER_HDR_T *)((UINT8 *)hdr + act_size);
+    }
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         gki_print_used_bufs
+**
+** Description      Dumps used buffers in the particular pool
+**
+*******************************************************************************/
+GKI_API void gki_print_used_bufs (FP_PRINT print, UINT8 pool_id)
+{
+    UINT8        *p_start;
+    UINT16       buf_size;
+    UINT16       num_bufs;
+    BUFFER_HDR_T *p_hdr;
+    UINT16       i;
+    UINT32         *magic;
+    UINT16       *p;
+
+
+    if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS && gki_cb.com.pool_start[pool_id] != 0)
+    {
+        print("Not a valid Buffer pool\n");
+        return;
+    }
+
+    p_start = gki_cb.com.pool_start[pool_id];
+    buf_size = gki_cb.com.freeq[pool_id].size + BUFFER_PADDING_SIZE;
+    num_bufs = gki_cb.com.freeq[pool_id].total;
+
+    for (i = 0; i < num_bufs; i++, p_start += buf_size)
+    {
+        p_hdr = (BUFFER_HDR_T *)p_start;
+        magic = (UINT32 *)((UINT8 *)p_hdr + buf_size - sizeof(UINT32));
+        p     = (UINT16 *) p_hdr;
+
+        if (p_hdr->status != BUF_STATUS_FREE)
+        {
+            print ("%d:0x%x (Q:%d,Task:%s,Stat:%d,%s) %04x %04x %04x %04x %04x %04x %04x %04x\n",
+                i, p_hdr,
+                p_hdr->q_id,
+                GKI_map_taskname(p_hdr->task_id),
+                p_hdr->status,
+                (*magic == MAGIC_NO)? "OK" : "CORRUPTED",
+                p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+        }
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         gki_print_task
+**
+** Description      This function prints the task states.
+**
+** Returns          void
+**
+*******************************************************************************/
+void gki_print_task (FP_PRINT print)
+{
+    UINT8 i;
+
+    print("TID VID TASKNAME STATE WAIT WAITFOR TIMEOUT STACK\n");
+    print("-------------------------------------------------\n");
+    for(i=0; i<GKI_MAX_TASKS; i++)
+    {
+        if (gki_cb.com.OSRdyTbl[i] != TASK_DEAD)
+        {
+            print("%2u  %-8s %-5s %04X    %04X %7u %u/%u Bytes\n",
+                (UINT16)i,  gki_cb.com.OSTName[i],
+                OSTaskStates[gki_cb.com.OSRdyTbl[i]],
+                gki_cb.com.OSWaitEvt[i], gki_cb.com.OSWaitForEvt[i],
+                gki_cb.com.OSWaitTmr[i], gki_calc_stack(i), gki_cb.com.OSStackSize[i]);
+        }
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         gki_print_exception
+**
+** Description      This function prints the exception information.
+**
+** Returns          void
+**
+*******************************************************************************/
+void gki_print_exception(FP_PRINT print)
+{
+    UINT16 i;
+    EXCEPTION_T *pExp;
+
+    print ("GKI Exceptions:\n");
+    for (i = 0; i < gki_cb.com.ExceptionCnt; i++)
+    {
+        pExp =     &gki_cb.com.Exception[i];
+        print("%d: Type=%d, Task=%d: %s\n", i,
+            (INT32)pExp->type, (INT32)pExp->taskid, (INT8 *)pExp->msg);
+    }
+}
+
+
+/*****************************************************************************/
+void gki_dump (UINT8 *s, UINT16 len, FP_PRINT print)
+{
+    UINT16 i, j;
+
+    for(i=0, j=0; i<len; i++)
+    {
+        if(j == 0)
+            print("\n%lX: %02X, ", &s[i], s[i]);
+        else if(j == 7)
+            print("%02X,  ", s[i]);
+        else
+            print("%02X, ", s[i]);
+        if(++j == 16)
+            j=0;
+    }
+    print("\n");
+}
+
+void gki_dump2 (UINT16 *s, UINT16 len, FP_PRINT print)
+{
+    UINT16 i, j;
+
+    for(i=0, j=0; i<len; i++)
+    {
+        if(j == 0)
+            print("\n%lX: %04X, ", &s[i], s[i]);
+        else
+            print("%04X, ", s[i]);
+        if(++j == 8)
+            j=0;
+    }
+    print("\n");
+}
+
+void gki_dump4 (UINT32 *s, UINT16 len, FP_PRINT print)
+{
+    UINT16 i, j;
+
+    for(i=0, j=0; i<len; i++)
+    {
+        if(j == 0)
+            print("\n%lX: %08lX, ", &s[i], s[i]);
+        else
+            print("%08lX, ", s[i]);
+        if(++j == 4)
+            j=0;
+    }
+    print("\n");
+}
+
+
+#endif
diff --git a/halimpl/bcm2079x/gki/common/gki_inet.h b/halimpl/bcm2079x/gki/common/gki_inet.h
new file mode 100644
index 0000000..569c4fd
--- /dev/null
+++ b/halimpl/bcm2079x/gki/common/gki_inet.h
@@ -0,0 +1,47 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef GKI_INET_H
+#define GKI_INET_H
+
+#include "data_types.h"
+
+#define htons   ntohs
+#define htonl   ntohl
+
+#define htonets	nettohs
+#define htonetl	nettohl
+
+#if BIG_ENDIAN == TRUE
+#define ntohs(n) (n)
+#define ntohl(n) (n)
+#define ntoh6(n) (n)
+
+#define nettohs(n) (n)
+#define nettohl(n) (n)
+#else
+extern UINT16 ntohs(UINT16 n);
+extern UINT32 ntohl(UINT32 n);
+extern UINT8 *ntoh6(UINT8 *p);
+
+#define nettohs(n) ((UINT16)((((n) << 8) & 0xff00) | (((n) >> 8) & 0x00ff)))
+#define nettohl(n) ((((n) & 0x000000ff) << 24) | (((n) << 8) & 0x00ff0000) | \
+                   (((n) >> 8) & 0x0000ff00) | (((n) >> 24) & 0x000000ff))
+#endif
+
+#endif /* GKI_INET_H */
+
diff --git a/halimpl/bcm2079x/gki/common/gki_time.c b/halimpl/bcm2079x/gki/common/gki_time.c
new file mode 100644
index 0000000..e840a36
--- /dev/null
+++ b/halimpl/bcm2079x/gki/common/gki_time.c
@@ -0,0 +1,1017 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "gki_int.h"
+
+#ifndef BT_ERROR_TRACE_0
+#define BT_ERROR_TRACE_0(l,m)
+#endif
+
+/* Make sure that this has been defined in target.h */
+#ifndef GKI_NUM_TIMERS
+#error  NO TIMERS: Must define at least 1 timer in the system!
+#endif
+
+
+#define GKI_NO_NEW_TMRS_STARTED (0x7fffffffL)   /* Largest signed positive timer count */
+#define GKI_UNUSED_LIST_ENTRY   (0x80000000L)   /* Marks an unused timer list entry (initial value) */
+#define GKI_MAX_INT32           (0x7fffffffL)
+
+/*******************************************************************************
+**
+** Function         gki_timers_init
+**
+** Description      This internal function is called once at startup to initialize
+**                  all the timer structures.
+**
+** Returns          void
+**
+*******************************************************************************/
+void gki_timers_init(void)
+{
+    UINT8   tt;
+
+    gki_cb.com.OSTicksTilExp = 0;       /* Remaining time (of OSTimeCurTimeout) before next timer expires */
+    gki_cb.com.OSNumOrigTicks = 0;
+#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
+    gki_cb.com.OSTicksTilStop = 0;      /* clear inactivity delay timer */
+#endif
+
+    for (tt = 0; tt < GKI_MAX_TASKS; tt++)
+    {
+        gki_cb.com.OSWaitTmr   [tt] = 0;
+
+#if (GKI_NUM_TIMERS > 0)
+        gki_cb.com.OSTaskTmr0  [tt] = 0;
+        gki_cb.com.OSTaskTmr0R [tt] = 0;
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+        gki_cb.com.OSTaskTmr1  [tt] = 0;
+        gki_cb.com.OSTaskTmr1R [tt] = 0;
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+        gki_cb.com.OSTaskTmr2  [tt] = 0;
+        gki_cb.com.OSTaskTmr2R [tt] = 0;
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+        gki_cb.com.OSTaskTmr3  [tt] = 0;
+        gki_cb.com.OSTaskTmr3R [tt] = 0;
+#endif
+    }
+
+    for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
+    {
+        gki_cb.com.timer_queues[tt] = NULL;
+    }
+
+    gki_cb.com.p_tick_cb = NULL;
+    gki_cb.com.system_tick_running = FALSE;
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         gki_timers_is_timer_running
+**
+** Description      This internal function is called to test if any gki timer are running
+**
+**
+** Returns          TRUE if at least one time is running in the system, FALSE else.
+**
+*******************************************************************************/
+BOOLEAN gki_timers_is_timer_running(void)
+{
+    UINT8   tt;
+    for (tt = 0; tt < GKI_MAX_TASKS; tt++)
+    {
+
+#if (GKI_NUM_TIMERS > 0)
+        if(gki_cb.com.OSTaskTmr0  [tt])
+        {
+            return TRUE;
+        }
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+        if(gki_cb.com.OSTaskTmr1  [tt] )
+        {
+            return TRUE;
+        }
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+        if(gki_cb.com.OSTaskTmr2  [tt] )
+        {
+            return TRUE;
+        }
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+        if(gki_cb.com.OSTaskTmr3  [tt] )
+        {
+            return TRUE;
+        }
+#endif
+    }
+
+    return FALSE;
+
+}
+
+/*******************************************************************************
+**
+** Function         GKI_get_tick_count
+**
+** Description      This function returns the current system ticks
+**
+** Returns          The current number of system ticks
+**
+*******************************************************************************/
+UINT32  GKI_get_tick_count(void)
+{
+    return gki_cb.com.OSTicks;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_ready_to_sleep
+**
+** Description      This function returns the number of system ticks until the
+**                  next timer will expire.  It is typically called by a power
+**                  savings manager to find out how long it can have the system
+**                  sleep before it needs to service the next entry.
+**
+** Parameters:      None
+**
+** Returns          Number of ticks til the next timer expires
+**                  Note: the value is a signed  value.  This value should be
+**                      compared to x > 0, to avoid misinterpreting negative tick
+**                      values.
+**
+*******************************************************************************/
+INT32    GKI_ready_to_sleep (void)
+{
+    return (gki_cb.com.OSTicksTilExp);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_start_timer
+**
+** Description      An application can call this function to start one of
+**                  it's four general purpose timers. Any of the four timers
+**                  can be 1-shot or continuous. If a timer is already running,
+**                  it will be reset to the new parameters.
+**
+** Parameters       tnum            - (input) timer number to be started (TIMER_0,
+**                                              TIMER_1, TIMER_2, or TIMER_3)
+**                  ticks           - (input) the number of system ticks til the
+**                                              timer expires.
+**                  is_continuous   - (input) TRUE if timer restarts automatically,
+**                                              else FALSE if it is a 'one-shot'.
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_start_timer (UINT8 tnum, INT32 ticks, BOOLEAN is_continuous)
+{
+    INT32   reload;
+    INT32   orig_ticks;
+    UINT8   task_id = GKI_get_taskid();
+    BOOLEAN bad_timer = FALSE;
+
+    if (ticks <= 0)
+        ticks = 1;
+
+    orig_ticks = ticks;     /* save the ticks in case adjustment is necessary */
+
+
+    /* If continuous timer, set reload, else set it to 0 */
+    if (is_continuous)
+        reload = ticks;
+    else
+        reload = 0;
+
+    GKI_disable();
+
+    if(gki_timers_is_timer_running() == FALSE)
+    {
+#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
+        /* if inactivity delay timer is not running, start system tick */
+        if(gki_cb.com.OSTicksTilStop == 0)
+        {
+#endif
+            if(gki_cb.com.p_tick_cb)
+            {
+                /* start system tick */
+                gki_cb.com.system_tick_running = TRUE;
+                (gki_cb.com.p_tick_cb) (TRUE);
+            }
+#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
+        }
+        else
+        {
+            /* clear inactivity delay timer */
+            gki_cb.com.OSTicksTilStop = 0;
+        }
+#endif
+    }
+    /* Add the time since the last task timer update.
+    ** Note that this works when no timers are active since
+    ** both OSNumOrigTicks and OSTicksTilExp are 0.
+    */
+    if (GKI_MAX_INT32 - (gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp) > ticks)
+    {
+        ticks += gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp;
+    }
+    else
+        ticks = GKI_MAX_INT32;
+
+    switch (tnum)
+    {
+#if (GKI_NUM_TIMERS > 0)
+        case TIMER_0:
+            gki_cb.com.OSTaskTmr0R[task_id] = reload;
+            gki_cb.com.OSTaskTmr0 [task_id] = ticks;
+            break;
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+        case TIMER_1:
+            gki_cb.com.OSTaskTmr1R[task_id] = reload;
+            gki_cb.com.OSTaskTmr1 [task_id] = ticks;
+            break;
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+        case TIMER_2:
+            gki_cb.com.OSTaskTmr2R[task_id] = reload;
+            gki_cb.com.OSTaskTmr2 [task_id] = ticks;
+            break;
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+        case TIMER_3:
+            gki_cb.com.OSTaskTmr3R[task_id] = reload;
+            gki_cb.com.OSTaskTmr3 [task_id] = ticks;
+            break;
+#endif
+        default:
+            bad_timer = TRUE;       /* Timer number is bad, so do not use */
+    }
+
+    /* Update the expiration timeout if a legitimate timer */
+    if (!bad_timer)
+    {
+        /* Only update the timeout value if it is less than any other newly started timers */
+        gki_adjust_timer_count (orig_ticks);
+    }
+
+    GKI_enable();
+
+}
+
+/*******************************************************************************
+**
+** Function         GKI_stop_timer
+**
+** Description      An application can call this function to stop one of
+**                  it's four general purpose timers. There is no harm in
+**                  stopping a timer that is already stopped.
+**
+** Parameters       tnum            - (input) timer number to be started (TIMER_0,
+**                                              TIMER_1, TIMER_2, or TIMER_3)
+** Returns          void
+**
+*******************************************************************************/
+void GKI_stop_timer (UINT8 tnum)
+{
+    UINT8  task_id = GKI_get_taskid();
+
+    GKI_disable();
+
+    switch (tnum)
+    {
+#if (GKI_NUM_TIMERS > 0)
+        case TIMER_0:
+            gki_cb.com.OSTaskTmr0R[task_id] = 0;
+            gki_cb.com.OSTaskTmr0 [task_id] = 0;
+            break;
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+        case TIMER_1:
+            gki_cb.com.OSTaskTmr1R[task_id] = 0;
+            gki_cb.com.OSTaskTmr1 [task_id] = 0;
+            break;
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+        case TIMER_2:
+            gki_cb.com.OSTaskTmr2R[task_id] = 0;
+            gki_cb.com.OSTaskTmr2 [task_id] = 0;
+            break;
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+        case TIMER_3:
+            gki_cb.com.OSTaskTmr3R[task_id] = 0;
+            gki_cb.com.OSTaskTmr3 [task_id] = 0;
+            break;
+#endif
+    }
+
+    if (gki_timers_is_timer_running() == FALSE)
+    {
+        if (gki_cb.com.p_tick_cb)
+        {
+#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
+            /* if inactivity delay timer is not running */
+            if ((gki_cb.com.system_tick_running)&&(gki_cb.com.OSTicksTilStop == 0))
+            {
+                /* set inactivity delay timer */
+                /* when timer expires, system tick will be stopped */
+                gki_cb.com.OSTicksTilStop = GKI_DELAY_STOP_SYS_TICK;
+            }
+#else
+            gki_cb.com.system_tick_running = FALSE;
+            gki_cb.com.p_tick_cb(FALSE); /* stop system tick */
+#endif
+        }
+    }
+
+    GKI_enable();
+
+
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_timer_update
+**
+** Description      This function is called by an OS to drive the GKI's timers.
+**                  It is typically called at every system tick to
+**                  update the timers for all tasks, and check for timeouts.
+**
+**                  Note: It has been designed to also allow for variable tick updates
+**                      so that systems with strict power savings requirements can
+**                      have the update occur at variable intervals.
+**
+** Parameters:      ticks_since_last_update - (input) This is the number of TICKS that have
+**                          occurred since the last time GKI_timer_update was called.
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_timer_update (INT32 ticks_since_last_update)
+{
+    UINT8   task_id;
+    long    next_expiration;        /* Holds the next soonest expiration time after this update */
+
+    /* Increment the number of ticks used for time stamps */
+    gki_cb.com.OSTicks += ticks_since_last_update;
+
+    /* If any timers are running in any tasks, decrement the remaining time til
+     * the timer updates need to take place (next expiration occurs)
+     */
+    gki_cb.com.OSTicksTilExp -= ticks_since_last_update;
+
+    /* Don't allow timer interrupt nesting */
+    if (gki_cb.com.timer_nesting)
+        return;
+
+    gki_cb.com.timer_nesting = 1;
+
+#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
+    /* if inactivity delay timer is set and expired */
+    if (gki_cb.com.OSTicksTilStop)
+    {
+        if( gki_cb.com.OSTicksTilStop <= (UINT32)ticks_since_last_update )
+        {
+            if(gki_cb.com.p_tick_cb)
+            {
+                gki_cb.com.system_tick_running = FALSE;
+                (gki_cb.com.p_tick_cb) (FALSE); /* stop system tick */
+            }
+            gki_cb.com.OSTicksTilStop = 0;      /* clear inactivity delay timer */
+            gki_cb.com.timer_nesting = 0;
+            return;
+        }
+        else
+            gki_cb.com.OSTicksTilStop -= ticks_since_last_update;
+    }
+#endif
+
+    /* No need to update the ticks if no timeout has occurred */
+    if (gki_cb.com.OSTicksTilExp > 0)
+    {
+        gki_cb.com.timer_nesting = 0;
+        return;
+    }
+
+    GKI_disable();
+
+    next_expiration = GKI_NO_NEW_TMRS_STARTED;
+
+    /* If here then gki_cb.com.OSTicksTilExp <= 0. If negative, then increase gki_cb.com.OSNumOrigTicks
+       to account for the difference so timer updates below are decremented by the full number
+       of ticks. gki_cb.com.OSNumOrigTicks is reset at the bottom of this function so changing this
+       value only affects the timer updates below
+     */
+    gki_cb.com.OSNumOrigTicks -= gki_cb.com.OSTicksTilExp;
+
+    /* Check for OS Task Timers */
+    for (task_id = 0; task_id < GKI_MAX_TASKS; task_id++)
+    {
+        if (gki_cb.com.OSRdyTbl[task_id] == TASK_DEAD)
+        {
+            // task is shutdown do not try to service timers
+            continue;
+        }
+
+        if (gki_cb.com.OSWaitTmr[task_id] > 0) /* If timer is running */
+        {
+            gki_cb.com.OSWaitTmr[task_id] -= gki_cb.com.OSNumOrigTicks;
+            if (gki_cb.com.OSWaitTmr[task_id] <= 0)
+            {
+                /* Timer Expired */
+                gki_cb.com.OSRdyTbl[task_id] = TASK_READY;
+            }
+        }
+
+#if (GKI_NUM_TIMERS > 0)
+         /* If any timer is running, decrement */
+        if (gki_cb.com.OSTaskTmr0[task_id] > 0)
+        {
+            gki_cb.com.OSTaskTmr0[task_id] -= gki_cb.com.OSNumOrigTicks;
+
+            if (gki_cb.com.OSTaskTmr0[task_id] <= 0)
+            {
+                /* Set Timer 0 Expired event mask and reload timer */
+#if (defined(GKI_TIMER_UPDATES_FROM_ISR) &&  GKI_TIMER_UPDATES_FROM_ISR == TRUE)
+                GKI_isend_event (task_id, TIMER_0_EVT_MASK);
+#else
+                GKI_send_event (task_id, TIMER_0_EVT_MASK);
+#endif
+                gki_cb.com.OSTaskTmr0[task_id] = gki_cb.com.OSTaskTmr0R[task_id];
+            }
+        }
+
+        /* Check to see if this timer is the next one to expire */
+        if (gki_cb.com.OSTaskTmr0[task_id] > 0 && gki_cb.com.OSTaskTmr0[task_id] < next_expiration)
+            next_expiration = gki_cb.com.OSTaskTmr0[task_id];
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+         /* If any timer is running, decrement */
+        if (gki_cb.com.OSTaskTmr1[task_id] > 0)
+        {
+            gki_cb.com.OSTaskTmr1[task_id] -= gki_cb.com.OSNumOrigTicks;
+
+            if (gki_cb.com.OSTaskTmr1[task_id] <= 0)
+            {
+                /* Set Timer 1 Expired event mask and reload timer */
+#if (defined(GKI_TIMER_UPDATES_FROM_ISR) &&  GKI_TIMER_UPDATES_FROM_ISR == TRUE)
+                GKI_isend_event (task_id, TIMER_1_EVT_MASK);
+#else
+                GKI_send_event (task_id, TIMER_1_EVT_MASK);
+#endif
+                gki_cb.com.OSTaskTmr1[task_id] = gki_cb.com.OSTaskTmr1R[task_id];
+            }
+        }
+
+        /* Check to see if this timer is the next one to expire */
+        if (gki_cb.com.OSTaskTmr1[task_id] > 0 && gki_cb.com.OSTaskTmr1[task_id] < next_expiration)
+            next_expiration = gki_cb.com.OSTaskTmr1[task_id];
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+         /* If any timer is running, decrement */
+        if (gki_cb.com.OSTaskTmr2[task_id] > 0)
+        {
+            gki_cb.com.OSTaskTmr2[task_id] -= gki_cb.com.OSNumOrigTicks;
+
+            if (gki_cb.com.OSTaskTmr2[task_id] <= 0)
+            {
+                /* Set Timer 2 Expired event mask and reload timer */
+#if (defined(GKI_TIMER_UPDATES_FROM_ISR) &&  GKI_TIMER_UPDATES_FROM_ISR == TRUE)
+                GKI_isend_event (task_id, TIMER_2_EVT_MASK);
+#else
+                GKI_send_event (task_id, TIMER_2_EVT_MASK);
+#endif
+                gki_cb.com.OSTaskTmr2[task_id] = gki_cb.com.OSTaskTmr2R[task_id];
+            }
+        }
+
+        /* Check to see if this timer is the next one to expire */
+        if (gki_cb.com.OSTaskTmr2[task_id] > 0 && gki_cb.com.OSTaskTmr2[task_id] < next_expiration)
+            next_expiration = gki_cb.com.OSTaskTmr2[task_id];
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+         /* If any timer is running, decrement */
+        if (gki_cb.com.OSTaskTmr3[task_id] > 0)
+        {
+            gki_cb.com.OSTaskTmr3[task_id] -= gki_cb.com.OSNumOrigTicks;
+
+            if (gki_cb.com.OSTaskTmr3[task_id] <= 0)
+            {
+                /* Set Timer 3 Expired event mask and reload timer */
+#if (defined(GKI_TIMER_UPDATES_FROM_ISR) &&  GKI_TIMER_UPDATES_FROM_ISR == TRUE)
+                GKI_isend_event (task_id, TIMER_3_EVT_MASK);
+#else
+                GKI_send_event (task_id, TIMER_3_EVT_MASK);
+#endif
+                gki_cb.com.OSTaskTmr3[task_id] = gki_cb.com.OSTaskTmr3R[task_id];
+            }
+        }
+
+        /* Check to see if this timer is the next one to expire */
+        if (gki_cb.com.OSTaskTmr3[task_id] > 0 && gki_cb.com.OSTaskTmr3[task_id] < next_expiration)
+            next_expiration = gki_cb.com.OSTaskTmr3[task_id];
+#endif
+
+    }
+
+    /* Set the next timer experation value if there is one to start */
+    if (next_expiration < GKI_NO_NEW_TMRS_STARTED)
+    {
+        gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = next_expiration;
+    }
+    else
+    {
+        gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = 0;
+    }
+
+    gki_cb.com.timer_nesting = 0;
+
+    GKI_enable();
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_timer_queue_empty
+**
+** Description      This function is called by applications to see whether the timer
+**                  queue is empty
+**
+** Parameters
+**
+** Returns          BOOLEAN
+**
+*******************************************************************************/
+BOOLEAN GKI_timer_queue_empty (void)
+{
+    UINT8 tt;
+
+    for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
+    {
+        if (gki_cb.com.timer_queues[tt])
+            return FALSE;
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_timer_queue_register_callback
+**
+** Description      This function is called by applications to register system tick
+**                  start/stop callback for time queues
+**
+**
+** Parameters       p_callback - (input) pointer to the system tick callback
+**
+** Returns          BOOLEAN
+**
+*******************************************************************************/
+void GKI_timer_queue_register_callback (SYSTEM_TICK_CBACK *p_callback)
+{
+    gki_cb.com.p_tick_cb = p_callback;
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_init_timer_list
+**
+** Description      This function is called by applications when they
+**                  want to initialize a timer list.
+**
+** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_init_timer_list (TIMER_LIST_Q *p_timer_listq)
+{
+    p_timer_listq->p_first    = NULL;
+    p_timer_listq->p_last     = NULL;
+    p_timer_listq->last_ticks = 0;
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_init_timer_list_entry
+**
+** Description      This function is called by the applications when they
+**                  want to initialize a timer list entry. This must be
+**                  done prior to first use of the entry.
+**
+** Parameters       p_tle           - (input) pointer to a timer list queue entry
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_init_timer_list_entry (TIMER_LIST_ENT  *p_tle)
+{
+    p_tle->p_next  = NULL;
+    p_tle->p_prev  = NULL;
+    p_tle->ticks   = GKI_UNUSED_LIST_ENTRY;
+    p_tle->in_use  = FALSE;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_update_timer_list
+**
+** Description      This function is called by the applications when they
+**                  want to update a timer list. This should be at every
+**                  timer list unit tick, e.g. once per sec, once per minute etc.
+**
+** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
+**                  num_units_since_last_update - (input) number of units since the last update
+**                                  (allows for variable unit update)
+**
+**      NOTE: The following timer list update routines should not be used for exact time
+**            critical purposes.  The timer tasks should be used when exact timing is needed.
+**
+** Returns          the number of timers that have expired
+**
+*******************************************************************************/
+UINT16 GKI_update_timer_list (TIMER_LIST_Q *p_timer_listq, INT32 num_units_since_last_update)
+{
+    TIMER_LIST_ENT  *p_tle;
+    UINT16           num_time_out = 0;
+    INT32            rem_ticks;
+    INT32            temp_ticks;
+
+    p_tle = p_timer_listq->p_first;
+
+    /* First, get the guys who have previously timed out */
+    /* Note that the tick value of the timers should always be '0' */
+    while ((p_tle) && (p_tle->ticks <= 0))
+    {
+        num_time_out++;
+        p_tle = p_tle->p_next;
+    }
+
+    /* Timer entriy tick values are relative to the preceeding entry */
+    rem_ticks = num_units_since_last_update;
+
+    /* Now, adjust remaining timer entries */
+    while ((p_tle != NULL) && (rem_ticks > 0))
+    {
+        temp_ticks = p_tle->ticks;
+        p_tle->ticks -= rem_ticks;
+
+        /* See if this timer has just timed out */
+        if (p_tle->ticks <= 0)
+        {
+            /* We set the number of ticks to '0' so that the legacy code
+             * that assumes a '0' or nonzero value will still work as coded. */
+            p_tle->ticks = 0;
+
+            num_time_out++;
+        }
+
+        rem_ticks -= temp_ticks;  /* Decrement the remaining ticks to process */
+        p_tle = p_tle->p_next;
+    }
+
+    if (p_timer_listq->last_ticks > 0)
+    {
+        p_timer_listq->last_ticks -= num_units_since_last_update;
+
+        /* If the last timer has expired set last_ticks to 0 so that other list update
+        * functions will calculate correctly
+        */
+        if (p_timer_listq->last_ticks < 0)
+            p_timer_listq->last_ticks = 0;
+    }
+
+    return (num_time_out);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_get_remaining_ticks
+**
+** Description      This function is called by an application to get remaining
+**                  ticks to expire
+**
+** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
+**                  p_target_tle    - (input) pointer to a timer list queue entry
+**
+** Returns          0 if timer is not used or timer is not in the list
+**                  remaining ticks if success
+**
+*******************************************************************************/
+UINT32 GKI_get_remaining_ticks (TIMER_LIST_Q *p_timer_listq, TIMER_LIST_ENT  *p_target_tle)
+{
+    TIMER_LIST_ENT  *p_tle;
+    UINT32           rem_ticks = 0;
+
+    if (p_target_tle->in_use)
+    {
+        p_tle = p_timer_listq->p_first;
+
+        /* adding up all of ticks in previous entries */
+        while ((p_tle)&&(p_tle != p_target_tle))
+        {
+            rem_ticks += p_tle->ticks;
+            p_tle = p_tle->p_next;
+        }
+
+        /* if found target entry */
+        if (p_tle == p_target_tle)
+        {
+            rem_ticks += p_tle->ticks;
+        }
+        else
+        {
+            BT_ERROR_TRACE_0(TRACE_LAYER_GKI, "GKI_get_remaining_ticks: No timer entry in the list");
+            return(0);
+        }
+    }
+    else
+    {
+        BT_ERROR_TRACE_0(TRACE_LAYER_GKI, "GKI_get_remaining_ticks: timer entry is not active");
+    }
+
+    return (rem_ticks);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_add_to_timer_list
+**
+** Description      This function is called by an application to add a timer
+**                  entry to a timer list.
+**
+**                  Note: A timer value of '0' will effectively insert an already
+**                      expired event.  Negative tick values will be ignored.
+**
+** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
+**                  p_tle           - (input) pointer to a timer list queue entry
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_add_to_timer_list (TIMER_LIST_Q *p_timer_listq, TIMER_LIST_ENT  *p_tle)
+{
+    UINT32           nr_ticks_total;
+    UINT8 tt;
+    TIMER_LIST_ENT  *p_temp;
+    if (p_tle == NULL || p_timer_listq == NULL) {
+        GKI_TRACE_3("%s: invalid argument %x, %x****************************<<", __func__, p_timer_listq, p_tle);
+        return;
+    }
+
+
+    /* Only process valid tick values */
+    if (p_tle->ticks >= 0)
+    {
+        /* If this entry is the last in the list */
+        if (p_tle->ticks >= p_timer_listq->last_ticks)
+        {
+            /* If this entry is the only entry in the list */
+            if (p_timer_listq->p_first == NULL)
+                p_timer_listq->p_first = p_tle;
+            else
+            {
+                /* Insert the entry onto the end of the list */
+                if (p_timer_listq->p_last != NULL)
+                    p_timer_listq->p_last->p_next = p_tle;
+
+                p_tle->p_prev = p_timer_listq->p_last;
+            }
+
+            p_tle->p_next = NULL;
+            p_timer_listq->p_last = p_tle;
+            nr_ticks_total = p_tle->ticks;
+            p_tle->ticks -= p_timer_listq->last_ticks;
+
+            p_timer_listq->last_ticks = nr_ticks_total;
+        }
+        else    /* This entry needs to be inserted before the last entry */
+        {
+            /* Find the entry that the new one needs to be inserted in front of */
+            p_temp = p_timer_listq->p_first;
+            while (p_tle->ticks > p_temp->ticks)
+            {
+                /* Update the tick value if looking at an unexpired entry */
+                if (p_temp->ticks > 0)
+                    p_tle->ticks -= p_temp->ticks;
+
+                p_temp = p_temp->p_next;
+            }
+
+            /* The new entry is the first in the list */
+            if (p_temp == p_timer_listq->p_first)
+            {
+                p_tle->p_next = p_timer_listq->p_first;
+                p_timer_listq->p_first->p_prev = p_tle;
+                p_timer_listq->p_first = p_tle;
+            }
+            else
+            {
+                p_temp->p_prev->p_next = p_tle;
+                p_tle->p_prev = p_temp->p_prev;
+                p_temp->p_prev = p_tle;
+                p_tle->p_next = p_temp;
+            }
+            p_temp->ticks -= p_tle->ticks;
+        }
+
+        p_tle->in_use = TRUE;
+
+        /* if we already add this timer queue to the array */
+        for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
+        {
+             if (gki_cb.com.timer_queues[tt] == p_timer_listq)
+                 return;
+        }
+        /* add this timer queue to the array */
+        for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
+        {
+             if (gki_cb.com.timer_queues[tt] == NULL)
+                 break;
+        }
+        if (tt < GKI_MAX_TIMER_QUEUES)
+        {
+            gki_cb.com.timer_queues[tt] = p_timer_listq;
+        }
+    }
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_remove_from_timer_list
+**
+** Description      This function is called by an application to remove a timer
+**                  entry from a timer list.
+**
+** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
+**                  p_tle           - (input) pointer to a timer list queue entry
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_remove_from_timer_list (TIMER_LIST_Q *p_timer_listq, TIMER_LIST_ENT  *p_tle)
+{
+    UINT8 tt;
+
+    /* Verify that the entry is valid */
+    if (p_tle == NULL || p_tle->in_use == FALSE || p_timer_listq->p_first == NULL)
+    {
+        return;
+    }
+
+    /* Add the ticks remaining in this timer (if any) to the next guy in the list.
+    ** Note: Expired timers have a tick value of '0'.
+    */
+    if (p_tle->p_next != NULL)
+    {
+        p_tle->p_next->ticks += p_tle->ticks;
+    }
+    else
+    {
+        p_timer_listq->last_ticks -= p_tle->ticks;
+    }
+
+    /* Unlink timer from the list.
+    */
+    if (p_timer_listq->p_first == p_tle)
+    {
+        p_timer_listq->p_first = p_tle->p_next;
+
+        if (p_timer_listq->p_first != NULL)
+            p_timer_listq->p_first->p_prev = NULL;
+
+        if (p_timer_listq->p_last == p_tle)
+            p_timer_listq->p_last = NULL;
+    }
+    else
+    {
+        if (p_timer_listq->p_last == p_tle)
+        {
+            p_timer_listq->p_last = p_tle->p_prev;
+
+            if (p_timer_listq->p_last != NULL)
+                p_timer_listq->p_last->p_next = NULL;
+        }
+        else
+        {
+            if (p_tle->p_next != NULL && p_tle->p_next->p_prev == p_tle)
+                p_tle->p_next->p_prev = p_tle->p_prev;
+            else
+            {
+                /* Error case - chain messed up ?? */
+                return;
+            }
+
+            if (p_tle->p_prev != NULL && p_tle->p_prev->p_next == p_tle)
+                p_tle->p_prev->p_next = p_tle->p_next;
+            else
+            {
+                /* Error case - chain messed up ?? */
+                return;
+            }
+        }
+    }
+
+    p_tle->p_next = p_tle->p_prev = NULL;
+    p_tle->ticks = GKI_UNUSED_LIST_ENTRY;
+    p_tle->in_use = FALSE;
+
+    /* if timer queue is empty */
+    if (p_timer_listq->p_first == NULL && p_timer_listq->p_last == NULL)
+    {
+        for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
+        {
+            if (gki_cb.com.timer_queues[tt] == p_timer_listq)
+            {
+                gki_cb.com.timer_queues[tt] = NULL;
+                break;
+            }
+        }
+    }
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         gki_adjust_timer_count
+**
+** Description      This function is called whenever a new timer or GKI_wait occurs
+**                  to adjust (if necessary) the current time til the first expiration.
+**                  This only needs to make an adjustment if the new timer (in ticks) is
+**                  less than the number of ticks remaining on the current timer.
+**
+** Parameters:      ticks - (input) number of system ticks of the new timer entry
+**
+**                  NOTE:  This routine MUST be called while interrupts are disabled to
+**                          avoid updates while adjusting the timer variables.
+**
+** Returns          void
+**
+*******************************************************************************/
+void gki_adjust_timer_count (INT32 ticks)
+{
+    if (ticks > 0)
+    {
+        /* See if the new timer expires before the current first expiration */
+        if (gki_cb.com.OSNumOrigTicks == 0 || (ticks < gki_cb.com.OSTicksTilExp && gki_cb.com.OSTicksTilExp > 0))
+        {
+            gki_cb.com.OSNumOrigTicks = (gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp) + ticks;
+            gki_cb.com.OSTicksTilExp = ticks;
+        }
+    }
+
+    return;
+}
diff --git a/halimpl/bcm2079x/gki/ulinux/data_types.h b/halimpl/bcm2079x/gki/ulinux/data_types.h
new file mode 100644
index 0000000..27ae561
--- /dev/null
+++ b/halimpl/bcm2079x/gki/ulinux/data_types.h
@@ -0,0 +1,71 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef DATA_TYPES_H
+#define DATA_TYPES_H
+
+#ifndef NULL
+#define NULL     0
+#endif
+
+#ifndef FALSE
+#define FALSE  0
+#endif
+
+typedef unsigned char   UINT8;
+typedef unsigned short  UINT16;
+typedef unsigned long   UINT32;
+typedef unsigned long long int UINT64;
+typedef signed   long   INT32;
+typedef signed   char   INT8;
+typedef signed   short  INT16;
+typedef unsigned char   BOOLEAN;
+typedef UINT32          UINTPTR;
+typedef UINT32          TIME_STAMP;
+
+#ifndef TRUE
+#define TRUE   (!FALSE)
+#endif
+
+typedef unsigned char   UBYTE;
+
+#ifdef __arm
+#define PACKED  __packed
+#define INLINE  __inline
+#else
+#define PACKED
+#define INLINE
+#endif
+
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN FALSE
+#endif
+
+#define UINT16_LOW_BYTE(x)      ((x) & 0xff)
+#define UINT16_HI_BYTE(x)       ((x) >> 8)
+
+/* MACRO definitions for safe string functions */
+/* Replace standard string functions with safe functions if available */
+#define BCM_STRCAT_S(x1,x2,x3)      strcat((x1),(x3))
+#define BCM_STRNCAT_S(x1,x2,x3,x4)  strncat((x1),(x3),(x4))
+#define BCM_STRCPY_S(x1,x2,x3)      strcpy((x1),(x3))
+#define BCM_STRNCPY_S(x1,x2,x3,x4)  strncpy((x1),(x3),(x4))
+#define BCM_SPRINTF_S(x1,x2,x3,x4)  sprintf((x1),(x3),(x4))
+#define BCM_VSPRINTF_S(x1,x2,x3,x4) vsprintf((x1),(x3),(x4))
+
+#endif
+
diff --git a/halimpl/bcm2079x/gki/ulinux/gki_int.h b/halimpl/bcm2079x/gki/ulinux/gki_int.h
new file mode 100644
index 0000000..c59ac32
--- /dev/null
+++ b/halimpl/bcm2079x/gki/ulinux/gki_int.h
@@ -0,0 +1,79 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef GKI_INT_H
+#define GKI_INT_H
+
+#include "gki_common.h"
+#include <pthread.h>
+
+/**********************************************************************
+** OS specific definitions
+*/
+#ifdef ANDROID
+#include <sys/times.h>
+#endif
+
+typedef struct
+{
+    pthread_mutex_t     GKI_mutex;
+    pthread_t           thread_id[GKI_MAX_TASKS];
+    pthread_mutex_t     thread_evt_mutex[GKI_MAX_TASKS];
+    pthread_cond_t      thread_evt_cond[GKI_MAX_TASKS];
+    pthread_mutex_t     thread_timeout_mutex[GKI_MAX_TASKS];
+    pthread_cond_t      thread_timeout_cond[GKI_MAX_TASKS];
+    int                 no_timer_suspend;   /* 1: no suspend, 0 stop calling GKI_timer_update() */
+    pthread_mutex_t     gki_timer_mutex;
+    pthread_cond_t      gki_timer_cond;
+    int                 gki_timer_wake_lock_on;
+#if (GKI_DEBUG == TRUE)
+    pthread_mutex_t     GKI_trace_mutex;
+#endif
+} tGKI_OS;
+
+/* condition to exit or continue GKI_run() timer loop */
+#define GKI_TIMER_TICK_RUN_COND 1
+#define GKI_TIMER_TICK_STOP_COND 0
+#define GKI_TIMER_TICK_EXIT_COND 2
+
+extern void gki_system_tick_start_stop_cback(BOOLEAN start);
+
+/* Contains common control block as well as OS specific variables */
+typedef struct
+{
+    tGKI_OS     os;
+    tGKI_COM_CB com;
+} tGKI_CB;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if GKI_DYNAMIC_MEMORY == FALSE
+GKI_API extern tGKI_CB  gki_cb;
+#else
+GKI_API extern tGKI_CB *gki_cb_ptr;
+#define gki_cb (*gki_cb_ptr)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/halimpl/bcm2079x/gki/ulinux/gki_ulinux.c b/halimpl/bcm2079x/gki/ulinux/gki_ulinux.c
new file mode 100644
index 0000000..df58e27
--- /dev/null
+++ b/halimpl/bcm2079x/gki/ulinux/gki_ulinux.c
@@ -0,0 +1,1317 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include <malloc.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <errno.h>
+
+#define GKI_DEBUG   FALSE
+
+#include <pthread.h>  /* must be 1st header defined  */
+#include <time.h>
+#include <hardware_legacy/power.h>  /* Android header */
+#include "gki_int.h"
+#include "gki_target.h"
+
+/* Temp android logging...move to android tgt config file */
+
+#ifndef LINUX_NATIVE
+#include <cutils/log.h>
+#else
+#define LOGV(format, ...)  fprintf (stdout, LOG_TAG format, ## __VA_ARGS__)
+#define LOGE(format, ...)  fprintf (stderr, LOG_TAG format, ## __VA_ARGS__)
+#define LOGI(format, ...)  fprintf (stdout, LOG_TAG format, ## __VA_ARGS__)
+
+#define SCHED_NORMAL 0
+#define SCHED_FIFO 1
+#define SCHED_RR 2
+#define SCHED_BATCH 3
+
+#endif
+
+/* Define the structure that holds the GKI variables
+*/
+#if GKI_DYNAMIC_MEMORY == FALSE
+tGKI_CB   gki_cb;
+#endif
+
+#define NANOSEC_PER_MILLISEC (1000000)
+#define NSEC_PER_SEC (1000*NANOSEC_PER_MILLISEC)
+
+/* works only for 1ms to 1000ms heart beat ranges */
+#define LINUX_SEC (1000/TICKS_PER_SEC)
+// #define GKI_TICK_TIMER_DEBUG
+
+#define LOCK(m)  pthread_mutex_lock(&m)
+#define UNLOCK(m) pthread_mutex_unlock(&m)
+#define INIT(m) pthread_mutex_init(&m, NULL)
+
+
+/* this kind of mutex go into tGKI_OS control block!!!! */
+/* static pthread_mutex_t GKI_sched_mutex; */
+/*static pthread_mutex_t thread_delay_mutex;
+static pthread_cond_t thread_delay_cond;
+static pthread_mutex_t gki_timer_update_mutex;
+static pthread_cond_t   gki_timer_update_cond;
+*/
+#ifdef NO_GKI_RUN_RETURN
+static pthread_t            timer_thread_id = 0;
+#endif
+
+
+/* For Android */
+
+#ifndef GKI_SHUTDOWN_EVT
+#define GKI_SHUTDOWN_EVT    APPL_EVT_7
+#endif
+
+typedef struct
+{
+    UINT8 task_id;          /* GKI task id */
+    TASKPTR task_entry;     /* Task entry function*/
+    UINT32 params;          /* Extra params to pass to task entry function */
+    pthread_cond_t* pCond;	/* for android*/
+    pthread_mutex_t* pMutex;  /* for android*/
+} gki_pthread_info_t;
+gki_pthread_info_t gki_pthread_info[GKI_MAX_TASKS];
+
+static void* GKI_run_worker_thread (void*);
+
+/*******************************************************************************
+**
+** Function         gki_task_entry
+**
+** Description      entry point of GKI created tasks
+**
+** Returns          void
+**
+*******************************************************************************/
+void gki_task_entry(UINT32 params)
+{
+    pthread_t thread_id = pthread_self();
+    gki_pthread_info_t *p_pthread_info = (gki_pthread_info_t *)params;
+    GKI_TRACE_5("gki_task_entry task_id=%i, thread_id=%x/%x, pCond/pMutex=%x/%x", p_pthread_info->task_id,
+                gki_cb.os.thread_id[p_pthread_info->task_id], pthread_self(),
+                p_pthread_info->pCond, p_pthread_info->pMutex);
+
+    gki_cb.os.thread_id[p_pthread_info->task_id] = thread_id;
+    /* Call the actual thread entry point */
+    (p_pthread_info->task_entry)(p_pthread_info->params);
+
+    GKI_TRACE_1("gki_task task_id=%i terminating", p_pthread_info->task_id);
+    gki_cb.os.thread_id[p_pthread_info->task_id] = 0;
+
+    pthread_exit(0);    /* GKI tasks have no return value */
+}
+/* end android */
+
+#ifndef ANDROID
+void GKI_TRACE(char *fmt, ...)
+{
+    LOCK(gki_cb.os.GKI_trace_mutex);
+    va_list ap;
+
+    va_start(ap, fmt);
+    vfprintf(stderr, fmt, ap);
+    fprintf(stderr, "\n");
+
+    va_end(ap);
+    UNLOCK(gki_cb.os.GKI_trace_mutex);
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         GKI_init
+**
+** Description      This function is called once at startup to initialize
+**                  all the timer structures.
+**
+** Returns          void
+**
+*******************************************************************************/
+
+void GKI_init(void)
+{
+    pthread_mutexattr_t attr;
+    tGKI_OS             *p_os;
+
+    memset (&gki_cb, 0, sizeof (gki_cb));
+
+    gki_buffer_init();
+    gki_timers_init();
+    gki_cb.com.OSTicks = (UINT32) times(0);
+
+    pthread_mutexattr_init(&attr);
+
+#ifndef __CYGWIN__
+    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
+#endif
+    p_os = &gki_cb.os;
+    pthread_mutex_init(&p_os->GKI_mutex, &attr);
+    /* pthread_mutex_init(&GKI_sched_mutex, NULL); */
+#if (GKI_DEBUG == TRUE)
+    pthread_mutex_init(&p_os->GKI_trace_mutex, NULL);
+#endif
+    /* pthread_mutex_init(&thread_delay_mutex, NULL); */  /* used in GKI_delay */
+    /* pthread_cond_init (&thread_delay_cond, NULL); */
+
+    /* Initialiase GKI_timer_update suspend variables & mutexes to be in running state.
+     * this works too even if GKI_NO_TICK_STOP is defined in btld.txt */
+    p_os->no_timer_suspend = GKI_TIMER_TICK_RUN_COND;
+    pthread_mutex_init(&p_os->gki_timer_mutex, NULL);
+    pthread_cond_init(&p_os->gki_timer_cond, NULL);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_get_os_tick_count
+**
+** Description      This function is called to retrieve the native OS system tick.
+**
+** Returns          Tick count of native OS.
+**
+*******************************************************************************/
+UINT32 GKI_get_os_tick_count(void)
+{
+
+    /* TODO - add any OS specific code here
+    **/
+    return (gki_cb.com.OSTicks);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_create_task
+**
+** Description      This function is called to create a new OSS task.
+**
+** Parameters:      task_entry  - (input) pointer to the entry function of the task
+**                  task_id     - (input) Task id is mapped to priority
+**                  taskname    - (input) name given to the task
+**                  stack       - (input) pointer to the top of the stack (highest memory location)
+**                  stacksize   - (input) size of the stack allocated for the task
+**
+** Returns          GKI_SUCCESS if all OK, GKI_FAILURE if any problem
+**
+** NOTE             This function take some parameters that may not be needed
+**                  by your particular OS. They are here for compatability
+**                  of the function prototype.
+**
+*******************************************************************************/
+UINT8 GKI_create_task (TASKPTR task_entry, UINT8 task_id, INT8 *taskname, UINT16 *stack, UINT16 stacksize, void* pCondVar, void* pMutex)
+{
+    UINT16  i;
+    UINT8   *p;
+    struct sched_param param;
+    int policy, ret = 0;
+    pthread_condattr_t attr;
+    pthread_attr_t attr1;
+
+    pthread_condattr_init(&attr);
+    pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
+    GKI_TRACE_5 ("GKI_create_task func=0x%x  id=%d  name=%s  stack=0x%x  stackSize=%d", task_entry, task_id, taskname, stack, stacksize);
+
+    if (task_id >= GKI_MAX_TASKS)
+    {
+        GKI_TRACE_0("Error! task ID > max task allowed");
+        return (GKI_FAILURE);
+    }
+
+
+    gki_cb.com.OSRdyTbl[task_id]    = TASK_READY;
+    gki_cb.com.OSTName[task_id]     = taskname;
+    gki_cb.com.OSWaitTmr[task_id]   = 0;
+    gki_cb.com.OSWaitEvt[task_id]   = 0;
+
+    /* Initialize mutex and condition variable objects for events and timeouts */
+    pthread_mutex_init(&gki_cb.os.thread_evt_mutex[task_id], NULL);
+    pthread_cond_init (&gki_cb.os.thread_evt_cond[task_id], &attr);
+    pthread_mutex_init(&gki_cb.os.thread_timeout_mutex[task_id], NULL);
+    pthread_cond_init (&gki_cb.os.thread_timeout_cond[task_id], &attr);
+
+    pthread_attr_init(&attr1);
+    /* by default, pthread creates a joinable thread */
+#if ( FALSE == GKI_PTHREAD_JOINABLE )
+    pthread_attr_setdetachstate(&attr1, PTHREAD_CREATE_DETACHED);
+
+    GKI_TRACE_3("GKI creating task %i, pCond/pMutex=%x/%x", task_id, pCondVar, pMutex);
+#else
+    GKI_TRACE_1("GKI creating JOINABLE task %i", task_id);
+#endif
+
+    /* On Android, the new tasks starts running before 'gki_cb.os.thread_id[task_id]' is initialized */
+    /* Pass task_id to new task so it can initialize gki_cb.os.thread_id[task_id] for it calls GKI_wait */
+    gki_pthread_info[task_id].task_id = task_id;
+    gki_pthread_info[task_id].task_entry = task_entry;
+    gki_pthread_info[task_id].params = 0;
+    gki_pthread_info[task_id].pCond = (pthread_cond_t*)pCondVar;
+    gki_pthread_info[task_id].pMutex = (pthread_mutex_t*)pMutex;
+
+    ret = pthread_create( &gki_cb.os.thread_id[task_id],
+              &attr1,
+              (void *)gki_task_entry,
+              &gki_pthread_info[task_id]);
+
+    if (ret != 0)
+    {
+         GKI_TRACE_2("pthread_create failed(%d), %s!", ret, taskname);
+         return GKI_FAILURE;
+    }
+
+    if(pthread_getschedparam(gki_cb.os.thread_id[task_id], &policy, &param)==0)
+    {
+#if defined(PBS_SQL_TASK)
+         if (task_id == PBS_SQL_TASK)
+         {
+             GKI_TRACE_0("PBS SQL lowest priority task");
+             policy = SCHED_NORMAL;
+         }
+         else
+#endif
+         {
+             policy = SCHED_RR;
+             param.sched_priority = 30 - task_id - 2;
+         }
+         pthread_setschedparam(gki_cb.os.thread_id[task_id], policy, &param);
+     }
+
+    GKI_TRACE_6( "Leaving GKI_create_task %x %d %x %s %x %d",
+              task_entry,
+              task_id,
+              gki_cb.os.thread_id[task_id],
+              taskname,
+              stack,
+              stacksize);
+
+    return (GKI_SUCCESS);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_shutdown
+**
+** Description      shutdowns the GKI tasks/threads in from max task id to 0 and frees
+**                  pthread resources!
+**                  IMPORTANT: in case of join method, GKI_shutdown must be called outside
+**                  a GKI thread context!
+**
+** Returns          void
+**
+*******************************************************************************/
+#define WAKE_LOCK_ID "brcm_nfca"
+
+void GKI_shutdown(void)
+{
+    UINT8 task_id;
+    volatile int    *p_run_cond = &gki_cb.os.no_timer_suspend;
+    int     oldCOnd = 0;
+#if ( FALSE == GKI_PTHREAD_JOINABLE )
+    int i = 0;
+#else
+    int result;
+#endif
+
+    /* release threads and set as TASK_DEAD. going from low to high priority fixes
+     * GKI_exception problem due to btu->hci sleep request events  */
+    for (task_id = GKI_MAX_TASKS; task_id > 0; task_id--)
+    {
+        if (gki_cb.com.OSRdyTbl[task_id - 1] != TASK_DEAD)
+        {
+            gki_cb.com.OSRdyTbl[task_id - 1] = TASK_DEAD;
+
+            /* paranoi settings, make sure that we do not execute any mailbox events */
+            gki_cb.com.OSWaitEvt[task_id-1] &= ~(TASK_MBOX_0_EVT_MASK|TASK_MBOX_1_EVT_MASK|
+                                                TASK_MBOX_2_EVT_MASK|TASK_MBOX_3_EVT_MASK);
+            GKI_send_event(task_id - 1, EVENT_MASK(GKI_SHUTDOWN_EVT));
+
+#if ( FALSE == GKI_PTHREAD_JOINABLE )
+            i = 0;
+
+            while ((gki_cb.com.OSWaitEvt[task_id - 1] != 0) && (++i < 10))
+                usleep(100 * 1000);
+#else
+            /* wait for proper Arnold Schwarzenegger task state */
+            result = pthread_join( gki_cb.os.thread_id[task_id-1], NULL );
+            if ( result < 0 )
+            {
+                GKI_TRACE_1( "pthread_join() FAILED: result: %d", result );
+            }
+#endif
+            GKI_TRACE_1( "GKI_shutdown(): task %s dead", gki_cb.com.OSTName[task_id]);
+            GKI_exit_task(task_id - 1);
+        }
+    }
+
+    /* Destroy mutex and condition variable objects */
+    pthread_mutex_destroy(&gki_cb.os.GKI_mutex);
+    /*    pthread_mutex_destroy(&GKI_sched_mutex); */
+#if (GKI_DEBUG == TRUE)
+    pthread_mutex_destroy(&gki_cb.os.GKI_trace_mutex);
+#endif
+    /*    pthread_mutex_destroy(&thread_delay_mutex);
+     pthread_cond_destroy (&thread_delay_cond); */
+#if ( FALSE == GKI_PTHREAD_JOINABLE )
+    i = 0;
+#endif
+
+#ifdef NO_GKI_RUN_RETURN
+    shutdown_timer = 1;
+#endif
+    if (gki_cb.os.gki_timer_wake_lock_on)
+    {
+        GKI_TRACE_0("GKI_shutdown :  release_wake_lock(brcm_btld)");
+        release_wake_lock(WAKE_LOCK_ID);
+        gki_cb.os.gki_timer_wake_lock_on = 0;
+    }
+    oldCOnd = *p_run_cond;
+    *p_run_cond = GKI_TIMER_TICK_EXIT_COND;
+    if (oldCOnd == GKI_TIMER_TICK_STOP_COND)
+        pthread_cond_signal( &gki_cb.os.gki_timer_cond );
+
+}
+
+/*******************************************************************************
+ **
+ ** Function        GKI_run
+ **
+ ** Description     This function runs a task
+ **
+ ** Parameters:     start: TRUE start system tick (again), FALSE stop
+ **
+ ** Returns         void
+ **
+ *********************************************************************************/
+void gki_system_tick_start_stop_cback(BOOLEAN start)
+{
+    tGKI_OS         *p_os = &gki_cb.os;
+    volatile int    *p_run_cond = &p_os->no_timer_suspend;
+    volatile static int wake_lock_count;
+    if ( FALSE == start )
+    {
+        /* this can lead to a race condition. however as we only read this variable in the timer loop
+         * we should be fine with this approach. otherwise uncomment below mutexes.
+         */
+        /* GKI_disable(); */
+        *p_run_cond = GKI_TIMER_TICK_STOP_COND;
+        /* GKI_enable(); */
+#ifdef GKI_TICK_TIMER_DEBUG
+        BT_TRACE_1( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, ">>> STOP GKI_timer_update(), wake_lock_count:%d", --wake_lock_count);
+#endif
+        release_wake_lock(WAKE_LOCK_ID);
+        gki_cb.os.gki_timer_wake_lock_on = 0;
+    }
+    else
+    {
+        /* restart GKI_timer_update() loop */
+        acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
+        gki_cb.os.gki_timer_wake_lock_on = 1;
+        *p_run_cond = GKI_TIMER_TICK_RUN_COND;
+        pthread_mutex_lock( &p_os->gki_timer_mutex );
+        pthread_cond_signal( &p_os->gki_timer_cond );
+        pthread_mutex_unlock( &p_os->gki_timer_mutex );
+
+#ifdef GKI_TICK_TIMER_DEBUG
+        BT_TRACE_1( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, ">>> START GKI_timer_update(), wake_lock_count:%d", ++wake_lock_count );
+#endif
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         timer_thread
+**
+** Description      Timer thread
+**
+** Parameters:      id  - (input) timer ID
+**
+** Returns          void
+**
+*********************************************************************************/
+#ifdef NO_GKI_RUN_RETURN
+void timer_thread(signed long id)
+{
+    GKI_TRACE_1("%s enter", __func__);
+    struct timespec delay;
+    int timeout = 1000;  /* 10  ms per system tick  */
+    int err;
+
+    while(!shutdown_timer)
+    {
+        delay.tv_sec = timeout / 1000;
+        delay.tv_nsec = 1000 * 1000 * (timeout%1000);
+
+        /* [u]sleep can't be used because it uses SIGALRM */
+
+        do
+        {
+            err = nanosleep(&delay, &delay);
+        } while (err < 0 && errno ==EINTR);
+
+        GKI_timer_update(1);
+    }
+    GKI_TRACE_1("%s exit", __func__);
+    pthread_exit(NULL);
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         GKI_run
+**
+** Description      This function runs a task
+**
+** Parameters:      p_task_id  - (input) pointer to task id
+**
+** Returns          void
+**
+** NOTE             This function is only needed for operating systems where
+**                  starting a task is a 2-step process. Most OS's do it in
+**                  one step, If your OS does it in one step, this function
+**                  should be empty.
+*********************************************************************************/
+void GKI_run (void *p_task_id)
+{
+    GKI_TRACE_1("%s enter", __func__);
+    int retval = EACCES;
+    static pthread_t workerThreadId = 0;
+
+    retval = pthread_create (&workerThreadId, NULL, GKI_run_worker_thread, NULL);
+    if (retval != 0)
+    {
+        GKI_TRACE_ERROR_2 ("%s: fail create thread %d", __func__, retval);
+    }
+    GKI_TRACE_1("%s exit", __func__);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_run_worker_thread
+**
+** Description      This function runs a task
+**
+** Parameters:      None
+**
+** Returns:         error code
+*********************************************************************************/
+void* GKI_run_worker_thread (void* dummy)
+{
+    GKI_TRACE_1("%s: enter", __func__);
+    struct timespec delay;
+    int err = 0;
+    volatile int * p_run_cond = &gki_cb.os.no_timer_suspend;
+
+#ifndef GKI_NO_TICK_STOP
+    /* register start stop function which disable timer loop in GKI_run() when no timers are
+     * in any GKI/BTA/BTU this should save power when BTLD is idle! */
+    GKI_timer_queue_register_callback( gki_system_tick_start_stop_cback );
+    GKI_TRACE_1( "%s: Start/Stop GKI_timer_update_registered!", __func__ );
+#endif
+
+#ifdef NO_GKI_RUN_RETURN
+    GKI_TRACE_1("%s: GKI_run == NO_GKI_RUN_RETURN", __func__);
+    pthread_attr_t timer_attr;
+
+    shutdown_timer = 0;
+
+    pthread_attr_init(&timer_attr);
+    pthread_attr_setdetachstate(&timer_attr, PTHREAD_CREATE_DETACHED);
+    if (pthread_create( &timer_thread_id,
+              &timer_attr,
+              timer_thread,
+              NULL) != 0 )
+    {
+        GKI_TRACE_1("%s: pthread_create failed to create timer_thread!", __func__);
+        return NULL;
+    }
+#else
+    GKI_TRACE_3("%s: run_cond(%x)=%d ", __func__, p_run_cond, *p_run_cond);
+    for (;GKI_TIMER_TICK_EXIT_COND != *p_run_cond;)
+    {
+        do
+        {
+            /* adjust hear bit tick in btld by changning TICKS_PER_SEC!!!!! this formula works only for
+             * 1-1000ms heart beat units! */
+            delay.tv_sec = LINUX_SEC / 1000;
+            delay.tv_nsec = 1000 * 1000 * (LINUX_SEC % 1000);
+
+            /* [u]sleep can't be used because it uses SIGALRM */
+            do
+            {
+                err = nanosleep(&delay, &delay);
+            } while (err < 0 && errno == EINTR);
+
+            /* the unit should be alsways 1 (1 tick). only if you vary for some reason heart beat tick
+             * e.g. power saving you may want to provide more ticks
+             */
+            GKI_timer_update( 1 );
+            /* BT_TRACE_2( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, "update: tv_sec: %d, tv_nsec: %d", delay.tv_sec, delay.tv_nsec ); */
+        } while ( GKI_TIMER_TICK_RUN_COND == *p_run_cond);
+
+        /* currently on reason to exit above loop is no_timer_suspend == GKI_TIMER_TICK_STOP_COND
+         * block timer main thread till re-armed by  */
+#ifdef GKI_TICK_TIMER_DEBUG
+        BT_TRACE_0( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, ">>> SUSPENDED GKI_timer_update()" );
+#endif
+        if (GKI_TIMER_TICK_EXIT_COND != *p_run_cond) {
+            GKI_TRACE_1("%s: waiting timer mutex", __func__);
+            pthread_mutex_lock( &gki_cb.os.gki_timer_mutex );
+            pthread_cond_wait( &gki_cb.os.gki_timer_cond, &gki_cb.os.gki_timer_mutex );
+            pthread_mutex_unlock( &gki_cb.os.gki_timer_mutex );
+            GKI_TRACE_1("%s: exited timer mutex", __func__);
+        }
+        /* potentially we need to adjust os gki_cb.com.OSTicks */
+
+#ifdef GKI_TICK_TIMER_DEBUG
+        BT_TRACE_1( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, ">>> RESTARTED GKI_timer_update(): run_cond: %d",
+                    *p_run_cond );
+#endif
+    } /* for */
+#endif
+    GKI_TRACE_1("%s: exit", __func__);
+    return NULL;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_stop
+**
+** Description      This function is called to stop
+**                  the tasks and timers when the system is being stopped
+**
+** Returns          void
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If you want to use it in your own implementation,
+**                  put specific code here.
+**
+*******************************************************************************/
+void GKI_stop (void)
+{
+    UINT8 task_id;
+
+    /*  gki_queue_timer_cback(FALSE); */
+    /* TODO - add code here if needed*/
+
+    for(task_id = 0; task_id<GKI_MAX_TASKS; task_id++)
+    {
+        if(gki_cb.com.OSRdyTbl[task_id] != TASK_DEAD)
+        {
+            GKI_exit_task(task_id);
+        }
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_wait
+**
+** Description      This function is called by tasks to wait for a specific
+**                  event or set of events. The task may specify the duration
+**                  that it wants to wait for, or 0 if infinite.
+**
+** Parameters:      flag -    (input) the event or set of events to wait for
+**                  timeout - (input) the duration that the task wants to wait
+**                                    for the specific events (in system ticks)
+**
+**
+** Returns          the event mask of received events or zero if timeout
+**
+*******************************************************************************/
+UINT16 GKI_wait (UINT16 flag, UINT32 timeout)
+{
+    UINT16 evt;
+    UINT8 rtask;
+    struct timespec abstime = { 0, 0 };
+    int sec;
+    int nano_sec;
+
+    rtask = GKI_get_taskid();
+    GKI_TRACE_3("GKI_wait %d %x %d", rtask, flag, timeout);
+    if (rtask >= GKI_MAX_TASKS) {
+        pthread_exit(NULL);
+        return 0;
+    }
+
+    gki_pthread_info_t* p_pthread_info = &gki_pthread_info[rtask];
+    if (p_pthread_info->pCond != NULL && p_pthread_info->pMutex != NULL) {
+        int ret;
+        GKI_TRACE_3("GKI_wait task=%i, pCond/pMutex = %x/%x", rtask, p_pthread_info->pCond, p_pthread_info->pMutex);
+        ret = pthread_mutex_lock(p_pthread_info->pMutex);
+        ret = pthread_cond_signal(p_pthread_info->pCond);
+        ret = pthread_mutex_unlock(p_pthread_info->pMutex);
+        p_pthread_info->pMutex = NULL;
+        p_pthread_info->pCond = NULL;
+    }
+    gki_cb.com.OSWaitForEvt[rtask] = flag;
+
+    /* protect OSWaitEvt[rtask] from modification from an other thread */
+    pthread_mutex_lock(&gki_cb.os.thread_evt_mutex[rtask]);
+
+#if 0 /* for clean scheduling we probably should always call pthread_cond_wait() */
+    /* Check if anything in any of the mailboxes. There is a potential race condition where OSTaskQFirst[rtask]
+     has been modified. however this should only result in addtional call to  pthread_cond_wait() but as
+     the cond is met, it will exit immediately (depending on schedulling) */
+    if (gki_cb.com.OSTaskQFirst[rtask][0])
+    gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_0_EVT_MASK;
+    if (gki_cb.com.OSTaskQFirst[rtask][1])
+    gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_1_EVT_MASK;
+    if (gki_cb.com.OSTaskQFirst[rtask][2])
+    gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_2_EVT_MASK;
+    if (gki_cb.com.OSTaskQFirst[rtask][3])
+    gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_3_EVT_MASK;
+#endif
+
+    if (!(gki_cb.com.OSWaitEvt[rtask] & flag))
+    {
+        if (timeout)
+        {
+            //            timeout = GKI_MS_TO_TICKS(timeout);     /* convert from milliseconds to ticks */
+
+            /* get current system time */
+            //            clock_gettime(CLOCK_MONOTONIC, &currSysTime);
+            //            abstime.tv_sec = currSysTime.time;
+            //            abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
+            clock_gettime(CLOCK_MONOTONIC, &abstime);
+
+            /* add timeout */
+            sec = timeout / 1000;
+            nano_sec = (timeout % 1000) * NANOSEC_PER_MILLISEC;
+            abstime.tv_nsec += nano_sec;
+            if (abstime.tv_nsec > NSEC_PER_SEC)
+            {
+                abstime.tv_sec += (abstime.tv_nsec / NSEC_PER_SEC);
+                abstime.tv_nsec = abstime.tv_nsec % NSEC_PER_SEC;
+            }
+            abstime.tv_sec += sec;
+
+            pthread_cond_timedwait(&gki_cb.os.thread_evt_cond[rtask],
+                    &gki_cb.os.thread_evt_mutex[rtask], &abstime);
+
+        }
+        else
+        {
+            pthread_cond_wait(&gki_cb.os.thread_evt_cond[rtask], &gki_cb.os.thread_evt_mutex[rtask]);
+        }
+
+        /* TODO: check, this is probably neither not needed depending on phtread_cond_wait() implmentation,
+         e.g. it looks like it is implemented as a counter in which case multiple cond_signal
+         should NOT be lost! */
+        // we are waking up after waiting for some events, so refresh variables
+        // no need to call GKI_disable() here as we know that we will have some events as we've been waking up after condition pending or timeout
+        if (gki_cb.com.OSTaskQFirst[rtask][0])
+            gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_0_EVT_MASK;
+        if (gki_cb.com.OSTaskQFirst[rtask][1])
+            gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_1_EVT_MASK;
+        if (gki_cb.com.OSTaskQFirst[rtask][2])
+            gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_2_EVT_MASK;
+        if (gki_cb.com.OSTaskQFirst[rtask][3])
+            gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_3_EVT_MASK;
+
+        if (gki_cb.com.OSRdyTbl[rtask] == TASK_DEAD)
+        {
+            gki_cb.com.OSWaitEvt[rtask] = 0;
+            /* unlock thread_evt_mutex as pthread_cond_wait() does auto lock when cond is met */
+            pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[rtask]);
+            GKI_TRACE_1("GKI TASK_DEAD received. exit thread %d...", rtask );
+
+            gki_cb.os.thread_id[rtask] = 0;
+            pthread_exit(NULL);
+            return (EVENT_MASK(GKI_SHUTDOWN_EVT));
+        }
+    }
+
+    /* Clear the wait for event mask */
+    gki_cb.com.OSWaitForEvt[rtask] = 0;
+
+    /* Return only those bits which user wants... */
+    evt = gki_cb.com.OSWaitEvt[rtask] & flag;
+
+    /* Clear only those bits which user wants... */
+    gki_cb.com.OSWaitEvt[rtask] &= ~flag;
+
+    /* unlock thread_evt_mutex as pthread_cond_wait() does auto lock mutex when cond is met */
+    pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[rtask]);
+    GKI_TRACE_4("GKI_wait %d %x %d %x resumed", rtask, flag, timeout, evt);
+
+    return (evt);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_delay
+**
+** Description      This function is called by tasks to sleep unconditionally
+**                  for a specified amount of time. The duration is in milliseconds
+**
+** Parameters:      timeout -    (input) the duration in milliseconds
+**
+** Returns          void
+**
+*******************************************************************************/
+
+void GKI_delay (UINT32 timeout)
+{
+    UINT8 rtask = GKI_get_taskid();
+    struct timespec delay;
+    int err;
+
+    GKI_TRACE_2("GKI_delay %d %d", rtask, timeout);
+
+    delay.tv_sec = timeout / 1000;
+    delay.tv_nsec = 1000 * 1000 * (timeout%1000);
+
+    /* [u]sleep can't be used because it uses SIGALRM */
+
+    do {
+        err = nanosleep(&delay, &delay);
+    } while (err < 0 && errno ==EINTR);
+
+    /* Check if task was killed while sleeping */
+    /* NOTE
+    **      if you do not implement task killing, you do not
+    **      need this check.
+    */
+    if (rtask && gki_cb.com.OSRdyTbl[rtask] == TASK_DEAD)
+    {
+    }
+
+    GKI_TRACE_2("GKI_delay %d %d done", rtask, timeout);
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_send_event
+**
+** Description      This function is called by tasks to send events to other
+**                  tasks. Tasks can also send events to themselves.
+**
+** Parameters:      task_id -  (input) The id of the task to which the event has to
+**                  be sent
+**                  event   -  (input) The event that has to be sent
+**
+**
+** Returns          GKI_SUCCESS if all OK, else GKI_FAILURE
+**
+*******************************************************************************/
+UINT8 GKI_send_event (UINT8 task_id, UINT16 event)
+{
+    GKI_TRACE_2("GKI_send_event %d %x", task_id, event);
+
+    /* use efficient coding to avoid pipeline stalls */
+    if (task_id < GKI_MAX_TASKS)
+    {
+        /* protect OSWaitEvt[task_id] from manipulation in GKI_wait() */
+        pthread_mutex_lock(&gki_cb.os.thread_evt_mutex[task_id]);
+
+        /* Set the event bit */
+        gki_cb.com.OSWaitEvt[task_id] |= event;
+
+        pthread_cond_signal(&gki_cb.os.thread_evt_cond[task_id]);
+
+        pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[task_id]);
+
+        GKI_TRACE_2("GKI_send_event %d %x done", task_id, event);
+        return ( GKI_SUCCESS );
+    }
+    return (GKI_FAILURE);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_isend_event
+**
+** Description      This function is called from ISRs to send events to other
+**                  tasks. The only difference between this function and GKI_send_event
+**                  is that this function assumes interrupts are already disabled.
+**
+** Parameters:      task_id -  (input) The destination task Id for the event.
+**                  event   -  (input) The event flag
+**
+** Returns          GKI_SUCCESS if all OK, else GKI_FAILURE
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If you want to use it in your own implementation,
+**                  put your code here, otherwise you can delete the entire
+**                  body of the function.
+**
+*******************************************************************************/
+UINT8 GKI_isend_event (UINT8 task_id, UINT16 event)
+{
+
+    GKI_TRACE_2("GKI_isend_event %d %x", task_id, event);
+    GKI_TRACE_2("GKI_isend_event %d %x done", task_id, event);
+    return    GKI_send_event(task_id, event);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_get_taskid
+**
+** Description      This function gets the currently running task ID.
+**
+** Returns          task ID
+**
+** NOTE             The Widcomm upper stack and profiles may run as a single task.
+**                  If you only have one GKI task, then you can hard-code this
+**                  function to return a '1'. Otherwise, you should have some
+**                  OS-specific method to determine the current task.
+**
+*******************************************************************************/
+UINT8 GKI_get_taskid (void)
+{
+    int i;
+
+    pthread_t thread_id = pthread_self( );
+    for (i = 0; i < GKI_MAX_TASKS; i++) {
+        if (gki_cb.os.thread_id[i] == thread_id) {
+            GKI_TRACE_2("GKI_get_taskid %x %d done", thread_id, i);
+            return(i);
+        }
+    }
+
+    GKI_TRACE_1("GKI_get_taskid: thread id = %x, task id = -1", thread_id);
+
+    return(-1);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_map_taskname
+**
+** Description      This function gets the task name of the taskid passed as arg.
+**                  If GKI_MAX_TASKS is passed as arg the currently running task
+**                  name is returned
+**
+** Parameters:      task_id -  (input) The id of the task whose name is being
+**                  sought. GKI_MAX_TASKS is passed to get the name of the
+**                  currently running task.
+**
+** Returns          pointer to task name
+**
+** NOTE             this function needs no customization
+**
+*******************************************************************************/
+UINT8 *GKI_map_taskname (UINT8 task_id)
+{
+    GKI_TRACE_1("GKI_map_taskname %d", task_id);
+
+    if (task_id < GKI_MAX_TASKS)
+    {
+        GKI_TRACE_2("GKI_map_taskname %d %s done", task_id, gki_cb.com.OSTName[task_id]);
+         return (gki_cb.com.OSTName[task_id]);
+    }
+    else if (task_id == GKI_MAX_TASKS )
+    {
+        return (gki_cb.com.OSTName[GKI_get_taskid()]);
+    }
+    else
+    {
+        return (UINT8*) "BAD";
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_enable
+**
+** Description      This function enables interrupts.
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_enable (void)
+{
+    GKI_TRACE_0("GKI_enable");
+    pthread_mutex_unlock(&gki_cb.os.GKI_mutex);
+/* 	pthread_mutex_xx is nesting save, no need for this: already_disabled = 0; */
+    GKI_TRACE_0("Leaving GKI_enable");
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_disable
+**
+** Description      This function disables interrupts.
+**
+** Returns          void
+**
+*******************************************************************************/
+
+void GKI_disable (void)
+{
+    //GKI_TRACE_0("GKI_disable");
+
+/*	pthread_mutex_xx is nesting save, no need for this: if (!already_disabled) {
+    already_disabled = 1; */
+    		pthread_mutex_lock(&gki_cb.os.GKI_mutex);
+/*  } */
+    //GKI_TRACE_0("Leaving GKI_disable");
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_exception
+**
+** Description      This function throws an exception.
+**                  This is normally only called for a nonrecoverable error.
+**
+** Parameters:      code    -  (input) The code for the error
+**                  msg     -  (input) The message that has to be logged
+**
+** Returns          void
+**
+*******************************************************************************/
+
+void GKI_exception (UINT16 code, char *msg)
+{
+    UINT8 task_id;
+    int i = 0;
+
+    GKI_TRACE_ERROR_0( "GKI_exception(): Task State Table");
+
+    for(task_id = 0; task_id < GKI_MAX_TASKS; task_id++)
+    {
+        GKI_TRACE_ERROR_3( "TASK ID [%d] task name [%s] state [%d]",
+                         task_id,
+                         gki_cb.com.OSTName[task_id],
+                         gki_cb.com.OSRdyTbl[task_id]);
+    }
+
+    GKI_TRACE_ERROR_2("GKI_exception %d %s", code, msg);
+    GKI_TRACE_ERROR_0( "********************************************************************");
+    GKI_TRACE_ERROR_2( "* GKI_exception(): %d %s", code, msg);
+    GKI_TRACE_ERROR_0( "********************************************************************");
+
+#if (GKI_DEBUG == TRUE)
+    GKI_disable();
+
+    if (gki_cb.com.ExceptionCnt < GKI_MAX_EXCEPTION)
+    {
+        EXCEPTION_T *pExp;
+
+        pExp =  &gki_cb.com.Exception[gki_cb.com.ExceptionCnt++];
+        pExp->type = code;
+        pExp->taskid = GKI_get_taskid();
+        strncpy((char *)pExp->msg, msg, GKI_MAX_EXCEPTION_MSGLEN - 1);
+    }
+
+    GKI_enable();
+#endif
+
+    GKI_TRACE_ERROR_2("GKI_exception %d %s done", code, msg);
+
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_get_time_stamp
+**
+** Description      This function formats the time into a user area
+**
+** Parameters:      tbuf -  (output) the address to the memory containing the
+**                  formatted time
+**
+** Returns          the address of the user area containing the formatted time
+**                  The format of the time is ????
+**
+** NOTE             This function is only called by OBEX.
+**
+*******************************************************************************/
+INT8 *GKI_get_time_stamp (INT8 *tbuf)
+{
+    UINT32 ms_time;
+    UINT32 s_time;
+    UINT32 m_time;
+    UINT32 h_time;
+    INT8   *p_out = tbuf;
+
+    gki_cb.com.OSTicks = times(0);
+    ms_time = GKI_TICKS_TO_MS(gki_cb.com.OSTicks);
+    s_time  = ms_time/100;   /* 100 Ticks per second */
+    m_time  = s_time/60;
+    h_time  = m_time/60;
+
+    ms_time -= s_time*100;
+    s_time  -= m_time*60;
+    m_time  -= h_time*60;
+
+    *p_out++ = (INT8)((h_time / 10) + '0');
+    *p_out++ = (INT8)((h_time % 10) + '0');
+    *p_out++ = ':';
+    *p_out++ = (INT8)((m_time / 10) + '0');
+    *p_out++ = (INT8)((m_time % 10) + '0');
+    *p_out++ = ':';
+    *p_out++ = (INT8)((s_time / 10) + '0');
+    *p_out++ = (INT8)((s_time % 10) + '0');
+    *p_out++ = ':';
+    *p_out++ = (INT8)((ms_time / 10) + '0');
+    *p_out++ = (INT8)((ms_time % 10) + '0');
+    *p_out++ = ':';
+    *p_out   = 0;
+
+    return (tbuf);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_register_mempool
+**
+** Description      This function registers a specific memory pool.
+**
+** Parameters:      p_mem -  (input) pointer to the memory pool
+**
+** Returns          void
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If your OS has different memory pools, you
+**                  can tell GKI the pool to use by calling this function.
+**
+*******************************************************************************/
+void GKI_register_mempool (void *p_mem)
+{
+    gki_cb.com.p_user_mempool = p_mem;
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_os_malloc
+**
+** Description      This function allocates memory
+**
+** Parameters:      size -  (input) The size of the memory that has to be
+**                  allocated
+**
+** Returns          the address of the memory allocated, or NULL if failed
+**
+** NOTE             This function is called by the Widcomm stack when
+**                  dynamic memory allocation is used. (see dyn_mem.h)
+**
+*******************************************************************************/
+void *GKI_os_malloc (UINT32 size)
+{
+    return (malloc(size));
+}
+
+/*******************************************************************************
+**
+** Function         GKI_os_free
+**
+** Description      This function frees memory
+**
+** Parameters:      size -  (input) The address of the memory that has to be
+**                  freed
+**
+** Returns          void
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. It is only called from within GKI if dynamic
+**
+*******************************************************************************/
+void GKI_os_free (void *p_mem)
+{
+    if(p_mem != NULL)
+		free(p_mem);
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_suspend_task()
+**
+** Description      This function suspends the task specified in the argument.
+**
+** Parameters:      task_id  - (input) the id of the task that has to suspended
+**
+** Returns          GKI_SUCCESS if all OK, else GKI_FAILURE
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If you want to implement task suspension capability,
+**                  put specific code here.
+**
+*******************************************************************************/
+UINT8 GKI_suspend_task (UINT8 task_id)
+{
+    GKI_TRACE_1("GKI_suspend_task %d - NOT implemented", task_id);
+
+
+    GKI_TRACE_1("GKI_suspend_task %d done", task_id);
+
+    return (GKI_SUCCESS);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_resume_task()
+**
+** Description      This function resumes the task specified in the argument.
+**
+** Parameters:      task_id  - (input) the id of the task that has to resumed
+**
+** Returns          GKI_SUCCESS if all OK
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If you want to implement task suspension capability,
+**                  put specific code here.
+**
+*******************************************************************************/
+UINT8 GKI_resume_task (UINT8 task_id)
+{
+    GKI_TRACE_1("GKI_resume_task %d - NOT implemented", task_id);
+
+
+    GKI_TRACE_1("GKI_resume_task %d done", task_id);
+
+    return (GKI_SUCCESS);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_exit_task
+**
+** Description      This function is called to stop a GKI task.
+**
+** Parameters:      task_id  - (input) the id of the task that has to be stopped
+**
+** Returns          void
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If you want to use it in your own implementation,
+**                  put specific code here to kill a task.
+**
+*******************************************************************************/
+void GKI_exit_task (UINT8 task_id)
+{
+    GKI_disable();
+    gki_cb.com.OSRdyTbl[task_id] = TASK_DEAD;
+
+    /* Destroy mutex and condition variable objects */
+    pthread_mutex_destroy(&gki_cb.os.thread_evt_mutex[task_id]);
+    pthread_cond_destroy (&gki_cb.os.thread_evt_cond[task_id]);
+    pthread_mutex_destroy(&gki_cb.os.thread_timeout_mutex[task_id]);
+    pthread_cond_destroy (&gki_cb.os.thread_timeout_cond[task_id]);
+
+    GKI_enable();
+
+	//GKI_send_event(task_id, EVENT_MASK(GKI_SHUTDOWN_EVT));
+
+    GKI_TRACE_1("GKI_exit_task %d done", task_id);
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_sched_lock
+**
+** Description      This function is called by tasks to disable scheduler
+**                  task context switching.
+**
+** Returns          void
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If you want to use it in your own implementation,
+**                  put code here to tell the OS to disable context switching.
+**
+*******************************************************************************/
+void GKI_sched_lock(void)
+{
+    GKI_TRACE_0("GKI_sched_lock");
+    GKI_disable ();
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_sched_unlock
+**
+** Description      This function is called by tasks to enable scheduler switching.
+**
+** Returns          void
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If you want to use it in your own implementation,
+**                  put code here to tell the OS to re-enable context switching.
+**
+*******************************************************************************/
+void GKI_sched_unlock(void)
+{
+    GKI_TRACE_0("GKI_sched_unlock");
+    GKI_enable ();
+}
+
+/*******************************************************************************
+**
+** Function         GKI_shiftdown
+**
+** Description      shift memory down (to make space to insert a record)
+**
+*******************************************************************************/
+void GKI_shiftdown (UINT8 *p_mem, UINT32 len, UINT32 shift_amount)
+{
+    register UINT8 *ps = p_mem + len - 1;
+    register UINT8 *pd = ps + shift_amount;
+    register UINT32 xx;
+
+    for (xx = 0; xx < len; xx++)
+        *pd-- = *ps--;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_shiftup
+**
+** Description      shift memory up (to delete a record)
+**
+*******************************************************************************/
+void GKI_shiftup (UINT8 *p_dest, UINT8 *p_src, UINT32 len)
+{
+    register UINT8 *ps = p_src;
+    register UINT8 *pd = p_dest;
+    register UINT32 xx;
+
+    for (xx = 0; xx < len; xx++)
+        *pd++ = *ps++;
+}
+
+
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_api.c b/halimpl/bcm2079x/hal/hal/nfc_hal_api.c
new file mode 100644
index 0000000..a2faa94
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_api.c
@@ -0,0 +1,326 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ *
+ *  NFC Hardware Abstraction Layer API: Implementation for Broadcom NFC
+ *  controllers
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "gki.h"
+#include "nfc_hal_target.h"
+#include "nfc_hal_api.h"
+#include "nfc_hal_int.h"
+
+/*******************************************************************************
+** NFC_HAL_TASK declarations
+*******************************************************************************/
+#define NFC_HAL_TASK_STR            ((INT8 *) "NFC_HAL_TASK")
+#define NFC_HAL_TASK_STACK_SIZE     0x400
+UINT32 nfc_hal_task_stack[(NFC_HAL_TASK_STACK_SIZE+3)/4];
+
+/*******************************************************************************
+**
+** Function         HAL_NfcInitialize
+**
+** Description      Called when HAL library is loaded.
+**
+**                  Initialize GKI and start the HCIT task
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcInitialize (void)
+{
+    /* Initialize HAL control block */
+    nfc_hal_main_init ();
+
+   HAL_TRACE_API1 ("HAL_NfcInitialize (): NFC_HAL_TASK id=%i", NFC_HAL_TASK);
+
+
+#ifndef NFC_HAL_SHARED_GKI
+    /* Initialize GKI (not needed if using shared NFC/HAL GKI resources) */
+    GKI_init ();
+    GKI_enable ();
+#endif
+
+    /* Create the NCI transport task */
+    GKI_create_task ((TASKPTR)nfc_hal_main_task,
+                     NFC_HAL_TASK,
+                     NFC_HAL_TASK_STR,
+                     (UINT16 *) ((UINT8 *)nfc_hal_task_stack + NFC_HAL_TASK_STACK_SIZE),
+                     sizeof(nfc_hal_task_stack), NULL, NULL);
+
+#ifndef NFC_HAL_SHARED_GKI
+    /* Start GKI scheduler (not needed if using shared NFC/HAL GKI resources) */
+    GKI_run (0);
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcTerminate
+**
+** Description      Called to terminate NFC HAL
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcTerminate(void)
+{
+    HAL_TRACE_API0 ("HAL_NfcTerminate ()");
+}
+
+
+/*******************************************************************************
+**
+** Function         HAL_NfcOpen
+**
+** Description      Open transport and intialize the NFCC, and
+**                  Register callback for HAL event notifications,
+**
+**                  HAL_OPEN_CPLT_EVT will notify when operation is complete.
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcOpen (tHAL_NFC_CBACK *p_hal_cback, tHAL_NFC_DATA_CBACK *p_data_cback)
+{
+    HAL_TRACE_API0 ("HAL_NfcOpen ()");
+
+    /* Only handle if HAL is not opened (stack cback is NULL) */
+    if (p_hal_cback)
+    {
+        nfc_hal_dm_init ();
+        nfc_hal_cb.p_stack_cback = p_hal_cback;
+        nfc_hal_cb.p_data_cback  = p_data_cback;
+
+        /* Send startup event to NFC_HAL_TASK */
+        GKI_send_event (NFC_HAL_TASK, NFC_HAL_TASK_EVT_INITIALIZE);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcClose
+**
+** Description      Prepare for shutdown. A HAL_CLOSE_DONE_EVENT will be
+**                  reported when complete.
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcClose (void)
+{
+    HAL_TRACE_API0 ("HAL_NfcClose ()");
+
+    /* Only handle if HAL is opened (stack cback is not-NULL) */
+    if (nfc_hal_cb.p_stack_cback)
+    {
+        /* Send shutdown event to NFC_HAL_TASK */
+        GKI_send_event (NFC_HAL_TASK, NFC_HAL_TASK_EVT_TERMINATE);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcCoreInitialized
+**
+** Description      Called after the CORE_INIT_RSP is received from the NFCC.
+**                  At this time, the HAL can do any chip-specific configuration,
+**                  and when finished signal the libnfc-nci with event
+**                  HAL_POST_INIT_DONE.
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcCoreInitialized (UINT16 data_len, UINT8 *p_core_init_rsp_params)
+{
+    NFC_HDR *p_msg;
+    UINT16  size;
+
+    HAL_TRACE_API0 ("HAL_NfcCoreInitialized ()");
+
+    /* NCI payload len + NCI header size */
+    size = p_core_init_rsp_params[2] + NCI_MSG_HDR_SIZE;
+
+    /* Send message to NFC_HAL_TASK */
+    if ((p_msg = (NFC_HDR *)GKI_getbuf ((UINT16)(size + NFC_HDR_SIZE))) != NULL)
+    {
+        p_msg->event  = NFC_HAL_EVT_POST_CORE_RESET;
+        p_msg->offset = 0;
+        p_msg->len    = size;
+        p_msg->layer_specific = 0;
+        memcpy ((UINT8 *)(p_msg + 1) + p_msg->offset, p_core_init_rsp_params, size);
+
+        GKI_send_msg (NFC_HAL_TASK, NFC_HAL_TASK_MBOX, p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcWrite
+**
+** Description      Send an NCI control message or data packet to the
+**                  transport. If an NCI command message exceeds the transport
+**                  size, HAL is responsible for fragmenting it, Data packets
+**                  must be of the correct size.
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcWrite (UINT16 data_len, UINT8 *p_data)
+{
+    NFC_HDR *p_msg;
+    UINT8 mt;
+
+    HAL_TRACE_API0 ("HAL_NfcWrite ()");
+
+    if (data_len > (NCI_MAX_CTRL_SIZE + NCI_MSG_HDR_SIZE))
+    {
+        HAL_TRACE_ERROR1 ("HAL_NfcWrite (): too many bytes (%d)", data_len);
+        return;
+    }
+
+    /* Send message to NFC_HAL_TASK */
+    if ((p_msg = (NFC_HDR *)GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
+    {
+        p_msg->event  = NFC_HAL_EVT_TO_NFC_NCI;
+        p_msg->offset = NFC_HAL_NCI_MSG_OFFSET_SIZE;
+        p_msg->len    = data_len;
+        memcpy ((UINT8 *)(p_msg+1) + p_msg->offset, p_data, data_len);
+
+        /* Check if message is a command or data */
+        mt = (*(p_data) & NCI_MT_MASK) >> NCI_MT_SHIFT;
+        p_msg->layer_specific = (mt == NCI_MT_CMD) ? NFC_HAL_WAIT_RSP_CMD : 0;
+
+
+        GKI_send_msg (NFC_HAL_TASK, NFC_HAL_TASK_MBOX, p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPreDiscover
+**
+** Description      Perform any vendor-specific pre-discovery actions (if needed)
+**                  If any actions were performed TRUE will be returned, and
+**                  HAL_PRE_DISCOVER_DONE_EVENT will notify when actions are
+**                  completed.
+**
+** Returns          TRUE if vendor-specific pre-discovery actions initialized
+**                  FALSE if no vendor-specific pre-discovery actions are needed.
+**
+*******************************************************************************/
+BOOLEAN HAL_NfcPreDiscover (void)
+{
+    BOOLEAN status = FALSE;
+
+    NFC_HDR *p_msg;
+
+    HAL_TRACE_API0 ("HAL_NfcPreDiscover ()");
+    if (nfc_hal_cb.pre_discover_done == FALSE)
+    {
+        nfc_hal_cb.pre_discover_done    = TRUE;
+        if (p_nfc_hal_pre_discover_cfg && *p_nfc_hal_pre_discover_cfg)
+        {
+            status                          = TRUE;
+            /* Send message to NFC_HAL_TASK */
+            if ((p_msg = (NFC_HDR *)GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
+            {
+                p_msg->event  = NFC_HAL_EVT_PRE_DISCOVER;
+                GKI_send_msg (NFC_HAL_TASK, NFC_HAL_TASK_MBOX, p_msg);
+            }
+        }
+    }
+
+    HAL_TRACE_API1 ("HAL_NfcPreDiscover status:%d", status);
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcControlGranted
+**
+** Description      Grant control to HAL control for sending NCI commands.
+**
+**                  Call in response to HAL_REQUEST_CONTROL_EVENT.
+**
+**                  Must only be called when there are no NCI commands pending.
+**
+**                  HAL_RELEASE_CONTROL_EVENT will notify when HAL no longer
+**                  needs control of NCI.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcControlGranted (void)
+{
+    NFC_HDR *p_msg;
+    HAL_TRACE_API0 ("HAL_NfcControlGranted ()");
+
+    /* Send message to NFC_HAL_TASK */
+    if ((p_msg = (NFC_HDR *)GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
+    {
+        p_msg->event  = NFC_HAL_EVT_CONTROL_GRANTED;
+        GKI_send_msg (NFC_HAL_TASK, NFC_HAL_TASK_MBOX, p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPowerCycle
+**
+** Description      Restart NFCC by power cyle
+**
+**                  HAL_OPEN_CPLT_EVT will notify when operation is complete.
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcPowerCycle (void)
+{
+    HAL_TRACE_API0 ("HAL_NfcPowerCycle ()");
+
+    /* Only handle if HAL is opened (stack cback is not-NULL) */
+    if (nfc_hal_cb.p_stack_cback)
+    {
+        /* Send power cycle event to NFC_HAL_TASK */
+        GKI_send_event (NFC_HAL_TASK, NFC_HAL_TASK_EVT_POWER_CYCLE);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcGetMaxNfcee
+**
+** Description      Retrieve the maximum number of NFCEEs supported by NFCC
+**
+** Returns          the maximum number of NFCEEs supported by NFCC
+**
+*******************************************************************************/
+UINT8 HAL_NfcGetMaxNfcee (void)
+{
+    HAL_TRACE_API1 ("HAL_NfcGetMaxNfcee: %d",nfc_hal_cb.max_ee);
+    return nfc_hal_cb.max_ee;
+}
+
+
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_brcm.c b/halimpl/bcm2079x/hal/hal/nfc_hal_brcm.c
new file mode 100644
index 0000000..aaae0a4
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_brcm.c
@@ -0,0 +1,30 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ *
+ *  This file contains function of the NFC unit to receive/process NFC VS
+ *  commands.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "gki.h"
+#include "nfc_hal_int.h"
+#include "userial.h"
+
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_dm.c b/halimpl/bcm2079x/hal/hal/nfc_hal_dm.c
new file mode 100644
index 0000000..9e200f8
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_dm.c
@@ -0,0 +1,1289 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ *
+ *  Vendor-specific handler for DM events
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_hal_int.h"
+#include "nfc_hal_post_reset.h"
+#include "userial.h"
+#include "upio.h"
+
+/*****************************************************************************
+** Constants and types
+*****************************************************************************/
+
+#define NFC_HAL_I93_RW_CFG_LEN              (5)
+#define NFC_HAL_I93_RW_CFG_PARAM_LEN        (3)
+#define NFC_HAL_I93_AFI                     (0)
+#define NFC_HAL_I93_ENABLE_SMART_POLL       (1)
+
+static UINT8 nfc_hal_dm_i93_rw_cfg[NFC_HAL_I93_RW_CFG_LEN] =
+{
+    NCI_PARAM_ID_I93_DATARATE,
+    NFC_HAL_I93_RW_CFG_PARAM_LEN,
+    NFC_HAL_I93_FLAG_DATA_RATE,    /* Bit0:Sub carrier, Bit1:Data rate, Bit4:Enable/Disable AFI */
+    NFC_HAL_I93_AFI,               /* AFI if Bit 4 is set in the flag byte */
+    NFC_HAL_I93_ENABLE_SMART_POLL  /* Bit0:Enable/Disable smart poll */
+};
+
+static UINT8 nfc_hal_dm_set_fw_fsm_cmd[NCI_MSG_HDR_SIZE + 1] =
+{
+    NCI_MTS_CMD|NCI_GID_PROP,
+    NCI_MSG_SET_FWFSM,
+    0x01,
+    0x00,
+};
+#define NCI_SET_FWFSM_OFFSET_ENABLE      3
+
+#define NCI_PROP_PARAM_SIZE_XTAL_INDEX      3       /* length of parameters in XTAL_INDEX CMD */
+#ifndef NCI_PROP_PARAM_MAX_SIZE_XTAL_INDEX
+#define NCI_PROP_PARAM_MAX_SIZE_XTAL_INDEX      20
+#endif
+
+const UINT8 nfc_hal_dm_get_build_info_cmd[NCI_MSG_HDR_SIZE] =
+{
+    NCI_MTS_CMD|NCI_GID_PROP,
+    NCI_MSG_GET_BUILD_INFO,
+    0x00
+};
+#define NCI_BUILD_INFO_OFFSET_HWID  25  /* HW ID offset in build info RSP */
+
+const UINT8 nfc_hal_dm_get_patch_version_cmd [NCI_MSG_HDR_SIZE] =
+{
+    NCI_MTS_CMD|NCI_GID_PROP,
+    NCI_MSG_GET_PATCH_VERSION,
+    0x00
+};
+#define NCI_PATCH_INFO_VERSION_LEN  16  /* Length of patch version string in PATCH_INFO */
+
+/*****************************************************************************
+** Extern function prototypes
+*****************************************************************************/
+extern UINT8 *p_nfc_hal_dm_lptd_cfg;
+extern UINT8 *p_nfc_hal_dm_pll_325_cfg;
+extern UINT8 *p_nfc_hal_dm_start_up_cfg;
+extern UINT8 *p_nfc_hal_dm_start_up_vsc_cfg;
+extern tNFC_HAL_CFG *p_nfc_hal_cfg;
+extern tNFC_HAL_DM_PRE_SET_MEM *p_nfc_hal_dm_pre_set_mem;
+
+/*****************************************************************************
+** Local function prototypes
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_set_config
+**
+** Description      Send NCI config items to NFCC
+**
+** Returns          tHAL_NFC_STATUS
+**
+*******************************************************************************/
+tHAL_NFC_STATUS nfc_hal_dm_set_config (UINT8 tlv_size,
+                                       UINT8 *p_param_tlvs,
+                                       tNFC_HAL_NCI_CBACK *p_cback)
+{
+    UINT8  *p_buff, *p;
+    UINT8  num_param = 0, param_len, rem_len, *p_tlv;
+    UINT16 cmd_len = NCI_MSG_HDR_SIZE + tlv_size + 1;
+    tHAL_NFC_STATUS status = HAL_NFC_STATUS_FAILED;
+
+    if ((tlv_size == 0)||(p_param_tlvs == NULL))
+    {
+        return status;
+    }
+
+    if ((p_buff = (UINT8 *) GKI_getbuf ((UINT16)(NCI_MSG_HDR_SIZE + tlv_size))) != NULL)
+    {
+        p = p_buff;
+
+        NCI_MSG_BLD_HDR0 (p, NCI_MT_CMD, NCI_GID_CORE);
+        NCI_MSG_BLD_HDR1 (p, NCI_MSG_CORE_SET_CONFIG);
+        UINT8_TO_STREAM  (p, (UINT8) (tlv_size + 1));
+
+        rem_len = tlv_size;
+        p_tlv   = p_param_tlvs;
+        while (rem_len > 1)
+        {
+            num_param++;                /* number of params */
+
+            p_tlv ++;                   /* param type   */
+            param_len = *p_tlv++;       /* param length */
+
+            rem_len -= 2;               /* param type and length */
+            if (rem_len >= param_len)
+            {
+                rem_len -= param_len;
+                p_tlv   += param_len;   /* next param_type */
+
+                if (rem_len == 0)
+                {
+                    status = HAL_NFC_STATUS_OK;
+                    break;
+                }
+            }
+            else
+            {
+                /* error found */
+                break;
+            }
+        }
+
+        if (status == HAL_NFC_STATUS_OK)
+        {
+            UINT8_TO_STREAM (p, num_param);
+            ARRAY_TO_STREAM (p, p_param_tlvs, tlv_size);
+
+            nfc_hal_dm_send_nci_cmd (p_buff, cmd_len, p_cback);
+        }
+        else
+        {
+            HAL_TRACE_ERROR0 ("nfc_hal_dm_set_config ():Bad TLV");
+        }
+
+        GKI_freebuf (p_buff);
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_set_fw_fsm
+**
+** Description      Enable or disable FW FSM
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_dm_set_fw_fsm (BOOLEAN enable, tNFC_HAL_NCI_CBACK *p_cback)
+{
+    if (enable)
+        nfc_hal_dm_set_fw_fsm_cmd[NCI_SET_FWFSM_OFFSET_ENABLE] = 0x01; /* Enable, default is disabled */
+    else
+        nfc_hal_dm_set_fw_fsm_cmd[NCI_SET_FWFSM_OFFSET_ENABLE] = 0x00; /* Disable */
+
+    nfc_hal_dm_send_nci_cmd (nfc_hal_dm_set_fw_fsm_cmd, NCI_MSG_HDR_SIZE + 1, p_cback);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_config_nfcc_cback
+**
+** Description      Callback for NCI vendor specific command complete
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_dm_config_nfcc_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data)
+{
+    if (nfc_hal_cb.dev_cb.next_dm_config == NFC_HAL_DM_CONFIG_NONE)
+    {
+        nfc_hal_hci_enable ();
+    }
+    else
+    {
+        nfc_hal_dm_config_nfcc ();
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_send_startup_vsc
+**
+** Description      Send VS command before NFA start-up
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfc_hal_dm_send_startup_vsc (void)
+{
+    UINT8  *p, *p_end;
+    UINT16 len;
+
+    HAL_TRACE_DEBUG0 ("nfc_hal_dm_send_startup_vsc ()");
+
+    /* VSC must have NCI header at least */
+    if (nfc_hal_cb.dev_cb.next_startup_vsc + NCI_MSG_HDR_SIZE - 1 <= *p_nfc_hal_dm_start_up_vsc_cfg)
+    {
+        p     = p_nfc_hal_dm_start_up_vsc_cfg + nfc_hal_cb.dev_cb.next_startup_vsc;
+        len   = *(p + 2);
+        p_end = p + NCI_MSG_HDR_SIZE - 1 + len;
+
+        if (p_end <= p_nfc_hal_dm_start_up_vsc_cfg + *p_nfc_hal_dm_start_up_vsc_cfg)
+        {
+            /* move to next VSC */
+            nfc_hal_cb.dev_cb.next_startup_vsc += NCI_MSG_HDR_SIZE + len;
+
+            /* if this is last VSC */
+            if (p_end == p_nfc_hal_dm_start_up_vsc_cfg + *p_nfc_hal_dm_start_up_vsc_cfg)
+                nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_NONE;
+
+            nfc_hal_dm_send_nci_cmd (p, (UINT16)(NCI_MSG_HDR_SIZE + len), nfc_hal_dm_config_nfcc_cback);
+            return;
+        }
+    }
+
+    HAL_TRACE_ERROR0 ("nfc_hal_dm_send_startup_vsc (): Bad start-up VSC");
+
+    NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+    nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_config_nfcc
+**
+** Description      Send VS config before NFA start-up
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_dm_config_nfcc (void)
+{
+    HAL_TRACE_DEBUG1 ("nfc_hal_dm_config_nfcc (): next_dm_config = %d", nfc_hal_cb.dev_cb.next_dm_config);
+
+    if ((p_nfc_hal_dm_lptd_cfg[0]) && (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_LPTD))
+    {
+        nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_PLL_325;
+
+        if (nfc_hal_dm_set_config (p_nfc_hal_dm_lptd_cfg[0],
+                                   &p_nfc_hal_dm_lptd_cfg[1],
+                                   nfc_hal_dm_config_nfcc_cback) == HAL_NFC_STATUS_OK)
+        {
+            return;
+        }
+        else
+        {
+            NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+            nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_FAILED);
+            return;
+        }
+    }
+
+    if ((p_nfc_hal_dm_pll_325_cfg) && (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_PLL_325))
+    {
+        nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_START_UP;
+
+        if (nfc_hal_dm_set_config (NFC_HAL_PLL_325_SETCONFIG_PARAM_LEN,
+                                   p_nfc_hal_dm_pll_325_cfg,
+                                   nfc_hal_dm_config_nfcc_cback) == HAL_NFC_STATUS_OK)
+        {
+            return;
+        }
+        else
+        {
+            NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+            nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_FAILED);
+            return;
+        }
+    }
+
+    if ((p_nfc_hal_dm_start_up_cfg[0]) && (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_START_UP))
+    {
+        nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_I93_DATA_RATE;
+        if (nfc_hal_dm_set_config (p_nfc_hal_dm_start_up_cfg[0],
+                                   &p_nfc_hal_dm_start_up_cfg[1],
+                                   nfc_hal_dm_config_nfcc_cback) == HAL_NFC_STATUS_OK)
+        {
+            return;
+        }
+        else
+        {
+            NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+            nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_FAILED);
+            return;
+        }
+    }
+
+#if (NFC_HAL_I93_FLAG_DATA_RATE == NFC_HAL_I93_FLAG_DATA_RATE_HIGH)
+    if (nfc_hal_cb.dev_cb.next_dm_config  <= NFC_HAL_DM_CONFIG_I93_DATA_RATE)
+    {
+        nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_FW_FSM;
+        if (nfc_hal_dm_set_config (NFC_HAL_I93_RW_CFG_LEN,
+                                   nfc_hal_dm_i93_rw_cfg,
+                                   nfc_hal_dm_config_nfcc_cback) == HAL_NFC_STATUS_OK)
+        {
+            return;
+        }
+        else
+        {
+            NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+            nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_FAILED);
+            return;
+        }
+    }
+#endif
+
+    /* FW FSM is disabled as default in NFCC */
+    if (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_FW_FSM)
+    {
+        nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_START_UP_VSC;
+        nfc_hal_dm_set_fw_fsm (NFC_HAL_DM_MULTI_TECH_RESP, nfc_hal_dm_config_nfcc_cback);
+        return;
+    }
+
+    if (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_START_UP_VSC)
+    {
+        if (p_nfc_hal_dm_start_up_vsc_cfg && *p_nfc_hal_dm_start_up_vsc_cfg)
+        {
+            nfc_hal_dm_send_startup_vsc ();
+            return;
+        }
+    }
+
+    /* nothing to config */
+    nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_NONE;
+    nfc_hal_dm_config_nfcc_cback (0, 0, NULL);
+}
+
+/*******************************************************************************
+**
+** Function:    nfc_hal_dm_get_xtal_index
+**
+** Description: Return Xtal index and frequency
+**
+** Returns:     tNFC_HAL_XTAL_INDEX
+**
+*******************************************************************************/
+tNFC_HAL_XTAL_INDEX nfc_hal_dm_get_xtal_index (UINT32 brcm_hw_id, UINT16 *p_xtal_freq)
+{
+    UINT8 xx;
+
+    HAL_TRACE_DEBUG1("nfc_hal_dm_get_xtal_index() brcm_hw_id:0x%x", brcm_hw_id);
+
+    for (xx = 0; xx < nfc_post_reset_cb.dev_init_config.num_xtal_cfg; xx++)
+    {
+        if ((brcm_hw_id & BRCM_NFC_GEN_MASK)
+            == nfc_post_reset_cb.dev_init_config.xtal_cfg[xx].brcm_hw_id)
+        {
+            *p_xtal_freq = nfc_post_reset_cb.dev_init_config.xtal_cfg[xx].xtal_freq;
+            return (nfc_post_reset_cb.dev_init_config.xtal_cfg[xx].xtal_index);
+        }
+    }
+
+    /* if not found */
+    *p_xtal_freq = 0;
+    return (NFC_HAL_XTAL_INDEX_MAX);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_set_xtal_freq_index
+**
+** Description      Set crystal frequency index
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_dm_set_xtal_freq_index (void)
+{
+    UINT8 nci_brcm_xtal_index_cmd[NCI_MSG_HDR_SIZE + NCI_PROP_PARAM_MAX_SIZE_XTAL_INDEX];
+    UINT8 *p;
+    tNFC_HAL_XTAL_INDEX xtal_index;
+    UINT16              xtal_freq;
+    UINT8               cmd_len = NCI_PROP_PARAM_SIZE_XTAL_INDEX;
+    extern UINT8 *p_nfc_hal_dm_xtal_params_cfg;
+
+    HAL_TRACE_DEBUG1 ("nfc_hal_dm_set_xtal_freq_index (): brcm_hw_id = 0x%x", nfc_hal_cb.dev_cb.brcm_hw_id);
+
+    xtal_index = nfc_hal_dm_get_xtal_index (nfc_hal_cb.dev_cb.brcm_hw_id, &xtal_freq);
+    if ((xtal_index == NFC_HAL_XTAL_INDEX_SPECIAL) && (p_nfc_hal_dm_xtal_params_cfg))
+    {
+        cmd_len += p_nfc_hal_dm_xtal_params_cfg[0]; /* [0] is the length of extra params */
+    }
+
+    p = nci_brcm_xtal_index_cmd;
+    UINT8_TO_STREAM  (p, (NCI_MTS_CMD|NCI_GID_PROP));
+    UINT8_TO_STREAM  (p, NCI_MSG_GET_XTAL_INDEX_FROM_DH);
+    UINT8_TO_STREAM  (p, cmd_len);
+    UINT8_TO_STREAM  (p, xtal_index);
+    UINT16_TO_STREAM (p, xtal_freq);
+    if (cmd_len > NCI_PROP_PARAM_SIZE_XTAL_INDEX)
+    {
+        memcpy (p, &p_nfc_hal_dm_xtal_params_cfg[1], p_nfc_hal_dm_xtal_params_cfg[0]);
+    }
+
+    NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_XTAL_SET);
+
+    nfc_hal_dm_send_nci_cmd (nci_brcm_xtal_index_cmd, NCI_MSG_HDR_SIZE + cmd_len, NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_send_get_build_info_cmd
+**
+** Description      Send NCI_MSG_GET_BUILD_INFO CMD
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_dm_send_get_build_info_cmd (void)
+{
+    NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_BUILD_INFO);
+
+    /* get build information to find out HW */
+    nfc_hal_dm_send_nci_cmd (nfc_hal_dm_get_build_info_cmd, NCI_MSG_HDR_SIZE, NULL);
+}
+/*******************************************************************************
+**
+** Function:    nfc_hal_dm_adjust_hw_id
+**
+** Description: The hw_id of certain chips are shifted by 8 bits.
+**              Adjust the hw_id before processing.
+**
+** Returns:     Nothing
+**
+*******************************************************************************/
+static UINT32 nfc_hal_dm_adjust_hw_id (UINT32 hw_id)
+{
+    if ((hw_id & 0xF0000000) == 0)
+        hw_id <<= 4; /* shift hw_id by 4 bits to align w the format of most chips */
+    return hw_id;
+}
+
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_check_xtal
+**
+** Description      check if need to send xtal command.
+**                  If not, proceed to next step get_patch_version.
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfc_hal_dm_check_xtal (void)
+{
+    UINT16  xtal_freq;
+    tNFC_HAL_XTAL_INDEX xtal_index;
+
+    /* if NFCC needs to set Xtal frequency before getting patch version */
+    xtal_index = nfc_hal_dm_get_xtal_index (nfc_hal_cb.dev_cb.brcm_hw_id, &xtal_freq);
+    if ((xtal_index < NFC_HAL_XTAL_INDEX_MAX) || (xtal_index == NFC_HAL_XTAL_INDEX_SPECIAL))
+    {
+        {
+            /* set Xtal index before getting patch version */
+            nfc_hal_dm_set_xtal_freq_index ();
+            return;
+        }
+    }
+
+    NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_PATCH_INFO);
+
+    nfc_hal_dm_send_nci_cmd (nfc_hal_dm_get_patch_version_cmd, NCI_MSG_HDR_SIZE, NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_pre_set_mem_cback
+**
+** Description      This is pre-set mem complete callback.
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfc_hal_dm_pre_set_mem_cback (tNFC_HAL_BTVSC_CPLT *pData)
+{
+    UINT8   status = pData->p_param_buf[0];
+
+    HAL_TRACE_DEBUG1 ("nfc_hal_dm_pre_set_mem_cback: %d", status);
+    /* if it is completed */
+    if (status == HCI_SUCCESS)
+    {
+        if (!nfc_hal_dm_check_pre_set_mem())
+        {
+            return;
+        }
+    }
+    nfc_hal_dm_check_xtal();
+}
+
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_check_pre_set_mem
+**
+** Description      Check if need to send the command.
+**
+** Returns          TRUE if done.
+**
+*******************************************************************************/
+BOOLEAN nfc_hal_dm_check_pre_set_mem (void)
+{
+    UINT8   cmd[NFC_HAL_BT_HCI_CMD_HDR_SIZE + HCI_BRCM_PRE_SET_MEM_LENGTH];
+    UINT8   *p;
+    UINT32  addr = 0;
+
+    if (p_nfc_hal_dm_pre_set_mem)
+        addr     = p_nfc_hal_dm_pre_set_mem[nfc_hal_cb.pre_set_mem_idx].addr;
+    HAL_TRACE_DEBUG2 ("nfc_hal_dm_check_pre_set_mem: %d/0x%x", nfc_hal_cb.pre_set_mem_idx, addr);
+    if (addr == 0)
+    {
+        return TRUE;
+    }
+    p = cmd;
+
+    /* Add the command */
+    UINT16_TO_STREAM (p, HCI_BRCM_PRE_SET_MEM);
+    UINT8_TO_STREAM  (p, HCI_BRCM_PRE_SET_MEM_LENGTH);
+
+    UINT8_TO_STREAM  (p, HCI_BRCM_PRE_SET_MEM_TYPE);
+    UINT32_TO_STREAM  (p, addr);
+    UINT8_TO_STREAM   (p, 0);
+    UINT32_TO_STREAM  (p, p_nfc_hal_dm_pre_set_mem[nfc_hal_cb.pre_set_mem_idx].data);
+    nfc_hal_cb.pre_set_mem_idx++;
+
+    nfc_hal_dm_send_bt_cmd (cmd,
+                            NFC_HAL_BT_HCI_CMD_HDR_SIZE + HCI_BRCM_PRE_SET_MEM_LENGTH,
+                            nfc_hal_dm_pre_set_mem_cback);
+    return FALSE;
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_proc_msg_during_init
+**
+** Description      Process NCI message while initializing NFCC
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_dm_proc_msg_during_init (NFC_HDR *p_msg)
+{
+    UINT8 *p;
+    UINT8 reset_reason, reset_type;
+    UINT8 mt, pbf, gid, op_code;
+    UINT8 *p_old, old_gid, old_oid, old_mt;
+    UINT8 u8;
+    tNFC_HAL_NCI_CBACK *p_cback = NULL;
+    UINT8   chipverlen;
+    UINT8   chipverstr[NCI_SPD_HEADER_CHIPVER_LEN];
+    UINT32  hw_id = 0;
+
+    HAL_TRACE_DEBUG1 ("nfc_hal_dm_proc_msg_during_init(): init state:%d", nfc_hal_cb.dev_cb.initializing_state);
+
+    p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+
+    NCI_MSG_PRS_HDR0 (p, mt, pbf, gid);
+    NCI_MSG_PRS_HDR1 (p, op_code);
+
+    /* check if waiting for this response */
+    if (  (nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_CMD)
+        ||(nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_VSC)  )
+    {
+        if (mt == NCI_MT_RSP)
+        {
+            p_old = nfc_hal_cb.ncit_cb.last_hdr;
+            NCI_MSG_PRS_HDR0 (p_old, old_mt, pbf, old_gid);
+            old_oid = ((*p_old) & NCI_OID_MASK);
+            /* make sure this is the RSP we are waiting for before updating the command window */
+            if ((old_gid == gid) && (old_oid == op_code))
+            {
+                nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_NONE;
+                p_cback = (tNFC_HAL_NCI_CBACK *)nfc_hal_cb.ncit_cb.p_vsc_cback;
+                nfc_hal_cb.ncit_cb.p_vsc_cback  = NULL;
+                nfc_hal_main_stop_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
+            }
+        }
+    }
+
+    if (gid == NCI_GID_CORE)
+    {
+        if (op_code == NCI_MSG_CORE_RESET)
+        {
+            if (mt == NCI_MT_NTF)
+            {
+                if (  (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_NFCC_ENABLE)
+                    ||(nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_POST_XTAL_SET)  )
+                {
+                    /*
+                    ** Core reset ntf in the following cases;
+                    ** 1) after power up (raising REG_PU)
+                    ** 2) after setting xtal index
+                    ** Start pre-initializing NFCC
+                    */
+                    nfc_hal_main_stop_quick_timer (&nfc_hal_cb.timer);
+                    nfc_hal_dm_pre_init_nfcc ();
+                }
+                else
+                {
+                    /* Core reset ntf after post-patch download, Call reset notification callback */
+                    p++;                                /* Skip over param len */
+                    STREAM_TO_UINT8 (reset_reason, p);
+                    STREAM_TO_UINT8 (reset_type, p);
+                    nfc_hal_prm_spd_reset_ntf (reset_reason, reset_type);
+                }
+            }
+        }
+        else if (p_cback)
+        {
+            (*p_cback) ((tNFC_HAL_NCI_EVT) (op_code),
+                        p_msg->len,
+                        (UINT8 *) (p_msg + 1) + p_msg->offset);
+        }
+    }
+    else if (gid == NCI_GID_PROP) /* this is for download patch */
+    {
+        if (mt == NCI_MT_NTF)
+            op_code |= NCI_NTF_BIT;
+        else
+            op_code |= NCI_RSP_BIT;
+
+        if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_XTAL_SET)
+        {
+            if (op_code == (NCI_RSP_BIT|NCI_MSG_GET_XTAL_INDEX_FROM_DH))
+            {
+                /* start timer in case that NFCC doesn't send RESET NTF after loading patch from NVM */
+                NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_POST_XTAL_SET);
+
+                nfc_hal_main_start_quick_timer (&nfc_hal_cb.timer, NFC_HAL_TTYPE_NFCC_ENABLE,
+                                                ((p_nfc_hal_cfg->nfc_hal_post_xtal_timeout)*QUICK_TIMER_TICKS_PER_SEC)/1000);
+            }
+        }
+        else if (  (op_code == NFC_VS_GET_BUILD_INFO_EVT)
+                 &&(nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_BUILD_INFO)  )
+        {
+            p += NCI_BUILD_INFO_OFFSET_HWID;
+
+            STREAM_TO_UINT32 (hw_id, p);
+            nfc_hal_cb.dev_cb.brcm_hw_id = nfc_hal_dm_adjust_hw_id (hw_id);
+            HAL_TRACE_DEBUG2 ("brcm_hw_id: 0x%x -> 0x%x", hw_id, nfc_hal_cb.dev_cb.brcm_hw_id);
+
+            STREAM_TO_UINT8 (chipverlen, p);
+            memset (chipverstr, 0, NCI_SPD_HEADER_CHIPVER_LEN);
+
+            STREAM_TO_ARRAY (chipverstr, p, chipverlen);
+
+            nfc_hal_hci_handle_build_info (chipverlen, chipverstr);
+            nfc_hal_cb.pre_set_mem_idx = 0;
+            if (!nfc_hal_dm_check_pre_set_mem())
+            {
+                /* pre-set mem started */
+                return;
+            }
+            nfc_hal_dm_check_xtal();
+        }
+        else if (  (op_code == NFC_VS_GET_PATCH_VERSION_EVT)
+                 &&(nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_PATCH_INFO)  )
+        {
+            /* Store NVM info to control block */
+
+            /* Skip over rsp len */
+            p++;
+
+            /* Get project id */
+            STREAM_TO_UINT16 (nfc_hal_cb.nvm_cb.project_id, p);
+
+            /* RFU */
+            p++;
+
+            /* Get chip version string */
+            STREAM_TO_UINT8 (u8, p);
+            if (u8 > NFC_HAL_PRM_MAX_CHIP_VER_LEN)
+                u8 = NFC_HAL_PRM_MAX_CHIP_VER_LEN;
+            memcpy (nfc_hal_cb.nvm_cb.chip_ver, p, u8);
+            p += NCI_PATCH_INFO_VERSION_LEN;
+
+            /* Get major/minor version */
+            STREAM_TO_UINT16 (nfc_hal_cb.nvm_cb.ver_major, p);
+            STREAM_TO_UINT16 (nfc_hal_cb.nvm_cb.ver_minor, p);
+
+            /* Skip over max_size and patch_max_size */
+            p += 4;
+
+            /* Get current lpm patch size */
+            STREAM_TO_UINT16 (nfc_hal_cb.nvm_cb.lpm_size, p);
+            STREAM_TO_UINT16 (nfc_hal_cb.nvm_cb.fpm_size, p);
+
+            /* clear all flags which may be set during previous initialization */
+            nfc_hal_cb.nvm_cb.flags = 0;
+
+            /* Set patch present flag */
+            if ((nfc_hal_cb.nvm_cb.fpm_size) || (nfc_hal_cb.nvm_cb.lpm_size))
+                nfc_hal_cb.nvm_cb.flags |= NFC_HAL_NVM_FLAGS_PATCH_PRESENT;
+
+            /* LPMPatchCodeHasBadCRC (if not bad crc, then indicate LPM patch is present in nvm) */
+            STREAM_TO_UINT8 (u8, p);
+            if (u8)
+            {
+                /* LPM patch in NVM fails CRC check */
+                nfc_hal_cb.nvm_cb.flags |= NFC_HAL_NVM_FLAGS_LPM_BAD;
+            }
+
+
+            /* FPMPatchCodeHasBadCRC (if not bad crc, then indicate LPM patch is present in nvm) */
+            STREAM_TO_UINT8 (u8, p);
+            if (u8)
+            {
+                /* FPM patch in NVM fails CRC check */
+                nfc_hal_cb.nvm_cb.flags |= NFC_HAL_NVM_FLAGS_FPM_BAD;
+            }
+
+            /* Check if downloading patch to RAM only (no NVM) */
+            STREAM_TO_UINT8 (nfc_hal_cb.nvm_cb.nvm_type, p);
+            if (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_NONE)
+            {
+                nfc_hal_cb.nvm_cb.flags |= NFC_HAL_NVM_FLAGS_NO_NVM;
+            }
+
+            /* let platform update baudrate or download patch */
+            NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_APP_COMPLETE);
+            nfc_hal_post_reset_init (nfc_hal_cb.dev_cb.brcm_hw_id, nfc_hal_cb.nvm_cb.nvm_type);
+        }
+        else if (p_cback)
+        {
+            (*p_cback) ((tNFC_HAL_NCI_EVT) (op_code),
+                        p_msg->len,
+                        (UINT8 *) (p_msg + 1) + p_msg->offset);
+        }
+        else if (op_code == NFC_VS_SEC_PATCH_AUTH_EVT)
+        {
+            HAL_TRACE_DEBUG0 ("signature!!");
+            nfc_hal_prm_nci_command_complete_cback ((tNFC_HAL_NCI_EVT) (op_code),
+                                                    p_msg->len,
+                                                    (UINT8 *) (p_msg + 1) + p_msg->offset);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_send_nci_cmd
+**
+** Description      Send NCI command to NFCC while initializing BRCM NFCC
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_dm_send_nci_cmd (const UINT8 *p_data, UINT16 len, tNFC_HAL_NCI_CBACK *p_cback)
+{
+    NFC_HDR *p_buf;
+    UINT8  *ps;
+
+    HAL_TRACE_DEBUG1 ("nfc_hal_dm_send_nci_cmd (): nci_wait_rsp = 0x%x", nfc_hal_cb.ncit_cb.nci_wait_rsp);
+
+    if (nfc_hal_cb.ncit_cb.nci_wait_rsp != NFC_HAL_WAIT_RSP_NONE)
+    {
+        HAL_TRACE_ERROR0 ("nfc_hal_dm_send_nci_cmd(): no command window");
+        return;
+    }
+
+    if ((p_buf = (NFC_HDR *)GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
+    {
+        nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_VSC;
+
+        p_buf->offset = NFC_HAL_NCI_MSG_OFFSET_SIZE;
+        p_buf->event  = NFC_HAL_EVT_TO_NFC_NCI;
+        p_buf->len    = len;
+
+        memcpy ((UINT8*) (p_buf + 1) + p_buf->offset, p_data, len);
+
+        /* Keep a copy of the command and send to NCI transport */
+
+        /* save the message header to double check the response */
+        ps   = (UINT8 *)(p_buf + 1) + p_buf->offset;
+        memcpy(nfc_hal_cb.ncit_cb.last_hdr, ps, NFC_HAL_SAVED_HDR_SIZE);
+        memcpy(nfc_hal_cb.ncit_cb.last_cmd, ps + NCI_MSG_HDR_SIZE, NFC_HAL_SAVED_CMD_SIZE);
+
+        /* save the callback for NCI VSCs */
+        nfc_hal_cb.ncit_cb.p_vsc_cback = (void *)p_cback;
+
+        nfc_hal_nci_send_cmd (p_buf);
+
+        /* start NFC command-timeout timer */
+        nfc_hal_main_start_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer, (UINT16)(NFC_HAL_TTYPE_NCI_WAIT_RSP),
+                                        ((UINT32) NFC_HAL_CMD_TOUT) * QUICK_TIMER_TICKS_PER_SEC / 1000);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_send_pend_cmd
+**
+** Description      Send a command to NFCC
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_dm_send_pend_cmd (void)
+{
+    NFC_HDR *p_buf = nfc_hal_cb.ncit_cb.p_pend_cmd;
+    UINT8  *p;
+
+    if (p_buf == NULL)
+        return;
+
+    /* check low power mode state */
+    if (!nfc_hal_dm_power_mode_execute (NFC_HAL_LP_TX_DATA_EVT))
+    {
+        return;
+    }
+
+    if (nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_PROP)
+    {
+#if (NFC_HAL_TRACE_PROTOCOL == TRUE)
+        DispHciCmd (p_buf);
+#endif
+
+        /* save the message header to double check the response */
+        p = (UINT8 *)(p_buf + 1) + p_buf->offset;
+        memcpy(nfc_hal_cb.ncit_cb.last_hdr, p, NFC_HAL_SAVED_HDR_SIZE);
+
+        /* add packet type for BT message */
+        p_buf->offset--;
+        p_buf->len++;
+
+        p  = (UINT8 *) (p_buf + 1) + p_buf->offset;
+        *p = HCIT_TYPE_COMMAND;
+
+        USERIAL_Write (USERIAL_NFC_PORT, p, p_buf->len);
+
+        GKI_freebuf (p_buf);
+        nfc_hal_cb.ncit_cb.p_pend_cmd = NULL;
+
+        /* start NFC command-timeout timer */
+        nfc_hal_main_start_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer, (UINT16)(NFC_HAL_TTYPE_NCI_WAIT_RSP),
+                                        ((UINT32) NFC_HAL_CMD_TOUT) * QUICK_TIMER_TICKS_PER_SEC / 1000);
+
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_send_bt_cmd
+**
+** Description      Send BT message to NFCC while initializing BRCM NFCC
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_dm_send_bt_cmd (const UINT8 *p_data, UINT16 len, tNFC_HAL_BTVSC_CPLT_CBACK *p_cback)
+{
+    NFC_HDR *p_buf;
+    char buff[300];
+    char tmp[4];
+    buff[0] = 0;
+    int i;
+
+    HAL_TRACE_DEBUG1 ("nfc_hal_dm_send_bt_cmd (): nci_wait_rsp = 0x%x", nfc_hal_cb.ncit_cb.nci_wait_rsp);
+
+    for (i = 0; i < len; i++)
+    {
+        sprintf (tmp, "%02x ", p_data[i]);
+        strcat(buff, tmp);
+    }
+    HAL_TRACE_DEBUG2 ("nfc_hal_dm_send_bt_cmd (): HCI Write (%d bytes): %s", len, buff);
+
+    if (nfc_hal_cb.ncit_cb.nci_wait_rsp != NFC_HAL_WAIT_RSP_NONE)
+    {
+        HAL_TRACE_ERROR0 ("nfc_hal_dm_send_bt_cmd(): no command window");
+        return;
+    }
+
+    if ((p_buf = (NFC_HDR *) GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
+    {
+        nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_PROP;
+
+        p_buf->offset = NFC_HAL_NCI_MSG_OFFSET_SIZE;
+        p_buf->len    = len;
+
+        memcpy ((UINT8*) (p_buf + 1) + p_buf->offset, p_data, len);
+
+        /* save the callback for NCI VSCs)  */
+        nfc_hal_cb.ncit_cb.p_vsc_cback = (void *)p_cback;
+
+        nfc_hal_cb.ncit_cb.p_pend_cmd = p_buf;
+        if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_IDLE)
+        {
+            NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_CONTROL_DONE);
+            nfc_hal_cb.p_stack_cback (HAL_NFC_REQUEST_CONTROL_EVT, HAL_NFC_STATUS_OK);
+            return;
+        }
+
+        nfc_hal_dm_send_pend_cmd();
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_set_nfc_wake
+**
+** Description      Set NFC_WAKE line
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_dm_set_nfc_wake (UINT8 cmd)
+{
+    HAL_TRACE_DEBUG1 ("nfc_hal_dm_set_nfc_wake () %s",
+                      (cmd == NFC_HAL_ASSERT_NFC_WAKE ? "ASSERT" : "DEASSERT"));
+
+    /*
+    **  nfc_wake_active_mode             cmd              result of voltage on NFC_WAKE
+    **
+    **  NFC_HAL_LP_ACTIVE_LOW (0)    NFC_HAL_ASSERT_NFC_WAKE (0)    pull down NFC_WAKE (GND)
+    **  NFC_HAL_LP_ACTIVE_LOW (0)    NFC_HAL_DEASSERT_NFC_WAKE (1)  pull up NFC_WAKE (VCC)
+    **  NFC_HAL_LP_ACTIVE_HIGH (1)   NFC_HAL_ASSERT_NFC_WAKE (0)    pull up NFC_WAKE (VCC)
+    **  NFC_HAL_LP_ACTIVE_HIGH (1)   NFC_HAL_DEASSERT_NFC_WAKE (1)  pull down NFC_WAKE (GND)
+    */
+
+    if (cmd == nfc_hal_cb.dev_cb.nfc_wake_active_mode)
+        UPIO_Set (UPIO_GENERAL, NFC_HAL_LP_NFC_WAKE_GPIO, UPIO_OFF); /* pull down NFC_WAKE */
+    else
+        UPIO_Set (UPIO_GENERAL, NFC_HAL_LP_NFC_WAKE_GPIO, UPIO_ON);  /* pull up NFC_WAKE */
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_power_mode_execute
+**
+** Description      If snooze mode is enabled in full power mode,
+**                     Assert NFC_WAKE before sending data
+**                     Deassert NFC_WAKE when idle timer expires
+**
+** Returns          TRUE if DH can send data to NFCC
+**
+*******************************************************************************/
+BOOLEAN nfc_hal_dm_power_mode_execute (tNFC_HAL_LP_EVT event)
+{
+    BOOLEAN send_to_nfcc = FALSE;
+
+    HAL_TRACE_DEBUG1 ("nfc_hal_dm_power_mode_execute () event = %d", event);
+
+    if (nfc_hal_cb.dev_cb.power_mode == NFC_HAL_POWER_MODE_FULL)
+    {
+        if (nfc_hal_cb.dev_cb.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE)
+        {
+            /* if any transport activity */
+            if (  (event == NFC_HAL_LP_TX_DATA_EVT)
+                ||(event == NFC_HAL_LP_RX_DATA_EVT)  )
+            {
+                /* if idle timer is not running */
+                if (nfc_hal_cb.dev_cb.lp_timer.in_use == FALSE)
+                {
+                    nfc_hal_dm_set_nfc_wake (NFC_HAL_ASSERT_NFC_WAKE);
+                }
+
+                /* start or extend idle timer */
+                nfc_hal_main_start_quick_timer (&nfc_hal_cb.dev_cb.lp_timer, 0x00,
+                                                ((UINT32) NFC_HAL_LP_IDLE_TIMEOUT) * QUICK_TIMER_TICKS_PER_SEC / 1000);
+            }
+            else if (event == NFC_HAL_LP_TIMEOUT_EVT)
+            {
+                /* let NFCC go to snooze mode */
+                nfc_hal_dm_set_nfc_wake (NFC_HAL_DEASSERT_NFC_WAKE);
+            }
+        }
+
+        send_to_nfcc = TRUE;
+    }
+
+    return (send_to_nfcc);
+}
+
+/*******************************************************************************
+**
+** Function         nci_brcm_lp_timeout_cback
+**
+** Description      callback function for low power timeout
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nci_brcm_lp_timeout_cback (void *p_tle)
+{
+    HAL_TRACE_DEBUG0 ("nci_brcm_lp_timeout_cback ()");
+
+    nfc_hal_dm_power_mode_execute (NFC_HAL_LP_TIMEOUT_EVT);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_pre_init_nfcc
+**
+** Description      This function initializes Broadcom specific control blocks for
+**                  NCI transport
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_dm_pre_init_nfcc (void)
+{
+    HAL_TRACE_DEBUG0 ("nfc_hal_dm_pre_init_nfcc ()");
+
+    /* if it was waiting for core reset notification after raising REG_PU */
+    if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_NFCC_ENABLE)
+    {
+        nfc_hal_dm_send_get_build_info_cmd ();
+    }
+    /* if it was waiting for core reset notification after setting Xtal */
+    else if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_POST_XTAL_SET)
+    {
+        {
+            /* Core reset ntf after xtal setting indicating NFCC loaded patch from NVM */
+            NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_PATCH_INFO);
+
+            nfc_hal_dm_send_nci_cmd (nfc_hal_dm_get_patch_version_cmd, NCI_MSG_HDR_SIZE, NULL);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_shutting_down_nfcc
+**
+** Description      This function initializes Broadcom specific control blocks for
+**                  NCI transport
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_dm_shutting_down_nfcc (void)
+{
+    HAL_TRACE_DEBUG0 ("nfc_hal_dm_shutting_down_nfcc ()");
+
+    nfc_hal_cb.dev_cb.initializing_state = NFC_HAL_INIT_STATE_CLOSING;
+
+    /* reset low power mode variables */
+    if (  (nfc_hal_cb.dev_cb.power_mode  == NFC_HAL_POWER_MODE_FULL)
+        &&(nfc_hal_cb.dev_cb.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE)  )
+    {
+        nfc_hal_dm_set_nfc_wake (NFC_HAL_ASSERT_NFC_WAKE);
+    }
+
+    nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_NONE;
+
+    nfc_hal_cb.dev_cb.power_mode  = NFC_HAL_POWER_MODE_FULL;
+    nfc_hal_cb.dev_cb.snooze_mode = NFC_HAL_LP_SNOOZE_MODE_NONE;
+
+    /* Stop all timers */
+    nfc_hal_main_stop_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
+    nfc_hal_main_stop_quick_timer (&nfc_hal_cb.dev_cb.lp_timer);
+    nfc_hal_main_stop_quick_timer (&nfc_hal_cb.prm.timer);
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+    nfc_hal_cb.hci_cb.hcp_conn_id = 0;
+    nfc_hal_main_stop_quick_timer (&nfc_hal_cb.hci_cb.hci_timer);
+#endif
+    nfc_hal_main_stop_quick_timer (&nfc_hal_cb.timer);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_init
+**
+** Description      This function initializes Broadcom specific control blocks for
+**                  NCI transport
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_dm_init (void)
+{
+    HAL_TRACE_DEBUG0 ("nfc_hal_dm_init ()");
+
+    nfc_hal_cb.dev_cb.lp_timer.p_cback = nci_brcm_lp_timeout_cback;
+
+    nfc_hal_cb.ncit_cb.nci_wait_rsp_timer.p_cback = nfc_hal_nci_cmd_timeout_cback;
+
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+    nfc_hal_cb.hci_cb.hci_timer.p_cback = nfc_hal_hci_timeout_cback;
+#endif
+
+    nfc_hal_cb.pre_discover_done        = FALSE;
+
+    nfc_post_reset_cb.spd_nvm_detection_cur_count = 0;
+    nfc_post_reset_cb.spd_skip_on_power_cycle     = FALSE;
+
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcDevInitDone
+**
+** Description      Notify that pre-initialization of NFCC is complete
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcPreInitDone (tHAL_NFC_STATUS status)
+{
+    HAL_TRACE_DEBUG1 ("HAL_NfcPreInitDone () status=%d", status);
+
+    if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_APP_COMPLETE)
+    {
+        NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+
+        nfc_hal_main_pre_init_done (status);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcReInit
+**
+** Description      This function is called to restart initialization after REG_PU
+**                  toggled because of failure to detect NVM type or download patchram.
+**
+** Note             This function should be called only during the HAL init process
+**
+** Returns          HAL_NFC_STATUS_OK if successfully initiated
+**                  HAL_NFC_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tHAL_NFC_STATUS HAL_NfcReInit (void)
+{
+    tHAL_NFC_STATUS status = HAL_NFC_STATUS_FAILED;
+
+    HAL_TRACE_DEBUG1 ("HAL_NfcReInit () init st=0x%x", nfc_hal_cb.dev_cb.initializing_state);
+    if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_APP_COMPLETE)
+    {
+        {
+            /* Wait for NFCC to enable - Core reset notification */
+            NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_NFCC_ENABLE);
+
+            /* NFCC Enable timeout */
+            nfc_hal_main_start_quick_timer (&nfc_hal_cb.timer, NFC_HAL_TTYPE_NFCC_ENABLE,
+                                            ((p_nfc_hal_cfg->nfc_hal_nfcc_enable_timeout)*QUICK_TIMER_TICKS_PER_SEC)/1000);
+        }
+
+        status = HAL_NFC_STATUS_OK;
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_set_snooze_mode_cback
+**
+** Description      This is snooze update complete callback.
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfc_hal_dm_set_snooze_mode_cback (tNFC_HAL_BTVSC_CPLT *pData)
+{
+    UINT8             status = pData->p_param_buf[0];
+    tHAL_NFC_STATUS   hal_status;
+    tHAL_NFC_STATUS_CBACK *p_cback;
+
+    /* if it is completed */
+    if (status == HCI_SUCCESS)
+    {
+        /* update snooze mode */
+        nfc_hal_cb.dev_cb.snooze_mode = nfc_hal_cb.dev_cb.new_snooze_mode;
+
+        nfc_hal_dm_set_nfc_wake (NFC_HAL_ASSERT_NFC_WAKE);
+
+        if ( nfc_hal_cb.dev_cb.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE)
+        {
+            /* start idle timer */
+            nfc_hal_main_start_quick_timer (&nfc_hal_cb.dev_cb.lp_timer, 0x00,
+                                            ((UINT32) NFC_HAL_LP_IDLE_TIMEOUT) * QUICK_TIMER_TICKS_PER_SEC / 1000);
+        }
+        else
+        {
+            nfc_hal_main_stop_quick_timer (&nfc_hal_cb.dev_cb.lp_timer);
+        }
+        hal_status = HAL_NFC_STATUS_OK;
+    }
+    else
+    {
+        hal_status = HAL_NFC_STATUS_FAILED;
+    }
+
+    if (nfc_hal_cb.dev_cb.p_prop_cback)
+    {
+        p_cback = nfc_hal_cb.dev_cb.p_prop_cback;
+        nfc_hal_cb.dev_cb.p_prop_cback = NULL;
+        (*p_cback) (hal_status);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcSetSnoozeMode
+**
+** Description      Set snooze mode
+**                  snooze_mode
+**                      NFC_HAL_LP_SNOOZE_MODE_NONE - Snooze mode disabled
+**                      NFC_HAL_LP_SNOOZE_MODE_UART - Snooze mode for UART
+**                      NFC_HAL_LP_SNOOZE_MODE_SPI_I2C - Snooze mode for SPI/I2C
+**
+**                  idle_threshold_dh/idle_threshold_nfcc
+**                      Idle Threshold Host in 100ms unit
+**
+**                  nfc_wake_active_mode/dh_wake_active_mode
+**                      NFC_HAL_LP_ACTIVE_LOW - high to low voltage is asserting
+**                      NFC_HAL_LP_ACTIVE_HIGH - low to high voltage is asserting
+**
+**                  p_snooze_cback
+**                      Notify status of operation
+**
+** Returns          tHAL_NFC_STATUS
+**
+*******************************************************************************/
+tHAL_NFC_STATUS HAL_NfcSetSnoozeMode (UINT8 snooze_mode,
+                                      UINT8 idle_threshold_dh,
+                                      UINT8 idle_threshold_nfcc,
+                                      UINT8 nfc_wake_active_mode,
+                                      UINT8 dh_wake_active_mode,
+                                      tHAL_NFC_STATUS_CBACK *p_snooze_cback)
+{
+    UINT8 cmd[NFC_HAL_BT_HCI_CMD_HDR_SIZE + HCI_BRCM_WRITE_SLEEP_MODE_LENGTH];
+    UINT8 *p;
+
+    HAL_TRACE_API1 ("HAL_NfcSetSnoozeMode (): snooze_mode = %d", snooze_mode);
+
+    nfc_hal_cb.dev_cb.new_snooze_mode      = snooze_mode;
+    nfc_hal_cb.dev_cb.nfc_wake_active_mode = nfc_wake_active_mode;
+    nfc_hal_cb.dev_cb.p_prop_cback         = p_snooze_cback;
+
+    p = cmd;
+
+    /* Add the HCI command */
+    UINT16_TO_STREAM (p, HCI_BRCM_WRITE_SLEEP_MODE);
+    UINT8_TO_STREAM  (p, HCI_BRCM_WRITE_SLEEP_MODE_LENGTH);
+
+    memset (p, 0x00, HCI_BRCM_WRITE_SLEEP_MODE_LENGTH);
+
+    UINT8_TO_STREAM  (p, snooze_mode);          /* Sleep Mode               */
+
+    UINT8_TO_STREAM  (p, idle_threshold_dh);    /* Idle Threshold Host      */
+    UINT8_TO_STREAM  (p, idle_threshold_nfcc);  /* Idle Threshold HC        */
+    UINT8_TO_STREAM  (p, nfc_wake_active_mode); /* BT Wake Active Mode      */
+    UINT8_TO_STREAM  (p, dh_wake_active_mode);  /* Host Wake Active Mode    */
+
+    nfc_hal_dm_send_bt_cmd (cmd,
+                            NFC_HAL_BT_HCI_CMD_HDR_SIZE + HCI_BRCM_WRITE_SLEEP_MODE_LENGTH,
+                            nfc_hal_dm_set_snooze_mode_cback);
+    return (NCI_STATUS_OK);
+}
+
+
+
+
+
+
+
+
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_dm_cfg.c b/halimpl/bcm2079x/hal/hal/nfc_hal_dm_cfg.c
new file mode 100644
index 0000000..7c8e1e8
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_dm_cfg.c
@@ -0,0 +1,182 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2011-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ *
+ *  This file contains compile-time configurable constants for BRCM HAL
+ *  modules
+ *
+ ******************************************************************************/
+#include "nfc_hal_int.h"
+#include "nci_defs.h"
+#include "nfc_brcm_defs.h"
+
+/* the SetConfig at start up*/
+UINT8 nfc_hal_start_up_cfg[] = {
+    /* TLV len */   31,
+    /* B0 */        NCI_PARAM_ID_EMVCO_ENABLE,
+    /* B1 */        1,
+    /* B2 */        1,     /* (1 = enable emvco mode, 0 = disable emvco mode) Default = 0.*/
+    /* B3 */        NCI_PARAM_ID_CONTINUE_MODE, /* NFCC will restart discovery after deactivated */
+    /* B4 */        1,
+    /* B5 */        1,     /* (1 = enable, 0 = disable) Default = 0.*/
+    /* B6 */        NCI_PARAM_ID_RFU_CONFIG,
+    /* B7 */        0x14,
+    /* B8 */        0x00,
+    /* B9 */        0x00,
+    /* B10*/        0x00,
+    /* B11*/        0x00,
+    /* B12*/        0x0E,
+    /* B13*/        0xE8,
+    /* B14*/        0xF0,
+    /* B15*/        0x55,
+    /* B16*/        0x00,
+    /* B17*/        0x0F, /* CE3 SO delay in sec */
+    /* B18*/        0x00,
+    /* B19*/        0x00,
+    /* B20*/        0x00,
+    /* B21*/        0x00,
+    /* B22*/        0x00,
+    /* B23*/        0x00,
+    /* B24*/        0x00,
+    /* B25*/        0x00,
+    /* B26*/        0x00,
+    /* B27*/        0x00,
+    /* B28*/        NCI_PARAM_ID_ACT_ORDER, /* polling sequence */
+    /* B29*/        1,
+    /* B30*/        1,     /* (1 = active mode polling before passive, 0 = passive polling first) Default = 0.*/
+};
+
+UINT8 *p_nfc_hal_dm_start_up_cfg = (UINT8 *) nfc_hal_start_up_cfg;
+
+/* the VSCs at start up:
+ * The VSCs are specified in TLV format similar to nfa_start_up_cfg[]
+ * first byte is the TLV total len.
+ * B0 is the first T; i.e. the opcode for the VSC
+ * B1 is the len of the VSC parameters/payload
+ * */
+UINT8 nfc_hal_dm_start_up_vsc_cfg[] = {
+    /* TLV len */   5,
+    /* B0 */        NCI_MTS_CMD|NCI_GID_PROP,
+    /* B1 */        NCI_MSG_FRAME_LOG,
+    /* B2 */        2,
+    /* B3 */        0,  /* 1 to enable RF frames */
+    /* B4 */        1   /* 1 to enable SWP frames */
+};
+
+UINT8 *p_nfc_hal_dm_start_up_vsc_cfg = NULL;
+
+/* the SetConfig at HAL_NfcPreDiscover. This is done once after HAL_NfcOpen */
+UINT8 nfc_hal_pre_discover_cfg[] = {
+    /* TLV len */   0x0A,
+    /* B0 */        NCI_PARAM_ID_SWPCFG,
+    /* B1 */        0x08,
+    /* B2 */        0x01,
+    /* B3 */        0x08,
+    /* B4 */        0x00,
+    /* B5 */        0x04,
+    /* B6 */        0x80,
+    /* B7 */        0xC3,
+    /* B8 */        0xC9,
+    /* B9 */        0x01
+};
+
+UINT8 *p_nfc_hal_pre_discover_cfg = NULL;
+
+/* LPTD parameters (LowPowerTagDetection)
+ * This is typical values for 20791B2
+ * The timing and threshold parameters used for a customer handset/hardware may vary
+ * depending on antenna and should be verified during a customer testing phase.
+ * the data fields without comments are too complicated. Please see ""
+ * */
+const UINT8 nfc_hal_dm_lptd_cfg[] =
+{
+    21,             /* total TLV length excluding itself */
+    NCI_PARAM_ID_TAGSNIFF_CFG,  /* type */
+    19,             /* length */
+    0x01,           /* B0 enable: 0/disable, 1/enable*/
+    0x02,           /* B1 poll count: number of full power poll before starting lptd poll */
+    0xFF,           /* B2 sniff count lsb: number of lptd poll before switching to full power poll */
+    0xFF,           /* B3 sniff count msb */
+    0x80,           /* B4 threshold: Bigger thresholds give a smaller LPTD range but more immunity to false detections. Smaller thresholds increase LPTD range at the cost of greater likelihood of false detections. */
+    0x40,           /* B5 delay lsb: delay (us) to sampling power */
+    0x00,           /* B6 delay msb */
+    0x40,           /* B7 carrier threshold lsb */
+    0x00,           /* B8 carrier threshold msb */
+    0x80,           /* B9 mode: Bitwise variable used to enable various algorithm modes.*/
+    0x80,           /* B10 0-offset lsb */
+    0x00,           /* B11 0-offset msb */
+    0x10,           /* B12 field sense time lsb */
+    0x00,           /* B13 field sense time msb */
+    0x00,           /* B14 false detect threshold lsb: 0x00 to disable LPTD NTF. The number of false tag detections to resport LPTD NTF. */
+    0x00,           /* B15 false detect threshold msb. A false tag detect - full poll results in no tag being detected.*/
+    0x75,           /* B16 mode1; Bitwise variable used to enable various algorithm modes. */
+    0x0D,           /* B17 lptd ant cfg rx */
+    0x30,           /* B18 lptd rdr cfg ve */
+};
+
+UINT8 *p_nfc_hal_dm_lptd_cfg = (UINT8 *) &nfc_hal_dm_lptd_cfg[0];
+
+/*
+** NFCC has a table which has 9 XTAL frequencies: 9.6, 13, 16.2,  19.2, 24, 26, 38.4, 52 and 37.4 in MHz.
+** For these 9 xtal frequencies, host doesn't need to configure PLL325.
+** For 43341, host doesn't need to configure it at all.
+*/
+UINT8 *p_nfc_hal_dm_pll_325_cfg = NULL;
+
+/*
+** Proprietary pre-set is required, if not NULL.
+*/
+tNFC_HAL_DM_PRE_SET_MEM *p_nfc_hal_dm_pre_set_mem = NULL;
+
+tNFC_HAL_CFG nfc_hal_cfg =
+{
+    FALSE,                                  /* set nfc_hal_prm_nvm_required to TRUE, if the platform wants to abort PRM process without NVM */
+    (UINT16) NFC_HAL_NFCC_ENABLE_TIMEOUT,   /* max time to wait for RESET NTF after setting REG_PU to high
+                                            ** If NFCC doesn't have NVM or cannot load patch from NVM without Xtal setting
+                                            ** then set it to short to optimize bootup time because NFCC cannot send RESET NTF.
+                                            ** Otherwise, it depends on NVM type and size of patchram.
+                                            */
+    (UINT16) NFC_HAL_NFCC_ENABLE_TIMEOUT    /* max time to wait for RESET NTF after setting Xtal frequency
+                                            ** It depends on NVM type and size of patchram.
+                                            */
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+    ,
+    TRUE,                                   /* set nfc_hal_first_boot to TRUE, if platform enables NFC for the first time after bootup */
+    (HAL_NFC_HCI_UICC0_HOST | HAL_NFC_HCI_UICC1_HOST | HAL_NFC_HCI_UICC2_HOST)  /* Set bit(s) for supported UICC(s) */
+#endif
+};
+
+tNFC_HAL_CFG *p_nfc_hal_cfg= (tNFC_HAL_CFG *) &nfc_hal_cfg;
+
+const UINT8 nfc_hal_dm_xtal_params_cfg [] =
+{
+    8,             /* length */
+    0x00,           /* B0 Rfpll_cfg_pll_xtal_div_2                  */
+    0x00,           /* B1 Rfpll_cfg_pll_vcocal1_0_cal_ref_timeout   */
+    0x00,           /* B2 Rfpll_cfg_pll_vcocal2_cal_count           */
+    0x00,           /* B3 Rfpll_cfg_pll_vcocal3_cal_count           */
+    0x00,           /* B4 Rfpll_cfg_pll_dsm_b_msb_wild_base         */
+    0x00,           /* B5 Rfpll_cfg_pll_dsm_b_lsb_3_wild_base_3     */
+    0x00,           /* B6 Rfpll_cfg_pll_dsm_b_lsb_2_wild_base_2     */
+    0x00            /* B7 Rfpll_cfg_pll_dsm_b_lsb_1_wild_base_1     */
+};
+
+/* By default, the XTAL command does not need these extra params. */
+UINT8 *p_nfc_hal_dm_xtal_params_cfg = NULL;
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_hci.c b/halimpl/bcm2079x/hal/hal/nfc_hal_hci.c
new file mode 100644
index 0000000..6b573d5
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_hci.c
@@ -0,0 +1,817 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ *
+ *  Vendor-specific handler for HCI events
+ *
+ ******************************************************************************/
+#include "gki.h"
+#include "nfc_hal_target.h"
+#include "nfc_hal_api.h"
+#include "nfc_hal_int.h"
+
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+
+#include "nfc_hal_nv_ci.h"
+#include "nfc_hal_nv_co.h"
+
+#include <string.h>
+
+
+#ifndef NFC_HAL_HCI_NV_READ_TIMEOUT
+#define NFC_HAL_HCI_NV_READ_TIMEOUT    1000
+#endif
+
+#ifndef NFC_HAL_HCI_NFCC_RSP_TIMEOUT
+#define NFC_HAL_HCI_NFCC_RSP_TIMEOUT   3000
+#endif
+
+#define NFC_HAL_HCI_NETWK_CMD_TYPE_A_CE_PIPE_INFO_OFFSET    0x0C
+#define NFC_HAL_HCI_NETWK_CMD_TYPE_B_CE_PIPE_INFO_OFFSET    0x32
+#define NFC_HAL_HCI_NETWK_CMD_TYPE_BP_CE_PIPE_INFO_OFFSET   0x7F
+#define NFC_HAL_HCI_NETWK_CMD_TYPE_F_CE_PIPE_INFO_OFFSET    0xB4
+
+#define NFC_HAL_HCI_PIPE_VALID_MASK                         0x80
+
+#define NFC_HAL_HCI_FIRST_BOOT_SESSION_ID_0_VAL             0xFF
+#define NFC_HAL_HCI_NEXT_BOOT_SESSION_ID_0_VAL              0xFE
+
+/* Version string for BCM20791B3 */
+const UINT8 NFC_HAL_DM_BCM20791B3_STR[]   = "20791B3";
+#define NFC_HAL_DM_BCM20791B3_STR_LEN     (sizeof (NFC_HAL_DM_BCM20791B3_STR)-1)
+
+/* Version string for BCM20791B4 */
+const UINT8 NFC_HAL_DM_BCM20791B4_STR[]   = "20791B4";
+#define NFC_HAL_DM_BCM20791B4_STR_LEN     (sizeof (NFC_HAL_DM_BCM20791B4_STR)-1)
+
+/* Version string for BCM43341B0 */
+const UINT8 NFC_HAL_DM_BCM43341B0_STR[]   = "43341B0";
+#define NFC_HAL_DM_BCM43341B0_STR_LEN     (sizeof (NFC_HAL_DM_BCM43341B0_STR)-1)
+
+extern tNFC_HAL_CFG *p_nfc_hal_cfg;
+/****************************************************************************
+** Internal function prototypes
+****************************************************************************/
+static void nfc_hal_hci_set_next_hci_netwk_config (UINT8 block);
+static void nfc_hal_hci_remove_dyn_pipe_to_uicc1 (void);
+static void nfc_hal_hci_handle_nv_read (UINT8 block, tHAL_NFC_STATUS status, UINT16 size);
+static void nfc_hal_hci_init_complete (tHAL_NFC_STATUS status);
+static void nfc_hal_hci_vsc_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data);
+
+/*******************************************************************************
+**
+** Function         nfc_hal_hci_evt_hdlr
+**
+** Description      Processing event for NFA HCI
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfc_hal_hci_evt_hdlr (tNFC_HAL_HCI_EVENT_DATA *p_evt_data)
+{
+    HAL_TRACE_DEBUG0 ("nfc_hal_hci_evt_hdlr ()");
+
+    switch (p_evt_data->hdr.event)
+    {
+    case NFC_HAL_HCI_RSP_NV_READ_EVT:
+        if (  (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf && (p_evt_data->nv_read.block == HC_F3_NV_BLOCK || p_evt_data->nv_read.block == HC_F4_NV_BLOCK || p_evt_data->nv_read.block == HC_F5_NV_BLOCK))
+            ||(nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf && p_evt_data->nv_read.block == HC_F2_NV_BLOCK)  )
+        {
+            nfc_hal_hci_handle_nv_read (p_evt_data->nv_read.block, p_evt_data->nv_read.status, p_evt_data->nv_read.size);
+        }
+        else
+        {
+            /* Invalid block or no buffer, Ignore */
+            HAL_TRACE_ERROR1 ("nfc_hal_hci_evt_hdlr: No buffer for handling read NV block: 0x%02x", p_evt_data->nv_read.block);
+        }
+        break;
+
+    case NFC_HAL_HCI_RSP_NV_WRITE_EVT:
+        /* NV Ram write completed - nothing to do... */
+        break;
+
+    default:
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_hci_enable
+**
+** Description      Program nv data on to controller
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_hci_enable (void)
+{
+
+    UINT8 *p_hci_netwk_cmd;
+
+    HAL_TRACE_DEBUG0 ("nfc_hal_hci_enable ()");
+
+    if (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_NONE)
+    {
+        HAL_TRACE_DEBUG1 ("nfc_hal_hci_enable (): No HCI NETWK CMD to send for NVM Type: 0x%02x", nfc_hal_cb.nvm_cb.nvm_type);
+        nfc_hal_hci_init_complete (HAL_NFC_STATUS_OK);
+        return;
+    }
+
+    if (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf)
+    {
+        p_hci_netwk_cmd = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf - NCI_MSG_HDR_SIZE);
+        GKI_freebuf (p_hci_netwk_cmd);
+        nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf = NULL;
+    }
+
+    if (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf)
+    {
+        p_hci_netwk_cmd = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf - NCI_MSG_HDR_SIZE);
+        GKI_freebuf (p_hci_netwk_cmd);
+        nfc_hal_cb.hci_cb.p_hci_netwk_info_buf = NULL;
+    }
+
+    if (  (p_nfc_hal_cfg->nfc_hal_hci_uicc_support & HAL_NFC_HCI_UICC0_HOST)
+        ||((p_nfc_hal_cfg->nfc_hal_hci_uicc_support & HAL_NFC_HCI_UICC1_HOST) && ((!nfc_hal_cb.hci_cb.hci_fw_workaround) || (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_EEPROM)))
+        ||(p_nfc_hal_cfg->nfc_hal_hci_uicc_support & HAL_NFC_HCI_UICC2_HOST)  )
+    {
+        if ((p_hci_netwk_cmd = (UINT8 *) GKI_getbuf (NCI_MSG_HDR_SIZE + NFC_HAL_HCI_NETWK_INFO_SIZE)) == NULL)
+        {
+            HAL_TRACE_ERROR0 ("nfc_hal_hci_enable: unable to allocate buffer for reading hci network info from nvram");
+            nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
+        }
+        else
+        {
+            nfc_hal_cb.hci_cb.p_hci_netwk_info_buf   = (UINT8 *) (p_hci_netwk_cmd + NCI_MSG_HDR_SIZE);
+            nfc_hal_cb.hci_cb.hci_netwk_config_block = 0;
+            if (p_nfc_hal_cfg->nfc_hal_hci_uicc_support & HAL_NFC_HCI_UICC0_HOST)
+            {
+                memset (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, 0, NFC_HAL_HCI_NETWK_INFO_SIZE);
+                nfc_hal_nv_co_read ((UINT8 *) nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, NFC_HAL_HCI_NETWK_INFO_SIZE, HC_F3_NV_BLOCK);
+                nfc_hal_main_start_quick_timer (&nfc_hal_cb.hci_cb.hci_timer, NFC_HAL_HCI_VSC_TIMEOUT_EVT, NFC_HAL_HCI_NV_READ_TIMEOUT);
+            }
+            else
+            {
+                HAL_TRACE_DEBUG1 ("nfc_hal_hci_enable (): Skip send F3 HCI NETWK CMD for UICC Mask: 0x%02x", p_nfc_hal_cfg->nfc_hal_hci_uicc_support);
+                nfc_hal_hci_set_next_hci_netwk_config (HC_F3_NV_BLOCK);
+            }
+
+        }
+    }
+    else
+    {
+        HAL_TRACE_DEBUG2 ("nfc_hal_hci_enable (): No HCI NETWK CMD to send for UICC Mask: 0x%02x & NVM Type: 0x%02x", p_nfc_hal_cfg->nfc_hal_hci_uicc_support, nfc_hal_cb.nvm_cb.nvm_type);
+        nfc_hal_hci_set_next_hci_netwk_config (HC_F2_NV_BLOCK);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_hci_handle_build_info
+**
+** Description      handle build info evt
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_hci_handle_build_info (UINT8 chipverlen, UINT8 *p_chipverstr)
+{
+    HAL_TRACE_DEBUG0 ("nfc_hal_hci_handle_build_info ()");
+
+    if ((chipverlen == NFC_HAL_DM_BCM20791B3_STR_LEN) && (memcmp (NFC_HAL_DM_BCM20791B3_STR, p_chipverstr, NFC_HAL_DM_BCM20791B3_STR_LEN) == 0))
+    {
+        /* BCM2079B3 FW - eSE restarted for patch download */
+        nfc_hal_cb.hci_cb.hci_fw_workaround         = TRUE;
+        nfc_hal_cb.hci_cb.hci_fw_validate_netwk_cmd = TRUE;
+    }
+    else if (  ((chipverlen == NFC_HAL_DM_BCM20791B4_STR_LEN) && (memcmp (NFC_HAL_DM_BCM20791B4_STR, p_chipverstr, NFC_HAL_DM_BCM20791B4_STR_LEN) == 0))
+             ||((chipverlen == NFC_HAL_DM_BCM43341B0_STR_LEN) && (memcmp (NFC_HAL_DM_BCM43341B0_STR, p_chipverstr, NFC_HAL_DM_BCM43341B0_STR_LEN) == 0))  )
+    {
+        /* BCM43341B0/BCM2079B4 FW - eSE restarted for patch download */
+        nfc_hal_cb.hci_cb.hci_fw_workaround         = TRUE;
+        nfc_hal_cb.hci_cb.hci_fw_validate_netwk_cmd = FALSE;
+    }
+    else
+    {
+        /* BCM2079B5 FW - eSE not be restarted for patch download from UICC */
+        nfc_hal_cb.hci_cb.hci_fw_workaround         = FALSE;
+        nfc_hal_cb.hci_cb.hci_fw_validate_netwk_cmd = FALSE;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_hci_handle_hci_netwk_info
+**
+** Description      Handler function for HCI Network Notification
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfc_hal_hci_handle_hci_netwk_info (UINT8 *p_data)
+{
+    UINT8  *p = p_data;
+    UINT16 data_len;
+    UINT8  target_handle = 0;
+    UINT8  hci_netwk_cmd[1 + NFC_HAL_HCI_SESSION_ID_LEN];
+    UINT8  block = 0;
+
+    HAL_TRACE_DEBUG0 ("nfc_hal_hci_handle_hci_netwk_info ()");
+
+    /* skip NCI header byte0 (MT,GID), byte1 (OID) */
+    p += 2;
+
+    STREAM_TO_UINT8 (data_len, p);
+    target_handle = *(UINT8 *) p;
+
+    if (target_handle == NFC_HAL_HCI_DH_TARGET_HANDLE)
+    {
+        /* Correct the session id assigned by DH */
+        *(p+1) = nfc_hal_cb.hci_cb.dh_session_id[0];
+        nfc_hal_nv_co_write (p, data_len, HC_F2_NV_BLOCK);
+        return;
+    }
+
+    if (target_handle == NFC_HAL_HCI_UICC0_TARGET_HANDLE)
+    {
+        block = HC_F3_NV_BLOCK;
+    }
+    else if (target_handle == NFC_HAL_HCI_UICC1_TARGET_HANDLE)
+    {
+        block = HC_F4_NV_BLOCK;
+    }
+    else if (target_handle == NFC_HAL_HCI_UICC2_TARGET_HANDLE)
+    {
+        block = HC_F5_NV_BLOCK;
+    }
+    else
+    {
+        HAL_TRACE_DEBUG1 ("nfc_hal_hci_handle_hci_netwk_info(): Invalid Target handle: 0x%02x", target_handle);
+        return;
+    }
+
+    if (  (!nfc_hal_cb.hci_cb.hci_fw_validate_netwk_cmd)
+        ||(p[NFC_HAL_HCI_NETWK_CMD_TYPE_A_CE_PIPE_INFO_OFFSET] & NFC_HAL_HCI_PIPE_VALID_MASK)
+        ||(p[NFC_HAL_HCI_NETWK_CMD_TYPE_B_CE_PIPE_INFO_OFFSET] & NFC_HAL_HCI_PIPE_VALID_MASK)
+        ||(p[NFC_HAL_HCI_NETWK_CMD_TYPE_BP_CE_PIPE_INFO_OFFSET] & NFC_HAL_HCI_PIPE_VALID_MASK)
+        ||(p[NFC_HAL_HCI_NETWK_CMD_TYPE_F_CE_PIPE_INFO_OFFSET] & NFC_HAL_HCI_PIPE_VALID_MASK)  )
+    {
+        /* HCI Network notification received for UICC0/UICC1/UICC2, Update nv data */
+        nfc_hal_nv_co_write (p, data_len, block);
+    }
+    else
+    {
+        HAL_TRACE_DEBUG1 ("nfc_hal_hci_handle_hci_netwk_info(): Type A Card Emulation invalid, Reset nv file: 0x%02x", p[NFC_HAL_HCI_NETWK_CMD_TYPE_A_CE_PIPE_INFO_OFFSET]);
+        hci_netwk_cmd[0] = target_handle;
+        memset (&hci_netwk_cmd[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
+        nfc_hal_nv_co_write (hci_netwk_cmd, 1, block);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_hci_fake_adm_notify_all_pipe_cleared_to_dh
+**
+** Description      Fake ADM_NOTIFY_ALL_PIPE_CLEARED cmd to nfc task
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfc_hal_hci_fake_adm_notify_all_pipe_cleared_to_dh (void)
+{
+    NFC_HDR  *p_msg;
+    UINT8 *p, *ps;
+
+    HAL_TRACE_DEBUG1 ("nfc_hal_hci_fake_adm_notify_all_pipe_cleared_to_dh (): Fake ADM_NOTIFY_ALL_PIPE_CLEARED (0x%02x) from HAL", NFC_HAL_HCI_HOST_ID_UICC1);
+
+    /* Start of new message. Allocate a buffer for message */
+    if ((p_msg = (NFC_HDR *) GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
+    {
+        /* Initialize NFC_HDR */
+        p_msg->len    = NCI_DATA_HDR_SIZE + 0x03;
+        p_msg->event  = 0;
+        p_msg->offset = 0;
+        p_msg->layer_specific = 0;
+
+        p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+        ps = p;
+        NCI_DATA_BLD_HDR (p, nfc_hal_cb.hci_cb.hcp_conn_id, 0x03);
+        /* HCP header with ADMIN pipe id and chaining bit set */
+        *p++ = ((1 << 0x07) | (NFC_HAL_HCI_ADMIN_PIPE & 0x7F));
+        /* HCP Message header with Command type instruction and ADM_NOTIFY_ALL_PIPE_CLEARED command */
+        *p++ = ((NFC_HAL_HCI_COMMAND_TYPE << 6) | (NFC_HAL_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED & 0x3F));
+        /* HCP Data with UICC1 host id */
+        *p = NFC_HAL_HCI_HOST_ID_UICC1;
+
+#ifdef DISP_NCI
+        DISP_NCI (ps, (UINT16) p_msg->len, TRUE);
+#endif
+        nfc_hal_send_nci_msg_to_nfc_task (p_msg);
+
+    }
+    else
+    {
+        HAL_TRACE_ERROR0 ("Unable to allocate buffer for faking ADM_NOTIFY_ALL_PIPE_CLEARED cmd from HAL to stack");
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_hci_handle_hcp_pkt_to_hc
+**
+** Description      Handle HCP Packet from NFC task to Host Controller
+**
+** Returns          FALSE to send the packet to host controller
+**                  TRUE to drop the packet and fake credit ntf for hcp connection
+**
+*******************************************************************************/
+BOOLEAN nfc_hal_hci_handle_hcp_pkt_to_hc (UINT8 *p_data)
+{
+    UINT8   chaining_bit;
+    UINT8   pipe;
+    UINT8   type;
+    UINT8   inst;
+    UINT8   index;
+
+    HAL_TRACE_DEBUG0 ("nfc_hal_hci_handle_hcp_pkt_to_hc ()");
+
+    chaining_bit = ((*p_data) >> 0x07) & 0x01;
+    pipe = (*p_data++) & 0x7F;
+
+    if (  (chaining_bit)
+        &&(pipe == NFC_HAL_HCI_ADMIN_PIPE)  )
+    {
+        type  = ((*p_data) >> 0x06) & 0x03;
+
+        if (type == NFC_HAL_HCI_COMMAND_TYPE)
+        {
+            inst  = (*p_data++ & 0x3F);
+            if (inst == NFC_HAL_HCI_ANY_GET_PARAMETER)
+            {
+                index = *(p_data++);
+                if (index == NFC_HAL_HCI_SESSION_IDENTITY_INDEX)
+                {
+                    /* Set flag to modify session id[0] on response
+                     * from host controller to set session id cmd
+                     */
+                    nfc_hal_cb.hci_cb.update_session_id = TRUE;
+                }
+            }
+            else if (inst == NFC_HAL_HCI_ANY_SET_PARAMETER)
+            {
+                index = *(p_data++);
+                if (index == NFC_HAL_HCI_WHITELIST_INDEX)
+                {
+                    if (  (nfc_hal_cb.hci_cb.hci_fw_workaround)
+                        &&(nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_UICC)  )
+                    {
+                        /* Set flag to fake ADM_NOTIFY_ALL_PIPE_CLEARED cmd to nfc task after
+                         * response from host controller to set whitelist cmd
+                         */
+                        nfc_hal_cb.hci_cb.clear_all_pipes_to_uicc1 = TRUE;
+                    }
+                }
+                else if (index == NFC_HAL_HCI_SESSION_IDENTITY_INDEX)
+                {
+                    nfc_hal_cb.hci_cb.dh_session_id[0] = *p_data;
+                    if (p_nfc_hal_cfg->nfc_hal_first_boot)
+                        *p_data = NFC_HAL_HCI_FIRST_BOOT_SESSION_ID_0_VAL;
+                    else
+                        *p_data = NFC_HAL_HCI_NEXT_BOOT_SESSION_ID_0_VAL;
+                }
+            }
+        }
+        else if (type == NFC_HAL_HCI_RESPONSE_TYPE)
+        {
+            if (  (nfc_hal_cb.hci_cb.hci_fw_workaround)
+                &&(nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_UICC)
+                &&(nfc_hal_cb.hci_cb.clear_all_pipes_to_uicc1)  )
+            {
+                /* Got response to the fake ADM_NOTIFY_ALL_PIPE_CLEARED cmd sent by HAL to nfc task */
+                nfc_hal_cb.hci_cb.clear_all_pipes_to_uicc1 =  FALSE;
+                /* return TRUE to drop this hcp without forwarding to host controller */
+                return TRUE;
+            }
+        }
+    }
+
+    return FALSE;
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_hci_handle_hcp_pkt_from_hc
+**
+** Description      Handle HCP Packet from Host controller to Terminal Host
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfc_hal_hci_handle_hcp_pkt_from_hc (UINT8 *p_data)
+{
+    UINT8   chaining_bit;
+    UINT8   pipe;
+    UINT8   type;
+    UINT8   inst;
+    UINT8   hci_netwk_cmd[1 + NFC_HAL_HCI_SESSION_ID_LEN];
+    UINT8   source_host;
+    UINT8   block = 0;
+
+    HAL_TRACE_DEBUG0 ("nfc_hal_hci_handle_hcp_pkt_from_hc ()");
+
+    chaining_bit = ((*p_data) >> 0x07) & 0x01;
+    pipe = (*p_data++) & 0x7F;
+
+    if (  (chaining_bit)
+        &&(pipe == NFC_HAL_HCI_ADMIN_PIPE)  )
+    {
+        type  = ((*p_data) >> 0x06) & 0x03;
+
+        if (type == NFC_HAL_HCI_COMMAND_TYPE)
+        {
+            if (!nfc_hal_cb.hci_cb.hci_fw_workaround)
+                return;
+
+            inst  = (*p_data++ & 0x3F);
+
+            if (inst == NFC_HAL_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED)
+            {
+                STREAM_TO_UINT8 (source_host, p_data);
+
+                HAL_TRACE_DEBUG1 ("nfc_hal_hci_handle_hcp_pkt_from_hc (): Received ADM_NOTIFY_ALL_PIPE_CLEARED command for UICC: 0x%02x", source_host);
+                if (source_host == NFC_HAL_HCI_HOST_ID_UICC0)
+                {
+                    block            = HC_F3_NV_BLOCK;
+                    hci_netwk_cmd[0] = NFC_HAL_HCI_UICC0_TARGET_HANDLE;
+                }
+                else if (source_host == NFC_HAL_HCI_HOST_ID_UICC1)
+                {
+                    block            = HC_F4_NV_BLOCK;
+                    hci_netwk_cmd[0] = NFC_HAL_HCI_UICC1_TARGET_HANDLE;
+                }
+                else if (source_host == NFC_HAL_HCI_HOST_ID_UICC2)
+                {
+                    block            = HC_F5_NV_BLOCK;
+                    hci_netwk_cmd[0] = NFC_HAL_HCI_UICC2_TARGET_HANDLE;
+                }
+
+                if (source_host >= NFC_HAL_HCI_HOST_ID_UICC0)
+                {
+                    /* Reset Session ID */
+                    memset (&hci_netwk_cmd[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
+                    nfc_hal_nv_co_write (hci_netwk_cmd, 1, block);
+                    HAL_TRACE_DEBUG1 ("nfc_hal_hci_handle_hcp_pkt_from_hc (): Sent command to reset nv file for block: 0x%02x", block);
+                }
+            }
+        }
+        else if (type == NFC_HAL_HCI_RESPONSE_TYPE)
+        {
+            if (nfc_hal_cb.hci_cb.update_session_id)
+            {
+                nfc_hal_cb.hci_cb.update_session_id = FALSE;
+                inst  = (*p_data++ & 0x3F);
+                if (inst == NFC_HAL_HCI_ANY_OK)
+                {
+                    /* Correct the session id assigned by DH */
+                    *p_data = nfc_hal_cb.hci_cb.dh_session_id[0];
+                }
+            }
+            else if (nfc_hal_cb.hci_cb.clear_all_pipes_to_uicc1)
+            {
+                /* NVM Type is UICC and got response from host controller
+                 * to Set whitelist command. Now fake ADM_NOTIFY_ALL_PIPE_CLEARED cmd to
+                 * NFC Task and then forward the whitelist cmd response
+                 */
+                nfc_hal_hci_fake_adm_notify_all_pipe_cleared_to_dh ();
+            }
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_hci_handle_nv_read
+**
+** Description      handler function for nv read complete event
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfc_hal_hci_handle_nv_read (UINT8 block, tHAL_NFC_STATUS status, UINT16 size)
+{
+    UINT8   *p;
+    UINT8   *p_hci_netwk_info = NULL;
+
+    HAL_TRACE_DEBUG3 ("nfc_hal_hci_handle_nv_read (): Block: [0x%02x], Status: [0x%02x], Size: [0x%04x]", block, status, size);
+
+    /* Stop timer as NVDATA Read Completed */
+    nfc_hal_main_stop_quick_timer (&nfc_hal_cb.hci_cb.hci_timer);
+
+    switch (block)
+    {
+    case HC_F3_NV_BLOCK:
+    case HC_F4_NV_BLOCK:
+    case HC_F5_NV_BLOCK:
+        if (  (status != HAL_NFC_STATUS_OK)
+            ||(size > NFC_HAL_HCI_NETWK_INFO_SIZE)
+            ||(size < NFC_HAL_HCI_MIN_NETWK_INFO_SIZE)
+            ||((nfc_hal_cb.hci_cb.hci_fw_workaround) && (block == HC_F4_NV_BLOCK) && (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_UICC))  )
+        {
+            HAL_TRACE_DEBUG1 ("nfc_hal_hci_handle_nv_read: Invalid data from nv memory, Set DEFAULT Configuration for block:0x%02x", block);
+            memset (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, 0, NFC_HAL_HCI_NETWK_INFO_SIZE);
+            if (block == HC_F3_NV_BLOCK)
+                nfc_hal_cb.hci_cb.p_hci_netwk_info_buf[0] = NFC_HAL_HCI_UICC0_TARGET_HANDLE;
+            else if (block == HC_F4_NV_BLOCK)
+                nfc_hal_cb.hci_cb.p_hci_netwk_info_buf[0] = NFC_HAL_HCI_UICC1_TARGET_HANDLE;
+            else
+                nfc_hal_cb.hci_cb.p_hci_netwk_info_buf[0] = NFC_HAL_HCI_UICC2_TARGET_HANDLE;
+
+            memset (&nfc_hal_cb.hci_cb.p_hci_netwk_info_buf[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
+            size = NFC_HAL_HCI_NETWK_INFO_SIZE;
+        }
+
+        p_hci_netwk_info = (UINT8 *) nfc_hal_cb.hci_cb.p_hci_netwk_info_buf - NCI_MSG_HDR_SIZE;
+        break;
+
+    case HC_F2_NV_BLOCK:
+        nfc_hal_cb.hci_cb.dh_session_id[0] = nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf[1];
+        if (p_nfc_hal_cfg->nfc_hal_first_boot)
+            nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf[1] = NFC_HAL_HCI_FIRST_BOOT_SESSION_ID_0_VAL;
+        else
+            nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf[1] = NFC_HAL_HCI_NEXT_BOOT_SESSION_ID_0_VAL;
+
+        if (  (status != HAL_NFC_STATUS_OK)
+            ||(size > NFC_HAL_HCI_DH_NETWK_INFO_SIZE)
+            ||(size < NFC_HAL_HCI_MIN_DH_NETWK_INFO_SIZE)  )
+        {
+            HAL_TRACE_DEBUG1 ("nfc_hal_hci_handle_nv_read: Invalid data from nv memory, Set DEFAULT Configuration for block:0x%02x", block);
+            nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf[0] = NFC_HAL_HCI_DH_TARGET_HANDLE;
+            nfc_hal_cb.hci_cb.dh_session_id[0] = 0xFF;
+            memset (&nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf[2], 0xFF, (NFC_HAL_HCI_SESSION_ID_LEN - 1));
+            memset ((nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf + NFC_HAL_HCI_SESSION_ID_LEN + 1), 0, (NFC_HAL_HCI_DH_NETWK_INFO_SIZE - NFC_HAL_HCI_SESSION_ID_LEN - 1));
+            size = NFC_HAL_HCI_DH_NETWK_INFO_SIZE;
+            p_hci_netwk_info = (UINT8 *) nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf - NCI_MSG_HDR_SIZE;
+        }
+        else
+        {
+            if ((nfc_hal_cb.hci_cb.hci_fw_workaround) && (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_UICC))
+            {
+                /* if NVM Type is UICC, then UICC1 will find session id mismatch when activated for patch download,
+                 * and will remove pipes connected to DH even before DH is enabled, So DH will update NFCC
+                 * control block by removing all dynamic pipes connected to UICC1 */
+
+                nfc_hal_hci_remove_dyn_pipe_to_uicc1 ();
+                size = NFC_HAL_HCI_DH_NETWK_INFO_SIZE;
+            }
+            p_hci_netwk_info = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf - NCI_MSG_HDR_SIZE);
+        }
+        break;
+
+    default:
+        return;
+    }
+
+    p = p_hci_netwk_info;
+    /* Send HCI Network ntf command using nv data */
+    NCI_MSG_BLD_HDR0 (p, NCI_MT_CMD, NCI_GID_PROP);
+    NCI_MSG_BLD_HDR1 (p, NCI_MSG_HCI_NETWK);
+    UINT8_TO_STREAM (p, (UINT8) size);
+
+    nfc_hal_dm_send_nci_cmd (p_hci_netwk_info, (UINT16) (NCI_MSG_HDR_SIZE + size), nfc_hal_hci_vsc_cback);
+
+    nfc_hal_cb.hci_cb.hci_netwk_config_block = block;
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_hci_remove_dyn_pipe_to_uicc1
+**
+** Description      Prepare hci network command read from nv file removing
+**                  all pipes connected to UICC1
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfc_hal_hci_remove_dyn_pipe_to_uicc1 (void)
+{
+    UINT8 *p, *np;
+    UINT8 num_dyn_pipes = 0, new_num_dyn_pipes = 0;
+    UINT8 xx;
+    UINT8 source_host, dest_host, pipe_id;
+
+    HAL_TRACE_DEBUG0 ("nfc_hal_hci_remove_dyn_pipe_to_uicc1 ()");
+
+    p  = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf + NFC_HAL_HCI_MIN_DH_NETWK_INFO_SIZE);
+    np = p;
+    num_dyn_pipes = *(p - 1);
+
+    for (xx = 0; xx < num_dyn_pipes; xx++,p += NFC_HAL_HCI_PIPE_INFO_SIZE)
+    {
+        source_host = *(UINT8 *) (p);
+        dest_host   = *(UINT8 *) (p + 1);
+        pipe_id     = *(UINT8 *) (p + 4);
+
+        if ((source_host != NFC_HAL_HCI_HOST_ID_UICC1) && (dest_host != NFC_HAL_HCI_HOST_ID_UICC1))
+        {
+            memcpy (np, p, NFC_HAL_HCI_PIPE_INFO_SIZE);
+            np += NFC_HAL_HCI_PIPE_INFO_SIZE;
+            new_num_dyn_pipes++;
+        }
+    }
+
+    memset ((UINT8 *) (np), 0, NFC_HAL_HCI_PIPE_INFO_SIZE * (20 - new_num_dyn_pipes));
+
+    /* Update number of pipes after removing pipes connected to UICC1 */
+    p = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf + NFC_HAL_HCI_MIN_DH_NETWK_INFO_SIZE);
+    *(p - 1) = new_num_dyn_pipes;
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_hci_init_complete
+**
+** Description      Notify VSC initialization is complete
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfc_hal_hci_init_complete (tHAL_NFC_STATUS status)
+{
+    UINT8 *p_hci_netwk_cmd;
+
+    HAL_TRACE_DEBUG1 ("nfc_hal_hci_init_complete (): Status: [0x%02x]", status);
+
+    if (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf)
+    {
+        p_hci_netwk_cmd = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf - NCI_MSG_HDR_SIZE);
+        GKI_freebuf (p_hci_netwk_cmd);
+        nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf = NULL;
+    }
+
+    if (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf)
+    {
+        p_hci_netwk_cmd = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf - NCI_MSG_HDR_SIZE);
+        GKI_freebuf (p_hci_netwk_cmd);
+        nfc_hal_cb.hci_cb.p_hci_netwk_info_buf = NULL;
+    }
+
+    NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+
+    nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, status);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_hci_set_next_hci_netwk_config
+**
+** Description      set next hci network configuration
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfc_hal_hci_set_next_hci_netwk_config (UINT8 block)
+{
+    UINT8 *p_hci_netwk_cmd;
+
+    HAL_TRACE_DEBUG1 ("nfc_hal_hci_set_next_hci_netwk_config (): Block: [0x%02x]", block);
+
+    switch (block)
+    {
+    case HC_F3_NV_BLOCK:
+        if (  (p_nfc_hal_cfg->nfc_hal_hci_uicc_support & HAL_NFC_HCI_UICC1_HOST)
+            &&(nfc_hal_cb.hci_cb.p_hci_netwk_info_buf)
+            &&((!nfc_hal_cb.hci_cb.hci_fw_workaround) || (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_EEPROM))  )
+        {
+            /* Send command to read nvram data for 0xF4 */
+            memset (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, 0, NFC_HAL_HCI_NETWK_INFO_SIZE);
+            nfc_hal_nv_co_read ((UINT8 *) nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, NFC_HAL_HCI_NETWK_INFO_SIZE, HC_F4_NV_BLOCK);
+            nfc_hal_main_start_quick_timer (&nfc_hal_cb.hci_cb.hci_timer, NFC_HAL_HCI_VSC_TIMEOUT_EVT, NFC_HAL_HCI_NV_READ_TIMEOUT);
+            break;
+        }
+        HAL_TRACE_DEBUG2 ("nfc_hal_hci_set_next_hci_netwk_config (): Skip send F4 HCI NETWK CMD for UICC Mask: 0x%02x & NVM Type: 0x%02x", p_nfc_hal_cfg->nfc_hal_hci_uicc_support, nfc_hal_cb.nvm_cb.nvm_type);
+
+    case HC_F4_NV_BLOCK:
+        if (  (p_nfc_hal_cfg->nfc_hal_hci_uicc_support & HAL_NFC_HCI_UICC2_HOST)
+            &&(nfc_hal_cb.hci_cb.p_hci_netwk_info_buf)  )
+        {
+            /* Send command to read nvram data for 0xF5 */
+            memset (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, 0, NFC_HAL_HCI_NETWK_INFO_SIZE);
+            nfc_hal_nv_co_read ((UINT8 *) nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, NFC_HAL_HCI_NETWK_INFO_SIZE, HC_F5_NV_BLOCK);
+            nfc_hal_main_start_quick_timer (&nfc_hal_cb.hci_cb.hci_timer, NFC_HAL_HCI_VSC_TIMEOUT_EVT, NFC_HAL_HCI_NV_READ_TIMEOUT);
+            break;
+        }
+        HAL_TRACE_DEBUG2 ("nfc_hal_hci_set_next_hci_netwk_config (): Skip send F5 HCI NETWK CMD for UICC Mask: 0x%02x & NVM Type: 0x%02x", p_nfc_hal_cfg->nfc_hal_hci_uicc_support, nfc_hal_cb.nvm_cb.nvm_type);
+
+    case HC_F5_NV_BLOCK:
+        if ((p_hci_netwk_cmd = (UINT8 *) GKI_getbuf (NCI_MSG_HDR_SIZE + NFC_HAL_HCI_DH_NETWK_INFO_SIZE)) == NULL)
+        {
+            HAL_TRACE_ERROR0 ("nfc_hal_hci_set_next_hci_netwk_config: unable to allocate buffer for reading hci network info from nvram");
+            nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
+        }
+        else
+        {
+            nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf   = (UINT8 *) (p_hci_netwk_cmd + NCI_MSG_HDR_SIZE);
+            /* Send command to read nvram data for 0xF2 */
+            memset (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf, 0, NFC_HAL_HCI_DH_NETWK_INFO_SIZE);
+            nfc_hal_nv_co_read ((UINT8 *) nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf, NFC_HAL_HCI_DH_NETWK_INFO_SIZE, HC_F2_NV_BLOCK);
+            nfc_hal_main_start_quick_timer (&nfc_hal_cb.hci_cb.hci_timer, NFC_HAL_HCI_VSC_TIMEOUT_EVT, NFC_HAL_HCI_NV_READ_TIMEOUT);
+        }
+        break;
+
+    case HC_F2_NV_BLOCK:
+        nfc_hal_hci_init_complete (HAL_NFC_STATUS_OK);
+        break;
+
+    default:
+        HAL_TRACE_ERROR1 ("nfc_hal_hci_set_next_hci_netwk_config: unable to allocate buffer to send VSC 0x%02x", block);
+        /* Brcm initialization failed */
+        nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_hci_vsc_cback
+**
+** Description      process VS callback event from stack
+**
+** Returns          none
+**
+*******************************************************************************/
+static void nfc_hal_hci_vsc_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data)
+{
+    UINT8 *p_ret = NULL;
+    UINT8 status;
+
+    p_ret  = p_data + NCI_MSG_HDR_SIZE;
+    status = *p_ret;
+
+    HAL_TRACE_DEBUG3 ("nfc_hal_hci_vsc_cback (): Event: [0x%02x], Data length: [0x%04x], Status: [0x%02x]", event, data_len, status);
+
+    if (event  != NFC_VS_HCI_NETWK_RSP)
+        return;
+
+    if (status != HAL_NFC_STATUS_OK)
+    {
+        nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
+        return;
+    }
+
+    switch (nfc_hal_cb.hci_cb.hci_netwk_config_block)
+    {
+    case HC_F3_NV_BLOCK:
+    case HC_F4_NV_BLOCK:
+    case HC_F5_NV_BLOCK:
+    case HC_F2_NV_BLOCK:
+        nfc_hal_hci_set_next_hci_netwk_config (nfc_hal_cb.hci_cb.hci_netwk_config_block);
+        break;
+
+    default:
+        /* Ignore the event */
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nci_cmd_timeout_cback
+**
+** Description      callback function for timeout
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_hci_timeout_cback (void *p_tle)
+{
+    TIMER_LIST_ENT  *p_tlent = (TIMER_LIST_ENT *)p_tle;
+
+    HAL_TRACE_DEBUG0 ("nfc_hal_hci_timeout_cback ()");
+
+    if (p_tlent->event == NFC_HAL_HCI_VSC_TIMEOUT_EVT)
+    {
+        HAL_TRACE_ERROR0 ("nfc_hal_hci_timeout_cback: Timeout - NFC HAL HCI BRCM Initialization Failed!");
+        nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
+    }
+}
+
+#endif
+
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_hci_ci.c b/halimpl/bcm2079x/hal/hal/nfc_hal_hci_ci.c
new file mode 100644
index 0000000..49236f9
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_hci_ci.c
@@ -0,0 +1,93 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ *
+ *  This file contains the call-in functions for NFC HAL HCI
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "gki.h"
+#include "nfc_hal_api.h"
+#include "nfc_hal_int.h"
+
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+#include "nfc_hal_nv_ci.h"
+#include "nfc_hal_nv_co.h"
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nv_ci_read
+**
+** Description      call-in function for non volatile memory read acess
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfc_hal_nv_ci_read (UINT16 num_bytes_read, tNFC_HAL_NV_CO_STATUS status, UINT8 block)
+{
+    tNFC_HAL_HCI_EVENT_DATA *p_msg;
+
+    /* Send message to NCIT task */
+    if ((p_msg = (tNFC_HAL_HCI_EVENT_DATA *) GKI_getbuf (sizeof (tNFC_HAL_HCI_EVENT_DATA))) != NULL)
+    {
+        p_msg->nv_read.hdr.event  = NFC_HAL_HCI_RSP_NV_READ_EVT;
+        p_msg->hdr.offset         = 0;
+        p_msg->hdr.len            = sizeof (tNFC_HAL_HCI_RSP_NV_READ_EVT);
+        p_msg->hdr.layer_specific = 0;
+
+        if (  (status == NFC_HAL_NV_CO_OK)
+            &&(num_bytes_read != 0) )
+            p_msg->nv_read.status = HAL_NFC_STATUS_OK;
+        else
+            p_msg->nv_read.status = HAL_NFC_STATUS_FAILED;
+
+        p_msg->nv_read.size  = num_bytes_read;
+        p_msg->nv_read.block = block;
+
+        GKI_send_msg (NFC_HAL_TASK, NFC_HAL_TASK_MBOX, p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nv_ci_write
+**
+** Description      call-in function for non volatile memory write acess
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfc_hal_nv_ci_write (tNFC_HAL_NV_CO_STATUS status)
+{
+    tNFC_HAL_HCI_EVENT_DATA *p_msg;
+
+    if ((p_msg = (tNFC_HAL_HCI_EVENT_DATA *) GKI_getbuf (sizeof (tNFC_HAL_HCI_EVENT_DATA))) != NULL)
+    {
+        p_msg->nv_write.hdr.event          = NFC_HAL_HCI_RSP_NV_WRITE_EVT;
+        p_msg->nv_write.hdr.offset         = 0;
+        p_msg->nv_write.hdr.len            = sizeof (tNFC_HAL_HCI_RSP_NV_READ_EVT);
+        p_msg->nv_write.hdr.layer_specific = 0;
+        p_msg->nv_write.status             = HAL_NFC_STATUS_OK;
+
+        GKI_send_msg (NFC_HAL_TASK, NFC_HAL_TASK_MBOX, p_msg);
+    }
+}
+
+#endif
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_main.c b/halimpl/bcm2079x/hal/hal/nfc_hal_main.c
new file mode 100644
index 0000000..d7fc5d5
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_main.c
@@ -0,0 +1,752 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ *
+ *  Functions for handling NFC HAL NCI Transport events
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_hal_int.h"
+#include "nfc_hal_post_reset.h"
+#include "userial.h"
+#include "upio.h"
+
+/****************************************************************************
+** Definitions
+****************************************************************************/
+
+/* Default NFC HAL NCI port configuration  */
+NFC_HAL_TRANS_CFG_QUALIFIER tNFC_HAL_TRANS_CFG nfc_hal_trans_cfg =
+{
+    NFC_HAL_SHARED_TRANSPORT_ENABLED,   /* bSharedTransport */
+    USERIAL_BAUD_115200,                /* Baud rate */
+    USERIAL_FC_HW                       /* Flow control */
+};
+
+/* Control block for NFC HAL NCI transport */
+#if NFC_DYNAMIC_MEMORY == FALSE
+tNFC_HAL_CB nfc_hal_cb;
+#endif
+
+extern tNFC_HAL_CFG *p_nfc_hal_cfg;
+/****************************************************************************
+** Internal function prototypes
+****************************************************************************/
+static void nfc_hal_main_userial_cback (tUSERIAL_PORT port, tUSERIAL_EVT evt, tUSERIAL_EVT_DATA *p_data);
+static void nfc_hal_main_handle_terminate (void);
+static void nfc_hal_main_timeout_cback (void *p_tle);
+
+#if (NFC_HAL_DEBUG == TRUE)
+const char * const nfc_hal_init_state_str[] =
+{
+    "IDLE",             /* Initialization is done                */
+    "W4_XTAL_SET",      /* Waiting for crystal setting rsp       */
+    "POST_XTAL_SET",    /* Waiting for reset ntf after xtal set  */
+    "W4_NFCC_ENABLE",   /* Waiting for reset ntf atter REG_PU up */
+    "W4_BUILD_INFO",    /* Waiting for build info rsp            */
+    "W4_PATCH_INFO",    /* Waiting for patch info rsp            */
+    "W4_APP_COMPL",     /* Waiting for complete from application */
+    "W4_POST_INIT",     /* Waiting for complete of post init     */
+    "W4_CONTROL",       /* Waiting for control release           */
+    "W4_PREDISC",       /* Waiting for complete of prediscover   */
+    "CLOSING"           /* Shutting down                         */
+};
+#endif
+
+/*******************************************************************************
+**
+** Function         nfc_hal_main_init
+**
+** Description      This function initializes control block for NFC HAL
+**
+** Returns          nothing
+**
+*******************************************************************************/
+void nfc_hal_main_init (void)
+{
+    /* Clear control block */
+    memset (&nfc_hal_cb, 0, sizeof (tNFC_HAL_CB));
+
+    nfc_hal_cb.ncit_cb.nci_ctrl_size   = NFC_HAL_NCI_INIT_CTRL_PAYLOAD_SIZE;
+    nfc_hal_cb.trace_level             = NFC_HAL_INITIAL_TRACE_LEVEL;
+    nfc_hal_cb.timer.p_cback           = nfc_hal_main_timeout_cback;
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_main_open_transport
+**
+** Description      Open transport and prepare for new incoming message;
+**
+** Returns          nothing
+**
+*******************************************************************************/
+static void nfc_hal_main_open_transport (void)
+{
+    tUSERIAL_OPEN_CFG open_cfg;
+
+    /* Initialize control block */
+    nfc_hal_cb.ncit_cb.rcv_state = NFC_HAL_RCV_IDLE_ST; /* to process packet type */
+
+    if (nfc_hal_cb.ncit_cb.p_rcv_msg)
+    {
+        GKI_freebuf (nfc_hal_cb.ncit_cb.p_rcv_msg);
+        nfc_hal_cb.ncit_cb.p_rcv_msg = NULL;
+    }
+
+    /* open transport */
+    open_cfg.fmt    = (USERIAL_DATABITS_8 | USERIAL_PARITY_NONE | USERIAL_STOPBITS_1);
+    open_cfg.baud   = nfc_hal_trans_cfg.userial_baud;
+    open_cfg.fc     = nfc_hal_trans_cfg.userial_fc;
+    open_cfg.buf    = USERIAL_BUF_BYTE;
+
+    USERIAL_Open (USERIAL_NFC_PORT, &open_cfg, nfc_hal_main_userial_cback);
+
+    {
+        /* Wait for NFCC to enable - Core reset notification */
+        NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_NFCC_ENABLE);
+
+        /* NFCC Enable timeout */
+        nfc_hal_main_start_quick_timer (&nfc_hal_cb.timer, NFC_HAL_TTYPE_NFCC_ENABLE,
+                                        ((p_nfc_hal_cfg->nfc_hal_nfcc_enable_timeout)*QUICK_TIMER_TICKS_PER_SEC)/1000);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hal_pre_discover_done_cback
+**
+** Description      Pre-discovery CFG is sent.
+**
+** Returns          nothing
+**
+*******************************************************************************/
+void nfa_hal_pre_discover_done_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data)
+{
+    NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE);
+    nfc_hal_main_stop_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
+    nfc_hal_cb.p_stack_cback (HAL_NFC_PRE_DISCOVER_CPLT_EVT, HAL_NFC_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hal_send_pre_discover_cfg
+**
+** Description      sending Pre-discovery CFG
+**
+** Returns          nothing
+**
+*******************************************************************************/
+void nfa_hal_send_pre_discover_cfg (void)
+{
+    if (nfc_hal_dm_set_config (p_nfc_hal_pre_discover_cfg [0],
+                               &p_nfc_hal_pre_discover_cfg[1],
+                                nfa_hal_pre_discover_done_cback) != HAL_NFC_STATUS_OK)
+    {
+        nfa_hal_pre_discover_done_cback(0, 0, NULL);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_main_send_error
+**
+** Description      send an Error event to NFC stack
+**
+** Returns          nothing
+**
+*******************************************************************************/
+void nfc_hal_main_send_error (tHAL_NFC_STATUS status)
+{
+    /* Notify stack */
+    nfc_hal_cb.p_stack_cback(HAL_NFC_ERROR_EVT, status);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_main_userial_cback
+**
+** Description      USERIAL callback for NCI transport
+**
+** Returns          nothing
+**
+*******************************************************************************/
+static void nfc_hal_main_userial_cback (tUSERIAL_PORT port, tUSERIAL_EVT evt, tUSERIAL_EVT_DATA *p_data)
+{
+    if (evt == USERIAL_RX_READY_EVT)
+    {
+        /* Notify transport task of serial port event */
+        GKI_send_event (NFC_HAL_TASK, NFC_HAL_TASK_EVT_DATA_RDY);
+    }
+    else if (evt == USERIAL_TX_DONE_EVT)
+    {
+        /* Serial driver has finshed sending data from USERIAL_Write */
+        /* Currently, no action is needed for this event */
+    }
+    else if (evt == USERIAL_ERR_EVT)
+    {
+        HAL_TRACE_ERROR0 ("nfc_hal_main_userial_cback: USERIAL_ERR_EVT. Notifying NFC_TASK of transport error");
+        if (nfc_hal_cb.ncit_cb.nci_wait_rsp != NFC_HAL_WAIT_RSP_NONE)
+        {
+            nfc_hal_main_stop_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
+            nfc_hal_nci_cmd_timeout_cback ((void *)&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
+        }
+        else
+        {
+            nfc_hal_main_send_error (HAL_NFC_STATUS_ERR_TRANSPORT);
+        }
+    }
+    else if (evt == USERIAL_WAKEUP_EVT)
+    {
+        HAL_TRACE_DEBUG1 ("nfc_hal_main_userial_cback: USERIAL_WAKEUP_EVT: %d", p_data->sigs);
+    }
+    else
+    {
+        HAL_TRACE_DEBUG1 ("nfc_hal_main_userial_cback: unhandled userial evt: %i", evt);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_main_pre_init_done
+**
+** Description      notify complete of pre-initialization
+**
+** Returns          nothing
+**
+*******************************************************************************/
+void nfc_hal_main_pre_init_done (tHAL_NFC_STATUS status)
+{
+    HAL_TRACE_DEBUG1 ("nfc_hal_main_pre_init_done () status = %d", status);
+
+    if (status != HAL_NFC_STATUS_OK)
+    {
+        nfc_hal_main_handle_terminate ();
+
+        /* Close uart */
+        USERIAL_Close (USERIAL_NFC_PORT);
+    }
+
+    /* Notify NFC Task the status of initialization */
+    nfc_hal_cb.p_stack_cback (HAL_NFC_OPEN_CPLT_EVT, status);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_main_timeout_cback
+**
+** Description      callback function for timeout
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfc_hal_main_timeout_cback (void *p_tle)
+{
+    TIMER_LIST_ENT  *p_tlent = (TIMER_LIST_ENT *) p_tle;
+
+    HAL_TRACE_DEBUG0 ("nfc_hal_main_timeout_cback ()");
+
+    switch (p_tlent->event)
+    {
+    case NFC_HAL_TTYPE_POWER_CYCLE:
+        nfc_hal_main_open_transport ();
+        break;
+
+    case NFC_HAL_TTYPE_NFCC_ENABLE:
+        /* NFCC should have enabled now, notify transport openned */
+        nfc_hal_dm_pre_init_nfcc ();
+        break;
+
+    default:
+        HAL_TRACE_DEBUG1 ("nfc_hal_main_timeout_cback: unhandled timer event (0x%04x)", p_tlent->event);
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_main_handle_terminate
+**
+** Description      Handle NFI transport shutdown
+**
+** Returns          nothing
+**
+*******************************************************************************/
+static void nfc_hal_main_handle_terminate (void)
+{
+    NFC_HDR *p_msg;
+
+    /* dequeue and free buffer */
+    if (nfc_hal_cb.ncit_cb.p_pend_cmd != NULL)
+    {
+        GKI_freebuf (nfc_hal_cb.ncit_cb.p_pend_cmd);
+        nfc_hal_cb.ncit_cb.p_pend_cmd = NULL;
+    }
+
+    /* Free unsent nfc rx buffer */
+    if (nfc_hal_cb.ncit_cb.p_rcv_msg)
+    {
+        GKI_freebuf (nfc_hal_cb.ncit_cb.p_rcv_msg);
+        nfc_hal_cb.ncit_cb.p_rcv_msg  = NULL;
+    }
+
+    /* Free buffer for pending fragmented response/notification */
+    if (nfc_hal_cb.ncit_cb.p_frag_msg)
+    {
+        GKI_freebuf (nfc_hal_cb.ncit_cb.p_frag_msg);
+        nfc_hal_cb.ncit_cb.p_frag_msg = NULL;
+    }
+
+    /* Free buffers in the tx mbox */
+    while ((p_msg = (NFC_HDR *) GKI_read_mbox (NFC_HAL_TASK_MBOX)) != NULL)
+    {
+        GKI_freebuf (p_msg);
+    }
+
+    /* notify closing transport */
+    nfc_hal_dm_shutting_down_nfcc ();
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_main_start_quick_timer
+**
+** Description      Start a timer for the specified amount of time.
+**                  NOTE: The timeout resolution depends on including modules.
+**                  QUICK_TIMER_TICKS_PER_SEC should be used to convert from
+**                  time to ticks.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_main_start_quick_timer (TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout)
+{
+    NFC_HDR *p_msg;
+
+    /* if timer list is currently empty, start periodic GKI timer */
+    if (nfc_hal_cb.quick_timer_queue.p_first == NULL)
+    {
+        /* if timer starts on other than NCIT task (script wrapper) */
+        if(GKI_get_taskid () != NFC_HAL_TASK)
+        {
+            /* post event to start timer in NCIT task */
+            if ((p_msg = (NFC_HDR *) GKI_getbuf (NFC_HDR_SIZE)) != NULL)
+            {
+                p_msg->event = NFC_HAL_EVT_TO_START_QUICK_TIMER;
+                GKI_send_msg (NFC_HAL_TASK, NFC_HAL_TASK_MBOX, p_msg);
+            }
+        }
+        else
+        {
+            GKI_start_timer (NFC_HAL_QUICK_TIMER_ID, ((GKI_SECS_TO_TICKS (1) / QUICK_TIMER_TICKS_PER_SEC)), TRUE);
+        }
+    }
+
+    GKI_remove_from_timer_list (&nfc_hal_cb.quick_timer_queue, p_tle);
+
+    p_tle->event = type;
+    p_tle->ticks = timeout; /* Save the number of ticks for the timer */
+
+    GKI_add_to_timer_list (&nfc_hal_cb.quick_timer_queue, p_tle);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_main_stop_quick_timer
+**
+** Description      Stop a timer.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_main_stop_quick_timer (TIMER_LIST_ENT *p_tle)
+{
+    GKI_remove_from_timer_list (&nfc_hal_cb.quick_timer_queue, p_tle);
+
+    /* if timer list is empty stop periodic GKI timer */
+    if (nfc_hal_cb.quick_timer_queue.p_first == NULL)
+    {
+        GKI_stop_timer (NFC_HAL_QUICK_TIMER_ID);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_main_process_quick_timer_evt
+**
+** Description      Process quick timer event
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfc_hal_main_process_quick_timer_evt (void)
+{
+    TIMER_LIST_ENT  *p_tle;
+
+    GKI_update_timer_list (&nfc_hal_cb.quick_timer_queue, 1);
+
+    while ((nfc_hal_cb.quick_timer_queue.p_first) && (!nfc_hal_cb.quick_timer_queue.p_first->ticks))
+    {
+        p_tle = nfc_hal_cb.quick_timer_queue.p_first;
+        GKI_remove_from_timer_list (&nfc_hal_cb.quick_timer_queue, p_tle);
+
+        if (p_tle->p_cback)
+        {
+            (*p_tle->p_cback) (p_tle);
+        }
+    }
+
+    /* if timer list is empty stop periodic GKI timer */
+    if (nfc_hal_cb.quick_timer_queue.p_first == NULL)
+    {
+        GKI_stop_timer (NFC_HAL_QUICK_TIMER_ID);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_send_nci_msg_to_nfc_task
+**
+** Description      This function is called to send nci message to nfc task
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_send_nci_msg_to_nfc_task (NFC_HDR * p_msg)
+{
+#ifdef NFC_HAL_SHARED_GKI
+    /* Using shared NFC/HAL GKI resources - send message buffer directly to NFC_TASK for processing */
+    p_msg->event = BT_EVT_TO_NFC_NCI;
+    GKI_send_msg (NFC_TASK, NFC_MBOX_ID, p_msg);
+#else
+    /* Send NCI message to the stack */
+    nfc_hal_cb.p_data_cback (p_msg->len, (UINT8 *) ((p_msg + 1)
+                                 + p_msg->offset));
+    GKI_freebuf(p_msg);
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_send_credit_ntf_for_cid
+**
+** Description      This function is called to send credit ntf
+**                  for the specified connection id to nfc task
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfc_hal_send_credit_ntf_for_cid (UINT8 cid)
+{
+    NFC_HDR  *p_msg;
+    UINT8    *p, *ps;
+
+    /* Start of new message. Allocate a buffer for message */
+    if ((p_msg = (NFC_HDR *) GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
+    {
+        /* Initialize NFC_HDR */
+        p_msg->len    = NCI_DATA_HDR_SIZE + 0x03;
+        p_msg->event  = 0;
+        p_msg->offset = 0;
+        p_msg->layer_specific = 0;
+
+        p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+        ps = p;
+        NCI_MSG_BLD_HDR0(p, NCI_MT_NTF, NCI_GID_CORE);
+        NCI_MSG_BLD_HDR1(p, NCI_MSG_CORE_CONN_CREDITS);
+        UINT8_TO_STREAM (p, 0x03);
+
+        /* Number of credit entries */
+        *p++ = 0x01;
+        /* Connection id of the credit ntf */
+        *p++ = cid;
+        /* Number of credits */
+        *p = 0x01;
+#ifdef DISP_NCI
+        DISP_NCI (ps, (UINT16) p_msg->len, TRUE);
+#endif
+        nfc_hal_send_nci_msg_to_nfc_task (p_msg);
+    }
+    else
+    {
+        HAL_TRACE_ERROR0 ("Unable to allocate buffer for Sending credit ntf to stack");
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_main_send_message
+**
+** Description      This function is calledto send an NCI message.
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfc_hal_main_send_message (NFC_HDR *p_msg)
+{
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+    UINT8   cid, pbf;
+    UINT16  data_len;
+#endif
+    UINT8   *ps, *pp;
+    UINT16  len = p_msg->len;
+#ifdef DISP_NCI
+    UINT8   delta;
+#endif
+
+    HAL_TRACE_DEBUG1 ("nfc_hal_main_send_message() ls:0x%x", p_msg->layer_specific);
+    if (  (p_msg->layer_specific == NFC_HAL_WAIT_RSP_CMD)
+        ||(p_msg->layer_specific == NFC_HAL_WAIT_RSP_VSC)  )
+    {
+        nfc_hal_nci_send_cmd (p_msg);
+    }
+    else
+    {
+        /* NFC task has fragmented the data packet to the appropriate size
+         * and data credit is available; just send it */
+
+        /* add NCI packet type in front of message */
+        nfc_hal_nci_add_nfc_pkt_type (p_msg);
+
+        /* send this packet to transport */
+        ps = (UINT8 *) (p_msg + 1) + p_msg->offset;
+        pp = ps + 1;
+#ifdef DISP_NCI
+        delta = p_msg->len - len;
+        DISP_NCI (ps + delta, (UINT16) (p_msg->len - delta), FALSE);
+#endif
+
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+        if (nfc_hal_cb.hci_cb.hcp_conn_id)
+        {
+            NCI_DATA_PRS_HDR(pp, pbf, cid, data_len);
+            if (cid == nfc_hal_cb.hci_cb.hcp_conn_id)
+            {
+                if (nfc_hal_hci_handle_hcp_pkt_to_hc (pp))
+                {
+                    HAL_TRACE_DEBUG0 ("nfc_hal_main_send_message() - Drop rsp to Fake cmd, Fake credit ntf");
+                    GKI_freebuf (p_msg);
+                    nfc_hal_send_credit_ntf_for_cid (cid);
+                    return;
+                }
+            }
+
+        }
+#endif
+
+        /* check low power mode state */
+        if (nfc_hal_dm_power_mode_execute (NFC_HAL_LP_TX_DATA_EVT))
+        {
+            USERIAL_Write (USERIAL_NFC_PORT, ps, p_msg->len);
+        }
+        else
+        {
+            HAL_TRACE_ERROR0 ("nfc_hal_main_send_message(): drop data in low power mode");
+        }
+        GKI_freebuf (p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_main_task
+**
+** Description      NFC HAL NCI transport event processing task
+**
+** Returns          0
+**
+*******************************************************************************/
+UINT32 nfc_hal_main_task (UINT32 param)
+{
+    UINT16   event;
+    UINT8    byte;
+    UINT8    num_interfaces;
+    UINT8    *p;
+    NFC_HDR  *p_msg;
+    BOOLEAN  free_msg;
+
+    HAL_TRACE_DEBUG0 ("NFC_HAL_TASK started");
+
+    /* Main loop */
+    while (TRUE)
+    {
+        event = GKI_wait (0xFFFF, 0);
+
+        /* Handle NFC_HAL_TASK_EVT_INITIALIZE (for initializing NCI transport) */
+        if (event & NFC_HAL_TASK_EVT_INITIALIZE)
+        {
+            HAL_TRACE_DEBUG0 ("NFC_HAL_TASK got NFC_HAL_TASK_EVT_INITIALIZE signal. Opening NFC transport...");
+
+            nfc_hal_main_open_transport ();
+        }
+
+        /* Check for terminate event */
+        if (event & NFC_HAL_TASK_EVT_TERMINATE)
+        {
+            HAL_TRACE_DEBUG0 ("NFC_HAL_TASK got NFC_HAL_TASK_EVT_TERMINATE");
+            nfc_hal_main_handle_terminate ();
+
+            /* Close uart */
+            USERIAL_Close (USERIAL_NFC_PORT);
+
+            if (nfc_hal_cb.p_stack_cback)
+            {
+                nfc_hal_cb.p_stack_cback (HAL_NFC_CLOSE_CPLT_EVT, HAL_NFC_STATUS_OK);
+                nfc_hal_cb.p_stack_cback = NULL;
+            }
+            continue;
+        }
+
+        /* Check for power cycle event */
+        if (event & NFC_HAL_TASK_EVT_POWER_CYCLE)
+        {
+            HAL_TRACE_DEBUG0 ("NFC_HAL_TASK got NFC_HAL_TASK_EVT_POWER_CYCLE");
+            nfc_hal_main_handle_terminate ();
+
+            /* Close uart */
+            USERIAL_Close (USERIAL_NFC_PORT);
+
+            /* power cycle timeout */
+            nfc_hal_main_start_quick_timer (&nfc_hal_cb.timer, NFC_HAL_TTYPE_POWER_CYCLE,
+                                            (NFC_HAL_POWER_CYCLE_DELAY*QUICK_TIMER_TICKS_PER_SEC)/1000);
+            continue;
+        }
+
+        /* NCI message ready to be sent to NFCC */
+        if (event & NFC_HAL_TASK_EVT_MBOX)
+        {
+            while ((p_msg = (NFC_HDR *) GKI_read_mbox (NFC_HAL_TASK_MBOX)) != NULL)
+            {
+                free_msg = TRUE;
+                switch (p_msg->event & NFC_EVT_MASK)
+                {
+                case NFC_HAL_EVT_TO_NFC_NCI:
+                    nfc_hal_main_send_message (p_msg);
+                    /* do not free buffer. NCI VS code may keep it for processing later */
+                    free_msg = FALSE;
+                    break;
+
+                case NFC_HAL_EVT_POST_CORE_RESET:
+                    NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_POST_INIT_DONE);
+
+                    /* set NCI Control packet size from CORE_INIT_RSP */
+                    p = (UINT8 *) (p_msg + 1) + p_msg->offset + NCI_MSG_HDR_SIZE;
+                    p += 5;
+                    STREAM_TO_UINT8 (num_interfaces, p);
+                    p += (num_interfaces + 3);
+                    nfc_hal_cb.ncit_cb.nci_ctrl_size = *p;
+
+                    /* start post initialization */
+                    nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_LPTD;
+                    nfc_hal_cb.dev_cb.next_startup_vsc = 1;
+
+                    nfc_hal_dm_config_nfcc ();
+                    break;
+
+                case NFC_HAL_EVT_TO_START_QUICK_TIMER:
+                    GKI_start_timer (NFC_HAL_QUICK_TIMER_ID, ((GKI_SECS_TO_TICKS (1) / QUICK_TIMER_TICKS_PER_SEC)), TRUE);
+                    break;
+
+                case NFC_HAL_EVT_HCI:
+                    nfc_hal_hci_evt_hdlr ((tNFC_HAL_HCI_EVENT_DATA *) p_msg);
+                    break;
+
+                case NFC_HAL_EVT_PRE_DISCOVER:
+                    NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_PREDISCOVER_DONE);
+                    nfa_hal_send_pre_discover_cfg ();
+                    break;
+
+                case NFC_HAL_EVT_CONTROL_GRANTED:
+                    nfc_hal_dm_send_pend_cmd ();
+                    break;
+
+                default:
+                    break;
+                }
+
+                if (free_msg)
+                    GKI_freebuf (p_msg);
+            }
+        }
+
+        /* Data waiting to be read from serial port */
+        if (event & NFC_HAL_TASK_EVT_DATA_RDY)
+        {
+            while (TRUE)
+            {
+                /* Read one byte to see if there is anything waiting to be read */
+                if (USERIAL_Read (USERIAL_NFC_PORT, &byte, 1) == 0)
+                {
+                    break;
+                }
+
+                if (nfc_hal_nci_receive_msg (byte))
+                {
+                    /* complete of receiving NCI message */
+                    nfc_hal_nci_assemble_nci_msg ();
+                    if (nfc_hal_cb.ncit_cb.p_rcv_msg)
+                    {
+                        if (nfc_hal_nci_preproc_rx_nci_msg (nfc_hal_cb.ncit_cb.p_rcv_msg))
+                        {
+                            /* Send NCI message to the stack */
+                            nfc_hal_send_nci_msg_to_nfc_task (nfc_hal_cb.ncit_cb.p_rcv_msg);
+                        }
+                        else
+                        {
+                            if (nfc_hal_cb.ncit_cb.p_rcv_msg)
+                                GKI_freebuf(nfc_hal_cb.ncit_cb.p_rcv_msg);
+                        }
+                        nfc_hal_cb.ncit_cb.p_rcv_msg = NULL;
+                    }
+                }
+            } /* while (TRUE) */
+        }
+
+        /* Process quick timer tick */
+        if (event & NFC_HAL_QUICK_TIMER_EVT_MASK)
+        {
+            nfc_hal_main_process_quick_timer_evt ();
+        }
+    }
+
+    HAL_TRACE_DEBUG0 ("nfc_hal_main_task terminated");
+
+    GKI_exit_task (GKI_get_taskid ());
+    return 0;
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcSetTraceLevel
+**
+** Description      This function sets the trace level for HAL.  If called with
+**                  a value of 0xFF, it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+UINT8 HAL_NfcSetTraceLevel (UINT8 new_level)
+{
+    if (new_level != 0xFF)
+        nfc_hal_cb.trace_level = new_level;
+
+    return (nfc_hal_cb.trace_level);
+}
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_nci.c b/halimpl/bcm2079x/hal/hal/nfc_hal_nci.c
new file mode 100644
index 0000000..f4eb9af
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_nci.c
@@ -0,0 +1,887 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ *
+ *  This file contains function of the NFC unit to receive/process NCI/VS
+ *  commands/responses.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_hal_int.h"
+#include "nfc_hal_post_reset.h"
+#include "userial.h"
+#include "nci_defs.h"
+
+
+/*****************************************************************************
+** Constants and types
+*****************************************************************************/
+
+/*****************************************************************************
+** Local function prototypes
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nci_assemble_nci_msg
+**
+** Description      This function is called to reassemble the received NCI
+**                  response/notification packet, if required.
+**                  (The data packets are posted to NFC task for reassembly)
+**
+** Returns          void.
+**
+*******************************************************************************/
+void nfc_hal_nci_assemble_nci_msg (void)
+{
+    NFC_HDR *p_msg = nfc_hal_cb.ncit_cb.p_rcv_msg;
+    UINT8 u8;
+    UINT8 *p, *pp;
+    UINT8 hdr[2];
+    UINT8   *ps, *pd;
+    UINT16  size, needed;
+    BOOLEAN disp_again = FALSE;
+
+    if ((p_msg == NULL) || (p_msg->len < NCI_MSG_HDR_SIZE))
+        return;
+
+#ifdef DISP_NCI
+    DISP_NCI ((UINT8 *) (p_msg + 1) + p_msg->offset, (UINT16) (p_msg->len), TRUE);
+#endif
+
+    p       = (UINT8 *) (p_msg + 1) + p_msg->offset;
+    u8      = *p++;
+    /* remove the PBF bit for potential reassembly later */
+    hdr[0]  = u8 & ~NCI_PBF_MASK;
+    if ((u8 & NCI_MT_MASK) == NCI_MT_DATA)
+    {
+        /* clear the RFU in octet1 */
+        *(p) = 0;
+        /* data packet reassembly is performed in NFC task */
+        return;
+    }
+    else
+    {
+        *(p) &= NCI_OID_MASK;
+    }
+
+    hdr[1]  = *p;
+    pp = hdr;
+    /* save octet0 and octet1 of an NCI header in layer_specific for the received packet */
+    STREAM_TO_UINT16 (p_msg->layer_specific, pp);
+
+    if (nfc_hal_cb.ncit_cb.p_frag_msg)
+    {
+        if (nfc_hal_cb.ncit_cb.p_frag_msg->layer_specific != p_msg->layer_specific)
+        {
+            /* check if these fragments are of the same NCI message */
+            HAL_TRACE_ERROR2 ("nfc_hal_nci_assemble_nci_msg() - different messages 0x%x, 0x%x!!", nfc_hal_cb.ncit_cb.p_frag_msg->layer_specific, p_msg->layer_specific);
+            nfc_hal_cb.ncit_cb.nci_ras  |= NFC_HAL_NCI_RAS_ERROR;
+        }
+        else if (nfc_hal_cb.ncit_cb.nci_ras == 0)
+        {
+            disp_again = TRUE;
+            /* if not previous reassembly error, append the new fragment */
+            p_msg->offset   += NCI_MSG_HDR_SIZE;
+            p_msg->len      -= NCI_MSG_HDR_SIZE;
+            size    = GKI_get_buf_size (nfc_hal_cb.ncit_cb.p_frag_msg);
+            needed  = (NFC_HDR_SIZE + nfc_hal_cb.ncit_cb.p_frag_msg->len + nfc_hal_cb.ncit_cb.p_frag_msg->offset + p_msg->len);
+            if (size >= needed)
+            {
+                /* the buffer for reassembly is big enough to append the new fragment */
+                ps   = (UINT8 *) (p_msg + 1) + p_msg->offset;
+                pd   = (UINT8 *) (nfc_hal_cb.ncit_cb.p_frag_msg + 1) + nfc_hal_cb.ncit_cb.p_frag_msg->offset + nfc_hal_cb.ncit_cb.p_frag_msg->len;
+                memcpy (pd, ps, p_msg->len);
+                nfc_hal_cb.ncit_cb.p_frag_msg->len  += p_msg->len;
+                /* adjust the NCI packet length */
+                pd   = (UINT8 *) (nfc_hal_cb.ncit_cb.p_frag_msg + 1) + nfc_hal_cb.ncit_cb.p_frag_msg->offset + 2;
+                *pd  = (UINT8) (nfc_hal_cb.ncit_cb.p_frag_msg->len - NCI_MSG_HDR_SIZE);
+            }
+            else
+            {
+                nfc_hal_cb.ncit_cb.nci_ras  |= NFC_HAL_NCI_RAS_TOO_BIG;
+                HAL_TRACE_ERROR2 ("nfc_hal_nci_assemble_nci_msg() buffer overrun (%d + %d)!!", nfc_hal_cb.ncit_cb.p_frag_msg->len, p_msg->len);
+            }
+        }
+        /* we are done with this new fragment, free it */
+        GKI_freebuf (p_msg);
+    }
+    else
+    {
+        nfc_hal_cb.ncit_cb.p_frag_msg = p_msg;
+    }
+
+
+    if ((u8 & NCI_PBF_MASK) == NCI_PBF_NO_OR_LAST)
+    {
+        /* last fragment */
+        p_msg               = nfc_hal_cb.ncit_cb.p_frag_msg;
+        p                   = (UINT8 *) (p_msg + 1) + p_msg->offset;
+        *p                  = u8; /* this should make the PBF flag as Last Fragment */
+        nfc_hal_cb.ncit_cb.p_frag_msg  = NULL;
+
+        p_msg->layer_specific = nfc_hal_cb.ncit_cb.nci_ras;
+        /* still report the data packet, if the incoming packet is too big */
+        if (nfc_hal_cb.ncit_cb.nci_ras & NFC_HAL_NCI_RAS_ERROR)
+        {
+            /* NFCC reported NCI fragments for different NCI messages and this is the last fragment - drop it */
+            HAL_TRACE_ERROR0 ("nfc_hal_nci_assemble_nci_msg() clearing NCI_RAS_ERROR");
+            GKI_freebuf (p_msg);
+            p_msg = NULL;
+        }
+#ifdef DISP_NCI
+        if ((nfc_hal_cb.ncit_cb.nci_ras == 0) && (disp_again))
+        {
+            DISP_NCI ((UINT8 *) (p_msg + 1) + p_msg->offset, (UINT16) (p_msg->len), TRUE);
+        }
+#endif
+        /* clear the error flags, so the next NCI packet is clean */
+        nfc_hal_cb.ncit_cb.nci_ras = 0;
+    }
+    else
+    {
+        /* still reassembling */
+        p_msg = NULL;
+    }
+
+    nfc_hal_cb.ncit_cb.p_rcv_msg = p_msg;
+}
+
+/*****************************************************************************
+**
+** Function         nfc_hal_nci_receive_nci_msg
+**
+** Description
+**      Handle incoming data (NCI events) from the serial port.
+**
+**      If there is data waiting from the serial port, this funciton reads the
+**      data and parses it. Once an entire NCI message has been read, it sends
+**      the message the the NFC_TASK for processing
+**
+*****************************************************************************/
+static BOOLEAN nfc_hal_nci_receive_nci_msg (tNFC_HAL_NCIT_CB *p_cb, UINT8 byte)
+{
+    UINT16      len;
+    BOOLEAN     msg_received = FALSE;
+
+    switch (p_cb->rcv_state)
+    {
+    case NFC_HAL_RCV_NCI_MSG_ST:
+
+        /* Initialize rx parameters */
+        p_cb->rcv_state = NFC_HAL_RCV_NCI_HDR_ST;
+        p_cb->rcv_len   = NCI_MSG_HDR_SIZE;
+
+        /* Start of new message. Allocate a buffer for message */
+        if ((p_cb->p_rcv_msg = (NFC_HDR *) GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
+        {
+            /* Initialize NFC_HDR */
+            p_cb->p_rcv_msg->len    = 0;
+            p_cb->p_rcv_msg->event  = 0;
+            p_cb->p_rcv_msg->offset = 0;
+
+            *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte;
+        }
+        else
+        {
+            HAL_TRACE_ERROR0 ("Unable to allocate buffer for incoming NCI message.");
+        }
+        p_cb->rcv_len--;
+        break;
+
+    case NFC_HAL_RCV_NCI_HDR_ST:
+
+        if (p_cb->p_rcv_msg)
+        {
+            *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte;
+        }
+
+        p_cb->rcv_len--;
+
+        /* Check if we read in entire NFC message header yet */
+        if (p_cb->rcv_len == 0)
+        {
+            p_cb->rcv_len       = byte;
+
+            /* If non-zero payload, then go to receive-data state */
+            if (byte > 0)
+            {
+                p_cb->rcv_state = NFC_HAL_RCV_NCI_PAYLOAD_ST;
+            }
+            else
+            {
+                msg_received    = TRUE;
+                p_cb->rcv_state = NFC_HAL_RCV_IDLE_ST;
+            }
+        }
+        break;
+
+    case NFC_HAL_RCV_NCI_PAYLOAD_ST:
+
+        p_cb->rcv_len--;
+        if (p_cb->p_rcv_msg)
+        {
+            *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte;
+
+            if (p_cb->rcv_len > 0)
+            {
+                /* Read in the rest of the message */
+                len = USERIAL_Read (USERIAL_NFC_PORT, ((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len),  p_cb->rcv_len);
+                p_cb->p_rcv_msg->len    += len;
+                p_cb->rcv_len           -= len;
+            }
+        }
+
+        /* Check if we read in entire message yet */
+        if (p_cb->rcv_len == 0)
+        {
+            msg_received    = TRUE;
+            p_cb->rcv_state = NFC_HAL_RCV_IDLE_ST;
+        }
+        break;
+    }
+
+    return (msg_received);
+}
+
+/*****************************************************************************
+**
+** Function         nfc_hal_nci_receive_bt_msg
+**
+** Description
+**      Handle incoming BRCM specific data from the serial port.
+**
+**      If there is data waiting from the serial port, this funciton reads the
+**      data and parses it. Once an entire message has been read, it returns
+**      TRUE.
+**
+*****************************************************************************/
+static BOOLEAN nfc_hal_nci_receive_bt_msg (tNFC_HAL_NCIT_CB *p_cb, UINT8 byte)
+{
+    UINT16  len;
+    BOOLEAN msg_received = FALSE;
+
+    switch (p_cb->rcv_state)
+    {
+    case NFC_HAL_RCV_BT_MSG_ST:
+
+        /* Initialize rx parameters */
+        p_cb->rcv_state = NFC_HAL_RCV_BT_HDR_ST;
+        p_cb->rcv_len   = HCIE_PREAMBLE_SIZE;
+
+        if ((p_cb->p_rcv_msg = (NFC_HDR *) GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
+        {
+            /* Initialize NFC_HDR */
+            p_cb->p_rcv_msg->len    = 0;
+            p_cb->p_rcv_msg->event  = 0;
+            p_cb->p_rcv_msg->offset = 0;
+
+            *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte;
+        }
+        else
+        {
+            HAL_TRACE_ERROR0 ("[nfc] Unable to allocate buffer for incoming NCI message.");
+        }
+        p_cb->rcv_len--;
+        break;
+
+    case NFC_HAL_RCV_BT_HDR_ST:
+        if (p_cb->p_rcv_msg)
+        {
+            *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte;
+        }
+        p_cb->rcv_len--;
+
+        /* Check if we received entire preamble yet */
+        if (p_cb->rcv_len == 0)
+        {
+            /* Received entire preamble. Length is in the last byte(s) of the preamble */
+            p_cb->rcv_len = byte;
+
+            /* Verify that buffer is big enough to fit message */
+            if ((p_cb->p_rcv_msg) &&
+                ((sizeof (NFC_HDR) + HCIE_PREAMBLE_SIZE + byte) > GKI_get_buf_size (p_cb->p_rcv_msg))  )
+            {
+                /* Message cannot fit into buffer */
+                GKI_freebuf (p_cb->p_rcv_msg);
+                p_cb->p_rcv_msg     = NULL;
+
+                HAL_TRACE_ERROR0 ("Invalid length for incoming BT HCI message.");
+            }
+
+            /* Message length is valid */
+            if (byte)
+            {
+                /* Read rest of message */
+                p_cb->rcv_state = NFC_HAL_RCV_BT_PAYLOAD_ST;
+            }
+            else
+            {
+                /* Message has no additional parameters. (Entire message has been received) */
+                msg_received    = TRUE;
+                p_cb->rcv_state = NFC_HAL_RCV_IDLE_ST;  /* Next, wait for packet type of next message */
+            }
+        }
+        break;
+
+    case NFC_HAL_RCV_BT_PAYLOAD_ST:
+        p_cb->rcv_len--;
+        if (p_cb->p_rcv_msg)
+        {
+            *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte;
+
+            if (p_cb->rcv_len > 0)
+            {
+                /* Read in the rest of the message */
+                len = USERIAL_Read (USERIAL_NFC_PORT, ((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len),  p_cb->rcv_len);
+                p_cb->p_rcv_msg->len    += len;
+                p_cb->rcv_len           -= len;
+            }
+        }
+
+        /* Check if we read in entire message yet */
+        if (p_cb->rcv_len == 0)
+        {
+            msg_received        = TRUE;
+            p_cb->rcv_state     = NFC_HAL_RCV_IDLE_ST;      /* Next, wait for packet type of next message */
+        }
+        break;
+    }
+
+    /* If we received entire message */
+#if (NFC_HAL_TRACE_PROTOCOL == TRUE)
+    if (msg_received && p_cb->p_rcv_msg)
+    {
+        /* Display protocol trace message */
+        DispHciEvt (p_cb->p_rcv_msg);
+    }
+#endif
+
+    return (msg_received);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nci_proc_rx_bt_msg
+**
+** Description      Received BT message from NFCC
+**
+**                  Notify command complete if initializing NFCC
+**                  Forward BT message to NFC task
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfc_hal_nci_proc_rx_bt_msg (void)
+{
+    UINT8   *p;
+    NFC_HDR *p_msg;
+    UINT16  opcode, old_opcode;
+    tNFC_HAL_BTVSC_CPLT       vcs_cplt_params;
+    tNFC_HAL_BTVSC_CPLT_CBACK *p_cback = NULL;
+
+    /* if complete BT message is received successfully */
+    if (nfc_hal_cb.ncit_cb.p_rcv_msg)
+    {
+        p_msg   = nfc_hal_cb.ncit_cb.p_rcv_msg;
+        HAL_TRACE_DEBUG1 ("nfc_hal_nci_proc_rx_bt_msg (): GOT an BT msgs init_sta:%d", nfc_hal_cb.dev_cb.initializing_state);
+        HAL_TRACE_DEBUG2 ("event: 0x%x, wait_rsp:0x%x", p_msg->event, nfc_hal_cb.ncit_cb.nci_wait_rsp);
+        /* increase the cmd window here */
+        if (nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_PROP)
+        {
+            p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+            if (*p == HCI_COMMAND_COMPLETE_EVT)
+            {
+                p  += 3; /* code, len, cmd window */
+                STREAM_TO_UINT16 (opcode, p);
+                p   = nfc_hal_cb.ncit_cb.last_hdr;
+                STREAM_TO_UINT16 (old_opcode, p);
+                if (opcode == old_opcode)
+                {
+                    nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_NONE;
+                    p_cback = (tNFC_HAL_BTVSC_CPLT_CBACK *)nfc_hal_cb.ncit_cb.p_vsc_cback;
+                    nfc_hal_cb.ncit_cb.p_vsc_cback  = NULL;
+                    nfc_hal_main_stop_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
+                }
+            }
+        }
+
+        /* if initializing BRCM NFCC */
+        if ((nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_APP_COMPLETE) ||
+            (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_BUILD_INFO) ||
+            (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_CONTROL_DONE))
+        {
+            /* this is command complete event for baud rate update or download patch */
+            p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+
+            p += 1;    /* skip opcode */
+            STREAM_TO_UINT8  (vcs_cplt_params.param_len, p);
+
+            p += 1;    /* skip num command packets */
+            STREAM_TO_UINT16 (vcs_cplt_params.opcode, p);
+
+            vcs_cplt_params.param_len -= 3;
+            vcs_cplt_params.p_param_buf = p;
+
+            if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_CONTROL_DONE)
+            {
+                NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE);
+                nfc_hal_cb.p_stack_cback (HAL_NFC_RELEASE_CONTROL_EVT, HAL_NFC_STATUS_OK);
+            }
+            if (p_cback)
+            {
+                nfc_hal_cb.ncit_cb.p_vsc_cback = NULL;
+                (*p_cback) (&vcs_cplt_params);
+            }
+
+            /* do not BT send message to NFC task */
+            GKI_freebuf (p_msg);
+        }
+        else
+        {
+            /* do not BT send message to NFC task */
+            GKI_freebuf(nfc_hal_cb.ncit_cb.p_rcv_msg);
+        }
+        nfc_hal_cb.ncit_cb.p_rcv_msg = NULL;
+    }
+}
+
+/*****************************************************************************
+**
+** Function         nfc_hal_nci_receive_msg
+**
+** Description
+**      Handle incoming data (NCI events) from the serial port.
+**
+**      If there is data waiting from the serial port, this funciton reads the
+**      data and parses it. Once an entire NCI message has been read, it sends
+**      the message the the NFC_TASK for processing
+**
+*****************************************************************************/
+BOOLEAN nfc_hal_nci_receive_msg (UINT8 byte)
+{
+    tNFC_HAL_NCIT_CB *p_cb = &(nfc_hal_cb.ncit_cb);
+    BOOLEAN msg_received = FALSE;
+
+    if (p_cb->rcv_state == NFC_HAL_RCV_IDLE_ST)
+    {
+        /* if this is NCI message */
+        if (byte == HCIT_TYPE_NFC)
+        {
+            p_cb->rcv_state = NFC_HAL_RCV_NCI_MSG_ST;
+        }
+        /* if this is BT message */
+        else if (byte == HCIT_TYPE_EVENT)
+        {
+            p_cb->rcv_state = NFC_HAL_RCV_BT_MSG_ST;
+        }
+        else
+        {
+            HAL_TRACE_ERROR1 ("Unknown packet type drop this byte 0x%x", byte);
+        }
+    }
+    else if (p_cb->rcv_state <= NFC_HAL_RCV_NCI_PAYLOAD_ST)
+    {
+        msg_received = nfc_hal_nci_receive_nci_msg (p_cb, byte);
+    }
+    else
+    {
+        if (nfc_hal_nci_receive_bt_msg (p_cb, byte))
+        {
+            /* received BT message */
+            nfc_hal_nci_proc_rx_bt_msg ();
+        }
+    }
+
+    return (msg_received);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nci_preproc_rx_nci_msg
+**
+** Description      NFCC sends NCI message to DH while initializing NFCC
+**                  processing low power mode
+**
+** Returns          TRUE, if NFC task need to receive NCI message
+**
+*******************************************************************************/
+BOOLEAN nfc_hal_nci_preproc_rx_nci_msg (NFC_HDR *p_msg)
+{
+    UINT8 *p, *pp;
+    UINT8 mt, pbf, gid, op_code;
+    UINT8 payload_len;
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+    UINT8  cid;
+    UINT16 data_len;
+#endif
+
+    HAL_TRACE_DEBUG0 ("nfc_hal_nci_preproc_rx_nci_msg()");
+
+    /* if initializing BRCM NFCC */
+    if (nfc_hal_cb.dev_cb.initializing_state != NFC_HAL_INIT_STATE_IDLE)
+    {
+        nfc_hal_dm_proc_msg_during_init (p_msg);
+        /* do not send message to NFC task while initializing NFCC */
+        return (FALSE);
+    }
+    else
+    {
+        p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+        pp = p;
+        NCI_MSG_PRS_HDR0 (p, mt, pbf, gid);
+        NCI_MSG_PRS_HDR1 (p, op_code);
+        payload_len = *p++;
+
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+        if (mt == NCI_MT_DATA)
+        {
+            if (nfc_hal_cb.hci_cb.hcp_conn_id)
+            {
+                NCI_DATA_PRS_HDR(pp, pbf, cid, data_len);
+                if (cid == nfc_hal_cb.hci_cb.hcp_conn_id)
+                {
+                    nfc_hal_hci_handle_hcp_pkt_from_hc (pp);
+                }
+
+            }
+        }
+
+        if (gid == NCI_GID_PROP) /* this is for hci netwk ntf */
+        {
+            if (mt == NCI_MT_NTF)
+            {
+                if (op_code == NCI_MSG_HCI_NETWK)
+                {
+                    nfc_hal_hci_handle_hci_netwk_info ((UINT8 *) (p_msg + 1) + p_msg->offset);
+                }
+            }
+        }
+        else
+#endif
+        if (gid == NCI_GID_RF_MANAGE)
+        {
+            if (mt == NCI_MT_NTF)
+            {
+                if (op_code == NCI_MSG_RF_INTF_ACTIVATED)
+                {
+                    if ((nfc_hal_cb.max_rf_credits) && (payload_len > 5))
+                    {
+                        /* API used wants to limit the RF data credits */
+                        p += 5; /* skip RF disc id, interface, protocol, tech&mode, payload size */
+                        if (*p > nfc_hal_cb.max_rf_credits)
+                        {
+                            HAL_TRACE_DEBUG2 ("RfDataCredits %d->%d", *p, nfc_hal_cb.max_rf_credits);
+                            *p = nfc_hal_cb.max_rf_credits;
+                        }
+                    }
+                }
+            }
+        }
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+        else if (gid == NCI_GID_CORE)
+        {
+            if (mt == NCI_MT_RSP)
+            {
+                if (op_code == NCI_MSG_CORE_CONN_CREATE)
+                {
+                    if (nfc_hal_cb.hci_cb.b_wait_hcp_conn_create_rsp)
+                    {
+                        p++; /* skip status byte */
+                        nfc_hal_cb.hci_cb.b_wait_hcp_conn_create_rsp = FALSE;
+                        p++; /* skip buff size */
+                        p++; /* num of buffers */
+                        nfc_hal_cb.hci_cb.hcp_conn_id = *p;
+                    }
+                }
+            }
+        }
+#endif
+    }
+
+    if (nfc_hal_cb.dev_cb.power_mode == NFC_HAL_POWER_MODE_FULL)
+    {
+        if (nfc_hal_cb.dev_cb.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE)
+        {
+            /* extend idle timer */
+            nfc_hal_dm_power_mode_execute (NFC_HAL_LP_RX_DATA_EVT);
+        }
+    }
+
+    return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nci_add_nfc_pkt_type
+**
+** Description      Add packet type (HCIT_TYPE_NFC)
+**
+** Returns          TRUE, if NFCC can receive NCI message
+**
+*******************************************************************************/
+void nfc_hal_nci_add_nfc_pkt_type (NFC_HDR *p_msg)
+{
+    UINT8   *p;
+    UINT8   hcit;
+
+    /* add packet type in front of NCI header */
+    if (p_msg->offset > 0)
+    {
+        p_msg->offset--;
+        p_msg->len++;
+
+        p  = (UINT8 *) (p_msg + 1) + p_msg->offset;
+        *p = HCIT_TYPE_NFC;
+    }
+    else
+    {
+        HAL_TRACE_ERROR0 ("nfc_hal_nci_add_nfc_pkt_type () : No space for packet type");
+        hcit = HCIT_TYPE_NFC;
+        USERIAL_Write (USERIAL_NFC_PORT, &hcit, 1);
+    }
+}
+
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+/*******************************************************************************
+**
+** Function         nci_brcm_check_cmd_create_hcp_connection
+**
+** Description      Check if this is command to create HCP connection
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nci_brcm_check_cmd_create_hcp_connection (NFC_HDR *p_msg)
+{
+    UINT8 *p;
+    UINT8 mt, pbf, gid, op_code;
+
+    nfc_hal_cb.hci_cb.b_wait_hcp_conn_create_rsp = FALSE;
+
+    p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+
+    if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_IDLE)
+    {
+        NCI_MSG_PRS_HDR0 (p, mt, pbf, gid);
+        NCI_MSG_PRS_HDR1 (p, op_code);
+
+        if (gid == NCI_GID_CORE)
+        {
+            if (mt == NCI_MT_CMD)
+            {
+                if (op_code == NCI_MSG_CORE_CONN_CREATE)
+                {
+                    if (  ((NCI_CORE_PARAM_SIZE_CON_CREATE + 4) == *p++)
+                        &&(NCI_DEST_TYPE_NFCEE == *p++)
+                        &&(1 == *p++)
+                        &&(NCI_CON_CREATE_TAG_NFCEE_VAL == *p++)
+                        &&(2 == *p++)  )
+                    {
+                        p++;
+                        if (NCI_NFCEE_INTERFACE_HCI_ACCESS == *p)
+                        {
+                            nfc_hal_cb.hci_cb.b_wait_hcp_conn_create_rsp = TRUE;
+                            return;
+                        }
+                    }
+
+                }
+            }
+        }
+    }
+}
+
+#endif
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nci_send_cmd
+**
+** Description      Send NCI command to the transport
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_nci_send_cmd (NFC_HDR *p_buf)
+{
+    BOOLEAN continue_to_process = TRUE;
+    UINT8   *ps, *pd;
+    UINT16  max_len;
+    UINT16  buf_len, offset;
+    UINT8   *p;
+    UINT8   hdr[NCI_MSG_HDR_SIZE];
+    UINT8   nci_ctrl_size = nfc_hal_cb.ncit_cb.nci_ctrl_size;
+    UINT8   delta = 0;
+
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+    if (  (nfc_hal_cb.hci_cb.hcp_conn_id == 0)
+        &&(nfc_hal_cb.nvm_cb.nvm_type != NCI_SPD_NVM_TYPE_NONE)  )
+        nci_brcm_check_cmd_create_hcp_connection ((NFC_HDR*) p_buf);
+#endif
+
+    /* check low power mode state */
+    continue_to_process = nfc_hal_dm_power_mode_execute (NFC_HAL_LP_TX_DATA_EVT);
+
+    if (!continue_to_process)
+    {
+        /* save the command to be sent until NFCC is free. */
+        nfc_hal_cb.ncit_cb.p_pend_cmd   = p_buf;
+        return;
+    }
+
+    max_len = nci_ctrl_size + NCI_MSG_HDR_SIZE;
+    buf_len = p_buf->len;
+    offset  = p_buf->offset;
+#ifdef DISP_NCI
+    if (buf_len > max_len)
+    {
+        /* this command needs to be fragmented. display the complete packet first */
+        DISP_NCI ((UINT8 *) (p_buf + 1) + p_buf->offset, p_buf->len, FALSE);
+    }
+#endif
+    ps      = (UINT8 *) (p_buf + 1) + p_buf->offset;
+    memcpy (hdr, ps, NCI_MSG_HDR_SIZE);
+    while (buf_len > max_len)
+    {
+        HAL_TRACE_DEBUG2 ("buf_len (%d) > max_len (%d)", buf_len, max_len);
+        /* the NCI command is bigger than the NFCC Max Control Packet Payload Length
+         * fragment the command */
+
+        p_buf->len  = max_len;
+        ps   = (UINT8 *) (p_buf + 1) + p_buf->offset;
+        /* mark the control packet as fragmented */
+        *ps |= NCI_PBF_ST_CONT;
+        /* adjust the length of this fragment */
+        ps  += 2;
+        *ps  = nci_ctrl_size;
+
+        /* add NCI packet type in front of message */
+        nfc_hal_nci_add_nfc_pkt_type (p_buf);
+
+        /* send this fragment to transport */
+        p = (UINT8 *) (p_buf + 1) + p_buf->offset;
+
+#ifdef DISP_NCI
+        delta = p_buf->len - max_len;
+        DISP_NCI (p + delta, (UINT16) (p_buf->len - delta), FALSE);
+#endif
+        USERIAL_Write (USERIAL_NFC_PORT, p, p_buf->len);
+
+        /* adjust the len and offset to reflect that part of the command is already sent */
+        buf_len -= nci_ctrl_size;
+        offset  += nci_ctrl_size;
+        HAL_TRACE_DEBUG2 ("p_buf->len: %d buf_len (%d)", p_buf->len, buf_len);
+        p_buf->len      = buf_len;
+        p_buf->offset   = offset;
+        pd   = (UINT8 *) (p_buf + 1) + p_buf->offset;
+        /* restore the NCI header */
+        memcpy (pd, hdr, NCI_MSG_HDR_SIZE);
+        pd  += 2;
+        *pd  = (UINT8) (p_buf->len - NCI_MSG_HDR_SIZE);
+    }
+
+    HAL_TRACE_DEBUG1 ("p_buf->len: %d", p_buf->len);
+
+    /* add NCI packet type in front of message */
+    nfc_hal_nci_add_nfc_pkt_type (p_buf);
+
+    /* send this fragment to transport */
+    p = (UINT8 *) (p_buf + 1) + p_buf->offset;
+
+#ifdef DISP_NCI
+    delta = p_buf->len - buf_len;
+    DISP_NCI (p + delta, (UINT16) (p_buf->len - delta), FALSE);
+#endif
+    USERIAL_Write (USERIAL_NFC_PORT, p, p_buf->len);
+
+    GKI_freebuf (p_buf);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nci_cmd_timeout_cback
+**
+** Description      callback function for timeout
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_nci_cmd_timeout_cback (void *p_tle)
+{
+    TIMER_LIST_ENT  *p_tlent = (TIMER_LIST_ENT *)p_tle;
+
+    HAL_TRACE_DEBUG0 ("nfc_hal_nci_cmd_timeout_cback ()");
+
+    nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_NONE;
+
+    if (p_tlent->event == NFC_HAL_TTYPE_NCI_WAIT_RSP)
+    {
+        if (nfc_hal_cb.dev_cb.initializing_state <= NFC_HAL_INIT_STATE_W4_PATCH_INFO)
+        {
+            NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+            nfc_hal_main_pre_init_done (HAL_NFC_STATUS_ERR_CMD_TIMEOUT);
+        }
+        else if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_APP_COMPLETE)
+        {
+            if (nfc_hal_cb.prm.state != NFC_HAL_PRM_ST_IDLE)
+            {
+                nfc_hal_prm_process_timeout (NULL);
+            }
+            else
+            {
+                NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+                nfc_hal_main_pre_init_done (HAL_NFC_STATUS_ERR_CMD_TIMEOUT);
+            }
+        }
+        else if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_POST_INIT_DONE)
+        {
+            NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+            nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_ERR_CMD_TIMEOUT);
+        }
+        else if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_CONTROL_DONE)
+        {
+            NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE);
+            nfc_hal_cb.p_stack_cback (HAL_NFC_RELEASE_CONTROL_EVT, HAL_NFC_STATUS_ERR_CMD_TIMEOUT);
+        }
+        else if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_PREDISCOVER_DONE)
+        {
+            NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE);
+            nfc_hal_cb.p_stack_cback (HAL_NFC_PRE_DISCOVER_CPLT_EVT, HAL_NFC_STATUS_ERR_CMD_TIMEOUT);
+        }
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         HAL_NfcSetMaxRfDataCredits
+**
+** Description      This function sets the maximum RF data credit for HAL.
+**                  If 0, use the value reported from NFCC.
+**
+** Returns          none
+**
+*******************************************************************************/
+void HAL_NfcSetMaxRfDataCredits (UINT8 max_credits)
+{
+    HAL_TRACE_DEBUG2 ("HAL_NfcSetMaxRfDataCredits %d->%d", nfc_hal_cb.max_rf_credits, max_credits);
+    nfc_hal_cb.max_rf_credits   = max_credits;
+}
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_prm.c b/halimpl/bcm2079x/hal/hal/nfc_hal_prm.c
new file mode 100644
index 0000000..d1b739c
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_prm.c
@@ -0,0 +1,1195 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include "nfc_hal_int.h"
+#include "userial.h"
+
+/*****************************************************************************
+* Definitions
+*****************************************************************************/
+
+/* Internal flags */
+#define NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF  0x01    /* Application provided patchram in a single buffer */
+#define NFC_HAL_PRM_FLAGS_RFU               0x02    /* Reserved for future use */
+#define NFC_HAL_PRM_FLAGS_SIGNATURE_SENT    0x04    /* Signature sent to NFCC */
+#define NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED  0x08    /* PreI2C patch required */
+#define NFC_HAL_PRM_FLAGS_BCM20791B3        0x10    /* B3 Patch (no RESET_NTF after patch download) */
+#define NFC_HAL_PRM_FLAGS_RM_RF             0x20    /* Erase Personality data */
+
+/* Secure patch download definitions */
+#define NFC_HAL_PRM_NCD_PATCHFILE_HDR_LEN  7       /* PRJID + MAJORVER + MINORVER + COUNT */
+
+/* Enumeration of power modes IDs */
+#define NFC_HAL_PRM_SPD_POWER_MODE_LPM     0
+#define NFC_HAL_PRM_SPD_POWER_MODE_FPM     1
+
+/* Version string for BCM20791B3 */
+const UINT8 NFC_HAL_PRM_BCM20791B3_STR[]   = "20791B3";
+#define NFC_HAL_PRM_BCM20791B3_STR_LEN     (sizeof (NFC_HAL_PRM_BCM20791B3_STR)-1)
+
+#define NFC_HAL_PRM_SPD_TOUT                   (6000)  /* timeout for SPD events (in ms)   */
+#define NFC_HAL_PRM_END_DELAY                  (250)   /* delay before sending any new command (ms)*/
+
+#if (NFC_HAL_PRM_DEBUG == TRUE)
+#define NFC_HAL_PRM_STATE(str)  HAL_TRACE_DEBUG2 ("%s st: %d", str, nfc_hal_cb.prm.state)
+#else
+#define NFC_HAL_PRM_STATE(str)
+#endif
+
+void nfc_hal_prm_post_baud_update (tHAL_NFC_STATUS status);
+typedef struct
+{
+    UINT16              offset;
+    UINT8               len;
+} tNFC_HAL_PRM_RM_RF;
+
+const tNFC_HAL_PRM_RM_RF nfc_hal_prm_rm_rf_20795a1 [] =
+{
+    {0x0000,    0xFB},
+    {0x019C,    0x08},
+    {0x05E8,    0xFB},
+    {0,         0}
+};
+static BOOLEAN nfc_hal_prm_nvm_rw_cmd(void);
+
+/*****************************************************************************
+** Extern variable from nfc_hal_dm_cfg.c
+*****************************************************************************/
+extern tNFC_HAL_CFG *p_nfc_hal_cfg;
+
+/*******************************************************************************
+**
+** Function         nfc_hal_prm_spd_handle_download_complete
+**
+** Description      Patch download complete (for secure patch download)
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_prm_spd_handle_download_complete (UINT8 event)
+{
+    nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_IDLE;
+
+    /* Notify application now */
+    if (nfc_hal_cb.prm.p_cback)
+        (nfc_hal_cb.prm.p_cback) (event);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_prm_spd_send_next_segment
+**
+** Description      Send next patch segment (for secure patch download)
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_prm_spd_send_next_segment (void)
+{
+    UINT8   *p_src;
+    UINT16  len, offset = nfc_hal_cb.prm.cur_patch_offset;
+    UINT8   hcit, oid, hdr0, type;
+    UINT8   chipverlen;
+    UINT8   chipverstr[NCI_SPD_HEADER_CHIPVER_LEN];
+    UINT8   patch_hdr_size = NCI_MSG_HDR_SIZE + 1; /* 1 is for HCIT */
+
+    /* Validate that segment is at least big enought to have NCI_MSG_HDR_SIZE + 1 (hcit) */
+    if (nfc_hal_cb.prm.cur_patch_len_remaining < patch_hdr_size)
+    {
+        HAL_TRACE_ERROR0 ("Unexpected end of patch.");
+        nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
+        return;
+    }
+
+    /* Parse NCI command header */
+    p_src = (UINT8*) (nfc_hal_cb.prm.p_cur_patch_data + offset);
+    STREAM_TO_UINT8 (hcit, p_src);
+    STREAM_TO_UINT8 (hdr0, p_src);
+    STREAM_TO_UINT8 (oid,  p_src);
+    STREAM_TO_UINT8 (len,  p_src);
+    STREAM_TO_UINT8 (type, p_src);
+
+
+    /* Update number of bytes comsumed */
+    nfc_hal_cb.prm.cur_patch_offset += (len + patch_hdr_size);
+    nfc_hal_cb.prm.cur_patch_len_remaining -=  (len + patch_hdr_size);
+
+    /* Check if sending signature byte */
+    if (  (oid == NCI_MSG_SECURE_PATCH_DOWNLOAD )
+        &&(type == NCI_SPD_TYPE_SIGNATURE)  )
+    {
+        nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_SIGNATURE_SENT;
+    }
+    /* Check for header */
+    else if (  (oid == NCI_MSG_SECURE_PATCH_DOWNLOAD )
+             &&(type == NCI_SPD_TYPE_HEADER)  )
+    {
+        /* Check if patch is for BCM20791B3 */
+        p_src += NCI_SPD_HEADER_OFFSET_CHIPVERLEN;
+        STREAM_TO_UINT8 (chipverlen, p_src);
+        if (memcmp (nfc_hal_cb.nvm_cb.chip_ver, p_src, chipverlen) != 0)
+        {
+            HAL_TRACE_ERROR0 ("Unexpected chip ver.");
+            nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
+            return;
+        }
+        STREAM_TO_ARRAY (chipverstr, p_src, NCI_SPD_HEADER_CHIPVER_LEN);
+
+        if (memcmp (NFC_HAL_PRM_BCM20791B3_STR, chipverstr, NFC_HAL_PRM_BCM20791B3_STR_LEN) == 0)
+        {
+            /* Patch is for BCM2079B3 - do not wait for RESET_NTF after patch download */
+            nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_BCM20791B3;
+        }
+        else
+        {
+            /* Patch is for BCM2079B4 or newer - wait for RESET_NTF after patch download */
+            nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_BCM20791B3;
+        }
+    }
+
+    /* Send the command (not including HCIT here) */
+    nfc_hal_dm_send_nci_cmd ((UINT8*) (nfc_hal_cb.prm.p_cur_patch_data + offset + 1), (UINT8) (len + NCI_MSG_HDR_SIZE),
+                             nfc_hal_prm_nci_command_complete_cback);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_prm_spd_handle_next_patch_start
+**
+** Description      Handle start of next patch (for secure patch download)
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_prm_spd_handle_next_patch_start (void)
+{
+    UINT32  cur_patch_mask;
+    UINT32  cur_patch_len;
+    BOOLEAN found_patch_to_download = FALSE;
+
+    while (!found_patch_to_download)
+    {
+        /* Get length of current patch */
+        cur_patch_len = nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].len;
+
+        /* Check if this is a patch we need to download */
+        cur_patch_mask = ((UINT32) 1 << nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].power_mode);
+        if (nfc_hal_cb.prm.spd_patch_needed_mask & cur_patch_mask)
+        {
+            found_patch_to_download = TRUE;
+        }
+        else
+        {
+            /* Do not need to download this patch. Skip to next patch */
+            HAL_TRACE_DEBUG1 ("Skipping patch for power_mode %i.", nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].power_mode);
+
+            nfc_hal_cb.prm.spd_cur_patch_idx++;
+            if (nfc_hal_cb.prm.spd_cur_patch_idx >= nfc_hal_cb.prm.spd_patch_count)
+            {
+                /* No more to download */
+                nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_COMPLETE_EVT);
+                return;
+            }
+            else if (!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF))
+            {
+                /* Notify adaptation layer to call HAL_NfcPrmDownloadContinue with the next patch header */
+                (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_SPD_GET_NEXT_PATCH);
+                return;
+            }
+            else
+            {
+                /* Patch in buffer. Skip over current patch. Check next patch */
+                nfc_hal_cb.prm.cur_patch_len_remaining -= (UINT16) cur_patch_len;
+                nfc_hal_cb.prm.cur_patch_offset += (UINT16) cur_patch_len;
+            }
+        }
+    }
+
+
+    /* Begin downloading patch */
+    HAL_TRACE_DEBUG1 ("Downloading patch for power_mode %i.", nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].power_mode);
+    nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_DOWNLOADING;
+    nfc_hal_prm_spd_send_next_segment ();
+}
+
+#if (defined (NFC_HAL_PRE_I2C_PATCH_INCLUDED) && (NFC_HAL_PRE_I2C_PATCH_INCLUDED == TRUE))
+/*******************************************************************************
+**
+** Function         nfc_hal_prm_spd_download_i2c_fix
+**
+** Description      Start downloading patch for i2c fix
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_prm_spd_download_i2c_fix (void)
+{
+    UINT8 *p, *p_start;
+    UINT16 patchfile_project_id;
+    UINT16 patchfile_ver_major;
+    UINT16 patchfile_ver_minor;
+    UINT16 patchfile_patchsize;
+    UINT8 u8;
+
+    HAL_TRACE_DEBUG0 ("Downloading I2C fix...");
+
+    /* Save pointer and offset of patchfile, so we can resume after downloading the i2c fix */
+    nfc_hal_cb.prm.spd_patch_offset = nfc_hal_cb.prm.cur_patch_offset;
+    nfc_hal_cb.prm.spd_patch_len_remaining = nfc_hal_cb.prm.cur_patch_len_remaining;
+
+    /* Initialize pointers for downloading i2c fix */
+    nfc_hal_cb.prm.p_cur_patch_data = nfc_hal_cb.prm_i2c.p_patch;
+    nfc_hal_cb.prm.cur_patch_offset = 0;
+    nfc_hal_cb.prm.cur_patch_len_remaining = nfc_hal_cb.prm_i2c.len;
+
+    /* Parse the i2c patchfile */
+    if (nfc_hal_cb.prm.cur_patch_len_remaining >= NFC_HAL_PRM_NCD_PATCHFILE_HDR_LEN)
+    {
+        /* Parse patchfile header */
+        p = (UINT8 *) nfc_hal_cb.prm.p_cur_patch_data;
+        p_start = p;
+        STREAM_TO_UINT16 (patchfile_project_id, p);
+        STREAM_TO_UINT16 (patchfile_ver_major, p);
+        STREAM_TO_UINT16 (patchfile_ver_minor, p);
+
+        /* RFU */
+        p++;
+
+        /* Check how many patches are in the patch file */
+        STREAM_TO_UINT8 (u8, p);
+
+        /* Should only be one patch */
+        if (u8 > 1)
+        {
+            HAL_TRACE_ERROR1 ("Invalid i2c fix: invalid number of patches (%i)", u8);
+            nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
+            return;
+        }
+
+
+        /* Get info about the i2c patch*/
+        STREAM_TO_UINT8 (u8, p);                     /* power mode (not needed for i2c patch)    */
+        STREAM_TO_UINT16 (patchfile_patchsize, p);   /* size of patch                            */
+
+        /* 5 byte RFU */
+        p += 5;
+
+        /* Adjust length to exclude patchfiloe header */
+        nfc_hal_cb.prm.cur_patch_len_remaining -= (UINT16) (p - p_start);       /* Adjust size of patchfile                        */
+        nfc_hal_cb.prm.cur_patch_offset += (UINT16) (p - p_start);              /* Bytes of patchfile transmitted/processed so far */
+
+        /* Begin sending patch to the NFCC */
+        nfc_hal_prm_spd_send_next_segment ();
+    }
+    else
+    {
+        /* ERROR: Bad length for patchfile */
+        HAL_TRACE_ERROR0 ("Invalid i2c fix: unexpected end of patch");
+        nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
+    }
+}
+#endif /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */
+
+/*******************************************************************************
+**
+** Function         nfc_hal_prm_spd_check_version_continue
+**
+** Description      Check patchfile version with current downloaded version
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfc_hal_prm_spd_check_version_continue (void)
+{
+    HAL_TRACE_DEBUG1 ("nfc_hal_prm_spd_check_version_continue 0x%02x", nfc_hal_cb.prm.flags);
+    if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_RM_RF)
+    {
+        HAL_TRACE_DEBUG0("erase relevant blocks in NVM");
+        nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_RM_RF;
+        if (!nfc_hal_prm_nvm_rw_cmd())
+        {
+            /* nvm rw started successfully */
+            return;
+        }
+    }
+#if (defined (NFC_HAL_PRE_I2C_PATCH_INCLUDED) && (NFC_HAL_PRE_I2C_PATCH_INCLUDED == TRUE))
+    if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED)
+    {
+        HAL_TRACE_DEBUG0 ("I2C patch fix required.");
+        /* Download i2c fix first */
+        nfc_hal_prm_spd_download_i2c_fix ();
+        return;
+    }
+#endif  /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */
+
+    /* Download first segment */
+    nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER;
+    if (!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF))
+    {
+        /* Notify adaptation layer to call HAL_NfcPrmDownloadContinue with the next patch segment */
+        (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_SPD_GET_NEXT_PATCH);
+    }
+    else
+    {
+        nfc_hal_prm_spd_handle_next_patch_start ();
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_prm_spd_check_version
+**
+** Description      Check patchfile version with current downloaded version
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_prm_spd_check_version (void)
+{
+    UINT8 *p, *p_start, i;
+    UINT32 nvm_patch_present_mask = 0;
+    UINT32 patchfile_patch_present_mask;
+    UINT16 patchfile_project_id = 0;
+    UINT16 patchfile_ver_major = 0;
+    UINT16 patchfile_ver_minor = 0;
+    UINT16 patchfile_patchsize;
+
+    UINT8  return_code = NFC_HAL_PRM_COMPLETE_EVT;
+
+    /* Initialize patchfile offset pointers */
+    p = p_start = NULL;
+    patchfile_patchsize = 0;
+
+    /* the good patches in NVM */
+    if (nfc_hal_cb.nvm_cb.lpm_size && !(nfc_hal_cb.nvm_cb.flags & (NFC_HAL_NVM_FLAGS_LPM_BAD)))
+        nvm_patch_present_mask  |= (1 << NFC_HAL_PRM_SPD_POWER_MODE_LPM);
+
+    if (nfc_hal_cb.nvm_cb.fpm_size && !(nfc_hal_cb.nvm_cb.flags & (NFC_HAL_NVM_FLAGS_FPM_BAD)))
+        nvm_patch_present_mask  |= (1 << NFC_HAL_PRM_SPD_POWER_MODE_FPM);
+
+    /* Get patchfile version */
+    if (nfc_hal_cb.prm.cur_patch_len_remaining >= NFC_HAL_PRM_NCD_PATCHFILE_HDR_LEN)
+    {
+        /* Parse patchfile header */
+        p       = (UINT8 *) nfc_hal_cb.prm.p_cur_patch_data;
+        p_start = p;
+        STREAM_TO_UINT16 (patchfile_project_id, p);
+        STREAM_TO_UINT16 (patchfile_ver_major, p);
+        STREAM_TO_UINT16 (patchfile_ver_minor, p);
+
+        /* RFU */
+        p++;
+
+        /* Check how many patches are in the patch file */
+        STREAM_TO_UINT8 (nfc_hal_cb.prm.spd_patch_count, p);
+
+        if (nfc_hal_cb.prm.spd_patch_count > NFC_HAL_PRM_MAX_PATCH_COUNT)
+        {
+            HAL_TRACE_ERROR2 ("Unsupported patchfile (number of patches (%i) exceeds maximum (%i)",
+                               nfc_hal_cb.prm.spd_patch_count, NFC_HAL_PRM_MAX_PATCH_COUNT);
+        }
+
+        /* Mask of patches that are present in the patchfile */
+        patchfile_patch_present_mask = 0;
+
+        /* Get lengths for each patch */
+        for (i = 0; i < nfc_hal_cb.prm.spd_patch_count; i++)
+        {
+            /* Get power mode for this patch */
+            STREAM_TO_UINT8 (nfc_hal_cb.prm.spd_patch_desc[i].power_mode, p);
+
+            /* Update mask of power-modes present in the patchfile */
+            patchfile_patch_present_mask |= ((UINT32) 1 << nfc_hal_cb.prm.spd_patch_desc[i].power_mode);
+
+            /* Get length of patch */
+            STREAM_TO_UINT16 (nfc_hal_cb.prm.spd_patch_desc[i].len, p);
+
+            /* Add total size of patches */
+            patchfile_patchsize += nfc_hal_cb.prm.spd_patch_desc[i].len;
+
+            /* 5 byte RFU */
+            p += 5;
+        }
+
+        /* Adjust offset to after the patch file header */
+        nfc_hal_cb.prm.cur_patch_offset += (UINT16) (p - p_start);              /* Bytes of patchfile transmitted/processed so far */
+        nfc_hal_cb.prm.cur_patch_len_remaining -= (UINT16) (p - p_start);       /* Adjust size of patchfile                        */
+
+
+        HAL_TRACE_DEBUG4 ("NVM Patch info: flags=0x%04x,   Ver=%i.%i, PatchMask=0x%08x",
+            nfc_hal_cb.nvm_cb.flags, nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.ver_minor, nvm_patch_present_mask );
+        HAL_TRACE_DEBUG6 ("Patchfile info: ProjID=0x%04x,  Ver=%i.%i, Num patches=%i, PatchMask=0x%08x, PatchSize=%i",
+                           patchfile_project_id, patchfile_ver_major, patchfile_ver_minor,
+                           nfc_hal_cb.prm.spd_patch_count, patchfile_patch_present_mask, patchfile_patchsize);
+
+        /*********************************************************************
+        * Version check of patchfile against NVM
+        *********************************************************************/
+        /* Download the patchfile if no patches in NVM */
+        if ((nfc_hal_cb.nvm_cb.project_id == 0) || !(nfc_hal_cb.nvm_cb.flags & NFC_HAL_NVM_FLAGS_PATCH_PRESENT))
+        {
+            /* No patch in NVM, need to download all */
+            nfc_hal_cb.prm.spd_patch_needed_mask = patchfile_patch_present_mask;
+            if (nfc_hal_cb.dev_cb.brcm_hw_id == BRCM_20795A1_ID)
+            {
+                nfc_hal_cb.prm.flags   |= NFC_HAL_PRM_FLAGS_RM_RF;
+                nfc_hal_cb.prm.p_param  = (void *)nfc_hal_prm_rm_rf_20795a1;
+                nfc_hal_cb.prm.param_idx = 0;
+            }
+
+            HAL_TRACE_DEBUG2 ("No previous patch detected. Downloading patch %i.%i",
+                              patchfile_ver_major, patchfile_ver_minor);
+        }
+        /* Skip download if project ID of patchfile does not match NVM */
+        else if (nfc_hal_cb.nvm_cb.project_id != patchfile_project_id)
+        {
+            /* Project IDs mismatch */
+            HAL_TRACE_DEBUG2 ("Patch download skipped: Mismatched Project ID (NVM ProjId: 0x%04x, Patchfile ProjId: 0x%04x)",
+                              nfc_hal_cb.nvm_cb.project_id, patchfile_project_id);
+
+            return_code = NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT;
+        }
+        /* Skip download if version of patchfile is equal to version in NVM */
+        /*                  and patches of the power modes are the same as the good patches in NVM */
+        else if (  (nfc_hal_cb.nvm_cb.ver_major == patchfile_ver_major)
+            &&(nfc_hal_cb.nvm_cb.ver_minor == patchfile_ver_minor)
+                 &&((nvm_patch_present_mask | patchfile_patch_present_mask) == nvm_patch_present_mask)  ) /* if the NVM patch include all the patched in file */
+        {
+            HAL_TRACE_DEBUG2 ("Patch download skipped. NVM patch (version %i.%i) is the same than the patchfile ",
+                              nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.ver_minor);
+
+            return_code = NFC_HAL_PRM_COMPLETE_EVT;
+        }
+        /* Remaining cases: Download all patches in the patchfile */
+        else
+        {
+            nfc_hal_cb.prm.spd_patch_needed_mask = patchfile_patch_present_mask;
+
+            HAL_TRACE_DEBUG4 ("Downloading patch version: %i.%i (previous version in NVM: %i.%i)...",
+                              patchfile_ver_major, patchfile_ver_minor,
+                              nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.ver_minor);
+        }
+
+    }
+    else
+    {
+        /* Invalid patch file header */
+        HAL_TRACE_ERROR0 ("Invalid patch file header.");
+
+        return_code = NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT;
+    }
+
+    /* If we need to download anything, get the first patch to download */
+    if (nfc_hal_cb.prm.spd_patch_needed_mask)
+    {
+        HAL_TRACE_ERROR4 ("Downloading patch version: %i.%i (previous version in NVM: %i.%i)...",
+                            patchfile_ver_major, patchfile_ver_minor,
+                            nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.ver_minor);
+#if (defined (NFC_HAL_PRE_I2C_PATCH_INCLUDED) && (NFC_HAL_PRE_I2C_PATCH_INCLUDED == TRUE))
+        /* Check if I2C patch is needed: if                                     */
+        /*      - I2C patch file was provided using HAL_NfcPrmSetI2cPatch, and        */
+        /*      -   current patch in NVM has ProjectID=0, or                    */
+        /*          FPM is not present or corrupted, or                         */
+        /*          or patchfile is major-ver 76+                               */
+        /*          or patchfile is not for B3 (always download for B4 onward)  */
+        if (  (nfc_hal_cb.prm_i2c.p_patch)
+            &&(  (nfc_hal_cb.nvm_cb.project_id == 0)
+               ||(nfc_hal_cb.nvm_cb.fpm_size == 0)
+               ||(nfc_hal_cb.nvm_cb.flags & NFC_HAL_NVM_FLAGS_FPM_BAD)
+               ||(patchfile_ver_major >= 76)
+               ||(!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_BCM20791B3)) ))
+        {
+            HAL_TRACE_DEBUG0 ("I2C patch fix required.");
+            nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED;
+        }
+#endif  /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */
+        nfc_hal_prm_spd_check_version_continue ();
+    }
+    else
+    {
+        static BOOLEAN firstTime = TRUE;
+        if (firstTime)
+        {
+            HAL_TRACE_ERROR2 ("NVM patch version is %d.%d",
+                              nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.ver_minor);
+            firstTime = FALSE;
+        }
+        /* Download complete */
+        nfc_hal_prm_spd_handle_download_complete (return_code);
+    }
+}
+
+#if (NFC_HAL_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function         nfc_hal_prm_spd_status_str
+**
+** Description      Return status string for a given spd status code
+**
+** Returns          Status string
+**
+*******************************************************************************/
+UINT8 *nfc_hal_prm_spd_status_str (UINT8 spd_status_code)
+{
+    char *p_str;
+
+    switch (spd_status_code)
+    {
+    case NCI_STATUS_SPD_ERROR_DEST:
+        p_str = "SPD_ERROR_DEST";
+        break;
+
+    case NCI_STATUS_SPD_ERROR_PROJECTID:
+        p_str = "SPD_ERROR_PROJECTID";
+        break;
+
+    case NCI_STATUS_SPD_ERROR_CHIPVER:
+        p_str = "SPD_ERROR_CHIPVER";
+        break;
+
+    case NCI_STATUS_SPD_ERROR_MAJORVER:
+        p_str = "SPD_ERROR_MAJORVER";
+        break;
+
+    case NCI_STATUS_SPD_ERROR_INVALID_PARAM:
+        p_str = "SPD_ERROR_INVALID_PARAM";
+        break;
+
+    case NCI_STATUS_SPD_ERROR_INVALID_SIG:
+        p_str = "SPD_ERROR_INVALID_SIG";
+        break;
+
+    case NCI_STATUS_SPD_ERROR_NVM_CORRUPTED:
+        p_str = "SPD_ERROR_NVM_CORRUPTED";
+        break;
+
+    case NCI_STATUS_SPD_ERROR_PWR_MODE:
+        p_str = "SPD_ERROR_PWR_MODE";
+        break;
+
+    case NCI_STATUS_SPD_ERROR_MSG_LEN:
+        p_str = "SPD_ERROR_MSG_LEN";
+        break;
+
+    case NCI_STATUS_SPD_ERROR_PATCHSIZE:
+        p_str = "SPD_ERROR_PATCHSIZE";
+        break;
+
+    default:
+        p_str = "Unspecified Error";
+        break;
+
+    }
+
+    return ((UINT8*) p_str);
+}
+#endif  /* (NFC_HAL_TRACE_VERBOSE == TRUE) */
+/*******************************************************************************
+**
+** Function         nfc_hal_prm_nvm_rw_cmd
+**
+** Description      Non Volatile Read Write Command; for now only write zeros
+**
+** Returns          TRUE if done.
+**
+*******************************************************************************/
+static BOOLEAN nfc_hal_prm_nvm_rw_cmd(void)
+{
+    tNFC_HAL_PRM_RM_RF  *p_param = (tNFC_HAL_PRM_RM_RF *)(nfc_hal_cb.prm.p_param);
+    UINT8   *p_buff, *p, *p_end;
+    UINT8   len = 0;
+    UINT16  cmd_len;
+
+    if (p_param)
+        len     = p_param[nfc_hal_cb.prm.param_idx].len;
+    HAL_TRACE_DEBUG2 ("nfc_hal_prm_nvm_rw_cmd: %d/%d", nfc_hal_cb.prm.param_idx, len);
+    if (len == 0)
+    {
+        return TRUE;
+    }
+    cmd_len = len + 7;
+
+    if ((p_buff = (UINT8 *) GKI_getbuf(cmd_len)) == NULL)
+    {
+        HAL_TRACE_ERROR0 ("NVM No buffer");
+        nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT);
+        return TRUE;
+    }
+
+    p = p_buff;
+
+    UINT8_TO_STREAM  (p, (NCI_MTS_CMD|NCI_GID_PROP));
+    UINT8_TO_STREAM  (p, NCI_MSG_EEPROM_RW);
+    UINT8_TO_STREAM  (p, (len+4));
+    UINT8_TO_STREAM  (p, 1); /* 1=write 0=read */
+    UINT16_TO_STREAM  (p, p_param[nfc_hal_cb.prm.param_idx].offset);
+    UINT8_TO_STREAM  (p, len);
+    memset (p, 0, len); /* Fill remaining bytes with zeros*/
+
+    nfc_hal_cb.prm.param_idx++;
+    nfc_hal_dm_send_nci_cmd(p_buff, cmd_len, nfc_hal_prm_nci_command_complete_cback);
+    GKI_freebuf (p_buff);
+    return FALSE;
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_prm_nci_command_complete_cback
+**
+** Description      Callback for NCI vendor specific command complete
+**                  (for secure patch download)
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_prm_nci_command_complete_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data)
+{
+    UINT8 status, u8;
+    UINT8 *p;
+    UINT32 post_signature_delay;
+
+    NFC_HAL_PRM_STATE ("nfc_hal_prm_nci_command_complete_cback");
+
+    /* Stop the command-timeout timer */
+    nfc_hal_main_stop_quick_timer (&nfc_hal_cb.prm.timer);
+
+    /* Skip over NCI header */
+    p = p_data + NCI_MSG_HDR_SIZE;
+
+    /* Handle SECURE_PATCH_DOWNLOAD Rsp */
+    if (event == NFC_VS_SEC_PATCH_DOWNLOAD_EVT)
+    {
+        /* Status and error code */
+        STREAM_TO_UINT8 (status, p);
+        STREAM_TO_UINT8 (u8, p);
+
+        if (status != NCI_STATUS_OK)
+        {
+#if (NFC_HAL_TRACE_VERBOSE == TRUE)
+            HAL_TRACE_ERROR2 ("Patch download failed, reason code=0x%X (%s)", status, nfc_hal_prm_spd_status_str (status));
+#else
+            HAL_TRACE_ERROR1 ("Patch download failed, reason code=0x%X", status);
+#endif
+
+            /* Notify application */
+            nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
+            return;
+        }
+
+        /* If last segment (SIGNATURE) sent */
+        if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_SIGNATURE_SENT)
+        {
+            /* Wait for authentication complete (SECURE_PATCH_DOWNLOAD NTF), including time to commit to NVM (for BCM43341B0) */
+            nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_AUTHENTICATING;
+            nfc_hal_main_start_quick_timer (&nfc_hal_cb.prm.timer, 0x00,
+                                            (NFC_HAL_PRM_COMMIT_DELAY * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+            return;
+        }
+        /* Download next segment */
+        else if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF)
+        {
+            /* If patch is in a buffer, get next patch from buffer */
+            nfc_hal_prm_spd_send_next_segment ();
+        }
+        else
+        {
+            /* Notify adaptation layer to get next patch segment (via HAL_NfcPrmDownloadContinue) */
+            (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_CONTINUE_EVT);
+        }
+    }
+    /* Handle SECURE_PATCH_DOWNLOAD NTF */
+    else if (event == NFC_VS_SEC_PATCH_AUTH_EVT)
+    {
+        HAL_TRACE_DEBUG1 ("prm flags:0x%x.", nfc_hal_cb.prm.flags);
+        /* Status and error code */
+        STREAM_TO_UINT8 (status, p);
+        STREAM_TO_UINT8 (u8, p);
+
+        /* Sanity check - should only get this NTF while in AUTHENTICATING stage */
+        if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_AUTHENTICATING)
+        {
+            if (status != NCI_STATUS_OK)
+            {
+                HAL_TRACE_ERROR0 ("Patch authentication failed");
+                nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_BAD_SIGNATURE_EVT);
+                return;
+            }
+
+#if (defined (NFC_HAL_PRE_I2C_PATCH_INCLUDED) && (NFC_HAL_PRE_I2C_PATCH_INCLUDED == TRUE))
+            if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED)
+            {
+                HAL_TRACE_DEBUG1 ("PreI2C patch downloaded...waiting %i ms for NFCC to reboot.", nfc_hal_cb.prm_i2c.prei2c_delay);
+
+                /* Restore pointers to patchfile */
+                nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED;
+                nfc_hal_cb.prm.p_cur_patch_data = nfc_hal_cb.prm.p_spd_patch;
+                nfc_hal_cb.prm.cur_patch_offset = nfc_hal_cb.prm.spd_patch_offset;
+                nfc_hal_cb.prm.cur_patch_len_remaining = nfc_hal_cb.prm.spd_patch_len_remaining;
+
+                /* Resume normal patch download */
+                nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER;
+                nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_SIGNATURE_SENT;
+
+                /* Post PreI2C delay */
+                nfc_hal_main_start_quick_timer (&nfc_hal_cb.prm.timer, 0x00, (nfc_hal_cb.prm_i2c.prei2c_delay * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+
+                return;
+            }
+#endif  /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */
+
+
+            /* Wait for NFCC to save the patch to NVM */
+            if (!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_BCM20791B3))
+            {
+                /* 20791B4 or newer - wait for RESET_NTF; including time to commit to NVM (for BCM20791B4+) */
+                post_signature_delay = NFC_HAL_PRM_COMMIT_DELAY;
+                HAL_TRACE_DEBUG1 ("Patch downloaded and authenticated. Waiting %i ms for RESET NTF...", post_signature_delay);
+
+            }
+            else if (nfc_hal_cb.nvm_cb.flags & NFC_HAL_NVM_FLAGS_NO_NVM)
+            {
+                /* No NVM. Wait for NFCC to restart */
+                post_signature_delay = NFC_HAL_PRM_END_DELAY;
+                HAL_TRACE_DEBUG1 ("Patch downloaded and authenticated. Waiting %i ms for NFCC to restart...", post_signature_delay);
+            }
+            else
+            {
+                /* Wait for NFCC to save the patch to NVM (need about 1 ms per byte) */
+                post_signature_delay = nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].len;
+                if (post_signature_delay < nfc_hal_cb.prm.patchram_delay)
+                    post_signature_delay = nfc_hal_cb.prm.patchram_delay;
+                HAL_TRACE_DEBUG1 ("Patch downloaded and authenticated. Waiting %i ms for NVM update to complete...", post_signature_delay);
+            }
+
+            nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_AUTH_DONE;
+
+            nfc_hal_main_start_quick_timer (&nfc_hal_cb.prm.timer, 0x00,
+                                            (post_signature_delay * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+        }
+        else
+        {
+            HAL_TRACE_ERROR0 ("Got unexpected SECURE_PATCH_DOWNLOAD NTF");
+            nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT);
+        }
+    }
+    /* Handle NCI_MSG_GET_PATCH_VERSION RSP */
+    else if (event == NFC_VS_GET_PATCH_VERSION_EVT)
+    {
+        nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_COMPLETE_EVT);
+    }
+    else if (event == NFC_VS_EEPROM_RW_EVT)
+    {
+        STREAM_TO_UINT8 (status, p);
+        if (status == NCI_STATUS_OK)
+        {
+            if (nfc_hal_prm_nvm_rw_cmd ())
+            {
+                nfc_hal_prm_spd_check_version_continue ();
+            }
+        }
+        else
+        {
+            HAL_TRACE_ERROR0 ("NVM failed");
+            nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT);
+        }
+    }
+    else
+    {
+        /* Invalid response from NFCC during patch download */
+        HAL_TRACE_ERROR1 ("Invalid response from NFCC during patch download (opcode=0x%02X)", event);
+        nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
+    }
+
+    NFC_HAL_PRM_STATE ("prm_nci_command_complete_cback");
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_prm_nfcc_ready_to_continue
+**
+** Description      Continue to download patch or notify application completition
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_prm_nfcc_ready_to_continue (void)
+{
+    UINT8 get_patch_version_cmd [NCI_MSG_HDR_SIZE] =
+    {
+        NCI_MTS_CMD|NCI_GID_PROP,
+        NCI_MSG_GET_PATCH_VERSION,
+        0x00
+    };
+
+    /* Clear the bit for the patch we just downloaded */
+    nfc_hal_cb.prm.spd_patch_needed_mask &= ~ ((UINT32) 1 << nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].power_mode);
+
+    /* Check if another patch to download */
+    nfc_hal_cb.prm.spd_cur_patch_idx++;
+    if ((nfc_hal_cb.prm.spd_patch_needed_mask) && (nfc_hal_cb.prm.spd_cur_patch_idx < nfc_hal_cb.prm.spd_patch_count))
+    {
+        nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER;
+        nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_SIGNATURE_SENT;
+
+        if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF)
+        {
+            /* If patch is in a buffer, get next patch from buffer */
+            nfc_hal_prm_spd_handle_next_patch_start ();
+        }
+        else
+        {
+            /* Notify adaptation layer to get next patch header (via HAL_NfcPrmDownloadContinue) */
+            (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_SPD_GET_NEXT_PATCH);
+        }
+
+    }
+    else
+    {
+        /* Done downloading */
+        HAL_TRACE_DEBUG0 ("Patch downloaded and authenticated. Get new patch version.");
+        /* add get patch info again to verify the effective FW version */
+        nfc_hal_dm_send_nci_cmd (get_patch_version_cmd, NCI_MSG_HDR_SIZE, nfc_hal_prm_nci_command_complete_cback);
+        nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_W4_GET_VERSION;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_prm_spd_reset_ntf
+**
+** Description      Received RESET NTF from NFCC, indicating it has completed
+**                  reset after patch download.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_prm_spd_reset_ntf (UINT8 reset_reason, UINT8 reset_type)
+{
+    /* Check if we were expecting a RESET NTF */
+    if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_AUTH_DONE)
+    {
+        HAL_TRACE_DEBUG2 ("Received RESET NTF after patch download (reset_reason=%i, reset_type=%i)", reset_reason, reset_type);
+
+        /* Stop waiting for RESET NTF */
+        nfc_hal_main_stop_quick_timer (&nfc_hal_cb.prm.timer);
+
+        {
+            /* Continue with patch download */
+            nfc_hal_prm_nfcc_ready_to_continue ();
+        }
+    }
+    else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER)
+    {
+        HAL_TRACE_DEBUG0 ("Received RESET NTF after pre-I2C patch download. Proceeding with patch download...");
+
+        /* Stop waiting for RESET NTF */
+        nfc_hal_main_stop_quick_timer (&nfc_hal_cb.prm.timer);
+        nfc_hal_prm_spd_handle_next_patch_start ();
+    }
+    else
+    {
+        HAL_TRACE_ERROR2 ("Received unexpected RESET NTF (reset_reason=%i, reset_type=%i)", reset_reason, reset_type);
+    }
+}
+
+/*******************************************************************************
+**
+** Function:    nfc_post_final_baud_update
+**
+** Description: Called after baud rate udate
+**
+** Returns:     Nothing
+**
+*******************************************************************************/
+void nfc_hal_prm_post_baud_update (tHAL_NFC_STATUS status)
+{
+    NFC_HAL_PRM_STATE ("nfc_hal_prm_post_baud_update");
+
+    if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_AUTH_DONE)
+    {
+        /* Proceed with next step of patch download sequence */
+        nfc_hal_prm_nfcc_ready_to_continue ();
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_prm_process_timeout
+**
+** Description      Process timer expireation for patch download
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_prm_process_timeout (void *p_tle)
+{
+    NFC_HAL_PRM_STATE ("nfc_hal_prm_process_timeout");
+
+    if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_AUTH_DONE)
+    {
+        if (!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_BCM20791B3))
+        {
+            /* Timeout waiting for RESET NTF after signature sent */
+            HAL_TRACE_ERROR0 ("Timeout waiting for RESET NTF after patch download");
+            nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT);
+        }
+        else
+        {
+            nfc_hal_prm_nfcc_ready_to_continue ();
+        }
+    }
+    else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER)
+    {
+        HAL_TRACE_DEBUG0 ("Delay after PreI2C patch download...proceeding to download firmware patch");
+        nfc_hal_prm_spd_handle_next_patch_start ();
+    }
+    else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_W4_GET_VERSION)
+    {
+        HAL_TRACE_DEBUG0 ("get patch version timeout???");
+        nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_COMPLETE_EVT);
+    }
+    else
+    {
+        HAL_TRACE_ERROR1 ("Patch download: command timeout (state=%i)", nfc_hal_cb.prm.state);
+
+        nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT);
+    }
+
+    NFC_HAL_PRM_STATE ("nfc_hal_prm_process_timeout");
+}
+
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPrmDownloadStart
+**
+** Description      Initiate patch download
+**
+** Input Params
+**                  format_type     patch format type
+**                                  (NFC_HAL_PRM_FORMAT_BIN, NFC_HAL_PRM_FORMAT_HCD, or
+**                                   NFC_HAL_PRM_FORMAT_NCD)
+**
+**                  dest_address    destination adderess (needed for BIN format only)
+**
+**                  p_patchram_buf  pointer to patchram buffer. If NULL,
+**                                  then app must call HAL_NfcPrmDownloadContinue when
+**                                  NFC_HAL_PRM_CONTINUE_EVT is received, to send the next
+**                                  segment of patchram
+**
+**                  patchram_len    size of p_patchram_buf (if non-NULL)
+**
+**                  patchram_delay  The delay after each patch.
+**                                  If the given value is less than the size of the patchram,
+**                                  the size of patchram is used instead.
+**
+**                  p_cback         callback for download status
+**
+**
+** Returns          TRUE if successful, otherwise FALSE
+**
+**
+*******************************************************************************/
+BOOLEAN HAL_NfcPrmDownloadStart (tNFC_HAL_PRM_FORMAT format_type,
+                                 UINT32              dest_address,
+                                 UINT8               *p_patchram_buf,
+                                 UINT32              patchram_len,
+                                 UINT32              patchram_delay,
+                                 tNFC_HAL_PRM_CBACK  *p_cback)
+{
+    HAL_TRACE_API0 ("HAL_NfcPrmDownloadStart ()");
+
+    memset (&nfc_hal_cb.prm, 0, sizeof (tNFC_HAL_PRM_CB));
+
+    if (p_patchram_buf)
+    {
+        nfc_hal_cb.prm.p_cur_patch_data = p_patchram_buf;
+        nfc_hal_cb.prm.cur_patch_offset = 0;
+        nfc_hal_cb.prm.cur_patch_len_remaining = (UINT16) patchram_len;
+        nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF;
+
+        if (patchram_len == 0)
+            return FALSE;
+    }
+
+    nfc_hal_cb.prm.p_cback          = p_cback;
+    nfc_hal_cb.prm.dest_ram         = dest_address;
+    nfc_hal_cb.prm.format           = format_type;
+    nfc_hal_cb.prm.patchram_delay   = patchram_delay;
+
+    nfc_hal_cb.prm.timer.p_cback = nfc_hal_prm_process_timeout;
+
+    if (format_type == NFC_HAL_PRM_FORMAT_NCD)
+    {
+        /* Store patch buffer pointer and length */
+        nfc_hal_cb.prm.p_spd_patch             = p_patchram_buf;
+        nfc_hal_cb.prm.spd_patch_len_remaining = (UINT16)patchram_len;
+        nfc_hal_cb.prm.spd_patch_offset        = 0;
+
+        /* If patch download is required, but no NVM is available, then abort */
+        if ((p_nfc_hal_cfg->nfc_hal_prm_nvm_required) && (nfc_hal_cb.nvm_cb.flags & NFC_HAL_NVM_FLAGS_NO_NVM))
+        {
+            HAL_TRACE_ERROR0 ("This platform requires NVM and the NVM is not available - Abort");
+            nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_NO_NVM_EVT);
+            return FALSE;
+        }
+
+        /* Compare patch version in NVM with version in patchfile */
+        nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_COMPARE_VERSION;
+        if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF)
+        {
+            /* If patchfile is in a buffer, get patch version from buffer */
+            nfc_hal_prm_spd_check_version ();
+        }
+        else
+        {
+            /* If patchfile is not in a buffer, then request patchfile header from adaptation layer. */
+            (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_SPD_GET_PATCHFILE_HDR_EVT);
+        }
+    }
+    else
+    {
+        HAL_TRACE_ERROR0 ("Unexpected patch format.");
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPrmDownloadContinue
+**
+** Description      Send next segment of patchram to controller. Called when
+**                  NFC_HAL_PRM_CONTINUE_EVT is received.
+**
+**                  Only needed if HAL_NfcPrmDownloadStart was called with
+**                  p_patchram_buf=NULL
+**
+** Input Params     p_patch_data    pointer to patch data
+**                  patch_data_len  patch data len
+**
+** Returns          TRUE if successful, otherwise FALSE
+**
+*******************************************************************************/
+BOOLEAN HAL_NfcPrmDownloadContinue (UINT8 *p_patch_data,
+                                    UINT16 patch_data_len)
+{
+    HAL_TRACE_API2 ("HAL_NfcPrmDownloadContinue ():state = %d, patch_data_len=%d",
+                     nfc_hal_cb.prm.state, patch_data_len);
+
+    /* Check if we are in a valid state for this API */
+    if (  (nfc_hal_cb.prm.state != NFC_HAL_PRM_ST_SPD_COMPARE_VERSION)
+        &&(nfc_hal_cb.prm.state != NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER)
+        &&(nfc_hal_cb.prm.state != NFC_HAL_PRM_ST_SPD_DOWNLOADING)  )
+        return FALSE;
+
+    if (patch_data_len == 0)
+        return FALSE;
+
+    nfc_hal_cb.prm.cur_patch_offset = 0;
+    nfc_hal_cb.prm.p_cur_patch_data = p_patch_data;
+    nfc_hal_cb.prm.cur_patch_len_remaining = patch_data_len;
+
+    /* Call appropriate handler */
+    if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_COMPARE_VERSION)
+    {
+        nfc_hal_prm_spd_check_version ();
+    }
+    else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER)
+    {
+        nfc_hal_prm_spd_handle_next_patch_start ();
+    }
+    else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_DOWNLOADING)
+    {
+        nfc_hal_prm_spd_send_next_segment ();
+    }
+    else
+    {
+        HAL_TRACE_ERROR1 ("Unexpected patch state:%d.", nfc_hal_cb.prm.state);
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPrmSetI2cPatch
+**
+** Description      Specify patchfile for BCM20791B3 I2C fix. This fix
+**                  must be downloaded prior to initial patch download for I2C
+**                  transport
+**
+** Input Params     p_i2c_patchfile_buf: pointer to patch for i2c fix
+**                  i2c_patchfile_len: length of patch
+**                  prei2c_delay: the delay before downloading main patch
+**                                if 0 is given, NFC_HAL_PRM_POST_I2C_FIX_DELAY is used instead.
+**
+** Returns          Nothing
+**
+**
+*******************************************************************************/
+void HAL_NfcPrmSetI2cPatch (UINT8 *p_i2c_patchfile_buf, UINT16 i2c_patchfile_len, UINT32 prei2c_delay)
+{
+#if (defined (NFC_HAL_PRE_I2C_PATCH_INCLUDED) && (NFC_HAL_PRE_I2C_PATCH_INCLUDED == TRUE))
+    HAL_TRACE_API0 ("HAL_NfcPrmSetI2cPatch ()");
+
+    nfc_hal_cb.prm_i2c.prei2c_delay    = NFC_HAL_PRM_POST_I2C_FIX_DELAY;
+    if (prei2c_delay)
+        nfc_hal_cb.prm_i2c.prei2c_delay = prei2c_delay;
+    nfc_hal_cb.prm_i2c.p_patch = p_i2c_patchfile_buf;
+    nfc_hal_cb.prm_i2c.len = i2c_patchfile_len;
+#endif  /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPrmSetSpdNciCmdPayloadSize
+**
+** Description      Set Host-to-NFCC NCI message size for secure patch download
+**
+**                  This API must be called before calling HAL_NfcPrmDownloadStart.
+**                  If the API is not called, then PRM will use the default
+**                  message size.
+**
+**                  Typically, this API is only called for platforms that have
+**                  message-size limitations in the transport/driver.
+**
+**                  Valid message size range: NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE to 255.
+**
+** Returns          HAL_NFC_STATUS_OK if successful
+**                  HAL_NFC_STATUS_FAILED otherwise
+**
+**
+*******************************************************************************/
+tHAL_NFC_STATUS HAL_NfcPrmSetSpdNciCmdPayloadSize (UINT8 max_payload_size)
+{
+    /* Validate: minimum size is NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE */
+    if (max_payload_size < NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE)
+    {
+        HAL_TRACE_ERROR2 ("HAL_NfcPrmSetSpdNciCmdPayloadSize: invalid size (%i). Must be between %i and 255", max_payload_size, NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE);
+        return (HAL_NFC_STATUS_FAILED);
+    }
+    else
+    {
+        HAL_TRACE_API1 ("HAL_NfcPrmSetSpdNciCmdPayloadSize: new message size during download: %i", max_payload_size);
+        nfc_hal_cb.ncit_cb.nci_ctrl_size = max_payload_size;
+        return (HAL_NFC_STATUS_OK);
+    }
+}
diff --git a/halimpl/bcm2079x/include/HalAdaptation.h b/halimpl/bcm2079x/include/HalAdaptation.h
new file mode 100644
index 0000000..9599c07
--- /dev/null
+++ b/halimpl/bcm2079x/include/HalAdaptation.h
@@ -0,0 +1,66 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  HAL Adaptation Interface (HAI). This interface regulates the interaction
+ *  between standard Android HAL and Broadcom-specific HAL.  It adapts
+ *  Broadcom-specific features to the Android framework.
+ *
+ ******************************************************************************/
+#pragma once
+#include <hardware/hardware.h>
+#include <hardware/nfc.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct
+{
+    struct nfc_nci_device nci_device;
+    //below declarations are private variables within Broadcom HAL
+    void* data;
+}
+bcm2079x_dev_t;
+
+
+/*
+All functions return POSIX error codes (see errno):
+  0 means success.
+  non-zero means failure; for example EACCES.
+*/
+
+
+extern int HaiInitializeLibrary (const bcm2079x_dev_t* device);
+extern int HaiTerminateLibrary ();
+extern int HaiOpen (const bcm2079x_dev_t* device, nfc_stack_callback_t* halCallbackFunc, nfc_stack_data_callback_t* halDataCallbackFunc);
+extern int HaiClose (const bcm2079x_dev_t* device);
+extern int HaiCoreInitialized (const bcm2079x_dev_t* device, uint8_t* coreInitResponseParams);
+extern int HaiWrite (const bcm2079x_dev_t* dev, uint16_t dataLen, const uint8_t* data);
+extern int HaiPreDiscover (const bcm2079x_dev_t* device);
+extern int HaiControlGranted (const bcm2079x_dev_t* device);
+extern int HaiPowerCycle (const bcm2079x_dev_t* device);
+extern int HaiGetMaxNfcee (const bcm2079x_dev_t* device, uint8_t* maxNfcee);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/halimpl/bcm2079x/include/OverrideLog.h b/halimpl/bcm2079x/include/OverrideLog.h
new file mode 100644
index 0000000..a441cbd
--- /dev/null
+++ b/halimpl/bcm2079x/include/OverrideLog.h
@@ -0,0 +1,70 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Override the Android logging macro(s) from
+ *  /system/core/include/cutils/log.h. This header must be the first header
+ *  included by a *.cpp file so the original Android macro can be replaced.
+ *  Do not include this header in another header, because that will create
+ *  unnecessary dependency.
+ *
+ ******************************************************************************/
+#pragma once
+
+//Override Android's ALOGD macro by adding a boolean expression.
+#define ALOGD(...) ((void)ALOGD_IF(appl_trace_level>=BT_TRACE_LEVEL_DEBUG, __VA_ARGS__))
+
+
+#include <cutils/log.h> //define Android logging macros
+#include "bt_types.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern unsigned char appl_trace_level;
+extern UINT32 ScrProtocolTraceFlag;
+
+
+/*******************************************************************************
+**
+** Function:        InitializeGlobalAppLogLevel
+**
+** Description:     Initialize and get global logging level from .conf or
+**                  Android property nfc.app_log_level.  The Android property
+**                  overrides .conf variable.
+**
+** Returns:         Global log level:
+**                  BT_TRACE_LEVEL_NONE    0        * No trace messages to be generated
+**                  BT_TRACE_LEVEL_ERROR   1        * Error condition trace messages
+**                  BT_TRACE_LEVEL_WARNING 2        * Warning condition trace messages
+**                  BT_TRACE_LEVEL_API     3        * API traces
+**                  BT_TRACE_LEVEL_EVENT   4        * Debug messages for events
+**                  BT_TRACE_LEVEL_DEBUG   5        * Debug messages (general)
+**
+*******************************************************************************/
+unsigned char InitializeGlobalAppLogLevel ();
+UINT32 InitializeProtocolLogLevel ();
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/halimpl/bcm2079x/include/StartupConfig.h b/halimpl/bcm2079x/include/StartupConfig.h
new file mode 100644
index 0000000..e56a83c
--- /dev/null
+++ b/halimpl/bcm2079x/include/StartupConfig.h
@@ -0,0 +1,93 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ * Construct a buffer that contains multiple Type-Length-Value contents
+ * that is used by the HAL in a CORE_SET_CONFIG NCI command.
+ ******************************************************************************/
+
+#pragma once
+#include "bt_types.h"
+#include <string>
+
+
+class StartupConfig
+{
+public:
+    typedef std::basic_string<UINT8> uint8_string;
+    StartupConfig ();
+
+
+    /*******************************************************************************
+    **
+    ** Function:        initialize
+    **
+    ** Description:     Reset all member variables.
+    **
+    ** Returns:         None
+    **
+    *******************************************************************************/
+    void initialize ();
+
+
+    /*******************************************************************************
+    **
+    ** Function:        getInternalBuffer
+    **
+    ** Description:     Get the pointer to buffer that contains multiple
+    **                  Type-Length-Value contents.
+    **
+    ** Returns:         Pointer to buffer.
+    **
+    *******************************************************************************/
+    const UINT8* getInternalBuffer ();
+
+
+    /*******************************************************************************
+    **
+    ** Function:        append
+    **
+    ** Description:     Append new config data to internal buffer.
+    **                  newContent: buffer containing new content; newContent[0] is
+    **                          payload length; newContent[1..end] is payload.
+    **                  newContentLen: total length of newContent.
+    **
+    ** Returns:         True if ok.
+    **
+    *******************************************************************************/
+    bool append (const UINT8* newContent, UINT8 newContentLen);
+
+
+    /*******************************************************************************
+    **
+    ** Function:        disableSecureElement
+    **
+    ** Description:     Adjust a TLV to disable secure element(s).  The TLV's type is 0xC2.
+    **                  bitmask: 0xC0 = do not detect any secure element.
+    **                           0x40 = do not detect secure element in slot 0.
+    **                           0x80 = do not detect secure element in slot 1.
+    **
+    ** Returns:         True if ok.
+    **
+    *******************************************************************************/
+    bool disableSecureElement (UINT8 bitmask);
+
+private:
+    static const UINT8 mMaxLength;
+    uint8_string mBuffer;
+};
diff --git a/halimpl/bcm2079x/include/android_logmsg.h b/halimpl/bcm2079x/include/android_logmsg.h
new file mode 100644
index 0000000..9922893
--- /dev/null
+++ b/halimpl/bcm2079x/include/android_logmsg.h
@@ -0,0 +1,65 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2011-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ * Decode NFC packets and print them to ADB log.
+ * If protocol decoder is not present, then decode packets into hex numbers.
+ ******************************************************************************/
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+#include "data_types.h"
+
+
+#define DISP_NCI    ProtoDispAdapterDisplayNciPacket
+void ProtoDispAdapterDisplayNciPacket (UINT8* nciPacket, UINT16 nciPacketLen, BOOLEAN is_recv);
+void ProtoDispAdapterUseRawOutput (BOOLEAN isUseRaw);
+void ScrLog (UINT32 trace_set_mask, const char* fmt_str, ...);
+void LogMsg (UINT32 trace_set_mask, const char *fmt_str, ...);
+void LogMsg_0 (UINT32 trace_set_mask, const char *p_str);
+void LogMsg_1 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1);
+void LogMsg_2 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2);
+void LogMsg_3 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2, UINT32 p3);
+void LogMsg_4 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2, UINT32 p3, UINT32 p4);
+void LogMsg_5 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2, UINT32 p3, UINT32 p4, UINT32 p5);
+void LogMsg_6 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2, UINT32 p3, UINT32 p4, UINT32 p5, UINT32 p6);
+UINT8* scru_dump_hex (UINT8* p, char* pTitle, UINT32 len, UINT32 layer, UINT32 type);
+void BTDISP_LOCK_LOG();
+void BTDISP_UNLOCK_LOG();
+void BTDISP_INIT_LOCK();
+void BTDISP_UNINIT_LOCK();
+void DispHciCmd (BT_HDR* p_buf);
+void DispHciEvt (BT_HDR* p_buf);
+void DispLLCP (BT_HDR *p_buf, BOOLEAN is_recv);
+void DispHcp (UINT8 *data, UINT16 len, BOOLEAN is_recv);
+void DispSNEP (UINT8 local_sap, UINT8 remote_sap, BT_HDR *p_buf, BOOLEAN is_first, BOOLEAN is_rx);
+void DispCHO (UINT8 *pMsg, UINT32 MsgLen, BOOLEAN is_rx);
+void DispT3TagMessage(BT_HDR *p_msg, BOOLEAN is_rx);
+void DispRWT4Tags (BT_HDR *p_buf, BOOLEAN is_rx);
+void DispCET4Tags (BT_HDR *p_buf, BOOLEAN is_rx);
+void DispRWI93Tag (BT_HDR *p_buf, BOOLEAN is_rx, UINT8 command_to_respond);
+void DispNDEFMsg (UINT8 *pMsg, UINT32 MsgLen, BOOLEAN is_recv);
+
+
+
+#ifdef __cplusplus
+};
+#endif
diff --git a/halimpl/bcm2079x/include/bcm2079x.h b/halimpl/bcm2079x/include/bcm2079x.h
new file mode 100644
index 0000000..beb5786
--- /dev/null
+++ b/halimpl/bcm2079x/include/bcm2079x.h
@@ -0,0 +1,45 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#ifndef _BCM2079X_H
+#define _BCM2079X_H
+
+#define BCMNFC_MAGIC	0xFA
+
+/*
+ * BCMNFC power control via ioctl
+ * BCMNFC_POWER_CTL(0): power off
+ * BCMNFC_POWER_CTL(1): power on
+ * BCMNFC_WAKE_CTL(0): wake off
+ * BCMNFC_WAKE_CTL(1): wake on
+ */
+#define BCMNFC_POWER_CTL		_IO(BCMNFC_MAGIC, 0x01)
+#define BCMNFC_CHANGE_ADDR		_IO(BCMNFC_MAGIC, 0x02)
+#define BCMNFC_READ_FULL_PACKET		_IO(BCMNFC_MAGIC, 0x03)
+#define BCMNFC_SET_WAKE_ACTIVE_STATE	_IO(BCMNFC_MAGIC, 0x04)
+#define BCMNFC_WAKE_CTL			_IO(BCMNFC_MAGIC, 0x05)
+#define BCMNFC_READ_MULTI_PACKETS	_IO(BCMNFC_MAGIC, 0x06)
+#define BCMNFC_SET_CLIENT_ADDR		_IO(BCMNFC_MAGIC, 0x07)
+
+struct bcm2079x_platform_data {
+	unsigned int irq_gpio;
+	unsigned int en_gpio;
+	int wake_gpio;
+};
+
+#endif
diff --git a/halimpl/bcm2079x/include/buildcfg.h b/halimpl/bcm2079x/include/buildcfg.h
new file mode 100644
index 0000000..32cf681
--- /dev/null
+++ b/halimpl/bcm2079x/include/buildcfg.h
@@ -0,0 +1,41 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#pragma once
+#include <string.h>
+#include <memory.h>
+#include <stdio.h>
+#include "data_types.h"
+
+
+#define BTE_APPL_MAX_USERIAL_DEV_NAME           (256)
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+
+extern UINT8 *scru_dump_hex (UINT8 *p, char *p_title, UINT32 len, UINT32 trace_layer, UINT32 trace_type);
+void DispNci (UINT8 *p, UINT16 len, BOOLEAN is_recv);
+void ProtoDispAdapterDisplayNciPacket (UINT8* nciPacket, UINT16 nciPacketLen, BOOLEAN is_recv);
+#define DISP_NCI    ProtoDispAdapterDisplayNciPacket
+#define LOGMSG_TAG_NAME "NfcNciHal"
+
+
+#ifdef	__cplusplus
+};
+#endif
diff --git a/halimpl/bcm2079x/include/buildcfg_hal.h b/halimpl/bcm2079x/include/buildcfg_hal.h
new file mode 100644
index 0000000..a8136b7
--- /dev/null
+++ b/halimpl/bcm2079x/include/buildcfg_hal.h
@@ -0,0 +1,31 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2001-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+//override any HAL-specific macros
+#pragma once
+
+#include "bt_types.h"
+
+//NFC_HAL_TASK=0 is already defined in gki_hal_target.h; it executes the Broadcom HAL
+#define USERIAL_HAL_TASK  1  //execute userial's read thread
+#define GKI_RUNNER_HAL_TASK 2  //execute GKI_run(), which runs forever
+#define GKI_MAX_TASKS  3 //total of 3 tasks
+
+#define GKI_BUF0_MAX                16
+#define GKI_BUF1_MAX                16
+
+#define NFC_HAL_PRM_POST_I2C_FIX_DELAY (500)
diff --git a/halimpl/bcm2079x/include/gki_target.h b/halimpl/bcm2079x/include/gki_target.h
new file mode 100644
index 0000000..afb4f78
--- /dev/null
+++ b/halimpl/bcm2079x/include/gki_target.h
@@ -0,0 +1,19 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2001-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#pragma once
+#include "gki_hal_target.h"
diff --git a/halimpl/bcm2079x/include/spdhelper.h b/halimpl/bcm2079x/include/spdhelper.h
new file mode 100644
index 0000000..e496c98
--- /dev/null
+++ b/halimpl/bcm2079x/include/spdhelper.h
@@ -0,0 +1,47 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#pragma once
+
+#include <string>
+
+using namespace std;
+#define DEFAULT_SPD_MAXRETRYCOUNT (3)
+
+class SpdHelper
+{
+public:
+    static bool isPatchBad(UINT8* prm, UINT32 len);
+    static void setPatchAsBad();
+    static void incErrorCount();
+    static bool isSpdDebug();
+
+private:
+    SpdHelper();
+    static SpdHelper& getInstance();
+
+    bool isPatchBadImpl(UINT8* prm, UINT32 len);
+    void setPatchAsBadImpl();
+    void incErrorCountImpl();
+    bool isSpdDebugImpl() {return mSpdDebug;}
+    string mPatchId;
+    int  mErrorCount;
+    int  mMaxErrorCount;
+    bool mIsPatchBad;
+    bool mSpdDebug;
+};
diff --git a/halimpl/bcm2079x/include/userial.h b/halimpl/bcm2079x/include/userial.h
new file mode 100644
index 0000000..7ca7369
--- /dev/null
+++ b/halimpl/bcm2079x/include/userial.h
@@ -0,0 +1,289 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2001-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains serial definitions from WIDCOMM's Universal Embedded
+ *  Drivers API.
+ *
+ ******************************************************************************/
+
+#ifndef USERIAL_H
+#define USERIAL_H
+
+/*******************************************************************************
+** Serial APIs
+*******************************************************************************/
+
+/**** port IDs ****/
+#define USERIAL_PORT_1            0
+#define USERIAL_PORT_2            1
+#define USERIAL_PORT_3            2
+#define USERIAL_PORT_4            3
+#define USERIAL_PORT_5            4
+#define USERIAL_PORT_6            5
+#define USERIAL_PORT_7            6
+#define USERIAL_PORT_8            7
+#define USERIAL_PORT_9            8
+#define USERIAL_PORT_10           9
+#define USERIAL_PORT_11           10
+#define USERIAL_PORT_12           11
+#define USERIAL_PORT_13           12
+#define USERIAL_PORT_14           13
+#define USERIAL_PORT_15           14
+#define USERIAL_PORT_16           15
+#define USERIAL_PORT_17           16
+#define USERIAL_PORT_18           17
+
+typedef UINT8 tUSERIAL_PORT;
+
+/**** baud rates ****/
+#define USERIAL_BAUD_300          0
+#define USERIAL_BAUD_600          1
+#define USERIAL_BAUD_1200         2
+#define USERIAL_BAUD_2400         3
+#define USERIAL_BAUD_9600         4
+#define USERIAL_BAUD_19200        5
+#define USERIAL_BAUD_57600        6
+#define USERIAL_BAUD_115200       7
+#define USERIAL_BAUD_230400       8
+#define USERIAL_BAUD_460800       9
+#define USERIAL_BAUD_921600       10
+#define USERIAL_BAUD_1M           11
+#define USERIAL_BAUD_1_5M         12
+#define USERIAL_BAUD_2M           13
+#define USERIAL_BAUD_3M           14
+#define USERIAL_BAUD_4M           15
+#define USERIAL_BAUD_AUTO         16
+
+/**** Data Format ****/
+
+/* Stop Bits */
+#define USERIAL_STOPBITS_1        1
+#define USERIAL_STOPBITS_1_5      (1<<1)
+#define USERIAL_STOPBITS_2        (1<<2)
+
+/* Parity Bits */
+#define USERIAL_PARITY_NONE       (1<<3)
+#define USERIAL_PARITY_EVEN       (1<<4)
+#define USERIAL_PARITY_ODD        (1<<5)
+
+/* Data Bits */
+#define USERIAL_DATABITS_5        (1<<6)
+#define USERIAL_DATABITS_6        (1<<7)
+#define USERIAL_DATABITS_7        (1<<8)
+#define USERIAL_DATABITS_8        (1<<9)
+
+
+/**** Flow Control ****/
+#define USERIAL_FC_NONE           0
+#define USERIAL_FC_HW             1
+#define USERIAL_FC_SW             2
+
+/**** Data Buffering Mechanism ****/
+#define USERIAL_BUF_BYTE          0
+#define USERIAL_BUF_GKI           1
+
+/**** Signals ****/
+#define USERIAL_SIG_RTSCTS        1
+#define USERIAL_SIG_DSRDTR        (1<<1)
+#define USERIAL_SIG_RI            (1<<2)
+#define USERIAL_SIG_CD            (1<<3)
+#define USERIAL_SIG_DTE_DEVICE    (1<<4)
+
+/**** Errors *****/
+#define USERIAL_ERR_OVERRUN       1
+#define USERIAL_ERR_PARITY        (1<<1)
+#define USERIAL_ERR_FRAMING       (1<<2)
+#define USERIAL_ERR_BREAK         (1<<3)
+
+/**** Serial Operations ****/
+#define USERIAL_OP_FLUSH          0
+#define USERIAL_OP_FLUSH_RX       1
+#define USERIAL_OP_FLUSH_TX       2
+#define USERIAL_OP_BREAK_OFF      3
+#define USERIAL_OP_BREAK_ON       4
+#define USERIAL_OP_BAUD_RD        5
+#define USERIAL_OP_BAUD_WR        6
+#define USERIAL_OP_FMT_RD         7
+#define USERIAL_OP_FMT_WR         8
+#define USERIAL_OP_SIG_RD         9
+#define USERIAL_OP_SIG_WR         10
+#define USERIAL_OP_FC_RD          11
+#define USERIAL_OP_FC_WR          12
+#define USERIAL_OP_CTS_AS_WAKEUP  13    /* H4IBSS */
+#define USERIAL_OP_CTS_AS_FC      14    /* H4IBSS */
+
+#if (defined LINUX_OS) && (LINUX_OS == TRUE)
+#define USERIAL_OP_SCO_UP         20    /* LINUX SCO */
+#define USERIAL_OP_SCO_DOWN       21    /* LINUX SCO */
+#endif
+
+typedef UINT8 tUSERIAL_OP;
+
+
+/**** Serial feature types ****/
+#define USERIAL_FEAT_PORT_1       0
+#define USERIAL_FEAT_PORT_2       1
+#define USERIAL_FEAT_PORT_3       2
+#define USERIAL_FEAT_PORT_4       3
+#define USERIAL_FEAT_BAUD_AUTO    4
+#define USERIAL_FEAT_BAUD_300     5
+#define USERIAL_FEAT_BAUD_600     6
+#define USERIAL_FEAT_BAUD_1200    7
+#define USERIAL_FEAT_BAUD_2400    8
+#define USERIAL_FEAT_BAUD_9600    9
+#define USERIAL_FEAT_BAUD_19200   10
+#define USERIAL_FEAT_BAUD_57600   11
+#define USERIAL_FEAT_BAUD_115200  12
+#define USERIAL_FEAT_BAUD_230400  13
+#define USERIAL_FEAT_BAUD_460800  14
+#define USERIAL_FEAT_BAUD_921600  15
+#define USERIAL_FEAT_STOPBITS_1   16
+#define USERIAL_FEAT_STOPBITS_1_5 17
+#define USERIAL_FEAT_STOPBITS_2   18
+#define USERIAL_FEAT_PARITY_NONE  19
+#define USERIAL_FEAT_PARITY_EVEN  20
+#define USERIAL_FEAT_PARITY_ODD   21
+#define USERIAL_FEAT_DATABITS_5   22
+#define USERIAL_FEAT_DATABITS_6   23
+#define USERIAL_FEAT_DATABITS_7   24
+#define USERIAL_FEAT_DATABITS_8   25
+#define USERIAL_FEAT_FC_NONE      26
+#define USERIAL_FEAT_FC_HW        27
+#define USERIAL_FEAT_FC_SW        28
+#define USERIAL_FEAT_BUF_BYTE     29
+#define USERIAL_FEAT_BUF_GKI      30
+#define USERIAL_FEAT_SIG_RTS      31
+#define USERIAL_FEAT_SIG_CTS      32
+#define USERIAL_FEAT_SIG_DSR      33
+#define USERIAL_FEAT_SIG_DTR      34
+#define USERIAL_FEAT_SIG_RI       35
+#define USERIAL_FEAT_SIG_CD       36
+#define USERIAL_FEAT_OP_FLUSH     37
+#define USERIAL_FEAT_OP_FLUSH_RX  38
+#define USERIAL_FEAT_OP_FLUSH_TX  39
+#define USERIAL_FEAT_OP_BREAK     40
+#define USERIAL_FEAT_OP_BAUD_RD   41
+#define USERIAL_FEAT_OP_BAUD_WR   42
+#define USERIAL_FEAT_OP_FMT_RD    43
+#define USERIAL_FEAT_OP_FMT_WR    44
+#define USERIAL_FEAT_OP_SIG_RD    45
+#define USERIAL_FEAT_OP_SIG_WR    46
+#define USERIAL_FEAT_OP_FC_RD     47
+#define USERIAL_FEAT_OP_FC_WR     48
+
+typedef UINT8 tUSERIAL_FEATURE;
+
+
+/**** Event types ****/
+#define USERIAL_RX_READY_EVT      0
+#define USERIAL_TX_DONE_EVT       1
+#define USERIAL_SIG_EVT           2
+#define USERIAL_ERR_EVT           3
+#define USERIAL_WAKEUP_EVT        4 /* H4IBSS */
+
+typedef UINT8 tUSERIAL_EVT;
+
+
+/* Structure used to configure serial port during open        */
+typedef struct
+{
+    UINT16 fmt;          /* Data format                       */
+    UINT8  baud;         /* Baud rate                         */
+    UINT8  fc;           /* Flow control                      */
+    UINT8  buf;          /* Data buffering mechanism          */
+    UINT8  pool;         /* GKI buffer pool for received data */
+    UINT16 size;         /* Size of GKI buffer pool           */
+    UINT16 offset;       /* Offset in GKI buffer pool         */
+} tUSERIAL_OPEN_CFG;
+
+/* Union used to pass ioctl arguments */
+typedef union
+{
+    UINT16 fmt;
+    UINT8  baud;
+    UINT8  fc;
+    UINT8  sigs;
+#if (defined LINUX_OS) && (LINUX_OS == TRUE)
+    UINT16 sco_handle;
+#endif
+} tUSERIAL_IOCTL_DATA;
+
+
+/* Union to pass event data */
+typedef union
+{
+    UINT8 sigs;
+    UINT8 error;
+} tUSERIAL_EVT_DATA;
+
+/* callback for events */
+typedef void (tUSERIAL_CBACK)(tUSERIAL_PORT, tUSERIAL_EVT, tUSERIAL_EVT_DATA *);
+
+/*******************************************************************************
+** Function Prototypes
+*******************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+UDRV_API extern void    USERIAL_Init(void *);
+UDRV_API extern void    USERIAL_Open(tUSERIAL_PORT, tUSERIAL_OPEN_CFG *, tUSERIAL_CBACK *);
+UDRV_API extern void    USERIAL_ReadBuf(tUSERIAL_PORT, BT_HDR **);
+UDRV_API extern UINT16  USERIAL_Read(tUSERIAL_PORT, UINT8 *, UINT16);
+UDRV_API extern BOOLEAN USERIAL_WriteBuf(tUSERIAL_PORT, BT_HDR *);
+UDRV_API extern UINT16  USERIAL_Write(tUSERIAL_PORT, UINT8 *, UINT16);
+UDRV_API extern void    USERIAL_Ioctl(tUSERIAL_PORT, tUSERIAL_OP, tUSERIAL_IOCTL_DATA *);
+UDRV_API extern void    USERIAL_Close(tUSERIAL_PORT);
+UDRV_API extern BOOLEAN USERIAL_Feature(tUSERIAL_FEATURE);
+UDRV_API extern BOOLEAN USERIAL_IsClosed();
+UDRV_API extern void    USERIAL_SetPowerOffDelays(int,int);
+UDRV_API extern void    USERIAL_PowerupDevice(tUSERIAL_PORT port);
+
+/*******************************************************************************
+ **
+ ** Function           USERIAL_GetLineSpeed
+ **
+ ** Description        This function convert USERIAL baud to line speed.
+ **
+ ** Output Parameter   None
+ **
+ ** Returns            line speed
+ **
+ *******************************************************************************/
+UDRV_API extern UINT32 USERIAL_GetLineSpeed(UINT8 baud);
+/*******************************************************************************
+ **
+ ** Function           USERIAL_GetBaud
+ **
+ ** Description        This function convert line speed to USERIAL baud.
+ **
+ ** Output Parameter   None
+ **
+ ** Returns            line speed
+ **
+ *******************************************************************************/
+UDRV_API extern UINT8 USERIAL_GetBaud(UINT32 line_speed);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* USERIAL_H */
diff --git a/halimpl/bcm2079x/nfc_nci.c b/halimpl/bcm2079x/nfc_nci.c
new file mode 100644
index 0000000..b293c2b
--- /dev/null
+++ b/halimpl/bcm2079x/nfc_nci.c
@@ -0,0 +1,189 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+
+#define LOG_TAG "NfcNciHal"
+#include "OverrideLog.h"
+#include <errno.h>
+#include <malloc.h>
+#include <string.h>
+#include <hardware/hardware.h>
+#include <hardware/nfc.h>
+#include "HalAdaptation.h"
+
+
+/*********************************
+ * NCI HAL method implementations.
+ *********************************/
+
+
+static int hal_open (const struct nfc_nci_device *p_dev, nfc_stack_callback_t *p_hal_cback, nfc_stack_data_callback_t *p_hal_data_callback)
+{
+    int retval = 0;
+    bcm2079x_dev_t *dev = (bcm2079x_dev_t*) p_dev;
+
+    retval = HaiOpen (dev, p_hal_cback, p_hal_data_callback);
+    return retval;
+}
+
+
+static int hal_write (const struct nfc_nci_device *p_dev,
+        uint16_t data_len, const uint8_t *p_data)
+{
+    int retval = 0;
+    bcm2079x_dev_t* dev = (bcm2079x_dev_t*) p_dev;
+
+    retval = HaiWrite (dev, data_len, p_data);
+    return retval;
+}
+
+
+static int hal_core_initialized (const struct nfc_nci_device *p_dev,
+        uint8_t* p_core_init_rsp_params)
+{
+    int retval = 0;
+    bcm2079x_dev_t* dev = (bcm2079x_dev_t*) p_dev;
+
+    retval = HaiCoreInitialized (dev, p_core_init_rsp_params);
+    return retval;
+}
+
+
+static int hal_pre_discover (const struct nfc_nci_device *p_dev)
+{
+    int retval = 0;
+    bcm2079x_dev_t* dev = (bcm2079x_dev_t*) p_dev;
+
+    retval = HaiPreDiscover (dev);
+    return retval;
+}
+
+
+static int hal_close (const struct nfc_nci_device *p_dev)
+{
+    int retval = 0;
+    bcm2079x_dev_t* dev = (bcm2079x_dev_t*) p_dev;
+
+    retval = HaiClose (dev);
+    return retval;
+}
+
+
+static int hal_control_granted (const struct nfc_nci_device *p_dev)
+{
+    int retval = 0;
+    bcm2079x_dev_t* dev = (bcm2079x_dev_t*) p_dev;
+
+    retval = HaiControlGranted (dev);
+   return retval;
+}
+
+
+static int hal_power_cycle (const struct nfc_nci_device *p_dev)
+{
+    int retval = 0;
+    bcm2079x_dev_t* dev = (bcm2079x_dev_t*) p_dev;
+
+    retval = HaiPowerCycle (dev);
+    return retval;
+}
+
+
+static int hal_get_max_nfcee (const struct nfc_nci_device *p_dev, uint8_t* maxNfcee)
+{
+    int retval = 0;
+    bcm2079x_dev_t* dev = (bcm2079x_dev_t*) p_dev;
+
+    retval = HaiGetMaxNfcee (dev, maxNfcee);
+    return retval;
+}
+
+
+/*************************************
+ * Generic device handling.
+ *************************************/
+
+
+/* Close an opened nfc device instance */
+static int nfc_close (hw_device_t *dev)
+{
+    int retval = 0;
+    free (dev);
+    retval = HaiTerminateLibrary ();
+    return retval;
+}
+
+
+static int nfc_open (const hw_module_t* module, const char* name, hw_device_t** device)
+{
+    ALOGD ("%s: enter; name=%s", __FUNCTION__, name);
+    int retval = 0; //0 is ok; -1 is error
+
+    if (strcmp (name, NFC_NCI_CONTROLLER) == 0)
+    {
+        bcm2079x_dev_t *dev = calloc (1, sizeof(bcm2079x_dev_t));
+
+        // Common hw_device_t fields
+        dev->nci_device.common.tag = HARDWARE_DEVICE_TAG;
+        dev->nci_device.common.version = 0x00010000; // [31:16] major, [15:0] minor
+        dev->nci_device.common.module = (struct hw_module_t*) module;
+        dev->nci_device.common.close = nfc_close;
+
+        // NCI HAL method pointers
+        dev->nci_device.open = hal_open;
+        dev->nci_device.write = hal_write;
+        dev->nci_device.core_initialized = hal_core_initialized;
+        dev->nci_device.pre_discover = hal_pre_discover;
+        dev->nci_device.close = hal_close;
+        dev->nci_device.control_granted = hal_control_granted;
+        dev->nci_device.power_cycle = hal_power_cycle;
+        //dev->nci_device.get_max_ee = hal_get_max_nfcee;
+
+
+        // Copy in
+        *device = (hw_device_t*) dev;
+
+        retval = HaiInitializeLibrary (dev);
+    }
+    else
+    {
+        retval = -EINVAL;
+    }
+    ALOGD ("%s: exit %d", __FUNCTION__, retval);
+    return retval;
+}
+
+
+static struct hw_module_methods_t nfc_module_methods =
+{
+    .open = nfc_open,
+};
+
+
+struct nfc_nci_module_t HAL_MODULE_INFO_SYM =
+{
+    .common =
+    {
+        .tag = HARDWARE_MODULE_TAG, .module_api_version = 0x0100, // [15:8] major, [7:0] minor (1.0)
+        .hal_api_version = 0x00, // 0 is only valid value
+        .id = NFC_NCI_BCM2079X_HARDWARE_MODULE_ID,
+        .name = "BCM2079x NFC NCI HW HAL",
+        .author = "Broadcom Corporation",
+        .methods = &nfc_module_methods,
+    },
+};
diff --git a/halimpl/pn54x/Android.mk b/halimpl/pn54x/Android.mk
new file mode 100644
index 0000000..f9ce2c1
--- /dev/null
+++ b/halimpl/pn54x/Android.mk
@@ -0,0 +1,171 @@
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+HAL_SUFFIX := $(TARGET_DEVICE)
+ifeq ($(TARGET_DEVICE),crespo)
+	HAL_SUFFIX := herring
+endif
+
+#Enable NXP Specific
+D_CFLAGS += -DNXP_EXTNS=TRUE
+
+#variables for NFC_NXP_CHIP_TYPE
+PN547C2 := 1
+PN548C2 := 2
+PN551   := 3
+PN553   := 4
+PN557   := 5
+
+NQ110 := $PN547C2
+NQ120 := $PN547C2
+NQ210 := $PN548C2
+NQ220 := $PN548C2
+
+#Enable HCE-F specific
+D_CFLAGS += -DNXP_NFCC_HCE_F=TRUE
+
+#NXP PN547 Enable
+ifeq ($(PN547C2),1)
+D_CFLAGS += -DPN547C2=1
+endif
+ifeq ($(PN548C2),2)
+D_CFLAGS += -DPN548C2=2
+endif
+ifeq ($(PN551),3)
+D_CFLAGS += -DPN551=3
+endif
+ifeq ($(PN553),4)
+D_CFLAGS += -DPN553=4
+endif
+ifeq ($(PN557),5)
+D_CFLAGS += -DPN557=5
+endif
+
+#### Select the CHIP ####
+ifeq ($(strip $(NQ3XX_PRESENT)),true)
+NXP_CHIP_TYPE := $(PN553)
+else
+NXP_CHIP_TYPE := $(PN548C2)
+endif
+
+ifeq ($(NXP_CHIP_TYPE),$(PN547C2))
+D_CFLAGS += -DNFC_NXP_CHIP_TYPE=PN547C2
+else ifeq ($(NXP_CHIP_TYPE),$(PN548C2))
+D_CFLAGS += -DNFC_NXP_CHIP_TYPE=PN548C2
+else ifeq ($(NXP_CHIP_TYPE),$(PN551))
+D_CFLAGS += -DNFC_NXP_CHIP_TYPE=PN551
+else ifeq ($(NXP_CHIP_TYPE),$(PN553))
+D_CFLAGS += -DNFC_NXP_CHIP_TYPE=PN553
+else ifeq ($(NXP_CHIP_TYPE),$(PN557))
+D_CFLAGS += -DNFC_NXP_CHIP_TYPE=PN557
+endif
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+ifeq ($(NXP_CHIP_TYPE),$(PN547C2))
+LOCAL_MODULE := nfc_nci_pn547.grouper
+else ifeq ($(NXP_CHIP_TYPE),$(PN548C2))
+LOCAL_MODULE := nfc_nci.nqx.default
+else ifeq ($(NXP_CHIP_TYPE),$(PN551))
+LOCAL_MODULE := nfc_nci.nqx.default
+else ifeq ($(NXP_CHIP_TYPE),$(PN553))
+LOCAL_MODULE := nfc_nci.nqx.default
+else ifeq ($(NXP_CHIP_TYPE),$(PN557))
+LOCAL_MODULE := nfc_nci.nqx.default
+endif
+ifeq (true,$(TARGET_IS_64_BIT))
+LOCAL_MULTILIB := 64
+else
+LOCAL_MULTILIB := 32
+endif
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_SRC_FILES := \
+	$(call all-c-files-under, common) \
+	$(call all-c-files-under, dnld) \
+	$(call all-c-files-under, hal) \
+	$(call all-c-files-under, log) \
+	$(call all-c-files-under, self-test) \
+	$(call all-c-files-under, tml) \
+	$(call all-c-files-under, utils) \
+	$(call all-cpp-files-under, utils) \
+	nfc_nci.c
+LOCAL_SHARED_LIBRARIES := liblog libcutils libhardware_legacy libdl
+LOCAL_MODULE_TAGS := optional
+LOCAL_PROPRIETARY_MODULE := true
+LOCAL_MODULE_OWNER := nxp
+
+LOCAL_CFLAGS := $(D_CFLAGS)
+LOCAL_C_INCLUDES += \
+    $(LOCAL_PATH)/utils \
+    $(LOCAL_PATH)/inc \
+    $(LOCAL_PATH)/common \
+    $(LOCAL_PATH)/dnld \
+    $(LOCAL_PATH)/hal \
+    $(LOCAL_PATH)/log \
+    $(LOCAL_PATH)/tml \
+    $(LOCAL_PATH)/configs \
+    $(LOCAL_PATH)/self-test
+
+LOCAL_CFLAGS += -DANDROID \
+        -DNXP_HW_SELF_TEST
+LOCAL_CFLAGS += -DNFC_NXP_HFO_SETTINGS=FALSE
+NFC_NXP_ESE:= TRUE
+ifeq ($(NFC_NXP_ESE),TRUE)
+D_CFLAGS += -DNFC_NXP_ESE=TRUE
+ifeq ($(NXP_CHIP_TYPE),$(PN553))
+D_CFLAGS += -DJCOP_WA_ENABLE=FALSE
+else
+D_CFLAGS += -DJCOP_WA_ENABLE=TRUE
+endif
+else
+D_CFLAGS += -DNFC_NXP_ESE=FALSE
+endif
+LOCAL_CFLAGS += $(D_CFLAGS)
+#LOCAL_CFLAGS += -DFELICA_CLT_ENABLE
+#-DNXP_PN547C1_DOWNLOAD
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE       := libnfc-brcm.conf
+LOCAL_MODULE_TAGS  := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH  := $(TARGET_OUT_VENDOR_ETC)
+LOCAL_SRC_FILES    := $(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE       := libnfc-nxp.conf
+LOCAL_MODULE_TAGS  := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH  := $(TARGET_OUT_VENDOR_ETC)
+ifeq ($(strip $(NQ3XX_PRESENT)),true)
+LOCAL_SRC_FILES    := libnfc-nxp-PN80T_example.conf
+else
+LOCAL_SRC_FILES    := libnfc-nxp-PN66T_example.conf
+endif
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE       := libnfc-nxp_default.conf
+LOCAL_MODULE_TAGS  := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH  := $(TARGET_OUT_VENDOR_ETC)
+
+ifeq ($(strip $(NQ3XX_PRESENT)),true)
+LOCAL_SRC_FILES    := libnfc-nxp-PN80T_example.conf
+else
+LOCAL_SRC_FILES    := libnfc-nxp-PN66T_example.conf
+endif
+include $(BUILD_PREBUILT)
diff --git a/halimpl/pn54x/common/phNfcCommon.h b/halimpl/pn54x/common/phNfcCommon.h
new file mode 100644
index 0000000..4ba1bbf
--- /dev/null
+++ b/halimpl/pn54x/common/phNfcCommon.h
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ *  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>
+
+/* HAL Version number (Updated as per release) */
+#define NXP_MW_VERSION_MAJ (0x01)
+#define NXP_MW_VERSION_MIN (0x00)
+
+#define GET_EEPROM_DATA (1U)
+#define SET_EEPROM_DATA (2U)
+
+#define BITWISE (1U)
+#define BYTEWISE (2U)
+
+#define GET_FW_DWNLD_FLAG (1U)
+#define RESET_FW_DWNLD_FLAG (2U)
+/*
+ *****************************************************************
+ ***********  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*/
+/* Use one of CLK_SRC_<value> */
+#define NXP_SYS_CLK_SRC_SEL CLK_SRC_PLL
+/*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_32MHZ         5
+#define CLK_FREQ_38_4MHZ       6
+#define CLK_FREQ_52MHZ         7
+
+#define SET_CONFIG_CMD_PLL_13MHZ        {0x20, 0x02, 0x0C, 0x01, 0xA0, 0x20, 0x08, 0x08,\
+                                        0x52, 0xA2, 0x02, 0x30, 0x01, 0xE1, 0x02}
+
+#define SET_CONFIG_CMD_DPLL_13MHZ       {0x20, 0x02, 0x0C, 0x01, 0xA0, 0x26, 0x08, 0x40,\
+                                        0x42, 0xA3, 0x02, 0x88, 0x01, 0xE2, 0x02}
+
+#define SET_CONFIG_CMD_PLL_19_2MHZ      {0x20, 0x02, 0x0C, 0x01, 0xA0, 0x20, 0x08, 0x88,\
+                                        0x51, 0xE3, 0x02, 0xB8, 0x21, 0xE1, 0x02}
+
+#define SET_CONFIG_CMD_DPLL_19_2MHZ     {0x20, 0x02, 0x0C, 0x01, 0xA0, 0x26, 0x08, 0x88,\
+                                        0x01, 0xE2, 0x02, 0xF0, 0x00, 0xA2, 0x01}
+
+#define SET_CONFIG_CMD_PLL_24MHZ        {0x20, 0x02, 0x0C, 0x01, 0xA0, 0x20, 0x08, 0x28,\
+                                         0xC2, 0xA2, 0x83, 0x88, 0x11, 0xE1, 0x02}
+
+#define SET_CONFIG_CMD_DPLL_24MHZ       {0x20, 0x02, 0x0C, 0x01, 0xA0, 0x26, 0x08, 0x38,\
+                                         0x41, 0xD3, 0x02, 0x88, 0x01, 0xE2, 0x02}
+
+#define SET_CONFIG_CMD_PLL_26MHZ        {0x20, 0x02, 0x0C, 0x01, 0xA0, 0x20, 0x08, 0x08,\
+                                         0x52, 0xA2, 0x82, 0x30, 0x01, 0xE1, 0x02}
+
+#define SET_CONFIG_CMD_DPLL_26MHZ       {0x20, 0x02, 0x0C, 0x01, 0xA0, 0x26, 0x08, 0x20,\
+                                         0x41, 0xA3, 0x01, 0x88, 0x01, 0xE2, 0x02}
+
+#define SET_CONFIG_CMD_PLL_32MHZ        {0x20, 0x02, 0x0C, 0x01, 0xA0, 0x20, 0x08, 0xB8, 0x51, 0xA3, 0x82, 0x88, 0xF1, 0xF0, 0x02}
+
+#define SET_CONFIG_CMD_DPLL_32MHZ       {0x20, 0x02, 0x0C, 0x01, 0xA0, 0x26, 0x08, 0xB0,\
+                                         0x01, 0xA3, 0x82, 0x88, 0x01, 0xE2, 0x02}
+
+#define SET_CONFIG_CMD_PLL_38_4MHZ      {0x20, 0x02, 0x0C, 0x01, 0xA0, 0x20, 0x08, 0x88,\
+                                         0x51, 0xE3, 0x82, 0x88, 0x21, 0xE1, 0x02}
+
+#define SET_CONFIG_CMD_DPLL_38_4MHZ     {0x20, 0x02, 0x0C, 0x01, 0xA0, 0x26, 0x08, 0x88,\
+                                        0x01, 0xE2, 0x82, 0xF0, 0x00, 0xA2, 0x01}
+
+/* Set to one of CLK_FREQ_<value> */
+#define NXP_SYS_CLK_FREQ_SEL CLK_FREQ_19_2MHZ
+
+#define CLK_TO_CFG_DEF 1
+#define CLK_TO_CFG_MAX 6
+/*
+ *  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 */
+  /* Timer callback function to be invoked */
+  pphOsalNfc_TimerCallbck_t Application_callback;
+  void* pContext; /* Parameter to be passed to the callback function */
+  phOsalNfc_TimerStates_t eState; /* Timer states */
+  /* Osal Timer message posted on User Thread */
+  phLibNfc_Message_t tOsalMessage;
+  /* Deferred Call structure to Invoke Callback function */
+  phOsalNfc_DeferedCallInfo_t tDeferedCallInfo;
+  /* Variables for Structure Instance and Structure Ptr */
+} phOsalNfc_TimerHandle_t, *pphOsalNfc_TimerHandle_t;
+
+#endif /*  PHOSALNFC_H  */
diff --git a/halimpl/pn54x/common/phNfcCompId.h b/halimpl/pn54x/common/phNfcCompId.h
new file mode 100644
index 0000000..687669c
--- /dev/null
+++ b/halimpl/pn54x/common/phNfcCompId.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * 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".
+ */
+/* Unassigned or doesn't apply (see #NFCSTATUS_SUCCESS) */
+#define CID_NFC_NONE 0x00
+#define CID_NFC_TML 0x01 /* Transport Mapping Layer */
+#define CID_NFC_LLC 0x07 /* Logical Link Control Layer */
+/* NFC Controller(NFCC) Interface Layer */
+#define CID_NFC_NCI 0x08
+/* Firmware Download Management Layer */
+#define CID_NFC_DNLD 0x09
+#define CID_NFC_HAL 0x10 /* Hardware Abstraction Layer */
+/* Operating System Abstraction Layer*/
+#define CID_NFC_OSAL CID_NFC_NONE
+#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. */
+/* Automatic Device Discovery. */
+#define CID_FRI_NFC_AUTO_DEV_DIS 0x25
+#define CID_FRI_NFC_NDEF_SMTCRDFMT 0x26 /* Smart Card Formatting */
+#define CID_NFC_LIB 0x30                /* NFC Library Layer*/
+/* The maximum CID value that is defined. */
+#define CID_MAX_VALUE 0xF0
+/* Logical Link Control Protocol */
+#define CID_FRI_NFC_LLCP 0x40
+#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..5057b01
--- /dev/null
+++ b/halimpl/pn54x/common/phNfcStatus.h
@@ -0,0 +1,392 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * 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)
+
+/*
+ * The function indicates given module not initialized
+ */
+#define NFC_STATUS_NOT_INITIALIZED (0x0004)
+
+/*
+
+ * 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)
+
+/*
+ * FW version error while performing FW download,
+ * FW major version mismatch (cannot downgrade FW major version) or FW version
+ * already upto date
+ * User may be trying to flash Mobile FW on top of Infra FW, which is not
+ * allowed
+ * Download appropriate version of FW
+ */
+#define NFCSTATUS_FW_VERSION_ERROR (0x003C)
+
+/*
+ *  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)
+
+#define NFCSTATUS_SMX_SPI_STATE (0x00F0)
+
+/* The current module is free ; one might use it */
+#define NFCSTATUS_SMX_IDLE_STATE (0x00F1)
+
+/* The current module is busy with wired; one might use it */
+#define NFCSTATUS_SMX_WIRED_STATE (0x00F3)
+
+/* The current module is free ; one might use it */
+#define NFCSTATUS_NFCC_DWNLD_STATE (0x00F4)
+
+/* 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..3a0baf9
--- /dev/null
+++ b/halimpl/pn54x/common/phNfcTypes.h
@@ -0,0 +1,336 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef PHNFCTYPES_H
+#define PHNFCTYPES_H
+
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include "Nxp_Features.h"
+
+#ifndef true
+#define true (0x01) /* Logical True Value */
+#endif
+#ifndef TRUE
+#define TRUE (0x01) /* Logical True Value */
+#endif
+#ifndef false
+#define false (0x00) /* Logical False 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 */
+/* Maximum ATR_RES (General Bytes) length expected */
+#define PHNFC_MAX_ATR_LENGTH 0x30U
+#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;
+#if (NXP_EXTNS == TRUE)
+typedef enum p61_access_state {
+  P61_STATE_INVALID = 0x0000,
+  P61_STATE_IDLE = 0x0100,         /* p61 is free to use */
+  P61_STATE_WIRED = 0x0200,        /* p61 is being accessed by DWP (NFCC)*/
+  P61_STATE_SPI = 0x0400,          /* P61 is being accessed by SPI */
+  P61_STATE_DWNLD = 0x0800,        /* NFCC fw download is in progress */
+  P61_STATE_SPI_PRIO = 0x1000,     /*Start of p61 access by SPI on priority*/
+  P61_STATE_SPI_PRIO_END = 0x2000, /*End of p61 access by SPI on priority*/
+  P61_STATE_SPI_END = 0x4000,
+  P61_STATE_JCP_DWNLD = 0x8000,           /* JCOP downlad in progress */
+  P61_STATE_SECURE_MODE = 0x100000,       /* secure mode state*/
+  P61_STATE_SPI_SVDD_SYNC_START = 0x0001, /*ESE_VDD Low req by SPI*/
+  P61_STATE_SPI_SVDD_SYNC_END = 0x0002,   /*ESE_VDD is Low by SPI*/
+  P61_STATE_DWP_SVDD_SYNC_START = 0x0004, /*ESE_VDD  Low req by Nfc*/
+  P61_STATE_DWP_SVDD_SYNC_END = 0x0008    /*ESE_VDD is Low by Nfc*/
+} p61_access_state_t;
+
+typedef enum jcop_dwnld_state {
+  JCP_DWNLD_IDLE = P61_STATE_JCP_DWNLD, /* jcop dwnld is not ongoing*/
+  JCP_DWNLD_INIT = 0x8010,              /* jcop dwonload init state*/
+  JCP_DWNLD_START = 0x8020,             /* download started */
+  JCP_SPI_DWNLD_COMPLETE = 0x8040, /* jcop download complete in spi interface*/
+  JCP_DWP_DWNLD_COMPLETE = 0x8080, /* jcop download complete */
+} jcop_dwnld_state_t;
+#endif
+#define UNUSED(X) (void) X;
+
+#endif /* PHNFCTYPES_H */
diff --git a/halimpl/pn54x/configs/NxpNfcCapability.cpp b/halimpl/pn54x/configs/NxpNfcCapability.cpp
new file mode 100644
index 0000000..5a89486
--- /dev/null
+++ b/halimpl/pn54x/configs/NxpNfcCapability.cpp
@@ -0,0 +1,95 @@
+/******************************************************************************
+ *
+ *  Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT 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 "NxpNfcCapability.h"
+#include <phNxpLog.h>
+
+capability* capability::instance = NULL;
+tNFC_chipType capability::chipType = pn80T;
+
+capability::capability(){}
+
+capability* capability::getInstance() {
+    if (NULL == instance) {
+        instance = new capability();
+    }
+    return instance;
+}
+
+tNFC_chipType capability::processChipType(uint8_t* msg, uint16_t msg_len) {
+    if((msg != NULL) && (msg_len != 0)) {
+        if((msg[0] == 0x60 && msg[1] == 00) ||
+                ((offsetFwVersion < msg_len) && (msg[offsetFwVersion] == 0x12))) {
+            chipType = pn81T;
+        }
+        else if(offsetHwVersion < msg_len) {
+            ALOGD ("%s HwVersion : 0x%02x", __func__,msg[offsetHwVersion]);
+            switch(msg[offsetHwVersion]){
+
+            case 0x40 : //PN553 A0
+            case 0x41 : //PN553 B0
+                chipType = pn553;
+                break;
+
+            case 0x50 : //PN553 A0 + P73
+            case 0x51 : //PN553 B0 + P73
+                chipType = pn80T;
+                break;
+
+            case 0x98 :
+                chipType = pn551;
+                break;
+
+            case 0xA8 :
+                chipType = pn67T;
+                break;
+
+            case 0x28 :
+            case 0x48 :
+                chipType = pn548C2;
+                break;
+
+            case 0x18 :
+            case 0x58 :
+                chipType = pn66T;
+                break;
+
+            default :
+                chipType = pn80T;
+            }
+        }
+        else {
+            ALOGD ("%s Wrong msg_len. Setting Default ChiptType pn80T",__func__);
+            chipType = pn80T;
+        }
+    }
+    return chipType;
+}
+
+extern "C" tNFC_chipType configChipType(uint8_t* msg, uint16_t msg_len) {
+    return pConfigFL->processChipType(msg,msg_len);
+}
+
+extern "C" tNFC_chipType getChipType() {
+    ALOGD ("%s", __FUNCTION__);
+    return capability::chipType;
+}
+
+
diff --git a/halimpl/pn54x/configs/NxpNfcCapability.h b/halimpl/pn54x/configs/NxpNfcCapability.h
new file mode 100644
index 0000000..538a9c8
--- /dev/null
+++ b/halimpl/pn54x/configs/NxpNfcCapability.h
@@ -0,0 +1,69 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "Nxp_Features.h"
+#ifndef __CAP_H__
+#define __CAP_H__
+#define pConfigFL       (capability::getInstance())
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+**
+** Function         getChipType
+**
+** Description      Gets the chipType which is configured during bootup
+**
+** Parameters       none
+**
+** Returns          chipType
+*******************************************************************************/
+tNFC_chipType getChipType ();
+
+/*******************************************************************************
+**
+** Function         configChipType
+**
+** Description      Finds chiptType by processing msg buffer
+**
+** Parameters       msg, len
+**                  msg : CORE_INIT_RESPONSE (NCI 1.0)
+**                           CORE_RST_NTF (NCI 2.0)
+**
+** Returns          chipType
+*******************************************************************************/
+tNFC_chipType configChipType(uint8_t* msg, uint16_t msg_len);
+#ifdef __cplusplus
+};
+
+class capability {
+private:
+    static capability* instance;
+    const uint16_t offsetHwVersion = 24;
+    const uint16_t offsetFwVersion = 25;
+    capability();
+public:
+    static tNFC_chipType chipType;
+    static capability* getInstance();
+    tNFC_chipType processChipType(uint8_t* msg, uint16_t msg_len);
+};
+
+#endif
+
+#endif
+
diff --git a/halimpl/pn54x/dnld/phDnldNfc.c b/halimpl/pn54x/dnld/phDnldNfc.c
new file mode 100644
index 0000000..09882d2
--- /dev/null
+++ b/halimpl/pn54x/dnld/phDnldNfc.c
@@ -0,0 +1,1296 @@
+/*
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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>
+#include <phNxpConfig.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 */
+uint8_t gRecFWDwnld; /* flag set to true to indicate dummy FW download */
+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) ||
+           ((nfcFL.chipType == pn551) &&
+                   ((PHDNLDNFC_HWVER_PN551_MRA1_0 == bChipVer) ||
+           (PHDNLDNFC_HWVER_PN553_MRA1_0 == bChipVer))) ||
+            ((nfcFL.chipType == pn548C2) &&
+                    (PHDNLDNFC_HWVER_PN548AD_MRA1_0 == bChipVer)) ||
+            (((nfcFL.chipType == pn553) || (nfcFL.chipType == pn557)) &&
+               ((PHDNLDNFC_HWVER_PN553_MRA1_0 == bChipVer) ||
+            (PHDNLDNFC_HWVER_PN553_MRA1_0_UPDATED & bChipVer) ||
+            (PHDNLDNFC_HWVER_PN557_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 error
+**
+*******************************************************************************/
+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;
+  char fwFileName[256];
+  char fwpathName[256];
+  char* pathName = NULL;
+
+  /* if memory is not allocated then allocate memory for download context
+   * structure */
+  phDnldNfc_SetHwDevHandle();
+
+  /*Read Firmware file name from config file*/
+  if (GetNxpStrValue(NAME_NXP_FW_NAME, (char*)fwFileName, sizeof(fwFileName)) ==
+      true) {
+    strlcpy(fwpathName, FW_DLL_ROOT_DIR, sizeof(fwpathName));
+    strlcat(fwpathName, fwFileName, sizeof(fwpathName));
+    pathName = fwpathName;
+  }
+
+/* load the library and get the image info pointer */
+  if ((nfcFL.chipType != pn547C2) && (gRecFWDwnld == true)) {
+    wStatus = phDnldNfc_LoadRecoveryFW(pathName, &pImageInfo, &ImageInfoLen);
+  } else {
+    wStatus = phDnldNfc_LoadFW(pathName, &pImageInfo, &ImageInfoLen);
+  }
+
+  NXPLOG_FWDNLD_D("FW Image Length - ImageInfoLen %d", ImageInfoLen);
+  NXPLOG_FWDNLD_D("FW Image Info Pointer - pImageInfo %p", 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 libpn5xx_fw.so !!!\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 - %p", 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();
+  if ((nfcFL.chipType != pn547C2) && (gRecFWDwnld == true)) {
+      wStatus =
+              phDnldNfc_LoadRecoveryFW(nfcFL.nfcMwFL._PLATFORM_LIB_PATH,
+                      &pImageInfo, &ImageInfoLen);
+  } else {
+      wStatus = phDnldNfc_LoadFW(nfcFL.nfcMwFL._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 - %p", 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 */
+  if ((nfcFL.chipType != pn547C2) && (gRecFWDwnld == true)) {
+      wStatus =
+              phDnldNfc_LoadRecoveryFW(nfcFL.nfcMwFL._PKU_LIB_PATH,
+                      &pImageInfo, &ImageInfoLen);
+  } else {
+      wStatus = phDnldNfc_LoadFW(nfcFL.nfcMwFL._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 - %p", 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 (pathName == NULL) {
+      if(nfcFL.chipType == pn548C2) {
+          pathName = "/vendor/firmware/libpn548ad_fw.so";
+      } else if(nfcFL.chipType == pn551) {
+          pathName = "/vendor/firmware/libpn551_fw.so";
+      } else if(nfcFL.chipType == pn553) {
+          pathName = "/vendor/firmware/libpn553_fw.so";
+      } else if(nfcFL.chipType == pn557) {
+          pathName = "/vendor/firmware/libpn557_fw.so";
+      } else {
+          pathName = "/vendor/firmware/libpn547_fw.so";
+      }
+  }
+
+  /* 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_LoadRecoveryFW
+**
+** Description      Load the dummy firmware version form firmware lib for
+**                  recovery. This will change the FW version of the NFCC
+**                  firmware and enable flashing of firmware of same version.
+**
+** Parameters       pathName    - Firmware image path
+**                  pImgInfo    - Firmware image handle
+**                  pImgInfoLen - Firmware image length
+**
+** Returns          NFCSTATUS
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_LoadRecoveryFW(const char* pathName, uint8_t** pImgInfo,
+                                   uint16_t* pImgInfoLen) {
+  void* pImageInfo = NULL;
+  void* pImageInfoLen = NULL;
+
+  /* check for path name */
+  if (pathName == NULL) {
+      if(nfcFL.chipType == pn548C2) {
+          pathName = "/vendor/firmware/libpn548ad_fw.so";
+      } else if(nfcFL.chipType == pn551) {
+          pathName = "/vendor/firmware/libpn551_fw.so";
+      } else if(nfcFL.chipType == pn553) {
+          pathName = "/vendor/firmware/libpn553_fw.so";
+      }else if(nfcFL.chipType == pn557) {
+          pathName = "/vendor/firmware/libpn557_fw.so";
+      } else {
+          pathName = "/vendor/firmware/libpn547_fw.so";
+      }
+  }
+  /* 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("phDnldNfc_LoadRecoveryFW %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_DummyDlSeq");
+
+  if (dlerror() || (NULL == pImageInfo)) {
+    NXPLOG_FWDNLD_E("Problem loading symbol : gphDnldNfc_DummyDlSeq");
+    return NFCSTATUS_FAILED;
+  }
+  (*pImgInfo) = (*(uint8_t**)pImageInfo);
+
+  pImageInfoLen = (void*)dlsym(pFwLibHandle, "gphDnldNfc_DlSeqDummyFwSz");
+  if (dlerror() || (NULL == pImageInfoLen)) {
+    NXPLOG_FWDNLD_E("Problem loading symbol : gphDnldNfc_DlSeqDummyFwSz");
+    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..59bb756
--- /dev/null
+++ b/halimpl/pn54x/dnld/phDnldNfc.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * 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 */
+
+/* PN548AD ChipVersion MRA1.0 */
+#define PHDNLDNFC_HWVER_PN548AD_MRA1_0 (0x08U)
+
+/* PN551 ChipVersion MRA1.0 */
+#define PHDNLDNFC_HWVER_PN551_MRA1_0 (0x08U)
+
+#define PHDNLDNFC_HWVER_PN553_MRA1_0 \
+  (0x0BU) /* PN553-NCI1.0 ChipVersion MRA1.0 */
+          /* PN553 A0 -> 0x40 hardware version
+             PN553 B0 -> 0x41
+             PN80T A0 -> 0x50
+             PN80T B0 -> 0x51 */
+#define PHDNLDNFC_HWVER_PN553_MRA1_0_UPDATED (0x40U)
+#define PHDNLDNFC_HWVER_PN557_MRA1_0 (0x01U)
+/*
+ * 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_LoadRecoveryFW(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..05349c5
--- /dev/null
+++ b/halimpl/pn54x/dnld/phDnldNfc_Cmd.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * 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..d6d0bad
--- /dev/null
+++ b/halimpl/pn54x/dnld/phDnldNfc_Internal.c
@@ -0,0 +1,1208 @@
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Internal Download Management routines
+ * Download Component
+ */
+
+#include <phDnldNfc_Internal.h>
+#include <phDnldNfc_Utils.h>
+#include <phTmlNfc.h>
+#include <phNxpLog.h>
+#include <phNxpNciHal_utils.h>
+
+/* Minimum length of payload including 1 byte CmdId */
+#define PHDNLDNFC_MIN_PLD_LEN (0x04U)
+/* Offset of Length byte within the frame */
+#define PHDNLDNFC_FRAME_HDR_OFFSET (0x00)
+/* Offset of FrameId within the frame */
+#define PHDNLDNFC_FRAMEID_OFFSET (PHDNLDNFC_FRAME_HDR_LEN)
+/* Offset of status byte within the frame */
+#define PHDNLDNFC_FRAMESTATUS_OFFSET PHDNLDNFC_FRAMEID_OFFSET
+/* Offset within frame where payload starts*/
+#define PHDNLDNFC_PLD_OFFSET (PHDNLDNFC_MIN_PLD_LEN - 1)
+
+#define PHDNLDNFC_FRAME_RDDATA_OFFSET \
+  ((PHDNLDNFC_FRAME_HDR_LEN) +        \
+   (PHDNLDNFC_MIN_PLD_LEN)) /* recvd frame offset where data starts */
+/* Size of first secure write frame Signature */
+#define PHDNLDNFC_FRAME_SIGNATURE_SIZE (0xC0U)
+/* Size of first secure write frame payload */
+#define PHDNLDNFC_FIRST_FRAME_PLD_SIZE (0xE4U)
+
+/* Status response for first fragmented write frame */
+#define PHDNLDNFC_FIRST_FRAGFRAME_RESP (0x2DU)
+/* Status response for subsequent fragmented write frame */
+#define PHDNLDNFC_NEXT_FRAGFRAME_RESP (0x2EU)
+
+#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 */
+
+/* Timeout value to wait for response from NFCC */
+#define PHDNLDNFC_RSP_TIMEOUT (2500)
+/* Timeout value to wait before resending the last frame */
+#define PHDNLDNFC_RETRY_FRAME_WRITE (50)
+
+/* size of EEPROM user data length */
+#define PHDNLDNFC_USERDATA_EEPROM_LENSIZE (0x02U)
+/* size of EEPROM offset */
+#define PHDNLDNFC_USERDATA_EEPROM_OFFSIZE (0x02U)
+
+#ifdef NXP_PN547C1_DOWNLOAD
+/* EEPROM offset and length value for PN547C1 */
+/* 16 bits offset indicating user data area start location */
+#define PHDNLDNFC_USERDATA_EEPROM_OFFSET (0x003CU)
+/* 16 bits length of user data area */
+#define PHDNLDNFC_USERDATA_EEPROM_LEN (0x0DC0U)
+
+#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);
+
+          /* set read status to pDlCtxt->wCmdSendStatus to enable callback */
+          pDlCtxt->wCmdSendStatus = wStatus;
+          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);
+
+          /* set read status to pDlCtxt->wCmdSendStatus to enable callback */
+          pDlCtxt->wCmdSendStatus = wStatus;
+          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 (wFrameLen > PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE) {
+        NXPLOG_FWDNLD_D("wFrameLen exceeds the limit");
+        return NFCSTATUS_FAILED;
+      }
+
+      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;
+          }
+        }
+        /*Check whether enough space is left for 2 bytes of CRC append*/
+        if (wFrameLen > (PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE - 2)) {
+          NXPLOG_FWDNLD_D("wFrameLen exceeds the limit");
+          return NFCSTATUS_FAILED;
+        }
+        /* 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;
+#ifdef NXP_PN547C1_DOWNLOAD
+      wChkIntgVal = PHDNLDNFC_USERDATA_EEPROM_OFFSET;
+#else
+      wChkIntgVal = nfcFL.nfcMwFL._PHDNLDNFC_USERDATA_EEPROM_OFFSET;
+#endif
+
+      memcpy(&(pDlContext->tCmdRspFrameInfo
+                   .aFrameBuff[PHDNLDNFC_FRAME_RDDATA_OFFSET]),
+             &wChkIntgVal, sizeof(wChkIntgVal));
+
+#ifdef NXP_PN547C1_DOWNLOAD
+      wChkIntgVal = PHDNLDNFC_USERDATA_EEPROM_LEN;
+#else
+      wChkIntgVal = nfcFL.nfcMwFL._PHDNLDNFC_USERDATA_EEPROM_LEN;
+#endif
+      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 == true)
+      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(
+            "FW version Error !!!could be either due to FW major version "
+            "mismatch or 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_FW_VERSION_ERROR;
+      } 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..e03a87b
--- /dev/null
+++ b/halimpl/pn54x/dnld/phDnldNfc_Internal.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * 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
+
+/* DL Host Short Frame Buffer Size for pipelined WRITE RSP */
+#define PHDNLDNFC_WRITERSP_BUFF_SIZE (0x08U)
+
+/* DL Host Frame Buffer Header Length */
+#define PHDNLDNFC_FRAME_HDR_LEN (0x02U)
+/* DL Host Frame Buffer CRC Length */
+#define PHDNLDNFC_FRAME_CRC_LEN (PHDNLDNFC_FRAME_HDR_LEN)
+#define PHDNLDNFC_FRAME_ID_LEN (0x01U) /* Length of Cmd Id */
+
+/* size of EEPROM/Flash address */
+#define PHDNLDNFC_EEFL_ADDR_SIZE (0x03U)
+/* 2 Byte size of data */
+#define PHDNLDNFC_DATA_SIZE (PHDNLDNFC_FRAME_HDR_LEN)
+
+/* Start of EEPROM address for log */
+#define PHDNLDNFC_EEPROM_LOG_START_ADDR (0x201F80U)
+/* End of EEPROM address for log */
+#define PHDNLDNFC_EEPROM_LOG_END_ADDR (0x201FBFU)
+
+#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..f8d3fb3
--- /dev/null
+++ b/halimpl/pn54x/dnld/phDnldNfc_Status.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * 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..ae49f8c
--- /dev/null
+++ b/halimpl/pn54x/dnld/phDnldNfc_Utils.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * 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..3c8e955
--- /dev/null
+++ b/halimpl/pn54x/dnld/phDnldNfc_Utils.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * 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..100b72b
--- /dev/null
+++ b/halimpl/pn54x/dnld/phNxpNciHal_Dnld.c
@@ -0,0 +1,1827 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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;
+extern uint8_t
+    gRecFWDwnld; /* flag  set to true to  indicate dummy FW download */
+/* 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_stat[])(void* pContext,
+                                                   NFCSTATUS status,
+                                                   void* pInfo) = {
+    phNxpNciHal_fw_dnld_normal, phNxpNciHal_fw_dnld_normal,
+    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};
+
+/* Array of pointers to start fw download seq */
+static NFCSTATUS (*phNxpNciHal_dwnld_seqhandler_common[])(void* pContext,
+                                                   NFCSTATUS status,
+                                                   void* pInfo) = {
+    phNxpNciHal_fw_dnld_normal, phNxpNciHal_fw_dnld_normal,
+    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};
+
+/* Array of pointers to start dummy fw download seq */
+static NFCSTATUS (*phNxpNciHal_dummy_rec_dwnld_seqhandler[])(void* pContext,
+                                                             NFCSTATUS status,
+                                                             void* pInfo) = {
+    phNxpNciHal_fw_dnld_normal,          phNxpNciHal_fw_dnld_normal,
+    phNxpNciHal_fw_dnld_get_sessn_state, phNxpNciHal_fw_dnld_get_version,
+    phNxpNciHal_fw_dnld_log_read,        phNxpNciHal_fw_dnld_write,
+    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) ||
+               ((nfcFL.chipType == pn551) &&
+                       ((PHDNLDNFC_HWVER_PN551_MRA1_0 == bHwVer) ||
+              (PHDNLDNFC_HWVER_PN553_MRA1_0 == bHwVer))) ||
+              ((nfcFL.chipType == pn548C2) &&
+                    (PHDNLDNFC_HWVER_PN548AD_MRA1_0 == bHwVer)) ||
+              (((nfcFL.chipType == pn553) || (nfcFL.chipType == pn557)) &&
+                     ((PHDNLDNFC_HWVER_PN553_MRA1_0 == bHwVer ||
+              PHDNLDNFC_HWVER_PN553_MRA1_0_UPDATED & pRespBuff->pBuff[0])))) {
+        bExpectedLen = PHLIBNFC_IOCTL_DNLD_GETVERLEN_MRA2_1;
+        (gphNxpNciHal_fw_IoctlCtx.bChipVer) = bHwVer;
+        if ((nfcFL.chipType == pn553) &&
+                (PHDNLDNFC_HWVER_PN553_MRA1_0_UPDATED & pRespBuff->pBuff[0])) {
+            (gphNxpNciHal_fw_IoctlCtx.bChipVer) = pRespBuff->pBuff[0];
+        }
+
+      } 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");
+        NXPLOG_FWDNLD_E("NewVer %d != CurrVer %d\n", bNewVer[1], bCurrVer[1]);
+        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");
+        if ((nfcFL.nfccFL._NFCC_FORCE_FW_DOWNLOAD == true) &&
+                ((gphNxpNciHal_fw_IoctlCtx.bForceDnld) == false)) {
+            (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = true;
+        }
+        else {
+            (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 ((nfcFL.nfccFL._NFCC_FORCE_FW_DOWNLOAD == false) &&
+          (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);
+    if (NFCSTATUS_SUCCESS != gphNxpNciHal_fw_IoctlCtx.bLastStatus) {
+      /* update the previous Download Write status to upper layer and not the
+       * status of Log command */
+      wStatus = gphNxpNciHal_fw_IoctlCtx.bLastStatus;
+      NXPLOG_FWDNLD_E(
+          "phNxpNciHal_fw_dnld_complete: Last Download Write Status before Log "
+          "command bLastStatus = 0x%x",
+          gphNxpNciHal_fw_IoctlCtx.bLastStatus);
+    }
+    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 */
+    if(nfcFL.chipType == pn547C2) {
+        wStatus = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_seqhandler_stat);
+    } else {
+        wStatus = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_seqhandler_common);
+    }
+
+    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 {
+    NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_complete: Download Status = 0x%x",
+                    status);
+    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,
+                                      uint8_t force_fwDnld_Req)
+{
+  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;
+
+  if (nfcFL.nfccFL._NFCC_FORCE_FW_DOWNLOAD && force_fwDnld_Req) {
+    (gphNxpNciHal_fw_IoctlCtx.bForceDnld) = true;
+  }
+  /* Get firmware version */
+  if (NFCSTATUS_SUCCESS == phDnldNfc_InitImgInfo()) {
+    NXPLOG_FWDNLD_D("phDnldNfc_InitImgInfo:SUCCESS");
+    if ((nfcFL.chipType != pn547C2) && (gRecFWDwnld == true)) {
+      status =
+          phNxpNciHal_fw_seq_handler(phNxpNciHal_dummy_rec_dwnld_seqhandler);
+    } else
+    {
+        if(nfcFL.chipType == pn547C2) {
+            status = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_seqhandler_stat);
+        } else {
+            status = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_seqhandler_common);
+        }
+    }
+  } 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;
+    uint8_t bShiftVal;
+    if((nfcFL.chipType == pn551) || (nfcFL.chipType == pn553)) {
+        bBitPos = 1;
+        bShiftVal = 2;
+    } else {
+        bBitPos = 0;
+        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..dcd3c0d
--- /dev/null
+++ b/halimpl/pn54x/dnld/phNxpNciHal_Dnld.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef _PHNXPNCIHAL_DNLD_H_
+#define _PHNXPNCIHAL_DNLD_H_
+
+#include <phNfcTypes.h>
+#include <phNfcStatus.h>
+
+NFCSTATUS phNxpNciHal_fw_download_seq(uint8_t bClkSrcVal, uint8_t bClkFreqVal,
+                                      uint8_t force_fwDnld_Req);
+
+#endif /* _PHNXPNCIHAL_DNLD_H_ */
diff --git a/halimpl/pn54x/hal/phNxpNciHal.c b/halimpl/pn54x/hal/phNxpNciHal.c
new file mode 100644
index 0000000..6fcad93
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal.c
@@ -0,0 +1,4064 @@
+/*
+ * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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>
+#include <phTmlNfc_i2c.h>
+#include "phNxpNciHal_nciParser.h"
+/*********************** Global Variables *************************************/
+#define PN547C2_CLOCK_SETTING
+#undef PN547C2_FACTORY_RESET_DEBUG
+#define CORE_RES_STATUS_BYTE 3
+#if (NXP_NFCC_FORCE_NCI1_0_INIT == true)
+#ifndef PH_LIBNFC_ENABLE_FORCE_DOWNLOAD
+#define PH_LIBNFC_ENABLE_FORCE_DOWNLOAD false
+#endif
+#endif
+
+
+#define NXP_NCI_HAL_CORE_INIT_RECOVER(recoveryCount, recoveryLabel)\
+do\
+{\
+    recoveryCount++;\
+    goto recoveryLabel;\
+}while(0)
+
+/* Processing of ISO 15693 EOF */
+extern uint8_t icode_send_eof;
+extern uint8_t icode_detected;
+static uint8_t cmd_icode_eof[] = {0x00, 0x00, 0x00};
+static uint8_t read_failed_disable_nfc = false;
+static uint8_t pwr_link_required = false;
+static uint8_t config_access = false;
+static uint8_t config_success = true;
+static NFCSTATUS phNxpNciHal_FwDwnld(uint16_t aType);
+static NFCSTATUS phNxpNciHal_SendCmd(uint8_t cmd_len, uint8_t* pcmd_buff);
+static void phNxpNciHal_check_delete_nfaStorage_DHArea();
+/* 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);
+
+extern int phNxpNciHal_CheckFwRegFlashRequired(uint8_t* fw_update_req,
+                                               uint8_t* rf_update_req);
+phNxpNci_getCfg_info_t* mGetCfg_info = NULL;
+uint32_t gSvddSyncOff_Delay = 10;
+bool_t force_fw_download_req = false;
+bool_t gParserCreated = FALSE;
+/* global variable to get FW version from NCI response*/
+uint32_t wFwVerRsp;
+/* External global variable to get FW version */
+extern uint16_t wFwVer;
+
+extern uint16_t fw_maj_ver;
+extern uint16_t rom_version;
+extern int send_to_upper_kovio;
+extern int kovio_detected;
+extern int disable_kovio;
+extern uint8_t
+    gRecFWDwnld; /* flag  set to true to  indicate dummy FW download */
+static uint8_t gRecFwRetryCount;  // variable to hold dummy FW recovery count
+static uint8_t write_unlocked_status = NFCSTATUS_SUCCESS;
+static uint8_t Rx_data[NCI_MAX_DATA_LEN];
+uint32_t timeoutTimerId = 0;
+#ifndef FW_DWNLD_FLAG
+uint8_t fw_dwnld_flag = false;
+#endif
+phNxpNciHal_Sem_t config_data;
+
+phNxpNciClock_t phNxpNciClock = {0, {0}};
+
+phNxpNciRfSetting_t phNxpNciRfSet = {false, {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_nfccClockCfgRead(void);
+static NFCSTATUS phNxpNciHal_nfccClockCfgApply(void);
+static void phNxpNciHal_txNfccClockSetCmd(void);
+static void phNxpNciHal_check_factory_reset(void);
+static NFCSTATUS phNxpNciHal_check_eSE_Session_Identity(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();
+static void phNxpNciHal_core_MinInitialized_complete(NFCSTATUS status);
+static NFCSTATUS phNxpNciHal_set_Boot_Mode(uint8_t mode);
+NFCSTATUS phNxpNciHal_set_china_region_configs(void);
+static void phNxpNciHal_configNciParser(void);
+static NFCSTATUS phNxpNciHalRFConfigCmdRecSequence();
+static NFCSTATUS phNxpNciHal_CheckRFCmdRespStatus();
+int check_config_parameter();
+static NFCSTATUS phNxpNciHal_uicc_baud_rate();
+
+//static tNfc_featureList phNxpNciHal_getFeatureList();
+/******************************************************************************
+ * 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;
+      }
+      case NCI_HAL_POST_MIN_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_MIN_INIT_CPLT_EVT,
+                                              HAL_NFC_STATUS_OK);
+        }
+        REENTRANCE_UNLOCK();
+        break;
+      }
+    }
+  }
+
+  NXPLOG_NCIHAL_D("NxpNciHal thread stopped");
+
+  pthread_exit(NULL);
+  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;
+  NFCSTATUS wConfigStatus = NFCSTATUS_FAILED;
+  phNxpNciHal_nfccClockCfgRead();
+  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");
+if(nfcFL.nfccFL._NFCC_FORCE_FW_DOWNLOAD) {
+    status = phNxpNciHal_fw_download_seq(nxpprofile_ctrl.bClkSrcVal,
+                                         nxpprofile_ctrl.bClkFreqVal,
+                                         force_fw_download_req);
+}
+else {
+    status = phNxpNciHal_fw_download_seq(nxpprofile_ctrl.bClkSrcVal,
+                                         nxpprofile_ctrl.bClkFreqVal,
+                                         false);
+}
+    phDnldNfc_ReSetHwDevHandle();
+    /* call read pending */
+    wConfigStatus = phTmlNfc_Read(
+        nxpncihal_ctrl.p_cmd_data, NCI_MAX_DATA_LEN,
+        (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_read_complete, NULL);
+    if (wConfigStatus != NFCSTATUS_PENDING) {
+      NXPLOG_NCIHAL_E("TML Read status error status = %x", status);
+      phTmlNfc_Shutdown();
+      status = NFCSTATUS_FAILED;
+    }
+  } 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_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", __func__, ufw_current_major_no);
+
+  if (ufw_current_major_no == nfcFL.nfcMwFL._FW_MOBILE_MAJOR_NUMBER) {
+    status = NFCSTATUS_SUCCESS;
+  } else if (ufw_current_major_no == sfw_infra_major_no) {
+        if(rom_version == FW_MOBILE_ROM_VERSION_PN553 || rom_version == FW_MOBILE_ROM_VERSION_PN557) {
+          NXPLOG_NCIHAL_D(" PN557  allow Fw download with major number =  0x%x",
+          ufw_current_major_no);
+          status = NFCSTATUS_SUCCESS;
+        } else {
+    /* 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 ((nfcFL.chipType != pn547C2) && (gRecFWDwnld == true)) {
+    status = NFCSTATUS_SUCCESS;
+  }
+  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;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_FwDwnld
+ *
+ * Description      This function is called by libnfc-nci after core init is
+ *                  completed, to download the firmware.
+ *
+ * Returns          This function return NFCSTATUS_SUCCES (0) in case of success
+ *                  In case of failure returns other failure value.
+ *
+ ******************************************************************************/
+static NFCSTATUS phNxpNciHal_FwDwnld(uint16_t aType) {
+   NFCSTATUS status = NFCSTATUS_SUCCESS;
+
+   if(aType != NFC_STATUS_NOT_INITIALIZED) {
+   if (wFwVerRsp == 0) {
+            phDnldNfc_InitImgInfo();
+        }
+        status= phNxpNciHal_CheckValidFwVersion();
+   }
+  if (NFCSTATUS_SUCCESS == status) {
+    NXPLOG_NCIHAL_D("Found Valid Firmware Type");
+    status = phNxpNciHal_fw_download();
+    if (status != NFCSTATUS_SUCCESS) {
+      if (NFCSTATUS_SUCCESS != phNxpNciHal_fw_mw_ver_check()) {
+        NXPLOG_NCIHAL_D("Chip Version Middleware Version mismatch!!!!");
+        goto clean_and_return;
+      }
+      NXPLOG_NCIHAL_E("FW Download failed - NFCC init will continue");
+    }
+  } else {
+    if (wFwVerRsp == 0) phDnldNfc_ReSetHwDevHandle();
+  }
+clean_and_return:
+  return status;
+}
+/******************************************************************************
+ * Function         phNxpNciHal_MinOpen
+ *
+ * Description      This function is called by libnfc-nci during the minimum
+ *                  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.
+ *                  NFCSTATUS_FAILED(0xFF)
+ *
+ ******************************************************************************/
+int phNxpNciHal_MinOpen(nfc_stack_callback_t* p_cback,
+                        nfc_stack_data_callback_t* p_data_cback) {
+  NXPLOG_NCIHAL_E("Init monitor phNxpNciHal_MinOpen");
+  NFCSTATUS status = NFCSTATUS_SUCCESS;
+  phOsalNfc_Config_t tOsalConfig;
+  phTmlNfc_Config_t tTmlConfig;
+  static phLibNfc_Message_t msg;
+  int init_retry_cnt = 0;
+  /*NCI_RESET_CMD*/
+  uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x01};
+  /*NCI_INIT_CMD*/
+  uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
+  uint8_t boot_mode = nxpncihal_ctrl.hal_boot_mode;
+  char* nfc_dev_node = NULL;
+  const uint16_t max_len = 260;
+
+  phNxpLog_InitializeLogLevel();
+
+  /*Create the timer for extns write response*/
+  timeoutTimerId = phOsalNfc_Timer_Create();
+  if (timeoutTimerId == PH_OSALNFC_TIMER_ID_INVALID) {
+    NXPLOG_NCIHAL_E("Invalid Timer Id, Timer Creation failed");
+    return NFCSTATUS_FAILED;
+  }
+
+  if (phNxpNciHal_init_monitor() == NULL) {
+    NXPLOG_NCIHAL_E("Init monitor failed");
+    phOsalNfc_Timer_Delete(timeoutTimerId);
+    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 */
+  nxpncihal_ctrl.hal_boot_mode = boot_mode;
+
+  /*Get the device node name from config file*/
+  /* Read the nfc device node name */
+  nfc_dev_node = (char*)nxp_malloc(max_len * sizeof(char));
+  if (nfc_dev_node == NULL) {
+    NXPLOG_NCIHAL_E("malloc of nfc_dev_node failed ");
+
+    CONCURRENCY_UNLOCK();
+
+    return NFCSTATUS_FAILED;
+  } else if (!GetNxpStrValue(NAME_NXP_NFC_DEV_NODE, nfc_dev_node,
+                             max_len * sizeof(uint8_t))) {
+    NXPLOG_NCIHAL_E(
+        "Invalid nfc device node name keeping the default device node "
+        "/dev/nq-nci");
+    strlcpy(nfc_dev_node, "/dev/nq-nci", max_len);
+  }
+
+  tTmlConfig.pDevName = (int8_t*)nfc_dev_node;
+
+  tOsalConfig.dwCallbackThreadId = (uintptr_t)nxpncihal_ctrl.gDrvCfg.nClientId;
+  tOsalConfig.pLogFile = NULL;
+  tTmlConfig.dwGetMsgThreadId = (uintptr_t)nxpncihal_ctrl.gDrvCfg.nClientId;
+
+  /* Initialize TML layer */
+  status = phTmlNfc_Init(&tTmlConfig);
+  if (status == NFCSTATUS_SUCCESS) {
+    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) == 0x00) {
+      status = phTmlNfc_Read(
+          nxpncihal_ctrl.p_cmd_data, NCI_MAX_DATA_LEN,
+          (pphTmlNfc_TransactCompletionCb_t)&phNxpNciHal_read_complete, NULL);
+      if (status == NFCSTATUS_PENDING) {
+        phNxpNciHal_ext_init();
+        do {
+          status = phNxpNciHal_SendCmd(sizeof(cmd_reset_nci), cmd_reset_nci);
+          if (status == NFCSTATUS_SUCCESS) {
+            status = phNxpNciHal_SendCmd(sizeof(cmd_init_nci), cmd_init_nci);
+          }
+          if (status != NFCSTATUS_SUCCESS) {
+            (void)phNxpNciHal_power_cycle();
+          } else {
+            break;
+          }
+          init_retry_cnt++;
+        } while (init_retry_cnt < 0x03);
+      }
+    }
+  }
+  CONCURRENCY_UNLOCK();
+  init_retry_cnt = 0;
+  if (status == NFCSTATUS_SUCCESS) {
+    /* print message*/
+    phNxpNciHal_core_MinInitialized_complete(status);
+  } else {
+    phTmlNfc_Shutdown();
+    (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_POST_MIN_INIT_CPLT_EVT,
+                                        HAL_NFC_STATUS_FAILED);
+    /* Report error status */
+    nxpncihal_ctrl.p_nfc_stack_cback = NULL;
+    nxpncihal_ctrl.p_nfc_stack_data_cback = NULL;
+    phNxpNciHal_cleanup_monitor();
+    nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;
+  }
+  if (nfc_dev_node != NULL) {
+    free(nfc_dev_node);
+    nfc_dev_node = NULL;
+  }
+  return status;
+}
+
+static NFCSTATUS phNxpNciHal_SendCmd(uint8_t cmd_len, uint8_t* pcmd_buff) {
+  int counter = 0x00;
+  NFCSTATUS status;
+  do {
+    status = NFCSTATUS_FAILED;
+    status = phNxpNciHal_send_ext_cmd(cmd_len, pcmd_buff);
+    counter++;
+  } while (counter < 0x03 && status != NFCSTATUS_SUCCESS);
+  return status;
+}
+/******************************************************************************
+ * 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) {
+  NFCSTATUS wConfigStatus = NFCSTATUS_SUCCESS;
+  NFCSTATUS status = NFCSTATUS_SUCCESS;
+  uint8_t boot_mode = nxpncihal_ctrl.hal_boot_mode;
+  uint8_t* nfc_dev_node = NULL;
+  uint8_t ret_val = 0x00;
+  const uint16_t max_len =
+      260; /* device node name is max of 255 bytes + 5 bytes (/dev/) */
+  static uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
+  static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00};
+  /*NCI2_0_INIT_CMD*/
+  static uint8_t cmd_init_nci2_0[] = {0x20,0x01,0x02,0x00,0x00};
+  phTmlNfc_Config_t tTmlConfig;
+  phOsalNfc_Config_t tOsalConfig;
+  int init_retry_cnt = 0;
+
+  if (nxpncihal_ctrl.hal_boot_mode == NFC_FAST_BOOT_MODE) {
+    NXPLOG_NCIHAL_E(" HAL NFC fast init mode calling min_open %d",
+                    nxpncihal_ctrl.hal_boot_mode);
+    wConfigStatus = phNxpNciHal_MinOpen(p_cback, p_data_cback);
+    return wConfigStatus;
+  }
+
+  if (nxpncihal_ctrl.halStatus == HAL_STATUS_OPEN) {
+    NXPLOG_NCIHAL_E("phNxpNciHal_open already open");
+    return NFCSTATUS_SUCCESS;
+  }
+  /* reset config cache */
+  resetNxpConfig();
+  phNxpLog_InitializeLogLevel();
+
+  /*Create the timer for extns write response*/
+  timeoutTimerId = phOsalNfc_Timer_Create();
+  if (timeoutTimerId == PH_OSALNFC_TIMER_ID_INVALID) {
+    NXPLOG_NCIHAL_E("Invalid Timer Id, Timer Creation failed");
+    return NFCSTATUS_FAILED;
+  }
+
+  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.is_wait_for_ce_ntf = false;
+  nxpncihal_ctrl.p_nfc_stack_cback = p_cback;
+  nxpncihal_ctrl.p_nfc_stack_data_cback = p_data_cback;
+  nxpncihal_ctrl.hal_boot_mode = boot_mode;
+
+  /*nci version NCI_VERSION_UNKNOWN version by default*/
+  nxpncihal_ctrl.nci_info.nci_version = NCI_VERSION_UNKNOWN;
+
+  /*Structure related to set config management*/
+  mGetCfg_info = NULL;
+  mGetCfg_info = nxp_malloc(sizeof(phNxpNci_getCfg_info_t));
+  if (mGetCfg_info == NULL) {
+    goto clean_and_return;
+  }
+  memset(mGetCfg_info, 0x00, sizeof(phNxpNci_getCfg_info_t));
+
+  /*Read the nfc device node name*/
+  nfc_dev_node = (uint8_t*)nxp_malloc(max_len * sizeof(uint8_t));
+  if (nfc_dev_node == NULL) {
+    NXPLOG_NCIHAL_E("malloc of nfc_dev_node failed ");
+    goto clean_and_return;
+  } else if (!GetNxpStrValue(NAME_NXP_NFC_DEV_NODE, (char*)nfc_dev_node,
+                             max_len)) {
+    NXPLOG_NCIHAL_E(
+        "Invalid nfc device node name keeping the default device node "
+        "/dev/nq-nci");
+    strlcpy((char*)nfc_dev_node, "/dev/nq-nci", max_len);
+  }
+  /* 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*)nfc_dev_node;
+  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;
+  } else {
+    if (nfc_dev_node != NULL) {
+      free(nfc_dev_node);
+      nfc_dev_node = NULL;
+    }
+  }
+  /* Create the client thread */
+  pthread_attr_t attr;
+  pthread_attr_init(&attr);
+  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+  ret_val = pthread_create(&nxpncihal_ctrl.client_thread, &attr,
+                           phNxpNciHal_client_thread, &nxpncihal_ctrl);
+  pthread_attr_destroy(&attr);
+  if (ret_val != 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("NFCC not coming out from Standby");
+      NXPLOG_NCIHAL_E("Trying Force FW download");
+      goto force_download;
+      wConfigStatus = NFCSTATUS_FAILED;
+    } 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;
+    }
+    if(nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) {
+        status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), cmd_init_nci2_0);
+    } else {
+        status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci), cmd_init_nci);
+        if(status == NFCSTATUS_SUCCESS && (nfcFL.chipType == pn557)) {
+            NXPLOG_NCIHAL_E("Chip is in NCI1.0 mode reset the chip to 2.0 mode");
+            status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
+            if(status == NFCSTATUS_SUCCESS) {
+                status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), cmd_init_nci2_0);
+                if(status == NFCSTATUS_SUCCESS) {
+                    goto init_retry;
+                }
+            }
+        }
+    }
+
+    if (status != NFCSTATUS_SUCCESS) {
+      NXPLOG_NCIHAL_E("COMMAND 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;
+    }
+  /* Call open complete */
+  phNxpNciHal_open_complete(wConfigStatus);
+
+  return wConfigStatus;
+
+force_download:
+  wFwVerRsp = 0;
+  phNxpNciHal_FwDwnld(NFC_STATUS_NOT_INITIALIZED);
+  goto init_retry;
+
+clean_and_return:
+  CONCURRENCY_UNLOCK();
+  if (nfc_dev_node != NULL) {
+    free(nfc_dev_node);
+    nfc_dev_node = NULL;
+  }
+  if (mGetCfg_info != NULL) {
+    free(mGetCfg_info);
+    mGetCfg_info = NULL;
+  }
+  /* 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_fw_mw_check
+ *
+ * Description      This function inform the status of phNxpNciHal_fw_mw_check
+ *                  function to libnfc-nci.
+ *
+ * Returns          int.
+ *
+ ******************************************************************************/
+int phNxpNciHal_fw_mw_ver_check() {
+    NFCSTATUS status = NFCSTATUS_FAILED;
+
+    if (((nfcFL.chipType == pn553)||(nfcFL.chipType == pn80T)) &&
+            (rom_version == 0x11) && (fw_maj_ver == 0x01)) {
+        status = NFCSTATUS_SUCCESS;
+    } else if (((nfcFL.chipType == pn551)||(nfcFL.chipType == pn67T)) &&
+            (rom_version == 0x10) && (fw_maj_ver == 0x05)) {
+        status = NFCSTATUS_SUCCESS;
+    } else if (((nfcFL.chipType == pn548C2)||(nfcFL.chipType == pn66T)) &&
+            (rom_version == 0x10) && (fw_maj_ver == 0x01)) {
+        status = NFCSTATUS_SUCCESS;
+    } else if (((nfcFL.chipType == pn547C2)||(nfcFL.chipType == pn65T)) &&
+            (rom_version == 0x08) && (fw_maj_ver == 0x01)) {
+        status = NFCSTATUS_SUCCESS;
+    }
+    return status;
+}
+/******************************************************************************
+ * 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;
+
+  CONCURRENCY_LOCK();
+
+  if (nxpncihal_ctrl.halStatus != HAL_STATUS_OPEN) {
+    return NFCSTATUS_FAILED;
+  }
+
+  /* Create local copy of cmd_data */
+  memcpy(nxpncihal_ctrl.p_cmd_data, p_data, data_len);
+  nxpncihal_ctrl.cmd_len = data_len;
+  if (nxpncihal_ctrl.cmd_len > NCI_MAX_DATA_LEN) {
+    NXPLOG_NCIHAL_D("cmd_len exceeds limit NCI_MAX_DATA_LEN");
+    goto clean_and_return;
+  }
+#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
+
+  /* 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;
+  }
+
+  data_len = phNxpNciHal_write_unlocked(nxpncihal_ctrl.cmd_len,
+                                        nxpncihal_ctrl.p_cmd_data);
+
+  if (icode_send_eof == 1) {
+    usleep(10000);
+    icode_send_eof = 2;
+    phNxpNciHal_send_ext_cmd(3, cmd_icode_eof);
+  }
+
+clean_and_return:
+  CONCURRENCY_UNLOCK();
+  /* 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");
+      if(nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT) {
+          /* 5ms delay to give NFCC wake up delay */
+          usleep(5000);
+      } else {
+          /* 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.hal_open_status == true) {
+        if (nxpncihal_ctrl.p_rx_data != NULL) {
+          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);
+        } else {
+          (*nxpncihal_ctrl.p_nfc_stack_data_cback)(0x00, NULL);
+        }
+        write_unlocked_status = NFCSTATUS_FAILED;
+      }
+    }
+  } else {
+    write_unlocked_status = NFCSTATUS_SUCCESS;
+  }
+
+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 (nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT &&
+          (pInfo->wStatus == NFCSTATUS_READ_FAILED)) {
+      if (nxpncihal_ctrl.p_nfc_stack_cback != NULL) {
+          read_failed_disable_nfc = true;
+          /* Send the event */
+          (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_ERROR_EVT,
+                  HAL_NFC_STATUS_ERR_CMD_TIMEOUT);
+      }
+      return;
+  }
+
+  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);
+#if (NXP_NFCC_FORCE_NCI1_0_INIT == true)
+    /* Notification Checking */
+    if (nfcFL.nfccFL._NFCC_FORCE_NCI1_0_INIT && ((nxpncihal_ctrl.hal_ext_enabled == 1) &&
+        (nxpncihal_ctrl.p_rx_data[0x00] == 0x60) &&
+        (nxpncihal_ctrl.p_rx_data[0x03] == 0x02))) {
+      nxpncihal_ctrl.ext_cb_data.status = NFCSTATUS_SUCCESS;
+      SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
+    } else
+#endif
+        /* Check if response should go to hal module only */
+        if (nxpncihal_ctrl.hal_ext_enabled == 1 &&
+            ((nxpncihal_ctrl.p_rx_data[0x00] & 0xF0) == 0x40 ||
+             ((icode_detected == true) && (icode_send_eof == 3)))) {
+      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));
+    }
+     //Notification Checking
+    else if((nxpncihal_ctrl.hal_ext_enabled == TRUE)    &&
+            ((nxpncihal_ctrl.p_rx_data[0x00]  & NCI_MT_MASK) == NCI_MT_NTF) &&
+            (nxpncihal_ctrl.nci_info.wait_for_ntf == TRUE)) {
+        /* Unlock semaphore waiting for only  ntf*/
+      SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
+      nxpncihal_ctrl.nci_info.wait_for_ntf = FALSE;
+    }
+    /* 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 &&
+    nxpncihal_ctrl.nci_info.wait_for_ntf == FALSE) {
+    NXPLOG_NCIHAL_E(" Ignoring read , HAL close triggered");
+    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_check_delete_nfaStorage_DHArea
+**
+** Description      check the file and delete if present.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void phNxpNciHal_check_delete_nfaStorage_DHArea() {
+  struct stat st;
+  int ret = 0;
+  const char config_eseinfo_path[] = "/data/nfc/nfaStorage.bin1";
+  if (stat(config_eseinfo_path, &st) == -1) {
+    ALOGD("%s: file not found %s", __func__, config_eseinfo_path);
+  } else {
+    ALOGD("%s: file found %s, delete it", __func__, config_eseinfo_path);
+    ret = remove(config_eseinfo_path);
+    if(ret!=0)
+      ALOGE("%s: error deleting file %s", __func__, config_eseinfo_path);
+  }
+}
+
+/******************************************************************************
+ * 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;
+  uint8_t* buffer = NULL;
+  uint8_t isfound = false;
+#ifdef FW_DWNLD_FLAG
+  uint8_t fw_dwnld_flag = false;
+#endif
+  uint8_t setConfigAlways = false;
+  static uint8_t retry_core_init_cnt = 0;
+  static uint8_t p2p_listen_mode_routing_cmd[] = {0x21, 0x01, 0x07, 0x00, 0x01,
+                                                  0x01, 0x03, 0x00, 0x01, 0x05};
+  static uint8_t swp_full_pwr_mode_on_cmd[] = {0x20, 0x02, 0x05, 0x01,
+                                               0xA0, 0xF1, 0x01, 0x01};
+  static uint8_t swp_switch_timeout_cmd[] = {0x20, 0x02, 0x06, 0x01, 0xA0,
+                                             0xF3, 0x02, 0x00, 0x00};
+  static uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
+  static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00};
+  static uint8_t cmd_init_nci2_0[] = {0x20,0x01,0x02,0x00,0x00};
+  config_success = true;
+  long bufflen = 260;
+  long retlen = 0;
+  unsigned long num = 0;
+  static uint8_t  init_param;
+  init_param = *p_core_init_rsp_params;
+  phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
+  static uint8_t android_l_aid_matching_mode_on_cmd[] = {
+      0x20, 0x02, 0x05, 0x01, 0xA0, 0x91, 0x01, 0x01};
+  /*initialize dummy FW recovery variables*/
+  if(nfcFL.chipType != pn547C2) {
+      gRecFwRetryCount = 0;
+      gRecFWDwnld = false;
+  }
+  if (nxpncihal_ctrl.halStatus != HAL_STATUS_OPEN) {
+    return NFCSTATUS_FAILED;
+  }
+
+  NXPLOG_NCIHAL_D("phNxpNciHal_core_initialized::p_core_init_rsp_params : %d", *p_core_init_rsp_params);
+
+  /*MW recovery -- begins*/
+  if ((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4)) {
+  retry_core_init:
+    *p_core_init_rsp_params = init_param;
+    config_access = false;
+    if (mGetCfg_info != NULL) {
+      mGetCfg_info->isGetcfg = false;
+    }
+    if (buffer != NULL) {
+      free(buffer);
+      buffer = NULL;
+    }
+    if (retry_core_init_cnt > 3) {
+        if (nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT &&
+                (nxpncihal_ctrl.p_nfc_stack_cback != NULL)) {
+            NXPLOG_NCIHAL_D("Posting Core Init Failed\n");
+            read_failed_disable_nfc = true;
+            (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_ERROR_EVT,
+                    HAL_NFC_STATUS_ERR_CMD_TIMEOUT);
+        }
+        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");
+    }
+
+    if(nfcFL.nfccFL._NFCC_FORCE_NCI1_0_INIT) {
+        status = phNxpNciHal_send_ext_cmd_ntf(sizeof(cmd_reset_nci), cmd_reset_nci);
+    }
+    else {
+        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(
+          "NFCC not coming out from Standby Max retry count reached");
+      NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+    } else if (status != NFCSTATUS_SUCCESS) {
+      NXPLOG_NCIHAL_E("NCI_CORE_RESET: Failed");
+      NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+    }
+
+    if (*p_core_init_rsp_params == 2) {
+      NXPLOG_NCIHAL_E(" Last command is CORE_RESET!!");
+      goto invoke_callback;
+    }
+
+    if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) {
+      status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), cmd_init_nci2_0);
+    } else {
+      status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci), cmd_init_nci);
+    }
+    if (status != NFCSTATUS_SUCCESS) {
+      NXPLOG_NCIHAL_E("NCI_CORE_INIT : Failed");
+      NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+    }
+
+    if (*p_core_init_rsp_params == 3) {
+      NXPLOG_NCIHAL_E(" Last command is CORE_INIT!!");
+      goto invoke_callback;
+    }
+  }
+
+  /*MW recovery --ended*/
+
+  buffer = (uint8_t*)nxp_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");
+      NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+    }
+  }
+
+  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");
+      NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+    }
+  }
+
+  if(nfcFL.eseFL._ESE_SVDD_SYNC) {
+      if (GetNxpNumValue(NAME_NXP_SVDD_SYNC_OFF_DELAY, (void*)&gSvddSyncOff_Delay,
+              sizeof(gSvddSyncOff_Delay))) {
+          if (gSvddSyncOff_Delay > 20) gSvddSyncOff_Delay = 10;
+          NXPLOG_NCIHAL_E("NAME_NXP_SVDD_SYNC_OFF_DELAY success value = %d",
+                  gSvddSyncOff_Delay);
+      } else {
+          NXPLOG_NCIHAL_E("NAME_NXP_SVDD_SYNC_OFF_DELAY failed");
+          gSvddSyncOff_Delay = 10;
+      }
+  }
+  config_access = false;
+  if(nfcFL.eseFL._EXCLUDE_NV_MEM_DEPENDENCY == false) {
+  phNxpNciHal_check_factory_reset();
+  }
+
+#ifdef FW_DWNLD_FLAG
+  mEEPROM_info.buffer = &fw_dwnld_flag;
+  mEEPROM_info.bufflen = sizeof(fw_dwnld_flag);
+  mEEPROM_info.request_type = EEPROM_FW_DWNLD;
+  mEEPROM_info.request_mode = GET_EEPROM_DATA;
+  request_EEPROM(&mEEPROM_info);
+#endif
+
+
+  if((nfcFL.chipType != pn547C2) && nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT_PROP) {
+      if (isNxpConfigModified() || (fw_dwnld_flag == 0x01)) {
+          uint8_t value;
+          retlen = 0;
+          if (GetNxpNumValue(NAME_NXP_PROP_BLACKLIST_ROUTING,
+                  (void*)&retlen, sizeof(retlen))) {
+              if (retlen == 0x00 || retlen == 0x01) {
+                  value = (uint8_t)retlen;
+                  mEEPROM_info.buffer = &value;
+                  mEEPROM_info.bufflen = sizeof(value);
+                  mEEPROM_info.request_type = EEPROM_PROP_ROUTING;
+                  mEEPROM_info.request_mode = SET_EEPROM_DATA;
+                  status = request_EEPROM(&mEEPROM_info);
+              }
+          }
+      }
+}
+
+  if((nfcFL.chipType != pn547C2) && (nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME ==
+          nfcFL.eseFL._ESE_WIRED_MODE_RESUME)) {
+      uint8_t resume_timeout_buf[NXP_WIREDMODE_RESUME_TIMEOUT_LEN];
+      mEEPROM_info.request_mode = GET_EEPROM_DATA;
+      NXPLOG_NCIHAL_D("Timeout value");
+      if (isNxpConfigModified() || (fw_dwnld_flag == 0x01)) {
+          NXPLOG_NCIHAL_D("Timeout value - 1");
+          if (GetNxpByteArrayValue(NAME_NXP_WIREDMODE_RESUME_TIMEOUT, (char*)buffer,
+                  bufflen, &retlen)) {
+              NXPLOG_NCIHAL_D("Time out value %x %x %x %x retlen=%ld", buffer[0],
+                      buffer[1], buffer[2], buffer[3], retlen);
+              if (retlen >= NXP_WIREDMODE_RESUME_TIMEOUT_LEN) {
+                  memcpy(&resume_timeout_buf, buffer, NXP_STAG_TIMEOUT_BUF_LEN);
+                  mEEPROM_info.request_mode = SET_EEPROM_DATA;
+              }
+          }
+      }
+      mEEPROM_info.buffer = resume_timeout_buf;
+      mEEPROM_info.bufflen = sizeof(resume_timeout_buf);
+      mEEPROM_info.request_type = EEPROM_WIREDMODE_RESUME_TIMEOUT;
+      request_EEPROM(&mEEPROM_info);
+  }
+
+#if (NXP_EXTNS == TRUE)
+  if(nfcFL.eseFL._ESE_POWER_MODE)
+  {
+    uint8_t value;
+    retlen = 0;
+    if (GetNxpNumValue(NAME_NXP_ESE_POWER_DH_CONTROL, (void*)&retlen,
+                       sizeof(retlen))) {
+      if (retlen == 0x01 || retlen == 0x02) {
+        value = (uint8_t)retlen;
+        if (value == 2) value = 0;
+        mEEPROM_info.buffer = &value;
+        mEEPROM_info.bufflen = sizeof(value);
+        mEEPROM_info.request_type = EEPROM_ESE_SVDD_POWER;
+        mEEPROM_info.request_mode = SET_EEPROM_DATA;
+
+        if (isNxpConfigModified() || (fw_dwnld_flag == 0x01))
+          status = request_EEPROM(&mEEPROM_info);
+      }
+      if (retlen == 0x01) {
+        retlen = 0;
+        value = 0x40;
+        mEEPROM_info.buffer = &value;
+        mEEPROM_info.bufflen = sizeof(value);
+        mEEPROM_info.request_type = EEPROM_ESE_POWER_EXT_PMU;
+        mEEPROM_info.request_mode = SET_EEPROM_DATA;
+        phTmlNfc_IoCtl(phTmlNfc_e_SetLegacyPowerScheme);
+
+        if (isNxpConfigModified() || (fw_dwnld_flag == 0x01))
+          status = request_EEPROM(&mEEPROM_info);
+      } else if (retlen == 0x02) {
+        retlen = 0;
+        value = 0;
+        if (GetNxpNumValue(NAME_NXP_ESE_POWER_EXT_PMU, (void*)&retlen,
+                           sizeof(retlen))) {
+          if (retlen == 0x01 || retlen == 0x02) {
+            value = (uint8_t)retlen;
+            if (value == 1) {
+              value = 0x50;
+            } else {
+              value = 0x48;
+            }
+            phTmlNfc_IoCtl(phTmlNfc_e_SetExtPMUPowerScheme);
+            mEEPROM_info.buffer = &value;
+            mEEPROM_info.bufflen = sizeof(value);
+            mEEPROM_info.request_type = EEPROM_ESE_POWER_EXT_PMU;
+            mEEPROM_info.request_mode = SET_EEPROM_DATA;
+            if (isNxpConfigModified() || (fw_dwnld_flag == 0x01))
+              status = request_EEPROM(&mEEPROM_info);
+          }
+        }
+      }
+    }
+  }
+#endif
+  setConfigAlways = false;
+  isfound = GetNxpNumValue(NAME_NXP_SET_CONFIG_ALWAYS, &num, sizeof(num));
+  if (isfound > 0) {
+    setConfigAlways = num;
+  }
+  NXPLOG_NCIHAL_D("EEPROM_fw_dwnld_flag : 0x%02x SetConfigAlways flag : 0x%02x",
+                  fw_dwnld_flag, setConfigAlways);
+
+  if (fw_dwnld_flag == 0x01) {
+    phNxpNciHal_check_delete_nfaStorage_DHArea();
+  }
+
+  if ((true == fw_dwnld_flag) || (true == setConfigAlways) ||
+      isNxpRFConfigModified() || isNxpConfigModified()) {
+    config_access = true;
+    retlen = 0;
+    if (phNxpNciHal_nfccClockCfgApply() != NFCSTATUS_SUCCESS) {
+        NXPLOG_NCIHAL_E("phNxpNciHal_nfccClockCfgApply failed");
+        NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+    }
+
+  if (config_success == false) return NFCSTATUS_FAILED;
+#ifdef PN547C2_CLOCK_SETTING
+#if (NFC_NXP_HFO_SETTINGS == TRUE)
+    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");
+        NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+    }
+    /* reset the NFCC after applying the clock setting and DPLL setting */
+    //phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
+    goto retry_core_init;
+  }
+#endif
+#endif
+
+    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");
+        NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+      }
+    }
+
+    retlen = 0;
+    if(nfcFL.chipType != pn547C2) {
+        NXPLOG_NCIHAL_D("Performing TVDD Settings");
+        /*TVDD settings commented for PN553 bringup FW  */
+        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");
+                        NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, 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");
+                        NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, 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");
+                        NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+                    }
+                }
+            } else {
+                NXPLOG_NCIHAL_E("Wrong Configuration Value %ld", num);
+            }
+        }
+}
+
+    retlen = 0;
+
+    if(nfcFL.chipType != pn547C2) {
+        config_access = false;
+    }
+    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 ((nfcFL.chipType != pn547C2) && (status == NFCSTATUS_SUCCESS)) {
+          status = phNxpNciHal_CheckRFCmdRespStatus();
+          /*STATUS INVALID PARAM 0x09*/
+          if (status == 0x09) {
+              phNxpNciHalRFConfigCmdRecSequence();
+              NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+          }
+      } else if (status != NFCSTATUS_SUCCESS) {
+          NXPLOG_NCIHAL_E("RF Settings BLK 1 failed");
+          NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, 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 ((nfcFL.chipType != pn547C2) && (status == NFCSTATUS_SUCCESS)) {
+          status = phNxpNciHal_CheckRFCmdRespStatus();
+          /*STATUS INVALID PARAM 0x09*/
+          if (status == 0x09) {
+              phNxpNciHalRFConfigCmdRecSequence();
+              NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+          }
+      } else if (status != NFCSTATUS_SUCCESS) {
+        NXPLOG_NCIHAL_E("RF Settings BLK 2 failed");
+        NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, 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 ((nfcFL.chipType != pn547C2) && (status == NFCSTATUS_SUCCESS)) {
+          status = phNxpNciHal_CheckRFCmdRespStatus();
+          /*STATUS INVALID PARAM 0x09*/
+          if (status == 0x09) {
+              phNxpNciHalRFConfigCmdRecSequence();
+              NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+          }
+      } else if (status != NFCSTATUS_SUCCESS) {
+          NXPLOG_NCIHAL_E("RF Settings BLK 3 failed");
+          NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, 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 ((nfcFL.chipType != pn547C2) && (status == NFCSTATUS_SUCCESS)) {
+          status = phNxpNciHal_CheckRFCmdRespStatus();
+          /*STATUS INVALID PARAM 0x09*/
+          if (status == 0x09) {
+              phNxpNciHalRFConfigCmdRecSequence();
+              NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+          }
+      } else if (status != NFCSTATUS_SUCCESS) {
+          NXPLOG_NCIHAL_E("RF Settings BLK 4 failed");
+          NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, 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 ((nfcFL.chipType != pn547C2) && (status == NFCSTATUS_SUCCESS)) {
+          status = phNxpNciHal_CheckRFCmdRespStatus();
+          /*STATUS INVALID PARAM 0x09*/
+          if (status == 0x09) {
+              phNxpNciHalRFConfigCmdRecSequence();
+              NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+          }
+      } else if (status != NFCSTATUS_SUCCESS) {
+          NXPLOG_NCIHAL_E("RF Settings BLK 5 failed");
+          NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, 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 ((nfcFL.chipType != pn547C2) && (status == NFCSTATUS_SUCCESS)) {
+          status = phNxpNciHal_CheckRFCmdRespStatus();
+          /*STATUS INVALID PARAM 0x09*/
+          if (status == 0x09) {
+              phNxpNciHalRFConfigCmdRecSequence();
+              NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+          }
+      } else if (status != NFCSTATUS_SUCCESS) {
+          NXPLOG_NCIHAL_E("RF Settings BLK 6 failed");
+          NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+      }
+    }
+    retlen = 0;
+    if (nfcFL.chipType != pn547C2) {
+        config_access = true;
+    }
+
+    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");
+        NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+      }
+    }
+
+    if(nfcFL.eseFL._ESE_ETSI12_PROP_INIT) {
+        uint8_t swp_info_buff[2];
+        uint8_t swp_intf_status = 0x00;
+        uint8_t swp1A_intf_status = 0x00;
+        NFCSTATUS status = NFCSTATUS_FAILED;
+        phNxpNci_EEPROM_info_t swp_intf_info;
+
+        memset(swp_info_buff, 0, sizeof(swp_info_buff));
+        /*Read SWP1 data*/
+        memset(&swp_intf_info, 0, sizeof(swp_intf_info));
+        swp_intf_info.request_mode = GET_EEPROM_DATA;
+        swp_intf_info.request_type = EEPROM_SWP1_INTF;
+        swp_intf_info.buffer = &swp_intf_status;
+        swp_intf_info.bufflen = sizeof(uint8_t);
+        status = request_EEPROM(&swp_intf_info);
+        if (status == NFCSTATUS_OK)
+            swp_info_buff[0] = swp_intf_status;
+        else {
+            NXPLOG_NCIHAL_E("request_EEPROM error occured %d", status);
+            NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+        }
+        if ((nfcFL.chipType == pn551) || (nfcFL.chipType == pn553) || (nfcFL.chipType == pn557)) {
+            /*Read SWP1A data*/
+            memset(&swp_intf_info, 0, sizeof(swp_intf_info));
+            swp_intf_info.request_mode = GET_EEPROM_DATA;
+            swp_intf_info.request_type = EEPROM_SWP1A_INTF;
+            swp_intf_info.buffer = &swp1A_intf_status;
+            swp_intf_info.bufflen = sizeof(uint8_t);
+            status = request_EEPROM(&swp_intf_info);
+            if (status == NFCSTATUS_OK)
+                swp_info_buff[1] = swp1A_intf_status;
+            else {
+                NXPLOG_NCIHAL_E("request_EEPROM error occured %d", status);
+                NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+            }
+        }
+        phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
+        mEEPROM_info.buffer = swp_info_buff;
+        mEEPROM_info.bufflen= sizeof(swp_info_buff);
+        mEEPROM_info.request_type = EEPROM_RF_CFG;
+        mEEPROM_info.request_mode = SET_EEPROM_DATA;
+        status = request_EEPROM(&mEEPROM_info);
+        NXPLOG_NCIHAL_D("Setting value %d %d", swp_info_buff[1], swp_info_buff[0]);
+    }  // END_OF_NFC_NXP_ESE_ETSI12_PROP_INIT
+
+    NXPLOG_NCIHAL_D("Performing NAME_NXP_CORE_CONF Settings");
+    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");
+        NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, 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");
+        NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+      }
+    }
+
+    retlen = 0;
+    if (nfcFL.chipType != pn547C2) {
+        config_access = false;
+    }
+    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 ((nfcFL.chipType != pn547C2) && (status == NFCSTATUS_SUCCESS)) {
+            status = phNxpNciHal_CheckRFCmdRespStatus();
+            /*STATUS INVALID PARAM 0x09*/
+            if (status == 0x09) {
+                phNxpNciHalRFConfigCmdRecSequence();
+                NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+            }
+        } else if (status != NFCSTATUS_SUCCESS) {
+            NXPLOG_NCIHAL_E("Setting NXP_CORE_RF_FIELD status failed");
+            NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+        }
+    }
+    if (nfcFL.chipType != pn547C2) {
+        config_access = true;
+    }
+    num = 0;
+
+    if (nfcFL.chipType != pn547C2) {
+        /* NXP SWP switch timeout Setting*/
+        if (GetNxpNumValue(NAME_NXP_SWP_SWITCH_TIMEOUT, (void*)&num, sizeof(num))) {
+            // Check the permissible range [0 - 60]
+            if (num <= 60) {
+                if (0 < num) {
+                    uint16_t timeout = num * 1000;
+                    unsigned int timeoutHx = 0x0000;
+
+                    uint8_t tmpbuffer[10];
+                    snprintf((char*)tmpbuffer, 10, "%04x", timeout);
+                    sscanf((const char*)tmpbuffer, "%x", (unsigned int*)&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");
+                    NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+                }
+            } else {
+                NXPLOG_NCIHAL_E("SWP switch timeout Setting Failed - out of range!");
+            }
+        }
+    }
+    if (nfcFL.chipType != pn547C2) {
+        status = phNxpNciHal_set_china_region_configs();
+        if (status != NFCSTATUS_SUCCESS) {
+            NXPLOG_NCIHAL_E("phNxpNciHal_set_china_region_configs failed");
+            NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+        }
+    }
+
+    if (nfcFL.chipType == pn547C2) {
+        status = phNxpNciHal_uicc_baud_rate();
+        if (status != NFCSTATUS_SUCCESS) {
+            NXPLOG_NCIHAL_E("Setting NXP_CORE_RF_FIELD status failed");
+            NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+        }
+    }
+
+    config_access = false;
+    // if recovery mode and length of last command is 0 then only reset the P2P
+    // listen mode routing.
+    if ((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4) &&
+            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");
+        NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+      }
+    }
+
+    num = 0;
+
+    /* SWP FULL PWR MODE SETTING ON */
+    if (GetNxpNumValue(NAME_NXP_SWP_FULL_PWR_ON, (void*)&num, sizeof(num))) {
+      if (1 == num) {
+        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");
+          NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, 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");
+          NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+        }
+      }
+    }
+    if(nfcFL.nfccFL._NFCC_AID_MATCHING_PLATFORM_CONFIG == true) {
+        num = 0;
+        /* Android L AID Matching Platform Setting*/
+        if (GetNxpNumValue(NAME_AID_MATCHING_PLATFORM, (void*)&num, sizeof(num))) {
+            if (1 == num) {
+                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");
+                    NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+                }
+            } else if (2 == num) {
+                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");
+                    NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+                }
+            }
+        }
+    }
+
+    NXPLOG_NCIHAL_E("Resetting FW Dnld flag");
+    fw_dwnld_flag = 0x00;
+
+#ifdef FW_DWNLD_FLAG
+    mEEPROM_info.buffer = &fw_dwnld_flag;
+    mEEPROM_info.bufflen = sizeof(fw_dwnld_flag);
+    mEEPROM_info.request_type = EEPROM_FW_DWNLD;
+    mEEPROM_info.request_mode = SET_EEPROM_DATA;
+    status = request_EEPROM(&mEEPROM_info);
+    if (status == NFCSTATUS_SUCCESS) {
+      NXPLOG_NCIHAL_E("Resetting FW Dnld flag SUCCESS");
+    } else {
+      NXPLOG_NCIHAL_E("Resetting FW Dnld flag FAILED");
+    }
+#endif
+  }
+
+  config_access = false;
+  if (!((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4))) {
+      if(nfcFL.nfcNxpEse == true) {
+          status = phNxpNciHal_check_eSE_Session_Identity();
+          if (status != NFCSTATUS_SUCCESS) {
+              NXPLOG_NCIHAL_E("Session id/ SWP intf reset Failed");
+              NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+          }
+      }
+    status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci), cmd_reset_nci);
+    if (status == NFCSTATUS_SUCCESS) {
+        if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) {
+          status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), cmd_init_nci2_0);
+        } else {
+          status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci), cmd_init_nci);
+        }
+        if (status != NFCSTATUS_SUCCESS)
+            return status;
+    } else {
+      return NFCSTATUS_FAILED;
+    }
+    status = phNxpNciHal_send_get_cfgs();
+    if (status == NFCSTATUS_SUCCESS) {
+      NXPLOG_NCIHAL_E("Send get Configs SUCCESS");
+    } else {
+      NXPLOG_NCIHAL_E("Send get Configs FAILED");
+    }
+  }
+
+  if(nfcFL.eseFL._WIRED_MODE_STANDBY == true) {
+      if (nxpncihal_ctrl.hal_boot_mode == NFC_OSU_BOOT_MODE) {
+          status = phNxpNciHal_send_nfcee_pwr_cntl_cmd(POWER_ALWAYS_ON);
+          if (status == NFCSTATUS_SUCCESS) {
+              NXPLOG_NCIHAL_E("Send nfcee_pwrcntl cmd SUCCESS");
+          } else {
+              NXPLOG_NCIHAL_E("Send nfcee_pwrcntl cmd FAILED");
+          }
+      }
+
+      if (pwr_link_required == true) {
+          phNxpNciHal_send_nfcee_pwr_cntl_cmd(POWER_ALWAYS_ON | LINK_ALWAYS_ON);
+          pwr_link_required = false;
+      }
+  }
+
+  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 set_screen_state_nci2[] = {0x20,0x09,0x01,0x00};
+    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};
+    if(nxpncihal_ctrl.nci_info.nci_version != NCI_VERSION_2_0)
+   {
+    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");
+      NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, 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");
+      NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+    }
+   }
+
+    // Set the proper screen state
+    switch (p_core_init_rsp_params[295]) {
+      case 0x0:
+      case 0x8:
+        NXPLOG_NCIHAL_E("Last Screen State Sent = 0x0");
+        set_screen_state[3] = 0x00;  // SCREEN ON UNLOCKED (listen and poll
+                                     // mode)
+        break;
+      case 0x2:
+        NXPLOG_NCIHAL_E("Last Screen State Sent = 0x1");
+        set_screen_state[3] = 0x01;  // SCREEN OFF LOCKED
+        set_screen_state_nci2[3] = 0x03;
+        break;
+      case 0x4:
+        NXPLOG_NCIHAL_E("Last Screen State Sent = 0x2");
+        set_screen_state[3] = 0x02;  // SCREEN ON LOCKED (only listen mode)
+        set_screen_state_nci2[3] = 0x02;
+        break;
+      case 1:
+        set_screen_state_nci2[3] = 0x01;
+        set_screen_state[3] = 0x02;  // SCREEN OFF UNLOCKED (only listen mode)
+        break;
+      default:
+        NXPLOG_NCIHAL_E("Setting default as SCREEN ON UNLOCKED");
+        set_screen_state[3] = 0x00;  // SCREEN ON UNLOCKED (listen and poll
+                                     // mode)
+        break;
+    }
+
+    if (*(p_core_init_rsp_params + 1) == 1)  // RF state is Discovery!!
+    {
+      NXPLOG_NCIHAL_E("Sending Set Screen ON State Command as raw packet!!");
+      if(nxpncihal_ctrl.nci_info.nci_version != NCI_VERSION_2_0)
+      {
+      status =
+          phNxpNciHal_send_ext_cmd(sizeof(set_screen_state), set_screen_state);
+      }else
+      {
+          status =
+              phNxpNciHal_send_ext_cmd(sizeof(set_screen_state_nci2), set_screen_state_nci2);
+      }
+      if (status != NFCSTATUS_SUCCESS) {
+        NXPLOG_NCIHAL_E(
+            "Sending Set Screen ON State Command as raw packet!! Failed");
+        NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, 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");
+        NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+      }
+    } else {
+      NXPLOG_NCIHAL_E("Sending Set Screen OFF State Command as raw packet!!");
+      if(nxpncihal_ctrl.nci_info.nci_version != NCI_VERSION_2_0)
+      {
+      status =
+          phNxpNciHal_send_ext_cmd(sizeof(set_screen_state), set_screen_state);
+      }else
+      {
+          status =
+              phNxpNciHal_send_ext_cmd(sizeof(set_screen_state_nci2), set_screen_state_nci2);
+      }
+      if (status != NFCSTATUS_SUCCESS) {
+        NXPLOG_NCIHAL_E(
+            "Sending Set Screen OFF State Command as raw packet!! Failed");
+        NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+        }
+      }
+
+    if (nxpprofile_ctrl.profile_type == EMV_CO_PROFILE) {
+      NXPLOG_NCIHAL_E(
+          "Current Profile : EMV_CO_PROFILE. Resetting to "
+          "NFC_FORUM_PROFILE...");
+      nxpprofile_ctrl.profile_type = NFC_FORUM_PROFILE;
+    }
+
+    NXPLOG_NCIHAL_E("Sending last command for Recovery ");
+
+    if (p_core_init_rsp_params[35] == 1) {
+      if (!((p_core_init_rsp_params[36] == 0x21) &&
+            (p_core_init_rsp_params[37] == 0x03) &&
+            (*(p_core_init_rsp_params + 1) == 0x01)) &&
+          !((p_core_init_rsp_params[36] == 0x21) &&
+            (p_core_init_rsp_params[37] == 0x06) &&
+            (p_core_init_rsp_params[39] == 0x00) &&
+            (*(p_core_init_rsp_params + 1) == 0x00)))
+      // if last command is discovery and RF status is also discovery state,
+      // then it doesn't need to execute or similarly
+      // if the last command is deactivate to idle and RF status is also idle ,
+      // no need to execute the command .
+      {
+          tmp_len = p_core_init_rsp_params[38] + 3; //Field 38 gives length of data + 3 - header and length field
+        /* 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) {
+          if (buffer) {
+            free(buffer);
+            buffer = NULL;
+          }
+          /* 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;
+        }
+
+        status = phNxpNciHal_send_ext_cmd(
+                tmp_len, (uint8_t*)&p_core_init_rsp_params[36]);
+        if (status != NFCSTATUS_SUCCESS) {
+          NXPLOG_NCIHAL_E("Sending last command for Recovery Failed");
+          NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
+        }
+      }
+    }
+  }
+
+  isfound = GetNxpNumValue(NAME_NXP_NCI_PARSER_LIBRARY, &num, sizeof(num));
+  if(isfound > 0 && num == 0x01)
+  {
+    phNxpNciHal_configNciParser();
+  }
+
+  retry_core_init_cnt = 0;
+
+  if (buffer) {
+    free(buffer);
+    buffer = NULL;
+  }
+  config_access = false;
+
+  if(nfcFL.chipType != pn547C2) {
+  // initialize dummy FW recovery variables
+  gRecFWDwnld = false;
+  gRecFwRetryCount = 0;
+}
+  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);
+    }
+  }
+  /* This code is moved to JNI
+  #ifdef PN547C2_CLOCK_SETTING
+      if (isNxpConfigModified())
+      {
+          updateNxpConfigTimestamp();
+      }
+  #endif*/
+  return NFCSTATUS_SUCCESS;
+}
+/******************************************************************************
+ * Function         phNxpNciHal_check_eSE_Session_Identity
+ *
+ * Description      This function is called at init time to check
+ *                  the presence of ese related info and disable SWP interfaces.
+ *
+ * Returns          void.
+ *
+ ******************************************************************************/
+static NFCSTATUS phNxpNciHal_check_eSE_Session_Identity(void) {
+  struct stat st;
+  int ret = 0;
+  NFCSTATUS status = NFCSTATUS_FAILED;
+  const char config_eseinfo_path[] = "/data/nfc/nfaStorage.bin1";
+  static uint8_t session_identity[8] = {0x00};
+  uint8_t default_session[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+  uint8_t swp2_intf_status = 0x00;
+  long retlen = 0;
+  static uint8_t disable_dual_swp_intf[] = {0x20, 0x02, 0x09, 0x02, 0xA0, 0xEC,
+                                       0x01, 0x00, 0xA0, 0xD4, 0x01, 0x00};
+  static uint8_t disable_swp_intf[] = {0x20, 0x02, 0x05, 0x01,
+                                       0xA0, 0xEC, 0x01, 0x00};
+
+  phNxpNci_EEPROM_info_t swp_intf_info;
+  uint8_t swp_info_buff[32] = {0};
+
+  memset(&swp_intf_info, 0, sizeof(swp_intf_info));
+  swp_intf_info.request_mode = GET_EEPROM_DATA;
+  swp_intf_info.request_type = EEPROM_SWP2_INTF;
+  swp_intf_info.buffer = &swp2_intf_status;
+  swp_intf_info.bufflen = sizeof(uint8_t);
+  status = request_EEPROM(&swp_intf_info);
+  NXPLOG_NCIHAL_D("%s swp2_intf_status = 0x%02X", __func__, swp2_intf_status);
+  if ((status == NFCSTATUS_OK) && (swp2_intf_status == 0x00)) {
+    pwr_link_required = false;
+    return NFCSTATUS_SUCCESS;
+  }
+
+  if (stat(config_eseinfo_path, &st) == -1) {
+    status = NFCSTATUS_FAILED;
+    NXPLOG_NCIHAL_D("%s file not present = %s", __func__, config_eseinfo_path);
+  } else {
+    phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
+    mEEPROM_info.request_mode = GET_EEPROM_DATA;
+    mEEPROM_info.request_type = EEPROM_ESE_SESSION_ID;
+    mEEPROM_info.buffer = session_identity;
+    mEEPROM_info.bufflen = sizeof(session_identity);
+    status = request_EEPROM(&mEEPROM_info);
+    if (status == NFCSTATUS_OK) {
+      if (!memcmp((uint8_t*)session_identity, (uint8_t*)default_session,
+                  sizeof(session_identity))) {
+        status = NFCSTATUS_FAILED;
+      } else {
+        status = NFCSTATUS_OK;
+      }
+    }
+  }
+
+  if (status == NFCSTATUS_FAILED) {
+    /*Disable SWP1 and 1A interfaces*/
+      if ((nfcFL.chipType == pn551) || (nfcFL.chipType == pn553) || (nfcFL.chipType == pn557)) {
+          status = phNxpNciHal_send_ext_cmd(sizeof(disable_dual_swp_intf),
+                  disable_dual_swp_intf);
+      }
+      else {
+          status = phNxpNciHal_send_ext_cmd(sizeof(disable_swp_intf),
+                  disable_swp_intf);
+      }
+    if (status != NFCSTATUS_SUCCESS) {
+      NXPLOG_NCIHAL_E("NXP disable SWP interface_set command failed");
+    }
+    pwr_link_required = true;
+  }
+  return status;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_CheckRFCmdRespStatus
+ *
+ * Description      This function is called to check the resp status of
+ *                  RF update commands.
+ *
+ * Returns          NFCSTATUS_SUCCESS           if successful,
+ *                  NFCSTATUS_INVALID_PARAMETER if parameter is inavlid
+ *                  NFCSTATUS_FAILED            if failed response
+ *
+ ******************************************************************************/
+NFCSTATUS phNxpNciHal_CheckRFCmdRespStatus() {
+    NXPLOG_NCIHAL_D("phNxpNciHal_CheckRFCmdRespStatus () Enter");
+    if(nfcFL.chipType == pn547C2) {
+        NXPLOG_NCIHAL_D("chipType : pn547C2. Not allowed. Returning");
+        return NFCSTATUS_FAILED;
+    }
+  NFCSTATUS status = NFCSTATUS_SUCCESS;
+  static uint16_t INVALID_PARAM = 0x09;
+  if ((nxpncihal_ctrl.rx_data_len > 0) && (nxpncihal_ctrl.p_rx_data[2] > 0)) {
+    if (nxpncihal_ctrl.p_rx_data[3] == 0x09) {
+      status = INVALID_PARAM;
+    } else if (nxpncihal_ctrl.p_rx_data[3] != NFCSTATUS_SUCCESS) {
+      status = NFCSTATUS_FAILED;
+    }
+  }
+  return status;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHalRFConfigCmdRecSequence
+ *
+ * Description      This function is called to handle dummy FW recovery sequence
+ *                  Whenever RF settings are failed to apply with invalid param
+ *                  response , recovery mechanism  includes dummy firmware
+ *download
+ *                  followed by irmware downlaod and then config settings. The
+ *dummy
+ *                  firmware changes the major number of the firmware inside
+ *NFCC.
+ *                  Then actual firmware dowenload will be successful.This can
+ *be
+ *                  retried maximum three times.
+ *
+ * Returns          Always returns NFCSTATUS_SUCCESS
+ *
+ ******************************************************************************/
+NFCSTATUS phNxpNciHalRFConfigCmdRecSequence() {
+    NXPLOG_NCIHAL_D("phNxpNciHalRFConfigCmdRecSequence () Enter");
+    if(nfcFL.chipType == pn547C2) {
+        NXPLOG_NCIHAL_D("chipType : pn547C2. Not allowed. Returning");
+        return NFCSTATUS_FAILED;
+    }
+  NFCSTATUS status = NFCSTATUS_SUCCESS;
+  uint16_t recFWState = 1;
+  if(nfcFL.nfccFL._NFCC_FORCE_FW_DOWNLOAD == true) {
+      gRecFWDwnld = false;
+      force_fw_download_req = true;
+  } else {
+      gRecFWDwnld = true;
+  }
+  gRecFwRetryCount++;
+  if (gRecFwRetryCount > 0x03) {
+    NXPLOG_NCIHAL_D("Max retry count for RF config FW recovery exceeded ");
+    gRecFWDwnld = false;
+    if(nfcFL.nfccFL._NFCC_FORCE_FW_DOWNLOAD == true) {
+        force_fw_download_req = false;
+    }
+    return NFCSTATUS_FAILED;
+  }
+  do {
+    phDnldNfc_InitImgInfo();
+    if (NFCSTATUS_SUCCESS == phNxpNciHal_CheckValidFwVersion()) {
+      status = phNxpNciHal_fw_download();
+      if (status == NFCSTATUS_FAILED) {
+        break;
+      }
+    }
+    gRecFWDwnld = false;
+  } while (recFWState--);
+  gRecFWDwnld = false;
+  if(nfcFL.nfccFL._NFCC_FORCE_FW_DOWNLOAD == true) {
+      force_fw_download_req = false;
+  }
+  return status;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_uicc_baud_rate
+ *
+ * Description      This function is used to restrict the UICC baud
+ *                  rate for type A and type B UICC.
+ *
+ * Returns          Status.
+ *
+ ******************************************************************************/
+static NFCSTATUS phNxpNciHal_uicc_baud_rate() {
+    NXPLOG_NCIHAL_D("phNxpNciHal_uicc_baud_rate () Enter");
+    if(nfcFL.chipType != pn547C2) {
+        NXPLOG_NCIHAL_D("chipType != pn547C2. Not allowed. Returning");
+        return NFCSTATUS_FAILED;
+    }
+  unsigned long configValue = 0x00;
+  uint16_t bitRateCmdLen = 0x04;  // HDR + LEN + PARAMS   2 + 1 + 1
+  uint8_t uiccTypeAValue = 0x00;  // read uicc type A value
+  uint8_t uiccTypeBValue = 0x00;  // read uicc type B value
+  uint8_t setUiccBitRateBuf[] = {0x20, 0x02, 0x01, 0x00, 0xA0, 0x86,
+                                 0x01, 0x91, 0xA0, 0x87, 0x01, 0x91};
+  uint8_t getUiccBitRateBuf[] = {0x20, 0x03, 0x05, 0x02,
+                                 0xA0, 0x86, 0xA0, 0x87};
+  NFCSTATUS status = NFCSTATUS_SUCCESS;
+  status =
+      phNxpNciHal_send_ext_cmd(sizeof(getUiccBitRateBuf), getUiccBitRateBuf);
+  if (status == NFCSTATUS_SUCCESS && nxpncihal_ctrl.rx_data_len >= 0x0D) {
+    if (nxpncihal_ctrl.p_rx_data[0] == 0x40 &&
+        nxpncihal_ctrl.p_rx_data[1] == 0x03 &&
+        nxpncihal_ctrl.p_rx_data[2] > 0x00 &&
+        nxpncihal_ctrl.p_rx_data[3] == 0x00) {
+      uiccTypeAValue = nxpncihal_ctrl.p_rx_data[8];
+      uiccTypeBValue = nxpncihal_ctrl.p_rx_data[12];
+    }
+  }
+  /* NXP Restrict Type A UICC baud rate */
+  if (GetNxpNumValue(NAME_NXP_TYPEA_UICC_BAUD_RATE, (void*)&configValue,
+                     sizeof(configValue))) {
+    if (configValue == 0x00) {
+      NXPLOG_NCIHAL_D("Default UICC TypeA Baud Rate supported");
+    } else {
+      setUiccBitRateBuf[2] += 0x04;  // length byte
+      setUiccBitRateBuf[3] = 0x01;   // param byte
+      bitRateCmdLen += 0x04;
+      if (configValue == 0x01 && uiccTypeAValue != 0x91) {
+        NXPLOG_NCIHAL_D("UICC TypeA Baud Rate 212kbps supported");
+        setUiccBitRateBuf[7] = 0x91;  // set config value for 212
+      } else if (configValue == 0x02 && uiccTypeAValue != 0xB3) {
+        NXPLOG_NCIHAL_D("UICC TypeA Baud Rate 424kbps supported");
+        setUiccBitRateBuf[7] = 0xB3;  // set config value for 424
+      } else if (configValue == 0x03 && uiccTypeAValue != 0xF7) {
+        NXPLOG_NCIHAL_D("UICC TypeA Baud Rate 848kbps supported");
+        setUiccBitRateBuf[7] = 0xF7;  // set config value for 848
+      } else {
+        setUiccBitRateBuf[3] = 0x00;
+        setUiccBitRateBuf[2] -= 0x04;
+        bitRateCmdLen -= 0x04;
+      }
+    }
+  }
+  configValue = 0;
+  /* NXP Restrict Type B UICC baud rate*/
+  if (GetNxpNumValue(NAME_NXP_TYPEB_UICC_BAUD_RATE, (void*)&configValue,
+                     sizeof(configValue))) {
+    if (configValue == 0x00) {
+      NXPLOG_NCIHAL_D("Default UICC TypeB Baud Rate supported");
+    } else {
+      setUiccBitRateBuf[2] += 0x04;
+      setUiccBitRateBuf[3] += 0x01;
+      setUiccBitRateBuf[bitRateCmdLen++] = 0xA0;
+      setUiccBitRateBuf[bitRateCmdLen++] = 0x87;
+      setUiccBitRateBuf[bitRateCmdLen++] = 0x01;
+      if (configValue == 0x01 && uiccTypeBValue != 0x91) {
+        NXPLOG_NCIHAL_D("UICC TypeB Baud Rate 212kbps supported");
+        setUiccBitRateBuf[bitRateCmdLen++] = 0x91;  // set config value for 212
+      } else if (configValue == 0x02 && uiccTypeBValue != 0xB3) {
+        NXPLOG_NCIHAL_D("UICC TypeB Baud Rate 424kbps supported");
+        setUiccBitRateBuf[bitRateCmdLen++] = 0xB3;  // set config value for 424
+      } else if (configValue == 0x03 && uiccTypeBValue != 0xF7) {
+        NXPLOG_NCIHAL_D("UICC TypeB Baud Rate 848kbps supported");
+        setUiccBitRateBuf[bitRateCmdLen++] = 0xF7;  // set config value for 848
+      } else {
+        setUiccBitRateBuf[2] -= 0x04;
+        setUiccBitRateBuf[3] -= 0x01;
+        bitRateCmdLen -= 0x04;
+      }
+    }
+  }
+  if (bitRateCmdLen > 0x04) {
+    status = phNxpNciHal_send_ext_cmd(bitRateCmdLen, setUiccBitRateBuf);
+  }
+  return status;
+}
+
+/******************************************************************************
+ * 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_core_MinInitialized_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_MinInitialized_complete(NFCSTATUS status) {
+  static phLibNfc_Message_t msg;
+
+  if (status == NFCSTATUS_SUCCESS) {
+    msg.eMsgType = NCI_HAL_POST_MIN_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_release_info
+ *
+ * Description      This function frees allocated memory for mGetCfg_info
+ *
+ * Returns          void.
+ *
+ ******************************************************************************/
+static void phNxpNciHal_release_info(void) {
+  NXPLOG_NCIHAL_D("phNxpNciHal_release_info mGetCfg_info");
+  if (mGetCfg_info != NULL) {
+    free(mGetCfg_info);
+    mGetCfg_info = NULL;
+  }
+}
+
+/******************************************************************************
+ * 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 = NFCSTATUS_FAILED;
+  uint8_t cmd_ce_discovery_nci[10] = {
+      0x21, 0x03,
+  };
+  static uint8_t cmd_core_reset_nci[] = {0x20, 0x00, 0x01, 0x00};
+  uint8_t length = 0;
+  uint8_t numPrms = 0;
+  uint8_t ptr = 4;
+  unsigned long uiccListenMask = 0x00;
+  unsigned long eseListenMask = 0x00;
+
+  if (!(GetNxpNumValue(NAME_NXP_UICC_LISTEN_TECH_MASK, &uiccListenMask,
+                       sizeof(uiccListenMask)))) {
+    uiccListenMask = 0x07;
+    NXPLOG_NCIHAL_D("UICC_LISTEN_TECH_MASK = 0x%0lX", uiccListenMask);
+  }
+
+  if (!(GetNxpNumValue(NAME_NXP_ESE_LISTEN_TECH_MASK, &eseListenMask, 
+                      sizeof(eseListenMask)))) {
+    eseListenMask = 0x07;
+    NXPLOG_NCIHAL_D ("NXP_ESE_LISTEN_TECH_MASK = 0x%0lX", eseListenMask);
+  }
+
+  if (nxpncihal_ctrl.hal_boot_mode == NFC_FAST_BOOT_MODE) {
+    NXPLOG_NCIHAL_E(" HAL NFC fast init mode calling min_close %d",
+                    nxpncihal_ctrl.hal_boot_mode);
+    status = phNxpNciHal_Minclose();
+    return status;
+  }
+
+  if (nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE) {
+    NXPLOG_NCIHAL_E("phNxpNciHal_close is already closed, ignoring close");
+    return NFCSTATUS_FAILED;
+  }
+
+  CONCURRENCY_LOCK();
+  if (nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT &&
+          read_failed_disable_nfc) {
+      read_failed_disable_nfc = false;
+      goto close_and_return;
+  }
+
+  if (write_unlocked_status == NFCSTATUS_FAILED) {
+    NXPLOG_NCIHAL_D("phNxpNciHal_close i2c write failed .Clean and Return");
+    goto close_and_return;
+  }
+
+  if((uiccListenMask & 0x1) == 0x01 || (eseListenMask & 0x1) == 0x01) {
+    NXPLOG_NCIHAL_D("phNxpNciHal_close (): Adding A passive listen");
+    numPrms++;
+    cmd_ce_discovery_nci[ptr++] = 0x80;
+    cmd_ce_discovery_nci[ptr++] = 0x01;
+    length += 2;
+  }
+  if((uiccListenMask & 0x2) == 0x02 || (eseListenMask & 0x4) == 0x02) {
+    NXPLOG_NCIHAL_D("phNxpNciHal_close (): Adding B passive listen");
+    numPrms++;
+    cmd_ce_discovery_nci[ptr++] = 0x81;
+    cmd_ce_discovery_nci[ptr++] = 0x01;
+    length += 2;
+  }
+  if((uiccListenMask & 0x4) == 0x04 || (eseListenMask & 0x4) == 0x04) {
+    NXPLOG_NCIHAL_D("phNxpNciHal_close (): Adding F passive listen");
+    numPrms++;
+    cmd_ce_discovery_nci[ptr++] = 0x82;
+    cmd_ce_discovery_nci[ptr++] = 0x01;
+    length += 2;
+  }
+
+  if (length != 0) {
+    cmd_ce_discovery_nci[2] = length + 1;
+    cmd_ce_discovery_nci[3] = numPrms;
+    status = phNxpNciHal_send_ext_cmd(length + 4, cmd_ce_discovery_nci);
+    if (status != NFCSTATUS_SUCCESS) {
+      NXPLOG_NCIHAL_E("CMD_CE_DISC_NCI: Failed");
+    }
+  } else {
+    NXPLOG_NCIHAL_E(
+        "No changes in the discovery command, sticking to last discovery "
+        "command sent");
+  }
+
+  nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;
+
+  status =
+      phNxpNciHal_send_ext_cmd(sizeof(cmd_core_reset_nci), cmd_core_reset_nci);
+
+  if (status != NFCSTATUS_SUCCESS) {
+    NXPLOG_NCIHAL_E("NCI_CORE_RESET: Failed");
+  }
+
+  if(gParserCreated)
+    {
+        phNxpNciHal_deinitParser();
+        gParserCreated = FALSE;
+    }
+close_and_return:
+
+  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();
+  write_unlocked_status = NFCSTATUS_SUCCESS;
+  phNxpNciHal_release_info();
+  /* Return success always */
+  return NFCSTATUS_SUCCESS;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_Minclose
+ *
+ * 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_Minclose(void) {
+  NFCSTATUS status;
+  /*NCI_RESET_CMD*/
+  uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00};
+  CONCURRENCY_LOCK();
+  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;
+  if (nxpncihal_ctrl.halStatus != HAL_STATUS_OPEN) {
+    NXPLOG_NCIHAL_D("Power Cycle failed due to hal status not open");
+    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");
+  }
+
+  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_ioctl
+ *
+ * Description      This function is called by jni when wired mode is
+ *                  performed.First Pn54x driver will give the access
+ *                  permission whether wired mode is allowed or not
+ *                  arg (0):
+ * Returns          return 0 on success and -1 on fail, On success
+ *                  update the acutual state of operation in arg pointer
+ *
+ ******************************************************************************/
+int phNxpNciHal_ioctl(long arg, void* p_data) {
+  NXPLOG_NCIHAL_D("%s : enter - arg = %ld", __func__, arg);
+  nfc_nci_IoctlInOutData_t* pInpOutData = p_data;
+  int ret = -1;
+  NFCSTATUS status = NFCSTATUS_FAILED;
+  phNxpNciHal_FwRfupdateInfo_t* FwRfInfo;
+  NFCSTATUS fm_mw_ver_check = NFCSTATUS_FAILED;
+
+  switch (arg) {
+    case HAL_NFC_IOCTL_P61_IDLE_MODE:
+        if(nfcFL.nfcNxpEse) {
+            status = phTmlNfc_IoCtl(phTmlNfc_e_SetP61IdleMode);
+            if (NFCSTATUS_FAILED != status) {
+                if (NULL != p_data) pInpOutData->out.data.status = (uint16_t)status;
+                ret = 0;
+            }
+        }
+      break;
+    case HAL_NFC_IOCTL_P61_WIRED_MODE:
+        if(nfcFL.nfcNxpEse) {
+            status = phTmlNfc_IoCtl(phTmlNfc_e_SetP61WiredMode);
+            if (NFCSTATUS_FAILED != status) {
+                if (NULL != p_data) pInpOutData->out.data.status = (uint16_t)status;
+                ret = 0;
+            }
+        }
+      break;
+    case HAL_NFC_IOCTL_P61_PWR_MODE:
+        if(nfcFL.nfcNxpEse) {
+            status = phTmlNfc_IoCtl(phTmlNfc_e_GetP61PwrMode);
+            if (NFCSTATUS_FAILED != status) {
+                if (NULL != p_data)
+                    pInpOutData->out.data.p61CurrentState = (uint16_t)status;
+                ret = 0;
+            }
+        }
+      break;
+    case HAL_NFC_IOCTL_P61_ENABLE_MODE:
+        if(nfcFL.nfcNxpEse) {
+            status = phTmlNfc_IoCtl(phTmlNfc_e_SetP61EnableMode);
+            if (NFCSTATUS_FAILED != status) {
+                if (NULL != p_data) pInpOutData->out.data.status = (uint16_t)status;
+                ret = 0;
+            }
+        }
+      break;
+    case HAL_NFC_IOCTL_P61_DISABLE_MODE:
+        if(nfcFL.nfcNxpEse) {
+            status = phTmlNfc_IoCtl(phTmlNfc_e_SetP61DisableMode);
+            if (NFCSTATUS_FAILED != status) {
+                if (NULL != p_data) pInpOutData->out.data.status = (uint16_t)status;
+                ret = 0;
+            }
+        }
+      break;
+    case HAL_NFC_IOCTL_P61_GET_ACCESS:
+        if(nfcFL.nfcNxpEse) {
+            NXPLOG_NCIHAL_D("HAL_NFC_IOCTL_P61_GET_ACCESS timeoutInMillisec = %d",
+                    pInpOutData->inp.data.timeoutMilliSec);
+            status = phTmlNfc_get_ese_access(gpphTmlNfc_Context->pDevHandle,
+                    pInpOutData->inp.data.timeoutMilliSec);
+            if (NFCSTATUS_SUCCESS == status) {
+                ret = 0;
+            }
+        }
+      break;
+    case HAL_NFC_IOCTL_P61_REL_ACCESS:
+        if(nfcFL.nfcNxpEse) {
+            status = phTmlNfc_IoCtl(phTmlNfc_e_RelP61Access);
+            NXPLOG_NCIHAL_D("HAL_NFC_IOCTL_P61_REL_ACCESS retval = %d\n", status);
+            pInpOutData->out.data.status = status;
+            if (NFCSTATUS_SUCCESS == status) {
+                ret = 0;
+            }
+        }
+      break;
+    case HAL_NFC_IOCTL_ESE_CHIP_RST:
+        if(nfcFL.nfcNxpEse) {
+            status = phTmlNfc_IoCtl(phTmlNfc_e_eSEChipRstMode);
+            if (NFCSTATUS_FAILED != status) {
+                if (NULL != p_data) pInpOutData->out.data.status = (uint16_t)status;
+                ret = 0;
+            }
+        }
+      break;
+    case HAL_NFC_IOCTL_REL_SVDD_WAIT:
+        if(nfcFL.nfcNxpEse && nfcFL.eseFL._ESE_SVDD_SYNC) {
+            status = phTmlNfc_rel_svdd_wait(gpphTmlNfc_Context->pDevHandle);
+            NXPLOG_NCIHAL_D("HAL_NFC_IOCTL_P61_REL_SVDD_WAIT retval = %d\n", status);
+            pInpOutData->out.data.status = status;
+            if (NFCSTATUS_SUCCESS == status) {
+                ret = 0;
+            }
+        }
+      break;
+
+    case HAL_NFC_IOCTL_SET_BOOT_MODE:
+      if (NULL != p_data) {
+        status = phNxpNciHal_set_Boot_Mode(pInpOutData->inp.data.bootMode);
+        if (NFCSTATUS_FAILED != status) {
+          pInpOutData->out.data.status = (uint16_t)status;
+          ret = 0;
+        }
+      }
+      break;
+    case HAL_NFC_IOCTL_SET_JCP_DWNLD_ENABLE:
+        if(nfcFL.eseFL._ESE_JCOP_DWNLD_PROTECTION) {
+            NXPLOG_NCIHAL_D("HAL_NFC_IOCTL_SET_JCP_DWNLD_ENABLE: \n");
+            status = phTmlNfc_IoCtl(phTmlNfc_e_SetJcopDwnldEnable);
+            if (NFCSTATUS_FAILED != status) {
+                if (NULL != p_data) pInpOutData->out.data.status = (uint16_t)status;
+                ret = 0;
+            }
+        }
+      break;
+    case HAL_NFC_IOCTL_SET_JCP_DWNLD_DISABLE:
+        if(nfcFL.eseFL._ESE_JCOP_DWNLD_PROTECTION) {
+            NXPLOG_NCIHAL_D("HAL_NFC_IOCTL_SET_JCP_DWNLD_DISABLE: \n");
+            status = phTmlNfc_IoCtl(phTmlNfc_e_SetJcopDwnldDisable);
+            if (NFCSTATUS_FAILED != status) {
+                if (NULL != p_data) pInpOutData->out.data.status = (uint16_t)status;
+                ret = 0;
+            }
+        }
+      break;
+
+    case HAL_NFC_IOCTL_GET_CONFIG_INFO:
+      if (mGetCfg_info) {
+        memcpy(pInpOutData->out.data.nxpNciAtrInfo, mGetCfg_info,
+               sizeof(phNxpNci_getCfg_info_t));
+      } else {
+        NXPLOG_NCIHAL_E("%s : Error! mgetCfg_info is Empty ", __func__);
+      }
+      ret = 0;
+      break;
+    case HAL_NFC_IOCTL_CHECK_FLASH_REQ:
+      FwRfInfo =
+          (phNxpNciHal_FwRfupdateInfo_t*)&pInpOutData->out.data.fwUpdateInf;
+      status = phNxpNciHal_CheckFwRegFlashRequired(&FwRfInfo->fw_update_reqd,
+                                                   &FwRfInfo->rf_update_reqd);
+      if (NFCSTATUS_SUCCESS == status) {
+#ifndef FW_DWNLD_FLAG
+        fw_dwnld_flag = FwRfInfo->fw_update_reqd;
+#endif
+        ret = 0;
+      }
+      break;
+    case HAL_NFC_IOCTL_FW_DWNLD:
+      status = phNxpNciHal_FwDwnld(*(uint16_t*)p_data);
+      pInpOutData->out.data.fwDwnldStatus = (uint16_t)status;
+      if (NFCSTATUS_SUCCESS == status) {
+        ret = 0;
+      }
+      if(nfcFL.nfccFL._NFCC_FORCE_FW_DOWNLOAD) {
+          force_fw_download_req = false;
+      }
+      break;
+    case HAL_NFC_IOCTL_FW_MW_VER_CHECK:
+      fm_mw_ver_check = phNxpNciHal_fw_mw_ver_check();
+      pInpOutData->out.data.fwMwVerStatus = fm_mw_ver_check;
+      ret = 0;
+      break;
+    case HAL_NFC_IOCTL_NCI_TRANSCEIVE:
+      if (p_data == NULL) {
+        ret = -1;
+        break;
+      }
+
+      if (pInpOutData->inp.data.nciCmd.cmd_len <= 0) {
+        ret = -1;
+        break;
+      }
+
+      ret = phNxpNciHal_send_ext_cmd(pInpOutData->inp.data.nciCmd.cmd_len,
+                                     pInpOutData->inp.data.nciCmd.p_cmd);
+      pInpOutData->out.data.nciRsp.rsp_len = nxpncihal_ctrl.rx_data_len;
+      if ((nxpncihal_ctrl.rx_data_len > 0) &&
+          (nxpncihal_ctrl.rx_data_len <= MAX_IOCTL_TRANSCEIVE_RESP_LEN) &&
+          (nxpncihal_ctrl.p_rx_data != NULL)) {
+        memcpy(pInpOutData->out.data.nciRsp.p_rsp, nxpncihal_ctrl.p_rx_data,
+               nxpncihal_ctrl.rx_data_len);
+      }
+      break;
+    case HAL_NFC_IOCTL_DISABLE_HAL_LOG:
+      status = phNxpLog_EnableDisableLogLevel(pInpOutData->inp.data.halType);
+      break;
+    case HAL_NFC_IOCTL_SET_NFC_SERVICE_PID:
+      if(gpphTmlNfc_Context) {
+          gpphTmlNfc_Context->nfc_service_pid = pInpOutData->inp.data.nfcServicePid;
+          status = phTmlNfc_IoCtl(phTmlNfc_e_SetNfcServicePid);
+          if (NFCSTATUS_FAILED != status) {
+              if (NULL != p_data) pInpOutData->out.data.status = (uint16_t)status;
+              ret = 0;
+          }
+      }
+      break;
+    case HAL_NFC_IOCTL_GET_FEATURE_LIST:
+        pInpOutData->out.data.chipType = (uint8_t)phNxpNciHal_getChipType();
+        ret = 0;
+        break;
+    default:
+      NXPLOG_NCIHAL_E("%s : Wrong arg = %ld", __func__, arg);
+      break;
+  }
+  NXPLOG_NCIHAL_D("%s : exit - ret = %d", __func__, ret);
+  return ret;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_nfccClockCfgRead
+ *
+ * Description      This function is called for loading a data strcuture from
+ *                  the config file with clock source and clock frequency values
+ *
+ * Returns          void.
+ *
+ ******************************************************************************/
+static void phNxpNciHal_nfccClockCfgRead(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_txNfccClockSetCmd
+ *
+ * Description      This function is called after successfull download
+ *                  to apply the clock setting provided in config file
+ *
+ * Returns          void.
+ *
+ ******************************************************************************/
+static void phNxpNciHal_txNfccClockSetCmd(void) {
+  NFCSTATUS status = NFCSTATUS_FAILED;
+
+if(nfcFL.chipType == pn553) {
+    static uint8_t set_clock_cmd[] = {0x20, 0x02, 0x05, 0x01, 0xA0, 0x03, 0x01, 0x08};
+    unsigned long  clockSource, frequency;
+    uint32_t pllSetRetryCount = 3, dpllSetRetryCount = 3;
+    uint8_t *pCmd4PllSetting;
+    uint8_t *pCmd4DpllSetting;
+    uint32_t pllCmdLen, dpllCmdLen;
+    int srcCfgFound, freqCfgFound;
+
+    srcCfgFound = (GetNxpNumValue(NAME_NXP_SYS_CLK_SRC_SEL, &clockSource, sizeof(clockSource)) > 0);
+
+    freqCfgFound = (GetNxpNumValue(NAME_NXP_SYS_CLK_FREQ_SEL, &frequency, sizeof(frequency)) > 0);
+
+    NXPLOG_NCIHAL_D("%s : clock source = %lu, frequency = %lu", __FUNCTION__, clockSource, frequency);
+
+    if(srcCfgFound && freqCfgFound && (clockSource == CLK_SRC_PLL))
+    {
+         phNxpNciClock.isClockSet = TRUE;
+
+        switch(frequency)
+        {
+            case CLK_FREQ_13MHZ:
+
+                NXPLOG_NCIHAL_D("PLL setting for CLK_FREQ_13MHZ");
+                uint8_t cmd4PllSetting13MHz[] = SET_CONFIG_CMD_PLL_13MHZ;
+                pCmd4PllSetting = cmd4PllSetting13MHz;
+                pllCmdLen = sizeof(cmd4PllSetting13MHz);
+
+                uint8_t cmd4DpllSetting13MHz[] = SET_CONFIG_CMD_DPLL_13MHZ;
+                pCmd4DpllSetting = cmd4DpllSetting13MHz;
+                dpllCmdLen = sizeof(cmd4DpllSetting13MHz);
+
+            break;
+
+            case CLK_FREQ_19_2MHZ:
+
+                NXPLOG_NCIHAL_D("PLL setting for CLK_FREQ_19_2MHZ");
+                uint8_t cmd4PllSetting19_2MHz[] = SET_CONFIG_CMD_PLL_19_2MHZ;
+                pCmd4PllSetting = cmd4PllSetting19_2MHz;
+                pllCmdLen = sizeof(cmd4PllSetting19_2MHz);
+
+                uint8_t cmd4DpllSetting19_2MHz[] = SET_CONFIG_CMD_DPLL_19_2MHZ;
+                pCmd4DpllSetting = cmd4DpllSetting19_2MHz;
+                dpllCmdLen = sizeof(cmd4DpllSetting19_2MHz);
+
+            break;
+
+            case CLK_FREQ_24MHZ:
+
+                NXPLOG_NCIHAL_D("PLL setting for CLK_FREQ_24MHZ");
+                uint8_t cmd4PllSetting24MHz[] = SET_CONFIG_CMD_PLL_24MHZ;
+                pCmd4PllSetting = cmd4PllSetting24MHz;
+                pllCmdLen = sizeof(cmd4PllSetting24MHz);
+
+                uint8_t cmd4DpllSetting24MHz[] = SET_CONFIG_CMD_DPLL_24MHZ;
+                pCmd4DpllSetting = cmd4DpllSetting24MHz;
+                dpllCmdLen = sizeof(cmd4DpllSetting24MHz);
+
+            break;
+
+            case CLK_FREQ_26MHZ:
+
+                NXPLOG_NCIHAL_D("PLL setting for CLK_FREQ_26MHZ");
+                uint8_t cmd4PllSetting26MHz[] = SET_CONFIG_CMD_PLL_26MHZ;
+                pCmd4PllSetting = cmd4PllSetting26MHz;
+                pllCmdLen = sizeof(cmd4PllSetting26MHz);
+
+                uint8_t cmd4DpllSetting26MHz[] = SET_CONFIG_CMD_DPLL_26MHZ;
+                pCmd4DpllSetting = cmd4DpllSetting26MHz;
+                dpllCmdLen = sizeof(cmd4DpllSetting26MHz);
+
+            break;
+            case CLK_FREQ_32MHZ:
+
+                NXPLOG_NCIHAL_D("PLL setting for CLK_FREQ_32MHZ");
+                uint8_t cmd4PllSetting32MHz[] = SET_CONFIG_CMD_PLL_32MHZ;
+                pCmd4PllSetting = cmd4PllSetting32MHz;
+                pllCmdLen = sizeof(cmd4PllSetting32MHz);
+
+                uint8_t cmd4DpllSetting32MHz[] = SET_CONFIG_CMD_DPLL_32MHZ;
+                pCmd4DpllSetting = cmd4DpllSetting32MHz;
+                dpllCmdLen = sizeof(cmd4DpllSetting32MHz);
+
+            break;
+
+            case CLK_FREQ_38_4MHZ:
+
+                NXPLOG_NCIHAL_D("PLL setting for CLK_FREQ_38_4MHZ");
+                uint8_t cmd4PllSetting38_4MHz[] = SET_CONFIG_CMD_PLL_38_4MHZ;
+                pCmd4PllSetting = cmd4PllSetting38_4MHz;
+                pllCmdLen = sizeof(cmd4PllSetting38_4MHz);
+
+                uint8_t cmd4DpllSetting38_4MHz[] = SET_CONFIG_CMD_DPLL_38_4MHZ;
+                pCmd4DpllSetting = cmd4DpllSetting38_4MHz;
+                dpllCmdLen = sizeof(cmd4DpllSetting38_4MHz);
+
+            break;
+
+            default:
+                phNxpNciClock.isClockSet = FALSE;
+                NXPLOG_NCIHAL_E("ERROR: Invalid clock frequency!!");
+                return;
+        }
+    }
+    switch(clockSource)
+    {
+        case CLK_SRC_PLL:
+            while(status != NFCSTATUS_SUCCESS && pllSetRetryCount -- > 0)
+                status = phNxpNciHal_send_ext_cmd(pllCmdLen, pCmd4PllSetting);
+
+            status = NFCSTATUS_FAILED;
+
+            while(status != NFCSTATUS_SUCCESS && dpllSetRetryCount -- > 0)
+                status = phNxpNciHal_send_ext_cmd(dpllCmdLen, pCmd4DpllSetting);
+
+            break;
+
+        case CLK_SRC_XTAL:
+            status = phNxpNciHal_send_ext_cmd(sizeof(set_clock_cmd), set_clock_cmd);
+            if (status != NFCSTATUS_SUCCESS)
+            {
+                NXPLOG_NCIHAL_E("XTAL clock setting failed !!");
+            }
+            break;
+
+        default:            NXPLOG_NCIHAL_E("Wrong clock source. Dont apply any modification");
+                            return;
+    }
+    phNxpNciClock.isClockSet = FALSE;
+    if(status == NFCSTATUS_SUCCESS && phNxpNciClock.p_rx_data[3] == NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_NCIHAL_D("PLL and DPLL settings applied successfully");
+    }
+    return;
+}
+else {
+    NXPLOG_NCIHAL_D("Clock setting older version");
+  }
+
+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;
+
+    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_determineConfiguredClockSrc
+ *
+ * Description      This function determines and encodes clock source based on
+ *                  clock frequency
+ *
+ * Returns          encoded form of clock source
+ *
+ *****************************************************************************/
+int   phNxpNciHal_determineConfiguredClockSrc()
+{
+    NFCSTATUS status = NFCSTATUS_FAILED;
+    uint8_t param_clock_src = CLK_SRC_PLL;
+    if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_PLL)
+    {
+
+    if(nfcFL.chipType == pn553) {
+        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_nfccClockCfgApply
+ *
+ * Description      This function is called after successfull download
+ *                  to check if clock settings in config file and chip
+ *                  is same
+ *
+ * Returns          void.
+ *
+ ******************************************************************************/
+NFCSTATUS phNxpNciHal_nfccClockCfgApply(void) {
+  NFCSTATUS status = NFCSTATUS_SUCCESS;
+  uint8_t nfcc_cfg_clock_src, nfcc_cur_clock_src;
+  uint8_t nfcc_clock_set_needed;
+  static uint8_t get_clock_cmd[] = {0x20, 0x03, 0x07, 0x03, 0xA0,
+                                    0x02, 0xA0, 0x03, 0xA0, 0x04};
+  phNxpNciHal_nfccClockCfgRead();
+  phNxpNciClock.isClockSet = true;
+  status = phNxpNciHal_send_ext_cmd(sizeof(get_clock_cmd), get_clock_cmd);
+  phNxpNciClock.isClockSet = false;
+
+  if (status != NFCSTATUS_SUCCESS) {
+    NXPLOG_NCIHAL_E("unable to retrieve get_clk_src_sel");
+    return status;
+  }
+  
+  nfcc_cfg_clock_src = phNxpNciHal_determineConfiguredClockSrc();
+  nfcc_cur_clock_src = phNxpNciClock.p_rx_data[12];
+
+  nfcc_clock_set_needed = (nfcc_cfg_clock_src != nfcc_cur_clock_src ||
+                              phNxpNciClock.p_rx_data[16] == nxpprofile_ctrl.bTimeout) ?\
+                              true : false;
+  if(nfcc_clock_set_needed) {
+    NXPLOG_NCIHAL_D ("Setting Clock Source and Frequency");
+    phNxpNciHal_txNfccClockSetCmd();
+  }
+
+  return status;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_set_china_region_configs
+ *
+ * Description      This function is called to set china region specific configs
+ *
+ * Returns          Status.
+ *
+ ******************************************************************************/
+NFCSTATUS phNxpNciHal_set_china_region_configs(void) {
+  NFCSTATUS status = NFCSTATUS_SUCCESS;
+  int isfound = 0;
+  unsigned long rf_enable = false;
+  unsigned long cfg_blk_chk_enable = false;
+  unsigned long cma_bypass_enable = false;
+  int rf_val = 0;
+  int flag_send_tianjin_config = true;
+  int flag_send_transit_config = true;
+  int flag_send_cmabypass_config = true;
+  uint8_t retry_cnt = 0;
+  int enable_bit = 0;
+  int enable_blk_num_chk_bit = 0;
+  static uint8_t get_rf_cmd[] = {0x20, 0x03, 0x03, 0x01, 0xA0, 0x85};
+  NXPLOG_NCIHAL_D("phNxpNciHal_set_china_region_configs - Enter");
+
+retry_send_ext:
+  if (retry_cnt > 3) {
+    return NFCSTATUS_FAILED;
+  }
+
+  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;
+  }
+
+  /* check if tianjin_rf_setting is required */
+  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(nfcFL.nfccFL._NFCC_MIFARE_TIANJIN) {
+          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 {
+              flag_send_tianjin_config = false;  // No need to change in RF setting
+          }
+      }
+      else {
+          enable_bit = phNxpNciRfSet.p_rx_data[11] & 0x10;
+          if ((rf_enable == 1) && (enable_bit != 0x10)) {
+              NXPLOG_NCIHAL_E("Setting Non-Mifare reader for china tianjin");
+              phNxpNciRfSet.p_rx_data[11] |= 0x10;
+          } else if ((rf_enable == 0) && (enable_bit == 0x10)) {
+              NXPLOG_NCIHAL_E("Setting Non-Mifare reader for china tianjin");
+              phNxpNciRfSet.p_rx_data[11] &= 0xEF;
+          } else {
+              flag_send_tianjin_config = false;
+          }
+      }
+  }
+  else {
+    flag_send_tianjin_config = false;
+  }
+  /*check if china block number check is required*/
+  rf_val = phNxpNciRfSet.p_rx_data[8];
+  isfound =
+      (GetNxpNumValue(NAME_NXP_CHINA_BLK_NUM_CHK_ENABLE,
+                      (void*)&cfg_blk_chk_enable, sizeof(cfg_blk_chk_enable)));
+  if (isfound > 0) {
+    enable_blk_num_chk_bit = rf_val & 0x40;
+    if ((enable_blk_num_chk_bit != 0x40) && (cfg_blk_chk_enable == 1)) {
+      phNxpNciRfSet.p_rx_data[8] |= 0x40;  // Enable if it is disabled
+    } else if ((enable_blk_num_chk_bit == 0x40) && (cfg_blk_chk_enable == 0)) {
+      phNxpNciRfSet.p_rx_data[8] &= ~0x40;  // Disable if it is Enabled
+    } else {
+      flag_send_transit_config = false;  // No need to change in RF setting
+    }
+  }
+  else
+    {
+        flag_send_transit_config = FALSE;  // No need to change in RF setting
+    }
+
+    isfound = (GetNxpNumValue(NAME_NXP_CN_TRANSIT_CMA_BYPASSMODE_ENABLE, (void *)&cma_bypass_enable, sizeof(cma_bypass_enable)));
+    if(isfound >0) {
+        if(cma_bypass_enable == 0 && ((phNxpNciRfSet.p_rx_data[10] & 0x80) == 1)) {
+            NXPLOG_NCIHAL_D("Disable CMA_BYPASSMODE Supports EMVCo PICC Complaincy");
+            phNxpNciRfSet.p_rx_data[10] &=~0x80;        //set 24th bit of RF MISC SETTING to 0 for EMVCo PICC Complaincy support
+        }
+        else if(cma_bypass_enable == 1 && ((phNxpNciRfSet.p_rx_data[10] & 0x80) == 0)) {
+            NXPLOG_NCIHAL_D("Enable CMA_BYPASSMODE bypass the ISO14443-3A state machine from READY to ACTIVE and backward compatibility with MIfrae Reader ");
+            phNxpNciRfSet.p_rx_data[10] |=0x80;        //set 24th bit of RF MISC SETTING to 1 for backward compatibility with MIfrae Reader
+        }
+        else {
+            flag_send_cmabypass_config = FALSE;  // No need to change in RF setting
+        }
+    }
+    else {
+       flag_send_cmabypass_config = FALSE;
+    }
+
+  if (flag_send_tianjin_config || flag_send_transit_config || flag_send_cmabypass_config) {
+    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;
+}
+
+/******************************************************************************
+ * 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;
+  unsigned long i2c_status = 0x00;
+  unsigned long config_i2c_value = 0xff;
+  /*NCI_RESET_CMD*/
+  static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00};
+  /*NCI_INIT_CMD*/
+  static uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
+  static uint8_t cmd_init_nci2_0[] = {0x20,0x01,0x02,0x00,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_value = 0x01;
+      phNxpNciHal_notify_i2c_fragmentation();
+      phTmlNfc_set_fragmentation_enabled(I2C_FRAGMENTATION_ENABLED);
+    } else if (nxpncihal_ctrl.p_rx_data[8] == 0x00) {
+      config_i2c_value = 0x00;
+    }
+    if (config_i2c_value == 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_value == 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");
+      }
+
+      if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) {
+        status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci2_0), cmd_init_nci2_0);
+      } else {
+        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";
+  uint8_t *reset_ese_session_identity_set;
+  uint8_t ese_session_dyn_uicc_nv[] = {
+            0x20, 0x02, 0x17, 0x02,0xA0, 0xEA, 0x08, 0xFF, 0xFF, 0xFF,
+            0xFF, 0xFF, 0xFF, 0xFF, 0xFF,0xA0, 0x1E, 0x08, 0xFF, 0xFF,
+            0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+  uint8_t ese_session_dyn_uicc[] = {
+            0x20, 0x02, 0x22, 0x03, 0xA0, 0xEA, 0x08, 0xFF, 0xFF, 0xFF,
+            0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0x1E, 0x08, 0xFF, 0xFF,
+            0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0xEB, 0x08, 0xFF,
+            0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+  uint8_t ese_session_nv[] = {
+            0x20, 0x02, 0x0C, 0x01, 0xA0, 0xEA, 0x08, 0xFF, 0xFF,
+            0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+  uint8_t ese_session[] = {
+            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};
+  if(nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH || nfcFL.nfccFL._NFCC_DYNAMIC_DUAL_UICC) {
+    if(nfcFL.eseFL._EXCLUDE_NV_MEM_DEPENDENCY) {
+      reset_ese_session_identity_set = ese_session_dyn_uicc_nv;
+    }
+    else {
+      reset_ese_session_identity_set = ese_session_dyn_uicc;
+    }
+  }
+  else {
+    if(nfcFL.eseFL._EXCLUDE_NV_MEM_DEPENDENCY) {
+      reset_ese_session_identity_set = ese_session_nv;
+    }
+    else {
+      reset_ese_session_identity_set = ese_session;
+    }
+  }
+
+
+#ifdef PN547C2_FACTORY_RESET_DEBUG
+  static uint8_t reset_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", __func__, 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_session_identity),
+            reset_session_identity);
+    if (status != NFCSTATUS_SUCCESS) {
+      NXPLOG_NCIHAL_E("NXP reset_session_identity command failed");
+    }
+#endif
+    if((nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH) &&
+            (nfcFL.nfccFL._NFCC_DYNAMIC_DUAL_UICC)) {
+        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_session_identity),
+            reset_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", __func__,
+                      response_buf[status_byte]);
+    } else {
+      NXPLOG_NCIHAL_D("%s: response status =%s", __func__, 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",__func__,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.");
+        config_success = false;
+    }
+  }
+}
+/******************************************************************************
+ * Function         phNxpNciHal_set_Boot_Mode
+ *
+ * Description      This function is called to  set hal
+ *                  boot mode. This can be normal nfc boot
+ *                  or fast boot.The param mode can take the
+ *                  following values.
+ *                  NORAML_NFC_MODE = 0 FAST_BOOT_MODE = 1
+ *
+ *
+ * Returns          void.
+ *
+ ******************************************************************************/
+NFCSTATUS phNxpNciHal_set_Boot_Mode(uint8_t mode) {
+  nxpncihal_ctrl.hal_boot_mode = mode;
+  return NFCSTATUS_SUCCESS;
+}
+
+/*****************************************************************************
+ * Function         phNxpNciHal_send_get_cfgs
+ *
+ * Description      This function is called to  send get configs
+ *                  for all the types in get_cfg_arr.
+ *                  Response of getConfigs(EEPROM stored) will be
+ *                  compared with request coming from MW during discovery.
+ *                  If same, then current setConfigs will be dropped
+ *
+ * Returns          Returns NFCSTATUS_SUCCESS if sending cmd is successful and
+ *                  response is received.
+ *
+ *****************************************************************************/
+NFCSTATUS phNxpNciHal_send_get_cfgs() {
+  NXPLOG_NCIHAL_D("%s Enter", __func__);
+  NFCSTATUS status = NFCSTATUS_FAILED;
+  uint8_t num_cfgs = sizeof(get_cfg_arr) / sizeof(uint8_t);
+  uint8_t cfg_count = 0, retry_cnt = 0;
+  if (mGetCfg_info != NULL) {
+      mGetCfg_info->isGetcfg = true;
+  }
+  uint8_t cmd_get_cfg[] = {0x20, 0x03, 0x02, 0x01, 0x00};
+
+  while (cfg_count < num_cfgs) {
+    cmd_get_cfg[sizeof(cmd_get_cfg) - 1] = get_cfg_arr[cfg_count];
+
+  retry_get_cfg:
+    status = phNxpNciHal_send_ext_cmd(sizeof(cmd_get_cfg), cmd_get_cfg);
+    if (status != NFCSTATUS_SUCCESS && retry_cnt < 3) {
+      NXPLOG_NCIHAL_E("cmd_get_cfg failed");
+      retry_cnt++;
+      goto retry_get_cfg;
+    }
+    if (retry_cnt == 3) {
+      break;
+    }
+    cfg_count++;
+    retry_cnt = 0;
+  }
+  mGetCfg_info->isGetcfg = false;
+  return status;
+}
+NFCSTATUS phNxpNciHal_send_nfcee_pwr_cntl_cmd(uint8_t type) {
+  NFCSTATUS status = NFCSTATUS_FAILED;
+  uint8_t cmd_buf[] = {0x22, 0x03, 0x02, 0xC0, 0x00};
+  uint8_t retry_cnt = 0;
+
+  NXPLOG_NCIHAL_D("phNxpNciHal_send_nfcee_pwr_cntl_cmd; enter");
+  cmd_buf[sizeof(cmd_buf) - 1] = type;
+  while (status != NFCSTATUS_SUCCESS && retry_cnt < 3) {
+    status = phNxpNciHal_send_ext_cmd(sizeof(cmd_buf), cmd_buf);
+    NXPLOG_NCIHAL_E("cmd_nfcee_pwr_cntl_cfg failed");
+    retry_cnt++;
+  }
+  retry_cnt = 0;
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_getFWDownloadFlags
+**
+** Description      Returns the current mode
+**
+** Parameters       none
+**
+** Returns          Current mode download/NCI
+*******************************************************************************/
+int phNxpNciHal_getFWDownloadFlag(uint8_t* fwDnldRequest) {
+  int status = NFCSTATUS_FAILED;
+
+  NXPLOG_NCIHAL_D("notifyFwrequest %d", notifyFwrequest);
+  if (fwDnldRequest != NULL) {
+    status = NFCSTATUS_OK;
+    if (notifyFwrequest == true) {
+      *fwDnldRequest = true;
+      notifyFwrequest = false;
+    } else {
+      *fwDnldRequest = false;
+    }
+  }
+
+  return status;
+}
+
+tNFC_chipType configChipType(uint8_t* msg, uint16_t msg_len) {
+    tNFC_chipType chipType;
+    const uint16_t offsetHwVersion = 24;
+    const uint16_t offsetFwVersion = 25;
+
+    if((msg != NULL) && (msg_len != 0)) {
+        if((msg[0] == 0x60 && msg[1] == 00) ||
+                ((offsetFwVersion < msg_len) && (msg[offsetFwVersion] == 0x12))) {
+            chipType = pn81T;
+        }
+        else if(offsetHwVersion < msg_len) {
+            ALOGD ("%s HwVersion : 0x%02x", __func__,msg[offsetHwVersion]);
+            switch(msg[offsetHwVersion]){
+
+            case 0x40 : //PN553 A0
+            case 0x41 : //PN553 B0
+                chipType = pn553;
+                break;
+
+            case 0x50 : //PN553 A0 + P73
+            case 0x51 : //PN553 B0 + P73
+                chipType = pn80T;
+                break;
+
+            case 0x98 :
+                chipType = pn551;
+                break;
+
+            case 0xA8 :
+                chipType = pn67T;
+                break;
+
+            case 0x28 :
+            case 0x48 :
+                chipType = pn548C2;
+                break;
+
+            case 0x18 :
+            case 0x58 :
+                chipType = pn66T;
+                break;
+
+            default :
+                chipType = pn80T;
+            }
+        }
+        else {
+            ALOGD ("%s Wrong msg_len. Setting Default ChiptType pn80T",__func__);
+            chipType = pn80T;
+        }
+    }
+    return chipType;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_configFeatureList
+**
+** Description      Configures the featureList based on chip type
+**                  HW Version information number will provide chipType.
+**                  HW Version can be obtained from CORE_INIT_RESPONSE(NCI 1.0)
+**                  or CORE_RST_NTF(NCI 2.0)
+**
+** Parameters       CORE_INIT_RESPONSE/CORE_RST_NTF, len
+**
+** Returns          none
+*******************************************************************************/
+void phNxpNciHal_configFeatureList(uint8_t* init_rsp, uint16_t rsp_len) {
+    nxpncihal_ctrl.chipType = configChipType(init_rsp,rsp_len);
+    tNFC_chipType chipType = nxpncihal_ctrl.chipType;
+    CONFIGURE_FEATURELIST(chipType);
+    NXPLOG_NCIHAL_D("NFC_GetFeatureList ()chipType = %d", chipType);
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_getChipType
+**
+** Description      Gets the chipType which is configured during bootup
+**
+** Parameters       none
+**
+** Returns          chipType
+*******************************************************************************/
+tNFC_chipType phNxpNciHal_getChipType() {
+    return nxpncihal_ctrl.chipType;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_configLxDebug(void)
+**
+** Description      Helper function to configure LxDebug modes
+**
+** Parameters       none
+**
+** Returns          void
+*******************************************************************************/
+void phNxpNciHal_configNciParser(void)
+{
+    NFCSTATUS status = NFCSTATUS_SUCCESS;
+    unsigned long num = 0;
+    uint8_t  isfound = 0;
+    static uint8_t cmd_lxdebug[] = { 0x20, 0x02, 0x06, 0x01, 0xA0, 0x1D, 0x02, 0x00, 0x00 };
+
+    isfound = GetNxpNumValue(NAME_NXP_CORE_PROP_SYSTEM_DEBUG, &num, sizeof(num));
+
+    if(isfound > 0)
+    {
+        if(num == 0x00)
+        {
+            NXPLOG_NCIHAL_D("Disable LxDebug");
+        }
+        else if(num == 0x01)
+        {
+            NXPLOG_NCIHAL_D("Enable L1 RF NTF debugs");
+            cmd_lxdebug[7] = 0x10;
+        }
+        else if(num == 0x02)
+        {
+            NXPLOG_NCIHAL_D("Enable L2 RF NTF debugs");
+            cmd_lxdebug[7] = 0x01;
+        }
+        else if(num == 0x03)
+        {
+            NXPLOG_NCIHAL_D("Enable L1 & L2 RF NTF debugs");
+            cmd_lxdebug[7] = 0x31;
+        }
+        else if(num == 0x04)
+        {
+            NXPLOG_NCIHAL_D("Enable L1 & L2 & RSSI NTF debugs");
+            cmd_lxdebug[7] = 0x31;
+            cmd_lxdebug[8] = 0x01;
+        }
+        else if(num == 0x05)
+        {
+            NXPLOG_NCIHAL_D("Enable L2 & Felica RF NTF debugs");
+            cmd_lxdebug[7] = 0x03;
+        }
+        else
+            NXPLOG_NCIHAL_E("Invalid Level, Disable LxDebug");
+
+        status = phNxpNciHal_send_ext_cmd(sizeof(cmd_lxdebug)/sizeof(cmd_lxdebug[0]),cmd_lxdebug);
+        if (status != NFCSTATUS_SUCCESS)
+        {
+            NXPLOG_NCIHAL_E("Set lxDebug config failed");
+        }
+    }
+
+    // try initializing parser library
+    NXPLOG_NCIHAL_D("Try Init Parser gParserCreated:%d",gParserCreated);
+
+    if(!gParserCreated) {
+        gParserCreated = phNxpNciHal_initParser();
+    } else {
+        NXPLOG_NCIHAL_D("Parser Already Initialized");
+    }
+
+    if(gParserCreated) {
+        NXPLOG_NCIHAL_D("Parser Initialized Successfully");
+        if(isfound) {
+            NXPLOG_NCIHAL_D("Setting lxdebug levels in library");
+            phNxpNciHal_parsePacket(cmd_lxdebug,sizeof(cmd_lxdebug)/sizeof(cmd_lxdebug[0]));
+        }
+    } else {
+        NXPLOG_NCIHAL_E("Parser Library Not Available");
+    }
+}
diff --git a/halimpl/pn54x/hal/phNxpNciHal.h b/halimpl/pn54x/hal/phNxpNciHal.h
new file mode 100644
index 0000000..3839631
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal.h
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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>
+#include "NxpNfcCapability.h"
+
+/********************* Definitions and structures *****************************/
+#define MAX_RETRY_COUNT 5
+#define NCI_MAX_DATA_LEN 300
+#define NCI_POLL_DURATION 500
+#define NXP_STAG_TIMEOUT_BUF_LEN 0x04 /*FIXME:TODO:remove*/
+#define NXP_WIREDMODE_RESUME_TIMEOUT_LEN 0x04
+#define NFCC_DECIDES 00
+#define POWER_ALWAYS_ON 01
+#define LINK_ALWAYS_ON 02
+#undef P2P_PRIO_LOGIC_HAL_IMP
+
+enum {
+    HAL_NFC_ENABLE_I2C_FRAGMENTATION_EVT = 0x07,
+    HAL_NFC_POST_MIN_INIT_CPLT_EVT  = 0x08
+};
+
+enum {
+    HAL_NFC_IOCTL_P61_IDLE_MODE = 0,
+    HAL_NFC_IOCTL_P61_WIRED_MODE,
+    HAL_NFC_IOCTL_P61_PWR_MODE,
+    HAL_NFC_IOCTL_P61_DISABLE_MODE,
+    HAL_NFC_IOCTL_P61_ENABLE_MODE,
+    HAL_NFC_IOCTL_SET_BOOT_MODE,
+    HAL_NFC_IOCTL_GET_CONFIG_INFO,
+    HAL_NFC_IOCTL_CHECK_FLASH_REQ,
+    HAL_NFC_IOCTL_FW_DWNLD,
+    HAL_NFC_IOCTL_FW_MW_VER_CHECK,
+    HAL_NFC_IOCTL_DISABLE_HAL_LOG,
+    HAL_NFC_IOCTL_NCI_TRANSCEIVE,
+    HAL_NFC_IOCTL_P61_GET_ACCESS,
+    HAL_NFC_IOCTL_P61_REL_ACCESS,
+    HAL_NFC_IOCTL_ESE_CHIP_RST,
+    HAL_NFC_IOCTL_REL_SVDD_WAIT,
+    HAL_NFC_IOCTL_SET_JCP_DWNLD_ENABLE,
+    HAL_NFC_IOCTL_SET_JCP_DWNLD_DISABLE,
+    HAL_NFC_IOCTL_SET_NFC_SERVICE_PID,
+    HAL_NFC_IOCTL_GET_FEATURE_LIST
+};
+
+#define NCI_VERSION_2_0 0x20
+#define NCI_VERSION_1_1 0x11
+#define NCI_VERSION_1_0 0x10
+#define NCI_VERSION_UNKNOWN 0x00
+
+/*Mem alloc with 8 byte alignment*/
+#define size_align(sz) ((((sz)-1) | 7) + 1)
+#define nxp_malloc(size) malloc(size_align((size)))
+
+typedef void(phNxpNciHal_control_granted_callback_t)();
+
+/*ROM CODE VERSION FW*/
+#define FW_MOBILE_ROM_VERSION_PN551 0x10
+#define FW_MOBILE_ROM_VERSION_PN553 0x11
+#define FW_MOBILE_ROM_VERSION_PN548AD 0x10
+#define FW_MOBILE_ROM_VERSION_PN547C2 0x08
+#define FW_MOBILE_ROM_VERSION_PN557 0x12
+
+/* NCI Data */
+#define NCI_MT_CMD  0x20
+#define NCI_MT_RSP  0x40
+#define NCI_MT_NTF  0x60
+
+#define CORE_RESET_TRIGGER_TYPE_CORE_RESET_CMD_RECEIVED 0x02
+#define CORE_RESET_TRIGGER_TYPE_POWERED_ON              0x01
+#define NCI_MSG_CORE_RESET           0x00
+#define NCI_MSG_CORE_INIT            0x01
+#define NCI_MT_MASK                  0xE0
+#define NCI_OID_MASK                 0x3F
+typedef struct nci_data {
+  uint16_t len;
+  uint8_t p_data[NCI_MAX_DATA_LEN];
+} nci_data_t;
+
+typedef enum { HAL_STATUS_CLOSE = 0, HAL_STATUS_OPEN } 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)
+
+typedef struct phNxpNciInfo {
+  uint8_t   nci_version;
+  bool_t    wait_for_ntf;
+}phNxpNciInfo_t;
+/* 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;
+
+  bool_t is_wait_for_ce_ntf;
+
+  /* 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;
+  phNxpNciInfo_t nci_info;
+  uint8_t hal_boot_mode;
+  tNFC_chipType chipType;
+} phNxpNciHal_Control_t;
+
+typedef struct {
+  uint8_t fw_update_reqd;
+  uint8_t rf_update_reqd;
+} phNxpNciHal_FwRfupdateInfo_t;
+
+typedef struct phNxpNciClock {
+  bool_t isClockSet;
+  uint8_t p_rx_data[20];
+} phNxpNciClock_t;
+
+typedef struct phNxpNciRfSetting {
+  bool_t isGetRfSetting;
+  uint8_t p_rx_data[20];
+} phNxpNciRfSetting_t;
+
+/*set config management*/
+
+#define TOTAL_DURATION 0x00
+#define ATR_REQ_GEN_BYTES_POLL 0x29
+#define ATR_REQ_GEN_BYTES_LIS 0x61
+#define LEN_WT 0x60
+
+/*Whenever a new get cfg need to be sent,
+ * array must be updated with defined config type*/
+static const uint8_t get_cfg_arr[] = {TOTAL_DURATION, ATR_REQ_GEN_BYTES_POLL,
+                                      ATR_REQ_GEN_BYTES_LIS, LEN_WT};
+
+typedef enum {
+  EEPROM_RF_CFG,
+  EEPROM_FW_DWNLD,
+  EEPROM_WIREDMODE_RESUME_TIMEOUT,
+  EEPROM_ESE_SVDD_POWER,
+  EEPROM_ESE_POWER_EXT_PMU,
+  EEPROM_PROP_ROUTING,
+  EEPROM_ESE_SESSION_ID,
+  EEPROM_SWP1_INTF,
+  EEPROM_SWP1A_INTF,
+  EEPROM_SWP2_INTF
+} phNxpNci_EEPROM_request_type_t;
+
+typedef struct phNxpNci_EEPROM_info {
+  uint8_t request_mode;
+  phNxpNci_EEPROM_request_type_t request_type;
+  uint8_t update_mode;
+  uint8_t* buffer;
+  uint8_t bufflen;
+} phNxpNci_EEPROM_info_t;
+
+typedef struct phNxpNci_getCfg_info {
+  bool_t isGetcfg;
+  uint8_t total_duration[4];
+  uint8_t total_duration_len;
+  uint8_t atr_req_gen_bytes[48];
+  uint8_t atr_req_gen_bytes_len;
+  uint8_t atr_res_gen_bytes[48];
+  uint8_t atr_res_gen_bytes_len;
+  uint8_t pmid_wt[3];
+  uint8_t pmid_wt_len;
+} phNxpNci_getCfg_info_t;
+
+typedef enum {
+  NFC_FORUM_PROFILE,
+  EMV_CO_PROFILE,
+  INVALID_PROFILe
+} phNxpNciProfile_t;
+
+typedef enum {
+  NFC_NORMAL_BOOT_MODE,
+  NFC_FAST_BOOT_MODE,
+  NFC_OSU_BOOT_MODE
+} phNxpNciBootMode;
+/* 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 NCI_HAL_POST_MIN_INIT_CPLT_MSG 0xF02
+#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);
+NFCSTATUS phNxpNciHal_send_get_cfgs();
+int phNxpNciHal_write_unlocked(uint16_t data_len, const uint8_t* p_data);
+static int phNxpNciHal_fw_mw_ver_check();
+NFCSTATUS request_EEPROM(phNxpNci_EEPROM_info_t* mEEPROM_info);
+NFCSTATUS phNxpNciHal_send_nfcee_pwr_cntl_cmd(uint8_t type);
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_configFeatureList
+**
+** Description      Configures the featureList based on chip type
+**                  HW Version information number will provide chipType.
+**                  HW Version can be obtained from CORE_INIT_RESPONSE(NCI 1.0)
+**                  or CORE_RST_NTF(NCI 2.0)
+**
+** Parameters       CORE_INIT_RESPONSE/CORE_RST_NTF, len
+**
+** Returns          none
+*******************************************************************************/
+void phNxpNciHal_configFeatureList(uint8_t* init_rsp, uint16_t rsp_len);
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_getChipType
+**
+** Description      Gets the chipType which is configured during bootup
+**
+** Parameters       none
+**
+** Returns          chipType
+*******************************************************************************/
+tNFC_chipType phNxpNciHal_getChipType();
+#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..7cd95de
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal_Kovio.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <phNxpNciHal_Kovio.h>
+#include <phNxpLog.h>
+
+/* Timeout value to wait for RF INTF Activated NTF.*/
+#define KOVIO_TIMEOUT 1000
+#define KOVIO_ACT_NTF_TEMP_BUFF_LEN         \
+  64 /* 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 (((nfcFL.chipType != pn547C2) &&
+              ((p_ntf[5] == 0x81) && (p_ntf[6] == 0x70))) ||
+              ((nfcFL.chipType != pn547C2)
+                      && ((p_ntf[5] == 0x8A) && (p_ntf[6] == 0x77)))) {
+          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;
+      }
+
+      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..c8b516b
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal_Kovio.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef _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..8e34295
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal_NfcDepSWPrio.c
@@ -0,0 +1,551 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <phNxpNciHal_NfcDepSWPrio.h>
+#include <phNxpLog.h>
+#include <phNxpNciHal.h>
+
+/* Timeout value to wait for NFC-DEP detection.*/
+#define CUSTOM_POLL_TIMEOUT 160
+#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");
+  }
+  pthread_attr_destroy(&attr);
+  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");
+  }
+  pthread_attr_destroy(&attr);
+  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");
+  }
+  pthread_attr_destroy(&attr);
+  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");
+  pthread_exit(NULL);
+  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");
+  }
+  pthread_attr_destroy(&attr);
+  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..a1c27eb
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal_NfcDepSWPrio.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef _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..a3f37f8
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal_dta.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <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) {
+    // 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("DTA - 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..b5103a5
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal_dta.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _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..805fe9b
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal_ext.c
@@ -0,0 +1,1387 @@
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <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>
+#include <phDnldNfc.h>
+#include "phNxpNciHal_nciParser.h"
+
+/* Timeout value to wait for response from PN548AD */
+#define HAL_EXTNS_WRITE_RSP_TIMEOUT (2500)
+
+#undef P2P_PRIO_LOGIC_HAL_IMP
+
+/******************* Global variables *****************************************/
+extern phNxpNciHal_Control_t nxpncihal_ctrl;
+extern phNxpNciProfile_Control_t nxpprofile_ctrl;
+extern phNxpNci_getCfg_info_t* mGetCfg_info;
+
+extern int kovio_detected;
+extern int disable_kovio;
+extern int send_to_upper_kovio;
+extern uint32_t cleanup_timer;
+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;
+extern bool_t gParserCreated;
+uint16_t fw_maj_ver;
+uint16_t rom_version;
+/* local buffer to store CORE_INIT response */
+static uint32_t bCoreInitRsp[40];
+static uint32_t iCoreInitRspLen;
+
+static uint32_t bCoreRstNtf[40];
+static uint32_t iCoreRstNtfLen;
+
+extern uint32_t timeoutTimerId;
+extern uint32_t gSvddSyncOff_Delay; /*default delay*/
+tNfc_featureList nfcFL;
+extern NFCSTATUS read_retry();
+/************** HAL extension functions ***************************************/
+static void hal_extns_write_rsp_timeout_cb(uint32_t TimerId, void* pContext);
+
+/*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;
+static NFCSTATUS phNxpNciHal_ext_process_nfc_init_rsp(uint8_t* p_ntf, uint16_t* p_len);
+/*******************************************************************************
+**
+** 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;
+
+  /*parse and decode LxDebug Notifications*/
+    if(p_ntf[0] == 0x6F && (p_ntf[1] == 0x35 || p_ntf[1] == 0x36))
+    {
+        if(gParserCreated)
+            phNxpNciHal_parsePacket(p_ntf,*p_len);
+    }
+
+  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;
+      case 0x81:
+      case 0x8A:
+        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;
+      case 0x70:
+      case 0x77:
+        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;
+    }
+  }
+  phNxpNciHal_ext_process_nfc_init_rsp(p_ntf,p_len);
+  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("> Notification for 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;
+  } else if (p_ntf[0] == 0x00 && p_ntf[1] == 0x00 && icode_detected == 1) {
+    if (icode_send_eof == 3) {
+      icode_send_eof = 0;
+    }
+    if(nxpncihal_ctrl.nci_info.nci_version != NCI_VERSION_2_0)
+    {
+#if 0 /* this is work around added initially. not required now */
+      if (p_ntf[p_ntf[2] + 2] == 0x00) {
+        NXPLOG_NCIHAL_D("> Data of ISO-15693");
+        p_ntf[2]--;
+        (*p_len)--;
+      } else {
+        p_ntf[p_ntf[2] + 2] |= 0x01;
+      }
+#endif
+    }
+  } 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 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;
+  }
+if(nfcFL.nfccFL._NFCC_FORCE_NCI1_0_INIT == true) {
+  /*Handle NFCC2.0 in NCI2.0 Boot sequence*/
+  /*After TML sent Hard Reset, we may or may not receive this notification*/
+  if (p_ntf[0] == 0x60 && p_ntf[1] == 0x00 && p_ntf[2] == 0x09 &&
+           p_ntf[3] == 0x01) {
+    NXPLOG_NCIHAL_D("CORE_RESET_NTF 2 reason NFCC Powered ON received !");
+  } else if (p_ntf[0] == 0x40 && p_ntf[1] == 0x00 && p_ntf[2] == 0x03 &&
+             p_ntf[3] == 0x00 && p_ntf[4] == 0x10 && p_ntf[5] == 0x01 &&
+             *p_len == 0x06) {
+    NXPLOG_NCIHAL_D("CORE_RESET_RSP 1 received !");
+  }
+  /*After HAL sent Soft(NCI) Reset*/
+  /*NCI2.0 Controller only will send with this response after receiving
+     CORE_RESET_CMD*/
+  else if (p_ntf[0] == 0x40 && p_ntf[1] == 0x00 && p_ntf[2] == 0x01 &&
+           p_ntf[3] == 0x00 && *p_len == 0x04)  // if CORE_RST_RESPONSE ==
+                                                // STATUS_OK received means
+                                                // NCI2.0 controller else NCI1.0
+  {
+    NXPLOG_NCIHAL_D("CORE_RESET_RSP 2 received !");
+    nxpncihal_ctrl.is_wait_for_ce_ntf = true;
+  } else if (p_ntf[0] == 0x60 && p_ntf[1] == 0x00 && p_ntf[2] == 0x09 &&
+             p_ntf[3] == 0x02 && nxpncihal_ctrl.is_wait_for_ce_ntf) {
+    NXPLOG_NCIHAL_D("CORE_RESET_NTF 2 reason Command received !");
+    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];
+    iCoreRstNtfLen = *p_len;
+    memcpy(bCoreRstNtf, p_ntf, *p_len);
+    NXPLOG_NCIHAL_D("NxpNci> FW Version: %x.%x.%x", p_ntf[len - 2],
+                    p_ntf[len - 1], p_ntf[len]);
+    nxpncihal_ctrl.is_wait_for_ce_ntf = false;
+    if (nxpncihal_ctrl.hal_ext_enabled == 1) {
+      status = NFCSTATUS_FAILED;
+      return status;
+    }
+  } else if (p_ntf[0] == 0x60 && p_ntf[1] == 0x00 && p_ntf[2] == 0x09 &&
+             p_ntf[3] == 0x00 && nxpncihal_ctrl.is_wait_for_ce_ntf) {
+    NXPLOG_NCIHAL_E("CORE_RESET_NTF 2 reason Unrecoverable error received !");
+    phNxpNciHal_emergency_recovery();
+  } else if (p_ntf[0] == 0x40 && p_ntf[1] == 0x01 &&
+             nxpncihal_ctrl.is_wait_for_ce_ntf) {
+    NXPLOG_NCIHAL_D("CORE_INIT_RSP 2 received !");
+  }
+}
+/*Handle NFCC2.0 in NCI1.0 Boot sequence*/
+if (((nfcFL.nfccFL._NFCC_FORCE_NCI1_0_INIT) &&
+        ((p_ntf[0] == 0x40) && (p_ntf[1] == 0x01) &&
+                !nxpncihal_ctrl.is_wait_for_ce_ntf)) ||
+        ((!nfcFL.nfccFL._NFCC_FORCE_NCI1_0_INIT) &&
+                ((p_ntf[0] == 0x40) && (p_ntf[1] == 0x01)))) {
+    if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) {
+        NXPLOG_NCIHAL_D("CORE_INIT_RSP NCI2.0 received !");
+    } else {
+        NXPLOG_NCIHAL_D("CORE_INIT_RSP 1 received !");
+
+        if(!nxpncihal_ctrl.hal_open_status && nxpncihal_ctrl.nci_info.nci_version != NCI_VERSION_2_0) {
+            phNxpNciHal_configFeatureList(p_ntf,*p_len);
+        }
+        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]);
+        NXPLOG_NCIHAL_D("NxpNci> Model id: %x", p_ntf[len - 3] >> 4);
+        fw_maj_ver = p_ntf[len - 1];
+        rom_version = p_ntf[len - 2];
+        /* Before FW version: 10.01.12, products are PN548c2(for model id = 0) and
+         * PN66T(for model id = 1)*/
+        if (p_ntf[len - 2] == 0x10) {
+            if ((p_ntf[len - 1] < 0x01) |
+                    ((p_ntf[len - 1] == 0x01) &&
+                            (p_ntf[len] <= 0x11)))  // for FW < 10.01.12
+            {
+                NXPLOG_NCIHAL_D("NxpNci> Model ID: %x", p_ntf[len - 3] >> 4);
+                if (0x01 == (p_ntf[len - 3] >> 4)) {
+                    NXPLOG_NCIHAL_D("NxpNci> Product: PN66T");
+                } else {
+                    NXPLOG_NCIHAL_D("NxpNci> Product: PN548C2");
+                }
+            } else if ((p_ntf[len - 1] == 0x01) &&
+                    (p_ntf[len] >= 0x12))  // for FW >= 10.01.12
+            {
+                NXPLOG_NCIHAL_D("NxpNci> Model ID: %x", p_ntf[len - 3] >> 4);
+                /* From FW version: 10.01.12, product names based on Hardware Version
+                 * number */
+                switch (p_ntf[len - 3]) {
+                case 0x08:
+                    NXPLOG_NCIHAL_D("NxpNci> Product: PN546");
+                    break;
+                case 0x18:
+                    NXPLOG_NCIHAL_D("NxpNci> Product: PN66T");
+                    break;
+                case 0x28:
+                    NXPLOG_NCIHAL_D("NxpNci> Product: PN548C2");
+                    break;
+                case 0x38:
+                    NXPLOG_NCIHAL_D("NxpNci> Product: PN66U");
+                    break;
+                case 0x48:
+                    NXPLOG_NCIHAL_D("NxpNci> Product: NQ210");
+                    break;
+                case 0x58:
+                    NXPLOG_NCIHAL_D("NxpNci> Product: NQ220");
+                    break;
+                case 0x68:
+                    NXPLOG_NCIHAL_D("NxpNci> Product: NPC300");
+                    break;
+                case 0x78:
+                    NXPLOG_NCIHAL_D("NxpNci> Product: NPC320");
+                    break;
+                case 0x88:
+                    NXPLOG_NCIHAL_D("NxpNci> Product: PN7150");
+                    break;
+                case 0x98:
+                    NXPLOG_NCIHAL_D("NxpNci> Product: PN548C3");
+                    break;
+                default:
+                    NXPLOG_NCIHAL_D("NxpNci> Product: Invalid");
+                    break;
+                }
+            }
+        } else {
+            /* Do Nothing */
+        }
+    }
+}
+
+  else if (p_ntf[0] == 0x42 && p_ntf[1] == 0x00 && ee_disc_done == 0x01) {
+    NXPLOG_NCIHAL_D(
+        "As done with the NFCEE discovery so setting it to zero  - "
+        "NFCEE_DISCOVER_RSP");
+    if (p_ntf[4] == 0x01) {
+      p_ntf[4] = 0x00;
+
+      ee_disc_done = 0x00;
+    }
+  } 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 ((nfcFL.chipType == pn547C2) &&
+          (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 the 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;
+      }
+  }
+  /*
+  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_ext_process_nfc_init_rsp
+ *
+ * Description      This function is used to process the HAL NFC core reset rsp
+ *                  and ntf and core init rsp of NCI 1.0 or NCI2.0 and update NCI version.
+ *                  It also handles error response such as core_reset_ntf with
+ *                  error status in both NCI2.0 and NCI1.0.
+ *
+ * Returns          Returns NFCSTATUS_SUCCESS if parsing response is successful or
+ *                  returns failure.
+ *
+******************************************************************************/
+static NFCSTATUS phNxpNciHal_ext_process_nfc_init_rsp(uint8_t* p_ntf, uint16_t* p_len) {
+   NFCSTATUS status = NFCSTATUS_SUCCESS;
+   uint8_t nfcdep_detected = 0x00;
+    /* Parsing CORE_RESET_RSP and CORE_RESET_NTF to update NCI version.*/
+    if(p_ntf == NULL || *p_len == 0x00) {
+      return NFCSTATUS_FAILED;
+    }
+    if (p_ntf[0] == NCI_MT_RSP && ((p_ntf[1] & NCI_OID_MASK) == NCI_MSG_CORE_RESET)) {
+      if (p_ntf[2] == 0x01 && p_ntf[3] == 0x00) {
+        NXPLOG_NCIHAL_D("CORE_RESET_RSP NCI2.0");
+        if(nxpncihal_ctrl.hal_ext_enabled == TRUE) {
+          nxpncihal_ctrl.nci_info.wait_for_ntf = TRUE;
+        }
+      } else if(p_ntf[2] == 0x03 && p_ntf[3] == 0x00){
+          NXPLOG_NCIHAL_D("CORE_RESET_RSP NCI1.0");
+          nxpncihal_ctrl.nci_info.nci_version = p_ntf[4];
+      }
+    } else if (p_ntf[0] == NCI_MT_NTF && ((p_ntf[1] & NCI_OID_MASK) == NCI_MSG_CORE_RESET)) {
+        if(p_ntf[3] == CORE_RESET_TRIGGER_TYPE_CORE_RESET_CMD_RECEIVED ||
+           p_ntf[3] == CORE_RESET_TRIGGER_TYPE_POWERED_ON) {
+          NXPLOG_NCIHAL_D("CORE_RESET_NTF NCI2.0 reason CORE_RESET_CMD received !");
+          nxpncihal_ctrl.nci_info.nci_version  = p_ntf[5];
+          phNxpNciHal_configFeatureList(p_ntf,*p_len);
+          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];
+          fw_maj_ver = p_ntf[len - 1];
+          rom_version = p_ntf[len - 2];
+          NXPLOG_NCIHAL_D ("NxpNci> FW Version: %x.%x.%x", p_ntf[len-2], p_ntf[len-1], p_ntf[len]);
+          }else {
+              if(nfcFL.chipType == pn548C2) {
+                  if (nfcdep_detected &&
+                          !(p_ntf[2] == 0x06 && p_ntf[3] == 0xA0 && p_ntf[4] == 0x00 &&
+                                  ((p_ntf[5] == 0xC9 && p_ntf[6] == 0x95 && p_ntf[7] == 0x00 &&
+                                          p_ntf[8] == 0x00) ||
+                                          (p_ntf[5] == 0x07 && p_ntf[6] == 0x39 && p_ntf[7] == 0xF2 &&
+                                                  p_ntf[8] == 0x00)))) {
+                      nfcdep_detected = 0x00;
+                  }
+              }
+        phNxpNciHal_emergency_recovery();
+        status = NFCSTATUS_FAILED;
+      } /* Parsing CORE_INIT_RSP*/
+    } else if (p_ntf[0] == NCI_MT_RSP && ((p_ntf[1] & NCI_OID_MASK) == NCI_MSG_CORE_INIT)) {
+      if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) {
+        NXPLOG_NCIHAL_D("CORE_INIT_RSP NCI2.0 received !");
+      } else {
+        NXPLOG_NCIHAL_D("CORE_INIT_RSP NCI1.0 received !");
+        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]);
+        fw_maj_ver = p_ntf[len - 1];
+        rom_version = p_ntf[len - 2];
+      }
+    }
+    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;
+  uint8_t get_cfg_value_index = 0x07, get_cfg_value_len = 0x00,
+          get_cfg_type = 0x05;
+  /* 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;
+  }
+  /* Start timer to wait for NTF*/
+  if (nxpncihal_ctrl.nci_info.wait_for_ntf == TRUE) {
+    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;
+    }
+    if (SEM_WAIT(nxpncihal_ctrl.ext_cb_data)) {
+      NXPLOG_NCIHAL_E("p_hal_ext->ext_cb_data.sem semaphore error");
+      /* Stop Timer */
+      status = phOsalNfc_Timer_Stop(timeoutTimerId);
+      goto clean_and_return;
+    }
+    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");
+
+  if ((mGetCfg_info != NULL) && (mGetCfg_info->isGetcfg == true) &&
+      (nxpncihal_ctrl.p_rx_data[0] == 0x40) &&
+      (nxpncihal_ctrl.p_rx_data[1] == 0x03) &&
+      (nxpncihal_ctrl.p_rx_data[3] == NFCSTATUS_SUCCESS)) {
+    get_cfg_value_len = nxpncihal_ctrl.rx_data_len - get_cfg_value_index;
+    switch (nxpncihal_ctrl.p_rx_data[get_cfg_type]) {
+      case TOTAL_DURATION:
+        memcpy(&mGetCfg_info->total_duration,
+               nxpncihal_ctrl.p_rx_data + get_cfg_value_index,
+               get_cfg_value_len);
+        mGetCfg_info->total_duration_len = get_cfg_value_len;
+        break;
+
+      case ATR_REQ_GEN_BYTES_POLL:
+        memcpy(&mGetCfg_info->atr_req_gen_bytes,
+               nxpncihal_ctrl.p_rx_data + get_cfg_value_index,
+               get_cfg_value_len);
+        mGetCfg_info->atr_req_gen_bytes_len = (uint8_t)get_cfg_value_len;
+        break;
+
+      case ATR_REQ_GEN_BYTES_LIS:
+        memcpy(&mGetCfg_info->atr_res_gen_bytes,
+               nxpncihal_ctrl.p_rx_data + get_cfg_value_index,
+               get_cfg_value_len);
+        mGetCfg_info->atr_res_gen_bytes_len = (uint8_t)get_cfg_value_len;
+        break;
+
+      case LEN_WT:
+        memcpy(&mGetCfg_info->pmid_wt,
+               nxpncihal_ctrl.p_rx_data + get_cfg_value_index,
+               get_cfg_value_len);
+        mGetCfg_info->pmid_wt_len = (uint8_t)get_cfg_value_len;
+        ;
+        break;
+      default:
+        // do nothing
+        break;
+    }
+  }
+
+  status = NFCSTATUS_SUCCESS;
+
+clean_and_return:
+  phNxpNciHal_cleanup_cb_data(&nxpncihal_ctrl.ext_cb_data);
+
+  nxpncihal_ctrl.nci_info.wait_for_ntf = FALSE;
+  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;
+  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] = 0x40;
+    p_rsp_data[1] = 0x03;
+    p_rsp_data[2] = 0x01;
+    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;
+  }
+  else if ((nfcFL.eseFL._ESE_SVDD_SYNC) &&
+          (p_cmd_data[0] == 0x2F && p_cmd_data[1] == 0x31 &&
+                  p_cmd_data[2] == 0x01 && p_cmd_data[3] == 0x00)) {
+    NXPLOG_NCIHAL_D("SVDD Sync Off Command - delay it by %d ms",
+                    gSvddSyncOff_Delay);
+    usleep(gSvddSyncOff_Delay * 1000);
+  }
+  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 (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 if (p_cmd_data[3] == 0x81 && p_cmd_data[4] == 0x01 &&
+             p_cmd_data[5] == 0x03) {
+    NXPLOG_NCIHAL_D("> Going through the set host list");
+    if(nfcFL.chipType != 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;
+    }
+    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;
+    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("> Dirty Set Config ");
+    //        phNxpNciHal_print_packet("SEND", p_cmd_data, *cmd_len);
+  }
+  //    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("> 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;
+  }
+
+  // 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("> 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;
+  }
+#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 ("> 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;
+    }
+
+    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 ("> 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;
+    }
+#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");
+    }
+  }
+
+  if ((nfcFL.chipType == pn548C2) &&
+          (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02)) {
+      uint8_t temp;
+      uint8_t* p = p_cmd_data + 4;
+      uint8_t* end = p_cmd_data + *cmd_len;
+      while (p < end) {
+          if (*p == 0x53)  // LF_T3T_FLAGS
+          {
+              NXPLOG_NCIHAL_D("> Going through workaround - LF_T3T_FLAGS swap");
+              temp = *(p + 3);
+              *(p + 3) = *(p + 2);
+              *(p + 2) = temp;
+              NXPLOG_NCIHAL_D("> Going through workaround - LF_T3T_FLAGS - End");
+              status = NFCSTATUS_SUCCESS;
+              break;
+          }
+          if (*p == 0xA0) {
+              p += *(p + 2) + 3;
+          } else {
+              p += *(p + 1) + 2;
+          }
+      }
+  }
+
+  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         phNxpNciHal_send_ext_cmd_ntf
+ *
+ * Description      This function send the extension command to NFCC. No
+ *                  response is checked by this function but it waits for
+ *                  the response. Also it can wait for notification
+ *
+ * Returns          Returns NFCSTATUS_SUCCESS if sending cmd is successful and
+ *                  response is received followed by notification.
+ *
+ ******************************************************************************/
+NFCSTATUS phNxpNciHal_send_ext_cmd_ntf(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);
+  if (NFCSTATUS_FAILED != status) {
+    /* 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;
+    }
+
+    /* By default callback data status set success.
+     * This will be set failed by timer callback
+     * when timeout is there */
+    nxpncihal_ctrl.ext_cb_data.status = NFCSTATUS_SUCCESS;
+
+    /*check whether to wait for notification*/
+    if (phNxpNciHal_check_wait_for_ntf()) {
+      /* Start timer after writing the data*/
+      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 notification */
+      NXPLOG_NCIHAL_D("Waiting for notification...");
+      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;
+      }
+
+      /*Checking the status if timeout happens*/
+      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 notification...");
+      status = NFCSTATUS_SUCCESS;
+
+    clean_and_return:
+      phNxpNciHal_cleanup_cb_data(&nxpncihal_ctrl.ext_cb_data);
+    }
+  }
+
+  HAL_DISABLE_EXT();
+
+  return status;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_check_wait_for_ntf
+ *
+ * Description      This function checks the condition provided by the user to
+ *                  wait for notification or not.
+ *
+ * Returns          Returns true/false.
+ *
+ ******************************************************************************/
+bool_t phNxpNciHal_check_wait_for_ntf() {
+  bool_t status;
+  if (nxpncihal_ctrl.is_wait_for_ce_ntf) {
+    status = true;
+  } else {
+    status = false;
+  }
+  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;
+}
+
+/*******************************************************************************
+ **
+ ** Function:        request_EEPROM()
+ **
+ ** Description:     get and set EEPROM data
+ **                  In case of request_modes GET_EEPROM_DATA or
+ *SET_EEPROM_DATA,
+ **                   1.caller has to pass the buffer and the length of data
+ *required
+ **                     to be read/written.
+ **                   2.Type of information required to be read/written
+ **                     (Example - EEPROM_RF_CFG)
+ **
+ ** Returns:         Returns NFCSTATUS_SUCCESS if sending cmd is successful and
+ **                  status failed if not succesful
+ **
+ *******************************************************************************/
+NFCSTATUS request_EEPROM(phNxpNci_EEPROM_info_t* mEEPROM_info) {
+  NXPLOG_NCIHAL_D(
+      "%s Enter  request_type : 0x%02x,  request_mode : 0x%02x,  bufflen : "
+      "0x%02x",
+      __func__, mEEPROM_info->request_type, mEEPROM_info->request_mode,
+      mEEPROM_info->bufflen);
+  NFCSTATUS status = NFCSTATUS_FAILED;
+  uint8_t retry_cnt = 0;
+  uint8_t getCfgStartIndex = 0x08;
+  uint8_t setCfgStartIndex = 0x07;
+  uint8_t memIndex = 0x00;
+  uint8_t fieldLen = 0x01;  // Memory field len 1bytes
+  char addr[2] = {0};
+  uint8_t cur_value = 0, len = 5;
+  uint8_t b_position = 0;
+  bool_t update_req = false;
+  uint8_t set_cfg_cmd_len = 0;
+  uint8_t* set_cfg_eeprom, *base_addr;
+
+  mEEPROM_info->update_mode = BITWISE;
+
+  switch (mEEPROM_info->request_type) {
+    case EEPROM_RF_CFG:
+      memIndex = 0x00;
+      fieldLen = 0x20;
+      len = fieldLen + 4;  // 4 - numParam+2add+val
+      addr[0] = 0xA0;
+      addr[1] = 0x14;
+      mEEPROM_info->update_mode = BYTEWISE;
+      break;
+
+    case EEPROM_FW_DWNLD:
+      fieldLen = 0x20;
+      memIndex = 0x0C;
+      len = fieldLen + 4;
+      addr[0] = 0xA0;
+      addr[1] = 0x0F;
+      break;
+
+    case EEPROM_WIREDMODE_RESUME_TIMEOUT:
+      mEEPROM_info->update_mode = BYTEWISE;
+      memIndex = 0x00;
+      fieldLen = 0x04;
+      len = fieldLen + 4;
+      addr[0] = 0xA0;
+      addr[1] = 0xFC;
+      break;
+
+    case EEPROM_ESE_SVDD_POWER:
+      b_position = 0;
+      memIndex = 0x00;
+      addr[0] = 0xA0;
+      addr[1] = 0xF2;
+      break;
+    case EEPROM_ESE_POWER_EXT_PMU:
+      mEEPROM_info->update_mode = BYTEWISE;
+      memIndex = 0x00;
+      addr[0] = 0xA0;
+      addr[1] = 0xD7;
+      break;
+
+    case EEPROM_PROP_ROUTING:
+      b_position = 7;
+      memIndex = 0x00;
+      addr[0] = 0xA0;
+      addr[1] = 0x98;
+      break;
+
+    case EEPROM_ESE_SESSION_ID:
+      b_position = 0;
+      memIndex = 0x00;
+      addr[0] = 0xA0;
+      addr[1] = 0xEB;
+      break;
+
+    case EEPROM_SWP1_INTF:
+      b_position = 0;
+      memIndex = 0x00;
+      addr[0] = 0xA0;
+      addr[1] = 0xEC;
+      break;
+
+    case EEPROM_SWP1A_INTF:
+      b_position = 0;
+      memIndex = 0x00;
+      addr[0] = 0xA0;
+      addr[1] = 0xD4;
+      break;
+    case EEPROM_SWP2_INTF:
+      b_position = 0;
+      memIndex = 0x00;
+      addr[0] = 0xA0;
+      addr[1] = 0xED;
+      break;
+    default:
+      ALOGE("No valid request information found");
+      break;
+  }
+
+  uint8_t get_cfg_eeprom[6] = {
+      0x20,    0x03,  // get_cfg header
+      0x03,           // len of following value
+      0x01,           // Num Parameters
+      addr[0],        // First byte of Address
+      addr[1]         // Second byte of Address
+  };
+
+  uint8_t set_cfg_cmd_hdr[7] = {
+      0x20,    0x02,  // set_cfg header
+      len,            // len of following value
+      0x01,           // Num Param
+      addr[0],        // First byte of Address
+      addr[1],        // Second byte of Address
+      fieldLen        // Data len
+  };
+
+  set_cfg_cmd_len = sizeof(set_cfg_cmd_hdr) + fieldLen;
+  set_cfg_eeprom = (uint8_t*)malloc(set_cfg_cmd_len);
+  if (set_cfg_eeprom == NULL) {
+    ALOGE("memory allocation failed");
+    return status;
+  }
+  base_addr = set_cfg_eeprom;
+  memset(set_cfg_eeprom, 0, set_cfg_cmd_len);
+  memcpy(set_cfg_eeprom, set_cfg_cmd_hdr, sizeof(set_cfg_cmd_hdr));
+
+retryget:
+  status = phNxpNciHal_send_ext_cmd(sizeof(get_cfg_eeprom), get_cfg_eeprom);
+  if (status == NFCSTATUS_SUCCESS) {
+    status = nxpncihal_ctrl.p_rx_data[3];
+    if (status != NFCSTATUS_SUCCESS) {
+      ALOGE("failed to get requested memory address");
+    } else if (mEEPROM_info->request_mode == GET_EEPROM_DATA) {
+      memcpy(mEEPROM_info->buffer,
+             nxpncihal_ctrl.p_rx_data + getCfgStartIndex + memIndex,
+             mEEPROM_info->bufflen);
+    } else if (mEEPROM_info->request_mode == SET_EEPROM_DATA) {
+      // Clear the buffer first
+      memset(set_cfg_eeprom + setCfgStartIndex, 0x00,
+             (set_cfg_cmd_len - setCfgStartIndex));
+
+      // copy get config data into set_cfg_eeprom
+      memcpy(set_cfg_eeprom + setCfgStartIndex,
+             nxpncihal_ctrl.p_rx_data + getCfgStartIndex, fieldLen);
+      if (mEEPROM_info->update_mode == BITWISE) {
+        cur_value =
+            (set_cfg_eeprom[setCfgStartIndex + memIndex] >> b_position) & 0x01;
+        if (cur_value != mEEPROM_info->buffer[0]) {
+          update_req = true;
+          if (mEEPROM_info->buffer[0] == 1) {
+            set_cfg_eeprom[setCfgStartIndex + memIndex] |= (1 << b_position);
+          } else if (mEEPROM_info->buffer[0] == 0) {
+            set_cfg_eeprom[setCfgStartIndex + memIndex] &= (~(1 << b_position));
+          }
+        }
+      } else if (mEEPROM_info->update_mode == BYTEWISE) {
+        if (memcmp(set_cfg_eeprom + setCfgStartIndex + memIndex,
+                   mEEPROM_info->buffer, mEEPROM_info->bufflen)) {
+          update_req = true;
+          memcpy(set_cfg_eeprom + setCfgStartIndex + memIndex,
+                 mEEPROM_info->buffer, mEEPROM_info->bufflen);
+        }
+      } else {
+        ALOGE("%s, invalid update mode", __func__);
+      }
+
+      if (update_req) {
+      // do set config
+      retryset:
+        status = phNxpNciHal_send_ext_cmd(set_cfg_cmd_len, set_cfg_eeprom);
+        if (status != NFCSTATUS_SUCCESS && retry_cnt < 3) {
+          retry_cnt++;
+          ALOGE("Set Cfg Retry cnt=%x", retry_cnt);
+          goto retryset;
+        }
+      } else {
+        ALOGD("%s: values are same no update required", __func__);
+      }
+    }
+  } else if (retry_cnt < 3) {
+    retry_cnt++;
+    ALOGE("Get Cfg Retry cnt=%x", retry_cnt);
+    goto retryget;
+  }
+
+  if (base_addr != NULL) {
+    free(base_addr);
+    base_addr = NULL;
+  }
+  retry_cnt = 0;
+  return status;
+}
+
+/*******************************************************************************
+ **
+ ** Function:        phNxpNciHal_CheckFwRegFlashRequired()
+ **
+ ** Description:     Updates FW and Reg configurations if required
+ **
+ ** Returns:         status
+ **
+ ********************************************************************************/
+int phNxpNciHal_CheckFwRegFlashRequired(uint8_t* fw_update_req,
+                                        uint8_t* rf_update_req) {
+  int status = NFCSTATUS_OK;
+  UNUSED(rf_update_req);
+  NXPLOG_NCIHAL_D("phNxpNciHal_CheckFwRegFlashRequired() : enter");
+  status = phDnldNfc_InitImgInfo();
+  NXPLOG_NCIHAL_D("FW version of the libpn5xx.so binary = 0x%x", wFwVer);
+  NXPLOG_NCIHAL_D("FW version found on the device = 0x%x", wFwVerRsp);
+  /* Consider for each chip type */
+  *fw_update_req = (((wFwVerRsp & 0x0000FFFF) != wFwVer) ? true : false);
+
+  if (false == *fw_update_req) {
+    NXPLOG_NCIHAL_D("FW update not required");
+    phDnldNfc_ReSetHwDevHandle();
+  }
+
+  NXPLOG_NCIHAL_D("phNxpNciHal_CheckFwRegFlashRequired() : exit - status = %x ",
+                  status);
+  return status;
+}
diff --git a/halimpl/pn54x/hal/phNxpNciHal_ext.h b/halimpl/pn54x/hal/phNxpNciHal_ext.h
new file mode 100644
index 0000000..946b60c
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal_ext.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef _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_send_ext_cmd_ntf(uint16_t cmd_len, uint8_t* p_cmd);
+bool_t phNxpNciHal_check_wait_for_ntf(void);
+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/hal/phNxpNciHal_nciParser.c b/halimpl/pn54x/hal/phNxpNciHal_nciParser.c
new file mode 100644
index 0000000..19d2d66
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal_nciParser.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2017 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_nciParser.h"
+
+#include <dlfcn.h>
+#include <string.h>
+
+#include "phNxpLog.h"
+
+typedef void* tNCI_PARSER_INSTANCE;
+typedef void* tNCI_PARSER_LIB_HANDLE;
+
+typedef struct {
+    tNCI_PARSER_INSTANCE   pvInstance;
+    tNCI_PARSER_LIB_HANDLE pvHandle;
+    tNCI_PARSER_FUNCTIONS  sEntryFuncs;
+} sParserContext_t;
+
+static sParserContext_t sParserContext;
+
+unsigned char
+phNxpNciHal_initParser() {
+
+    sParserContext_t *psContext = &sParserContext;
+
+    memset(&psContext->sEntryFuncs,0,sizeof(psContext->sEntryFuncs));
+
+    psContext->pvInstance = NULL;
+    psContext->sEntryFuncs.createParser = NULL;
+    psContext->sEntryFuncs.initParser = NULL;
+    psContext->sEntryFuncs.deinitParser = NULL;
+    psContext->sEntryFuncs.destroyParser = NULL;
+    psContext->sEntryFuncs.parsePacket = NULL;
+
+    NXPLOG_NCIHAL_D("%s: enter", __FUNCTION__);
+
+    psContext->pvHandle = dlopen(NXP_NCI_PARSER_PATH, RTLD_NOW);
+    if (!psContext->pvHandle)
+    {
+        NXPLOG_NCIHAL_E("%s: dlopen failed !!!", __FUNCTION__);
+        return FALSE;
+    }
+
+    psContext->sEntryFuncs.createParser = dlsym(psContext->pvHandle, "native_createParser");
+    if (psContext->sEntryFuncs.createParser == NULL)
+    {
+        NXPLOG_NCIHAL_E("%s: dlsym native_createParser failed !!!", __FUNCTION__);
+        return FALSE;
+    }
+
+    psContext->sEntryFuncs.destroyParser = dlsym(psContext->pvHandle, "native_destroyParser");
+    if (psContext->sEntryFuncs.destroyParser == NULL)
+    {
+        NXPLOG_NCIHAL_E("%s: dlsym native_destroyParser failed !!!", __FUNCTION__);
+        return FALSE;
+    }
+
+    psContext->sEntryFuncs.initParser = dlsym(psContext->pvHandle, "native_initParser");
+    if (psContext->sEntryFuncs.initParser == NULL)
+    {
+        NXPLOG_NCIHAL_E("%s: dlsym native_initParser failed !!!", __FUNCTION__);
+        return FALSE;
+    }
+
+    psContext->sEntryFuncs.deinitParser = dlsym(psContext->pvHandle, "native_deinitParser");
+    if (psContext->sEntryFuncs.deinitParser == NULL)
+    {
+        NXPLOG_NCIHAL_E("%s: dlsym native_deinitParser failed !!!", __FUNCTION__);
+        return FALSE;
+    }
+
+    psContext->sEntryFuncs.parsePacket = dlsym(psContext->pvHandle, "native_parseNciMsg");
+    if (psContext->sEntryFuncs.parsePacket == NULL)
+    {
+        NXPLOG_NCIHAL_E("%s: dlsym native_parseNciMsg failed !!!", __FUNCTION__);
+        return FALSE;
+    }
+
+    psContext->pvInstance = (*(psContext->sEntryFuncs.createParser))();
+
+    if(psContext->pvInstance != NULL)
+    {
+        (*(psContext->sEntryFuncs.initParser))(psContext->pvInstance);
+    }
+    else
+    {
+        NXPLOG_NCIHAL_E("Parser Creation Failed !!!");
+        return FALSE;
+    }
+
+    NXPLOG_NCIHAL_D("%s: exit", __FUNCTION__);
+
+    return TRUE;
+}
+
+void
+phNxpNciHal_parsePacket(unsigned char *pNciPkt, unsigned short pktLen) {
+
+    sParserContext_t *psContext = &sParserContext;
+
+    NXPLOG_NCIHAL_D("%s: enter", __FUNCTION__);
+
+    if((pNciPkt == NULL) || (pktLen == 0))
+    {
+        NXPLOG_NCIHAL_E("Invalid NCI Packet");
+        return;
+    }
+
+    if(psContext->pvInstance != NULL)
+    {
+        (*(psContext->sEntryFuncs.parsePacket))(psContext->pvInstance, pNciPkt, pktLen);
+    }
+    else
+    {
+        NXPLOG_NCIHAL_E("Invalid Handle");
+    }
+    NXPLOG_NCIHAL_D("%s: exit", __FUNCTION__);
+}
+
+void phNxpNciHal_deinitParser() {
+
+    sParserContext_t *psContext = &sParserContext;
+
+    NXPLOG_NCIHAL_D("%s: enter", __FUNCTION__);
+
+    if(psContext->pvInstance != NULL)
+    {
+        (*(psContext->sEntryFuncs.deinitParser))(psContext->pvInstance);
+
+        (*(psContext->sEntryFuncs.destroyParser))(psContext->pvInstance);
+    }
+    else
+    {
+        NXPLOG_NCIHAL_E("Invalid Handle");
+    }
+
+    if(psContext->pvHandle != NULL)
+    {
+        dlclose(psContext->pvHandle);
+    }
+
+    NXPLOG_NCIHAL_D("%s: exit", __FUNCTION__);
+}
diff --git a/halimpl/pn54x/hal/phNxpNciHal_nciParser.h b/halimpl/pn54x/hal/phNxpNciHal_nciParser.h
new file mode 100644
index 0000000..bffbbb3
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal_nciParser.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+/*
+ * phNxpNciHal_nciParser.h
+ */
+
+#ifndef _PHNXPNCIHAL_NCIPARSER_H_
+#define _PHNXPNCIHAL_NCIPARSER_H_
+
+#define NXP_NCI_PARSER_PATH "/system/lib64/libnxp_nciparser.so"
+
+typedef void* (*tHAL_API_NATIVE_CREATE_PARSER)();
+typedef void  (*tHAL_API_NATIVE_DESTROY_PARSER)(void*);
+typedef void  (*tHAL_API_NATIVE_INIT_PARSER)(void*);
+typedef void  (*tHAL_API_NATIVE_DEINIT_PARSER)(void*);
+typedef void  (*tHAL_API_NATIVE_PARSE_PACKET)(void*,unsigned char *, unsigned short);
+
+typedef struct
+{
+    tHAL_API_NATIVE_CREATE_PARSER  createParser;
+    tHAL_API_NATIVE_DESTROY_PARSER destroyParser;
+    tHAL_API_NATIVE_INIT_PARSER    initParser;
+    tHAL_API_NATIVE_DEINIT_PARSER  deinitParser;
+    tHAL_API_NATIVE_PARSE_PACKET   parsePacket;
+} tNCI_PARSER_FUNCTIONS;
+
+unsigned char phNxpNciHal_initParser();
+void phNxpNciHal_parsePacket(unsigned char*, unsigned short);
+void phNxpNciHal_deinitParser();
+
+#endif /* _PHNXPNCIHAL_NCIPARSER_H_ */
diff --git a/halimpl/pn54x/inc/Nxp_Features.h b/halimpl/pn54x/inc/Nxp_Features.h
new file mode 100644
index 0000000..84ab3dc
--- /dev/null
+++ b/halimpl/pn54x/inc/Nxp_Features.h
@@ -0,0 +1,518 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2012-2016 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * NXP features declarations
+ */
+#include <unistd.h>
+#include <string.h>
+#ifndef NXP_FEATURES_H
+#define NXP_FEATURES_H
+
+#define STRMAX_1 40
+#define STRMAX_2 100
+#define FW_DLL_ROOT_DIR "/system/vendor/firmware/"
+#define FW_DLL_EXTENSION ".so"
+
+#define FW_MOBILE_MAJOR_NUMBER_PN553 0x01
+#define FW_MOBILE_MAJOR_NUMBER_PN551 0x05
+#define FW_MOBILE_MAJOR_NUMBER_PN48AD 0x01
+
+#define NFA_EE_MAX_EE_SUPPORTED 4
+
+#define JCOP_VER_3_1    1
+#define JCOP_VER_3_2    2
+#define JCOP_VER_3_3    3
+#define JCOP_VER_4_0    4
+
+typedef enum {
+    pn547C2 = 0x01,
+    pn65T,
+    pn548C2,
+    pn66T,
+    pn551,
+    pn67T,
+    pn553,
+    pn80T,
+    pn557,
+    pn81T
+}tNFC_chipType;
+
+/*
+ * TODO renaming
+ * */
+typedef struct {
+    /*Flags common to all chip types*/
+    uint8_t _NXP_NFCC_EMPTY_DATA_PACKET                     : 1;
+    uint8_t _GEMALTO_SE_SUPPORT                             : 1;
+    uint8_t _NFCC_I2C_READ_WRITE_IMPROVEMENT                : 1;
+    uint8_t _NFCC_MIFARE_TIANJIN                            : 1;
+    uint8_t _NFCC_MW_RCVRY_BLK_FW_DNLD                      : 1;
+    uint8_t _NFCC_DYNAMIC_DUAL_UICC                         : 1;
+    uint8_t _NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH              : 1;
+    uint8_t _NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH           : 1;
+    uint8_t _NFCC_FW_WA                                     : 1;
+    uint8_t _NFCC_FORCE_NCI1_0_INIT                         : 1;
+    uint8_t _NFCC_ROUTING_BLOCK_BIT                         : 1;
+    uint8_t _NFCC_SPI_FW_DOWNLOAD_SYNC                      : 1;
+    uint8_t _HW_ANTENNA_LOOP4_SELF_TEST                     : 1;
+    uint8_t _NFCEE_REMOVED_NTF_RECOVERY                     : 1;
+    uint8_t _NFCC_FORCE_FW_DOWNLOAD                         : 1;
+    uint8_t _UICC_CREATE_CONNECTIVITY_PIPE                  : 1;
+    uint8_t _NFCC_AID_MATCHING_PLATFORM_CONFIG              : 1;
+    uint8_t _NFCC_ROUTING_BLOCK_BIT_PROP                    : 1;
+    uint8_t _NXP_NFC_UICC_ETSI12                            : 1;
+    uint8_t _NFA_EE_MAX_EE_SUPPORTED                        : 3;
+}tNfc_nfccFeatureList;
+/*
+ * TODO renaming
+ * */
+typedef struct {
+    uint8_t _ESE_EXCLUSIVE_WIRED_MODE                    : 2;
+    uint8_t _ESE_WIRED_MODE_RESUME                       : 2;
+    uint8_t _ESE_WIRED_MODE_TIMEOUT                      : 2;
+    uint8_t _ESE_PN67T_RESET                             : 2;
+    uint8_t _ESE_APDU_GATE_RESET                         : 2;
+    uint8_t _ESE_WIRED_MODE_DISABLE_DISCOVERY            : 1;
+    uint8_t _LEGACY_APDU_GATE                            : 1;
+    uint8_t _TRIPLE_MODE_PROTECTION                      : 1;
+    uint8_t _ESE_FELICA_CLT                              : 1;
+    uint8_t _WIRED_MODE_STANDBY_PROP                     : 1;
+    uint8_t _WIRED_MODE_STANDBY                          : 1;
+    uint8_t _ESE_DUAL_MODE_PRIO_SCHEME                   : 2;
+    uint8_t _ESE_FORCE_ENABLE                            : 1;
+    uint8_t _ESE_RESET_METHOD                            : 1;
+    uint8_t _EXCLUDE_NV_MEM_DEPENDENCY                   : 1;
+    uint8_t _ESE_ETSI_READER_ENABLE                      : 1;
+    uint8_t _ESE_SVDD_SYNC                               : 1;
+    uint8_t _NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION  : 1;
+    uint8_t _ESE_JCOP_DWNLD_PROTECTION                   : 1;
+    uint8_t _UICC_HANDLE_CLEAR_ALL_PIPES                 : 1;
+    uint8_t _GP_CONTINOUS_PROCESSING                     : 1;
+    uint8_t _ESE_DWP_SPI_SYNC_ENABLE                     : 1;
+    uint8_t _ESE_ETSI12_PROP_INIT                        : 1;
+    uint8_t _ESE_WIRED_MODE_PRIO                         : 1;
+    uint8_t _ESE_UICC_EXCLUSIVE_WIRED_MODE               : 1;
+    uint8_t _ESE_POWER_MODE                              : 1;
+    uint8_t _ESE_P73_ISO_RST                             : 1;
+    uint8_t _BLOCK_PROPRIETARY_APDU_GATE                 : 1;
+    uint8_t _JCOP_WA_ENABLE                              : 1;
+    uint8_t _NXP_LDR_SVC_VER_2                           : 1;
+    uint8_t _NXP_ESE_VER                                 : 3;
+}tNfc_eseFeatureList;
+/*
+ * TODO renaming
+ * */
+typedef struct {
+    uint8_t _NFCC_RESET_RSP_LEN;
+}tNfc_platformFeatureList;
+
+typedef struct {
+    uint8_t _NCI_INTERFACE_UICC_DIRECT;
+    uint8_t _NCI_INTERFACE_ESE_DIRECT;
+    uint8_t _NCI_PWR_LINK_PARAM_CMD_SIZE;
+    uint8_t _NCI_EE_PWR_LINK_ALWAYS_ON;
+    uint8_t _NFA_EE_MAX_AID_ENTRIES;
+    uint8_t _NFC_NXP_AID_MAX_SIZE_DYN : 1;
+    uint8_t _FW_LIB_PATH[STRMAX_2];
+    uint8_t _PLATFORM_LIB_PATH[STRMAX_2];
+    uint8_t _PKU_LIB_PATH[STRMAX_2];
+    uint16_t _PHDNLDNFC_USERDATA_EEPROM_OFFSET;
+    uint16_t _PHDNLDNFC_USERDATA_EEPROM_LEN;
+    uint8_t  _FW_MOBILE_MAJOR_NUMBER;
+}tNfc_nfcMwFeatureList;
+/*
+ * TODO renaming
+ * */
+typedef struct {
+    uint8_t nfcNxpEse : 1;
+    tNFC_chipType chipType;
+    tNfc_nfccFeatureList nfccFL;
+    tNfc_eseFeatureList eseFL;
+    tNfc_platformFeatureList platformFL;
+    tNfc_nfcMwFeatureList nfcMwFL;
+}tNfc_featureList;
+
+extern tNfc_featureList nfcFL;
+
+#define CONFIGURE_FEATURELIST(chipType) {                                   \
+        nfcFL.chipType = chipType;                                          \
+        nfcFL.nfcMwFL._NFC_NXP_AID_MAX_SIZE_DYN = true;                     \
+        if(chipType == pn81T) {                                             \
+            nfcFL.chipType = pn557;                                         \
+        }                                                                   \
+        else if(chipType == pn80T) {                                        \
+            nfcFL.chipType = pn553;                                         \
+        }                                                                   \
+        else if(chipType == pn67T) {                                        \
+            nfcFL.chipType = pn551;                                         \
+        }                                                                   \
+        else if(chipType == pn66T) {                                        \
+            nfcFL.chipType = pn548C2;                                       \
+        }                                                                   \
+        else if(chipType == pn65T) {                                        \
+            nfcFL.chipType = pn547C2;                                       \
+        }                                                                   \
+        if ((chipType == pn65T) || (chipType == pn66T) ||                   \
+                (chipType == pn67T) || (chipType == pn80T) ||               \
+                (chipType == pn81T)) {                                      \
+            nfcFL.nfcNxpEse = true;                                         \
+            CONFIGURE_FEATURELIST_NFCC_WITH_ESE(chipType)                   \
+        } \
+        else {                                                              \
+            nfcFL.nfcNxpEse = false;                                        \
+            CONFIGURE_FEATURELIST_NFCC(chipType)                            \
+        }                                                                   \
+        \
+        \
+}
+
+#define CONFIGURE_FEATURELIST_NFCC_WITH_ESE(chipType) {                     \
+        nfcFL.nfccFL._NXP_NFCC_EMPTY_DATA_PACKET = true;                    \
+        nfcFL.nfccFL._GEMALTO_SE_SUPPORT = true;                            \
+        \
+        \
+        nfcFL.eseFL._ESE_EXCLUSIVE_WIRED_MODE = 1;                          \
+        nfcFL.eseFL._ESE_WIRED_MODE_RESUME = 2;                             \
+        nfcFL.eseFL._ESE_PN67T_RESET = 1;                                   \
+        nfcFL.eseFL._ESE_APDU_GATE_RESET = 2;                               \
+        nfcFL.eseFL._NXP_ESE_VER = JCOP_VER_4_0;                            \
+        nfcFL.eseFL._NXP_LDR_SVC_VER_2 = true;                              \
+        \
+        \
+        if (chipType == pn81T) {                                            \
+            CONFIGURE_FEATURELIST_NFCC(pn557)                               \
+            nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC = true;                 \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 4;                      \
+            \
+            \
+            nfcFL.eseFL._ESE_FELICA_CLT = true;                             \
+            nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME =                        \
+            nfcFL.eseFL._ESE_WIRED_MODE_RESUME;                             \
+            nfcFL.eseFL._ESE_RESET_METHOD = true;                           \
+            nfcFL.eseFL._ESE_POWER_MODE = true;                             \
+            nfcFL.eseFL._ESE_P73_ISO_RST = true;                            \
+            nfcFL.eseFL._WIRED_MODE_STANDBY = true;                         \
+            nfcFL.eseFL._ESE_ETSI_READER_ENABLE = true;                     \
+            nfcFL.eseFL._ESE_SVDD_SYNC = true;                              \
+            nfcFL.eseFL._ESE_JCOP_DWNLD_PROTECTION = true;                  \
+            nfcFL.eseFL._UICC_HANDLE_CLEAR_ALL_PIPES = true;                \
+            nfcFL.eseFL._GP_CONTINOUS_PROCESSING = false;                   \
+            nfcFL.eseFL._ESE_DWP_SPI_SYNC_ENABLE = true;                    \
+            nfcFL.eseFL._ESE_ETSI12_PROP_INIT = true;                       \
+        }                                                                   \
+        if (chipType == pn80T) {                                            \
+            CONFIGURE_FEATURELIST_NFCC(pn553)                               \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 4;                      \
+            \
+            \
+            nfcFL.eseFL._ESE_FELICA_CLT = true;                             \
+            nfcFL.eseFL._WIRED_MODE_STANDBY = true;                         \
+            nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME =                        \
+            nfcFL.eseFL._ESE_WIRED_MODE_RESUME;                             \
+            nfcFL.eseFL._ESE_RESET_METHOD = true;                           \
+            nfcFL.eseFL._ESE_ETSI_READER_ENABLE = true;                     \
+            nfcFL.eseFL._ESE_SVDD_SYNC = true;                              \
+            nfcFL.eseFL._ESE_JCOP_DWNLD_PROTECTION = true;                  \
+            nfcFL.eseFL._UICC_HANDLE_CLEAR_ALL_PIPES = true;                \
+            nfcFL.eseFL._ESE_DWP_SPI_SYNC_ENABLE = true;                    \
+            nfcFL.eseFL._ESE_POWER_MODE = true;                             \
+            nfcFL.eseFL._ESE_P73_ISO_RST = true;                            \
+            \
+            \
+            nfcFL.nfcMwFL._NCI_PWR_LINK_PARAM_CMD_SIZE = 0x02;              \
+            nfcFL.nfcMwFL._NCI_EE_PWR_LINK_ALWAYS_ON = 0x01;                \
+        }                                                                   \
+        else if (chipType == pn67T)                                         \
+        {                                                                   \
+            CONFIGURE_FEATURELIST_NFCC(pn551)                               \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 3;                      \
+            \
+            \
+            nfcFL.eseFL._TRIPLE_MODE_PROTECTION = true;                     \
+            nfcFL.eseFL._WIRED_MODE_STANDBY_PROP = true;                    \
+            nfcFL.eseFL._ESE_FORCE_ENABLE = true;                           \
+            nfcFL.eseFL._ESE_ETSI_READER_ENABLE = true;                     \
+            nfcFL.eseFL._ESE_SVDD_SYNC = true;                              \
+            nfcFL.eseFL._LEGACY_APDU_GATE = true;                           \
+            nfcFL.eseFL._NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION = true; \
+            nfcFL.eseFL._ESE_DWP_SPI_SYNC_ENABLE = true;                    \
+        }                                                                   \
+        else if (chipType == pn66T)                                         \
+        {                                                                   \
+            CONFIGURE_FEATURELIST_NFCC(pn548C2)                             \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 3;                      \
+            \
+            \
+            nfcFL.eseFL._TRIPLE_MODE_PROTECTION = true;                     \
+            nfcFL.eseFL._WIRED_MODE_STANDBY = true;                         \
+            nfcFL.eseFL._WIRED_MODE_STANDBY_PROP = true;                    \
+            nfcFL.eseFL._ESE_FORCE_ENABLE = true;                           \
+            nfcFL.eseFL._ESE_ETSI_READER_ENABLE = true;                     \
+            nfcFL.eseFL._ESE_SVDD_SYNC = true;                              \
+            nfcFL.eseFL._LEGACY_APDU_GATE = true;                           \
+            nfcFL.eseFL._NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION = true; \
+            nfcFL.eseFL._ESE_DWP_SPI_SYNC_ENABLE = true;                    \
+        }                                                                   \
+        else if (chipType == pn65T)                                         \
+        {                                                                   \
+            CONFIGURE_FEATURELIST_NFCC(pn547C2)                             \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 3;                      \
+            nfcFL.eseFL._ESE_WIRED_MODE_DISABLE_DISCOVERY = true;           \
+            nfcFL.eseFL._LEGACY_APDU_GATE = true;                           \
+        }                                                                   \
+}
+
+
+#define CONFIGURE_FEATURELIST_NFCC(chipType) {                              \
+        nfcFL.eseFL._ESE_WIRED_MODE_TIMEOUT = 3;                            \
+        nfcFL.eseFL._ESE_WIRED_MODE_DISABLE_DISCOVERY = false;              \
+        nfcFL.eseFL._LEGACY_APDU_GATE = false;                              \
+        nfcFL.eseFL._TRIPLE_MODE_PROTECTION = false;                        \
+        nfcFL.eseFL._ESE_FELICA_CLT = false;                                \
+        nfcFL.eseFL._WIRED_MODE_STANDBY_PROP = false;                       \
+        nfcFL.eseFL._WIRED_MODE_STANDBY = false;                            \
+        nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME =                            \
+        nfcFL.eseFL._ESE_WIRED_MODE_TIMEOUT;                                \
+        nfcFL.eseFL._ESE_FORCE_ENABLE = false;                              \
+        nfcFL.eseFL._ESE_RESET_METHOD = false;                              \
+        nfcFL.eseFL._ESE_ETSI_READER_ENABLE = false;                        \
+        nfcFL.eseFL._ESE_SVDD_SYNC = false;                                 \
+        nfcFL.eseFL._NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION = false;    \
+        nfcFL.eseFL._ESE_JCOP_DWNLD_PROTECTION = false;                     \
+        nfcFL.eseFL._UICC_HANDLE_CLEAR_ALL_PIPES = false;                   \
+        nfcFL.eseFL._GP_CONTINOUS_PROCESSING = false;                       \
+        nfcFL.eseFL._ESE_DWP_SPI_SYNC_ENABLE = false;                       \
+        nfcFL.eseFL._ESE_ETSI12_PROP_INIT = false;                          \
+        nfcFL.eseFL._ESE_WIRED_MODE_PRIO = false;                           \
+        nfcFL.eseFL._ESE_UICC_EXCLUSIVE_WIRED_MODE = false;                 \
+        nfcFL.eseFL._ESE_POWER_MODE = false;                                \
+        nfcFL.eseFL._ESE_P73_ISO_RST = false;                               \
+        nfcFL.eseFL._BLOCK_PROPRIETARY_APDU_GATE = false;                   \
+        nfcFL.eseFL._JCOP_WA_ENABLE = true;                                 \
+        nfcFL.eseFL._EXCLUDE_NV_MEM_DEPENDENCY = false;                     \
+        nfcFL.nfccFL._NXP_NFC_UICC_ETSI12 = false;                          \
+        nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC = false;                    \
+        \
+        \
+        nfcFL.platformFL._NFCC_RESET_RSP_LEN = 0;                           \
+        \
+        \
+        nfcFL.nfcMwFL._NCI_INTERFACE_UICC_DIRECT = 0x00;                    \
+        nfcFL.nfcMwFL._NCI_INTERFACE_ESE_DIRECT = 0x00;                     \
+        nfcFL.nfcMwFL._NCI_PWR_LINK_PARAM_CMD_SIZE = 0x02;                  \
+        nfcFL.nfcMwFL._NCI_EE_PWR_LINK_ALWAYS_ON = 0x01;                    \
+        nfcFL.nfcMwFL._PHDNLDNFC_USERDATA_EEPROM_OFFSET = 0x023CU;          \
+        nfcFL.nfcMwFL._PHDNLDNFC_USERDATA_EEPROM_LEN = 0x0C80U;             \
+        nfcFL.nfcMwFL._FW_MOBILE_MAJOR_NUMBER =                             \
+        FW_MOBILE_MAJOR_NUMBER_PN48AD;                                      \
+        \
+        \
+        if (chipType == pn557)                                              \
+        {                                                                   \
+            nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT = true;           \
+            nfcFL.nfccFL._NFCC_MIFARE_TIANJIN = false;                      \
+            nfcFL.nfccFL._NFCC_MW_RCVRY_BLK_FW_DNLD = true;                 \
+            nfcFL.nfccFL._NFCC_DYNAMIC_DUAL_UICC = true;                    \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH = false;        \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH = true;      \
+            nfcFL.nfccFL._NFCC_FW_WA = true;                                \
+            nfcFL.nfccFL._NFCC_FORCE_NCI1_0_INIT = false;                   \
+            nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC = true;                 \
+            nfcFL.nfccFL._HW_ANTENNA_LOOP4_SELF_TEST = false;               \
+            nfcFL.nfccFL._NFCEE_REMOVED_NTF_RECOVERY = true;                \
+            nfcFL.nfccFL._NFCC_FORCE_FW_DOWNLOAD = true;                    \
+            nfcFL.nfccFL._UICC_CREATE_CONNECTIVITY_PIPE = true;             \
+            nfcFL.nfccFL._NXP_NFC_UICC_ETSI12 = false;                      \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 3;                      \
+            \
+            \
+            nfcFL.eseFL._ESE_ETSI12_PROP_INIT = true;                       \
+            nfcFL.eseFL._EXCLUDE_NV_MEM_DEPENDENCY = true;                  \
+            \
+            \
+            nfcFL.platformFL._NFCC_RESET_RSP_LEN = 0x10U;                   \
+            \
+            \
+        }                                                                   \
+        else if (chipType == pn553)                                         \
+        {                                                                   \
+            nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT = true;           \
+            nfcFL.nfccFL._NFCC_MIFARE_TIANJIN = false;                      \
+            nfcFL.nfccFL._NFCC_MW_RCVRY_BLK_FW_DNLD = true;                 \
+            nfcFL.nfccFL._NFCC_DYNAMIC_DUAL_UICC = true;                    \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH = false;        \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH = true;      \
+            nfcFL.nfccFL._NFCC_FW_WA = true;                                \
+            nfcFL.nfccFL._NFCC_FORCE_NCI1_0_INIT = true;                    \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT = true;                    \
+            nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC = true;                 \
+            nfcFL.nfccFL._HW_ANTENNA_LOOP4_SELF_TEST = false;               \
+            nfcFL.nfccFL._NFCEE_REMOVED_NTF_RECOVERY = true;                \
+            nfcFL.nfccFL._NFCC_FORCE_FW_DOWNLOAD = true;                    \
+            nfcFL.nfccFL._UICC_CREATE_CONNECTIVITY_PIPE = true;             \
+            nfcFL.nfccFL._NFCC_AID_MATCHING_PLATFORM_CONFIG = false;        \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT_PROP = false;              \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 3;                      \
+            \
+            \
+            nfcFL.eseFL._ESE_ETSI12_PROP_INIT = true;                       \
+            nfcFL.eseFL._JCOP_WA_ENABLE = false;                            \
+            nfcFL.eseFL._EXCLUDE_NV_MEM_DEPENDENCY = true;                  \
+            \
+            \
+            nfcFL.platformFL._NFCC_RESET_RSP_LEN = 0x10U;                   \
+            \
+            \
+            nfcFL.nfcMwFL._NCI_INTERFACE_UICC_DIRECT = 0x82;                \
+            nfcFL.nfcMwFL._NCI_INTERFACE_ESE_DIRECT = 0x83;                 \
+            \
+            \
+            SRTCPY_FW("libpn553tc_fw", "libpn553tc_fw_platform",            \
+                    "libpn553tc_fw_pku")                                    \
+            \
+            \
+            nfcFL.nfcMwFL._FW_MOBILE_MAJOR_NUMBER =                         \
+            FW_MOBILE_MAJOR_NUMBER_PN553;                                   \
+            \
+            \
+        }                                                                   \
+        else if (chipType == pn551)                                         \
+        {                                                                   \
+            nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT = true;           \
+            nfcFL.nfccFL._NFCC_MIFARE_TIANJIN = true;                       \
+            nfcFL.nfccFL._NFCC_MW_RCVRY_BLK_FW_DNLD = false;                \
+            nfcFL.nfccFL._NFCC_DYNAMIC_DUAL_UICC = false;                   \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH = true;         \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH = false;     \
+            nfcFL.nfccFL._NFCC_FW_WA = false;                               \
+            nfcFL.nfccFL._NFCC_FORCE_NCI1_0_INIT = false;                   \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT = false;                   \
+            nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC = false;                \
+            nfcFL.nfccFL._HW_ANTENNA_LOOP4_SELF_TEST = true;                \
+            nfcFL.nfccFL._NFCEE_REMOVED_NTF_RECOVERY = true;                \
+            nfcFL.nfccFL._NFCC_FORCE_FW_DOWNLOAD = false;                   \
+            nfcFL.nfccFL._UICC_CREATE_CONNECTIVITY_PIPE = false;            \
+            nfcFL.nfccFL._NFCC_AID_MATCHING_PLATFORM_CONFIG = true;         \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT_PROP = true;               \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 2;                      \
+            \
+            \
+            nfcFL.eseFL._ESE_FORCE_ENABLE = true;                           \
+            \
+            \
+            nfcFL.platformFL._NFCC_RESET_RSP_LEN = 0x11U;                   \
+            \
+            \
+            nfcFL.nfcMwFL._NCI_INTERFACE_UICC_DIRECT = 0x82;                \
+            nfcFL.nfcMwFL._NCI_INTERFACE_ESE_DIRECT = 0x83;                 \
+            \
+            \
+            SRTCPY_FW("libpn551_fw", "libpn551_fw_platform",                \
+                    "libpn551_fw_pku")                                      \
+            \
+            \
+            nfcFL.nfcMwFL._PHDNLDNFC_USERDATA_EEPROM_OFFSET = 0x02BCU;      \
+            nfcFL.nfcMwFL._PHDNLDNFC_USERDATA_EEPROM_LEN = 0x0C00U;         \
+            nfcFL.nfcMwFL._FW_MOBILE_MAJOR_NUMBER =                         \
+            FW_MOBILE_MAJOR_NUMBER_PN551;                                   \
+            \
+            \
+        }                                                                   \
+        else if (chipType == pn548C2)                                       \
+        {                                                                   \
+            nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT = true;           \
+            nfcFL.nfccFL._NFCC_MIFARE_TIANJIN = true;                       \
+            nfcFL.nfccFL._NFCC_MW_RCVRY_BLK_FW_DNLD = false;                \
+            nfcFL.nfccFL._NFCC_DYNAMIC_DUAL_UICC = false;                   \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH = true;         \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH = false;     \
+            nfcFL.nfccFL._NFCC_FW_WA = false;                               \
+            nfcFL.nfccFL._NFCC_FORCE_NCI1_0_INIT = false;                   \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT = false;                   \
+            nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC = false;                \
+            nfcFL.nfccFL._HW_ANTENNA_LOOP4_SELF_TEST = true;                \
+            nfcFL.nfccFL._NFCEE_REMOVED_NTF_RECOVERY = true;                \
+            nfcFL.nfccFL._NFCC_FORCE_FW_DOWNLOAD = false;                   \
+            nfcFL.nfccFL._UICC_CREATE_CONNECTIVITY_PIPE = false;            \
+            nfcFL.nfccFL._NFCC_AID_MATCHING_PLATFORM_CONFIG = true;         \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT_PROP = true;               \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 2;                      \
+            \
+            \
+            nfcFL.eseFL._ESE_FORCE_ENABLE = true;                           \
+            nfcFL.eseFL._ESE_ETSI12_PROP_INIT = true;                       \
+            \
+            \
+            nfcFL.nfcMwFL._NCI_INTERFACE_UICC_DIRECT = 0x82;                \
+            nfcFL.nfcMwFL._NCI_INTERFACE_ESE_DIRECT = 0x83;                 \
+            \
+            \
+            SRTCPY_FW("libpn548ad_fw", "libpn548ad_fw_platform",            \
+                    "libpn548ad_fw_pku")                                    \
+            \
+            \
+            nfcFL.nfcMwFL._PHDNLDNFC_USERDATA_EEPROM_OFFSET = 0x02BCU;      \
+            nfcFL.nfcMwFL._PHDNLDNFC_USERDATA_EEPROM_LEN = 0x0C00U;         \
+            \
+            \
+        }                                                                   \
+        else if(chipType == pn547C2)                                        \
+        {                                                                   \
+            nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT = false;          \
+            nfcFL.nfccFL._NFCC_MIFARE_TIANJIN = true;                       \
+            nfcFL.nfccFL._NFCC_MW_RCVRY_BLK_FW_DNLD = false;                \
+            nfcFL.nfccFL._NFCC_DYNAMIC_DUAL_UICC = false;                   \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH = false;        \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH = false;     \
+            nfcFL.nfccFL._NFCC_FW_WA = false;                               \
+            nfcFL.nfccFL._NFCC_FORCE_NCI1_0_INIT = false;                   \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT = false;                   \
+            nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC = false;                \
+            nfcFL.nfccFL._HW_ANTENNA_LOOP4_SELF_TEST = true;                \
+            nfcFL.nfccFL._NFCEE_REMOVED_NTF_RECOVERY = true;                \
+            nfcFL.nfccFL._NFCC_FORCE_FW_DOWNLOAD = false;                   \
+            nfcFL.nfccFL._UICC_CREATE_CONNECTIVITY_PIPE = false;            \
+            nfcFL.nfccFL._NFCC_AID_MATCHING_PLATFORM_CONFIG = true;         \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT_PROP = false;              \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 2;                      \
+            \
+            \
+            nfcFL.nfcMwFL._NCI_INTERFACE_UICC_DIRECT = 0x81;                \
+            nfcFL.nfcMwFL._NCI_INTERFACE_ESE_DIRECT = 0x82;                 \
+            \
+            \
+            SRTCPY_FW("libpn547_fw", "libpn547_fw_platform",                \
+                    "libpn547_fw_pku")                                      \
+            \
+            \
+        }                                                                   \
+}
+#ifdef __cplusplus
+#define SRTCPY_FW(str1,str2,str3)
+#else
+#define SRTCPY_FW(str1, str2,str3)                                                      \
+        snprintf(nfcFL.nfcMwFL._FW_LIB_PATH, STRMAX_2, "%s%s%s",                        \
+                FW_DLL_ROOT_DIR, str1, FW_DLL_EXTENSION);                               \
+                snprintf(nfcFL.nfcMwFL._PLATFORM_LIB_PATH, STRMAX_2, "%s%s%s",          \
+                        FW_DLL_ROOT_DIR, str2, FW_DLL_EXTENSION);                       \
+                        snprintf(nfcFL.nfcMwFL._PKU_LIB_PATH, STRMAX_2, "%s%s%s",       \
+                                FW_DLL_ROOT_DIR, str3, FW_DLL_EXTENSION);
+#endif
+#endif
diff --git a/halimpl/pn54x/inc/phNxpNciHal_Adaptation.h b/halimpl/pn54x/inc/phNxpNciHal_Adaptation.h
new file mode 100644
index 0000000..e73c5bc
--- /dev/null
+++ b/halimpl/pn54x/inc/phNxpNciHal_Adaptation.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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>
+
+#define NFC_NCI_NXP_PN54X_HARDWARE_MODULE_ID "nfc_nci.nqx"
+
+typedef struct
+{
+    struct nfc_nci_device nci_device;
+
+    /* Local definitions */
+    int (*ioctl)(const struct nfc_nci_device *p_dev, long arg, void *p_data);
+    int(*check_fw_dwnld_flag)(const struct nfc_nci_device *p_dev, uint8_t* param1);
+} pn547_dev_t;
+
+#define MAX_IOCTL_TRANSCEIVE_CMD_LEN  256
+#define MAX_IOCTL_TRANSCEIVE_RESP_LEN 256
+#define MAX_ATR_INFO_LEN              128
+
+/*
+ * Data structures provided below are used of Hal Ioctl calls
+ */
+/*
+ * nfc_nci_ExtnCmd_t shall contain data for commands used for transceive command in ioctl
+ */
+typedef struct
+{
+    uint16_t cmd_len;
+    uint8_t  p_cmd[MAX_IOCTL_TRANSCEIVE_CMD_LEN];
+} nfc_nci_ExtnCmd_t;
+
+/*
+ * nfc_nci_ExtnRsp_t shall contain response for command sent in transceive command
+ */
+typedef struct
+{
+    uint16_t rsp_len;
+    uint8_t  p_rsp[MAX_IOCTL_TRANSCEIVE_RESP_LEN];
+} nfc_nci_ExtnRsp_t;
+/*
+ * InputData_t :ioctl has multiple subcommands
+ * Each command has corresponding input data which needs to be populated in this
+ */
+typedef union {
+    uint16_t          bootMode;
+    uint8_t           halType;
+    nfc_nci_ExtnCmd_t nciCmd;
+    uint32_t          timeoutMilliSec;
+    long              nfcServicePid;
+}InputData_t;
+/*
+ * nfc_nci_ExtnInputData_t :Apart from InputData_t, there are context data
+ * which is required during callback from stub to proxy.
+ * To avoid additional copy of data while propagating from libnfc to Adaptation
+ * and Nfcstub to ncihal, common structure is used. As a sideeffect, context data
+ * is exposed to libnfc (Not encapsulated).
+ */
+typedef struct {
+    /*
+     * context to be used/updated only by users of proxy & stub of Nfc.hal
+     * i.e NfcAdaptation & Nfc hidl
+     */
+    void*       context;
+    InputData_t data;
+}nfc_nci_ExtnInputData_t;
+
+/*
+ * outputData_t :ioctl has multiple commands/responses
+ * This contains the output types for each ioctl.
+ */
+typedef union{
+    uint32_t            status;
+    nfc_nci_ExtnRsp_t   nciRsp;
+    uint8_t             nxpNciAtrInfo[MAX_ATR_INFO_LEN];
+    uint32_t            p61CurrentState;
+    uint16_t            fwUpdateInf;
+    uint16_t            fwDwnldStatus;
+    uint16_t            fwMwVerStatus;
+    uint8_t             chipType;
+}outputData_t;
+
+/*
+ * nfc_nci_ExtnOutputData_t :Apart from outputData_t, there are other information
+ * which is required during callback from stub to proxy.
+ * For ex (context, result of the operation , type of ioctl which was completed).
+ * To avoid additional copy of data while propagating from libnfc to Adaptation
+ * and Nfcstub to ncihal, common structure is used. As a sideeffect, these data
+ * is exposed(Not encapsulated).
+ */
+typedef struct {
+    /*
+     * ioctlType, result & context to be used/updated only by users of
+     * proxy & stub of Nfc.hal.
+     * i.e, NfcAdaptation & Nfc hidl
+     * These fields shall not be used by libnfc or halimplementation
+     */
+    uint64_t     ioctlType;
+    uint32_t     result;
+    void*        context;
+    outputData_t data;
+}nfc_nci_ExtnOutputData_t;
+
+/*
+ * nfc_nci_IoctlInOutData_t :data structure for input & output
+ * to be sent for ioctl command. input is populated by client/proxy side
+ * output is provided from server/stub to client/proxy
+ */
+typedef struct {
+    nfc_nci_ExtnInputData_t  inp;
+    nfc_nci_ExtnOutputData_t out;
+}nfc_nci_IoctlInOutData_t;
+
+/* NXP HAL functions */
+
+int phNxpNciHal_open(nfc_stack_callback_t* p_cback,
+                     nfc_stack_data_callback_t* p_data_cback);
+int phNxpNciHal_write(uint16_t data_len, const uint8_t* p_data);
+int phNxpNciHal_ioctl(long arg, void* 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);
+int phNxpNciHal_MinOpen(nfc_stack_callback_t* p_cback,
+                        nfc_stack_data_callback_t* p_data_cback);
+int phNxpNciHal_Minclose(void);
+int phNxpNciHal_getFWDownloadFlag(uint8_t* fwDnldRequest);
+#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..12eacb9
--- /dev/null
+++ b/halimpl/pn54x/inc/phNxpNciHal_Api.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef _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..0b4f22c
--- /dev/null
+++ b/halimpl/pn54x/inc/phNxpNciHal_SelfTest.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef _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.
+ **
+ ******************************************************************************/
+NFCSTATUS phNxpNciHal_PrbsTestStart(phNxpNfc_PrbsType_t prbs_type,
+                                    phNxpNfc_PrbsHwType_t hw_prbs_type,
+                                    phNxpNfc_Tech_t tech,
+                                    phNxpNfc_Bitrate_t bitrate);
+
+/*******************************************************************************
+ **
+ ** 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..32e5a3d
--- /dev/null
+++ b/halimpl/pn54x/libnfc-brcm.conf
@@ -0,0 +1,410 @@
+###################### Start of libnfc-common.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
+NFA_HCI_STATIC_PIPE_ID_02=0x20
+###############################################################################
+# 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
+
+###############################################################################
+# Forcing HOST to listen for a selected protocol
+# 0x00 : Disable Host Listen
+# 0x01 : Enable Host to Listen (A)  for ISO-DEP tech A
+# 0x02 : Enable Host to Listen (B)  for ISO-DEP tech B
+# 0x04 : Enable Host to Listen (F)  for T3T Tag Type Protocol tech F
+# 0x07 : Enable Host to Listen (ABF)for ISO-DEP tech AB & T3T Tag Type Protocol tech F
+HOST_LISTEN_TECH_MASK=0x07
+
+###############################################################################
+# 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=1
+
+###############################################################################
+# 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 4 by default as it assumes we will additionally discover
+# 0xF2, 0xF3, and 0xF4. If a platform will exclude any SE, this value can be
+# reduced so that the stack will not wait any longer than necessary.
+
+# Maximum EE supported number
+# NXP PN547C2 0x02
+# NXP PN65T 0x03
+# NXP PN548C2 0x02
+# NXP PN66T 0x03
+# NXP PN551 0x02
+# NXP PN67T 0x03
+# NXP PN553 0x02
+# NXP PN80T 0x04
+NFA_MAX_EE_SUPPORTED=0x04
+
+###############################################################################
+# NCI Hal Module name
+NCI_HAL_MODULE="nfc_nci.nqx"
+
+##############################################################################
+# 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
+
+###############################################################################
+# Default Secure Element route id
+DEFAULT_OFFHOST_ROUTE=0x02
+
+###############################################################################
+# Vendor Specific Proprietary Protocol & Discovery Configuration
+# Set to 0xFF if unsupported
+#  byte[0] NCI_PROTOCOL_18092_ACTIVE
+#  byte[1] NCI_PROTOCOL_B_PRIME
+#  byte[2] NCI_PROTOCOL_DUAL
+#  byte[3] NCI_PROTOCOL_15693
+#  byte[4] NCI_PROTOCOL_KOVIO
+#  byte[5] NCI_PROTOCOL_MIFARE
+#  byte[6] NCI_DISCOVERY_TYPE_POLL_KOVIO
+#  byte[7] NCI_DISCOVERY_TYPE_POLL_B_PRIME
+#  byte[8] NCI_DISCOVERY_TYPE_LISTEN_B_PRIME
+NFA_PROPRIETARY_CFG={05:FF:FF:06:81:80:70:FF:FF}
+
+#################################################################################
+# Bail out mode
+#  If set to 1, NFCC is using bail out mode for either Type A or Type B poll.
+NFA_POLL_BAIL_OUT_MODE=0x01
+#################################################################################
diff --git a/halimpl/pn54x/libnfc-brcm_NCI2_0.conf b/halimpl/pn54x/libnfc-brcm_NCI2_0.conf
new file mode 100644
index 0000000..0eca62c
--- /dev/null
+++ b/halimpl/pn54x/libnfc-brcm_NCI2_0.conf
@@ -0,0 +1,412 @@
+######################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
+NFA_HCI_STATIC_PIPE_ID_02=0x20
+###############################################################################
+#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
+
+###############################################################################
+# Forcing HOST to listen for a selected protocol
+# 0x00 : Disable Host Listen
+# 0x01 : Enable Host to Listen (A)  for ISO-DEP tech A
+# 0x02 : Enable Host to Listen (B)  for ISO-DEP tech B
+# 0x04 : Enable Host to Listen (F)  for T3T Tag Type Protocol tech F
+# 0x07 : Enable Host to Listen (ABF)for ISO-DEP tech AB & T3T Tag Type Protocol tech F
+HOST_LISTEN_TECH_MASK=0x07
+
+###############################################################################
+#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
+# 5 NFA_RW_PRES_CHK_ISO_DEP_NAK; Type - 4 tag protocol iso-dep nak presence check command is sent waiting for rsp and ntf.
+PRESENCE_CHECK_ALGORITHM=5
+
+###############################################################################
+# 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_ACTIVE 0x40   /* NFC Technology Active*/
+
+POLLING_TECH_MASK=0x6F
+
+###############################################################################
+# 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_ACTIVE   0x40 /* NFC Technology Active        */
+
+P2P_LISTEN_TECH_MASK=0x45
+
+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_EXACT_OR_SUBSET_OR_PREFIX 0x03
+AID_MATCHING_MODE=0x03
+
+###############################################################################
+#Default Secure Element route id
+DEFAULT_OFFHOST_ROUTE=0x02
+
+###############################################################################
+#Vendor Specific Proprietary Protocol& Discovery Configuration
+#Set to 0xFF if unsupported
+#byte[0] NCI_PROTOCOL_18092_ACTIVE
+#byte[1] NCI_PROTOCOL_B_PRIME
+#byte[2] NCI_PROTOCOL_DUAL
+#byte[3] NCI_PROTOCOL_15693
+#byte[4] NCI_PROTOCOL_KOVIO
+#byte[5] NCI_PROTOCOL_MIFARE
+#byte[6] NCI_DISCOVERY_TYPE_POLL_KOVIO
+#byte[7] NCI_DISCOVERY_TYPE_POLL_B_PRIME
+#byte[8] NCI_DISCOVERY_TYPE_LISTEN_B_PRIME
+NFA_PROPRIETARY_CFG={05 : FF : FF : 06 : 81 : 80 : 70 : FF : FF}
+
+###############################################################################
+#Bail out mode
+#If set to 1, NFCC is using bail out mode for either Type A or Type B poll.
+NFA_POLL_BAIL_OUT_MODE=0x01
+###############################################################################
+# Enable/Disable Block Route feature.
+# Block Route will restrict routing to first matched rule
+# Block Route enable   0x01
+# Block Route disable  0x00
+NFA_BLOCK_ROUTE=0x00
diff --git a/halimpl/pn54x/libnfc-nxp-PN547C2_example.conf b/halimpl/pn54x/libnfc-nxp-PN547C2_example.conf
new file mode 100644
index 0000000..a3d727c
--- /dev/null
+++ b/halimpl/pn54x/libnfc-nxp-PN547C2_example.conf
@@ -0,0 +1,188 @@
+## This file is used by NFC NXP NCI HAL(external/libnfc-nci/halimpl/pn547)
+## and NFC Service Java Native Interface Extensions (packages/apps/Nfc/nci/jni/extns/pn547)
+###############################################################################
+# 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
+
+###############################################################################
+# Nfc Device Node name
+NXP_NFC_DEV_NODE="/dev/nq-nci"
+
+###############################################################################
+# Extension for Mifare reader enable
+MIFARE_READER_ENABLE=0x01
+
+###############################################################################
+# Vzw Feature enable
+VZW_FEATURE_ENABLE=0x01
+
+###############################################################################
+# File name for Firmware
+NXP_FW_NAME="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_32MHZ         5
+#define CLK_FREQ_38_4MHZ       6
+#define CLK_FREQ_52MHZ         7
+NXP_SYS_CLK_FREQ_SEL=0x00
+
+###############################################################################
+# The timeout value to be used for clock request acknowledgment 
+# min value = 0x01 to max = 0x06
+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
+
+
+###############################################################################
+## Set configuration optimization decision setting
+## Enable    = 0x01
+## Disable   = 0x00
+NXP_SET_CONFIG_ALWAYS=0x01
+
+###############################################################################
+# 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
+
+###############################################################################
+# 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=20
+
+###############################################################################
+#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=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
+# This setting is for DEFAULT_AID_ROUTE,
+# DEFAULT_DESFIRE_ROUTE and DEFAULT_MIFARE_CLT_ROUTE
+# 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
+
+################################################################################
+#Used to Restrict Type A UICC baud rate
+#0 = default supported
+#1 = 212 maximum supported
+#2 = 424 maximum supported
+#3 = 848 maximum supported
+NXP_TYPEA_UICC_BAUD_RATE=0x00
+
+################################################################################
+#Used to Restrict Type B UICC baud rate
+#0 = default supported
+#1 = 212 maximum supported
+#2 = 424 maximum supported
+#3 = 848 maximum supported
+NXP_TYPEB_UICC_BAUD_RATE=0x00
+
+################################################################################
+#Config to allow adding aids
+#NFC on/off is required after this config
+#1 = enabling adding aid  to NFCC routing table.
+#0 = disabling adding aid to NFCC routing table.
+NXP_ENABLE_ADD_AID=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..49cb58a
--- /dev/null
+++ b/halimpl/pn54x/libnfc-nxp-PN548AD_example.conf
@@ -0,0 +1,265 @@
+## This file is used by NFC NXP NCI HAL(external/libnfc-nci/halimpl/pn54x)
+## and NFC Service Java Native Interface Extensions (packages/apps/Nfc/nci/jni/extns/pn54x)
+
+###############################################################################
+# Application options
+# Logging Levels
+# NXPLOG_DEFAULT_LOGLEVEL    0x01
+# ANDROID_LOG_DEBUG          0x03
+# ANDROID_LOG_WARN           0x02
+# ANDROID_LOG_ERROR          0x01
+# ANDROID_LOG_SILENT         0x00
+#
+NXPLOG_EXTNS_LOGLEVEL=0x03
+NXPLOG_NCIHAL_LOGLEVEL=0x03
+NXPLOG_NCIX_LOGLEVEL=0x03
+NXPLOG_NCIR_LOGLEVEL=0x03
+NXPLOG_FWDNLD_LOGLEVEL=0x03
+NXPLOG_TML_LOGLEVEL=0x03
+
+###############################################################################
+# Extension for Mifare reader enable
+MIFARE_READER_ENABLE=0x01
+
+###############################################################################
+# Vzw Feature enable
+VZW_FEATURE_ENABLE=0x01
+
+###############################################################################
+# File location for Firmware
+#FW_STORAGE="/vendor/firmware/libpn548_fw.so"
+
+###############################################################################
+# System clock source selection configuration
+#define CLK_SRC_XTAL       1
+#define CLK_SRC_PLL        2
+
+NXP_SYS_CLK_SRC_SEL=0x02
+
+###############################################################################
+# System clock frequency selection configuration
+#define CLK_FREQ_13MHZ         1
+#define CLK_FREQ_19_2MHZ       2
+#define CLK_FREQ_24MHZ         3
+#define CLK_FREQ_26MHZ         4
+#define CLK_FREQ_38_4MHZ       5
+#define CLK_FREQ_52MHZ         6
+
+NXP_SYS_CLK_FREQ_SEL=0x02
+
+###############################################################################
+# The timeout value to be used for clock request acknowledgment
+# min value = 0x01 to max = 0x1A
+
+NXP_SYS_CLOCK_TO_CFG=0x01
+
+###############################################################################
+# NXP proprietary settings
+NXP_ACT_PROP_EXTN={2F, 02, 00}
+
+###############################################################################
+# NFC forum profile settings
+NXP_NFC_PROFILE_EXTN={20, 02, 05, 01, A0, 44, 01, 00}
+
+###############################################################################
+# NFCC Configuration Control
+# Allow NFCC to manage RF Config       0x01
+# Don't allow NFCC to manage RF Config 0x00
+NXP_NFC_MERGE_RF_PARAMS={20, 02, 04, 01, 85, 01, 01}
+
+###############################################################################
+# Standby enable settings
+#NXP_CORE_STANDBY={2F, 00, 01, 01}
+
+###############################################################################
+# NXP TVDD configurations settings
+# Allow NFCC to configure External TVDD, There are currently three
+#configurations (1, 2 and 3) are supported, out of them only one can be
+#supported.
+
+NXP_EXT_TVDD_CFG=0x01
+
+###############################################################################
+#config1:SLALM, 3.3V for both RM and CM
+NXP_EXT_TVDD_CFG_1={20, 02, 0B, 02, A0, 66, 01, 00, A0, 0E, 03, 02, 09, 00}
+
+###############################################################################
+#config2: use DCDC in CE, use Tx_Pwr_Req, set CFG2 mode, SLALM,
+#monitoring 5V from DCDC, 4.7V for both RM and CM, DCDCWaitTime=4.2ms
+NXP_EXT_TVDD_CFG_2={20, 02, 0B, 02, A0, 66, 01, 00, A0, 0E, 03, 56, 64, 0A}
+
+###############################################################################
+#config3: use DCDC in CE, use Tx_Pwr_Req, SLALM, monitoring 5V from DCDC,
+#DCDCWaitTime=4.2ms
+NXP_EXT_TVDD_CFG_3={20, 02, 0B, 02, A0, 66, 01, 01, A0, 0E, 03, 52, 64, 0A}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_1={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_2={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_3={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_4={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_5={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_6={
+#}
+
+###############################################################################
+# Core configuration extensions
+# It includes
+# Wired mode settings A0ED, A0EE
+# Tag Detector A040, A041, A043
+# Low Power mode A007
+# Clock settings A002, A003
+# PbF settings A008
+NXP_CORE_CONF_EXTN={20, 02, 15, 05,
+    A0, EC, 01, 01,
+    A0, ED, 01, 00,
+    A0, 5E, 01, 01,
+    A0, 40, 01, 01,
+    A0, DD, 01, 2D
+    }
+
+###############################################################################
+# Core configuration rf field filter settings to enable set 01 ,to disable set to 00 last bit
+NXP_CORE_RF_FIELD={ 20, 02, 05, 01, A0, 62, 01, 01
+        }
+
+###############################################################################
+# To enable i2c fragmentation set i2c fragmentation enable 0x01 to disable set to 0x00
+NXP_I2C_FRAGMENTATION_ENABLED=0x00
+
+###############################################################################
+# Core configuration settings
+NXP_CORE_CONF={ 20, 02, 2B, 0D,
+        28, 01, 00,
+        21, 01, 00,
+        30, 01, 08,
+        31, 01, 03,
+        33, 04, 01, 02, 03, 04,
+        54, 01, 06,
+        50, 01, 02,
+        5B, 01, 00,
+        60, 01, 0E,
+        80, 01, 01,
+        81, 01, 01,
+        82, 01, 0E,
+        18, 01, 01
+        }
+
+###############################################################################
+# Mifare Classic Key settings
+#NXP_CORE_MFCKEY_SETTING={20, 02, 25,04, A0, 51, 06, A0, A1, A2, A3, A4, A5,
+#                                     A0, 52, 06, D3, F7, D3, F7, D3, F7,
+#                                     A0, 53, 06, FF, FF, FF, FF, FF, FF,
+#                                     A0, 54, 06, 00, 00, 00, 00, 00, 00}
+
+###############################################################################
+# Default SE Options
+# No secure element 0x00
+# eSE               0x01
+# UICC              0x02
+
+NXP_DEFAULT_SE=0x07
+
+###############################################################################
+#Enable SWP full power mode when phone is power off
+NXP_SWP_FULL_PWR_ON=0x00
+
+###############################################################################
+#### Select the CHIP ####
+#PN547C2            0x01
+#PN65T              0x02
+#PN548AD            0x03
+#PN66T              0x04
+
+NXP_NFC_CHIP=0x03
+
+###############################################################################
+# CE when Screen state is locked
+# Disable           0x00
+# Enable            0x01
+NXP_CE_ROUTE_STRICT_DISABLE=0x01
+
+###############################################################################
+#Timeout in secs to get NFCEE Discover notification
+NXP_DEFAULT_NFCEE_DISC_TIMEOUT=20
+
+NXP_DEFAULT_NFCEE_TIMEOUT=0x06
+
+###############################################################################
+#Timeout in secs
+NXP_SWP_RD_START_TIMEOUT=0x0A
+
+###############################################################################
+#Timeout in secs
+NXP_SWP_RD_TAG_OP_TIMEOUT=0x01
+
+###############################################################################
+#Set the default AID route Location :
+#This settings will be used when application does not set this parameter
+# host 0x00
+# eSE  0x01
+# UICC 0x02
+DEFAULT_AID_ROUTE=0x00
+
+###############################################################################
+#Set the Mifare Desfire route Location :
+#This settings will be used when application does not set this parameter
+# host 0x00
+# eSE  0x01
+# UICC 0x02
+DEFAULT_DESFIRE_ROUTE=0x02
+
+###############################################################################
+#Set the Mifare CLT route Location :
+#This settings will be used when application does not set this parameter
+# host 0x00
+# eSE  0x01
+# UICC 0x02
+DEFAULT_MIFARE_CLT_ROUTE=0x02
+
+###############################################################################
+# AID Matching platform options
+# AID_MATCHING_L 0x01
+# AID_MATCHING_K 0x02
+AID_MATCHING_PLATFORM=0x01
+
+###############################################################################
+#CHINA_TIANJIN_RF_SETTING
+#Enable  0x01
+#Disable 0x00
+NXP_CHINA_TIANJIN_RF_ENABLED=0x01
+
+###############################################################################
+#SWP_SWITCH_TIMEOUT_SETTING
+# Allowed range of swp timeout setting is 0x00 to 0x3C [0 - 60].
+# Timeout in milliseconds, for example
+# No Timeout  0x00
+# 10 millisecond timeout 0x0A
+NXP_SWP_SWITCH_TIMEOUT=0x0A
diff --git a/halimpl/pn54x/libnfc-nxp-PN548C2_example.conf b/halimpl/pn54x/libnfc-nxp-PN548C2_example.conf
new file mode 100644
index 0000000..5a5fd07
--- /dev/null
+++ b/halimpl/pn54x/libnfc-nxp-PN548C2_example.conf
@@ -0,0 +1,337 @@
+## This file is used by NFC NXP NCI HAL(external/libnfc-nci/halimpl/pn547)
+## and NFC Service Java Native Interface Extensions (packages/apps/Nfc/nci/jni/extns/pn547)
+###############################################################################
+# 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
+
+###############################################################################
+# Nfc Device Node name
+NXP_NFC_DEV_NODE="/dev/nq-nci"
+
+###############################################################################
+# Extension for Mifare reader enable
+MIFARE_READER_ENABLE=0x01
+
+###############################################################################
+# Vzw Feature enable
+VZW_FEATURE_ENABLE=0x01
+
+###############################################################################
+# File name for Firmware
+NXP_FW_NAME="libpn548ad_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_32MHZ         5
+#define CLK_FREQ_38_4MHZ       6
+#define CLK_FREQ_52MHZ         7
+NXP_SYS_CLK_FREQ_SEL=0x02
+
+###############################################################################
+# The timeout value to be used for clock request acknowledgment
+# min value = 0x01 to max = 0x06
+NXP_SYS_CLOCK_TO_CFG=0x06
+
+###############################################################################
+# 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={
+#}
+
+###############################################################################
+## Set configuration optimization decision setting
+## Enable    = 0x01
+## Disable   = 0x00
+NXP_SET_CONFIG_ALWAYS=0x01
+
+###############################################################################
+# Core configuration extensions
+# It includes
+# Wired mode settings A0ED, A0EE
+# Tag Detector A040, A041, A043
+# Low Power mode A007
+# Clock settings A002, A003
+# PbF settings A008
+NXP_CORE_CONF_EXTN={20, 02, 19, 06,
+    A0, EC, 01, 01,
+    A0, ED, 01, 00,
+    A0, 5E, 01, 01,
+    A0, 40, 01, 01,
+    A0, DD, 01, 2D,
+    A0, 96, 01, 01
+    }
+#       A0, 41, 01, 02,
+#       A0, 43, 01, 04,
+#       A0, 02, 01, 01,
+#       A0, 03, 01, 11,
+#       A0, 07, 01, 03,
+#       A0, 08, 01, 01
+#       }
+
+###############################################################################
+# Core configuration rf field filter settings to enable set to 01 to disable set to 00 last bit
+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, 2E, 0E,
+        28, 01, 00,
+        21, 01, 00,
+        30, 01, 08,
+        31, 01, 03,
+        32, 01, 60,
+        38, 01, 01,
+        33, 04, 01, 02, 03, 04,
+        54, 01, 06,
+        50, 01, 02,
+        5B, 01, 00,
+        80, 01, 01,
+        81, 01, 01,
+        82, 01, 0E,
+        18, 01, 01
+        }
+
+###############################################################################
+# Mifare Classic Key settings
+#NXP_CORE_MFCKEY_SETTING={20, 02, 25,04, A0, 51, 06, A0, A1, A2, A3, A4, A5,
+#                                     A0, 52, 06, D3, F7, D3, F7, D3, F7,
+#                                     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
+# This setting is for DEFAULT_AID_ROUTE,
+# DEFAULT_DESFIRE_ROUTE and DEFAULT_MIFARE_CLT_ROUTE
+# 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=20
+
+###############################################################################
+#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
+
+###############################################################################
+#Set the default AID Power state :
+#This settings will be used when application does not set this parameter
+# bit pos 0 = Switch On
+# bit pos 1 = Switch Off
+# bit pos 2 = Battery Off
+# bit pos 3 = Screen Lock
+# bit pos 4 = Screen Off
+DEFAULT_AID_PWR_STATE=0x19
+
+###############################################################################
+#Set the Mifare Desfire Power state :
+#This settings will be used when application does not set this parameter
+# bit pos 0 = Switch On
+# bit pos 1 = Switch Off
+# bit pos 2 = Battery Off
+# bit pos 3 = Screen Lock
+# bit pos 4 = Screen Off
+DEFAULT_DESFIRE_PWR_STATE=0x1B
+
+###############################################################################
+#Set the Mifare CLT Power state :
+#This settings will be used when application does not set this parameter
+# bit pos 0 = Switch On
+# bit pos 1 = Switch Off
+# bit pos 2 = Battery Off
+# bit pos 3 = Screen Lock
+# bit pos 4 = Screen Off
+DEFAULT_MIFARE_CLT_PWR_STATE=0x1B
+
+###############################################################################
+# 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
+
+###############################################################################
+#Dynamic RSSI feature enable
+# Disable 0x00
+# Enable  0x01
+NXP_AGC_DEBUG_ENABLE=0x00
+
+###############################################################################
+# UICC mode supported
+# Disable           0x00
+# Enable            0x01
+NXP_DUAL_UICC_ENABLE=0x00
+
+###############################################################################
+#Config to allow adding aids
+#NFC on/off is required after this config
+#1 = enabling adding aid  to NFCC routing table.
+#0 = disabling adding aid to NFCC routing table.
+NXP_ENABLE_ADD_AID=0x01
+
+###############################################################################
+# Enable/Disable checking default proto SE Id
+# Disable           0x00
+# Enable            0x01
+NXP_CHECK_DEFAULT_PROTO_SE_ID=0x01
+
+###############################################################################
diff --git a/halimpl/pn54x/libnfc-nxp-PN551_example.conf b/halimpl/pn54x/libnfc-nxp-PN551_example.conf
new file mode 100644
index 0000000..990824f
--- /dev/null
+++ b/halimpl/pn54x/libnfc-nxp-PN551_example.conf
@@ -0,0 +1,344 @@
+## This file is used by NFC NXP NCI HAL(external/libnfc-nci/halimpl/pn551)
+## and NFC Service Java Native Interface Extensions (packages/apps/Nfc/nci/jni/extns/pn551)
+###############################################################################
+# 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
+
+###############################################################################
+# Nfc Device Node name
+NXP_NFC_DEV_NODE="/dev/nq-nci"
+
+###############################################################################
+# Extension for Mifare reader enable
+MIFARE_READER_ENABLE=0x01
+
+###############################################################################
+# Vzw Feature enable
+VZW_FEATURE_ENABLE=0x01
+
+###############################################################################
+# File name for Firmware
+NXP_FW_NAME="libpn551_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_32MHZ         5
+#define CLK_FREQ_38_4MHZ       6
+#define CLK_FREQ_52MHZ         7
+NXP_SYS_CLK_FREQ_SEL=0x01
+
+###############################################################################
+# The timeout value to be used for clock request acknowledgment
+# min value = 0x01 to max = 0x06
+NXP_SYS_CLOCK_TO_CFG=0x06
+
+###############################################################################
+# 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, 3.3V 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, 24, 08 }
+
+###############################################################################
+#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, 40, 0A}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_1={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_2={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_3={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_4={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_5={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_6={
+#}
+
+###############################################################################
+## Set configuration optimization decision setting
+## Enable    = 0x01
+## Disable   = 0x00
+NXP_SET_CONFIG_ALWAYS=0x00
+
+###############################################################################
+# Core configuration extensions
+# It includes
+# Wired mode settings A0ED, A0EE
+# Tag Detector A040, A041, A043
+# Low Power mode A007
+# Clock settings A002, A003
+# PbF settings A008
+NXP_CORE_CONF_EXTN={20, 02, 19, 06,
+    A0, EC, 01, 01,
+    A0, ED, 01, 00,
+    A0, 5E, 01, 01,
+    A0, 40, 01, 01,
+    A0, DD, 01, 2D,
+    A0, 96, 01, 01
+    }
+#       A0, 41, 01, 02,
+#       A0, 43, 01, 04,
+#       A0, 02, 01, 01,
+#       A0, 03, 01, 11,
+#       A0, 07, 01, 03,
+#       A0, 08, 01, 01
+#       }
+
+###############################################################################
+# Core configuration rf field filter settings to enable set to 01 to disable set to 00 last bit
+NXP_CORE_RF_FIELD={ 20, 02, 05, 01, A0, 62, 01, 01 }
+
+###############################################################################
+# 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, 2E, 0E,
+        28, 01, 00,
+        21, 01, 00,
+        30, 01, 08,
+        31, 01, 03,
+        32, 01, 60,
+        38, 01, 01,
+        33, 04, 01, 02, 03, 04,
+        54, 01, 06,
+        50, 01, 02,
+        5B, 01, 00,
+        80, 01, 01,
+        81, 01, 01,
+        82, 01, 0E,
+        18, 01, 01
+        }
+
+###############################################################################
+# Mifare Classic Key settings
+#NXP_CORE_MFCKEY_SETTING={20, 02, 25,04, A0, 51, 06, A0, A1, A2, A3, A4, A5,
+#                                     A0, 52, 06, D3, F7, D3, F7, D3, F7,
+#                                     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
+#PN551              0x05
+#PN67T              0x06
+NXP_NFC_CHIP=0x05
+
+###############################################################################
+# CE when Screen state is locked
+# This setting is for DEFAULT_AID_ROUTE,
+# DEFAULT_DESFIRE_ROUTE and DEFAULT_MIFARE_CLT_ROUTE
+# 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=20
+
+###############################################################################
+#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
+
+###############################################################################
+#Set the default AID Power state :
+#This settings will be used when application does not set this parameter
+# bit pos 0 = Switch On
+# bit pos 1 = Switch Off
+# bit pos 2 = Battery Off
+# bit pos 3 = Screen Lock
+# bit pos 4 = Screen Off
+DEFAULT_AID_PWR_STATE=0x19
+
+###############################################################################
+#Set the Mifare Desfire Power state :
+#This settings will be used when application does not set this parameter
+# bit pos 0 = Switch On
+# bit pos 1 = Switch Off
+# bit pos 2 = Battery Off
+# bit pos 3 = Screen Lock
+# bit pos 4 = Screen Off
+DEFAULT_DESFIRE_PWR_STATE=0x1B
+
+###############################################################################
+#Set the Mifare CLT Power state :
+#This settings will be used when application does not set this parameter
+# bit pos 0 = Switch On
+# bit pos 1 = Switch Off
+# bit pos 2 = Battery Off
+# bit pos 3 = Screen Lock
+# bit pos 4 = Screen Off
+DEFAULT_MIFARE_CLT_PWR_STATE=0x1B
+
+###############################################################################
+# 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
+
+###############################################################################
+#Dynamic RSSI feature enable
+# Disable           0x00
+# Enable            0x01
+NXP_AGC_DEBUG_ENABLE=0x00
+
+###############################################################################
+# UICC mode supported
+# Disable           0x00
+# Enable            0x01
+NXP_DUAL_UICC_ENABLE=0x00
+
+###############################################################################
+#Config to allow adding aids
+#NFC on/off is required after this config
+#1 = enabling adding aid  to NFCC routing table.
+#0 = disabling adding aid to NFCC routing table.
+NXP_ENABLE_ADD_AID=0x01
+
+###############################################################################
+# Enable/Disable checking default proto SE Id
+# Disable           0x00
+# Enable            0x01
+NXP_CHECK_DEFAULT_PROTO_SE_ID=0x01
+
+###############################################################################
+# Restrict routing to first matched rule only.
+# Blacklist enable   0x01
+# Blacklist disable  0x00
+NXP_PROP_BLACKLIST_ROUTING=0x00
+
+###############################################################################
diff --git a/halimpl/pn54x/libnfc-nxp-PN553_example.conf b/halimpl/pn54x/libnfc-nxp-PN553_example.conf
new file mode 100644
index 0000000..1fdedf5
--- /dev/null
+++ b/halimpl/pn54x/libnfc-nxp-PN553_example.conf
@@ -0,0 +1,478 @@
+## This file is used by NFC NXP NCI HAL(external/libnfc-nci/halimpl/pn547)
+## and NFC Service Java Native Interface Extensions (packages/apps/Nfc/nci/jni/extns/pn547)
+###############################################################################
+# 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
+
+###############################################################################
+# Nfc Device Node name
+NXP_NFC_DEV_NODE="/dev/nq-nci"
+
+###############################################################################
+# Extension for Mifare reader enable
+MIFARE_READER_ENABLE=0x01
+
+###############################################################################
+# Vzw Feature enable
+VZW_FEATURE_ENABLE=0x01
+
+###############################################################################
+# File name for Firmware
+NXP_FW_NAME="libpn553_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_32MHZ         5
+#define CLK_FREQ_38_4MHZ       6
+#define CLK_FREQ_52MHZ         7
+NXP_SYS_CLK_FREQ_SEL=0x02
+
+###############################################################################
+# The timeout value to be used for clock request acknowledgment
+# min value = 0x01 to max = 0x06
+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, two configurations (1 and 2) supported,
+# out of them only one can be configured at a time.
+NXP_EXT_TVDD_CFG=0x02
+
+###############################################################################
+#config1:SLALM, 3.3V for both RM and CM
+NXP_EXT_TVDD_CFG_1={20, 02, 0F, 01, A0, 0E, 0B, 31, 01, 01, 31, 00, 00, 00, 01, 00, D0, 0C}
+
+###############################################################################
+#config2: use DCDC in CE, use Tx_Pwr_Req, set CFG2 mode, SLALM,
+#monitoring 5V from DCDC, 3.3V for both RM and CM, DCDCWaitTime=4.2ms
+NXP_EXT_TVDD_CFG_2={20, 02, 0F, 01, A0, 0E, 0B, 11, 01, C2, B2, 00, B2, 1E, 1F, 00, D0, 0C}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+# DPC deactivated
+NXP_RF_CONF_BLK_1={
+20, 02, 5C, 01, A0, 0B, 58, 10, 90, 90, 78, 0F, 4E, 32, 00, 3D, 9F, 00, 00, 3D,
+9F, 00, 00, 50, 9F, 00, 00, 59, 9F, 00, 00, 5A, 9F, 00, 00, 64, 9F, 00, 00, 65,
+9F, 00, 00, 6E, 9F, 00, 00, 72, 9F, 00, 00, 79, 9F, 00, 00, 7B, 9F, 00, 00, 84,
+9F, 00, 00, 86, 9F, 00, 00, 8F, 9F, 00, 00, 91, 9F, 00, 00, 9A, 9F, 00, 00, A1,
+9F, 00, 00, A7, 1F, 00, 00, B0, 1F, 00, 00, B9, 1F, 00, 00
+}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+# DLMA Deactivated
+NXP_RF_CONF_BLK_2={
+20, 02, D6, 01, A0, 34, D2, 23, 04, 18, 07, 40, 00, 20, 40, 00, BE, 23, 60, 00,
+2B, 13, 40, 00, B8, 21, 60, 00, 38, 35, 00, 00, 18, 46, 08, 00, DE, 54, 08, 02,
+00, 00, 08, 02, 00, 00, 08, 02, 00, 00, 08, 02, 00, 00, 08, 02, 00, 00, 08, 02,
+00, 00, 08, 02, 00, 00, 48, 01, 00, 00, 08, 03, 00, 00, 08, 01, 00, 00, C8, 02,
+00, 00, C8, 00, 00, 00, 88, 02, 00, 00, 48, 02, 00, 00, B8, 00, 00, 00, 68, 00,
+00, 00, 18, 00, 00, 00, 08, 02, 00, 00, 00, 00, 00, 00, 00, 00, 07, 00, 20, 40,
+00, BE, 23, 60, 00, 2B, 13, 40, 00, B8, 21, 60, 00, 38, 35, 00, 00, 18, 46, 08,
+00, DE, 54, 08, 02, 00, 00, 08, 02, 00, 00, 08, 02, 00, 00, 08, 02, 00, 00, 08,
+02, 00, 00, 08, 02, 00, 00, 08, 02, 00, 00, 48, 01, 00, 00, 08, 03, 00, 00, 08,
+01, 00, 00, C8, 02, 00, 00, C8, 00, 00, 00, 88, 02, 00, 00, 48, 02, 00, 00, B8,
+00, 00, 00, 68, 00, 00, 00, 18, 00, 00, 00, 08, 02, 00, 00, 00, 00
+}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_3={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_4={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_5={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_6={
+#}
+
+###############################################################################
+# Set configuration optimization decision setting
+# Enable    = 0x01
+# Disable   = 0x00
+NXP_SET_CONFIG_ALWAYS=0x00
+
+###############################################################################
+# Core configuration extensions
+# It includes
+# Wired mode settings A0ED, A0EE
+# Tag Detector A040, A041, A043
+# Low Power mode A007
+# Clock settings A002, A003
+# PbF settings A008
+# Clock timeout settings A004
+# eSE (SVDD) PWR REQ settings A0F2
+# How eSE connected to PN553 A012
+# UICC2 bit rate A0D1
+# SWP1A interface A0D4
+# DWP intf behavior config, SVDD Load activated by default if set to 0x31 - A037
+NXP_CORE_CONF_EXTN={20, 02, 25, 09,
+    A0, EC, 01, 01,
+    A0, ED, 01, 01,
+    A0, 5E, 01, 01,
+    A0, 12, 01, 02,
+    A0, 40, 01, 01,
+    A0, DD, 01, 2D,
+    A0, D1, 01, 02,
+    A0, D4, 01, 01,
+    A0, 37, 01, 35
+   }
+#       A0, F2, 01, 01,
+#       A0, 40, 01, 01,
+#       A0, 41, 01, 02,
+#       A0, 43, 01, 04,
+#       A0, 02, 01, 01,
+#       A0, 03, 01, 11,
+#       A0, 07, 01, 03,
+#       A0, 08, 01, 01
+#       }
+
+###############################################################################
+# Core configuration rf field filter settings to enable set to 01 to disable set
+# to 00 last bit
+NXP_CORE_RF_FIELD={ 20, 02, 05, 01, A0, 62, 01, 00 }
+
+###############################################################################
+# 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, 2E, 0E,
+        28, 01, 00,
+        21, 01, 00,
+        30, 01, 08,
+        31, 01, 03,
+        32, 01, 60,
+        38, 01, 01,
+        33, 04, 01, 02, 03, 04,
+        54, 01, 06,
+        50, 01, 02,
+        5B, 01, 00,
+        80, 01, 01,
+        81, 01, 01,
+        82, 01, 0E,
+        18, 01, 01
+        }
+
+###############################################################################
+# Mifare Classic Key settings
+#NXP_CORE_MFCKEY_SETTING={20, 02, 25,04, A0, 51, 06, A0, A1, A2, A3, A4, A5,
+#                                     A0, 52, 06, D3, F7, D3, F7, D3, F7,
+#                                     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
+# UICC2             0x04
+
+NXP_DEFAULT_SE=0x07
+
+###############################################################################
+#Enable SWP full power mode when phone is power off
+NXP_SWP_FULL_PWR_ON=0x00
+
+###############################################################################
+#### Select the CHIP ####
+#PN547C2            0x01
+#PN65T              0x02
+#PN548AD            0x03
+#PN66T              0x04
+#PN551              0x05
+#PN67T              0x06
+#PN553              0x07
+#PN80T              0x08
+NXP_NFC_CHIP=0x07
+
+###############################################################################
+# CE when Screen state is locked
+# This setting is for DEFAULT_AID_ROUTE,
+# DEFAULT_DESFIRE_ROUTE and DEFAULT_MIFARE_CLT_ROUTE
+# 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=20
+
+###############################################################################
+#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
+# UICC2 0x03
+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
+# UICC2 0x03
+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
+# UICC2 0x03
+DEFAULT_MIFARE_CLT_ROUTE=0x02
+
+###############################################################################
+#Set the default AID Power state :
+#This settings will be used when application does not set this parameter
+# bit pos 0 = Switch On
+# bit pos 1 = Switch Off
+# bit pos 2 = Battery Off
+# bit pos 3 = Screen Lock
+# bit pos 4 = Screen Off
+DEFAULT_AID_PWR_STATE=0x19
+
+###############################################################################
+#Set the Mifare Desfire Power state :
+#This settings will be used when application does not set this parameter
+# bit pos 0 = Switch On
+# bit pos 1 = Switch Off
+# bit pos 2 = Battery Off
+# bit pos 3 = Screen Lock
+# bit pos 4 = Screen Off
+DEFAULT_DESFIRE_PWR_STATE=0x1B
+
+###############################################################################
+#Set the Mifare CLT Power state :
+#This settings will be used when application does not set this parameter
+# bit pos 0 = Switch On
+# bit pos 1 = Switch Off
+# bit pos 2 = Battery Off
+# bit pos 3 = Screen Lock
+# bit pos 4 = Screen Off
+DEFAULT_MIFARE_CLT_PWR_STATE=0x1B
+
+###############################################################################
+#Set the Felica CLT route Location :
+#This settings will be used when application does not set this parameter
+# eSE  0x01
+# UICC 0x02
+# UICC2 0x03
+DEFAULT_FELICA_CLT_ROUTE=0x01
+
+###############################################################################
+#Set the Felica CLT Power state :
+#This settings will be used when application does not set this parameter
+# bit pos 0 = Switch On
+# bit pos 1 = Switch Off
+# bit pos 2 = Battery Off
+# bit pos 3 = Screen Lock
+# bit pos 4 = Screen Off
+DEFAULT_FELICA_CLT_PWR_STATE=0x1B
+
+###############################################################################
+# 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=0x22
+
+###############################################################################
+#Timeout value  in milliseconds for NFCC standby mode.The range is between 5000
+#msec to 20000 msec and zero is to disable.
+NXP_NFCC_STANDBY_TIMEOUT=20000
+
+###############################################################################
+#Dynamic RSSI feature enable
+# Disable           0x00
+# Enable            0x01
+NXP_AGC_DEBUG_ENABLE=0x00
+
+###############################################################################
+#Virtual Mode ESE and Wired Mode ongoing delay Wired Mode
+# For Technology routing to ESE Technology Mask = 4
+# For ISO-DEP Protocol routing to ESE Mask      = 2
+# It can also take TECH|PROTO    = 6
+# To ignore the delay set mask to = 0
+NXP_ESE_WIRED_PRT_MASK=0x00
+
+###############################################################################
+#Virtual Mode UICC and Wired Mode  ongoing delay Wired Mode
+#For Technology routing to UICC Technology Mask = 4
+#For ISO-DEP Protocol routing to UICC set Mask  = 2
+#For Select AID Routing to UICC       set Mask  = 1
+#It can also take values TECH|PROTO|SELECT_AID  = 7 , 6 , 5 ,3 .To ignore delay
+#set mask = 0
+NXP_UICC_WIRED_PRT_MASK=0x00
+
+###############################################################################
+#RF field true delay Wired Mode
+# delay wired mode = 1
+# allow wired mode = 0
+NXP_WIRED_MODE_RF_FIELD_ENABLE=0x00
+
+###############################################################################
+#Config to allow adding aids
+#NFC on/off is required after this config
+#1 = enabling adding aid  to NFCC routing table.
+#0 = disabling adding aid to NFCC routing table.
+NXP_ENABLE_ADD_AID=0x01
+
+###############################################################################
+# JCOP-3.3 continuous process timeout in msec and value should be in Hexadecimal
+# JCOP CP TIMEOUT
+NXP_CP_TIMEOUT={00, 77}
+
+###############################################################################
+# Enable/Disable checking default proto SE Id
+# Disable           0x00
+# Enable            0x01
+NXP_CHECK_DEFAULT_PROTO_SE_ID=0x01
+
+###############################################################################
+#NXP_CN_TRANSIT_BLK_NUM_CHECK_ENABLE
+#Enable/Disable block number checks for china transit use case
+#Enable  0x01
+#Disable  0x00
+NXP_CN_TRANSIT_BLK_NUM_CHECK_ENABLE=0x01
+
+###############################################################################
+#This config will enable different level of Rf transaction debugs based on the
+#following values provided. Decoded information will be printed in adb logcat
+#Debug Mode         Levels
+#Disable Debug      0x00
+#L1 Debug           0x01
+#L2 Debug           0x02
+#L1 & L2 Debug      0x03
+#L1 & L2 & RSSI     0x04
+#L1 & L2 & Felica   0x05
+#NXP_CORE_PROP_SYSTEM_DEBUG=0x00
+
+###############################################################################
+# Restrict routing to first matched rule only.
+# Blacklist enable   0x01
+# Blacklist disable  0x00
+NXP_PROP_BLACKLIST_ROUTING=0x00
+
+###############################################################################
+# Timeout value in milliseconds to send response for Felica command received
+NXP_HCEF_CMD_RSP_TIMEOUT_VALUE=5000
+
+###############################################################################
diff --git a/halimpl/pn54x/libnfc-nxp-PN557_example.conf b/halimpl/pn54x/libnfc-nxp-PN557_example.conf
new file mode 100644
index 0000000..db3b79d
--- /dev/null
+++ b/halimpl/pn54x/libnfc-nxp-PN557_example.conf
@@ -0,0 +1,453 @@
+## This file is used by NFC NXP NCI HAL(external/libnfc-nci/halimpl/pn547)
+## and NFC Service Java Native Interface Extensions (packages/apps/Nfc/nci/jni/extns/pn547)
+###############################################################################
+# 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
+
+###############################################################################
+# Nfc Device Node name
+NXP_NFC_DEV_NODE="/dev/nq-nci"
+
+###############################################################################
+# Extension for Mifare reader enable
+MIFARE_READER_ENABLE=0x01
+
+###############################################################################
+# Vzw Feature enable
+VZW_FEATURE_ENABLE=0x01
+
+###############################################################################
+# File name for Firmware
+NXP_FW_NAME="libpn553_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 = 0x06
+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, two configurations (1 and 2) supported,
+# out of them only one can be configured at a time.
+NXP_EXT_TVDD_CFG=0x02
+
+###############################################################################
+#config1:SLALM, 3.3V for both RM and CM
+NXP_EXT_TVDD_CFG_1={20, 02, 0F, 01, A0, 0E, 0B, 31, 01, 01, 31, 00, 00, 00, 01, 00, D0, 0C}
+
+###############################################################################
+#config2: use DCDC in CE, use Tx_Pwr_Req, set CFG2 mode, SLALM,
+#monitoring 5V from DCDC, 3.3V for both RM and CM, DCDCWaitTime=4.2ms
+NXP_EXT_TVDD_CFG_2={20, 02, 0F, 01, A0, 0E, 0B, 11, 01, C2, B2, 00, B2, 1E, 1F, 00, D0, 0C}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_1={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_2={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_3={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_4={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_5={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_6={
+#}
+
+###############################################################################
+# Set configuration optimization decision setting
+# Enable    = 0x01
+# Disable   = 0x00
+NXP_SET_CONFIG_ALWAYS=0x00
+
+###############################################################################
+# Core configuration extensions
+# It includes
+# Wired mode settings A0ED, A0EE
+# Tag Detector A040, A041, A043
+# Low Power mode A007
+# Clock settings A002, A003
+# PbF settings A008
+# Clock timeout settings A004
+# eSE (SVDD) PWR REQ settings A0F2
+# How eSE connected to PN553 A012
+# UICC2 bit rate A0D1
+# SWP1A interface A0D4
+# DWP intf behavior config, SVDD Load activated by default if set to 0x31 - A037
+NXP_CORE_CONF_EXTN={20, 02, 25, 09,
+    A0, EC, 01, 01,
+    A0, ED, 01, 00,
+    A0, 5E, 01, 01,
+    A0, 12, 01, 02,
+    A0, 40, 01, 01,
+    A0, DD, 01, 2D,
+    A0, D1, 01, 02,
+    A0, D4, 01, 01,
+    A0, 37, 01, 35
+   }
+#       A0, F2, 01, 01,
+#       A0, 40, 01, 01,
+#       A0, 41, 01, 02,
+#       A0, 43, 01, 04,
+#       A0, 02, 01, 01,
+#       A0, 03, 01, 11,
+#       A0, 07, 01, 03,
+#       A0, 08, 01, 01
+#       }
+
+###############################################################################
+# Core configuration rf field filter settings to enable set to 01 to disable set
+# to 00 last bit
+NXP_CORE_RF_FIELD={ 20, 02, 05, 01, A0, 62, 01, 00 }
+
+###############################################################################
+# 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, 34, 10,
+        85, 01, 01,
+        28, 01, 00,
+        21, 01, 00,
+        30, 01, 08,
+        31, 01, 03,
+        32, 01, 60,
+        38, 01, 01,
+        33, 04, 01, 02, 03, 04,
+        54, 01, 06,
+        50, 01, 02,
+        5B, 01, 00,
+        80, 01, 01,
+        81, 01, 01,
+        82, 01, 0E,
+        18, 01, 01,
+        68, 01, 00
+        }
+
+###############################################################################
+# 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
+# UICC2             0x04
+
+NXP_DEFAULT_SE=0x07
+
+###############################################################################
+#Enable SWP full power mode when phone is power off
+NXP_SWP_FULL_PWR_ON=0x00
+
+###############################################################################
+#### Select the CHIP ####
+#PN547C2            0x01
+#PN65T              0x02
+#PN548AD            0x03
+#PN66T              0x04
+#PN551              0x05
+#PN67T              0x06
+#PN553              0x07
+#PN80T              0x08
+NXP_NFC_CHIP=0x07
+
+###############################################################################
+# CE when Screen state is locked
+# This setting is for DEFAULT_AID_ROUTE,
+# DEFAULT_DESFIRE_ROUTE and DEFAULT_MIFARE_CLT_ROUTE
+# 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=20
+
+###############################################################################
+#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
+# UICC2 0x03
+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
+# UICC2 0x03
+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
+# UICC2 0x03
+DEFAULT_MIFARE_CLT_ROUTE=0x02
+
+###############################################################################
+#Set the default AID Power state :
+#This settings will be used when application does not set this parameter
+# bit pos 0 = Switch On
+# bit pos 1 = Switch Off
+# bit pos 2 = Battery Off
+# bit pos 3 = Screen Off lock
+# bit pos 4 = Screen On lock
+# bit pos 5 = Screen Off lock
+DEFAULT_AID_PWR_STATE=0x39
+
+###############################################################################
+#Set the Mifare Desfire Power state :
+#This settings will be used when application does not set this parameter
+# bit pos 0 = Switch On
+# bit pos 1 = Switch Off
+# bit pos 2 = Battery Off
+# bit pos 3 = Screen Off lock
+# bit pos 4 = Screen On lock
+# bit pos 5 = Screen Off lock
+DEFAULT_DESFIRE_PWR_STATE=0x3B
+
+###############################################################################
+#Set the Mifare CLT Power state :
+#This settings will be used when application does not set this parameter
+# bit pos 0 = Switch On
+# bit pos 1 = Switch Off
+# bit pos 2 = Battery Off
+# bit pos 3 = Screen Off lock
+# bit pos 4 = Screen On lock
+# bit pos 5 = Screen Off lock
+DEFAULT_MIFARE_CLT_PWR_STATE=0x3B
+
+###############################################################################
+#Set the Felica CLT route Location :
+#This settings will be used when application does not set this parameter
+# eSE  0x01
+# UICC 0x02
+# UICC2 0x03
+DEFAULT_FELICA_CLT_ROUTE=0x01
+
+###############################################################################
+#Set the Felica CLT Power state :
+#This settings will be used when application does not set this parameter
+# bit pos 0 = Switch On
+# bit pos 1 = Switch Off
+# bit pos 2 = Battery Off
+# bit pos 3 = Screen Off lock
+# bit pos 4 = Screen On lock
+# bit pos 5 = Screen Off lock
+DEFAULT_FELICA_CLT_PWR_STATE=0x3B
+
+###############################################################################
+# 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=0x22
+
+###############################################################################
+#Timeout value  in milliseconds for NFCC standby mode.The range is between 5000
+#msec to 20000 msec and zero is to disable.
+NXP_NFCC_STANDBY_TIMEOUT=20000
+
+###############################################################################
+#Dynamic RSSI feature enable
+# Disable           0x00
+# Enable            0x01
+NXP_AGC_DEBUG_ENABLE=0x00
+
+###############################################################################
+#Virtual Mode ESE and Wired Mode ongoing delay Wired Mode
+# For Technology routing to ESE Technology Mask = 4
+# For ISO-DEP Protocol routing to ESE Mask      = 2
+# It can also take TECH|PROTO    = 6
+# To ignore the delay set mask to = 0
+NXP_ESE_WIRED_PRT_MASK=0x00
+
+###############################################################################
+#Virtual Mode UICC and Wired Mode  ongoing delay Wired Mode
+#For Technology routing to UICC Technology Mask = 4
+#For ISO-DEP Protocol routing to UICC set Mask  = 2
+#For Select AID Routing to UICC       set Mask  = 1
+#It can also take values TECH|PROTO|SELECT_AID  = 7 , 6 , 5 ,3 .To ignore delay
+#set mask = 0
+NXP_UICC_WIRED_PRT_MASK=0x00
+
+###############################################################################
+#RF field true delay Wired Mode
+# delay wired mode = 1
+# allow wired mode = 0
+NXP_WIRED_MODE_RF_FIELD_ENABLE=0x00
+
+###############################################################################
+#Config to allow adding aids
+#NFC on/off is required after this config
+#1 = enabling adding aid  to NFCC routing table.
+#0 = disabling adding aid to NFCC routing table.
+NXP_ENABLE_ADD_AID=0x01
+
+###############################################################################
+# JCOP-3.3 continuous process timeout in msec and value should be in Hexadecimal
+# JCOP CP TIMEOUT
+NXP_CP_TIMEOUT={00, 77}
+
+###############################################################################
+# Enable/Disable checking default proto SE Id
+# Disable           0x00
+# Enable            0x01
+NXP_CHECK_DEFAULT_PROTO_SE_ID=0x01
+
+###############################################################################
+#NXP_CN_TRANSIT_BLK_NUM_CHECK_ENABLE
+#Enable/Disable block number checks for china transit use case
+#Enable  0x01
+#Disable  0x00
+NXP_CN_TRANSIT_BLK_NUM_CHECK_ENABLE=0x01
+
+###############################################################################
+# Restrict routing to first matched rule only.
+# Blacklist enable   0x01
+# Blacklist disable  0x00
+NXP_PROP_BLACKLIST_ROUTING=0x00
+
+###############################################################################
+# Timeout value in milliseconds to send response for Felica command received
+NXP_HCEF_CMD_RSP_TIMEOUT_VALUE=5000
+
+###############################################################################
diff --git a/halimpl/pn54x/libnfc-nxp-PN65T_example.conf b/halimpl/pn54x/libnfc-nxp-PN65T_example.conf
new file mode 100644
index 0000000..3a9a807
--- /dev/null
+++ b/halimpl/pn54x/libnfc-nxp-PN65T_example.conf
@@ -0,0 +1,313 @@
+## This file is used by NFC NXP NCI HAL(external/libnfc-nci/halimpl/pn547)
+## and NFC Service Java Native Interface Extensions (packages/apps/Nfc/nci/jni/extns/pn547)
+###############################################################################
+# 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
+
+###############################################################################
+# Nfc Device Node name
+NXP_NFC_DEV_NODE="/dev/nq-nci"
+
+###############################################################################
+# Extension for Mifare reader enable
+MIFARE_READER_ENABLE=0x01
+
+###############################################################################
+# Vzw Feature enable
+VZW_FEATURE_ENABLE=0x01
+
+###############################################################################
+# File name for Firmware
+NXP_FW_NAME="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_32MHZ         5
+#define CLK_FREQ_38_4MHZ       6
+#define CLK_FREQ_52MHZ         7
+NXP_SYS_CLK_FREQ_SEL=0x00
+
+###############################################################################
+# The timeout value to be used for clock request acknowledgment
+# min value = 0x01 to max = 0x06
+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={
+#}
+
+###############################################################################
+## Set configuration optimization decision setting
+## Enable    = 0x01
+## Disable   = 0x00
+NXP_SET_CONFIG_ALWAYS=0x01
+
+###############################################################################
+# Core configuration extensions
+# It includes
+# Wired mode settings A0ED, A0EE
+# Tag Detector A040, A041, A043
+# Low Power mode A007
+# Clock settings A002, A003
+# PbF settings A008
+NXP_CORE_CONF_EXTN={20, 02, 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
+    }
+#       A0, 40, 01, 01, 
+#       A0, 41, 01, 02, 
+#       A0, 43, 01, 04,
+#       A0, 02, 01, 01, 
+#       A0, 03, 01, 11,
+#       A0, 07, 01, 03,
+#       A0, 08, 01, 01
+#       }
+
+###############################################################################
+# Core configuration rf field filter settings to enable set to 01 to disable set
+# to 00 last bit
+NXP_CORE_RF_FIELD={ 20, 02, 05, 01, A0, 62, 01, 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=20
+
+###############################################################################
+#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=0x0A
+
+###############################################################################
+#Timeout in secs
+NXP_SWP_RD_TAG_OP_TIMEOUT=0x01
+
+###############################################################################
+# CE when Screen state is locked
+# This setting is for DEFAULT_AID_ROUTE,
+# DEFAULT_DESFIRE_ROUTE and DEFAULT_MIFARE_CLT_ROUTE
+# 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
+
+################################################################################
+#Used to Restrict Type A UICC baud rate
+#0 = default supported
+#1 = 212 maximum supported
+#2 = 424 maximum supported
+#3 = 848 maximum supported
+NXP_TYPEA_UICC_BAUD_RATE=0x00
+
+################################################################################
+#Used to Restrict Type B UICC baud rate
+#0 = default supported
+#1 = 212 maximum supported
+#2 = 424 maximum supported
+#3 = 848 maximum supported
+NXP_TYPEB_UICC_BAUD_RATE=0x00
+
+###############################################################################
+#Config to allow adding aids
+#NFC on/off is required after this config
+#1 = enabling adding aid  to NFCC routing table.
+#0 = disabling adding aid to NFCC routing table.
+NXP_ENABLE_ADD_AID=0x01
+
+###############################################################################
diff --git a/halimpl/pn54x/libnfc-nxp-PN66T_example.conf b/halimpl/pn54x/libnfc-nxp-PN66T_example.conf
new file mode 100644
index 0000000..1af8100
--- /dev/null
+++ b/halimpl/pn54x/libnfc-nxp-PN66T_example.conf
@@ -0,0 +1,423 @@
+## This file is used by NFC NXP NCI HAL(external/libnfc-nci/halimpl/pn547)
+## and NFC Service Java Native Interface Extensions (packages/apps/Nfc/nci/jni/extns/pn547)
+###############################################################################
+# 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
+
+###############################################################################
+# Nfc Device Node name
+NXP_NFC_DEV_NODE="/dev/nq-nci"
+
+###############################################################################
+# Extension for Mifare reader enable
+MIFARE_READER_ENABLE=0x01
+
+###############################################################################
+# Vzw Feature enable
+VZW_FEATURE_ENABLE=0x01
+
+###############################################################################
+# File name for Firmware
+NXP_FW_NAME="libpn548ad_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_32MHZ         5
+#define CLK_FREQ_38_4MHZ       6
+#define CLK_FREQ_52MHZ         7
+NXP_SYS_CLK_FREQ_SEL=0x02
+
+###############################################################################
+# The timeout value to be used for clock request acknowledgment
+# min value = 0x01 to max = 0x06
+NXP_SYS_CLOCK_TO_CFG=0x06
+
+###############################################################################
+# 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={
+#}
+
+###############################################################################
+# Set configuration optimization decision setting
+# Enable    = 0x01
+# Disable   = 0x00
+NXP_SET_CONFIG_ALWAYS=0x01
+
+###############################################################################
+# Core configuration extensions
+# It includes
+# Wired mode settings A0ED, A0EE
+# Tag Detector A040, A041, A043
+# Low Power mode A007
+# Clock settings A002, A003
+# PbF settings A008
+# Clock timeout settings A004
+# A0 9F 02 <svdd ON guard time (msec)> <svdd off guard time(msec)>
+NXP_CORE_CONF_EXTN={20, 02, 26, 09,
+    A0, EC, 01, 01,
+    A0, ED, 01, 03,
+    A0, 5E, 01, 01,
+    A0, 12, 01, 02,
+    A0, 40, 01, 01,
+    A0, DD, 01, 2D,
+    A0, F2, 01, 01,
+    A0, 96, 01, 01,
+    A0, 9F, 02, 08, 08
+    }
+#       A0, 41, 01, 02,
+#       A0, 43, 01, 04,
+#       A0, 02, 01, 01,
+#       A0, 03, 01, 11,
+#       A0, 07, 01, 03,
+#       A0, 08, 01, 01
+#       }
+
+###############################################################################
+# Core configuration rf field filter settings to enable set to 01 to disable set
+# 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, 2E, 0E,
+        28, 01, 00,
+        21, 01, 00,
+        30, 01, 08,
+        31, 01, 03,
+        32, 01, 60,
+        38, 01, 01,
+        33, 04, 01, 02, 03, 04,
+        54, 01, 06,
+        50, 01, 02,
+        5B, 01, 00,
+        80, 01, 01,
+        81, 01, 01,
+        82, 01, 0E,
+        18, 01, 01
+        }
+
+###############################################################################
+# Mifare Classic Key settings
+#NXP_CORE_MFCKEY_SETTING={20, 02, 25,04, A0, 51, 06, A0, A1, A2, A3, A4, A5,
+#                                     A0, 52, 06, D3, F7, D3, F7, D3, F7,
+#                                     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
+#PN551              0x05
+#PN67T              0x06
+NXP_NFC_CHIP=0x04
+
+###############################################################################
+# CE when Screen state is locked
+# This setting is for DEFAULT_AID_ROUTE,
+# DEFAULT_DESFIRE_ROUTE and DEFAULT_MIFARE_CLT_ROUTE
+# 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=20
+
+###############################################################################
+#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
+
+###############################################################################
+#Set the default AID Power state :
+#This settings will be used when application does not set this parameter
+# bit pos 0 = Switch On
+# bit pos 1 = Switch Off
+# bit pos 2 = Battery Off
+# bit pos 3 = Screen Lock
+# bit pos 4 = Screen Off
+DEFAULT_AID_PWR_STATE=0x19
+
+###############################################################################
+#Set the Mifare Desfire Power state :
+#This settings will be used when application does not set this parameter
+# bit pos 0 = Switch On
+# bit pos 1 = Switch Off
+# bit pos 2 = Battery Off
+# bit pos 3 = Screen Lock
+# bit pos 4 = Screen Off
+DEFAULT_DESFIRE_PWR_STATE=0x1B
+
+###############################################################################
+#Set the Mifare CLT Power state :
+#This settings will be used when application does not set this parameter
+# bit pos 0 = Switch On
+# bit pos 1 = Switch Off
+# bit pos 2 = Battery Off
+# bit pos 3 = Screen Lock
+# bit pos 4 = Screen Off
+DEFAULT_MIFARE_CLT_PWR_STATE=0x1B
+
+###############################################################################
+# 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
+
+###############################################################################
+#Timeout value  in milliseconds for NFCC standby mode.The range is between 5000
+#msec to 20000 msec and zero is to disable.
+NXP_NFCC_STANDBY_TIMEOUT=20000
+
+###############################################################################
+#Dynamic RSSI feature enable
+# Disable 0x00
+# Enable  0x01
+NXP_AGC_DEBUG_ENABLE=0x00
+
+###############################################################################
+#Virtual Mode ESE and Wired Mode ongoing delay Wired Mode
+# For Technology routing to ESE Technology Mask = 4
+# For ISO-DEP Protocol routing to ESE Mask      = 2
+# It can also take TECH|PROTO    = 6
+# To ignore the delay set mask to = 0
+NXP_ESE_WIRED_PRT_MASK=0x00
+
+###############################################################################
+#Virtual Mode UICC and Wired Mode  ongoing delay Wired Mode
+#For Technology routing to UICC Technology Mask = 4
+#For ISO-DEP Protocol routing to UICC set Mask  = 2
+#For Select AID Routing to UICC       set Mask  = 1
+#It can also take values TECH|PROTO|SELECT_AID  = 7 , 6 , 5 ,3 .To ignore delay
+#set mask = 0
+NXP_UICC_WIRED_PRT_MASK=0x00
+
+################################################################################
+#RF field true delay Wired Mode
+# delay wired mode = 1
+# allow wired mode = 0
+NXP_WIRED_MODE_RF_FIELD_ENABLE=0x00
+
+###############################################################################
+#Config to allow adding aids
+#NFC on/off is required after this config
+#1 = enabling adding aid  to NFCC routing table.
+#0 = disabling adding aid to NFCC routing table.
+NXP_ENABLE_ADD_AID=0x01
+
+###############################################################################
+# UICC mode supported
+# Disable           0x00
+# Enable            0x01
+NXP_DUAL_UICC_ENABLE=0x00
+
+###############################################################################
+# JCOP-3.3 continuous process timeout in msec and value should be in Hexadecimal
+# JCOP CP TIMEOUT
+# NXP_CP_TIMEOUT={00, 77}
+
+###############################################################################
+# Enable/Disable checking default proto SE Id
+# Disable           0x00
+# Enable            0x01
+NXP_CHECK_DEFAULT_PROTO_SE_ID=0x01
+
+###############################################################################
+# SVDD sync off Delay in ms it can be max 20 ms
+# If out of range timeout used, default delay of 10ms will be set
+NXP_SVDD_SYNC_OFF_DELAY=10
+
+###############################################################################
+#NXP_CN_TRANSIT_BLK_NUM_CHECK_ENABLE
+#Enable/Disable block number checks for china transit use case
+#Enable  0x01
+#Disable  0x00
+NXP_CN_TRANSIT_BLK_NUM_CHECK_ENABLE=0x01
+
+###############################################################################
diff --git a/halimpl/pn54x/libnfc-nxp-PN67T_example.conf b/halimpl/pn54x/libnfc-nxp-PN67T_example.conf
new file mode 100644
index 0000000..25f7a5f
--- /dev/null
+++ b/halimpl/pn54x/libnfc-nxp-PN67T_example.conf
@@ -0,0 +1,434 @@
+## This file is used by NFC NXP NCI HAL(external/libnfc-nci/halimpl/pn547)
+## and NFC Service Java Native Interface Extensions (packages/apps/Nfc/nci/jni/extns/pn547)
+###############################################################################
+# 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
+
+###############################################################################
+# Nfc Device Node name
+NXP_NFC_DEV_NODE="/dev/nq-nci"
+
+###############################################################################
+# Extension for Mifare reader enable
+MIFARE_READER_ENABLE=0x01
+
+###############################################################################
+# Vzw Feature enable
+VZW_FEATURE_ENABLE=0x01
+
+###############################################################################
+# File name for Firmware
+NXP_FW_NAME="libpn551_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_32MHZ         5
+#define CLK_FREQ_38_4MHZ       6
+#define CLK_FREQ_52MHZ         7
+NXP_SYS_CLK_FREQ_SEL=0x02
+
+###############################################################################
+# The timeout value to be used for clock request acknowledgment
+# min value = 0x01 to max = 0x06
+NXP_SYS_CLOCK_TO_CFG=0x06
+
+###############################################################################
+# 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={
+#}
+
+###############################################################################
+# Set configuration optimization decision setting
+# Enable    = 0x01
+# Disable   = 0x00
+NXP_SET_CONFIG_ALWAYS=0x00
+
+###############################################################################
+# Core configuration extensions
+# It includes
+# Wired mode settings A0ED, A0EE
+# Tag Detector A040, A041, A043
+# Low Power mode A007
+# Clock settings A002, A003
+# PbF settings A008
+# Clock timeout settings A004
+# A0 9F 02 <svdd ON guard time (msec)> <svdd off guard time(msec)>
+NXP_CORE_CONF_EXTN={20, 02, 26, 09,
+    A0, EC, 01, 01,
+    A0, ED, 01, 03,
+    A0, 5E, 01, 01,
+    A0, 12, 01, 02,
+    A0, 40, 01, 01,
+    A0, DD, 01, 2D,
+    A0, F2, 01, 01,
+    A0, 96, 01, 01,
+    A0, 9F, 02, 08, 08
+    }
+#       A0, 41, 01, 02,
+#       A0, 43, 01, 04,
+#       A0, 02, 01, 01,
+#       A0, 03, 01, 11,
+#       A0, 07, 01, 03,
+#       A0, 08, 01, 01
+#       }
+
+###############################################################################
+# Core configuration rf field filter settings to enable set to 01 to disable set
+# to 00 last bit
+NXP_CORE_RF_FIELD={ 20, 02, 05, 01, A0, 62, 01, 01 }
+
+###############################################################################
+# 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, 2E, 0E,
+        28, 01, 00,
+        21, 01, 00,
+        30, 01, 08,
+        31, 01, 03,
+        32, 01, 60,
+        38, 01, 01,
+        33, 04, 01, 02, 03, 04,
+        54, 01, 06,
+        50, 01, 02,
+        5B, 01, 00,
+        80, 01, 01,
+        81, 01, 01,
+        82, 01, 0E,
+        18, 01, 01
+        }
+
+###############################################################################
+# Mifare Classic Key settings
+#NXP_CORE_MFCKEY_SETTING={20, 02, 25,04, A0, 51, 06, A0, A1, A2, A3, A4, A5,
+#                                     A0, 52, 06, D3, F7, D3, F7, D3, F7,
+#                                     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
+#PN551              0x05
+#PN67T              0x06
+NXP_NFC_CHIP=0x06
+
+###############################################################################
+# CE when Screen state is locked
+# This setting is for DEFAULT_AID_ROUTE,
+# DEFAULT_DESFIRE_ROUTE and DEFAULT_MIFARE_CLT_ROUTE
+# 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=20
+
+###############################################################################
+#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
+
+###############################################################################
+#Set the default AID Power state :
+#This settings will be used when application does not set this parameter
+# bit pos 0 = Switch On
+# bit pos 1 = Switch Off
+# bit pos 2 = Battery Off
+# bit pos 3 = Screen Lock
+# bit pos 4 = Screen Off
+DEFAULT_AID_PWR_STATE=0x19
+
+###############################################################################
+#Set the Mifare Desfire Power state :
+#This settings will be used when application does not set this parameter
+# bit pos 0 = Switch On
+# bit pos 1 = Switch Off
+# bit pos 2 = Battery Off
+# bit pos 3 = Screen Lock
+# bit pos 4 = Screen Off
+DEFAULT_DESFIRE_PWR_STATE=0x1B
+
+###############################################################################
+#Set the Mifare CLT Power state :
+#This settings will be used when application does not set this parameter
+# bit pos 0 = Switch On
+# bit pos 1 = Switch Off
+# bit pos 2 = Battery Off
+# bit pos 3 = Screen Lock
+# bit pos 4 = Screen Off
+DEFAULT_MIFARE_CLT_PWR_STATE=0x1B
+
+###############################################################################
+# 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=0x22
+
+###############################################################################
+#Timeout value  in milliseconds for NFCC standby mode.The range is between 5000
+#msec to 20000 msec and zero is to disable.
+NXP_NFCC_STANDBY_TIMEOUT=20000
+
+###############################################################################
+#Dynamic RSSI feature enable
+# Disable           0x00
+# Enable            0x01
+NXP_AGC_DEBUG_ENABLE=0x00
+
+###############################################################################
+#Virtual Mode ESE and Wired Mode ongoing delay Wired Mode
+# For Technology routing to ESE Technology Mask = 4
+# For ISO-DEP Protocol routing to ESE Mask      = 2
+# It can also take TECH|PROTO    = 6
+# To ignore the delay set mask to = 0
+NXP_ESE_WIRED_PRT_MASK=0x00
+
+###############################################################################
+#Virtual Mode UICC and Wired Mode  ongoing delay Wired Mode
+#For Technology routing to UICC Technology Mask = 4
+#For ISO-DEP Protocol routing to UICC set Mask  = 2
+#For Select AID Routing to UICC       set Mask  = 1
+#It can also take values TECH|PROTO|SELECT_AID  = 7 , 6 , 5 ,3 .To ignore delay
+#set mask = 0
+NXP_UICC_WIRED_PRT_MASK=0x00
+
+###############################################################################
+#RF field true delay Wired Mode
+# delay wired mode = 1
+# allow wired mode = 0
+NXP_WIRED_MODE_RF_FIELD_ENABLE=0x00
+
+###############################################################################
+#Config to allow adding aids
+#NFC on/off is required after this config
+#1 = enabling adding aid  to NFCC routing table.
+#0 = disabling adding aid to NFCC routing table.
+NXP_ENABLE_ADD_AID=0x01
+
+###############################################################################
+# UICC mode supported
+# Disable           0x00
+# Enable            0x01
+NXP_DUAL_UICC_ENABLE=0x00
+
+###############################################################################
+# JCOP-3.3 continuous process timeout in msec and value should be in Hexadecimal
+# JCOP CP TIMEOUT
+# NXP_CP_TIMEOUT={00, 77}
+
+###############################################################################
+# Enable/Disable checking default proto SE Id
+# Disable           0x00
+# Enable            0x01
+NXP_CHECK_DEFAULT_PROTO_SE_ID=0x01
+
+###############################################################################
+# SVDD sync off Delay in ms it can be max 20 ms
+# If out of range timeout used, default delay of 10ms will be set
+NXP_SVDD_SYNC_OFF_DELAY=10
+
+###############################################################################
+#NXP_CN_TRANSIT_BLK_NUM_CHECK_ENABLE
+#Enable/Disable block number checks for china transit use case
+#Enable  0x01
+#Disable  0x00
+NXP_CN_TRANSIT_BLK_NUM_CHECK_ENABLE=0x01
+
+###############################################################################
+#Enable Passive Listen Timeout
+# Maximum retry three times, Timeout in millisec
+NXP_NFCC_PASSIVE_LISTEN_TIMEOUT=5000
+
+###############################################################################
+# Restrict routing to first matched rule only.
+# Blacklist enable   0x01
+# Blacklist disable  0x00
+NXP_PROP_BLACKLIST_ROUTING=0x00
+
+###############################################################################
diff --git a/halimpl/pn54x/libnfc-nxp-PN80T_example.conf b/halimpl/pn54x/libnfc-nxp-PN80T_example.conf
new file mode 100644
index 0000000..31d6ddc
--- /dev/null
+++ b/halimpl/pn54x/libnfc-nxp-PN80T_example.conf
@@ -0,0 +1,555 @@
+## This file is used by NFC NXP NCI HAL(external/libnfc-nci/halimpl/pn547)
+## and NFC Service Java Native Interface Extensions (packages/apps/Nfc/nci/jni/extns/pn547)
+###############################################################################
+# 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
+
+###############################################################################
+# Nfc Device Node name
+NXP_NFC_DEV_NODE="/dev/nq-nci"
+
+###############################################################################
+# Extension for Mifare reader enable
+MIFARE_READER_ENABLE=0x01
+
+###############################################################################
+# Vzw Feature enable
+VZW_FEATURE_ENABLE=0x01
+
+###############################################################################
+# File name for Firmware
+NXP_FW_NAME="libpn553_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_32MHZ         5
+#define CLK_FREQ_38_4MHZ       6
+#define CLK_FREQ_52MHZ         7
+NXP_SYS_CLK_FREQ_SEL=0x02
+
+###############################################################################
+# The timeout value to be used for clock request acknowledgment
+# min value = 0x01 to max = 0x06
+NXP_SYS_CLOCK_TO_CFG=0x06
+
+###############################################################################
+# 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, two configurations (1 and 2) supported,
+# out of them only one can be configured at a time.
+NXP_EXT_TVDD_CFG=0x02
+
+###############################################################################
+#config1:SLALM, 3.3V for both RM and CM
+NXP_EXT_TVDD_CFG_1={20, 02, 0F, 01, A0, 0E, 0B, 31, 01, 01, 31, 00, 00, 00, 01, 00, D0, 0C}
+
+###############################################################################
+#config2: use DCDC in CE, use Tx_Pwr_Req, set CFG2 mode, SLALM,
+#monitoring 5V from DCDC, 3.3V for both RM and CM, DCDCWaitTime=4.2ms
+NXP_EXT_TVDD_CFG_2={20, 02, 0F, 01, A0, 0E, 0B, 11, 01, C2, B2, 00, B2, 1E, 1F, 00, D0, 0C}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+# DPC deactivated
+NXP_RF_CONF_BLK_1={
+20, 02, 5C, 01, A0, 0B, 58, 10, 90, 90, 78, 0F, 4E, 32, 00, 3D, 9F, 00, 00, 3D,
+9F, 00, 00, 50, 9F, 00, 00, 59, 9F, 00, 00, 5A, 9F, 00, 00, 64, 9F, 00, 00, 65,
+9F, 00, 00, 6E, 9F, 00, 00, 72, 9F, 00, 00, 79, 9F, 00, 00, 7B, 9F, 00, 00, 84,
+9F, 00, 00, 86, 9F, 00, 00, 8F, 9F, 00, 00, 91, 9F, 00, 00, 9A, 9F, 00, 00, A1,
+9F, 00, 00, A7, 1F, 00, 00, B0, 1F, 00, 00, B9, 1F, 00, 00
+}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+# DLMA Deactivated
+NXP_RF_CONF_BLK_2={
+20, 02, D6, 01, A0, 34, D2, 23, 04, 18, 07, 40, 00, 20, 40, 00, BE, 23, 60, 00,
+2B, 13, 40, 00, B8, 21, 60, 00, 38, 35, 00, 00, 18, 46, 08, 00, DE, 54, 08, 02,
+00, 00, 08, 02, 00, 00, 08, 02, 00, 00, 08, 02, 00, 00, 08, 02, 00, 00, 08, 02,
+00, 00, 08, 02, 00, 00, 48, 01, 00, 00, 08, 03, 00, 00, 08, 01, 00, 00, C8, 02,
+00, 00, C8, 00, 00, 00, 88, 02, 00, 00, 48, 02, 00, 00, B8, 00, 00, 00, 68, 00,
+00, 00, 18, 00, 00, 00, 08, 02, 00, 00, 00, 00, 00, 00, 00, 00, 07, 00, 20, 40,
+00, BE, 23, 60, 00, 2B, 13, 40, 00, B8, 21, 60, 00, 38, 35, 00, 00, 18, 46, 08,
+00, DE, 54, 08, 02, 00, 00, 08, 02, 00, 00, 08, 02, 00, 00, 08, 02, 00, 00, 08,
+02, 00, 00, 08, 02, 00, 00, 08, 02, 00, 00, 48, 01, 00, 00, 08, 03, 00, 00, 08,
+01, 00, 00, C8, 02, 00, 00, C8, 00, 00, 00, 88, 02, 00, 00, 48, 02, 00, 00, B8,
+00, 00, 00, 68, 00, 00, 00, 18, 00, 00, 00, 08, 02, 00, 00, 00, 00
+}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_3={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_4={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_5={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_6={
+#}
+
+###############################################################################
+# Set configuration optimization decision setting
+# Enable    = 0x01
+# Disable   = 0x00
+NXP_SET_CONFIG_ALWAYS=0x00
+
+###############################################################################
+# Core configuration extensions
+# It includes
+# Wired mode settings A0ED, A0EE
+# Tag Detector A040, A041, A043
+# Low Power mode A007
+# Clock settings A002, A003
+# PbF settings A008
+# Clock timeout settings A004
+# eSE (SVDD) PWR REQ settings A0F2
+# Window size A0D8
+# DWP Speed   A0D5
+# How eSE connected to PN553 A012
+# UICC2 bit rate A0D1
+# SWP1A interface A0D4
+# DWP intf behavior config, SVDD Load activated by default if set to 0x31 A037
+NXP_CORE_CONF_EXTN={20, 02, 29, 0A,
+    A0, EC, 01, 01,
+    A0, ED, 01, 01,
+    A0, 5E, 01, 01,
+    A0, 12, 01, 02,
+    A0, 40, 01, 01,
+    A0, D1, 01, 02,
+    A0, D4, 01, 01,
+    A0, 37, 01, 35,
+    A0, D8, 01, 02,
+    A0, D5, 01, 0A
+   }
+#       A0, F2, 01, 01,
+#       A0, 40, 01, 01,
+#       A0, 41, 01, 02,
+#       A0, 43, 01, 04,
+#       A0, 02, 01, 01,
+#       A0, 03, 01, 11,
+#       A0, 07, 01, 03,
+#       A0, 08, 01, 01
+#       }
+
+###############################################################################
+# Core configuration rf field filter settings to enable set to 01 to disable set
+# to 00 last bit
+NXP_CORE_RF_FIELD={ 20, 02, 05, 01, A0, 62, 01, 00 }
+
+###############################################################################
+# 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, 2E, 0E,
+        28, 01, 00,
+        21, 01, 00,
+        30, 01, 08,
+        31, 01, 03,
+        32, 01, 60,
+        38, 01, 01,
+        33, 04, 01, 02, 03, 04,
+        54, 01, 06,
+        50, 01, 02,
+        5B, 01, 00,
+        80, 01, 01,
+        81, 01, 01,
+        82, 01, 0E,
+        18, 01, 01
+        }
+
+###############################################################################
+# Mifare Classic Key settings
+#NXP_CORE_MFCKEY_SETTING={20, 02, 25,04, A0, 51, 06, A0, A1, A2, A3, A4, A5,
+#                                     A0, 52, 06, D3, F7, D3, F7, D3, F7,
+#                                     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
+# UICC2             0x04
+NXP_DEFAULT_SE=0x07
+
+###############################################################################
+# Force ESE 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
+NXP_ESE_LISTEN_TECH_MASK=0x07
+
+###############################################################################
+#set autonomous mode
+# disable autonomous 0x00
+# enable autonomous  0x01
+NXP_CORE_SCRN_OFF_AUTONOMOUS_ENABLE=0x00
+
+###############################################################################
+#Enable SWP full power mode when phone is power off
+NXP_SWP_FULL_PWR_ON=0x00
+
+###############################################################################
+#### Select the CHIP ####
+#PN547C2            0x01
+#PN65T              0x02
+#PN548AD            0x03
+#PN66T              0x04
+#PN551              0x05
+#PN67T              0x06
+#PN553              0x07
+#PN80T              0x08
+NXP_NFC_CHIP=0x08
+
+###############################################################################
+# CE when Screen state is locked
+# This setting is for DEFAULT_AID_ROUTE,
+# DEFAULT_DESFIRE_ROUTE and DEFAULT_MIFARE_CLT_ROUTE
+# 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=20
+
+###############################################################################
+#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
+# UICC2 0x03
+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
+# UICC2 0x03
+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
+# UICC2 0x03
+DEFAULT_MIFARE_CLT_ROUTE=0x02
+
+###############################################################################
+#Set the Felica CLT route Location :
+#This settings will be used when application does not set this parameter
+# eSE   0x01
+# UICC  0x02
+# UICC2 0x03
+DEFAULT_FELICA_CLT_ROUTE=0x01
+
+###############################################################################
+#Set the default AID Power state :
+#This settings will be used when application does not set this parameter
+# bit pos 0 = Switch On
+# bit pos 1 = Switch Off
+# bit pos 2 = Battery Off
+# bit pos 3 = Screen Lock
+# bit pos 4 = Screen Off
+DEFAULT_AID_PWR_STATE=0x19
+
+###############################################################################
+#Set the Mifare Desfire Power state :
+#This settings will be used when application does not set this parameter
+# bit pos 0 = Switch On
+# bit pos 1 = Switch Off
+# bit pos 2 = Battery Off
+# bit pos 3 = Screen Lock
+# bit pos 4 = Screen Off
+DEFAULT_DESFIRE_PWR_STATE=0x1B
+
+###############################################################################
+#Set the Mifare CLT Power state :
+#This settings will be used when application does not set this parameter
+# bit pos 0 = Switch On
+# bit pos 1 = Switch Off
+# bit pos 2 = Battery Off
+# bit pos 3 = Screen Lock
+# bit pos 4 = Screen Off
+DEFAULT_MIFARE_CLT_PWR_STATE=0x1B
+
+###############################################################################
+#Set the Felica CLT Power state :
+#This settings will be used when application does not set this parameter
+# bit pos 0 = Switch On
+# bit pos 1 = Switch Off
+# bit pos 2 = Battery Off
+# bit pos 3 = Screen Lock
+# bit pos 4 = Screen Off
+DEFAULT_FELICA_CLT_PWR_STATE=0x1B
+
+###############################################################################
+# 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=0x22
+
+###############################################################################
+#Timeout value  in milliseconds for NFCC standby mode.The range is between 5000
+#msec to 20000 msec and zero is to disable.
+NXP_NFCC_STANDBY_TIMEOUT=20000
+
+###############################################################################
+#Dynamic RSSI feature enable
+# Disable           0x00
+# Enable            0x01
+NXP_AGC_DEBUG_ENABLE=0x00
+
+###############################################################################
+#Virtual Mode ESE and Wired Mode ongoing delay Wired Mode
+# For Technology routing to ESE Technology Mask = 4
+# For ISO-DEP Protocol routing to ESE Mask      = 2
+# It can also take TECH|PROTO    = 6
+# To ignore the delay set mask to = 0
+NXP_ESE_WIRED_PRT_MASK=0x00
+
+###############################################################################
+#Virtual Mode UICC and Wired Mode  ongoing delay Wired Mode
+#For Technology routing to UICC Technology Mask = 4
+#For ISO-DEP Protocol routing to UICC set Mask  = 2
+#For Select AID Routing to UICC       set Mask  = 1
+#It can also take values TECH|PROTO|SELECT_AID  = 7 , 6 , 5 ,3 .To ignore delay
+#set mask = 0
+NXP_UICC_WIRED_PRT_MASK=0x00
+
+################################################################################
+#RF field true delay Wired Mode
+# delay wired mode = 1
+# allow wired mode = 0
+NXP_WIRED_MODE_RF_FIELD_ENABLE=0x00
+
+###############################################################################
+#Config to allow adding aids
+#NFC on/off is required after this config
+#1 = enabling adding aid  to NFCC routing table.
+#0 = disabling adding aid to NFCC routing table.
+NXP_ENABLE_ADD_AID=0x01
+
+###############################################################################
+# JCOP-3.3 continuous process timeout in msec and value should be in Hexadecimal
+# JCOP CP TIMEOUT
+NXP_CP_TIMEOUT={00, 77}
+
+###############################################################################
+# Enable/Disable checking default proto SE Id
+# Disable           0x00
+# Enable            0x01
+NXP_CHECK_DEFAULT_PROTO_SE_ID=0x01
+
+###############################################################################
+# SVDD sync off Delay in ms it can be max 20 ms
+# If out of range timeout used, default delay of 10ms will be set
+NXP_SVDD_SYNC_OFF_DELAY=10
+
+###############################################################################
+#NXP_CN_TRANSIT_BLK_NUM_CHECK_ENABLE
+#Enable/Disable block number checks for china transit use case
+#Enable  0x01
+#Disable  0x00
+NXP_CN_TRANSIT_BLK_NUM_CHECK_ENABLE=0x01
+
+###############################################################################
+#NXP_CN_TRANSIT_CMA_BYPASSMODE_ENABLE
+#Enable this config it prevents EMVCo PICC compliancy and Mifare backward compatibility works
+#Disable this config EMVCo PICC compliancy works and Mifare backward compatibility will not work
+#Default config is Disable
+#Enable  0x01
+#Disable  0x00
+NXP_CN_TRANSIT_CMA_BYPASSMODE_ENABLE=0x00
+
+###############################################################################
+#Enable NXP NCI runtime parser library
+#Enable 0x01
+#Disable 0x00
+NXP_NCI_PARSER_LIBRARY=0x00
+
+###############################################################################
+#This config will enable different level of Rf transaction debugs based on the
+#following values provided. Decoded information will be printed in adb logcat
+#Debug Mode         Levels
+#Disable Debug      0x00
+#L1 Debug           0x01
+#L2 Debug           0x02
+#L1 & L2 Debug      0x03
+#L1 & L2 & RSSI     0x04
+#L1 & L2 & Felica   0x05
+#NXP_CORE_PROP_SYSTEM_DEBUG=0x00
+
+###############################################################################
+# Wired mode resume timeout vaule in wired mode resume feature enable
+# DWP resume time out in ms( 4 bytes hex value and LSB first)
+#example 1000 = 0x03E8
+#exmaple 2000 = 0x07D0
+#example 500 = 0x01F4
+NXP_WIREDMODE_RESUME_TIMEOUT={E8,03,00,00}
+
+###############################################################################
+# Power to eSE is controlled by DH or PMU depending on following configurations
+#define DH_PWR_CONTROL         1
+#define PMU_PWR_CONTROL        2
+NXP_ESE_POWER_DH_CONTROL=1
+
+###############################################################################
+# Timeout value in milliseconds for wired mode resume after RF field event timeout
+NXP_NFCC_RF_FIELD_EVENT_TIMEOUT=3000
+
+###############################################################################
+# NXP PMU Support configuration is sent if PMU_PWR_CONTROL is configured
+# External PMU available in phone ON and phone OFF case if NXP_ESE_POWER_EXT_PMU=1
+# External PMU available only in phone ON case if NXP_ESE_POWER_EXT_PMU=2
+NXP_ESE_POWER_EXT_PMU=2
+
+###############################################################################
+# Whether to allow wired mode in desfire and mifare CLT
+# Disable           0x00
+# Enable            0x01
+NXP_ALLOW_WIRED_IN_MIFARE_DESFIRE_CLT=0x00
+
+###############################################################################
+# Restrict routing to first matched rule only.
+# Blacklist enable   0x01
+# Blacklist disable  0x00
+NXP_PROP_BLACKLIST_ROUTING=0x00
+
+###############################################################################
+# Send DWP interface reset command as part of SE open
+# Disable           0x00
+# Enable            0x01
+NXP_DWP_INTF_RESET_ENABLE=0x01
+
+###############################################################################
+# Timeout value in milliseconds for JCOP OS download to complete
+OS_DOWNLOAD_TIMEOUT_VALUE=60000
+
+###############################################################################
+# Timeout value in milliseconds to send response for Felica command received
+NXP_HCEF_CMD_RSP_TIMEOUT_VALUE=5000
+
+###############################################################################
+# Maximum WTX requests entertained by MW
+NXP_WM_MAX_WTX_COUNT=9000
+
+###############################################################################
\ No newline at end of file
diff --git a/halimpl/pn54x/libnfc-nxp-PN81T_example.conf b/halimpl/pn54x/libnfc-nxp-PN81T_example.conf
new file mode 100644
index 0000000..66948fd
--- /dev/null
+++ b/halimpl/pn54x/libnfc-nxp-PN81T_example.conf
@@ -0,0 +1,403 @@
+## This file is used by NFC NXP NCI HAL(external/libnfc-nci/halimpl/pn547)
+## and NFC Service Java Native Interface Extensions (packages/apps/Nfc/nci/jni/extns/pn547)
+###############################################################################
+# 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
+
+###############################################################################
+# Nfc Device Node name
+NXP_NFC_DEV_NODE="/dev/nq-nci"
+
+###############################################################################
+# Extension for Mifare reader enable
+MIFARE_READER_ENABLE=0x01
+
+###############################################################################
+# Vzw Feature enable
+VZW_FEATURE_ENABLE=0x01
+
+###############################################################################
+# File name for Firmware
+NXP_FW_NAME="libpn557_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 = 0x06
+NXP_SYS_CLOCK_TO_CFG=0x06
+
+###############################################################################
+# 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}
+
+###############################################################################
+# NXP TVDD configurations settings
+# Allow NFCC to configure External TVDD, two configurations (1 and 2) supported,
+# out of them only one can be configured at a time.
+NXP_EXT_TVDD_CFG=0x02
+
+###############################################################################
+#config1:SLALM, 3.3V for both RM and CM
+NXP_EXT_TVDD_CFG_1={20, 02, 0F, 01, A0, 0E, 0B, 31, 01, 01, 31, 00, 00, 00, 01, 00, D0, 0C}
+
+###############################################################################
+#config2: use DCDC in CE, use Tx_Pwr_Req, set CFG2 mode, SLALM,
+#monitoring 5V from DCDC, 3.3V for both RM and CM, DCDCWaitTime=4.2ms
+NXP_EXT_TVDD_CFG_2={20, 02, 0F, 01, A0, 0E, 0B, 11, 01, C2, B2, 00, B2, 1E, 1F, 00, D0, 0C}
+
+
+###############################################################################
+# Set configuration optimization decision setting
+# Enable    = 0x01
+# Disable   = 0x00
+NXP_SET_CONFIG_ALWAYS=0x01
+
+###############################################################################
+# Core configuration rf field filter settings to enable set to 01 to disable set
+# to 00 last bit
+NXP_CORE_RF_FIELD={ 20, 02, 05, 01, A0, 62, 01, 00 }
+
+###############################################################################
+# To enable i2c fragmentation set i2c fragmentation enable 0x01 to disable set
+# to 0x00
+NXP_I2C_FRAGMENTATION_ENABLED=0x00
+
+###############################################################################
+# 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
+# UICC2             0x04
+NXP_DEFAULT_SE=0x07
+
+###############################################################################
+#set autonomous mode
+# disable autonomous 0x00
+# enable autonomous  0x01
+NXP_CORE_SCRN_OFF_AUTONOMOUS_ENABLE=0x00
+
+###############################################################################
+#Enable SWP full power mode when phone is power off
+NXP_SWP_FULL_PWR_ON=0x00
+
+###############################################################################
+#### Select the CHIP ####
+#PN547C2            0x01
+#PN65T              0x02
+#PN548AD            0x03
+#PN66T              0x04
+#PN551              0x05
+#PN67T              0x06
+#PN553              0x07
+#PN80T              0x08
+NXP_NFC_CHIP=0x08
+
+###############################################################################
+# CE when Screen state is locked
+# This setting is for DEFAULT_AID_ROUTE,
+# DEFAULT_DESFIRE_ROUTE and DEFAULT_MIFARE_CLT_ROUTE
+# 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=20
+
+###############################################################################
+#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
+# UICC2 0x03
+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
+# UICC2 0x03
+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
+# UICC2 0x03
+DEFAULT_MIFARE_CLT_ROUTE=0x02
+
+###############################################################################
+#Set the Felica CLT route Location :
+#This settings will be used when application does not set this parameter
+# eSE   0x01
+# UICC  0x02
+# UICC2 0x03
+DEFAULT_FELICA_CLT_ROUTE=0x01
+
+###############################################################################
+#Set the default AID Power state :
+#This settings will be used when application does not set this parameter
+# bit pos 0 = Switch On
+# bit pos 1 = Switch Off
+# bit pos 2 = Battery Off
+# bit pos 3 = Screen On lock
+# bit pos 4 = Screen off unlock
+# bit pos 5 = Screen Off lock
+DEFAULT_AID_PWR_STATE=0x39
+###############################################################################
+#Set the Mifare Desfire Power state :
+#This settings will be used when application does not set this parameter
+# bit pos 0 = Switch On
+# bit pos 1 = Switch Off
+# bit pos 2 = Battery Off
+# bit pos 3 = Screen On lock
+# bit pos 4 = Screen off unlock
+# bit pos 5 = Screen Off lock
+DEFAULT_DESFIRE_PWR_STATE=0x3B
+
+###############################################################################
+#Set the Mifare CLT Power state :
+#This settings will be used when application does not set this parameter
+# bit pos 0 = Switch On
+# bit pos 1 = Switch Off
+# bit pos 2 = Battery Off
+# bit pos 3 = Screen On lock
+# bit pos 4 = Screen off unlock
+# bit pos 5 = Screen Off lock
+DEFAULT_MIFARE_CLT_PWR_STATE=0x3B
+
+###############################################################################
+#Set the Felica CLT Power state :
+#This settings will be used when application does not set this parameter
+# bit pos 0 = Switch On
+# bit pos 1 = Switch Off
+# bit pos 2 = Battery Off
+# bit pos 3 = Screen On lock
+# bit pos 4 = Screen off unlock
+# bit pos 5 = Screen Off lock
+DEFAULT_FELICA_CLT_PWR_STATE=0x3B
+
+###############################################################################
+# 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=0x22
+
+###############################################################################
+#Timeout value  in milliseconds for NFCC standby mode.The range is between 5000
+#msec to 20000 msec and zero is to disable.
+NXP_NFCC_STANDBY_TIMEOUT=20000
+
+###############################################################################
+#Dynamic RSSI feature enable
+# Disable           0x00
+# Enable            0x01
+NXP_AGC_DEBUG_ENABLE=0x00
+
+###############################################################################
+#Virtual Mode ESE and Wired Mode ongoing delay Wired Mode
+# For Technology routing to ESE Technology Mask = 4
+# For ISO-DEP Protocol routing to ESE Mask      = 2
+# It can also take TECH|PROTO    = 6
+# To ignore the delay set mask to = 0
+NXP_ESE_WIRED_PRT_MASK=0x00
+
+###############################################################################
+#Virtual Mode UICC and Wired Mode  ongoing delay Wired Mode
+#For Technology routing to UICC Technology Mask = 4
+#For ISO-DEP Protocol routing to UICC set Mask  = 2
+#For Select AID Routing to UICC       set Mask  = 1
+#It can also take values TECH|PROTO|SELECT_AID  = 7 , 6 , 5 ,3 .To ignore delay
+#set mask = 0
+NXP_UICC_WIRED_PRT_MASK=0x00
+
+################################################################################
+#RF field true delay Wired Mode
+# delay wired mode = 1
+# allow wired mode = 0
+NXP_WIRED_MODE_RF_FIELD_ENABLE=0x00
+
+###############################################################################
+#Config to allow adding aids
+#NFC on/off is required after this config
+#1 = enabling adding aid  to NFCC routing table.
+#0 = disabling adding aid to NFCC routing table.
+NXP_ENABLE_ADD_AID=0x01
+
+###############################################################################
+# JCOP-3.3 continuous process timeout in msec and value should be in Hexadecimal
+# JCOP CP TIMEOUT
+NXP_CP_TIMEOUT={00, 77}
+
+###############################################################################
+# Enable/Disable checking default proto SE Id
+# Disable           0x00
+# Enable            0x01
+NXP_CHECK_DEFAULT_PROTO_SE_ID=0x01
+
+###############################################################################
+# SVDD sync off Delay in ms it can be max 20 ms
+# If out of range timeout used, default delay of 10ms will be set
+NXP_SVDD_SYNC_OFF_DELAY=10
+
+###############################################################################
+#NXP_CN_TRANSIT_BLK_NUM_CHECK_ENABLE
+#Enable/Disable block number checks for china transit use case
+#Enable  0x01
+#Disable  0x00
+NXP_CN_TRANSIT_BLK_NUM_CHECK_ENABLE=0x01
+
+###############################################################################
+# Wired mode resume timeout vaule in wired mode resume feature enable
+# DWP resume time out in ms( 4 bytes hex value and LSB first)
+#example 1000 = 0x03E8
+#exmaple 2000 = 0x07D0
+#example 500 = 0x01F4
+NXP_WIREDMODE_RESUME_TIMEOUT={E8,03,00,00}
+###############################################################################
+# Power to eSE is controlled by DH or PMU depending on following configurations
+#define DH_PWR_CONTROL         1
+#define PMU_PWR_CONTROL        2
+NXP_ESE_POWER_DH_CONTROL=1
+
+###############################################################################
+# Timeout value in milliseconds for wired mode resume after RF field event timeout
+NXP_NFCC_RF_FIELD_EVENT_TIMEOUT=3000
+
+###############################################################################
+# NXP PMU Support configuration is sent if PMU_PWR_CONTROL is configured
+# External PMU available in phone ON and phone OFF case if NXP_ESE_POWER_EXT_PMU=1
+# External PMU available only in phone ON case if NXP_ESE_POWER_EXT_PMU=2
+NXP_ESE_POWER_EXT_PMU=2
+
+###############################################################################
+# Whether to allow wired mode in desfire and mifare CLT
+# Disable           0x00
+# Enable            0x01
+NXP_ALLOW_WIRED_IN_MIFARE_DESFIRE_CLT=0x00
+
+###############################################################################
+# Restrict routing to first matched rule only.
+# Blacklist enable   0x01
+# Blacklist disable  0x00
+NXP_PROP_BLACKLIST_ROUTING=0x00
+
+###############################################################################
+# Send DWP interface reset command as part of SE open
+# Disable           0x00
+# Enable            0x01
+NXP_DWP_INTF_RESET_ENABLE=0x01
+
+###############################################################################
+# Timeout value in milliseconds for JCOP OS download to complete
+OS_DOWNLOAD_TIMEOUT_VALUE=60000
+
+###############################################################################
+# Timeout value in milliseconds to send response for Felica command received
+NXP_HCEF_CMD_RSP_TIMEOUT_VALUE=5000
+
+###############################################################################
diff --git a/halimpl/pn54x/libnfc-nxp_RF-PN547C2_example b/halimpl/pn54x/libnfc-nxp_RF-PN547C2_example
new file mode 100644
index 0000000..df28264
--- /dev/null
+++ b/halimpl/pn54x/libnfc-nxp_RF-PN547C2_example
@@ -0,0 +1,78 @@
+###############################################################################
+# 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, 00,
+    A0, 5E, 01, 01,
+    A0, 0D, 06, 3E, 2D, 15, 88, 15, 00
+    }
+#       A0, 40, 01, 01,
+#       A0, 41, 01, 02,
+#       A0, 43, 01, 04,
+#       A0, 02, 01, 01,
+#       A0, 03, 01, 11,
+#       A0, 07, 01, 03,
+#       A0, 08, 01, 01
+#       }
+
+###############################################################################
+# Core configuration 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 
+        }
+###############################################################################
+
diff --git a/halimpl/pn54x/libnfc-nxp_RF-PN548C2_example b/halimpl/pn54x/libnfc-nxp_RF-PN548C2_example
new file mode 100644
index 0000000..c65a94c
--- /dev/null
+++ b/halimpl/pn54x/libnfc-nxp_RF-PN548C2_example
@@ -0,0 +1,80 @@
+###############################################################################
+# 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 settings
+NXP_CORE_CONF={ 20, 02, 2E, 0E,
+        28, 01, 00,
+        21, 01, 00,
+        30, 01, 08,
+        31, 01, 03,
+        32, 01, 60,
+        38, 01, 01,
+        33, 04, 01, 02, 03, 04,
+        54, 01, 06,
+        50, 01, 02,
+        5B, 01, 00,
+        80, 01, 01,
+        81, 01, 01,
+        82, 01, 0E,
+        18, 01, 01
+        }
+
+###############################################################################
+# Core configuration extensions
+# It includes
+# Wired mode settings A0ED, A0EE
+# Tag Detector A040, A041, A043
+# Low Power mode A007
+# Clock settings A002, A003
+# PbF settings A008
+NXP_CORE_CONF_EXTN={20, 02, 19, 06,
+    A0, EC, 01, 01,
+    A0, ED, 01, 00,
+    A0, 5E, 01, 01,
+    A0, 40, 01, 01,
+    A0, DD, 01, 2D,
+    A0, 96, 01, 01
+    }
+#       A0, 41, 01, 02,
+#       A0, 43, 01, 04,
+#       A0, 02, 01, 01,
+#       A0, 03, 01, 11,
+#       A0, 07, 01, 03,
+#       A0, 08, 01, 01
+#       }
+###############################################################################
+
diff --git a/halimpl/pn54x/libnfc-nxp_RF-PN551_example b/halimpl/pn54x/libnfc-nxp_RF-PN551_example
new file mode 100644
index 0000000..e42920f
--- /dev/null
+++ b/halimpl/pn54x/libnfc-nxp_RF-PN551_example
@@ -0,0 +1,80 @@
+###############################################################################
+# 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, 19, 06,
+    A0, EC, 01, 01,
+    A0, ED, 01, 00,
+    A0, 5E, 01, 01,
+    A0, 40, 01, 01,
+    A0, DD, 01, 2D,
+    A0, 96, 01, 01
+    }
+#       A0, 41, 01, 02,
+#       A0, 43, 01, 04,
+#       A0, 02, 01, 01,
+#       A0, 03, 01, 11,
+#       A0, 07, 01, 03,
+#       A0, 08, 01, 01
+#       }
+
+###############################################################################
+# Core configuration settings
+NXP_CORE_CONF={ 20, 02, 2E, 0E,
+        28, 01, 00,
+        21, 01, 00,
+        30, 01, 08,
+        31, 01, 03,
+        32, 01, 60,
+        38, 01, 01,
+        33, 04, 01, 02, 03, 04,
+        54, 01, 06,
+        50, 01, 02,
+        5B, 01, 00,
+        80, 01, 01,
+        81, 01, 01,
+        82, 01, 0E,
+        18, 01, 01
+        }
+###############################################################################
+
diff --git a/halimpl/pn54x/libnfc-nxp_RF-PN553_example b/halimpl/pn54x/libnfc-nxp_RF-PN553_example
new file mode 100644
index 0000000..724f217
--- /dev/null
+++ b/halimpl/pn54x/libnfc-nxp_RF-PN553_example
@@ -0,0 +1,91 @@
+###############################################################################
+# 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
+# eSE (SVDD) PWR REQ settings A0F2
+# How eSE connected to PN553 A012
+# UICC2 bit rate A0D1
+# SWP1A interface A0D4
+# DWP intf behavior config, SVDD Load activated by default if set to 0x31 - A037
+NXP_CORE_CONF_EXTN={20, 02, 25, 09,
+    A0, EC, 01, 01,
+    A0, ED, 01, 00,
+    A0, 5E, 01, 01,
+    A0, 12, 01, 02,
+    A0, 40, 01, 01,
+    A0, DD, 01, 2D,
+    A0, D1, 01, 02,
+    A0, D4, 01, 01,
+    A0, 37, 01, 35
+   }
+#       A0, F2, 01, 01,
+#       A0, 40, 01, 01,
+#       A0, 41, 01, 02,
+#       A0, 43, 01, 04,
+#       A0, 02, 01, 01,
+#       A0, 03, 01, 11,
+#       A0, 07, 01, 03,
+#       A0, 08, 01, 01
+#       }
+
+###############################################################################
+# Core configuration settings
+NXP_CORE_CONF={ 20, 02, 2E, 0E,
+        28, 01, 00,
+        21, 01, 00,
+        30, 01, 08,
+        31, 01, 03,
+        32, 01, 60,
+        38, 01, 01,
+        33, 04, 01, 02, 03, 04,
+        54, 01, 06,
+        50, 01, 02,
+        5B, 01, 00,
+        80, 01, 01,
+        81, 01, 01,
+        82, 01, 0E,
+        18, 01, 01
+        }
+###############################################################################
+
diff --git a/halimpl/pn54x/libnfc-nxp_RF-PN66T_example.conf b/halimpl/pn54x/libnfc-nxp_RF-PN66T_example.conf
new file mode 100644
index 0000000..4697eed
--- /dev/null
+++ b/halimpl/pn54x/libnfc-nxp_RF-PN66T_example.conf
@@ -0,0 +1,86 @@
+###############################################################################
+# 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
+# A0 9F 02 <svdd ON guard time (msec)> <svdd off guard time(msec)>
+NXP_CORE_CONF_EXTN={20, 02, 26, 09,
+    A0, EC, 01, 01,
+    A0, ED, 01, 03,
+    A0, 5E, 01, 01,
+    A0, 12, 01, 02,
+    A0, 40, 01, 01,
+    A0, DD, 01, 2D,
+    A0, F2, 01, 01,
+    A0, 96, 01, 01,
+    A0, 9F, 02, 08, 08
+    }
+#       A0, 41, 01, 02,
+#       A0, 43, 01, 04,
+#       A0, 02, 01, 01,
+#       A0, 03, 01, 11,
+#       A0, 07, 01, 03,
+#       A0, 08, 01, 01
+#       }
+
+###############################################################################
+# Core configuration settings
+NXP_CORE_CONF={ 20, 02, 2E, 0E,
+        28, 01, 00,
+        21, 01, 00,
+        30, 01, 08,
+        31, 01, 03,
+        32, 01, 60,
+        38, 01, 01,
+        33, 04, 01, 02, 03, 04,
+        54, 01, 06,
+        50, 01, 02,
+        5B, 01, 00,
+        80, 01, 01,
+        81, 01, 01,
+        82, 01, 0E,
+        18, 01, 01
+        }
+
+###############################################################################
+
diff --git a/halimpl/pn54x/libnfc-nxp_RF-PN67T_example.conf b/halimpl/pn54x/libnfc-nxp_RF-PN67T_example.conf
new file mode 100644
index 0000000..4697eed
--- /dev/null
+++ b/halimpl/pn54x/libnfc-nxp_RF-PN67T_example.conf
@@ -0,0 +1,86 @@
+###############################################################################
+# 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
+# A0 9F 02 <svdd ON guard time (msec)> <svdd off guard time(msec)>
+NXP_CORE_CONF_EXTN={20, 02, 26, 09,
+    A0, EC, 01, 01,
+    A0, ED, 01, 03,
+    A0, 5E, 01, 01,
+    A0, 12, 01, 02,
+    A0, 40, 01, 01,
+    A0, DD, 01, 2D,
+    A0, F2, 01, 01,
+    A0, 96, 01, 01,
+    A0, 9F, 02, 08, 08
+    }
+#       A0, 41, 01, 02,
+#       A0, 43, 01, 04,
+#       A0, 02, 01, 01,
+#       A0, 03, 01, 11,
+#       A0, 07, 01, 03,
+#       A0, 08, 01, 01
+#       }
+
+###############################################################################
+# Core configuration settings
+NXP_CORE_CONF={ 20, 02, 2E, 0E,
+        28, 01, 00,
+        21, 01, 00,
+        30, 01, 08,
+        31, 01, 03,
+        32, 01, 60,
+        38, 01, 01,
+        33, 04, 01, 02, 03, 04,
+        54, 01, 06,
+        50, 01, 02,
+        5B, 01, 00,
+        80, 01, 01,
+        81, 01, 01,
+        82, 01, 0E,
+        18, 01, 01
+        }
+
+###############################################################################
+
diff --git a/halimpl/pn54x/libnfc-nxp_RF-PN80T_example.conf b/halimpl/pn54x/libnfc-nxp_RF-PN80T_example.conf
new file mode 100644
index 0000000..3f4e061
--- /dev/null
+++ b/halimpl/pn54x/libnfc-nxp_RF-PN80T_example.conf
@@ -0,0 +1,93 @@
+###############################################################################
+# 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
+# eSE (SVDD) PWR REQ settings A0F2
+# Window size A0D8
+# DWP Speed   A0D5
+# How eSE connected to PN553 A012
+# UICC2 bit rate A0D1
+# SWP1A interface A0D4
+# DWP intf behavior config, SVDD Load activated by default if set to 0x31 A037
+NXP_CORE_CONF_EXTN={20, 02, 29, 0A,
+    A0, EC, 01, 01,
+    A0, ED, 01, 01,
+    A0, 5E, 01, 01,
+    A0, 12, 01, 02,
+    A0, 40, 01, 01,
+    A0, D1, 01, 02,
+    A0, D4, 01, 01,
+    A0, 37, 01, 35,
+    A0, D8, 01, 02,
+    A0, D5, 01, 0A
+   }
+#       A0, F2, 01, 01,
+#       A0, 40, 01, 01,
+#       A0, 41, 01, 02,
+#       A0, 43, 01, 04,
+#       A0, 02, 01, 01,
+#       A0, 03, 01, 11,
+#       A0, 07, 01, 03,
+#       A0, 08, 01, 01
+#       }
+
+###############################################################################
+# Core configuration settings
+NXP_CORE_CONF={ 20, 02, 2E, 0E,
+        28, 01, 00,
+        21, 01, 00,
+        30, 01, 08,
+        31, 01, 03,
+        32, 01, 60,
+        38, 01, 01,
+        33, 04, 01, 02, 03, 04,
+        54, 01, 06,
+        50, 01, 02,
+        5B, 01, 00,
+        80, 01, 01,
+        81, 01, 01,
+        82, 01, 0E,
+        18, 01, 01
+        }
+###############################################################################
diff --git a/halimpl/pn54x/libnfc-nxp_RF-PN81T_example.conf b/halimpl/pn54x/libnfc-nxp_RF-PN81T_example.conf
new file mode 100644
index 0000000..cb74752
--- /dev/null
+++ b/halimpl/pn54x/libnfc-nxp_RF-PN81T_example.conf
@@ -0,0 +1,95 @@
+###############################################################################
+# 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
+# eSE (SVDD) PWR REQ settings A0F2
+# Window size A0D8
+# DWP Speed   A0D5
+# How eSE connected to PN553 A012
+# UICC2 bit rate A0D1
+# SWP1A interface A0D4
+# DWP intf behavior config, SVDD Load activated by default if set to 0x31 A037
+NXP_CORE_CONF_EXTN={20, 02, 29, 0A,
+    A0, EC, 01, 01,
+    A0, ED, 01, 01,
+    A0, 5E, 01, 01,
+    A0, 12, 01, 02,
+    A0, 40, 01, 01,
+    A0, D1, 01, 02,
+    A0, D4, 01, 01,
+    A0, 37, 01, 35,
+    A0, D8, 01, 02,
+    A0, D5, 01, 0A
+   }
+#       A0, F2, 01, 01,
+#       A0, 40, 01, 01,
+#       A0, 41, 01, 02,
+#       A0, 43, 01, 04,
+#       A0, 02, 01, 01,
+#       A0, 03, 01, 11,
+#       A0, 07, 01, 03,
+#       A0, 08, 01, 01
+#       }
+
+###############################################################################
+# Core configuration settings
+NXP_CORE_CONF={ 20, 02, 34, 10,
+        28, 01, 00,
+        21, 01, 00,
+        30, 01, 08,
+        31, 01, 03,
+        32, 01, 60,
+        38, 01, 01,
+        33, 04, 01, 02, 03, 04,
+        54, 01, 06,
+        50, 01, 02,
+        5B, 01, 00,
+        80, 01, 01,
+        81, 01, 01,
+        82, 01, 0E,
+        18, 01, 01,
+        68, 01, 01,
+        85, 01, 01
+        }
+###############################################################################
diff --git a/halimpl/pn54x/log/phNxpLog.c b/halimpl/pn54x/log/phNxpLog.c
new file mode 100644
index 0000000..2b35cc8
--- /dev/null
+++ b/halimpl/pn54x/log/phNxpLog.c
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* ############################################### Header Includes
+ * ################################################ */
+#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",
+      __func__, 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);
+}
+
+/******************************************************************************
+ * Function         phNxpLog_EnableDisableLogLevel
+ *
+ * Description      This function can be called to enable/disable the log levels
+ *
+ *
+ *                  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
+ *
+ ******************************************************************************/
+NFCSTATUS phNxpLog_EnableDisableLogLevel(uint8_t enable) {
+  static nci_log_level_t prevTraceLevel = {0, 0, 0, 0, 0, 0, 0};
+  static uint8_t currState = 0x01;
+  NFCSTATUS status = NFCSTATUS_FAILED;
+  if (0x01 == enable && currState != 0x01) {
+    memcpy(&gLog_level, &prevTraceLevel, sizeof(nci_log_level_t));
+    currState = 0x01;
+    status = NFCSTATUS_SUCCESS;
+  } else if (0x00 == enable && currState != 0x00) {
+    memcpy(&prevTraceLevel, &gLog_level, sizeof(nci_log_level_t));
+    gLog_level.hal_log_level = 0;
+    gLog_level.extns_log_level = 0;
+    gLog_level.tml_log_level = 0;
+    gLog_level.ncix_log_level = 0;
+    gLog_level.ncir_log_level = 0;
+    currState = 0x00;
+    status = NFCSTATUS_SUCCESS;
+  }
+
+  return status;
+}
diff --git a/halimpl/pn54x/log/phNxpLog.h b/halimpl/pn54x/log/phNxpLog.h
new file mode 100644
index 0000000..496450f
--- /dev/null
+++ b/halimpl/pn54x/log/phNxpLog.h
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#if !defined(NXPLOG__H_INCLUDED)
+#define NXPLOG__H_INCLUDED
+
+#include <cutils/log.h>
+#include <phNxpNciHal_utils.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", (__func__))
+#define NXPLOG_FUNC_EXIT(COMP) \
+  LOG_PRI(ANDROID_LOG_VERBOSE, (COMP), "-:%s", (__func__))
+#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);
+NFCSTATUS phNxpLog_EnableDisableLogLevel(uint8_t enable);
+#endif /* NXPLOG__H_INCLUDED */
diff --git a/halimpl/pn54x/nfc_nci.c b/halimpl/pn54x/nfc_nci.c
new file mode 100644
index 0000000..3bda6f8
--- /dev/null
+++ b/halimpl/pn54x/nfc_nci.c
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <errno.h>
+#include <hardware/hardware.h>
+#include <hardware/nfc.h>
+#include <log/log.h>
+#include <phNxpNciHal_Adaptation.h>
+#include <string.h>
+#include <stdlib.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_ioctl
+**
+** Description      Invoke ioctl to  to NFCC driver.
+**
+** Returns          status code of ioctl.
+**
+*******************************************************************************/
+static int hal_ioctl(const struct nfc_nci_device *p_dev, long arg, void *p_data)
+{
+    int retval = 0;
+    pn547_dev_t* dev = (pn547_dev_t*) p_dev;
+
+    retval = phNxpNciHal_ioctl(arg, p_data);
+    return retval;
+}
+
+/*******************************************************************************
+**
+** 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;
+}
+
+/*******************************************************************************
+**
+** Function         hal_get_fw_dwnld_flag
+**
+** Description      Notify FW download request.
+**
+** Returns          true if successful otherwise false.
+**
+*******************************************************************************/
+static int hal_get_fw_dwnld_flag(const struct nfc_nci_device *p_dev, uint8_t* fwDnldRequest)
+{
+    int retval = 0;
+    pn547_dev_t* dev = (pn547_dev_t*) p_dev;
+
+    retval = phNxpNciHal_getFWDownloadFlag(fwDnldRequest);
+
+  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 */
+    pn547_dev_t *dev = NULL;
+    if (strcmp(name, NFC_NCI_CONTROLLER) == 0)
+    {
+        dev = calloc(1, sizeof(pn547_dev_t));
+        if(dev == NULL)
+        {
+            retval = -EINVAL;
+        }
+        else
+        {
+            /* Common hw_device_t fields */
+            dev->nci_device.common.tag = HARDWARE_DEVICE_TAG;
+            dev->nci_device.common.version = 0x00010000; /* [31:16] major, [15:0] minor */
+            dev->nci_device.common.module = (struct hw_module_t*) module;
+            dev->nci_device.common.close = nfc_close;
+
+            /* NCI HAL method pointers */
+            dev->nci_device.open = hal_open;
+            dev->nci_device.write = hal_write;
+            dev->ioctl = hal_ioctl;
+            dev->nci_device.core_initialized = hal_core_initialized;
+            dev->nci_device.pre_discover = hal_pre_discover;
+            dev->nci_device.close = hal_close;
+            dev->nci_device.control_granted = hal_control_granted;
+            dev->nci_device.power_cycle = hal_power_cycle;
+            dev->check_fw_dwnld_flag = hal_get_fw_dwnld_flag;
+            *device = (hw_device_t*) dev;
+        }
+  } else {
+    retval = -EINVAL;
+  }
+
+  ALOGD("%s: exit %d", __func__, 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..b475412
--- /dev/null
+++ b/halimpl/pn54x/self-test/phNxpNciHal_SelfTest.c
@@ -0,0 +1,1855 @@
+/*
+ * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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>
+#include <phNxpConfig.h>
+
+/* Timeout value to wait for response from PN54X */
+#define HAL_WRITE_RSP_TIMEOUT (2000)
+#define HAL_WRITE_MAX_RETRY (10)
+#define CORE_INIT_NCI2_0 false
+
+#define NXP_NFCC_RESET_RSP_LEN (0x10U) //for PN553 (0x10U) else (0x11U)
+
+/******************* 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);
+
+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);
+
+/* Test data to validate SWP line 2*/
+static nci_test_data_t swp2_test_data[] = {
+    {{
+      0x04, {0x20, 0x00, 0x01, 0x00} /* cmd */
+     },
+     {
+#if (NFC_NXP_CHIP_TYPE != PN547C2)
+      0x06, {0x40, 0x00, 0x03, 0x00, NXP_NFCC_RESET_RSP_LEN, 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) && (CORE_INIT_NCI2_0))
+      0x05, {0x20, 0x01, 0x02, 0x00, 0x00} /* cmd */
+#else
+      0x03, {0x20, 0x01, 0x00}
+#endif
+     },
+     {
+#if ((NFC_NXP_CHIP_TYPE == PN551) || (NFC_NXP_CHIP_TYPE == PN553)\
+    || (NFC_NXP_CHIP_TYPE == PN557))
+      0x4, {0x40, 0x01, 0x19, 0x00} /* exp_rsp */
+#elif(NFC_NXP_CHIP_TYPE == PN548C2)
+      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, 0x00} /* cmd */
+     },
+     {
+#if (NFC_NXP_CHIP_TYPE != PN547C2)
+      0x06, {0x40, 0x00, 0x03, 0x00, NXP_NFCC_RESET_RSP_LEN, 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) && (CORE_INIT_NCI2_0))
+      0x05, {0x20, 0x01, 0x02, 0x00, 0x00} /* cmd */
+#else
+      0x03, {0x20, 0x01, 0x00}
+#endif
+     },
+     {
+#if ((NFC_NXP_CHIP_TYPE == PN551) || (NFC_NXP_CHIP_TYPE == PN553)\
+    || (NFC_NXP_CHIP_TYPE == PN557))
+      0x4, {0x40, 0x01, 0x19, 0x00} /* exp_rsp */
+#elif(NFC_NXP_CHIP_TYPE == PN548C2)
+      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, NXP_NFCC_RESET_RSP_LEN, 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) && (CORE_INIT_NCI2_0))
+      0x05, {0x20, 0x01, 0x02, 0x00, 0x00} /* cmd */
+#else
+      0x03, {0x20, 0x01, 0x00}                               /* cmd */
+#endif
+     },
+     {
+#if ((NFC_NXP_CHIP_TYPE == PN551) || (NFC_NXP_CHIP_TYPE == PN553)\
+    || (NFC_NXP_CHIP_TYPE == PN557))
+      0x4, {0x40, 0x01, 0x19, 0x00} /* exp_rsp */
+#elif(NFC_NXP_CHIP_TYPE == PN548C2)
+      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, NXP_NFCC_RESET_RSP_LEN, 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) && (CORE_INIT_NCI2_0))
+      0x05, {0x20, 0x01, 0x02, 0x00, 0x00} /* cmd */
+#else
+      0x03, {0x20, 0x01, 0x00}                               /* cmd */
+#endif
+     },
+     {
+#if ((NFC_NXP_CHIP_TYPE == PN551) || (NFC_NXP_CHIP_TYPE == PN553)\
+     || (NFC_NXP_CHIP_TYPE == PN557))
+      0x4, {0x40, 0x01, 0x19, 0x00} /* exp_rsp */
+#elif(NFC_NXP_CHIP_TYPE == PN548C2)
+      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, NXP_NFCC_RESET_RSP_LEN, 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) && (CORE_INIT_NCI2_0))
+      0x05, {0x20, 0x01, 0x02, 0x00, 0x00} /* cmd */
+#else
+      0x03, {0x20, 0x01, 0x00}                               /* cmd */
+#endif
+     },
+     {
+#if ((NFC_NXP_CHIP_TYPE == PN551) || (NFC_NXP_CHIP_TYPE == PN553)\
+     || (NFC_NXP_CHIP_TYPE == PN557))
+      0x4, {0x40, 0x01, 0x19, 0x00} /* exp_rsp */
+#elif(NFC_NXP_CHIP_TYPE == PN548C2)
+      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, 0x00} /* cmd */
+     },
+     {
+#if (NFC_NXP_CHIP_TYPE != PN547C2)
+      0x06, {0x40, 0x00, 0x03, 0x00, NXP_NFCC_RESET_RSP_LEN, 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},
+};
+
+/* 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, NXP_NFCC_RESET_RSP_LEN, 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) && (CORE_INIT_NCI2_0))
+      0x05, {0x20, 0x01, 0x02, 0x00, 0x00} /* cmd */
+#else
+      0x03, {0x20, 0x01, 0x00}                               /* cmd */
+#endif
+     },
+     {
+#if ((NFC_NXP_CHIP_TYPE == PN551) || (NFC_NXP_CHIP_TYPE == PN553)\
+     || (NFC_NXP_CHIP_TYPE == PN557))
+      0x4, {0x40, 0x01, 0x19, 0x00} /* exp_rsp */
+#elif(NFC_NXP_CHIP_TYPE == PN548C2)
+      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},
+#if (NXP_HW_ANTENNA_LOOP4_SELF_TEST == true)
+    {{
+      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},
+#endif
+    {{
+      0x04, {0x2F, 0x00, 0x01, 0x01} /* cmd */
+     },
+     {
+      0x04, {0x4F, 0x00, 0x01, 0x00} /* exp_rsp */
+     },
+     {
+      0x00, {0x00} /* ext_ntf */
+     },
+     st_validator_testEquals, /* validator */
+     st_validator_null}};
+
+/************** 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 == NULL) {
+      NXPLOG_NCIHAL_E("Empty TransactInfo");
+      p_cb_data->status = NFCSTATUS_FAILED;
+    } else {
+      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");
+
+  pthread_exit(NULL);
+  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;
+  uint8_t* nfc_dev_node = NULL;
+  const uint16_t max_len =
+      260; /* device node name is max of 255 bytes + 5 bytes (/dev/) */
+  NFCSTATUS status = NFCSTATUS_SUCCESS;
+  uint16_t read_len = 255;
+  int8_t ret_val = 0x00;
+  /* 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));
+
+  /* Read the nfc device node name */
+  nfc_dev_node = (uint8_t*)malloc(max_len * sizeof(uint8_t));
+  if (nfc_dev_node == NULL) {
+    NXPLOG_NCIHAL_E("malloc of nfc_dev_node failed ");
+    goto clean_and_return;
+  } else if (!GetNxpStrValue(NAME_NXP_NFC_DEV_NODE, (char*)nfc_dev_node,
+                             max_len)) {
+    NXPLOG_NCIHAL_E(
+        "Invalid nfc device node name keeping the default device node "
+        "/dev/nq-nci");
+    strlcpy((char*)nfc_dev_node, "/dev/nq-nci", max_len);
+  }
+
+  gDrvCfg.nClientId = phDal4Nfc_msgget(0, 0600);
+  gDrvCfg.nLinkType = ENUM_LINK_TYPE_I2C; /* For PN54X */
+  tTmlConfig.pDevName = (int8_t*)nfc_dev_node;
+  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;
+  } else {
+    if (nfc_dev_node != NULL) {
+      free(nfc_dev_node);
+      nfc_dev_node = NULL;
+    }
+  }
+
+  pthread_attr_t attr;
+  pthread_attr_init(&attr);
+  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+  ret_val =
+      pthread_create(&test_rx_thread, &attr, phNxpNciHal_test_rx_thread, NULL);
+  pthread_attr_destroy(&attr);
+  if (ret_val != 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();
+  if (nfc_dev_node != NULL) {
+    free(nfc_dev_node);
+    nfc_dev_node = NULL;
+  }
+  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.
+ **
+ ******************************************************************************/
+
+NFCSTATUS phNxpNciHal_PrbsTestStart(phNxpNfc_PrbsType_t prbs_type,
+                                    phNxpNfc_PrbsHwType_t hw_prbs_type,
+                                    phNxpNfc_Tech_t tech,
+                                    phNxpNfc_Bitrate_t bitrate)
+{
+  NFCSTATUS status = NFCSTATUS_FAILED;
+
+  nci_test_data_t prbs_cmd_data;
+
+  uint8_t rsp_cmd_info[] = {0x4F, 0x30, 0x01, 0x00};
+
+  if(nfcFL.chipType != pn547C2) {
+      prbs_cmd_data.cmd.len = 0x09;
+  }
+  else {
+      prbs_cmd_data.cmd.len = 0x07;
+  }
+
+  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(nfcFL.chipType != 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(0,0,tech, bitrate, prbs_cmd_data.cmd.p_data,
+              prbs_cmd_data.cmd.len);
+  }
+
+  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.
+**
+*******************************************************************************/
+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)
+
+{
+  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 ||
+          ((nfcFL.chipType != pn547C2) && (prbs_cmd_len != 0x09)) ||
+          ((nfcFL.chipType == pn547C2) && (prbs_cmd_len != 0x07)))
+  {
+      return status;
+  }
+
+  prbs_cmd[0] = 0x2F;
+  prbs_cmd[1] = 0x30;
+  if(nfcFL.chipType != 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;
+  }
+
+  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)
+              && ((nfcFL.nfccFL._HW_ANTENNA_LOOP4_SELF_TEST) &&
+                      (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..caff27d
--- /dev/null
+++ b/halimpl/pn54x/tml/phDal4Nfc_messageQueueLib.c
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * 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(3000);
+    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..f5ce67d
--- /dev/null
+++ b/halimpl/pn54x/tml/phDal4Nfc_messageQueueLib.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * 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..dc9c82d
--- /dev/null
+++ b/halimpl/pn54x/tml/phOsalNfc_Timer.c
@@ -0,0 +1,447 @@
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * 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..d0efa01
--- /dev/null
+++ b/halimpl/pn54x/tml/phOsalNfc_Timer.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * 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..9f4f8aa
--- /dev/null
+++ b/halimpl/pn54x/tml/phTmlNfc.c
@@ -0,0 +1,1195 @@
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * TML Implementation.
+ */
+
+#include <phTmlNfc.h>
+#include <phOsalNfc_Timer.h>
+#include <phNxpLog.h>
+#include <phDal4Nfc_messageQueueLib.h>
+#include <phTmlNfc_i2c.h>
+#include <phNxpNciHal_utils.h>
+#include <errno.h>
+
+/*
+ * Duration of Timer to wait after sending an Nci packet
+ */
+#define PHTMLNFC_MAXTIME_RETRANSMIT (200U)
+#define MAX_WRITE_RETRY_COUNT 0x03
+#define MAX_READ_RETRY_COUNT 0x05
+
+/* 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;
+/* 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);
+static void phTmlNfc_WaitWriteComplete(void);
+static void phTmlNfc_SignalWriteComplete(void);
+static int phTmlNfc_WaitReadInit(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 = NULL;
+      } 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 != phTmlNfc_WaitReadInit()) {
+          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];
+  static uint8_t read_count = 0;
+
+  /* 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 (((uintptr_t)gpphTmlNfc_Context->pDevHandle) > 0) {
+        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");
+            if(nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT) {
+                if (read_count <= MAX_READ_RETRY_COUNT) {
+                    read_count++;
+                    /*sleep for 30/60/90/120/150 msec between each read trial incase of
+                     * read error*/
+                    usleep(read_count * 30 * 1000);
+                } else {
+                    /* Fill the Transaction info structure to be passed to Callback
+                     * Function */
+                    tTransactionInfo.wStatus = NFCSTATUS_READ_FAILED;
+                    // tTransactionInfo.pBuff = gpphTmlNfc_Context->tReadInfo.pBuffer;
+                    /* Actual number of bytes read is filled in the structure */
+                    // tTransactionInfo.wLength = gpphTmlNfc_Context->tReadInfo.wLength;
+
+                    /* Read operation Failed. 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 failure message.....\n");
+                    phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
+                            &tMsg);
+                    return;
+                }
+            }
+          sem_post(&gpphTmlNfc_Context->rxSemaphore);
+        } else if (dwNoBytesWrRd > 260) {
+          NXPLOG_TML_E("Numer of bytes read exceeds the limit 260.....\n");
+          if(nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT) {
+              read_count = 0;
+          }
+          sem_post(&gpphTmlNfc_Context->rxSemaphore);
+        } else {
+          memcpy(gpphTmlNfc_Context->tReadInfo.pBuffer, temp, dwNoBytesWrRd);
+          if(nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT) {
+              read_count = 0;
+          }
+          NXPLOG_TML_D("PN54X - I2C Read successful.....len = %d\n",
+                       dwNoBytesWrRd);
+          /* 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;
+            }
+          }
+          if (gpphTmlNfc_Context->tWriteInfo.bThreadBusy) {
+            NXPLOG_TML_D("Delay Read if write thread is busy");
+            usleep(2000); /*2ms delay to give prio to write complete */
+          }
+          /* Update the actual number of bytes read including header */
+          gpphTmlNfc_Context->tReadInfo.wLength = (uint16_t)(dwNoBytesWrRd);
+          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);
+          /*Don't wait for posting notifications. Only wait for posting
+           * responses*/
+          /*TML reader writer callback syncronization-- START*/
+          pthread_mutex_lock(&gpphTmlNfc_Context->wait_busy_lock);
+          if ((gpphTmlNfc_Context->gWriterCbflag == false) &&
+              ((gpphTmlNfc_Context->tReadInfo.pBuffer[0] & 0x60) != 0x60)) {
+            phTmlNfc_WaitWriteComplete();
+          }
+          /*TML reader writer callback syncronization-- END*/
+          pthread_mutex_unlock(&gpphTmlNfc_Context->wait_busy_lock);
+          NXPLOG_TML_D("PN54X - Posting read message.....\n");
+          phNxpNciHal_print_packet("RECV",
+                                   gpphTmlNfc_Context->tReadInfo.pBuffer,
+                                   gpphTmlNfc_Context->tReadInfo.wLength);
+          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 (((uintptr_t)gpphTmlNfc_Context->pDevHandle) > 0) {
+      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");
+        gpphTmlNfc_Context->gWriterCbflag = false;
+        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);
+          if (NFCSTATUS_SUCCESS == wStatus) {
+            /*TML reader writer thread callback syncronization---START*/
+            pthread_mutex_lock(&gpphTmlNfc_Context->wait_busy_lock);
+            gpphTmlNfc_Context->gWriterCbflag = true;
+            phTmlNfc_SignalWriteComplete();
+            /*TML reader writer thread callback syncronization---END*/
+            pthread_mutex_unlock(&gpphTmlNfc_Context->wait_busy_lock);
+          }
+        }
+      } 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) {
+    return;
+  }
+  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);
+  pthread_mutex_destroy(&gpphTmlNfc_Context->wait_busy_lock);
+  pthread_cond_destroy(&gpphTmlNfc_Context->wait_busy_condition);
+  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:
+      case phTmlNfc_e_EnableNormalMode: {
+        /*Block reader thread until VEN Toggling is completed*/
+        /*Reset PN54X*/
+        uint8_t read_flag = false;
+        if (gpphTmlNfc_Context->tReadInfo.bEnable) {
+          gpphTmlNfc_Context->tReadInfo.bEnable = 0;
+          read_flag = true;
+        }
+        gpphTmlNfc_Context->tReadInfo.bEnable = 0;
+        phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle, 0);
+        usleep(10 * 1000);
+        phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle, 1);
+        usleep(100 * 1000);
+        if (read_flag) {
+          gpphTmlNfc_Context->tReadInfo.bEnable = 1;
+          sem_post(&gpphTmlNfc_Context->rxSemaphore);
+        }
+        break;
+      }
+      case phTmlNfc_e_EnableDownloadMode: {
+        phTmlNfc_ConfigNciPktReTx(phTmlNfc_e_DisableRetrans, 0);
+        gpphTmlNfc_Context->tReadInfo.bEnable = 0;
+        wStatus = phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle, 2);
+        usleep(100 * 1000);
+        gpphTmlNfc_Context->tReadInfo.bEnable = 1;
+        sem_post(&gpphTmlNfc_Context->rxSemaphore);
+        break;
+      }
+      case phTmlNfc_e_SetJcopDwnldEnable: {
+          if(nfcFL.nfcNxpEse) {
+              wStatus = phTmlNfc_i2c_set_Jcop_dwnld_state(
+                      gpphTmlNfc_Context->pDevHandle, JCP_DWNLD_START);
+          }
+          break;
+      }
+      case phTmlNfc_e_SetJcopDwnldDisable: {
+          if(nfcFL.nfcNxpEse) {
+              wStatus = phTmlNfc_i2c_set_Jcop_dwnld_state(
+                      gpphTmlNfc_Context->pDevHandle, JCP_DWP_DWNLD_COMPLETE);
+          }
+          break;
+      }
+      case phTmlNfc_e_SetNfcServicePid: {
+          if(nfcFL.nfcNxpEse) {
+              wStatus = phTmlNfc_set_pid(gpphTmlNfc_Context->pDevHandle,
+                      gpphTmlNfc_Context->nfc_service_pid);
+          }
+          break;
+      }
+      case phTmlNfc_e_GetP61PwrMode: {
+          if(nfcFL.nfcNxpEse) {
+              wStatus = phTmlNfc_i2c_get_p61_power_state(
+                      gpphTmlNfc_Context->pDevHandle);
+          }
+          break;
+      }
+      case phTmlNfc_e_SetP61WiredMode: {
+          if(nfcFL.nfcNxpEse) {
+              wStatus = phTmlNfc_i2c_set_p61_power_state(
+                              gpphTmlNfc_Context->pDevHandle, 1);
+          }
+          break;
+      }
+      case phTmlNfc_e_SetP61IdleMode: {
+          if(nfcFL.nfcNxpEse) {
+              wStatus = phTmlNfc_i2c_set_p61_power_state(
+                              gpphTmlNfc_Context->pDevHandle, 0);
+          }
+          break;
+      }
+      case phTmlNfc_e_SetP61DisableMode: {
+          if(nfcFL.nfcNxpEse) {
+              wStatus = phTmlNfc_i2c_set_p61_power_state(
+                              gpphTmlNfc_Context->pDevHandle, 2);
+          }
+          break;
+      }
+      case phTmlNfc_e_SetP61EnableMode: {
+          {
+              wStatus = phTmlNfc_i2c_set_p61_power_state(
+                      gpphTmlNfc_Context->pDevHandle, 3);
+          }
+          break;
+      }
+      case phTmlNfc_e_RelP61Access: {
+          if(nfcFL.nfcNxpEse) {
+              wStatus = phTmlNfc_i2c_set_p61_power_state(
+                      gpphTmlNfc_Context->pDevHandle, 4);
+          }
+          break;
+      }
+      case phTmlNfc_e_eSEChipRstMode: {
+          if(nfcFL.nfcNxpEse) {
+              wStatus = phTmlNfc_i2c_reset(
+                      gpphTmlNfc_Context->pDevHandle, 3);
+          }
+          break;
+      }
+      case phTmlNfc_e_SetLegacyPowerScheme: {
+          if(nfcFL.nfcNxpEse) {
+              wStatus = phTmlNfc_set_power_scheme(
+                      gpphTmlNfc_Context->pDevHandle, 2);
+          }
+          break;
+      }
+      case phTmlNfc_e_SetExtPMUPowerScheme: {
+          if(nfcFL.nfcNxpEse) {
+              wStatus = phTmlNfc_set_power_scheme(
+                      gpphTmlNfc_Context->pDevHandle, 3);
+          }
+          break;
+      }
+      case phTmlNfc_e_SetPN67TPowerScheme: {
+          if(nfcFL.nfcNxpEse) {
+              wStatus = phTmlNfc_set_power_scheme(
+                      gpphTmlNfc_Context->pDevHandle, 1);
+          }
+          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;
+}
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_WaitWriteComplete
+**
+** Description      wait function for reader thread
+**
+** Parameters       None
+**
+** Returns          None
+**
+*******************************************************************************/
+static void phTmlNfc_WaitWriteComplete(void) {
+  int ret = -1;
+  struct timespec absTimeout;
+  if (clock_gettime(CLOCK_MONOTONIC, &absTimeout) == -1) {
+    NXPLOG_TML_E("Reader Thread clock_gettime failed");
+  } else {
+    absTimeout.tv_sec += 1; /*1 second timeout*/
+    gpphTmlNfc_Context->wait_busy_flag = true;
+    NXPLOG_TML_D("phTmlNfc_WaitWriteComplete - enter");
+    ret = pthread_cond_timedwait(&gpphTmlNfc_Context->wait_busy_condition,
+                                 &gpphTmlNfc_Context->wait_busy_lock,
+                                 &absTimeout);
+    if ((ret != 0) && (ret != ETIMEDOUT)) {
+      NXPLOG_TML_E("Reader Thread wait failed");
+    }
+    NXPLOG_TML_D("phTmlNfc_WaitWriteComplete - exit");
+  }
+}
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_SignalWriteComplete
+**
+** Description      function to invoke reader thread
+**
+** Parameters       None
+**
+** Returns          None
+**
+*******************************************************************************/
+static void phTmlNfc_SignalWriteComplete(void) {
+  int ret = -1;
+  if (gpphTmlNfc_Context->wait_busy_flag == true) {
+    NXPLOG_TML_D("phTmlNfc_SignalWriteComplete - enter");
+    gpphTmlNfc_Context->wait_busy_flag = false;
+
+    ret = pthread_cond_signal(&gpphTmlNfc_Context->wait_busy_condition);
+    if (ret) {
+      NXPLOG_TML_E(" phTmlNfc_SignalWriteComplete failed, error = 0x%X", ret);
+    }
+    NXPLOG_TML_D("phTmlNfc_SignalWriteComplete - exit");
+  }
+}
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_WaitReadInit
+**
+** Description      init function for reader thread
+**
+** Parameters       None
+**
+** Returns          int
+**
+*******************************************************************************/
+static int phTmlNfc_WaitReadInit(void) {
+  int ret = -1;
+  pthread_condattr_t attr;
+  pthread_condattr_init(&attr);
+  pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
+  memset(&gpphTmlNfc_Context->wait_busy_condition, 0,
+         sizeof(gpphTmlNfc_Context->wait_busy_condition));
+  pthread_mutex_init(&gpphTmlNfc_Context->wait_busy_lock, NULL);
+  ret = pthread_cond_init(&gpphTmlNfc_Context->wait_busy_condition, &attr);
+  if (ret) {
+    NXPLOG_TML_E(" phTphTmlNfc_WaitReadInit failed, error = 0x%X", ret);
+  }
+  return ret;
+}
diff --git a/halimpl/pn54x/tml/phTmlNfc.h b/halimpl/pn54x/tml/phTmlNfc.h
new file mode 100644
index 0000000..5bdfb80
--- /dev/null
+++ b/halimpl/pn54x/tml/phTmlNfc.h
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * 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_e_SetNfcServicePid, /* Register the Nfc service PID with the driver
+                                  */
+  phTmlNfc_e_GetP61PwrMode,    /* Get the current P61 mode of operation */
+  phTmlNfc_e_SetP61WiredMode,  /* Set the current P61 mode of operation to
+                                  Wired*/
+  phTmlNfc_e_SetP61IdleMode, /* Set the current P61 mode of operation to Idle*/
+  phTmlNfc_e_SetP61DisableMode, /* Set the ese vdd gpio to low*/
+  phTmlNfc_e_SetP61EnableMode,  /* Set the ese vdd gpio to high*/
+  phTmlNfc_e_eSEChipRstMode,    /* ISO RST of P73*/
+  phTmlNfc_e_RelP61Access,      /*Release the P61 lock*/
+  phTmlNfc_e_SetLegacyPowerScheme,
+  phTmlNfc_e_SetExtPMUPowerScheme,
+  phTmlNfc_e_SetPN67TPowerScheme,
+  phTmlNfc_e_RelP61SvddWait,
+  phTmlNfc_e_SetJcopDwnldEnable,
+  phTmlNfc_e_SetJcopDwnldDisable
+} 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 */
+  pthread_cond_t wait_busy_condition; /*Condition to wait reader thread*/
+  pthread_mutex_t wait_busy_lock;     /*Condition lock to wait reader thread*/
+  volatile uint8_t wait_busy_flag;    /*Condition flag to wait reader thread*/
+  volatile uint8_t
+      gWriterCbflag; /* flag to indicate write callback message is pushed to
+                        queue*/
+  long    nfc_service_pid; /*NFC Service PID to be used by driver to signal*/
+} 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);
+NFCSTATUS phTmlNfc_get_ese_access(void* pDevHandle, long timeout);
+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..55d0c0e
--- /dev/null
+++ b/halimpl/pn54x/tml/phTmlNfc_i2c.c
@@ -0,0 +1,580 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * 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((const char*)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), 0);
+  usleep(10 * 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;
+    }
+    if ((totalBtyesToRead - numRead) != 0) {
+      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;
+      }
+    } else {
+      NXPLOG_TML_E("_>>>>> Empty packet recieved !!");
+    }
+  }
+  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
+**
+*******************************************************************************/
+int phTmlNfc_i2c_reset(void* pDevHandle, long level) {
+  int ret = -1;
+
+  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 (ret < 0) {
+    NXPLOG_TML_E("%s :failed errno = 0x%x", __func__, errno);
+    if (level == 2 && errno == EBUSY) {
+      notifyFwrequest = true;
+    } else {
+      notifyFwrequest = false;
+    }
+  }
+  if (level == 2 && ret == 0) {
+    bFwDnldFlag = true;
+  } else {
+    bFwDnldFlag = false;
+  }
+  return ret;
+}
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_i2c_set_Jcop_dwnld_state
+**
+** Description      This function set jcop download state.
+**
+** Parameters       pDevHandle     - valid device handle
+**
+** Returns          NFCSTATUS
+**
+**
+*******************************************************************************/
+NFCSTATUS phTmlNfc_i2c_set_Jcop_dwnld_state(void* pDevHandle, long level) {
+    NXPLOG_TML_D("phTmlNfc_i2c_set_Jcop_dwnld_state()");
+    if(!nfcFL.nfcNxpEse) {
+        NXPLOG_TML_D("NxpEse not available. Returning");
+        return NFCSTATUS_FAILED;
+    }
+  int32_t ret = -1;
+  NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+
+  NXPLOG_TML_D("phTmlNfc_i2c_set_Jcop_dwnld_state(), level %ld", level);
+
+  if (NULL == pDevHandle) return NFCSTATUS_FAILED;
+
+  ret =
+      ioctl((intptr_t)pDevHandle, PN544_SET_DWNLD_STATUS, (unsigned long)level);
+  if (ret < 0) {
+    NXPLOG_TML_E("%s : failed errno = 0x%x", __func__, errno);
+    if (errno == -EBUSY) {
+      wStatus = NFCSTATUS_BUSY;
+    } else if (errno == -EBADRQC) {
+      wStatus = NFCSTATUS_INVALID_FORMAT;
+    } else if (errno == -EINVAL) {
+      wStatus = NFCSTATUS_INVALID_PARAMETER;
+    } else {
+      wStatus = NFCSTATUS_FAILED;
+    }
+  }
+  return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_set_pid
+**
+** Description
+**
+** Parameters       pDevHandle     - valid device handle
+**                        pid - nfc service pid
+**
+** Returns          p61_access_state_t  - get_p61_power operation success
+**                  P61_STATE_INVALID   - get_p61_power operation failure
+**
+*******************************************************************************/
+NFCSTATUS phTmlNfc_set_pid(void* pDevHandle, long pid) {
+    NXPLOG_TML_D("phTmlNfc_set_pid()");
+        if(!nfcFL.nfcNxpEse) {
+            NXPLOG_TML_D("NxpEse not available. Returning");
+            return NFCSTATUS_FAILED;
+        }
+  NFCSTATUS wStatus = NFCSTATUS_FAILED;
+  uint32_t ret = -1;
+  NXPLOG_TML_D("phTmlNfc_set_pid(), pid  %ld", pid);
+
+  if (NULL == pDevHandle) {
+    return NFCSTATUS_FAILED;
+  }
+
+  ret = (uint32_t)ioctl((intptr_t)pDevHandle, P544_SET_NFC_SERVICE_PID, pid);
+  if (!ret) wStatus = NFCSTATUS_SUCCESS;
+
+  return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_set_power_scheme
+**
+** Description      This function sets the eSE power scheme in pn544 driver
+**
+** Parameters       pDevHandle     - valid device handle
+**                        pid - nfc service pid
+**
+** Returns          p61_access_state_t  - get_p61_power operation success
+**                  P61_STATE_INVALID   - get_p61_power operation failure
+**
+*******************************************************************************/
+NFCSTATUS phTmlNfc_set_power_scheme(void* pDevHandle, long id) {
+    NXPLOG_TML_D("phTmlNfc_set_power_scheme()");
+    if(!nfcFL.nfcNxpEse) {
+        NXPLOG_TML_D("NxpEse not available. Returning");
+        return NFCSTATUS_FAILED;
+    }
+  int ret;
+  NXPLOG_TML_D("phTmlNfc_set_power_scheme(), id  %ld", id);
+
+  if (NULL == pDevHandle) {
+    return NFCSTATUS_FAILED;
+  }
+
+  ret = ioctl((intptr_t)pDevHandle, P544_SET_POWER_SCHEME, id);
+  return ret;
+}
+/*******************************************************************************
+**
+** Function         phTmlNfc_i2c_set_p61_power_state
+**
+** Description
+**
+** Parameters       pDevHandle     - valid device handle
+**
+** Returns          p61_access_state_t  - get_p61_power operation success
+**                  P61_STATE_INVALID   - get_p61_power operation failure
+**
+*******************************************************************************/
+NFCSTATUS phTmlNfc_i2c_set_p61_power_state(void* pDevHandle, long level) {
+    NXPLOG_TML_D("phTmlNfc_i2c_set_p61_power_state()");
+    if(!nfcFL.nfcNxpEse) {
+        NXPLOG_TML_D("NxpEse not available. Returning");
+        return NFCSTATUS_FAILED;
+    }
+  int ret = -1;
+  NFCSTATUS wStatus = NFCSTATUS_FAILED;
+
+  NXPLOG_TML_D("phTmlNfc_i2c_set_p61_power_state(), level %ld", level);
+
+  if (NULL == pDevHandle) {
+    return -1;
+  }
+  ret = ioctl((intptr_t)pDevHandle, P61_SET_WIRED_ACCESS, (unsigned long)level);
+  if (ret < 0) {
+    NXPLOG_TML_E("%s : failed errno = 0x%x", __func__, errno);
+    if (errno == -EBUSY) {
+      wStatus = NFCSTATUS_BUSY;
+    } else if (errno == -EPERM) {
+      wStatus = NFCSTATUS_NOT_ALLOWED;
+    } else if (errno == -EBADRQC) {
+      wStatus = NFCSTATUS_INVALID_PARAMETER;
+    } else {
+      wStatus = NFCSTATUS_FAILED;
+    }
+  } else {
+    wStatus = NFCSTATUS_SUCCESS;
+  }
+
+  return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_i2c_get_p61_power_state
+**
+** Description
+**
+** Parameters       pDevHandle     - valid device handle
+**
+** Returns          get_p61_power operation success
+**                  NFCSTATUS_FAILED   - get_p61_power operation failure
+**
+*******************************************************************************/
+NFCSTATUS phTmlNfc_i2c_get_p61_power_state(void* pDevHandle) {
+    NXPLOG_TML_D("phTmlNfc_i2c_get_p61_power_state()");
+    if(!nfcFL.nfcNxpEse) {
+        NXPLOG_TML_D("NxpEse not available. Returning");
+        return NFCSTATUS_FAILED;
+    }
+  int ret;
+  NFCSTATUS wStatus = NFCSTATUS_FAILED;
+  p61_access_state_t p61_current_state = P61_STATE_INVALID;
+  NXPLOG_TML_D("phTmlNfc_i2c_get_p61_power_mode()");
+
+  if (NULL == pDevHandle) {
+    return -1;
+  }
+  ret = ioctl((intptr_t)pDevHandle, P61_GET_PWR_STATUS,
+              (unsigned long)&p61_current_state);
+  if (ret < 0) {
+    NXPLOG_TML_E("%s : failed errno = 0x%x", __func__, errno);
+    p61_current_state = P61_STATE_INVALID;
+  }
+  wStatus = p61_current_state;
+  return wStatus;
+}
+/*******************************************************************************
+**
+** Function         phTmlNfc_get_ese_access
+**
+** Description
+**
+** Parameters       pDevHandle     - valid device handle
+**                  timeout - timeout to wait for ese access
+**
+** Returns          success or failure
+**
+*******************************************************************************/
+NFCSTATUS phTmlNfc_get_ese_access(void* pDevHandle, long timeout) {
+    NXPLOG_TML_D("phTmlNfc_get_ese_access()");
+    if(!nfcFL.nfcNxpEse) {
+        NXPLOG_TML_D("NxpEse not available. Returning");
+        return NFCSTATUS_FAILED;
+    }
+  int ret = -1;
+  NFCSTATUS status = NFCSTATUS_SUCCESS;
+  NXPLOG_TML_D("phTmlNfc_get_ese_access(), enter timeout  %ld", timeout);
+
+  if (NULL == pDevHandle) {
+    return NFCSTATUS_FAILED;
+  }
+
+  ret = ioctl((intptr_t)pDevHandle, P544_GET_ESE_ACCESS, timeout);
+  if (ret < 0) {
+    if (ret == -EBUSY)
+      status = NFCSTATUS_BUSY;
+    else
+      status = NFCSTATUS_FAILED;
+  }
+  NXPLOG_TML_D("phTmlNfc_get_ese_access(), exit ret %d, status %d", ret,
+               status);
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_rel_svdd_wait
+**
+** Description
+**
+** Parameters       pDevHandle     - valid device handle
+**
+** Returns          success or failure
+**
+*******************************************************************************/
+NFCSTATUS phTmlNfc_rel_svdd_wait(void* pDevHandle) {
+    NXPLOG_TML_D("phTmlNfc_rel_svdd_wait()");
+    if(!nfcFL.nfcNxpEse && !nfcFL.eseFL._ESE_SVDD_SYNC) {
+        NXPLOG_TML_D("NxpEse and ESE_SVDD_SYNC not available. Returning");
+        return NFCSTATUS_FAILED;
+    }
+  int ret = -1;
+  NFCSTATUS status = NFCSTATUS_SUCCESS;
+  NXPLOG_TML_D("phTmlNfc_rel_svdd_wait(), enter ");
+
+  if (NULL == pDevHandle) {
+    return NFCSTATUS_FAILED;
+  }
+
+  ret = ioctl((intptr_t)pDevHandle, P544_REL_SVDD_WAIT);
+  if (ret < 0) {
+    if (ret == -EBUSY)
+      status = NFCSTATUS_BUSY;
+    else
+      status = NFCSTATUS_FAILED;
+  }
+  NXPLOG_TML_D("phTmlNfc_rel_svdd_wait(), exit  ret %d, status %d", ret,
+               status);
+  return status;
+}
+
+/*******************************************************************************
+**
+** 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..23441f5
--- /dev/null
+++ b/halimpl/pn54x/tml/phTmlNfc_i2c.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * TML I2C port implementation for linux
+ */
+
+/* Basic type definitions */
+#include <phNfcTypes.h>
+#include <phTmlNfc.h>
+
+#define PN544_MAGIC 0xE9
+
+/* 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);
+bool_t notifyFwrequest;
+phTmlNfc_i2cfragmentation_t fragmentation_enabled;
+
+/*
+ * PN544 power control via ioctl
+ * PN544_SET_PWR(0): power off
+ * PN544_SET_PWR(1): power on
+ * PN544_SET_PWR(2): reset and power on with firmware download enabled
+ */
+#define PN544_SET_PWR    _IOW(PN544_MAGIC, 0x01, unsigned int)
+
+NFCSTATUS phTmlNfc_i2c_get_p61_power_state(void* pDevHandle);
+NFCSTATUS phTmlNfc_i2c_set_p61_power_state(void* pDevHandle, long arg);
+NFCSTATUS phTmlNfc_set_pid(void* pDevHandle, long pid);
+NFCSTATUS phTmlNfc_set_power_scheme(void* pDevHandle, long id);
+NFCSTATUS phTmlNfc_get_ese_access(void* pDevHandle, long timeout);
+NFCSTATUS phTmlNfc_i2c_set_Jcop_dwnld_state(void* pDevHandle, long level);
+NFCSTATUS phTmlNfc_rel_svdd_wait(void* pDevHandle);
+/*
+ * SPI Request NFCC to enable p61 power, only in param
+ * Only for SPI
+ * level 1 = Enable power
+ * level 0 = Disable power
+ */
+#define P61_SET_SPI_PWR    _IOW(PN544_MAGIC, 0x02, unsigned int)
+
+/* SPI or DWP can call this ioctl to get the current
+ * power state of P61
+ *
+*/
+#define P61_GET_PWR_STATUS    _IOR(PN544_MAGIC, 0x03, unsigned int)
+
+/* DWP side this ioctl will be called
+ * level 1 = Wired access is enabled/ongoing
+ * level 0 = Wired access is disalbed/stopped
+*/
+#define P61_SET_WIRED_ACCESS _IOW(PN544_MAGIC, 0x04, unsigned int)
+
+/*
+  NFC Init will call the ioctl to register the PID with the i2c driver
+*/
+#define P544_SET_NFC_SERVICE_PID _IOW(PN544_MAGIC, 0x05, long)
+
+/*
+  NFC and SPI will call the ioctl to get the i2c/spi bus access
+*/
+#define P544_GET_ESE_ACCESS _IOW(PN544_MAGIC, 0x06, long)
+
+/*
+  NFC and SPI will call the ioctl to update the power scheme
+*/
+#define P544_SET_POWER_SCHEME _IOW(PN544_MAGIC, 0x07, long)
+/*
+  NFC will call the ioctl to release the svdd protection
+*/
+#define P544_REL_SVDD_WAIT _IOW(PN544_MAGIC, 0x08, long)
+/* SPI or DWP can call this ioctl to set the JCOP download
+ * state of P61
+ *
+*/
+#define PN544_SET_DWNLD_STATUS _IOW(PN544_MAGIC, 0x09, long)
diff --git a/halimpl/pn54x/utils/phNxpConfig.cpp b/halimpl/pn54x/utils/phNxpConfig.cpp
new file mode 100644
index 0000000..acfe888
--- /dev/null
+++ b/halimpl/pn54x/utils/phNxpConfig.cpp
@@ -0,0 +1,1423 @@
+/******************************************************************************
+ *  Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  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) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+ /**
+  * @file phNxpConfig.cpp
+  * @date 24 Aug 2016
+  * @brief File containing code for dynamic selection of config files based on target.
+  *
+  * The target device has to be configured with some primary setting while booting.So a
+  * config file will be picked while the target is booted. Here based on the target device
+  * a configuration file will be selected dynamically and the device will be configured.
+  */
+
+#include <phNxpConfig.h>
+#include <stdio.h>
+#include <string>
+#include <vector>
+#include <list>
+#include <sys/stat.h>
+#include <stdlib.h>
+
+#include <phNxpLog.h>
+#include <cutils/log.h>
+#include <cutils/properties.h>
+#include <errno.h>
+
+#if GENERIC_TARGET
+const char alternative_config_path[] = "/data/vendor/nfc/";
+#else
+const char alternative_config_path[] = "";
+#endif
+
+#if 1
+const char* transport_config_paths[] = {"/odm/etc/", "/vendor/etc/", "/etc/"};
+const char transit_config_path[] = "/data/vendor/nfc/libnfc-nxpTransit.conf";
+#else
+const char* transport_config_paths[] = {"res/"};
+#endif
+const int transport_config_path_size =
+    (sizeof(transport_config_paths) / sizeof(transport_config_paths[0]));
+#define config_name "libnfc-nxp.conf"
+#if (NXP_EXTNS == TRUE)
+#define extra_config_base "libnfc-"
+#else
+#define extra_config_base "libnfc-nxp-"
+#endif
+#define extra_config_ext ".conf"
+#define IsStringValue 0x80000000
+
+const char rf_config_timestamp_path[] =
+        "/data/vendor/nfc/libnfc-nxpRFConfigState.bin";
+const char tr_config_timestamp_path[] =
+    "/data/vendor/nfc/libnfc-nxpTransitConfigState.bin";
+const char config_timestamp_path[] =
+        "/data/vendor/nfc/libnfc-nxpConfigState.bin";
+const char default_nxp_config_path[] =
+        "/etc/libnfc-nxp.conf";
+const char nxp_rf_config_path[] =
+        "/system/vendor/libnfc-nxp_RF.conf";
+
+/**
+ *  @brief target platform ID values.
+ */
+
+typedef enum
+{
+  CONFIG_GENERIC                         = 0x00,
+  MTP_TYPE_DEFAULT                       = 0x01, /**< default MTP config. DC DC ON */
+  QRD_TYPE_DEFAULT                       = 0x02, /**< default QRD config DC DC OFF */
+  MTP_TYPE_1                             = 0x03, /**< mtp config type1 : newer chip */
+  MTP_TYPE_2                             = 0x04, /**< mtp config type2 TBD */
+  QRD_TYPE_1                             = 0x05, /**< qrd config type1 DC DC ON*/
+  QRD_TYPE_2                             = 0x06, /**< qrd config type2  Newer chip */
+  MTP_TYPE_NQ3XX                         = 0x07, /**< mtp config : for NQ3XX chip */
+  QRD_TYPE_NQ3XX                         = 0x08, /**< qrd config : for NQ3XX chip */
+  MTP_TYPE_NQ4XX                         = 0x09, /**< mtp config : for NQ4XX chip */
+  QRD_TYPE_NQ4XX                         = 0x10, /**< qrd config : for NQ4XX chip */
+  DEFAULT_CONFIG                         = QRD_TYPE_DEFAULT, /**< default is qrd default config */
+  CONFIG_INVALID                         = 0xFF
+} CONFIGIDVALUE;
+
+/**
+ *  @brief Defines the soc_id values for different targets.
+ */
+
+typedef enum
+{
+  TARGET_GENERIC                       = 0x00,/**< new targets */
+  TARGET_MSM8952                       = 264, /**< 8952 target */
+  TARGET_MSM8976                       = 278, /**< 8976 target */
+  TARGET_MSM8937                       = 294, /**< 8937 target */
+  TARGET_MSM8953                       = 293, /**< 8953 target */
+  TARGET_MSM8996                       = 246, /**< 8996 target*/
+  TARGET_MSM8909                       = 245, /**< 8909w target */
+  TARGET_MSM8998                       = 292, /**< 8998 target */
+  TARGET_MSM8997                       = 306, /**< 8997 target */
+  TARGET_MSM8917                       = 303, /**< 8917 target */
+  TARGET_MSM8940                       = 313, /**< 8940 target */
+  TARGET_SDM660                        = 317, /**< SDM660 target */
+  TARGET_SDM630                        = 318, /**< SDM630 target */
+  TARGET_SDM845                        = 321, /**< SDM845 target */
+  TARGET_DEFAULT                       = TARGET_GENERIC, /**< new targets */
+  TARGET_INVALID                       = 0xFF
+} TARGETTYPE;
+
+using namespace::std;
+
+namespace nxp {
+
+void readOptionalConfig(const char* optional);
+void findConfigFilePathFromTransportConfigPaths(const string& configName, string& filePath);
+
+class CNfcParam : public string {
+ public:
+  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(const char* fileName, const char* fileTimeStamp);
+
+  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 readNxpTransitConfig(const char* fileName) const;
+  void readNxpRFConfig(const char* fileName) const;
+  void clean();
+
+ private:
+  CNfcConfig();
+  bool readConfig(const char* name, bool bResetContent);
+  int     file_exist (const char* filename);
+  int     getconfiguration_id (char * config_file);
+  void moveFromList();
+  void moveToList();
+  void add(const CNfcParam* pParam);
+  void dump();
+  bool isAllowed(const char* name);
+  list<const CNfcParam*> m_list;
+  bool mValidFile;
+  bool    mDynamConfig;
+  unsigned long m_timeStamp;
+  unsigned long m_timeStampRF;
+  unsigned long m_timeStampTransit;
+  string mCurrentFile;
+
+  unsigned long state;
+  inline bool Is(unsigned long f) { return (state & f) == f; }
+  inline void Set(unsigned long f) { state |= f; }
+  inline void Reset(unsigned long f) { state &= ~f; }
+};
+
+/**
+ * @brief This function reads the hardware information from the given path.
+ *
+ * This function receives the path and then reads the hardware information
+ * from the file present in the given path. It reads the details like whether
+ * it is QRD or MTP. It reads the data from that file and stores in buffer.
+ * It also receives a count which tells the number of characters to be read
+ * Finally the length of the buffer is returned.
+ *
+ * @param path The path where the file containing hardware details to be read.
+ * @param buff The hardware details that is read from that path will be stored here.
+ * @param count It represents the number of characters to be read from that file.
+ * @return It returns the length of the buffer.
+ */
+
+static int read_line_from_file(const char *path, char *buf, size_t count)
+{
+    char *fgets_ret = NULL;
+    FILE *fd = NULL;
+    int rv = 0;
+
+    // opens the file to read the HW_PLATFORM detail of the target
+    fd = fopen(path, "r");
+    if (fd == NULL)
+        return -1;
+
+    // stores the data that is read from the given path into buf
+    fgets_ret = fgets(buf, (int)count, fd);
+    if (NULL != fgets_ret)
+        rv = (int)strlen(buf);
+    else
+        rv = ferror(fd);
+
+    fclose(fd);
+
+    return rv;
+}
+
+/**
+ * @brief This function gets the source information from the file.
+ *
+ * This function receives a buffer variable to store the read information
+ * and also receives two different path. The hardware information may be
+ * present in any one of the received path. So this function checks in
+ * both the paths. This function internally uses read_line_from_file
+ * function to read the check and read the hardware details in each path.
+ *
+ * @param buf hardware details that is read will be stored.
+ * @param soc_node_path1 The first path where the file may be present.
+ * @param soc_node_path2 The second path where the file may be present.
+ * @return Returns the length of buffer.
+ */
+
+static int get_soc_info(char *buf, const char *soc_node_path1,
+            const char *soc_node_path2)
+{
+    int ret = 0;
+
+    // checks whether the hw platform detail is present in this path
+    ret = read_line_from_file(soc_node_path1, buf, MAX_SOC_INFO_NAME_LEN);
+    if (ret < 0) {
+        // if the hw platform detail is not present in the former path it checks here
+        ret = read_line_from_file(soc_node_path2, buf, MAX_SOC_INFO_NAME_LEN);
+        if (ret < 0) {
+            ALOGE("getting socinfo(%s, %d) failed.\n", soc_node_path1, ret);
+            return ret;
+        }
+    }
+    if (ret && buf[ret - 1] == '\n')
+        buf[ret - 1] = '\0';
+
+    return ret;
+}
+
+/**
+ * @brief finds the cofiguration id value for the particular target.
+ *
+ * This function reads the target board platform detail and hardware
+ * platform detail from the target device and generate a generic
+ * config file name.If that config file is present then it will be
+ * used for configuring that target. If not then based on the target
+ * information a config file will be assigned.
+ *
+ * @param config_file The generic config file name will be stored.
+ * @return it returns the config id for the target.
+ */
+
+int CNfcConfig::getconfiguration_id (char * config_file)
+{
+    int config_id = QRD_TYPE_DEFAULT;
+    char target_type[MAX_SOC_INFO_NAME_LEN] = {'\0'};
+    char soc_info[MAX_SOC_INFO_NAME_LEN] = {'\0'};
+    char nq_chipid[PROPERTY_VALUE_MAX] = {0};
+    char nq_fw_ver[PROPERTY_VALUE_MAX] = {0};
+    bool nq2xx_present = false;
+    string strPath;
+    int rc = 0;
+    int idx = 0;
+
+    rc = get_soc_info(soc_info, SYSFS_SOCID_PATH1, SYSFS_SOCID_PATH2);
+    if (rc < 0) {
+        ALOGE("get_soc_info(SOC_ID) fail!\n");
+        return DEFAULT_CONFIG;
+    }
+    idx = atoi(soc_info);
+
+    rc = get_soc_info(target_type, SYSFS_HW_PLATFORM_PATH1, SYSFS_HW_PLATFORM_PATH2);
+    if (rc < 0) {
+        ALOGE("get_soc_info(HW_PLATFORM) fail!\n");
+        return DEFAULT_CONFIG;
+    }
+
+    rc = __system_property_get("sys.nfc.nq.chipid", nq_chipid);
+    if (rc <= 0)
+        ALOGE("get sys.nfc.nq.chipid fail, chipid_found = %d\n", rc);
+    else
+        ALOGD("sys.nfc.nq.chipid = %s\n", nq_chipid);
+
+    rc = __system_property_get("sys.nfc.nq.fwver", nq_fw_ver);
+    if (rc <= 0)
+        ALOGE("get sys.nfc.nq.fwver fail, fwver found = %d\n", rc);
+    else
+        ALOGD("sys.nfc.nq.fwver = %s\n", nq_fw_ver);
+
+    nq2xx_present = (!strncmp(nq_chipid, NQ220, PROPERTY_VALUE_MAX))
+                 || (!strncmp(nq_chipid, NQ210, PROPERTY_VALUE_MAX));
+
+    // Converting the HW_PLATFORM detail that is read from target to lowercase
+    for (int i=0;target_type[i];i++)
+        target_type[i] = tolower(target_type[i]);
+
+    // generating a generic config file name based on the target details
+    snprintf(config_file, MAX_DATA_CONFIG_PATH_LEN, "libnfc-%s_%s.conf",
+            soc_info, target_type);
+
+    findConfigFilePathFromTransportConfigPaths(config_file, strPath);
+    if (file_exist(strPath.c_str()))
+        idx = 0;
+
+    if (DEBUG)
+        ALOGI("id:%d, config_file_name:%s\n", idx, config_file);
+
+    // if target is QRD platform then config id is assigned here
+    if (0 == strncmp(target_type, QRD_HW_PLATFORM, MAX_SOC_INFO_NAME_LEN)) {
+        switch (idx)
+        {
+        case TARGET_GENERIC:
+            config_id = CONFIG_GENERIC;
+            break;
+        case TARGET_MSM8952:
+            config_id = QRD_TYPE_DEFAULT;
+            strlcpy(config_file, config_name_qrd, MAX_DATA_CONFIG_PATH_LEN);
+            break;
+        case TARGET_MSM8953:
+        case TARGET_MSM8937:
+        case TARGET_MSM8917:
+        case TARGET_MSM8940:
+        case TARGET_MSM8909:
+            if (nq2xx_present) {
+                // NQ210 or NQ220
+                config_id = QRD_TYPE_DEFAULT;
+                strlcpy(config_file, config_name_qrd, MAX_DATA_CONFIG_PATH_LEN);
+            } else {
+                config_id = QRD_TYPE_NQ3XX;
+                strlcpy(config_file, config_name_qrd_NQ3XX, MAX_DATA_CONFIG_PATH_LEN);
+            }
+            break;
+        case TARGET_MSM8976:
+        case TARGET_MSM8996:
+            strlcpy(config_file, config_name_qrd1, MAX_DATA_CONFIG_PATH_LEN);
+            config_id = QRD_TYPE_1;
+            break;
+        case TARGET_SDM845:
+            if (!strncmp(nq_fw_ver, FW_MAJOR_NUM_NQ4xx, FW_MAJOR_NUM_LENGTH)) {
+                config_id = QRD_TYPE_NQ4XX;
+                strlcpy(config_file, config_name_qrd_NQ4XX, MAX_DATA_CONFIG_PATH_LEN);
+            }
+            else {
+                config_id = QRD_TYPE_NQ3XX;
+                strlcpy(config_file, config_name_qrd_NQ3XX, MAX_DATA_CONFIG_PATH_LEN);
+            }
+            break;
+        case TARGET_SDM660:
+        case TARGET_SDM630:
+        case TARGET_MSM8998:
+        case TARGET_MSM8997:
+            if (nq2xx_present) {
+                // NQ210 or NQ220
+                config_id = QRD_TYPE_2;
+                strlcpy(config_file, config_name_qrd2, MAX_DATA_CONFIG_PATH_LEN);
+            } else {
+                config_id = QRD_TYPE_NQ3XX;
+                strlcpy(config_file, config_name_qrd_NQ3XX, MAX_DATA_CONFIG_PATH_LEN);
+            }
+            break;
+        default:
+            config_id = QRD_TYPE_DEFAULT;
+            strlcpy(config_file, config_name_qrd, MAX_DATA_CONFIG_PATH_LEN);
+            break;
+        }
+    }
+    // if target is MTP platform then config id is assigned here
+    else if (0 == strncmp(target_type, MTP_HW_PLATFORM, MAX_SOC_INFO_NAME_LEN)) {
+        switch (idx)
+        {
+        case TARGET_GENERIC:
+            config_id = CONFIG_GENERIC;
+            break;
+        case TARGET_MSM8953:
+        case TARGET_MSM8937:
+        case TARGET_MSM8917:
+        case TARGET_MSM8940:
+        case TARGET_MSM8909:
+            if (nq2xx_present) {
+                // NQ210 or NQ220
+                config_id = MTP_TYPE_DEFAULT;
+                strlcpy(config_file, config_name_mtp, MAX_DATA_CONFIG_PATH_LEN);
+            } else {
+                config_id = MTP_TYPE_NQ3XX;
+                strlcpy(config_file, config_name_mtp_NQ3XX, MAX_DATA_CONFIG_PATH_LEN);
+            }
+            break;
+        case TARGET_SDM845:
+            if (!strncmp(nq_fw_ver, FW_MAJOR_NUM_NQ4xx, FW_MAJOR_NUM_LENGTH)) {
+                config_id = MTP_TYPE_NQ4XX;
+                strlcpy(config_file, config_name_mtp_NQ4XX, MAX_DATA_CONFIG_PATH_LEN);
+            }
+            else {
+                config_id = MTP_TYPE_NQ3XX;
+                strlcpy(config_file, config_name_mtp_NQ3XX, MAX_DATA_CONFIG_PATH_LEN);
+            }
+            break;
+        case TARGET_SDM660:
+        case TARGET_SDM630:
+        case TARGET_MSM8998:
+        case TARGET_MSM8997:
+            if (nq2xx_present) {
+                // NQ210 or NQ220
+                config_id = MTP_TYPE_1;
+                strlcpy(config_file, config_name_mtp1, MAX_DATA_CONFIG_PATH_LEN);
+            } else {
+                config_id = MTP_TYPE_NQ3XX;
+                strlcpy(config_file, config_name_mtp_NQ3XX, MAX_DATA_CONFIG_PATH_LEN);
+            }
+            break;
+        default:
+            config_id = MTP_TYPE_DEFAULT;
+            strlcpy(config_file, config_name_mtp, MAX_DATA_CONFIG_PATH_LEN);
+            break;
+        }
+    }
+    if (DEBUG)
+        ALOGI("platform config id:%d, config_file_name:%s\n", config_id, config_file);
+
+    return config_id;
+}
+
+/*******************************************************************************
+**
+** Function:    isPrintable()
+**
+** 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:    findConfigFilePathFromTransportConfigPaths()
+**
+** Description: find a config file path with a given config name from transport
+**              config paths
+**
+** Returns:     none
+**
+*******************************************************************************/
+void findConfigFilePathFromTransportConfigPaths(const string& configName,
+                                                string& filePath) {
+  for (int i = 0; i < transport_config_path_size - 1; i++) {
+    filePath.assign(transport_config_paths[i]);
+    filePath += configName;
+    struct stat file_stat;
+    if (stat(filePath.c_str(), &file_stat) == 0 && S_ISREG(file_stat.st_mode)) {
+      return;
+    }
+  }
+  filePath.assign(transport_config_paths[transport_config_path_size - 1]);
+  filePath += configName;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::readConfig()
+**
+** Description: read Config settings and parse them into a linked list
+**              move the element from linked list to a array at the end
+**
+** Returns:     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;
+  mCurrentFile = name;
+
+  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;
+  }
+  ALOGD("%s Opened %s config %s\n", __func__,
+        (bResetContent ? "base" : "optional"), name);
+  stat(name, &buf);
+  if(mDynamConfig)
+        m_timeStamp = (unsigned long)buf.st_mtime;
+    else {
+        if(strcmp(default_nxp_config_path, name) == 0)
+            m_timeStamp = (unsigned long)buf.st_mtime;
+    }
+  if (strcmp(nxp_rf_config_path, name) == 0) {
+    m_timeStampRF = (unsigned long)buf.st_mtime;
+  }
+  if (strcmp(transit_config_path, name) == 0) {
+    m_timeStampTransit = (unsigned long)buf.st_mtime;
+  }
+  mValidFile = true;
+  if (size() > 0) {
+    if (bResetContent)
+      clean();
+    else
+      moveToList();
+  }
+
+  for (;;) {
+    if (feof(fd) || fread(&c, 1, 1, fd) != 1) {
+      if (state == BEGIN_LINE) break;
+
+      // got to the EOF but not in BEGIN_LINE state so the file
+      // probably does not end with a newline, so the parser has
+      // not processed current line, simulate a newline in the file
+      c = '\n';
+    }
+
+    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),
+      mDynamConfig(true),
+      m_timeStamp(0),
+      m_timeStampRF(0),
+      m_timeStampTransit(0),
+      state(0) {}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::~CNfcConfig()
+**
+** Description: class destructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcConfig::~CNfcConfig() {}
+
+/**
+ * @brief checks whether the given file exist.
+ *
+ * This function gets the file name and checks whether the given file
+ * exist in the particular path.Internaly it uses stat system call to
+ * find the existance.
+ *
+ * @param filename The name of the file whose existance has to be checked.
+ * @return it returns true if the given file name exist.
+ */
+int CNfcConfig::file_exist (const char* filename)
+{
+    struct stat   buffer;
+    return (stat (filename, &buffer) == 0);
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::GetInstance()
+**
+** Description: get class singleton object
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcConfig& CNfcConfig::GetInstance() {
+  static CNfcConfig theInstance;
+  int gconfigpathid=0;
+  char config_name_generic[MAX_DATA_CONFIG_PATH_LEN] = {'\0'};
+
+    if (theInstance.size() == 0 && theInstance.mValidFile)
+    {
+        string strPath;
+        if (alternative_config_path[0] != '\0')
+        {
+            strPath.assign(alternative_config_path);
+            strPath += config_name;
+            theInstance.readConfig(strPath.c_str(), true);
+            if (!theInstance.empty())
+            {
+                return theInstance;
+            }
+        }
+        findConfigFilePathFromTransportConfigPaths(config_name, strPath);
+        //checks whether the default config file is present in th target
+        if (theInstance.file_exist(strPath.c_str())) {
+            ALOGI("default config file exists = %s, disables dynamic selection", strPath.c_str());
+            theInstance.mDynamConfig = false;
+            theInstance.readConfig(strPath.c_str(), true);
+            /*
+             * if libnfc-nxp.conf exists then dynamic selection will
+             * be turned off by default we will not have this file.
+             */
+            return theInstance;
+        }
+
+        gconfigpathid = theInstance.getconfiguration_id(config_name_generic);
+        findConfigFilePathFromTransportConfigPaths(config_name_generic, strPath);
+        if (!(theInstance.file_exist(strPath.c_str()))) {
+            ALOGI("no matching file found, using default file for stability\n");
+            findConfigFilePathFromTransportConfigPaths(config_name_default, strPath);
+        }
+        ALOGI("config file used = %s\n",strPath.c_str());
+        theInstance.readConfig(strPath.c_str(), true);
+#if(NXP_EXTNS == TRUE)
+        readOptionalConfig("brcm");
+        theInstance.readNxpTransitConfig("nxpTransit");
+#endif
+    }
+    return theInstance;
+}
+
+/*******************************************************************************
+**
+** 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::readNxpTransitConfig()
+**
+** Description: read Config settings from transit conf file
+**
+** Returns:     none
+**
+*******************************************************************************/
+void CNfcConfig::readNxpTransitConfig(const char* fileName) const {
+  ALOGD("readNxpTransitConfig-Enter..Reading %s", fileName);
+  CNfcConfig::GetInstance().readConfig(fileName, false);
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::readNxpRFConfig()
+**
+** Description: read Config settings from RF conf file
+**
+** Returns:     none
+**
+*******************************************************************************/
+void CNfcConfig::readNxpRFConfig(const char* fileName) const {
+  ALOGD("readNxpRFConfig-Enter..Reading %s", fileName);
+  CNfcConfig::GetInstance().readConfig(fileName, false);
+}
+
+/*******************************************************************************
+**
+** 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;
+  }
+  if ((mCurrentFile.find("nxpTransit") != std::string::npos) &&
+      !isAllowed(pParam->c_str())) {
+    ALOGD("%s Token restricted. Returning", __func__);
+    return;
+  }
+  for (list<const CNfcParam*>::iterator it = m_list.begin(),
+                                        itEnd = m_list.end();
+       it != itEnd; ++it) {
+    if (**it < pParam->c_str()) continue;
+    if (**it == pParam->c_str())
+      m_list.insert(m_list.erase(it), pParam);
+    else
+      m_list.insert(it, pParam);
+
+    return;
+  }
+  m_list.push_back(pParam);
+}
+/*******************************************************************************
+**
+** Function:    CNfcConfig::dump()
+**
+** Description: prints all elements in the list
+**
+** Returns:     none
+**
+*******************************************************************************/
+void CNfcConfig::dump() {
+  ALOGD("%s Enter", __func__);
+
+  for (list<const CNfcParam*>::iterator it = m_list.begin(),
+                                        itEnd = m_list.end();
+       it != itEnd; ++it) {
+    if ((*it)->str_len() > 0)
+      ALOGD("%s %s \t= %s", __func__, (*it)->c_str(), (*it)->str_value());
+    else
+      ALOGD("%s %s \t= (0x%0lX)\n", __func__, (*it)->c_str(),
+            (*it)->numValue());
+  }
+}
+/*******************************************************************************
+**
+** Function:    CNfcConfig::isAllowed()
+**
+** Description: checks if token update is allowed
+**
+** Returns:     true if allowed else false
+**
+*******************************************************************************/
+bool CNfcConfig::isAllowed(const char* name) {
+  string token(name);
+  bool stat = false;
+  if ((token.find("P2P_LISTEN_TECH_MASK") != std::string::npos) ||
+      (token.find("HOST_LISTEN_TECH_MASK") != std::string::npos) ||
+      (token.find("UICC_LISTEN_TECH_MASK") != std::string::npos) ||
+      (token.find("NXP_ESE_LISTEN_TECH_MASK") != std::string::npos) ||
+      (token.find("POLLING_TECH_MASK") != std::string::npos) ||
+      (token.find("NXP_RF_CONF_BLK") != std::string::npos) ||
+      (token.find("NXP_CN_TRANSIT_BLK_NUM_CHECK_ENABLE") !=
+       std::string::npos) ||
+      (token.find("NXP_FWD_FUNCTIONALITY_ENABLE") != std::string::npos))
+
+  {
+    stat = true;
+  }
+  return stat;
+}
+/*******************************************************************************
+**
+** Function:    CNfcConfig::moveFromList()
+**
+** Description: move the setting object from list to array
+**
+** Returns:     none
+**
+*******************************************************************************/
+void CNfcConfig::moveFromList() {
+  if (m_list.size() == 0) return;
+
+  for (list<const CNfcParam*>::iterator it = m_list.begin(),
+                                        itEnd = m_list.end();
+       it != itEnd; ++it)
+    push_back(*it);
+  m_list.clear();
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::moveToList()
+**
+** Description: move the setting object from array to list
+**
+** Returns:     none
+**
+*******************************************************************************/
+void CNfcConfig::moveToList() {
+  if (m_list.size() != 0) m_list.clear();
+
+  for (iterator it = begin(), itEnd = end(); it != itEnd; ++it)
+    m_list.push_back(*it);
+  clear();
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::checkTimestamp(const char* fileName,const char*
+*fileNameTime)
+**
+** Description: check if config file has modified
+**
+** Returns:     0 if not modified, 1 otherwise.
+**
+*******************************************************************************/
+int CNfcConfig::checkTimestamp(const char* fileName, const char* fileNameTime) {
+  FILE* fd;
+  struct stat st;
+  unsigned long value = 0, timeStamp = 0;
+  int ret = 0;
+  if (strcmp(config_timestamp_path, fileNameTime) == 0) {
+    timeStamp = m_timeStamp;
+  } else if (strcmp(rf_config_timestamp_path, fileNameTime) == 0) {
+    timeStamp = m_timeStampRF;
+  } else if (strcmp(tr_config_timestamp_path, fileNameTime) == 0) {
+    timeStamp = m_timeStampTransit;
+  } else
+    ALOGD("Invalid file \n");
+
+  if (stat(fileNameTime, &st) != 0) {
+    ALOGD("%s file not exist.\n", __func__);
+    if ((fd = fopen(fileNameTime, "w+")) != NULL) {
+      fwrite(&timeStamp, sizeof(unsigned long), 1, fd);
+      fclose(fd);
+    }
+    return 1;
+  } else {
+    fd = fopen(fileNameTime, "r+");
+    if (fd == NULL) {
+      ALOGE("%s Cannot open file %s\n", __func__, fileNameTime);
+      return 1;
+    }
+    fread(&value, sizeof(unsigned long), 1, fd);
+    ret = (value != timeStamp) ? 1 : 0;
+    if (ret) {
+      ALOGD("Config File Modified Update timestamp");
+      fseek(fd, 0, SEEK_SET);
+      fwrite(&timeStamp, sizeof(unsigned long), 1, fd);
+    }
+    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);
+    fd = fopen(config_timestamp_path, "w+");
+    if (fd != 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:    readOptionalConfig()
+**
+** Description: read Config settings from an optional conf file
+**
+** Returns:     none
+**
+*******************************************************************************/
+void readOptionalConfig(const char* extra) {
+  string strPath;
+  string configName(extra_config_base);
+  configName += extra;
+  configName += extra_config_ext;
+
+  if (alternative_config_path[0] != '\0') {
+    strPath.assign(alternative_config_path);
+    strPath += configName;
+  } else {
+    findConfigFilePathFromTransportConfigPaths(configName, strPath);
+  }
+
+  CNfcConfig::GetInstance().readConfig(strPath.c_str(), false);
+}
+
+}  // namespace nxp
+/*******************************************************************************
+**
+** 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) {
+  nxp::CNfcConfig& rConfig = nxp::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) {
+  nxp::CNfcConfig& rConfig = nxp::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;
+
+  nxp::CNfcConfig& rConfig = nxp::CNfcConfig::GetInstance();
+  const nxp::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()
+
+{
+  nxp::CNfcConfig& rConfig = nxp::CNfcConfig::GetInstance();
+
+  rConfig.clean();
+}
+
+/*******************************************************************************
+**
+** Function:    isNxpConfigModified()
+**
+** Description: check if config file has modified
+**
+** Returns:     0 if not modified, 1 otherwise.
+**
+*******************************************************************************/
+extern "C" int isNxpConfigModified() {
+  nxp::CNfcConfig& rConfig = nxp::CNfcConfig::GetInstance();
+  return rConfig.checkTimestamp(default_nxp_config_path, config_timestamp_path);
+}
+/*******************************************************************************
+**
+** Function:    isNxpRFConfigModified()
+**
+** Description: check if config file has modified
+**
+** Returns:     0 if not modified, 1 otherwise.
+**
+*******************************************************************************/
+extern "C" int isNxpRFConfigModified() {
+  int retRF = 0, rettransit = 0, ret = 0;
+  nxp::CNfcConfig& rConfig = nxp::CNfcConfig::GetInstance();
+  retRF = rConfig.checkTimestamp(nxp_rf_config_path, rf_config_timestamp_path);
+  rettransit =
+      rConfig.checkTimestamp(transit_config_path, tr_config_timestamp_path);
+  ret = retRF | rettransit;
+  ALOGD("ret RF or Transit value %d", ret);
+  return ret;
+}
+
+/*******************************************************************************
+**
+** Function:    updateNxpConfigTimestamp()
+**
+** Description: update if config file has modified
+**
+** Returns:     0 if not modified, 1 otherwise.
+**
+*******************************************************************************/
+extern "C" int updateNxpConfigTimestamp() {
+  nxp::CNfcConfig& rConfig = nxp::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..63eba34
--- /dev/null
+++ b/halimpl/pn54x/utils/phNxpConfig.h
@@ -0,0 +1,187 @@
+/******************************************************************************
+ *
+ *  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) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#ifndef __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 isNxpRFConfigModified();
+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_NFC_DEV_NODE "NXP_NFC_DEV_NODE"
+#define NAME_NXP_NFC_CHIP "NXP_NFC_CHIP"
+#define NAME_NXP_FW_NAME "NXP_FW_NAME"
+#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_CHINA_BLK_NUM_CHK_ENABLE "NXP_CN_TRANSIT_BLK_NUM_CHECK_ENABLE"
+#define NAME_NXP_CN_TRANSIT_CMA_BYPASSMODE_ENABLE  "NXP_CN_TRANSIT_CMA_BYPASSMODE_ENABLE"
+#define NAME_NXP_ESE_POWER_DH_CONTROL "NXP_ESE_POWER_DH_CONTROL"
+#define NAME_NXP_ESE_POWER_EXT_PMU "NXP_ESE_POWER_EXT_PMU"
+#define NAME_NXP_ESE_POWER_DH_CONTROL_CFG_1 "NXP_ESE_POWER_DH_CONTROL_CFG_1"
+#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"
+#define NAME_NXP_TYPEA_UICC_BAUD_RATE "NXP_TYPEA_UICC_BAUD_RATE"
+#define NAME_NXP_TYPEB_UICC_BAUD_RATE "NXP_TYPEB_UICC_BAUD_RATE"
+#define NAME_NXP_SET_CONFIG_ALWAYS "NXP_SET_CONFIG_ALWAYS"
+#define NAME_NXP_PROP_BLACKLIST_ROUTING "NXP_PROP_BLACKLIST_ROUTING"
+#define NAME_NXP_WIREDMODE_RESUME_TIMEOUT "NXP_WIREDMODE_RESUME_TIMEOUT"
+#define NAME_NXP_UICC_LISTEN_TECH_MASK "UICC_LISTEN_TECH_MASK"
+#define NAME_NXP_HOST_LISTEN_TECH_MASK "HOST_LISTEN_TECH_MASK"
+#define NAME_NXP_ESE_LISTEN_TECH_MASK "NXP_ESE_LISTEN_TECH_MASK"
+#define NAME_NXP_SVDD_SYNC_OFF_DELAY "NXP_SVDD_SYNC_OFF_DELAY"
+#define NAME_NXP_CORE_PROP_SYSTEM_DEBUG "NXP_CORE_PROP_SYSTEM_DEBUG"
+#define NAME_NXP_NCI_PARSER_LIBRARY "NXP_NCI_PARSER_LIBRARY"
+/**
+ *  @brief defines the different config files used.
+ */
+
+#define config_name_mtp         "libnfc-mtp_default.conf"
+#define config_name_mtp1        "libnfc-mtp_rf1.conf"
+#define config_name_mtp2        "libnfc-mtp_rf2.conf"
+#define config_name_mtp_NQ3XX   "libnfc-mtp-NQ3XX.conf"
+#define config_name_mtp_NQ4XX   "libnfc-mtp-NQ4XX.conf"
+#define config_name_qrd         "libnfc-qrd_default.conf"
+#define config_name_qrd1        "libnfc-qrd_rf1.conf"
+#define config_name_qrd2        "libnfc-qrd_rf2.conf"
+#define config_name_qrd_NQ3XX   "libnfc-qrd-NQ3XX.conf"
+#define config_name_qrd_NQ4XX   "libnfc-qrd-NQ4XX.conf"
+#define config_name_default     "libnfc-nxp_default.conf"
+
+/**
+ *  @brief defines the different major number used.
+ */
+#define FW_MAJOR_NUM_NQ2xx      "10"
+#define FW_MAJOR_NUM_NQ3xx      "11"
+#define FW_MAJOR_NUM_NQ4xx      "12"
+
+#define FW_MAJOR_NUM_LENGTH     2
+
+/**
+ *  @brief defines the maximum length of the target name.
+ */
+
+#define MAX_SOC_INFO_NAME_LEN (15)
+
+/**
+ *  @brief Defines the type of hardware platform.
+ */
+
+#define QRD_HW_PLATFORM  "qrd"
+#define MTP_HW_PLATFORM  "mtp"
+
+/**
+ *  @brief Defines the path where the hardware platform details are present.
+ */
+
+#define SYSFS_HW_PLATFORM_PATH1  "/sys/devices/soc0/hw_platform"
+#define SYSFS_HW_PLATFORM_PATH2   "/sys/devices/system/soc/soc0/hw_platform"
+
+/**
+ *  @brief Defines the path where the soc_id details are present.
+ */
+
+#define SYSFS_SOCID_PATH1    "/sys/devices/soc0/soc_id"
+#define SYSFS_SOCID_PATH2    "/sys/devices/system/soc/soc0/id"
+
+/**
+ *  @brief Defines the maximum length of the config file name.
+ */
+
+#define MAX_DATA_CONFIG_PATH_LEN 64
+
+/**
+ *  @brief Defines the NQ chip type.
+ */
+
+#define NQ210 "0x48"
+#define NQ220 "0x58"
+
+/**
+ *  @brief Defines whether debugging is enabled or disabled.
+ */
+
+#define DEBUG 0
+
+/* default configuration */
+#define default_storage_location "/data/vendor/nfc"
+
+#endif
diff --git a/halimpl/pn54x/utils/phNxpNciHal_utils.c b/halimpl/pn54x/utils/phNxpNciHal_utils.c
new file mode 100644
index 0000000..3b9fcfd
--- /dev/null
+++ b/halimpl/pn54x/utils/phNxpNciHal_utils.c
@@ -0,0 +1,475 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#include <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()", __func__);
+  //    abort();
+}
diff --git a/halimpl/pn54x/utils/phNxpNciHal_utils.h b/halimpl/pn54x/utils/phNxpNciHal_utils.h
new file mode 100644
index 0000000..b1a5bfc
--- /dev/null
+++ b/halimpl/pn54x/utils/phNxpNciHal_utils.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#ifndef _PHNXPNCIHAL_UTILS_H_
+#define _PHNXPNCIHAL_UTILS_H_
+
+#include <pthread.h>
+#include <semaphore.h>
+#include <phNfcStatus.h>
+#include <assert.h>
+#include <errno.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)) == 0) ? 0 : (errno == EINTR)                 \
+                                               ? sem_wait(&((cb_data).sem)) \
+                                               : -1)
+
+#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_ */
diff --git a/p61-jcop-kit/Android.mk b/p61-jcop-kit/Android.mk
new file mode 100644
index 0000000..a2a328d
--- /dev/null
+++ b/p61-jcop-kit/Android.mk
@@ -0,0 +1,30 @@
+# function to find all *.cpp files under a directory
+define all-cpp-files-under
+$(patsubst ./%,%, \
+  $(shell cd $(LOCAL_PATH) ; \
+          find $(1) -name "*.cpp" -and -not -name ".*") \
+ )
+endef
+
+
+LOCAL_PATH:= $(call my-dir)
+D_CFLAGS += -DNXP_LDR_SVC_VER_2=TRUE
+######################################
+# Build shared library system/vendor/lib/libp61-jcop-kit.so for stack code.
+
+include $(CLEAR_VARS)
+LOCAL_PRELINK_MODULE := false
+LOCAL_ARM_MODE := arm
+LOCAL_MODULE := libnqp61-jcop-kit
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_OWNER := nxp
+LOCAL_SHARED_LIBRARIES := libhardware_legacy libcutils liblog libdl libhardware
+LOCAL_CFLAGS := $(D_CFLAGS)
+LOCAL_C_INCLUDES := \
+    $(LOCAL_PATH)/include/ \
+    $(LOCAL_PATH)/inc/
+LOCAL_SRC_FILES := \
+    $(call all-c-files-under, src) \
+    $(call all-cpp-files-under, src)
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/p61-jcop-kit/README.md b/p61-jcop-kit/README.md
new file mode 100644
index 0000000..01eeb1c
--- /dev/null
+++ b/p61-jcop-kit/README.md
@@ -0,0 +1,30 @@
+# NXPNFC_P61_JCOP_Kit
+
+####Git Repository
+
+| DESCRIPTION        | CHECKOUT COMMAND          |
+| :-------------: |:-------------:| 
+| NXPNFC_P61_JCOP_Kit    |  git clone https://github.com/NXPNFCProject/NXPNFC_P61_JCOP_Kit.git |
+
+####Supported Android Versions
+
+| Android Version        | NXP Release          | NXP Tag  |
+| :-------------: |:-------------:| :-----:|
+| android-6.0.0_r1                     |  3.1.0_M (PN547C2/PN548C2) |  SEAccessKit_AR3.1.0_OpnSrc |
+| android-6.0.0_r1                     |  3.2.0_M (PN547C2/PN548C2) |  SEAccessKit_AR3.2.0_OpnSrc |
+| android-6.0.1_r17                    |  3.3.0_M (PN551/PN548C2)   |  SEAccessKit_AR3.3.0_OpnSrc |
+| android-6.0.1_r17                    |  3.5.0_M (PN553)   |  SEAccessKit_AR3.5.0_OpnSrc |
+| android-7.0.0_r4                     |  3.5.2 (PN553)   |  SEAccessKit_AR3.5.2_OpnSrc |
+| android-6.0.1_r17                    |  3.6.0_M (PN551/PN548C2)   |  SEAccessKit_AR3.6.0_OpnSrc |
+| android-7.0.0_r12                     |  7.0.3_N (PN548C2/PN551/PN553) |  SEAccessKit_AR7.0.3_OpnSrc |
+| android-7.0.0_r12                     |  7.1.0_N (PN553) |  SEAccessKit_AR7.1.0_OpnSrc |
+| android-7.0.0_r12                     |  7.2.0_N (PN553) |  SEAccessKit_AR7.2.0_OpnSrc |
+| android-7.1.1_r1                     |  7.3.0_N (PN548C2/PN551) |  SEAccessKit_AR7.3.0_OpnSrc |
+| android-7.1.1_r1                     |  7.4.0_N (PN553) |  SEAccessKit_AR7.4.0_OpnSrc |
+| android-o-preview2                     |  8.0.9_O (PN553/PN557) |  SEAccessKit_AR8.0.9_OpnSrc |
+| android-o-preview2                     |  8.0.C_O (PN553/PN557) |  SEAccessKit_AR8.0.C_OpnSrc |
+| android-o-preview2                     |  8.0.13_O (PN553/PN557) |  SEAccessKit_AR8.0.13_OpnSrc |
+| android-8.0.0_r4               |  8.1.0_O (PN553) |  SEAccessKit_AR8.1.0_OpnSrc |
+| android-8.0.0_r4               |  8.2.0_O (PN557) |  SEAccessKit_AR8.2.0_OpnSrc |
+| android-8.0.0_r4               |  8.2.3_O (PN557) |  SEAccessKit_AR8.2.3_OpnSrc |
+| android-8.0.0_r4               |  8.3.0_O (PN548C2/PN551/PN553) |  SEAccessKit_AR8.3.0_OpnSrc |
diff --git a/inc/Ala.h b/p61-jcop-kit/inc/Ala.h
similarity index 100%
rename from inc/Ala.h
rename to p61-jcop-kit/inc/Ala.h
diff --git a/inc/JcopOsDownload.h b/p61-jcop-kit/inc/JcopOsDownload.h
similarity index 100%
rename from inc/JcopOsDownload.h
rename to p61-jcop-kit/inc/JcopOsDownload.h
diff --git a/inc/data_types.h b/p61-jcop-kit/inc/data_types.h
similarity index 100%
rename from inc/data_types.h
rename to p61-jcop-kit/inc/data_types.h
diff --git a/include/AlaLib.h b/p61-jcop-kit/include/AlaLib.h
similarity index 100%
rename from include/AlaLib.h
rename to p61-jcop-kit/include/AlaLib.h
diff --git a/include/IChannel.h b/p61-jcop-kit/include/IChannel.h
similarity index 100%
rename from include/IChannel.h
rename to p61-jcop-kit/include/IChannel.h
diff --git a/include/JcDnld.h b/p61-jcop-kit/include/JcDnld.h
similarity index 100%
rename from include/JcDnld.h
rename to p61-jcop-kit/include/JcDnld.h
diff --git a/src/Ala.cpp b/p61-jcop-kit/src/Ala.cpp
similarity index 99%
rename from src/Ala.cpp
rename to p61-jcop-kit/src/Ala.cpp
index 501b9dd..6790411 100644
--- a/src/Ala.cpp
+++ b/p61-jcop-kit/src/Ala.cpp
@@ -1,4 +1,7 @@
  /*
+  * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+  * Not a Contribution.
+  *
   * Copyright (C) 2015 NXP Semiconductors
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
@@ -473,7 +476,7 @@
 #if(NXP_LDR_SVC_VER_2 == TRUE)
     if(dest != NULL)
     {
-        strcat(update_info.fls_RespPath, dest);
+        strlcat(update_info.fls_RespPath, dest, sizeof(update_info.fls_RespPath));
         ALOGD("Loader Service response data path/destination: %s", dest);
         update_info.bytes_wrote = 0xAA;
     }
@@ -486,8 +489,7 @@
         return false;
     }
 #endif
-    //memcpy(update_info.fls_path, (char*)Ala_path, sizeof(Ala_path));
-    strcat(update_info.fls_path, name);
+    strlcat(update_info.fls_path, name, sizeof(update_info.fls_path));
     ALOGD("Selected applet to install is: %s", update_info.fls_path);
 
     while((seq_handler[seq_counter]) != NULL )
@@ -524,7 +526,6 @@
     bool stat = false;
     int32_t recvBufferActualSize = 0;
     IChannel_t *mchannel = gpAla_Dwnld_Context->mchannel;
-    Os_info->channel_cnt = 0x00;
     ALOGD("%s: enter", fn);
     if(Os_info == NULL ||
        pTranscv_Info == NULL)
@@ -533,6 +534,7 @@
     }
     else
     {
+        Os_info->channel_cnt = 0x00;
         pTranscv_Info->timeout = gTransceiveTimeout;
         pTranscv_Info->sSendlength = (int32_t)sizeof(OpenChannel);
         pTranscv_Info->sRecvlength = 1024;//(int32_t)sizeof(int32_t);
@@ -790,6 +792,14 @@
     uint8_t temp_buf[1024];
     uint8_t len_byte=0, offset =0;
     IChannel_t *mchannel = gpAla_Dwnld_Context->mchannel;
+
+    ALOGD("%s: enter", fn);
+    if(Os_info == NULL ||
+       pTranscv_Info == NULL)
+    {
+        ALOGE("%s: invalid parameter", fn);
+        return status;
+    }
     Os_info->bytes_read = 0;
 #if(NXP_LDR_SVC_VER_2 == TRUE)
     bool    reachEOFCheck = false;
@@ -810,13 +820,6 @@
         ALOGD("%s: Response Out file is optional as per input", fn);
     }
 #endif
-    ALOGD("%s: enter", fn);
-    if(Os_info == NULL ||
-       pTranscv_Info == NULL)
-    {
-        ALOGE("%s: invalid parameter", fn);
-        return status;
-    }
     Os_info->fp = fopen(Os_info->fls_path, "r");
 
     if (Os_info->fp == NULL) {
diff --git a/src/AlaLib.cpp b/p61-jcop-kit/src/AlaLib.cpp
similarity index 100%
rename from src/AlaLib.cpp
rename to p61-jcop-kit/src/AlaLib.cpp
diff --git a/src/JcDnld.cpp b/p61-jcop-kit/src/JcDnld.cpp
similarity index 100%
rename from src/JcDnld.cpp
rename to p61-jcop-kit/src/JcDnld.cpp
diff --git a/src/JcopOsDownload.cpp b/p61-jcop-kit/src/JcopOsDownload.cpp
similarity index 98%
rename from src/JcopOsDownload.cpp
rename to p61-jcop-kit/src/JcopOsDownload.cpp
index a0e3c52..645c22b 100644
--- a/src/JcopOsDownload.cpp
+++ b/p61-jcop-kit/src/JcopOsDownload.cpp
@@ -1,4 +1,7 @@
  /*
+  * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+  * Not a Contribution.
+  *
   * Copyright (C) 2015 NXP Semiconductors
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
@@ -383,7 +386,7 @@
 #endif
             {
                 ALOGE("Starting 3-Step update");
-                memcpy(pImageInfo->fls_path, path[pImageInfo->index], sizeof(path[pImageInfo->index]));
+                memcpy(pImageInfo->fls_path, path[pImageInfo->index], strlen(path[pImageInfo->index]));
                 pImageInfo->index++;
             }
             status = STATUS_OK;
diff --git a/src/adaptation/CrcChecksum.cpp b/src/adaptation/CrcChecksum.cpp
new file mode 100644
index 0000000..774d1d6
--- /dev/null
+++ b/src/adaptation/CrcChecksum.cpp
@@ -0,0 +1,140 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#include "_OverrideLog.h"
+#include "CrcChecksum.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string>
+
+#undef LOG_TAG
+#define LOG_TAG "NfcNciHal"
+
+static const unsigned short crctab[256] = {
+    0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, 0xc601,
+    0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, 0xcc01, 0x0cc0,
+    0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, 0x0a00, 0xcac1, 0xcb81,
+    0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, 0xd801, 0x18c0, 0x1980, 0xd941,
+    0x1b00, 0xdbc1, 0xda81, 0x1a40, 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01,
+    0x1dc0, 0x1c80, 0xdc41, 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0,
+    0x1680, 0xd641, 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081,
+    0x1040, 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
+    0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, 0x3c00,
+    0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, 0xfa01, 0x3ac0,
+    0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, 0x2800, 0xe8c1, 0xe981,
+    0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, 0xee01, 0x2ec0, 0x2f80, 0xef41,
+    0x2d00, 0xedc1, 0xec81, 0x2c40, 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700,
+    0xe7c1, 0xe681, 0x2640, 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0,
+    0x2080, 0xe041, 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281,
+    0x6240, 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
+    0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, 0xaa01,
+    0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, 0x7800, 0xb8c1,
+    0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, 0xbe01, 0x7ec0, 0x7f80,
+    0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, 0xb401, 0x74c0, 0x7580, 0xb541,
+    0x7700, 0xb7c1, 0xb681, 0x7640, 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101,
+    0x71c0, 0x7080, 0xb041, 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0,
+    0x5280, 0x9241, 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481,
+    0x5440, 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
+    0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, 0x8801,
+    0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, 0x4e00, 0x8ec1,
+    0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, 0x4400, 0x84c1, 0x8581,
+    0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, 0x8201, 0x42c0, 0x4380, 0x8341,
+    0x4100, 0x81c1, 0x8081, 0x4040,
+};
+
+/*******************************************************************************
+**
+** Function         crcChecksumCompute
+**
+** Description      Compute a checksum on a buffer of data.
+**
+** Returns          2-byte checksum.
+**
+*******************************************************************************/
+unsigned short crcChecksumCompute(const unsigned char* buffer, int bufferLen) {
+  register unsigned short crc = 0;
+  const register unsigned char* cp = buffer;
+  register int cnt = bufferLen;
+
+  while (cnt--) {
+    crc = ((crc >> 8) & 0xff) ^ crctab[(crc & 0xff) ^ *cp++];
+  }
+  return (crc);
+}
+
+/*******************************************************************************
+**
+** Function         crcChecksumVerifyIntegrity
+**
+** Description      Detect any corruption in a file by computing a checksum.
+**                  filename: file name.
+**
+** Returns          True if file is good.
+**
+*******************************************************************************/
+bool crcChecksumVerifyIntegrity(const char* filename) {
+  ALOGD("%s: filename=%s", __func__, filename);
+  bool isGood = false;
+  int fileStream = open(filename, O_RDONLY);
+  if (fileStream >= 0) {
+    unsigned short checksum = 0;
+    std::string data;
+    size_t actualReadCrc = read(fileStream, &checksum, sizeof(checksum));
+    while (true) {
+      char buffer[1024];
+      ssize_t actualReadData = read(fileStream, buffer, sizeof(buffer));
+      if (actualReadData > 0)
+        data.append(buffer, actualReadData);
+      else
+        break;
+    }
+    close(fileStream);
+    if ((actualReadCrc == sizeof(checksum)) && (data.size() > 0)) {
+      ALOGD("%s: data size=%zu", __func__, data.size());
+      if (checksum ==
+          crcChecksumCompute((const unsigned char*)data.data(), data.size()))
+        isGood = true;
+      else
+        ALOGE("%s: checksum mismatch", __func__);
+    } else
+      ALOGE("%s: invalid length", __func__);
+  } else
+    isGood = true;  // assume file does not exist
+  return isGood;
+}
diff --git a/src/adaptation/NfcAdaptation.cpp b/src/adaptation/NfcAdaptation.cpp
new file mode 100644
index 0000000..273684d
--- /dev/null
+++ b/src/adaptation/NfcAdaptation.cpp
@@ -0,0 +1,1042 @@
+/******************************************************************************
+ *
+ *  Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "_OverrideLog.h"
+
+#include <android/hardware/nfc/1.0/INfc.h>
+#include <vendor/nxp/hardware/nfc/1.0/INqNfc.h>
+#include <android/hardware/nfc/1.0/INfcClientCallback.h>
+#include <android/hardware/nfc/1.0/types.h>
+#include <hwbinder/ProcessState.h>
+#include <pthread.h>
+#include "NfcAdaptation.h"
+extern "C"
+{
+    #include "gki.h"
+    #include "nfa_api.h"
+    #include "nfc_int.h"
+    #include "nfc_target.h"
+    #include "vendor_cfg.h"
+}
+#include "config.h"
+#include "android_logmsg.h"
+
+#undef LOG_TAG
+#define LOG_TAG "NfcAdaptation"
+
+using android::OK;
+using android::sp;
+using android::status_t;
+
+using android::hardware::ProcessState;
+using android::hardware::Return;
+using android::hardware::Void;
+using android::hardware::nfc::V1_0::INfc;
+using vendor::nxp::hardware::nfc::V1_0::INqNfc;
+using android::hardware::nfc::V1_0::INfcClientCallback;
+using android::hardware::hidl_vec;
+
+extern "C" void GKI_shutdown();
+extern void resetConfig();
+extern "C" void verify_stack_non_volatile_store();
+extern "C" void delete_stack_non_volatile_store(bool forceDelete);
+
+NfcAdaptation* NfcAdaptation::mpInstance = NULL;
+ThreadMutex NfcAdaptation::sLock;
+ThreadMutex NfcAdaptation::sIoctlLock;
+sp<INfc> NfcAdaptation::mHal;
+sp<INqNfc> NfcAdaptation::mNqHal;
+INfcClientCallback* NfcAdaptation::mCallback;
+nfc_nci_device_t* NfcAdaptation::mHalDeviceContext = NULL;
+tHAL_NFC_CBACK* NfcAdaptation::mHalCallback = NULL;
+tHAL_NFC_DATA_CBACK* NfcAdaptation::mHalDataCallback = NULL;
+ThreadCondVar NfcAdaptation::mHalOpenCompletedEvent;
+ThreadCondVar NfcAdaptation::mHalCloseCompletedEvent;
+ThreadCondVar NfcAdaptation::mHalIoctlEvent;
+#if (NXP_EXTNS == TRUE)
+ThreadCondVar NfcAdaptation::mHalCoreResetCompletedEvent;
+ThreadCondVar NfcAdaptation::mHalCoreInitCompletedEvent;
+ThreadCondVar NfcAdaptation::mHalInitCompletedEvent;
+#define SIGNAL_NONE 0
+#define SIGNAL_SIGNALED 1
+static uint8_t isSignaled = SIGNAL_NONE;
+static uint8_t evt_status;
+#endif
+
+uint32_t ScrProtocolTraceFlag = SCR_PROTO_TRACE_ALL;  // 0x017F00;
+uint8_t appl_trace_level = 0xff;
+#if (NXP_EXTNS == TRUE)
+uint8_t appl_dta_mode_flag = 0x00;
+#endif
+char bcm_nfc_location[120];
+
+static uint8_t nfa_dm_cfg[sizeof(tNFA_DM_CFG)];
+static uint8_t nfa_proprietary_cfg[sizeof(tNFA_PROPRIETARY_CFG)];
+extern tNFA_DM_CFG* p_nfa_dm_cfg;
+extern tNFA_PROPRIETARY_CFG* p_nfa_proprietary_cfg;
+extern uint8_t nfa_ee_max_ee_cfg;
+extern const uint8_t nfca_version_string[];
+extern const uint8_t nfa_version_string[];
+static uint8_t deviceHostWhiteList[NFA_HCI_MAX_HOST_IN_NETWORK];
+static tNFA_HCI_CFG jni_nfa_hci_cfg;
+extern tNFA_HCI_CFG* p_nfa_hci_cfg;
+extern bool nfa_poll_bail_out_mode;
+
+class NfcClientCallback : public INfcClientCallback {
+ public:
+  NfcClientCallback(tHAL_NFC_CBACK* eventCallback,
+                    tHAL_NFC_DATA_CBACK dataCallback) {
+    mEventCallback = eventCallback;
+    mDataCallback = dataCallback;
+  };
+  virtual ~NfcClientCallback() = default;
+  Return<void> sendEvent(
+      ::android::hardware::nfc::V1_0::NfcEvent event,
+      ::android::hardware::nfc::V1_0::NfcStatus event_status) override {
+    mEventCallback((uint8_t)event, (tHAL_NFC_STATUS)event_status);
+    return Void();
+  };
+  Return<void> sendData(
+      const ::android::hardware::nfc::V1_0::NfcData& data) override {
+    ::android::hardware::nfc::V1_0::NfcData copy = data;
+    mDataCallback(copy.size(), &copy[0]);
+    return Void();
+  };
+
+ private:
+  tHAL_NFC_CBACK* mEventCallback;
+  tHAL_NFC_DATA_CBACK* mDataCallback;
+};
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::NfcAdaptation()
+**
+** Description: class constructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+NfcAdaptation::NfcAdaptation() {
+  memset(&mHalEntryFuncs, 0, sizeof(mHalEntryFuncs));
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::~NfcAdaptation()
+**
+** Description: class destructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+NfcAdaptation::~NfcAdaptation() { mpInstance = NULL; }
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::GetInstance()
+**
+** Description: access class singleton
+**
+** Returns:     pointer to the singleton object
+**
+*******************************************************************************/
+NfcAdaptation& NfcAdaptation::GetInstance() {
+  AutoThreadMutex a(sLock);
+
+  if (!mpInstance) mpInstance = new NfcAdaptation;
+  return *mpInstance;
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::Initialize()
+**
+** Description: class initializer
+**
+** Returns:     none
+**
+*******************************************************************************/
+void NfcAdaptation::Initialize() {
+  const char* func = "NfcAdaptation::Initialize";
+  ALOGD("%s: enter", func);
+  ALOGE("%s: ver=%s nfa=%s", func, nfca_version_string, nfa_version_string);
+  unsigned long num;
+
+  if (GetNumValue(NAME_USE_RAW_NCI_TRACE, &num, sizeof(num))) {
+    if (num == 1) {
+      // display protocol traces in raw format
+      ProtoDispAdapterUseRawOutput(true);
+      ALOGD("%s: logging protocol in raw format", func);
+    }
+  }
+  if (!GetStrValue(NAME_NFA_STORAGE, bcm_nfc_location,
+                   sizeof(bcm_nfc_location))) {
+    strlcpy(bcm_nfc_location, "/data/nfc", sizeof(bcm_nfc_location));
+  }
+
+  initializeProtocolLogLevel();
+
+  if (GetStrValue(NAME_NFA_DM_CFG, (char*)nfa_dm_cfg, sizeof(nfa_dm_cfg)))
+    p_nfa_dm_cfg = (tNFA_DM_CFG*)((void*)&nfa_dm_cfg[0]);
+
+  nfa_ee_max_ee_cfg = NFA_EE_MAX_EE_SUPPORTED;
+  ALOGD("%s: NFA_EE_MAX_EE_SUPPORTED to use %d", func, nfa_ee_max_ee_cfg);
+
+  if (GetNumValue(NAME_NFA_POLL_BAIL_OUT_MODE, &num, sizeof(num))) {
+    nfa_poll_bail_out_mode = num;
+    ALOGD("%s: Overriding NFA_POLL_BAIL_OUT_MODE to use %d", func,
+          nfa_poll_bail_out_mode);
+  }
+
+  if (GetStrValue(NAME_NFA_PROPRIETARY_CFG, (char*)nfa_proprietary_cfg,
+                  sizeof(tNFA_PROPRIETARY_CFG))) {
+    p_nfa_proprietary_cfg =
+        (tNFA_PROPRIETARY_CFG*)(void*)(&nfa_proprietary_cfg[0]);
+  }
+  // configure device host whitelist of HCI host ID's; see specification ETSI TS
+  // 102 622 V11.1.10
+  //(2012-10), section 6.1.3.1
+  num = GetStrValue(NAME_DEVICE_HOST_WHITE_LIST, (char*)deviceHostWhiteList,
+                    sizeof(deviceHostWhiteList));
+  if (num) {
+    memmove(&jni_nfa_hci_cfg, p_nfa_hci_cfg, sizeof(jni_nfa_hci_cfg));
+    jni_nfa_hci_cfg.num_whitelist_host =
+        (uint8_t)num;  // number of HCI host ID's in the whitelist
+    jni_nfa_hci_cfg.p_whitelist = deviceHostWhiteList;  // array of HCI host
+                                                        // ID's
+    p_nfa_hci_cfg = &jni_nfa_hci_cfg;
+  }
+
+  initializeGlobalAppLogLevel();
+
+  verify_stack_non_volatile_store();
+  if (GetNumValue(NAME_PRESERVE_STORAGE, (char*)&num, sizeof(num)) &&
+      (num == 1))
+    ALOGD("%s: preserve stack NV store", __func__);
+  else {
+    delete_stack_non_volatile_store(false);
+  }
+
+  GKI_init();
+  GKI_enable();
+  GKI_create_task((TASKPTR)NFCA_TASK, BTU_TASK, (int8_t*)"NFCA_TASK", 0, 0,
+                  (pthread_cond_t*)NULL, NULL);
+  {
+    AutoThreadMutex guard(mCondVar);
+    GKI_create_task((TASKPTR)Thread, MMI_TASK, (int8_t*)"NFCA_THREAD", 0, 0,
+                    (pthread_cond_t*)NULL, NULL);
+    mCondVar.wait();
+  }
+
+  mHalCallback = NULL;
+  memset(&mHalEntryFuncs, 0, sizeof(mHalEntryFuncs));
+  InitializeHalDeviceContext();
+  ALOGD("%s: exit", func);
+}
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::MinInitialize()
+**
+** Description: class initializer
+**
+** Returns:     none
+**
+*******************************************************************************/
+void NfcAdaptation::MinInitialize() {
+  const char* func = "NfcAdaptation::MinInitialize";
+  ALOGD("%s: enter", func);
+  GKI_init();
+  GKI_enable();
+  GKI_create_task((TASKPTR)NFCA_TASK, BTU_TASK, (int8_t*)"NFCA_TASK", 0, 0,
+                  (pthread_cond_t*)NULL, NULL);
+  {
+    AutoThreadMutex guard(mCondVar);
+    GKI_create_task((TASKPTR)Thread, MMI_TASK, (int8_t*)"NFCA_THREAD", 0, 0,
+                    (pthread_cond_t*)NULL, NULL);
+    mCondVar.wait();
+  }
+
+  mHalCallback = NULL;
+  memset(&mHalEntryFuncs, 0, sizeof(mHalEntryFuncs));
+  InitializeHalDeviceContext();
+  ALOGD("%s: exit", func);
+}
+#endif
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::Finalize()
+**
+** Description: class finalizer
+**
+** Returns:     none
+**
+*******************************************************************************/
+void NfcAdaptation::Finalize() {
+  const char* func = "NfcAdaptation::Finalize";
+  AutoThreadMutex a(sLock);
+
+  ALOGD("%s: enter", func);
+  GKI_shutdown();
+
+  resetConfig();
+
+  mCallback = NULL;
+  memset(&mHalEntryFuncs, 0, sizeof(mHalEntryFuncs));
+
+  ALOGD("%s: exit", func);
+  delete this;
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::signal()
+**
+** Description: signal the CondVar to release the thread that is waiting
+**
+** Returns:     none
+**
+*******************************************************************************/
+void NfcAdaptation::signal() { mCondVar.signal(); }
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::NFCA_TASK()
+**
+** Description: NFCA_TASK runs the GKI main task
+**
+** Returns:     none
+**
+*******************************************************************************/
+uint32_t NfcAdaptation::NFCA_TASK(uint32_t arg) {
+  const char* func = "NfcAdaptation::NFCA_TASK";
+  ALOGD("%s: enter", func);
+  GKI_run(0);
+  ALOGD("%s: exit", func);
+  return 0;
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::Thread()
+**
+** Description: Creates work threads
+**
+** Returns:     none
+**
+*******************************************************************************/
+uint32_t NfcAdaptation::Thread(uint32_t arg) {
+  const char* func = "NfcAdaptation::Thread";
+  ALOGD("%s: enter", func);
+
+  {
+    ThreadCondVar CondVar;
+    AutoThreadMutex guard(CondVar);
+    GKI_create_task((TASKPTR)nfc_task, NFC_TASK, (int8_t*)"NFC_TASK", 0, 0,
+                    (pthread_cond_t*)CondVar, (pthread_mutex_t*)CondVar);
+    CondVar.wait();
+  }
+
+  NfcAdaptation::GetInstance().signal();
+
+  GKI_exit_task(GKI_get_taskid());
+  ALOGD("%s: exit", func);
+  return 0;
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::GetHalEntryFuncs()
+**
+** Description: Get the set of HAL entry points.
+**
+** Returns:     Functions pointers for HAL entry points.
+**
+*******************************************************************************/
+tHAL_NFC_ENTRY* NfcAdaptation::GetHalEntryFuncs() { return &mHalEntryFuncs; }
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::InitializeHalDeviceContext
+**
+** Description: Ask the generic Android HAL to find the Broadcom-specific HAL.
+**
+** Returns:     None.
+**
+*******************************************************************************/
+void NfcAdaptation::InitializeHalDeviceContext() {
+  const char* func = "NfcAdaptation::InitializeHalDeviceContext";
+  ALOGD("%s: enter", func);
+  int ret = 0;  // 0 means success
+
+    mHalEntryFuncs.initialize = HalInitialize;
+    mHalEntryFuncs.terminate = HalTerminate;
+    mHalEntryFuncs.open = HalOpen;
+    mHalEntryFuncs.close = HalClose;
+    mHalEntryFuncs.core_initialized = HalCoreInitialized;
+    mHalEntryFuncs.write = HalWrite;
+#if(NXP_EXTNS == TRUE)
+    mHalEntryFuncs.ioctl = HalIoctl;
+#endif
+    mHalEntryFuncs.prediscover = HalPrediscover;
+    mHalEntryFuncs.control_granted = HalControlGranted;
+    mHalEntryFuncs.power_cycle = HalPowerCycle;
+    mHalEntryFuncs.get_max_ee = HalGetMaxNfcee;
+    ALOGI("%s: INfc::getService()", func);
+    mHal = INfc::getService();
+    LOG_FATAL_IF(mHal == nullptr, "Failed to retrieve the NFC HAL!");
+    ALOGI("%s: INfc::getService() returned %p (%s)", func,
+          mHal.get(), (mHal->isRemote() ? "remote" : "local"));
+    mNqHal = INqNfc::getService();
+    LOG_FATAL_IF(mNqHal == nullptr, "Failed to retrieve the vendor NFC HAL!");
+    ALOGI("%s: INqNfc::getService() returned %p (%s)", func,
+          mNqHal.get(), (mNqHal->isRemote() ? "remote" : "local"));
+    ALOGD ("%s: exit", func);
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::HalInitialize
+**
+** Description: Not implemented because this function is only needed
+**              within the HAL.
+**
+** Returns:     None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalInitialize() {
+  const char* func = "NfcAdaptation::HalInitialize";
+  ALOGD("%s", func);
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::HalTerminate
+**
+** Description: Not implemented because this function is only needed
+**              within the HAL.
+**
+** Returns:     None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalTerminate() {
+  const char* func = "NfcAdaptation::HalTerminate";
+  ALOGD("%s", func);
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::HalOpen
+**
+** Description: Turn on controller, download firmware.
+**
+** Returns:     None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalOpen(tHAL_NFC_CBACK* p_hal_cback,
+                            tHAL_NFC_DATA_CBACK* p_data_cback) {
+  const char* func = "NfcAdaptation::HalOpen";
+  ALOGD("%s", func);
+  mCallback = new NfcClientCallback(p_hal_cback, p_data_cback);
+  mHal->open(mCallback);
+}
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::HalClose
+**
+** Description: Turn off controller.
+**
+** Returns:     None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalClose() {
+  const char* func = "NfcAdaptation::HalClose";
+  ALOGD("%s", func);
+  mHal->close();
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::HalDeviceContextCallback
+**
+** Description: Translate generic Android HAL's callback into Broadcom-specific
+**              callback function.
+**
+** Returns:     None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalDeviceContextCallback(nfc_event_t event,
+                                             nfc_status_t event_status) {
+  const char* func = "NfcAdaptation::HalDeviceContextCallback";
+  ALOGD("%s: event=%u", func, event);
+  if (mHalCallback) mHalCallback(event, (tHAL_NFC_STATUS)event_status);
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::HalDeviceContextDataCallback
+**
+** Description: Translate generic Android HAL's callback into Broadcom-specific
+**              callback function.
+**
+** Returns:     None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalDeviceContextDataCallback(uint16_t data_len,
+                                                 uint8_t* p_data) {
+  const char* func = "NfcAdaptation::HalDeviceContextDataCallback";
+  ALOGD("%s: len=%u", func, data_len);
+  if (mHalDataCallback) mHalDataCallback(data_len, p_data);
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::HalWrite
+**
+** Description: Write NCI message to the controller.
+**
+** Returns:     None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalWrite(uint16_t data_len, uint8_t* p_data) {
+  const char* func = "NfcAdaptation::HalWrite";
+  ALOGD("%s", func);
+  ::android::hardware::nfc::V1_0::NfcData data;
+  data.setToExternal(p_data, data_len);
+  mHal->write(data);
+}
+
+#if (NXP_EXTNS == TRUE)
+typedef struct {
+    struct nfc_nci_device nci_device;
+
+    /* Local definitions */
+    int(*ioctl)(const struct nfc_nci_device *p_dev, long arg, void *p_data);
+    int(*check_fw_dwnld_flag)(const struct nfc_nci_device *p_dev, uint8_t* param1);
+
+} pn547_dev_t;
+/*******************************************************************************
+**
+** Function:    IoctlCallback
+**
+** Description: Callback from HAL stub for IOCTL api invoked.
+**              Output data for IOCTL is sent as argument
+**
+** Returns:     None.
+**
+*******************************************************************************/
+void IoctlCallback(::android::hardware::nfc::V1_0::NfcData outputData) {
+  const char* func = "IoctlCallback";
+  nfc_nci_ExtnOutputData_t* pOutData =
+      (nfc_nci_ExtnOutputData_t*)&outputData[0];
+  ALOGD("%s Ioctl Type=%llu", func, pOutData->ioctlType);
+  NfcAdaptation* pAdaptation = (NfcAdaptation*)pOutData->context;
+  /*Output Data from stub->Proxy is copied back to output data
+   * This data will be sent back to libnfc*/
+  memcpy(&pAdaptation->mCurrentIoctlData->out, &outputData[0],
+         sizeof(nfc_nci_ExtnOutputData_t));
+}
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::HalIoctl
+**
+** Description: Calls ioctl to the Nfc driver.
+**              If called with a arg value of 0x01 than wired access requested,
+**              status of the requst would be updated to p_data.
+**              If called with a arg value of 0x00 than wired access will be
+**              released, status of the requst would be updated to p_data.
+**              If called with a arg value of 0x02 than current p61 state would
+*be
+**              updated to p_data.
+**
+** Returns:     -1 or 0.
+**
+*******************************************************************************/
+int NfcAdaptation::HalIoctl(long arg, void* p_data) {
+  const char* func = "NfcAdaptation::HalIoctl";
+  mHalIoctlEvent.lock();
+  ::android::hardware::nfc::V1_0::NfcData data;
+  AutoThreadMutex a(sIoctlLock);
+  nfc_nci_IoctlInOutData_t* pInpOutData = (nfc_nci_IoctlInOutData_t*)p_data;
+  int status = 0;
+  ALOGD("%s arg=%ld", func, arg);
+  pInpOutData->inp.context = &NfcAdaptation::GetInstance();
+  NfcAdaptation::GetInstance().mCurrentIoctlData = pInpOutData;
+  data.setToExternal((uint8_t*)pInpOutData, sizeof(nfc_nci_IoctlInOutData_t));
+  mNqHal->ioctl(arg, data, IoctlCallback);
+  ALOGD("%s Ioctl Completed for Type=%llu", func, pInpOutData->out.ioctlType);
+  mHalIoctlEvent.unlock();
+  return (pInpOutData->out.result);
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::HalGetFwDwnldFlag
+**
+** Description: Get FW Download Flag.
+**
+** Returns:     SUCESS or FAIL.
+**
+*******************************************************************************/
+int NfcAdaptation::HalGetFwDwnldFlag(uint8_t* fwDnldRequest) {
+  const char* func = "NfcAdaptation::HalGetFwDwnldFlag";
+  int status = NFA_STATUS_FAILED;
+  ALOGD("%s : Dummy", func);
+  /*FIXME: Additional IOCTL type can be added for this
+   * Instead of extra function pointer
+   * This is required for a corner case or delayed FW download after SPI session
+   * is completed
+   * This shall be fixed with a better design later*/
+  /*
+  if (mHalDeviceContext)
+  {
+      status = mHalDeviceContext->check_fw_dwnld_flag(mHalDeviceContext,
+  fwDnldRequest);
+  }*/
+  return status;
+}
+#endif
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::HalCoreInitialized
+**
+** Description: Adjust the configurable parameters in the controller.
+**
+** Returns:     None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalCoreInitialized(uint16_t data_len,
+                                       uint8_t* p_core_init_rsp_params) {
+  const char* func = "NfcAdaptation::HalCoreInitialized";
+  ALOGD("%s", func);
+  hidl_vec<uint8_t> data;
+  data.setToExternal(p_core_init_rsp_params, data_len);
+  mHal->coreInitialized(data);
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::HalPrediscover
+**
+** Description:     Perform any vendor-specific pre-discovery actions (if
+**                  needed) If any actions were performed true will be returned,
+**                  and HAL_PRE_DISCOVER_CPLT_EVT will notify when actions are
+**                  completed.
+**
+** Returns:         true if vendor-specific pre-discovery actions initialized
+**                  false if no vendor-specific pre-discovery actions are
+**                  needed.
+**
+*******************************************************************************/
+bool NfcAdaptation::HalPrediscover() {
+  const char* func = "NfcAdaptation::HalPrediscover";
+  ALOGD("%s", func);
+  bool retval = false;
+  if(mHal != nullptr)
+  {
+      mHal->prediscover();
+  }
+  /*FIXME: Additional IOCTL type can be added for this
+   * Instead of extra function pointer
+   * prediscover in HAL is empty dummy function
+   */
+  /*if (mHalDeviceContext)
+  {
+      retval = mHalDeviceContext->pre_discover (mHalDeviceContext);
+  }*/
+  return retval;
+}
+
+/*******************************************************************************
+**
+** Function:        HAL_NfcControlGranted
+**
+** Description:     Grant control to HAL control for sending NCI commands.
+**                  Call in response to HAL_REQUEST_CONTROL_EVT.
+**                  Must only be called when there are no NCI commands pending.
+**                  HAL_RELEASE_CONTROL_EVT will notify when HAL no longer
+**                  needs control of NCI.
+**
+** Returns:         void
+**
+*******************************************************************************/
+void NfcAdaptation::HalControlGranted() {
+  const char* func = "NfcAdaptation::HalControlGranted";
+  ALOGD("%s", func);
+  mHal->controlGranted();
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::HalPowerCycle
+**
+** Description: Turn off and turn on the controller.
+**
+** Returns:     None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalPowerCycle() {
+  const char* func = "NfcAdaptation::HalPowerCycle";
+  ALOGD("%s", func);
+  mHal->powerCycle();
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::HalGetMaxNfcee
+**
+** Description: Turn off and turn on the controller.
+**
+** Returns:     None.
+**
+*******************************************************************************/
+uint8_t NfcAdaptation::HalGetMaxNfcee() {
+  const char* func = "NfcAdaptation::HalPowerCycle";
+  uint8_t maxNfcee = 0;
+  ALOGD("%s", func);
+  return nfa_ee_max_ee_cfg;
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::DownloadFirmware
+**
+** Description: Download firmware patch files.
+**
+** Returns:     None.
+**
+*******************************************************************************/
+void NfcAdaptation::DownloadFirmware() {
+  const char* func = "NfcAdaptation::DownloadFirmware";
+  ALOGD("%s: enter", func);
+#if (NXP_EXTNS == TRUE)
+  static uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00};
+  static uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
+  static uint8_t cmd_init_nci2_0[] = {0x20,0x01,0x02,0x00,0x00};
+  static uint8_t cmd_reset_nci_size = sizeof(cmd_reset_nci) / sizeof(uint8_t);
+  static uint8_t cmd_init_nci_size = sizeof(cmd_init_nci) / sizeof(uint8_t);
+  if(NFA_GetNCIVersion() == NCI_VERSION_2_0)
+  {
+      cmd_init_nci_size = sizeof(cmd_init_nci2_0) / sizeof(uint8_t);
+  }
+  nfc_nci_IoctlInOutData_t inpOutData;
+  tNFC_FWUpdate_Info_t fw_update_inf;
+  uint8_t p_core_init_rsp_params;
+  uint16_t fw_dwnld_status = NFC_STATUS_FAILED;
+  evt_status = NFC_STATUS_FAILED;
+#endif
+  HalInitialize();
+
+  mHalOpenCompletedEvent.lock();
+  ALOGD("%s: try open HAL", func);
+  HalOpen(HalDownloadFirmwareCallback, HalDownloadFirmwareDataCallback);
+  mHalOpenCompletedEvent.wait();
+  mHalOpenCompletedEvent.unlock();
+#if (NXP_EXTNS == TRUE)
+  /* Send a CORE_RESET and CORE_INIT to the NFCC. This is required because when
+   * calling
+   * HalCoreInitialized, the HAL is going to parse the conf file and send NCI
+   * commands
+   * to the NFCC. Hence CORE-RESET and CORE-INIT have to be sent prior to this.
+   */
+  isSignaled = SIGNAL_NONE;
+  ALOGD("%s: send CORE_RESET", func);
+  HalWrite(cmd_reset_nci_size, cmd_reset_nci);
+  mHalCoreResetCompletedEvent.lock();
+  if (SIGNAL_NONE == isSignaled) {
+    mHalCoreResetCompletedEvent.wait();
+  }
+  isSignaled = SIGNAL_NONE;
+  mHalCoreResetCompletedEvent.unlock();
+  if (evt_status == NFC_STATUS_FAILED) {
+    goto TheEnd;
+  }
+  ALOGD("%s: send CORE_INIT", func);
+  ALOGD("%s: send CORE_INIT NCI Version : %d", func, NFA_GetNCIVersion());
+  if(NFA_GetNCIVersion() == NCI_VERSION_2_0)
+    HalWrite(cmd_init_nci_size, cmd_init_nci2_0);
+  else
+    HalWrite(cmd_init_nci_size, cmd_init_nci);
+  mHalCoreInitCompletedEvent.lock();
+  if (SIGNAL_NONE == isSignaled) {
+    mHalCoreInitCompletedEvent.wait();
+  }
+  isSignaled = SIGNAL_NONE;
+  mHalCoreInitCompletedEvent.unlock();
+  if (evt_status == NFC_STATUS_FAILED) {
+    goto TheEnd;
+  }
+  mHalEntryFuncs.ioctl(HAL_NFC_IOCTL_CHECK_FLASH_REQ, &inpOutData);
+  fw_update_inf = *(tNFC_FWUpdate_Info_t*)&inpOutData.out.data.fwUpdateInf;
+  NFC_TRACE_DEBUG1("fw_update required  -> %d", fw_update_inf.fw_update_reqd);
+  if (fw_update_inf.fw_update_reqd == true) {
+    mHalEntryFuncs.ioctl(HAL_NFC_IOCTL_FW_DWNLD, &inpOutData);
+    fw_dwnld_status = inpOutData.out.data.fwDwnldStatus;
+    if (fw_dwnld_status != NFC_STATUS_OK) {
+      ALOGD("%s: FW Download failed", func);
+    } else {
+      isSignaled = SIGNAL_NONE;
+      ALOGD("%s: send CORE_RESET", func);
+      HalWrite(cmd_reset_nci_size, cmd_reset_nci);
+      mHalCoreResetCompletedEvent.lock();
+      if (SIGNAL_NONE == isSignaled) {
+        mHalCoreResetCompletedEvent.wait();
+      }
+      isSignaled = SIGNAL_NONE;
+      mHalCoreResetCompletedEvent.unlock();
+      if (evt_status == NFC_STATUS_FAILED) {
+        goto TheEnd;
+      }
+      ALOGD("%s: send CORE_INIT", func);
+      if(NFA_GetNCIVersion() == NCI_VERSION_2_0)
+        HalWrite(cmd_init_nci_size, cmd_init_nci2_0);
+      else
+        HalWrite(cmd_init_nci_size, cmd_init_nci);
+      mHalCoreInitCompletedEvent.lock();
+      if (SIGNAL_NONE == isSignaled) {
+        mHalCoreInitCompletedEvent.wait();
+      }
+      isSignaled = SIGNAL_NONE;
+      mHalCoreInitCompletedEvent.unlock();
+      if (evt_status == NFC_STATUS_FAILED) {
+        goto TheEnd;
+      }
+      ALOGD("%s: try init HAL", func);
+      HalCoreInitialized(sizeof(uint8_t), &p_core_init_rsp_params);
+      mHalInitCompletedEvent.lock();
+      mHalInitCompletedEvent.wait();
+      mHalInitCompletedEvent.unlock();
+    }
+  }
+
+TheEnd:
+  isSignaled = SIGNAL_NONE;
+#endif
+  ALOGD("%s: try close HAL", func);
+  HalClose();
+#if (NXP_EXTNS == TRUE)
+  mHalCloseCompletedEvent.lock();
+  if (SIGNAL_NONE == isSignaled) {
+    mHalCloseCompletedEvent.wait();
+  }
+  isSignaled = SIGNAL_NONE;
+  mHalCloseCompletedEvent.unlock();
+#endif
+  HalTerminate();
+  ALOGD("%s: exit", func);
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::HalDownloadFirmwareCallback
+**
+** Description: Receive events from the HAL.
+**
+** Returns:     None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalDownloadFirmwareCallback(nfc_event_t event,
+                                                nfc_status_t event_status) {
+  const char* func = "NfcAdaptation::HalDownloadFirmwareCallback";
+  (void)(event_status);
+  ALOGD("%s: event=0x%X", func, event);
+  switch (event) {
+    case HAL_NFC_OPEN_CPLT_EVT: {
+      ALOGD("%s: HAL_NFC_OPEN_CPLT_EVT", func);
+      mHalOpenCompletedEvent.signal();
+      break;
+    }
+    case HAL_NFC_POST_INIT_CPLT_EVT: {
+      ALOGD("%s: HAL_NFC_POST_INIT_CPLT_EVT", func);
+      mHalInitCompletedEvent.signal();
+      break;
+    }
+    case HAL_NFC_CLOSE_CPLT_EVT: {
+      ALOGD("%s: HAL_NFC_CLOSE_CPLT_EVT", func);
+#if (NXP_EXTNS == TRUE)
+      isSignaled = SIGNAL_SIGNALED;
+#endif
+      mHalCloseCompletedEvent.signal();
+      break;
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::HalDownloadFirmwareDataCallback
+**
+** Description: Receive data events from the HAL.
+**
+** Returns:     None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalDownloadFirmwareDataCallback(uint16_t data_len,
+                                                    uint8_t* p_data) {
+#if (NXP_EXTNS == TRUE)
+  isSignaled = SIGNAL_SIGNALED;
+  if (data_len > 3) {
+    evt_status = NFC_STATUS_OK;
+    if (p_data[0] == 0x40 && p_data[1] == 0x00) {
+      mHalCoreResetCompletedEvent.signal();
+    } else if (p_data[0] == 0x40 && p_data[1] == 0x01) {
+      mHalCoreInitCompletedEvent.signal();
+    }
+  } else {
+    evt_status = NFC_STATUS_FAILED;
+    mHalCoreResetCompletedEvent.signal();
+    mHalCoreInitCompletedEvent.signal();
+  }
+#endif
+}
+
+/*******************************************************************************
+**
+** Function:    ThreadMutex::ThreadMutex()
+**
+** Description: class constructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+ThreadMutex::ThreadMutex() {
+  pthread_mutexattr_t mutexAttr;
+
+  pthread_mutexattr_init(&mutexAttr);
+  pthread_mutex_init(&mMutex, &mutexAttr);
+  pthread_mutexattr_destroy(&mutexAttr);
+}
+
+/*******************************************************************************
+**
+** Function:    ThreadMutex::~ThreadMutex()
+**
+** Description: class destructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+ThreadMutex::~ThreadMutex() { pthread_mutex_destroy(&mMutex); }
+
+/*******************************************************************************
+**
+** Function:    ThreadMutex::lock()
+**
+** Description: lock kthe mutex
+**
+** Returns:     none
+**
+*******************************************************************************/
+void ThreadMutex::lock() { pthread_mutex_lock(&mMutex); }
+
+/*******************************************************************************
+**
+** Function:    ThreadMutex::unblock()
+**
+** Description: unlock the mutex
+**
+** Returns:     none
+**
+*******************************************************************************/
+void ThreadMutex::unlock() { pthread_mutex_unlock(&mMutex); }
+
+/*******************************************************************************
+**
+** Function:    ThreadCondVar::ThreadCondVar()
+**
+** Description: class constructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+ThreadCondVar::ThreadCondVar() {
+  pthread_condattr_t CondAttr;
+
+  pthread_condattr_init(&CondAttr);
+  pthread_cond_init(&mCondVar, &CondAttr);
+
+  pthread_condattr_destroy(&CondAttr);
+}
+
+/*******************************************************************************
+**
+** Function:    ThreadCondVar::~ThreadCondVar()
+**
+** Description: class destructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+ThreadCondVar::~ThreadCondVar() { pthread_cond_destroy(&mCondVar); }
+
+/*******************************************************************************
+**
+** Function:    ThreadCondVar::wait()
+**
+** Description: wait on the mCondVar
+**
+** Returns:     none
+**
+*******************************************************************************/
+void ThreadCondVar::wait() {
+  pthread_cond_wait(&mCondVar, *this);
+  pthread_mutex_unlock(*this);
+}
+
+/*******************************************************************************
+**
+** Function:    ThreadCondVar::signal()
+**
+** Description: signal the mCondVar
+**
+** Returns:     none
+**
+*******************************************************************************/
+void ThreadCondVar::signal() {
+  AutoThreadMutex a(*this);
+  pthread_cond_signal(&mCondVar);
+}
+
+/*******************************************************************************
+**
+** Function:    AutoThreadMutex::AutoThreadMutex()
+**
+** Description: class constructor, automatically lock the mutex
+**
+** Returns:     none
+**
+*******************************************************************************/
+AutoThreadMutex::AutoThreadMutex(ThreadMutex& m) : mm(m) { mm.lock(); }
+
+/*******************************************************************************
+**
+** Function:    AutoThreadMutex::~AutoThreadMutex()
+**
+** Description: class destructor, automatically unlock the mutex
+**
+** Returns:     none
+**
+*******************************************************************************/
+AutoThreadMutex::~AutoThreadMutex() { mm.unlock(); }
diff --git a/src/adaptation/OverrideLog.cpp b/src/adaptation/OverrideLog.cpp
new file mode 100644
index 0000000..08a477d
--- /dev/null
+++ b/src/adaptation/OverrideLog.cpp
@@ -0,0 +1,145 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  Override the ALOGD(), ALOGE(), and other logging macros from
+ *  /system/core/include/cutils/log.h
+ *
+ ******************************************************************************/
+#include "_OverrideLog.h"
+#include <cutils/properties.h>
+#include <string.h>
+#include "config.h"
+#include "android_logmsg.h"
+
+#undef LOG_TAG
+#define LOG_TAG "BrcmNfcJni"
+
+/*******************************************************************************
+**
+** Function:        initializeGlobalAppLogLevel
+**
+** Description:     Initialize and get global logging level from .conf or
+**                  Android property nfc.app_log_level.  The Android property
+**                  overrides .conf variable.
+**
+** Returns:         Global log level:
+**                  BT_TRACE_LEVEL_NONE    0 * No trace messages to be generated
+**                  BT_TRACE_LEVEL_ERROR   1 * Error condition trace messages
+**                  BT_TRACE_LEVEL_WARNING 2 * Warning condition trace messages
+**                  BT_TRACE_LEVEL_API     3 * API traces
+**                  BT_TRACE_LEVEL_EVENT   4 * Debug messages for events
+**                  BT_TRACE_LEVEL_DEBUG   5 * Debug messages (general)
+**
+*******************************************************************************/
+unsigned char initializeGlobalAppLogLevel() {
+  unsigned long num = 0;
+  char valueStr[PROPERTY_VALUE_MAX] = {0};
+
+  num = 1;
+  if (GetNumValue(NAME_APPL_TRACE_LEVEL, &num, sizeof(num)))
+    appl_trace_level = (unsigned char)num;
+  int len = property_get("nfc.app_log_level", valueStr, "");
+  if (len > 0) {
+    // let Android property override .conf variable
+    sscanf(valueStr, "%lu", &num);
+    appl_trace_level = (unsigned char)num;
+  }
+
+  // 0xFF is a special value used by the stack to query the current
+  // trace level; it does not change any trace level
+  if (appl_trace_level == 0xFF) appl_trace_level = BT_TRACE_LEVEL_DEBUG;
+  ALOGD("%s: level=%u", __func__, appl_trace_level);
+
+  if (appl_trace_level < BT_TRACE_LEVEL_DEBUG) {
+    // display protocol traces in raw format
+    ProtoDispAdapterUseRawOutput(true);
+  }
+  return appl_trace_level;
+}
+
+uint32_t initializeProtocolLogLevel() {
+  uint32_t num = 0;
+  char valueStr[PROPERTY_VALUE_MAX] = {0};
+
+  if (GetNumValue(NAME_PROTOCOL_TRACE_LEVEL, &num, sizeof(num)))
+    ScrProtocolTraceFlag = num;
+
+  int len = property_get("nfc.enable_protocol_log", valueStr, "");
+  if (len > 0) {
+    if (strncmp("0", valueStr, 1) == 0) {
+      ScrProtocolTraceFlag = 0;
+    } else {
+      ScrProtocolTraceFlag = ~0;
+    }
+  }
+
+  return ScrProtocolTraceFlag;
+}
+
+#if (NXP_EXTNS == TRUE)
+/*********************************************************************************
+** Function:        enableDisableAppLevel
+**
+** Description:     Enable/Disable applicaton trace logs
+**
+** Returns:         none:
+**
+*******************************************************************************/
+void enableDisableAppLevel(uint8_t type) {
+  static uint8_t backup_app_trace = appl_trace_level;
+  if (0x01 == type && (backup_app_trace != appl_trace_level)) {
+    appl_trace_level = backup_app_trace;
+  } else if (0x00 == type && (0x00 != appl_trace_level)) {
+    backup_app_trace = appl_trace_level;
+    appl_trace_level = 0x00;
+  }
+}
+/*******************************************************************************
+**
+** Function:        initializeGlobalDtaMode
+**
+** Description:     Initialize and get global DTA mode from .conf
+**
+** Returns:         none:
+**
+*******************************************************************************/
+void initializeGlobalAppDtaMode() {
+  appl_dta_mode_flag = 0x01;
+  ALOGD("%s: DTA Enabled", __func__);
+}
+#endif
diff --git a/src/adaptation/android_logmsg.cpp b/src/adaptation/android_logmsg.cpp
new file mode 100644
index 0000000..0a82175
--- /dev/null
+++ b/src/adaptation/android_logmsg.cpp
@@ -0,0 +1,351 @@
+/******************************************************************************
+ *
+ *  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) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#include "_OverrideLog.h"
+#include "android_logmsg.h"
+#include "nfc_target.h"
+#include "buildcfg.h"
+#include <cutils/log.h>
+
+extern uint32_t ScrProtocolTraceFlag;
+#define MAX_NCI_PACKET_SIZE 259
+#define BTE_LOG_BUF_SIZE 1024
+#define BTE_LOG_MAX_SIZE (BTE_LOG_BUF_SIZE - 12)
+#define MAX_LOGCAT_LINE 4096
+#define PRINT(s) __android_log_write(ANDROID_LOG_DEBUG, "BrcmNci", s)
+#define UNUSED(X) (void) X
+static char log_line[MAX_LOGCAT_LINE];
+static const char* sTable = "0123456789abcdef";
+static bool sIsUseRaw = false;
+static void ToHex(const uint8_t* data, uint16_t len, char* hexString,
+                  uint16_t hexStringSize);
+static void dumpbin(const char* data, int size, uint32_t trace_layer,
+                    uint32_t trace_type);
+static inline void word2hex(const char* data, char** hex);
+static inline void byte2char(const char* data, char** str);
+static inline void byte2hex(const char* data, char** str);
+
+void BTDISP_LOCK_LOG() {}
+
+void BTDISP_UNLOCK_LOG() {}
+
+void BTDISP_INIT_LOCK() {}
+
+void BTDISP_UNINIT_LOCK() {}
+
+void ProtoDispAdapterUseRawOutput(bool isUseRaw) { sIsUseRaw = isUseRaw; }
+
+void ProtoDispAdapterDisplayNciPacket(uint8_t* nciPacket, uint16_t nciPacketLen,
+                                      bool is_recv) {
+  // Protocol decoder is not available, so decode NCI packet into hex numbers.
+  if (!(ScrProtocolTraceFlag & SCR_PROTO_TRACE_NCI)) return;
+  char line_buf[(MAX_NCI_PACKET_SIZE * 2) + 1];
+  ToHex(nciPacket, nciPacketLen, line_buf, sizeof(line_buf));
+  __android_log_write(ANDROID_LOG_DEBUG, (is_recv) ? "BrcmNciR" : "BrcmNciX",
+                      line_buf);
+}
+
+void ToHex(const uint8_t* data, uint16_t len, char* hexString,
+           uint16_t hexStringSize) {
+  int i = 0, j = 0;
+  for (i = 0, j = 0; i < len && j < hexStringSize - 3; i++) {
+    hexString[j++] = sTable[(*data >> 4) & 0xf];
+    hexString[j++] = sTable[*data & 0xf];
+    data++;
+  }
+  hexString[j] = '\0';
+}
+
+// Protodisp code calls ScrLog() to print decoded texts.
+void ScrLog(uint32_t trace_set_mask, const char* fmt_str, ...) {
+  static char buffer[BTE_LOG_BUF_SIZE];
+  va_list ap;
+  UNUSED(trace_set_mask);
+  va_start(ap, fmt_str);
+  vsnprintf(buffer, BTE_LOG_MAX_SIZE, fmt_str, ap);
+  va_end(ap);
+  __android_log_write(ANDROID_LOG_INFO, "BrcmNci", buffer);
+}
+
+uint8_t* scru_dump_hex(uint8_t* p, char* pTitle, uint32_t len, uint32_t layer,
+                       uint32_t type) {
+  if (pTitle && *pTitle) PRINT(pTitle);
+  dumpbin((char*)p, len, layer, type);
+  return p;
+}
+
+void dumpbin(const char* data, int size, uint32_t trace_layer,
+             uint32_t trace_type) {
+  char line_buff[256];
+  char* line;
+  int i, j, addr;
+  const int width = 16;
+  UNUSED(trace_layer);
+  UNUSED(trace_type);
+  if (size <= 0) return;
+  for (i = 0; i < size / width; i++) {
+    line = line_buff;
+    // write address:
+    addr = i * width;
+    word2hex((const char*)&addr, &line);
+    *line++ = ':';
+    *line++ = ' ';
+    // write hex of data
+    for (j = 0; j < width; j++) {
+      byte2hex(&data[j], &line);
+      *line++ = ' ';
+    }
+    // write char of data
+    for (j = 0; j < width; j++) byte2char(data++, &line);
+    // wirte the end of line
+    *line = 0;
+    // output the line
+    PRINT(line_buff);
+  }
+  // last line of left over if any
+  int leftover = size % width;
+  if (leftover > 0) {
+    line = line_buff;
+    // write address:
+    addr = i * width;
+    word2hex((const char*)&addr, &line);
+    *line++ = ':';
+    *line++ = ' ';
+    // write hex of data
+    for (j = 0; j < leftover; j++) {
+      byte2hex(&data[j], &line);
+      *line++ = ' ';
+    }
+    // write hex padding
+    for (; j < width; j++) {
+      *line++ = ' ';
+      *line++ = ' ';
+      *line++ = ' ';
+    }
+    // write char of data
+    for (j = 0; j < leftover; j++) byte2char(data++, &line);
+    // write the end of line
+    *line = 0;
+    // output the line
+    PRINT(line_buff);
+  }
+}
+
+inline void word2hex(const char* data, char** hex) {
+  byte2hex(&data[1], hex);
+  byte2hex(&data[0], hex);
+}
+
+inline void byte2char(const char* data, char** str) {
+  **str = *data < ' ' ? '.' : *data > '~' ? '.' : *data;
+  ++(*str);
+}
+
+inline void byte2hex(const char* data, char** str) {
+  **str = sTable[(*data >> 4) & 0xf];
+  ++*str;
+  **str = sTable[*data & 0xf];
+  ++*str;
+}
+
+// Decode a few Bluetooth HCI packets into hex numbers.
+void DispHciCmd(NFC_HDR* p_buf) {
+  uint32_t nBytes = ((NFC_HDR_SIZE + p_buf->offset + p_buf->len) * 2) + 1;
+  uint8_t* data = (uint8_t*)p_buf;
+  int data_len = NFC_HDR_SIZE + p_buf->offset + p_buf->len;
+
+  if (appl_trace_level < BT_TRACE_LEVEL_DEBUG) return;
+
+  if (nBytes > sizeof(log_line)) return;
+
+  ToHex(data, data_len, log_line, sizeof(log_line));
+  __android_log_write(ANDROID_LOG_DEBUG, "BrcmHciX", log_line);
+}
+
+// Decode a few Bluetooth HCI packets into hex numbers.
+void DispHciEvt(NFC_HDR* p_buf) {
+  uint32_t nBytes = ((NFC_HDR_SIZE + p_buf->offset + p_buf->len) * 2) + 1;
+  uint8_t* data = (uint8_t*)p_buf;
+  int data_len = NFC_HDR_SIZE + p_buf->offset + p_buf->len;
+
+  if (appl_trace_level < BT_TRACE_LEVEL_DEBUG) return;
+
+  if (nBytes > sizeof(log_line)) return;
+
+  ToHex(data, data_len, log_line, sizeof(log_line));
+  __android_log_write(ANDROID_LOG_DEBUG, "BrcmHciR", log_line);
+}
+
+/***************************************************************************
+**
+** Function         DispLLCP
+**
+** Description      Log LLCP packet as hex-ascii bytes.
+**
+** Returns          None.
+**
+***************************************************************************/
+void DispLLCP(NFC_HDR* p_buf, bool is_recv) {
+  uint32_t nBytes = ((NFC_HDR_SIZE + p_buf->offset + p_buf->len) * 2) + 1;
+  uint8_t* data = (uint8_t*)p_buf;
+  int data_len = NFC_HDR_SIZE + p_buf->offset + p_buf->len;
+
+  if (appl_trace_level < BT_TRACE_LEVEL_DEBUG) return;
+
+  if (nBytes > sizeof(log_line)) return;
+
+  ToHex(data, data_len, log_line, sizeof(log_line));
+  __android_log_write(ANDROID_LOG_DEBUG, (is_recv) ? "BrcmLlcpR" : "BrcmLlcpX",
+                      log_line);
+}
+
+/***************************************************************************
+**
+** Function         DispHcp
+**
+** Description      Log raw HCP packet as hex-ascii bytes
+**
+** Returns          None.
+**
+***************************************************************************/
+void DispHcp(uint8_t* data, uint16_t len, bool is_recv) {
+  uint32_t nBytes = (len * 2) + 1;
+
+  if (appl_trace_level < BT_TRACE_LEVEL_DEBUG) return;
+
+  // Only trace HCP if we're tracing HCI as well
+  if (!(ScrProtocolTraceFlag & SCR_PROTO_TRACE_HCI_SUMMARY)) return;
+
+  if (nBytes > sizeof(log_line)) return;
+
+  ToHex(data, len, log_line, sizeof(log_line));
+  __android_log_write(ANDROID_LOG_DEBUG, (is_recv) ? "BrcmHcpR" : "BrcmHcpX",
+                      log_line);
+}
+
+void DispSNEP(uint8_t local_sap, uint8_t remote_sap, NFC_HDR* p_buf,
+              bool is_first, bool is_rx) {
+  UNUSED(local_sap);
+  UNUSED(remote_sap);
+  UNUSED(p_buf);
+  UNUSED(is_first);
+  UNUSED(is_rx);
+}
+void DispCHO(uint8_t* pMsg, uint32_t MsgLen, bool is_rx) {
+  UNUSED(pMsg);
+  UNUSED(MsgLen);
+  UNUSED(is_rx);
+}
+void DispT3TagMessage(NFC_HDR* p_msg, bool is_rx) {
+  UNUSED(p_msg);
+  UNUSED(is_rx);
+}
+void DispRWT4Tags(NFC_HDR* p_buf, bool is_rx) {
+  UNUSED(p_buf);
+  UNUSED(is_rx);
+}
+void DispCET4Tags(NFC_HDR* p_buf, bool is_rx) {
+  UNUSED(p_buf);
+  UNUSED(is_rx);
+}
+void DispRWI93Tag(NFC_HDR* p_buf, bool is_rx, uint8_t command_to_respond) {
+  UNUSED(p_buf);
+  UNUSED(is_rx);
+  UNUSED(command_to_respond);
+}
+void DispNDEFMsg(uint8_t* pMsg, uint32_t MsgLen, bool is_recv) {
+  UNUSED(pMsg);
+  UNUSED(MsgLen);
+  UNUSED(is_recv);
+}
+
+/*******************************************************************************
+**
+** Function:        LogMsg
+**
+** Description:     Print messages from NFC stack.
+**
+** Returns:         None.
+**
+*******************************************************************************/
+void LogMsg(uint32_t trace_set_mask, const char* fmt_str, ...) {
+  static char buffer[BTE_LOG_BUF_SIZE];
+  va_list ap;
+  uint32_t trace_type =
+      trace_set_mask & 0x07;  // lower 3 bits contain trace type
+  int android_log_type = ANDROID_LOG_INFO;
+
+  va_start(ap, fmt_str);
+  vsnprintf(buffer, BTE_LOG_MAX_SIZE, fmt_str, ap);
+  va_end(ap);
+  if (trace_type == TRACE_TYPE_ERROR) android_log_type = ANDROID_LOG_ERROR;
+  __android_log_write(android_log_type, LOGMSG_TAG_NAME, buffer);
+}
+
+void LogMsg_0(uint32_t maskTraceSet, const char* p_str) {
+  LogMsg(maskTraceSet, p_str);
+}
+
+void LogMsg_1(uint32_t maskTraceSet, const char* fmt_str, uintptr_t p1) {
+  LogMsg(maskTraceSet, fmt_str, p1);
+}
+
+void LogMsg_2(uint32_t maskTraceSet, const char* fmt_str, uintptr_t p1,
+              uintptr_t p2) {
+  LogMsg(maskTraceSet, fmt_str, p1, p2);
+}
+
+void LogMsg_3(uint32_t maskTraceSet, const char* fmt_str, uintptr_t p1,
+              uintptr_t p2, uintptr_t p3) {
+  LogMsg(maskTraceSet, fmt_str, p1, p2, p3);
+}
+
+void LogMsg_4(uint32_t maskTraceSet, const char* fmt_str, uintptr_t p1,
+              uintptr_t p2, uintptr_t p3, uintptr_t p4) {
+  LogMsg(maskTraceSet, fmt_str, p1, p2, p3, p4);
+}
+
+void LogMsg_5(uint32_t maskTraceSet, const char* fmt_str, uintptr_t p1,
+              uintptr_t p2, uintptr_t p3, uintptr_t p4, uintptr_t p5) {
+  LogMsg(maskTraceSet, fmt_str, p1, p2, p3, p4, p5);
+}
+
+void LogMsg_6(uint32_t maskTraceSet, const char* fmt_str, uintptr_t p1,
+              uintptr_t p2, uintptr_t p3, uintptr_t p4, uintptr_t p5,
+              uintptr_t p6) {
+  LogMsg(maskTraceSet, fmt_str, p1, p2, p3, p4, p5, p6);
+}
diff --git a/src/adaptation/config.cpp b/src/adaptation/config.cpp
new file mode 100644
index 0000000..c3fb02b
--- /dev/null
+++ b/src/adaptation/config.cpp
@@ -0,0 +1,812 @@
+/******************************************************************************
+ *
+ *  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 "_OverrideLog.h"
+#include "config.h"
+#include <stdio.h>
+#include <sys/stat.h>
+#include <string>
+#include <vector>
+#include <list>
+
+#undef LOG_TAG
+#define LOG_TAG "NfcAdaptation"
+
+const char* transport_config_paths[] = {"/odm/etc/", "/vendor/etc/", "/etc/"};
+const int transport_config_path_size =
+    (sizeof(transport_config_paths) / sizeof(transport_config_paths[0]));
+
+#if (NXP_EXTNS == TRUE)
+const char transit_config_path[] = "/data/vendor/nfc/";
+#endif
+
+#define config_name "libnfc-brcm.conf"
+#if (NXP_EXTNS == TRUE)
+#define extra_config_base "libnfc-"
+#else
+#define extra_config_base "libnfc-brcm-"
+#endif
+#define extra_config_ext ".conf"
+#define IsStringValue 0x80000000
+
+using namespace ::std;
+
+class CNfcParam : public string {
+ public:
+  CNfcParam();
+  CNfcParam(const char* name, const string& value);
+  CNfcParam(const char* name, unsigned long value);
+  virtual ~CNfcParam();
+  unsigned long numValue() const { return m_numValue; }
+  const char* str_value() const { return m_str_value.c_str(); }
+  size_t str_len() const { return m_str_value.length(); }
+
+ private:
+  string m_str_value;
+  unsigned long m_numValue;
+};
+
+class CNfcConfig : public vector<const CNfcParam*> {
+ public:
+  virtual ~CNfcConfig();
+  static CNfcConfig& GetInstance();
+  friend void readOptionalConfigExt(const char* optional);
+  bool getValue(const char* name, char* pValue, size_t& len) const;
+  bool getValue(const char* name, unsigned long& rValue) const;
+  bool getValue(const char* name, unsigned short& rValue) const;
+  const CNfcParam* find(const char* p_name) const;
+#if (NXP_EXTNS == TRUE)
+  void readNxpTransitConfig(const char* fileName) const;
+#endif
+  void clean();
+
+ private:
+  CNfcConfig();
+  bool readConfig(const char* name, bool bResetContent);
+  void moveFromList();
+  void moveToList();
+  void add(const CNfcParam* pParam);
+#if (NXP_EXTNS == TRUE)
+  void dump();
+  bool isAllowed(const char* name);
+  string mCurrentFile;
+#endif
+  list<const CNfcParam*> m_list;
+  bool mValidFile;
+
+  unsigned long state;
+
+  inline bool Is(unsigned long f) { return (state & f) == f; }
+  inline void Set(unsigned long f) { state |= f; }
+  inline void Reset(unsigned long f) { state &= ~f; }
+};
+
+/*******************************************************************************
+**
+** Function:    isPrintable()
+**
+** Description: detremine if a char is printable
+**
+** Returns:     none
+**
+*******************************************************************************/
+inline bool isPrintable(char c) {
+  return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
+         (c >= '0' && c <= '9') || c == '/' || c == '_' || c == '-' || c == '.';
+}
+
+/*******************************************************************************
+**
+** Function:    isDigit()
+**
+** Description: detremine if a char is numeral digit
+**
+** Returns:     none
+**
+*******************************************************************************/
+inline bool isDigit(char c, int base) {
+  if ('0' <= c && c <= '9') return true;
+  if (base == 16) {
+    if (('A' <= c && c <= 'F') || ('a' <= c && c <= 'f')) return true;
+  }
+  return false;
+}
+
+/*******************************************************************************
+**
+** Function:    getDigitValue()
+**
+** Description: return numercal value of a char
+**
+** Returns:     none
+**
+*******************************************************************************/
+inline int getDigitValue(char c, int base) {
+  if ('0' <= c && c <= '9') return c - '0';
+  if (base == 16) {
+    if ('A' <= c && c <= 'F')
+      return c - 'A' + 10;
+    else if ('a' <= c && c <= 'f')
+      return c - 'a' + 10;
+  }
+  return 0;
+}
+
+/*******************************************************************************
+**
+** Function:    findConfigFilePathFromTransportConfigPaths()
+**
+** Description: find a config file path with a given config name from transport
+**              config paths
+**
+** Returns:     none
+**
+*******************************************************************************/
+void findConfigFilePathFromTransportConfigPaths(const string& configName,
+                                                string& filePath) {
+  for (int i = 0; i < transport_config_path_size - 1; i++) {
+    filePath.assign(transport_config_paths[i]);
+    filePath += configName;
+    struct stat file_stat;
+    if (stat(filePath.c_str(), &file_stat) == 0 && S_ISREG(file_stat.st_mode)) {
+      return;
+    }
+  }
+  filePath.assign(transport_config_paths[transport_config_path_size - 1]);
+  filePath += configName;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::readConfig()
+**
+** Description: read Config settings and parse them into a linked list
+**              move the element from linked list to a array at the end
+**
+** Returns:     none
+**
+*******************************************************************************/
+bool CNfcConfig::readConfig(const char* name, bool bResetContent) {
+  enum {
+    BEGIN_LINE = 1,
+    TOKEN,
+    STR_VALUE,
+    NUM_VALUE,
+    BEGIN_HEX,
+    BEGIN_QUOTE,
+    END_LINE
+  };
+
+  FILE* fd = NULL;
+  string token;
+  string strValue;
+  unsigned long numValue = 0;
+  CNfcParam* pParam = NULL;
+  int i = 0;
+  int base = 0;
+  char c = 0;
+#if (NXP_EXTNS == TRUE)
+  mCurrentFile = name;
+#endif
+
+  state = BEGIN_LINE;
+  /* open config file, read it into a buffer */
+  if ((fd = fopen(name, "rb")) == NULL) {
+    ALOGD("%s Cannot open config file %s\n", __func__, name);
+    if (bResetContent) {
+      ALOGD("%s Using default value for all settings\n", __func__);
+      mValidFile = false;
+    }
+    return false;
+  }
+  ALOGD("%s Opened %s config %s\n", __func__,
+        (bResetContent ? "base" : "optional"), name);
+
+  mValidFile = true;
+  if (size() > 0) {
+    if (bResetContent)
+      clean();
+    else
+      moveToList();
+  }
+
+  for (;;) {
+    if (feof(fd) || fread(&c, 1, 1, fd) != 1) {
+      if (state == BEGIN_LINE) break;
+
+      // got to the EOF but not in BEGIN_LINE state so the file
+      // probably does not end with a newline, so the parser has
+      // not processed current line, simulate a newline in the file
+      c = '\n';
+    }
+
+    switch (state & 0xff) {
+      case BEGIN_LINE:
+        if (c == '#')
+          state = END_LINE;
+        else if (isPrintable(c)) {
+          i = 0;
+          token.erase();
+          strValue.erase();
+          state = TOKEN;
+          token.push_back(c);
+        }
+        break;
+      case TOKEN:
+        if (c == '=') {
+          token.push_back('\0');
+          state = BEGIN_QUOTE;
+        } else if (isPrintable(c))
+          token.push_back(c);
+        else
+          state = END_LINE;
+        break;
+      case BEGIN_QUOTE:
+        if (c == '"') {
+          state = STR_VALUE;
+          base = 0;
+        } else if (c == '0')
+          state = BEGIN_HEX;
+        else if (isDigit(c, 10)) {
+          state = NUM_VALUE;
+          base = 10;
+          numValue = getDigitValue(c, base);
+          i = 0;
+        } else if (c == '{') {
+          state = NUM_VALUE;
+          base = 16;
+          i = 0;
+          Set(IsStringValue);
+        } else
+          state = END_LINE;
+        break;
+      case BEGIN_HEX:
+        if (c == 'x' || c == 'X') {
+          state = NUM_VALUE;
+          base = 16;
+          numValue = 0;
+          i = 0;
+          break;
+        } else if (isDigit(c, 10)) {
+          state = NUM_VALUE;
+          base = 10;
+          numValue = getDigitValue(c, base);
+          break;
+        } else if (c != '\n' && c != '\r') {
+          state = END_LINE;
+          break;
+        }
+      // fal through to numValue to handle numValue
+
+      case NUM_VALUE:
+        if (isDigit(c, base)) {
+          numValue *= base;
+          numValue += getDigitValue(c, base);
+          ++i;
+        } else if (base == 16 &&
+                   (c == ':' || c == '-' || c == ' ' || c == '}')) {
+          if (i > 0) {
+            int n = (i + 1) / 2;
+            while (n-- > 0) {
+              unsigned char c = (numValue >> (n * 8)) & 0xFF;
+              strValue.push_back(c);
+            }
+          }
+          Set(IsStringValue);
+          numValue = 0;
+          i = 0;
+        } else {
+          if (c == '\n' || c == '\r')
+            state = BEGIN_LINE;
+          else
+            state = END_LINE;
+          if (Is(IsStringValue) && base == 16 && i > 0) {
+            int n = (i + 1) / 2;
+            while (n-- > 0) strValue.push_back(((numValue >> (n * 8)) & 0xFF));
+          }
+          if (strValue.length() > 0)
+            pParam = new CNfcParam(token.c_str(), strValue);
+          else
+            pParam = new CNfcParam(token.c_str(), numValue);
+          add(pParam);
+          strValue.erase();
+          numValue = 0;
+        }
+        break;
+      case STR_VALUE:
+        if (c == '"') {
+          strValue.push_back('\0');
+          state = END_LINE;
+          pParam = new CNfcParam(token.c_str(), strValue);
+          add(pParam);
+        } else if (isPrintable(c))
+          strValue.push_back(c);
+        break;
+      case END_LINE:
+        if (c == '\n' || c == '\r') state = BEGIN_LINE;
+        break;
+      default:
+        break;
+    }
+
+    if (feof(fd)) break;
+  }
+
+  fclose(fd);
+
+  moveFromList();
+  return size() > 0;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::CNfcConfig()
+**
+** Description: class constructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcConfig::CNfcConfig() : mValidFile(true), 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;
+    findConfigFilePathFromTransportConfigPaths(config_name, strPath);
+    theInstance.readConfig(strPath.c_str(), true);
+#if (NXP_EXTNS == TRUE)
+    readOptionalConfigExt("nxp");
+    theInstance.readNxpTransitConfig("nxpTransit");
+#endif
+  }
+
+  return theInstance;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::getValue()
+**
+** Description: get a string value of a setting
+**
+** Returns:     true if setting exists
+**              false if setting does not exist
+**
+*******************************************************************************/
+bool CNfcConfig::getValue(const char* name, char* pValue, size_t& len) const {
+  const CNfcParam* pParam = find(name);
+  if (pParam == NULL) return false;
+
+  if (pParam->str_len() > 0) {
+    memset(pValue, 0, len);
+    if (len > pParam->str_len()) len = pParam->str_len();
+    memcpy(pValue, pParam->str_value(), len);
+    return true;
+  }
+  return false;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::getValue()
+**
+** Description: get a long numerical value of a setting
+**
+** Returns:     true if setting exists
+**              false if setting does not exist
+**
+*******************************************************************************/
+bool CNfcConfig::getValue(const char* name, unsigned long& rValue) const {
+  const CNfcParam* pParam = find(name);
+  if (pParam == NULL) return false;
+
+  if (pParam->str_len() == 0) {
+    rValue = static_cast<unsigned long>(pParam->numValue());
+    return true;
+  }
+  return false;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::getValue()
+**
+** Description: get a short numerical value of a setting
+**
+** Returns:     true if setting exists
+**              false if setting does not exist
+**
+*******************************************************************************/
+bool CNfcConfig::getValue(const char* name, unsigned short& rValue) const {
+  const CNfcParam* pParam = find(name);
+  if (pParam == NULL) return false;
+
+  if (pParam->str_len() == 0) {
+    rValue = static_cast<unsigned short>(pParam->numValue());
+    return true;
+  }
+  return false;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::find()
+**
+** Description: search if a setting exist in the setting array
+**
+** Returns:     pointer to the setting object
+**
+*******************************************************************************/
+const CNfcParam* CNfcConfig::find(const char* p_name) const {
+  if (size() == 0) return NULL;
+
+  for (const_iterator it = begin(), itEnd = end(); it != itEnd; ++it) {
+    if (**it < p_name)
+      continue;
+    else if (**it == p_name) {
+      if ((*it)->str_len() > 0)
+        ALOGD("%s found %s=%s\n", __func__, p_name, (*it)->str_value());
+      else
+        ALOGD("%s found %s=(0x%lX)\n", __func__, p_name, (*it)->numValue());
+      return *it;
+    } else
+      break;
+  }
+  return NULL;
+}
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function:    CNfcConfig::readNxpTransitConfig()
+**
+** Description: read Config settings from transit conf file
+**
+** Returns:     none
+**
+*******************************************************************************/
+void CNfcConfig::readNxpTransitConfig(const char* fileName) const {
+  string strPath;
+  strPath.assign(transit_config_path);
+  strPath += extra_config_base;
+  strPath += fileName;
+  strPath += extra_config_ext;
+  CNfcConfig::GetInstance().readConfig(strPath.c_str(), false);
+}
+#endif
+
+/*******************************************************************************
+**
+** 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;
+  }
+#if (NXP_EXTNS == TRUE)
+  if ((mCurrentFile.find("nxpTransit") != std::string::npos) &&
+      !isAllowed(pParam->c_str())) {
+    ALOGD("%s Token restricted. Returning", __func__);
+    return;
+  }
+#endif
+  for (list<const CNfcParam*>::iterator it = m_list.begin(),
+                                        itEnd = m_list.end();
+       it != itEnd; ++it) {
+    if (**it < pParam->c_str()) continue;
+#if (NXP_EXTNS == TRUE)
+    /*If pParam->c_str() already exist in the list replace it*/
+    if (**it == pParam->c_str())
+      m_list.insert(m_list.erase(it), pParam);
+    else
+      m_list.insert(it, pParam);
+#else
+    m_list.insert(it, pParam);
+#endif
+    return;
+  }
+  m_list.push_back(pParam);
+}
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function:    CNfcConfig::dump()
+**
+** Description: prints all elements in the list
+**
+** Returns:     none
+**
+*******************************************************************************/
+void CNfcConfig::dump() {
+  ALOGD("%s Enter", __func__);
+
+  for (list<const CNfcParam*>::iterator it = m_list.begin(),
+                                        itEnd = m_list.end();
+       it != itEnd; ++it) {
+    if ((*it)->str_len() > 0)
+      ALOGD("%s %s \t= %s", __func__, (*it)->c_str(), (*it)->str_value());
+    else
+      ALOGD("%s %s \t= (0x%0lX)\n", __func__, (*it)->c_str(),
+            (*it)->numValue());
+  }
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::isAllowed()
+**
+** Description: checks if token update is allowed
+**
+** Returns:     true if allowed else false
+**
+*******************************************************************************/
+bool CNfcConfig::isAllowed(const char* name) {
+  string token(name);
+  bool stat = false;
+  if ((token.find("P2P_LISTEN_TECH_MASK") != std::string::npos) ||
+      (token.find("HOST_LISTEN_TECH_MASK") != std::string::npos) ||
+      (token.find("UICC_LISTEN_TECH_MASK") != std::string::npos) ||
+      (token.find("NXP_ESE_LISTEN_TECH_MASK") != std::string::npos) ||
+      (token.find("POLLING_TECH_MASK") != std::string::npos) ||
+      (token.find("NXP_RF_CONF_BLK") != std::string::npos) ||
+      (token.find("NXP_CN_TRANSIT_BLK_NUM_CHECK_ENABLE") !=
+       std::string::npos) ||
+      (token.find("NXP_FWD_FUNCTIONALITY_ENABLE") != std::string::npos))
+
+  {
+    stat = true;
+  }
+  return stat;
+}
+#endif
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::moveFromList()
+**
+** Description: move the setting object from list to array
+**
+** Returns:     none
+**
+*******************************************************************************/
+void CNfcConfig::moveFromList() {
+  if (m_list.size() == 0) return;
+
+  for (list<const CNfcParam*>::iterator it = m_list.begin(),
+                                        itEnd = m_list.end();
+       it != itEnd; ++it)
+    push_back(*it);
+  m_list.clear();
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::moveToList()
+**
+** Description: move the setting object from array to list
+**
+** Returns:     none
+**
+*******************************************************************************/
+void CNfcConfig::moveToList() {
+  if (m_list.size() != 0) m_list.clear();
+
+  for (iterator it = begin(), itEnd = end(); it != itEnd; ++it)
+    m_list.push_back(*it);
+  clear();
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcParam::CNfcParam()
+**
+** Description: class constructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcParam::CNfcParam() : m_numValue(0) {}
+
+/*******************************************************************************
+**
+** Function:    CNfcParam::~CNfcParam()
+**
+** Description: class destructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcParam::~CNfcParam() {}
+
+/*******************************************************************************
+**
+** Function:    CNfcParam::CNfcParam()
+**
+** Description: class copy constructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcParam::CNfcParam(const char* name, const string& value)
+    : string(name), m_str_value(value), m_numValue(0) {}
+
+/*******************************************************************************
+**
+** Function:    CNfcParam::CNfcParam()
+**
+** Description: class copy constructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcParam::CNfcParam(const char* name, unsigned long value)
+    : string(name), m_numValue(value) {}
+
+/*******************************************************************************
+**
+** Function:    GetStrValue
+**
+** Description: API function for getting a string value of a setting
+**
+** Returns:     none
+**
+*******************************************************************************/
+extern "C" int GetStrValue(const char* name, char* pValue, unsigned long l) {
+  size_t len = l;
+  CNfcConfig& rConfig = CNfcConfig::GetInstance();
+
+  bool b = rConfig.getValue(name, pValue, len);
+  return b ? len : 0;
+}
+
+/*******************************************************************************
+**
+** Function:    GetNumValue
+**
+** Description: API function for getting a numerical value of a setting
+**
+** Returns:     none
+**
+*******************************************************************************/
+extern "C" int GetNumValue(const char* name, void* pValue, unsigned long len) {
+  if (!pValue) return false;
+
+  CNfcConfig& rConfig = CNfcConfig::GetInstance();
+  const CNfcParam* pParam = rConfig.find(name);
+
+  if (pParam == NULL) return false;
+  unsigned long v = pParam->numValue();
+  if (v == 0 && pParam->str_len() > 0 && pParam->str_len() < 4) {
+    const unsigned char* p = (const unsigned char*)pParam->str_value();
+    for (size_t i = 0; i < pParam->str_len(); ++i) {
+      v *= 256;
+      v += *p++;
+    }
+  }
+  switch (len) {
+    case sizeof(unsigned long):
+      *(static_cast<unsigned long*>(pValue)) = (unsigned long)v;
+      break;
+    case sizeof(unsigned short):
+      *(static_cast<unsigned short*>(pValue)) = (unsigned short)v;
+      break;
+    case sizeof(unsigned char):
+      *(static_cast<unsigned char*>(pValue)) = (unsigned char)v;
+      break;
+    default:
+      return false;
+  }
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function:    resetConfig
+**
+** Description: reset settings array
+**
+** Returns:     none
+**
+*******************************************************************************/
+extern void resetConfig() {
+  CNfcConfig& rConfig = CNfcConfig::GetInstance();
+
+  rConfig.clean();
+}
+
+/*******************************************************************************
+**
+** Function:    readOptionalConfig()
+**
+** Description: read Config settings from an optional conf file
+**
+** Returns:     none
+**
+*******************************************************************************/
+void readOptionalConfigExt(const char* extra) {
+  string strPath;
+  string configName(extra_config_base);
+  configName += extra;
+  configName += extra_config_ext;
+
+  findConfigFilePathFromTransportConfigPaths(configName, strPath);
+  CNfcConfig::GetInstance().readConfig(strPath.c_str(), false);
+}
diff --git a/src/adaptation/libmain.c b/src/adaptation/libmain.c
new file mode 100644
index 0000000..c4ad050
--- /dev/null
+++ b/src/adaptation/libmain.c
@@ -0,0 +1,251 @@
+/******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 2011-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "_OverrideLog.h"
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <nfa_nv_ci.h>
+#include "buildcfg.h"
+#include "nfa_nv_co.h"
+#include "config.h"
+#include "nfc_hal_target.h"
+#include "nfc_hal_nv_co.h"
+#include "CrcChecksum.h"
+extern char bcm_nfc_location[];
+static const char* sNfaStorageBin = "/nfaStorage.bin";
+
+/*******************************************************************************
+**
+** Function         nfa_mem_co_alloc
+**
+** Description      allocate a buffer from platform's memory pool
+**
+** Returns:
+**                  pointer to buffer if successful
+**                  NULL otherwise
+**
+*******************************************************************************/
+extern void* nfa_mem_co_alloc(uint32_t num_bytes) { return malloc(num_bytes); }
+
+/*******************************************************************************
+**
+** Function         nfa_mem_co_free
+**
+** Description      free buffer previously allocated using nfa_mem_co_alloc
+**
+** Returns:
+**                  Nothing
+**
+*******************************************************************************/
+extern void nfa_mem_co_free(void* pBuffer) { free(pBuffer); }
+
+/*******************************************************************************
+**
+** Function         nfa_nv_co_read
+**
+** Description      This function is called by NFA to read in data from the
+**                  previously opened file.
+**
+** Parameters       pBuffer   - buffer to read the data into.
+**                  nbytes  - number of bytes to read into the buffer.
+**
+** Returns          void
+**
+**                  Note: Upon completion of the request, nfa_nv_ci_read() is
+**                        called with the buffer of data, along with the number
+**                        of bytes read into the buffer, and a status.  The
+**                        call-in function should only be called when ALL
+**                        requested bytes have been read, the end of file has
+**                        been detected, or an error has occurred.
+**
+*******************************************************************************/
+extern void nfa_nv_co_read(uint8_t* pBuffer, uint16_t nbytes, uint8_t block) {
+  char filename[256], filename2[256];
+
+  memset(filename, 0, sizeof(filename));
+  memset(filename2, 0, sizeof(filename2));
+  strlcpy(filename2, bcm_nfc_location, sizeof(filename2));
+  strlcat(filename2, sNfaStorageBin, sizeof(filename2)-strlen(filename2)-1);
+  if (strlen(filename2) > 200) {
+    ALOGE("%s: filename too long", __func__);
+    return;
+  }
+  snprintf (filename, 256, "%s%u", filename2, block);
+
+  ALOGD("%s: buffer len=%u; file=%s", __func__, nbytes, filename);
+  int fileStream = open(filename, O_RDONLY);
+  if (fileStream >= 0) {
+    unsigned short checksum = 0;
+    size_t actualReadCrc = read(fileStream, &checksum, sizeof(checksum));
+    size_t actualReadData = read(fileStream, pBuffer, nbytes);
+    close(fileStream);
+    if (actualReadData > 0) {
+      ALOGD("%s: data size=%zu", __func__, actualReadData);
+      nfa_nv_ci_read(actualReadData, NFA_NV_CO_OK, block);
+    } else {
+      ALOGE("%s: fail to read", __func__);
+      nfa_nv_ci_read(0, NFA_NV_CO_FAIL, block);
+    }
+  } else {
+    ALOGD("%s: fail to open", __func__);
+    nfa_nv_ci_read(0, NFA_NV_CO_FAIL, block);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_nv_co_write
+**
+** Description      This function is called by io to send file data to the
+**                  phone.
+**
+** Parameters       pBuffer   - buffer to read the data from.
+**                  nbytes  - number of bytes to write out to the file.
+**
+** Returns          void
+**
+**                  Note: Upon completion of the request, nfa_nv_ci_write() is
+**                        called with the file descriptor and the status.  The
+**                        call-in function should only be called when ALL
+**                        requested bytes have been written, or an error has
+**                        been detected,
+**
+*******************************************************************************/
+extern void nfa_nv_co_write(const uint8_t* pBuffer, uint16_t nbytes,
+                            uint8_t block) {
+  char filename[256], filename2[256];
+
+  memset(filename, 0, sizeof(filename));
+  memset(filename2, 0, sizeof(filename2));
+  strlcpy(filename2, bcm_nfc_location, sizeof(filename2));
+  strlcat(filename2, sNfaStorageBin, sizeof(filename2)-strlen(filename2)-1);
+  if (strlen(filename2) > 200) {
+    ALOGE("%s: filename too long", __func__);
+    return;
+  }
+  snprintf (filename, 256, "%s%u", filename2, block);
+  ALOGD("%s: bytes=%u; file=%s", __func__, nbytes, filename);
+
+  int fileStream = 0;
+
+  fileStream = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
+  if (fileStream >= 0) {
+    unsigned short checksum = crcChecksumCompute(pBuffer, nbytes);
+    size_t actualWrittenCrc = write(fileStream, &checksum, sizeof(checksum));
+    size_t actualWrittenData = write(fileStream, pBuffer, nbytes);
+    ALOGD("%s: %zu bytes written", __func__, actualWrittenData);
+    if ((actualWrittenData == nbytes) &&
+        (actualWrittenCrc == sizeof(checksum))) {
+      nfa_nv_ci_write(NFA_NV_CO_OK);
+    } else {
+      ALOGE("%s: fail to write", __func__);
+      nfa_nv_ci_write(NFA_NV_CO_FAIL);
+    }
+    close(fileStream);
+  } else {
+    ALOGE("%s: fail to open, error = %d", __func__, errno);
+    nfa_nv_ci_write(NFA_NV_CO_FAIL);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         delete_stack_non_volatile_store
+**
+** Description      Delete all the content of the stack's storage location.
+**
+** Parameters       forceDelete: unconditionally delete the storage.
+**
+** Returns          none
+**
+*******************************************************************************/
+void delete_stack_non_volatile_store(bool forceDelete) {
+  static bool firstTime = true;
+  char filename[256], filename2[256];
+
+  if ((firstTime == false) && (forceDelete == false)) return;
+  firstTime = false;
+
+  ALOGD("%s", __func__);
+
+  memset(filename, 0, sizeof(filename));
+  memset(filename2, 0, sizeof(filename2));
+  strlcpy(filename2, bcm_nfc_location, sizeof(filename2));
+  strlcat(filename2, sNfaStorageBin, sizeof(filename2)-strlen(filename2)-1);
+  if (strlen(filename2) > 200) {
+    ALOGE("%s: filename too long", __func__);
+    return;
+  }
+  snprintf (filename, 256, "%s%u", filename2, DH_NV_BLOCK);
+  remove(filename);
+  snprintf (filename, 256, "%s%u", filename2, HC_F3_NV_BLOCK);
+  remove(filename);
+  snprintf (filename, 256, "%s%u", filename2, HC_F4_NV_BLOCK);
+  remove(filename);
+  snprintf (filename, 256, "%s%u", filename2, HC_F2_NV_BLOCK);
+  remove(filename);
+  snprintf (filename, 256, "%s%u", filename2, HC_F5_NV_BLOCK);
+  remove(filename);
+}
+
+/*******************************************************************************
+**
+** Function         verify_stack_non_volatile_store
+**
+** Description      Verify the content of all non-volatile store.
+**
+** Parameters       none
+**
+** Returns          none
+**
+*******************************************************************************/
+void verify_stack_non_volatile_store() {
+  ALOGD("%s", __func__);
+  char filename[256], filename2[256];
+  bool isValid = false;
+
+  memset(filename, 0, sizeof(filename));
+  memset(filename2, 0, sizeof(filename2));
+  strlcpy(filename2, bcm_nfc_location, sizeof(filename2));
+  strlcat(filename2, sNfaStorageBin, sizeof(filename2)-strlen(filename2)-1);
+  if (strlen(filename2) > 200) {
+    ALOGE("%s: filename too long", __func__);
+    return;
+  }
+
+  snprintf (filename, 256, "%s%u", filename2, DH_NV_BLOCK);
+  if (crcChecksumVerifyIntegrity(filename)) {
+    snprintf (filename, 256, "%s%u", filename2, HC_F3_NV_BLOCK);
+    if (crcChecksumVerifyIntegrity(filename)) {
+      snprintf (filename, 256, "%s%u", filename2, HC_F4_NV_BLOCK);
+      if (crcChecksumVerifyIntegrity(filename)) {
+        snprintf (filename, 256, "%s%u", filename2, HC_F2_NV_BLOCK);
+        if (crcChecksumVerifyIntegrity(filename)) {
+          snprintf (filename, 256, "%s%u", filename2, HC_F5_NV_BLOCK);
+          if (crcChecksumVerifyIntegrity(filename)) isValid = true;
+        }
+      }
+    }
+  }
+
+  if (isValid == false) delete_stack_non_volatile_store(true);
+}
diff --git a/src/gki/common/gki.h b/src/gki/common/gki.h
new file mode 100644
index 0000000..bc05315
--- /dev/null
+++ b/src/gki/common/gki.h
@@ -0,0 +1,485 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef GKI_H
+#define GKI_H
+
+#ifdef BUILDCFG
+#include "buildcfg.h"
+#endif
+
+#ifndef NFC_STANDALONE
+#define NFC_STANDALONE false
+#endif
+
+#include "bt_types.h"
+#include "gki_target.h"
+
+/* Uncomment this line for verbose GKI debugging and buffer tracking */
+#define GKI_BUFFER_DEBUG false
+
+/* Error codes */
+#define GKI_SUCCESS 0x00
+#define GKI_FAILURE 0x01
+#define GKI_INVALID_TASK 0xF0
+#define GKI_INVALID_POOL 0xFF
+
+/************************************************************************
+** Mailbox definitions. Each task has 4 mailboxes that are used to
+** send buffers to the task.
+*/
+#define TASK_MBOX_0 0
+#define TASK_MBOX_1 1
+#define TASK_MBOX_2 2
+#define TASK_MBOX_3 3
+
+#define NUM_TASK_MBOX 4
+
+/************************************************************************
+** Event definitions.
+**
+** There are 4 reserved events used to signal messages rcvd in task mailboxes.
+** There are 4 reserved events used to signal timeout events.
+** There are 8 general purpose events available for applications.
+*/
+#define MAX_EVENTS 16
+
+#define TASK_MBOX_0_EVT_MASK 0x0001
+#define TASK_MBOX_1_EVT_MASK 0x0002
+#define TASK_MBOX_2_EVT_MASK 0x0004
+#define TASK_MBOX_3_EVT_MASK 0x0008
+
+#define TIMER_0 0
+#define TIMER_1 1
+#define TIMER_2 2
+#define TIMER_3 3
+
+#define TIMER_0_EVT_MASK 0x0010
+#define TIMER_1_EVT_MASK 0x0020
+#define TIMER_2_EVT_MASK 0x0040
+#define TIMER_3_EVT_MASK 0x0080
+
+#define APPL_EVT_0 8
+#define APPL_EVT_1 9
+#define APPL_EVT_2 10
+#define APPL_EVT_3 11
+#define APPL_EVT_4 12
+#define APPL_EVT_5 13
+#define APPL_EVT_6 14
+#define APPL_EVT_7 15
+
+#define EVENT_MASK(evt) ((uint16_t)(0x0001 << (evt)))
+
+/************************************************************************
+**  Max Time Queue
+**/
+#ifndef GKI_MAX_TIMER_QUEUES
+#define GKI_MAX_TIMER_QUEUES 3
+#endif
+
+/************************************************************************
+**  Utility macros for timer conversion
+**/
+#ifdef TICKS_PER_SEC
+#define GKI_MS_TO_TICKS(x) ((x) / (1000 / TICKS_PER_SEC))
+#define GKI_SECS_TO_TICKS(x) ((x) * (TICKS_PER_SEC))
+#define GKI_TICKS_TO_MS(x) ((x) * (1000 / TICKS_PER_SEC))
+#define GKI_TICKS_TO_SECS(x) ((x) * (1 / TICKS_PER_SEC))
+#endif
+
+/************************************************************************
+**  Macro to determine the pool buffer size based on the GKI POOL ID at compile
+**  time. Pool IDs index from 0 to GKI_NUM_FIXED_BUF_POOLS - 1
+*/
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 1)
+
+#ifndef GKI_POOL_ID_0
+#define GKI_POOL_ID_0 0
+#endif /* ifndef GKI_POOL_ID_0 */
+
+#ifndef GKI_BUF0_SIZE
+#define GKI_BUF0_SIZE 0
+#endif /* ifndef GKI_BUF0_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 1 */
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 2)
+
+#ifndef GKI_POOL_ID_1
+#define GKI_POOL_ID_1 0
+#endif /* ifndef GKI_POOL_ID_1 */
+
+#ifndef GKI_BUF1_SIZE
+#define GKI_BUF1_SIZE 0
+#endif /* ifndef GKI_BUF1_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 2 */
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 3)
+
+#ifndef GKI_POOL_ID_2
+#define GKI_POOL_ID_2 0
+#endif /* ifndef GKI_POOL_ID_2 */
+
+#ifndef GKI_BUF2_SIZE
+#define GKI_BUF2_SIZE 0
+#endif /* ifndef GKI_BUF2_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 3 */
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 4)
+
+#ifndef GKI_POOL_ID_3
+#define GKI_POOL_ID_3 0
+#endif /* ifndef GKI_POOL_ID_4 */
+
+#ifndef GKI_BUF3_SIZE
+#define GKI_BUF3_SIZE 0
+#endif /* ifndef GKI_BUF3_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 4 */
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 5)
+
+#ifndef GKI_POOL_ID_4
+#define GKI_POOL_ID_4 0
+#endif /* ifndef GKI_POOL_ID_4 */
+
+#ifndef GKI_BUF4_SIZE
+#define GKI_BUF4_SIZE 0
+#endif /* ifndef GKI_BUF4_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 5 */
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 6)
+
+#ifndef GKI_POOL_ID_5
+#define GKI_POOL_ID_5 0
+#endif /* ifndef GKI_POOL_ID_5 */
+
+#ifndef GKI_BUF5_SIZE
+#define GKI_BUF5_SIZE 0
+#endif /* ifndef GKI_BUF5_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 6 */
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 7)
+
+#ifndef GKI_POOL_ID_6
+#define GKI_POOL_ID_6 0
+#endif /* ifndef GKI_POOL_ID_6 */
+
+#ifndef GKI_BUF6_SIZE
+#define GKI_BUF6_SIZE 0
+#endif /* ifndef GKI_BUF6_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 7 */
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 8)
+
+#ifndef GKI_POOL_ID_7
+#define GKI_POOL_ID_7 0
+#endif /* ifndef GKI_POOL_ID_7 */
+
+#ifndef GKI_BUF7_SIZE
+#define GKI_BUF7_SIZE 0
+#endif /* ifndef GKI_BUF7_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 8 */
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 9)
+
+#ifndef GKI_POOL_ID_8
+#define GKI_POOL_ID_8 0
+#endif /* ifndef GKI_POOL_ID_8 */
+
+#ifndef GKI_BUF8_SIZE
+#define GKI_BUF8_SIZE 0
+#endif /* ifndef GKI_BUF8_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 9 */
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 10)
+
+#ifndef GKI_POOL_ID_9
+#define GKI_POOL_ID_9 0
+#endif /* ifndef GKI_POOL_ID_9 */
+
+#ifndef GKI_BUF9_SIZE
+#define GKI_BUF9_SIZE 0
+#endif /* ifndef GKI_BUF9_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 10 */
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 11)
+
+#ifndef GKI_POOL_ID_10
+#define GKI_POOL_ID_10 0
+#endif /* ifndef GKI_POOL_ID_10 */
+
+#ifndef GKI_BUF10_SIZE
+#define GKI_BUF10_SIZE 0
+#endif /* ifndef GKI_BUF10_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 11 */
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 12)
+
+#ifndef GKI_POOL_ID_11
+#define GKI_POOL_ID_11 0
+#endif /* ifndef GKI_POOL_ID_11 */
+
+#ifndef GKI_BUF11_SIZE
+#define GKI_BUF11_SIZE 0
+#endif /* ifndef GKI_BUF11_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 12 */
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 13)
+
+#ifndef GKI_POOL_ID_12
+#define GKI_POOL_ID_12 0
+#endif /* ifndef GKI_POOL_ID_12 */
+
+#ifndef GKI_BUF12_SIZE
+#define GKI_BUF12_SIZE 0
+#endif /* ifndef GKI_BUF12_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 13 */
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 14)
+
+#ifndef GKI_POOL_ID_13
+#define GKI_POOL_ID_13 0
+#endif /* ifndef GKI_POOL_ID_13 */
+
+#ifndef GKI_BUF13_SIZE
+#define GKI_BUF13_SIZE 0
+#endif /* ifndef GKI_BUF13_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 14 */
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 15)
+
+#ifndef GKI_POOL_ID_14
+#define GKI_POOL_ID_14 0
+#endif /* ifndef GKI_POOL_ID_14 */
+
+#ifndef GKI_BUF14_SIZE
+#define GKI_BUF14_SIZE 0
+#endif /* ifndef GKI_BUF14_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 15 */
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 16)
+
+#ifndef GKI_POOL_ID_15
+#define GKI_POOL_ID_15 0
+#endif /* ifndef GKI_POOL_ID_15 */
+
+#ifndef GKI_BUF15_SIZE
+#define GKI_BUF15_SIZE 0
+#endif /* ifndef GKI_BUF15_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 16 */
+
+#ifndef GKI_SHUTDOWN_EVT
+#define GKI_SHUTDOWN_EVT APPL_EVT_7
+#endif
+
+/* Timer list entry callback type
+*/
+typedef void(TIMER_CBACK)(void* p_tle);
+
+/* Define a timer list entry
+*/
+typedef struct _tle {
+  struct _tle* p_next;
+  struct _tle* p_prev;
+  TIMER_CBACK* p_cback;
+  int32_t ticks;
+  uintptr_t param;
+  uint16_t event;
+  uint8_t in_use;
+} TIMER_LIST_ENT;
+
+/* Define a timer list queue
+*/
+typedef struct {
+  TIMER_LIST_ENT* p_first;
+  TIMER_LIST_ENT* p_last;
+  int32_t last_ticks;
+} TIMER_LIST_Q;
+
+/***********************************************************************
+** This queue is a general purpose buffer queue, for application use.
+*/
+typedef struct {
+  void* p_first;
+  void* p_last;
+  uint16_t count;
+} BUFFER_Q;
+
+#define GKI_IS_QUEUE_EMPTY(p_q) ((p_q)->count == 0)
+
+/* Task constants
+*/
+#ifndef TASKPTR
+typedef void (*TASKPTR)(uint32_t);
+#endif
+
+/* General pool accessible to GKI_getbuf() */
+#define GKI_PUBLIC_POOL 0
+#define GKI_RESTRICTED_POOL 1 /* Inaccessible pool to GKI_getbuf() */
+
+/***********************************************************************
+** Function prototypes
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Task management
+*/
+extern uint8_t GKI_create_task(TASKPTR, uint8_t, int8_t*, uint16_t*, uint16_t,
+                               void*, void*);
+extern void GKI_exit_task(uint8_t);
+extern uint8_t GKI_get_taskid(void);
+extern void GKI_init(void);
+extern int8_t* GKI_map_taskname(uint8_t);
+extern uint8_t GKI_resume_task(uint8_t);
+extern void GKI_run(void*);
+extern void GKI_stop(void);
+extern uint8_t GKI_suspend_task(uint8_t);
+extern uint8_t GKI_is_task_running(uint8_t);
+
+/* memory management
+*/
+extern void GKI_shiftdown(uint8_t* p_mem, uint32_t len, uint32_t shift_amount);
+extern void GKI_shiftup(uint8_t* p_dest, uint8_t* p_src, uint32_t len);
+
+/* To send buffers and events between tasks
+*/
+extern uint8_t GKI_isend_event(uint8_t, uint16_t);
+extern void GKI_isend_msg(uint8_t, uint8_t, void*);
+extern void* GKI_read_mbox(uint8_t);
+extern void GKI_send_msg(uint8_t, uint8_t, void*);
+extern uint8_t GKI_send_event(uint8_t, uint16_t);
+
+/* To get and release buffers, change owner and get size
+*/
+extern void GKI_change_buf_owner(void*, uint8_t);
+extern uint8_t GKI_create_pool(uint16_t, uint16_t, uint8_t, void*);
+extern void GKI_delete_pool(uint8_t);
+extern void* GKI_find_buf_start(void*);
+extern void GKI_freebuf(void*);
+#if (GKI_BUFFER_DEBUG == true)
+#define GKI_getbuf(size) GKI_getbuf_debug(size, __func__, __LINE__)
+extern void* GKI_getbuf_debug(uint16_t, const char*, int);
+#else
+extern void* GKI_getbuf(uint16_t);
+#endif
+extern uint16_t GKI_get_buf_size(void*);
+#if (GKI_BUFFER_DEBUG == true)
+#define GKI_getpoolbuf(id) GKI_getpoolbuf_debug(id, __func__, __LINE__)
+extern void* GKI_getpoolbuf_debug(uint8_t, const char*, int);
+#else
+extern void* GKI_getpoolbuf(uint8_t);
+#endif
+
+extern uint16_t GKI_poolcount(uint8_t);
+extern uint16_t GKI_poolfreecount(uint8_t);
+extern uint16_t GKI_poolutilization(uint8_t);
+extern void GKI_register_mempool(void* p_mem);
+extern uint8_t GKI_set_pool_permission(uint8_t, uint8_t);
+
+/* User buffer queue management
+*/
+extern void* GKI_dequeue(BUFFER_Q*);
+extern void GKI_enqueue(BUFFER_Q*, void*);
+extern void GKI_enqueue_head(BUFFER_Q*, void*);
+extern void* GKI_getfirst(BUFFER_Q*);
+extern void* GKI_getlast(BUFFER_Q*);
+extern void* GKI_getnext(void*);
+extern void GKI_init_q(BUFFER_Q*);
+extern bool GKI_queue_is_empty(BUFFER_Q*);
+extern void* GKI_remove_from_queue(BUFFER_Q*, void*);
+extern uint16_t GKI_get_pool_bufsize(uint8_t);
+
+/* Timer management
+*/
+extern void GKI_add_to_timer_list(TIMER_LIST_Q*, TIMER_LIST_ENT*);
+extern void GKI_delay(uint32_t);
+extern uint32_t GKI_get_tick_count(void);
+extern int8_t* GKI_get_time_stamp(int8_t*);
+extern void GKI_init_timer_list(TIMER_LIST_Q*);
+extern void GKI_init_timer_list_entry(TIMER_LIST_ENT*);
+extern int32_t GKI_ready_to_sleep(void);
+extern void GKI_remove_from_timer_list(TIMER_LIST_Q*, TIMER_LIST_ENT*);
+extern void GKI_start_timer(uint8_t, int32_t, bool);
+extern void GKI_stop_timer(uint8_t);
+extern void GKI_timer_update(int32_t);
+extern uint16_t GKI_update_timer_list(TIMER_LIST_Q*, int32_t);
+extern uint32_t GKI_get_remaining_ticks(TIMER_LIST_Q*, TIMER_LIST_ENT*);
+extern uint16_t GKI_wait(uint16_t, uint32_t);
+
+/* Start and Stop system time tick callback
+ * true for start system tick if time queue is not empty
+ * false to stop system tick if time queue is empty
+*/
+typedef void(SYSTEM_TICK_CBACK)(bool);
+
+/* Time queue management for system ticks
+*/
+extern bool GKI_timer_queue_empty(void);
+extern void GKI_timer_queue_register_callback(SYSTEM_TICK_CBACK*);
+
+/* Disable Interrupts, Enable Interrupts
+*/
+extern void GKI_enable(void);
+extern void GKI_disable(void);
+extern void GKI_sched_lock(void);
+extern void GKI_sched_unlock(void);
+
+/* Allocate (Free) memory from an OS
+*/
+extern void* GKI_os_malloc(uint32_t);
+extern void GKI_os_free(void*);
+
+/* os timer operation */
+extern uint32_t GKI_get_os_tick_count(void);
+
+/* Exception handling
+*/
+extern void GKI_exception(uint16_t, char*);
+
+#if (GKI_BUFFER_DEBUG == true)
+extern void GKI_PrintBufferUsage(uint8_t* p_num_pools, uint16_t* p_cur_used);
+extern void GKI_PrintBuffer(void);
+extern void GKI_print_task(void);
+#else
+#undef GKI_PrintBufferUsage
+#define GKI_PrintBuffer() NULL
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/gki/common/gki_buffer.c b/src/gki/common/gki_buffer.c
new file mode 100644
index 0000000..09f49e0
--- /dev/null
+++ b/src/gki/common/gki_buffer.c
@@ -0,0 +1,1479 @@
+/******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "gki_int.h"
+#include <stdio.h>
+
+#if (GKI_NUM_TOTAL_BUF_POOLS > 16)
+#error Number of pools out of range (16 Max)!
+#endif
+
+#if (BTU_STACK_LITE_ENABLED == false)
+static void gki_add_to_pool_list(uint8_t pool_id);
+static void gki_remove_from_pool_list(uint8_t pool_id);
+#endif /*  BTU_STACK_LITE_ENABLED == false */
+
+#if (GKI_BUFFER_DEBUG == true)
+#define LOG_TAG "GKI_DEBUG"
+#include <android/log.h>
+#include <cutils/log.h>
+#define LOGD(format, ...)                                       \
+  LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | \
+             TRACE_TYPE_GENERIC,                                \
+         format, ##__VA_ARGS__)
+#endif
+/*******************************************************************************
+**
+** Function         gki_init_free_queue
+**
+** Description      Internal function called at startup to initialize a free
+**                  queue. It is called once for each free queue.
+**
+** Returns          void
+**
+*******************************************************************************/
+static void gki_init_free_queue(uint8_t id, uint16_t size, uint16_t total,
+                                void* p_mem) {
+  uint16_t i;
+  uint16_t act_size;
+  BUFFER_HDR_T* hdr;
+  BUFFER_HDR_T* hdr1 = NULL;
+  uint32_t* magic;
+  int32_t tempsize = size;
+  tGKI_COM_CB* p_cb = &gki_cb.com;
+
+  /* Ensure an even number of longwords */
+  tempsize = (int32_t)ALIGN_POOL(size);
+  act_size = (uint16_t)(tempsize + BUFFER_PADDING_SIZE);
+
+  /* Remember pool start and end addresses */
+  if (p_mem) {
+    p_cb->pool_start[id] = (uint8_t*)p_mem;
+    p_cb->pool_end[id] = (uint8_t*)p_mem + (act_size * total);
+  }
+
+  p_cb->pool_size[id] = act_size;
+
+  p_cb->freeq[id].size = (uint16_t)tempsize;
+  p_cb->freeq[id].total = total;
+  p_cb->freeq[id].cur_cnt = 0;
+  p_cb->freeq[id].max_cnt = 0;
+
+#if (GKI_BUFFER_DEBUG == true)
+  LOGD(
+      "gki_init_free_queue() init pool=%d, size=%d (aligned=%d) total=%d "
+      "start=%p",
+      id, size, tempsize, total, p_mem);
+#endif
+
+  /* Initialize  index table */
+  if (p_mem) {
+    hdr = (BUFFER_HDR_T*)p_mem;
+    p_cb->freeq[id].p_first = hdr;
+    for (i = 0; i < total; i++) {
+      hdr->task_id = GKI_INVALID_TASK;
+      hdr->q_id = id;
+      hdr->status = BUF_STATUS_FREE;
+      magic = (uint32_t*)((uint8_t*)hdr + BUFFER_HDR_SIZE + tempsize);
+      *magic = MAGIC_NO;
+      hdr1 = hdr;
+      hdr = (BUFFER_HDR_T*)((uint8_t*)hdr + act_size);
+      hdr1->p_next = hdr;
+    }
+    if (hdr1 != NULL) hdr = hdr1;
+    hdr->p_next = NULL;
+    p_cb->freeq[id].p_last = hdr;
+  }
+  return;
+}
+
+#if (GKI_USE_DEFERED_ALLOC_BUF_POOLS == true)
+static bool gki_alloc_free_queue(uint8_t id) {
+  FREE_QUEUE_T* Q;
+  tGKI_COM_CB* p_cb = &gki_cb.com;
+#if (GKI_BUFFER_DEBUG == true)
+  ALOGD("\ngki_alloc_free_queue in, id:%d \n", id);
+#endif
+
+  Q = &p_cb->freeq[p_cb->pool_list[id]];
+
+  if (Q->p_first == 0) {
+    void* p_mem = GKI_os_malloc((Q->size + BUFFER_PADDING_SIZE) * Q->total);
+    if (p_mem) {
+// re-initialize the queue with allocated memory
+#if (GKI_BUFFER_DEBUG == true)
+      ALOGD(
+          "\ngki_alloc_free_queue calling  gki_init_free_queue, id:%d  "
+          "size:%d, totol:%d\n",
+          id, Q->size, Q->total);
+#endif
+      gki_init_free_queue(id, Q->size, Q->total, p_mem);
+#if (GKI_BUFFER_DEBUG == true)
+      ALOGD("\ngki_alloc_free_queue ret OK, id:%d  size:%d, totol:%d\n", id,
+            Q->size, Q->total);
+#endif
+      return true;
+    }
+    GKI_exception(GKI_ERROR_BUF_SIZE_TOOBIG,
+                  "gki_alloc_free_queue: Not enough memory");
+  }
+#if (GKI_BUFFER_DEBUG == true)
+  ALOGD("\ngki_alloc_free_queue out failed, id:%d\n", id);
+#endif
+  return false;
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         gki_buffer_init
+**
+** Description      Called once internally by GKI at startup to initialize all
+**                  buffers and free buffer pools.
+**
+** Returns          void
+**
+*******************************************************************************/
+void gki_buffer_init(void) {
+  uint8_t i, tt, mb;
+  tGKI_COM_CB* p_cb = &gki_cb.com;
+
+  /* Initialize mailboxes */
+  for (tt = 0; tt < GKI_MAX_TASKS; tt++) {
+    for (mb = 0; mb < NUM_TASK_MBOX; mb++) {
+      p_cb->OSTaskQFirst[tt][mb] = NULL;
+      p_cb->OSTaskQLast[tt][mb] = NULL;
+    }
+  }
+
+  for (tt = 0; tt < GKI_NUM_TOTAL_BUF_POOLS; tt++) {
+    p_cb->pool_start[tt] = NULL;
+    p_cb->pool_end[tt] = NULL;
+    p_cb->pool_size[tt] = 0;
+
+    p_cb->freeq[tt].p_first = 0;
+    p_cb->freeq[tt].p_last = 0;
+    p_cb->freeq[tt].size = 0;
+    p_cb->freeq[tt].total = 0;
+    p_cb->freeq[tt].cur_cnt = 0;
+    p_cb->freeq[tt].max_cnt = 0;
+  }
+
+  /* Use default from target.h */
+  p_cb->pool_access_mask = GKI_DEF_BUFPOOL_PERM_MASK;
+
+#if (GKI_USE_DEFERED_ALLOC_BUF_POOLS == false && \
+     GKI_USE_DYNAMIC_BUFFERS == true)
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 0)
+  p_cb->bufpool0 = (uint8_t*)GKI_os_malloc(
+      (GKI_BUF0_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF0_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 1)
+  p_cb->bufpool1 = (uint8_t*)GKI_os_malloc(
+      (GKI_BUF1_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF1_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 2)
+  p_cb->bufpool2 = (uint8_t*)GKI_os_malloc(
+      (GKI_BUF2_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF2_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 3)
+  p_cb->bufpool3 = (uint8_t*)GKI_os_malloc(
+      (GKI_BUF3_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF3_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 4)
+  p_cb->bufpool4 = (uint8_t*)GKI_os_malloc(
+      (GKI_BUF4_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF4_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 5)
+  p_cb->bufpool5 = (uint8_t*)GKI_os_malloc(
+      (GKI_BUF5_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF5_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 6)
+  p_cb->bufpool6 = (uint8_t*)GKI_os_malloc(
+      (GKI_BUF6_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF6_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 7)
+  p_cb->bufpool7 = (uint8_t*)GKI_os_malloc(
+      (GKI_BUF7_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF7_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 8)
+  p_cb->bufpool8 = (uint8_t*)GKI_os_malloc(
+      (GKI_BUF8_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF8_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 9)
+  p_cb->bufpool9 = (uint8_t*)GKI_os_malloc(
+      (GKI_BUF9_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF9_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 10)
+  p_cb->bufpool10 = (uint8_t*)GKI_os_malloc(
+      (GKI_BUF10_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF10_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 11)
+  p_cb->bufpool11 = (uint8_t*)GKI_os_malloc(
+      (GKI_BUF11_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF11_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 12)
+  p_cb->bufpool12 = (uint8_t*)GKI_os_malloc(
+      (GKI_BUF12_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF12_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 13)
+  p_cb->bufpool13 = (uint8_t*)GKI_os_malloc(
+      (GKI_BUF13_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF13_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 14)
+  p_cb->bufpool14 = (uint8_t*)GKI_os_malloc(
+      (GKI_BUF14_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF14_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 15)
+  p_cb->bufpool15 = (uint8_t*)GKI_os_malloc(
+      (GKI_BUF15_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF15_MAX);
+#endif
+
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 0)
+  gki_init_free_queue(0, GKI_BUF0_SIZE, GKI_BUF0_MAX, p_cb->bufpool0);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 1)
+  gki_init_free_queue(1, GKI_BUF1_SIZE, GKI_BUF1_MAX, p_cb->bufpool1);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 2)
+  gki_init_free_queue(2, GKI_BUF2_SIZE, GKI_BUF2_MAX, p_cb->bufpool2);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 3)
+  gki_init_free_queue(3, GKI_BUF3_SIZE, GKI_BUF3_MAX, p_cb->bufpool3);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 4)
+  gki_init_free_queue(4, GKI_BUF4_SIZE, GKI_BUF4_MAX, p_cb->bufpool4);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 5)
+  gki_init_free_queue(5, GKI_BUF5_SIZE, GKI_BUF5_MAX, p_cb->bufpool5);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 6)
+  gki_init_free_queue(6, GKI_BUF6_SIZE, GKI_BUF6_MAX, p_cb->bufpool6);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 7)
+  gki_init_free_queue(7, GKI_BUF7_SIZE, GKI_BUF7_MAX, p_cb->bufpool7);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 8)
+  gki_init_free_queue(8, GKI_BUF8_SIZE, GKI_BUF8_MAX, p_cb->bufpool8);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 9)
+  gki_init_free_queue(9, GKI_BUF9_SIZE, GKI_BUF9_MAX, p_cb->bufpool9);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 10)
+  gki_init_free_queue(10, GKI_BUF10_SIZE, GKI_BUF10_MAX, p_cb->bufpool10);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 11)
+  gki_init_free_queue(11, GKI_BUF11_SIZE, GKI_BUF11_MAX, p_cb->bufpool11);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 12)
+  gki_init_free_queue(12, GKI_BUF12_SIZE, GKI_BUF12_MAX, p_cb->bufpool12);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 13)
+  gki_init_free_queue(13, GKI_BUF13_SIZE, GKI_BUF13_MAX, p_cb->bufpool13);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 14)
+  gki_init_free_queue(14, GKI_BUF14_SIZE, GKI_BUF14_MAX, p_cb->bufpool14);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 15)
+  gki_init_free_queue(15, GKI_BUF15_SIZE, GKI_BUF15_MAX, p_cb->bufpool15);
+#endif
+
+  /* add pools to the pool_list which is arranged in the order of size */
+  for (i = 0; i < GKI_NUM_FIXED_BUF_POOLS; i++) {
+    p_cb->pool_list[i] = i;
+  }
+
+  p_cb->curr_total_no_of_pools = GKI_NUM_FIXED_BUF_POOLS;
+
+  return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_init_q
+**
+** Description      Called by an application to initialize a buffer queue.
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_init_q(BUFFER_Q* p_q) {
+  p_q->p_first = p_q->p_last = NULL;
+  p_q->count = 0;
+
+  return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_getbuf
+**
+** Description      Called by an application to get a free buffer which
+**                  is of size greater or equal to the requested size.
+**
+**                  Note: This routine only takes buffers from public pools.
+**                        It will not use any buffers from pools
+**                        marked GKI_RESTRICTED_POOL.
+**
+** Parameters       size - (input) number of bytes needed.
+**
+** Returns          A pointer to the buffer, or NULL if none available
+**
+*******************************************************************************/
+#if (GKI_BUFFER_DEBUG == true)
+void* GKI_getbuf_debug(uint16_t size, const char* _function_, int _line_)
+#else
+void* GKI_getbuf(uint16_t size)
+#endif
+{
+  uint8_t i;
+  FREE_QUEUE_T* Q;
+  BUFFER_HDR_T* p_hdr;
+  tGKI_COM_CB* p_cb = &gki_cb.com;
+#if (GKI_BUFFER_DEBUG == true)
+  uint8_t x;
+#endif
+
+  if (size == 0) {
+    GKI_exception(GKI_ERROR_BUF_SIZE_ZERO, "getbuf: Size is zero");
+    return (NULL);
+  }
+
+#if (GKI_BUFFER_DEBUG == true)
+  LOGD("GKI_getbuf() requesting %d func:%s(line=%d)", size, _function_, _line_);
+#endif
+  /* Find the first buffer pool that is public that can hold the desired size */
+  for (i = 0; i < p_cb->curr_total_no_of_pools; i++) {
+    if (size <= p_cb->freeq[p_cb->pool_list[i]].size) break;
+  }
+
+  if (i == p_cb->curr_total_no_of_pools) {
+    GKI_exception(GKI_ERROR_BUF_SIZE_TOOBIG, "getbuf: Size is too big");
+    return (NULL);
+  }
+
+  /* Make sure the buffers aren't disturbed til finished with allocation */
+  GKI_disable();
+
+  /* search the public buffer pools that are big enough to hold the size
+   * until a free buffer is found */
+  for (; i < p_cb->curr_total_no_of_pools; i++) {
+    /* Only look at PUBLIC buffer pools (bypass RESTRICTED pools) */
+    if (((uint16_t)1 << p_cb->pool_list[i]) & p_cb->pool_access_mask) continue;
+
+    Q = &p_cb->freeq[p_cb->pool_list[i]];
+    if (Q->cur_cnt < Q->total) {
+#if (GKI_USE_DEFERED_ALLOC_BUF_POOLS == true)
+      if (Q->p_first == 0 && gki_alloc_free_queue(i) != true) {
+        GKI_TRACE_ERROR_0("GKI_getbuf() out of buffer");
+        GKI_enable();
+        return NULL;
+      }
+#endif
+
+      if (Q->p_first == 0) {
+        /* gki_alloc_free_queue() failed to alloc memory */
+        GKI_TRACE_ERROR_0("GKI_getbuf() fail alloc free queue");
+        GKI_enable();
+        return NULL;
+      }
+
+      p_hdr = Q->p_first;
+      Q->p_first = p_hdr->p_next;
+
+      if (!Q->p_first) Q->p_last = NULL;
+
+      if (++Q->cur_cnt > Q->max_cnt) Q->max_cnt = Q->cur_cnt;
+
+      GKI_enable();
+
+      p_hdr->task_id = GKI_get_taskid();
+
+      p_hdr->status = BUF_STATUS_UNLINKED;
+      p_hdr->p_next = NULL;
+      p_hdr->Type = 0;
+#if (GKI_BUFFER_DEBUG == true)
+      LOGD("GKI_getbuf() allocated, %x, %x (%d of %d used) %d",
+           (uint8_t*)p_hdr + BUFFER_HDR_SIZE, p_hdr, Q->cur_cnt, Q->total,
+           p_cb->freeq[i].total);
+
+      strlcpy(p_hdr->_function, _function_, _GKI_MAX_FUNCTION_NAME_LEN);
+      p_hdr->_function[_GKI_MAX_FUNCTION_NAME_LEN] = '\0';
+      p_hdr->_line = _line_;
+#endif
+      return ((void*)((uint8_t*)p_hdr + BUFFER_HDR_SIZE));
+    }
+  }
+
+  GKI_TRACE_ERROR_0("GKI_getbuf() unable to allocate buffer!!!!!");
+#if (GKI_BUFFER_DEBUG == true)
+  LOGD("GKI_getbuf() unable to allocate buffer!!!!!");
+  LOGD("******************** GKI Memory Pool Dump ********************");
+
+  p_cb = &gki_cb.com;
+
+  LOGD("Dumping total of %d buffer pools", p_cb->curr_total_no_of_pools);
+
+  for (i = 0; i < p_cb->curr_total_no_of_pools; i++) {
+    p_hdr = (BUFFER_HDR_T*)p_cb->pool_start[i];
+
+    LOGD("pool %d has a total of %d buffers (start=%p)", i,
+         p_cb->freeq[i].total, p_hdr);
+
+    for (x = 0; p_hdr && x < p_cb->freeq[i].total; x++) {
+      if (p_hdr->status != BUF_STATUS_FREE) {
+        LOGD("pool:%d, buf[%d]:%x, hdr:%x status=%d func:%s(line=%d)", i, x,
+             (uint8_t*)p_hdr + BUFFER_HDR_SIZE, p_hdr, p_hdr->status,
+             p_hdr->_function, p_hdr->_line);
+      }
+
+      p_hdr = (BUFFER_HDR_T*)((uint8_t*)p_hdr + p_cb->pool_size[i]);
+    }
+  }
+  LOGD("**************************************************************");
+#endif
+
+  GKI_TRACE_ERROR_0("Failed to allocate GKI buffer");
+
+  GKI_enable();
+
+  return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_getpoolbuf
+**
+** Description      Called by an application to get a free buffer from
+**                  a specific buffer pool.
+**
+**                  Note: If there are no more buffers available from the pool,
+**                        the public buffers are searched for an available
+**                        buffer.
+**
+** Parameters       pool_id - (input) pool ID to get a buffer out of.
+**
+** Returns          A pointer to the buffer, or NULL if none available
+**
+*******************************************************************************/
+#if (GKI_BUFFER_DEBUG == true)
+void* GKI_getpoolbuf_debug(uint8_t pool_id, const char* _function_, int _line_)
+#else
+void* GKI_getpoolbuf(uint8_t pool_id)
+#endif
+{
+  FREE_QUEUE_T* Q;
+  BUFFER_HDR_T* p_hdr;
+  tGKI_COM_CB* p_cb = &gki_cb.com;
+
+  if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS) return (NULL);
+
+#if (GKI_BUFFER_DEBUG == true)
+  LOGD("GKI_getpoolbuf() requesting from %d func:%s(line=%d)", pool_id,
+       _function_, _line_);
+#endif
+  /* Make sure the buffers aren't disturbed til finished with allocation */
+  GKI_disable();
+
+  Q = &p_cb->freeq[pool_id];
+  if (Q->cur_cnt < Q->total) {
+#if (GKI_USE_DEFERED_ALLOC_BUF_POOLS == true)
+    if (Q->p_first == 0 && gki_alloc_free_queue(pool_id) != true) return NULL;
+#endif
+
+    if (Q->p_first == 0) {
+      /* gki_alloc_free_queue() failed to alloc memory */
+      GKI_TRACE_ERROR_0("GKI_getpoolbuf() fail alloc free queue");
+      return NULL;
+    }
+
+    p_hdr = Q->p_first;
+    Q->p_first = p_hdr->p_next;
+
+    if (!Q->p_first) Q->p_last = NULL;
+
+    if (++Q->cur_cnt > Q->max_cnt) Q->max_cnt = Q->cur_cnt;
+
+    GKI_enable();
+
+    p_hdr->task_id = GKI_get_taskid();
+
+    p_hdr->status = BUF_STATUS_UNLINKED;
+    p_hdr->p_next = NULL;
+    p_hdr->Type = 0;
+
+#if (GKI_BUFFER_DEBUG == true)
+    LOGD("GKI_getpoolbuf() allocated, %x, %x (%d of %d used) %d",
+         (uint8_t*)p_hdr + BUFFER_HDR_SIZE, p_hdr, Q->cur_cnt, Q->total,
+         p_cb->freeq[pool_id].total);
+
+    strlcpy(p_hdr->_function, _function_, _GKI_MAX_FUNCTION_NAME_LEN);
+    p_hdr->_function[_GKI_MAX_FUNCTION_NAME_LEN] = '\0';
+    p_hdr->_line = _line_;
+#endif
+    return ((void*)((uint8_t*)p_hdr + BUFFER_HDR_SIZE));
+  }
+
+  /* If here, no buffers in the specified pool */
+  GKI_enable();
+
+#if (GKI_BUFFER_DEBUG == true)
+  /* try for free buffers in public pools */
+  return (GKI_getbuf_debug(p_cb->freeq[pool_id].size, _function_, _line_));
+#else
+  /* try for free buffers in public pools */
+  return (GKI_getbuf(p_cb->freeq[pool_id].size));
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         GKI_freebuf
+**
+** Description      Called by an application to return a buffer to the free
+**                  pool.
+**
+** Parameters       p_buf - (input) address of the beginning of a buffer.
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_freebuf(void* p_buf) {
+  FREE_QUEUE_T* Q;
+  BUFFER_HDR_T* p_hdr;
+
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == true)
+  if (!p_buf || gki_chk_buf_damage(p_buf)) {
+    GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Free - Buf Corrupted");
+    return;
+  }
+#endif
+
+  p_hdr = (BUFFER_HDR_T*)((uint8_t*)p_buf - BUFFER_HDR_SIZE);
+
+#if (GKI_BUFFER_DEBUG == true)
+  LOGD("GKI_freebuf() freeing, %x, %x, func:%s(line=%d)", p_buf, p_hdr,
+       p_hdr->_function, p_hdr->_line);
+#endif
+
+  if (p_hdr->status != BUF_STATUS_UNLINKED) {
+    GKI_exception(GKI_ERROR_FREEBUF_BUF_LINKED, "Freeing Linked Buf");
+    return;
+  }
+
+  if (p_hdr->q_id >= GKI_NUM_TOTAL_BUF_POOLS) {
+    GKI_exception(GKI_ERROR_FREEBUF_BAD_QID, "Bad Buf QId");
+    return;
+  }
+
+  GKI_disable();
+
+  /*
+  ** Release the buffer
+  */
+  Q = &gki_cb.com.freeq[p_hdr->q_id];
+  if (Q->p_last)
+    Q->p_last->p_next = p_hdr;
+  else
+    Q->p_first = p_hdr;
+
+  Q->p_last = p_hdr;
+  p_hdr->p_next = NULL;
+  p_hdr->status = BUF_STATUS_FREE;
+  p_hdr->task_id = GKI_INVALID_TASK;
+  if (Q->cur_cnt > 0) Q->cur_cnt--;
+
+  GKI_enable();
+
+  return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_get_buf_size
+**
+** Description      Called by an application to get the size of a buffer.
+**
+** Parameters       p_buf - (input) address of the beginning of a buffer.
+**
+** Returns          the size of the buffer
+**
+*******************************************************************************/
+uint16_t GKI_get_buf_size(void* p_buf) {
+  BUFFER_HDR_T* p_hdr;
+
+  p_hdr = (BUFFER_HDR_T*)((uint8_t*)p_buf - BUFFER_HDR_SIZE);
+
+  if ((uint32_t)p_hdr & 1) return (0);
+
+  if (p_hdr->q_id < GKI_NUM_TOTAL_BUF_POOLS) {
+    return (gki_cb.com.freeq[p_hdr->q_id].size);
+  }
+
+  return (0);
+}
+
+/*******************************************************************************
+**
+** Function         gki_chk_buf_damage
+**
+** Description      Called internally by OSS to check for buffer corruption.
+**
+** Returns          true if there is a problem, else false
+**
+*******************************************************************************/
+bool gki_chk_buf_damage(void* p_buf) {
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == true)
+
+  uint32_t* magic;
+  magic = (uint32_t*)((uint8_t*)p_buf + GKI_get_buf_size(p_buf));
+
+  if ((uint32_t)magic & 1) return (true);
+
+  if (*magic == MAGIC_NO) return (false);
+
+  return (true);
+
+#else
+
+  return (false);
+
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         GKI_send_msg
+**
+** Description      Called by applications to send a buffer to a task
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void GKI_send_msg(uint8_t task_id, uint8_t mbox, void* msg) {
+  BUFFER_HDR_T* p_hdr;
+  tGKI_COM_CB* p_cb = &gki_cb.com;
+
+  /* If task non-existant or not started, drop buffer */
+  if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX) ||
+      (p_cb->OSRdyTbl[task_id] == TASK_DEAD)) {
+    GKI_exception(GKI_ERROR_SEND_MSG_BAD_DEST, "Sending to unknown dest");
+    GKI_freebuf(msg);
+    return;
+  }
+
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == true)
+  if (gki_chk_buf_damage(msg)) {
+    GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Send - Buffer corrupted");
+    return;
+  }
+#endif
+
+  p_hdr = (BUFFER_HDR_T*)((uint8_t*)msg - BUFFER_HDR_SIZE);
+
+  if (p_hdr->status != BUF_STATUS_UNLINKED) {
+    GKI_exception(GKI_ERROR_SEND_MSG_BUF_LINKED, "Send - buffer linked");
+    return;
+  }
+
+  GKI_disable();
+
+  if (p_cb->OSTaskQFirst[task_id][mbox])
+    p_cb->OSTaskQLast[task_id][mbox]->p_next = p_hdr;
+  else
+    p_cb->OSTaskQFirst[task_id][mbox] = p_hdr;
+
+  p_cb->OSTaskQLast[task_id][mbox] = p_hdr;
+
+  p_hdr->p_next = NULL;
+  p_hdr->status = BUF_STATUS_QUEUED;
+  p_hdr->task_id = task_id;
+
+  GKI_enable();
+
+  GKI_send_event(task_id, (uint16_t)EVENT_MASK(mbox));
+
+  return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_read_mbox
+**
+** Description      Called by applications to read a buffer from one of
+**                  the task mailboxes.  A task can only read its own mailbox.
+**
+** Parameters:      mbox  - (input) mailbox ID to read (0, 1, 2, or 3)
+**
+** Returns          NULL if the mailbox was empty, else the address of a buffer
+**
+*******************************************************************************/
+void* GKI_read_mbox(uint8_t mbox) {
+  uint8_t task_id = GKI_get_taskid();
+  void* p_buf = NULL;
+  BUFFER_HDR_T* p_hdr;
+
+  if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX)) return (NULL);
+
+  GKI_disable();
+
+  if (gki_cb.com.OSTaskQFirst[task_id][mbox]) {
+    p_hdr = gki_cb.com.OSTaskQFirst[task_id][mbox];
+    gki_cb.com.OSTaskQFirst[task_id][mbox] = p_hdr->p_next;
+
+    p_hdr->p_next = NULL;
+    p_hdr->status = BUF_STATUS_UNLINKED;
+
+    p_buf = (uint8_t*)p_hdr + BUFFER_HDR_SIZE;
+  }
+
+  GKI_enable();
+
+  return (p_buf);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_enqueue
+**
+** Description      Enqueue a buffer at the tail of the queue
+**
+** Parameters:      p_q  -  (input) pointer to a queue.
+**                  p_buf - (input) address of the buffer to enqueue
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_enqueue(BUFFER_Q* p_q, void* p_buf) {
+  BUFFER_HDR_T* p_hdr;
+
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == true)
+  if (gki_chk_buf_damage(p_buf)) {
+    GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Enqueue - Buffer corrupted");
+    return;
+  }
+#endif
+
+  p_hdr = (BUFFER_HDR_T*)((uint8_t*)p_buf - BUFFER_HDR_SIZE);
+
+  if (p_hdr->status != BUF_STATUS_UNLINKED) {
+    GKI_exception(GKI_ERROR_ENQUEUE_BUF_LINKED, "Eneueue - buf already linked");
+    return;
+  }
+
+  GKI_disable();
+
+  /* Since the queue is exposed (C vs C++), keep the pointers in exposed format
+   */
+  if (p_q->p_first) {
+    BUFFER_HDR_T* p_last_hdr =
+        (BUFFER_HDR_T*)((uint8_t*)p_q->p_last - BUFFER_HDR_SIZE);
+    p_last_hdr->p_next = p_hdr;
+  } else
+    p_q->p_first = p_buf;
+
+  p_q->p_last = p_buf;
+  p_q->count++;
+
+  p_hdr->p_next = NULL;
+  p_hdr->status = BUF_STATUS_QUEUED;
+
+  GKI_enable();
+
+  return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_enqueue_head
+**
+** Description      Enqueue a buffer at the head of the queue
+**
+** Parameters:      p_q  -  (input) pointer to a queue.
+**                  p_buf - (input) address of the buffer to enqueue
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_enqueue_head(BUFFER_Q* p_q, void* p_buf) {
+  BUFFER_HDR_T* p_hdr;
+
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == true)
+  if (gki_chk_buf_damage(p_buf)) {
+    GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Enqueue - Buffer corrupted");
+    return;
+  }
+#endif
+
+  p_hdr = (BUFFER_HDR_T*)((uint8_t*)p_buf - BUFFER_HDR_SIZE);
+
+  if (p_hdr->status != BUF_STATUS_UNLINKED) {
+    GKI_exception(GKI_ERROR_ENQUEUE_BUF_LINKED,
+                  "Eneueue head - buf already linked");
+    return;
+  }
+
+  GKI_disable();
+
+  if (p_q->p_first) {
+    p_hdr->p_next = (BUFFER_HDR_T*)((uint8_t*)p_q->p_first - BUFFER_HDR_SIZE);
+    p_q->p_first = p_buf;
+  } else {
+    p_q->p_first = p_buf;
+    p_q->p_last = p_buf;
+    p_hdr->p_next = NULL;
+  }
+  p_q->count++;
+
+  p_hdr->status = BUF_STATUS_QUEUED;
+
+  GKI_enable();
+
+  return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_dequeue
+**
+** Description      Dequeues a buffer from the head of a queue
+**
+** Parameters:      p_q  - (input) pointer to a queue.
+**
+** Returns          NULL if queue is empty, else buffer
+**
+*******************************************************************************/
+void* GKI_dequeue(BUFFER_Q* p_q) {
+  BUFFER_HDR_T* p_hdr;
+
+  GKI_disable();
+
+  if (!p_q || !p_q->count) {
+    GKI_enable();
+    return (NULL);
+  }
+
+  p_hdr = (BUFFER_HDR_T*)((uint8_t*)p_q->p_first - BUFFER_HDR_SIZE);
+
+  /* Keep buffers such that GKI header is invisible
+  */
+  if (p_hdr->p_next)
+    p_q->p_first = ((uint8_t*)p_hdr->p_next + BUFFER_HDR_SIZE);
+  else {
+    p_q->p_first = NULL;
+    p_q->p_last = NULL;
+  }
+
+  p_q->count--;
+
+  p_hdr->p_next = NULL;
+  p_hdr->status = BUF_STATUS_UNLINKED;
+
+  GKI_enable();
+
+  return ((uint8_t*)p_hdr + BUFFER_HDR_SIZE);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_remove_from_queue
+**
+** Description      Dequeue a buffer from the middle of the queue
+**
+** Parameters:      p_q  - (input) pointer to a queue.
+**                  p_buf - (input) address of the buffer to enqueue
+**
+** Returns          NULL if queue is empty, else buffer
+**
+*******************************************************************************/
+void* GKI_remove_from_queue(BUFFER_Q* p_q, void* p_buf) {
+  BUFFER_HDR_T* p_prev;
+  BUFFER_HDR_T* p_buf_hdr;
+
+  GKI_disable();
+
+  if (p_buf == p_q->p_first) {
+    GKI_enable();
+    return (GKI_dequeue(p_q));
+  }
+
+  p_buf_hdr = (BUFFER_HDR_T*)((uint8_t*)p_buf - BUFFER_HDR_SIZE);
+  p_prev = (BUFFER_HDR_T*)((uint8_t*)p_q->p_first - BUFFER_HDR_SIZE);
+
+  for (; p_prev; p_prev = p_prev->p_next) {
+    /* If the previous points to this one, move the pointers around */
+    if (p_prev->p_next == p_buf_hdr) {
+      p_prev->p_next = p_buf_hdr->p_next;
+
+      /* If we are removing the last guy in the queue, update p_last */
+      if (p_buf == p_q->p_last) p_q->p_last = p_prev + 1;
+
+      /* One less in the queue */
+      p_q->count--;
+
+      /* The buffer is now unlinked */
+      p_buf_hdr->p_next = NULL;
+      p_buf_hdr->status = BUF_STATUS_UNLINKED;
+
+      GKI_enable();
+      return (p_buf);
+    }
+  }
+
+  GKI_enable();
+  return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_getfirst
+**
+** Description      Return a pointer to the first buffer in a queue
+**
+** Parameters:      p_q  - (input) pointer to a queue.
+**
+** Returns          NULL if queue is empty, else buffer address
+**
+*******************************************************************************/
+void* GKI_getfirst(BUFFER_Q* p_q) { return (p_q->p_first); }
+
+/*******************************************************************************
+**
+** Function         GKI_getlast
+**
+** Description      Return a pointer to the last buffer in a queue
+**
+** Parameters:      p_q  - (input) pointer to a queue.
+**
+** Returns          NULL if queue is empty, else buffer address
+**
+*******************************************************************************/
+void* GKI_getlast(BUFFER_Q* p_q) { return (p_q->p_last); }
+
+/*******************************************************************************
+**
+** Function         GKI_getnext
+**
+** Description      Return a pointer to the next buffer in a queue
+**
+** Parameters:      p_buf - (input) pointer to the buffer to find the next one
+**                                  from.
+**
+** Returns          NULL if no more buffers in the queue, else next buffer
+**                  address
+**
+*******************************************************************************/
+void* GKI_getnext(void* p_buf) {
+  BUFFER_HDR_T* p_hdr;
+
+  p_hdr = (BUFFER_HDR_T*)((uint8_t*)p_buf - BUFFER_HDR_SIZE);
+
+  if (p_hdr->p_next)
+    return ((uint8_t*)p_hdr->p_next + BUFFER_HDR_SIZE);
+  else
+    return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_queue_is_empty
+**
+** Description      Check the status of a queue.
+**
+** Parameters:      p_q  - (input) pointer to a queue.
+**
+** Returns          true if queue is empty, else false
+**
+*******************************************************************************/
+bool GKI_queue_is_empty(BUFFER_Q* p_q) { return ((bool)(p_q->count == 0)); }
+
+/*******************************************************************************
+**
+** Function         GKI_find_buf_start
+**
+** Description      This function is called with an address inside a buffer,
+**                  and returns the start address ofthe buffer.
+**
+**                  The buffer should be one allocated from one of GKI's pools.
+**
+** Parameters:      p_user_area - (input) address of anywhere in a GKI buffer.
+**
+** Returns          void * - Address of the beginning of the specified buffer if
+**                           successful, otherwise NULL if unsuccessful
+**
+*******************************************************************************/
+void* GKI_find_buf_start(void* p_user_area) {
+  uint16_t xx, size;
+  uint32_t yy;
+  tGKI_COM_CB* p_cb = &gki_cb.com;
+  uint8_t* p_ua = (uint8_t*)p_user_area;
+
+  for (xx = 0; xx < GKI_NUM_TOTAL_BUF_POOLS; xx++) {
+    if ((p_ua > p_cb->pool_start[xx]) && (p_ua < p_cb->pool_end[xx])) {
+      yy = (uint32_t)(p_ua - p_cb->pool_start[xx]);
+
+      size = p_cb->pool_size[xx];
+
+      yy = (yy / size) * size;
+
+      return ((void*)(p_cb->pool_start[xx] + yy + sizeof(BUFFER_HDR_T)));
+    }
+  }
+
+  /* If here, invalid address - not in one of our buffers */
+  GKI_exception(GKI_ERROR_BUF_SIZE_ZERO, "GKI_get_buf_start:: bad addr");
+
+  return (NULL);
+}
+
+/********************************************************
+* The following functions are not needed for light stack
+*********************************************************/
+#ifndef BTU_STACK_LITE_ENABLED
+#define BTU_STACK_LITE_ENABLED false
+#endif
+#if (BTU_STACK_LITE_ENABLED == false)
+
+/*******************************************************************************
+**
+** Function         GKI_set_pool_permission
+**
+** Description      This function is called to set or change the permissions for
+**                  the specified pool ID.
+**
+** Parameters       pool_id - (input) pool ID to be set or changed
+**                  permission - (input) GKI_PUBLIC_POOL or GKI_RESTRICTED_POOL
+**
+** Returns          GKI_SUCCESS if successful
+**                  GKI_INVALID_POOL if unsuccessful
+**
+*******************************************************************************/
+uint8_t GKI_set_pool_permission(uint8_t pool_id, uint8_t permission) {
+  tGKI_COM_CB* p_cb = &gki_cb.com;
+
+  if (pool_id < GKI_NUM_TOTAL_BUF_POOLS) {
+    if (permission == GKI_RESTRICTED_POOL)
+      p_cb->pool_access_mask =
+          (uint16_t)(p_cb->pool_access_mask | (1 << pool_id));
+
+    else /* mark the pool as public */
+      p_cb->pool_access_mask =
+          (uint16_t)(p_cb->pool_access_mask & ~(1 << pool_id));
+
+    return (GKI_SUCCESS);
+  } else
+    return (GKI_INVALID_POOL);
+}
+
+/*******************************************************************************
+**
+** Function         gki_add_to_pool_list
+**
+** Description      Adds pool to the pool list which is arranged in the
+**                  order of size
+**
+** Returns          void
+**
+*******************************************************************************/
+static void gki_add_to_pool_list(uint8_t pool_id) {
+  int32_t i, j;
+  tGKI_COM_CB* p_cb = &gki_cb.com;
+
+  /* Find the position where the specified pool should be inserted into the list
+   */
+  for (i = 0; i < p_cb->curr_total_no_of_pools; i++) {
+    if (p_cb->freeq[pool_id].size <= p_cb->freeq[p_cb->pool_list[i]].size)
+      break;
+  }
+
+  /* Insert the new buffer pool ID into the list of pools */
+  for (j = p_cb->curr_total_no_of_pools; j > i; j--) {
+    p_cb->pool_list[j] = p_cb->pool_list[j - 1];
+  }
+
+  p_cb->pool_list[i] = pool_id;
+
+  return;
+}
+
+/*******************************************************************************
+**
+** Function         gki_remove_from_pool_list
+**
+** Description      Removes pool from the pool list. Called when a pool is
+**                  deleted
+**
+** Returns          void
+**
+*******************************************************************************/
+static void gki_remove_from_pool_list(uint8_t pool_id) {
+  tGKI_COM_CB* p_cb = &gki_cb.com;
+  uint8_t i;
+
+  for (i = 0; i < p_cb->curr_total_no_of_pools; i++) {
+    if (pool_id == p_cb->pool_list[i]) break;
+  }
+
+  while (i < (p_cb->curr_total_no_of_pools - 1)) {
+    p_cb->pool_list[i] = p_cb->pool_list[i + 1];
+    i++;
+  }
+
+  return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_igetpoolbuf
+**
+** Description      Called by an interrupt service routine to get a free buffer
+**                  from a specific buffer pool.
+**
+** Parameters       pool_id - (input) pool ID to get a buffer out of.
+**
+** Returns          A pointer to the buffer, or NULL if none available
+**
+*******************************************************************************/
+void* GKI_igetpoolbuf(uint8_t pool_id) {
+  FREE_QUEUE_T* Q;
+  BUFFER_HDR_T* p_hdr;
+
+  if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS) return (NULL);
+
+  Q = &gki_cb.com.freeq[pool_id];
+  if (Q->cur_cnt < Q->total) {
+    p_hdr = Q->p_first;
+    Q->p_first = p_hdr->p_next;
+
+    if (!Q->p_first) Q->p_last = NULL;
+
+    if (++Q->cur_cnt > Q->max_cnt) Q->max_cnt = Q->cur_cnt;
+
+    p_hdr->task_id = GKI_get_taskid();
+
+    p_hdr->status = BUF_STATUS_UNLINKED;
+    p_hdr->p_next = NULL;
+    p_hdr->Type = 0;
+
+    return ((void*)((uint8_t*)p_hdr + BUFFER_HDR_SIZE));
+  }
+
+  return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_poolcount
+**
+** Description      Called by an application to get the total number of buffers
+**                  in the specified buffer pool.
+**
+** Parameters       pool_id - (input) pool ID to get the free count of.
+**
+** Returns          the total number of buffers in the pool
+**
+*******************************************************************************/
+uint16_t GKI_poolcount(uint8_t pool_id) {
+  if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS) return (0);
+
+  return (gki_cb.com.freeq[pool_id].total);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_poolfreecount
+**
+** Description      Called by an application to get the number of free buffers
+**                  in the specified buffer pool.
+**
+** Parameters       pool_id - (input) pool ID to get the free count of.
+**
+** Returns          the number of free buffers in the pool
+**
+*******************************************************************************/
+uint16_t GKI_poolfreecount(uint8_t pool_id) {
+  FREE_QUEUE_T* Q;
+
+  if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS) return (0);
+
+  Q = &gki_cb.com.freeq[pool_id];
+
+  return ((uint16_t)(Q->total - Q->cur_cnt));
+}
+
+/*******************************************************************************
+**
+** Function         GKI_change_buf_owner
+**
+** Description      Called to change the task ownership of a buffer.
+**
+** Parameters:      p_buf   - (input) pointer to the buffer
+**                  task_id - (input) task id to change ownership to
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_change_buf_owner(void* p_buf, uint8_t task_id) {
+  BUFFER_HDR_T* p_hdr = (BUFFER_HDR_T*)((uint8_t*)p_buf - BUFFER_HDR_SIZE);
+
+  p_hdr->task_id = task_id;
+
+  return;
+}
+
+#if (GKI_SEND_MSG_FROM_ISR == true)
+/*******************************************************************************
+**
+** Function         GKI_isend_msg
+**
+** Description      Called from interrupt context to send a buffer to a task
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void GKI_isend_msg(uint8_t task_id, uint8_t mbox, void* msg) {
+  BUFFER_HDR_T* p_hdr;
+  tGKI_COM_CB* p_cb = &gki_cb.com;
+
+  /* If task non-existant or not started, drop buffer */
+  if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX) ||
+      (p_cb->OSRdyTbl[task_id] == TASK_DEAD)) {
+    GKI_exception(GKI_ERROR_SEND_MSG_BAD_DEST, "Sending to unknown dest");
+    GKI_freebuf(msg);
+    return;
+  }
+
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == true)
+  if (gki_chk_buf_damage(msg)) {
+    GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Send - Buffer corrupted");
+    return;
+  }
+#endif
+
+#if (GKI_ENABLE_OWNER_CHECK == true)
+  if (gki_chk_buf_owner(msg)) {
+    GKI_exception(GKI_ERROR_NOT_BUF_OWNER, "Send by non-owner");
+    return;
+  }
+#endif
+
+  p_hdr = (BUFFER_HDR_T*)((uint8_t*)msg - BUFFER_HDR_SIZE);
+
+  if (p_hdr->status != BUF_STATUS_UNLINKED) {
+    GKI_exception(GKI_ERROR_SEND_MSG_BUF_LINKED, "Send - buffer linked");
+    return;
+  }
+
+  if (p_cb->OSTaskQFirst[task_id][mbox])
+    p_cb->OSTaskQLast[task_id][mbox]->p_next = p_hdr;
+  else
+    p_cb->OSTaskQFirst[task_id][mbox] = p_hdr;
+
+  p_cb->OSTaskQLast[task_id][mbox] = p_hdr;
+
+  p_hdr->p_next = NULL;
+  p_hdr->status = BUF_STATUS_QUEUED;
+  p_hdr->task_id = task_id;
+
+  GKI_isend_event(task_id, (uint16_t)EVENT_MASK(mbox));
+
+  return;
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         GKI_create_pool
+**
+** Description      Called by applications to create a buffer pool.
+**
+** Parameters:      size - (input) length (in bytes) of each buffer in the pool
+**                  count - (input) number of buffers to allocate for the pool
+**                  permission - (input) restricted or public access?
+**                                      (GKI_PUBLIC_POOL or GKI_RESTRICTED_POOL)
+**                  p_mem_pool - (input) pointer to an OS memory pool, NULL if
+**                                       not provided
+**
+** Returns          the buffer pool ID, which should be used in calls to
+**                  GKI_getpoolbuf(). If a pool could not be created, this
+**                  function returns 0xff.
+**
+*******************************************************************************/
+uint8_t GKI_create_pool(uint16_t size, uint16_t count, uint8_t permission,
+                        void* p_mem_pool) {
+  uint8_t xx;
+  uint32_t mem_needed;
+  int32_t tempsize = size;
+  tGKI_COM_CB* p_cb = &gki_cb.com;
+
+  /* First make sure the size of each pool has a valid size with room for the
+   * header info */
+  if (size > MAX_USER_BUF_SIZE) return (GKI_INVALID_POOL);
+
+  /* First, look for an unused pool */
+  for (xx = 0; xx < GKI_NUM_TOTAL_BUF_POOLS; xx++) {
+    if (!p_cb->pool_start[xx]) break;
+  }
+
+  if (xx == GKI_NUM_TOTAL_BUF_POOLS) return (GKI_INVALID_POOL);
+
+  /* Ensure an even number of longwords */
+  tempsize = (int32_t)ALIGN_POOL(size);
+
+  mem_needed = (tempsize + BUFFER_PADDING_SIZE) * count;
+
+  if (!p_mem_pool) p_mem_pool = GKI_os_malloc(mem_needed);
+
+  if (p_mem_pool) {
+    /* Initialize the new pool */
+    gki_init_free_queue(xx, size, count, p_mem_pool);
+    gki_add_to_pool_list(xx);
+    (void)GKI_set_pool_permission(xx, permission);
+    p_cb->curr_total_no_of_pools++;
+
+    return (xx);
+  } else
+    return (GKI_INVALID_POOL);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_delete_pool
+**
+** Description      Called by applications to delete a buffer pool.  The
+**                  function calls the operating specific function to free the
+**                  actual memory. An exception is generated if an error is
+**                  detected.
+**
+** Parameters:      pool_id - (input) Id of the poll being deleted.
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_delete_pool(uint8_t pool_id) {
+  FREE_QUEUE_T* Q;
+  tGKI_COM_CB* p_cb = &gki_cb.com;
+
+  if ((pool_id >= GKI_NUM_TOTAL_BUF_POOLS) || (!p_cb->pool_start[pool_id]))
+    return;
+
+  GKI_disable();
+  Q = &p_cb->freeq[pool_id];
+
+  if (!Q->cur_cnt) {
+    Q->size = 0;
+    Q->total = 0;
+    Q->cur_cnt = 0;
+    Q->max_cnt = 0;
+    Q->p_first = NULL;
+    Q->p_last = NULL;
+
+    GKI_os_free(p_cb->pool_start[pool_id]);
+
+    p_cb->pool_start[pool_id] = NULL;
+    p_cb->pool_end[pool_id] = NULL;
+    p_cb->pool_size[pool_id] = 0;
+
+    gki_remove_from_pool_list(pool_id);
+    p_cb->curr_total_no_of_pools--;
+  } else
+    GKI_exception(GKI_ERROR_DELETE_POOL_BAD_QID, "Deleting bad pool");
+
+  GKI_enable();
+
+  return;
+}
+
+#endif /*  BTU_STACK_LITE_ENABLED == false */
+
+/*******************************************************************************
+**
+** Function         GKI_get_pool_bufsize
+**
+** Description      Called by an application to get the size of buffers in a
+**                  pool
+**
+** Parameters       Pool ID.
+**
+** Returns          the size of buffers in the pool
+**
+*******************************************************************************/
+uint16_t GKI_get_pool_bufsize(uint8_t pool_id) {
+  if (pool_id < GKI_NUM_TOTAL_BUF_POOLS)
+    return (gki_cb.com.freeq[pool_id].size);
+
+  return (0);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_poolutilization
+**
+** Description      Called by an application to get the buffer utilization
+**                  in the specified buffer pool.
+**
+** Parameters       pool_id - (input) pool ID to get the free count of.
+**
+** Returns          % of buffers used from 0 to 100
+**
+*******************************************************************************/
+uint16_t GKI_poolutilization(uint8_t pool_id) {
+  FREE_QUEUE_T* Q;
+
+  if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS) return (100);
+
+  Q = &gki_cb.com.freeq[pool_id];
+
+  if (Q->total == 0) return (100);
+
+  return ((Q->cur_cnt * 100) / Q->total);
+}
diff --git a/src/gki/common/gki_common.h b/src/gki/common/gki_common.h
new file mode 100644
index 0000000..c4592cb
--- /dev/null
+++ b/src/gki/common/gki_common.h
@@ -0,0 +1,445 @@
+/******************************************************************************
+ *
+ *  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) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef GKI_COMMON_H
+#define GKI_COMMON_H
+
+#include "gki.h"
+
+#ifndef GKI_DEBUG
+#define GKI_DEBUG false
+#endif
+
+/* Task States: (For OSRdyTbl) */
+#define TASK_DEAD 0    /* b0000 */
+#define TASK_READY 1   /* b0001 */
+#define TASK_WAIT 2    /* b0010 */
+#define TASK_DELAY 4   /* b0100 */
+#define TASK_SUSPEND 8 /* b1000 */
+
+/********************************************************************
+**  Internal Error codes
+*********************************************************************/
+#define GKI_ERROR_BUF_CORRUPTED 0xFFFF
+#define GKI_ERROR_NOT_BUF_OWNER 0xFFFE
+#define GKI_ERROR_FREEBUF_BAD_QID 0xFFFD
+#define GKI_ERROR_FREEBUF_BUF_LINKED 0xFFFC
+#define GKI_ERROR_SEND_MSG_BAD_DEST 0xFFFB
+#define GKI_ERROR_SEND_MSG_BUF_LINKED 0xFFFA
+#define GKI_ERROR_ENQUEUE_BUF_LINKED 0xFFF9
+#define GKI_ERROR_DELETE_POOL_BAD_QID 0xFFF8
+#define GKI_ERROR_BUF_SIZE_TOOBIG 0xFFF7
+#define GKI_ERROR_BUF_SIZE_ZERO 0xFFF6
+#define GKI_ERROR_ADDR_NOT_IN_BUF 0xFFF5
+
+/********************************************************************
+**  Misc constants
+*********************************************************************/
+
+#define GKI_MAX_INT32 (0x7fffffffL)
+#define GKI_MAX_TIMESTAMP (0xffffffffL)
+
+/********************************************************************
+**  Buffer Management Data Structures
+*********************************************************************/
+
+typedef struct _buffer_hdr {
+  struct _buffer_hdr* p_next; /* next buffer in the queue */
+  uint8_t q_id;               /* id of the queue */
+  uint8_t task_id;            /* task which allocated the buffer*/
+  uint8_t status;             /* FREE, UNLINKED or QUEUED */
+  uint8_t Type;
+
+#if (GKI_BUFFER_DEBUG == true)
+/* for tracking who allocated the buffer */
+#define _GKI_MAX_FUNCTION_NAME_LEN (50)
+  char _function[_GKI_MAX_FUNCTION_NAME_LEN + 1];
+  int _line;
+#endif
+
+} BUFFER_HDR_T;
+
+typedef struct _free_queue {
+  BUFFER_HDR_T* p_first; /* first buffer in the queue */
+  BUFFER_HDR_T* p_last;  /* last buffer in the queue */
+  uint16_t size;         /* size of the buffers in the pool */
+  uint16_t total;        /* toatal number of buffers */
+  uint16_t cur_cnt;      /* number of  buffers currently allocated */
+  uint16_t max_cnt;      /* maximum number of buffers allocated at any time */
+} FREE_QUEUE_T;
+
+/* Buffer related defines
+*/
+#if (NXP_EXTNS == TRUE)
+#define ALIGN_POOL(pl_size) \
+  ((((pl_size) + (sizeof(uint32_t) - 1)) / sizeof(uint32_t)) * sizeof(uint32_t))
+#else
+#define ALIGN_POOL(pl_size) \
+  ((((pl_size) + 3) / sizeof(uint32_t)) * sizeof(uint32_t))
+#endif
+/* Offset past header */
+#define BUFFER_HDR_SIZE (sizeof(BUFFER_HDR_T))
+/* Header + Magic Number */
+#define BUFFER_PADDING_SIZE (sizeof(BUFFER_HDR_T) + sizeof(uint32_t))
+/* pool size must allow for header */
+#define MAX_USER_BUF_SIZE ((uint16_t)0xffff - BUFFER_PADDING_SIZE)
+#define MAGIC_NO 0xDDBADDBA
+
+#define BUF_STATUS_FREE 0
+#define BUF_STATUS_UNLINKED 1
+#define BUF_STATUS_QUEUED 2
+
+#define GKI_USE_DEFERED_ALLOC_BUF_POOLS true
+
+/* Exception related structures (Used in debug mode only)
+*/
+#if (GKI_DEBUG == true)
+typedef struct {
+  uint16_t type;
+  uint8_t taskid;
+  uint8_t msg[GKI_MAX_EXCEPTION_MSGLEN];
+} EXCEPTION_T;
+#endif
+
+/* Put all GKI variables into one control block
+*/
+typedef struct {
+/* Task management variables
+*/
+/* The stack and stack size are not used on Windows
+*/
+#if (GKI_USE_DYNAMIC_BUFFERS == false)
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 0)
+  uint8_t bufpool0[(ALIGN_POOL(GKI_BUF0_SIZE) + BUFFER_PADDING_SIZE) *
+                   GKI_BUF0_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 1)
+  uint8_t bufpool1[(ALIGN_POOL(GKI_BUF1_SIZE) + BUFFER_PADDING_SIZE) *
+                   GKI_BUF1_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 2)
+  uint8_t bufpool2[(ALIGN_POOL(GKI_BUF2_SIZE) + BUFFER_PADDING_SIZE) *
+                   GKI_BUF2_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 3)
+  uint8_t bufpool3[(ALIGN_POOL(GKI_BUF3_SIZE) + BUFFER_PADDING_SIZE) *
+                   GKI_BUF3_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 4)
+  uint8_t bufpool4[(ALIGN_POOL(GKI_BUF4_SIZE) + BUFFER_PADDING_SIZE) *
+                   GKI_BUF4_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 5)
+  uint8_t bufpool5[(ALIGN_POOL(GKI_BUF5_SIZE) + BUFFER_PADDING_SIZE) *
+                   GKI_BUF5_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 6)
+  uint8_t bufpool6[(ALIGN_POOL(GKI_BUF6_SIZE) + BUFFER_PADDING_SIZE) *
+                   GKI_BUF6_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 7)
+  uint8_t bufpool7[(ALIGN_POOL(GKI_BUF7_SIZE) + BUFFER_PADDING_SIZE) *
+                   GKI_BUF7_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 8)
+  uint8_t bufpool8[(ALIGN_POOL(GKI_BUF8_SIZE) + BUFFER_PADDING_SIZE) *
+                   GKI_BUF8_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 9)
+  uint8_t bufpool9[(ALIGN_POOL(GKI_BUF9_SIZE) + BUFFER_PADDING_SIZE) *
+                   GKI_BUF9_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 10)
+  uint8_t bufpool10[(ALIGN_POOL(GKI_BUF10_SIZE) + BUFFER_PADDING_SIZE) *
+                    GKI_BUF10_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 11)
+  uint8_t bufpool11[(ALIGN_POOL(GKI_BUF11_SIZE) + BUFFER_PADDING_SIZE) *
+                    GKI_BUF11_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 12)
+  uint8_t bufpool12[(ALIGN_POOL(GKI_BUF12_SIZE) + BUFFER_PADDING_SIZE) *
+                    GKI_BUF12_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 13)
+  uint8_t bufpool13[(ALIGN_POOL(GKI_BUF13_SIZE) + BUFFER_PADDING_SIZE) *
+                    GKI_BUF13_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 14)
+  uint8_t bufpool14[(ALIGN_POOL(GKI_BUF14_SIZE) + BUFFER_PADDING_SIZE) *
+                    GKI_BUF14_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 15)
+  uint8_t bufpool15[(ALIGN_POOL(GKI_BUF15_SIZE) + BUFFER_PADDING_SIZE) *
+                    GKI_BUF15_MAX];
+#endif
+
+#else
+/* Definitions for dynamic buffer use */
+#if (GKI_NUM_FIXED_BUF_POOLS > 0)
+  uint8_t* bufpool0;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 1)
+  uint8_t* bufpool1;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 2)
+  uint8_t* bufpool2;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 3)
+  uint8_t* bufpool3;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 4)
+  uint8_t* bufpool4;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 5)
+  uint8_t* bufpool5;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 6)
+  uint8_t* bufpool6;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 7)
+  uint8_t* bufpool7;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 8)
+  uint8_t* bufpool8;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 9)
+  uint8_t* bufpool9;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 10)
+  uint8_t* bufpool10;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 11)
+  uint8_t* bufpool11;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 12)
+  uint8_t* bufpool12;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 13)
+  uint8_t* bufpool13;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 14)
+  uint8_t* bufpool14;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 15)
+  uint8_t* bufpool15;
+#endif
+
+#endif
+
+  uint8_t* OSStack[GKI_MAX_TASKS];     /* pointer to beginning of stack */
+  uint16_t OSStackSize[GKI_MAX_TASKS]; /* stack size available to each task */
+
+  int8_t* OSTName[GKI_MAX_TASKS]; /* name of the task */
+
+  uint8_t OSRdyTbl[GKI_MAX_TASKS]; /* current state of the task */
+  uint16_t OSWaitEvt
+      [GKI_MAX_TASKS]; /* events that have to be processed by the task */
+  uint16_t OSWaitForEvt[GKI_MAX_TASKS]; /* events the task is waiting for*/
+
+  uint32_t OSTicks;   /* system ticks from start */
+  uint32_t OSIdleCnt; /* idle counter */
+  int16_t
+      OSDisableNesting; /* counter to keep track of interrupt disable nesting */
+  int16_t OSLockNesting; /* counter to keep track of sched lock nesting */
+  int16_t OSIntNesting;  /* counter to keep track of interrupt nesting */
+
+  /* Timer related variables
+  */
+  int32_t OSTicksTilExp; /* Number of ticks till next timer expires */
+#if (GKI_DELAY_STOP_SYS_TICK > 0)
+  uint32_t OSTicksTilStop; /* inactivity delay timer; OS Ticks till stopping
+                              system tick */
+#endif
+  int32_t OSNumOrigTicks; /* Number of ticks between last timer expiration to
+                             the next one */
+
+  int32_t OSWaitTmr
+      [GKI_MAX_TASKS]; /* ticks the task has to wait, for specific events */
+
+/* Only take up space timers used in the system (GKI_NUM_TIMERS defined in
+ * target.h) */
+#if (GKI_NUM_TIMERS > 0)
+  int32_t OSTaskTmr0[GKI_MAX_TASKS];
+  int32_t OSTaskTmr0R[GKI_MAX_TASKS];
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+  int32_t OSTaskTmr1[GKI_MAX_TASKS];
+  int32_t OSTaskTmr1R[GKI_MAX_TASKS];
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+  int32_t OSTaskTmr2[GKI_MAX_TASKS];
+  int32_t OSTaskTmr2R[GKI_MAX_TASKS];
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+  int32_t OSTaskTmr3[GKI_MAX_TASKS];
+  int32_t OSTaskTmr3R[GKI_MAX_TASKS];
+#endif
+
+  /* Buffer related variables
+  */
+  BUFFER_HDR_T*
+      OSTaskQFirst[GKI_MAX_TASKS][NUM_TASK_MBOX]; /* array of pointers to the
+                                                     first event in the task
+                                                     mailbox */
+  BUFFER_HDR_T*
+      OSTaskQLast[GKI_MAX_TASKS][NUM_TASK_MBOX]; /* array of pointers to the
+                                                    last event in the task
+                                                    mailbox */
+
+  /* Define the buffer pool management variables
+  */
+  FREE_QUEUE_T freeq[GKI_NUM_TOTAL_BUF_POOLS];
+
+  uint16_t pool_buf_size[GKI_NUM_TOTAL_BUF_POOLS];
+  uint16_t pool_max_count[GKI_NUM_TOTAL_BUF_POOLS];
+  uint16_t pool_additions[GKI_NUM_TOTAL_BUF_POOLS];
+
+  /* Define the buffer pool start addresses
+  */
+  uint8_t* pool_start[GKI_NUM_TOTAL_BUF_POOLS]; /* array of pointers to the
+                                                   start of each buffer pool */
+  uint8_t*
+      pool_end[GKI_NUM_TOTAL_BUF_POOLS]; /* array of pointers to the end of each
+                                            buffer pool */
+  uint16_t pool_size
+      [GKI_NUM_TOTAL_BUF_POOLS]; /* actual size of the buffers in a pool */
+
+  /* Define the buffer pool access control variables */
+  void* p_user_mempool; /* User O/S memory pool */
+  uint16_t
+      pool_access_mask; /* Bits are set if the corresponding buffer pool is a
+                           restricted pool */
+  uint8_t pool_list[GKI_NUM_TOTAL_BUF_POOLS]; /* buffer pools arranged in the
+                                                 order of size */
+  uint8_t
+      curr_total_no_of_pools; /* number of fixed buf pools + current number of
+                                 dynamic pools */
+
+  bool timer_nesting; /* flag to prevent timer interrupt nesting */
+
+  /* Time queue arrays */
+  TIMER_LIST_Q* timer_queues[GKI_MAX_TIMER_QUEUES];
+  /* System tick callback */
+  SYSTEM_TICK_CBACK* p_tick_cb;
+  bool system_tick_running; /* true if system tick is running. Valid only if
+                               p_tick_cb is not NULL */
+
+#if (GKI_DEBUG == true)
+  uint16_t ExceptionCnt; /* number of GKI exceptions that have happened */
+  EXCEPTION_T Exception[GKI_MAX_EXCEPTION];
+#endif
+
+} tGKI_COM_CB;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Internal GKI function prototypes
+*/
+extern bool gki_chk_buf_damage(void*);
+extern bool gki_chk_buf_owner(void*);
+extern void gki_buffer_init(void);
+extern void gki_timers_init(void);
+extern void gki_adjust_timer_count(int32_t);
+
+extern void OSStartRdy(void);
+extern void OSCtxSw(void);
+extern void OSIntCtxSw(void);
+extern void OSSched(void);
+extern void OSIntEnter(void);
+extern void OSIntExit(void);
+
+/* Debug aids
+*/
+typedef void (*FP_PRINT)(char*, ...);
+
+#if (GKI_DEBUG == true)
+
+typedef void (*PKT_PRINT)(uint8_t*, uint16_t);
+
+extern void gki_print_task(FP_PRINT);
+extern void gki_print_exception(FP_PRINT);
+extern void gki_print_timer(FP_PRINT);
+extern void gki_print_stack(FP_PRINT);
+extern void gki_print_buffer(FP_PRINT);
+extern void gki_print_buffer_statistics(FP_PRINT, int16_t);
+extern void gki_print_used_bufs(FP_PRINT, uint8_t);
+extern void gki_dump(uint8_t*, uint16_t, FP_PRINT);
+extern void gki_dump2(uint16_t*, uint16_t, FP_PRINT);
+extern void gki_dump4(uint32_t*, uint16_t, FP_PRINT);
+
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/gki/common/gki_debug.c b/src/gki/common/gki_debug.c
new file mode 100644
index 0000000..204649c
--- /dev/null
+++ b/src/gki/common/gki_debug.c
@@ -0,0 +1,308 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "gki_int.h"
+
+#if (GKI_DEBUG == true)
+
+const int8_t* const OSTaskStates[] = {
+    (int8_t*)"DEAD",                                                    /* 0 */
+    (int8_t*) "REDY",                                                   /* 1 */
+    (int8_t*) "WAIT",                                                   /* 2 */
+    (int8_t*) "",     (int8_t*) "DELY",                                 /* 4 */
+    (int8_t*) "",     (int8_t*) "",     (int8_t*) "", (int8_t*) "SUSP", /* 8 */
+};
+
+/*******************************************************************************
+**
+** Function         GKI_PrintBufferUsage
+**
+** Description      Displays Current Buffer Pool summary
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_PrintBufferUsage(uint8_t* p_num_pools, uint16_t* p_cur_used) {
+  int i;
+  FREE_QUEUE_T* p;
+  uint8_t num = gki_cb.com.curr_total_no_of_pools;
+  uint16_t cur[GKI_NUM_TOTAL_BUF_POOLS];
+
+  GKI_TRACE_0("");
+  GKI_TRACE_0("--- GKI Buffer Pool Summary (R - restricted, P - public) ---");
+
+  GKI_TRACE_0("POOL     SIZE  USED  MAXU  TOTAL");
+  GKI_TRACE_0("------------------------------");
+  for (i = 0; i < gki_cb.com.curr_total_no_of_pools; i++) {
+    p = &gki_cb.com.freeq[i];
+    if ((1 << i) & gki_cb.com.pool_access_mask) {
+      GKI_TRACE_5("%02d: (R), %4d, %3d, %3d, %3d", i, p->size, p->cur_cnt,
+                  p->max_cnt, p->total);
+    } else {
+      GKI_TRACE_5("%02d: (P), %4d, %3d, %3d, %3d", i, p->size, p->cur_cnt,
+                  p->max_cnt, p->total);
+    }
+    cur[i] = p->cur_cnt;
+  }
+  if (p_num_pools) *p_num_pools = num;
+  if (p_cur_used) memcpy(p_cur_used, cur, num * 2);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_PrintBuffer
+**
+** Description      Called internally by OSS to print the buffer pools
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_PrintBuffer(void) {
+  uint16_t i;
+  for (i = 0; i < GKI_NUM_TOTAL_BUF_POOLS; i++) {
+    GKI_TRACE_5("pool:%4u free %4u cur %3u max %3u  total%3u", i,
+                gki_cb.com.freeq[i].size, gki_cb.com.freeq[i].cur_cnt,
+                gki_cb.com.freeq[i].max_cnt, gki_cb.com.freeq[i].total);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         gki_calc_stack
+**
+** Description      This function tries to calculate the amount of
+**                  stack used by looking non magic num. Magic num is consider
+**                  the first byte in the stack.
+**
+** Returns          the number of unused byte on the stack. 4 in case of stack
+**                  overrun
+**
+*******************************************************************************/
+uint16_t gki_calc_stack(uint8_t task) {
+  int j, stacksize;
+  uint32_t MagicNum;
+  uint32_t* p;
+
+  stacksize = (int)gki_cb.com.OSStackSize[task];
+  p = (uint32_t*)gki_cb.com.OSStack[task]; /* assume stack is aligned, */
+  MagicNum = *p;
+
+  for (j = 0; j < stacksize; j++) {
+    if (*p++ != MagicNum) break;
+  }
+
+  return (j * sizeof(uint32_t));
+}
+
+/*******************************************************************************
+**
+** Function         GKI_print_task
+**
+** Description      Print task stack usage.
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_print_task(void) {
+#ifdef _BT_WIN32
+  GKI_TRACE_0("Service not available under insight");
+#else
+  uint8_t TaskId;
+
+  GKI_TRACE_0("TID TASKNAME STATE FREE_STACK  STACK");
+  for (TaskId = 0; TaskId < GKI_MAX_TASKS; TaskId++) {
+    if (gki_cb.com.OSRdyTbl[TaskId] != TASK_DEAD) {
+      GKI_TRACE_5("%2u   %-8s %-5s  0x%04X     0x%04X Bytes", (uint16_t)TaskId,
+                  gki_cb.com.OSTName[TaskId],
+                  OSTaskStates[gki_cb.com.OSRdyTbl[TaskId]],
+                  gki_calc_stack(TaskId), gki_cb.com.OSStackSize[TaskId]);
+    }
+  }
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         gki_print_buffer_statistics
+**
+** Description      Called internally by OSS to print the buffer pools
+**                  statistics
+**
+** Returns          void
+**
+*******************************************************************************/
+void gki_print_buffer_statistics(FP_PRINT print, int16_t pool) {
+  uint16_t i;
+  BUFFER_HDR_T* hdr;
+  uint16_t size, act_size, maxbuffs;
+  uint32_t* magic;
+
+  if (pool > GKI_NUM_TOTAL_BUF_POOLS || pool < 0) {
+    print("Not a valid Buffer pool\n");
+    return;
+  }
+
+  size = gki_cb.com.freeq[pool].size;
+  maxbuffs = gki_cb.com.freeq[pool].total;
+  act_size = size + BUFFER_PADDING_SIZE;
+  print("Buffer Pool[%u] size=%u cur_cnt=%u max_cnt=%u  total=%u\n", pool,
+        gki_cb.com.freeq[pool].size, gki_cb.com.freeq[pool].cur_cnt,
+        gki_cb.com.freeq[pool].max_cnt, gki_cb.com.freeq[pool].total);
+
+  print("      Owner  State    Sanity\n");
+  print("----------------------------\n");
+  hdr = (BUFFER_HDR_T*)(gki_cb.com.pool_start[pool]);
+  for (i = 0; i < maxbuffs; i++) {
+    magic = (uint32_t*)((uint8_t*)hdr + BUFFER_HDR_SIZE + size);
+    print("%3d: 0x%02x %4d %10s\n", i, hdr->task_id, hdr->status,
+          (*magic == MAGIC_NO) ? "OK" : "CORRUPTED");
+    hdr = (BUFFER_HDR_T*)((uint8_t*)hdr + act_size);
+  }
+  return;
+}
+
+/*******************************************************************************
+**
+** Function         gki_print_used_bufs
+**
+** Description      Dumps used buffers in the particular pool
+**
+*******************************************************************************/
+void gki_print_used_bufs(FP_PRINT print, uint8_t pool_id) {
+  uint8_t* p_start;
+  uint16_t buf_size;
+  uint16_t num_bufs;
+  BUFFER_HDR_T* p_hdr;
+  uint16_t i;
+  uint32_t* magic;
+  uint16_t* p;
+
+  if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS &&
+      gki_cb.com.pool_start[pool_id] != 0) {
+    print("Not a valid Buffer pool\n");
+    return;
+  }
+
+  p_start = gki_cb.com.pool_start[pool_id];
+  buf_size = gki_cb.com.freeq[pool_id].size + BUFFER_PADDING_SIZE;
+  num_bufs = gki_cb.com.freeq[pool_id].total;
+
+  for (i = 0; i < num_bufs; i++, p_start += buf_size) {
+    p_hdr = (BUFFER_HDR_T*)p_start;
+    magic = (uint32_t*)((uint8_t*)p_hdr + buf_size - sizeof(uint32_t));
+    p = (uint16_t*)p_hdr;
+
+    if (p_hdr->status != BUF_STATUS_FREE) {
+      print(
+          "%d:0x%x (Q:%d,Task:%s,Stat:%d,%s) %04x %04x %04x %04x %04x %04x "
+          "%04x %04x\n",
+          i, p_hdr, p_hdr->q_id, GKI_map_taskname(p_hdr->task_id),
+          p_hdr->status, (*magic == MAGIC_NO) ? "OK" : "CORRUPTED", p[0], p[1],
+          p[2], p[3], p[4], p[5], p[6], p[7]);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         gki_print_task
+**
+** Description      This function prints the task states.
+**
+** Returns          void
+**
+*******************************************************************************/
+void gki_print_task(FP_PRINT print) {
+  uint8_t i;
+
+  print("TID VID TASKNAME STATE WAIT WAITFOR TIMEOUT STACK\n");
+  print("-------------------------------------------------\n");
+  for (i = 0; i < GKI_MAX_TASKS; i++) {
+    if (gki_cb.com.OSRdyTbl[i] != TASK_DEAD) {
+      print("%2u  %-8s %-5s %04X    %04X %7u %u/%u Bytes\n", (uint16_t)i,
+            gki_cb.com.OSTName[i], OSTaskStates[gki_cb.com.OSRdyTbl[i]],
+            gki_cb.com.OSWaitEvt[i], gki_cb.com.OSWaitForEvt[i],
+            gki_cb.com.OSWaitTmr[i], gki_calc_stack(i),
+            gki_cb.com.OSStackSize[i]);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         gki_print_exception
+**
+** Description      This function prints the exception information.
+**
+** Returns          void
+**
+*******************************************************************************/
+void gki_print_exception(FP_PRINT print) {
+  uint16_t i;
+  EXCEPTION_T* pExp;
+
+  print("GKI Exceptions:\n");
+  for (i = 0; i < gki_cb.com.ExceptionCnt; i++) {
+    pExp = &gki_cb.com.Exception[i];
+    print("%d: Type=%d, Task=%d: %s\n", i, (int32_t)pExp->type,
+          (int32_t)pExp->taskid, (int8_t*)pExp->msg);
+  }
+}
+
+/*****************************************************************************/
+void gki_dump(uint8_t* s, uint16_t len, FP_PRINT print) {
+  uint16_t i, j;
+
+  for (i = 0, j = 0; i < len; i++) {
+    if (j == 0)
+      print("\n%lX: %02X, ", &s[i], s[i]);
+    else if (j == 7)
+      print("%02X,  ", s[i]);
+    else
+      print("%02X, ", s[i]);
+    if (++j == 16) j = 0;
+  }
+  print("\n");
+}
+
+void gki_dump2(uint16_t* s, uint16_t len, FP_PRINT print) {
+  uint16_t i, j;
+
+  for (i = 0, j = 0; i < len; i++) {
+    if (j == 0)
+      print("\n%lX: %04X, ", &s[i], s[i]);
+    else
+      print("%04X, ", s[i]);
+    if (++j == 8) j = 0;
+  }
+  print("\n");
+}
+
+void gki_dump4(uint32_t* s, uint16_t len, FP_PRINT print) {
+  uint16_t i, j;
+
+  for (i = 0, j = 0; i < len; i++) {
+    if (j == 0)
+      print("\n%lX: %08lX, ", &s[i], s[i]);
+    else
+      print("%08lX, ", s[i]);
+    if (++j == 4) j = 0;
+  }
+  print("\n");
+}
+
+#endif
diff --git a/src/gki/common/gki_inet.h b/src/gki/common/gki_inet.h
new file mode 100644
index 0000000..677013b
--- /dev/null
+++ b/src/gki/common/gki_inet.h
@@ -0,0 +1,47 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef GKI_INET_H
+#define GKI_INET_H
+
+#include "data_types.h"
+
+#define htons ntohs
+#define htonl ntohl
+
+#define htonets nettohs
+#define htonetl nettohl
+
+#if (BIG_ENDIAN == true)
+#define ntohs(n) (n)
+#define ntohl(n) (n)
+#define ntoh6(n) (n)
+
+#define nettohs(n) (n)
+#define nettohl(n) (n)
+#else
+extern uint16_t ntohs(uint16_t n);
+extern uint32_t ntohl(uint32_t n);
+extern uint8_t* ntoh6(uint8_t* p);
+
+#define nettohs(n) ((uint16_t)((((n) << 8) & 0xff00) | (((n) >> 8) & 0x00ff)))
+#define nettohl(n)                                        \
+  ((((n)&0x000000ff) << 24) | (((n) << 8) & 0x00ff0000) | \
+   (((n) >> 8) & 0x0000ff00) | (((n) >> 24) & 0x000000ff))
+#endif
+
+#endif /* GKI_INET_H */
diff --git a/src/gki/common/gki_time.c b/src/gki/common/gki_time.c
new file mode 100644
index 0000000..f941354
--- /dev/null
+++ b/src/gki/common/gki_time.c
@@ -0,0 +1,935 @@
+/******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "gki_int.h"
+
+#ifndef BT_ERROR_TRACE_0
+#define BT_ERROR_TRACE_0(l, m)
+#endif
+
+/* Make sure that this has been defined in target.h */
+#ifndef GKI_NUM_TIMERS
+#error NO TIMERS: Must define at least 1 timer in the system!
+#endif
+
+/* Largest signed positive timer count */
+#define GKI_NO_NEW_TMRS_STARTED (0x7fffffffL)
+/* Marks an unused timer list entry (initial value) */
+#define GKI_UNUSED_LIST_ENTRY (0x80000000L)
+#define GKI_MAX_INT32 (0x7fffffffL)
+
+/*******************************************************************************
+**
+** Function         gki_timers_init
+**
+** Description      This internal function is called once at startup to
+**                  initialize all the timer structures.
+**
+** Returns          void
+**
+*******************************************************************************/
+void gki_timers_init(void) {
+  uint8_t tt;
+
+  gki_cb.com.OSTicksTilExp =
+      0; /* Remaining time (of OSTimeCurTimeout) before next timer expires */
+  gki_cb.com.OSNumOrigTicks = 0;
+#if (GKI_DELAY_STOP_SYS_TICK > 0)
+  gki_cb.com.OSTicksTilStop = 0; /* clear inactivity delay timer */
+#endif
+
+  for (tt = 0; tt < GKI_MAX_TASKS; tt++) {
+    gki_cb.com.OSWaitTmr[tt] = 0;
+
+#if (GKI_NUM_TIMERS > 0)
+    gki_cb.com.OSTaskTmr0[tt] = 0;
+    gki_cb.com.OSTaskTmr0R[tt] = 0;
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+    gki_cb.com.OSTaskTmr1[tt] = 0;
+    gki_cb.com.OSTaskTmr1R[tt] = 0;
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+    gki_cb.com.OSTaskTmr2[tt] = 0;
+    gki_cb.com.OSTaskTmr2R[tt] = 0;
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+    gki_cb.com.OSTaskTmr3[tt] = 0;
+    gki_cb.com.OSTaskTmr3R[tt] = 0;
+#endif
+  }
+
+  for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++) {
+    gki_cb.com.timer_queues[tt] = NULL;
+  }
+
+  gki_cb.com.p_tick_cb = NULL;
+  gki_cb.com.system_tick_running = false;
+
+  return;
+}
+
+/*******************************************************************************
+**
+** Function         gki_timers_is_timer_running
+**
+** Description      This internal function is called to test if any gki timer
+**                  are running
+**
+**
+** Returns          true if at least one time is running in the system, false
+**                  else.
+**
+*******************************************************************************/
+bool gki_timers_is_timer_running(void) {
+  uint8_t tt;
+  for (tt = 0; tt < GKI_MAX_TASKS; tt++) {
+#if (GKI_NUM_TIMERS > 0)
+    if (gki_cb.com.OSTaskTmr0[tt]) {
+      return true;
+    }
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+    if (gki_cb.com.OSTaskTmr1[tt]) {
+      return true;
+    }
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+    if (gki_cb.com.OSTaskTmr2[tt]) {
+      return true;
+    }
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+    if (gki_cb.com.OSTaskTmr3[tt]) {
+      return true;
+    }
+#endif
+  }
+
+  return false;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_get_tick_count
+**
+** Description      This function returns the current system ticks
+**
+** Returns          The current number of system ticks
+**
+*******************************************************************************/
+uint32_t GKI_get_tick_count(void) { return gki_cb.com.OSTicks; }
+
+/*******************************************************************************
+**
+** Function         GKI_ready_to_sleep
+**
+** Description      This function returns the number of system ticks until the
+**                  next timer will expire.  It is typically called by a power
+**                  savings manager to find out how long it can have the system
+**                  sleep before it needs to service the next entry.
+**
+** Parameters:      None
+**
+** Returns          Number of ticks til the next timer expires
+**                  Note: The value is a signed  value.  This value should be
+**                      compared to x > 0, to avoid misinterpreting negative
+**                      tick values.
+**
+*******************************************************************************/
+int32_t GKI_ready_to_sleep(void) { return (gki_cb.com.OSTicksTilExp); }
+
+/*******************************************************************************
+**
+** Function         GKI_start_timer
+**
+** Description      An application can call this function to start one of
+**                  it's four general purpose timers. Any of the four timers
+**                  can be 1-shot or continuous. If a timer is already running,
+**                  it will be reset to the new parameters.
+**
+** Parameters       tnum            - (input) timer number to be started
+**                                            (TIMER_0, TIMER_1, TIMER_2, or
+**                                            TIMER_3)
+**                  ticks           - (input) the number of system ticks til the
+**                                              timer expires.
+**                  is_continuous   - (input) true if timer restarts
+**                                            automatically, else false if it is
+**                                            a 'one-shot'.
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_start_timer(uint8_t tnum, int32_t ticks, bool is_continuous) {
+  int32_t reload;
+  int32_t orig_ticks;
+  uint8_t task_id = GKI_get_taskid();
+  bool bad_timer = false;
+
+  if (ticks <= 0) ticks = 1;
+
+  orig_ticks = ticks; /* save the ticks in case adjustment is necessary */
+
+  /* If continuous timer, set reload, else set it to 0 */
+  if (is_continuous)
+    reload = ticks;
+  else
+    reload = 0;
+
+  GKI_disable();
+
+  if (gki_timers_is_timer_running() == false) {
+#if (GKI_DELAY_STOP_SYS_TICK > 0)
+    /* if inactivity delay timer is not running, start system tick */
+    if (gki_cb.com.OSTicksTilStop == 0) {
+#endif
+      if (gki_cb.com.p_tick_cb) {
+        /* start system tick */
+        gki_cb.com.system_tick_running = true;
+        (gki_cb.com.p_tick_cb)(true);
+      }
+#if (GKI_DELAY_STOP_SYS_TICK > 0)
+    } else {
+      /* clear inactivity delay timer */
+      gki_cb.com.OSTicksTilStop = 0;
+    }
+#endif
+  }
+  /* Add the time since the last task timer update.
+  ** Note that this works when no timers are active since
+  ** both OSNumOrigTicks and OSTicksTilExp are 0.
+  */
+  if (GKI_MAX_INT32 - (gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp) >
+      ticks) {
+    ticks += gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp;
+  } else
+    ticks = GKI_MAX_INT32;
+
+  switch (tnum) {
+#if (GKI_NUM_TIMERS > 0)
+    case TIMER_0:
+      gki_cb.com.OSTaskTmr0R[task_id] = reload;
+      gki_cb.com.OSTaskTmr0[task_id] = ticks;
+      break;
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+    case TIMER_1:
+      gki_cb.com.OSTaskTmr1R[task_id] = reload;
+      gki_cb.com.OSTaskTmr1[task_id] = ticks;
+      break;
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+    case TIMER_2:
+      gki_cb.com.OSTaskTmr2R[task_id] = reload;
+      gki_cb.com.OSTaskTmr2[task_id] = ticks;
+      break;
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+    case TIMER_3:
+      gki_cb.com.OSTaskTmr3R[task_id] = reload;
+      gki_cb.com.OSTaskTmr3[task_id] = ticks;
+      break;
+#endif
+    default:
+      bad_timer = true; /* Timer number is bad, so do not use */
+  }
+
+  /* Update the expiration timeout if a legitimate timer */
+  if (!bad_timer) {
+    /* Only update the timeout value if it is less than any other newly started
+     * timers */
+    gki_adjust_timer_count(orig_ticks);
+  }
+
+  GKI_enable();
+}
+
+/*******************************************************************************
+**
+** Function         GKI_stop_timer
+**
+** Description      An application can call this function to stop one of
+**                  it's four general purpose timers. There is no harm in
+**                  stopping a timer that is already stopped.
+**
+** Parameters       tnum - (input) timer number to be started (TIMER_0,
+**                                 TIMER_1, TIMER_2, or TIMER_3)
+** Returns          void
+**
+*******************************************************************************/
+void GKI_stop_timer(uint8_t tnum) {
+  uint8_t task_id = GKI_get_taskid();
+
+  GKI_disable();
+
+  switch (tnum) {
+#if (GKI_NUM_TIMERS > 0)
+    case TIMER_0:
+      gki_cb.com.OSTaskTmr0R[task_id] = 0;
+      gki_cb.com.OSTaskTmr0[task_id] = 0;
+      break;
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+    case TIMER_1:
+      gki_cb.com.OSTaskTmr1R[task_id] = 0;
+      gki_cb.com.OSTaskTmr1[task_id] = 0;
+      break;
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+    case TIMER_2:
+      gki_cb.com.OSTaskTmr2R[task_id] = 0;
+      gki_cb.com.OSTaskTmr2[task_id] = 0;
+      break;
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+    case TIMER_3:
+      gki_cb.com.OSTaskTmr3R[task_id] = 0;
+      gki_cb.com.OSTaskTmr3[task_id] = 0;
+      break;
+#endif
+  }
+
+  if (gki_timers_is_timer_running() == false) {
+    if (gki_cb.com.p_tick_cb) {
+#if (GKI_DELAY_STOP_SYS_TICK > 0)
+      /* if inactivity delay timer is not running */
+      if ((gki_cb.com.system_tick_running) &&
+          (gki_cb.com.OSTicksTilStop == 0)) {
+        /* set inactivity delay timer */
+        /* when timer expires, system tick will be stopped */
+        gki_cb.com.OSTicksTilStop = GKI_DELAY_STOP_SYS_TICK;
+      }
+#else
+      gki_cb.com.system_tick_running = false;
+      gki_cb.com.p_tick_cb(false); /* stop system tick */
+#endif
+    }
+  }
+
+  GKI_enable();
+}
+
+/*******************************************************************************
+**
+** Function         GKI_timer_update
+**
+** Description      This function is called by an OS to drive the GKI's timers.
+**                  It is typically called at every system tick to
+**                  update the timers for all tasks, and check for timeouts.
+**
+**                  Note: It has been designed to also allow for variable tick
+**                        updates so that systems with strict power savings
+**                        requirements can have the update occur at variable
+**                        intervals.
+**
+** Parameters:      ticks_since_last_update - (input) This is the number of
+**                  TICKS that have occurred since the last time
+**                  GKI_timer_update was called.
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_timer_update(int32_t ticks_since_last_update) {
+  uint8_t task_id;
+  long next_expiration; /* Holds the next soonest expiration time after this
+                           update */
+
+  /* Increment the number of ticks used for time stamps */
+  gki_cb.com.OSTicks += ticks_since_last_update;
+
+  /* If any timers are running in any tasks, decrement the remaining time til
+   * the timer updates need to take place (next expiration occurs)
+   */
+  gki_cb.com.OSTicksTilExp -= ticks_since_last_update;
+
+  /* Don't allow timer interrupt nesting */
+  if (gki_cb.com.timer_nesting) return;
+
+  gki_cb.com.timer_nesting = 1;
+
+#if (GKI_DELAY_STOP_SYS_TICK > 0)
+  /* if inactivity delay timer is set and expired */
+  if (gki_cb.com.OSTicksTilStop) {
+    if (gki_cb.com.OSTicksTilStop <= (uint32_t)ticks_since_last_update) {
+      if (gki_cb.com.p_tick_cb) {
+        gki_cb.com.system_tick_running = false;
+        (gki_cb.com.p_tick_cb)(false); /* stop system tick */
+      }
+      gki_cb.com.OSTicksTilStop = 0; /* clear inactivity delay timer */
+      gki_cb.com.timer_nesting = 0;
+      return;
+    } else
+      gki_cb.com.OSTicksTilStop -= ticks_since_last_update;
+  }
+#endif
+
+  /* No need to update the ticks if no timeout has occurred */
+  if (gki_cb.com.OSTicksTilExp > 0) {
+    gki_cb.com.timer_nesting = 0;
+    return;
+  }
+
+  GKI_disable();
+
+  next_expiration = GKI_NO_NEW_TMRS_STARTED;
+
+  /* If here then gki_cb.com.OSTicksTilExp <= 0. If negative, then increase
+     gki_cb.com.OSNumOrigTicks
+     to account for the difference so timer updates below are decremented by the
+     full number
+     of ticks. gki_cb.com.OSNumOrigTicks is reset at the bottom of this function
+     so changing this
+     value only affects the timer updates below
+   */
+  gki_cb.com.OSNumOrigTicks -= gki_cb.com.OSTicksTilExp;
+
+  /* Check for OS Task Timers */
+  for (task_id = 0; task_id < GKI_MAX_TASKS; task_id++) {
+    if (gki_cb.com.OSRdyTbl[task_id] == TASK_DEAD) {
+      // task is shutdown do not try to service timers
+      continue;
+    }
+
+    if (gki_cb.com.OSWaitTmr[task_id] > 0) /* If timer is running */
+    {
+      gki_cb.com.OSWaitTmr[task_id] -= gki_cb.com.OSNumOrigTicks;
+      if (gki_cb.com.OSWaitTmr[task_id] <= 0) {
+        /* Timer Expired */
+        gki_cb.com.OSRdyTbl[task_id] = TASK_READY;
+      }
+    }
+
+#if (GKI_NUM_TIMERS > 0)
+    /* If any timer is running, decrement */
+    if (gki_cb.com.OSTaskTmr0[task_id] > 0) {
+      gki_cb.com.OSTaskTmr0[task_id] -= gki_cb.com.OSNumOrigTicks;
+
+      if (gki_cb.com.OSTaskTmr0[task_id] <= 0) {
+/* Set Timer 0 Expired event mask and reload timer */
+#if (GKI_TIMER_UPDATES_FROM_ISR == true)
+        GKI_isend_event(task_id, TIMER_0_EVT_MASK);
+#else
+        GKI_send_event(task_id, TIMER_0_EVT_MASK);
+#endif
+        gki_cb.com.OSTaskTmr0[task_id] = gki_cb.com.OSTaskTmr0R[task_id];
+      }
+    }
+
+    /* Check to see if this timer is the next one to expire */
+    if (gki_cb.com.OSTaskTmr0[task_id] > 0 &&
+        gki_cb.com.OSTaskTmr0[task_id] < next_expiration)
+      next_expiration = gki_cb.com.OSTaskTmr0[task_id];
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+    /* If any timer is running, decrement */
+    if (gki_cb.com.OSTaskTmr1[task_id] > 0) {
+      gki_cb.com.OSTaskTmr1[task_id] -= gki_cb.com.OSNumOrigTicks;
+
+      if (gki_cb.com.OSTaskTmr1[task_id] <= 0) {
+/* Set Timer 1 Expired event mask and reload timer */
+#if (GKI_TIMER_UPDATES_FROM_ISR == true)
+        GKI_isend_event(task_id, TIMER_1_EVT_MASK);
+#else
+        GKI_send_event(task_id, TIMER_1_EVT_MASK);
+#endif
+        gki_cb.com.OSTaskTmr1[task_id] = gki_cb.com.OSTaskTmr1R[task_id];
+      }
+    }
+
+    /* Check to see if this timer is the next one to expire */
+    if (gki_cb.com.OSTaskTmr1[task_id] > 0 &&
+        gki_cb.com.OSTaskTmr1[task_id] < next_expiration)
+      next_expiration = gki_cb.com.OSTaskTmr1[task_id];
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+    /* If any timer is running, decrement */
+    if (gki_cb.com.OSTaskTmr2[task_id] > 0) {
+      gki_cb.com.OSTaskTmr2[task_id] -= gki_cb.com.OSNumOrigTicks;
+
+      if (gki_cb.com.OSTaskTmr2[task_id] <= 0) {
+/* Set Timer 2 Expired event mask and reload timer */
+#if (GKI_TIMER_UPDATES_FROM_ISR == true)
+        GKI_isend_event(task_id, TIMER_2_EVT_MASK);
+#else
+        GKI_send_event(task_id, TIMER_2_EVT_MASK);
+#endif
+        gki_cb.com.OSTaskTmr2[task_id] = gki_cb.com.OSTaskTmr2R[task_id];
+      }
+    }
+
+    /* Check to see if this timer is the next one to expire */
+    if (gki_cb.com.OSTaskTmr2[task_id] > 0 &&
+        gki_cb.com.OSTaskTmr2[task_id] < next_expiration)
+      next_expiration = gki_cb.com.OSTaskTmr2[task_id];
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+    /* If any timer is running, decrement */
+    if (gki_cb.com.OSTaskTmr3[task_id] > 0) {
+      gki_cb.com.OSTaskTmr3[task_id] -= gki_cb.com.OSNumOrigTicks;
+
+      if (gki_cb.com.OSTaskTmr3[task_id] <= 0) {
+/* Set Timer 3 Expired event mask and reload timer */
+#if (GKI_TIMER_UPDATES_FROM_ISR == true)
+        GKI_isend_event(task_id, TIMER_3_EVT_MASK);
+#else
+        GKI_send_event(task_id, TIMER_3_EVT_MASK);
+#endif
+        gki_cb.com.OSTaskTmr3[task_id] = gki_cb.com.OSTaskTmr3R[task_id];
+      }
+    }
+
+    /* Check to see if this timer is the next one to expire */
+    if (gki_cb.com.OSTaskTmr3[task_id] > 0 &&
+        gki_cb.com.OSTaskTmr3[task_id] < next_expiration)
+      next_expiration = gki_cb.com.OSTaskTmr3[task_id];
+#endif
+  }
+
+  /* Set the next timer experation value if there is one to start */
+  if (next_expiration < GKI_NO_NEW_TMRS_STARTED) {
+    gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = next_expiration;
+  } else {
+    gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = 0;
+  }
+
+  gki_cb.com.timer_nesting = 0;
+
+  GKI_enable();
+
+  return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_timer_queue_empty
+**
+** Description      This function is called by applications to see whether the
+**                  timer queue is empty
+**
+** Parameters
+**
+** Returns          bool
+**
+*******************************************************************************/
+bool GKI_timer_queue_empty(void) {
+  uint8_t tt;
+
+  for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++) {
+    if (gki_cb.com.timer_queues[tt]) return false;
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_timer_queue_register_callback
+**
+** Description      This function is called by applications to register system
+**                  tick start/stop callback for time queues
+**
+**
+** Parameters       p_callback - (input) pointer to the system tick callback
+**
+** Returns          bool
+**
+*******************************************************************************/
+void GKI_timer_queue_register_callback(SYSTEM_TICK_CBACK* p_callback) {
+  gki_cb.com.p_tick_cb = p_callback;
+
+  return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_init_timer_list
+**
+** Description      This function is called by applications when they
+**                  want to initialize a timer list.
+**
+** Parameters       p_timer_listq - (input) pointer to the timer list queue
+**                                          object
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_init_timer_list(TIMER_LIST_Q* p_timer_listq) {
+  p_timer_listq->p_first = NULL;
+  p_timer_listq->p_last = NULL;
+  p_timer_listq->last_ticks = 0;
+
+  return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_init_timer_list_entry
+**
+** Description      This function is called by the applications when they
+**                  want to initialize a timer list entry. This must be
+**                  done prior to first use of the entry.
+**
+** Parameters       p_tle - (input) pointer to a timer list queue entry
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_init_timer_list_entry(TIMER_LIST_ENT* p_tle) {
+  p_tle->p_next = NULL;
+  p_tle->p_prev = NULL;
+  p_tle->ticks = GKI_UNUSED_LIST_ENTRY;
+  p_tle->in_use = false;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_update_timer_list
+**
+** Description      This function is called by the applications when they
+**                  want to update a timer list. This should be at every
+**                  timer list unit tick, e.g. once per sec, once per minute
+**                  etc.
+**
+** Parameters       p_timer_listq - (input) pointer to the timer list queue
+**                  object
+**                  num_units_since_last_update - (input) number of units since
+**                  the last update (allows for variable unit update)
+**
+** NOTE: The following timer list update routines should not be used for exact
+**       time critical purposes.  The timer tasks should be used when exact
+**       timing is needed.
+**
+** Returns          the number of timers that have expired
+**
+*******************************************************************************/
+uint16_t GKI_update_timer_list(TIMER_LIST_Q* p_timer_listq,
+                               int32_t num_units_since_last_update) {
+  TIMER_LIST_ENT* p_tle;
+  uint16_t num_time_out = 0;
+  int32_t rem_ticks;
+  int32_t temp_ticks;
+
+  p_tle = p_timer_listq->p_first;
+
+  /* First, get the guys who have previously timed out */
+  /* Note that the tick value of the timers should always be '0' */
+  while ((p_tle) && (p_tle->ticks <= 0)) {
+    num_time_out++;
+    p_tle = p_tle->p_next;
+  }
+
+  /* Timer entriy tick values are relative to the preceeding entry */
+  rem_ticks = num_units_since_last_update;
+
+  /* Now, adjust remaining timer entries */
+  while ((p_tle != NULL) && (rem_ticks > 0)) {
+    temp_ticks = p_tle->ticks;
+    p_tle->ticks -= rem_ticks;
+
+    /* See if this timer has just timed out */
+    if (p_tle->ticks <= 0) {
+      /* We set the number of ticks to '0' so that the legacy code
+       * that assumes a '0' or nonzero value will still work as coded. */
+      p_tle->ticks = 0;
+
+      num_time_out++;
+    }
+
+    rem_ticks -= temp_ticks; /* Decrement the remaining ticks to process */
+    p_tle = p_tle->p_next;
+  }
+
+  if (p_timer_listq->last_ticks > 0) {
+    p_timer_listq->last_ticks -= num_units_since_last_update;
+
+    /* If the last timer has expired set last_ticks to 0 so that other list
+    * update
+    * functions will calculate correctly
+    */
+    if (p_timer_listq->last_ticks < 0) p_timer_listq->last_ticks = 0;
+  }
+
+  return (num_time_out);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_get_remaining_ticks
+**
+** Description      This function is called by an application to get remaining
+**                  ticks to expire
+**
+** Parameters       p_timer_listq - (input) pointer to the timer list queue
+**                                          object
+**                  p_target_tle - (input) pointer to a timer list queue entry
+**
+** Returns          0 if timer is not used or timer is not in the list
+**                  remaining ticks if success
+**
+*******************************************************************************/
+uint32_t GKI_get_remaining_ticks(TIMER_LIST_Q* p_timer_listq,
+                                 TIMER_LIST_ENT* p_target_tle) {
+  TIMER_LIST_ENT* p_tle;
+  uint32_t rem_ticks = 0;
+
+  if (p_target_tle->in_use) {
+    p_tle = p_timer_listq->p_first;
+
+    /* adding up all of ticks in previous entries */
+    while ((p_tle) && (p_tle != p_target_tle)) {
+      rem_ticks += p_tle->ticks;
+      p_tle = p_tle->p_next;
+    }
+
+    /* if found target entry */
+    if ((p_tle != NULL) && (p_tle == p_target_tle)) {
+      rem_ticks += p_tle->ticks;
+    } else {
+      BT_ERROR_TRACE_0(TRACE_LAYER_GKI,
+                       "GKI_get_remaining_ticks: No timer entry in the list");
+      return (0);
+    }
+  } else {
+    BT_ERROR_TRACE_0(TRACE_LAYER_GKI,
+                     "GKI_get_remaining_ticks: timer entry is not active");
+  }
+
+  return (rem_ticks);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_add_to_timer_list
+**
+** Description      This function is called by an application to add a timer
+**                  entry to a timer list.
+**
+**                  Note: A timer value of '0' will effectively insert an
+**                        already expired event.  Negative tick values will be
+**                        ignored.
+**
+** Parameters       p_timer_listq - (input) pointer to the timer list queue
+**                                          object
+**                  p_tle - (input) pointer to a timer list queue entry
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_add_to_timer_list(TIMER_LIST_Q* p_timer_listq, TIMER_LIST_ENT* p_tle) {
+  uint32_t nr_ticks_total;
+  uint8_t tt;
+  TIMER_LIST_ENT* p_temp;
+  if (p_tle == NULL || p_timer_listq == NULL) {
+    GKI_TRACE_3("%s: invalid argument %x, %x****************************<<",
+                __func__, p_timer_listq, p_tle);
+    return;
+  }
+
+  /* Only process valid tick values */
+  if (p_tle->ticks >= 0) {
+    /* If this entry is the last in the list */
+    if (p_tle->ticks >= p_timer_listq->last_ticks) {
+      /* If this entry is the only entry in the list */
+      if (p_timer_listq->p_first == NULL)
+        p_timer_listq->p_first = p_tle;
+      else {
+        /* Insert the entry onto the end of the list */
+        if (p_timer_listq->p_last != NULL)
+          p_timer_listq->p_last->p_next = p_tle;
+
+        p_tle->p_prev = p_timer_listq->p_last;
+      }
+
+      p_tle->p_next = NULL;
+      p_timer_listq->p_last = p_tle;
+      nr_ticks_total = p_tle->ticks;
+      p_tle->ticks -= p_timer_listq->last_ticks;
+
+      p_timer_listq->last_ticks = nr_ticks_total;
+    } else /* This entry needs to be inserted before the last entry */
+    {
+      /* Find the entry that the new one needs to be inserted in front of */
+      p_temp = p_timer_listq->p_first;
+      while (p_tle->ticks > p_temp->ticks) {
+        /* Update the tick value if looking at an unexpired entry */
+        if (p_temp->ticks > 0) p_tle->ticks -= p_temp->ticks;
+
+        p_temp = p_temp->p_next;
+      }
+
+      /* The new entry is the first in the list */
+      if (p_temp == p_timer_listq->p_first) {
+        p_tle->p_next = p_timer_listq->p_first;
+        p_timer_listq->p_first->p_prev = p_tle;
+        p_timer_listq->p_first = p_tle;
+      } else {
+        p_temp->p_prev->p_next = p_tle;
+        p_tle->p_prev = p_temp->p_prev;
+        p_temp->p_prev = p_tle;
+        p_tle->p_next = p_temp;
+      }
+      p_temp->ticks -= p_tle->ticks;
+    }
+
+    p_tle->in_use = true;
+
+    /* if we already add this timer queue to the array */
+    for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++) {
+      if (gki_cb.com.timer_queues[tt] == p_timer_listq) return;
+    }
+    /* add this timer queue to the array */
+    for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++) {
+      if (gki_cb.com.timer_queues[tt] == NULL) break;
+    }
+    if (tt < GKI_MAX_TIMER_QUEUES) {
+      gki_cb.com.timer_queues[tt] = p_timer_listq;
+    }
+  }
+
+  return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_remove_from_timer_list
+**
+** Description      This function is called by an application to remove a timer
+**                  entry from a timer list.
+**
+** Parameters       p_timer_listq  - (input) pointer to the timer list queue
+**                                            object
+**                  p_tle - (input) pointer to a timer list queue entry
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_remove_from_timer_list(TIMER_LIST_Q* p_timer_listq,
+                                TIMER_LIST_ENT* p_tle) {
+  uint8_t tt;
+
+  /* Verify that the entry is valid */
+  if (p_tle == NULL || p_tle->in_use == false ||
+      p_timer_listq->p_first == NULL) {
+    return;
+  }
+
+  /* Add the ticks remaining in this timer (if any) to the next guy in the list.
+  ** Note: Expired timers have a tick value of '0'.
+  */
+  if (p_tle->p_next != NULL) {
+    p_tle->p_next->ticks += p_tle->ticks;
+  } else {
+    p_timer_listq->last_ticks -= p_tle->ticks;
+  }
+
+  /* Unlink timer from the list.
+  */
+  if (p_timer_listq->p_first == p_tle) {
+    p_timer_listq->p_first = p_tle->p_next;
+
+    if (p_timer_listq->p_first != NULL) p_timer_listq->p_first->p_prev = NULL;
+
+    if (p_timer_listq->p_last == p_tle) p_timer_listq->p_last = NULL;
+  } else {
+    if (p_timer_listq->p_last == p_tle) {
+      p_timer_listq->p_last = p_tle->p_prev;
+
+      if (p_timer_listq->p_last != NULL) p_timer_listq->p_last->p_next = NULL;
+    } else {
+      if (p_tle->p_next != NULL && p_tle->p_next->p_prev == p_tle)
+        p_tle->p_next->p_prev = p_tle->p_prev;
+      else {
+        /* Error case - chain messed up ?? */
+        return;
+      }
+
+      if (p_tle->p_prev != NULL && p_tle->p_prev->p_next == p_tle)
+        p_tle->p_prev->p_next = p_tle->p_next;
+      else {
+        /* Error case - chain messed up ?? */
+        return;
+      }
+    }
+  }
+
+  p_tle->p_next = p_tle->p_prev = NULL;
+  p_tle->ticks = GKI_UNUSED_LIST_ENTRY;
+  p_tle->in_use = false;
+
+  /* if timer queue is empty */
+  if (p_timer_listq->p_first == NULL && p_timer_listq->p_last == NULL) {
+    for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++) {
+      if (gki_cb.com.timer_queues[tt] == p_timer_listq) {
+        gki_cb.com.timer_queues[tt] = NULL;
+        break;
+      }
+    }
+  }
+
+  return;
+}
+
+/*******************************************************************************
+**
+** Function         gki_adjust_timer_count
+**
+** Description      This function is called whenever a new timer or GKI_wait
+**                  occurs to adjust (if necessary) the current time til the
+**                  first expiration. This only needs to make an adjustment if
+**                  the new timer (in ticks) is less than the number of ticks
+**                  remaining on the current timer.
+**
+** Parameters:      ticks - (input) number of system ticks of the new timer
+**                                  entry
+**
+**                  NOTE:  This routine MUST be called while interrupts are
+**                         disabled to avoid updates while adjusting the timer
+**                         variables.
+**
+** Returns          void
+**
+*******************************************************************************/
+void gki_adjust_timer_count(int32_t ticks) {
+  if (ticks > 0) {
+    /* See if the new timer expires before the current first expiration */
+    if (gki_cb.com.OSNumOrigTicks == 0 ||
+        (ticks < gki_cb.com.OSTicksTilExp && gki_cb.com.OSTicksTilExp > 0)) {
+      gki_cb.com.OSNumOrigTicks =
+          (gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp) + ticks;
+      gki_cb.com.OSTicksTilExp = ticks;
+    }
+  }
+
+  return;
+}
diff --git a/src/gki/ulinux/data_types.h b/src/gki/ulinux/data_types.h
new file mode 100644
index 0000000..5ede586
--- /dev/null
+++ b/src/gki/ulinux/data_types.h
@@ -0,0 +1,74 @@
+/******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef DATA_TYPES_H
+#define DATA_TYPES_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#ifndef false
+#define false 0
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+typedef uint32_t TIME_STAMP;
+
+#ifndef true
+#define true (!false)
+#endif
+
+#ifndef TRUE
+#define TRUE (!FALSE)
+#endif
+typedef unsigned char UBYTE;
+
+#ifdef __arm
+#define PACKED __packed
+#define INLINE __inline
+#else
+#define PACKED
+#define INLINE
+#endif
+
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN false
+#endif
+
+#define UINT16_LOW_BYTE(x) ((x)&0xff)
+#define UINT16_HI_BYTE(x) ((x) >> 8)
+
+/* MACRO definitions for safe string functions */
+/* Replace standard string functions with safe functions if available */
+#define BCM_STRCAT_S(x1,x2,x3)      strcat((x1),(x3))
+#define BCM_STRNCAT_S(x1,x2,x3,x4)  strncat((x1),(x3),(x4))
+#define BCM_STRCPY_S(x1,x2,x3)      strcpy((x1),(x3))
+#define BCM_STRNCPY_S(x1,x2,x3,x4)  strncpy((x1),(x3),(x4))
+#define BCM_SPRINTF_S(x1,x2,x3,x4)  sprintf((x1),(x3),(x4))
+#define BCM_VSPRINTF_S(x1,x2,x3,x4) vsprintf((x1),(x3),(x4))
+#define NQ_STRLCPY_S(x1,x2,x3,x4)   strlcpy((x1),(x3),(x2))
+
+#endif
diff --git a/src/gki/ulinux/gki_int.h b/src/gki/ulinux/gki_int.h
new file mode 100644
index 0000000..07cc590
--- /dev/null
+++ b/src/gki/ulinux/gki_int.h
@@ -0,0 +1,71 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef GKI_INT_H
+#define GKI_INT_H
+
+#include "gki_common.h"
+#include <stdlib.h>
+#include <pthread.h>
+
+/**********************************************************************
+** OS specific definitions
+*/
+#ifdef ANDROID
+#include <sys/times.h>
+#endif
+
+typedef struct {
+  pthread_mutex_t GKI_mutex;
+  pthread_t thread_id[GKI_MAX_TASKS];
+  pthread_mutex_t thread_evt_mutex[GKI_MAX_TASKS];
+  pthread_cond_t thread_evt_cond[GKI_MAX_TASKS];
+  pthread_mutex_t thread_timeout_mutex[GKI_MAX_TASKS];
+  pthread_cond_t thread_timeout_cond[GKI_MAX_TASKS];
+  int no_timer_suspend; /* 1: no suspend, 0 stop calling GKI_timer_update() */
+  pthread_mutex_t gki_timer_mutex;
+  pthread_cond_t gki_timer_cond;
+  int gki_timer_wake_lock_on;
+#if (GKI_DEBUG == true)
+  pthread_mutex_t GKI_trace_mutex;
+#endif
+} tGKI_OS;
+
+/* condition to exit or continue GKI_run() timer loop */
+#define GKI_TIMER_TICK_RUN_COND 1
+#define GKI_TIMER_TICK_STOP_COND 0
+#define GKI_TIMER_TICK_EXIT_COND 2
+
+extern void gki_system_tick_start_stop_cback(bool start);
+
+/* Contains common control block as well as OS specific variables */
+typedef struct {
+  tGKI_OS os;
+  tGKI_COM_CB com;
+} tGKI_CB;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern tGKI_CB gki_cb;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/gki/ulinux/gki_ulinux.c b/src/gki/ulinux/gki_ulinux.c
new file mode 100644
index 0000000..bbcff6e
--- /dev/null
+++ b/src/gki/ulinux/gki_ulinux.c
@@ -0,0 +1,1269 @@
+/******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include <stdio.h>
+#include <stdarg.h>
+#include <errno.h>
+
+#define GKI_DEBUG false
+
+#include <pthread.h> /* must be 1st header defined  */
+#include <time.h>
+#include "gki_int.h"
+#include "gki_target.h"
+#include "bt_trace.h"
+
+/* Temp android logging...move to android tgt config file */
+
+#ifndef LINUX_NATIVE
+#include <cutils/log.h>
+#else
+#define LOGV(format, ...) fprintf(stdout, LOG_TAG format, ##__VA_ARGS__)
+#define LOGE(format, ...) fprintf(stderr, LOG_TAG format, ##__VA_ARGS__)
+#define LOGI(format, ...) fprintf(stdout, LOG_TAG format, ##__VA_ARGS__)
+
+#define SCHED_NORMAL 0
+#define SCHED_FIFO 1
+#define SCHED_RR 2
+#define SCHED_BATCH 3
+
+#endif
+
+/* Define the structure that holds the GKI variables
+*/
+tGKI_CB gki_cb;
+
+#define NANOSEC_PER_MILLISEC (1000000)
+#define NSEC_PER_SEC (1000 * NANOSEC_PER_MILLISEC)
+
+/* works only for 1ms to 1000ms heart beat ranges */
+#define LINUX_SEC (1000 / TICKS_PER_SEC)
+// #define GKI_TICK_TIMER_DEBUG
+
+#define LOCK(m) pthread_mutex_lock(&m)
+#define UNLOCK(m) pthread_mutex_unlock(&m)
+#define INIT(m) pthread_mutex_init(&m, NULL)
+
+/* this kind of mutex go into tGKI_OS control block!!!! */
+/* static pthread_mutex_t GKI_sched_mutex; */
+/*static pthread_mutex_t thread_delay_mutex;
+static pthread_cond_t thread_delay_cond;
+static pthread_mutex_t gki_timer_update_mutex;
+static pthread_cond_t   gki_timer_update_cond;
+*/
+#ifdef NO_GKI_RUN_RETURN
+static pthread_t timer_thread_id = 0;
+#endif
+#if (NXP_EXTNS == TRUE)
+uint8_t gki_buf_init_done = false;
+#endif
+/* For Android */
+
+typedef struct {
+  uint8_t task_id;         /* GKI task id */
+  TASKPTR task_entry;      /* Task entry function*/
+  uintptr_t params;        /* Extra params to pass to task entry function */
+  pthread_cond_t* pCond;   /* for android*/
+  pthread_mutex_t* pMutex; /* for android*/
+} gki_pthread_info_t;
+gki_pthread_info_t gki_pthread_info[GKI_MAX_TASKS];
+
+static struct tms buffer;
+
+/*******************************************************************************
+**
+** Function         gki_task_entry
+**
+** Description      entry point of GKI created tasks
+**
+** Returns          void
+**
+*******************************************************************************/
+void gki_task_entry(uintptr_t params) {
+  pthread_t thread_id = pthread_self();
+  gki_pthread_info_t* p_pthread_info = (gki_pthread_info_t*)params;
+  GKI_TRACE_5("gki_task_entry task_id=%i, thread_id=%x/%x, pCond/pMutex=%x/%x",
+              p_pthread_info->task_id,
+              gki_cb.os.thread_id[p_pthread_info->task_id], pthread_self(),
+              p_pthread_info->pCond, p_pthread_info->pMutex);
+
+  gki_cb.os.thread_id[p_pthread_info->task_id] = thread_id;
+  /* Call the actual thread entry point */
+  (p_pthread_info->task_entry)(p_pthread_info->params);
+
+  GKI_TRACE_ERROR_1("gki_task task_id=%i terminating", p_pthread_info->task_id);
+  gki_cb.os.thread_id[p_pthread_info->task_id] = 0;
+
+  return;
+}
+/* end android */
+
+#ifndef ANDROID
+void GKI_TRACE(char* fmt, ...) {
+  LOCK(gki_cb.os.GKI_trace_mutex);
+  va_list ap;
+
+  va_start(ap, fmt);
+  vfprintf(stderr, fmt, ap);
+  fprintf(stderr, "\n");
+
+  va_end(ap);
+  UNLOCK(gki_cb.os.GKI_trace_mutex);
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         GKI_init
+**
+** Description      This function is called once at startup to initialize
+**                  all the timer structures.
+**
+** Returns          void
+**
+*******************************************************************************/
+
+void GKI_init(void) {
+  pthread_mutexattr_t attr;
+  tGKI_OS* p_os;
+#if (NXP_EXTNS == TRUE)
+  /* Added to avoid re-initialization of memory pool (memory leak) */
+  if (!gki_buf_init_done) {
+    memset(&gki_cb, 0, sizeof(gki_cb));
+    gki_buffer_init();
+    gki_buf_init_done = true;
+  }
+#else
+  memset(&gki_cb, 0, sizeof(gki_cb));
+  gki_buffer_init();
+#endif
+
+  gki_timers_init();
+  gki_cb.com.OSTicks = (uint32_t)times(&buffer);
+
+  pthread_mutexattr_init(&attr);
+
+#ifndef __CYGWIN__
+  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
+#endif
+  p_os = &gki_cb.os;
+  pthread_mutex_init(&p_os->GKI_mutex, &attr);
+/* pthread_mutex_init(&GKI_sched_mutex, NULL); */
+#if (GKI_DEBUG == true)
+  pthread_mutex_init(&p_os->GKI_trace_mutex, NULL);
+#endif
+  /* pthread_mutex_init(&thread_delay_mutex, NULL); */ /* used in GKI_delay */
+  /* pthread_cond_init (&thread_delay_cond, NULL); */
+
+  /* Initialiase GKI_timer_update suspend variables & mutexes to be in running
+   * state.
+   * this works too even if GKI_NO_TICK_STOP is defined in btld.txt */
+  p_os->no_timer_suspend = GKI_TIMER_TICK_RUN_COND;
+  pthread_mutex_init(&p_os->gki_timer_mutex, NULL);
+  pthread_cond_init(&p_os->gki_timer_cond, NULL);
+#if (NXP_EXTNS == TRUE)
+  pthread_mutexattr_destroy(&attr);
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         GKI_get_os_tick_count
+**
+** Description      This function is called to retrieve the native OS system
+**                  tick.
+**
+** Returns          Tick count of native OS.
+**
+*******************************************************************************/
+uint32_t GKI_get_os_tick_count(void) {
+  /* TODO - add any OS specific code here
+  **/
+  return (gki_cb.com.OSTicks);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_create_task
+**
+** Description      This function is called to create a new OSS task.
+**
+** Parameters:      task_entry  - (input) pointer to the entry function of the
+**                                        task
+**                  task_id     - (input) Task id is mapped to priority
+**                  taskname    - (input) name given to the task
+**                  stack       - (input) pointer to the top of the stack
+**                                        (highest memory location)
+**                  stacksize   - (input) size of the stack allocated for the
+**                                        task
+**
+** Returns          GKI_SUCCESS if all OK, GKI_FAILURE if any problem
+**
+** NOTE             This function take some parameters that may not be needed
+**                  by your particular OS. They are here for compatability
+**                  of the function prototype.
+**
+*******************************************************************************/
+uint8_t GKI_create_task(TASKPTR task_entry, uint8_t task_id, int8_t* taskname,
+                        uint16_t* stack, uint16_t stacksize, void* pCondVar,
+                        void* pMutex) {
+  uint16_t i;
+  uint8_t* p;
+  struct sched_param param;
+  int policy, ret = 0;
+  pthread_condattr_t attr;
+  pthread_attr_t attr1;
+  (void)stack;
+  (void)stacksize;
+
+  pthread_condattr_init(&attr);
+  pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
+  GKI_TRACE_5(
+      "GKI_create_task func=0x%x  id=%d  name=%s  stack=0x%x  stackSize=%d",
+      task_entry, task_id, taskname, stack, stacksize);
+
+  if (task_id >= GKI_MAX_TASKS) {
+    GKI_TRACE_0("Error! task ID > max task allowed");
+    return (GKI_FAILURE);
+  }
+
+  gki_cb.com.OSRdyTbl[task_id] = TASK_READY;
+  gki_cb.com.OSTName[task_id] = taskname;
+  gki_cb.com.OSWaitTmr[task_id] = 0;
+  gki_cb.com.OSWaitEvt[task_id] = 0;
+
+  /* Initialize mutex and condition variable objects for events and timeouts */
+  pthread_mutex_init(&gki_cb.os.thread_evt_mutex[task_id], NULL);
+  pthread_cond_init(&gki_cb.os.thread_evt_cond[task_id], &attr);
+  pthread_mutex_init(&gki_cb.os.thread_timeout_mutex[task_id], NULL);
+  pthread_cond_init(&gki_cb.os.thread_timeout_cond[task_id], &attr);
+
+  pthread_attr_init(&attr1);
+/* by default, pthread creates a joinable thread */
+#if (false == GKI_PTHREAD_JOINABLE)
+  pthread_attr_setdetachstate(&attr1, PTHREAD_CREATE_DETACHED);
+
+  GKI_TRACE_3("GKI creating task %i, pCond/pMutex=%x/%x", task_id, pCondVar,
+              pMutex);
+#else
+  GKI_TRACE_1("GKI creating JOINABLE task %i", task_id);
+#endif
+
+  /* On Android, the new tasks starts running before
+   * 'gki_cb.os.thread_id[task_id]' is initialized */
+  /* Pass task_id to new task so it can initialize gki_cb.os.thread_id[task_id]
+   * for it calls GKI_wait */
+  gki_pthread_info[task_id].task_id = task_id;
+  gki_pthread_info[task_id].task_entry = task_entry;
+  gki_pthread_info[task_id].params = 0;
+  gki_pthread_info[task_id].pCond = (pthread_cond_t*)pCondVar;
+  gki_pthread_info[task_id].pMutex = (pthread_mutex_t*)pMutex;
+
+  ret = pthread_create(&gki_cb.os.thread_id[task_id], &attr1,
+                       (void*)gki_task_entry, &gki_pthread_info[task_id]);
+#if (NXP_EXTNS == TRUE)
+  pthread_attr_destroy(&attr1);
+  pthread_condattr_destroy(&attr);
+#endif
+  if (ret != 0) {
+    GKI_TRACE_2("pthread_create failed(%d), %s!", ret, taskname);
+    return GKI_FAILURE;
+  }
+
+  if (pthread_getschedparam(gki_cb.os.thread_id[task_id], &policy, &param) ==
+      0) {
+#if (PBS_SQL_TASK == true)
+    if (task_id == PBS_SQL_TASK) {
+      GKI_TRACE_0("PBS SQL lowest priority task");
+      policy = SCHED_NORMAL;
+    } else
+#endif
+    {
+      policy = SCHED_RR;
+      param.sched_priority = 30 - task_id - 2;
+    }
+    pthread_setschedparam(gki_cb.os.thread_id[task_id], policy, &param);
+  }
+
+  GKI_TRACE_6("Leaving GKI_create_task %x %d %x %s %x %d", task_entry, task_id,
+              gki_cb.os.thread_id[task_id], taskname, stack, stacksize);
+
+  return (GKI_SUCCESS);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_shutdown
+**
+** Description      shutdowns the GKI tasks/threads in from max task id to 0 and
+**                  frees pthread resources!
+**                  IMPORTANT: in case of join method, GKI_shutdown must be
+**                  called outside a GKI thread context!
+**
+** Returns          void
+**
+*******************************************************************************/
+#define WAKE_LOCK_ID "brcm_nfca"
+#define PARTIAL_WAKE_LOCK 1
+extern int acquire_wake_lock(int lock, const char* id);
+extern int release_wake_lock(const char* id);
+
+void GKI_shutdown(void) {
+  uint8_t task_id;
+  volatile int* p_run_cond = &gki_cb.os.no_timer_suspend;
+  int oldCOnd = 0;
+#if (false == GKI_PTHREAD_JOINABLE)
+  int i = 0;
+#else
+  int result;
+#endif
+
+  /* release threads and set as TASK_DEAD. going from low to high priority fixes
+   * GKI_exception problem due to btu->hci sleep request events  */
+  for (task_id = GKI_MAX_TASKS; task_id > 0; task_id--) {
+    if (gki_cb.com.OSRdyTbl[task_id - 1] != TASK_DEAD) {
+      gki_cb.com.OSRdyTbl[task_id - 1] = TASK_DEAD;
+
+      /* paranoi settings, make sure that we do not execute any mailbox events
+       */
+      gki_cb.com.OSWaitEvt[task_id - 1] &=
+          ~(TASK_MBOX_0_EVT_MASK | TASK_MBOX_1_EVT_MASK | TASK_MBOX_2_EVT_MASK |
+            TASK_MBOX_3_EVT_MASK);
+      GKI_send_event(task_id - 1, EVENT_MASK(GKI_SHUTDOWN_EVT));
+
+#if (false == GKI_PTHREAD_JOINABLE)
+      i = 0;
+      while ((gki_cb.com.OSWaitEvt[task_id - 1] != 0) && (++i < 5))
+        usleep(2 * 1000);
+#else
+      /* wait for proper Arnold Schwarzenegger task state */
+      result = pthread_join(gki_cb.os.thread_id[task_id - 1], NULL);
+      if (result < 0) {
+        GKI_TRACE_1("pthread_join() FAILED: result: %d", result);
+      }
+#endif
+      GKI_TRACE_1("GKI_shutdown(): task %s dead", gki_cb.com.OSTName[task_id]);
+      GKI_exit_task(task_id - 1);
+    }
+  }
+
+  /* Destroy mutex and condition variable objects */
+  pthread_mutex_destroy(&gki_cb.os.GKI_mutex);
+/*    pthread_mutex_destroy(&GKI_sched_mutex); */
+#if (GKI_DEBUG == true)
+  pthread_mutex_destroy(&gki_cb.os.GKI_trace_mutex);
+#endif
+/*    pthread_mutex_destroy(&thread_delay_mutex);
+ pthread_cond_destroy (&thread_delay_cond); */
+#if (false == GKI_PTHREAD_JOINABLE)
+  i = 0;
+#endif
+
+#ifdef NO_GKI_RUN_RETURN
+  shutdown_timer = 1;
+#endif
+  if (gki_cb.os.gki_timer_wake_lock_on) {
+    GKI_TRACE_0("GKI_shutdown :  release_wake_lock(brcm_btld)");
+    release_wake_lock(WAKE_LOCK_ID);
+    gki_cb.os.gki_timer_wake_lock_on = 0;
+  }
+  oldCOnd = *p_run_cond;
+  *p_run_cond = GKI_TIMER_TICK_EXIT_COND;
+  if (oldCOnd == GKI_TIMER_TICK_STOP_COND)
+    pthread_cond_signal(&gki_cb.os.gki_timer_cond);
+}
+
+/*******************************************************************************
+ **
+ ** Function        GKI_run
+ **
+ ** Description     This function runs a task
+ **
+ ** Parameters:     start: true start system tick (again), false stop
+ **
+ ** Returns         void
+ **
+ ******************************************************************************/
+void gki_system_tick_start_stop_cback(bool start) {
+  tGKI_OS* p_os = &gki_cb.os;
+  volatile int* p_run_cond = &p_os->no_timer_suspend;
+  static volatile int wake_lock_count;
+  if (false == start) {
+    /* this can lead to a race condition. however as we only read this variable
+     * in the timer loop
+     * we should be fine with this approach. otherwise uncomment below mutexes.
+     */
+    /* GKI_disable(); */
+    *p_run_cond = GKI_TIMER_TICK_STOP_COND;
+/* GKI_enable(); */
+#ifdef GKI_TICK_TIMER_DEBUG
+    BT_TRACE_1(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG,
+               ">>> STOP GKI_timer_update(), wake_lock_count:%d",
+               --wake_lock_count);
+#endif
+    release_wake_lock(WAKE_LOCK_ID);
+    gki_cb.os.gki_timer_wake_lock_on = 0;
+  } else {
+    /* restart GKI_timer_update() loop */
+    acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
+    gki_cb.os.gki_timer_wake_lock_on = 1;
+    *p_run_cond = GKI_TIMER_TICK_RUN_COND;
+    pthread_mutex_lock(&p_os->gki_timer_mutex);
+    pthread_cond_signal(&p_os->gki_timer_cond);
+    pthread_mutex_unlock(&p_os->gki_timer_mutex);
+
+#ifdef GKI_TICK_TIMER_DEBUG
+    BT_TRACE_1(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG,
+               ">>> START GKI_timer_update(), wake_lock_count:%d",
+               ++wake_lock_count);
+#endif
+  }
+}
+
+/*******************************************************************************
+**
+** Function         timer_thread
+**
+** Description      Timer thread
+**
+** Parameters:      id  - (input) timer ID
+**
+** Returns          void
+**
+*******************************************************************************/
+#ifdef NO_GKI_RUN_RETURN
+void timer_thread(signed long id) {
+  GKI_TRACE_1("%s enter", __func__);
+  struct timespec delay;
+  int timeout = 1000; /* 10  ms per system tick  */
+  int err;
+
+  while (!shutdown_timer) {
+    delay.tv_sec = timeout / 1000;
+    delay.tv_nsec = 1000 * 1000 * (timeout % 1000);
+
+    /* [u]sleep can't be used because it uses SIGALRM */
+
+    do {
+      err = nanosleep(&delay, &delay);
+    } while (err < 0 && errno == EINTR);
+
+    GKI_timer_update(1);
+  }
+  GKI_TRACE_ERROR_1("%s exit", __func__);
+  return;
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         GKI_run
+**
+** Description      This function runs a task
+**
+** Parameters:      p_task_id  - (input) pointer to task id
+**
+** Returns          void
+**
+** NOTE             This function is only needed for operating systems where
+**                  starting a task is a 2-step process. Most OS's do it in
+**                  one step, If your OS does it in one step, this function
+**                  should be empty.
+*******************************************************************************/
+void GKI_run(void* p_task_id) {
+  GKI_TRACE_1("%s enter", __func__);
+  struct timespec delay;
+  int err = 0;
+#if (NXP_EXTNS == TRUE)
+  uint8_t rtask = 0;
+  (void)p_task_id;
+#endif
+  volatile int* p_run_cond = &gki_cb.os.no_timer_suspend;
+#if (NXP_EXTNS == TRUE)
+  int ret = 0;
+#endif
+#ifndef GKI_NO_TICK_STOP
+  /* register start stop function which disable timer loop in GKI_run() when no
+   * timers are
+   * in any GKI/BTA/BTU this should save power when BTLD is idle! */
+  GKI_timer_queue_register_callback(gki_system_tick_start_stop_cback);
+  APPL_TRACE_DEBUG0("GKI_run(): Start/Stop GKI_timer_update_registered!");
+#endif
+
+#ifdef NO_GKI_RUN_RETURN
+  GKI_TRACE_0("GKI_run == NO_GKI_RUN_RETURN");
+  pthread_attr_t timer_attr;
+
+  shutdown_timer = 0;
+
+  pthread_attr_init(&timer_attr);
+  pthread_attr_setdetachstate(&timer_attr, PTHREAD_CREATE_DETACHED);
+#if (NXP_EXTNS == TRUE)
+  ret = pthread_create(&timer_thread_id, &timer_attr, timer_thread, NULL);
+  pthread_attr_destroy(&timer_attr);
+  if (ret != 0)
+#else
+  if (pthread_create(&timer_thread_id, &timer_attr, timer_thread, NULL) != 0)
+#endif
+  {
+    GKI_TRACE_0("GKI_run: pthread_create failed to create timer_thread!");
+    return GKI_FAILURE;
+  }
+#else
+  GKI_TRACE_2("GKI_run, run_cond(%x)=%d ", p_run_cond, *p_run_cond);
+#if (NXP_EXTNS == TRUE)
+  rtask = GKI_get_taskid();
+#endif
+  for (; GKI_TIMER_TICK_EXIT_COND != *p_run_cond;) {
+    do {
+      /* adjust hear bit tick in btld by changning TICKS_PER_SEC!!!!! this
+       * formula works only for
+       * 1-1000ms heart beat units! */
+      delay.tv_sec = LINUX_SEC / 1000;
+      delay.tv_nsec = 1000 * 1000 * (LINUX_SEC % 1000);
+
+      /* [u]sleep can't be used because it uses SIGALRM */
+      do {
+        err = nanosleep(&delay, &delay);
+      } while (err < 0 && errno == EINTR);
+
+      if (GKI_TIMER_TICK_RUN_COND != *p_run_cond) break;  // GKI has shutdown
+
+      /* the unit should be alsways 1 (1 tick). only if you vary for some reason
+       * heart beat tick
+       * e.g. power saving you may want to provide more ticks
+       */
+      GKI_timer_update(1);
+      /* BT_TRACE_2( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, "update: tv_sec: %d,
+       * tv_nsec: %d", delay.tv_sec, delay.tv_nsec ); */
+    } while (GKI_TIMER_TICK_RUN_COND == *p_run_cond);
+
+/* currently on reason to exit above loop is no_timer_suspend ==
+ * GKI_TIMER_TICK_STOP_COND
+ * block timer main thread till re-armed by  */
+#ifdef GKI_TICK_TIMER_DEBUG
+    BT_TRACE_0(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG,
+               ">>> SUSPENDED GKI_timer_update()");
+#endif
+#if (NXP_EXTNS == TRUE)
+    if (gki_cb.com.OSRdyTbl[rtask] == TASK_DEAD) {
+      gki_cb.com.OSWaitEvt[rtask] = 0;
+      BT_TRACE_1(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG,
+                 "GKI TASK_DEAD received. exit thread %d...", rtask);
+      gki_cb.os.thread_id[rtask] = 0;
+    }
+#endif
+    if (GKI_TIMER_TICK_EXIT_COND != *p_run_cond) {
+      GKI_TRACE_1("%s waiting timer mutex", __func__);
+      pthread_mutex_lock(&gki_cb.os.gki_timer_mutex);
+      pthread_cond_wait(&gki_cb.os.gki_timer_cond, &gki_cb.os.gki_timer_mutex);
+      pthread_mutex_unlock(&gki_cb.os.gki_timer_mutex);
+      GKI_TRACE_1("%s exited timer mutex", __func__);
+    }
+/* potentially we need to adjust os gki_cb.com.OSTicks */
+
+#ifdef GKI_TICK_TIMER_DEBUG
+    BT_TRACE_1(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG,
+               ">>> RESTARTED GKI_timer_update(): run_cond: %d", *p_run_cond);
+#endif
+  } /* for */
+#endif
+  GKI_TRACE_1("%s exit", __func__);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_stop
+**
+** Description      This function is called to stop
+**                  the tasks and timers when the system is being stopped
+**
+** Returns          void
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If you want to use it in your own implementation,
+**                  put specific code here.
+**
+*******************************************************************************/
+void GKI_stop(void) {
+  uint8_t task_id;
+
+  /*  gki_queue_timer_cback(false); */
+  /* TODO - add code here if needed*/
+
+  for (task_id = 0; task_id < GKI_MAX_TASKS; task_id++) {
+    if (gki_cb.com.OSRdyTbl[task_id] != TASK_DEAD) {
+      GKI_exit_task(task_id);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         GKI_wait
+**
+** Description      This function is called by tasks to wait for a specific
+**                  event or set of events. The task may specify the duration
+**                  that it wants to wait for, or 0 if infinite.
+**
+** Parameters:      flag -    (input) the event or set of events to wait for
+**                  timeout - (input) the duration that the task wants to wait
+**                                    for the specific events (in system ticks)
+**
+**
+** Returns          the event mask of received events or zero if timeout
+**
+*******************************************************************************/
+uint16_t GKI_wait(uint16_t flag, uint32_t timeout) {
+  uint16_t evt;
+  uint8_t rtask;
+  struct timespec abstime = {0, 0};
+  int sec;
+  int nano_sec;
+
+  rtask = GKI_get_taskid();
+  GKI_TRACE_3("GKI_wait %d %x %d", rtask, flag, timeout);
+  if (rtask >= GKI_MAX_TASKS) {
+    GKI_TRACE_ERROR_3("%s() Exiting thread; rtask %d >= %d", __func__, rtask,
+                      GKI_MAX_TASKS);
+    return EVENT_MASK(GKI_SHUTDOWN_EVT);
+  }
+
+  gki_pthread_info_t* p_pthread_info = &gki_pthread_info[rtask];
+  if (p_pthread_info->pCond != NULL && p_pthread_info->pMutex != NULL) {
+    int ret;
+    GKI_TRACE_3("GKI_wait task=%i, pCond/pMutex = %x/%x", rtask,
+                p_pthread_info->pCond, p_pthread_info->pMutex);
+    ret = pthread_mutex_lock(p_pthread_info->pMutex);
+    ret = pthread_cond_signal(p_pthread_info->pCond);
+    ret = pthread_mutex_unlock(p_pthread_info->pMutex);
+    p_pthread_info->pMutex = NULL;
+    p_pthread_info->pCond = NULL;
+  }
+  gki_cb.com.OSWaitForEvt[rtask] = flag;
+
+  /* protect OSWaitEvt[rtask] from modification from an other thread */
+  pthread_mutex_lock(&gki_cb.os.thread_evt_mutex[rtask]);
+
+#if 0 /* for clean scheduling we probably should always call \
+         pthread_cond_wait() */
+    /* Check if anything in any of the mailboxes. There is a potential race condition where OSTaskQFirst[rtask]
+     has been modified. however this should only result in addtional call to  pthread_cond_wait() but as
+     the cond is met, it will exit immediately (depending on schedulling) */
+    if (gki_cb.com.OSTaskQFirst[rtask][0])
+    gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_0_EVT_MASK;
+    if (gki_cb.com.OSTaskQFirst[rtask][1])
+    gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_1_EVT_MASK;
+    if (gki_cb.com.OSTaskQFirst[rtask][2])
+    gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_2_EVT_MASK;
+    if (gki_cb.com.OSTaskQFirst[rtask][3])
+    gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_3_EVT_MASK;
+#endif
+
+  if (!(gki_cb.com.OSWaitEvt[rtask] & flag)) {
+    if (timeout) {
+      //            timeout = GKI_MS_TO_TICKS(timeout);     /* convert from
+      //            milliseconds to ticks */
+
+      /* get current system time */
+      //            clock_gettime(CLOCK_MONOTONIC, &currSysTime);
+      //            abstime.tv_sec = currSysTime.time;
+      //            abstime.tv_nsec = NANOSEC_PER_MILLISEC *
+      //            currSysTime.millitm;
+      clock_gettime(CLOCK_MONOTONIC, &abstime);
+
+      /* add timeout */
+      sec = timeout / 1000;
+      nano_sec = (timeout % 1000) * NANOSEC_PER_MILLISEC;
+      abstime.tv_nsec += nano_sec;
+      if (abstime.tv_nsec > NSEC_PER_SEC) {
+        abstime.tv_sec += (abstime.tv_nsec / NSEC_PER_SEC);
+        abstime.tv_nsec = abstime.tv_nsec % NSEC_PER_SEC;
+      }
+      abstime.tv_sec += sec;
+
+      pthread_cond_timedwait(&gki_cb.os.thread_evt_cond[rtask],
+                             &gki_cb.os.thread_evt_mutex[rtask], &abstime);
+
+    } else {
+      pthread_cond_wait(&gki_cb.os.thread_evt_cond[rtask],
+                        &gki_cb.os.thread_evt_mutex[rtask]);
+    }
+
+    /* TODO: check, this is probably neither not needed depending on
+     phtread_cond_wait() implementation,
+     e.g. it looks like it is implemented as a counter in which case multiple
+     cond_signal
+     should NOT be lost! */
+    // we are waking up after waiting for some events, so refresh variables
+    // no need to call GKI_disable() here as we know that we will have some
+    // events as we've been waking up after condition pending or timeout
+    if (gki_cb.com.OSTaskQFirst[rtask][0])
+      gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_0_EVT_MASK;
+    if (gki_cb.com.OSTaskQFirst[rtask][1])
+      gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_1_EVT_MASK;
+    if (gki_cb.com.OSTaskQFirst[rtask][2])
+      gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_2_EVT_MASK;
+    if (gki_cb.com.OSTaskQFirst[rtask][3])
+      gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_3_EVT_MASK;
+
+    if (gki_cb.com.OSRdyTbl[rtask] == TASK_DEAD) {
+      gki_cb.com.OSWaitEvt[rtask] = 0;
+      /* unlock thread_evt_mutex as pthread_cond_wait() does auto lock when cond
+       * is met */
+      pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[rtask]);
+      GKI_TRACE_ERROR_1("GKI TASK_DEAD received. exit thread %d...", rtask);
+
+      gki_cb.os.thread_id[rtask] = 0;
+      return (EVENT_MASK(GKI_SHUTDOWN_EVT));
+    }
+  }
+
+  /* Clear the wait for event mask */
+  gki_cb.com.OSWaitForEvt[rtask] = 0;
+
+  /* Return only those bits which user wants... */
+  evt = gki_cb.com.OSWaitEvt[rtask] & flag;
+
+  /* Clear only those bits which user wants... */
+  gki_cb.com.OSWaitEvt[rtask] &= ~flag;
+
+  /* unlock thread_evt_mutex as pthread_cond_wait() does auto lock mutex when
+   * cond is met */
+  pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[rtask]);
+  GKI_TRACE_4("GKI_wait %d %x %d %x resumed", rtask, flag, timeout, evt);
+
+  return (evt);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_delay
+**
+** Description      This function is called by tasks to sleep unconditionally
+**                  for a specified amount of time. The duration is in
+**                  milliseconds
+**
+** Parameters:      timeout -    (input) the duration in milliseconds
+**
+** Returns          void
+**
+*******************************************************************************/
+
+void GKI_delay(uint32_t timeout) {
+  uint8_t rtask = GKI_get_taskid();
+  struct timespec delay;
+  int err;
+
+  GKI_TRACE_2("GKI_delay %d %d", rtask, timeout);
+
+  delay.tv_sec = timeout / 1000;
+  delay.tv_nsec = 1000 * 1000 * (timeout % 1000);
+
+  /* [u]sleep can't be used because it uses SIGALRM */
+
+  do {
+    err = nanosleep(&delay, &delay);
+  } while (err < 0 && errno == EINTR);
+
+  /* Check if task was killed while sleeping */
+  /* NOTE
+  **      if you do not implement task killing, you do not
+  **      need this check.
+  */
+  if (rtask && gki_cb.com.OSRdyTbl[rtask] == TASK_DEAD) {
+  }
+
+  GKI_TRACE_2("GKI_delay %d %d done", rtask, timeout);
+  return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_send_event
+**
+** Description      This function is called by tasks to send events to other
+**                  tasks. Tasks can also send events to themselves.
+**
+** Parameters:      task_id -  (input) The id of the task to which the event has
+**                                     to be sent
+**                  event   -  (input) The event that has to be sent
+**
+**
+** Returns          GKI_SUCCESS if all OK, else GKI_FAILURE
+**
+*******************************************************************************/
+uint8_t GKI_send_event(uint8_t task_id, uint16_t event) {
+  GKI_TRACE_2("GKI_send_event %d %x", task_id, event);
+
+  /* use efficient coding to avoid pipeline stalls */
+  if (task_id < GKI_MAX_TASKS) {
+    /* protect OSWaitEvt[task_id] from manipulation in GKI_wait() */
+    pthread_mutex_lock(&gki_cb.os.thread_evt_mutex[task_id]);
+
+    /* Set the event bit */
+    gki_cb.com.OSWaitEvt[task_id] |= event;
+
+    pthread_cond_signal(&gki_cb.os.thread_evt_cond[task_id]);
+
+    pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[task_id]);
+
+    GKI_TRACE_2("GKI_send_event %d %x done", task_id, event);
+    return (GKI_SUCCESS);
+  }
+  return (GKI_FAILURE);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_isend_event
+**
+** Description      This function is called from ISRs to send events to other
+**                  tasks. The only difference between this function and
+**                  GKI_send_event is that this function assumes interrupts are
+**                  already disabled.
+**
+** Parameters:      task_id -  (input) The destination task Id for the event.
+**                  event   -  (input) The event flag
+**
+** Returns          GKI_SUCCESS if all OK, else GKI_FAILURE
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If you want to use it in your own implementation,
+**                  put your code here, otherwise you can delete the entire
+**                  body of the function.
+**
+*******************************************************************************/
+uint8_t GKI_isend_event(uint8_t task_id, uint16_t event) {
+  GKI_TRACE_2("GKI_isend_event %d %x", task_id, event);
+  GKI_TRACE_2("GKI_isend_event %d %x done", task_id, event);
+  return GKI_send_event(task_id, event);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_get_taskid
+**
+** Description      This function gets the currently running task ID.
+**
+** Returns          task ID
+**
+** NOTE             The Widcomm upper stack and profiles may run as a single
+**                  task. If you only have one GKI task, then you can hard-code
+**                  this function to return a '1'. Otherwise, you should have
+**                  some OS-specific method to determine the current task.
+**
+*******************************************************************************/
+uint8_t GKI_get_taskid(void) {
+  int i;
+
+  pthread_t thread_id = pthread_self();
+  for (i = 0; i < GKI_MAX_TASKS; i++) {
+    if (gki_cb.os.thread_id[i] == thread_id) {
+      GKI_TRACE_2("GKI_get_taskid %x %d done", thread_id, i);
+      return (i);
+    }
+  }
+
+  GKI_TRACE_1("GKI_get_taskid: thread id = %x, task id = -1", thread_id);
+
+  return (-1);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_map_taskname
+**
+** Description      This function gets the task name of the taskid passed as
+**                  arg. If GKI_MAX_TASKS is passed as arg the currently running
+**                  task name is returned
+**
+** Parameters:      task_id -  (input) The id of the task whose name is being
+**                  sought. GKI_MAX_TASKS is passed to get the name of the
+**                  currently running task.
+**
+** Returns          pointer to task name
+**
+** NOTE             this function needs no customization
+**
+*******************************************************************************/
+int8_t* GKI_map_taskname(uint8_t task_id) {
+  GKI_TRACE_1("GKI_map_taskname %d", task_id);
+
+  if (task_id < GKI_MAX_TASKS) {
+    GKI_TRACE_2("GKI_map_taskname %d %s done", task_id,
+                gki_cb.com.OSTName[task_id]);
+    return (gki_cb.com.OSTName[task_id]);
+  } else if (task_id == GKI_MAX_TASKS) {
+    return (gki_cb.com.OSTName[GKI_get_taskid()]);
+  } else {
+    return (int8_t*)"BAD";
+  }
+}
+
+/*******************************************************************************
+**
+** Function         GKI_enable
+**
+** Description      This function enables interrupts.
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_enable(void) {
+  GKI_TRACE_0("GKI_enable");
+  pthread_mutex_unlock(&gki_cb.os.GKI_mutex);
+  /*  pthread_mutex_xx is nesting save, no need for this: already_disabled = 0;
+   */
+  GKI_TRACE_0("Leaving GKI_enable");
+  return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_disable
+**
+** Description      This function disables interrupts.
+**
+** Returns          void
+**
+*******************************************************************************/
+
+void GKI_disable(void) {
+  // GKI_TRACE_0("GKI_disable");
+
+  /*  pthread_mutex_xx is nesting save, no need for this: if (!already_disabled)
+     {
+      already_disabled = 1; */
+  pthread_mutex_lock(&gki_cb.os.GKI_mutex);
+  /*  } */
+  // GKI_TRACE_0("Leaving GKI_disable");
+  return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_exception
+**
+** Description      This function throws an exception.
+**                  This is normally only called for a nonrecoverable error.
+**
+** Parameters:      code    -  (input) The code for the error
+**                  msg     -  (input) The message that has to be logged
+**
+** Returns          void
+**
+*******************************************************************************/
+
+void GKI_exception(uint16_t code, char* msg) {
+  uint8_t task_id;
+  int i = 0;
+
+  GKI_TRACE_ERROR_0("GKI_exception(): Task State Table");
+
+  for (task_id = 0; task_id < GKI_MAX_TASKS; task_id++) {
+    GKI_TRACE_ERROR_3("TASK ID [%d] task name [%s] state [%d]", task_id,
+                      gki_cb.com.OSTName[task_id],
+                      gki_cb.com.OSRdyTbl[task_id]);
+  }
+
+  GKI_TRACE_ERROR_2("GKI_exception %d %s", code, msg);
+  GKI_TRACE_ERROR_0(
+      "********************************************************************");
+  GKI_TRACE_ERROR_2("* GKI_exception(): %d %s", code, msg);
+  GKI_TRACE_ERROR_0(
+      "********************************************************************");
+
+#if (GKI_DEBUG == true)
+  GKI_disable();
+
+  if (gki_cb.com.ExceptionCnt < GKI_MAX_EXCEPTION) {
+    EXCEPTION_T* pExp;
+
+    pExp = &gki_cb.com.Exception[gki_cb.com.ExceptionCnt++];
+    pExp->type = code;
+    pExp->taskid = GKI_get_taskid();
+    strlcpy((char*)pExp->msg, msg, GKI_MAX_EXCEPTION_MSGLEN - 1);
+  }
+
+  GKI_enable();
+#endif
+
+  GKI_TRACE_ERROR_2("GKI_exception %d %s done", code, msg);
+
+  return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_get_time_stamp
+**
+** Description      This function formats the time into a user area
+**
+** Parameters:      tbuf -  (output) the address to the memory containing the
+**                  formatted time
+**
+** Returns          the address of the user area containing the formatted time
+**                  The format of the time is ????
+**
+** NOTE             This function is only called by OBEX.
+**
+*******************************************************************************/
+int8_t* GKI_get_time_stamp(int8_t* tbuf) {
+  uint32_t ms_time;
+  uint32_t s_time;
+  uint32_t m_time;
+  uint32_t h_time;
+  int8_t* p_out = tbuf;
+
+  gki_cb.com.OSTicks = (uint32_t)times(&buffer);
+  ms_time = GKI_TICKS_TO_MS(gki_cb.com.OSTicks);
+  s_time = ms_time / 100; /* 100 Ticks per second */
+  m_time = s_time / 60;
+  h_time = m_time / 60;
+
+  ms_time -= s_time * 100;
+  s_time -= m_time * 60;
+  m_time -= h_time * 60;
+
+  *p_out++ = (int8_t)((h_time / 10) + '0');
+  *p_out++ = (int8_t)((h_time % 10) + '0');
+  *p_out++ = ':';
+  *p_out++ = (int8_t)((m_time / 10) + '0');
+  *p_out++ = (int8_t)((m_time % 10) + '0');
+  *p_out++ = ':';
+  *p_out++ = (int8_t)((s_time / 10) + '0');
+  *p_out++ = (int8_t)((s_time % 10) + '0');
+  *p_out++ = ':';
+  *p_out++ = (int8_t)((ms_time / 10) + '0');
+  *p_out++ = (int8_t)((ms_time % 10) + '0');
+  *p_out++ = ':';
+  *p_out = 0;
+
+  return (tbuf);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_register_mempool
+**
+** Description      This function registers a specific memory pool.
+**
+** Parameters:      p_mem -  (input) pointer to the memory pool
+**
+** Returns          void
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If your OS has different memory pools, you
+**                  can tell GKI the pool to use by calling this function.
+**
+*******************************************************************************/
+void GKI_register_mempool(void* p_mem) {
+  gki_cb.com.p_user_mempool = p_mem;
+
+  return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_os_malloc
+**
+** Description      This function allocates memory
+**
+** Parameters:      size -  (input) The size of the memory that has to be
+**                  allocated
+**
+** Returns          the address of the memory allocated, or NULL if failed
+**
+** NOTE             This function is called by the Widcomm stack when
+**                  dynamic memory allocation is used.
+**
+*******************************************************************************/
+void* GKI_os_malloc(uint32_t size) { return (malloc(size)); }
+
+/*******************************************************************************
+**
+** Function         GKI_os_free
+**
+** Description      This function frees memory
+**
+** Parameters:      size -  (input) The address of the memory that has to be
+**                  freed
+**
+** Returns          void
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. It is only called from within GKI if dynamic
+**
+*******************************************************************************/
+void GKI_os_free(void* p_mem) {
+  if (p_mem != NULL) free(p_mem);
+  return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_suspend_task()
+**
+** Description      This function suspends the task specified in the argument.
+**
+** Parameters:      task_id  - (input) the id of the task that has to suspended
+**
+** Returns          GKI_SUCCESS if all OK, else GKI_FAILURE
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If you want to implement task suspension
+**                  capability, put specific code here.
+**
+*******************************************************************************/
+uint8_t GKI_suspend_task(uint8_t task_id) {
+  (void)task_id;
+  GKI_TRACE_1("GKI_suspend_task %d - NOT implemented", task_id);
+
+  GKI_TRACE_1("GKI_suspend_task %d done", task_id);
+
+  return (GKI_SUCCESS);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_resume_task()
+**
+** Description      This function resumes the task specified in the argument.
+**
+** Parameters:      task_id  - (input) the id of the task that has to resumed
+**
+** Returns          GKI_SUCCESS if all OK
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If you want to implement task suspension
+**                  capability, put specific code here.
+**
+*******************************************************************************/
+uint8_t GKI_resume_task(uint8_t task_id) {
+  (void)task_id;
+
+  GKI_TRACE_1("GKI_resume_task %d - NOT implemented", task_id);
+
+  GKI_TRACE_1("GKI_resume_task %d done", task_id);
+
+  return (GKI_SUCCESS);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_exit_task
+**
+** Description      This function is called to stop a GKI task.
+**
+** Parameters:      task_id  - (input) the id of the task that has to be stopped
+**
+** Returns          void
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If you want to use it in your own implementation,
+**                  put specific code here to kill a task.
+**
+*******************************************************************************/
+void GKI_exit_task(uint8_t task_id) {
+  GKI_disable();
+  gki_cb.com.OSRdyTbl[task_id] = TASK_DEAD;
+
+  /* Destroy mutex and condition variable objects */
+  pthread_mutex_destroy(&gki_cb.os.thread_evt_mutex[task_id]);
+  pthread_cond_destroy(&gki_cb.os.thread_evt_cond[task_id]);
+  pthread_mutex_destroy(&gki_cb.os.thread_timeout_mutex[task_id]);
+  pthread_cond_destroy(&gki_cb.os.thread_timeout_cond[task_id]);
+
+  GKI_enable();
+
+  // GKI_send_event(task_id, EVENT_MASK(GKI_SHUTDOWN_EVT));
+
+  GKI_TRACE_1("GKI_exit_task %d done", task_id);
+  return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_sched_lock
+**
+** Description      This function is called by tasks to disable scheduler
+**                  task context switching.
+**
+** Returns          void
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If you want to use it in your own implementation,
+**                  put code here to tell the OS to disable context switching.
+**
+*******************************************************************************/
+void GKI_sched_lock(void) {
+  GKI_TRACE_0("GKI_sched_lock");
+  GKI_disable();
+  return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_sched_unlock
+**
+** Description      This function is called by tasks to enable scheduler
+**                  switching.
+**
+** Returns          void
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If you want to use it in your own implementation,
+**                  put code here to tell the OS to re-enable context switching.
+**
+*******************************************************************************/
+void GKI_sched_unlock(void) {
+  GKI_TRACE_0("GKI_sched_unlock");
+  GKI_enable();
+}
+
+/*******************************************************************************
+**
+** Function         GKI_shiftdown
+**
+** Description      shift memory down (to make space to insert a record)
+**
+*******************************************************************************/
+void GKI_shiftdown(uint8_t* p_mem, uint32_t len, uint32_t shift_amount) {
+  register uint8_t* ps = p_mem + len - 1;
+  register uint8_t* pd = ps + shift_amount;
+  register uint32_t xx;
+
+  for (xx = 0; xx < len; xx++) *pd-- = *ps--;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_shiftup
+**
+** Description      shift memory up (to delete a record)
+**
+*******************************************************************************/
+void GKI_shiftup(uint8_t* p_dest, uint8_t* p_src, uint32_t len) {
+  register uint8_t* ps = p_src;
+  register uint8_t* pd = p_dest;
+  register uint32_t xx;
+
+  for (xx = 0; xx < len; xx++) *pd++ = *ps++;
+}
diff --git a/src/hal/include/Nxp_Features.h b/src/hal/include/Nxp_Features.h
new file mode 100644
index 0000000..84ab3dc
--- /dev/null
+++ b/src/hal/include/Nxp_Features.h
@@ -0,0 +1,518 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2012-2016 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * NXP features declarations
+ */
+#include <unistd.h>
+#include <string.h>
+#ifndef NXP_FEATURES_H
+#define NXP_FEATURES_H
+
+#define STRMAX_1 40
+#define STRMAX_2 100
+#define FW_DLL_ROOT_DIR "/system/vendor/firmware/"
+#define FW_DLL_EXTENSION ".so"
+
+#define FW_MOBILE_MAJOR_NUMBER_PN553 0x01
+#define FW_MOBILE_MAJOR_NUMBER_PN551 0x05
+#define FW_MOBILE_MAJOR_NUMBER_PN48AD 0x01
+
+#define NFA_EE_MAX_EE_SUPPORTED 4
+
+#define JCOP_VER_3_1    1
+#define JCOP_VER_3_2    2
+#define JCOP_VER_3_3    3
+#define JCOP_VER_4_0    4
+
+typedef enum {
+    pn547C2 = 0x01,
+    pn65T,
+    pn548C2,
+    pn66T,
+    pn551,
+    pn67T,
+    pn553,
+    pn80T,
+    pn557,
+    pn81T
+}tNFC_chipType;
+
+/*
+ * TODO renaming
+ * */
+typedef struct {
+    /*Flags common to all chip types*/
+    uint8_t _NXP_NFCC_EMPTY_DATA_PACKET                     : 1;
+    uint8_t _GEMALTO_SE_SUPPORT                             : 1;
+    uint8_t _NFCC_I2C_READ_WRITE_IMPROVEMENT                : 1;
+    uint8_t _NFCC_MIFARE_TIANJIN                            : 1;
+    uint8_t _NFCC_MW_RCVRY_BLK_FW_DNLD                      : 1;
+    uint8_t _NFCC_DYNAMIC_DUAL_UICC                         : 1;
+    uint8_t _NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH              : 1;
+    uint8_t _NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH           : 1;
+    uint8_t _NFCC_FW_WA                                     : 1;
+    uint8_t _NFCC_FORCE_NCI1_0_INIT                         : 1;
+    uint8_t _NFCC_ROUTING_BLOCK_BIT                         : 1;
+    uint8_t _NFCC_SPI_FW_DOWNLOAD_SYNC                      : 1;
+    uint8_t _HW_ANTENNA_LOOP4_SELF_TEST                     : 1;
+    uint8_t _NFCEE_REMOVED_NTF_RECOVERY                     : 1;
+    uint8_t _NFCC_FORCE_FW_DOWNLOAD                         : 1;
+    uint8_t _UICC_CREATE_CONNECTIVITY_PIPE                  : 1;
+    uint8_t _NFCC_AID_MATCHING_PLATFORM_CONFIG              : 1;
+    uint8_t _NFCC_ROUTING_BLOCK_BIT_PROP                    : 1;
+    uint8_t _NXP_NFC_UICC_ETSI12                            : 1;
+    uint8_t _NFA_EE_MAX_EE_SUPPORTED                        : 3;
+}tNfc_nfccFeatureList;
+/*
+ * TODO renaming
+ * */
+typedef struct {
+    uint8_t _ESE_EXCLUSIVE_WIRED_MODE                    : 2;
+    uint8_t _ESE_WIRED_MODE_RESUME                       : 2;
+    uint8_t _ESE_WIRED_MODE_TIMEOUT                      : 2;
+    uint8_t _ESE_PN67T_RESET                             : 2;
+    uint8_t _ESE_APDU_GATE_RESET                         : 2;
+    uint8_t _ESE_WIRED_MODE_DISABLE_DISCOVERY            : 1;
+    uint8_t _LEGACY_APDU_GATE                            : 1;
+    uint8_t _TRIPLE_MODE_PROTECTION                      : 1;
+    uint8_t _ESE_FELICA_CLT                              : 1;
+    uint8_t _WIRED_MODE_STANDBY_PROP                     : 1;
+    uint8_t _WIRED_MODE_STANDBY                          : 1;
+    uint8_t _ESE_DUAL_MODE_PRIO_SCHEME                   : 2;
+    uint8_t _ESE_FORCE_ENABLE                            : 1;
+    uint8_t _ESE_RESET_METHOD                            : 1;
+    uint8_t _EXCLUDE_NV_MEM_DEPENDENCY                   : 1;
+    uint8_t _ESE_ETSI_READER_ENABLE                      : 1;
+    uint8_t _ESE_SVDD_SYNC                               : 1;
+    uint8_t _NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION  : 1;
+    uint8_t _ESE_JCOP_DWNLD_PROTECTION                   : 1;
+    uint8_t _UICC_HANDLE_CLEAR_ALL_PIPES                 : 1;
+    uint8_t _GP_CONTINOUS_PROCESSING                     : 1;
+    uint8_t _ESE_DWP_SPI_SYNC_ENABLE                     : 1;
+    uint8_t _ESE_ETSI12_PROP_INIT                        : 1;
+    uint8_t _ESE_WIRED_MODE_PRIO                         : 1;
+    uint8_t _ESE_UICC_EXCLUSIVE_WIRED_MODE               : 1;
+    uint8_t _ESE_POWER_MODE                              : 1;
+    uint8_t _ESE_P73_ISO_RST                             : 1;
+    uint8_t _BLOCK_PROPRIETARY_APDU_GATE                 : 1;
+    uint8_t _JCOP_WA_ENABLE                              : 1;
+    uint8_t _NXP_LDR_SVC_VER_2                           : 1;
+    uint8_t _NXP_ESE_VER                                 : 3;
+}tNfc_eseFeatureList;
+/*
+ * TODO renaming
+ * */
+typedef struct {
+    uint8_t _NFCC_RESET_RSP_LEN;
+}tNfc_platformFeatureList;
+
+typedef struct {
+    uint8_t _NCI_INTERFACE_UICC_DIRECT;
+    uint8_t _NCI_INTERFACE_ESE_DIRECT;
+    uint8_t _NCI_PWR_LINK_PARAM_CMD_SIZE;
+    uint8_t _NCI_EE_PWR_LINK_ALWAYS_ON;
+    uint8_t _NFA_EE_MAX_AID_ENTRIES;
+    uint8_t _NFC_NXP_AID_MAX_SIZE_DYN : 1;
+    uint8_t _FW_LIB_PATH[STRMAX_2];
+    uint8_t _PLATFORM_LIB_PATH[STRMAX_2];
+    uint8_t _PKU_LIB_PATH[STRMAX_2];
+    uint16_t _PHDNLDNFC_USERDATA_EEPROM_OFFSET;
+    uint16_t _PHDNLDNFC_USERDATA_EEPROM_LEN;
+    uint8_t  _FW_MOBILE_MAJOR_NUMBER;
+}tNfc_nfcMwFeatureList;
+/*
+ * TODO renaming
+ * */
+typedef struct {
+    uint8_t nfcNxpEse : 1;
+    tNFC_chipType chipType;
+    tNfc_nfccFeatureList nfccFL;
+    tNfc_eseFeatureList eseFL;
+    tNfc_platformFeatureList platformFL;
+    tNfc_nfcMwFeatureList nfcMwFL;
+}tNfc_featureList;
+
+extern tNfc_featureList nfcFL;
+
+#define CONFIGURE_FEATURELIST(chipType) {                                   \
+        nfcFL.chipType = chipType;                                          \
+        nfcFL.nfcMwFL._NFC_NXP_AID_MAX_SIZE_DYN = true;                     \
+        if(chipType == pn81T) {                                             \
+            nfcFL.chipType = pn557;                                         \
+        }                                                                   \
+        else if(chipType == pn80T) {                                        \
+            nfcFL.chipType = pn553;                                         \
+        }                                                                   \
+        else if(chipType == pn67T) {                                        \
+            nfcFL.chipType = pn551;                                         \
+        }                                                                   \
+        else if(chipType == pn66T) {                                        \
+            nfcFL.chipType = pn548C2;                                       \
+        }                                                                   \
+        else if(chipType == pn65T) {                                        \
+            nfcFL.chipType = pn547C2;                                       \
+        }                                                                   \
+        if ((chipType == pn65T) || (chipType == pn66T) ||                   \
+                (chipType == pn67T) || (chipType == pn80T) ||               \
+                (chipType == pn81T)) {                                      \
+            nfcFL.nfcNxpEse = true;                                         \
+            CONFIGURE_FEATURELIST_NFCC_WITH_ESE(chipType)                   \
+        } \
+        else {                                                              \
+            nfcFL.nfcNxpEse = false;                                        \
+            CONFIGURE_FEATURELIST_NFCC(chipType)                            \
+        }                                                                   \
+        \
+        \
+}
+
+#define CONFIGURE_FEATURELIST_NFCC_WITH_ESE(chipType) {                     \
+        nfcFL.nfccFL._NXP_NFCC_EMPTY_DATA_PACKET = true;                    \
+        nfcFL.nfccFL._GEMALTO_SE_SUPPORT = true;                            \
+        \
+        \
+        nfcFL.eseFL._ESE_EXCLUSIVE_WIRED_MODE = 1;                          \
+        nfcFL.eseFL._ESE_WIRED_MODE_RESUME = 2;                             \
+        nfcFL.eseFL._ESE_PN67T_RESET = 1;                                   \
+        nfcFL.eseFL._ESE_APDU_GATE_RESET = 2;                               \
+        nfcFL.eseFL._NXP_ESE_VER = JCOP_VER_4_0;                            \
+        nfcFL.eseFL._NXP_LDR_SVC_VER_2 = true;                              \
+        \
+        \
+        if (chipType == pn81T) {                                            \
+            CONFIGURE_FEATURELIST_NFCC(pn557)                               \
+            nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC = true;                 \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 4;                      \
+            \
+            \
+            nfcFL.eseFL._ESE_FELICA_CLT = true;                             \
+            nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME =                        \
+            nfcFL.eseFL._ESE_WIRED_MODE_RESUME;                             \
+            nfcFL.eseFL._ESE_RESET_METHOD = true;                           \
+            nfcFL.eseFL._ESE_POWER_MODE = true;                             \
+            nfcFL.eseFL._ESE_P73_ISO_RST = true;                            \
+            nfcFL.eseFL._WIRED_MODE_STANDBY = true;                         \
+            nfcFL.eseFL._ESE_ETSI_READER_ENABLE = true;                     \
+            nfcFL.eseFL._ESE_SVDD_SYNC = true;                              \
+            nfcFL.eseFL._ESE_JCOP_DWNLD_PROTECTION = true;                  \
+            nfcFL.eseFL._UICC_HANDLE_CLEAR_ALL_PIPES = true;                \
+            nfcFL.eseFL._GP_CONTINOUS_PROCESSING = false;                   \
+            nfcFL.eseFL._ESE_DWP_SPI_SYNC_ENABLE = true;                    \
+            nfcFL.eseFL._ESE_ETSI12_PROP_INIT = true;                       \
+        }                                                                   \
+        if (chipType == pn80T) {                                            \
+            CONFIGURE_FEATURELIST_NFCC(pn553)                               \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 4;                      \
+            \
+            \
+            nfcFL.eseFL._ESE_FELICA_CLT = true;                             \
+            nfcFL.eseFL._WIRED_MODE_STANDBY = true;                         \
+            nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME =                        \
+            nfcFL.eseFL._ESE_WIRED_MODE_RESUME;                             \
+            nfcFL.eseFL._ESE_RESET_METHOD = true;                           \
+            nfcFL.eseFL._ESE_ETSI_READER_ENABLE = true;                     \
+            nfcFL.eseFL._ESE_SVDD_SYNC = true;                              \
+            nfcFL.eseFL._ESE_JCOP_DWNLD_PROTECTION = true;                  \
+            nfcFL.eseFL._UICC_HANDLE_CLEAR_ALL_PIPES = true;                \
+            nfcFL.eseFL._ESE_DWP_SPI_SYNC_ENABLE = true;                    \
+            nfcFL.eseFL._ESE_POWER_MODE = true;                             \
+            nfcFL.eseFL._ESE_P73_ISO_RST = true;                            \
+            \
+            \
+            nfcFL.nfcMwFL._NCI_PWR_LINK_PARAM_CMD_SIZE = 0x02;              \
+            nfcFL.nfcMwFL._NCI_EE_PWR_LINK_ALWAYS_ON = 0x01;                \
+        }                                                                   \
+        else if (chipType == pn67T)                                         \
+        {                                                                   \
+            CONFIGURE_FEATURELIST_NFCC(pn551)                               \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 3;                      \
+            \
+            \
+            nfcFL.eseFL._TRIPLE_MODE_PROTECTION = true;                     \
+            nfcFL.eseFL._WIRED_MODE_STANDBY_PROP = true;                    \
+            nfcFL.eseFL._ESE_FORCE_ENABLE = true;                           \
+            nfcFL.eseFL._ESE_ETSI_READER_ENABLE = true;                     \
+            nfcFL.eseFL._ESE_SVDD_SYNC = true;                              \
+            nfcFL.eseFL._LEGACY_APDU_GATE = true;                           \
+            nfcFL.eseFL._NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION = true; \
+            nfcFL.eseFL._ESE_DWP_SPI_SYNC_ENABLE = true;                    \
+        }                                                                   \
+        else if (chipType == pn66T)                                         \
+        {                                                                   \
+            CONFIGURE_FEATURELIST_NFCC(pn548C2)                             \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 3;                      \
+            \
+            \
+            nfcFL.eseFL._TRIPLE_MODE_PROTECTION = true;                     \
+            nfcFL.eseFL._WIRED_MODE_STANDBY = true;                         \
+            nfcFL.eseFL._WIRED_MODE_STANDBY_PROP = true;                    \
+            nfcFL.eseFL._ESE_FORCE_ENABLE = true;                           \
+            nfcFL.eseFL._ESE_ETSI_READER_ENABLE = true;                     \
+            nfcFL.eseFL._ESE_SVDD_SYNC = true;                              \
+            nfcFL.eseFL._LEGACY_APDU_GATE = true;                           \
+            nfcFL.eseFL._NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION = true; \
+            nfcFL.eseFL._ESE_DWP_SPI_SYNC_ENABLE = true;                    \
+        }                                                                   \
+        else if (chipType == pn65T)                                         \
+        {                                                                   \
+            CONFIGURE_FEATURELIST_NFCC(pn547C2)                             \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 3;                      \
+            nfcFL.eseFL._ESE_WIRED_MODE_DISABLE_DISCOVERY = true;           \
+            nfcFL.eseFL._LEGACY_APDU_GATE = true;                           \
+        }                                                                   \
+}
+
+
+#define CONFIGURE_FEATURELIST_NFCC(chipType) {                              \
+        nfcFL.eseFL._ESE_WIRED_MODE_TIMEOUT = 3;                            \
+        nfcFL.eseFL._ESE_WIRED_MODE_DISABLE_DISCOVERY = false;              \
+        nfcFL.eseFL._LEGACY_APDU_GATE = false;                              \
+        nfcFL.eseFL._TRIPLE_MODE_PROTECTION = false;                        \
+        nfcFL.eseFL._ESE_FELICA_CLT = false;                                \
+        nfcFL.eseFL._WIRED_MODE_STANDBY_PROP = false;                       \
+        nfcFL.eseFL._WIRED_MODE_STANDBY = false;                            \
+        nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME =                            \
+        nfcFL.eseFL._ESE_WIRED_MODE_TIMEOUT;                                \
+        nfcFL.eseFL._ESE_FORCE_ENABLE = false;                              \
+        nfcFL.eseFL._ESE_RESET_METHOD = false;                              \
+        nfcFL.eseFL._ESE_ETSI_READER_ENABLE = false;                        \
+        nfcFL.eseFL._ESE_SVDD_SYNC = false;                                 \
+        nfcFL.eseFL._NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION = false;    \
+        nfcFL.eseFL._ESE_JCOP_DWNLD_PROTECTION = false;                     \
+        nfcFL.eseFL._UICC_HANDLE_CLEAR_ALL_PIPES = false;                   \
+        nfcFL.eseFL._GP_CONTINOUS_PROCESSING = false;                       \
+        nfcFL.eseFL._ESE_DWP_SPI_SYNC_ENABLE = false;                       \
+        nfcFL.eseFL._ESE_ETSI12_PROP_INIT = false;                          \
+        nfcFL.eseFL._ESE_WIRED_MODE_PRIO = false;                           \
+        nfcFL.eseFL._ESE_UICC_EXCLUSIVE_WIRED_MODE = false;                 \
+        nfcFL.eseFL._ESE_POWER_MODE = false;                                \
+        nfcFL.eseFL._ESE_P73_ISO_RST = false;                               \
+        nfcFL.eseFL._BLOCK_PROPRIETARY_APDU_GATE = false;                   \
+        nfcFL.eseFL._JCOP_WA_ENABLE = true;                                 \
+        nfcFL.eseFL._EXCLUDE_NV_MEM_DEPENDENCY = false;                     \
+        nfcFL.nfccFL._NXP_NFC_UICC_ETSI12 = false;                          \
+        nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC = false;                    \
+        \
+        \
+        nfcFL.platformFL._NFCC_RESET_RSP_LEN = 0;                           \
+        \
+        \
+        nfcFL.nfcMwFL._NCI_INTERFACE_UICC_DIRECT = 0x00;                    \
+        nfcFL.nfcMwFL._NCI_INTERFACE_ESE_DIRECT = 0x00;                     \
+        nfcFL.nfcMwFL._NCI_PWR_LINK_PARAM_CMD_SIZE = 0x02;                  \
+        nfcFL.nfcMwFL._NCI_EE_PWR_LINK_ALWAYS_ON = 0x01;                    \
+        nfcFL.nfcMwFL._PHDNLDNFC_USERDATA_EEPROM_OFFSET = 0x023CU;          \
+        nfcFL.nfcMwFL._PHDNLDNFC_USERDATA_EEPROM_LEN = 0x0C80U;             \
+        nfcFL.nfcMwFL._FW_MOBILE_MAJOR_NUMBER =                             \
+        FW_MOBILE_MAJOR_NUMBER_PN48AD;                                      \
+        \
+        \
+        if (chipType == pn557)                                              \
+        {                                                                   \
+            nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT = true;           \
+            nfcFL.nfccFL._NFCC_MIFARE_TIANJIN = false;                      \
+            nfcFL.nfccFL._NFCC_MW_RCVRY_BLK_FW_DNLD = true;                 \
+            nfcFL.nfccFL._NFCC_DYNAMIC_DUAL_UICC = true;                    \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH = false;        \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH = true;      \
+            nfcFL.nfccFL._NFCC_FW_WA = true;                                \
+            nfcFL.nfccFL._NFCC_FORCE_NCI1_0_INIT = false;                   \
+            nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC = true;                 \
+            nfcFL.nfccFL._HW_ANTENNA_LOOP4_SELF_TEST = false;               \
+            nfcFL.nfccFL._NFCEE_REMOVED_NTF_RECOVERY = true;                \
+            nfcFL.nfccFL._NFCC_FORCE_FW_DOWNLOAD = true;                    \
+            nfcFL.nfccFL._UICC_CREATE_CONNECTIVITY_PIPE = true;             \
+            nfcFL.nfccFL._NXP_NFC_UICC_ETSI12 = false;                      \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 3;                      \
+            \
+            \
+            nfcFL.eseFL._ESE_ETSI12_PROP_INIT = true;                       \
+            nfcFL.eseFL._EXCLUDE_NV_MEM_DEPENDENCY = true;                  \
+            \
+            \
+            nfcFL.platformFL._NFCC_RESET_RSP_LEN = 0x10U;                   \
+            \
+            \
+        }                                                                   \
+        else if (chipType == pn553)                                         \
+        {                                                                   \
+            nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT = true;           \
+            nfcFL.nfccFL._NFCC_MIFARE_TIANJIN = false;                      \
+            nfcFL.nfccFL._NFCC_MW_RCVRY_BLK_FW_DNLD = true;                 \
+            nfcFL.nfccFL._NFCC_DYNAMIC_DUAL_UICC = true;                    \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH = false;        \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH = true;      \
+            nfcFL.nfccFL._NFCC_FW_WA = true;                                \
+            nfcFL.nfccFL._NFCC_FORCE_NCI1_0_INIT = true;                    \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT = true;                    \
+            nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC = true;                 \
+            nfcFL.nfccFL._HW_ANTENNA_LOOP4_SELF_TEST = false;               \
+            nfcFL.nfccFL._NFCEE_REMOVED_NTF_RECOVERY = true;                \
+            nfcFL.nfccFL._NFCC_FORCE_FW_DOWNLOAD = true;                    \
+            nfcFL.nfccFL._UICC_CREATE_CONNECTIVITY_PIPE = true;             \
+            nfcFL.nfccFL._NFCC_AID_MATCHING_PLATFORM_CONFIG = false;        \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT_PROP = false;              \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 3;                      \
+            \
+            \
+            nfcFL.eseFL._ESE_ETSI12_PROP_INIT = true;                       \
+            nfcFL.eseFL._JCOP_WA_ENABLE = false;                            \
+            nfcFL.eseFL._EXCLUDE_NV_MEM_DEPENDENCY = true;                  \
+            \
+            \
+            nfcFL.platformFL._NFCC_RESET_RSP_LEN = 0x10U;                   \
+            \
+            \
+            nfcFL.nfcMwFL._NCI_INTERFACE_UICC_DIRECT = 0x82;                \
+            nfcFL.nfcMwFL._NCI_INTERFACE_ESE_DIRECT = 0x83;                 \
+            \
+            \
+            SRTCPY_FW("libpn553tc_fw", "libpn553tc_fw_platform",            \
+                    "libpn553tc_fw_pku")                                    \
+            \
+            \
+            nfcFL.nfcMwFL._FW_MOBILE_MAJOR_NUMBER =                         \
+            FW_MOBILE_MAJOR_NUMBER_PN553;                                   \
+            \
+            \
+        }                                                                   \
+        else if (chipType == pn551)                                         \
+        {                                                                   \
+            nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT = true;           \
+            nfcFL.nfccFL._NFCC_MIFARE_TIANJIN = true;                       \
+            nfcFL.nfccFL._NFCC_MW_RCVRY_BLK_FW_DNLD = false;                \
+            nfcFL.nfccFL._NFCC_DYNAMIC_DUAL_UICC = false;                   \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH = true;         \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH = false;     \
+            nfcFL.nfccFL._NFCC_FW_WA = false;                               \
+            nfcFL.nfccFL._NFCC_FORCE_NCI1_0_INIT = false;                   \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT = false;                   \
+            nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC = false;                \
+            nfcFL.nfccFL._HW_ANTENNA_LOOP4_SELF_TEST = true;                \
+            nfcFL.nfccFL._NFCEE_REMOVED_NTF_RECOVERY = true;                \
+            nfcFL.nfccFL._NFCC_FORCE_FW_DOWNLOAD = false;                   \
+            nfcFL.nfccFL._UICC_CREATE_CONNECTIVITY_PIPE = false;            \
+            nfcFL.nfccFL._NFCC_AID_MATCHING_PLATFORM_CONFIG = true;         \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT_PROP = true;               \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 2;                      \
+            \
+            \
+            nfcFL.eseFL._ESE_FORCE_ENABLE = true;                           \
+            \
+            \
+            nfcFL.platformFL._NFCC_RESET_RSP_LEN = 0x11U;                   \
+            \
+            \
+            nfcFL.nfcMwFL._NCI_INTERFACE_UICC_DIRECT = 0x82;                \
+            nfcFL.nfcMwFL._NCI_INTERFACE_ESE_DIRECT = 0x83;                 \
+            \
+            \
+            SRTCPY_FW("libpn551_fw", "libpn551_fw_platform",                \
+                    "libpn551_fw_pku")                                      \
+            \
+            \
+            nfcFL.nfcMwFL._PHDNLDNFC_USERDATA_EEPROM_OFFSET = 0x02BCU;      \
+            nfcFL.nfcMwFL._PHDNLDNFC_USERDATA_EEPROM_LEN = 0x0C00U;         \
+            nfcFL.nfcMwFL._FW_MOBILE_MAJOR_NUMBER =                         \
+            FW_MOBILE_MAJOR_NUMBER_PN551;                                   \
+            \
+            \
+        }                                                                   \
+        else if (chipType == pn548C2)                                       \
+        {                                                                   \
+            nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT = true;           \
+            nfcFL.nfccFL._NFCC_MIFARE_TIANJIN = true;                       \
+            nfcFL.nfccFL._NFCC_MW_RCVRY_BLK_FW_DNLD = false;                \
+            nfcFL.nfccFL._NFCC_DYNAMIC_DUAL_UICC = false;                   \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH = true;         \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH = false;     \
+            nfcFL.nfccFL._NFCC_FW_WA = false;                               \
+            nfcFL.nfccFL._NFCC_FORCE_NCI1_0_INIT = false;                   \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT = false;                   \
+            nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC = false;                \
+            nfcFL.nfccFL._HW_ANTENNA_LOOP4_SELF_TEST = true;                \
+            nfcFL.nfccFL._NFCEE_REMOVED_NTF_RECOVERY = true;                \
+            nfcFL.nfccFL._NFCC_FORCE_FW_DOWNLOAD = false;                   \
+            nfcFL.nfccFL._UICC_CREATE_CONNECTIVITY_PIPE = false;            \
+            nfcFL.nfccFL._NFCC_AID_MATCHING_PLATFORM_CONFIG = true;         \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT_PROP = true;               \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 2;                      \
+            \
+            \
+            nfcFL.eseFL._ESE_FORCE_ENABLE = true;                           \
+            nfcFL.eseFL._ESE_ETSI12_PROP_INIT = true;                       \
+            \
+            \
+            nfcFL.nfcMwFL._NCI_INTERFACE_UICC_DIRECT = 0x82;                \
+            nfcFL.nfcMwFL._NCI_INTERFACE_ESE_DIRECT = 0x83;                 \
+            \
+            \
+            SRTCPY_FW("libpn548ad_fw", "libpn548ad_fw_platform",            \
+                    "libpn548ad_fw_pku")                                    \
+            \
+            \
+            nfcFL.nfcMwFL._PHDNLDNFC_USERDATA_EEPROM_OFFSET = 0x02BCU;      \
+            nfcFL.nfcMwFL._PHDNLDNFC_USERDATA_EEPROM_LEN = 0x0C00U;         \
+            \
+            \
+        }                                                                   \
+        else if(chipType == pn547C2)                                        \
+        {                                                                   \
+            nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT = false;          \
+            nfcFL.nfccFL._NFCC_MIFARE_TIANJIN = true;                       \
+            nfcFL.nfccFL._NFCC_MW_RCVRY_BLK_FW_DNLD = false;                \
+            nfcFL.nfccFL._NFCC_DYNAMIC_DUAL_UICC = false;                   \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH = false;        \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH = false;     \
+            nfcFL.nfccFL._NFCC_FW_WA = false;                               \
+            nfcFL.nfccFL._NFCC_FORCE_NCI1_0_INIT = false;                   \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT = false;                   \
+            nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC = false;                \
+            nfcFL.nfccFL._HW_ANTENNA_LOOP4_SELF_TEST = true;                \
+            nfcFL.nfccFL._NFCEE_REMOVED_NTF_RECOVERY = true;                \
+            nfcFL.nfccFL._NFCC_FORCE_FW_DOWNLOAD = false;                   \
+            nfcFL.nfccFL._UICC_CREATE_CONNECTIVITY_PIPE = false;            \
+            nfcFL.nfccFL._NFCC_AID_MATCHING_PLATFORM_CONFIG = true;         \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT_PROP = false;              \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 2;                      \
+            \
+            \
+            nfcFL.nfcMwFL._NCI_INTERFACE_UICC_DIRECT = 0x81;                \
+            nfcFL.nfcMwFL._NCI_INTERFACE_ESE_DIRECT = 0x82;                 \
+            \
+            \
+            SRTCPY_FW("libpn547_fw", "libpn547_fw_platform",                \
+                    "libpn547_fw_pku")                                      \
+            \
+            \
+        }                                                                   \
+}
+#ifdef __cplusplus
+#define SRTCPY_FW(str1,str2,str3)
+#else
+#define SRTCPY_FW(str1, str2,str3)                                                      \
+        snprintf(nfcFL.nfcMwFL._FW_LIB_PATH, STRMAX_2, "%s%s%s",                        \
+                FW_DLL_ROOT_DIR, str1, FW_DLL_EXTENSION);                               \
+                snprintf(nfcFL.nfcMwFL._PLATFORM_LIB_PATH, STRMAX_2, "%s%s%s",          \
+                        FW_DLL_ROOT_DIR, str2, FW_DLL_EXTENSION);                       \
+                        snprintf(nfcFL.nfcMwFL._PKU_LIB_PATH, STRMAX_2, "%s%s%s",       \
+                                FW_DLL_ROOT_DIR, str3, FW_DLL_EXTENSION);
+#endif
+#endif
diff --git a/src/hal/include/gki_hal_target.h b/src/hal/include/gki_hal_target.h
new file mode 100644
index 0000000..2863944
--- /dev/null
+++ b/src/hal/include/gki_hal_target.h
@@ -0,0 +1,312 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#ifndef GKI_HAL_TARGET_H
+#define GKI_HAL_TARGET_H
+
+#ifdef BUILDCFG
+#include "buildcfg_hal.h"
+#endif
+
+#include "data_types.h"
+
+/******************************************************************************
+**
+** Task configuration
+**
+******************************************************************************/
+
+/* Definitions of task IDs for inter-task messaging */
+#ifndef NFC_HAL_TASK
+#define NFC_HAL_TASK 0
+#endif
+
+/* The number of GKI tasks in the software system. */
+#ifndef GKI_MAX_TASKS
+#define GKI_MAX_TASKS 1
+#endif
+
+/******************************************************************************
+**
+** Buffer pool assignment
+**
+******************************************************************************/
+
+/* GKI pool for NCI messages */
+#ifndef NFC_HAL_NCI_POOL_ID
+#define NFC_HAL_NCI_POOL_ID GKI_POOL_ID_1
+#endif
+
+#ifndef NFC_HAL_NCI_POOL_BUF_SIZE
+#define NFC_HAL_NCI_POOL_BUF_SIZE GKI_BUF1_SIZE
+#endif
+
+/******************************************************************************
+**
+** Timer configuration
+**
+******************************************************************************/
+
+/* The number of GKI timers in the software system. */
+#ifndef GKI_NUM_TIMERS
+#define GKI_NUM_TIMERS 2
+#endif
+
+/* A conversion value for translating ticks to calculate GKI timer.  */
+#ifndef TICKS_PER_SEC
+#define TICKS_PER_SEC 100
+#endif
+
+/************************************************************************
+**  Utility macros converting ticks to time with user define OS ticks per sec
+**/
+#ifndef GKI_MS_TO_TICKS
+#define GKI_MS_TO_TICKS(x) ((x) / (1000 / TICKS_PER_SEC))
+#endif
+
+#ifndef GKI_SECS_TO_TICKS
+#define GKI_SECS_TO_TICKS(x) ((x) * (TICKS_PER_SEC))
+#endif
+
+#ifndef GKI_TICKS_TO_MS
+#define GKI_TICKS_TO_MS(x) ((x)*1000 / TICKS_PER_SEC)
+#endif
+
+#ifndef GKI_TICKS_TO_SECS
+#define GKI_TICKS_TO_SECS(x) ((x) / TICKS_PER_SEC)
+#endif
+
+/* TICK per second from OS (OS dependent change this macro accordingly to
+ * various OS) */
+#ifndef OS_TICKS_PER_SEC
+#define OS_TICKS_PER_SEC 1000
+#endif
+
+/************************************************************************
+**  Utility macros converting ticks to time with user define OS ticks per sec
+**/
+
+#ifndef GKI_OS_TICKS_TO_MS
+#define GKI_OS_TICKS_TO_MS(x) ((x)*1000 / OS_TICKS_PER_SEC)
+#endif
+
+#ifndef GKI_OS_TICKS_TO_SECS
+#define GKI_OS_TICKS_TO_SECS(x)   ((x) / OS_TICKS_PER_SEC))
+#endif
+
+/* delay in ticks before stopping system tick. */
+#ifndef GKI_DELAY_STOP_SYS_TICK
+#define GKI_DELAY_STOP_SYS_TICK 10
+#endif
+
+/* Option to guarantee no preemption during timer expiration (most system don't
+ * need this) */
+#ifndef GKI_TIMER_LIST_NOPREEMPT
+#define GKI_TIMER_LIST_NOPREEMPT false
+#endif
+
+/******************************************************************************
+**
+** Buffer configuration
+**
+******************************************************************************/
+
+/* true if GKI uses dynamic buffers. */
+#ifndef GKI_USE_DYNAMIC_BUFFERS
+#define GKI_USE_DYNAMIC_BUFFERS false
+#endif
+
+/* The size of the buffers in pool 0. */
+#ifndef GKI_BUF0_SIZE
+#define GKI_BUF0_SIZE 64
+#endif
+
+/* The number of buffers in buffer pool 0. */
+#ifndef GKI_BUF0_MAX
+#define GKI_BUF0_MAX 8
+#endif
+
+/* The ID of buffer pool 0. */
+#ifndef GKI_POOL_ID_0
+#define GKI_POOL_ID_0 0
+#endif
+
+/* The size of the buffers in pool 1. */
+#ifndef GKI_BUF1_SIZE
+#define GKI_BUF1_SIZE 288
+#endif
+
+/* The number of buffers in buffer pool 1. */
+#ifndef GKI_BUF1_MAX
+#define GKI_BUF1_MAX 8
+#endif
+
+/* The ID of buffer pool 1. */
+#ifndef GKI_POOL_ID_1
+#define GKI_POOL_ID_1 1
+#endif
+
+/* The size of the largest PUBLIC fixed buffer in system. */
+#ifndef GKI_MAX_BUF_SIZE
+#define GKI_MAX_BUF_SIZE GKI_BUF1_SIZE
+#endif
+
+/* The pool ID of the largest PUBLIC fixed buffer in system. */
+#ifndef GKI_MAX_BUF_SIZE_POOL_ID
+#define GKI_MAX_BUF_SIZE_POOL_ID GKI_POOL_ID_1
+#endif
+
+/* buffer size for USERIAL, it must large enough to hold NFC_HDR and max packet
+ * size */
+#ifndef USERIAL_POOL_BUF_SIZE
+#define USERIAL_POOL_BUF_SIZE GKI_BUF1_SIZE
+#endif
+
+/* buffer pool ID for USERIAL */
+#ifndef USERIAL_POOL_ID
+#define USERIAL_POOL_ID GKI_POOL_ID_1
+#endif
+
+#ifndef GKI_NUM_FIXED_BUF_POOLS
+#define GKI_NUM_FIXED_BUF_POOLS 2
+#endif
+
+/* The number of fixed and dynamic buffer pools */
+#ifndef GKI_NUM_TOTAL_BUF_POOLS
+#define GKI_NUM_TOTAL_BUF_POOLS 2
+#endif
+
+/* The buffer pool usage mask. */
+#ifndef GKI_DEF_BUFPOOL_PERM_MASK
+#define GKI_DEF_BUFPOOL_PERM_MASK 0xfff0
+#endif
+
+/* The buffer corruption check flag. */
+#ifndef GKI_ENABLE_BUF_CORRUPTION_CHECK
+#define GKI_ENABLE_BUF_CORRUPTION_CHECK true
+#endif
+
+/* The GKI severe error macro. */
+#ifndef GKI_SEVERE
+#define GKI_SEVERE(code)
+#endif
+
+/* true if GKI includes debug functionality. */
+#ifndef GKI_DEBUG
+#define GKI_DEBUG false
+#endif
+
+/* Maximum number of exceptions logged. */
+#ifndef GKI_MAX_EXCEPTION
+#define GKI_MAX_EXCEPTION 8
+#endif
+
+/* Maximum number of chars stored for each exception message. */
+#ifndef GKI_MAX_EXCEPTION_MSGLEN
+#define GKI_MAX_EXCEPTION_MSGLEN 64
+#endif
+
+#ifndef GKI_SEND_MSG_FROM_ISR
+#define GKI_SEND_MSG_FROM_ISR false
+#endif
+
+#if defined(GKI_DEBUG) && (GKI_DEBUG == true)
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "GKI_LINUX"
+/* GKI Trace Macros */
+#define GKI_TRACE_0(m)                                          \
+  LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | \
+             TRACE_TYPE_GENERIC,                                \
+         m)
+#define GKI_TRACE_1(m, p1)                                      \
+  LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | \
+             TRACE_TYPE_GENERIC,                                \
+         m, p1)
+#define GKI_TRACE_2(m, p1, p2)                                  \
+  LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | \
+             TRACE_TYPE_GENERIC,                                \
+         m, p1, p2)
+#define GKI_TRACE_3(m, p1, p2, p3)                              \
+  LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | \
+             TRACE_TYPE_GENERIC,                                \
+         m, p1, p2, p3)
+#define GKI_TRACE_4(m, p1, p2, p3, p4)                          \
+  LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | \
+             TRACE_TYPE_GENERIC,                                \
+         m, p1, p2, p3, p4)
+#define GKI_TRACE_5(m, p1, p2, p3, p4, p5)                      \
+  LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | \
+             TRACE_TYPE_GENERIC,                                \
+         m, p1, p2, p3, p4, p5)
+#define GKI_TRACE_6(m, p1, p2, p3, p4, p5, p6)                  \
+  LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | \
+             TRACE_TYPE_GENERIC,                                \
+         m, p1, p2, p3, p4, p5, p6)
+#else
+#define GKI_TRACE_0(m)
+#define GKI_TRACE_1(m, p1)
+#define GKI_TRACE_2(m, p1, p2)
+#define GKI_TRACE_3(m, p1, p2, p3)
+#define GKI_TRACE_4(m, p1, p2, p3, p4)
+#define GKI_TRACE_5(m, p1, p2, p3, p4, p5)
+#define GKI_TRACE_6(m, p1, p2, p3, p4, p5, p6)
+
+#endif
+
+#define GKI_TRACE_ERROR_0(m)                                                   \
+  LogMsg(                                                                      \
+      TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR, \
+      m)
+#define GKI_TRACE_ERROR_1(m, p1)                                               \
+  LogMsg(                                                                      \
+      TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR, \
+      m, p1)
+#define GKI_TRACE_ERROR_2(m, p1, p2)                                           \
+  LogMsg(                                                                      \
+      TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR, \
+      m, p1, p2)
+#define GKI_TRACE_ERROR_3(m, p1, p2, p3)                                       \
+  LogMsg(                                                                      \
+      TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR, \
+      m, p1, p2, p3)
+#define GKI_TRACE_ERROR_4(m, p1, p2, p3, p4)                                   \
+  LogMsg(                                                                      \
+      TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR, \
+      m, p1, p2, p3, p4)
+#define GKI_TRACE_ERROR_5(m, p1, p2, p3, p4, p5)                               \
+  LogMsg(                                                                      \
+      TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR, \
+      m, p1, p2, p3, p4, p5)
+#define GKI_TRACE_ERROR_6(m, p1, p2, p3, p4, p5, p6)                           \
+  LogMsg(                                                                      \
+      TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR, \
+      m, p1, p2, p3, p4, p5, p6)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void LogMsg(uint32_t trace_set_mask, const char* fmt_str, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GKI_TARGET_H */
diff --git a/src/hal/include/nci_defs.h b/src/hal/include/nci_defs.h
new file mode 100644
index 0000000..1b7e99e
--- /dev/null
+++ b/src/hal/include/nci_defs.h
@@ -0,0 +1,879 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the definition from NCI specification
+ *
+ ******************************************************************************/
+
+#ifndef NFC_NCI_DEFS_H
+#define NFC_NCI_DEFS_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NCI_BRCM_CO_ID 0x2E
+
+/* Define the message header size for all NCI Commands and Notifications.
+*/
+#define NCI_MSG_HDR_SIZE 3  /* per NCI spec */
+#define NCI_DATA_HDR_SIZE 3 /* per NCI spec */
+#define NCI_MAX_PAYLOAD_SIZE 0xFE
+#define NCI_MAX_CTRL_SIZE 0xFF /* max control message size */
+#define NCI_CTRL_INIT_SIZE 32  /* initial NFCC control payload size */
+#define NCI_MAX_VSC_SIZE 0xFF
+/* NCI header (3) + callback function pointer(8; use 8 to be safe) + HCIT (1
+ * byte) */
+#define NCI_VSC_MSG_HDR_SIZE 12
+#define NCI_TL_SIZE 2
+#define NCI_PARAM_ID_LF_CON_ADV_FEAT 0x55
+/*LF_T3T name changed in NCI2.0*/
+#define NCI_PARAM_ID_LF_T3T_RD_ALLOWED  0x55
+/* Max frame size (256) - Prologue (1) - Epilogue (2) in ISO-DEP, CID and NAD
+ * are not used*/
+#define NCI_ISO_DEP_MAX_INFO 253
+/* Max payload (254) - Protocol Header (3) in NFC-DEP, DID and NAD are not used
+ */
+#define NCI_NFC_DEP_MAX_DATA 251
+
+/* NCI Command and Notification Format:
+ * 3 byte message header:
+ * byte 0: MT PBF GID
+ * byte 1: OID
+ * byte 2: Message Length */
+/* MT: Message Type (byte 0) */
+#define NCI_MT_MASK 0xE0
+#define NCI_MT_SHIFT 5
+#define NCI_MT_DATA 0x00
+#define NCI_MT_CMD 1 /* (NCI_MT_CMD << NCI_MT_SHIFT) = 0x20 */
+#define NCI_MT_RSP 2 /* (NCI_MT_RSP << NCI_MT_SHIFT) = 0x40 */
+#define NCI_MT_NTF 3 /* (NCI_MT_NTF << NCI_MT_SHIFT) = 0x60 */
+#define NCI_MT_CFG 4 /* (NCI_MT_CFG << NCI_MT_SHIFT) = 0x80 */
+
+#define NCI_MTS_CMD 0x20
+#define NCI_MTS_RSP 0x40
+#define NCI_MTS_NTF 0x60
+#define NCI_MTS_CFG 0x80
+
+#define NCI_NTF_BIT 0x80 /* the tNFC_VS_EVT is a notification */
+#define NCI_RSP_BIT 0x40 /* the tNFC_VS_EVT is a response     */
+
+/* for internal use only; not from specification */
+/* the following 2 flags are used in layer_specific for fragmentation/reassembly
+ * of data packets */
+#define NCI_LS_DATA 0x00
+#define NCI_LS_DATA_PBF 0x01
+
+/* PBF: Packet Boundary Flag (byte 0) */
+#define NCI_PBF_MASK 0x10
+#define NCI_PBF_SHIFT 4
+#define NCI_PBF_NO_OR_LAST 0x00 /* not fragmented or last fragment */
+#define NCI_PBF_ST_CONT 0x10    /* start or continuing fragment */
+
+/* GID: Group Identifier (byte 0) */
+#define NCI_GID_MASK 0x0F
+#define NCI_GID_SHIFT 0
+#define NCI_GID_CORE 0x00      /* 0000b NCI Core group */
+#define NCI_GID_RF_MANAGE 0x01 /* 0001b RF Management group */
+#define NCI_GID_EE_MANAGE 0x02 /* 0010b NFCEE Management group */
+#define NCI_GID_PROP 0x0F      /* 1111b Proprietary */
+/* 0111b - 1110b RFU */
+
+/* OID: Opcode Identifier (byte 1) */
+#define NCI_OID_MASK 0x3F
+#define NCI_OID_SHIFT 0
+
+/* For routing */
+#define NCI_DH_ID 0 /* for DH */
+/* To identify the loopback test */
+#define NCI_TEST_ID 0xFE /* for loopback test */
+
+/* Destination Type */
+#define NCI_DEST_TYPE_NFCC 1   /* NFCC - loopback */
+#define NCI_DEST_TYPE_REMOTE 2 /* Remote NFC Endpoint */
+#define NCI_DEST_TYPE_NFCEE 3  /* NFCEE */
+
+/* builds byte0 of NCI Command and Notification packet */
+#define NCI_MSG_BLD_HDR0(p, mt, gid) \
+  *(p)++ = (uint8_t)(((mt) << NCI_MT_SHIFT) | (gid));
+
+#define NCI_MSG_PBLD_HDR0(p, mt, pbf, gid) \
+  *(p)++ = (uint8_t)(((mt) << NCI_MT_SHIFT) | ((pbf) << NCI_PBF_SHIFT) | (gid));
+
+/* builds byte1 of NCI Command and Notification packet */
+#define NCI_MSG_BLD_HDR1(p, oid) *(p)++ = (uint8_t)(((oid) << NCI_OID_SHIFT));
+
+/* parse byte0 of NCI packet */
+#define NCI_MSG_PRS_HDR0(p, mt, pbf, gid)     \
+  mt = (*(p)&NCI_MT_MASK) >> NCI_MT_SHIFT;    \
+  pbf = (*(p)&NCI_PBF_MASK) >> NCI_PBF_SHIFT; \
+  gid = *(p)++ & NCI_GID_MASK;
+
+/* parse MT and PBF bits of NCI packet */
+#define NCI_MSG_PRS_MT_PBF(p, mt, pbf)     \
+  mt = (*(p)&NCI_MT_MASK) >> NCI_MT_SHIFT; \
+  pbf = (*(p)&NCI_PBF_MASK) >> NCI_PBF_SHIFT;
+
+/* parse byte1 of NCI Cmd/Ntf */
+#define NCI_MSG_PRS_HDR1(p, oid) \
+  oid = (*(p)&NCI_OID_MASK);     \
+  (p)++;
+
+/* NCI Data Format:
+ * byte 0: MT(0) PBF CID
+ * byte 1: RFU
+ * byte 2: Data Length */
+/* CID: Connection Identifier (byte 0) 1-0xF Dynamically assigned (by NFCC), 0
+ * is predefined  */
+#define NCI_CID_MASK 0x0F
+
+/* builds 3-byte message header of NCI Data packet */
+#define NCI_DATA_BLD_HDR(p, cid, len) \
+  *(p)++ = (uint8_t)(cid);            \
+  *(p)++ = 0;                         \
+  *(p)++ = (uint8_t)(len);
+
+#define NCI_DATA_PBLD_HDR(p, pbf, cid, len)             \
+  *(p)++ = (uint8_t)(((pbf) << NCI_PBF_SHIFT) | (cid)); \
+  *(p)++ = 0;                                           \
+  *(p)++ = (len);
+
+#define NCI_DATA_PRS_HDR(p, pbf, cid, len)      \
+  (pbf) = (*(p)&NCI_PBF_MASK) >> NCI_PBF_SHIFT; \
+  (cid) = (*(p)&NCI_CID_MASK);                  \
+  p++;                                          \
+  p++;                                          \
+  (len) = *(p)++;
+
+/* Logical target ID 0x01-0xFE */
+/* CORE_RESET_NTF reset trigger type*/
+#define NCI2_0_RESET_TRIGGER_TYPE_ERROR                   0x00
+#define NCI2_0_RESET_TRIGGER_TYPE_POWERED_ON              0x01
+#define NCI2_0_RESET_TRIGGER_TYPE_CORE_RESET_CMD_RECEIVED 0x02
+/* Status Codes */
+#define NCI_STATUS_OK 0x00
+#define NCI_STATUS_REJECTED 0x01
+#define NCI_STATUS_MESSAGE_CORRUPTED 0x02
+#define NCI_STATUS_BUFFER_FULL 0xE0
+#define NCI_STATUS_FAILED 0x03
+#define NCI_STATUS_NOT_INITIALIZED 0x04
+#define NCI_STATUS_SYNTAX_ERROR 0x05
+#define NCI_STATUS_SEMANTIC_ERROR 0x06
+#define NCI_STATUS_UNKNOWN_GID 0x07
+#define NCI_STATUS_UNKNOWN_OID 0x08
+#define NCI_STATUS_INVALID_PARAM 0x09
+#define NCI_STATUS_MSG_SIZE_TOO_BIG 0x0A
+/* discovery */
+#define NCI_STATUS_ALREADY_STARTED 0xA0
+#define NCI_STATUS_ACTIVATION_FAILED 0xA1
+#define NCI_STATUS_TEAR_DOWN 0xA2
+/* RF Interface */
+#define NCI_STATUS_RF_TRANSMISSION_ERR 0xB0
+#define NCI_STATUS_RF_PROTOCOL_ERR 0xB1
+#define NCI_STATUS_TIMEOUT 0xB2
+/* NFCEE Interface */
+#define NCI_STATUS_EE_INTF_ACTIVE_FAIL 0xC0
+#define NCI_STATUS_EE_TRANSMISSION_ERR 0xC1
+#define NCI_STATUS_EE_PROTOCOL_ERR 0xC2
+#define NCI_STATUS_EE_TIMEOUT 0xC3
+#if (NXP_EXTNS == TRUE)
+#define NCI_STATUS_WIRED_SESSION_ABORTED 0xE6
+#define NCI_STATUS_DWP_APDU_DROPPPED \
+  0xE5 /* todo: need to place new error code when FW is readey*/
+#define NCI_STATUS_ALREADY_INITIALIZED 0x0C
+#endif
+
+typedef uint8_t tNCI_STATUS;
+
+/* RF Technologies */
+#define NCI_RF_TECHNOLOGY_A 0x00
+#define NCI_RF_TECHNOLOGY_B 0x01
+#define NCI_RF_TECHNOLOGY_F 0x02
+#define NCI_RF_TECHNOLOGY_15693 0x03
+
+/* Bit Rates */
+#define NCI_BIT_RATE_106 0x00  /* 106 kbit/s */
+#define NCI_BIT_RATE_212 0x01  /* 212 kbit/s */
+#define NCI_BIT_RATE_424 0x02  /* 424 kbit/s */
+#define NCI_BIT_RATE_848 0x03  /* 848 Kbit/s */
+#define NCI_BIT_RATE_1696 0x04 /* 1696 Kbit/s*/
+#define NCI_BIT_RATE_3392 0x05 /* 3392 Kbit/s*/
+#define NCI_BIT_RATE_6784 0x06 /* 6784 Kbit/s*/
+
+/**********************************************
+ * NCI Core Group Opcode        - 0
+ **********************************************/
+#define NCI_MSG_CORE_RESET 0
+#define NCI_MSG_CORE_INIT 1
+#define NCI_MSG_CORE_SET_CONFIG 2
+#define NCI_MSG_CORE_GET_CONFIG 3
+#define NCI_MSG_CORE_CONN_CREATE 4
+#define NCI_MSG_CORE_CONN_CLOSE 5
+#define NCI_MSG_CORE_CONN_CREDITS 6
+#define NCI_MSG_CORE_GEN_ERR_STATUS 7
+#define NCI_MSG_CORE_INTF_ERR_STATUS 8
+
+/**********************************************
+ * RF MANAGEMENT Group Opcode    - 1
+ **********************************************/
+#define NCI_MSG_RF_DISCOVER_MAP 0
+#define NCI_MSG_RF_SET_ROUTING 1
+#define NCI_MSG_RF_GET_ROUTING 2
+#define NCI_MSG_RF_DISCOVER 3
+#define NCI_MSG_RF_DISCOVER_SELECT 4
+#define NCI_MSG_RF_INTF_ACTIVATED 5
+#define NCI_MSG_RF_DEACTIVATE 6
+#define NCI_MSG_RF_FIELD 7
+#define NCI_MSG_RF_T3T_POLLING 8
+#define NCI_MSG_RF_EE_ACTION 9
+#define NCI_MSG_RF_EE_DISCOVERY_REQ 10
+#define NCI_MSG_RF_PARAMETER_UPDATE 11
+#define NCI_MSG_RF_ISO_DEP_NAK_PRESENCE 16
+/**********************************************
+ * NFCEE MANAGEMENT Group Opcode - 2
+ **********************************************/
+#define NCI_MSG_NFCEE_DISCOVER 0
+#define NCI_MSG_NFCEE_MODE_SET 1
+#define NCI_MSG_NFCEE_STATUS   2
+#if (NXP_EXTNS == TRUE)
+#define NCI_MSG_NFCEE_PWR_LNK_CTRL 3
+#define NCI_MSG_NFCEE_POWER_LINK_CTRL 4
+#endif
+
+/**********************************************
+ * NCI Proprietary  Group       - F
+ **********************************************/
+
+/**********************************************
+ * NCI Core Group Params
+ **********************************************/
+#define NCI_CORE_PARAM_SIZE_RESET 0x01
+#define NCI_CORE_PARAM_SIZE_RESET_RSP 0x03
+#define NCI_CORE_PARAM_SIZE_RESET_NTF 0x02
+/**********************************************
+ * NCI Feature Bit
+ **********************************************/
+#define NCI_FEAT_HCI_NETWORK        0x00000008
+#define NCI_CORE_PARAM_SIZE_INIT(X) (((X) == NCI_VERSION_2_0) ? (0x02) : (0x00))
+#define NCI2_0_CORE_INIT_CMD_BYTE_0 0x00
+#define NCI2_0_CORE_INIT_CMD_BYTE_1 0x00
+#define NCI_CORE_PARAM_SIZE_INIT_RSP 0x11
+#define NCI_CORE_INIT_RSP_OFFSET_NUM_INTF 0x05
+
+/* Status (1 octet) and number of params */
+#define NCI_CORE_PARAM_SIZE_SET_CONFIG_RSP 0x02
+
+/* octet 0 */
+#define NCI_FEAT_DISCOVERY_FREG 0x00000001
+#define NCI_FEAT_DISCOVERY_CFGM 0x00000006
+/* octet 1 */
+#define NCI_FEAT_TECHNOLOGY_ROUTING 0x00000200
+#define NCI_FEAT_PROTOCOL_ROUTING 0x00000400
+#define NCI_FEAT_AID_ROUTING 0x00000800
+/* octet 2 */
+#define NCI_FEAT_BATTERY_OFF_MD 0x00010000
+#define NCI_FEAT_SWITCH_OFF_MD 0x00020000
+
+/* supported Interfaces */
+#define NCI_SUP_INTF_FRAME 0x0001
+#define NCI_SUP_INTF_ISO_DEP 0x0002
+#define NCI_SUP_INTF_NFC_DEP 0x0004
+
+#define NCI_CORE_PARAM_SIZE_CON_CREATE 0x02 /* handle, num_tlv, (tlv) */
+/* status, size, credits, conn_id */
+#define NCI_CORE_PARAM_SIZE_CON_CREATE_RSP 0x04
+#define NCI_CON_CREATE_TAG_EE_INTF 0x00 /* old */
+#define NCI_CON_CREATE_TAG_RF_DISC_ID 0x00
+#define NCI_CON_CREATE_TAG_NFCEE_VAL 0x01
+
+#define NCI_CORE_PARAM_SIZE_CON_CLOSE 0x01     /* Conn ID (1 octet) */
+#define NCI_CORE_PARAM_SIZE_CON_CLOSE_RSP 0x01 /* Status (1 octet) */
+
+/* RF Field Status (1 octet) */
+#define NCI_CORE_PARAM_SIZE_RF_FIELD_NTF 0x01
+
+/* Keep the NCI configuration (if possible) and perform NCI initialization. */
+#define NCI_RESET_TYPE_KEEP_CFG 0x00
+/* Reset the NCI configuration, and perform NCI initialization. */
+#define NCI_RESET_TYPE_RESET_CFG 0x01
+
+/* NCI Configuration has been kept  */
+#define NCI_RESET_STATUS_KEPT_CFG 0x00
+/* NCI Configuration has been reset */
+#define NCI_RESET_STATUS_RESET_CFG 0x01
+
+/* No operating field generated by remote device  */
+#define NCI_RF_STS_NO_REMOTE 0x00
+/* Operating field generated by remote device  */
+#define NCI_RF_STS_REMOTE 0x01
+
+#define NCI_PARAM_SIZE_DISCOVER_NFCEE(X) (((X) == NCI_VERSION_2_0) ?0X00 : 0X01) /* Discovery Action (1 octet) */
+/* Status (1 octet)Number of NFCEEs (1 octet) */
+#define NCI_PARAM_SIZE_DISCOVER_NFCEE_RSP 0x02
+
+#define NCI_DISCOVER_ACTION_DISABLE 0
+#define NCI_DISCOVER_ACTION_ENABLE 1
+
+#define NCI_EE_DISCOVER_REQ_TYPE_LISTEN 0x01
+#define NCI_EE_DISCOVER_REQ_TYPE_POLL 0x02
+
+#define NCI_RF_PARAM_ID_TECH_N_MODE 0x00 /* RF Technology and Mode   */
+#define NCI_RF_PARAM_ID_TX_BIT_RATE 0x01 /* Transmit Bit Rate        */
+#define NCI_RF_PARAM_ID_RX_BIT_RATE 0x02 /* Receive Bit Rate         */
+#define NCI_RF_PARAM_ID_B_DATA_EX_PARAM \
+  0x03 /* B Data Exchange config param  \
+          */
+/****************************************************
+ * NCI NFCEE status
+ ****************************************************/
+#define NCI_NFCEE_STS_UNRECOVERABLE_ERROR 0x00
+#define NCI_NFCEE_STS_INIT_STARTED        0x01
+#define NCI_NFCEE_STS_INIT_COMPLETED      0x02
+
+#define NCI_NFCEE_INTERFACE_APDU 0x00
+#define NCI_NFCEE_INTERFACE_HCI_ACCESS 0x01
+#define NCI_NFCEE_INTERFACE_T3T 0x02
+#define NCI_NFCEE_INTERFACE_TRANSPARENT 0x03
+#define NCI_NFCEE_INTERFACE_PROPRIETARY 0x80
+
+/****************************************************
+ * NCI NFCEE INterface specific status Codes
+ ****************************************************/
+#define NCI_NFCEE_STS_INTF_ACTIVATION_FAILED 0xC0
+#define NCI_NFCEE_STS_TRANSMISSION_ERROR     0xC1
+#define NCI_NFCEE_STS_PROTOCOL_ERROR         0xC2
+#define NCI_NFCEE_STS_TIMEOUT_ERROR          0xC3
+
+#define NCI_NFCEE_STS_CONN_ACTIVE 0x00
+#define NCI_NFCEE_STS_CONN_INACTIVE 0x01
+#define NCI_NFCEE_STS_REMOVED 0x02
+#define NCI_NUM_NFCEE_STS 3
+
+/* Logical Target ID (1 octet)NFCEE Mode (1 octet) */
+#define NCI_CORE_PARAM_SIZE_NFCEE_MODE_SET 0x02
+#define NCI_CORE_PARAM_SIZE_NFCEE_MODE_SET_RSP 0x01 /* Status (1 octet) */
+
+#define NCI_MSG_CORE_SET_POWER_SUB_STATE 9
+#define NCI_CORE_PARAM_SIZE_SET_POWER_SUB_STATE    0x01
+/* Deactivate the connected NFCEE */
+#define NCI_NFCEE_MD_DEACTIVATE 0x00
+/* Activate the connected NFCEE */
+#define NCI_NFCEE_MD_ACTIVATE 0x01
+#define NCI_NUM_NFCEE_MODE 2
+
+/**********************************************
+ * NCI Deactivation Type
+ **********************************************/
+#define NCI_DEACTIVATE_TYPE_IDLE 0      /* Idle Mode     */
+#define NCI_DEACTIVATE_TYPE_SLEEP 1     /* Sleep Mode    */
+#define NCI_DEACTIVATE_TYPE_SLEEP_AF 2  /* Sleep_AF Mode */
+#define NCI_DEACTIVATE_TYPE_DISCOVERY 3 /* Discovery     */
+
+/**********************************************
+ * NCI Deactivation Reasons
+ **********************************************/
+#define NCI_DEACTIVATE_REASON_DH_REQ 0       /* DH Request       */
+#define NCI_DEACTIVATE_REASON_ENDPOINT_REQ 1 /* Endpoint Request */
+#define NCI_DEACTIVATE_REASON_RF_LINK_LOSS 2 /* RF Link Loss     */
+#define NCI_DEACTIVATE_REASON_NFCB_BAD_AFI 3 /* NFC-B Bad AFI    */
+
+
+/* The NFCEE status in NFCEE Status Notification */
+#define NCI_NFCEE_NTF_STATUS_ERROR          0x00    /* Unrecoverable Error */
+#define NCI_NFCEE_NTF_STATUS_INIT_STARTED   0x01    /* NFCEE initialization sequence started */
+#define NCI_NFCEE_NTF_STATUS_INIT_DONE      0x02    /* NFCEE initialization sequence completed */
+typedef uint8_t tNCI_EE_NTF_STATUS;
+
+/* NFCEE Power and Link Configuration */
+#define NFCEE_PL_CONFIG_NFCC_DECIDES        0x00
+#define NFCEE_PL_CONFIG_P_ALWAYS_ON         0x01
+#define NFCEE_PL_CONFIG_L_ON_WHEN_P_ON      0x02
+#define NFCEE_PL_CONFIG_PL_ALWAYS_ON        0x03
+typedef uint8_t tNCI_NFCEE_PL_CONFIG;
+
+/**********************************************
+* NCI Interface Mode
+**********************************************/
+#define NCI_INTERFACE_MODE_POLL 1
+#define NCI_INTERFACE_MODE_LISTEN 2
+#define NCI_INTERFACE_MODE_POLL_N_LISTEN 3
+
+/**********************************************
+ * NCI Interface Types
+ **********************************************/
+#define NCI_INTERFACE_EE_DIRECT_RF 0
+#define NCI_INTERFACE_FRAME 1
+#define NCI_INTERFACE_ISO_DEP 2
+#define NCI_INTERFACE_NFC_DEP 3
+
+#define NCI_INTERFACE_MAX NCI_INTERFACE_NFC_DEP
+#define NCI_INTERFACE_EXTENSION_MAX 2
+#define NCI_INTERFACE_FIRST_VS 0x80
+#if (NXP_EXTNS == TRUE)
+#define NCI_INTERFACE_MIFARE 0x80
+
+#endif
+typedef uint8_t tNCI_INTF_TYPE;
+
+/**********************************************
+ * NCI RF Management / DISCOVERY Group Params
+ **********************************************/
+#define NCI_DISCOVER_PARAM_SIZE_RSP 0x01
+
+#define NCI_DISCOVER_PARAM_SIZE_SELECT 0x03     /* ID, protocol, interface */
+#define NCI_DISCOVER_PARAM_SIZE_SELECT_RSP 0x01 /* Status (1 octet) */
+#define NCI_DISCOVER_PARAM_SIZE_STOP 0x00       /*  */
+#define NCI_DISCOVER_PARAM_SIZE_STOP_RSP 0x01   /* Status (1 octet) */
+#define NCI_DISCOVER_PARAM_SIZE_DEACT 0x01      /* type */
+#define NCI_DISCOVER_PARAM_SIZE_DEACT_RSP 0x01  /* Status (1 octet) */
+#define NCI_DISCOVER_PARAM_SIZE_DEACT_NTF 0x01  /* type */
+
+#define NCI_ROUTE_QUAL_MASK         0x70
+#define NCI_ROUTE_QUAL_LONG_SELECT  0x10 /* AID matching is allowed when the SELECT AID is longer */
+#define NCI_ROUTE_QUAL_SHORT_SELECT 0x20 /* AID matching is allowed when the SELECT AID is shorter */
+#define NCI_ROUTE_QUAL_BLOCK_ROUTE  0x40 /* AID is blocked in unsupported power mode */
+/**********************************************
+ * Supported Protocols
+ **********************************************/
+#define NCI_PROTOCOL_UNKNOWN 0x00
+#define NCI_PROTOCOL_T1T 0x01
+#define NCI_PROTOCOL_T2T 0x02
+#define NCI_PROTOCOL_T3T 0x03
+#define NCI_PROTOCOL_ISO_DEP 0x04
+#define NCI_PROTOCOL_NFC_DEP 0x05
+#if (NXP_EXTNS == TRUE)
+#define NCI_PROTOCOL_ISO7816 0xA0
+#endif
+/**********************************************
+ * Proprietary Protocols
+ **********************************************/
+#if (NXP_EXTNS == TRUE)
+#ifndef NCI_PROTOCOL_T3BT
+#define NCI_PROTOCOL_T3BT 0x8b
+#endif
+#endif
+
+/* Discovery Types/Detected Technology and Mode */
+#define NCI_DISCOVERY_TYPE_POLL_A 0x00
+#define NCI_DISCOVERY_TYPE_POLL_B 0x01
+#define NCI_DISCOVERY_TYPE_POLL_F 0x02
+#define NCI_DISCOVERY_TYPE_POLL_A_ACTIVE 0x03
+#define NCI_DISCOVERY_TYPE_POLL_F_ACTIVE 0x05
+#define NCI_DISCOVERY_TYPE_LISTEN_A 0x80
+#define NCI_DISCOVERY_TYPE_LISTEN_B 0x81
+#define NCI_DISCOVERY_TYPE_LISTEN_F 0x82
+#define NCI_DISCOVERY_TYPE_LISTEN_A_ACTIVE 0x83
+#define NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE 0x85
+#define NCI_DISCOVERY_TYPE_POLL_ISO15693 0x06
+#define NCI_DISCOVERY_TYPE_LISTEN_ISO15693 0x86
+#define NCI_DISCOVERY_TYPE_MAX NCI_DISCOVERY_TYPE_LISTEN_ISO15693
+
+typedef uint8_t tNCI_DISCOVERY_TYPE;
+
+#define NCI_EE_TRIG_7816_SELECT 0x00
+#define NCI_EE_TRIG_RF_PROTOCOL 0x01
+#define NCI_EE_TRIG_RF_TECHNOLOGY 0x02
+#define NCI_EE_TRIG_APP_INIT 0x10
+
+#define NCI_EE_ACT_TAG_AID 0xC0   /* AID                 */
+#define NCI_EE_ACT_TAG_PROTO 0xC1 /* RF protocol         */
+#define NCI_EE_ACT_TAG_TECH 0xC2  /* RF technology       */
+#define NCI_EE_ACT_TAG_DATA 0xC3  /* hex data for app    */
+#define NCI_EE_ACT_TAG_DEBUG 0xC4 /* debug trace         */
+
+#define NCI_CORE_PARAM_SIZE_NFCEE_PL_CTRL       0x02 /* NFCEE ID (1 octet) PL config (1 octet) */
+#define NCI_CORE_PARAM_SIZE_NFCEE_PL_CTRL_RSP   0x01 /* Status (1 octet) */
+
+/* Technology based routing  */
+#define NCI_ROUTE_TAG_TECH 0x00
+/* Protocol based routing  */
+#define NCI_ROUTE_TAG_PROTO 0x01
+#define NCI_ROUTE_TAG_AID 0x02 /* AID routing */
+
+#define NCI_ROUTE_TAG_APDU 0x4 /* APDU routing*/
+#define NCI_ROUTE_PWR_STATE_ON 0x01 /* The device is on */
+/* The device is switched off */
+#define NCI_ROUTE_PWR_STATE_SWITCH_OFF 0x02
+/* The device's battery is removed */
+#define NCI_ROUTE_PWR_STATE_BATT_OFF 0x04
+#if (NXP_EXTNS == TRUE)
+/* The device is screen off Unlock mode */
+#define NCI_ROUTE_PWR_STATE_SCREEN_OFF_UNLOCK()   ((NFC_GetNCIVersion() == NCI_VERSION_2_0)?0x08:0x80)
+/* The device is screen on lock mode */
+#define NCI_ROUTE_PWR_STATE_SCREEN_ON_LOCK()    ((NFC_GetNCIVersion() == NCI_VERSION_2_0)?0x10:0x40)
+/* The device is screen off lock mode */
+#define NCI_ROUTE_PWR_STATE_SCREEN_OFF_LOCK()   ((NFC_GetNCIVersion() == NCI_VERSION_2_0)?0x20:0x00)
+#endif
+/* Hardware / Registration Identification  */
+#define NCI_NFCEE_TAG_HW_ID 0x00
+#define NCI_NFCEE_TAG_ATR_BYTES 0x01 /* ATR Bytes  */
+/* T3T Command Set Interface Supplementary Info */
+#define NCI_NFCEE_TAG_T3T_INFO 0x02
+#define NCI_NFCEE_TAG_HCI_HOST_ID 0xA0 /* HCI host ID */
+
+#define NCI_DISCOVER_NTF_LAST 0x00
+#define NCI_DISCOVER_NTF_LAST_ABORT 0x01
+#define NCI_DISCOVER_NTF_MORE 0x02
+
+/* NCI RF Management Group Params */
+#define NCI_RF_PARAM_SIZE_T3T_POLLING 0x04 /* System Code, RC, TSN */
+#if (NXP_EXTNS == TRUE)
+#define NCI_MSG_RF_WTX 0x17
+#endif
+
+/**********************************************
+ * NCI Parameter IDs
+ **********************************************/
+
+#define NCI_PARAM_ID_TOTAL_DURATION 0x00
+#define NCI_PARAM_ID_CON_DEVICES_LIMIT 0x01
+#define NCI_PARAM_ID_CON_DISCOVERY_PARAM 0x02
+#define NCI_PARAM_ID_PA_BAILOUT 0x08
+#define NCI_PARAM_ID_PB_AFI 0x10
+#define NCI_PARAM_ID_PB_BAILOUT 0x11
+#define NCI_PARAM_ID_PB_ATTRIB_PARAM1 0x12
+#define NCI_PARAM_ID_PF_BIT_RATE 0x18
+#define NCI_PARAM_ID_PF_RC 0x19
+#define NCI_PARAM_ID_PB_H_INFO 0x20
+#define NCI_PARAM_ID_PI_BIT_RATE 0x21
+
+#define NCI_PARAM_ID_BITR_NFC_DEP 0x28
+#define NCI_PARAM_ID_ATR_REQ_GEN_BYTES 0x29
+#define NCI_PARAM_ID_ATR_REQ_CONFIG 0x2A
+
+#define NCI_PARAM_ID_LA_BIT_FRAME_SDD 0x30
+#define NCI_PARAM_ID_LA_PLATFORM_CONFIG 0x31
+#define NCI_PARAM_ID_LA_SEL_INFO 0x32
+#define NCI_PARAM_ID_LA_NFCID1 0x33
+#define NCI_PARAM_ID_LB_SENSB_INFO 0x38
+#define NCI_PARAM_ID_LB_NFCID0 0x39
+#define NCI_PARAM_ID_LB_APPDATA 0x3A
+#define NCI_PARAM_ID_LB_SFGI 0x3B
+#define NCI_PARAM_ID_LB_ADC_FO 0x3C
+#define NCI_PARAM_ID_LB_PROTOCOL NCI_PARAM_ID_LB_SENSB_INFO
+
+#define NCI_PARAM_ID_LF_T3T_ID1 0x40
+#define NCI_PARAM_ID_LF_T3T_ID2 0x41
+#define NCI_PARAM_ID_LF_T3T_ID3 0x42
+#define NCI_PARAM_ID_LF_T3T_ID4 0x43
+#define NCI_PARAM_ID_LF_T3T_ID5 0x44
+#define NCI_PARAM_ID_LF_T3T_ID6 0x45
+#define NCI_PARAM_ID_LF_T3T_ID7 0x46
+#define NCI_PARAM_ID_LF_T3T_ID8 0x47
+#define NCI_PARAM_ID_LF_T3T_ID9 0x48
+#define NCI_PARAM_ID_LF_T3T_ID10 0x49
+#define NCI_PARAM_ID_LF_T3T_ID11 0x4A
+#define NCI_PARAM_ID_LF_T3T_ID12 0x4B
+#define NCI_PARAM_ID_LF_T3T_ID13 0x4C
+#define NCI_PARAM_ID_LF_T3T_ID14 0x4D
+#define NCI_PARAM_ID_LF_T3T_ID15 0x4E
+#define NCI_PARAM_ID_LF_T3T_ID16 0x4F
+#define NCI_PARAM_ID_LF_PROTOCOL 0x50
+#define NCI_PARAM_ID_LF_T3T_PMM 0x51
+/* max num of LF_T3T_ID supported by NFCC (1 for now) */
+#define NCI_PARAM_ID_LF_T3T_MAX 0x52
+#define NCI_PARAM_ID_LF_T3T_FLAGS2 0x53
+#define NCI_PARAM_ID_LF_CON_BITR_F 0x54
+#define NCI_PARAM_ID_LF_CON_ADV_FEAT 0x55  // FelicaOnHost
+#define NCI_PARAM_ID_FWI 0x58
+#define NCI_PARAM_ID_LA_HIST_BY 0x59
+#define NCI_PARAM_ID_LB_H_INFO_RSP 0x5A
+#define NCI_PARAM_ID_LI_BIT_RATE 0x5B
+
+#define NCI_PARAM_ID_WT 0x60
+#define NCI_PARAM_ID_ATR_RES_GEN_BYTES 0x61
+#define NCI_PARAM_ID_ATR_RSP_CONFIG 0x62
+
+#define NCI_PARAM_ID_RF_FIELD_INFO 0x80
+#define NCI_PARAM_ID_RF_NFCEE_ACTION 0x81
+#define NCI_PARAM_ID_NFC_DEP_OP 0x82
+
+/* NCI_PARAM_ID_HOST_LISTEN_MASK (byte1 for DH, byte2 for UICC) */
+/* (0x01 << (NCI_DISCOVERY_TYPE_LISTEN_A_PASSIVE & 0x0F)) */
+#define NCI_LISTEN_MASK_A 0x01
+/* (0x01 << (NCI_DISCOVERY_TYPE_LISTEN_B_PASSIVE & 0x0F)) */
+#define NCI_LISTEN_MASK_B 0x02
+/* (0x01 << (NCI_DISCOVERY_TYPE_LISTEN_F_PASSIVE & 0x0F)) */
+#define NCI_LISTEN_MASK_F 0x04
+/* (0x01 << (NCI_DISCOVERY_TYPE_LISTEN_A_ACTIVE & 0x0F))  */
+#define NCI_LISTEN_MASK_A_ACTIVE 0x08
+/* (0x01 << (NCI_DISCOVERY_TYPE_LISTEN_B_PRIME & 0x0F))   */
+#define NCI_LISTEN_MASK_B_PRIME 0x10
+/* (0x01 << (NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE & 0x0F))  */
+#define NCI_LISTEN_MASK_F_ACTIVE 0x20
+/* (0x01 << (NCI_DISCOVERY_TYPE_LISTEN_ISO15693 & 0x0F))  */
+#define NCI_LISTEN_MASK_ISO15693 0x40
+
+#define NCI_LISTEN_DH_NFCEE_ENABLE_MASK 0x00 /* The DH-NFCEE listen is considered as a enable NFCEE */
+#define NCI_LISTEN_DH_NFCEE_DISABLE_MASK 0x02 /* The DH-NFCEE listen is considered as a disable NFCEE */
+#define NCI_POLLING_DH_DISABLE_MASK 0x00 /* The DH polling is considered as a disable NFCEE */
+#define NCI_POLLING_DH_ENABLE_MASK 0x01 /* The DH polling is considered as a enable NFCEE */
+
+/* Type A Parameters */
+#define NCI_PARAM_PLATFORM_T1T 0x0C
+#define NCI_PARAM_SEL_INFO_ISODEP 0x20
+#define NCI_PARAM_SEL_INFO_NFCDEP 0x40
+/**********************************************
+ * NCI Parameter ID Lens
+ **********************************************/
+#define NCI_PARAM_LEN_TOTAL_DURATION 2
+
+#define NCI_PARAM_LEN_CON_DISCOVERY_PARAM 1
+
+#define NCI_PARAM_LEN_PA_FSDI 1
+
+#define NCI_PARAM_LEN_PF_RC 1
+
+#define NCI_PARAM_LEN_LA_BIT_FRAME_SDD 1
+#define NCI_PARAM_LEN_LA_PLATFORM_CONFIG 1
+#define NCI_PARAM_LEN_LA_SEL_INFO 1
+
+#define NCI_PARAM_LEN_LB_SENSB_INFO 1
+#define NCI_PARAM_LEN_LB_NFCID0 4
+#define NCI_PARAM_LEN_LB_APPDATA 4
+#define NCI_PARAM_LEN_LB_ADC_FO 1
+
+#define NCI_PARAM_LEN_LF_PROTOCOL 1
+#define NCI_PARAM_LEN_LF_T3T_FLAGS2 2
+#define NCI_PARAM_LEN_LF_T3T_PMM 8
+#define NCI_PARAM_LEN_LF_T3T_ID(X) (((X) == NCI_VERSION_2_0) ? (0x12) : (0x0A))
+#define NCI_PARAM_LEN_LF_CON_ADV_FEAT 1  // FelicaOnHost
+
+#define NCI_PARAM_LEN_FWI 1
+#define NCI_PARAM_LEN_WT 1
+/* GEN_BYTES - variable */
+
+/* Listen protocol bits - NCI_PARAM_ID_LF_PROTOCOL and
+ * NCI_PARAM_ID_LB_SENSB_INFO */
+#define NCI_LISTEN_PROTOCOL_ISO_DEP 0x01
+#define NCI_LISTEN_PROTOCOL_NFC_DEP 0x02
+
+#define NCI_DISCOVER_PARAM_SIZE_TEST_RF 0x06
+
+/* LF_T3T_FLAGS2 listen bits all-disabled definition */
+#define NCI_LF_T3T_FLAGS2_ALL_DISABLED 0x0000
+#define NCI_LF_T3T_FLAGS2_ID1_ENABLED 0x0001
+
+#define NCI_PARAM_LEN_LF_CON_ADV_FEAT 1
+
+#define NCI_PARAM_LEN_LF_T3T_RD_ALLOWED 1 //Listen F NCI2.0 Parameter
+#define NCI_PARAM_LEN_LF_T3T_ID_MAX 16 //LF T3T indentifier Max Value 16
+#define NFA_CE_LISTEN_INFO_LF_MAX 16 //LF T3T indentifier Max Value 16
+
+typedef struct {
+  uint16_t addr;
+  uint8_t len;
+  uint8_t* data;
+} NCIP_T1T_SETMEM_CMD_t;
+
+typedef struct { uint8_t status; } NCIP_T1T_SETMEM_RSP_t;
+
+typedef struct { uint16_t addr; } NCIP_T1T_GETMEM_CMD_t;
+
+typedef struct {
+  uint8_t status;
+  uint8_t* data;
+} NCIP_T1T_GETMEM_RSP_t;
+
+typedef struct {
+  uint8_t hr0;
+  uint8_t hr1;
+} NCIP_T1T_SETHR_CMD_t;
+
+typedef struct { uint8_t status; } NCIP_T1T_SETHR_RSP_t;
+
+#ifndef NCI_GET_CMD_BUF
+#if (HCI_USE_VARIABLE_SIZE_CMD_BUF == false)
+/* Allocate fixed-size buffer from HCI_CMD_POOL (default case) */
+#define NCI_GET_CMD_BUF(paramlen) ((NFC_HDR*)GKI_getpoolbuf(NFC_NCI_POOL_ID))
+#else
+/* Allocate smallest possible buffer (for platforms with limited RAM) */
+#define NCI_GET_CMD_BUF(paramlen)                                    \
+  ((NFC_HDR*)GKI_getbuf((uint16_t)(NFC_HDR_SIZE + NCI_MSG_HDR_SIZE + \
+                                   NCI_MSG_OFFSET_SIZE + (paramlen))))
+#endif
+#endif /* NCI_GET_CMD_BUF */
+
+#define NCI_MAX_AID_LEN 16
+#define NCI_MIN_APDU_DATA_LEN 1
+#define NCI_MIN_APDU_MASK_LEN 1
+#define NCI_MAX_APDU_DATA_LEN 124
+#define NCI_MAX_APDU_MASK_LEN 124
+
+typedef struct {
+  uint8_t type;
+  uint8_t frequency;
+} tNCI_DISCOVER_PARAMS;
+
+typedef struct {
+  uint8_t protocol;
+  uint8_t mode;
+  uint8_t intf_type;
+} tNCI_DISCOVER_MAPS;
+
+#define NCI_NFCID1_MAX_LEN 10
+#define NCI_T1T_HR_LEN 2
+typedef struct {
+  uint8_t sens_res[2]; /* SENS_RES Response (ATQA). Available after Technology
+                          Detection */
+  uint8_t nfcid1_len;  /* 4, 7 or 10 */
+  uint8_t nfcid1[NCI_NFCID1_MAX_LEN]; /* AKA NFCID1 */
+  uint8_t sel_rsp; /* SEL_RSP (SAK) Available after Collision Resolution */
+  uint8_t hr_len;  /* 2, if T1T HR0/HR1 is reported */
+  uint8_t hr[NCI_T1T_HR_LEN]; /* T1T HR0 is in hr[0], HR1 is in hr[1] */
+} tNCI_RF_PA_PARAMS;
+
+#define NCI_MAX_SENSB_RES_LEN 12
+typedef struct {
+  uint8_t sensb_res_len; /* Length of SENSB_RES Response (Byte 2 - Byte 12 or
+                            13) Available after Technology Detection */
+  uint8_t sensb_res[NCI_MAX_SENSB_RES_LEN]; /* SENSB_RES Response (ATQ) */
+} tNCI_RF_PB_PARAMS;
+
+#define NCI_MAX_SENSF_RES_LEN 18
+#if (NXP_EXTNS == TRUE)
+#define NCI_SENSF_RES_OFFSET_NFCID2 1
+#endif
+#define NCI_SENSF_RES_OFFSET_PAD0 8
+#define NCI_SENSF_RES_OFFSET_RD 16
+#define NCI_NFCID2_LEN 8
+#define NCI_T3T_PMM_LEN 8
+#define NCI_SYSTEMCODE_LEN 2
+#define NCI_RF_F_UID_LEN NCI_NFCID2_LEN
+#define NCI_MRTI_CHECK_INDEX 13
+#define NCI_MRTI_UPDATE_INDEX 14
+typedef struct {
+  uint8_t bit_rate;      /* NFC_BIT_RATE_212 or NFC_BIT_RATE_424 */
+  uint8_t sensf_res_len; /* Length of SENSF_RES Response (Byte 2 - Byte 17 or
+                            19) Available after Technology Detection */
+  uint8_t sensf_res[NCI_MAX_SENSF_RES_LEN]; /* SENSB_RES Response */
+} tNCI_RF_PF_PARAMS;
+
+typedef struct {
+  uint8_t nfcid2[NCI_NFCID2_LEN]; /* NFCID2 generated by the Local NFCC for
+                                     NFC-DEP Protocol.Available for Frame
+                                     Interface  */
+} tNCI_RF_LF_PARAMS;
+
+typedef struct {
+  tNCI_DISCOVERY_TYPE mode;
+  union {
+    tNCI_RF_PA_PARAMS pa;
+    tNCI_RF_PB_PARAMS pb;
+    tNCI_RF_PF_PARAMS pf;
+    tNCI_RF_LF_PARAMS lf;
+  } param; /* Discovery Type specific parameters */
+} tNCI_RF_TECH_PARAMS;
+
+#ifndef NCI_MAX_ATS_LEN
+#define NCI_MAX_ATS_LEN 60
+#endif
+#ifndef NCI_MAX_HIS_BYTES_LEN
+#define NCI_MAX_HIS_BYTES_LEN 50
+#endif
+#ifndef NCI_MAX_GEN_BYTES_LEN
+#define NCI_MAX_GEN_BYTES_LEN 48
+#endif
+
+#define NCI_ATS_T0_INDEX 0
+#define NCI_ATS_TC_MASK 0x40
+#define NCI_ATS_TB_MASK 0x20
+#define NCI_ATS_TA_MASK 0x10
+#define NCI_ATS_FSCI_MASK 0x0F
+typedef struct {
+  uint8_t ats_res_len;              /* Length of ATS RES */
+  uint8_t ats_res[NCI_MAX_ATS_LEN]; /* ATS RES defined in [DIGPROT] */
+} tNCI_INTF_PA_ISO_DEP;
+
+typedef struct { uint8_t rats; /* RATS */ } tNCI_INTF_LA_ISO_DEP;
+
+#define NCI_P_GEN_BYTE_INDEX 15
+#define NCI_L_GEN_BYTE_INDEX 14
+#define NCI_L_NFC_DEP_TO_INDEX 13
+typedef struct {
+  uint8_t atr_res_len;              /* Length of ATR_RES */
+  uint8_t atr_res[NCI_MAX_ATS_LEN]; /* ATR_RES (Byte 3 - Byte 17+n) as defined
+                                       in [DIGPROT] */
+} tNCI_INTF_PA_NFC_DEP;
+
+/* Note: keep tNCI_INTF_PA_NFC_DEP data member in the same order as
+ * tNCI_INTF_LA_NFC_DEP */
+typedef struct {
+  uint8_t atr_req_len;              /* Length of ATR_REQ */
+  uint8_t atr_req[NCI_MAX_ATS_LEN]; /* ATR_REQ (Byte 3 - Byte 18+n) as defined
+                                       in [DIGPROT] */
+} tNCI_INTF_LA_NFC_DEP;
+typedef tNCI_INTF_LA_NFC_DEP tNCI_INTF_LF_NFC_DEP;
+typedef tNCI_INTF_PA_NFC_DEP tNCI_INTF_PF_NFC_DEP;
+
+#define NCI_MAX_ATTRIB_LEN (10 + NCI_MAX_GEN_BYTES_LEN)
+
+typedef struct {
+  uint8_t attrib_res_len; /* Length of ATTRIB RES */
+  uint8_t
+      attrib_res[NCI_MAX_ATTRIB_LEN]; /* ATTRIB RES  as defined in [DIGPROT] */
+} tNCI_INTF_PB_ISO_DEP;
+
+typedef struct {
+  uint8_t attrib_req_len;                 /* Length of ATTRIB REQ */
+  uint8_t attrib_req[NCI_MAX_ATTRIB_LEN]; /* ATTRIB REQ (Byte 2 - Byte 10+k) as
+                                             defined in [DIGPROT] */
+} tNCI_INTF_LB_ISO_DEP;
+
+typedef struct {
+  tNCI_INTF_TYPE type; /* Interface Type  1 Byte  See Table 67 */
+  union {
+    tNCI_INTF_LA_ISO_DEP la_iso;
+    tNCI_INTF_PA_ISO_DEP pa_iso;
+    tNCI_INTF_LB_ISO_DEP lb_iso;
+    tNCI_INTF_PB_ISO_DEP pb_iso;
+    tNCI_INTF_LA_NFC_DEP la_nfc;
+    tNCI_INTF_PA_NFC_DEP pa_nfc;
+    tNCI_INTF_LF_NFC_DEP lf_nfc;
+    tNCI_INTF_PF_NFC_DEP pf_nfc;
+  } intf_param; /* Activation Parameters   0 - n Bytes */
+} tNCI_INTF_PARAMS;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_NCI_DEFS_H */
diff --git a/src/hal/include/nfc_hal_api.h b/src/hal/include/nfc_hal_api.h
new file mode 100644
index 0000000..ac873c8
--- /dev/null
+++ b/src/hal/include/nfc_hal_api.h
@@ -0,0 +1,420 @@
+/******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2012-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT 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) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  NFC Hardware Abstraction Layer API
+ *
+ ******************************************************************************/
+#ifndef NFC_HAL_API_H
+#define NFC_HAL_API_H
+#include <hardware/nfc.h>
+#include "data_types.h"
+#include "nfc_hal_target.h"
+
+/*******************************************************************************
+** tHAL_STATUS Definitions
+*******************************************************************************/
+#define HAL_NFC_STATUS_OK               0
+#define HAL_NFC_STATUS_FAILED           1
+#define HAL_NFC_STATUS_ERR_TRANSPORT    2
+#define HAL_NFC_STATUS_ERR_CMD_TIMEOUT  3
+#define HAL_NFC_STATUS_REFUSED          4
+
+/*******************************************************************************
+** tHAL_HCI_NETWK_CMD Definitions
+*******************************************************************************/
+#define HAL_NFC_HCI_NO_UICC_HOST 0x00
+#define HAL_NFC_HCI_UICC0_HOST 0x01
+#define HAL_NFC_HCI_UICC1_HOST 0x02
+#define HAL_NFC_HCI_UICC2_HOST 0x04
+
+#define MAX_IOCTL_TRANSCEIVE_CMD_LEN  256
+#define MAX_IOCTL_TRANSCEIVE_RESP_LEN 256
+#define MAX_ATR_INFO_LEN              128
+
+/*
+ * Data structures provided below are used of Hal Ioctl calls
+ */
+/*
+ * nfc_nci_ExtnCmd_t shall contain data for commands used for transceive command in ioctl
+ */
+typedef struct
+{
+    uint16_t cmd_len;
+    uint8_t  p_cmd[MAX_IOCTL_TRANSCEIVE_CMD_LEN];
+} nfc_nci_ExtnCmd_t;
+
+/*
+ * nfc_nci_ExtnRsp_t shall contain response for command sent in transceive command
+ */
+typedef struct
+{
+    uint16_t rsp_len;
+    uint8_t  p_rsp[MAX_IOCTL_TRANSCEIVE_RESP_LEN];
+} nfc_nci_ExtnRsp_t;
+/*
+ * InputData_t :ioctl has multiple subcommands
+ * Each command has corresponding input data which needs to be populated in this
+ */
+typedef union {
+    uint16_t          bootMode;
+    uint8_t           halType;
+    nfc_nci_ExtnCmd_t nciCmd;
+    uint32_t          timeoutMilliSec;
+    long              nfcServicePid;
+}InputData_t;
+/*
+ * nfc_nci_ExtnInputData_t :Apart from InputData_t, there are context data
+ * which is required during callback from stub to proxy.
+ * To avoid additional copy of data while propagating from libnfc to Adaptation
+ * and Nfcstub to ncihal, common structure is used. As a sideeffect, context data
+ * is exposed to libnfc (Not encapsulated).
+ */
+typedef struct {
+    /*
+     * context to be used/updated only by users of proxy & stub of Nfc.hal
+     * i.e, NfcAdaptation & Nfc hidl
+     */
+    void*       context;
+    InputData_t data;
+}nfc_nci_ExtnInputData_t;
+
+
+/*
+ * outputData_t :ioctl has multiple commands/responses
+ * This contains the output types for each ioctl.
+ */
+typedef union{
+    uint32_t            status;
+    nfc_nci_ExtnRsp_t   nciRsp;
+    uint8_t             nxpNciAtrInfo[MAX_ATR_INFO_LEN];
+    uint32_t            p61CurrentState;
+    uint16_t            fwUpdateInf;
+    uint16_t            fwDwnldStatus;
+    uint16_t            fwMwVerStatus;
+    uint8_t             chipType;
+}outputData_t;
+
+/*
+ * nfc_nci_ExtnOutputData_t :Apart from outputData_t, there are other information
+ * which is required during callback from stub to proxy.
+ * For ex (context, result of the operation , type of ioctl which was completed).
+ * To avoid additional copy of data while propagating from libnfc to Adaptation
+ * and Nfcstub to ncihal, common structure is used. As a sideeffect, these data
+ * is exposed(Not encapsulated).
+ */
+typedef struct {
+    /*
+     * ioctlType, result & context to be used/updated only by users of
+     * proxy & stub of Nfc.hal.
+     * i.e, NfcAdaptation & Nfc hidl
+     * These fields shall not be used by libnfc or halimplementation
+     */
+    uint64_t     ioctlType;
+    uint32_t     result;
+    void*        context;
+    outputData_t data;
+}nfc_nci_ExtnOutputData_t;
+
+/*
+ * nfc_nci_IoctlInOutData_t :data structure for input & output
+ * to be sent for ioctl command. input is populated by client/proxy side
+ * output is provided from server/stub to client/proxy
+ */
+typedef struct {
+    nfc_nci_ExtnInputData_t  inp;
+    nfc_nci_ExtnOutputData_t out;
+}nfc_nci_IoctlInOutData_t;
+
+enum {
+    HAL_NFC_ENABLE_I2C_FRAGMENTATION_EVT = 0x07,
+    HAL_NFC_POST_MIN_INIT_CPLT_EVT  = 0x08
+};
+
+enum {
+    HAL_NFC_IOCTL_P61_IDLE_MODE = 0,
+    HAL_NFC_IOCTL_P61_WIRED_MODE,
+    HAL_NFC_IOCTL_P61_PWR_MODE,
+    HAL_NFC_IOCTL_P61_DISABLE_MODE,
+    HAL_NFC_IOCTL_P61_ENABLE_MODE,
+    HAL_NFC_IOCTL_SET_BOOT_MODE,
+    HAL_NFC_IOCTL_GET_CONFIG_INFO,
+    HAL_NFC_IOCTL_CHECK_FLASH_REQ,
+    HAL_NFC_IOCTL_FW_DWNLD,
+    HAL_NFC_IOCTL_FW_MW_VER_CHECK,
+    HAL_NFC_IOCTL_DISABLE_HAL_LOG,
+    HAL_NFC_IOCTL_NCI_TRANSCEIVE,
+    HAL_NFC_IOCTL_P61_GET_ACCESS,
+    HAL_NFC_IOCTL_P61_REL_ACCESS,
+    HAL_NFC_IOCTL_ESE_CHIP_RST,
+    HAL_NFC_IOCTL_REL_SVDD_WAIT,
+    HAL_NFC_IOCTL_SET_JCP_DWNLD_ENABLE,
+    HAL_NFC_IOCTL_SET_JCP_DWNLD_DISABLE,
+    HAL_NFC_IOCTL_SET_NFC_SERVICE_PID,
+    HAL_NFC_IOCTL_GET_FEATURE_LIST
+};
+
+typedef uint8_t tHAL_NFC_STATUS;
+typedef void(tHAL_NFC_STATUS_CBACK)(tHAL_NFC_STATUS status);
+typedef void(tHAL_NFC_CBACK)(uint8_t event, tHAL_NFC_STATUS status);
+typedef void(tHAL_NFC_DATA_CBACK)(uint16_t data_len, uint8_t* p_data);
+
+/*******************************************************************************
+** tHAL_NFC_ENTRY HAL entry-point lookup table
+*******************************************************************************/
+
+typedef void(tHAL_API_INITIALIZE)(void);
+typedef void(tHAL_API_TERMINATE)(void);
+typedef void(tHAL_API_OPEN)(tHAL_NFC_CBACK* p_hal_cback,
+                            tHAL_NFC_DATA_CBACK* p_data_cback);
+typedef void(tHAL_API_CLOSE)(void);
+typedef void(tHAL_API_CORE_INITIALIZED)(uint16_t data_len,
+                                        uint8_t* p_core_init_rsp_params);
+typedef void(tHAL_API_WRITE)(uint16_t data_len, uint8_t* p_data);
+typedef bool(tHAL_API_PREDISCOVER)(void);
+typedef void(tHAL_API_CONTROL_GRANTED)(void);
+typedef void(tHAL_API_POWER_CYCLE)(void);
+typedef uint8_t(tHAL_API_GET_MAX_NFCEE)(void);
+#if (NXP_EXTNS == TRUE)
+typedef int(tHAL_API_IOCTL)(long arg, void* p_data);
+typedef int(tHAL_API_GET_FW_DWNLD_FLAG)(uint8_t* fwDnldRequest);
+#endif
+
+#define NFC_HAL_DM_PRE_SET_MEM_LEN 5
+typedef struct {
+  uint32_t addr;
+  uint32_t data;
+} tNFC_HAL_DM_PRE_SET_MEM;
+
+/* data members for NFC_HAL-HCI */
+typedef struct {
+  bool nfc_hal_prm_nvm_required; /* set nfc_hal_prm_nvm_required to true, if the
+                                    platform wants to abort PRM process without
+                                    NVM */
+  uint16_t nfc_hal_nfcc_enable_timeout; /* max time to wait for RESET NTF after
+                                           setting REG_PU to high */
+  uint16_t nfc_hal_post_xtal_timeout;   /* max time to wait for RESET NTF after
+                                           setting Xtal frequency */
+#if (NFC_HAL_HCI_INCLUDED == true)
+  bool nfc_hal_first_boot; /* set nfc_hal_first_boot to true, if platform
+                              enables NFC for the first time after bootup */
+  uint8_t nfc_hal_hci_uicc_support; /* set nfc_hal_hci_uicc_support to Zero, if
+                                       no UICC is supported otherwise set
+                                       corresponding bit(s) for every supported
+                                       UICC(s) */
+#endif
+} tNFC_HAL_CFG;
+
+typedef struct {
+  tHAL_API_INITIALIZE* initialize;
+  tHAL_API_TERMINATE* terminate;
+  tHAL_API_OPEN* open;
+  tHAL_API_CLOSE* close;
+  tHAL_API_CORE_INITIALIZED* core_initialized;
+  tHAL_API_WRITE* write;
+  tHAL_API_PREDISCOVER* prediscover;
+  tHAL_API_CONTROL_GRANTED* control_granted;
+  tHAL_API_POWER_CYCLE* power_cycle;
+  tHAL_API_GET_MAX_NFCEE* get_max_ee;
+#if (NXP_EXTNS == TRUE)
+  tHAL_API_IOCTL* ioctl;
+  tHAL_API_GET_FW_DWNLD_FLAG* check_fw_dwnld_flag;
+#endif
+} tHAL_NFC_ENTRY;
+
+#if (NXP_EXTNS == TRUE)
+typedef struct {
+  tHAL_NFC_ENTRY* hal_entry_func;
+  uint8_t boot_mode;
+} tHAL_NFC_CONTEXT;
+#endif
+/*******************************************************************************
+** HAL API Function Prototypes
+*******************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+**
+** Function         HAL_NfcInitialize
+**
+** Description      Called when HAL library is loaded.
+**
+**                  Initialize GKI and start the HCIT task
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcInitialize(void);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcTerminate
+**
+** Description      Called to terminate NFC HAL
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcTerminate(void);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcOpen
+**
+** Description      Open transport and intialize the NFCC, and
+**                  Register callback for HAL event notifications,
+**
+**                  HAL_OPEN_CPLT_EVT will notify when operation is complete.
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcOpen(tHAL_NFC_CBACK* p_hal_cback,
+                 tHAL_NFC_DATA_CBACK* p_data_cback);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcClose
+**
+** Description      Prepare for shutdown. A HAL_CLOSE_CPLT_EVT will be
+**                  reported when complete.
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcClose(void);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcCoreInitialized
+**
+** Description      Called after the CORE_INIT_RSP is received from the NFCC.
+**                  At this time, the HAL can do any chip-specific
+**                  configuration, and when finished signal the libnfc-nci with
+**                  event HAL_POST_INIT_CPLT_EVT.
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcCoreInitialized(uint8_t* p_core_init_rsp_params);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcWrite
+**
+** Description      Send an NCI control message or data packet to the
+**                  transport. If an NCI command message exceeds the transport
+**                  size, HAL is responsible for fragmenting it, Data packets
+**                  must be of the correct size.
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcWrite(uint16_t data_len, uint8_t* p_data);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPreDiscover
+**
+** Description      Perform any vendor-specific pre-discovery actions (if
+**                  needed).If any actions were performed true will be
+**                  returned, and HAL_PRE_DISCOVER_CPLT_EVT will notify when
+**                  actions are completed.
+**
+** Returns          true if vendor-specific pre-discovery actions initialized
+**                  false if no vendor-specific pre-discovery actions are
+**                  needed.
+**
+*******************************************************************************/
+bool HAL_NfcPreDiscover(void);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcControlGranted
+**
+** Description      Grant control to HAL control for sending NCI commands.
+**
+**                  Call in response to HAL_REQUEST_CONTROL_EVT.
+**
+**                  Must only be called when there are no NCI commands pending.
+**
+**                  HAL_RELEASE_CONTROL_EVT will notify when HAL no longer
+**                  needs control of NCI.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcControlGranted(void);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPowerCycle
+**
+** Description      Restart NFCC by power cyle
+**
+**                  HAL_OPEN_CPLT_EVT will notify when operation is complete.
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcPowerCycle(void);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcGetMaxNfcee
+**
+** Description      Retrieve the maximum number of NFCEEs supported by NFCC
+**
+** Returns          the maximum number of NFCEEs supported by NFCC
+**
+*******************************************************************************/
+uint8_t HAL_NfcGetMaxNfcee(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_HAL_API_H  */
diff --git a/src/hal/include/nfc_hal_target.h b/src/hal/include/nfc_hal_target.h
new file mode 100644
index 0000000..8b766e3
--- /dev/null
+++ b/src/hal/include/nfc_hal_target.h
@@ -0,0 +1,437 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#ifndef NFC_HAL_TARGET_H
+#define NFC_HAL_TARGET_H
+
+#include "gki.h"
+#include "data_types.h"
+
+/****************************************************************************
+** NCI related configuration
+****************************************************************************/
+
+/* Initial Max Control Packet Payload Size (until receiving payload size in
+ * INIT_CORE_RSP) */
+#ifndef NFC_HAL_NCI_INIT_CTRL_PAYLOAD_SIZE
+#define NFC_HAL_NCI_INIT_CTRL_PAYLOAD_SIZE 0xFF
+#endif
+
+/* Number of bytes to reserve in front of NCI messages (e.g. for transport
+ * header) */
+#ifndef NFC_HAL_NCI_MSG_OFFSET_SIZE
+#define NFC_HAL_NCI_MSG_OFFSET_SIZE 1
+#endif
+
+/* NFC-WAKE */
+#ifndef NFC_HAL_LP_NFC_WAKE_GPIO
+#define NFC_HAL_LP_NFC_WAKE_GPIO UPIO_GENERAL3
+#endif
+
+/* NFCC snooze mode idle timeout before deassert NFC_WAKE in ms */
+#ifndef NFC_HAL_LP_IDLE_TIMEOUT
+#define NFC_HAL_LP_IDLE_TIMEOUT 100
+#endif
+
+/* NFC snooze mode */
+#ifndef NFC_HAL_LP_SNOOZE_MODE
+#define NFC_HAL_LP_SNOOZE_MODE NFC_HAL_LP_SNOOZE_MODE_UART
+#endif
+
+/* Idle Threshold Host in 100ms unit */
+#ifndef NFC_HAL_LP_IDLE_THRESHOLD_HOST
+#define NFC_HAL_LP_IDLE_THRESHOLD_HOST 0
+#endif
+
+/* Idle Threshold HC in 100ms unit */
+#ifndef NFC_HAL_LP_IDLE_THRESHOLD_HC
+#define NFC_HAL_LP_IDLE_THRESHOLD_HC 0
+#endif
+
+/* Default NFCC power-up baud rate */
+#ifndef NFC_HAL_DEFAULT_BAUD
+#define NFC_HAL_DEFAULT_BAUD USERIAL_BAUD_115200
+#endif
+
+/* time (in ms) between power off and on NFCC */
+#ifndef NFC_HAL_POWER_CYCLE_DELAY
+#define NFC_HAL_POWER_CYCLE_DELAY 100
+#endif
+
+/* time (in ms) between power off and on NFCC */
+#ifndef NFC_HAL_NFCC_ENABLE_TIMEOUT
+#define NFC_HAL_NFCC_ENABLE_TIMEOUT 1000
+#endif
+
+#ifndef NFC_HAL_PRM_DEBUG
+#define NFC_HAL_PRM_DEBUG true
+#endif
+
+/* max patch data length (Can be overridden by platform for ACL HCI command
+ * size) */
+#ifndef NFC_HAL_PRM_HCD_CMD_MAXLEN
+#define NFC_HAL_PRM_HCD_CMD_MAXLEN 250
+#endif
+
+/* Require PreI2C patch by default */
+#ifndef NFC_HAL_PRE_I2C_PATCH_INCLUDED
+#define NFC_HAL_PRE_I2C_PATCH_INCLUDED true
+#endif
+
+/* Mininum payload size for SPD NCI commands (used to validate
+ * HAL_NfcPrmSetSpdNciCmdPayloadSize) */
+/* Default is 32, as required by the NCI specifications; however this value may
+ * be          */
+/* over-riden for platforms that have transport packet limitations */
+#ifndef NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE
+#define NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE (32)
+#endif
+
+/* amount of time to wait for authenticating/committing patch to NVM */
+#ifndef NFC_HAL_PRM_COMMIT_DELAY
+#define NFC_HAL_PRM_COMMIT_DELAY (30000)
+#endif
+
+/* amount of time to wait after downloading preI2C patch before downloading
+ * LPM/FPM patch */
+#ifndef NFC_HAL_PRM_POST_I2C_FIX_DELAY
+#define NFC_HAL_PRM_POST_I2C_FIX_DELAY (200)
+#endif
+
+/* NFCC will respond to more than one technology during listen discovery  */
+#ifndef NFC_HAL_DM_MULTI_TECH_RESP
+#define NFC_HAL_DM_MULTI_TECH_RESP true
+#endif
+
+/* Data rate for 15693 command/response, it must be same as
+ * RW_I93_FLAG_DATA_RATE in nfc_target.h */
+#define NFC_HAL_I93_FLAG_DATA_RATE_LOW 0x00
+#define NFC_HAL_I93_FLAG_DATA_RATE_HIGH 0x02
+
+#ifndef NFC_HAL_I93_FLAG_DATA_RATE
+#define NFC_HAL_I93_FLAG_DATA_RATE NFC_HAL_I93_FLAG_DATA_RATE_HIGH
+#endif
+
+/* NFC HAL HCI */
+#ifndef NFC_HAL_HCI_INCLUDED
+#define NFC_HAL_HCI_INCLUDED true
+#endif
+
+/* Quick Timer */
+#ifndef QUICK_TIMER_TICKS_PER_SEC
+#define QUICK_TIMER_TICKS_PER_SEC 100 /* 10ms timer */
+#endif
+
+#ifndef NFC_HAL_SHARED_TRANSPORT_ENABLED
+#define NFC_HAL_SHARED_TRANSPORT_ENABLED false
+#endif
+
+/* Enable verbose tracing by default */
+#ifndef NFC_HAL_TRACE_VERBOSE
+#define NFC_HAL_TRACE_VERBOSE true
+#endif
+
+#ifndef NFC_HAL_INITIAL_TRACE_LEVEL
+#define NFC_HAL_INITIAL_TRACE_LEVEL 5
+#endif
+
+/* Map NFC serial port to USERIAL_PORT_6 by default */
+#ifndef USERIAL_NFC_PORT
+#define USERIAL_NFC_PORT (USERIAL_PORT_6)
+#endif
+
+/* Restore NFCC baud rate to default on shutdown if baud rate was updated */
+#ifndef NFC_HAL_RESTORE_BAUD_ON_SHUTDOWN
+#define NFC_HAL_RESTORE_BAUD_ON_SHUTDOWN true
+#endif
+
+/* Enable protocol tracing by default */
+#ifndef NFC_HAL_TRACE_PROTOCOL
+#define NFC_HAL_TRACE_PROTOCOL true
+#endif
+
+/* Legacy protocol-trace-enable macro */
+#ifndef BT_TRACE_PROTOCOL
+#define BT_TRACE_PROTOCOL (NFC_HAL_TRACE_PROTOCOL)
+#endif
+
+/* Enable HAL tracing by default */
+#ifndef NFC_HAL_USE_TRACES
+#define NFC_HAL_USE_TRACES true
+#endif
+
+/* HAL trace macros */
+#if (NFC_HAL_USE_TRACES == true)
+#define NCI_TRACE_0(l, t, m) \
+  LogMsg((TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t)), (m))
+#define NCI_TRACE_1(l, t, m, p1) \
+  LogMsg(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t), (m), (uintptr_t)(p1))
+#define NCI_TRACE_2(l, t, m, p1, p2)                            \
+  LogMsg(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t), (m), \
+         (uintptr_t)(p1), (uintptr_t)(p2))
+#define NCI_TRACE_3(l, t, m, p1, p2, p3)                        \
+  LogMsg(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t), (m), \
+         (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3))
+#define NCI_TRACE_4(l, t, m, p1, p2, p3, p4)                    \
+  LogMsg(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t), (m), \
+         (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3), (uintptr_t)(p4))
+#define NCI_TRACE_5(l, t, m, p1, p2, p3, p4, p5)                             \
+  LogMsg(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t), (m),              \
+         (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3), (uintptr_t)(p4), \
+         (uintptr_t)(p5))
+#define NCI_TRACE_6(l, t, m, p1, p2, p3, p4, p5, p6)                         \
+  LogMsg(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t), (m),              \
+         (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3), (uintptr_t)(p4), \
+         (uintptr_t)(p5), (uintptr_t)(p6))
+
+#define HAL_TRACE_ERROR0(m)                              \
+  {                                                      \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_ERROR)  \
+      NCI_TRACE_0(TRACE_LAYER_HAL, TRACE_TYPE_ERROR, m); \
+  }
+#define HAL_TRACE_ERROR1(m, p1)                              \
+  {                                                          \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_ERROR)      \
+      NCI_TRACE_1(TRACE_LAYER_HAL, TRACE_TYPE_ERROR, m, p1); \
+  }
+#define HAL_TRACE_ERROR2(m, p1, p2)                              \
+  {                                                              \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_ERROR)          \
+      NCI_TRACE_2(TRACE_LAYER_HAL, TRACE_TYPE_ERROR, m, p1, p2); \
+  }
+#define HAL_TRACE_ERROR3(m, p1, p2, p3)                              \
+  {                                                                  \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_ERROR)              \
+      NCI_TRACE_3(TRACE_LAYER_HAL, TRACE_TYPE_ERROR, m, p1, p2, p3); \
+  }
+#define HAL_TRACE_ERROR4(m, p1, p2, p3, p4)                              \
+  {                                                                      \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                  \
+      NCI_TRACE_4(TRACE_LAYER_HAL, TRACE_TYPE_ERROR, m, p1, p2, p3, p4); \
+  }
+#define HAL_TRACE_ERROR5(m, p1, p2, p3, p4, p5)                              \
+  {                                                                          \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                      \
+      NCI_TRACE_5(TRACE_LAYER_HAL, TRACE_TYPE_ERROR, m, p1, p2, p3, p4, p5); \
+  }
+#define HAL_TRACE_ERROR6(m, p1, p2, p3, p4, p5, p6)                         \
+  {                                                                         \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                     \
+      NCI_TRACE_6(TRACE_LAYER_HAL, TRACE_TYPE_ERROR, m, p1, p2, p3, p4, p5, \
+                  p6);                                                      \
+  }
+
+#define HAL_TRACE_WARNING0(m)                              \
+  {                                                        \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_WARNING)  \
+      NCI_TRACE_0(TRACE_LAYER_HAL, TRACE_TYPE_WARNING, m); \
+  }
+#define HAL_TRACE_WARNING1(m, p1)                              \
+  {                                                            \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_WARNING)      \
+      NCI_TRACE_1(TRACE_LAYER_HAL, TRACE_TYPE_WARNING, m, p1); \
+  }
+#define HAL_TRACE_WARNING2(m, p1, p2)                              \
+  {                                                                \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_WARNING)          \
+      NCI_TRACE_2(TRACE_LAYER_HAL, TRACE_TYPE_WARNING, m, p1, p2); \
+  }
+#define HAL_TRACE_WARNING3(m, p1, p2, p3)                              \
+  {                                                                    \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_WARNING)              \
+      NCI_TRACE_3(TRACE_LAYER_HAL, TRACE_TYPE_WARNING, m, p1, p2, p3); \
+  }
+#define HAL_TRACE_WARNING4(m, p1, p2, p3, p4)                              \
+  {                                                                        \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                  \
+      NCI_TRACE_4(TRACE_LAYER_HAL, TRACE_TYPE_WARNING, m, p1, p2, p3, p4); \
+  }
+#define HAL_TRACE_WARNING5(m, p1, p2, p3, p4, p5)                              \
+  {                                                                            \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                      \
+      NCI_TRACE_5(TRACE_LAYER_HAL, TRACE_TYPE_WARNING, m, p1, p2, p3, p4, p5); \
+  }
+#define HAL_TRACE_WARNING6(m, p1, p2, p3, p4, p5, p6)                         \
+  {                                                                           \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                     \
+      NCI_TRACE_6(TRACE_LAYER_HAL, TRACE_TYPE_WARNING, m, p1, p2, p3, p4, p5, \
+                  p6);                                                        \
+  }
+
+#define HAL_TRACE_API0(m)                              \
+  {                                                    \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_API)  \
+      NCI_TRACE_0(TRACE_LAYER_HAL, TRACE_TYPE_API, m); \
+  }
+#define HAL_TRACE_API1(m, p1)                              \
+  {                                                        \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_API)      \
+      NCI_TRACE_1(TRACE_LAYER_HAL, TRACE_TYPE_API, m, p1); \
+  }
+#define HAL_TRACE_API2(m, p1, p2)                              \
+  {                                                            \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_API)          \
+      NCI_TRACE_2(TRACE_LAYER_HAL, TRACE_TYPE_API, m, p1, p2); \
+  }
+#define HAL_TRACE_API3(m, p1, p2, p3)                              \
+  {                                                                \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_API)              \
+      NCI_TRACE_3(TRACE_LAYER_HAL, TRACE_TYPE_API, m, p1, p2, p3); \
+  }
+#define HAL_TRACE_API4(m, p1, p2, p3, p4)                              \
+  {                                                                    \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_API)                  \
+      NCI_TRACE_4(TRACE_LAYER_HAL, TRACE_TYPE_API, m, p1, p2, p3, p4); \
+  }
+#define HAL_TRACE_API5(m, p1, p2, p3, p4, p5)                              \
+  {                                                                        \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_API)                      \
+      NCI_TRACE_5(TRACE_LAYER_HAL, TRACE_TYPE_API, m, p1, p2, p3, p4, p5); \
+  }
+#define HAL_TRACE_API6(m, p1, p2, p3, p4, p5, p6)                              \
+  {                                                                            \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_API)                          \
+      NCI_TRACE_6(TRACE_LAYER_HAL, TRACE_TYPE_API, m, p1, p2, p3, p4, p5, p6); \
+  }
+
+#define HAL_TRACE_EVENT0(m)                              \
+  {                                                      \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_EVENT)  \
+      NCI_TRACE_0(TRACE_LAYER_HAL, TRACE_TYPE_EVENT, m); \
+  }
+#define HAL_TRACE_EVENT1(m, p1)                              \
+  {                                                          \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_EVENT)      \
+      NCI_TRACE_1(TRACE_LAYER_HAL, TRACE_TYPE_EVENT, m, p1); \
+  }
+#define HAL_TRACE_EVENT2(m, p1, p2)                              \
+  {                                                              \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_EVENT)          \
+      NCI_TRACE_2(TRACE_LAYER_HAL, TRACE_TYPE_EVENT, m, p1, p2); \
+  }
+#define HAL_TRACE_EVENT3(m, p1, p2, p3)                              \
+  {                                                                  \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_EVENT)              \
+      NCI_TRACE_3(TRACE_LAYER_HAL, TRACE_TYPE_EVENT, m, p1, p2, p3); \
+  }
+#define HAL_TRACE_EVENT4(m, p1, p2, p3, p4)                              \
+  {                                                                      \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                  \
+      NCI_TRACE_4(TRACE_LAYER_HAL, TRACE_TYPE_EVENT, m, p1, p2, p3, p4); \
+  }
+#define HAL_TRACE_EVENT5(m, p1, p2, p3, p4, p5)                              \
+  {                                                                          \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                      \
+      NCI_TRACE_5(TRACE_LAYER_HAL, TRACE_TYPE_EVENT, m, p1, p2, p3, p4, p5); \
+  }
+#define HAL_TRACE_EVENT6(m, p1, p2, p3, p4, p5, p6)                         \
+  {                                                                         \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                     \
+      NCI_TRACE_6(TRACE_LAYER_HAL, TRACE_TYPE_EVENT, m, p1, p2, p3, p4, p5, \
+                  p6);                                                      \
+  }
+
+#define HAL_TRACE_DEBUG0(m)                              \
+  {                                                      \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)  \
+      NCI_TRACE_0(TRACE_LAYER_HAL, TRACE_TYPE_DEBUG, m); \
+  }
+#define HAL_TRACE_DEBUG1(m, p1)                              \
+  {                                                          \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)      \
+      NCI_TRACE_1(TRACE_LAYER_HAL, TRACE_TYPE_DEBUG, m, p1); \
+  }
+#define HAL_TRACE_DEBUG2(m, p1, p2)                              \
+  {                                                              \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)          \
+      NCI_TRACE_2(TRACE_LAYER_HAL, TRACE_TYPE_DEBUG, m, p1, p2); \
+  }
+#define HAL_TRACE_DEBUG3(m, p1, p2, p3)                              \
+  {                                                                  \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)              \
+      NCI_TRACE_3(TRACE_LAYER_HAL, TRACE_TYPE_DEBUG, m, p1, p2, p3); \
+  }
+#define HAL_TRACE_DEBUG4(m, p1, p2, p3, p4)                              \
+  {                                                                      \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                  \
+      NCI_TRACE_4(TRACE_LAYER_HAL, TRACE_TYPE_DEBUG, m, p1, p2, p3, p4); \
+  }
+#define HAL_TRACE_DEBUG5(m, p1, p2, p3, p4, p5)                              \
+  {                                                                          \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                      \
+      NCI_TRACE_5(TRACE_LAYER_HAL, TRACE_TYPE_DEBUG, m, p1, p2, p3, p4, p5); \
+  }
+#define HAL_TRACE_DEBUG6(m, p1, p2, p3, p4, p5, p6)                         \
+  {                                                                         \
+    if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                     \
+      NCI_TRACE_6(TRACE_LAYER_HAL, TRACE_TYPE_DEBUG, m, p1, p2, p3, p4, p5, \
+                  p6);                                                      \
+  }
+
+#else /* Disable HAL tracing */
+
+#define HAL_TRACE_0(l, t, m)
+#define HAL_TRACE_1(l, t, m, p1)
+#define HAL_TRACE_2(l, t, m, p1, p2)
+#define HAL_TRACE_3(l, t, m, p1, p2, p3)
+#define HAL_TRACE_4(l, t, m, p1, p2, p3, p4)
+#define HAL_TRACE_5(l, t, m, p1, p2, p3, p4, p5)
+#define HAL_TRACE_6(l, t, m, p1, p2, p3, p4, p5, p6)
+
+#define HAL_TRACE_ERROR0(m)
+#define HAL_TRACE_ERROR1(m, p1)
+#define HAL_TRACE_ERROR2(m, p1, p2)
+#define HAL_TRACE_ERROR3(m, p1, p2, p3)
+#define HAL_TRACE_ERROR4(m, p1, p2, p3, p4)
+#define HAL_TRACE_ERROR5(m, p1, p2, p3, p4, p5)
+#define HAL_TRACE_ERROR6(m, p1, p2, p3, p4, p5, p6)
+
+#define HAL_TRACE_WARNING0(m)
+#define HAL_TRACE_WARNING1(m, p1)
+#define HAL_TRACE_WARNING2(m, p1, p2)
+#define HAL_TRACE_WARNING3(m, p1, p2, p3)
+#define HAL_TRACE_WARNING4(m, p1, p2, p3, p4)
+#define HAL_TRACE_WARNING5(m, p1, p2, p3, p4, p5)
+#define HAL_TRACE_WARNING6(m, p1, p2, p3, p4, p5, p6)
+
+#define HAL_TRACE_API0(m)
+#define HAL_TRACE_API1(m, p1)
+#define HAL_TRACE_API2(m, p1, p2)
+#define HAL_TRACE_API3(m, p1, p2, p3)
+#define HAL_TRACE_API4(m, p1, p2, p3, p4)
+#define HAL_TRACE_API5(m, p1, p2, p3, p4, p5)
+#define HAL_TRACE_API6(m, p1, p2, p3, p4, p5, p6)
+
+#define HAL_TRACE_EVENT0(m)
+#define HAL_TRACE_EVENT1(m, p1)
+#define HAL_TRACE_EVENT2(m, p1, p2)
+#define HAL_TRACE_EVENT3(m, p1, p2, p3)
+#define HAL_TRACE_EVENT4(m, p1, p2, p3, p4)
+#define HAL_TRACE_EVENT5(m, p1, p2, p3, p4, p5)
+#define HAL_TRACE_EVENT6(m, p1, p2, p3, p4, p5, p6)
+
+#define HAL_TRACE_DEBUG0(m)
+#define HAL_TRACE_DEBUG1(m, p1)
+#define HAL_TRACE_DEBUG2(m, p1, p2)
+#define HAL_TRACE_DEBUG3(m, p1, p2, p3)
+#define HAL_TRACE_DEBUG4(m, p1, p2, p3, p4)
+#define HAL_TRACE_DEBUG5(m, p1, p2, p3, p4, p5)
+#define HAL_TRACE_DEBUG6(m, p1, p2, p3, p4, p5, p6)
+#endif /* Disable HAL tracing */
+
+#endif /* GKI_TARGET_H */
diff --git a/src/hal/include/nfc_types.h b/src/hal/include/nfc_types.h
new file mode 100644
index 0000000..acd9126
--- /dev/null
+++ b/src/hal/include/nfc_types.h
@@ -0,0 +1,351 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#ifndef NFC_TYPES_H
+#define NFC_TYPES_H
+#include "Nxp_Features.h"
+/****************************************************************************
+** NFC_HDR header definition for NFC messages
+*****************************************************************************/
+typedef struct {
+  uint16_t event;
+  uint16_t len;
+  uint16_t offset;
+  uint16_t layer_specific;
+} NFC_HDR;
+#define NFC_HDR_SIZE (sizeof(NFC_HDR))
+
+/* Mask for NFC_HDR event field */
+#define NFC_EVT_MASK 0xFF00
+#define NFC_SUB_EVT_MASK 0x00FF
+
+/****************************************************************************
+** NFC_HAL_TASK  definitions
+*****************************************************************************/
+
+/* NFC_HAL_TASK event messages */
+/* NCI message for sending to NFCC          */
+#define NFC_HAL_EVT_TO_NFC_NCI 0x0100
+/* Request to start NCIT quick timer        */
+#define NFC_HAL_EVT_POST_CORE_RESET 0x0200
+/* Request to start chip-specific config    */
+#define NFC_HAL_EVT_TO_START_QUICK_TIMER 0x0300
+/* NCI message for hci persistency data     */
+#define NFC_HAL_EVT_HCI 0x0400
+/* NCI message to issue prediscover config  */
+#define NFC_HAL_EVT_PRE_DISCOVER 0x0500
+/* permission to send commands queued in HAL*/
+#define NFC_HAL_EVT_CONTROL_GRANTED 0x0600
+
+/* NFC_HAL_TASK sub event messages */
+#define NFC_HAL_HCI_RSP_NV_READ_EVT (0x01 | NFC_HAL_EVT_HCI)
+#define NFC_HAL_HCI_RSP_NV_WRITE_EVT (0x02 | NFC_HAL_EVT_HCI)
+#define NFC_HAL_HCI_VSC_TIMEOUT_EVT (0x03 | NFC_HAL_EVT_HCI)
+
+/* Event masks for NFC_TASK messages */
+/* NCI message for sending to host stack    */
+#define NFC_EVT_TO_NFC_NCI 0x4000
+/* Error notification to NFC Task           */
+#define NFC_EVT_TO_NFC_ERR 0x4100
+/* Messages between NFC and NCI task        */
+#define NFC_EVT_TO_NFC_MSGS 0x4200
+
+/*****************************************************************************
+** Macros to get and put bytes to and from a stream (Little Endian format).
+*****************************************************************************/
+
+#define UINT32_TO_STREAM(p, u32)     \
+  {                                  \
+    *(p)++ = (uint8_t)(u32);         \
+    *(p)++ = (uint8_t)((u32) >> 8);  \
+    *(p)++ = (uint8_t)((u32) >> 16); \
+    *(p)++ = (uint8_t)((u32) >> 24); \
+  }
+#define UINT24_TO_STREAM(p, u24)     \
+  {                                  \
+    *(p)++ = (uint8_t)(u24);         \
+    *(p)++ = (uint8_t)((u24) >> 8);  \
+    *(p)++ = (uint8_t)((u24) >> 16); \
+  }
+#define UINT16_TO_STREAM(p, u16)    \
+  {                                 \
+    *(p)++ = (uint8_t)(u16);        \
+    *(p)++ = (uint8_t)((u16) >> 8); \
+  }
+#define UINT8_TO_STREAM(p, u8) \
+  { *(p)++ = (uint8_t)(u8); }
+#define INT8_TO_STREAM(p, u8) \
+  { *(p)++ = (int8_t)(u8); }
+#define ARRAY32_TO_STREAM(p, a)                                   \
+  {                                                               \
+    register int ijk;                                             \
+    for (ijk = 0; ijk < 32; ijk++) *(p)++ = (uint8_t)a[31 - ijk]; \
+  }
+#define ARRAY16_TO_STREAM(p, a)                                   \
+  {                                                               \
+    register int ijk;                                             \
+    for (ijk = 0; ijk < 16; ijk++) *(p)++ = (uint8_t)a[15 - ijk]; \
+  }
+#define ARRAY8_TO_STREAM(p, a)                                  \
+  {                                                             \
+    register int ijk;                                           \
+    for (ijk = 0; ijk < 8; ijk++) *(p)++ = (uint8_t)a[7 - ijk]; \
+  }
+#define BDADDR_TO_STREAM(p, a)                    \
+  {                                               \
+    register int ijk;                             \
+    for (ijk = 0; ijk < BD_ADDR_LEN; ijk++)       \
+      *(p)++ = (uint8_t)a[BD_ADDR_LEN - 1 - ijk]; \
+  }
+#define LAP_TO_STREAM(p, a)                   \
+  {                                           \
+    register int ijk;                         \
+    for (ijk = 0; ijk < LAP_LEN; ijk++)       \
+      *(p)++ = (uint8_t)a[LAP_LEN - 1 - ijk]; \
+  }
+#define DEVCLASS_TO_STREAM(p, a)                    \
+  {                                                 \
+    register int ijk;                               \
+    for (ijk = 0; ijk < DEV_CLASS_LEN; ijk++)       \
+      *(p)++ = (uint8_t)a[DEV_CLASS_LEN - 1 - ijk]; \
+  }
+#define ARRAY_TO_STREAM(p, a, len)                            \
+  {                                                           \
+    register int ijk;                                         \
+    for (ijk = 0; ijk < len; ijk++) *(p)++ = (uint8_t)a[ijk]; \
+  }
+#define REVERSE_ARRAY_TO_STREAM(p, a, len)                              \
+  {                                                                     \
+    register int ijk;                                                   \
+    for (ijk = 0; ijk < len; ijk++) *(p)++ = (uint8_t)a[len - 1 - ijk]; \
+  }
+
+#define STREAM_TO_UINT8(u8, p) \
+  {                            \
+    u8 = (uint8_t)(*(p));      \
+    (p) += 1;                  \
+  }
+#define STREAM_TO_UINT16(u16, p)                                \
+  {                                                             \
+    u16 = ((uint16_t)(*(p)) + (((uint16_t)(*((p) + 1))) << 8)); \
+    (p) += 2;                                                   \
+  }
+#define STREAM_TO_UINT24(u32, p)                                    \
+  {                                                                 \
+    u32 = (((uint32_t)(*(p))) + ((((uint32_t)(*((p) + 1)))) << 8) + \
+           ((((uint32_t)(*((p) + 2)))) << 16));                     \
+    (p) += 3;                                                       \
+  }
+#define STREAM_TO_UINT32(u32, p)                                    \
+  {                                                                 \
+    u32 = (((uint32_t)(*(p))) + ((((uint32_t)(*((p) + 1)))) << 8) + \
+           ((((uint32_t)(*((p) + 2)))) << 16) +                     \
+           ((((uint32_t)(*((p) + 3)))) << 24));                     \
+    (p) += 4;                                                       \
+  }
+#define STREAM_TO_BDADDR(a, p)                              \
+  {                                                         \
+    register int ijk;                                       \
+    register uint8_t* pbda = (uint8_t*)a + BD_ADDR_LEN - 1; \
+    for (ijk = 0; ijk < BD_ADDR_LEN; ijk++) *pbda-- = *p++; \
+  }
+#define STREAM_TO_ARRAY32(a, p)                   \
+  {                                               \
+    register int ijk;                             \
+    register uint8_t* _pa = (uint8_t*)a + 31;     \
+    for (ijk = 0; ijk < 32; ijk++) *_pa-- = *p++; \
+  }
+#define STREAM_TO_ARRAY16(a, p)                   \
+  {                                               \
+    register int ijk;                             \
+    register uint8_t* _pa = (uint8_t*)a + 15;     \
+    for (ijk = 0; ijk < 16; ijk++) *_pa-- = *p++; \
+  }
+#define STREAM_TO_ARRAY8(a, p)                   \
+  {                                              \
+    register int ijk;                            \
+    register uint8_t* _pa = (uint8_t*)a + 7;     \
+    for (ijk = 0; ijk < 8; ijk++) *_pa-- = *p++; \
+  }
+#define STREAM_TO_DEVCLASS(a, p)                             \
+  {                                                          \
+    register int ijk;                                        \
+    register uint8_t* _pa = (uint8_t*)a + DEV_CLASS_LEN - 1; \
+    for (ijk = 0; ijk < DEV_CLASS_LEN; ijk++) *_pa-- = *p++; \
+  }
+#define STREAM_TO_LAP(a, p)                             \
+  {                                                     \
+    register int ijk;                                   \
+    register uint8_t* plap = (uint8_t*)a + LAP_LEN - 1; \
+    for (ijk = 0; ijk < LAP_LEN; ijk++) *plap-- = *p++; \
+  }
+#define STREAM_TO_ARRAY(a, p, len)                             \
+  {                                                            \
+    register int ijk;                                          \
+    for (ijk = 0; ijk < len; ijk++) ((uint8_t*)a)[ijk] = *p++; \
+  }
+#define REVERSE_STREAM_TO_ARRAY(a, p, len)         \
+  {                                                \
+    register int ijk;                              \
+    register uint8_t* _pa = (uint8_t*)a + len - 1; \
+    for (ijk = 0; ijk < len; ijk++) *_pa-- = *p++; \
+  }
+
+/*****************************************************************************
+** Macros to get and put bytes to and from a field (Little Endian format).
+** These are the same as to stream, except the pointer is not incremented.
+*****************************************************************************/
+
+#define UINT32_TO_FIELD(p, u32)                    \
+  {                                                \
+    *(uint8_t*)(p) = (uint8_t)(u32);               \
+    *((uint8_t*)(p) + 1) = (uint8_t)((u32) >> 8);  \
+    *((uint8_t*)(p) + 2) = (uint8_t)((u32) >> 16); \
+    *((uint8_t*)(p) + 3) = (uint8_t)((u32) >> 24); \
+  }
+#define UINT24_TO_FIELD(p, u24)                    \
+  {                                                \
+    *(uint8_t*)(p) = (uint8_t)(u24);               \
+    *((uint8_t*)(p) + 1) = (uint8_t)((u24) >> 8);  \
+    *((uint8_t*)(p) + 2) = (uint8_t)((u24) >> 16); \
+  }
+#define UINT16_TO_FIELD(p, u16)                   \
+  {                                               \
+    *(uint8_t*)(p) = (uint8_t)(u16);              \
+    *((uint8_t*)(p) + 1) = (uint8_t)((u16) >> 8); \
+  }
+#define UINT8_TO_FIELD(p, u8) \
+  { *(uint8_t*)(p) = (uint8_t)(u8); }
+
+/*****************************************************************************
+** Macros to get and put bytes to and from a stream (Big Endian format)
+*****************************************************************************/
+
+#define UINT32_TO_BE_STREAM(p, u32)  \
+  {                                  \
+    *(p)++ = (uint8_t)((u32) >> 24); \
+    *(p)++ = (uint8_t)((u32) >> 16); \
+    *(p)++ = (uint8_t)((u32) >> 8);  \
+    *(p)++ = (uint8_t)(u32);         \
+  }
+#define UINT24_TO_BE_STREAM(p, u24)  \
+  {                                  \
+    *(p)++ = (uint8_t)((u24) >> 16); \
+    *(p)++ = (uint8_t)((u24) >> 8);  \
+    *(p)++ = (uint8_t)(u24);         \
+  }
+#define UINT16_TO_BE_STREAM(p, u16) \
+  {                                 \
+    *(p)++ = (uint8_t)((u16) >> 8); \
+    *(p)++ = (uint8_t)(u16);        \
+  }
+#define UINT8_TO_BE_STREAM(p, u8) \
+  { *(p)++ = (uint8_t)(u8); }
+#define ARRAY_TO_BE_STREAM(p, a, len)                         \
+  {                                                           \
+    register int ijk;                                         \
+    for (ijk = 0; ijk < len; ijk++) *(p)++ = (uint8_t)a[ijk]; \
+  }
+
+#define BE_STREAM_TO_UINT8(u8, p) \
+  {                               \
+    u8 = (uint8_t)(*(p));         \
+    (p) += 1;                     \
+  }
+#define BE_STREAM_TO_UINT16(u16, p)                                     \
+  {                                                                     \
+    u16 = (uint16_t)(((uint16_t)(*(p)) << 8) + (uint16_t)(*((p) + 1))); \
+    (p) += 2;                                                           \
+  }
+#define BE_STREAM_TO_UINT24(u32, p)                                   \
+  {                                                                   \
+    u32 = (((uint32_t)(*((p) + 2))) + ((uint32_t)(*((p) + 1)) << 8) + \
+           ((uint32_t)(*(p)) << 16));                                 \
+    (p) += 3;                                                         \
+  }
+#define BE_STREAM_TO_UINT32(u32, p)                                    \
+  {                                                                    \
+    u32 = ((uint32_t)(*((p) + 3)) + ((uint32_t)(*((p) + 2)) << 8) +    \
+           ((uint32_t)(*((p) + 1)) << 16) + ((uint32_t)(*(p)) << 24)); \
+    (p) += 4;                                                          \
+  }
+#define BE_STREAM_TO_ARRAY(p, a, len)                          \
+  {                                                            \
+    register int ijk;                                          \
+    for (ijk = 0; ijk < len; ijk++) ((uint8_t*)a)[ijk] = *p++; \
+  }
+
+/*****************************************************************************
+** Macros to get and put bytes to and from a field (Big Endian format).
+** These are the same as to stream, except the pointer is not incremented.
+*****************************************************************************/
+
+#define UINT32_TO_BE_FIELD(p, u32)                 \
+  {                                                \
+    *(uint8_t*)(p) = (uint8_t)((u32) >> 24);       \
+    *((uint8_t*)(p) + 1) = (uint8_t)((u32) >> 16); \
+    *((uint8_t*)(p) + 2) = (uint8_t)((u32) >> 8);  \
+    *((uint8_t*)(p) + 3) = (uint8_t)(u32);         \
+  }
+#define UINT24_TO_BE_FIELD(p, u24)                \
+  {                                               \
+    *(uint8_t*)(p) = (uint8_t)((u24) >> 16);      \
+    *((uint8_t*)(p) + 1) = (uint8_t)((u24) >> 8); \
+    *((uint8_t*)(p) + 2) = (uint8_t)(u24);        \
+  }
+#define UINT16_TO_BE_FIELD(p, u16)          \
+  {                                         \
+    *(uint8_t*)(p) = (uint8_t)((u16) >> 8); \
+    *((uint8_t*)(p) + 1) = (uint8_t)(u16);  \
+  }
+#define UINT8_TO_BE_FIELD(p, u8) \
+  { *(uint8_t*)(p) = (uint8_t)(u8); }
+
+/*****************************************************************************
+** Define trace levels
+*****************************************************************************/
+
+/* No trace messages to be generated    */
+#define BT_TRACE_LEVEL_NONE 0
+/* Error condition trace messages       */
+#define BT_TRACE_LEVEL_ERROR 1
+/* Warning condition trace messages     */
+#define BT_TRACE_LEVEL_WARNING 2
+/* API traces                           */
+#define BT_TRACE_LEVEL_API 3
+/* Debug messages for events            */
+#define BT_TRACE_LEVEL_EVENT 4
+/* Full debug messages                  */
+#define BT_TRACE_LEVEL_DEBUG 5
+
+#define TRACE_CTRL_GENERAL 0x00000000
+#define TRACE_LAYER_NCI 0x00280000
+#define TRACE_LAYER_HAL 0x00310000
+#define TRACE_LAYER_GKI 0x001a0000
+#define TRACE_ORG_STACK 0x00000000
+#define TRACE_ORG_GKI 0x00000400
+
+#define TRACE_TYPE_ERROR 0x00000000
+#define TRACE_TYPE_WARNING 0x00000001
+#define TRACE_TYPE_API 0x00000002
+#define TRACE_TYPE_EVENT 0x00000003
+#define TRACE_TYPE_DEBUG 0x00000004
+
+#define TRACE_TYPE_GENERIC 0x00000008
+
+#endif /* NFC_TYPES_H */
diff --git a/src/hal/int/nfc_brcm_defs.h b/src/hal/int/nfc_brcm_defs.h
new file mode 100644
index 0000000..3a7af18
--- /dev/null
+++ b/src/hal/int/nfc_brcm_defs.h
@@ -0,0 +1,420 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the Broadcom-specific defintions that are shared
+ *  between HAL, nfc stack, adaptation layer and applications.
+ *
+ ******************************************************************************/
+
+#ifndef NFC_BRCM_DEFS_H
+#define NFC_BRCM_DEFS_H
+
+/*****************************************************************************
+** Broadcom HW ID definitions
+*****************************************************************************/
+#define BRCM_20791B3_ID 0x20791b03
+#define BRCM_20791B4_ID 0x20791b04
+#define BRCM_20791B5_ID 0x20791b05
+#define BRCM_43341B0_ID 0x43341b00
+#define BRCM_20795T1_ID 0x20795a01
+#define BRCM_20795A0_ID 0x20795a00
+#define BRCM_20795A1_ID 0x20795a10
+
+#define BRCM_NFC_GEN_MASK 0xFFFFF000 /* HW generation mask */
+#define BRCM_NFC_REV_MASK 0x00000FFF /* HW revision mask   */
+#define BRCM_NFC_20791_GEN 0x20791000
+#define BRCM_NFC_20791_GEN_MAX_EE 3 /* HCI access and 2 UICCs */
+#define BRCM_NFC_43341_GEN 0x43341000
+#define BRCM_NFC_43341_GEN_MAX_EE 3 /* HCI access and 2 UICCs */
+#define BRCM_NFC_20795_GEN 0x20795000
+#define BRCM_NFC_20795_GEN_MAX_EE 4 /* HCI access and 3 UICCs */
+
+/*****************************************************************************
+** Broadcom-specific NCI definitions
+*****************************************************************************/
+
+/**********************************************
+ * NCI Message Proprietary  Group       - F
+ **********************************************/
+#define NCI_MSG_TAG_SET_MEM 0x00
+#define NCI_MSG_TAG_GET_MEM 0x01
+#define NCI_MSG_T1T_SET_HR 0x02
+#define NCI_MSG_SET_CLF_REGISTERS 0x03
+#define NCI_MSG_GET_BUILD_INFO 0x04
+#define NCI_MSG_HCI_NETWK 0x05
+#define NCI_MSG_SET_FWFSM 0x06
+#define NCI_MSG_SET_UICCRDRF 0x07
+#define NCI_MSG_POWER_LEVEL 0x08
+#define NCI_MSG_FRAME_LOG 0x09
+#define NCI_MSG_UICC_READER_ACTION 0x0A
+#define NCI_MSG_SET_PPSE_RESPONSE 0x0B
+#define NCI_MSG_PRBS_SET 0x0C
+/* reset HCI network/close all pipes (S,D) register */
+#define NCI_MSG_RESET_ALL_UICC_CFG 0x0D
+#define NCI_MSG_GET_NFCEE_INFO 0x0E
+#define NCI_MSG_DISABLE_INIT_CHECK 0x0F
+#define NCI_MSG_ANTENNA_SELF_TEST 0x10
+#define NCI_MSG_SET_MAX_PKT_SIZE 0x11
+#define NCI_MSG_NCIP_CLK_REQ_OR_CAR_DET 0x12
+#define NCI_MSG_NCIP_CONFIG_DBUART 0x13
+#define NCI_MSG_NCIP_ENABLE_DVT_DRIVER 0x14
+#define NCI_MSG_SET_ASWP 0x15
+#define NCI_MSG_ENCAPSULATE_NCI 0x16
+#define NCI_MSG_CONFIGURE_ARM_JTAG 0x17
+#define NCI_MSG_STATISTICS 0x18
+#define NCI_MSG_SET_DSP_TABLE 0x19
+#define NCI_MSG_GET_DSP_TABLE 0x1a
+#define NCI_MSG_READY_RX_CMD 0x1b
+#define NCI_MSG_GET_VBAT 0x1c
+#define NCI_MSG_GET_XTAL_INDEX_FROM_DH 0x1d
+#define NCI_MSG_SWP_LOG 0x1e
+#define NCI_MSG_GET_PWRLEVEL 0x1f
+#define NCI_MSG_SET_VBAT_MONITOR 0x20
+#define NCI_MSG_SET_TINT_MODE 0x21
+#define NCI_MSG_ACCESS_APP 0x22
+#define NCI_MSG_SET_SECURE_MODE 0x23
+#define NCI_MSG_GET_NV_DEVICE 0x24
+#define NCI_MSG_LPTD 0x25
+#define NCI_MSG_SET_CE4_AS_SNOOZE 0x26
+#define NCI_MSG_NFCC_SEND_HCI 0x27
+#define NCI_MSG_CE4_PATCH_DOWNLOAD_DONE 0x28
+#define NCI_MSG_EEPROM_RW 0x29
+#define NCI_MSG_GET_CLF_REGISTERS 0x2A
+#define NCI_MSG_RF_TEST 0x2B
+#define NCI_MSG_DEBUG_PRINT 0x2C
+#define NCI_MSG_GET_PATCH_VERSION 0x2D
+#define NCI_MSG_SECURE_PATCH_DOWNLOAD 0x2E
+#define NCI_MSG_SPD_FORMAT_NVM 0x2F
+#define NCI_MSG_SPD_READ_NVM 0x30
+#define NCI_MSG_SWP_BIST 0x31
+#define NCI_MSG_WLESS_DBG_MODE 0x32
+#define NCI_MSG_I2C_REQ_POLARITY 0x33
+#define NCI_MSG_AID_FILTER 0x39
+
+/**********************************************
+ * Proprietary  NCI status codes
+ **********************************************/
+#define NCI_STATUS_SPD_ERROR_ORDER 0xE0
+#define NCI_STATUS_SPD_ERROR_DEST 0xE1
+#define NCI_STATUS_SPD_ERROR_PROJECTID 0xE2
+#define NCI_STATUS_SPD_ERROR_CHIPVER 0xE3
+#define NCI_STATUS_SPD_ERROR_MAJORVER 0xE4
+#define NCI_STATUS_SPD_ERROR_INVALID_PARAM 0xE5
+#define NCI_STATUS_SPD_ERROR_INVALID_SIG 0xE6
+#define NCI_STATUS_SPD_ERROR_NVM_CORRUPTED 0xE7
+#define NCI_STATUS_SPD_ERROR_PWR_MODE 0xE8
+#define NCI_STATUS_SPD_ERROR_MSG_LEN 0xE9
+#define NCI_STATUS_SPD_ERROR_PATCHSIZE 0xEA
+
+#define NCI_NV_DEVICE_NONE 0x00
+#define NCI_NV_DEVICE_EEPROM 0x08
+#define NCI_NV_DEVICE_UICC1 0x10
+
+/* The events reported on tNFC_VS_CBACK */
+/* The event is (NCI_NTF_BIT|oid) or (NCI_RSP_BIT|oid) */
+#define NFC_VS_HCI_NETWK_EVT (NCI_NTF_BIT | NCI_MSG_HCI_NETWK)
+#define NFC_VS_HCI_NETWK_RSP (NCI_RSP_BIT | NCI_MSG_HCI_NETWK)
+#define NFC_VS_UICC_READER_ACTION_EVT (NCI_NTF_BIT | NCI_MSG_UICC_READER_ACTION)
+#define NFC_VS_POWER_LEVEL_RSP (NCI_RSP_BIT | NCI_MSG_POWER_LEVEL)
+#define NFC_VS_GET_NV_DEVICE_EVT (NCI_RSP_BIT | NCI_MSG_GET_NV_DEVICE)
+#define NFC_VS_LPTD_EVT (NCI_NTF_BIT | NCI_MSG_LPTD)
+#define NFC_VS_GET_BUILD_INFO_EVT (NCI_RSP_BIT | NCI_MSG_GET_BUILD_INFO)
+#define NFC_VS_GET_PATCH_VERSION_EVT (NCI_RSP_BIT | NCI_MSG_GET_PATCH_VERSION)
+#define NFC_VS_SEC_PATCH_DOWNLOAD_EVT \
+  (NCI_RSP_BIT | NCI_MSG_SECURE_PATCH_DOWNLOAD)
+#define NFC_VS_SEC_PATCH_AUTH_EVT (NCI_NTF_BIT | NCI_MSG_SECURE_PATCH_DOWNLOAD)
+#define NFC_VS_EEPROM_RW_EVT (NCI_RSP_BIT | NCI_MSG_EEPROM_RW)
+
+#define NCI_GET_PATCH_VERSION_NVM_OFFSET 37
+
+/* Static and dynamic pipe id and status for each pipe to uicc0 and uicc1. */
+#define NCI_NFCC_PIPE_INFO_NV_SIZE 24
+#define NCI_PERSONALITY_SLOT_SIZE 19
+#define NCI_DYNAMIC_PIPE_SIZE 8
+
+/* Type of TLV in NCI_MSG_HCI_NETWK */
+#define NCI_SWP_INTERFACE_TYPE 0xFF
+/* Type of TLV in NCI_MSG_HCI_NETWK */
+#define NCI_HCI_GATE_TYPE 0xFE
+
+/* Secure Patch Download definitions (patch type definitions) */
+#define NCI_SPD_TYPE_HEADER 0x00
+#define NCI_SPD_TYPE_SRAM 0x01
+#define NCI_SPD_TYPE_AON 0x02
+#define NCI_SPD_TYPE_PATCH_TABLE 0x03
+#define NCI_SPD_TYPE_SECURE_CONFIG 0x04
+#define NCI_SPD_TYPE_CONTROLLED_CONFIG 0x05
+#define NCI_SPD_TYPE_SIGNATURE 0x06
+#define NCI_SPD_TYPE_SIGCHEK 0x07
+
+/* Secure Patch Download definitions (NCI_SPD_TYPE_HEADER definitions) */
+#define NCI_SPD_HEADER_OFFSET_CHIPVERLEN 0x18
+#define NCI_SPD_HEADER_CHIPVER_LEN 16
+
+/* NVM Type (in GET_PATCH_VERSION RSP) */
+#define NCI_SPD_NVM_TYPE_NONE 0x00
+#define NCI_SPD_NVM_TYPE_EEPROM 0x01
+#define NCI_SPD_NVM_TYPE_UICC 0x02
+
+/**********************************************
+ * NCI NFCC proprietary features in octet 3
+ **********************************************/
+#define NCI_FEAT_SIGNED_PATCH 0x01000000
+
+/**********************************************
+ * NCI Interface Types
+ **********************************************/
+#define NCI_INTERFACE_VS_MIFARE 0x80
+#define NCI_INTERFACE_VS_CALYPSO_CE 0x81
+#define NCI_INTERFACE_VS_T2T_CE 0x82 /* for Card Emulation side */
+/* for both Reader/Writer and Card Emulation side */
+#define NCI_INTERFACE_VS_15693 0x83
+#define NCI_INTERFACE_VS_T1T_CE 0x84 /* for Card Emulation side */
+
+/**********************************************
+ * NCI Proprietary Parameter IDs
+ **********************************************/
+#define NCI_PARAM_ID_LA_FSDI 0xA0
+#define NCI_PARAM_ID_LB_FSDI 0xA1
+#define NCI_PARAM_ID_HOST_LISTEN_MASK 0xA2
+#define NCI_PARAM_ID_CHIP_TYPE 0xA3 /* NFCDEP */
+#define NCI_PARAM_ID_PA_ANTICOLL 0xA4
+#define NCI_PARAM_ID_CONTINUE_MODE 0xA5
+#define NCI_PARAM_ID_LBP 0xA6
+#define NCI_PARAM_ID_T1T_RDR_ONLY 0xA7
+#define NCI_PARAM_ID_LA_SENS_RES 0xA8
+#define NCI_PARAM_ID_PWR_SETTING_BITMAP 0xA9
+#define NCI_PARAM_ID_WI_NTF_ENABLE 0xAA
+#define NCI_PARAM_ID_LN_BITRATE 0xAB /* NFCDEP Listen Bitrate */
+#define NCI_PARAM_ID_LF_BITRATE 0xAC /* FeliCa */
+#define NCI_PARAM_ID_SWP_BITRATE_MASK 0xAD
+#define NCI_PARAM_ID_KOVIO 0xAE
+#define NCI_PARAM_ID_UICC_NTF_TO 0xAF
+#define NCI_PARAM_ID_NFCDEP 0xB0
+#define NCI_PARAM_ID_CLF_REGS_CFG 0xB1
+#define NCI_PARAM_ID_NFCDEP_TRANS_TIME 0xB2
+#define NCI_PARAM_ID_CREDIT_TIMER 0xB3
+#define NCI_PARAM_ID_CORRUPT_RX 0xB4
+#define NCI_PARAM_ID_ISODEP 0xB5
+#define NCI_PARAM_ID_LF_CONFIG 0xB6
+#define NCI_PARAM_ID_I93_DATARATE 0xB7
+#define NCI_PARAM_ID_CREDITS_THRESHOLD 0xB8
+#define NCI_PARAM_ID_TAGSNIFF_CFG 0xB9
+#define NCI_PARAM_ID_PA_FSDI 0xBA /* ISODEP */
+#define NCI_PARAM_ID_PB_FSDI 0xBB /* ISODEP */
+#define NCI_PARAM_ID_FRAME_INTF_RETXN 0xBC
+
+#define NCI_PARAM_ID_UICC_RDR_PRIORITY 0xBD
+#define NCI_PARAM_ID_GUARD_TIME 0xBE
+#define NCI_PARAM_ID_STDCONFIG 0xBF /* dont not use this config item */
+/* dont not use this config item  */
+#define NCI_PARAM_ID_PROPCFG 0xC0
+#define NCI_PARAM_ID_MAXTRY2ACTIVATE 0xC1
+#define NCI_PARAM_ID_SWPCFG 0xC2
+#define NCI_PARAM_ID_CLF_LPM_CFG 0xC3
+#define NCI_PARAM_ID_DCLB 0xC4
+#define NCI_PARAM_ID_ACT_ORDER 0xC5
+#define NCI_PARAM_ID_DEP_DELAY_ACT 0xC6
+#define NCI_PARAM_ID_DH_PARITY_CRC_CTL 0xC7
+#define NCI_PARAM_ID_PREINIT_DSP_CFG 0xC8
+#define NCI_PARAM_ID_FW_WORKAROUND 0xC9
+#define NCI_PARAM_ID_RFU_CONFIG 0xCA
+#define NCI_PARAM_ID_EMVCO_ENABLE 0xCB
+#define NCI_PARAM_ID_ANTDRIVER_PARAM 0xCC
+#define NCI_PARAM_ID_PLL325_CFG_PARAM 0xCD
+#define NCI_PARAM_ID_OPNLP_ADPLL_ENABLE 0xCE
+#define NCI_PARAM_ID_CONFORMANCE_MODE 0xCF
+
+#define NCI_PARAM_ID_LPO_ON_OFF_ENABLE 0xD0
+#define NCI_PARAM_ID_FORCE_VANT 0xD1
+#define NCI_PARAM_ID_COEX_CONFIG 0xD2
+#define NCI_PARAM_ID_INTEL_MODE 0xD3
+
+#define NCI_PARAM_ID_AID 0xFF
+
+/**********************************************
+ * NCI Parameter ID Lens
+ **********************************************/
+#define NCI_PARAM_LEN_PWR_SETTING_BITMAP 3
+#define NCI_PARAM_LEN_HOST_LISTEN_MASK 2
+#define NCI_PARAM_LEN_PLL325_CFG_PARAM 14
+
+/**********************************************
+ * Snooze Mode
+ **********************************************/
+#define NFC_SNOOZE_MODE_NONE 0x00    /* Snooze mode disabled    */
+#define NFC_SNOOZE_MODE_UART 0x01    /* Snooze mode for UART    */
+#define NFC_SNOOZE_MODE_SPI_I2C 0x08 /* Snooze mode for SPI/I2C */
+
+#define NFC_SNOOZE_ACTIVE_LOW 0x00  /* high to low voltage is asserting */
+#define NFC_SNOOZE_ACTIVE_HIGH 0x01 /* low to high voltage is asserting */
+
+/**********************************************
+ * HCI definitions
+ **********************************************/
+#define NFC_HAL_HCI_SESSION_ID_LEN 8
+#define NFC_HAL_HCI_SYNC_ID_LEN 2
+
+/* HCI Network command definitions */
+#define NFC_HAL_HCI_NETWK_INFO_SIZE 250
+#define NFC_HAL_HCI_NO_RW_MODE_NETWK_INFO_SIZE 184
+#define NFC_HAL_HCI_DH_NETWK_INFO_SIZE 111
+#define NFC_HAL_HCI_MIN_NETWK_INFO_SIZE 12
+#define NFC_HAL_HCI_MIN_DH_NETWK_INFO_SIZE 11
+
+/* Card emulation RF Gate A definitions */
+#define NFC_HAL_HCI_CE_RF_A_UID_REG_LEN 10
+#define NFC_HAL_HCI_CE_RF_A_ATQA_RSP_CODE_LEN 2
+#define NFC_HAL_HCI_CE_RF_A_MAX_HIST_DATA_LEN 15
+#define NFC_HAL_HCI_CE_RF_A_MAX_DATA_RATE_LEN 3
+
+/* Card emulation RF Gate B definitions */
+#define NFC_HAL_HCI_CE_RF_B_PUPI_LEN 4
+#define NFC_HAL_HCI_CE_RF_B_ATQB_LEN 4
+#define NFC_HAL_HCI_CE_RF_B_HIGHER_LAYER_RSP_LEN 61
+#define NFC_HAL_HCI_CE_RF_B_MAX_DATA_RATE_LEN 3
+
+/* Card emulation RF Gate BP definitions */
+#define NFC_HAL_HCI_CE_RF_BP_MAX_PAT_IN_LEN 8
+#define NFC_HAL_HCI_CE_RF_BP_DATA_OUT_LEN 40
+
+/* Reader RF Gate A definitions */
+#define NFC_HAL_HCI_RD_RF_B_HIGHER_LAYER_DATA_LEN 61
+
+/* DH HCI Network command definitions */
+#define NFC_HAL_HCI_DH_MAX_DYN_PIPES 20
+
+/* Target handle for different host in the network */
+#define NFC_HAL_HCI_DH_TARGET_HANDLE 0xF2
+#define NFC_HAL_HCI_UICC0_TARGET_HANDLE 0xF3
+#define NFC_HAL_HCI_UICC1_TARGET_HANDLE 0xF4
+#define NFC_HAL_HCI_UICC2_TARGET_HANDLE 0xF5
+
+/* Card emulation RF Gate A registry information */
+typedef struct {
+  uint8_t pipe_id; /* if MSB is set then valid, 7 bits for Pipe ID */
+  uint8_t mode; /* Type A card emulation enabled indicator, 0x02:enabled    */
+  uint8_t sak;
+  uint8_t uid_reg_len;
+  uint8_t uid_reg[NFC_HAL_HCI_CE_RF_A_UID_REG_LEN];
+  uint8_t atqa[NFC_HAL_HCI_CE_RF_A_ATQA_RSP_CODE_LEN]; /* ATQA response code */
+  uint8_t app_data_len;
+  uint8_t
+      app_data[NFC_HAL_HCI_CE_RF_A_MAX_HIST_DATA_LEN]; /* 15 bytes optional
+                                                          storage for historic
+                                                          data, use 2 slots */
+  uint8_t fwi_sfgi; /* FRAME WAITING TIME, START-UP FRAME GUARD TIME */
+  uint8_t cid_support;
+  uint8_t datarate_max[NFC_HAL_HCI_CE_RF_A_MAX_DATA_RATE_LEN];
+  uint8_t clt_support;
+} tNCI_HCI_CE_RF_A;
+
+/* Card emulation RF Gate B registry information */
+typedef struct {
+  uint8_t pipe_id; /* if MSB is set then valid, 7 bits for Pipe ID */
+  uint8_t mode; /* Type B card emulation enabled indicator, 0x02:enabled    */
+  uint8_t pupi_len;
+  uint8_t pupi_reg[NFC_HAL_HCI_CE_RF_B_PUPI_LEN];
+  uint8_t afi;
+  uint8_t
+      atqb[NFC_HAL_HCI_CE_RF_B_ATQB_LEN]; /* 4 bytes ATQB application data */
+  uint8_t higherlayer_resp
+      [NFC_HAL_HCI_CE_RF_B_HIGHER_LAYER_RSP_LEN]; /* 0~ 61 bytes ATRB_INF use
+                                                     1~4 personality slots */
+  uint8_t datarate_max[NFC_HAL_HCI_CE_RF_B_MAX_DATA_RATE_LEN];
+  uint8_t natrb;
+} tNCI_HCI_CE_RF_B;
+
+/* Card emulation RF Gate BP registry information */
+typedef struct {
+  uint8_t pipe_id; /* if MSB is set then valid, 7 bits for Pipe ID */
+  uint8_t
+      mode; /* Type B prime card emulation enabled indicator, 0x02:enabled */
+  uint8_t pat_in_len;
+  uint8_t pat_in[NFC_HAL_HCI_CE_RF_BP_MAX_PAT_IN_LEN];
+  uint8_t dat_out_len;
+  uint8_t
+      dat_out[NFC_HAL_HCI_CE_RF_BP_DATA_OUT_LEN]; /* ISO7816-3 <=64 byte, and
+                                                     other fields are 9 bytes */
+  uint8_t natr;
+} tNCI_HCI_CE_RF_BP;
+
+/* Card emulation RF Gate F registry information */
+typedef struct {
+  uint8_t pipe_id; /* if MSB is set then valid, 7 bits for Pipe ID */
+  uint8_t mode; /* Type F card emulation enabled indicator, 0x02:enabled    */
+  uint8_t speed_cap;
+  uint8_t clt_support;
+} tNCI_HCI_CE_RF_F;
+
+/* Reader RF Gate A registry information */
+typedef struct {
+  uint8_t pipe_id; /* if MSB is set then valid, 7 bits for Pipe ID */
+  uint8_t datarate_max;
+} tNCI_HCI_RD_RF_A;
+
+/* Reader RF Gate B registry information */
+typedef struct {
+  uint8_t pipe_id; /* if MSB is set then valid, 7 bits for Pipe ID */
+  uint8_t afi;
+  uint8_t hldata_len;
+  uint8_t
+      high_layer_data[NFC_HAL_HCI_RD_RF_B_HIGHER_LAYER_DATA_LEN]; /* INF field
+                                                                     in ATTRIB
+                                                                     command */
+} tNCI_HCI_RD_RF_B;
+
+/* Dynamic pipe information */
+typedef struct {
+  uint8_t source_host;
+  uint8_t dest_host;
+  uint8_t source_gate;
+  uint8_t dest_gate;
+  uint8_t pipe_id; /* if MSB is set then valid, 7 bits for Pipe ID */
+} tNCI_HCI_DYN_PIPE_INFO;
+
+/*************************************************************
+ * HCI Network CMD/NTF structure for UICC host in the network
+ *************************************************************/
+typedef struct {
+  uint8_t target_handle;
+  uint8_t session_id[NFC_HAL_HCI_SESSION_ID_LEN];
+  uint8_t sync_id[NFC_HAL_HCI_SYNC_ID_LEN];
+  uint8_t static_pipe_info;
+  tNCI_HCI_CE_RF_A ce_rf_a;
+  tNCI_HCI_CE_RF_B ce_rf_b;
+  tNCI_HCI_CE_RF_BP ce_rf_bp;
+  tNCI_HCI_CE_RF_F ce_rf_f;
+  tNCI_HCI_RD_RF_A rw_rf_a;
+  tNCI_HCI_RD_RF_B rw_rf_b;
+} tNCI_HCI_NETWK;
+
+/************************************************
+ * HCI Network CMD/NTF structure for Device host
+ ************************************************/
+typedef struct {
+  uint8_t target_handle;
+  uint8_t session_id[NFC_HAL_HCI_SESSION_ID_LEN];
+  uint8_t static_pipe_info;
+  uint8_t num_dyn_pipes;
+  tNCI_HCI_DYN_PIPE_INFO dyn_pipe_info[NFC_HAL_HCI_DH_MAX_DYN_PIPES];
+} tNCI_HCI_NETWK_DH;
+
+#endif /* NFC_BRCM_DEFS_H */
diff --git a/src/hal/int/nfc_hal_int.h b/src/hal/int/nfc_hal_int.h
new file mode 100644
index 0000000..8ad1cc6
--- /dev/null
+++ b/src/hal/int/nfc_hal_int.h
@@ -0,0 +1,538 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  this file contains the NCI transport internal definitions and functions.
+ *
+ ******************************************************************************/
+
+#ifndef NFC_HAL_INT_H
+#define NFC_HAL_INT_H
+
+#include "nfc_hal_target.h"
+#include "gki.h"
+#include "nci_defs.h"
+#include "nfc_brcm_defs.h"
+#include "nfc_hal_api.h"
+#include "nfc_hal_int_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/****************************************************************************
+** NFC HAL TASK transport definitions
+****************************************************************************/
+/* NFC HAL Task event masks */
+#define NFC_HAL_TASK_EVT_DATA_RDY EVENT_MASK(APPL_EVT_0)
+#define NFC_HAL_TASK_EVT_INITIALIZE EVENT_MASK(APPL_EVT_5)
+#define NFC_HAL_TASK_EVT_TERMINATE EVENT_MASK(APPL_EVT_6)
+#define NFC_HAL_TASK_EVT_POWER_CYCLE EVENT_MASK(APPL_EVT_7)
+
+#define NFC_HAL_TASK_EVT_MBOX (TASK_MBOX_0_EVT_MASK)
+
+/* NFC HAL Task mailbox definitions */
+#define NFC_HAL_TASK_MBOX (TASK_MBOX_0)
+
+/* NFC HAL Task Timer events */
+#ifndef NFC_HAL_QUICK_TIMER_EVT_MASK
+#define NFC_HAL_QUICK_TIMER_EVT_MASK (TIMER_0_EVT_MASK)
+#endif
+
+#ifndef NFC_HAL_QUICK_TIMER_ID
+#define NFC_HAL_QUICK_TIMER_ID (TIMER_0)
+#endif
+
+/* NFC HAL Task Timer types */
+#define NFC_HAL_TTYPE_NCI_WAIT_RSP 0
+#define NFC_HAL_TTYPE_POWER_CYCLE 1
+#define NFC_HAL_TTYPE_NFCC_ENABLE 2
+
+/* NFC HAL Task Wait Response flag */
+/* wait response on an NCI command                  */
+#define NFC_HAL_WAIT_RSP_CMD 0x10
+/* wait response on an NCI vendor specific command  */
+#define NFC_HAL_WAIT_RSP_VSC 0x20
+/* wait response on a proprietary command           */
+#define NFC_HAL_WAIT_RSP_PROP 0x40
+/* not waiting for anything                         */
+#define NFC_HAL_WAIT_RSP_NONE 0x00
+
+typedef uint8_t tNFC_HAL_WAIT_RSP;
+
+#if (NFC_HAL_HCI_INCLUDED == true)
+
+typedef uint16_t tNFC_HAL_HCI_EVT;
+
+#define NFC_HAL_HCI_PIPE_INFO_SIZE 5
+
+#define NFC_HAL_HCI_ANY_SET_PARAMETER 0x01
+#define NFC_HAL_HCI_ANY_GET_PARAMETER 0x02
+#define NFC_HAL_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED 0x15
+
+#define NFC_HAL_HCI_SESSION_IDENTITY_INDEX 0x01
+#define NFC_HAL_HCI_WHITELIST_INDEX 0x03
+
+#define NFC_HAL_HCI_ADMIN_PIPE 0x01
+/* Host ID for UICC 0 */
+#define NFC_HAL_HCI_HOST_ID_UICC0 0x02
+/* Host ID for UICC 1 */
+#define NFC_HAL_HCI_HOST_ID_UICC1 0x03
+/* Host ID for UICC 2 */
+#define NFC_HAL_HCI_HOST_ID_UICC2 0x04
+#define NFC_HAL_HCI_COMMAND_TYPE 0x00
+#define NFC_HAL_HCI_RESPONSE_TYPE 0x02
+
+/* NFC HAL HCI responses */
+#define NFC_HAL_HCI_ANY_OK 0x00
+
+#endif
+
+/* Flag defintions for tNFC_HAL_NVM */
+/* No NVM available                     */
+#define NFC_HAL_NVM_FLAGS_NO_NVM 0x01
+/* FPM patch in NVM failed CRC check    */
+#define NFC_HAL_NVM_FLAGS_LPM_BAD 0x02
+/* LPM patch in NVM failed CRC check    */
+#define NFC_HAL_NVM_FLAGS_FPM_BAD 0x04
+/* Patch is present in NVM              */
+#define NFC_HAL_NVM_FLAGS_PATCH_PRESENT 0x08
+
+/* NFC HAL transport configuration */
+typedef struct {
+  bool shared_transport; /* true if using shared HCI/NCI transport */
+  uint8_t userial_baud;
+  uint8_t userial_fc;
+} tNFC_HAL_TRANS_CFG;
+
+#ifdef TESTER
+/* For Insight, ncit_cfg is runtime-configurable */
+#define NFC_HAL_TRANS_CFG_QUALIFIER
+#else
+/* For all other platforms, ncit_cfg is constant */
+#define NFC_HAL_TRANS_CFG_QUALIFIER const
+#endif
+extern NFC_HAL_TRANS_CFG_QUALIFIER tNFC_HAL_TRANS_CFG nfc_hal_trans_cfg;
+
+/*****************************************************************************
+* BT HCI definitions
+*****************************************************************************/
+
+/* Tranport message type */
+#define HCIT_TYPE_COMMAND 0x01
+#define HCIT_TYPE_EVENT 0x04
+#define HCIT_TYPE_NFC 0x10
+
+/* Vendor-Specific BT HCI definitions */
+#define HCI_SUCCESS 0x00
+#define HCI_GRP_VENDOR_SPECIFIC (0x3F << 10) /* 0xFC00 */
+#define HCI_BRCM_WRITE_SLEEP_MODE (0x0027 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_GRP_HOST_CONT_BASEBAND_CMDS (0x03 << 10) /* 0x0C00 */
+#define HCI_RESET (0x0003 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_COMMAND_COMPLETE_EVT 0x0E
+#define HCI_BRCM_WRITE_SLEEP_MODE_LENGTH 12
+#define HCI_BRCM_UPDATE_BAUD_RATE_UNENCODED_LENGTH 0x06
+#define HCIE_PREAMBLE_SIZE 2
+#define HCI_BRCM_PRE_SET_MEM (0x000C | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_PRE_SET_MEM_LENGTH 10
+#define HCI_BRCM_PRE_SET_MEM_TYPE 8
+
+/****************************************************************************
+** Internal constants and definitions
+****************************************************************************/
+
+/* NFC HAL receiving states */
+enum {
+  NFC_HAL_RCV_IDLE_ST,        /* waiting for packet type byte             */
+  NFC_HAL_RCV_NCI_MSG_ST,     /* waiting for the first byte of NCI header */
+  NFC_HAL_RCV_NCI_HDR_ST,     /* reading NCI header                       */
+  NFC_HAL_RCV_NCI_PAYLOAD_ST, /* reading NCI payload                      */
+  NFC_HAL_RCV_BT_MSG_ST,      /* waiting for the first byte of BT header  */
+  NFC_HAL_RCV_BT_HDR_ST,      /* reading BT HCI header                    */
+  NFC_HAL_RCV_BT_PAYLOAD_ST   /* reading BT HCI payload                   */
+};
+
+/* errors during NCI packet reassembly process */
+#define NFC_HAL_NCI_RAS_TOO_BIG 0x01
+#define NFC_HAL_NCI_RAS_ERROR 0x02
+typedef uint8_t tNFC_HAL_NCI_RAS;
+
+/* NFC HAL power mode */
+enum {
+  NFC_HAL_POWER_MODE_FULL, /* NFCC is full power mode      */
+  NFC_HAL_POWER_MODE_LAST
+};
+typedef uint8_t tNFC_HAL_POWER_MODE;
+
+/* NFC HAL event for low power mode */
+enum {
+  NFC_HAL_LP_TX_DATA_EVT, /* DH is sending data to NFCC   */
+  NFC_HAL_LP_RX_DATA_EVT, /* DH received data from NFCC   */
+  NFC_HAL_LP_TIMEOUT_EVT, /* Timeout                      */
+  NFC_HAL_LP_LAST_EVT
+};
+typedef uint8_t tNFC_HAL_LP_EVT;
+
+#define NFC_HAL_ASSERT_NFC_WAKE 0x00   /* assert NFC_WAKE      */
+#define NFC_HAL_DEASSERT_NFC_WAKE 0x01 /* deassert NFC_WAKE    */
+
+#define NFC_HAL_BT_HCI_CMD_HDR_SIZE 3 /* opcode (2) +  length (1)    */
+#define NFC_HAL_CMD_TOUT (2000)       /* timeout for NCI CMD (in ms) */
+
+#define NFC_HAL_SAVED_HDR_SIZE (2)
+#define NFC_HAL_SAVED_CMD_SIZE (2)
+
+#ifndef NFC_HAL_DEBUG
+#define NFC_HAL_DEBUG true
+#endif
+
+#if (NFC_HAL_DEBUG == true)
+extern const char* const nfc_hal_init_state_str[];
+#define NFC_HAL_SET_INIT_STATE(state)                           \
+  HAL_TRACE_DEBUG3("init state: %d->%d(%s)",                    \
+                   nfc_hal_cb.dev_cb.initializing_state, state, \
+                   nfc_hal_init_state_str[state]);              \
+  nfc_hal_cb.dev_cb.initializing_state = state;
+#else
+#define NFC_HAL_SET_INIT_STATE(state) \
+  nfc_hal_cb.dev_cb.initializing_state = state;
+#endif
+
+/* NFC HAL - NFCC initializing state */
+enum {
+  NFC_HAL_INIT_STATE_IDLE,           /* Initialization is done                */
+  NFC_HAL_INIT_STATE_W4_XTAL_SET,    /* Waiting for crystal setting rsp       */
+  NFC_HAL_INIT_STATE_POST_XTAL_SET,  /* Waiting for reset ntf after xtal set  */
+  NFC_HAL_INIT_STATE_W4_NFCC_ENABLE, /* Waiting for reset ntf atter REG_PU up */
+  NFC_HAL_INIT_STATE_W4_BUILD_INFO,  /* Waiting for build info rsp            */
+  NFC_HAL_INIT_STATE_W4_PATCH_INFO,  /* Waiting for patch info rsp            */
+  NFC_HAL_INIT_STATE_W4_APP_COMPLETE,   /* Waiting for complete from application
+                                           */
+  NFC_HAL_INIT_STATE_W4_POST_INIT_DONE, /* Waiting for complete of post init */
+  NFC_HAL_INIT_STATE_W4_CONTROL_DONE,   /* Waiting for control release */
+  NFC_HAL_INIT_STATE_W4_PREDISCOVER_DONE, /* Waiting for complete of prediscover
+                                             */
+  NFC_HAL_INIT_STATE_CLOSING /* Shutting down                         */
+};
+typedef uint8_t tNFC_HAL_INIT_STATE;
+
+/* NFC HAL - NFCC config items during post initialization */
+enum {
+  NFC_HAL_DM_CONFIG_LPTD,
+  NFC_HAL_DM_CONFIG_PLL_325,
+  NFC_HAL_DM_CONFIG_START_UP,
+  NFC_HAL_DM_CONFIG_I93_DATA_RATE,
+  NFC_HAL_DM_CONFIG_FW_FSM,
+  NFC_HAL_DM_CONFIG_START_UP_VSC,
+  NFC_HAL_DM_CONFIG_NONE
+};
+typedef uint8_t tNFC_HAL_DM_CONFIG;
+
+/* callback function prototype */
+typedef struct {
+  uint16_t opcode;
+  uint16_t param_len;
+  uint8_t* p_param_buf;
+} tNFC_HAL_BTVSC_CPLT;
+
+typedef void(tNFC_HAL_BTVSC_CPLT_CBACK)(tNFC_HAL_BTVSC_CPLT* p1);
+
+#if (NFC_HAL_HCI_INCLUDED == true)
+
+/* data type for NFC_HAL_HCI_RSP_NV_READ_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  uint8_t block;
+  uint16_t size;
+  tHAL_NFC_STATUS status;
+} tNFC_HAL_HCI_RSP_NV_READ_EVT;
+
+/* data type for NFC_HAL_HCI_RSP_NV_WRITE_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tHAL_NFC_STATUS status;
+} tNFC_HAL_HCI_RSP_NV_WRITE_EVT;
+
+/* union of all event data types */
+typedef union {
+  NFC_HDR hdr;
+  /* Internal events */
+  tNFC_HAL_HCI_RSP_NV_READ_EVT nv_read;
+  tNFC_HAL_HCI_RSP_NV_WRITE_EVT nv_write;
+} tNFC_HAL_HCI_EVENT_DATA;
+
+#endif
+/*****************************************************************************
+** Control block for NFC HAL
+*****************************************************************************/
+
+/* Patch RAM Download Control block */
+
+/* PRM states */
+enum {
+  NFC_HAL_PRM_ST_IDLE,
+
+  /* Secure patch download stated */
+  NFC_HAL_PRM_ST_SPD_COMPARE_VERSION,
+  NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER,
+  NFC_HAL_PRM_ST_SPD_DOWNLOADING,
+  NFC_HAL_PRM_ST_SPD_AUTHENTICATING,
+  NFC_HAL_PRM_ST_SPD_AUTH_DONE,
+  NFC_HAL_PRM_ST_W4_GET_VERSION
+};
+typedef uint8_t tNFC_HAL_PRM_STATE;
+
+/* Maximum number of patches (currently 2: LPM and FPM) */
+#define NFC_HAL_PRM_MAX_PATCH_COUNT 2
+#define NFC_HAL_PRM_PATCH_MASK_ALL 0xFFFFFFFF
+#define NFC_HAL_PRM_MAX_CHIP_VER_LEN 8
+
+/* Structures for PRM Control Block */
+typedef struct {
+  uint8_t power_mode;
+  uint16_t len;
+} tNFC_HAL_PRM_PATCHDESC;
+
+typedef struct {
+  tNFC_HAL_PRM_STATE state; /* download state */
+  uint32_t flags;           /* internal flags */
+  uint16_t
+      cur_patch_len_remaining; /* bytes remaining in patchfile to process     */
+  const uint8_t*
+      p_cur_patch_data;      /* pointer to patch currently being downloaded */
+  uint16_t cur_patch_offset; /* offset of next byte to process              */
+  uint32_t dest_ram;
+  TIMER_LIST_ENT timer; /* Timer for patch download                    */
+  void* p_param;        /* general purpose param for PRM               */
+  uint8_t param_idx;    /* information related to general purpose param*/
+
+  /* Secure Patch Download */
+  uint32_t
+      spd_patch_needed_mask; /* Mask of patches that need to be downloaded */
+  uint8_t spd_patch_count;   /* Number of patches left to download */
+  uint8_t spd_cur_patch_idx; /* Current patch being downloaded */
+
+  tNFC_HAL_PRM_PATCHDESC spd_patch_desc[NFC_HAL_PRM_MAX_PATCH_COUNT];
+
+  /* I2C-patch */
+  uint8_t* p_spd_patch;             /* pointer to spd patch             */
+  uint16_t spd_patch_len_remaining; /* patch length                     */
+  uint16_t spd_patch_offset;        /* offset of next byte to process   */
+
+  tNFC_HAL_PRM_FORMAT format;  /* format of patch ram              */
+  tNFC_HAL_PRM_CBACK* p_cback; /* Callback for download status notifications */
+  uint32_t patchram_delay;     /* the dealy after patch */
+} tNFC_HAL_PRM_CB;
+
+/* Information about current patch in NVM */
+typedef struct {
+  uint16_t project_id; /* Current project_id of patch in nvm       */
+  uint16_t ver_major;  /* Current major version of patch in nvm    */
+  uint16_t ver_minor;  /* Current minor version of patch in nvm    */
+  uint16_t fpm_size;   /* Current size of FPM patch in nvm         */
+  uint16_t lpm_size;   /* Current size of LPM patch in nvm         */
+  uint8_t flags;       /* See NFC_HAL_NVM_FLAGS_* flag definitions */
+  uint8_t nvm_type;    /* Current NVM Type - UICC/EEPROM           */
+  uint8_t chip_ver[NFC_HAL_PRM_MAX_CHIP_VER_LEN]; /* patch chip version       */
+} tNFC_HAL_NVM;
+
+/* Patch for I2C fix */
+typedef struct {
+  uint8_t* p_patch;      /* patch for i2c fix                */
+  uint32_t prei2c_delay; /* the dealy after preI2C patch */
+  uint16_t len;          /* i2c patch length                 */
+} tNFC_HAL_PRM_I2C_FIX_CB;
+
+/* Control block for NCI transport */
+typedef struct {
+  uint8_t nci_ctrl_size; /* Max size for NCI messages */
+  uint8_t rcv_state;     /* current rx state */
+  uint16_t rcv_len; /* bytes remaining to be received in current rx state     */
+  NFC_HDR* p_rcv_msg;  /* buffer to receive NCI message */
+  NFC_HDR* p_frag_msg; /* fragmented NCI message; waiting for last fragment */
+  NFC_HDR*
+      p_pend_cmd; /* pending NCI message; waiting for NFCC state to be free */
+  tNFC_HAL_NCI_RAS nci_ras; /* nci reassembly error status */
+  TIMER_LIST_ENT
+  nci_wait_rsp_timer; /* Timer for waiting for nci command response */
+  tNFC_HAL_WAIT_RSP nci_wait_rsp; /* nci wait response flag */
+  uint8_t
+      last_hdr[NFC_HAL_SAVED_HDR_SIZE]; /* part of last NCI command header */
+  uint8_t
+      last_cmd[NFC_HAL_SAVED_CMD_SIZE]; /* part of last NCI command payload */
+  void* p_vsc_cback; /* the callback function for last VSC command */
+} tNFC_HAL_NCIT_CB;
+
+/* Control block for device initialization */
+typedef struct {
+  tNFC_HAL_INIT_STATE initializing_state; /* state of initializing NFCC */
+
+  uint32_t brcm_hw_id; /* BRCM NFCC HW ID                          */
+  tNFC_HAL_DM_CONFIG next_dm_config; /* next config in post initialization */
+  uint8_t next_startup_vsc; /* next start-up VSC offset in post init    */
+
+  tNFC_HAL_POWER_MODE power_mode; /* NFCC power mode                          */
+  uint8_t snooze_mode;            /* current snooze mode                      */
+  uint8_t new_snooze_mode;        /* next snooze mode after receiving cmpl    */
+  uint8_t nfc_wake_active_mode;   /* NFC_HAL_LP_ACTIVE_LOW/HIGH               */
+  TIMER_LIST_ENT lp_timer;        /* timer for low power mode                 */
+
+  tHAL_NFC_STATUS_CBACK*
+      p_prop_cback; /* callback to notify complete of proprietary update */
+} tNFC_HAL_DEV_CB;
+
+#if (NFC_HAL_HCI_INCLUDED == true)
+
+/* data members for NFC_HAL-HCI */
+typedef struct {
+  TIMER_LIST_ENT
+  hci_timer; /* Timer to avoid indefinitely waiting for response */
+  uint8_t*
+      p_hci_netwk_info_buf; /* Buffer for reading HCI Network information */
+  uint8_t* p_hci_netwk_dh_info_buf; /* Buffer for reading HCI Network DH
+                                       information */
+  uint8_t hci_netwk_config_block;  /* Rsp awaiting for hci network configuration
+                                      block */
+  bool b_wait_hcp_conn_create_rsp; /* Waiting for hcp connection create response
+                                      */
+  bool clear_all_pipes_to_uicc1;   /* UICC1 was restarted for patch download */
+  bool update_session_id; /* Next response from NFCC is to Get Session id cmd */
+  bool hci_fw_validate_netwk_cmd; /* Flag to indicate if hci network ntf to
+                                     validate */
+  uint8_t hcp_conn_id;            /* NCI Connection id for HCP */
+  uint8_t dh_session_id[1];       /* Byte 0 of DH Session ID */
+} tNFC_HAL_HCI_CB;
+
+#endif
+
+typedef struct {
+  tHAL_NFC_CBACK* p_stack_cback;     /* Callback for HAL event notification  */
+  tHAL_NFC_DATA_CBACK* p_data_cback; /* Callback for data event notification  */
+
+  TIMER_LIST_Q quick_timer_queue; /* timer list queue                 */
+  TIMER_LIST_ENT timer;           /* timer for NCI transport task     */
+
+  tNFC_HAL_NCIT_CB ncit_cb; /* NCI transport */
+  tNFC_HAL_DEV_CB dev_cb;   /* device initialization */
+  tNFC_HAL_NVM nvm_cb;      /* Information about current patch in NVM */
+
+  /* Patchram control block */
+  tNFC_HAL_PRM_CB prm;
+  tNFC_HAL_PRM_I2C_FIX_CB prm_i2c;
+
+#if (NFC_HAL_HCI_INCLUDED == true)
+  /* data members for NFC_HAL-HCI */
+  tNFC_HAL_HCI_CB hci_cb;
+#endif
+
+  uint8_t pre_discover_done; /* true, when the prediscover config is complete */
+  uint8_t pre_set_mem_idx;
+
+  uint8_t max_rf_credits; /* NFC Max RF data credits */
+  uint8_t max_ee;         /* NFC Max number of NFCEE supported by NFCC */
+  uint8_t trace_level;    /* NFC HAL trace level */
+} tNFC_HAL_CB;
+
+/* Global NCI data */
+extern tNFC_HAL_CB nfc_hal_cb;
+
+extern uint8_t* p_nfc_hal_pre_discover_cfg;
+
+/****************************************************************************
+** Internal nfc functions
+****************************************************************************/
+
+/* From nfc_hal_main.c */
+uint32_t nfc_hal_main_task(uint32_t param);
+void nfc_hal_main_init(void);
+void nfc_hal_main_pre_init_done(tHAL_NFC_STATUS);
+void nfc_hal_main_start_quick_timer(TIMER_LIST_ENT* p_tle, uint16_t type,
+                                    uint32_t timeout);
+void nfc_hal_main_stop_quick_timer(TIMER_LIST_ENT* p_tle);
+void nfc_hal_main_send_error(tHAL_NFC_STATUS status);
+void nfc_hal_send_nci_msg_to_nfc_task(NFC_HDR* p_msg);
+
+/* nfc_hal_nci.c */
+bool nfc_hal_nci_receive_msg(uint8_t byte);
+bool nfc_hal_nci_preproc_rx_nci_msg(NFC_HDR* p_msg);
+NFC_HDR* nfc_hal_nci_postproc_rx_nci_msg(void);
+void nfc_hal_nci_assemble_nci_msg(void);
+void nfc_hal_nci_add_nfc_pkt_type(NFC_HDR* p_msg);
+void nfc_hal_nci_send_cmd(NFC_HDR* p_buf);
+void nfc_hal_nci_cmd_timeout_cback(void* p_tle);
+
+/* nfc_hal_dm.c */
+void nfc_hal_dm_init(void);
+void nfc_hal_dm_set_xtal_freq_index(void);
+void nfc_hal_dm_send_get_build_info_cmd(void);
+void nfc_hal_dm_proc_msg_during_init(NFC_HDR* p_msg);
+void nfc_hal_dm_config_nfcc(void);
+void nfc_hal_dm_send_nci_cmd(const uint8_t* p_data, uint16_t len,
+                             tNFC_HAL_NCI_CBACK* p_cback);
+void nfc_hal_dm_send_bt_cmd(const uint8_t* p_data, uint16_t len,
+                            tNFC_HAL_BTVSC_CPLT_CBACK* p_cback);
+void nfc_hal_dm_set_nfc_wake(uint8_t cmd);
+void nfc_hal_dm_pre_init_nfcc(void);
+void nfc_hal_dm_shutting_down_nfcc(void);
+bool nfc_hal_dm_power_mode_execute(tNFC_HAL_LP_EVT event);
+void nfc_hal_dm_send_pend_cmd(void);
+tHAL_NFC_STATUS nfc_hal_dm_set_config(uint8_t tlv_size, uint8_t* p_param_tlvs,
+                                      tNFC_HAL_NCI_CBACK* p_cback);
+bool nfc_hal_dm_check_pre_set_mem(void);
+
+/* nfc_hal_prm.c */
+void nfc_hal_prm_spd_reset_ntf(uint8_t reset_reason, uint8_t reset_type);
+void nfc_hal_prm_nci_command_complete_cback(tNFC_HAL_NCI_EVT event,
+                                            uint16_t data_len, uint8_t* p_data);
+void nfc_hal_prm_process_timeout(void* p_tle);
+
+#if (NFC_HAL_HCI_INCLUDED == true)
+/* nfc_hal_hci.c */
+void nfc_hal_hci_enable(void);
+void nfc_hal_hci_evt_hdlr(tNFC_HAL_HCI_EVENT_DATA* p_evt_data);
+void nfc_hal_hci_handle_hci_netwk_info(uint8_t* p_data);
+void nfc_hal_hci_handle_hcp_pkt_from_hc(uint8_t* p_data);
+NFC_HDR* nfc_hal_hci_postproc_hcp(void);
+bool nfc_hal_hci_handle_hcp_pkt_to_hc(uint8_t* p_data);
+void nfc_hal_hci_timeout_cback(void* p_tle);
+void nfc_hal_hci_handle_build_info(uint8_t chipverlen, uint8_t* p_chipverstr);
+#else
+#define nfc_hal_hci_enable() NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE);
+#define nfc_hal_hci_handle_build_info(p, a)
+#define nfc_hal_hci_evt_hdlr(p) ;
+#endif
+
+/* Define default NCI protocol trace function (if protocol tracing is enabled)
+ */
+#if (NFC_HAL_TRACE_PROTOCOL == true)
+#if !defined(DISP_NCI)
+#define DISP_NCI (DispNci)
+void DispNci(uint8_t* p, uint16_t len, bool is_recv);
+#endif /* DISP_NCI */
+
+/* For displaying vendor-specific HCI commands */
+void DispHciCmd(NFC_HDR* p_buf);
+void DispHciEvt(NFC_HDR* p_buf);
+#endif /* NFC_HAL_TRACE_PROTOCOL */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_HAL_INT_H */
diff --git a/src/hal/int/nfc_hal_int_api.h b/src/hal/int/nfc_hal_int_api.h
new file mode 100644
index 0000000..89edb03
--- /dev/null
+++ b/src/hal/int/nfc_hal_int_api.h
@@ -0,0 +1,307 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Internal NFC HAL API functions.
+ *
+ ******************************************************************************/
+#ifndef NFC_HAL_INT_API_H
+#define NFC_HAL_INT_API_H
+
+/****************************************************************************
+** Device Configuration definitions
+****************************************************************************/
+
+#define NFC_HAL_PLL_325_SETCONFIG_PARAM_LEN (2 + NCI_PARAM_LEN_PLL325_CFG_PARAM)
+
+/* Crystal Frequency Index (in 1 KHz) */
+enum {
+  NFC_HAL_XTAL_INDEX_9600,
+  NFC_HAL_XTAL_INDEX_13000,
+  NFC_HAL_XTAL_INDEX_16200,
+  NFC_HAL_XTAL_INDEX_19200,
+  NFC_HAL_XTAL_INDEX_24000,
+  NFC_HAL_XTAL_INDEX_26000,
+  NFC_HAL_XTAL_INDEX_38400,
+  NFC_HAL_XTAL_INDEX_52000,
+  NFC_HAL_XTAL_INDEX_37400,
+  NFC_HAL_XTAL_INDEX_MAX,
+  NFC_HAL_XTAL_INDEX_SPECIAL = 0xFF
+};
+typedef uint8_t tNFC_HAL_XTAL_INDEX;
+
+/* Broadcom specific device initialization before sending NCI reset */
+
+typedef struct {
+  uint32_t brcm_hw_id;
+  uint16_t xtal_freq;
+  uint8_t xtal_index;
+} tNFC_HAL_DEV_INIT_XTAL_CFG;
+
+#define NFC_HAL_DEV_INIT_MAX_XTAL_CFG 5
+
+typedef struct {
+  uint8_t num_xtal_cfg;
+  tNFC_HAL_DEV_INIT_XTAL_CFG xtal_cfg[NFC_HAL_DEV_INIT_MAX_XTAL_CFG];
+} tNFC_HAL_DEV_INIT_CFG;
+
+/*****************************************************************************
+**  Low Power Mode definitions
+*****************************************************************************/
+
+/* Snooze mode disabled    */
+#define NFC_HAL_LP_SNOOZE_MODE_NONE NFC_SNOOZE_MODE_NONE
+/* Snooze mode for UART    */
+#define NFC_HAL_LP_SNOOZE_MODE_UART NFC_SNOOZE_MODE_UART
+/* Snooze mode for SPI/I2C */
+#define NFC_HAL_LP_SNOOZE_MODE_SPI_I2C NFC_SNOOZE_MODE_SPI_I2C
+
+/* high to low voltage is asserting */
+#define NFC_HAL_LP_ACTIVE_LOW NFC_SNOOZE_ACTIVE_LOW
+/* low to high voltage is asserting */
+#define NFC_HAL_LP_ACTIVE_HIGH NFC_SNOOZE_ACTIVE_HIGH
+
+/*****************************************************************************
+**  Patch RAM Constants
+*****************************************************************************/
+
+/* patch format type */
+#define NFC_HAL_PRM_FORMAT_BIN 0x00
+#define NFC_HAL_PRM_FORMAT_HCD 0x01
+#define NFC_HAL_PRM_FORMAT_NCD 0x02
+typedef uint8_t tNFC_HAL_PRM_FORMAT;
+
+/*****************************************************************************
+**  Patch RAM Callback for event notificaton
+*****************************************************************************/
+/* Events for tNFC_HAL_PRM_CBACK */
+enum {
+  NFC_HAL_PRM_CONTINUE_EVT,
+  NFC_HAL_PRM_COMPLETE_EVT,
+  NFC_HAL_PRM_ABORT_EVT,
+  NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT, /* Patch is invalid (bad version, project
+                                          id, or chip)  */
+  NFC_HAL_PRM_ABORT_BAD_SIGNATURE_EVT, /* Patch has invalid signature */
+  NFC_HAL_PRM_SPD_GET_PATCHFILE_HDR_EVT, /* Secure Patch Download: request for
+                                            patchfile header  */
+  NFC_HAL_PRM_SPD_GET_NEXT_PATCH,        /* Get first command of next patch in
+                                            patchfile         */
+  NFC_HAL_PRM_ABORT_NO_NVM_EVT /* nfc_hal_prm_nvm_required is true and NVM is
+                                  unavail  */
+};
+
+typedef void(tNFC_HAL_PRM_CBACK)(uint8_t event);
+
+typedef uint8_t tNFC_HAL_NCI_EVT; /* MT + Opcode */
+typedef void(tNFC_HAL_NCI_CBACK)(tNFC_HAL_NCI_EVT event, uint16_t data_len,
+                                 uint8_t* p_data);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPreInitDone
+**
+** Description      Notify that pre-initialization of NFCC is complete
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcPreInitDone(tHAL_NFC_STATUS status);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcReInit
+**
+** Description      This function is called to restart initialization after
+**                  REG_PU toggled because of failure to detect NVM type or
+**                  download patchram.
+**
+** Note             This function should be called only during the HAL init
+**                  process
+**
+** Returns          HAL_NFC_STATUS_OK if successfully initiated
+**                  HAL_NFC_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tHAL_NFC_STATUS HAL_NfcReInit(void);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcSetSnoozeMode
+**
+** Description      Set snooze mode
+**                  snooze_mode
+**                      NFC_HAL_LP_SNOOZE_MODE_NONE - Snooze mode disabled
+**                      NFC_HAL_LP_SNOOZE_MODE_UART - Snooze mode for UART
+**                      NFC_HAL_LP_SNOOZE_MODE_SPI_I2C - Snooze mode for SPI/I2C
+**
+**                  idle_threshold_dh/idle_threshold_nfcc
+**                      Idle Threshold Host in 100ms unit
+**
+**                  nfc_wake_active_mode/dh_wake_active_mode
+**                      NFC_HAL_LP_ACTIVE_LOW - high to low voltage is asserting
+**                      NFC_HAL_LP_ACTIVE_HIGH - low to high voltage is
+**                                               asserting
+**
+**                  p_snooze_cback
+**                      Notify status of operation
+**
+** Returns          tHAL_NFC_STATUS
+**
+*******************************************************************************/
+tHAL_NFC_STATUS HAL_NfcSetSnoozeMode(uint8_t snooze_mode,
+                                     uint8_t idle_threshold_dh,
+                                     uint8_t idle_threshold_nfcc,
+                                     uint8_t nfc_wake_active_mode,
+                                     uint8_t dh_wake_active_mode,
+                                     tHAL_NFC_STATUS_CBACK* p_snooze_cback);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPrmDownloadStart
+**
+** Description      Initiate patch download
+**
+** Input Params
+**                  format_type     patch format type
+**                                  (NFC_HAL_PRM_FORMAT_BIN,
+**                                   NFC_HAL_PRM_FORMAT_HCD, or
+**                                   NFC_HAL_PRM_FORMAT_NCD)
+**
+**                  dest_address    destination adderess (needed for BIN format
+**                                  only)
+**
+**                  p_patchram_buf  pointer to patchram buffer. If NULL, then
+**                                  app must call HAL_NfcPrmDownloadContinue
+**                                  when NFC_HAL_PRM_CONTINUE_EVT is received,
+**                                  to send the next segment of patchram
+**
+**                  patchram_len    size of p_patchram_buf (if non-NULL)
+**
+**                  patchram_delay  The delay after each patch.
+**                                  If the given value is less than the size of
+**                                  the patchram, the size of patchram is used
+**                                  instead.
+**
+**                  p_cback         callback for download status
+**
+**
+** Returns          true if successful, otherwise false
+**
+**
+*******************************************************************************/
+bool HAL_NfcPrmDownloadStart(tNFC_HAL_PRM_FORMAT format_type,
+                             uint32_t dest_address, uint8_t* p_patchram_buf,
+                             uint32_t patchram_len, uint32_t patchram_delay,
+                             tNFC_HAL_PRM_CBACK* p_cback);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPrmDownloadContinue
+**
+** Description      Send next segment of patchram to controller. Called when
+**                  NFC_HAL_PRM_CONTINUE_EVT is received.
+**
+**                  Only needed if HAL_NfcPrmDownloadStart was called with
+**                  p_patchram_buf=NULL
+**
+** Input Params     p_patch_data    pointer to patch data
+**                  patch_data_len  patch data len
+**
+** Returns          true if successful, otherwise false
+**
+*******************************************************************************/
+bool HAL_NfcPrmDownloadContinue(uint8_t* p_patch_data, uint16_t patch_data_len);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPrmSetI2cPatch
+**
+** Description      Specify patchfile for BCM20791B3 I2C fix. This fix
+**                  must be downloaded prior to initial patch download for I2C
+**                  transport
+**
+** Input Params     p_i2c_patchfile_buf: pointer to patch for i2c fix
+**                  i2c_patchfile_len: length of patch
+**                  prei2c_delay: the delay before downloading main patch
+**                                if 0 is given, NFC_HAL_PRM_POST_I2C_FIX_DELAY
+**                                is used instead.
+**
+** Returns          Nothing
+**
+**
+*******************************************************************************/
+void HAL_NfcPrmSetI2cPatch(uint8_t* p_i2c_patchfile_buf,
+                           uint16_t i2c_patchfile_len, uint32_t prei2c_delay);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPrmSetSpdNciCmdPayloadSize
+**
+** Description      Set Host-to-NFCC NCI message size for secure patch download
+**
+**                  This API must be called before calling
+**                  HAL_NfcPrmDownloadStart. If the API is not called, then PRM
+**                  will use the default message size.
+**
+**                  Typically, this API is only called for platforms that have
+**                  message-size limitations in the transport/driver.
+**
+**                  Valid message size range:
+**                  NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE to 255.
+**
+** Returns          HAL_NFC_STATUS_OK if successful
+**                  HAL_NFC_STATUS_FAILED otherwise
+**
+**
+*******************************************************************************/
+tHAL_NFC_STATUS HAL_NfcPrmSetSpdNciCmdPayloadSize(uint8_t max_payload_size);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcSetMaxRfDataCredits
+**
+** Description      This function sets the maximum RF data credit for HAL.
+**                  If 0, use the value reported from NFCC.
+**
+** Returns          none
+**
+*******************************************************************************/
+void HAL_NfcSetMaxRfDataCredits(uint8_t max_credits);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcSetTraceLevel
+**
+** Description      This function sets the trace level for HAL.  If called with
+**                  a value of 0xFF, it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+uint8_t HAL_NfcSetTraceLevel(uint8_t new_level);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_HAL_INT_API_H */
diff --git a/src/hal/int/nfc_hal_nv_ci.h b/src/hal/int/nfc_hal_nv_ci.h
new file mode 100644
index 0000000..b63a8fb
--- /dev/null
+++ b/src/hal/int/nfc_hal_nv_ci.h
@@ -0,0 +1,89 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2003-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the interface file for non valtile memory call-in functions.
+ *
+ ******************************************************************************/
+#ifndef NFC_HAL_NV_CI_H
+#define NFC_HAL_NV_CI_H
+
+#include "nfc_hal_target.h"
+#if (NFC_HAL_HCI_INCLUDED == true)
+
+#include "nfc_hal_nv_co.h"
+
+/*****************************************************************************
+**  Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nv_ci_write
+**
+** Description      This function sends an event to NFAA indicating the phone
+**                  has written the number of bytes specified in the call-out
+**                  function, nfa_nv_co_write (), and is ready for more data.
+**                  This function is used to control the TX data flow.
+**                  Note: The data buffer is released by the stack aioer
+**                        calling this function.
+**
+** Parameters       status - NFA_NV_CO_OK, NFA_NV_CO_NOSPACE, or NFA_NV_CO_FAIL
+**                  evt - Used Internally by NFA -> MUST be same value passed
+**                       in call-out function.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_nv_ci_write(tNFC_HAL_NV_CO_STATUS status);
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nv_ci_read
+**
+** Description      This function sends an event to NCIT indicating the phone
+**                  has read in the requested amount of data specified in the
+**                  nfa_nv_co_read () call-out function.  It should only be
+**                  called when the requested number of bytes has been read.
+**
+** Parameters       num_bytes_read - number of bytes read into the buffer
+**                      specified in the read callout-function.
+**                  status - NFC_HAL_NV_CO_OK if full buffer of data,
+**                           NFC_HAL_NV_CO_EOF if the end of file has been
+**                           reached,
+**                           NFC_HAL_NV_CO_FAIL if an error has occurred.
+**                  evt - Used Internally by NFA -> MUST be same value passed
+**                       in call-out function.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_nv_ci_read(uint16_t num_bytes_read, tNFC_HAL_NV_CO_STATUS status,
+                        uint8_t block);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_HAL_HCI_INCLUDED */
+
+#endif /* NFC_HAL_NV_CI_H */
diff --git a/src/hal/int/nfc_hal_nv_co.h b/src/hal/int/nfc_hal_nv_co.h
new file mode 100644
index 0000000..870da24
--- /dev/null
+++ b/src/hal/int/nfc_hal_nv_co.h
@@ -0,0 +1,118 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2003-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the interface file for storing nv data
+ *
+ ******************************************************************************/
+#ifndef NFC_HAL_NV_CO_H
+#define NFC_HAL_NV_CO_H
+
+#include "nfc_hal_target.h"
+#if (NFC_HAL_HCI_INCLUDED == true)
+
+#include <time.h>
+
+/*****************************************************************************
+**  Constants and Data Types
+*****************************************************************************/
+
+/**************************
+**  Common Definitions
+***************************/
+
+/* Status codes returned by call-out functions, or in call-in functions as
+ * status */
+#define NFC_HAL_NV_CO_OK 0x00
+#define NFC_HAL_NV_CO_FAIL 0x01 /* Used to pass all other errors */
+#define NFC_HAL_NV_CO_EACCES 0x02
+#define NFC_HAL_NV_CO_ENOTEMPTY 0x03
+#define NFC_HAL_NV_CO_EOF 0x04
+#define NFC_HAL_NV_CO_EODIR 0x05
+/* Returned in nfa_nv_ci_open if no room */
+#define NFC_HAL_NV_CO_ENOSPACE 0x06
+#define NFC_HAL_NV_CO_EIS_DIR 0x07
+#define NFC_HAL_NV_CO_RESUME 0x08 /* used in nfa_nv_ci_open, on resume */
+/* used in nfa_nv_ci_open, on resume (no file to resume) */
+#define NFC_HAL_NV_CO_NONE 0x09
+
+typedef uint8_t tNFC_HAL_NV_CO_STATUS;
+
+#define DH_NV_BLOCK 0x01
+#define HC_F3_NV_BLOCK 0x02
+#define HC_F4_NV_BLOCK 0x03
+#define HC_F2_NV_BLOCK 0x04
+#define HC_F5_NV_BLOCK 0x05
+
+/*****************************************************************************
+**  Function Declarations
+*****************************************************************************/
+/**************************
+**  Common Functions
+***************************/
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nv_co_read
+**
+** Description      This function is called by NFA to read in data from the
+**                  previously opened file.
+**
+** Parameters       p_buf   - buffer to read the data into.
+**                  nbytes  - number of bytes to read into the buffer.
+**
+** Returns          void
+**
+**                  Note: Upon completion of the request, nfa_nv_ci_read () is
+**                        called with the buffer of data, along with the number
+**                        of bytes read into the buffer, and a status.  The
+**                        call-in function should only be called when ALL
+**                        requested bytes have been read, the end of file has
+**                        been detected, or an error has occurred.
+**
+*******************************************************************************/
+void nfc_hal_nv_co_read(uint8_t* p_buf, uint16_t nbytes, uint8_t block);
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nv_co_write
+**
+** Description      This function is called by io to send file data to the
+**                  phone.
+**
+** Parameters       p_buf   - buffer to read the data from.
+**                  nbytes  - number of bytes to write out to the file.
+**
+** Returns          void
+**
+**                  Note: Upon completion of the request, nfa_nv_ci_write () is
+**                        called with the file descriptor and the status. The
+**                        call-in function should only be called when ALL
+**                        requested bytes have been written, or an error has
+**                        been detected,
+**
+*******************************************************************************/
+void nfc_hal_nv_co_write(const uint8_t* p_buf, uint16_t nbytes, uint8_t block);
+
+extern void nfa_nv_ci_read(uint16_t num_bytes_read, tNFA_NV_CO_STATUS status,
+                           uint8_t block);
+extern void nfa_nv_ci_write(tNFA_NV_CO_STATUS status);
+
+#endif /* NFC_HAL_HCI_INCLUDED */
+#endif /* NFC_HAL_NV_CO_H */
diff --git a/src/hal/int/nfc_hal_post_reset.h b/src/hal/int/nfc_hal_post_reset.h
new file mode 100644
index 0000000..7ce3953
--- /dev/null
+++ b/src/hal/int/nfc_hal_post_reset.h
@@ -0,0 +1,73 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Post NCI reset routines
+ *
+ ******************************************************************************/
+#ifndef NFC_HAL_POST_RESET_H
+#define NFC_HAL_POST_RESET_H
+
+/*****************************************************************************
+** Application control block definitions
+******************************************************************************/
+#define NFA_APP_PATCHFILE_MAX_PATH 255
+#define NFA_APP_MAX_NUM_REINIT 5
+
+typedef struct {
+  uint8_t prm_file[NFA_APP_PATCHFILE_MAX_PATH + 1]; /* Filename of patchram */
+  uint8_t* p_prm_buf; /* Pointer to buffer for holding patchram data */
+
+  /* Patchfile for I2C fix */
+  uint8_t prm_i2c_patchfile[NFA_APP_PATCHFILE_MAX_PATH + 1];
+  uint8_t* p_prm_i2c_buf;
+
+  uint8_t userial_baud;
+
+  tNFC_HAL_DEV_INIT_CFG dev_init_config;
+
+  /* snooze mode setting */
+  uint8_t snooze_mode;
+  uint8_t idle_threshold_dh;
+  uint8_t idle_threshold_nfcc;
+  uint8_t nfc_wake_active_mode;
+  uint8_t dh_wake_active_mode;
+
+  /* NVM detection retry (some platforms require re-attempts to detect NVM) */
+  uint8_t spd_nvm_detection_max_count; /* max retry to get NVM type */
+  uint8_t spd_nvm_detection_cur_count; /* current retry count       */
+
+  /* handling for failure to download patch */
+  bool spd_debug_mode; /* debug mode for downloading patchram, report failure
+                          immediately and obviously */
+  bool spd_skip_on_power_cycle; /* skip downloading patchram after power cycle
+                                   because of patch download failure */
+} tNFC_POST_RESET_CB;
+extern tNFC_POST_RESET_CB nfc_post_reset_cb;
+
+/*
+** Post NCI reset handler
+**
+** This function is called to start device pre-initialization after
+** NCI CORE-RESET. When pre-initialization is completed,
+** HAL_NfcPreInitDone() must be called to proceed with stack start up.
+*/
+void nfc_hal_post_reset_init(uint32_t brcm_hw_id, uint8_t nvm_type);
+
+#endif /* NFC_HAL_POST_RESET_H */
diff --git a/src/include/CrcChecksum.h b/src/include/CrcChecksum.h
new file mode 100644
index 0000000..f3154f2
--- /dev/null
+++ b/src/include/CrcChecksum.h
@@ -0,0 +1,51 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#pragma once
+
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+**
+** Function         crcChecksumCompute
+**
+** Description      Compute a checksum on a buffer of data.
+**
+** Returns          2-byte checksum.
+**
+*******************************************************************************/
+unsigned short crcChecksumCompute(const unsigned char* buffer, int bufferLen);
+
+/*******************************************************************************
+**
+** Function         crcChecksumVerifyIntegrity
+**
+** Description      Detect any corruption in a file by computing a checksum.
+**                  filename: file name.
+**
+** Returns          True if file is good.
+**
+*******************************************************************************/
+bool crcChecksumVerifyIntegrity(const char* filename);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/include/NfcAdaptation.h b/src/include/NfcAdaptation.h
new file mode 100644
index 0000000..60aa1f8
--- /dev/null
+++ b/src/include/NfcAdaptation.h
@@ -0,0 +1,163 @@
+/******************************************************************************
+ *
+ *  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) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#pragma once
+#include <pthread.h>
+
+#include "nfc_target.h"
+#include "nfc_hal_api.h"
+#include <hardware/nfc.h>
+
+#include <utils/RefBase.h>
+
+namespace android {
+namespace hardware {
+namespace nfc {
+namespace V1_0 {
+    struct INfc;
+    struct INfcClientCallback;
+} } } }
+
+namespace vendor {
+namespace nxp {
+namespace hardware {
+namespace nfc {
+namespace V1_0 {
+struct INqNfc;
+} } } } }
+
+class ThreadMutex
+{
+public:
+    ThreadMutex();
+    virtual ~ThreadMutex();
+    void lock();
+    void unlock();
+    operator pthread_mutex_t* () {return &mMutex;}
+private:
+    pthread_mutex_t mMutex;
+};
+
+class ThreadCondVar : public ThreadMutex {
+ public:
+  ThreadCondVar();
+  virtual ~ThreadCondVar();
+  void signal();
+  void wait();
+  operator pthread_cond_t*() { return &mCondVar; }
+  operator pthread_mutex_t*() {
+    return ThreadMutex::operator pthread_mutex_t*();
+  }
+
+ private:
+  pthread_cond_t mCondVar;
+};
+
+class AutoThreadMutex {
+ public:
+  AutoThreadMutex(ThreadMutex& m);
+  virtual ~AutoThreadMutex();
+  operator ThreadMutex&() { return mm; }
+  operator pthread_mutex_t*() { return (pthread_mutex_t*)mm; }
+
+ private:
+  ThreadMutex& mm;
+};
+
+class NfcAdaptation {
+ public:
+  virtual ~NfcAdaptation();
+  void Initialize();
+  void Finalize();
+  static NfcAdaptation& GetInstance();
+  tHAL_NFC_ENTRY* GetHalEntryFuncs();
+  void DownloadFirmware();
+#if (NXP_EXTNS == TRUE)
+  void MinInitialize();
+  int HalGetFwDwnldFlag(uint8_t* fwDnldRequest);
+  nfc_nci_IoctlInOutData_t* mCurrentIoctlData;
+#endif
+
+private:
+    NfcAdaptation();
+    void    signal();
+    static  NfcAdaptation* mpInstance;
+    static  ThreadMutex sLock;
+    static ThreadMutex sIoctlLock;
+    ThreadCondVar    mCondVar;
+    tHAL_NFC_ENTRY   mHalEntryFuncs; // function pointers for HAL entry points
+    static nfc_nci_device_t* mHalDeviceContext;
+    static android::sp<android::hardware::nfc::V1_0::INfc> mHal;
+    static android::sp<vendor::nxp::hardware::nfc::V1_0::INqNfc> mNqHal;
+    static android::hardware::nfc::V1_0::INfcClientCallback* mCallback;
+    static tHAL_NFC_CBACK* mHalCallback;
+    static tHAL_NFC_DATA_CBACK* mHalDataCallback;
+    static ThreadCondVar mHalOpenCompletedEvent;
+    static ThreadCondVar mHalCloseCompletedEvent;
+    static ThreadCondVar mHalIoctlEvent;
+#if(NXP_EXTNS == TRUE)
+    pthread_t mThreadId;
+    static ThreadCondVar mHalCoreResetCompletedEvent;
+    static ThreadCondVar mHalCoreInitCompletedEvent;
+    static ThreadCondVar mHalInitCompletedEvent;
+#endif
+  static uint32_t NFCA_TASK(uint32_t arg);
+  static uint32_t Thread(uint32_t arg);
+  void InitializeHalDeviceContext();
+  static void HalDeviceContextCallback(nfc_event_t event,
+                                       nfc_status_t event_status);
+  static void HalDeviceContextDataCallback(uint16_t data_len, uint8_t* p_data);
+
+  static void HalInitialize();
+  static void HalTerminate();
+  static void HalOpen(tHAL_NFC_CBACK* p_hal_cback,
+                      tHAL_NFC_DATA_CBACK* p_data_cback);
+  static void HalClose();
+  static void HalCoreInitialized(uint16_t data_len,
+                                 uint8_t* p_core_init_rsp_params);
+  static void HalWrite(uint16_t data_len, uint8_t* p_data);
+#if (NXP_EXTNS == TRUE)
+  static int HalIoctl(long arg, void* p_data);
+#endif
+  static bool HalPrediscover();
+  static void HalControlGranted();
+  static void HalPowerCycle();
+  static uint8_t HalGetMaxNfcee();
+  static void HalDownloadFirmwareCallback(nfc_event_t event,
+                                          nfc_status_t event_status);
+  static void HalDownloadFirmwareDataCallback(uint16_t data_len,
+                                              uint8_t* p_data);
+};
diff --git a/src/include/_OverrideLog.h b/src/include/_OverrideLog.h
new file mode 100644
index 0000000..addbea7
--- /dev/null
+++ b/src/include/_OverrideLog.h
@@ -0,0 +1,95 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Override the Android logging macro(s) from
+ *  /system/core/include/cutils/log.h. This header must be the first header
+ *  included by a *.cpp file so the original Android macro can be replaced.
+ *  Do not include this header in another header, because that will create
+ *  unnecessary dependency.
+ *
+ ******************************************************************************/
+#pragma once
+
+// Override Android's ALOGD macro by adding a boolean expression.
+#define ALOGD(...) \
+  ((void)ALOGD_IF(appl_trace_level >= BT_TRACE_LEVEL_DEBUG, __VA_ARGS__))
+
+#include <cutils/log.h>  //define Android logging macros
+#include "bt_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern unsigned char appl_trace_level;
+extern uint32_t ScrProtocolTraceFlag;
+
+#if (NXP_EXTNS == TRUE)
+extern unsigned char
+    appl_dta_mode_flag;  // defined for run time DTA mode selection
+#endif
+/*******************************************************************************
+**
+** Function:        initializeGlobalAppLogLevel
+**
+** Description:     Initialize and get global logging level from .conf or
+**                  Android property nfc.app_log_level.  The Android property
+**                  overrides .conf variable.
+**
+** Returns:         Global log level:
+**                  BT_TRACE_LEVEL_NONE    0 * No trace messages to be generated
+**                  BT_TRACE_LEVEL_ERROR   1 * Error condition trace messages
+**                  BT_TRACE_LEVEL_WARNING 2 * Warning condition trace messages
+**                  BT_TRACE_LEVEL_API     3 * API traces
+**                  BT_TRACE_LEVEL_EVENT   4 * Debug messages for events
+**                  BT_TRACE_LEVEL_DEBUG   5 * Debug messages (general)
+**
+*******************************************************************************/
+unsigned char initializeGlobalAppLogLevel();
+uint32_t initializeProtocolLogLevel();
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function:        initializeGlobalDtaMode
+**
+** Description:     Initialize and get global DTA mode from .conf
+**
+** Returns:         none:
+**
+*******************************************************************************/
+void initializeGlobalAppDtaMode();
+
+/*******************************************************************************
+**
+** Function:        enableDisableAppLevel
+**
+** Description:      This function can be used to enable/disable application
+**                   trace  logs
+**
+** Returns:         none:
+**
+*******************************************************************************/
+void enableDisableAppLevel(uint8_t type);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/include/android_logmsg.h b/src/include/android_logmsg.h
new file mode 100644
index 0000000..efcaf0a
--- /dev/null
+++ b/src/include/android_logmsg.h
@@ -0,0 +1,88 @@
+/******************************************************************************
+ *
+ *  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) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/* Decode NFC packets and print them to ADB log.
+* If protocol decoder is not present, then decode packets into hex numbers.
+******************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "data_types.h"
+#include "nfc_types.h"
+
+#define DISP_NCI ProtoDispAdapterDisplayNciPacket
+void ProtoDispAdapterDisplayNciPacket(uint8_t* nciPacket, uint16_t nciPacketLen,
+                                      bool is_recv);
+void ProtoDispAdapterUseRawOutput(bool isUseRaw);
+void ScrLog(uint32_t trace_set_mask, const char* fmt_str, ...);
+void LogMsg(uint32_t trace_set_mask, const char* fmt_str, ...);
+void LogMsg_0(uint32_t trace_set_mask, const char* p_str);
+void LogMsg_1(uint32_t trace_set_mask, const char* fmt_str, uintptr_t p1);
+void LogMsg_2(uint32_t trace_set_mask, const char* fmt_str, uintptr_t p1,
+              uintptr_t p2);
+void LogMsg_3(uint32_t trace_set_mask, const char* fmt_str, uintptr_t p1,
+              uintptr_t p2, uintptr_t p3);
+void LogMsg_4(uint32_t trace_set_mask, const char* fmt_str, uintptr_t p1,
+              uintptr_t p2, uintptr_t p3, uintptr_t p4);
+void LogMsg_5(uint32_t trace_set_mask, const char* fmt_str, uintptr_t p1,
+              uintptr_t p2, uintptr_t p3, uintptr_t p4, uintptr_t p5);
+void LogMsg_6(uint32_t trace_set_mask, const char* fmt_str, uintptr_t p1,
+              uintptr_t p2, uintptr_t p3, uintptr_t p4, uintptr_t p5,
+              uintptr_t p6);
+uint8_t* scru_dump_hex(uint8_t* p, char* pTitle, uint32_t len, uint32_t layer,
+                       uint32_t type);
+void BTDISP_LOCK_LOG();
+void BTDISP_UNLOCK_LOG();
+void BTDISP_INIT_LOCK();
+void BTDISP_UNINIT_LOCK();
+void DispHciCmd(NFC_HDR* p_buf);
+void DispHciEvt(NFC_HDR* p_buf);
+void DispLLCP(NFC_HDR* p_buf, bool is_recv);
+void DispHcp(uint8_t* data, uint16_t len, bool is_recv);
+void DispSNEP(uint8_t local_sap, uint8_t remote_sap, NFC_HDR* p_buf,
+              bool is_first, bool is_rx);
+void DispCHO(uint8_t* pMsg, uint32_t MsgLen, bool is_rx);
+void DispT3TagMessage(NFC_HDR* p_msg, bool is_rx);
+void DispRWT4Tags(NFC_HDR* p_buf, bool is_rx);
+void DispCET4Tags(NFC_HDR* p_buf, bool is_rx);
+void DispRWI93Tag(NFC_HDR* p_buf, bool is_rx, uint8_t command_to_respond);
+void DispNDEFMsg(uint8_t* pMsg, uint32_t MsgLen, bool is_recv);
+
+#ifdef __cplusplus
+};
+#endif
diff --git a/src/include/bt_trace.h b/src/include/bt_trace.h
new file mode 100644
index 0000000..ccb9795
--- /dev/null
+++ b/src/include/bt_trace.h
@@ -0,0 +1,1876 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef BT_TRACE_H
+#define BT_TRACE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* External declaration for appl_trace_level here to avoid to add the
+ * declaration in all the files using APPL_TRACExxx macros */
+extern uint8_t appl_trace_level;
+
+/* Prototype for message logging function. */
+extern void LogMsg(uint32_t trace_set_mask, const char* fmt_str, ...);
+extern void LogMsg_0(uint32_t trace_set_mask, const char* p_str);
+extern void LogMsg_1(uint32_t trace_set_mask, const char* fmt_str,
+                     uintptr_t p1);
+extern void LogMsg_2(uint32_t trace_set_mask, const char* fmt_str, uintptr_t p1,
+                     uintptr_t p2);
+extern void LogMsg_3(uint32_t trace_set_mask, const char* fmt_str, uintptr_t p1,
+                     uintptr_t p2, uintptr_t p3);
+extern void LogMsg_4(uint32_t trace_set_mask, const char* fmt_str, uintptr_t p1,
+                     uintptr_t p2, uintptr_t p3, uintptr_t p4);
+extern void LogMsg_5(uint32_t trace_set_mask, const char* fmt_str, uintptr_t p1,
+                     uintptr_t p2, uintptr_t p3, uintptr_t p4, uintptr_t p5);
+extern void LogMsg_6(uint32_t trace_set_mask, const char* fmt_str, uintptr_t p1,
+                     uintptr_t p2, uintptr_t p3, uintptr_t p4, uintptr_t p5,
+                     uintptr_t p6);
+
+#ifdef __cplusplus
+}
+#endif
+
+/******************************************************************************
+**
+** Trace configurable parameters
+**
+******************************************************************************/
+
+/* Enables or disables verbose trace information. */
+#ifndef BT_TRACE_VERBOSE
+#define BT_TRACE_VERBOSE false
+#endif
+
+/* Enables or disables protocol trace information. */
+#ifndef BT_TRACE_PROTOCOL
+#define BT_TRACE_PROTOCOL true /* Android requires true */
+#endif
+
+/******************************************************************************
+**
+** Trace Levels
+**
+** The following values may be used for different levels:
+**      BT_TRACE_LEVEL_NONE    0        * No trace messages to be generated
+**      BT_TRACE_LEVEL_ERROR   1        * Error condition trace messages
+**      BT_TRACE_LEVEL_WARNING 2        * Warning condition trace messages
+**      BT_TRACE_LEVEL_API     3        * API traces
+**      BT_TRACE_LEVEL_EVENT   4        * Debug messages for events
+**      BT_TRACE_LEVEL_DEBUG   5        * Debug messages (general)
+******************************************************************************/
+
+/* Core Stack default trace levels */
+#ifndef HCI_INITIAL_TRACE_LEVEL
+#define HCI_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef LLCP_INITIAL_TRACE_LEVEL
+#define LLCP_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef APPL_INITIAL_TRACE_LEVEL
+#define APPL_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef NFC_INITIAL_TRACE_LEVEL
+#define NFC_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef SMP_INITIAL_TRACE_LEVEL
+#define SMP_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#define BT_TRACE_0(l, t, m) \
+  LogMsg_0((TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t)), (m))
+#define BT_TRACE_1(l, t, m, p1)                                   \
+  LogMsg_1(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t), (m), \
+           (uintptr_t)(p1))
+#define BT_TRACE_2(l, t, m, p1, p2)                               \
+  LogMsg_2(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t), (m), \
+           (uintptr_t)(p1), (uintptr_t)(p2))
+#define BT_TRACE_3(l, t, m, p1, p2, p3)                           \
+  LogMsg_3(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t), (m), \
+           (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3))
+#define BT_TRACE_4(l, t, m, p1, p2, p3, p4)                       \
+  LogMsg_4(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t), (m), \
+           (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3), (uintptr_t)(p4))
+#define BT_TRACE_5(l, t, m, p1, p2, p3, p4, p5)                                \
+  LogMsg_5(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t), (m),              \
+           (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3), (uintptr_t)(p4), \
+           (uintptr_t)(p5))
+#define BT_TRACE_6(l, t, m, p1, p2, p3, p4, p5, p6)                            \
+  LogMsg_6(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t), (m),              \
+           (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3), (uintptr_t)(p4), \
+           (uintptr_t)(p5), (uintptr_t)(p6))
+
+#define BT_ERROR_TRACE_0(l, m) \
+  LogMsg_0(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | TRACE_TYPE_ERROR, (m))
+#define BT_ERROR_TRACE_1(l, m, p1)                                             \
+  LogMsg_1(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | TRACE_TYPE_ERROR, (m), \
+           (uintptr_t)(p1))
+#define BT_ERROR_TRACE_2(l, m, p1, p2)                                         \
+  LogMsg_2(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | TRACE_TYPE_ERROR, (m), \
+           (uintptr_t)(p1), (uintptr_t)(p2))
+#define BT_ERROR_TRACE_3(l, m, p1, p2, p3)                                     \
+  LogMsg_3(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | TRACE_TYPE_ERROR, (m), \
+           (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3))
+
+/* Define tracing for the LLCP unit
+*/
+#define LLCP_TRACE_ERROR0(m)                             \
+  {                                                      \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_ERROR)     \
+      BT_TRACE_0(TRACE_LAYER_LLCP, TRACE_TYPE_ERROR, m); \
+  }
+#define LLCP_TRACE_ERROR1(m, p1)                             \
+  {                                                          \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_ERROR)         \
+      BT_TRACE_1(TRACE_LAYER_LLCP, TRACE_TYPE_ERROR, m, p1); \
+  }
+#define LLCP_TRACE_ERROR2(m, p1, p2)                             \
+  {                                                              \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_ERROR)             \
+      BT_TRACE_2(TRACE_LAYER_LLCP, TRACE_TYPE_ERROR, m, p1, p2); \
+  }
+#define LLCP_TRACE_ERROR3(m, p1, p2, p3)                             \
+  {                                                                  \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                 \
+      BT_TRACE_3(TRACE_LAYER_LLCP, TRACE_TYPE_ERROR, m, p1, p2, p3); \
+  }
+#define LLCP_TRACE_ERROR4(m, p1, p2, p3, p4)                             \
+  {                                                                      \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                     \
+      BT_TRACE_4(TRACE_LAYER_LLCP, TRACE_TYPE_ERROR, m, p1, p2, p3, p4); \
+  }
+#define LLCP_TRACE_ERROR5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                          \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                         \
+      BT_TRACE_5(TRACE_LAYER_LLCP, TRACE_TYPE_ERROR, m, p1, p2, p3, p4, p5); \
+  }
+#define LLCP_TRACE_ERROR6(m, p1, p2, p3, p4, p5, p6)                        \
+  {                                                                         \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                        \
+      BT_TRACE_6(TRACE_LAYER_LLCP, TRACE_TYPE_ERROR, m, p1, p2, p3, p4, p5, \
+                 p6);                                                       \
+  }
+
+#define LLCP_TRACE_WARNING0(m)                             \
+  {                                                        \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_WARNING)     \
+      BT_TRACE_0(TRACE_LAYER_LLCP, TRACE_TYPE_WARNING, m); \
+  }
+#define LLCP_TRACE_WARNING1(m, p1)                             \
+  {                                                            \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_WARNING)         \
+      BT_TRACE_1(TRACE_LAYER_LLCP, TRACE_TYPE_WARNING, m, p1); \
+  }
+#define LLCP_TRACE_WARNING2(m, p1, p2)                             \
+  {                                                                \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_WARNING)             \
+      BT_TRACE_2(TRACE_LAYER_LLCP, TRACE_TYPE_WARNING, m, p1, p2); \
+  }
+#define LLCP_TRACE_WARNING3(m, p1, p2, p3)                             \
+  {                                                                    \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                 \
+      BT_TRACE_3(TRACE_LAYER_LLCP, TRACE_TYPE_WARNING, m, p1, p2, p3); \
+  }
+#define LLCP_TRACE_WARNING4(m, p1, p2, p3, p4)                             \
+  {                                                                        \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                     \
+      BT_TRACE_4(TRACE_LAYER_LLCP, TRACE_TYPE_WARNING, m, p1, p2, p3, p4); \
+  }
+#define LLCP_TRACE_WARNING5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                            \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                         \
+      BT_TRACE_5(TRACE_LAYER_LLCP, TRACE_TYPE_WARNING, m, p1, p2, p3, p4, p5); \
+  }
+#define LLCP_TRACE_WARNING6(m, p1, p2, p3, p4, p5, p6)                        \
+  {                                                                           \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                        \
+      BT_TRACE_6(TRACE_LAYER_LLCP, TRACE_TYPE_WARNING, m, p1, p2, p3, p4, p5, \
+                 p6);                                                         \
+  }
+
+#define LLCP_TRACE_API0(m)                             \
+  {                                                    \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_API)     \
+      BT_TRACE_0(TRACE_LAYER_LLCP, TRACE_TYPE_API, m); \
+  }
+#define LLCP_TRACE_API1(m, p1)                             \
+  {                                                        \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_API)         \
+      BT_TRACE_1(TRACE_LAYER_LLCP, TRACE_TYPE_API, m, p1); \
+  }
+#define LLCP_TRACE_API2(m, p1, p2)                             \
+  {                                                            \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_API)             \
+      BT_TRACE_2(TRACE_LAYER_LLCP, TRACE_TYPE_API, m, p1, p2); \
+  }
+#define LLCP_TRACE_API3(m, p1, p2, p3)                             \
+  {                                                                \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_API)                 \
+      BT_TRACE_3(TRACE_LAYER_LLCP, TRACE_TYPE_API, m, p1, p2, p3); \
+  }
+#define LLCP_TRACE_API4(m, p1, p2, p3, p4)                             \
+  {                                                                    \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_API)                     \
+      BT_TRACE_4(TRACE_LAYER_LLCP, TRACE_TYPE_API, m, p1, p2, p3, p4); \
+  }
+#define LLCP_TRACE_API5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                        \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_API)                         \
+      BT_TRACE_5(TRACE_LAYER_LLCP, TRACE_TYPE_API, m, p1, p2, p3, p4, p5); \
+  }
+#define LLCP_TRACE_API6(m, p1, p2, p3, p4, p5, p6)                             \
+  {                                                                            \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_API)                             \
+      BT_TRACE_6(TRACE_LAYER_LLCP, TRACE_TYPE_API, m, p1, p2, p3, p4, p5, p6); \
+  }
+
+#define LLCP_TRACE_EVENT0(m)                             \
+  {                                                      \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_EVENT)     \
+      BT_TRACE_0(TRACE_LAYER_LLCP, TRACE_TYPE_EVENT, m); \
+  }
+#define LLCP_TRACE_EVENT1(m, p1)                             \
+  {                                                          \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_EVENT)         \
+      BT_TRACE_1(TRACE_LAYER_LLCP, TRACE_TYPE_EVENT, m, p1); \
+  }
+#define LLCP_TRACE_EVENT2(m, p1, p2)                             \
+  {                                                              \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_EVENT)             \
+      BT_TRACE_2(TRACE_LAYER_LLCP, TRACE_TYPE_EVENT, m, p1, p2); \
+  }
+#define LLCP_TRACE_EVENT3(m, p1, p2, p3)                             \
+  {                                                                  \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                 \
+      BT_TRACE_3(TRACE_LAYER_LLCP, TRACE_TYPE_EVENT, m, p1, p2, p3); \
+  }
+#define LLCP_TRACE_EVENT4(m, p1, p2, p3, p4)                             \
+  {                                                                      \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                     \
+      BT_TRACE_4(TRACE_LAYER_LLCP, TRACE_TYPE_EVENT, m, p1, p2, p3, p4); \
+  }
+#define LLCP_TRACE_EVENT5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                          \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                         \
+      BT_TRACE_5(TRACE_LAYER_LLCP, TRACE_TYPE_EVENT, m, p1, p2, p3, p4, p5); \
+  }
+#define LLCP_TRACE_EVENT6(m, p1, p2, p3, p4, p5, p6)                        \
+  {                                                                         \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                        \
+      BT_TRACE_6(TRACE_LAYER_LLCP, TRACE_TYPE_EVENT, m, p1, p2, p3, p4, p5, \
+                 p6);                                                       \
+  }
+
+#define LLCP_TRACE_DEBUG0(m)                             \
+  {                                                      \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)     \
+      BT_TRACE_0(TRACE_LAYER_LLCP, TRACE_TYPE_DEBUG, m); \
+  }
+#define LLCP_TRACE_DEBUG1(m, p1)                             \
+  {                                                          \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)         \
+      BT_TRACE_1(TRACE_LAYER_LLCP, TRACE_TYPE_DEBUG, m, p1); \
+  }
+#define LLCP_TRACE_DEBUG2(m, p1, p2)                             \
+  {                                                              \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)             \
+      BT_TRACE_2(TRACE_LAYER_LLCP, TRACE_TYPE_DEBUG, m, p1, p2); \
+  }
+#define LLCP_TRACE_DEBUG3(m, p1, p2, p3)                             \
+  {                                                                  \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                 \
+      BT_TRACE_3(TRACE_LAYER_LLCP, TRACE_TYPE_DEBUG, m, p1, p2, p3); \
+  }
+#define LLCP_TRACE_DEBUG4(m, p1, p2, p3, p4)                             \
+  {                                                                      \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                     \
+      BT_TRACE_4(TRACE_LAYER_LLCP, TRACE_TYPE_DEBUG, m, p1, p2, p3, p4); \
+  }
+#define LLCP_TRACE_DEBUG5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                          \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                         \
+      BT_TRACE_5(TRACE_LAYER_LLCP, TRACE_TYPE_DEBUG, m, p1, p2, p3, p4, p5); \
+  }
+#define LLCP_TRACE_DEBUG6(m, p1, p2, p3, p4, p5, p6)                        \
+  {                                                                         \
+    if (llcp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                        \
+      BT_TRACE_6(TRACE_LAYER_LLCP, TRACE_TYPE_DEBUG, m, p1, p2, p3, p4, p5, \
+                 p6);                                                       \
+  }
+
+/* Define tracing for the NFC unit
+*/
+#define NFC_TRACE_ERROR0(m)                             \
+  {                                                     \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR)     \
+      BT_TRACE_0(TRACE_LAYER_NFC, TRACE_TYPE_ERROR, m); \
+  }
+#define NFC_TRACE_ERROR1(m, p1)                             \
+  {                                                         \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR)         \
+      BT_TRACE_1(TRACE_LAYER_NFC, TRACE_TYPE_ERROR, m, p1); \
+  }
+#define NFC_TRACE_ERROR2(m, p1, p2)                             \
+  {                                                             \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR)             \
+      BT_TRACE_2(TRACE_LAYER_NFC, TRACE_TYPE_ERROR, m, p1, p2); \
+  }
+#define NFC_TRACE_ERROR3(m, p1, p2, p3)                             \
+  {                                                                 \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                 \
+      BT_TRACE_3(TRACE_LAYER_NFC, TRACE_TYPE_ERROR, m, p1, p2, p3); \
+  }
+#define NFC_TRACE_ERROR4(m, p1, p2, p3, p4)                             \
+  {                                                                     \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                     \
+      BT_TRACE_4(TRACE_LAYER_NFC, TRACE_TYPE_ERROR, m, p1, p2, p3, p4); \
+  }
+#define NFC_TRACE_ERROR5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                         \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                         \
+      BT_TRACE_5(TRACE_LAYER_NFC, TRACE_TYPE_ERROR, m, p1, p2, p3, p4, p5); \
+  }
+#define NFC_TRACE_ERROR6(m, p1, p2, p3, p4, p5, p6)                        \
+  {                                                                        \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                        \
+      BT_TRACE_6(TRACE_LAYER_NFC, TRACE_TYPE_ERROR, m, p1, p2, p3, p4, p5, \
+                 p6);                                                      \
+  }
+
+#define NFC_TRACE_WARNING0(m)                             \
+  {                                                       \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING)     \
+      BT_TRACE_0(TRACE_LAYER_NFC, TRACE_TYPE_WARNING, m); \
+  }
+#define NFC_TRACE_WARNING1(m, p1)                             \
+  {                                                           \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING)         \
+      BT_TRACE_1(TRACE_LAYER_NFC, TRACE_TYPE_WARNING, m, p1); \
+  }
+#define NFC_TRACE_WARNING2(m, p1, p2)                             \
+  {                                                               \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING)             \
+      BT_TRACE_2(TRACE_LAYER_NFC, TRACE_TYPE_WARNING, m, p1, p2); \
+  }
+#define NFC_TRACE_WARNING3(m, p1, p2, p3)                             \
+  {                                                                   \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                 \
+      BT_TRACE_3(TRACE_LAYER_NFC, TRACE_TYPE_WARNING, m, p1, p2, p3); \
+  }
+#define NFC_TRACE_WARNING4(m, p1, p2, p3, p4)                             \
+  {                                                                       \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                     \
+      BT_TRACE_4(TRACE_LAYER_NFC, TRACE_TYPE_WARNING, m, p1, p2, p3, p4); \
+  }
+#define NFC_TRACE_WARNING5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                           \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                         \
+      BT_TRACE_5(TRACE_LAYER_NFC, TRACE_TYPE_WARNING, m, p1, p2, p3, p4, p5); \
+  }
+#define NFC_TRACE_WARNING6(m, p1, p2, p3, p4, p5, p6)                        \
+  {                                                                          \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                        \
+      BT_TRACE_6(TRACE_LAYER_NFC, TRACE_TYPE_WARNING, m, p1, p2, p3, p4, p5, \
+                 p6);                                                        \
+  }
+
+#define NFC_TRACE_API0(m)                             \
+  {                                                   \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_API)     \
+      BT_TRACE_0(TRACE_LAYER_NFC, TRACE_TYPE_API, m); \
+  }
+#define NFC_TRACE_API1(m, p1)                             \
+  {                                                       \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_API)         \
+      BT_TRACE_1(TRACE_LAYER_NFC, TRACE_TYPE_API, m, p1); \
+  }
+#define NFC_TRACE_API2(m, p1, p2)                             \
+  {                                                           \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_API)             \
+      BT_TRACE_2(TRACE_LAYER_NFC, TRACE_TYPE_API, m, p1, p2); \
+  }
+#define NFC_TRACE_API3(m, p1, p2, p3)                             \
+  {                                                               \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_API)                 \
+      BT_TRACE_3(TRACE_LAYER_NFC, TRACE_TYPE_API, m, p1, p2, p3); \
+  }
+#define NFC_TRACE_API4(m, p1, p2, p3, p4)                             \
+  {                                                                   \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_API)                     \
+      BT_TRACE_4(TRACE_LAYER_NFC, TRACE_TYPE_API, m, p1, p2, p3, p4); \
+  }
+#define NFC_TRACE_API5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                       \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_API)                         \
+      BT_TRACE_5(TRACE_LAYER_NFC, TRACE_TYPE_API, m, p1, p2, p3, p4, p5); \
+  }
+#define NFC_TRACE_API6(m, p1, p2, p3, p4, p5, p6)                             \
+  {                                                                           \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_API)                             \
+      BT_TRACE_6(TRACE_LAYER_NFC, TRACE_TYPE_API, m, p1, p2, p3, p4, p5, p6); \
+  }
+
+#define NFC_TRACE_EVENT0(m)                             \
+  {                                                     \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT)     \
+      BT_TRACE_0(TRACE_LAYER_NFC, TRACE_TYPE_EVENT, m); \
+  }
+#define NFC_TRACE_EVENT1(m, p1)                             \
+  {                                                         \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT)         \
+      BT_TRACE_1(TRACE_LAYER_NFC, TRACE_TYPE_EVENT, m, p1); \
+  }
+#define NFC_TRACE_EVENT2(m, p1, p2)                             \
+  {                                                             \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT)             \
+      BT_TRACE_2(TRACE_LAYER_NFC, TRACE_TYPE_EVENT, m, p1, p2); \
+  }
+#define NFC_TRACE_EVENT3(m, p1, p2, p3)                             \
+  {                                                                 \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                 \
+      BT_TRACE_3(TRACE_LAYER_NFC, TRACE_TYPE_EVENT, m, p1, p2, p3); \
+  }
+#define NFC_TRACE_EVENT4(m, p1, p2, p3, p4)                             \
+  {                                                                     \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                     \
+      BT_TRACE_4(TRACE_LAYER_NFC, TRACE_TYPE_EVENT, m, p1, p2, p3, p4); \
+  }
+#define NFC_TRACE_EVENT5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                         \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                         \
+      BT_TRACE_5(TRACE_LAYER_NFC, TRACE_TYPE_EVENT, m, p1, p2, p3, p4, p5); \
+  }
+#define NFC_TRACE_EVENT6(m, p1, p2, p3, p4, p5, p6)                        \
+  {                                                                        \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                        \
+      BT_TRACE_6(TRACE_LAYER_NFC, TRACE_TYPE_EVENT, m, p1, p2, p3, p4, p5, \
+                 p6);                                                      \
+  }
+
+#define NFC_TRACE_DEBUG0(m)                             \
+  {                                                     \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)     \
+      BT_TRACE_0(TRACE_LAYER_NFC, TRACE_TYPE_DEBUG, m); \
+  }
+#define NFC_TRACE_DEBUG1(m, p1)                             \
+  {                                                         \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)         \
+      BT_TRACE_1(TRACE_LAYER_NFC, TRACE_TYPE_DEBUG, m, p1); \
+  }
+#define NFC_TRACE_DEBUG2(m, p1, p2)                             \
+  {                                                             \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)             \
+      BT_TRACE_2(TRACE_LAYER_NFC, TRACE_TYPE_DEBUG, m, p1, p2); \
+  }
+#define NFC_TRACE_DEBUG3(m, p1, p2, p3)                             \
+  {                                                                 \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                 \
+      BT_TRACE_3(TRACE_LAYER_NFC, TRACE_TYPE_DEBUG, m, p1, p2, p3); \
+  }
+#define NFC_TRACE_DEBUG4(m, p1, p2, p3, p4)                             \
+  {                                                                     \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                     \
+      BT_TRACE_4(TRACE_LAYER_NFC, TRACE_TYPE_DEBUG, m, p1, p2, p3, p4); \
+  }
+#define NFC_TRACE_DEBUG5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                         \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                         \
+      BT_TRACE_5(TRACE_LAYER_NFC, TRACE_TYPE_DEBUG, m, p1, p2, p3, p4, p5); \
+  }
+#define NFC_TRACE_DEBUG6(m, p1, p2, p3, p4, p5, p6)                        \
+  {                                                                        \
+    if (nfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                        \
+      BT_TRACE_6(TRACE_LAYER_NFC, TRACE_TYPE_DEBUG, m, p1, p2, p3, p4, p5, \
+                 p6);                                                      \
+  }
+
+#define NCI_TRACE_ERROR0(m)                             \
+  {                                                     \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_ERROR)    \
+      BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m); \
+  }
+#define NCI_TRACE_ERROR1(m, p1)                             \
+  {                                                         \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_ERROR)        \
+      BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m, p1); \
+  }
+#define NCI_TRACE_ERROR2(m, p1, p2)                             \
+  {                                                             \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_ERROR)            \
+      BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m, p1, p2); \
+  }
+#define NCI_TRACE_ERROR3(m, p1, p2, p3)                             \
+  {                                                                 \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                \
+      BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m, p1, p2, p3); \
+  }
+#define NCI_TRACE_ERROR4(m, p1, p2, p3, p4)                             \
+  {                                                                     \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                    \
+      BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m, p1, p2, p3, p4); \
+  }
+#define NCI_TRACE_ERROR5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                         \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                        \
+      BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m, p1, p2, p3, p4, p5); \
+  }
+#define NCI_TRACE_ERROR6(m, p1, p2, p3, p4, p5, p6)                        \
+  {                                                                        \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                       \
+      BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m, p1, p2, p3, p4, p5, \
+                 p6);                                                      \
+  }
+
+#define NCI_TRACE_WARNING0(m)                             \
+  {                                                       \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_WARNING)    \
+      BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m); \
+  }
+#define NCI_TRACE_WARNING1(m, p1)                             \
+  {                                                           \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_WARNING)        \
+      BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m, p1); \
+  }
+#define NCI_TRACE_WARNING2(m, p1, p2)                             \
+  {                                                               \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_WARNING)            \
+      BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m, p1, p2); \
+  }
+#define NCI_TRACE_WARNING3(m, p1, p2, p3)                             \
+  {                                                                   \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                \
+      BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m, p1, p2, p3); \
+  }
+#define NCI_TRACE_WARNING4(m, p1, p2, p3, p4)                             \
+  {                                                                       \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                    \
+      BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m, p1, p2, p3, p4); \
+  }
+#define NCI_TRACE_WARNING5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                           \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                        \
+      BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m, p1, p2, p3, p4, p5); \
+  }
+#define NCI_TRACE_WARNING6(m, p1, p2, p3, p4, p5, p6)                        \
+  {                                                                          \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                       \
+      BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m, p1, p2, p3, p4, p5, \
+                 p6);                                                        \
+  }
+
+#define NCI_TRACE_API0(m)                             \
+  {                                                   \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_API)    \
+      BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_API, m); \
+  }
+#define NCI_TRACE_API1(m, p1)                             \
+  {                                                       \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_API)        \
+      BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_API, m, p1); \
+  }
+#define NCI_TRACE_API2(m, p1, p2)                             \
+  {                                                           \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_API)            \
+      BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_API, m, p1, p2); \
+  }
+#define NCI_TRACE_API3(m, p1, p2, p3)                             \
+  {                                                               \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_API)                \
+      BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_API, m, p1, p2, p3); \
+  }
+#define NCI_TRACE_API4(m, p1, p2, p3, p4)                             \
+  {                                                                   \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_API)                    \
+      BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_API, m, p1, p2, p3, p4); \
+  }
+#define NCI_TRACE_API5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                       \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_API)                        \
+      BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_API, m, p1, p2, p3, p4, p5); \
+  }
+#define NCI_TRACE_API6(m, p1, p2, p3, p4, p5, p6)                             \
+  {                                                                           \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_API)                            \
+      BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_API, m, p1, p2, p3, p4, p5, p6); \
+  }
+
+#define NCI_TRACE_EVENT0(m)                             \
+  {                                                     \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_EVENT)    \
+      BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m); \
+  }
+#define NCI_TRACE_EVENT1(m, p1)                             \
+  {                                                         \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_EVENT)        \
+      BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m, p1); \
+  }
+#define NCI_TRACE_EVENT2(m, p1, p2)                             \
+  {                                                             \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_EVENT)            \
+      BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m, p1, p2); \
+  }
+#define NCI_TRACE_EVENT3(m, p1, p2, p3)                             \
+  {                                                                 \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                \
+      BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m, p1, p2, p3); \
+  }
+#define NCI_TRACE_EVENT4(m, p1, p2, p3, p4)                             \
+  {                                                                     \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                    \
+      BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m, p1, p2, p3, p4); \
+  }
+#define NCI_TRACE_EVENT5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                         \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                        \
+      BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m, p1, p2, p3, p4, p5); \
+  }
+#define NCI_TRACE_EVENT6(m, p1, p2, p3, p4, p5, p6)                        \
+  {                                                                        \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                       \
+      BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m, p1, p2, p3, p4, p5, \
+                 p6);                                                      \
+  }
+
+#define NCI_TRACE_DEBUG0(m)                             \
+  {                                                     \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)    \
+      BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m); \
+  }
+#define NCI_TRACE_DEBUG1(m, p1)                             \
+  {                                                         \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)        \
+      BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m, p1); \
+  }
+#define NCI_TRACE_DEBUG2(m, p1, p2)                             \
+  {                                                             \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)            \
+      BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m, p1, p2); \
+  }
+#define NCI_TRACE_DEBUG3(m, p1, p2, p3)                             \
+  {                                                                 \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                \
+      BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m, p1, p2, p3); \
+  }
+#define NCI_TRACE_DEBUG4(m, p1, p2, p3, p4)                             \
+  {                                                                     \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                    \
+      BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m, p1, p2, p3, p4); \
+  }
+#define NCI_TRACE_DEBUG5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                         \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                        \
+      BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m, p1, p2, p3, p4, p5); \
+  }
+#define NCI_TRACE_DEBUG6(m, p1, p2, p3, p4, p5, p6)                        \
+  {                                                                        \
+    if (ncit_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                       \
+      BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m, p1, p2, p3, p4, p5, \
+                 p6);                                                      \
+  }
+
+#define RW_TRACE_ERROR0(m)                             \
+  {                                                    \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_ERROR)     \
+      BT_TRACE_0(TRACE_LAYER_RW, TRACE_TYPE_ERROR, m); \
+  }
+#define RW_TRACE_ERROR1(m, p1)                             \
+  {                                                        \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_ERROR)         \
+      BT_TRACE_1(TRACE_LAYER_RW, TRACE_TYPE_ERROR, m, p1); \
+  }
+#define RW_TRACE_ERROR2(m, p1, p2)                             \
+  {                                                            \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_ERROR)             \
+      BT_TRACE_2(TRACE_LAYER_RW, TRACE_TYPE_ERROR, m, p1, p2); \
+  }
+#define RW_TRACE_ERROR3(m, p1, p2, p3)                             \
+  {                                                                \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                 \
+      BT_TRACE_3(TRACE_LAYER_RW, TRACE_TYPE_ERROR, m, p1, p2, p3); \
+  }
+#define RW_TRACE_ERROR4(m, p1, p2, p3, p4)                             \
+  {                                                                    \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                     \
+      BT_TRACE_4(TRACE_LAYER_RW, TRACE_TYPE_ERROR, m, p1, p2, p3, p4); \
+  }
+#define RW_TRACE_ERROR5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                        \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                         \
+      BT_TRACE_5(TRACE_LAYER_RW, TRACE_TYPE_ERROR, m, p1, p2, p3, p4, p5); \
+  }
+#define RW_TRACE_ERROR6(m, p1, p2, p3, p4, p5, p6)                             \
+  {                                                                            \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                             \
+      BT_TRACE_6(TRACE_LAYER_RW, TRACE_TYPE_ERROR, m, p1, p2, p3, p4, p5, p6); \
+  }
+
+#define RW_TRACE_WARNING0(m)                             \
+  {                                                      \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_WARNING)     \
+      BT_TRACE_0(TRACE_LAYER_RW, TRACE_TYPE_WARNING, m); \
+  }
+#define RW_TRACE_WARNING1(m, p1)                             \
+  {                                                          \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_WARNING)         \
+      BT_TRACE_1(TRACE_LAYER_RW, TRACE_TYPE_WARNING, m, p1); \
+  }
+#define RW_TRACE_WARNING2(m, p1, p2)                             \
+  {                                                              \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_WARNING)             \
+      BT_TRACE_2(TRACE_LAYER_RW, TRACE_TYPE_WARNING, m, p1, p2); \
+  }
+#define RW_TRACE_WARNING3(m, p1, p2, p3)                             \
+  {                                                                  \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                 \
+      BT_TRACE_3(TRACE_LAYER_RW, TRACE_TYPE_WARNING, m, p1, p2, p3); \
+  }
+#define RW_TRACE_WARNING4(m, p1, p2, p3, p4)                             \
+  {                                                                      \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                     \
+      BT_TRACE_4(TRACE_LAYER_RW, TRACE_TYPE_WARNING, m, p1, p2, p3, p4); \
+  }
+#define RW_TRACE_WARNING5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                          \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                         \
+      BT_TRACE_5(TRACE_LAYER_RW, TRACE_TYPE_WARNING, m, p1, p2, p3, p4, p5); \
+  }
+#define RW_TRACE_WARNING6(m, p1, p2, p3, p4, p5, p6)                        \
+  {                                                                         \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                        \
+      BT_TRACE_6(TRACE_LAYER_RW, TRACE_TYPE_WARNING, m, p1, p2, p3, p4, p5, \
+                 p6);                                                       \
+  }
+
+#define RW_TRACE_API0(m)                             \
+  {                                                  \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_API)     \
+      BT_TRACE_0(TRACE_LAYER_RW, TRACE_TYPE_API, m); \
+  }
+#define RW_TRACE_API1(m, p1)                             \
+  {                                                      \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_API)         \
+      BT_TRACE_1(TRACE_LAYER_RW, TRACE_TYPE_API, m, p1); \
+  }
+#define RW_TRACE_API2(m, p1, p2)                             \
+  {                                                          \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_API)             \
+      BT_TRACE_2(TRACE_LAYER_RW, TRACE_TYPE_API, m, p1, p2); \
+  }
+#define RW_TRACE_API3(m, p1, p2, p3)                             \
+  {                                                              \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_API)                 \
+      BT_TRACE_3(TRACE_LAYER_RW, TRACE_TYPE_API, m, p1, p2, p3); \
+  }
+#define RW_TRACE_API4(m, p1, p2, p3, p4)                             \
+  {                                                                  \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_API)                     \
+      BT_TRACE_4(TRACE_LAYER_RW, TRACE_TYPE_API, m, p1, p2, p3, p4); \
+  }
+#define RW_TRACE_API5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                      \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_API)                         \
+      BT_TRACE_5(TRACE_LAYER_RW, TRACE_TYPE_API, m, p1, p2, p3, p4, p5); \
+  }
+#define RW_TRACE_API6(m, p1, p2, p3, p4, p5, p6)                             \
+  {                                                                          \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_API)                             \
+      BT_TRACE_6(TRACE_LAYER_RW, TRACE_TYPE_API, m, p1, p2, p3, p4, p5, p6); \
+  }
+
+#define RW_TRACE_EVENT0(m)                             \
+  {                                                    \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_EVENT)     \
+      BT_TRACE_0(TRACE_LAYER_RW, TRACE_TYPE_EVENT, m); \
+  }
+#define RW_TRACE_EVENT1(m, p1)                             \
+  {                                                        \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_EVENT)         \
+      BT_TRACE_1(TRACE_LAYER_RW, TRACE_TYPE_EVENT, m, p1); \
+  }
+#define RW_TRACE_EVENT2(m, p1, p2)                             \
+  {                                                            \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_EVENT)             \
+      BT_TRACE_2(TRACE_LAYER_RW, TRACE_TYPE_EVENT, m, p1, p2); \
+  }
+#define RW_TRACE_EVENT3(m, p1, p2, p3)                             \
+  {                                                                \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                 \
+      BT_TRACE_3(TRACE_LAYER_RW, TRACE_TYPE_EVENT, m, p1, p2, p3); \
+  }
+#define RW_TRACE_EVENT4(m, p1, p2, p3, p4)                             \
+  {                                                                    \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                     \
+      BT_TRACE_4(TRACE_LAYER_RW, TRACE_TYPE_EVENT, m, p1, p2, p3, p4); \
+  }
+#define RW_TRACE_EVENT5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                        \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                         \
+      BT_TRACE_5(TRACE_LAYER_RW, TRACE_TYPE_EVENT, m, p1, p2, p3, p4, p5); \
+  }
+#define RW_TRACE_EVENT6(m, p1, p2, p3, p4, p5, p6)                             \
+  {                                                                            \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                             \
+      BT_TRACE_6(TRACE_LAYER_RW, TRACE_TYPE_EVENT, m, p1, p2, p3, p4, p5, p6); \
+  }
+
+#define RW_TRACE_DEBUG0(m)                             \
+  {                                                    \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)     \
+      BT_TRACE_0(TRACE_LAYER_RW, TRACE_TYPE_DEBUG, m); \
+  }
+#define RW_TRACE_DEBUG1(m, p1)                             \
+  {                                                        \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)         \
+      BT_TRACE_1(TRACE_LAYER_RW, TRACE_TYPE_DEBUG, m, p1); \
+  }
+#define RW_TRACE_DEBUG2(m, p1, p2)                             \
+  {                                                            \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)             \
+      BT_TRACE_2(TRACE_LAYER_RW, TRACE_TYPE_DEBUG, m, p1, p2); \
+  }
+#define RW_TRACE_DEBUG3(m, p1, p2, p3)                             \
+  {                                                                \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                 \
+      BT_TRACE_3(TRACE_LAYER_RW, TRACE_TYPE_DEBUG, m, p1, p2, p3); \
+  }
+#define RW_TRACE_DEBUG4(m, p1, p2, p3, p4)                             \
+  {                                                                    \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                     \
+      BT_TRACE_4(TRACE_LAYER_RW, TRACE_TYPE_DEBUG, m, p1, p2, p3, p4); \
+  }
+#define RW_TRACE_DEBUG5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                        \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                         \
+      BT_TRACE_5(TRACE_LAYER_RW, TRACE_TYPE_DEBUG, m, p1, p2, p3, p4, p5); \
+  }
+#define RW_TRACE_DEBUG6(m, p1, p2, p3, p4, p5, p6)                             \
+  {                                                                            \
+    if (rw_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                             \
+      BT_TRACE_6(TRACE_LAYER_RW, TRACE_TYPE_DEBUG, m, p1, p2, p3, p4, p5, p6); \
+  }
+
+#define CE_TRACE_ERROR0(m)                             \
+  {                                                    \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_ERROR)     \
+      BT_TRACE_0(TRACE_LAYER_CE, TRACE_TYPE_ERROR, m); \
+  }
+#define CE_TRACE_ERROR1(m, p1)                             \
+  {                                                        \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_ERROR)         \
+      BT_TRACE_1(TRACE_LAYER_CE, TRACE_TYPE_ERROR, m, p1); \
+  }
+#define CE_TRACE_ERROR2(m, p1, p2)                             \
+  {                                                            \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_ERROR)             \
+      BT_TRACE_2(TRACE_LAYER_CE, TRACE_TYPE_ERROR, m, p1, p2); \
+  }
+#define CE_TRACE_ERROR3(m, p1, p2, p3)                             \
+  {                                                                \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                 \
+      BT_TRACE_3(TRACE_LAYER_CE, TRACE_TYPE_ERROR, m, p1, p2, p3); \
+  }
+#define CE_TRACE_ERROR4(m, p1, p2, p3, p4)                             \
+  {                                                                    \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                     \
+      BT_TRACE_4(TRACE_LAYER_CE, TRACE_TYPE_ERROR, m, p1, p2, p3, p4); \
+  }
+#define CE_TRACE_ERROR5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                        \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                         \
+      BT_TRACE_5(TRACE_LAYER_CE, TRACE_TYPE_ERROR, m, p1, p2, p3, p4, p5); \
+  }
+#define CE_TRACE_ERROR6(m, p1, p2, p3, p4, p5, p6)                             \
+  {                                                                            \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                             \
+      BT_TRACE_6(TRACE_LAYER_CE, TRACE_TYPE_ERROR, m, p1, p2, p3, p4, p5, p6); \
+  }
+
+#define CE_TRACE_WARNING0(m)                             \
+  {                                                      \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_WARNING)     \
+      BT_TRACE_0(TRACE_LAYER_CE, TRACE_TYPE_WARNING, m); \
+  }
+#define CE_TRACE_WARNING1(m, p1)                             \
+  {                                                          \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_WARNING)         \
+      BT_TRACE_1(TRACE_LAYER_CE, TRACE_TYPE_WARNING, m, p1); \
+  }
+#define CE_TRACE_WARNING2(m, p1, p2)                             \
+  {                                                              \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_WARNING)             \
+      BT_TRACE_2(TRACE_LAYER_CE, TRACE_TYPE_WARNING, m, p1, p2); \
+  }
+#define CE_TRACE_WARNING3(m, p1, p2, p3)                             \
+  {                                                                  \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                 \
+      BT_TRACE_3(TRACE_LAYER_CE, TRACE_TYPE_WARNING, m, p1, p2, p3); \
+  }
+#define CE_TRACE_WARNING4(m, p1, p2, p3, p4)                             \
+  {                                                                      \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                     \
+      BT_TRACE_4(TRACE_LAYER_CE, TRACE_TYPE_WARNING, m, p1, p2, p3, p4); \
+  }
+#define CE_TRACE_WARNING5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                          \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                         \
+      BT_TRACE_5(TRACE_LAYER_CE, TRACE_TYPE_WARNING, m, p1, p2, p3, p4, p5); \
+  }
+#define CE_TRACE_WARNING6(m, p1, p2, p3, p4, p5, p6)                        \
+  {                                                                         \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                        \
+      BT_TRACE_6(TRACE_LAYER_CE, TRACE_TYPE_WARNING, m, p1, p2, p3, p4, p5, \
+                 p6);                                                       \
+  }
+
+#define CE_TRACE_API0(m)                             \
+  {                                                  \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_API)     \
+      BT_TRACE_0(TRACE_LAYER_CE, TRACE_TYPE_API, m); \
+  }
+#define CE_TRACE_API1(m, p1)                             \
+  {                                                      \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_API)         \
+      BT_TRACE_1(TRACE_LAYER_CE, TRACE_TYPE_API, m, p1); \
+  }
+#define CE_TRACE_API2(m, p1, p2)                             \
+  {                                                          \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_API)             \
+      BT_TRACE_2(TRACE_LAYER_CE, TRACE_TYPE_API, m, p1, p2); \
+  }
+#define CE_TRACE_API3(m, p1, p2, p3)                             \
+  {                                                              \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_API)                 \
+      BT_TRACE_3(TRACE_LAYER_CE, TRACE_TYPE_API, m, p1, p2, p3); \
+  }
+#define CE_TRACE_API4(m, p1, p2, p3, p4)                             \
+  {                                                                  \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_API)                     \
+      BT_TRACE_4(TRACE_LAYER_CE, TRACE_TYPE_API, m, p1, p2, p3, p4); \
+  }
+#define CE_TRACE_API5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                      \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_API)                         \
+      BT_TRACE_5(TRACE_LAYER_CE, TRACE_TYPE_API, m, p1, p2, p3, p4, p5); \
+  }
+#define CE_TRACE_API6(m, p1, p2, p3, p4, p5, p6)                             \
+  {                                                                          \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_API)                             \
+      BT_TRACE_6(TRACE_LAYER_CE, TRACE_TYPE_API, m, p1, p2, p3, p4, p5, p6); \
+  }
+
+#define CE_TRACE_EVENT0(m)                             \
+  {                                                    \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_EVENT)     \
+      BT_TRACE_0(TRACE_LAYER_CE, TRACE_TYPE_EVENT, m); \
+  }
+#define CE_TRACE_EVENT1(m, p1)                             \
+  {                                                        \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_EVENT)         \
+      BT_TRACE_1(TRACE_LAYER_CE, TRACE_TYPE_EVENT, m, p1); \
+  }
+#define CE_TRACE_EVENT2(m, p1, p2)                             \
+  {                                                            \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_EVENT)             \
+      BT_TRACE_2(TRACE_LAYER_CE, TRACE_TYPE_EVENT, m, p1, p2); \
+  }
+#define CE_TRACE_EVENT3(m, p1, p2, p3)                             \
+  {                                                                \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                 \
+      BT_TRACE_3(TRACE_LAYER_CE, TRACE_TYPE_EVENT, m, p1, p2, p3); \
+  }
+#define CE_TRACE_EVENT4(m, p1, p2, p3, p4)                             \
+  {                                                                    \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                     \
+      BT_TRACE_4(TRACE_LAYER_CE, TRACE_TYPE_EVENT, m, p1, p2, p3, p4); \
+  }
+#define CE_TRACE_EVENT5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                        \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                         \
+      BT_TRACE_5(TRACE_LAYER_CE, TRACE_TYPE_EVENT, m, p1, p2, p3, p4, p5); \
+  }
+#define CE_TRACE_EVENT6(m, p1, p2, p3, p4, p5, p6)                             \
+  {                                                                            \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                             \
+      BT_TRACE_6(TRACE_LAYER_CE, TRACE_TYPE_EVENT, m, p1, p2, p3, p4, p5, p6); \
+  }
+
+#define CE_TRACE_DEBUG0(m)                             \
+  {                                                    \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)     \
+      BT_TRACE_0(TRACE_LAYER_CE, TRACE_TYPE_DEBUG, m); \
+  }
+#define CE_TRACE_DEBUG1(m, p1)                             \
+  {                                                        \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)         \
+      BT_TRACE_1(TRACE_LAYER_CE, TRACE_TYPE_DEBUG, m, p1); \
+  }
+#define CE_TRACE_DEBUG2(m, p1, p2)                             \
+  {                                                            \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)             \
+      BT_TRACE_2(TRACE_LAYER_CE, TRACE_TYPE_DEBUG, m, p1, p2); \
+  }
+#define CE_TRACE_DEBUG3(m, p1, p2, p3)                             \
+  {                                                                \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                 \
+      BT_TRACE_3(TRACE_LAYER_CE, TRACE_TYPE_DEBUG, m, p1, p2, p3); \
+  }
+#define CE_TRACE_DEBUG4(m, p1, p2, p3, p4)                             \
+  {                                                                    \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                     \
+      BT_TRACE_4(TRACE_LAYER_CE, TRACE_TYPE_DEBUG, m, p1, p2, p3, p4); \
+  }
+#define CE_TRACE_DEBUG5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                        \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                         \
+      BT_TRACE_5(TRACE_LAYER_CE, TRACE_TYPE_DEBUG, m, p1, p2, p3, p4, p5); \
+  }
+#define CE_TRACE_DEBUG6(m, p1, p2, p3, p4, p5, p6)                             \
+  {                                                                            \
+    if (ce_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                             \
+      BT_TRACE_6(TRACE_LAYER_CE, TRACE_TYPE_DEBUG, m, p1, p2, p3, p4, p5, p6); \
+  }
+
+#define NDEF_TRACE_ERROR0(m)                             \
+  {                                                      \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_ERROR)     \
+      BT_TRACE_0(TRACE_LAYER_NDEF, TRACE_TYPE_ERROR, m); \
+  }
+#define NDEF_TRACE_ERROR1(m, p1)                             \
+  {                                                          \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_ERROR)         \
+      BT_TRACE_1(TRACE_LAYER_NDEF, TRACE_TYPE_ERROR, m, p1); \
+  }
+#define NDEF_TRACE_ERROR2(m, p1, p2)                             \
+  {                                                              \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_ERROR)             \
+      BT_TRACE_2(TRACE_LAYER_NDEF, TRACE_TYPE_ERROR, m, p1, p2); \
+  }
+#define NDEF_TRACE_ERROR3(m, p1, p2, p3)                             \
+  {                                                                  \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                 \
+      BT_TRACE_3(TRACE_LAYER_NDEF, TRACE_TYPE_ERROR, m, p1, p2, p3); \
+  }
+#define NDEF_TRACE_ERROR4(m, p1, p2, p3, p4)                             \
+  {                                                                      \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                     \
+      BT_TRACE_4(TRACE_LAYER_NDEF, TRACE_TYPE_ERROR, m, p1, p2, p3, p4); \
+  }
+#define NDEF_TRACE_ERROR5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                          \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                         \
+      BT_TRACE_5(TRACE_LAYER_NDEF, TRACE_TYPE_ERROR, m, p1, p2, p3, p4, p5); \
+  }
+#define NDEF_TRACE_ERROR6(m, p1, p2, p3, p4, p5, p6)                        \
+  {                                                                         \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                        \
+      BT_TRACE_6(TRACE_LAYER_NDEF, TRACE_TYPE_ERROR, m, p1, p2, p3, p4, p5, \
+                 p6);                                                       \
+  }
+
+#define NDEF_TRACE_WARNING0(m)                             \
+  {                                                        \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_WARNING)     \
+      BT_TRACE_0(TRACE_LAYER_NDEF, TRACE_TYPE_WARNING, m); \
+  }
+#define NDEF_TRACE_WARNING1(m, p1)                             \
+  {                                                            \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_WARNING)         \
+      BT_TRACE_1(TRACE_LAYER_NDEF, TRACE_TYPE_WARNING, m, p1); \
+  }
+#define NDEF_TRACE_WARNING2(m, p1, p2)                             \
+  {                                                                \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_WARNING)             \
+      BT_TRACE_2(TRACE_LAYER_NDEF, TRACE_TYPE_WARNING, m, p1, p2); \
+  }
+#define NDEF_TRACE_WARNING3(m, p1, p2, p3)                             \
+  {                                                                    \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                 \
+      BT_TRACE_3(TRACE_LAYER_NDEF, TRACE_TYPE_WARNING, m, p1, p2, p3); \
+  }
+#define NDEF_TRACE_WARNING4(m, p1, p2, p3, p4)                             \
+  {                                                                        \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                     \
+      BT_TRACE_4(TRACE_LAYER_NDEF, TRACE_TYPE_WARNING, m, p1, p2, p3, p4); \
+  }
+#define NDEF_TRACE_WARNING5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                            \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                         \
+      BT_TRACE_5(TRACE_LAYER_NDEF, TRACE_TYPE_WARNING, m, p1, p2, p3, p4, p5); \
+  }
+#define NDEF_TRACE_WARNING6(m, p1, p2, p3, p4, p5, p6)                        \
+  {                                                                           \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                        \
+      BT_TRACE_6(TRACE_LAYER_NDEF, TRACE_TYPE_WARNING, m, p1, p2, p3, p4, p5, \
+                 p6);                                                         \
+  }
+
+#define NDEF_TRACE_API0(m)                             \
+  {                                                    \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_API)     \
+      BT_TRACE_0(TRACE_LAYER_NDEF, TRACE_TYPE_API, m); \
+  }
+#define NDEF_TRACE_API1(m, p1)                             \
+  {                                                        \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_API)         \
+      BT_TRACE_1(TRACE_LAYER_NDEF, TRACE_TYPE_API, m, p1); \
+  }
+#define NDEF_TRACE_API2(m, p1, p2)                             \
+  {                                                            \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_API)             \
+      BT_TRACE_2(TRACE_LAYER_NDEF, TRACE_TYPE_API, m, p1, p2); \
+  }
+#define NDEF_TRACE_API3(m, p1, p2, p3)                             \
+  {                                                                \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_API)                 \
+      BT_TRACE_3(TRACE_LAYER_NDEF, TRACE_TYPE_API, m, p1, p2, p3); \
+  }
+#define NDEF_TRACE_API4(m, p1, p2, p3, p4)                             \
+  {                                                                    \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_API)                     \
+      BT_TRACE_4(TRACE_LAYER_NDEF, TRACE_TYPE_API, m, p1, p2, p3, p4); \
+  }
+#define NDEF_TRACE_API5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                        \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_API)                         \
+      BT_TRACE_5(TRACE_LAYER_NDEF, TRACE_TYPE_API, m, p1, p2, p3, p4, p5); \
+  }
+#define NDEF_TRACE_API6(m, p1, p2, p3, p4, p5, p6)                             \
+  {                                                                            \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_API)                             \
+      BT_TRACE_6(TRACE_LAYER_NDEF, TRACE_TYPE_API, m, p1, p2, p3, p4, p5, p6); \
+  }
+
+#define NDEF_TRACE_EVENT0(m)                             \
+  {                                                      \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_EVENT)     \
+      BT_TRACE_0(TRACE_LAYER_NDEF, TRACE_TYPE_EVENT, m); \
+  }
+#define NDEF_TRACE_EVENT1(m, p1)                             \
+  {                                                          \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_EVENT)         \
+      BT_TRACE_1(TRACE_LAYER_NDEF, TRACE_TYPE_EVENT, m, p1); \
+  }
+#define NDEF_TRACE_EVENT2(m, p1, p2)                             \
+  {                                                              \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_EVENT)             \
+      BT_TRACE_2(TRACE_LAYER_NDEF, TRACE_TYPE_EVENT, m, p1, p2); \
+  }
+#define NDEF_TRACE_EVENT3(m, p1, p2, p3)                             \
+  {                                                                  \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                 \
+      BT_TRACE_3(TRACE_LAYER_NDEF, TRACE_TYPE_EVENT, m, p1, p2, p3); \
+  }
+#define NDEF_TRACE_EVENT4(m, p1, p2, p3, p4)                             \
+  {                                                                      \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                     \
+      BT_TRACE_4(TRACE_LAYER_NDEF, TRACE_TYPE_EVENT, m, p1, p2, p3, p4); \
+  }
+#define NDEF_TRACE_EVENT5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                          \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                         \
+      BT_TRACE_5(TRACE_LAYER_NDEF, TRACE_TYPE_EVENT, m, p1, p2, p3, p4, p5); \
+  }
+#define NDEF_TRACE_EVENT6(m, p1, p2, p3, p4, p5, p6)                        \
+  {                                                                         \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                        \
+      BT_TRACE_6(TRACE_LAYER_NDEF, TRACE_TYPE_EVENT, m, p1, p2, p3, p4, p5, \
+                 p6);                                                       \
+  }
+
+#define NDEF_TRACE_DEBUG0(m)                             \
+  {                                                      \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)     \
+      BT_TRACE_0(TRACE_LAYER_NDEF, TRACE_TYPE_DEBUG, m); \
+  }
+#define NDEF_TRACE_DEBUG1(m, p1)                             \
+  {                                                          \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)         \
+      BT_TRACE_1(TRACE_LAYER_NDEF, TRACE_TYPE_DEBUG, m, p1); \
+  }
+#define NDEF_TRACE_DEBUG2(m, p1, p2)                             \
+  {                                                              \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)             \
+      BT_TRACE_2(TRACE_LAYER_NDEF, TRACE_TYPE_DEBUG, m, p1, p2); \
+  }
+#define NDEF_TRACE_DEBUG3(m, p1, p2, p3)                             \
+  {                                                                  \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                 \
+      BT_TRACE_3(TRACE_LAYER_NDEF, TRACE_TYPE_DEBUG, m, p1, p2, p3); \
+  }
+#define NDEF_TRACE_DEBUG4(m, p1, p2, p3, p4)                             \
+  {                                                                      \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                     \
+      BT_TRACE_4(TRACE_LAYER_NDEF, TRACE_TYPE_DEBUG, m, p1, p2, p3, p4); \
+  }
+#define NDEF_TRACE_DEBUG5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                          \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                         \
+      BT_TRACE_5(TRACE_LAYER_NDEF, TRACE_TYPE_DEBUG, m, p1, p2, p3, p4, p5); \
+  }
+#define NDEF_TRACE_DEBUG6(m, p1, p2, p3, p4, p5, p6)                        \
+  {                                                                         \
+    if (ndef_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                        \
+      BT_TRACE_6(TRACE_LAYER_NDEF, TRACE_TYPE_DEBUG, m, p1, p2, p3, p4, p5, \
+                 p6);                                                       \
+  }
+
+/* Define tracing for the NFA unit
+*/
+#define NFA_TRACE_ERROR0(m)                             \
+  {                                                     \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_ERROR) \
+      BT_TRACE_0(TRACE_LAYER_NFA, TRACE_TYPE_ERROR, m); \
+  }
+#define NFA_TRACE_ERROR1(m, p1)                             \
+  {                                                         \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_ERROR)     \
+      BT_TRACE_1(TRACE_LAYER_NFA, TRACE_TYPE_ERROR, m, p1); \
+  }
+#define NFA_TRACE_ERROR2(m, p1, p2)                             \
+  {                                                             \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_ERROR)         \
+      BT_TRACE_2(TRACE_LAYER_NFA, TRACE_TYPE_ERROR, m, p1, p2); \
+  }
+#define NFA_TRACE_ERROR3(m, p1, p2, p3)                             \
+  {                                                                 \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_ERROR)             \
+      BT_TRACE_3(TRACE_LAYER_NFA, TRACE_TYPE_ERROR, m, p1, p2, p3); \
+  }
+#define NFA_TRACE_ERROR4(m, p1, p2, p3, p4)                             \
+  {                                                                     \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                 \
+      BT_TRACE_4(TRACE_LAYER_NFA, TRACE_TYPE_ERROR, m, p1, p2, p3, p4); \
+  }
+#define NFA_TRACE_ERROR5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                         \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                     \
+      BT_TRACE_5(TRACE_LAYER_NFA, TRACE_TYPE_ERROR, m, p1, p2, p3, p4, p5); \
+  }
+#define NFA_TRACE_ERROR6(m, p1, p2, p3, p4, p5, p6)                        \
+  {                                                                        \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                    \
+      BT_TRACE_6(TRACE_LAYER_NFA, TRACE_TYPE_ERROR, m, p1, p2, p3, p4, p5, \
+                 p6);                                                      \
+  }
+
+#define NFA_TRACE_WARNING0(m)                             \
+  {                                                       \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_WARNING) \
+      BT_TRACE_0(TRACE_LAYER_NFA, TRACE_TYPE_WARNING, m); \
+  }
+#define NFA_TRACE_WARNING1(m, p1)                             \
+  {                                                           \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_WARNING)     \
+      BT_TRACE_1(TRACE_LAYER_NFA, TRACE_TYPE_WARNING, m, p1); \
+  }
+#define NFA_TRACE_WARNING2(m, p1, p2)                             \
+  {                                                               \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_WARNING)         \
+      BT_TRACE_2(TRACE_LAYER_NFA, TRACE_TYPE_WARNING, m, p1, p2); \
+  }
+#define NFA_TRACE_WARNING3(m, p1, p2, p3)                             \
+  {                                                                   \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_WARNING)             \
+      BT_TRACE_3(TRACE_LAYER_NFA, TRACE_TYPE_WARNING, m, p1, p2, p3); \
+  }
+#define NFA_TRACE_WARNING4(m, p1, p2, p3, p4)                             \
+  {                                                                       \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                 \
+      BT_TRACE_4(TRACE_LAYER_NFA, TRACE_TYPE_WARNING, m, p1, p2, p3, p4); \
+  }
+#define NFA_TRACE_WARNING5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                           \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                     \
+      BT_TRACE_5(TRACE_LAYER_NFA, TRACE_TYPE_WARNING, m, p1, p2, p3, p4, p5); \
+  }
+#define NFA_TRACE_WARNING6(m, p1, p2, p3, p4, p5, p6)                        \
+  {                                                                          \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                    \
+      BT_TRACE_6(TRACE_LAYER_NFA, TRACE_TYPE_WARNING, m, p1, p2, p3, p4, p5, \
+                 p6);                                                        \
+  }
+
+#define NFA_TRACE_API0(m)                             \
+  {                                                   \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_API) \
+      BT_TRACE_0(TRACE_LAYER_NFA, TRACE_TYPE_API, m); \
+  }
+#define NFA_TRACE_API1(m, p1)                             \
+  {                                                       \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_API)     \
+      BT_TRACE_1(TRACE_LAYER_NFA, TRACE_TYPE_API, m, p1); \
+  }
+#define NFA_TRACE_API2(m, p1, p2)                             \
+  {                                                           \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_API)         \
+      BT_TRACE_2(TRACE_LAYER_NFA, TRACE_TYPE_API, m, p1, p2); \
+  }
+#define NFA_TRACE_API3(m, p1, p2, p3)                             \
+  {                                                               \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_API)             \
+      BT_TRACE_3(TRACE_LAYER_NFA, TRACE_TYPE_API, m, p1, p2, p3); \
+  }
+#define NFA_TRACE_API4(m, p1, p2, p3, p4)                             \
+  {                                                                   \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_API)                 \
+      BT_TRACE_4(TRACE_LAYER_NFA, TRACE_TYPE_API, m, p1, p2, p3, p4); \
+  }
+#define NFA_TRACE_API5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                       \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_API)                     \
+      BT_TRACE_5(TRACE_LAYER_NFA, TRACE_TYPE_API, m, p1, p2, p3, p4, p5); \
+  }
+#define NFA_TRACE_API6(m, p1, p2, p3, p4, p5, p6)                             \
+  {                                                                           \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_API)                         \
+      BT_TRACE_6(TRACE_LAYER_NFA, TRACE_TYPE_API, m, p1, p2, p3, p4, p5, p6); \
+  }
+
+#define NFA_TRACE_EVENT0(m)                             \
+  {                                                     \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_EVENT) \
+      BT_TRACE_0(TRACE_LAYER_NFA, TRACE_TYPE_EVENT, m); \
+  }
+#define NFA_TRACE_EVENT1(m, p1)                             \
+  {                                                         \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_EVENT)     \
+      BT_TRACE_1(TRACE_LAYER_NFA, TRACE_TYPE_EVENT, m, p1); \
+  }
+#define NFA_TRACE_EVENT2(m, p1, p2)                             \
+  {                                                             \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_EVENT)         \
+      BT_TRACE_2(TRACE_LAYER_NFA, TRACE_TYPE_EVENT, m, p1, p2); \
+  }
+#define NFA_TRACE_EVENT3(m, p1, p2, p3)                             \
+  {                                                                 \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_EVENT)             \
+      BT_TRACE_3(TRACE_LAYER_NFA, TRACE_TYPE_EVENT, m, p1, p2, p3); \
+  }
+#define NFA_TRACE_EVENT4(m, p1, p2, p3, p4)                             \
+  {                                                                     \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                 \
+      BT_TRACE_4(TRACE_LAYER_NFA, TRACE_TYPE_EVENT, m, p1, p2, p3, p4); \
+  }
+#define NFA_TRACE_EVENT5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                         \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                     \
+      BT_TRACE_5(TRACE_LAYER_NFA, TRACE_TYPE_EVENT, m, p1, p2, p3, p4, p5); \
+  }
+#define NFA_TRACE_EVENT6(m, p1, p2, p3, p4, p5, p6)                        \
+  {                                                                        \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                    \
+      BT_TRACE_6(TRACE_LAYER_NFA, TRACE_TYPE_EVENT, m, p1, p2, p3, p4, p5, \
+                 p6);                                                      \
+  }
+
+#define NFA_TRACE_DEBUG0(m)                             \
+  {                                                     \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) \
+      BT_TRACE_0(TRACE_LAYER_NFA, TRACE_TYPE_DEBUG, m); \
+  }
+#define NFA_TRACE_DEBUG1(m, p1)                             \
+  {                                                         \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)     \
+      BT_TRACE_1(TRACE_LAYER_NFA, TRACE_TYPE_DEBUG, m, p1); \
+  }
+#define NFA_TRACE_DEBUG2(m, p1, p2)                             \
+  {                                                             \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)         \
+      BT_TRACE_2(TRACE_LAYER_NFA, TRACE_TYPE_DEBUG, m, p1, p2); \
+  }
+#define NFA_TRACE_DEBUG3(m, p1, p2, p3)                             \
+  {                                                                 \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)             \
+      BT_TRACE_3(TRACE_LAYER_NFA, TRACE_TYPE_DEBUG, m, p1, p2, p3); \
+  }
+#define NFA_TRACE_DEBUG4(m, p1, p2, p3, p4)                             \
+  {                                                                     \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                 \
+      BT_TRACE_4(TRACE_LAYER_NFA, TRACE_TYPE_DEBUG, m, p1, p2, p3, p4); \
+  }
+#define NFA_TRACE_DEBUG5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                         \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                     \
+      BT_TRACE_5(TRACE_LAYER_NFA, TRACE_TYPE_DEBUG, m, p1, p2, p3, p4, p5); \
+  }
+#define NFA_TRACE_DEBUG6(m, p1, p2, p3, p4, p5, p6)                        \
+  {                                                                        \
+    if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                    \
+      BT_TRACE_6(TRACE_LAYER_NFA, TRACE_TYPE_DEBUG, m, p1, p2, p3, p4, p5, \
+                 p6);                                                      \
+  }
+
+/* Define tracing for the NFA P2P unit
+*/
+#define P2P_TRACE_ERROR0(m)                             \
+  {                                                     \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_ERROR) \
+      BT_TRACE_0(TRACE_LAYER_P2P, TRACE_TYPE_ERROR, m); \
+  }
+#define P2P_TRACE_ERROR1(m, p1)                             \
+  {                                                         \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_ERROR)     \
+      BT_TRACE_1(TRACE_LAYER_P2P, TRACE_TYPE_ERROR, m, p1); \
+  }
+#define P2P_TRACE_ERROR2(m, p1, p2)                             \
+  {                                                             \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_ERROR)         \
+      BT_TRACE_2(TRACE_LAYER_P2P, TRACE_TYPE_ERROR, m, p1, p2); \
+  }
+#define P2P_TRACE_ERROR3(m, p1, p2, p3)                             \
+  {                                                                 \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_ERROR)             \
+      BT_TRACE_3(TRACE_LAYER_P2P, TRACE_TYPE_ERROR, m, p1, p2, p3); \
+  }
+#define P2P_TRACE_ERROR4(m, p1, p2, p3, p4)                             \
+  {                                                                     \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                 \
+      BT_TRACE_4(TRACE_LAYER_P2P, TRACE_TYPE_ERROR, m, p1, p2, p3, p4); \
+  }
+#define P2P_TRACE_ERROR5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                         \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                     \
+      BT_TRACE_5(TRACE_LAYER_P2P, TRACE_TYPE_ERROR, m, p1, p2, p3, p4, p5); \
+  }
+#define P2P_TRACE_ERROR6(m, p1, p2, p3, p4, p5, p6)                        \
+  {                                                                        \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_ERROR)                    \
+      BT_TRACE_6(TRACE_LAYER_P2P, TRACE_TYPE_ERROR, m, p1, p2, p3, p4, p5, \
+                 p6);                                                      \
+  }
+
+#define P2P_TRACE_WARNING0(m)                             \
+  {                                                       \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_WARNING) \
+      BT_TRACE_0(TRACE_LAYER_P2P, TRACE_TYPE_WARNING, m); \
+  }
+#define P2P_TRACE_WARNING1(m, p1)                             \
+  {                                                           \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_WARNING)     \
+      BT_TRACE_1(TRACE_LAYER_P2P, TRACE_TYPE_WARNING, m, p1); \
+  }
+#define P2P_TRACE_WARNING2(m, p1, p2)                             \
+  {                                                               \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_WARNING)         \
+      BT_TRACE_2(TRACE_LAYER_P2P, TRACE_TYPE_WARNING, m, p1, p2); \
+  }
+#define P2P_TRACE_WARNING3(m, p1, p2, p3)                             \
+  {                                                                   \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_WARNING)             \
+      BT_TRACE_3(TRACE_LAYER_P2P, TRACE_TYPE_WARNING, m, p1, p2, p3); \
+  }
+#define P2P_TRACE_WARNING4(m, p1, p2, p3, p4)                             \
+  {                                                                       \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                 \
+      BT_TRACE_4(TRACE_LAYER_P2P, TRACE_TYPE_WARNING, m, p1, p2, p3, p4); \
+  }
+#define P2P_TRACE_WARNING5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                           \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                     \
+      BT_TRACE_5(TRACE_LAYER_P2P, TRACE_TYPE_WARNING, m, p1, p2, p3, p4, p5); \
+  }
+#define P2P_TRACE_WARNING6(m, p1, p2, p3, p4, p5, p6)                        \
+  {                                                                          \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_WARNING)                    \
+      BT_TRACE_6(TRACE_LAYER_P2P, TRACE_TYPE_WARNING, m, p1, p2, p3, p4, p5, \
+                 p6);                                                        \
+  }
+
+#define P2P_TRACE_API0(m)                             \
+  {                                                   \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_API) \
+      BT_TRACE_0(TRACE_LAYER_P2P, TRACE_TYPE_API, m); \
+  }
+#define P2P_TRACE_API1(m, p1)                             \
+  {                                                       \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_API)     \
+      BT_TRACE_1(TRACE_LAYER_P2P, TRACE_TYPE_API, m, p1); \
+  }
+#define P2P_TRACE_API2(m, p1, p2)                             \
+  {                                                           \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_API)         \
+      BT_TRACE_2(TRACE_LAYER_P2P, TRACE_TYPE_API, m, p1, p2); \
+  }
+#define P2P_TRACE_API3(m, p1, p2, p3)                             \
+  {                                                               \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_API)             \
+      BT_TRACE_3(TRACE_LAYER_P2P, TRACE_TYPE_API, m, p1, p2, p3); \
+  }
+#define P2P_TRACE_API4(m, p1, p2, p3, p4)                             \
+  {                                                                   \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_API)                 \
+      BT_TRACE_4(TRACE_LAYER_P2P, TRACE_TYPE_API, m, p1, p2, p3, p4); \
+  }
+#define P2P_TRACE_API5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                       \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_API)                     \
+      BT_TRACE_5(TRACE_LAYER_P2P, TRACE_TYPE_API, m, p1, p2, p3, p4, p5); \
+  }
+#define P2P_TRACE_API6(m, p1, p2, p3, p4, p5, p6)                             \
+  {                                                                           \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_API)                         \
+      BT_TRACE_6(TRACE_LAYER_P2P, TRACE_TYPE_API, m, p1, p2, p3, p4, p5, p6); \
+  }
+
+#define P2P_TRACE_EVENT0(m)                             \
+  {                                                     \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_EVENT) \
+      BT_TRACE_0(TRACE_LAYER_P2P, TRACE_TYPE_EVENT, m); \
+  }
+#define P2P_TRACE_EVENT1(m, p1)                             \
+  {                                                         \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_EVENT)     \
+      BT_TRACE_1(TRACE_LAYER_P2P, TRACE_TYPE_EVENT, m, p1); \
+  }
+#define P2P_TRACE_EVENT2(m, p1, p2)                             \
+  {                                                             \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_EVENT)         \
+      BT_TRACE_2(TRACE_LAYER_P2P, TRACE_TYPE_EVENT, m, p1, p2); \
+  }
+#define P2P_TRACE_EVENT3(m, p1, p2, p3)                             \
+  {                                                                 \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_EVENT)             \
+      BT_TRACE_3(TRACE_LAYER_P2P, TRACE_TYPE_EVENT, m, p1, p2, p3); \
+  }
+#define P2P_TRACE_EVENT4(m, p1, p2, p3, p4)                             \
+  {                                                                     \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                 \
+      BT_TRACE_4(TRACE_LAYER_P2P, TRACE_TYPE_EVENT, m, p1, p2, p3, p4); \
+  }
+#define P2P_TRACE_EVENT5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                         \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                     \
+      BT_TRACE_5(TRACE_LAYER_P2P, TRACE_TYPE_EVENT, m, p1, p2, p3, p4, p5); \
+  }
+#define P2P_TRACE_EVENT6(m, p1, p2, p3, p4, p5, p6)                        \
+  {                                                                        \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_EVENT)                    \
+      BT_TRACE_6(TRACE_LAYER_P2P, TRACE_TYPE_EVENT, m, p1, p2, p3, p4, p5, \
+                 p6);                                                      \
+  }
+
+#define P2P_TRACE_DEBUG0(m)                             \
+  {                                                     \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) \
+      BT_TRACE_0(TRACE_LAYER_P2P, TRACE_TYPE_DEBUG, m); \
+  }
+#define P2P_TRACE_DEBUG1(m, p1)                             \
+  {                                                         \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)     \
+      BT_TRACE_1(TRACE_LAYER_P2P, TRACE_TYPE_DEBUG, m, p1); \
+  }
+#define P2P_TRACE_DEBUG2(m, p1, p2)                             \
+  {                                                             \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)         \
+      BT_TRACE_2(TRACE_LAYER_P2P, TRACE_TYPE_DEBUG, m, p1, p2); \
+  }
+#define P2P_TRACE_DEBUG3(m, p1, p2, p3)                             \
+  {                                                                 \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)             \
+      BT_TRACE_3(TRACE_LAYER_P2P, TRACE_TYPE_DEBUG, m, p1, p2, p3); \
+  }
+#define P2P_TRACE_DEBUG4(m, p1, p2, p3, p4)                             \
+  {                                                                     \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                 \
+      BT_TRACE_4(TRACE_LAYER_P2P, TRACE_TYPE_DEBUG, m, p1, p2, p3, p4); \
+  }
+#define P2P_TRACE_DEBUG5(m, p1, p2, p3, p4, p5)                             \
+  {                                                                         \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                     \
+      BT_TRACE_5(TRACE_LAYER_P2P, TRACE_TYPE_DEBUG, m, p1, p2, p3, p4, p5); \
+  }
+#define P2P_TRACE_DEBUG6(m, p1, p2, p3, p4, p5, p6)                        \
+  {                                                                        \
+    if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_DEBUG)                    \
+      BT_TRACE_6(TRACE_LAYER_P2P, TRACE_TYPE_DEBUG, m, p1, p2, p3, p4, p5, \
+                 p6);                                                      \
+  }
+
+/* define traces for application */
+#define APPL_TRACE_ERROR0(m)                                            \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_ERROR)                       \
+      LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_ERROR,                                    \
+               (m));                                                    \
+  }
+#define APPL_TRACE_ERROR1(m, p1)                                        \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_ERROR)                       \
+      LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_ERROR,                                    \
+               (m), (uintptr_t)(p1));                                   \
+  }
+#define APPL_TRACE_ERROR2(m, p1, p2)                                    \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_ERROR)                       \
+      LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_ERROR,                                    \
+               (m), (uintptr_t)(p1), (uintptr_t)(p2));                  \
+  }
+#define APPL_TRACE_ERROR3(m, p1, p2, p3)                                \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_ERROR)                       \
+      LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_ERROR,                                    \
+               (m), (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3)); \
+  }
+#define APPL_TRACE_ERROR4(m, p1, p2, p3, p4)                            \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_ERROR)                       \
+      LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_ERROR,                                    \
+               (m), (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3),  \
+               (uintptr_t)(p4));                                        \
+  }
+#define APPL_TRACE_ERROR5(m, p1, p2, p3, p4, p5)                        \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_ERROR)                       \
+      LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_ERROR,                                    \
+               (m), (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3),  \
+               (uintptr_t)(p4), (uintptr_t)(p5));                       \
+  }
+#define APPL_TRACE_ERROR6(m, p1, p2, p3, p4, p5, p6)                    \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_ERROR)                       \
+      LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_ERROR,                                    \
+               (m), (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3),  \
+               (uintptr_t)(p4), (uintptr_t)(p5), (uintptr_t)(p6));      \
+  }
+
+#define APPL_TRACE_WARNING0(m)                                          \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_WARNING)                     \
+      LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_WARNING,                                  \
+               (m));                                                    \
+  }
+#define APPL_TRACE_WARNING1(m, p1)                                      \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_WARNING)                     \
+      LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_WARNING,                                  \
+               (m), (uintptr_t)(p1));                                   \
+  }
+#define APPL_TRACE_WARNING2(m, p1, p2)                                  \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_WARNING)                     \
+      LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_WARNING,                                  \
+               (m), (uintptr_t)(p1), (uintptr_t)(p2));                  \
+  }
+
+#define APPL_TRACE_WARNING3(m, p1, p2, p3)                              \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_WARNING)                     \
+      LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_WARNING,                                  \
+               (m), (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3)); \
+  }
+#define APPL_TRACE_WARNING4(m, p1, p2, p3, p4)                          \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_WARNING)                     \
+      LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_WARNING,                                  \
+               (m), (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3),  \
+               (uintptr_t)(p4));                                        \
+  }
+#define APPL_TRACE_WARNING5(m, p1, p2, p3, p4, p5)                      \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_WARNING)                     \
+      LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_WARNING,                                  \
+               (m), (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3),  \
+               (uintptr_t)(p4), (uintptr_t)(p5));                       \
+  }
+#define APPL_TRACE_WARNING6(m, p1, p2, p3, p4, p5, p6)                  \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_WARNING)                     \
+      LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_WARNING,                                  \
+               (m), (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3),  \
+               (uintptr_t)(p4), (uintptr_t)(p5), (uintptr_t)(p6));      \
+  }
+
+#define APPL_TRACE_API0(m)                                              \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_API)                         \
+      LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_API,                                      \
+               (m));                                                    \
+  }
+#define APPL_TRACE_API1(m, p1)                                          \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_API)                         \
+      LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_API,                                      \
+               (m), (uintptr_t)(p1));                                   \
+  }
+#define APPL_TRACE_API2(m, p1, p2)                                      \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_API)                         \
+      LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_API,                                      \
+               (m), (uintptr_t)(p1), (uintptr_t)(p2));                  \
+  }
+#define APPL_TRACE_API3(m, p1, p2, p3)                                  \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_API)                         \
+      LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_API,                                      \
+               (m), (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3)); \
+  }
+#define APPL_TRACE_API4(m, p1, p2, p3, p4)                              \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_API)                         \
+      LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_API,                                      \
+               (m), (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3),  \
+               (uintptr_t)(p4));                                        \
+  }
+#define APPL_TRACE_API5(m, p1, p2, p3, p4, p5)                          \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_API)                         \
+      LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_API,                                      \
+               (m), (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3),  \
+               (uintptr_t)(p4), (uintptr_t)(p5));                       \
+  }
+#define APPL_TRACE_API6(m, p1, p2, p3, p4, p5, p6)                      \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_API)                         \
+      LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_API,                                      \
+               (m), (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3),  \
+               (uintptr_t)(p4), (uintptr_t)(p5), (uintptr_t)(p6));      \
+  }
+
+#define APPL_TRACE_EVENT0(m)                                            \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_EVENT)                       \
+      LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_EVENT,                                    \
+               (m));                                                    \
+  }
+#define APPL_TRACE_EVENT1(m, p1)                                        \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_EVENT)                       \
+      LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_EVENT,                                    \
+               (m), (uintptr_t)(p1));                                   \
+  }
+#define APPL_TRACE_EVENT2(m, p1, p2)                                    \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_EVENT)                       \
+      LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_EVENT,                                    \
+               (m), (uintptr_t)(p1), (uintptr_t)(p2));                  \
+  }
+#define APPL_TRACE_EVENT3(m, p1, p2, p3)                                \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_EVENT)                       \
+      LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_EVENT,                                    \
+               (m), (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3)); \
+  }
+#define APPL_TRACE_EVENT4(m, p1, p2, p3, p4)                            \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_EVENT)                       \
+      LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_EVENT,                                    \
+               (m), (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3),  \
+               (uintptr_t)(p4));                                        \
+  }
+#define APPL_TRACE_EVENT5(m, p1, p2, p3, p4, p5)                        \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_EVENT)                       \
+      LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_EVENT,                                    \
+               (m), (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3),  \
+               (uintptr_t)(p4), (uintptr_t)(p5));                       \
+  }
+#define APPL_TRACE_EVENT6(m, p1, p2, p3, p4, p5, p6)                    \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_EVENT)                       \
+      LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_EVENT,                                    \
+               (m), (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3),  \
+               (uintptr_t)(p4), (uintptr_t)(p5), (uintptr_t)(p6));      \
+  }
+
+#define APPL_TRACE_DEBUG0(m)                                            \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG)                       \
+      LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_DEBUG,                                    \
+               (m));                                                    \
+  }
+#define APPL_TRACE_DEBUG1(m, p1)                                        \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG)                       \
+      LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_DEBUG,                                    \
+               (m), (uintptr_t)(p1));                                   \
+  }
+#define APPL_TRACE_DEBUG2(m, p1, p2)                                    \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG)                       \
+      LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_DEBUG,                                    \
+               (m), (uintptr_t)(p1), (uintptr_t)(p2));                  \
+  }
+#define APPL_TRACE_DEBUG3(m, p1, p2, p3)                                \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG)                       \
+      LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_DEBUG,                                    \
+               (m), (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3)); \
+  }
+#define APPL_TRACE_DEBUG4(m, p1, p2, p3, p4)                            \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG)                       \
+      LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_DEBUG,                                    \
+               (m), (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3),  \
+               (uintptr_t)(p4));                                        \
+  }
+#define APPL_TRACE_DEBUG5(m, p1, p2, p3, p4, p5)                        \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG)                       \
+      LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_DEBUG,                                    \
+               (m), (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3),  \
+               (uintptr_t)(p4), (uintptr_t)(p5));                       \
+  }
+#define APPL_TRACE_DEBUG6(m, p1, p2, p3, p4, p5, p6)                    \
+  {                                                                     \
+    if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG)                       \
+      LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | \
+                   TRACE_TYPE_DEBUG,                                    \
+               (m), (uintptr_t)(p1), (uintptr_t)(p2), (uintptr_t)(p3),  \
+               (uintptr_t)(p4), (uintptr_t)(p5), (uintptr_t)(p6));      \
+  }
+
+#endif /* BT_TRACE_H */
diff --git a/src/include/bt_types.h b/src/include/bt_types.h
new file mode 100644
index 0000000..87ab96e
--- /dev/null
+++ b/src/include/bt_types.h
@@ -0,0 +1,70 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#ifndef BT_TYPES_H
+#define BT_TYPES_H
+
+#include "data_types.h"
+#include "nfc_types.h"
+
+#define SCR_PROTO_TRACE_NCI 0x00004000
+#define SCR_PROTO_TRACE_ALL 0x001fffff
+#define SCR_PROTO_TRACE_HCI_SUMMARY 0x00000001
+
+#define TRACE_LAYER_NONE 0x00000000
+#define TRACE_LAYER_HCI 0x00070000
+#define TRACE_LAYER_GKI 0x001a0000
+#define TRACE_LAYER_NFC 0x00270000
+/*it's overwritten in nfc_types.h*/
+#define TRACE_LAYER_NCI 0x00280000
+#define TRACE_LAYER_LLCP 0x00290000
+#define TRACE_LAYER_NDEF 0x002a0000
+#define TRACE_LAYER_RW 0x002b0000
+#define TRACE_LAYER_CE 0x002c0000
+#define TRACE_LAYER_P2P 0x002d0000
+#define TRACE_LAYER_NFA 0x00300000
+/*it's overwritten in nfc_types.h*/
+#define TRACE_LAYER_HAL 0x00310000
+#define TRACE_LAYER_MAX_NUM 0x0032
+
+/* NCI Command, Notification or Data*/
+#define BT_EVT_TO_NFC_NCI 0x4000
+#define BT_EVT_TO_NFC_NCI_VS 0x4200 /* Vendor specific message */
+/* messages between NFC and NCI task */
+#define BT_EVT_TO_NFC_MSGS 0x4300
+
+/* start timer */
+#define BT_EVT_TO_START_TIMER 0x3c00
+/* stop timer */
+#define BT_EVT_TO_STOP_TIMER 0x3d00
+
+#define TRACE_TYPE_MAX_NUM 20
+#define TRACE_TYPE_ALL 0xffff
+
+/* start quick timer */
+#define BT_EVT_TO_START_QUICK_TIMER 0x3e00
+
+#define TRACE_ORG_APPL 0x00000500
+
+#define DEV_CLASS_LEN 3
+typedef uint8_t DEV_CLASS[DEV_CLASS_LEN]; /* Device class */
+
+#define BD_ADDR_LEN 6                 /* Device address length */
+typedef uint8_t BD_ADDR[BD_ADDR_LEN]; /* Device address */
+
+#endif
diff --git a/src/include/buildcfg.h b/src/include/buildcfg.h
new file mode 100644
index 0000000..d1a8cc2
--- /dev/null
+++ b/src/include/buildcfg.h
@@ -0,0 +1,112 @@
+/******************************************************************************
+ *
+ *  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) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef __BUILDCFG_H
+#define __BUILDCFG_H
+#include <string.h>
+#include <memory.h>
+#include <stdio.h>
+#include "data_types.h"
+
+#ifndef NFC_CONTORLLER_ID
+#define NFC_CONTORLLER_ID (1)
+#endif
+
+#define BTE_APPL_MAX_USERIAL_DEV_NAME (256)
+
+#ifdef BT_TRACE_VERBOSE
+#undef BT_TRACE_VERBOSE
+#endif
+#define BT_TRACE_VERBOSE true
+
+#define TRACE_TASK_INCLUDED true
+
+#define GKI_BUF1_MAX 0
+// 2 is in use
+#if (NXP_EXTNS == TRUE)
+#define GKI_BUF2_MAX 70
+#define GKI_BUF3_MAX 70
+#define GKI_NUM_FIXED_BUF_POOLS 9
+#else
+#define GKI_BUF2_MAX 50
+#define GKI_BUF3_MAX 30
+#define GKI_NUM_FIXED_BUF_POOLS 4
+#endif
+#define GKI_BUF4_SIZE 2400
+#define GKI_BUF4_MAX 30
+#define GKI_BUF5_MAX 0
+#define GKI_BUF6_MAX 0
+#define GKI_BUF7_MAX 0
+#define GKI_BUF8_MAX 0
+
+#define GKI_BUF2_SIZE 660
+#define GKI_BUF0_SIZE 268
+#define GKI_BUF0_MAX 40
+
+#define NCI_BUF_POOL_ID GKI_POOL_ID_0
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern uint8_t* scru_dump_hex(uint8_t* p, char* p_title, uint32_t len,
+                              uint32_t trace_layer, uint32_t trace_type);
+extern void ScrLog(uint32_t trace_set_mask, const char* fmt_str, ...);
+extern void DispNci(uint8_t* p, uint16_t len, bool is_recv);
+
+extern void downloadFirmwarePatchFile(uint32_t brcm_hw_id);
+
+void ProtoDispAdapterDisplayNciPacket(uint8_t* nciPacket, uint16_t nciPacketLen,
+                                      bool is_recv);
+#define DISP_NCI ProtoDispAdapterDisplayNciPacket
+#define LOGMSG_TAG_NAME "BrcmNfcNfa"
+
+#ifndef _TIMEB
+#define _TIMEB
+struct _timeb {
+  long time;
+  short millitm;
+  short timezone;
+  short dstflag;
+};
+void _ftime(struct _timeb*);
+
+#endif
+
+#ifdef __cplusplus
+};
+#endif
+#endif
diff --git a/src/include/buildcfg_hal.h b/src/include/buildcfg_hal.h
new file mode 100644
index 0000000..d43fb0c
--- /dev/null
+++ b/src/include/buildcfg_hal.h
@@ -0,0 +1,24 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  this file contains constant definitions for customizing NFA
+ *
+ ******************************************************************************/
+#pragma once
diff --git a/src/include/config.h b/src/include/config.h
new file mode 100644
index 0000000..40185cc
--- /dev/null
+++ b/src/include/config.h
@@ -0,0 +1,179 @@
+/******************************************************************************
+ *
+ *  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) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int GetStrValue(const char* name, char* p_value, unsigned long len);
+int GetNumValue(const char* name, void* p_value, unsigned long len);
+
+#ifdef __cplusplus
+};
+#endif
+
+#define NAME_POLLING_TECH_MASK "POLLING_TECH_MASK"
+#define NAME_REGISTER_VIRTUAL_SE "REGISTER_VIRTUAL_SE"
+#define NAME_APPL_TRACE_LEVEL "APPL_TRACE_LEVEL"
+#define NAME_USE_RAW_NCI_TRACE "USE_RAW_NCI_TRACE"
+#define NAME_LOGCAT_FILTER "LOGCAT_FILTER"
+#define NAME_LPTD_CFG "LPTD_CFG"
+#define NAME_SCREEN_OFF_POWER_STATE "SCREEN_OFF_POWER_STATE"
+#define NAME_PREINIT_DSP_CFG "PREINIT_DSP_CFG"
+#define NAME_DTA_START_CFG "DTA_START_CFG"
+#define NAME_NXP_NFC_CHIP "NXP_NFC_CHIP"
+#if (NXP_EXTNS != TRUE)
+#define NAME_TRANSPORT_DRIVER "TRANSPORT_DRIVER"
+#define NAME_POWER_CONTROL_DRIVER "POWER_CONTROL_DRIVER"
+#endif
+#define NAME_PROTOCOL_TRACE_LEVEL "PROTOCOL_TRACE_LEVEL"
+#define NAME_UART_PORT "UART_PORT"
+#define NAME_UART_BAUD "UART_BAUD"
+#define NAME_UART_PARITY "UART_PARITY"
+#define NAME_UART_STOPBITS "UART_STOPBITS"
+#define NAME_UART_DATABITS "UART_DATABITS"
+#define NAME_CLIENT_ADDRESS "BCMI2CNFC_ADDRESS"
+#define NAME_NFA_DM_START_UP_CFG "NFA_DM_START_UP_CFG"
+#define NAME_NFA_DM_CFG "NFA_DM_CFG"
+#define NAME_NFA_DM_LP_CFG "NFA_DM_LP_CFG"
+#define NAME_LOW_SPEED_TRANSPORT "LOW_SPEED_TRANSPORT"
+#define NAME_NFC_WAKE_DELAY "NFC_WAKE_DELAY"
+#define NAME_NFC_WRITE_DELAY "NFC_WRITE_DELAY"
+#define NAME_PERF_MEASURE_FREQ "REPORT_PERFORMANCE_MEASURE"
+#define NAME_READ_MULTI_PACKETS "READ_MULTIPLE_PACKETS"
+#define NAME_POWER_ON_DELAY "POWER_ON_DELAY"
+#define NAME_PRE_POWER_OFF_DELAY "PRE_POWER_OFF_DELAY"
+#define NAME_POST_POWER_OFF_DELAY "POST_POWER_OFF_DELAY"
+#define NAME_CE3_PRE_POWER_OFF_DELAY "CE3_PRE_POWER_OFF_DELAY"
+#define NAME_NFA_STORAGE "NFA_STORAGE"
+#define NAME_NFA_DM_START_UP_VSC_CFG "NFA_DM_START_UP_VSC_CFG"
+#define NAME_NFA_DTA_START_UP_VSC_CFG "NFA_DTA_START_UP_VSC_CFG"
+#define NAME_UICC_LISTEN_TECH_MASK "UICC_LISTEN_TECH_MASK"
+#define NAME_P2P_LISTEN_TECH_MASK "P2P_LISTEN_TECH_MASK"
+#define NAME_UICC_LISTEN_TECH_EX_MASK "UICC_LISTEN_TECH_EXCLUDE_MASK"
+#if (NXP_EXTNS == TRUE)
+#define NAME_APPL_DTA_MODE "APPL_DTA_MODE"
+#define NAME_DEFAULT_AID_ROUTE "DEFAULT_AID_ROUTE"
+#define NAME_DEFAULT_DESFIRE_ROUTE "DEFAULT_DESFIRE_ROUTE"
+#define NAME_DEFAULT_MIFARE_CLT_ROUTE "DEFAULT_MIFARE_CLT_ROUTE"
+#define NAME_DEFAULT_AID_PWR_STATE "DEFAULT_AID_PWR_STATE"
+#define NAME_DEFAULT_DESFIRE_PWR_STATE "DEFAULT_DESFIRE_PWR_STATE"
+#define NAME_DEFAULT_MIFARE_CLT_PWR_STATE "DEFAULT_MIFARE_CLT_PWR_STATE"
+#define NAME_CHECK_DEFAULT_PROTO_SE_ID "NXP_CHECK_DEFAULT_PROTO_SE_ID"
+#define NAME_NFA_DM_DISC_NTF_TIMEOUT "NFA_DM_DISC_NTF_TIMEOUT"
+#define NAME_NXP_FWD_FUNCTIONALITY_ENABLE "NXP_FWD_FUNCTIONALITY_ENABLE"
+#define NAME_HOST_LISTEN_TECH_MASK "HOST_LISTEN_TECH_MASK"
+#define NAME_DEFAULT_FELICA_CLT_ROUTE "DEFAULT_FELICA_CLT_ROUTE"
+#define NAME_DEFAULT_FELICA_CLT_PWR_STATE "DEFAULT_FELICA_CLT_PWR_STATE"
+#define NAME_NXP_ESE_LISTEN_TECH_MASK "NXP_ESE_LISTEN_TECH_MASK"
+#endif
+#define NAME_DEFAULT_OFFHOST_ROUTE "DEFAULT_OFFHOST_ROUTE"
+#define NAME_SNOOZE_MODE_CFG "SNOOZE_MODE_CFG"
+#define NAME_NFA_DM_DISC_DURATION_POLL "NFA_DM_DISC_DURATION_POLL"
+#define NAME_SPD_DEBUG "SPD_DEBUG"
+#define NAME_SPD_MAXRETRYCOUNT "SPD_MAX_RETRY_COUNT"
+#define NAME_SPI_NEGOTIATION "SPI_NEGOTIATION"
+#define NAME_AID_FOR_EMPTY_SELECT "AID_FOR_EMPTY_SELECT"
+#define NAME_PRESERVE_STORAGE "PRESERVE_STORAGE"
+#define NAME_NFA_MAX_EE_SUPPORTED "NFA_MAX_EE_SUPPORTED"
+#define NAME_NFCC_ENABLE_TIMEOUT "NFCC_ENABLE_TIMEOUT"
+#define NAME_NFA_DM_PRE_DISCOVERY_CFG "NFA_DM_PRE_DISCOVERY_CFG"
+#define NAME_POLL_FREQUENCY "POLL_FREQUENCY"
+#define NAME_XTAL_HARDWARE_ID "XTAL_HARDWARE_ID"
+#define NAME_XTAL_FREQUENCY "XTAL_FREQUENCY"
+#define NAME_XTAL_FREQ_INDEX "XTAL_FREQ_INDEX"
+#define NAME_XTAL_PARAMS_CFG "XTAL_PARAMS_CFG"
+#define NAME_EXCLUSIVE_SE_ACCESS "EXCLUSIVE_SE_ACCESS"
+#define NAME_DBG_NO_UICC_IDLE_TIMEOUT_TOGGLING \
+  "DBG_NO_UICC_IDLE_TIMEOUT_TOGGLING"
+#define NAME_PRESENCE_CHECK_ALGORITHM "PRESENCE_CHECK_ALGORITHM"
+#define NAME_ALLOW_NO_NVM "ALLOW_NO_NVM"
+#define NAME_DEVICE_HOST_WHITE_LIST "DEVICE_HOST_WHITE_LIST"
+#define NAME_POWER_OFF_MODE "POWER_OFF_MODE"
+#define NAME_GLOBAL_RESET "DO_GLOBAL_RESET"
+#define NAME_NCI_HAL_MODULE "NCI_HAL_MODULE"
+#define NAME_NFA_POLL_BAIL_OUT_MODE "NFA_POLL_BAIL_OUT_MODE"
+#define NAME_NFA_PROPRIETARY_CFG "NFA_PROPRIETARY_CFG"
+#if (NXP_EXTNS == TRUE)
+#define NAME_NXP_ESE_LISTEN_TECH_MASK   "NXP_ESE_LISTEN_TECH_MASK"
+#define NAME_NXP_WM_MAX_WTX_COUNT       "NXP_WM_MAX_WTX_COUNT"
+#define NAME_NXP_NFCC_STANDBY_TIMEOUT "NXP_NFCC_STANDBY_TIMEOUT"
+#define NAME_NXP_CP_TIMEOUT "NXP_CP_TIMEOUT"
+#define NAME_NXP_CORE_SCRN_OFF_AUTONOMOUS_ENABLE \
+  "NXP_CORE_SCRN_OFF_AUTONOMOUS_ENABLE"
+#define NAME_NXP_ALLOW_WIRED_IN_MIFARE_DESFIRE_CLT \
+  "NXP_ALLOW_WIRED_IN_MIFARE_DESFIRE_CLT"
+#define NAME_NXP_NFCC_RF_FIELD_EVENT_TIMEOUT "NXP_NFCC_RF_FIELD_EVENT_TIMEOUT"
+#define NAME_NFA_BLOCK_ROUTE "NFA_BLOCK_ROUTE"
+#define NAME_NXP_MIFARE_DESFIRE_DISABLE "NXP_MIFARE_DESFIRE_DISABLE"
+#define NAME_NXP_DUAL_UICC_ENABLE "NXP_DUAL_UICC_ENABLE"
+#define NAME_NXP_DEFAULT_NFCEE_TIMEOUT "NXP_DEFAULT_NFCEE_TIMEOUT"
+#define NAME_NXP_DEFAULT_NFCEE_DISC_TIMEOUT "NXP_DEFAULT_NFCEE_DISC_TIMEOUT"
+#define NAME_NXP_NFCC_PASSIVE_LISTEN_TIMEOUT "NXP_NFCC_PASSIVE_LISTEN_TIMEOUT"
+#define NAME_OS_DOWNLOAD_TIMEOUT_VALUE "OS_DOWNLOAD_TIMEOUT_VALUE"
+#define NAME_NXP_HCEF_CMD_RSP_TIMEOUT_VALUE "NXP_HCEF_CMD_RSP_TIMEOUT_VALUE"
+#endif
+
+#define LPTD_PARAM_LEN (40)
+
+// default configuration
+#define default_transport "/dev/bcm2079x"
+
+struct tUART_CONFIG {
+  int m_iBaudrate;  // 115200
+  int m_iDatabits;  // 8
+  int m_iParity;    // 0 - none, 1 = odd, 2 = even
+  int m_iStopbits;
+};
+
+extern struct tUART_CONFIG uartConfig;
+#define MAX_CHIPID_LEN (16)
+void readOptionalConfigExt(const char* option);
+
+/* Snooze mode configuration structure */
+typedef struct {
+  unsigned char snooze_mode;         /* Snooze Mode */
+  unsigned char idle_threshold_dh;   /* Idle Threshold Host */
+  unsigned char idle_threshold_nfcc; /* Idle Threshold NFCC   */
+  unsigned char
+      nfc_wake_active_mode; /* NFC_LP_ACTIVE_LOW or NFC_LP_ACTIVE_HIGH */
+  unsigned char
+      dh_wake_active_mode; /* NFC_LP_ACTIVE_LOW or NFC_LP_ACTIVE_HIGH */
+} tSNOOZE_MODE_CONFIG;
+#endif
diff --git a/src/include/gki_target.h b/src/include/gki_target.h
new file mode 100644
index 0000000..1740ebd
--- /dev/null
+++ b/src/include/gki_target.h
@@ -0,0 +1,480 @@
+/******************************************************************************
+ *
+ *  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) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef GKI_TARGET_H
+#define GKI_TARGET_H
+
+#ifdef BUILDCFG
+#include "buildcfg.h"
+#endif
+
+#include "data_types.h"
+
+/* Operating System Selection */
+#ifndef BTE_SIM_APP
+#define _GKI_ARM
+#define _GKI_STANDALONE
+#else
+#define _BT_WIN32
+#endif
+
+/******************************************************************************
+**
+** Task configuration
+**
+******************************************************************************/
+
+/* Definitions of task IDs for inter-task messaging */
+#ifndef MMI_TASK
+#define MMI_TASK 0
+#endif
+
+#ifndef HCISU_TASK
+#define HCISU_TASK 1
+#endif
+
+#ifndef NCIT_TASK
+#define NCIT_TASK 2
+#endif
+
+#ifndef NFC_TASK
+#define NFC_TASK 3
+#endif
+
+#ifndef BTU_TASK
+#define BTU_TASK 4
+#endif
+
+/* BTE Application, Sample Apps, or Serial port Demo based on JP3 and JP4
+ * setting) */
+#ifndef BTE_APPL_TASK
+#define BTE_APPL_TASK 5
+#endif
+
+#ifndef DEV_MGR_TASK
+#define DEV_MGR_TASK 6
+#endif
+
+#ifndef ISE_SCR_TASK
+#define ISE_SCR_TASK 7
+#endif
+
+#ifndef UCODEC_TASK
+#define UCODEC_TASK 8
+#endif
+
+#ifndef RPCT_TASK
+#define RPCT_TASK 9
+#endif
+
+#ifndef UNV_TASK
+#define UNV_TASK 10
+#endif
+
+#ifndef BTE_IDLE_TASK
+#define BTE_IDLE_TASK 11
+#endif
+
+#ifndef UIPC_TASK
+#define UIPC_TASK 12
+#endif
+
+#ifndef HCISU_AMP_TASK
+#define HCISU_AMP_TASK 13
+#endif
+
+/* The number of GKI tasks in the software system. */
+#ifndef GKI_MAX_TASKS
+#define GKI_MAX_TASKS 14
+#endif
+
+/******************************************************************************
+**
+** Timer configuration
+**
+******************************************************************************/
+
+/* The number of GKI timers in the software system. */
+#ifndef GKI_NUM_TIMERS
+#define GKI_NUM_TIMERS 3
+#endif
+
+/* A conversion value for translating ticks to calculate GKI timer.  */
+#ifndef TICKS_PER_SEC
+#define TICKS_PER_SEC 100
+#endif
+
+/* delay in ticks before stopping system tick. */
+#ifndef GKI_DELAY_STOP_SYS_TICK
+#define GKI_DELAY_STOP_SYS_TICK 10
+#endif
+
+/******************************************************************************
+**
+** Buffer configuration
+**
+******************************************************************************/
+
+/* true if GKI uses dynamic buffers. */
+#ifndef GKI_USE_DYNAMIC_BUFFERS
+#define GKI_USE_DYNAMIC_BUFFERS false
+#endif
+
+/* The size of the buffers in pool 0. */
+#ifndef GKI_BUF0_SIZE
+#define GKI_BUF0_SIZE 64
+#endif
+
+/* The number of buffers in buffer pool 0. */
+#ifndef GKI_BUF0_MAX
+#define GKI_BUF0_MAX 48
+#endif
+
+/* The ID of buffer pool 0. */
+#ifndef GKI_POOL_ID_0
+#define GKI_POOL_ID_0 0
+#endif
+
+/* The size of the buffers in pool 1. */
+#ifndef GKI_BUF1_SIZE
+#define GKI_BUF1_SIZE 128
+#endif
+
+/* The number of buffers in buffer pool 1. */
+#ifndef GKI_BUF1_MAX
+#define GKI_BUF1_MAX 26
+#endif
+
+/* The ID of buffer pool 1. */
+#ifndef GKI_POOL_ID_1
+#define GKI_POOL_ID_1 1
+#endif
+
+/* The size of the buffers in pool 2. */
+#ifndef GKI_BUF2_SIZE
+#define GKI_BUF2_SIZE 660
+#endif
+
+/* The number of buffers in buffer pool 2. */
+#ifndef GKI_BUF2_MAX
+#define GKI_BUF2_MAX 45
+#endif
+
+/* The ID of buffer pool 2. */
+#ifndef GKI_POOL_ID_2
+#define GKI_POOL_ID_2 2
+#endif
+
+/* The size of the buffers in pool 3. */
+#ifndef GKI_BUF3_SIZE
+#if (NXP_EXTNS == TRUE)
+#define GKI_BUF3_SIZE (0xFFB0)
+#else
+#define GKI_BUF3_SIZE 2500
+#endif
+#endif
+
+/* The number of buffers in buffer pool 3. */
+#ifndef GKI_BUF3_MAX
+#define GKI_BUF3_MAX 30
+#endif
+
+/* The ID of buffer pool 3. */
+#ifndef GKI_POOL_ID_3
+#define GKI_POOL_ID_3 3
+#endif
+
+/* The size of the largest PUBLIC fixed buffer in system. */
+#ifndef GKI_MAX_BUF_SIZE
+#define GKI_MAX_BUF_SIZE GKI_BUF3_SIZE
+#endif
+
+/* The pool ID of the largest PUBLIC fixed buffer in system. */
+#ifndef GKI_MAX_BUF_SIZE_POOL_ID
+#define GKI_MAX_BUF_SIZE_POOL_ID GKI_POOL_ID_3
+#endif
+
+/* RESERVED buffer pool for OBX */
+/* Ideally there should be 1 buffer for each instance for RX data, and some
+number
+of TX buffers based on active instances. OBX will only use these if packet size
+requires it. In most cases the large packets are used in only one direction so
+the other direction will use smaller buffers.
+Devices with small amount of RAM should limit the number of active obex objects.
+*/
+/* The size of the buffers in pool 4. */
+#ifndef GKI_BUF4_SIZE
+#define GKI_BUF4_SIZE 0x2000
+#endif
+
+/* The number of buffers in buffer pool 4. */
+#ifndef GKI_BUF4_MAX
+#define GKI_BUF4_MAX 96 /* (OBX_NUM_SERVERS + OBX_NUM_CLIENTS) */
+#endif
+
+/* The ID of buffer pool 4. */
+#ifndef GKI_POOL_ID_4
+#define GKI_POOL_ID_4 4
+#endif
+
+/* The number of fixed GKI buffer pools.
+If L2CAP_FCR_INCLUDED is false, Pool ID 5 is unnecessary
+If BTM_SCO_HCI_INCLUDED is false, Pool ID 6 is unnecessary, otherwise set to 7
+If BTA_HL_INCLUDED is false then Pool ID 7 is uncessary and set the following to
+7, otherwise set to 8
+If GATT_SERVER_ENABLED is false then Pool ID 8 is uncessary and set the
+following to 8, otherwise set to 9
+*/
+#ifndef GKI_NUM_FIXED_BUF_POOLS
+#define GKI_NUM_FIXED_BUF_POOLS 9
+#endif
+
+/* The buffer pool usage mask. */
+#ifndef GKI_DEF_BUFPOOL_PERM_MASK
+#define GKI_DEF_BUFPOOL_PERM_MASK 0xfff0
+#endif
+
+/* The number of fixed and dynamic buffer pools.
+If L2CAP_FCR_INCLUDED is false, Pool ID 4 is unnecessary */
+#ifndef GKI_NUM_TOTAL_BUF_POOLS
+#define GKI_NUM_TOTAL_BUF_POOLS 10
+#endif
+
+/* The following is intended to be a reserved pool for L2CAP
+Flow control and retransmissions and intentionally kept out
+of order */
+
+/* The number of buffers in buffer pool 5. */
+#ifndef GKI_BUF5_MAX
+#define GKI_BUF5_MAX 64
+#endif
+
+/* The ID of buffer pool 5. */
+#ifndef GKI_POOL_ID_5
+#define GKI_POOL_ID_5 5
+#endif
+
+/* The size of the buffers in pool 5
+** Special pool used by l2cap retransmissions only. This size based on segment
+** that will fit into both DH5 and 2-DH3 packet types after accounting for GKI
+** header. 13 bytes of max headers allows us a 339 payload max.
+** (in btui_app.txt)
+** Note: 748 used for insight scriptwrapper with CAT-2 scripts.
+*/
+#ifndef GKI_BUF5_SIZE
+#define GKI_BUF5_SIZE 748
+#endif
+
+/* The buffer corruption check flag. */
+#ifndef GKI_ENABLE_BUF_CORRUPTION_CHECK
+#define GKI_ENABLE_BUF_CORRUPTION_CHECK true
+#endif
+
+/* The GKI severe error macro. */
+#ifndef GKI_SEVERE
+#define GKI_SEVERE(code)
+#endif
+
+/* true if GKI includes debug functionality. */
+#ifndef GKI_DEBUG
+#define GKI_DEBUG false
+#endif
+
+/* Maximum number of exceptions logged. */
+#ifndef GKI_MAX_EXCEPTION
+#define GKI_MAX_EXCEPTION 8
+#endif
+
+/* Maximum number of chars stored for each exception message. */
+#ifndef GKI_MAX_EXCEPTION_MSGLEN
+#define GKI_MAX_EXCEPTION_MSGLEN 64
+#endif
+
+#ifndef GKI_SEND_MSG_FROM_ISR
+#define GKI_SEND_MSG_FROM_ISR false
+#endif
+
+/* The following is intended to be a reserved pool for SCO
+over HCI data and intentionally kept out of order */
+
+/* The ID of buffer pool 6. */
+#ifndef GKI_POOL_ID_6
+#define GKI_POOL_ID_6 6
+#endif
+
+/* The size of the buffers in pool 6,
+  BUF_SIZE = max SCO data 255 + sizeof(NFC_HDR) = 8 + SCO packet header 3 +
+  padding 2 = 268 */
+#ifndef GKI_BUF6_SIZE
+#define GKI_BUF6_SIZE 268
+#endif
+
+/* The number of buffers in buffer pool 6. */
+#ifndef GKI_BUF6_MAX
+#define GKI_BUF6_MAX 60
+#endif
+
+/* The following pool is a dedicated pool for HDP
+   If a shared pool is more desirable then
+   1. set BTA_HL_LRG_DATA_POOL_ID to the desired Gki Pool ID
+   2. make sure that the shared pool size is larger than 9472
+   3. adjust GKI_NUM_FIXED_BUF_POOLS accordingly since
+      POOL ID 7 is not needed
+*/
+
+/* The ID of buffer pool 7. */
+#ifndef GKI_POOL_ID_7
+#define GKI_POOL_ID_7 7
+#endif
+
+/* The size of the buffers in pool 7 */
+#ifndef GKI_BUF7_SIZE
+#define GKI_BUF7_SIZE 9472
+#endif
+
+/* The number of buffers in buffer pool 7. */
+#ifndef GKI_BUF7_MAX
+#define GKI_BUF7_MAX 2
+#endif
+
+/* The following pool is a dedicated pool for GATT
+   If a shared pool is more desirable then
+   1. set GATT_DB_POOL_ID to the desired Gki Pool ID
+   2. make sure that the shared pool size fit a common GATT database needs
+   3. adjust GKI_NUM_FIXED_BUF_POOLS accordingly since
+      POOL ID 8 is not needed
+*/
+
+/* The ID of buffer pool 8. */
+#ifndef GKI_POOL_ID_8
+#define GKI_POOL_ID_8 8
+#endif
+
+/* The size of the buffers in pool 8 */
+#ifndef GKI_BUF8_SIZE
+#define GKI_BUF8_SIZE 128
+#endif
+
+/* The number of buffers in buffer pool 8. */
+#ifndef GKI_BUF8_MAX
+#define GKI_BUF8_MAX 30
+#endif
+
+#if defined(GKI_DEBUG) && (GKI_DEBUG == true)
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "GKI_LINUX"
+/* GKI Trace Macros */
+#define GKI_TRACE_0(m)                                          \
+  LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | \
+             TRACE_TYPE_GENERIC,                                \
+         m)
+#define GKI_TRACE_1(m, p1)                                      \
+  LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | \
+             TRACE_TYPE_GENERIC,                                \
+         m, p1)
+#define GKI_TRACE_2(m, p1, p2)                                  \
+  LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | \
+             TRACE_TYPE_GENERIC,                                \
+         m, p1, p2)
+#define GKI_TRACE_3(m, p1, p2, p3)                              \
+  LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | \
+             TRACE_TYPE_GENERIC,                                \
+         m, p1, p2, p3)
+#define GKI_TRACE_4(m, p1, p2, p3, p4)                          \
+  LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | \
+             TRACE_TYPE_GENERIC,                                \
+         m, p1, p2, p3, p4)
+#define GKI_TRACE_5(m, p1, p2, p3, p4, p5)                      \
+  LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | \
+             TRACE_TYPE_GENERIC,                                \
+         m, p1, p2, p3, p4, p5)
+#define GKI_TRACE_6(m, p1, p2, p3, p4, p5, p6)                  \
+  LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | \
+             TRACE_TYPE_GENERIC,                                \
+         m, p1, p2, p3, p4, p5, p6)
+#else
+#define GKI_TRACE_0(m)
+#define GKI_TRACE_1(m, p1)
+#define GKI_TRACE_2(m, p1, p2)
+#define GKI_TRACE_3(m, p1, p2, p3)
+#define GKI_TRACE_4(m, p1, p2, p3, p4)
+#define GKI_TRACE_5(m, p1, p2, p3, p4, p5)
+#define GKI_TRACE_6(m, p1, p2, p3, p4, p5, p6)
+
+#endif
+
+#define GKI_TRACE_ERROR_0(m)                                                   \
+  LogMsg(                                                                      \
+      TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR, \
+      m)
+#define GKI_TRACE_ERROR_1(m, p1)                                               \
+  LogMsg(                                                                      \
+      TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR, \
+      m, p1)
+#define GKI_TRACE_ERROR_2(m, p1, p2)                                           \
+  LogMsg(                                                                      \
+      TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR, \
+      m, p1, p2)
+#define GKI_TRACE_ERROR_3(m, p1, p2, p3)                                       \
+  LogMsg(                                                                      \
+      TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR, \
+      m, p1, p2, p3)
+#define GKI_TRACE_ERROR_4(m, p1, p2, p3, p4)                                   \
+  LogMsg(                                                                      \
+      TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR, \
+      m, p1, p2, p3, p4)
+#define GKI_TRACE_ERROR_5(m, p1, p2, p3, p4, p5)                               \
+  LogMsg(                                                                      \
+      TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR, \
+      m, p1, p2, p3, p4, p5)
+#define GKI_TRACE_ERROR_6(m, p1, p2, p3, p4, p5, p6)                           \
+  LogMsg(                                                                      \
+      TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR, \
+      m, p1, p2, p3, p4, p5, p6)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void LogMsg(uint32_t trace_set_mask, const char* fmt_str, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GKI_TARGET_H */
diff --git a/src/include/nfc_target.h b/src/include/nfc_target.h
new file mode 100644
index 0000000..c7ca261
--- /dev/null
+++ b/src/include/nfc_target.h
@@ -0,0 +1,733 @@
+/******************************************************************************
+ *
+ *  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) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef NFC_TARGET_H
+#define NFC_TARGET_H
+
+#include "data_types.h"
+
+#ifdef BUILDCFG
+#include "buildcfg.h"
+#endif
+
+/* Include common GKI definitions used by this platform */
+#include "gki_target.h"
+
+#include "bt_types.h" /* This must be defined AFTER buildcfg.h */
+#ifndef LMP_TEST
+#include "bt_trace.h"
+#endif
+
+#ifndef USERIAL_DEBUG
+#define USERIAL_DEBUG false
+#endif
+
+/******************************************************************************
+**
+** GKI Mail Box and Timer
+**
+******************************************************************************/
+
+/* Mailbox event mask for NFC stack */
+#ifndef NFC_MBOX_EVT_MASK
+#define NFC_MBOX_EVT_MASK (TASK_MBOX_0_EVT_MASK)
+#endif
+
+/* Mailbox ID for NFC stack */
+#ifndef NFC_MBOX_ID
+#define NFC_MBOX_ID (TASK_MBOX_0)
+#endif
+
+/* Mailbox event mask for NFA */
+#ifndef NFA_MBOX_EVT_MASK
+#define NFA_MBOX_EVT_MASK (TASK_MBOX_2_EVT_MASK)
+#endif
+
+/* Mailbox ID for NFA */
+#ifndef NFA_MBOX_ID
+#define NFA_MBOX_ID (TASK_MBOX_2)
+#endif
+
+/* GKI timer id used for protocol timer in NFC stack */
+#ifndef NFC_TIMER_ID
+#define NFC_TIMER_ID (TIMER_0)
+#endif
+
+/* GKI timer event mask used for protocol timer in NFC stack */
+#ifndef NFC_TIMER_EVT_MASK
+#define NFC_TIMER_EVT_MASK (TIMER_0_EVT_MASK)
+#endif
+
+/* GKI timer id used for quick timer in NFC stack */
+#ifndef NFC_QUICK_TIMER_ID
+#define NFC_QUICK_TIMER_ID (TIMER_1)
+#endif
+
+/* GKI timer event mask used for quick timer in NFC stack */
+#ifndef NFC_QUICK_TIMER_EVT_MASK
+#define NFC_QUICK_TIMER_EVT_MASK (TIMER_1_EVT_MASK)
+#endif
+
+/* GKI timer id used for protocol timer in NFA */
+#ifndef NFA_TIMER_ID
+#define NFA_TIMER_ID (TIMER_2)
+#endif
+
+/* GKI timer event mask used for protocol timer in NFA */
+#ifndef NFA_TIMER_EVT_MASK
+#define NFA_TIMER_EVT_MASK (TIMER_2_EVT_MASK)
+#endif
+
+/******************************************************************************
+**
+** GKI Buffer Pools
+**
+******************************************************************************/
+
+/* NCI command/notification/data */
+#ifndef NFC_NCI_POOL_ID
+#define NFC_NCI_POOL_ID GKI_POOL_ID_2
+#endif
+
+#ifndef NFC_NCI_POOL_BUF_SIZE
+#define NFC_NCI_POOL_BUF_SIZE GKI_BUF2_SIZE
+#endif
+
+/* Reader/Write commands (NCI data payload) */
+#ifndef NFC_RW_POOL_ID
+#define NFC_RW_POOL_ID GKI_POOL_ID_2
+#endif
+
+#ifndef NFC_RW_POOL_BUF_SIZE
+#define NFC_RW_POOL_BUF_SIZE GKI_BUF2_SIZE
+#endif
+
+/* Card Emulation responses (NCI data payload) */
+#ifndef NFC_CE_POOL_ID
+#define NFC_CE_POOL_ID GKI_POOL_ID_2
+#endif
+
+#ifndef NFC_CE_POOL_BUF_SIZE
+#define NFC_CE_POOL_BUF_SIZE GKI_BUF2_SIZE
+#endif
+
+/* NCI msg pool for HAL (for shared NFC/HAL GKI)*/
+#ifndef NFC_HAL_NCI_POOL_ID
+#define NFC_HAL_NCI_POOL_ID NFC_NCI_POOL_ID
+#endif
+
+#ifndef NFC_HAL_NCI_POOL_BUF_SIZE
+#define NFC_HAL_NCI_POOL_BUF_SIZE NFC_NCI_POOL_BUF_SIZE
+#endif
+
+/******************************************************************************
+**
+** NCI Transport definitions
+**
+******************************************************************************/
+/* offset of the first NCI packet in buffer for outgoing */
+#ifndef NCI_MSG_OFFSET_SIZE
+#define NCI_MSG_OFFSET_SIZE 1
+#endif
+
+/* Restore NFCC baud rate to default on shutdown if NFC_UpdateBaudRate was
+ * called */
+#ifndef NFC_RESTORE_BAUD_ON_SHUTDOWN
+#define NFC_RESTORE_BAUD_ON_SHUTDOWN true
+#endif
+
+/******************************************************************************
+**
+** NCI
+**
+******************************************************************************/
+
+#define NCI_VERSION_UNKNOWN 0x00
+#define NCI_VERSION_1_0     0x10
+#define NCI_VERSION_1_1     0x11
+#define NCI_VERSION_2_0     0x20
+
+#ifndef NCI_VERSION
+//#define NCI_VERSION NCI_VERSION_1_0
+#define NCI_VERSION NCI_VERSION_2_0
+#endif
+#define NCI_CORE_RESET_RSP_LEN(X) (((X) == NCI_VERSION_2_0)?(0x01) : (0x03))
+#define NCI_VERSION_0_F 0x0F
+/* true I2C patch is needed */
+#ifndef NFC_I2C_PATCH_INCLUDED
+#define NFC_I2C_PATCH_INCLUDED true /* NFC-Android uses this!!! */
+#endif
+
+/******************************************************************************
+**
+** NFC
+**
+******************************************************************************/
+
+/* Define to true to include Broadcom Vendor Specific implementation */
+#ifndef NFC_BRCM_VS_INCLUDED
+#define NFC_BRCM_VS_INCLUDED true
+#endif
+
+/* Define to true if compling for NFC Reader/Writer Only mode */
+#ifndef NFC_RW_ONLY
+#define NFC_RW_ONLY FALSE
+#endif
+
+/* Timeout for receiving response to NCI command */
+#ifndef NFC_CMD_CMPL_TIMEOUT
+#define NFC_CMD_CMPL_TIMEOUT 2
+#endif
+
+/* Timeout for waiting on data credit/NFC-DEP */
+#ifndef NFC_DEACTIVATE_TIMEOUT
+#define NFC_DEACTIVATE_TIMEOUT 2
+#endif
+
+/* the maximum number of Vendor Specific callback functions allowed to be
+ * registered. 1-14 */
+#ifndef NFC_NUM_VS_CBACKS
+#define NFC_NUM_VS_CBACKS 3
+#endif
+
+/* the maximum number of NCI connections allowed. 1-14 */
+#ifndef NCI_MAX_CONN_CBS
+#define NCI_MAX_CONN_CBS 4
+#endif
+
+/* Maximum number of NCI commands that the NFCC accepts without needing to wait
+ * for response */
+#ifndef NCI_MAX_CMD_WINDOW
+#define NCI_MAX_CMD_WINDOW 1
+#endif
+
+/* Define to true to include the NFCEE related functionalities */
+#ifndef NFC_NFCEE_INCLUDED
+#define NFC_NFCEE_INCLUDED true
+#endif
+
+/* the maximum number of NFCEE interface supported */
+#ifndef NFC_MAX_EE_INTERFACE
+#define NFC_MAX_EE_INTERFACE 3
+#endif
+
+/* the maximum number of NFCEE information supported. */
+#ifndef NFC_MAX_EE_INFO
+#define NFC_MAX_EE_INFO 8
+#endif
+
+/* the maximum number of NFCEE TLVs supported */
+#ifndef NFC_MAX_EE_TLVS
+#define NFC_MAX_EE_TLVS 1
+#endif
+
+/* the maximum size of NFCEE TLV list supported */
+#ifndef NFC_MAX_EE_TLV_SIZE
+#define NFC_MAX_EE_TLV_SIZE 150
+#endif
+
+/* Maximum time to discover NFCEE */
+#ifndef NFA_EE_DISCV_TIMEOUT_VAL
+#define NFA_EE_DISCV_TIMEOUT_VAL 4000
+#endif
+
+/* Number of times reader/writer should attempt to resend a command on failure
+ */
+#ifndef RW_MAX_RETRIES
+#define RW_MAX_RETRIES 5
+#endif
+
+/* RW NDEF Support */
+#ifndef RW_NDEF_INCLUDED
+#define RW_NDEF_INCLUDED true
+#endif
+
+/* RW Type 1 Tag timeout for each API call, in ms */
+#ifndef RW_T1T_TOUT_RESP
+#define RW_T1T_TOUT_RESP 100
+#endif
+
+/* CE Type 2 Tag timeout for controller command, in ms */
+#ifndef CE_T2T_TOUT_RESP
+#define CE_T2T_TOUT_RESP 1000
+#endif
+
+/* RW Type 2 Tag timeout for each API call, in ms */
+#ifndef RW_T2T_TOUT_RESP
+/* Android requires 150 instead of 100 for presence-check*/
+#define RW_T2T_TOUT_RESP 150
+#endif
+
+/* RW Type 2 Tag timeout for each API call, in ms */
+#ifndef RW_T2T_SEC_SEL_TOUT_RESP
+#define RW_T2T_SEC_SEL_TOUT_RESP 10
+#endif
+
+/* RW Type 3 Tag timeout for each API call, in ms */
+#ifndef RW_T3T_TOUT_RESP
+/* increased T3t presence-check time from 100 to 500, as Felica Secure mode
+ * commands require longer time to process */
+#define RW_T3T_TOUT_RESP 500
+#endif
+
+/* CE Type 3 Tag maximum response timeout index (for check and update, used in
+ * SENSF_RES) */
+#ifndef CE_T3T_MRTI_C
+#define CE_T3T_MRTI_C 0xFF
+#endif
+#ifndef CE_T3T_MRTI_U
+#define CE_T3T_MRTI_U 0xFF
+#endif
+
+/* Default maxblocks for CE_T3T UPDATE/CHECK operations */
+#ifndef CE_T3T_DEFAULT_UPDATE_MAXBLOCKS
+#define CE_T3T_DEFAULT_UPDATE_MAXBLOCKS 3
+#endif
+
+#ifndef CE_T3T_DEFAULT_CHECK_MAXBLOCKS
+#define CE_T3T_DEFAULT_CHECK_MAXBLOCKS 3
+#endif
+
+/* CE Type 4 Tag, Frame Waiting time Integer */
+#ifndef CE_T4T_ISO_DEP_FWI
+#define CE_T4T_ISO_DEP_FWI 7
+#endif
+
+/* RW Type 4 Tag timeout for each API call, in ms */
+#ifndef RW_T4T_TOUT_RESP
+#define RW_T4T_TOUT_RESP 1000
+#endif
+
+/* CE Type 4 Tag timeout for update file, in ms */
+#ifndef CE_T4T_TOUT_UPDATE
+#define CE_T4T_TOUT_UPDATE 1000
+#endif
+
+/* CE Type 4 Tag, mandatory NDEF File ID */
+#ifndef CE_T4T_MANDATORY_NDEF_FILE_ID
+#define CE_T4T_MANDATORY_NDEF_FILE_ID 0x1000
+#endif
+
+/* CE Type 4 Tag, max number of AID supported */
+#ifndef CE_T4T_MAX_REG_AID
+#define CE_T4T_MAX_REG_AID 4
+#endif
+
+/* Sub carrier */
+#ifndef RW_I93_FLAG_SUB_CARRIER
+#define RW_I93_FLAG_SUB_CARRIER I93_FLAG_SUB_CARRIER_SINGLE
+#endif
+
+/* Data rate for 15693 command/response */
+#ifndef RW_I93_FLAG_DATA_RATE
+#define RW_I93_FLAG_DATA_RATE I93_FLAG_DATA_RATE_HIGH
+#endif
+
+/* true, to include Card Emulation related test commands */
+#ifndef CE_TEST_INCLUDED
+#define CE_TEST_INCLUDED false
+#endif
+
+/* Quick Timer */
+#ifndef QUICK_TIMER_TICKS_PER_SEC
+#define QUICK_TIMER_TICKS_PER_SEC 100 /* 10ms timer */
+#endif
+
+/******************************************************************************
+**
+** LLCP
+**
+******************************************************************************/
+
+#ifndef LLCP_TEST_INCLUDED
+#define LLCP_TEST_INCLUDED false
+#endif
+
+#ifndef LLCP_POOL_ID
+#define LLCP_POOL_ID GKI_POOL_ID_3
+#endif
+
+#ifndef LLCP_POOL_BUF_SIZE
+#define LLCP_POOL_BUF_SIZE GKI_BUF3_SIZE
+#endif
+
+/* LLCP Maximum Information Unit (between LLCP_DEFAULT_MIU(128) and LLCP_MAX_MIU
+ * (2175)*/
+#ifndef LLCP_MIU
+#define LLCP_MIU                                             \
+  (LLCP_POOL_BUF_SIZE - NFC_HDR_SIZE - NCI_MSG_OFFSET_SIZE - \
+   NCI_DATA_HDR_SIZE - LLCP_PDU_HEADER_SIZE)
+#endif
+
+/* Link Timeout, LTO */
+#ifndef LLCP_LTO_VALUE
+/* Default is 100ms. It should be sufficiently larger than RWT */
+#define LLCP_LTO_VALUE 1000
+#endif
+
+/*
+** LTO is max time interval between the last bit received and the first bit sent
+** over the air. Link timeout must be delayed as much as time between the packet
+** sent from LLCP and the last bit transmitted at NFCC.
+**  - 200ms, max OTA transmitting time between the first bit and the last bit at
+**    NFCC. Largest MIU(2175bytes) of LLCP must be fragmented and sent on
+**    NFC-DEP over the air. 8 * (DEP_REQ/RES+ACK) + DEP_REQ/RES for 2175 MIU at
+**    106kbps bit rate.
+**  - 10ms, processing time
+*/
+#ifndef LLCP_INTERNAL_TX_DELAY
+#define LLCP_INTERNAL_TX_DELAY 210
+#endif
+
+/*
+** LTO is max time interval between the last bit received and the first bit sent
+** over the air. Link timeout must be delayed as much as time between the first
+** bit received at NFCC and the packet received at LLCP.
+**  - 200ms, max OTA transmitting time between the first bit and the last bit at
+**    NFCC. LLCP cannot receive data packet until all bit are received and
+**    reassembled in NCI. 8 * (DEP_REQ/RES+ACK) + DEP_REQ/RES for 2175 MIU at
+**    106kbps bit rate.
+**  - 10ms, processing time
+*/
+#ifndef LLCP_INTERNAL_RX_DELAY
+#define LLCP_INTERNAL_RX_DELAY 210
+#endif
+
+/* Wait for application layer sending data before sending SYMM */
+#ifndef LLCP_DELAY_RESP_TIME
+#define LLCP_DELAY_RESP_TIME 20 /* in ms */
+#endif
+
+/* LLCP inactivity timeout for initiator */
+#ifndef LLCP_INIT_INACTIVITY_TIMEOUT
+#define LLCP_INIT_INACTIVITY_TIMEOUT 0 /* in ms */
+#endif
+
+/* LLCP inactivity timeout for target */
+#ifndef LLCP_TARGET_INACTIVITY_TIMEOUT
+#define LLCP_TARGET_INACTIVITY_TIMEOUT 0 /* in ms */
+#endif
+
+/* LLCP delay timeout to send the first PDU as initiator */
+#ifndef LLCP_DELAY_TIME_TO_SEND_FIRST_PDU
+#define LLCP_DELAY_TIME_TO_SEND_FIRST_PDU 50 /* in ms */
+#endif
+
+/* Response Waiting Time */
+#ifndef LLCP_WAITING_TIME
+/* its scaled value should be less than LTO */
+#define LLCP_WAITING_TIME 7
+#endif
+
+/* Options Parameters */
+#ifndef LLCP_OPT_VALUE
+#define LLCP_OPT_VALUE LLCP_LSC_3 /* Link Service Class 3 */
+#endif
+
+/* Data link connection timeout */
+#ifndef LLCP_DATA_LINK_CONNECTION_TOUT
+#define LLCP_DATA_LINK_CONNECTION_TOUT 1000
+#endif
+
+/* Max length of service name */
+#ifndef LLCP_MAX_SN_LEN
+#define LLCP_MAX_SN_LEN 255 /* max length of service name */
+#endif
+
+/* Max number of well-known services, at least 2 for LM and SDP and up to 16 */
+#ifndef LLCP_MAX_WKS
+#define LLCP_MAX_WKS 5
+#endif
+
+/* Max number of services advertised by local SDP, up to 16 */
+#ifndef LLCP_MAX_SERVER
+#define LLCP_MAX_SERVER 10
+#endif
+
+/* Max number of services not advertised by local SDP, up to 32 */
+#ifndef LLCP_MAX_CLIENT
+#define LLCP_MAX_CLIENT 20
+#endif
+
+/* Max number of data link connections */
+#ifndef LLCP_MAX_DATA_LINK
+#define LLCP_MAX_DATA_LINK 16
+#endif
+
+/* Max number of outstanding service discovery requests */
+#ifndef LLCP_MAX_SDP_TRANSAC
+#define LLCP_MAX_SDP_TRANSAC 16
+#endif
+
+/* Percentage of LLCP buffer pool for receiving data */
+#ifndef LLCP_RX_BUFF_RATIO
+#define LLCP_RX_BUFF_RATIO 30
+#endif
+
+/* Rx congestion end threshold as percentage of receiving buffers */
+#ifndef LLCP_RX_CONGEST_END
+#define LLCP_RX_CONGEST_END 50
+#endif
+
+/* Rx congestion start threshold as percentage of receiving buffers */
+#ifndef LLCP_RX_CONGEST_START
+#define LLCP_RX_CONGEST_START 70
+#endif
+
+/* limitation of rx UI PDU as percentage of receiving buffers */
+#ifndef LLCP_LL_RX_BUFF_LIMIT
+#define LLCP_LL_RX_BUFF_LIMIT 30
+#endif
+
+/* minimum rx congestion threshold (number of rx I PDU in queue) for data link
+ * connection */
+#ifndef LLCP_DL_MIN_RX_CONGEST
+#define LLCP_DL_MIN_RX_CONGEST 4
+#endif
+
+/* limitation of tx UI PDU as percentage of transmitting buffers */
+#ifndef LLCP_LL_TX_BUFF_LIMIT
+#define LLCP_LL_TX_BUFF_LIMIT 30
+#endif
+
+/******************************************************************************
+**
+** NFA
+**
+******************************************************************************/
+
+#ifndef NFA_P2P_INCLUDED
+#define NFA_P2P_INCLUDED true
+#endif
+
+/* Maximum Idle time (no hcp) to wait for EE DISC REQ Ntf(s) */
+#ifndef NFA_HCI_NETWK_INIT_IDLE_TIMEOUT
+#define NFA_HCI_NETWK_INIT_IDLE_TIMEOUT 1000
+#endif
+
+#ifndef NFA_HCI_MAX_HOST_IN_NETWORK
+#define NFA_HCI_MAX_HOST_IN_NETWORK 0x06
+#endif
+
+#if (NXP_EXTNS == TRUE)
+#define NFA_HCI_MAX_NO_HOST_ETSI12 0x03
+#endif
+
+/* Max number of Application that can be registered to NFA-HCI */
+#ifndef NFA_HCI_MAX_APP_CB
+#define NFA_HCI_MAX_APP_CB 0x05
+#endif
+
+/* Max number of HCI gates that can be created */
+#ifndef NFA_HCI_MAX_GATE_CB
+#define NFA_HCI_MAX_GATE_CB 0x06
+#endif
+
+/* Max number of HCI pipes that can be created for the whole system */
+#ifndef NFA_HCI_MAX_PIPE_CB
+#define NFA_HCI_MAX_PIPE_CB 0x08
+#endif
+
+/* Timeout for waiting for the response to HCP Command packet */
+#if (NXP_EXTNS == TRUE)
+#ifndef NFA_HCI_RESPONSE_TIMEOUT
+/*
+ * NOTE : HCI Response will be received only after Credit Ntf is received.
+ *        If credit Ntf timeout is triggered then response timer will also be
+ * stopped.
+ *        So NFA_HCI_RESPONSE_TIMEOUT should always NFC_NCI_WAIT_DATA_NTF_TOUT +
+ * 1s
+ * */
+#define NFA_HCI_RESPONSE_TIMEOUT 3000
+#endif
+#else
+#ifndef NFA_HCI_RESPONSE_TIMEOUT
+#define NFA_HCI_RESPONSE_TIMEOUT 1000
+#endif
+#endif
+
+/* Default poll duration (may be over-ridden using NFA_SetRfDiscoveryDuration)
+ */
+#ifndef NFA_DM_DISC_DURATION_POLL
+#define NFA_DM_DISC_DURATION_POLL 500 /* Android requires 500 */
+#endif
+
+/* Automatic NDEF detection (when not in exclusive RF mode) */
+#ifndef NFA_DM_AUTO_DETECT_NDEF
+#define NFA_DM_AUTO_DETECT_NDEF false /* !!!!! NFC-Android needs false */
+#endif
+
+/* Automatic NDEF read (when not in exclusive RF mode) */
+#ifndef NFA_DM_AUTO_READ_NDEF
+#define NFA_DM_AUTO_READ_NDEF false /* !!!!! NFC-Android needs false */
+#endif
+
+/* Automatic NDEF presence check (when not in exclusive RF mode) */
+#ifndef NFA_DM_AUTO_PRESENCE_CHECK
+#define NFA_DM_AUTO_PRESENCE_CHECK false /* Android requires false */
+#endif
+
+/* Presence check option: 0x01: use sleep/wake for none-NDEF ISO-DEP tags */
+#ifndef NFA_DM_PRESENCE_CHECK_OPTION
+/* !!!!! Android needs value 3 */
+#define NFA_DM_PRESENCE_CHECK_OPTION 0x03
+#endif
+
+/* Maximum time to wait for presence check response */
+#ifndef NFA_DM_MAX_PRESENCE_CHECK_TIMEOUT
+#define NFA_DM_MAX_PRESENCE_CHECK_TIMEOUT 500
+#endif
+#if (NXP_EXTNS == TRUE)
+#define NFA_DM_ISO_15693_MAX_PRESENCE_CHECK_TIMEOUT 500
+#endif
+
+/* Default delay to auto presence check after sending raw frame */
+#ifndef NFA_DM_DEFAULT_PRESENCE_CHECK_START_DELAY
+#define NFA_DM_DEFAULT_PRESENCE_CHECK_START_DELAY 750
+#endif
+
+/* Timeout for reactivation of Kovio bar code tag (presence check) */
+#ifndef NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK
+#define NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK (1000)
+#endif
+
+/* Max number of NDEF type handlers that can be registered (including the
+ * default handler) */
+#ifndef NFA_NDEF_MAX_HANDLERS
+#define NFA_NDEF_MAX_HANDLERS 8
+#endif
+
+/* Maximum number of listen entries configured/registered with
+ * NFA_CeConfigureUiccListenTech, */
+/* NFA_CeRegisterFelicaSystemCodeOnDH, or NFA_CeRegisterT4tAidOnDH */
+#ifndef NFA_CE_LISTEN_INFO_MAX
+#if (NXP_EXTNS == TRUE)
+#define NFA_CE_LISTEN_INFO_MAX 10
+#else
+#define NFA_CE_LISTEN_INFO_MAX 5
+#endif
+#endif
+
+#ifndef NFA_SNEP_INCLUDED
+/* Android must use false to exclude SNEP */
+#define NFA_SNEP_INCLUDED false
+#endif
+
+/* Max acceptable length */
+#ifndef NFA_SNEP_DEFAULT_SERVER_MAX_NDEF_SIZE
+#define NFA_SNEP_DEFAULT_SERVER_MAX_NDEF_SIZE 500000
+#endif
+
+/* Max number of SNEP server/client and data link connection */
+#ifndef NFA_SNEP_MAX_CONN
+#define NFA_SNEP_MAX_CONN 6
+#endif
+
+/* Max number data link connection of SNEP default server*/
+#ifndef NFA_SNEP_DEFAULT_MAX_CONN
+#define NFA_SNEP_DEFAULT_MAX_CONN 3
+#endif
+
+/* MIU for SNEP              */
+#ifndef NFA_SNEP_MIU
+#define NFA_SNEP_MIU 1980 /* Modified for NFC-A */
+#endif
+
+/* Receiving Window for SNEP */
+#ifndef NFA_SNEP_RW
+#define NFA_SNEP_RW 2 /* Modified for NFC-A */
+#endif
+
+/* Maximum number of AID entries per target_handle  */
+#if (NXP_EXTNS == TRUE)
+#define NFA_EE_MIN_AID_SIZE (5)
+#define NFA_EE_MIN_AID_ENTRY_SIZE (NFA_EE_MIN_AID_SIZE + 4)
+
+#define NFA_EE_MAX_AID_ENTRIES (50)
+#else
+#define NFA_EE_MAX_AID_ENTRIES (10)
+#endif
+
+#define NFA_EE_MAX_APDU_PATTERN_ENTRIES (5)
+/* Maximum number of callback functions can be registered through
+ * NFA_EeRegister() */
+#ifndef NFA_EE_MAX_CBACKS
+#define NFA_EE_MAX_CBACKS (3)
+#endif
+
+#ifndef NFA_DTA_INCLUDED
+#define NFA_DTA_INCLUDED true
+#endif
+
+/*****************************************************************************
+**  Define HAL_WRITE depending on whether HAL is using shared GKI resources
+**  as the NFC stack.
+*****************************************************************************/
+#ifndef HAL_WRITE
+#define HAL_WRITE(p)                                            \
+  {                                                             \
+    nfc_cb.p_hal->write(p->len, (uint8_t*)(p + 1) + p->offset); \
+    GKI_freebuf(p);                                             \
+  }
+#if (NXP_EXTNS == TRUE)
+/*Mem alloc with 8 byte alignment*/
+#define size_align(sz) ((((sz)-1) | 7) + 1)
+#define HAL_MALLOC(size) malloc(size_align((size)))
+
+#define HAL_RE_WRITE(p) \
+  { nfc_cb.p_hal->write(p->len, (uint8_t*)(p + 1) + p->offset); }
+#endif
+
+#ifdef NFC_HAL_SHARED_GKI
+
+/* NFC HAL Included if NFC_NFCEE_INCLUDED */
+#if (NFC_NFCEE_INCLUDED == true)
+
+#ifndef NFC_HAL_HCI_INCLUDED
+#define NFC_HAL_HCI_INCLUDED true
+#endif
+#else /* NFC_NFCEE_INCLUDED == true */
+#ifndef NFC_HAL_HCI_INCLUDED
+#define NFC_HAL_HCI_INCLUDED false
+#endif
+
+#endif /* NFC_NFCEE_INCLUDED == false */
+
+#endif /* NFC_HAL_SHARED_GKI */
+
+#endif /* HAL_WRITE */
+
+#endif /* NFC_TARGET_H */
diff --git a/src/include/trace_api.h b/src/include/trace_api.h
new file mode 100644
index 0000000..2a41951
--- /dev/null
+++ b/src/include/trace_api.h
@@ -0,0 +1,49 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Contains API for BTE Test Tool trace related functions.
+ *
+ ******************************************************************************/
+
+#ifndef TRACE_API_H
+#define TRACE_API_H
+
+#include "nfc_hal_api.h"
+#include "bt_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Trace API Function External Declarations */
+extern void DispT3TagMessage(NFC_HDR* p_msg, bool is_rx);
+extern void DispRWT4Tags(NFC_HDR* p_buf, bool is_rx);
+extern void DispCET4Tags(NFC_HDR* p_buf, bool is_rx);
+extern void DispRWI93Tag(NFC_HDR* p_buf, bool is_rx,
+                         uint8_t command_to_respond);
+
+extern void DispLLCP(NFC_HDR* p_buf, bool is_rx);
+extern void DispHcp(uint8_t* p, uint16_t len, bool is_recv, bool is_first_seg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TRACE_API_H */
diff --git a/src/include/vendor_cfg.h b/src/include/vendor_cfg.h
new file mode 100644
index 0000000..5ebf0fb
--- /dev/null
+++ b/src/include/vendor_cfg.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/******************************************************************************
+ *
+ *  This file contains compile-time configurable constants for vendor specific
+ *proprietary protocols
+ *
+ ******************************************************************************/
+#ifndef __NFC_VENDOR_CFG_H__
+#define __NFC_VENDOR_CFG_H__
+
+/* compile-time configuration structure for proprietary protocol and discovery
+ * value */
+typedef struct {
+  uint8_t pro_protocol_18092_active;
+  uint8_t pro_protocol_b_prime;
+  uint8_t pro_protocol_dual;
+  uint8_t pro_protocol_15693;
+  uint8_t pro_protocol_kovio;
+  uint8_t pro_protocol_mfc;
+
+  uint8_t pro_discovery_kovio_poll;
+  uint8_t pro_discovery_b_prime_poll;
+  uint8_t pro_discovery_b_prime_listen;
+} tNFA_PROPRIETARY_CFG;
+
+extern tNFA_PROPRIETARY_CFG* p_nfa_proprietary_cfg;
+
+/**********************************************
+* Proprietary Protocols
+**********************************************/
+#ifndef NCI_PROTOCOL_18092_ACTIVE
+#define NCI_PROTOCOL_18092_ACTIVE \
+  (p_nfa_proprietary_cfg->pro_protocol_18092_active)
+#endif
+#ifndef NCI_PROTOCOL_B_PRIME
+#define NCI_PROTOCOL_B_PRIME (p_nfa_proprietary_cfg->pro_protocol_b_prime)
+#endif
+#ifndef NCI_PROTOCOL_DUAL
+#define NCI_PROTOCOL_DUAL (p_nfa_proprietary_cfg->pro_protocol_dual)
+#endif
+#ifndef NCI_PROTOCOL_15693
+#define NCI_PROTOCOL_15693 (p_nfa_proprietary_cfg->pro_protocol_15693)
+#endif
+#ifndef NCI_PROTOCOL_KOVIO
+#define NCI_PROTOCOL_KOVIO (p_nfa_proprietary_cfg->pro_protocol_kovio)
+#endif
+#ifndef NCI_PROTOCOL_MIFARE
+#define NCI_PROTOCOL_MIFARE (p_nfa_proprietary_cfg->pro_protocol_mfc)
+#endif
+
+/**********************************************
+* Proprietary Discovery technology and mode
+**********************************************/
+#ifndef NCI_DISCOVERY_TYPE_POLL_KOVIO
+#define NCI_DISCOVERY_TYPE_POLL_KOVIO \
+  (p_nfa_proprietary_cfg->pro_discovery_kovio_poll)
+#endif
+
+#ifndef NCI_DISCOVERY_TYPE_POLL_B_PRIME
+#define NCI_DISCOVERY_TYPE_POLL_B_PRIME \
+  (p_nfa_proprietary_cfg->pro_discovery_b_prime_poll)
+#endif
+
+#ifndef NCI_DISCOVERY_TYPE_LISTEN_B_PRIME
+#define NCI_DISCOVERY_TYPE_LISTEN_B_PRIME \
+  (p_nfa_proprietary_cfg->pro_discovery_b_prime_listen)
+#endif
+
+#endif /* __NFC_VENDOR_CFG_H__ */
diff --git a/src/nfa/ce/nfa_ce_act.c b/src/nfa/ce/nfa_ce_act.c
new file mode 100644
index 0000000..8b9c563
--- /dev/null
+++ b/src/nfa/ce/nfa_ce_act.c
@@ -0,0 +1,1791 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2011-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the action functions the NFA_CE state machine.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_ce_int.h"
+#include "nfa_dm_int.h"
+#include "nfa_sys_int.h"
+#include "nfa_mem_co.h"
+#include "ndef_utils.h"
+#include "ce_api.h"
+#if (NFC_NFCEE_INCLUDED == true)
+#include "nfa_ee_int.h"
+#endif
+
+/*****************************************************************************
+* Protocol-specific event handlers
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         nfa_ce_handle_t3t_evt
+**
+** Description      Handler for Type-3 tag card emulation events
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void nfa_ce_handle_t3t_evt(tCE_EVENT event, tCE_DATA* p_ce_data) {
+  tNFA_CE_CB* p_cb = &nfa_ce_cb;
+  tNFA_CONN_EVT_DATA conn_evt;
+
+  NFA_TRACE_DEBUG1("nfa_ce_handle_t3t_evt: event 0x%x", event);
+#if (NXP_EXTNS == TRUE && NXP_NFCC_HCE_F == TRUE)
+  uint8_t listen_info_idx;
+  /* For the felica on host for nfcFcallback */
+  for (listen_info_idx = 0; listen_info_idx < NFA_CE_LISTEN_INFO_IDX_INVALID;
+       listen_info_idx++) {
+    if ((p_cb->listen_info[listen_info_idx].flags &
+         NFA_CE_LISTEN_INFO_IN_USE) &&
+        (p_cb->listen_info[listen_info_idx].flags &
+         NFA_CE_LISTEN_INFO_FELICA) &&
+        (p_cb->listen_info[listen_info_idx].flags &
+         NFA_CE_LISTEN_INFO_T3T_ACTIVATE_PND)) {
+      p_cb->idx_cur_active = listen_info_idx;
+      p_cb->p_active_conn_cback =
+          p_cb->listen_info[p_cb->idx_cur_active].p_conn_cback;
+      break;
+    }
+  }
+#endif
+
+  switch (event) {
+    case CE_T3T_NDEF_UPDATE_START_EVT:
+      /* Notify app using callback associated with the active ndef */
+      if (p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF) {
+        conn_evt.status = NFA_STATUS_OK;
+        (*p_cb->p_active_conn_cback)(NFA_CE_NDEF_WRITE_START_EVT, &conn_evt);
+      } else {
+        NFA_TRACE_ERROR0(
+            "nfa_ce_handle_t3t_evt: got CE_T3T_UPDATE_START_EVT, but no active "
+            "NDEF");
+      }
+      break;
+
+    case CE_T3T_NDEF_UPDATE_CPLT_EVT:
+      /* Notify app using callback associated with the active ndef */
+      if (p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF) {
+        conn_evt.ndef_write_cplt.status = NFA_STATUS_OK;
+        conn_evt.ndef_write_cplt.len = p_ce_data->update_info.length;
+        conn_evt.ndef_write_cplt.p_data = p_ce_data->update_info.p_data;
+        (*p_cb->p_active_conn_cback)(NFA_CE_NDEF_WRITE_CPLT_EVT, &conn_evt);
+      } else {
+        NFA_TRACE_ERROR0(
+            "nfa_ce_handle_t3t_evt: got CE_T3T_UPDATE_CPLT_EVT, but no active "
+            "NDEF");
+      }
+      break;
+
+    case CE_T3T_RAW_FRAME_EVT:
+      if (p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF) {
+        conn_evt.data.status = p_ce_data->raw_frame.status;
+        conn_evt.data.p_data = (uint8_t*)(p_ce_data->raw_frame.p_data + 1) +
+                               p_ce_data->raw_frame.p_data->offset;
+        conn_evt.data.len = p_ce_data->raw_frame.p_data->len;
+        (*p_cb->p_active_conn_cback)(NFA_DATA_EVT, &conn_evt);
+      } else {
+#if (NXP_EXTNS == TRUE && NXP_NFCC_HCE_F == TRUE)
+        /* If we have not notified the app of activation, do so now */
+        if (p_cb->listen_info[p_cb->idx_cur_active].flags &
+            NFA_CE_LISTEN_INFO_T3T_ACTIVATE_PND) {
+          p_cb->listen_info[p_cb->idx_cur_active].flags &=
+              ~NFA_CE_LISTEN_INFO_T3T_ACTIVATE_PND;
+
+          conn_evt.ce_activated.handle =
+              NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)p_cb->idx_cur_active);
+          memcpy(&(conn_evt.ce_activated.activate_ntf),
+                 &p_cb->activation_params, sizeof(tNFC_ACTIVATE_DEVT));
+          conn_evt.ce_activated.status = NFA_STATUS_OK;
+
+          (*p_cb->p_active_conn_cback)(NFA_CE_ACTIVATED_EVT, &conn_evt);
+        }
+#endif
+        /* Notify app of t3t raw data */
+        conn_evt.ce_data.status = p_ce_data->raw_frame.status;
+        conn_evt.ce_data.handle =
+            (NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)p_cb->idx_cur_active));
+        conn_evt.ce_data.p_data = (uint8_t*)(p_ce_data->raw_frame.p_data + 1) +
+                                  p_ce_data->raw_frame.p_data->offset;
+        conn_evt.ce_data.len = p_ce_data->raw_frame.p_data->len;
+        (*p_cb->p_active_conn_cback)(NFA_CE_DATA_EVT, &conn_evt);
+      }
+      GKI_freebuf(p_ce_data->raw_frame.p_data);
+      break;
+
+    default:
+      NFA_TRACE_DEBUG1("nfa_ce_handle_t3t_evt unhandled event=0x%02x", event);
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_handle_t4t_evt
+**
+** Description      Handler for Type-4 tag card emulation events (for NDEF case)
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void nfa_ce_handle_t4t_evt(tCE_EVENT event, tCE_DATA* p_ce_data) {
+  tNFA_CE_CB* p_cb = &nfa_ce_cb;
+  tNFA_CONN_EVT_DATA conn_evt;
+
+  NFA_TRACE_DEBUG1("nfa_ce_handle_t4t_evt: event 0x%x", event);
+
+  /* AID for NDEF selected. we had notified the app of activation. */
+  p_cb->idx_cur_active = NFA_CE_LISTEN_INFO_IDX_NDEF;
+  if (p_cb->listen_info[p_cb->idx_cur_active].flags &
+      NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND) {
+    p_cb->p_active_conn_cback =
+        p_cb->listen_info[p_cb->idx_cur_active].p_conn_cback;
+  }
+
+  switch (event) {
+    case CE_T4T_NDEF_UPDATE_START_EVT:
+      conn_evt.status = NFA_STATUS_OK;
+      (*p_cb->p_active_conn_cback)(NFA_CE_NDEF_WRITE_START_EVT, &conn_evt);
+      break;
+
+    case CE_T4T_NDEF_UPDATE_CPLT_EVT:
+      conn_evt.ndef_write_cplt.len = p_ce_data->update_info.length;
+      conn_evt.ndef_write_cplt.p_data = p_ce_data->update_info.p_data;
+
+      if (NDEF_MsgValidate(p_ce_data->update_info.p_data,
+                           p_ce_data->update_info.length, true) != NDEF_OK)
+        conn_evt.ndef_write_cplt.status = NFA_STATUS_FAILED;
+      else
+        conn_evt.ndef_write_cplt.status = NFA_STATUS_OK;
+
+      (*p_cb->p_active_conn_cback)(NFA_CE_NDEF_WRITE_CPLT_EVT, &conn_evt);
+      break;
+
+    case CE_T4T_NDEF_UPDATE_ABORT_EVT:
+      conn_evt.ndef_write_cplt.len = 0;
+      conn_evt.ndef_write_cplt.status = NFA_STATUS_FAILED;
+      conn_evt.ndef_write_cplt.p_data = NULL;
+      (*p_cb->p_active_conn_cback)(NFA_CE_NDEF_WRITE_CPLT_EVT, &conn_evt);
+      break;
+
+    default:
+      /* CE_T4T_RAW_FRAME_EVT is not used in NFA CE */
+      NFA_TRACE_DEBUG1("nfa_ce_handle_t4t_evt unhandled event=0x%02x", event);
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_handle_t4t_aid_evt
+**
+** Description      Handler for Type-4 tag AID events (for AIDs registered using
+**                  NFA_CeRegisterT4tAidOnDH)
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void nfa_ce_handle_t4t_aid_evt(tCE_EVENT event, tCE_DATA* p_ce_data) {
+  tNFA_CE_CB* p_cb = &nfa_ce_cb;
+  uint8_t listen_info_idx;
+  tNFA_CONN_EVT_DATA conn_evt;
+
+  NFA_TRACE_DEBUG1("nfa_ce_handle_t4t_aid_evt: event 0x%x", event);
+
+  /* Get listen_info for this aid callback */
+  for (listen_info_idx = 0; listen_info_idx < NFA_CE_LISTEN_INFO_IDX_INVALID;
+       listen_info_idx++) {
+    if ((p_cb->listen_info[listen_info_idx].flags &
+         NFA_CE_LISTEN_INFO_IN_USE) &&
+        (p_cb->listen_info[listen_info_idx].flags &
+         NFA_CE_LISTEN_INFO_T4T_AID) &&
+        (p_cb->listen_info[listen_info_idx].t4t_aid_handle ==
+         p_ce_data->raw_frame.aid_handle)) {
+      p_cb->idx_cur_active = listen_info_idx;
+      p_cb->p_active_conn_cback =
+          p_cb->listen_info[p_cb->idx_cur_active].p_conn_cback;
+      break;
+    }
+  }
+
+  if (event == CE_T4T_RAW_FRAME_EVT) {
+    if (listen_info_idx != NFA_CE_LISTEN_INFO_IDX_INVALID) {
+      /* Found listen_info entry */
+      conn_evt.ce_activated.handle =
+          NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)p_cb->idx_cur_active);
+
+      /* If we have not notified the app of activation, do so now */
+      if (p_cb->listen_info[p_cb->idx_cur_active].flags &
+          NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND) {
+        p_cb->listen_info[p_cb->idx_cur_active].flags &=
+            ~NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND;
+
+        memcpy(&(conn_evt.ce_activated.activate_ntf), &p_cb->activation_params,
+               sizeof(tNFC_ACTIVATE_DEVT));
+        conn_evt.ce_activated.status = NFA_STATUS_OK;
+        (*p_cb->p_active_conn_cback)(NFA_CE_ACTIVATED_EVT, &conn_evt);
+      }
+
+      /* Notify app of AID data */
+      conn_evt.ce_data.status = p_ce_data->raw_frame.status;
+      conn_evt.ce_data.handle =
+          NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)p_cb->idx_cur_active);
+      conn_evt.ce_data.p_data = (uint8_t*)(p_ce_data->raw_frame.p_data + 1) +
+                                p_ce_data->raw_frame.p_data->offset;
+      conn_evt.ce_data.len = p_ce_data->raw_frame.p_data->len;
+      (*p_cb->p_active_conn_cback)(NFA_CE_DATA_EVT, &conn_evt);
+    } else {
+      NFA_TRACE_ERROR1(
+          "nfa_ce_handle_t4t_aid_evt: unable to find listen_info for aid hdl "
+          "%i",
+          p_ce_data->raw_frame.aid_handle)
+    }
+
+    GKI_freebuf(p_ce_data->raw_frame.p_data);
+  }
+}
+
+/*****************************************************************************
+* Discovery configuration and discovery event handlers
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         nfa_ce_discovery_cback
+**
+** Description      Processing event from discovery callback
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_ce_discovery_cback(tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER* p_data) {
+  tNFA_CE_MSG ce_msg;
+  NFA_TRACE_DEBUG1("nfa_ce_discovery_cback(): event:0x%02X", event);
+
+  switch (event) {
+    case NFA_DM_RF_DISC_START_EVT:
+      NFA_TRACE_DEBUG1("nfa_ce_handle_disc_start (status=0x%x)", p_data->start);
+      break;
+
+    case NFA_DM_RF_DISC_ACTIVATED_EVT:
+#if (NXP_EXTNS == TRUE)
+/*
+ *TODO: Handle the Reader over SWP.
+ * Pass this info to JNI as START_READER_EVT.
+ * Handle in nfa_ce_activate_ntf.
+ */
+#endif
+      ce_msg.activate_ntf.hdr.event = NFA_CE_ACTIVATE_NTF_EVT;
+      ce_msg.activate_ntf.p_activation_params = &p_data->activate;
+      nfa_ce_hdl_event((void*)&ce_msg);
+      break;
+
+    case NFA_DM_RF_DISC_DEACTIVATED_EVT:
+      /* DM broadcasts deactivaiton event in listen sleep state, so check before
+       * processing */
+      if (nfa_ce_cb.flags & NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP) {
+        ce_msg.hdr.event = NFA_CE_DEACTIVATE_NTF_EVT;
+        ce_msg.hdr.layer_specific = p_data->deactivate.type;
+#if (NXP_EXTNS == TRUE)
+        /*clear the p61 ce*/
+        nfa_ee_ce_p61_active = 0;
+#endif
+        nfa_ce_hdl_event((void*)&ce_msg);
+      }
+      break;
+
+    default:
+      NFA_TRACE_ERROR0("Unexpected event");
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ce_t3t_set_listen_params
+**
+** Description      Set t3t listening parameters
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void nfc_ce_t3t_set_listen_params(void) {
+  uint8_t i;
+  tNFA_CE_CB* p_cb = &nfa_ce_cb;
+  uint8_t tlv[128], *p_params;
+  uint8_t tlv_size;
+  uint16_t t3t_flags2_mask = 0xFFFF; /* Mask of which T3T_IDs are disabled */
+  uint8_t t3t_idx = 0;
+
+#if (NXP_EXTNS == TRUE && NXP_NFCC_HCE_F == TRUE)
+  uint8_t adv_Feat = 1;
+  uint8_t t3tPMM[NCI_T3T_PMM_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
+#endif
+
+  /* Point to start of tlv buffer */
+  p_params = tlv;
+
+  /* Set system code and NFCID2 */
+  for (i = 0; i < NFA_CE_LISTEN_INFO_MAX; i++) {
+    if ((p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE) &&
+        (p_cb->listen_info[i].protocol_mask & NFA_PROTOCOL_MASK_T3T)) {
+      /* Set tag's system code and NFCID2 */
+      UINT8_TO_STREAM(p_params, NFC_PMID_LF_T3T_ID1 + t3t_idx); /* type */
+      UINT8_TO_STREAM(p_params, NCI_PARAM_LEN_LF_T3T_ID(NFC_GetNCIVersion()));       /* length */
+      /* System Code */
+      UINT16_TO_BE_STREAM(p_params, p_cb->listen_info[i].t3t_system_code);
+      ARRAY_TO_BE_STREAM(p_params, p_cb->listen_info[i].t3t_nfcid2,
+                         NCI_RF_F_UID_LEN);
+      if(NFC_GetNCIVersion() == NCI_VERSION_2_0) {
+        ARRAY_TO_BE_STREAM(p_params, p_cb->listen_info[i].t3t_pmm,
+                          NCI_T3T_PMM_LEN);
+      }
+      /* Set mask for this ID */
+      t3t_flags2_mask &= ~((uint16_t)(1 << t3t_idx));
+      t3t_idx++;
+    }
+  }
+
+  /* For NCI draft 22+, the polarity of NFC_PMID_LF_T3T_FLAGS2 is flipped */
+  t3t_flags2_mask = ~t3t_flags2_mask;
+
+
+  if(nfcFL.chipType != pn547C2) {
+      NFA_TRACE_DEBUG0(" LF_T3T_FLAGS swap for NCI specification compliance");
+      t3t_flags2_mask = ((t3t_flags2_mask >> 8) | (t3t_flags2_mask << 8));
+  }
+
+  UINT8_TO_STREAM(p_params, NFC_PMID_LF_T3T_FLAGS2);      /* type */
+  UINT8_TO_STREAM(p_params, NCI_PARAM_LEN_LF_T3T_FLAGS2); /* length */
+#if ((NXP_EXTNS == TRUE) && (NXP_NFCC_HCE_F == TRUE))
+  // FelicaOnHost
+  UINT16_TO_BE_STREAM(p_params, t3t_flags2_mask);
+  if(NFC_GetNCIVersion() == NCI_VERSION_2_0) {
+    /*Name changed in NCI2.0*/
+     UINT8_TO_STREAM (p_params, NCI_PARAM_ID_LF_T3T_RD_ALLOWED);      /* type */
+     UINT8_TO_STREAM (p_params, NCI_PARAM_LEN_LF_T3T_RD_ALLOWED);     /* length */
+  } else {
+    UINT8_TO_STREAM (p_params, NCI_PARAM_ID_LF_CON_ADV_FEAT);      /* type */
+    UINT8_TO_STREAM (p_params, NCI_PARAM_LEN_LF_CON_ADV_FEAT);     /* length */
+  }
+  UINT8_TO_STREAM (p_params, adv_Feat);
+
+  if(NFC_GetNCIVersion() != NCI_VERSION_2_0) {
+    UINT8_TO_STREAM (p_params, NCI_PARAM_ID_LF_T3T_PMM);      /* type */
+    UINT8_TO_STREAM (p_params, NCI_PARAM_LEN_LF_T3T_PMM);     /* length */
+  }
+#else
+  /* Mask of IDs to disable listening */
+  UINT16_TO_STREAM(p_params, t3t_flags2_mask);
+#endif
+  tlv_size = (uint8_t)(p_params - tlv);
+  if (appl_dta_mode_flag == 0x01) {
+    nfa_dm_cb.eDtaMode |= NFA_DTA_HCEF_MODE;
+  }
+  nfa_dm_check_set_config(tlv_size, (uint8_t*)tlv, false);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_t3t_generate_rand_nfcid
+**
+** Description      Generate a random NFCID2 for Type-3 tag
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void nfa_ce_t3t_generate_rand_nfcid(uint8_t nfcid2[NCI_RF_F_UID_LEN]) {
+  uint32_t rand_seed = GKI_get_tick_count();
+
+  /* For Type-3 tag, nfcid2 starts witn 02:fe */
+  nfcid2[0] = 0x02;
+  nfcid2[1] = 0xFE;
+
+  /* The remaining 6 bytes are random */
+  nfcid2[2] = (uint8_t)(rand_seed & 0xFF);
+  nfcid2[3] = (uint8_t)(rand_seed >> 8 & 0xFF);
+  rand_seed >>= (rand_seed & 3);
+  nfcid2[4] = (uint8_t)(rand_seed & 0xFF);
+  nfcid2[5] = (uint8_t)(rand_seed >> 8 & 0xFF);
+  rand_seed >>= (rand_seed & 3);
+  nfcid2[6] = (uint8_t)(rand_seed & 0xFF);
+  nfcid2[7] = (uint8_t)(rand_seed >> 8 & 0xFF);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_start_listening
+**
+** Description      Start listening
+**
+** Returns          NFA_STATUS_OK if successful
+**
+*******************************************************************************/
+tNFA_STATUS nfa_ce_start_listening(void) {
+  tNFA_DM_DISC_TECH_PROTO_MASK listen_mask;
+  tNFA_CE_CB* p_cb = &nfa_ce_cb;
+  tNFA_HANDLE disc_handle;
+  uint8_t listen_info_idx;
+
+  NFA_TRACE_DEBUG0("nfa_ce_start_listening(): enter");
+  /*************************************************************************/
+  /* Construct protocol preference list to listen for */
+
+  /* First, get protocol preference for active NDEF (if any) */
+  if ((p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags &
+       NFA_CE_LISTEN_INFO_IN_USE) &&
+      (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle ==
+       NFA_HANDLE_INVALID)) {
+    listen_mask = 0;
+
+    if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask &
+        NFA_PROTOCOL_MASK_T3T) {
+      /* set T3T config params */
+      nfc_ce_t3t_set_listen_params();
+
+      listen_mask |= NFA_DM_DISC_MASK_LF_T3T;
+    }
+
+    if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask &
+        NFA_PROTOCOL_MASK_ISO_DEP) {
+      listen_mask |= nfa_ce_cb.isodep_disc_mask;
+    }
+
+    disc_handle = nfa_dm_add_rf_discover(listen_mask, NFA_DM_DISC_HOST_ID_DH,
+                                         nfa_ce_discovery_cback);
+
+    if (disc_handle == NFA_HANDLE_INVALID)
+      return (NFA_STATUS_FAILED);
+    else
+      p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle =
+          disc_handle;
+  }
+
+  /* Next, add protocols from non-NDEF, if any */
+  for (listen_info_idx = 0; listen_info_idx < NFA_CE_LISTEN_INFO_IDX_INVALID;
+       listen_info_idx++) {
+    /* add RF discovery to DM only if it is not added yet */
+    if ((p_cb->listen_info[listen_info_idx].flags &
+         NFA_CE_LISTEN_INFO_IN_USE) &&
+        (p_cb->listen_info[listen_info_idx].rf_disc_handle ==
+         NFA_HANDLE_INVALID)) {
+      if (p_cb->listen_info[listen_info_idx].flags &
+          NFA_CE_LISTEN_INFO_FELICA) {
+        /* set T3T config params */
+        nfc_ce_t3t_set_listen_params();
+
+        disc_handle = nfa_dm_add_rf_discover(NFA_DM_DISC_MASK_LF_T3T,
+                                             NFA_DM_DISC_HOST_ID_DH,
+                                             nfa_ce_discovery_cback);
+
+        if (disc_handle == NFA_HANDLE_INVALID)
+          return (NFA_STATUS_FAILED);
+        else
+          p_cb->listen_info[listen_info_idx].rf_disc_handle = disc_handle;
+      } else if (p_cb->listen_info[listen_info_idx].flags &
+                 NFA_CE_LISTEN_INFO_T4T_AID) {
+        disc_handle = nfa_dm_add_rf_discover(nfa_ce_cb.isodep_disc_mask,
+                                             NFA_DM_DISC_HOST_ID_DH,
+                                             nfa_ce_discovery_cback);
+
+        if (disc_handle == NFA_HANDLE_INVALID)
+          return (NFA_STATUS_FAILED);
+        else
+          p_cb->listen_info[listen_info_idx].rf_disc_handle = disc_handle;
+      }
+#if (NFC_NFCEE_INCLUDED == true)
+      else if (p_cb->listen_info[listen_info_idx].flags &
+#if (NXP_EXTNS == TRUE)
+               (NFA_CE_LISTEN_INFO_UICC | NFA_CE_LISTEN_INFO_ESE)
+#else
+               NFA_CE_LISTEN_INFO_UICC
+#endif
+                   ) {
+        listen_mask = 0;
+        if (nfa_ee_is_active(p_cb->listen_info[listen_info_idx].ee_handle)) {
+          if (p_cb->listen_info[listen_info_idx].tech_mask &
+              NFA_TECHNOLOGY_MASK_A) {
+            listen_mask |= NFA_DM_DISC_MASK_LA_ISO_DEP;
+          }
+          if (p_cb->listen_info[listen_info_idx].tech_mask &
+              NFA_TECHNOLOGY_MASK_B) {
+            listen_mask |= NFA_DM_DISC_MASK_LB_ISO_DEP;
+          }
+          if (p_cb->listen_info[listen_info_idx].tech_mask &
+              NFA_TECHNOLOGY_MASK_F) {
+            listen_mask |= NFA_DM_DISC_MASK_LF_T3T;
+          }
+          if (p_cb->listen_info[listen_info_idx].tech_mask &
+              NFA_TECHNOLOGY_MASK_B_PRIME) {
+            listen_mask |= NFA_DM_DISC_MASK_L_B_PRIME;
+          }
+#if (NXP_EXTNS == TRUE)
+          if (p_cb->listen_info[listen_info_idx].tech_mask &
+              NFA_TECHNOLOGY_MASK_A_ACTIVE) {
+            listen_mask |= NFA_DM_DISC_MASK_LAA_NFC_DEP;
+          }
+          if (p_cb->listen_info[listen_info_idx].tech_mask &
+              NFA_TECHNOLOGY_MASK_F_ACTIVE) {
+            listen_mask |= NFA_DM_DISC_MASK_LFA_NFC_DEP;
+          }
+#endif
+        }
+
+        if (listen_mask) {
+          /* Start listening for requested technologies */
+          /* register discovery callback to NFA DM */
+          disc_handle = nfa_dm_add_rf_discover(
+              listen_mask,
+              (tNFA_DM_DISC_HOST_ID)(
+                  p_cb->listen_info[listen_info_idx].ee_handle & 0x00FF),
+              nfa_ce_discovery_cback);
+
+          if (disc_handle == NFA_HANDLE_INVALID)
+            return (NFA_STATUS_FAILED);
+          else {
+            p_cb->listen_info[listen_info_idx].rf_disc_handle = disc_handle;
+            p_cb->listen_info[listen_info_idx].tech_proto_mask = listen_mask;
+          }
+        } else {
+#if (NXP_EXTNS == TRUE)
+          NFA_TRACE_ERROR1("UICC/ESE[0x%x] is not activated",
+                           p_cb->listen_info[listen_info_idx].ee_handle);
+#else
+          NFA_TRACE_ERROR1("UICC[0x%x] is not activated",
+                           p_cb->listen_info[listen_info_idx].ee_handle);
+#endif
+        }
+      }
+#endif
+    }
+  }
+  NFA_TRACE_DEBUG0("nfa_ce_start_listening(): exit");
+  return NFA_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_restart_listen_check
+**
+** Description      Called on deactivation. Check if any active listen_info
+**                  entries to listen for
+**
+** Returns          true if listening is restarted.
+**                  false if listening not restarted
+**
+*******************************************************************************/
+bool nfa_ce_restart_listen_check(void) {
+  tNFA_CE_CB* p_cb = &nfa_ce_cb;
+  uint8_t listen_info_idx;
+
+  /* Check if any active entries in listen_info table */
+  for (listen_info_idx = 0; listen_info_idx < NFA_CE_LISTEN_INFO_MAX;
+       listen_info_idx++) {
+    if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_IN_USE)
+      break;
+  }
+
+  /* Restart listening if there are any active listen_info entries */
+  if (listen_info_idx != NFA_CE_LISTEN_INFO_IDX_INVALID) {
+    /* restart listening */
+    nfa_ce_start_listening();
+  } else {
+    /* No active listen_info entries */
+    return false;
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_remove_listen_info_entry
+**
+** Description      Remove entry from listen_info table. (when API deregister is
+**                  called or listen_start failed)
+**
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void nfa_ce_remove_listen_info_entry(uint8_t listen_info_idx, bool notify_app) {
+  tNFA_CE_CB* p_cb = &nfa_ce_cb;
+  tNFA_CONN_EVT_DATA conn_evt;
+
+  NFA_TRACE_DEBUG1("NFA_CE: removing listen_info entry %i", listen_info_idx);
+
+  /* Notify app that listening has stopped  if requested (for API deregister) */
+  /* For LISTEN_START failures, app has already notified of NFA_LISTEN_START_EVT
+   * failure */
+  if (notify_app) {
+    if (listen_info_idx == NFA_CE_LISTEN_INFO_IDX_NDEF) {
+      conn_evt.status = NFA_STATUS_OK;
+      (*p_cb->listen_info[listen_info_idx].p_conn_cback)(
+          NFA_CE_LOCAL_TAG_CONFIGURED_EVT, &conn_evt);
+    }
+#if (NFC_NFCEE_INCLUDED == true)
+    else if (p_cb->listen_info[listen_info_idx].flags &
+             NFA_CE_LISTEN_INFO_UICC) {
+      conn_evt.status = NFA_STATUS_OK;
+      (*p_cb->listen_info[listen_info_idx].p_conn_cback)(
+          NFA_CE_UICC_LISTEN_CONFIGURED_EVT, &conn_evt);
+    }
+#if (NXP_EXTNS == TRUE)
+    else if (p_cb->listen_info[listen_info_idx].flags &
+             NFA_CE_LISTEN_INFO_ESE) {
+      conn_evt.status = NFA_STATUS_OK;
+      (*p_cb->listen_info[listen_info_idx].p_conn_cback)(
+          NFA_CE_ESE_LISTEN_CONFIGURED_EVT, &conn_evt);
+    }
+#endif
+
+#endif
+    else {
+      conn_evt.ce_deregistered.handle = NFA_HANDLE_GROUP_CE | listen_info_idx;
+      (*p_cb->listen_info[listen_info_idx].p_conn_cback)(
+          NFA_CE_DEREGISTERED_EVT, &conn_evt);
+    }
+  }
+
+  /* Handle NDEF stopping */
+  if (listen_info_idx == NFA_CE_LISTEN_INFO_IDX_NDEF) {
+    /* clear NDEF contents */
+    CE_T3tSetLocalNDEFMsg(true, 0, 0, NULL, NULL);
+    CE_T4tSetLocalNDEFMsg(true, 0, 0, NULL, NULL);
+
+    if (p_cb->listen_info[listen_info_idx].protocol_mask &
+        NFA_PROTOCOL_MASK_T3T) {
+      p_cb->listen_info[listen_info_idx].protocol_mask = 0;
+
+      /* clear T3T Flags for NDEF */
+      nfc_ce_t3t_set_listen_params();
+    }
+
+    /* Free scratch buffer for this NDEF, if one was allocated */
+    nfa_ce_free_scratch_buf();
+  }
+  /* If stopping listening Felica system code, then clear T3T Flags for this */
+  else if (p_cb->listen_info[listen_info_idx].flags &
+           NFA_CE_LISTEN_INFO_FELICA) {
+    p_cb->listen_info[listen_info_idx].protocol_mask = 0;
+
+    /* clear T3T Flags for registered Felica system code */
+    nfc_ce_t3t_set_listen_params();
+  }
+  /* If stopping listening T4T AID, then deregister this AID from CE_T4T */
+  else if (p_cb->listen_info[listen_info_idx].flags &
+           NFA_CE_LISTEN_INFO_T4T_AID) {
+    /* Free t4t_aid_cback used by this AID */
+    CE_T4tDeregisterAID(p_cb->listen_info[listen_info_idx].t4t_aid_handle);
+  }
+
+  if (p_cb->listen_info[listen_info_idx].rf_disc_handle != NFA_HANDLE_INVALID) {
+    nfa_dm_delete_rf_discover(
+        p_cb->listen_info[listen_info_idx].rf_disc_handle);
+    p_cb->listen_info[listen_info_idx].rf_disc_handle = NFA_HANDLE_INVALID;
+  }
+
+  /* Remove entry from listen_info table */
+  p_cb->listen_info[listen_info_idx].flags = 0;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_free_scratch_buf
+**
+** Description      free scratch buffer (if one is allocated)
+**
+** Returns          nothing
+**
+*******************************************************************************/
+void nfa_ce_free_scratch_buf(void) {
+  tNFA_CE_CB* p_cb = &nfa_ce_cb;
+  if (p_cb->p_scratch_buf) {
+    nfa_mem_co_free(p_cb->p_scratch_buf);
+    p_cb->p_scratch_buf = NULL;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_realloc_scratch_buffer
+**
+** Description      Set scratch buffer if necessary (for writable NDEF messages)
+**
+** Returns          NFA_STATUS_OK if successful
+**
+*******************************************************************************/
+tNFA_STATUS nfa_ce_realloc_scratch_buffer(void) {
+  tNFA_STATUS result = NFA_STATUS_OK;
+
+  /* If current NDEF message is read-only, then we do not need a scratch buffer
+   */
+  if (nfa_ce_cb.listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags &
+      NFC_CE_LISTEN_INFO_READONLY_NDEF) {
+    /* Free existing scratch buffer, if one was allocated */
+    nfa_ce_free_scratch_buf();
+  } else {
+    /* If no scratch buffer allocated yet, or if current scratch buffer size is
+     * different from current ndef size, */
+    /* then allocate a new scratch buffer. */
+    if ((nfa_ce_cb.p_scratch_buf == NULL) ||
+        (nfa_ce_cb.scratch_buf_size != nfa_ce_cb.ndef_max_size)) {
+      /* Free existing scratch buffer, if one was allocated */
+      nfa_ce_free_scratch_buf();
+
+      nfa_ce_cb.p_scratch_buf =
+          (uint8_t*)nfa_mem_co_alloc(nfa_ce_cb.ndef_max_size);
+      if (nfa_ce_cb.p_scratch_buf != NULL) {
+        nfa_ce_cb.scratch_buf_size = nfa_ce_cb.ndef_max_size;
+      } else {
+        NFA_TRACE_ERROR1(
+            "Unable to allocate scratch buffer for writable NDEF message (%i "
+            "bytes)",
+            nfa_ce_cb.ndef_max_size);
+        result = NFA_STATUS_FAILED;
+      }
+    }
+  }
+
+  return (result);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_set_content
+**
+** Description      Set NDEF contents
+**
+** Returns          void
+**
+*******************************************************************************/
+tNFC_STATUS nfa_ce_set_content(void) {
+  tNFC_STATUS status;
+  tNFA_CE_CB* p_cb = &nfa_ce_cb;
+  tNFA_PROTOCOL_MASK ndef_protocol_mask;
+  bool readonly;
+
+  /* Check if listening for NDEF */
+  if (!(p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags &
+        NFA_CE_LISTEN_INFO_IN_USE)) {
+    /* Not listening for NDEF */
+    return (NFA_STATUS_OK);
+  }
+
+  NFA_TRACE_DEBUG0("Setting NDEF contents");
+
+  readonly = (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags &
+              NFC_CE_LISTEN_INFO_READONLY_NDEF)
+                 ? true
+                 : false;
+  ndef_protocol_mask =
+      p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask;
+
+  /* Allocate a scratch buffer if needed (for handling write-requests) */
+  status = nfa_ce_realloc_scratch_buffer();
+  if (status == NFA_STATUS_OK) {
+    if ((ndef_protocol_mask & NFA_PROTOCOL_MASK_T3T) &&
+        (status == NFA_STATUS_OK)) {
+      /* Type3Tag    - NFC-F */
+      status = CE_T3tSetLocalNDEFMsg(readonly, p_cb->ndef_max_size,
+                                     p_cb->ndef_cur_size, p_cb->p_ndef_data,
+                                     p_cb->p_scratch_buf);
+    }
+
+    if ((ndef_protocol_mask & NFA_PROTOCOL_MASK_ISO_DEP) &&
+        (status == NFA_STATUS_OK)) {
+      /* ISODEP/4A,4B- NFC-A or NFC-B */
+      status = CE_T4tSetLocalNDEFMsg(readonly, p_cb->ndef_max_size,
+                                     p_cb->ndef_cur_size, p_cb->p_ndef_data,
+                                     p_cb->p_scratch_buf);
+    }
+  }
+
+  if (status != NFA_STATUS_OK) {
+    /* clear NDEF contents */
+    CE_T3tSetLocalNDEFMsg(true, 0, 0, NULL, NULL);
+    CE_T4tSetLocalNDEFMsg(true, 0, 0, NULL, NULL);
+
+    NFA_TRACE_ERROR1("Unable to set contents (error %02x)", status);
+  }
+
+  return (status);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_activate_ntf
+**
+** Description      Action when activation has occured (NFA_CE_ACTIVATE_NTF_EVT)
+**
+**                  - Find the listen_info entry assocated with this activation
+**                      - get the app callback that registered for this listen
+**                      - call CE_SetActivatedTagType with activation parameters
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_ce_activate_ntf(tNFA_CE_MSG* p_ce_msg) {
+  tNFC_ACTIVATE_DEVT* p_activation_params =
+      p_ce_msg->activate_ntf.p_activation_params;
+  tNFA_CE_CB* p_cb = &nfa_ce_cb;
+  tNFA_CONN_EVT_DATA conn_evt;
+  tCE_CBACK* p_ce_cback = NULL;
+  uint16_t t3t_system_code = 0xFFFF;
+  uint8_t listen_info_idx = NFA_CE_LISTEN_INFO_IDX_INVALID;
+  uint8_t* p_nfcid2 = NULL;
+  uint8_t i;
+  bool t4t_activate_pending = false;
+#if (NXP_EXTNS == TRUE)
+  bool t3t_activate_pending = false;
+  bool t3t_offhost_entry_found = false;
+  uint8_t t3t_activate_idx = 0;
+  uint8_t t3t_offhost_idx = 0;
+#endif
+
+  NFA_TRACE_DEBUG1("nfa_ce_activate_ntf () protocol=%d",
+                   p_ce_msg->activate_ntf.p_activation_params->protocol);
+
+  /* Tag is in listen active state */
+  p_cb->flags |= NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP;
+
+  /* Store activation parameters */
+  memcpy(&p_cb->activation_params, p_activation_params,
+         sizeof(tNFC_ACTIVATE_DEVT));
+
+#if (NXP_EXTNS == TRUE)
+  if (p_cb->activation_params.intf_param.type == nfcFL.nfcMwFL._NCI_INTERFACE_UICC_DIRECT ||
+      p_cb->activation_params.intf_param.type == nfcFL.nfcMwFL._NCI_INTERFACE_ESE_DIRECT) {
+    memcpy(&(conn_evt.activated.activate_ntf), &p_cb->activation_params,
+           sizeof(tNFC_ACTIVATE_DEVT));
+    for (i = 0; i < NFA_CE_LISTEN_INFO_IDX_INVALID; i++) {
+      if (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_UICC) {
+        listen_info_idx = i;
+        NFA_TRACE_DEBUG1(
+            "listen_info found for this activation. listen_info_idx=%d",
+            listen_info_idx);
+        /* Get CONN_CBACK for this activation */
+        p_cb->p_active_conn_cback =
+            p_cb->listen_info[listen_info_idx].p_conn_cback;
+        break;
+      }
+    }
+
+    (*p_cb->p_active_conn_cback)(NFA_ACTIVATED_EVT, &conn_evt);
+  }
+  /* Find the listen_info entry corresponding to this activation */
+  else if (p_cb->activation_params.protocol == NFA_PROTOCOL_T3T) {
+    /* Look for T3T entries in listen_info table that match activated system
+     * code and NFCID2 */
+    for (listen_info_idx = 0; listen_info_idx < NFA_CE_LISTEN_INFO_IDX_INVALID;
+         listen_info_idx++) {
+      /* Look for entries with NFA_PROTOCOL_MASK_T3T */
+      if (p_cb->listen_info[listen_info_idx].flags &
+          NFA_CE_LISTEN_INFO_IN_USE) {
+        if (p_cb->listen_info[listen_info_idx].protocol_mask &
+            NFA_PROTOCOL_MASK_T3T) {
+          /* Check if system_code and nfcid2 that matches activation params */
+          p_nfcid2 = p_cb->listen_info[listen_info_idx].t3t_nfcid2;
+          t3t_system_code = p_cb->listen_info[listen_info_idx].t3t_system_code;
+
+          /* Compare NFCID2 (note: NFCC currently does not return system code in
+           * activation parameters) */
+          if ((memcmp(p_nfcid2,
+                      p_cb->activation_params.rf_tech_param.param.lf.nfcid2,
+                      NCI_RF_F_UID_LEN) == 0)
+              /* && (t3t_system_code == p_ce_msg->activation.p_activate_info->rf_tech_param.param.lf.system_code) */) {
+            p_cb->listen_info[listen_info_idx].flags |=
+                NFA_CE_LISTEN_INFO_T3T_ACTIVATE_PND;
+            t3t_activate_pending = true;
+            t3t_activate_idx = listen_info_idx;
+          }
+        }
+
+        /* Check if entry is for T3T UICC */
+        if ((p_cb->listen_info[listen_info_idx].flags &
+             NFA_CE_LISTEN_INFO_UICC) &&
+            (p_cb->listen_info[listen_info_idx].tech_mask &
+             NFA_TECHNOLOGY_MASK_F)) {
+          t3t_offhost_entry_found = true;
+          t3t_offhost_idx = listen_info_idx;
+        }
+      }
+    }
+
+    p_ce_cback = nfa_ce_handle_t3t_evt;
+    /* If listening for PROTO_T3T on DH and eSE/UICC, then notify CE module now
+     * and wait for reader/writer to SELECT a target */
+    if (t3t_activate_pending && t3t_offhost_entry_found) {
+      CE_SetActivatedTagType(&p_cb->activation_params, t3t_system_code,
+                             p_ce_cback);
+      return true;
+    } else if (t3t_activate_pending) {
+      listen_info_idx = t3t_activate_idx;
+    } else if (t3t_offhost_entry_found) {
+      listen_info_idx = t3t_offhost_idx;
+    }
+  }
+#else
+  /* Find the listen_info entry corresponding to this activation */
+  if (p_cb->activation_params.protocol == NFA_PROTOCOL_T3T) {
+    /* Look for T3T entries in listen_info table that match activated system
+     * code and NFCID2 */
+    for (listen_info_idx = 0; listen_info_idx < NFA_CE_LISTEN_INFO_IDX_INVALID;
+         listen_info_idx++) {
+      /* Look for entries with NFA_PROTOCOL_MASK_T3T */
+      if (p_cb->listen_info[listen_info_idx].flags &
+          NFA_CE_LISTEN_INFO_IN_USE) {
+        if (p_cb->listen_info[listen_info_idx].protocol_mask &
+            NFA_PROTOCOL_MASK_T3T) {
+          /* Check if system_code and nfcid2 that matches activation params */
+          p_nfcid2 = p_cb->listen_info[listen_info_idx].t3t_nfcid2;
+          t3t_system_code = p_cb->listen_info[listen_info_idx].t3t_system_code;
+
+          /* Compare NFCID2 (note: NFCC currently does not return system code in
+           * activation parameters) */
+          if ((memcmp(p_nfcid2,
+                      p_cb->activation_params.rf_tech_param.param.lf.nfcid2,
+                      NCI_RF_F_UID_LEN) == 0)
+              /* && (t3t_system_code == p_ce_msg->activation.p_activate_info->rf_tech_param.param.lf.system_code) */) {
+            /* Found listen_info corresponding to this activation */
+            break;
+          }
+        }
+        /* Check if entry is for T3T UICC */
+        if ((p_cb->listen_info[listen_info_idx].flags &
+             NFA_CE_LISTEN_INFO_UICC) &&
+            (p_cb->listen_info[listen_info_idx].tech_mask &
+             NFA_TECHNOLOGY_MASK_F)) {
+          break;
+        }
+      }
+    }
+
+    p_ce_cback = nfa_ce_handle_t3t_evt;
+  }
+#endif
+  else if (p_cb->activation_params.protocol == NFA_PROTOCOL_ISO_DEP) {
+    p_ce_cback = nfa_ce_handle_t4t_evt;
+
+    /* For T4T, we do not know which AID will be selected yet */
+
+    /* For all T4T entries in listen_info, set T4T_ACTIVATE_NOTIFY_PENDING flag
+     */
+    for (i = 0; i < NFA_CE_LISTEN_INFO_IDX_INVALID; i++) {
+      if (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE) {
+        if (p_cb->listen_info[i].protocol_mask & NFA_PROTOCOL_MASK_ISO_DEP) {
+          /* Found listen_info table entry for T4T raw listen */
+          p_cb->listen_info[i].flags |= NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND;
+
+          /* If entry if for NDEF, select it, so application gets nofitifed of
+           * ACTIVATE_EVT now */
+          if (i == NFA_CE_LISTEN_INFO_IDX_NDEF) {
+            listen_info_idx = NFA_CE_LISTEN_INFO_IDX_NDEF;
+          }
+
+          t4t_activate_pending = true;
+        }
+
+#if (NFC_NFCEE_INCLUDED == true)
+        /* Check if entry is for ISO_DEP UICC */
+        if (p_cb->listen_info[i].flags &
+#if (NXP_EXTNS == TRUE)
+            (NFA_CE_LISTEN_INFO_UICC | NFA_CE_LISTEN_INFO_ESE)
+#else
+            NFA_CE_LISTEN_INFO_UICC
+#endif
+                ) {
+          if (((p_cb->activation_params.rf_tech_param.mode ==
+                NFC_DISCOVERY_TYPE_LISTEN_A) &&
+               (p_cb->listen_info[i].tech_proto_mask &
+                NFA_DM_DISC_MASK_LA_ISO_DEP)) ||
+              ((p_cb->activation_params.rf_tech_param.mode ==
+                NFC_DISCOVERY_TYPE_LISTEN_B) &&
+               (p_cb->listen_info[i].tech_proto_mask &
+                NFA_DM_DISC_MASK_LB_ISO_DEP))) {
+            listen_info_idx = i;
+          }
+        }
+#endif
+      }
+    }
+
+    /* If listening for ISO_DEP, but not NDEF nor UICC, then notify CE module
+     * now and wait for reader/writer to SELECT an AID */
+    if (t4t_activate_pending &&
+        (listen_info_idx == NFA_CE_LISTEN_INFO_IDX_INVALID)) {
+      CE_SetActivatedTagType(&p_cb->activation_params, 0, p_ce_cback);
+      return true;
+    }
+  } else if (p_cb->activation_params.intf_param.type ==
+             NFC_INTERFACE_EE_DIRECT_RF) {
+    /* search any entry listening UICC */
+    for (i = 0; i < NFA_CE_LISTEN_INFO_IDX_INVALID; i++) {
+      if ((p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE) &&
+          (p_cb->listen_info[i].flags &
+#if (NXP_EXTNS == TRUE)
+           (NFA_CE_LISTEN_INFO_UICC | NFA_CE_LISTEN_INFO_ESE)
+#else
+           NFA_CE_LISTEN_INFO_UICC
+#endif
+               )) {
+        listen_info_idx = i;
+        break;
+      }
+    }
+  }
+
+#if (NXP_EXTNS == TRUE)
+  // FelicaOnHost
+  if ((listen_info_idx == NFA_CE_LISTEN_INFO_IDX_INVALID) &&
+      (p_cb->activation_params.protocol == NFA_PROTOCOL_T3T)) {
+    for (listen_info_idx = 0; listen_info_idx < NFA_CE_LISTEN_INFO_IDX_INVALID;
+         listen_info_idx++) {
+      /* Look for entries with NFA_PROTOCOL_MASK_T3T */
+      if (p_cb->listen_info[listen_info_idx].flags &
+          NFA_CE_LISTEN_INFO_IN_USE) {
+        if ((p_cb->listen_info[listen_info_idx].flags &
+             NFA_CE_LISTEN_INFO_UICC) &&
+            (p_cb->listen_info[listen_info_idx].tech_mask &
+             NFA_TECHNOLOGY_MASK_F)) {
+          break;
+        }
+      }
+    }
+  }
+#endif
+  /* Check if valid listen_info entry was found */
+  if ((listen_info_idx == NFA_CE_LISTEN_INFO_IDX_INVALID) ||
+      ((listen_info_idx == NFA_CE_LISTEN_INFO_IDX_NDEF) &&
+       !(p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags &
+         NFA_CE_LISTEN_INFO_IN_USE))) {
+    NFA_TRACE_DEBUG1(
+        "No listen_info found for this activation. listen_info_idx=%d",
+        listen_info_idx);
+    return (true);
+  }
+
+  p_cb->listen_info[listen_info_idx].flags &=
+      ~NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND;
+
+#if (NXP_EXTNS == TRUE)
+  p_cb->listen_info[listen_info_idx].flags &=
+      ~NFA_CE_LISTEN_INFO_T3T_ACTIVATE_PND;
+#endif
+
+  /* Get CONN_CBACK for this activation */
+  p_cb->p_active_conn_cback = p_cb->listen_info[listen_info_idx].p_conn_cback;
+  p_cb->idx_cur_active = listen_info_idx;
+
+  if ((p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF) ||
+      (p_cb->listen_info[p_cb->idx_cur_active].flags &
+#if (NXP_EXTNS == TRUE)
+       (NFA_CE_LISTEN_INFO_UICC | NFA_CE_LISTEN_INFO_ESE)
+#else
+       NFA_CE_LISTEN_INFO_UICC
+#endif
+           )) {
+    memcpy(&(conn_evt.activated.activate_ntf), &p_cb->activation_params,
+           sizeof(tNFC_ACTIVATE_DEVT));
+
+    (*p_cb->p_active_conn_cback)(NFA_ACTIVATED_EVT, &conn_evt);
+  } else {
+    conn_evt.ce_activated.handle =
+        NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)p_cb->idx_cur_active);
+    memcpy(&(conn_evt.ce_activated.activate_ntf), &p_cb->activation_params,
+           sizeof(tNFC_ACTIVATE_DEVT));
+    conn_evt.ce_activated.status = NFA_STATUS_OK;
+
+    (*p_cb->p_active_conn_cback)(NFA_CE_ACTIVATED_EVT, &conn_evt);
+  }
+
+  /* we don't need any CE subsystem in case of NFCEE direct RF interface */
+  if (p_ce_cback) {
+    /* Notify CE subsystem */
+    CE_SetActivatedTagType(&p_cb->activation_params, t3t_system_code,
+                           p_ce_cback);
+  }
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_deactivate_ntf
+**
+** Description      Action when deactivate occurs. (NFA_CE_DEACTIVATE_NTF_EVT)
+**
+**                  - If deactivate due to API deregister, then remove its entry
+**                    from listen_info table
+**
+**                  - If NDEF was modified while activated, then restore
+**                    original NDEF contents
+**
+**                  - Restart listening (if any active entries in listen table)
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_ce_deactivate_ntf(tNFA_CE_MSG* p_ce_msg) {
+  tNFC_DEACT_TYPE deact_type = (tNFC_DEACT_TYPE)p_ce_msg->hdr.layer_specific;
+  tNFA_CE_CB* p_cb = &nfa_ce_cb;
+  tNFA_CONN_EVT_DATA conn_evt;
+  uint8_t i;
+
+  NFA_TRACE_DEBUG1("nfa_ce_deactivate_ntf () deact_type=%d", deact_type);
+
+  /* Check if deactivating to SLEEP mode */
+  if ((deact_type == NFC_DEACTIVATE_TYPE_SLEEP) ||
+      (deact_type == NFC_DEACTIVATE_TYPE_SLEEP_AF)) {
+    if (nfa_ce_cb.idx_wild_card == NFA_CE_LISTEN_INFO_IDX_INVALID) {
+      /* notify deactivated as sleep and wait for reactivation or deactivation
+       * to idle */
+      conn_evt.deactivated.type = deact_type;
+
+      /* if T4T AID application has not been selected then p_active_conn_cback
+       * could be NULL */
+      if (p_cb->p_active_conn_cback)
+        (*p_cb->p_active_conn_cback)(NFA_DEACTIVATED_EVT, &conn_evt);
+    } else {
+      conn_evt.ce_deactivated.handle =
+          NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)nfa_ce_cb.idx_wild_card);
+      conn_evt.ce_deactivated.type = deact_type;
+      if (p_cb->p_active_conn_cback)
+        (*p_cb->p_active_conn_cback)(NFA_CE_DEACTIVATED_EVT, &conn_evt);
+    }
+
+    return true;
+  } else {
+    deact_type = NFC_DEACTIVATE_TYPE_IDLE;
+  }
+
+  /* Tag is in idle state */
+  p_cb->flags &= ~NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP;
+
+  /* First, notify app of deactivation */
+  for (i = 0; i < NFA_CE_LISTEN_INFO_IDX_INVALID; i++) {
+    if (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE) {
+      if ((p_cb->listen_info[i].flags &
+#if (NXP_EXTNS == TRUE)
+           (NFA_CE_LISTEN_INFO_UICC | NFA_CE_LISTEN_INFO_ESE)
+#else
+           NFA_CE_LISTEN_INFO_UICC
+#endif
+               ) &&
+          (i == p_cb->idx_cur_active)) {
+        conn_evt.deactivated.type = deact_type;
+        (*p_cb->p_active_conn_cback)(NFA_DEACTIVATED_EVT, &conn_evt);
+      } else if ((p_cb->activation_params.protocol == NFA_PROTOCOL_ISO_DEP) &&
+                 (p_cb->listen_info[i].protocol_mask &
+                  NFA_PROTOCOL_MASK_ISO_DEP)) {
+        /* Don't send NFA_DEACTIVATED_EVT if NFA_ACTIVATED_EVT wasn't sent */
+        if (!(p_cb->listen_info[i].flags &
+              NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND)) {
+          if (i == NFA_CE_LISTEN_INFO_IDX_NDEF) {
+            conn_evt.deactivated.type = deact_type;
+            (*p_cb->p_active_conn_cback)(NFA_DEACTIVATED_EVT, &conn_evt);
+          } else {
+            conn_evt.ce_deactivated.handle =
+                NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)i);
+            conn_evt.ce_deactivated.type = deact_type;
+            (*p_cb->p_active_conn_cback)(NFA_CE_DEACTIVATED_EVT, &conn_evt);
+          }
+        }
+      } else if ((p_cb->activation_params.protocol == NFA_PROTOCOL_T3T) &&
+                 (p_cb->listen_info[i].protocol_mask & NFA_PROTOCOL_MASK_T3T)) {
+#if (NXP_EXTNS == TRUE)
+        /* Don't send NFA_DEACTIVATED_EVT if NFA_ACTIVATED_EVT wasn't sent */
+        if (!(p_cb->listen_info[i].flags &
+              NFA_CE_LISTEN_INFO_T3T_ACTIVATE_PND)) {
+#endif
+          if (i == NFA_CE_LISTEN_INFO_IDX_NDEF) {
+            conn_evt.deactivated.type = deact_type;
+            (*p_cb->p_active_conn_cback)(NFA_DEACTIVATED_EVT, &conn_evt);
+          } else {
+            conn_evt.ce_deactivated.handle =
+                NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)i);
+            conn_evt.ce_deactivated.type = deact_type;
+            (*p_cb->p_active_conn_cback)(NFA_CE_DEACTIVATED_EVT, &conn_evt);
+          }
+#if (NXP_EXTNS == TRUE)
+        }
+#endif
+      }
+    }
+  }
+
+  /* Check if app initiated the deactivation (due to API deregister). If so,
+   * remove entry from listen_info table. */
+  if (p_cb->flags & NFA_CE_FLAGS_APP_INIT_DEACTIVATION) {
+    p_cb->flags &= ~NFA_CE_FLAGS_APP_INIT_DEACTIVATION;
+    nfa_ce_remove_listen_info_entry(p_cb->idx_cur_active, true);
+  }
+
+  p_cb->p_active_conn_cback = NULL;
+  p_cb->idx_cur_active = NFA_CE_LISTEN_INFO_IDX_INVALID;
+
+  /* Restart listening (if any listen_info entries are still active) */
+  nfa_ce_restart_listen_check();
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_disable_local_tag
+**
+** Description      Disable local NDEF tag
+**                      - clean up control block
+**                      - remove NDEF discovery configuration
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void nfa_ce_disable_local_tag(void) {
+  tNFA_CE_CB* p_cb = &nfa_ce_cb;
+  tNFA_CONN_EVT_DATA evt_data;
+
+  NFA_TRACE_DEBUG0("Disabling local NDEF tag");
+
+  /* If local NDEF tag is in use, then disable it */
+  if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags &
+      NFA_CE_LISTEN_INFO_IN_USE) {
+    /* NDEF Tag is in not idle state */
+    if ((p_cb->flags & NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP) &&
+        (p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF)) {
+      /* wait for deactivation */
+      p_cb->flags |= NFA_CE_FLAGS_APP_INIT_DEACTIVATION;
+      nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_IDLE);
+    } else {
+      /* Notify DM to stop listening for ndef  */
+      if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle !=
+          NFA_HANDLE_INVALID) {
+        nfa_dm_delete_rf_discover(
+            p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle);
+        p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle =
+            NFA_HANDLE_INVALID;
+      }
+      nfa_ce_remove_listen_info_entry(NFA_CE_LISTEN_INFO_IDX_NDEF, true);
+    }
+  } else {
+    /* Notify application */
+    evt_data.status = NFA_STATUS_OK;
+    nfa_dm_conn_cback_event_notify(NFA_CE_LOCAL_TAG_CONFIGURED_EVT, &evt_data);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_api_cfg_local_tag
+**
+** Description      Configure local NDEF tag
+**                      - store ndef attributes in to control block
+**                      - update discovery configuration
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_ce_api_cfg_local_tag(tNFA_CE_MSG* p_ce_msg) {
+  tNFA_CE_CB* p_cb = &nfa_ce_cb;
+  tNFA_CONN_EVT_DATA conn_evt;
+
+  /* Check if disabling local tag */
+  if (p_ce_msg->local_tag.protocol_mask == 0) {
+    nfa_ce_disable_local_tag();
+    return true;
+  }
+
+  NFA_TRACE_DEBUG5(
+      "Configuring local NDEF tag: protocol_mask=%01x cur_size=%i, "
+      "max_size=%i, readonly=%i",
+      p_ce_msg->local_tag.protocol_mask, p_ce_msg->local_tag.ndef_cur_size,
+      p_ce_msg->local_tag.ndef_max_size, p_ce_msg->local_tag.read_only,
+      p_ce_msg->local_tag.uid_len);
+
+  /* If local tag was already set, then check if NFA_CeConfigureLocalTag called
+   * to change protocol mask  */
+  if ((p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags &
+       NFA_CE_LISTEN_INFO_IN_USE) &&
+      (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle !=
+       NFA_HANDLE_INVALID) &&
+      ((p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask &
+        (NFA_PROTOCOL_MASK_T3T | NFA_PROTOCOL_MASK_ISO_DEP)) !=
+       (p_ce_msg->local_tag.protocol_mask &
+        (NFA_PROTOCOL_MASK_T3T | NFA_PROTOCOL_MASK_ISO_DEP)))) {
+    /* Listening for different tag protocols. Stop discovery */
+    nfa_dm_delete_rf_discover(
+        p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle);
+    p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle =
+        NFA_HANDLE_INVALID;
+
+    /* clear NDEF contents */
+    CE_T3tSetLocalNDEFMsg(true, 0, 0, NULL, NULL);
+    CE_T4tSetLocalNDEFMsg(true, 0, 0, NULL, NULL);
+  }
+
+  /* Store NDEF info to control block */
+  p_cb->p_ndef_data = p_ce_msg->local_tag.p_ndef_data;
+  p_cb->ndef_cur_size = p_ce_msg->local_tag.ndef_cur_size;
+  p_cb->ndef_max_size = p_ce_msg->local_tag.ndef_max_size;
+
+  /* Fill in LISTEN_INFO entry for NDEF */
+  p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags =
+      NFA_CE_LISTEN_INFO_IN_USE;
+  p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask =
+      p_ce_msg->local_tag.protocol_mask;
+  p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].p_conn_cback =
+      nfa_dm_conn_cback_event_notify;
+  if (p_ce_msg->local_tag.read_only)
+    p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags |=
+        NFC_CE_LISTEN_INFO_READONLY_NDEF;
+  p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].t3t_system_code =
+      T3T_SYSTEM_CODE_NDEF;
+
+  /* Set NDEF contents */
+  conn_evt.status = NFA_STATUS_FAILED;
+
+  if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask &
+      (NFA_PROTOCOL_MASK_T3T | NFA_PROTOCOL_MASK_ISO_DEP)) {
+    /* Ok to set contents now */
+    if (nfa_ce_set_content() != NFA_STATUS_OK) {
+      NFA_TRACE_ERROR0("nfa_ce_api_cfg_local_tag: could not set contents");
+      nfa_dm_conn_cback_event_notify(NFA_CE_LOCAL_TAG_CONFIGURED_EVT,
+                                     &conn_evt);
+      return true;
+    }
+
+    /* Start listening and notify app of status */
+    conn_evt.status = nfa_ce_start_listening();
+    nfa_dm_conn_cback_event_notify(NFA_CE_LOCAL_TAG_CONFIGURED_EVT, &conn_evt);
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_api_reg_listen
+**
+** Description      Register listen params for Felica system code, T4T AID,
+**                  or UICC
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_ce_api_reg_listen(tNFA_CE_MSG* p_ce_msg) {
+  tNFA_CE_CB* p_cb = &nfa_ce_cb;
+  tNFA_CONN_EVT_DATA conn_evt;
+  uint8_t i;
+  uint8_t listen_info_idx = NFA_CE_LISTEN_INFO_IDX_INVALID;
+
+#if (NXP_EXTNS == TRUE)
+  NFA_TRACE_DEBUG1(
+      "nfa_ce_api_reg_listen ():Registering UICC/ESE/Felica/Type-4 tag "
+      "listener. Type=%i",
+      p_ce_msg->reg_listen.listen_type);
+#else
+  NFA_TRACE_DEBUG1(
+      "nfa_ce_api_reg_listen ():Registering UICC/Felica/Type-4 tag listener. "
+      "Type=%i",
+      p_ce_msg->reg_listen.listen_type);
+#endif
+
+  /* Look for available entry in listen_info table */
+  /* - If registering UICC listen, make sure there isn't another entry for the
+   * ee_handle  */
+  /* - Skip over entry 0 (reserved for local NDEF tag) */
+  for (i = 1; i < NFA_CE_LISTEN_INFO_MAX; i++) {
+    if ((p_ce_msg->reg_listen.listen_type == NFA_CE_REG_TYPE_UICC) &&
+        (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE) &&
+        (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_UICC) &&
+        (p_cb->listen_info[i].ee_handle == p_ce_msg->reg_listen.ee_handle)) {
+      NFA_TRACE_ERROR1("UICC (0x%x) listening already specified",
+                       p_ce_msg->reg_listen.ee_handle);
+      conn_evt.status = NFA_STATUS_FAILED;
+      nfa_dm_conn_cback_event_notify(NFA_CE_UICC_LISTEN_CONFIGURED_EVT,
+                                     &conn_evt);
+      return true;
+    }
+#if (NXP_EXTNS == TRUE)
+    else if ((p_ce_msg->reg_listen.listen_type == NFA_CE_REG_TYPE_ESE) &&
+             (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE) &&
+             (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_ESE) &&
+             (p_cb->listen_info[i].ee_handle ==
+              p_ce_msg->reg_listen.ee_handle)) {
+
+      NFA_TRACE_ERROR1("ESE (0x%x) listening already specified",
+                       p_ce_msg->reg_listen.ee_handle);
+      conn_evt.status = NFA_STATUS_FAILED;
+      nfa_dm_conn_cback_event_notify(NFA_CE_ESE_LISTEN_CONFIGURED_EVT,
+                                     &conn_evt);
+      return true;
+    }
+#endif
+    /* If this is a free entry, and we haven't found one yet, remember it */
+    else if ((!(p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE)) &&
+             (listen_info_idx == NFA_CE_LISTEN_INFO_IDX_INVALID)) {
+      listen_info_idx = i;
+      NFA_TRACE_DEBUG1(
+          "nfa_ce_api_reg_listen ():found free entry listen_info_idx = %d",
+          listen_info_idx);
+    }
+  }
+
+  /* Add new entry to listen_info table */
+  if (listen_info_idx == NFA_CE_LISTEN_INFO_IDX_INVALID) {
+    NFA_TRACE_ERROR1("Maximum listen callbacks exceeded (%i)",
+                     NFA_CE_LISTEN_INFO_MAX);
+
+    if (p_ce_msg->reg_listen.listen_type == NFA_CE_REG_TYPE_UICC) {
+      conn_evt.status = NFA_STATUS_FAILED;
+      nfa_dm_conn_cback_event_notify(NFA_CE_UICC_LISTEN_CONFIGURED_EVT,
+                                     &conn_evt);
+    }
+#if (NXP_EXTNS == TRUE)
+    else if (p_ce_msg->reg_listen.listen_type == NFA_CE_REG_TYPE_ESE) {
+      conn_evt.status = NFA_STATUS_FAILED;
+      nfa_dm_conn_cback_event_notify(NFA_CE_ESE_LISTEN_CONFIGURED_EVT,
+                                     &conn_evt);
+    }
+#endif
+    else {
+      /* Notify application */
+      conn_evt.ce_registered.handle = NFA_HANDLE_INVALID;
+      conn_evt.ce_registered.status = NFA_STATUS_FAILED;
+      (*p_ce_msg->reg_listen.p_conn_cback)(NFA_CE_REGISTERED_EVT, &conn_evt);
+    }
+    return true;
+  } else {
+    NFA_TRACE_DEBUG1("NFA_CE: adding listen_info entry %i", listen_info_idx);
+
+    /* Store common parameters */
+    /* Mark entry as 'in-use', and NFA_CE_LISTEN_INFO_START_NTF_PND */
+    /* (LISTEN_START_EVT will be notified when discovery successfully starts */
+    p_cb->listen_info[listen_info_idx].flags =
+        NFA_CE_LISTEN_INFO_IN_USE | NFA_CE_LISTEN_INFO_START_NTF_PND;
+    p_cb->listen_info[listen_info_idx].rf_disc_handle = NFA_HANDLE_INVALID;
+    p_cb->listen_info[listen_info_idx].protocol_mask = 0;
+
+    /* Store type-specific parameters */
+    switch (p_ce_msg->reg_listen.listen_type) {
+      case NFA_CE_REG_TYPE_ISO_DEP:
+        p_cb->listen_info[listen_info_idx].protocol_mask =
+            NFA_PROTOCOL_MASK_ISO_DEP;
+        p_cb->listen_info[listen_info_idx].flags |= NFA_CE_LISTEN_INFO_T4T_AID;
+        p_cb->listen_info[listen_info_idx].p_conn_cback =
+            p_ce_msg->reg_listen.p_conn_cback;
+
+        /* Register this AID with CE_T4T */
+        p_cb->listen_info[listen_info_idx].t4t_aid_handle = CE_T4tRegisterAID(
+            p_ce_msg->reg_listen.aid_len, p_ce_msg->reg_listen.aid,
+            nfa_ce_handle_t4t_aid_evt);
+        if (p_cb->listen_info[listen_info_idx].t4t_aid_handle ==
+            CE_T4T_AID_HANDLE_INVALID) {
+          NFA_TRACE_ERROR0("Unable to register AID");
+          p_cb->listen_info[listen_info_idx].flags = 0;
+
+          /* Notify application */
+          conn_evt.ce_registered.handle = NFA_HANDLE_INVALID;
+          conn_evt.ce_registered.status = NFA_STATUS_FAILED;
+          (*p_ce_msg->reg_listen.p_conn_cback)(NFA_CE_REGISTERED_EVT,
+                                               &conn_evt);
+
+          return true;
+        }
+        if (p_cb->listen_info[listen_info_idx].t4t_aid_handle ==
+            CE_T4T_WILDCARD_AID_HANDLE)
+          nfa_ce_cb.idx_wild_card = listen_info_idx;
+        break;
+
+      case NFA_CE_REG_TYPE_FELICA:
+        p_cb->listen_info[listen_info_idx].protocol_mask =
+            NFA_PROTOCOL_MASK_T3T;
+        p_cb->listen_info[listen_info_idx].flags |= NFA_CE_LISTEN_INFO_FELICA;
+        p_cb->listen_info[listen_info_idx].p_conn_cback =
+            p_ce_msg->reg_listen.p_conn_cback;
+
+        /* Store system code and nfcid2 */
+        p_cb->listen_info[listen_info_idx].t3t_system_code =
+            p_ce_msg->reg_listen.system_code;
+        memcpy(p_cb->listen_info[listen_info_idx].t3t_nfcid2,
+               p_ce_msg->reg_listen.nfcid2, NCI_RF_F_UID_LEN);
+        memcpy(p_cb->listen_info[listen_info_idx].t3t_pmm,
+                       p_ce_msg->reg_listen.t3tPmm, NCI_T3T_PMM_LEN);
+        break;
+
+#if (NFC_NFCEE_INCLUDED == true)
+      case NFA_CE_REG_TYPE_UICC:
+
+#if (NXP_EXTNS == TRUE)
+
+        for (i = 1; i < NFA_CE_LISTEN_INFO_MAX; i++) {
+          uint8_t tech = p_cb->listen_info[listen_info_idx].tech_mask &
+                         p_ce_msg->reg_listen.tech_mask;
+          if ((p_cb->listen_info[listen_info_idx].flags &
+               NFA_CE_LISTEN_INFO_ESE) &&
+              (tech)) {
+            NFA_TRACE_ERROR1(
+                "NFA_CE: Technology %0x listening already specified for ESE",
+                tech);
+            conn_evt.status = NFA_STATUS_FAILED;
+            nfa_dm_conn_cback_event_notify(NFA_CE_UICC_LISTEN_CONFIGURED_EVT,
+                                           &conn_evt);
+            return true;
+          }
+        }
+#endif
+        p_cb->listen_info[listen_info_idx].flags |= NFA_CE_LISTEN_INFO_UICC;
+        p_cb->listen_info[listen_info_idx].p_conn_cback =
+            &nfa_dm_conn_cback_event_notify;
+
+        /* Store EE handle and Tech */
+        p_cb->listen_info[listen_info_idx].ee_handle =
+            p_ce_msg->reg_listen.ee_handle;
+        p_cb->listen_info[listen_info_idx].tech_mask =
+            p_ce_msg->reg_listen.tech_mask;
+        break;
+
+#if (NXP_EXTNS == TRUE)
+      case NFA_CE_REG_TYPE_ESE:
+
+        for (i = 1; i < NFA_CE_LISTEN_INFO_MAX; i++) {
+          uint8_t tech = p_cb->listen_info[listen_info_idx].tech_mask &
+                         p_ce_msg->reg_listen.tech_mask;
+          if ((p_cb->listen_info[listen_info_idx].flags &
+               NFA_CE_LISTEN_INFO_UICC) &&
+              (tech)) {
+            NFA_TRACE_ERROR1(
+                "NFA_CE: Technology %0x listening already specified for UICC",
+                tech);
+            conn_evt.status = NFA_STATUS_FAILED;
+            nfa_dm_conn_cback_event_notify(NFA_CE_ESE_LISTEN_CONFIGURED_EVT,
+                                           &conn_evt);
+            return true;
+          }
+        }
+
+        p_cb->listen_info[listen_info_idx].flags |= NFA_CE_LISTEN_INFO_ESE;
+        p_cb->listen_info[listen_info_idx].p_conn_cback =
+            &nfa_dm_conn_cback_event_notify;
+
+        /* Store EE handle and Tech */
+        p_cb->listen_info[listen_info_idx].ee_handle =
+            p_ce_msg->reg_listen.ee_handle;
+        p_cb->listen_info[listen_info_idx].tech_mask =
+            p_ce_msg->reg_listen.tech_mask;
+        break;
+#endif
+
+#endif
+    }
+  }
+
+  /* Start listening */
+  conn_evt.status = nfa_ce_start_listening();
+  if (conn_evt.status != NFA_STATUS_OK) {
+    NFA_TRACE_ERROR0(
+        "nfa_ce_api_reg_listen: unable to register new listen params with DM");
+    p_cb->listen_info[listen_info_idx].flags = 0;
+  }
+
+  /* Nofitify app of status */
+  if (p_ce_msg->reg_listen.listen_type == NFA_CE_REG_TYPE_UICC) {
+    (*p_cb->listen_info[listen_info_idx].p_conn_cback)(
+        NFA_CE_UICC_LISTEN_CONFIGURED_EVT, &conn_evt);
+  }
+#if (NXP_EXTNS == TRUE)
+  else if (p_ce_msg->reg_listen.listen_type == NFA_CE_REG_TYPE_ESE) {
+    (*p_cb->listen_info[listen_info_idx].p_conn_cback)(
+        NFA_CE_ESE_LISTEN_CONFIGURED_EVT, &conn_evt);
+  }
+#endif
+  else {
+    conn_evt.ce_registered.handle = NFA_HANDLE_GROUP_CE | listen_info_idx;
+    NFA_TRACE_DEBUG1("nfa_ce_api_reg_listen: registered handle 0x%04X",
+                     conn_evt.ce_registered.handle);
+    (*p_cb->listen_info[listen_info_idx].p_conn_cback)(NFA_CE_REGISTERED_EVT,
+                                                       &conn_evt);
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_api_dereg_listen
+**
+** Description      Deregister listen params
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_ce_api_dereg_listen(tNFA_CE_MSG* p_ce_msg) {
+  tNFA_CE_CB* p_cb = &nfa_ce_cb;
+  uint8_t listen_info_idx;
+  tNFA_CONN_EVT_DATA conn_evt;
+
+#if (NFC_NFCEE_INCLUDED == true)
+  /* Check if deregistering UICC/ESE , or virtual secure element listen */
+  if (p_ce_msg->dereg_listen.listen_info
+#if (NXP_EXTNS == TRUE)
+      & (NFA_CE_LISTEN_INFO_UICC | NFA_CE_LISTEN_INFO_ESE)
+#else
+      == NFA_CE_LISTEN_INFO_UICC
+#endif
+          ) {
+    /* Deregistering UICC listen. Look for listen_info for this UICC ee handle
+     */
+    for (listen_info_idx = 0; listen_info_idx < NFA_CE_LISTEN_INFO_MAX;
+         listen_info_idx++) {
+      if ((p_cb->listen_info[listen_info_idx].flags &
+           NFA_CE_LISTEN_INFO_IN_USE) &&
+          (p_cb->listen_info[listen_info_idx].flags &
+#if (NXP_EXTNS == TRUE)
+           (NFA_CE_LISTEN_INFO_UICC | NFA_CE_LISTEN_INFO_ESE)
+#else
+           NFA_CE_LISTEN_INFO_UICC
+#endif
+               ) &&
+          (p_cb->listen_info[listen_info_idx].ee_handle ==
+           p_ce_msg->dereg_listen.handle)) {
+        /* UICC is in not idle state */
+        if ((p_cb->flags & NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP) &&
+            (p_cb->idx_cur_active == listen_info_idx)) {
+          /* wait for deactivation */
+          p_cb->flags |= NFA_CE_FLAGS_APP_INIT_DEACTIVATION;
+          nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_IDLE);
+        } else {
+          /* Stop listening */
+          if (p_cb->listen_info[listen_info_idx].rf_disc_handle !=
+              NFA_HANDLE_INVALID) {
+            nfa_dm_delete_rf_discover(
+                p_cb->listen_info[listen_info_idx].rf_disc_handle);
+            p_cb->listen_info[listen_info_idx].rf_disc_handle =
+                NFA_HANDLE_INVALID;
+          }
+
+          /* Remove entry and notify application */
+          nfa_ce_remove_listen_info_entry(listen_info_idx, true);
+        }
+        break;
+      }
+    }
+
+    if (listen_info_idx == NFA_CE_LISTEN_INFO_MAX) {
+      conn_evt.status = NFA_STATUS_INVALID_PARAM;
+#if (NXP_EXTNS == TRUE)
+      NFA_TRACE_ERROR0(
+          "nfa_ce_api_dereg_listen (): cannot find listen_info for UICC/ESE");
+      if (p_ce_msg->dereg_listen.listen_info & NFA_CE_LISTEN_INFO_UICC) {
+        nfa_dm_conn_cback_event_notify(NFA_CE_UICC_LISTEN_CONFIGURED_EVT,
+                                       &conn_evt);
+      } else if (p_ce_msg->dereg_listen.listen_info & NFA_CE_LISTEN_INFO_ESE) {
+        nfa_dm_conn_cback_event_notify(NFA_CE_ESE_LISTEN_CONFIGURED_EVT,
+                                       &conn_evt);
+      }
+#else
+      NFA_TRACE_ERROR0(
+          "nfa_ce_api_dereg_listen (): cannot find listen_info for UICC");
+      nfa_dm_conn_cback_event_notify(NFA_CE_UICC_LISTEN_CONFIGURED_EVT,
+                                     &conn_evt);
+#endif
+    }
+  } else
+#endif
+  {
+    /* Deregistering virtual secure element listen */
+    listen_info_idx = p_ce_msg->dereg_listen.handle & NFA_HANDLE_MASK;
+    if (nfa_ce_cb.idx_wild_card == listen_info_idx) {
+      nfa_ce_cb.idx_wild_card = NFA_CE_LISTEN_INFO_IDX_INVALID;
+    }
+
+    if ((listen_info_idx < NFA_CE_LISTEN_INFO_MAX) &&
+        (p_cb->listen_info[listen_info_idx].flags &
+         NFA_CE_LISTEN_INFO_IN_USE)) {
+      /* virtual secure element is in not idle state */
+      if ((p_cb->flags & NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP) &&
+          (p_cb->idx_cur_active == listen_info_idx)) {
+        /* wait for deactivation */
+        p_cb->flags |= NFA_CE_FLAGS_APP_INIT_DEACTIVATION;
+        nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_IDLE);
+      } else {
+        /* Stop listening */
+        if (p_cb->listen_info[listen_info_idx].rf_disc_handle !=
+            NFA_HANDLE_INVALID) {
+          nfa_dm_delete_rf_discover(
+              p_cb->listen_info[listen_info_idx].rf_disc_handle);
+          p_cb->listen_info[listen_info_idx].rf_disc_handle =
+              NFA_HANDLE_INVALID;
+        }
+
+        /* Remove entry and notify application */
+        nfa_ce_remove_listen_info_entry(listen_info_idx, true);
+      }
+    } else {
+      NFA_TRACE_ERROR0(
+          "nfa_ce_api_dereg_listen (): cannot find listen_info for "
+          "Felica/T4tAID");
+      conn_evt.status = NFA_STATUS_INVALID_PARAM;
+      nfa_dm_conn_cback_event_notify(NFA_CE_DEREGISTERED_EVT, &conn_evt);
+    }
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_api_cfg_isodep_tech
+**
+** Description      Configure the technologies (NFC-A and/or NFC-B) to listen
+**                  for ISO-DEP
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_ce_api_cfg_isodep_tech(tNFA_CE_MSG* p_ce_msg) {
+  nfa_ce_cb.isodep_disc_mask = 0;
+  if (p_ce_msg->hdr.layer_specific & NFA_TECHNOLOGY_MASK_A)
+    nfa_ce_cb.isodep_disc_mask = NFA_DM_DISC_MASK_LA_ISO_DEP;
+
+  if (p_ce_msg->hdr.layer_specific & NFA_TECHNOLOGY_MASK_B)
+    nfa_ce_cb.isodep_disc_mask |= NFA_DM_DISC_MASK_LB_ISO_DEP;
+  return true;
+}
diff --git a/src/nfa/ce/nfa_ce_api.c b/src/nfa/ce/nfa_ce_api.c
new file mode 100644
index 0000000..e516d81
--- /dev/null
+++ b/src/nfa/ce/nfa_ce_api.c
@@ -0,0 +1,512 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2011-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  NFA interface for card emulation
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_api.h"
+#include "nfa_sys.h"
+#include "nfa_ce_int.h"
+#include "nfa_sys_int.h"
+
+/*******************************************************************************
+**
+** Function         nfa_ce_api_deregister_listen
+**
+** Description      Internal function called by listening for Felica system
+**                  code, ISO-DEP AID, or UICC technology
+**
+** Returns:
+**                  NFA_STATUS_OK,            if command accepted
+**                  NFA_STATUS_BAD_HANDLE     invalid handle
+**                  NFA_STATUS_FAILED:        otherwise
+**
+*******************************************************************************/
+tNFA_STATUS nfa_ce_api_deregister_listen(tNFA_HANDLE handle,
+                                         uint32_t listen_info) {
+  tNFA_CE_MSG* p_ce_msg;
+
+  /* Validate handle */
+  if ((listen_info != NFA_CE_LISTEN_INFO_UICC
+#if (NXP_EXTNS == TRUE)
+       && listen_info != NFA_CE_LISTEN_INFO_ESE
+#endif
+       ) &&
+      ((handle & NFA_HANDLE_GROUP_MASK) != NFA_HANDLE_GROUP_CE)) {
+    NFA_TRACE_ERROR0("nfa_ce_api_reregister_listen: Invalid handle");
+    return (NFA_STATUS_BAD_HANDLE);
+  }
+
+  p_ce_msg = (tNFA_CE_MSG*)GKI_getbuf((uint16_t)(sizeof(tNFA_CE_MSG)));
+  if (p_ce_msg != NULL) {
+    p_ce_msg->hdr.event = NFA_CE_API_DEREG_LISTEN_EVT;
+    p_ce_msg->dereg_listen.handle = handle;
+    p_ce_msg->dereg_listen.listen_info = listen_info;
+
+    nfa_sys_sendmsg(p_ce_msg);
+
+    return (NFA_STATUS_OK);
+  } else {
+    NFA_TRACE_ERROR0("nfa_ce_api_reregister_listen: Out of buffers");
+    return (NFA_STATUS_FAILED);
+  }
+}
+
+/*****************************************************************************
+**  APIs
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         NFA_CeConfigureLocalTag
+**
+** Description      Configure local NDEF tag.
+**
+**                  Tag events will be notifed using the tNFA_CONN_CBACK
+**                  (registered during NFA_Enable)
+**
+**                  The NFA_CE_LOCAL_TAG_CONFIGURED_EVT reports the status of
+**                  the operation.
+**
+**                  Activation and deactivation are reported using the
+**                  NFA_ACTIVATED_EVT and NFA_DEACTIVATED_EVT events
+**
+**                  If a write-request is received to update the tag memory,
+**                  an NFA_CE_NDEF_WRITE_CPLT_EVT will notify the application,
+**                  along with a buffer containing the updated contents.
+**
+**                  To disable the local NDEF tag, set protocol_mask=0
+**
+**                  The NDEF data provided by p_ndef_data must be persistent
+**                  as long as the local NDEF tag is enabled.
+**
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function. Also, Input parameters
+**                  p_uid and uid_len are reserved for future use.
+**
+** Returns:
+**                  NFA_STATUS_OK,            if command accepted
+**                  NFA_STATUS_INVALID_PARAM,
+**                      if protocol_maks is not 0 and p_ndef_data is NULL
+**                  (or)uid_len is not 0
+**                  (or)if protocol mask is set for Type 1 or Type 2
+**
+**                  NFA_STATUS_FAILED:        otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_CeConfigureLocalTag(tNFA_PROTOCOL_MASK protocol_mask,
+                                    uint8_t* p_ndef_data,
+                                    uint16_t ndef_cur_size,
+                                    uint16_t ndef_max_size, bool read_only,
+                                    uint8_t uid_len, uint8_t* p_uid)
+
+{
+  tNFA_CE_MSG* p_msg;
+
+  NFA_TRACE_API0("NFA_CeConfigureLocalTag ()");
+
+  if (protocol_mask) {
+    /* If any protocols are specified, then NDEF buffer pointer must be non-NULL
+     */
+    if (p_ndef_data == NULL) {
+      NFA_TRACE_ERROR0("NFA_CeConfigureLocalTag: NULL ndef data pointer");
+      return (NFA_STATUS_INVALID_PARAM);
+    }
+
+    if ((protocol_mask & NFA_PROTOCOL_MASK_T1T) ||
+        (protocol_mask & NFA_PROTOCOL_MASK_T2T)) {
+      NFA_TRACE_ERROR0(
+          "NFA_CeConfigureLocalTag: Cannot emulate Type 1 / Type 2 tag");
+      return (NFA_STATUS_INVALID_PARAM);
+    }
+
+    if (uid_len) {
+      NFA_TRACE_ERROR1(
+          "NFA_CeConfigureLocalTag: Cannot Set UID for Protocol_mask: 0x%x",
+          protocol_mask);
+      return (NFA_STATUS_INVALID_PARAM);
+    }
+  }
+  p_msg = (tNFA_CE_MSG*)GKI_getbuf((uint16_t)sizeof(tNFA_CE_MSG));
+  if (p_msg != NULL) {
+    p_msg->local_tag.hdr.event = NFA_CE_API_CFG_LOCAL_TAG_EVT;
+
+    /* Copy ndef info */
+    p_msg->local_tag.protocol_mask = protocol_mask;
+    p_msg->local_tag.p_ndef_data = p_ndef_data;
+    p_msg->local_tag.ndef_cur_size = ndef_cur_size;
+    p_msg->local_tag.ndef_max_size = ndef_max_size;
+    p_msg->local_tag.read_only = read_only;
+    p_msg->local_tag.uid_len = uid_len;
+
+    if (uid_len) memcpy(p_msg->local_tag.uid, p_uid, uid_len);
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_CeConfigureUiccListenTech
+**
+** Description      Configure listening for the UICC, using the specified
+**                  technologies.
+**
+**                  Events will be notifed using the tNFA_CONN_CBACK
+**                  (registered during NFA_Enable)
+**
+**                  The NFA_CE_UICC_LISTEN_CONFIGURED_EVT reports the status of
+**                  the operation.
+**
+**                  Activation and deactivation are reported using the
+**                  NFA_ACTIVATED_EVT and NFA_DEACTIVATED_EVT events
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns:
+**                  NFA_STATUS_OK, if command accepted
+**                  NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_CeConfigureUiccListenTech(tNFA_HANDLE ee_handle,
+                                          tNFA_TECHNOLOGY_MASK tech_mask) {
+#if (NFC_NFCEE_INCLUDED == true)
+  tNFA_CE_MSG* p_msg;
+
+  NFA_TRACE_API2(
+      "NFA_CeConfigureUiccListenTech () ee_handle = 0x%x tech_mask = 0x%x",
+      ee_handle, tech_mask);
+
+  /* If tech_mask is zero, then app is disabling listening for specified uicc */
+  if (tech_mask == 0) {
+    return (nfa_ce_api_deregister_listen(ee_handle, NFA_CE_LISTEN_INFO_UICC));
+  }
+
+  /* Otherwise then app is configuring uicc listen for the specificed
+   * technologies */
+  p_msg = (tNFA_CE_MSG*)GKI_getbuf((uint16_t)sizeof(tNFA_CE_MSG));
+  if (p_msg != NULL) {
+    p_msg->reg_listen.hdr.event = NFA_CE_API_REG_LISTEN_EVT;
+    p_msg->reg_listen.listen_type = NFA_CE_REG_TYPE_UICC;
+
+    p_msg->reg_listen.ee_handle = ee_handle;
+    p_msg->reg_listen.tech_mask = tech_mask;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+#else
+  NFA_TRACE_ERROR0(
+      "NFA_CeConfigureUiccListenTech () NFCEE related functions are not "
+      "enabled!");
+#endif
+  return (NFA_STATUS_FAILED);
+}
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         NFA_CeConfigureEseListenTech
+**
+** Description      Configure listening for the Ese, using the specified
+**                  technologies.
+**
+**                  Events will be notifed using the tNFA_CONN_CBACK
+**                  (registered during NFA_Enable)
+**
+**                  The NFA_CE_ESE_LISTEN_CONFIGURED_EVT reports the status of
+*the
+**                  operation.
+**
+**                  Activation and deactivation are reported using the
+**                  NFA_ACTIVATED_EVT and NFA_DEACTIVATED_EVT events
+**
+** Note:            If RF discovery is started,
+*NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns:
+**                  NFA_STATUS_OK, if command accepted
+**                  NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_CeConfigureEseListenTech(tNFA_HANDLE ee_handle,
+                                         tNFA_TECHNOLOGY_MASK tech_mask) {
+#if (NFC_NFCEE_INCLUDED == true)
+  tNFA_CE_MSG* p_msg;
+
+  NFA_TRACE_API1("NFA_CeConfigureEseListenTech () ee_handle = 0x%x", ee_handle);
+
+  /* If tech_mask is zero, then app is disabling listening for specified uicc */
+  if (tech_mask == 0) {
+    return (nfa_ce_api_deregister_listen(ee_handle, NFA_CE_LISTEN_INFO_ESE));
+  }
+
+  /* Otherwise then app is configuring ese listen for the specificed
+   * technologies */
+  if ((p_msg = (tNFA_CE_MSG*)GKI_getbuf((uint16_t)sizeof(tNFA_CE_MSG))) !=
+      NULL) {
+    p_msg->reg_listen.hdr.event = NFA_CE_API_REG_LISTEN_EVT;
+    p_msg->reg_listen.listen_type = NFA_CE_REG_TYPE_ESE;
+
+    p_msg->reg_listen.ee_handle = ee_handle;
+    p_msg->reg_listen.tech_mask = tech_mask;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+#else
+  NFA_TRACE_ERROR0(
+      "NFA_CeConfigureEseListenTech () NFCEE related functions are not "
+      "enabled!");
+#endif
+  return (NFA_STATUS_FAILED);
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         NFA_CeRegisterFelicaSystemCodeOnDH
+**
+** Description      Register listening callback for Felica system code
+**
+**                  The NFA_CE_REGISTERED_EVT reports the status of the
+**                  operation.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns:
+**                  NFA_STATUS_OK, if command accepted
+**                  NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_CeRegisterFelicaSystemCodeOnDH(uint16_t system_code,
+                                               uint8_t nfcid2[NCI_RF_F_UID_LEN],
+                                               tNFA_CONN_CBACK* p_conn_cback) {
+  tNFA_CE_MSG* p_msg;
+
+  NFA_TRACE_API0("NFA_CeRegisterFelicaSystemCodeOnDH ()");
+
+  /* Validate parameters */
+  if (p_conn_cback == NULL) return (NFA_STATUS_INVALID_PARAM);
+
+  p_msg = (tNFA_CE_MSG*)GKI_getbuf((uint16_t)sizeof(tNFA_CE_MSG));
+  if (p_msg != NULL) {
+    p_msg->reg_listen.hdr.event = NFA_CE_API_REG_LISTEN_EVT;
+    p_msg->reg_listen.p_conn_cback = p_conn_cback;
+    p_msg->reg_listen.listen_type = NFA_CE_REG_TYPE_FELICA;
+
+    /* Listen info */
+    memcpy(p_msg->reg_listen.nfcid2, nfcid2, NCI_RF_F_UID_LEN);
+    p_msg->reg_listen.system_code = system_code;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_CeDeregisterFelicaSystemCodeOnDH
+**
+** Description      Deregister listening callback for Felica
+**                  (previously registered using
+**                  NFA_CeRegisterFelicaSystemCodeOnDH)
+**
+**                  The NFA_CE_DEREGISTERED_EVT reports the status of the
+**                  operation.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if invalid handle
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_CeDeregisterFelicaSystemCodeOnDH(tNFA_HANDLE handle) {
+  NFA_TRACE_API1("NFA_CeDeregisterFelicaSystemCodeOnDH (): handle:0x%X",
+                 handle);
+  return (nfa_ce_api_deregister_listen(handle, NFA_CE_LISTEN_INFO_FELICA));
+}
+
+/*******************************************************************************
+**
+** Function         NFA_CeRegisterAidOnDH
+**
+** Description      Register listening callback for the specified ISODEP AID
+**
+**                  The NFA_CE_REGISTERED_EVT reports the status of the
+**                  operation.
+**
+**                  If no AID is specified (aid_len=0), then p_conn_cback will
+**                  will get notifications for any AIDs routed to the DH. This
+**                  over-rides callbacks registered for specific AIDs.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns:
+**                  NFA_STATUS_OK, if command accepted
+**                  NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_CeRegisterAidOnDH(uint8_t aid[NFC_MAX_AID_LEN], uint8_t aid_len,
+                                  tNFA_CONN_CBACK* p_conn_cback) {
+  tNFA_CE_MSG* p_msg;
+
+  NFA_TRACE_API0("NFA_CeRegisterAidOnDH ()");
+
+/* Validate parameters */
+#if (NXP_EXTNS == TRUE)
+  if ((p_conn_cback == NULL) || (aid_len > NFC_MAX_AID_LEN))
+#else
+  if (p_conn_cback == NULL)
+#endif
+    return (NFA_STATUS_INVALID_PARAM);
+
+  p_msg = (tNFA_CE_MSG*)GKI_getbuf((uint16_t)sizeof(tNFA_CE_MSG));
+  if (p_msg != NULL) {
+    p_msg->reg_listen.hdr.event = NFA_CE_API_REG_LISTEN_EVT;
+    p_msg->reg_listen.p_conn_cback = p_conn_cback;
+    p_msg->reg_listen.listen_type = NFA_CE_REG_TYPE_ISO_DEP;
+
+    /* Listen info */
+    memcpy(p_msg->reg_listen.aid, aid, aid_len);
+    p_msg->reg_listen.aid_len = aid_len;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_CeDeregisterAidOnDH
+**
+** Description      Deregister listening callback for ISODEP AID
+**                  (previously registered using NFA_CeRegisterAidOnDH)
+**
+**                  The NFA_CE_DEREGISTERED_EVT reports the status of the
+**                  operation.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if invalid handle
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_CeDeregisterAidOnDH(tNFA_HANDLE handle) {
+  NFA_TRACE_API1("NFA_CeDeregisterAidOnDH (): handle:0x%X", handle);
+  return (nfa_ce_api_deregister_listen(handle, NFA_CE_LISTEN_INFO_T4T_AID));
+}
+
+/*******************************************************************************
+**
+** Function         NFA_CeSetIsoDepListenTech
+**
+** Description      Set the technologies (NFC-A and/or NFC-B) to listen for when
+**                  NFA_CeConfigureLocalTag or NFA_CeDeregisterAidOnDH are
+**                  called.
+**
+**                  By default (if this API is not called), NFA will listen
+**                  for both NFC-A and NFC-B for ISODEP.
+**
+** Note:            If listening for ISODEP on UICC, the DH listen callbacks
+**                  may still get activate notifications for ISODEP if the
+**                  reader/writer selects an AID that is not routed to the UICC
+**                  (regardless of whether A or B was disabled using
+**                  NFA_CeSetIsoDepListenTech)
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns:
+**                  NFA_STATUS_OK, if command accepted
+**                  NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_CeSetIsoDepListenTech(tNFA_TECHNOLOGY_MASK tech_mask) {
+  tNFA_CE_MSG* p_msg;
+  tNFA_TECHNOLOGY_MASK use_mask =
+      (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B);
+
+  NFA_TRACE_API1("NFA_CeSetIsoDepListenTech (): 0x%x", tech_mask);
+  if (((tech_mask & use_mask) == 0) || ((tech_mask & ~use_mask) != 0)) {
+    NFA_TRACE_ERROR0("NFA_CeSetIsoDepListenTech: Invalid technology mask");
+    return (NFA_STATUS_INVALID_PARAM);
+  }
+
+  p_msg = (tNFA_CE_MSG*)GKI_getbuf((uint16_t)sizeof(tNFA_CE_MSG));
+  if (p_msg != NULL) {
+    p_msg->hdr.event = NFA_CE_API_CFG_ISODEP_TECH_EVT;
+    p_msg->hdr.layer_specific = tech_mask;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
diff --git a/src/nfa/ce/nfa_ce_main.c b/src/nfa/ce/nfa_ce_main.c
new file mode 100644
index 0000000..013f078
--- /dev/null
+++ b/src/nfa/ce/nfa_ce_main.c
@@ -0,0 +1,228 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2011-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the main implementation file for the NFA_CE
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_ce_api.h"
+#include "nfa_sys.h"
+#include "nfa_ce_int.h"
+#include "nfa_dm_int.h"
+#include "nfa_sys_int.h"
+
+/* NFA_CE control block */
+tNFA_CE_CB nfa_ce_cb;
+
+/*****************************************************************************
+** Constants and types
+*****************************************************************************/
+#define NFA_CE_DEFAULT_ISODEP_DISC_MASK \
+  (NFA_DM_DISC_MASK_LA_ISO_DEP | NFA_DM_DISC_MASK_LB_ISO_DEP)
+static void nfa_ce_proc_nfcc_power_mode(uint8_t nfcc_power_mode);
+
+static const tNFA_SYS_REG nfa_ce_sys_reg = {
+    NULL, nfa_ce_hdl_event, nfa_ce_sys_disable, nfa_ce_proc_nfcc_power_mode};
+
+/* NFA_CE actions */
+const tNFA_CE_ACTION nfa_ce_action_tbl[] = {
+    nfa_ce_api_cfg_local_tag,   /* NFA_CE_API_CFG_LOCAL_TAG_EVT */
+    nfa_ce_api_reg_listen,      /* NFA_CE_API_REG_LISTEN_EVT    */
+    nfa_ce_api_dereg_listen,    /* NFA_CE_API_DEREG_LISTEN_EVT  */
+    nfa_ce_api_cfg_isodep_tech, /* NFA_CE_API_CFG_ISODEP_TECH_EVT*/
+    nfa_ce_activate_ntf,        /* NFA_CE_ACTIVATE_NTF_EVT      */
+    nfa_ce_deactivate_ntf,      /* NFA_CE_DEACTIVATE_NTF_EVT    */
+};
+#define NFA_CE_ACTION_TBL_SIZE \
+  (sizeof(nfa_ce_action_tbl) / sizeof(tNFA_CE_ACTION))
+
+/*****************************************************************************
+** Local function prototypes
+*****************************************************************************/
+#if (BT_TRACE_VERBOSE == true)
+static char* nfa_ce_evt_2_str(uint16_t event);
+#endif
+
+/*******************************************************************************
+**
+** Function         nfa_ce_init
+**
+** Description      Initialize NFA CE
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_ce_init(void) {
+  NFA_TRACE_DEBUG0("nfa_ce_init ()");
+
+  /* initialize control block */
+  memset(&nfa_ce_cb, 0, sizeof(tNFA_CE_CB));
+
+  /* Generate a random NFCID for Type-3 NDEF emulation (Type-3 tag NFCID2 must
+   * start with 02:FE) */
+  nfa_ce_t3t_generate_rand_nfcid(
+      nfa_ce_cb.listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].t3t_nfcid2);
+  nfa_ce_cb.listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle =
+      NFA_HANDLE_INVALID;
+  nfa_ce_cb.isodep_disc_mask = NFA_CE_DEFAULT_ISODEP_DISC_MASK;
+  nfa_ce_cb.idx_wild_card = NFA_CE_LISTEN_INFO_IDX_INVALID;
+
+  /* register message handler on NFA SYS */
+  nfa_sys_register(NFA_ID_CE, &nfa_ce_sys_reg);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_sys_disable
+**
+** Description      Clean up ce sub-system
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ce_sys_disable(void) {
+  tNFA_CE_LISTEN_INFO* p_info;
+  uint8_t xx;
+
+  NFC_SetStaticRfCback(NULL);
+
+  /* Free scratch buf if any */
+  nfa_ce_free_scratch_buf();
+
+  /* Delete discovery handles */
+  for (xx = 0, p_info = nfa_ce_cb.listen_info; xx < NFA_CE_LISTEN_INFO_MAX;
+       xx++, p_info++) {
+    if ((p_info->flags & NFA_CE_LISTEN_INFO_IN_USE) &&
+        (p_info->rf_disc_handle != NFA_HANDLE_INVALID)) {
+      nfa_dm_delete_rf_discover(p_info->rf_disc_handle);
+      p_info->rf_disc_handle = NFA_HANDLE_INVALID;
+    }
+  }
+
+  nfa_sys_deregister(NFA_ID_CE);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_proc_nfcc_power_mode
+**
+** Description      Processing NFCC power mode changes
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_ce_proc_nfcc_power_mode(uint8_t nfcc_power_mode) {
+  tNFA_CE_CB* p_cb = &nfa_ce_cb;
+  uint8_t listen_info_idx;
+
+  NFA_TRACE_DEBUG1("nfa_ce_proc_nfcc_power_mode (): nfcc_power_mode=%d",
+                   nfcc_power_mode);
+
+  /* if NFCC power mode is change to full power */
+  if (nfcc_power_mode == NFA_DM_PWR_MODE_FULL) {
+    nfa_ce_restart_listen_check();
+  } else {
+    for (listen_info_idx = 0; listen_info_idx < NFA_CE_LISTEN_INFO_IDX_INVALID;
+         listen_info_idx++) {
+      /* add RF discovery to DM only if it is not added yet */
+      if ((p_cb->listen_info[listen_info_idx].flags &
+           NFA_CE_LISTEN_INFO_IN_USE) &&
+          (p_cb->listen_info[listen_info_idx].rf_disc_handle !=
+           NFA_HANDLE_INVALID)) {
+        nfa_dm_delete_rf_discover(
+            p_cb->listen_info[listen_info_idx].rf_disc_handle);
+        p_cb->listen_info[listen_info_idx].rf_disc_handle = NFA_HANDLE_INVALID;
+      }
+    }
+  }
+
+  nfa_sys_cback_notify_nfcc_power_mode_proc_complete(NFA_ID_CE);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_hdl_event
+**
+** Description      nfa rw main event handling function.
+**
+** Returns          bool
+**
+*******************************************************************************/
+bool nfa_ce_hdl_event(NFC_HDR* p_msg) {
+  uint16_t act_idx;
+  bool freebuf = true;
+
+#if (BT_TRACE_VERBOSE == true)
+  NFA_TRACE_EVENT3("nfa_ce_handle_event event: %s (0x%02x), flags: %08x",
+                   nfa_ce_evt_2_str(p_msg->event), p_msg->event,
+                   nfa_ce_cb.flags);
+#else
+  NFA_TRACE_EVENT2("nfa_ce_handle_event event: 0x%x, flags: %08x", p_msg->event,
+                   nfa_ce_cb.flags);
+#endif
+
+  /* Get NFA_RW sub-event */
+  act_idx = (p_msg->event & 0x00FF);
+  if (act_idx < NFA_CE_ACTION_TBL_SIZE) {
+    freebuf = (*nfa_ce_action_tbl[act_idx])((tNFA_CE_MSG*)p_msg);
+  }
+
+  /* if vendor specific event handler is registered */
+  if (nfa_ce_cb.p_vs_evt_hdlr) {
+    (*nfa_ce_cb.p_vs_evt_hdlr)(p_msg);
+  }
+
+  return freebuf;
+}
+
+#if (BT_TRACE_VERBOSE == true)
+/*******************************************************************************
+**
+** Function         nfa_ce_evt_2_str
+**
+** Description      convert nfc evt to string
+**
+*******************************************************************************/
+static char* nfa_ce_evt_2_str(uint16_t event) {
+  switch (event) {
+    case NFA_CE_API_CFG_LOCAL_TAG_EVT:
+      return "NFA_CE_API_CFG_LOCAL_TAG_EVT";
+
+    case NFA_CE_API_REG_LISTEN_EVT:
+      return "NFA_CE_API_REG_LISTEN_EVT";
+
+    case NFA_CE_API_DEREG_LISTEN_EVT:
+      return "NFA_CE_API_DEREG_LISTEN_EVT";
+
+    case NFA_CE_API_CFG_ISODEP_TECH_EVT:
+      return "NFA_CE_API_CFG_ISODEP_TECH_EVT";
+
+    case NFA_CE_ACTIVATE_NTF_EVT:
+      return "NFA_CE_ACTIVATE_NTF_EVT";
+
+    case NFA_CE_DEACTIVATE_NTF_EVT:
+      return "NFA_CE_DEACTIVATE_NTF_EVT";
+
+    default:
+      return "Unknown";
+  }
+}
+#endif /* BT_TRACE_VERBOSE */
diff --git a/src/nfa/dm/nfa_dm_act.c b/src/nfa/dm/nfa_dm_act.c
new file mode 100644
index 0000000..f49cd30
--- /dev/null
+++ b/src/nfa/dm/nfa_dm_act.c
@@ -0,0 +1,2089 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  This file contains the action functions for device manager state
+ *  machine.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_sys.h"
+#include "nfa_api.h"
+#include "nfa_dm_int.h"
+#include "nfa_sys_int.h"
+#include "nfa_ce_int.h"
+#include "nfc_api.h"
+#include "nfa_rw_int.h"
+#include "nfa_rw_api.h"
+#include "nfa_p2p_int.h"
+#include "nci_hmsgs.h"
+
+#if (NFC_NFCEE_INCLUDED == true)
+#include "nfa_ee_int.h"
+#include "nfa_hci_int.h"
+#endif
+
+#if (NFA_SNEP_INCLUDED == true)
+#include "nfa_snep_int.h"
+#endif
+
+/* This is the timeout value to guarantee disable is performed within reasonable
+ * amount of time */
+#ifndef NFA_DM_DISABLE_TIMEOUT_VAL
+#define NFA_DM_DISABLE_TIMEOUT_VAL 1000
+#endif
+
+static void nfa_dm_set_init_nci_params(void);
+static tNFA_STATUS nfa_dm_start_polling(void);
+static bool nfa_dm_deactivate_polling(void);
+static void nfa_dm_excl_disc_cback(tNFA_DM_RF_DISC_EVT event,
+                                   tNFC_DISCOVER* p_data);
+static void nfa_dm_poll_disc_cback(tNFA_DM_RF_DISC_EVT event,
+                                   tNFC_DISCOVER* p_data);
+#if (NXP_EXTNS == TRUE)
+extern bool gFelicaReaderMode;
+#endif
+
+/*******************************************************************************
+**
+** Function         nfa_dm_module_init_cback
+**
+** Description      Processing initialization complete event from sub-modules
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_dm_module_init_cback(void) {
+  tNFA_DM_CBACK_DATA dm_cback_data;
+
+  nfa_dm_cb.flags &= ~NFA_DM_FLAGS_ENABLE_EVT_PEND;
+
+  /* All subsystem are initialized */
+  dm_cback_data.status = NFA_STATUS_OK;
+  (*nfa_dm_cb.p_dm_cback)(NFA_DM_ENABLE_EVT, &dm_cback_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_nfcc_power_mode_proc_complete_cback
+**
+** Description      Processing complete of processing NFCC power state change
+**                  from all sub-modules
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_dm_nfcc_power_mode_proc_complete_cback(void) {
+  tNFA_DM_PWR_MODE_CHANGE power_mode_change;
+
+  NFA_TRACE_DEBUG1(
+      "nfa_dm_nfcc_power_mode_proc_complete_cback () nfcc_pwr_mode = 0x%x",
+      nfa_dm_cb.nfcc_pwr_mode);
+
+  /* if NFCC power state is change to full power */
+  if (nfa_dm_cb.nfcc_pwr_mode != NFA_DM_PWR_MODE_OFF_SLEEP) {
+    nfa_dm_cb.flags &= ~NFA_DM_FLAGS_NFCC_IS_RESTORING;
+
+    /* reconfigure BRCM NFCC */
+    nfa_dm_disc_sm_execute(NFA_DM_RF_DISCOVER_CMD, NULL);
+  }
+
+  nfa_dm_cb.flags &= ~NFA_DM_FLAGS_SETTING_PWR_MODE;
+
+  power_mode_change.status = NFA_STATUS_OK;
+  power_mode_change.power_mode = nfa_dm_cb.nfcc_pwr_mode;
+  (*nfa_dm_cb.p_dm_cback)(NFA_DM_PWR_MODE_CHANGE_EVT,
+                          (void*)&power_mode_change);
+}
+/*******************************************************************************
+**
+** Function         nfa_dm_sys_enable
+**
+** Description      This function on enable
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_sys_enable(void) { nfa_dm_set_init_nci_params(); }
+
+/*******************************************************************************
+**
+** Function         nfa_dm_set_init_nci_params
+**
+** Description      Set initial NCI configuration parameters
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_set_init_nci_params(void) {
+  uint8_t xx, yy;
+
+  /* set NCI default value if other than zero */
+
+   if(NFC_GetNCIVersion() == NCI_VERSION_2_0) {
+    /* Default Values: For each identifier
+     * Octet 0-1   = OxFF
+     * Octet 2     = Ox02
+     * Octet 3     = 0xFE
+     * Octet 4-9   = 0x00
+     * Octet 10-17 = 0xFF*/
+    for (xx = 0; xx < NFA_CE_LISTEN_INFO_MAX; xx++)
+    {
+        nfa_dm_cb.params.lf_t3t_id[xx][0] = 0xFF;
+        nfa_dm_cb.params.lf_t3t_id[xx][1] = 0xFF;
+        nfa_dm_cb.params.lf_t3t_id[xx][2] = 0x02;
+        nfa_dm_cb.params.lf_t3t_id[xx][3] = 0xFE;
+    }
+
+    /* LF_T3T_PMM value is added to LF_T3T_IDENTIFIERS_X in NCI2.0. */
+    for (xx = 0; xx < NFA_CE_LISTEN_INFO_MAX ; xx++)
+    {
+        for (yy = 10; yy < NCI_PARAM_LEN_LF_T3T_ID(NCI_VERSION_2_0) ; yy++)
+           nfa_dm_cb.params.lf_t3t_id[xx][yy] = 0xFF;
+    }
+  } else {
+      /* LF_T3T_IDENTIFIERS_1/2/.../16 */
+      for (xx = 0; xx < NFA_CE_LISTEN_INFO_MAX; xx++) {
+        nfa_dm_cb.params.lf_t3t_id[xx][0] = 0xFF;
+        nfa_dm_cb.params.lf_t3t_id[xx][1] = 0xFF;
+        nfa_dm_cb.params.lf_t3t_id[xx][2] = 0x02;
+        nfa_dm_cb.params.lf_t3t_id[xx][3] = 0xFE;
+      }
+
+      /* LF_T3T_PMM */
+      for (xx = 0; xx < NCI_PARAM_LEN_LF_T3T_PMM; xx++) {
+        nfa_dm_cb.params.lf_t3t_pmm[xx] = 0xFF;
+      }
+  }
+
+  /* LF_T3T_FLAGS:
+  ** DH needs to set this configuration, even if default value (not listening)
+  ** is used, to let NFCC know of intention (not listening) of DH.
+  */
+
+  /* FWI */
+  nfa_dm_cb.params.fwi[0] = 0x04;
+
+  /* WT */
+  nfa_dm_cb.params.wt[0] = 14;
+
+// LF_T3T_PMM is not supported.
+/* Set CE default configuration */
+#if (NXP_EXTNS != TRUE)
+  if (p_nfa_dm_ce_cfg[0]) {
+    nfa_dm_check_set_config(p_nfa_dm_ce_cfg[0], &p_nfa_dm_ce_cfg[1], false);
+  }
+#endif
+
+  /* Set optional general default configuration */
+  if (p_nfa_dm_gen_cfg && p_nfa_dm_gen_cfg[0]) {
+    nfa_dm_check_set_config(p_nfa_dm_gen_cfg[0], &p_nfa_dm_gen_cfg[1], false);
+  }
+
+  if (p_nfa_dm_interface_mapping && nfa_dm_num_dm_interface_mapping) {
+  NFA_TRACE_DEBUG1("nfa_dm_num_dm_interface_mapping=%d",
+  nfa_dm_num_dm_interface_mapping);
+    NFC_DiscoveryMap(nfa_dm_num_dm_interface_mapping,
+                     p_nfa_dm_interface_mapping, NULL);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_proc_nfcc_power_mode
+**
+** Description      Processing NFCC power mode changes
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_dm_proc_nfcc_power_mode(uint8_t nfcc_power_mode) {
+  NFA_TRACE_DEBUG1("nfa_dm_proc_nfcc_power_mode (): nfcc_power_mode=%d",
+                   nfcc_power_mode);
+
+  /* if NFCC power mode is change to full power */
+  if (nfcc_power_mode == NFA_DM_PWR_MODE_FULL) {
+    memset(&nfa_dm_cb.params, 0x00, sizeof(tNFA_DM_PARAMS));
+    NFA_TRACE_DEBUG2("setcfg_pending_mask=0x%x, setcfg_pending_num=%d",
+                     nfa_dm_cb.setcfg_pending_mask,
+                     nfa_dm_cb.setcfg_pending_num);
+    nfa_dm_cb.setcfg_pending_mask = 0;
+    nfa_dm_cb.setcfg_pending_num = 0;
+
+    nfa_dm_set_init_nci_params();
+    nfa_dm_cb.flags &= ~NFA_DM_FLAGS_POWER_OFF_SLEEP;
+  } else if (nfcc_power_mode == NFA_DM_PWR_MODE_OFF_SLEEP) {
+    nfa_dm_cb.flags |= NFA_DM_FLAGS_POWER_OFF_SLEEP;
+  }
+
+  nfa_sys_cback_notify_nfcc_power_mode_proc_complete(NFA_ID_DM);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_set_power_sub_state
+**
+** Description      Process the power sub state command
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_dm_set_power_sub_state (tNFA_DM_MSG *p_data)
+{
+   tNFC_STATUS status;
+   tNFA_DM_CBACK_DATA dm_cback_data;
+
+   NFA_TRACE_DEBUG0(" nfa_dm_set_power_sub_state ()");
+
+   nfa_dm_cb.power_state = p_data->set_power_state.screen_state;
+   if( nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_LISTEN_ACTIVE)
+    {
+      NFA_TRACE_DEBUG0("nfa_dm_set_power_sub_state () : NFA_DM_RFST_LISTEN_ACTIVE");
+        /* NFCC will give semantic error for power sub state command in Rf listen active state */
+        status = NFC_STATUS_SEMANTIC_ERROR;
+    }
+   else
+    {
+        status = NFC_SetPowerSubState(p_data->set_power_state.screen_state);
+    }
+
+   if (status != NFC_STATUS_OK)
+    {
+        dm_cback_data.power_sub_state.status = NFC_STATUS_FAILED;
+        dm_cback_data.power_sub_state.power_state = nfa_dm_cb.power_state;
+        (*nfa_dm_cb.p_dm_cback) (NFA_DM_SET_POWER_SUB_STATE_EVT, &dm_cback_data);
+    }
+    return (true);
+}
+/*******************************************************************************
+**
+** Function         nfa_dm_disable_event
+**
+** Description      report disable event
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_disable_event(void) {
+  /* Deregister DM from sys */
+  nfa_sys_deregister(NFA_ID_DM);
+
+  /* Notify app */
+  nfa_dm_cb.flags &=
+      ~(NFA_DM_FLAGS_DM_IS_ACTIVE | NFA_DM_FLAGS_DM_DISABLING_NFC |
+        NFA_DM_FLAGS_ENABLE_EVT_PEND);
+  (*nfa_dm_cb.p_dm_cback)(NFA_DM_DISABLE_EVT, NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_nfc_response_cback
+**
+** Description      Call DM event hanlder with NFC response callback data
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_nfc_response_cback(tNFC_RESPONSE_EVT event,
+                                      tNFC_RESPONSE* p_data) {
+  tNFA_DM_CBACK_DATA dm_cback_data;
+  tNFA_GET_CONFIG* p_nfa_get_confg;
+#if (NXP_EXTNS == TRUE)
+  tNFA_GET_ROUTING* p_nfa_get_routing;
+#endif
+  tNFA_CONN_EVT_DATA conn_evt;
+  uint8_t dm_cback_evt;
+  uint8_t max_ee = 0;
+
+#if (BT_TRACE_VERBOSE == true)
+  NFA_TRACE_DEBUG2("nfa_dm_nfc_response_cback () %s(0x%x)",
+                   nfa_dm_nfc_revt_2_str(event), event);
+#else
+  NFA_TRACE_DEBUG1("nfa_dm_nfc_response_cback () event=0x%x", event);
+#endif
+
+  switch (event) {
+    case NFC_ENABLE_REVT: /* 0  Enable event */
+        nfa_ee_max_ee_cfg = nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED;
+      /* NFC stack enabled. Enable nfa sub-systems */
+      if (p_data->enable.status == NFC_STATUS_OK) {
+        if (nfa_ee_max_ee_cfg != 0) {
+          if (nfa_dm_cb.get_max_ee) {
+            max_ee = nfa_dm_cb.get_max_ee();
+            if (max_ee) {
+              nfa_ee_max_ee_cfg = max_ee;
+            }
+          }
+        }
+        /* Initialize NFA subsystems */
+        nfa_sys_enable_subsystems();
+      } else if (nfa_dm_cb.flags & NFA_DM_FLAGS_ENABLE_EVT_PEND) {
+        /* Notify app */
+        nfa_dm_cb.flags &=
+            ~(NFA_DM_FLAGS_ENABLE_EVT_PEND | NFA_DM_FLAGS_DM_IS_ACTIVE);
+        dm_cback_data.status = p_data->enable.status;
+        (*nfa_dm_cb.p_dm_cback)(NFA_DM_ENABLE_EVT, &dm_cback_data);
+      }
+      break;
+    case NFC_SET_POWER_SUB_STATE_REVT:
+      dm_cback_data.power_sub_state.status = p_data->status;
+      dm_cback_data.power_sub_state.power_state = nfa_dm_cb.power_state;
+      (*nfa_dm_cb.p_dm_cback) (NFA_DM_SET_POWER_SUB_STATE_EVT, &dm_cback_data);
+      break;
+    case NFC_DISABLE_REVT: /* 1  Disable event */
+      nfa_dm_disable_event();
+      break;
+
+    case NFC_SET_CONFIG_REVT: /* 2  Set Config Response */
+      /* If this setconfig was due to NFA_SetConfig, then notify the app */
+      /* lsb=whether last NCI_SET_CONFIG was due to NFA_SetConfig */
+      if (nfa_dm_cb.setcfg_pending_mask & 1) {
+        dm_cback_data.set_config.status = p_data->set_config.status;
+        dm_cback_data.set_config.num_param_id = p_data->set_config.num_param_id;
+        memcpy(dm_cback_data.set_config.param_ids, p_data->set_config.param_ids,
+               p_data->set_config.num_param_id);
+        (*nfa_dm_cb.p_dm_cback)(NFA_DM_SET_CONFIG_EVT, &dm_cback_data);
+      }
+
+      /* Update the pending mask */
+      if (nfa_dm_cb.setcfg_pending_num > 0) {
+        nfa_dm_cb.setcfg_pending_mask >>= 1;
+        nfa_dm_cb.setcfg_pending_num--;
+      } else {
+        /* This should not occur (means we got a SET_CONFIG_NTF that's
+         * unaccounted for */
+        NFA_TRACE_ERROR0("NFA received unexpected NFC_SET_CONFIG_REVT");
+      }
+      break;
+
+    case NFC_GET_CONFIG_REVT: /* 3  Get Config Response */
+      if (p_data->get_config.status == NFC_STATUS_OK) {
+        p_nfa_get_confg = (tNFA_GET_CONFIG*)GKI_getbuf(
+            (uint16_t)(sizeof(tNFA_GET_CONFIG) + p_data->get_config.tlv_size));
+        if (p_nfa_get_confg != NULL) {
+          p_nfa_get_confg->status = NFA_STATUS_OK;
+          p_nfa_get_confg->tlv_size = p_data->get_config.tlv_size;
+          memcpy(p_nfa_get_confg->param_tlvs, p_data->get_config.p_param_tlvs,
+                 p_data->get_config.tlv_size);
+          (*nfa_dm_cb.p_dm_cback)(NFA_DM_GET_CONFIG_EVT,
+                                  (tNFA_DM_CBACK_DATA*)p_nfa_get_confg);
+
+          GKI_freebuf(p_nfa_get_confg);
+          return;
+        } else {
+          NFA_TRACE_DEBUG0(
+              "nfa_dm_nfc_response_cback unable to allocate buffer");
+        }
+      }
+
+      /* Return result of getconfig to the app */
+      dm_cback_data.get_config.status = NFA_STATUS_FAILED;
+      (*nfa_dm_cb.p_dm_cback)(NFA_DM_GET_CONFIG_EVT, &dm_cback_data);
+      break;
+
+#if (NFC_NFCEE_INCLUDED == true)
+    case NFC_NFCEE_DISCOVER_REVT: /* NFCEE Discover response */
+    case NFC_NFCEE_INFO_REVT:     /* NFCEE Discover Notification */
+    case NFC_EE_ACTION_REVT:      /* EE Action notification */
+    case NFC_NFCEE_MODE_SET_REVT: /* NFCEE Mode Set response */
+#if (NXP_EXTNS == TRUE)
+    case NFC_NFCEE_PWR_LNK_CTRL_REVT:
+        if(!nfcFL.eseFL._WIRED_MODE_STANDBY) {
+            break;
+        }
+    case NFC_NFCEE_MODE_SET_INFO:
+#endif
+    case NFC_NFCEE_STATUS_REVT:
+    case NFC_SET_ROUTING_REVT: /* Configure Routing response */
+      nfa_ee_proc_evt(event, p_data);
+      break;
+
+    case NFC_EE_DISCOVER_REQ_REVT: /* EE Discover Req notification */
+#if(NXP_EXTNS == TRUE)
+        if((nfcFL.nfcNxpEse) &&
+                (!nfcFL.eseFL._ESE_ETSI_READER_ENABLE) &&
+                (!nfcFL.eseFL._ESE_DWP_SPI_SYNC_ENABLE)) {
+            if (nfa_dm_is_active() &&
+                    (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_DISCOVERY)) {
+                nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_IDLE);
+            }
+        }
+#endif
+      nfa_ee_proc_evt(event, p_data);
+      break;
+
+#endif
+
+    case NFC_RF_FIELD_REVT: /* RF Field information            */
+      dm_cback_data.rf_field.status = NFA_STATUS_OK;
+      dm_cback_data.rf_field.rf_field_status = p_data->rf_field.rf_field;
+      (*nfa_dm_cb.p_dm_cback)(NFA_DM_RF_FIELD_EVT, &dm_cback_data);
+#if (NXP_EXTNS == TRUE)
+      if (dm_cback_data.rf_field.rf_field_status == NFA_DM_RF_FIELD_OFF) {
+        nfa_ee_ce_p61_active = 0;
+      }
+#endif
+      break;
+
+    case NFC_GET_ROUTING_REVT: /* Retrieve Routing response */
+#if (NXP_EXTNS == TRUE)
+      if ((p_nfa_get_routing = (tNFA_GET_ROUTING*)GKI_getbuf(
+               (uint16_t)(sizeof(tNFA_GET_ROUTING)))) != NULL) {
+        p_nfa_get_routing->status = p_data->get_routing.status;
+        p_nfa_get_routing->num_tlvs = p_data->get_routing.num_tlvs;
+        p_nfa_get_routing->tlv_size = p_data->get_routing.tlv_size;
+        memcpy(p_nfa_get_routing->param_tlvs, p_data->get_routing.param_tlvs,
+               p_data->get_routing.tlv_size);
+        (*nfa_dm_cb.p_dm_cback)(NFA_DM_GET_ROUTE_CONFIG_REVT,
+                                (tNFA_DM_CBACK_DATA*)p_nfa_get_routing);
+        GKI_freebuf(p_nfa_get_routing);
+      } else {
+        NFA_TRACE_DEBUG0("nfa_dm_nfc_response_cback unable to allocate buffer");
+      }
+#endif
+      break;
+
+    case NFC_GEN_ERROR_REVT: /* generic error command or notification */
+#if (NXP_EXTNS == TRUE)
+      if (p_data->status ==
+          NXP_NFC_EMVCO_PCD_COLLISION_DETECTED)  // STATUS_EMVCO_PCD_COLLISION
+      {
+        dm_cback_data.status = p_data->status;
+        (*nfa_dm_cb.p_dm_cback)(NFA_DM_EMVCO_PCD_COLLISION_EVT, &dm_cback_data);
+      }
+#endif
+      break;
+
+    case NFC_NFCC_RESTART_REVT: /* NFCC has been re-initialized */
+
+      if (p_data->status == NFC_STATUS_OK) {
+        nfa_dm_cb.nfcc_pwr_mode = NFA_DM_PWR_MODE_FULL;
+        nfa_dm_cb.flags |= NFA_DM_FLAGS_NFCC_IS_RESTORING;
+
+        /* NFCC will start from IDLE when turned on again */
+        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
+        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
+        nfa_dm_cb.disc_cb.disc_state = NFA_DM_RFST_IDLE;
+      } else {
+        nfa_dm_cb.nfcc_pwr_mode = NFA_DM_PWR_MODE_OFF_SLEEP;
+      }
+      /* Notify NFA submodules change of NFCC power mode */
+      nfa_sys_cback_reg_nfcc_power_mode_proc_complete(
+          nfa_dm_nfcc_power_mode_proc_complete_cback);
+      nfa_sys_notify_nfcc_power_mode(nfa_dm_cb.nfcc_pwr_mode);
+      break;
+
+    case NFC_NFCC_TIMEOUT_REVT:
+#if (NXP_EXTNS == TRUE)
+        if (p_data->status == NFC_STATUS_FAILED) {
+            dm_cback_data.status = p_data->status;
+            (*nfa_dm_cb.p_dm_cback)(NFA_DM_NFCC_TIMEOUT_EVT, &dm_cback_data);
+        }
+        else if (nfcFL.nfcNxpEse &&
+                nfcFL.eseFL._ESE_ETSI_READER_ENABLE) {
+            conn_evt.status = p_data->status;
+            nfa_dm_conn_cback_event_notify(NFA_RECOVERY_EVT, &conn_evt);
+        }
+#endif
+        break;
+
+    case NFC_NFCC_TRANSPORT_ERR_REVT:
+      NFA_TRACE_DEBUG1("flags:0x%08x", nfa_dm_cb.flags);
+#if (NXP_EXTNS == TRUE)
+      if(nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT) {
+          if (p_data->status == NFC_STATUS_FAILED) {
+              dm_cback_data.status = p_data->status;
+          }
+          dm_cback_evt = NFA_DM_NFCC_TRANSPORT_ERR_EVT;
+      }
+#else
+      dm_cback_evt = (event == NFC_NFCC_TIMEOUT_REVT)
+                         ? NFA_DM_NFCC_TIMEOUT_EVT
+                         : NFA_DM_NFCC_TRANSPORT_ERR_EVT;
+#endif
+      (*nfa_dm_cb.p_dm_cback)(dm_cback_evt, NULL);
+      break;
+
+    case NFC_NFCC_POWER_OFF_REVT:
+      nfa_dm_cb.nfcc_pwr_mode = NFA_DM_PWR_MODE_OFF_SLEEP;
+
+      /* Notify NFA submodules change of NFCC power mode */
+      nfa_sys_cback_reg_nfcc_power_mode_proc_complete(
+          nfa_dm_nfcc_power_mode_proc_complete_cback);
+      nfa_sys_notify_nfcc_power_mode(NFA_DM_PWR_MODE_OFF_SLEEP);
+      break;
+
+    case NFC_RF_COMM_PARAMS_UPDATE_REVT:
+      conn_evt.status = p_data->status;
+      nfa_dm_conn_cback_event_notify(NFA_UPDATE_RF_PARAM_RESULT_EVT, &conn_evt);
+      break;
+
+    default:
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_enable
+**
+** Description      Initialises the NFC device manager
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_dm_enable(tNFA_DM_MSG* p_data) {
+  tNFA_DM_CBACK_DATA dm_cback_data;
+  NFA_TRACE_DEBUG0("nfa_dm_enable ()");
+
+  /* Check if NFA is already enabled */
+  if (!(nfa_dm_cb.flags & NFA_DM_FLAGS_DM_IS_ACTIVE)) {
+    /* Initialize BRCM control block, it musb be called before setting any flags
+     */
+    nfa_dm_cb.flags |=
+        (NFA_DM_FLAGS_DM_IS_ACTIVE | NFA_DM_FLAGS_ENABLE_EVT_PEND);
+    nfa_sys_cback_reg_enable_complete(nfa_dm_module_init_cback);
+
+    /* Store Enable parameters */
+    nfa_dm_cb.p_dm_cback = p_data->enable.p_dm_cback;
+    nfa_dm_cb.p_conn_cback = p_data->enable.p_conn_cback;
+
+    /* Enable NFC stack */
+    NFC_Enable(nfa_dm_nfc_response_cback);
+  } else {
+    NFA_TRACE_ERROR0("nfa_dm_enable: ERROR ALREADY ENABLED.");
+    dm_cback_data.status = NFA_STATUS_ALREADY_STARTED;
+    (*(p_data->enable.p_dm_cback))(NFA_DM_ENABLE_EVT, &dm_cback_data);
+  }
+
+  return (true);
+}
+/*******************************************************************************
+**
+** Function         nfa_dm_disable
+**
+** Description      Disables the NFC device manager
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_dm_disable(tNFA_DM_MSG* p_data) {
+  tNFC_DEACT_TYPE deactivate_type = NFA_DEACTIVATE_TYPE_IDLE;
+
+  NFA_TRACE_DEBUG1("nfa_dm_disable (): graceful:%d", p_data->disable.graceful);
+
+  if (p_data->disable.graceful) {
+    /* if RF discovery is enabled */
+    if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_ENABLED) {
+      nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_ENABLED;
+
+      if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_IDLE) {
+        /* if waiting RSP in idle state */
+        if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP) {
+          nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_DISABLING;
+        }
+      } else {
+        nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_DISABLING;
+        nfa_dm_disc_sm_execute(NFA_DM_RF_DEACTIVATE_CMD,
+                               (void*)&deactivate_type);
+        if ((nfa_dm_cb.disc_cb.disc_flags &
+             (NFA_DM_DISC_FLAGS_W4_RSP | NFA_DM_DISC_FLAGS_W4_NTF)) == 0) {
+          /* not waiting to deactivate, clear the flag now */
+          nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_DISABLING;
+        }
+      }
+    }
+    /* Start timeout for graceful shutdown. If timer expires, then force an
+     * ungraceful shutdown */
+    nfa_sys_start_timer(&nfa_dm_cb.tle, NFA_DM_TIMEOUT_DISABLE_EVT,
+                        NFA_DM_DISABLE_TIMEOUT_VAL);
+  }
+
+  /* Disable all subsystems other than DM (DM will be disabled after all  */
+  /* the other subsystem have been disabled)                              */
+  nfa_sys_disable_subsystems(p_data->disable.graceful);
+  return (true);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disable_complete
+**
+** Description      Called when all NFA subsytems are disabled.
+**
+**                  NFC core stack can now be disabled.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_disable_complete(void) {
+  NFA_TRACE_DEBUG0("nfa_dm_disable_complete ()");
+
+  if ((nfa_dm_cb.flags & NFA_DM_FLAGS_DM_DISABLING_NFC) == 0) {
+    NFA_TRACE_DEBUG0(
+        "nfa_dm_disable_complete (): proceeding with nfc core shutdown.");
+
+    nfa_dm_cb.flags |= NFA_DM_FLAGS_DM_DISABLING_NFC;
+
+    nfa_sys_stop_timer(&nfa_dm_cb.tle);
+
+    /* Free all buffers for NDEF handlers */
+    nfa_dm_ndef_dereg_all();
+
+    /* Disable nfc core stack */
+    NFC_Disable();
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_set_config
+**
+** Description      Process set config command
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_dm_set_config(tNFA_DM_MSG* p_data) {
+  tNFC_STATUS status;
+  uint8_t buff[255];
+  uint8_t* p = buff;
+
+  tNFA_DM_CBACK_DATA dm_cback_data;
+
+  if (p_data->setconfig.length + 2 > 255) {
+    /* Total length of TLV must be less than 256 (1 byte) */
+    status = NFC_STATUS_FAILED;
+  } else {
+    UINT8_TO_STREAM(p, p_data->setconfig.param_id);
+    UINT8_TO_STREAM(p, p_data->setconfig.length);
+    ARRAY_TO_STREAM(p, p_data->setconfig.p_data, p_data->setconfig.length)
+    status = nfa_dm_check_set_config((uint8_t)(p_data->setconfig.length + 2),
+                                     buff, true);
+  }
+
+  if (status != NFC_STATUS_OK) {
+    dm_cback_data.set_config.status = NFA_STATUS_INVALID_PARAM;
+    (*nfa_dm_cb.p_dm_cback)(NFA_DM_SET_CONFIG_EVT, &dm_cback_data);
+  }
+
+  return (true);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_get_config
+**
+** Description      Process get config command
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_dm_get_config(tNFA_DM_MSG* p_data) {
+  NFC_GetConfig(p_data->getconfig.num_ids, p_data->getconfig.p_pmids);
+
+  return (true);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_conn_cback_event_notify
+**
+** Description      Notify application of CONN_CBACK event, using appropriate
+**                  callback
+**
+** Returns          nothing
+**
+*******************************************************************************/
+void nfa_dm_conn_cback_event_notify(uint8_t event, tNFA_CONN_EVT_DATA* p_data) {
+  if (nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE) {
+    /* Use exclusive RF mode callback */
+    if (nfa_dm_cb.p_excl_conn_cback)
+      (*nfa_dm_cb.p_excl_conn_cback)(event, p_data);
+  } else {
+    (*nfa_dm_cb.p_conn_cback)(event, p_data);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_rel_excl_rf_control_and_notify
+**
+** Description      Stop exclusive RF control and notify app of
+**                  NFA_EXCLUSIVE_RF_CONTROL_STOPPED_EVT
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_rel_excl_rf_control_and_notify(void) {
+  tNFA_CONN_EVT_DATA conn_evt;
+
+  NFA_TRACE_DEBUG0("nfa_dm_rel_excl_rf_control_and_notify ()");
+
+  /* Exclusive RF control stopped. Notify app */
+  nfa_dm_cb.flags &= ~NFA_DM_FLAGS_EXCL_RF_ACTIVE;
+
+  /* Stop exclusive RF discovery for exclusive RF mode */
+  nfa_dm_stop_excl_discovery();
+
+  /* Notify app that exclusive RF control has stopped */
+  conn_evt.status = NFA_STATUS_OK;
+  (*nfa_dm_cb.p_excl_conn_cback)(NFA_EXCLUSIVE_RF_CONTROL_STOPPED_EVT,
+                                 &conn_evt);
+  nfa_dm_cb.p_excl_conn_cback = NULL;
+  nfa_dm_cb.p_excl_ndef_cback = NULL;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_request_excl_rf_ctrl
+**
+** Description      Request exclusive RF control
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_dm_act_request_excl_rf_ctrl(tNFA_DM_MSG* p_data) {
+  tNFA_CONN_EVT_DATA conn_evt;
+
+  NFA_TRACE_DEBUG0("nfa_dm_act_request_excl_rf_ctrl ()");
+
+  if (!nfa_dm_cb.p_excl_conn_cback) {
+    if (nfa_dm_cb.disc_cb.disc_state != NFA_DM_RFST_IDLE) {
+      conn_evt.status = NFA_STATUS_FAILED;
+      (*p_data->req_excl_rf_ctrl.p_conn_cback)(
+          NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT, &conn_evt);
+      return true;
+    }
+
+    /* Store callbacks */
+    nfa_dm_cb.p_excl_conn_cback = p_data->req_excl_rf_ctrl.p_conn_cback;
+    nfa_dm_cb.p_excl_ndef_cback = p_data->req_excl_rf_ctrl.p_ndef_cback;
+
+    nfa_dm_cb.flags |= NFA_DM_FLAGS_EXCL_RF_ACTIVE;
+
+    /* start exclusive RF discovery */
+    nfa_dm_start_excl_discovery(p_data->req_excl_rf_ctrl.poll_mask,
+                                &p_data->req_excl_rf_ctrl.listen_cfg,
+                                nfa_dm_excl_disc_cback);
+  } else {
+    NFA_TRACE_ERROR0("Exclusive rf control already requested");
+
+    conn_evt.status = NFA_STATUS_FAILED;
+    (*p_data->req_excl_rf_ctrl.p_conn_cback)(
+        NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT, &conn_evt);
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_release_excl_rf_ctrl
+**
+** Description      Release exclusive RF control
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_dm_act_release_excl_rf_ctrl(tNFA_DM_MSG* p_data) {
+  (void)p_data;
+  NFA_TRACE_DEBUG0("nfa_dm_act_release_excl_rf_ctrl ()");
+
+  /* nfa_dm_rel_excl_rf_control_and_notify() is called when discovery state goes
+   * IDLE */
+  nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_STOPPING;
+
+  /* if discover command has been sent in IDLE state and waiting for response
+  ** then just wait for responose. Otherwise initiate deactivating.
+  */
+  if (!((nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_IDLE) &&
+        (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP))) {
+    nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_IDLE);
+  }
+
+  if (nfa_dm_cb.disc_cb.kovio_tle.in_use)
+    nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.kovio_tle);
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_deactivate
+**
+** Description      Process deactivate command
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_dm_act_deactivate(tNFA_DM_MSG* p_data) {
+  tNFA_CONN_EVT_DATA conn_evt;
+  tNFA_DEACTIVATE_TYPE deact_type;
+
+  NFA_TRACE_DEBUG0("nfa_dm_act_deactivate ()");
+
+  /* Always allow deactivate to IDLE */
+  /* Do not allow deactivate to SLEEP for T1T,NFCDEP, ISO15693 */
+  if ((p_data->deactivate.sleep_mode == false) ||
+      ((nfa_dm_cb.disc_cb.activated_protocol != NFA_PROTOCOL_T1T) &&
+#if (NXP_EXTNS == TRUE)
+       (
+#endif
+           (nfa_dm_cb.disc_cb.activated_protocol != NFA_PROTOCOL_NFC_DEP)
+#if (NXP_EXTNS == TRUE)
+           || gFelicaReaderMode || appl_dta_mode_flag)
+#endif
+       &&
+       (nfa_dm_cb.disc_cb.activated_protocol != NFC_PROTOCOL_KOVIO))) {
+    deact_type = NFA_DEACTIVATE_TYPE_DISCOVERY;
+    if (p_data->deactivate.sleep_mode) {
+      if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_W4_HOST_SELECT) {
+        /* Deactivate to sleep mode not allowed in this state. */
+        deact_type = NFA_DEACTIVATE_TYPE_IDLE;
+      }
+#if (NXP_EXTNS == TRUE)
+      else if (appl_dta_mode_flag == true &&
+               (nfa_dm_cb.disc_cb.disc_state != NFA_DM_RFST_LISTEN_SLEEP ||
+                nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE)) {
+        deact_type = NFA_DEACTIVATE_TYPE_SLEEP;
+      }
+#endif
+      else if (nfa_dm_cb.disc_cb.disc_state != NFA_DM_RFST_LISTEN_SLEEP) {
+        deact_type = NFA_DEACTIVATE_TYPE_SLEEP;
+      }
+    }
+    if ((nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_W4_ALL_DISCOVERIES)
+#if (NXP_EXTNS == TRUE)
+        || (nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_T3BT)
+#endif
+            ) {
+      /* Only deactivate to IDLE is allowed in this state. */
+      deact_type = NFA_DEACTIVATE_TYPE_IDLE;
+    }
+
+    if ((nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_NFC_DEP) &&
+        ((nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE) == 0x00)
+#if (NXP_EXTNS == TRUE)
+        && appl_dta_mode_flag != true
+#endif
+        ) {
+      /* Exclusive RF control doesn't use NFA P2P */
+      /* NFA P2P will deactivate NFC link after deactivating LLCP link */
+      if (!(nfa_dm_cb.flags & NFA_DM_FLAGS_P2P_PAUSED)) {
+        nfa_p2p_deactivate_llcp();
+      } else {
+        nfa_dm_rf_deactivate(deact_type);
+      }
+      return (true);
+    } else {
+      if (nfa_dm_rf_deactivate(deact_type) == NFA_STATUS_OK) {
+        if (nfa_dm_cb.disc_cb.kovio_tle.in_use)
+          nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.kovio_tle);
+        nfa_rw_stop_presence_check_timer();
+        return (true);
+      }
+    }
+  }
+
+  NFA_TRACE_ERROR0("nfa_dm_act_deactivate (): invalid protocol, mode or state");
+
+  /* Notify error to application */
+  conn_evt.status = NFA_STATUS_FAILED;
+  nfa_dm_conn_cback_event_notify(NFA_DEACTIVATE_FAIL_EVT, &conn_evt);
+
+  return (true);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_power_off_sleep
+**
+** Description      Process power off sleep mode request
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_dm_act_power_off_sleep(tNFA_DM_MSG* p_data) {
+  NFA_TRACE_DEBUG0("nfa_dm_act_power_off_sleep ()");
+
+  NFC_SetPowerOffSleep((bool)(p_data->hdr.layer_specific));
+
+  return (true);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_reg_vsc
+**
+** Description      Process registers VSC callback
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_dm_act_reg_vsc(tNFA_DM_MSG* p_data) {
+  if (NFC_RegVSCback(p_data->reg_vsc.is_register, p_data->reg_vsc.p_cback) !=
+      NFC_STATUS_OK) {
+    NFA_TRACE_ERROR0("NFC_RegVSCback failed");
+  }
+  return (true);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_send_vsc
+**
+** Description      Send the NCI Vendor Specific command to the NCI command
+**                  queue
+**
+** Returns          false (message buffer is NOT freed by caller)
+**
+*******************************************************************************/
+bool nfa_dm_act_send_vsc(tNFA_DM_MSG* p_data) {
+  NFC_HDR* p_cmd = (NFC_HDR*)p_data;
+
+  p_cmd->offset = sizeof(tNFA_DM_API_SEND_VSC) - NFC_HDR_SIZE;
+  p_cmd->len = p_data->send_vsc.cmd_params_len;
+  NFC_SendVsCommand(p_data->send_vsc.oid, p_cmd, p_data->send_vsc.p_cback);
+
+  /* Most dm action functions return true, so nfa-sys frees the GKI buffer
+   * carrying the message,
+   * This action function re-use the GKI buffer to send the VSC, so the GKI
+   * buffer can not be freed by nfa-sys */
+  return (false);
+}
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         nfa_dm_act_send_nxp
+**
+** Description      Send the NXP NCI command to the NCI command queue
+**
+** Returns          false (message buffer is NOT freed by caller)
+**
+*******************************************************************************/
+bool nfa_dm_act_send_nxp(tNFA_DM_MSG* p_data) {
+  NFC_HDR* p_cmd = (NFC_HDR*)p_data;
+
+  p_cmd->offset = sizeof(tNFA_DM_API_SEND_VSC) - NFC_HDR_SIZE;
+  p_cmd->len = p_data->send_vsc.cmd_params_len;
+  NFC_SendNxpNciCommand(p_cmd, p_data->send_vsc.p_cback);
+
+  /* Most dm action functions return true, so nfa-sys frees the GKI buffer
+   * carrying the message,
+   * This action function re-use the GKI buffer to send the VSC, so the GKI
+   * buffer can not be freed by nfa-sys */
+  return (false);
+}
+#endif
+/*******************************************************************************
+**
+** Function         nfa_dm_start_polling
+**
+** Description      Start polling
+**
+** Returns          tNFA_STATUS
+**
+*******************************************************************************/
+tNFA_STATUS nfa_dm_start_polling(void) {
+  tNFA_STATUS status;
+  tNFA_TECHNOLOGY_MASK poll_tech_mask;
+  tNFA_DM_DISC_TECH_PROTO_MASK poll_disc_mask = 0;
+
+  NFA_TRACE_DEBUG0("nfa_dm_start_polling ()");
+
+  poll_tech_mask = nfa_dm_cb.poll_mask;
+
+  /* start RF discovery with discovery callback */
+  if (nfa_dm_cb.poll_disc_handle == NFA_HANDLE_INVALID) {
+    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_A) {
+      poll_disc_mask |= NFA_DM_DISC_MASK_PA_T1T;
+      poll_disc_mask |= NFA_DM_DISC_MASK_PA_T2T;
+      poll_disc_mask |= NFA_DM_DISC_MASK_PA_ISO_DEP;
+      poll_disc_mask |= NFA_DM_DISC_MASK_PA_NFC_DEP;
+      poll_disc_mask |= NFA_DM_DISC_MASK_P_LEGACY;
+    }
+    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_A_ACTIVE) {
+      poll_disc_mask |= NFA_DM_DISC_MASK_PAA_NFC_DEP;
+    }
+    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_B) {
+      poll_disc_mask |= NFA_DM_DISC_MASK_PB_ISO_DEP;
+#if (NXP_EXTNS == TRUE)
+      poll_disc_mask |= NFA_DM_DISC_MASK_PB_T3BT;
+#endif
+    }
+    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_F) {
+      poll_disc_mask |= NFA_DM_DISC_MASK_PF_T3T;
+      poll_disc_mask |= NFA_DM_DISC_MASK_PF_NFC_DEP;
+    }
+    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_F_ACTIVE) {
+      poll_disc_mask |= NFA_DM_DISC_MASK_PFA_NFC_DEP;
+    }
+    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_ISO15693) {
+      poll_disc_mask |= NFA_DM_DISC_MASK_P_ISO15693;
+    }
+    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_B_PRIME) {
+      poll_disc_mask |= NFA_DM_DISC_MASK_P_B_PRIME;
+    }
+    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_KOVIO) {
+      poll_disc_mask |= NFA_DM_DISC_MASK_P_KOVIO;
+    }
+
+    nfa_dm_cb.poll_disc_handle = nfa_dm_add_rf_discover(
+        poll_disc_mask, NFA_DM_DISC_HOST_ID_DH, nfa_dm_poll_disc_cback);
+
+    if (nfa_dm_cb.poll_disc_handle != NFA_HANDLE_INVALID)
+      status = NFA_STATUS_OK;
+    else
+      status = NFA_STATUS_FAILED;
+  } else {
+    status = NFA_STATUS_OK;
+  }
+
+  return (status);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_enable_polling
+**
+** Description      Process enable polling command
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_dm_act_enable_polling(tNFA_DM_MSG* p_data) {
+  tNFA_CONN_EVT_DATA evt_data;
+
+  NFA_TRACE_DEBUG0("nfa_dm_act_enable_polling ()");
+
+  if ((!(nfa_dm_cb.flags & NFA_DM_FLAGS_POLLING_ENABLED)) &&
+      (!(nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE))) {
+    nfa_dm_cb.poll_mask = p_data->enable_poll.poll_mask;
+
+    if (nfa_dm_start_polling() == NFA_STATUS_OK) {
+      nfa_dm_cb.flags |= NFA_DM_FLAGS_POLLING_ENABLED;
+
+      evt_data.status = NFA_STATUS_OK;
+      nfa_dm_conn_cback_event_notify(NFA_POLL_ENABLED_EVT, &evt_data);
+      return (true);
+    }
+  } else {
+    NFA_TRACE_ERROR0("nfa_dm_act_enable_polling (): already started");
+  }
+
+  /* send NFA_POLL_ENABLED_EVT with NFA_STATUS_FAILED */
+  evt_data.status = NFA_STATUS_FAILED;
+  nfa_dm_conn_cback_event_notify(NFA_POLL_ENABLED_EVT, &evt_data);
+
+  return (true);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_deactivate_polling
+**
+** Description      Deactivate any polling state
+**
+** Returns          true if need to wait for deactivation
+**
+*******************************************************************************/
+static bool nfa_dm_deactivate_polling(void) {
+  NFA_TRACE_DEBUG0("nfa_dm_deactivate_polling ()");
+
+  if ((nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_W4_ALL_DISCOVERIES) ||
+      (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_W4_HOST_SELECT)) {
+    nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_IDLE);
+    return false;
+  } else if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE) {
+    if (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_NFC_DEP) {
+      /* NFA P2P will deactivate NFC link after deactivating LLCP link */
+      nfa_p2p_deactivate_llcp();
+    } else {
+      nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_IDLE);
+    }
+    return true;
+  } else {
+    return false;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_disable_polling
+**
+** Description      Process disable polling command
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_dm_act_disable_polling(tNFA_DM_MSG* p_data) {
+  tNFA_CONN_EVT_DATA evt_data;
+  (void)p_data;
+
+  NFA_TRACE_DEBUG0("nfa_dm_act_disable_polling ()");
+
+  if (nfa_dm_cb.poll_disc_handle != NFA_HANDLE_INVALID) {
+    nfa_dm_cb.flags &= ~NFA_DM_FLAGS_POLLING_ENABLED;
+
+    if (nfa_dm_deactivate_polling() == false) {
+      nfa_dm_delete_rf_discover(nfa_dm_cb.poll_disc_handle);
+      nfa_dm_cb.poll_disc_handle = NFA_HANDLE_INVALID;
+
+      evt_data.status = NFA_STATUS_OK;
+      nfa_dm_conn_cback_event_notify(NFA_POLL_DISABLED_EVT, &evt_data);
+    } else {
+      nfa_dm_cb.flags |= NFA_DM_FLAGS_SEND_POLL_STOP_EVT;
+    }
+  } else {
+    evt_data.status = NFA_STATUS_FAILED;
+    nfa_dm_conn_cback_event_notify(NFA_POLL_DISABLED_EVT, &evt_data);
+  }
+
+  return (true);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_enable_listening
+**
+** Description      Process enable listening command
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_dm_act_enable_listening(tNFA_DM_MSG* p_data) {
+  tNFA_CONN_EVT_DATA evt_data;
+  (void)p_data;
+
+  NFA_TRACE_DEBUG0("nfa_dm_act_enable_listening ()");
+
+  nfa_dm_cb.flags &= ~NFA_DM_FLAGS_LISTEN_DISABLED;
+#if (NXP_EXTNS == TRUE)
+  if(nfcFL.eseFL._NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION) {
+      nfa_dm_cb.flags &= ~NFA_DM_FLAGS_PASSIVE_LISTEN_DISABLED;
+  }
+#endif
+  evt_data.status = NFA_STATUS_OK;
+  nfa_dm_conn_cback_event_notify(NFA_LISTEN_ENABLED_EVT, &evt_data);
+
+  return (true);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_disable_listening
+**
+** Description      Process disable listening command
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_dm_act_disable_listening(tNFA_DM_MSG* p_data) {
+  tNFA_CONN_EVT_DATA evt_data;
+  (void)p_data;
+
+  NFA_TRACE_DEBUG0("nfa_dm_act_disable_listening ()");
+
+  nfa_dm_cb.flags |= NFA_DM_FLAGS_LISTEN_DISABLED;
+  evt_data.status = NFA_STATUS_OK;
+  nfa_dm_conn_cback_event_notify(NFA_LISTEN_DISABLED_EVT, &evt_data);
+
+  return (true);
+}
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         nfa_dm_act_disable_passive_listening
+**
+** Description      Process disable passive listening command
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_dm_act_disable_passive_listening(tNFA_DM_MSG* p_data) {
+    if(!nfcFL.eseFL._NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION) {
+        NFA_TRACE_DEBUG0("NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION feature is not available!!");
+        return false;
+    }
+  tNFA_CONN_EVT_DATA evt_data;
+
+  NFA_TRACE_DEBUG0("nfa_dm_act_disable_passive_listening ()");
+
+  nfa_dm_cb.flags |= NFA_DM_FLAGS_PASSIVE_LISTEN_DISABLED;
+  evt_data.status = NFA_STATUS_OK;
+  nfa_dm_conn_cback_event_notify(NFA_PASSIVE_LISTEN_DISABLED_EVT, &evt_data);
+
+  return (true);
+}
+#endif
+/*******************************************************************************
+**
+** Function         nfa_dm_act_pause_p2p
+**
+** Description      Process Pause P2P command
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_dm_act_pause_p2p(tNFA_DM_MSG* p_data) {
+  tNFA_CONN_EVT_DATA evt_data;
+  (void)p_data;
+
+  NFA_TRACE_DEBUG0("nfa_dm_act_pause_p2p ()");
+
+  nfa_dm_cb.flags |= NFA_DM_FLAGS_P2P_PAUSED;
+  evt_data.status = NFA_STATUS_OK;
+  nfa_dm_conn_cback_event_notify(NFA_P2P_PAUSED_EVT, &evt_data);
+
+  return (true);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_resume_p2p
+**
+** Description      Process resume P2P command
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_dm_act_resume_p2p(tNFA_DM_MSG* p_data) {
+  tNFA_CONN_EVT_DATA evt_data;
+  (void)(p_data);
+
+  NFA_TRACE_DEBUG0("nfa_dm_act_resume_p2p ()");
+
+  nfa_dm_cb.flags &= ~NFA_DM_FLAGS_P2P_PAUSED;
+  evt_data.status = NFA_STATUS_OK;
+  nfa_dm_conn_cback_event_notify(NFA_P2P_RESUMED_EVT, &evt_data);
+
+  return (true);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_send_raw_frame
+**
+** Description      Send an raw frame on RF link
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_dm_act_send_raw_frame(tNFA_DM_MSG* p_data) {
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+
+  NFA_TRACE_DEBUG0("nfa_dm_act_send_raw_frame ()");
+
+  /* If NFC link is activated */
+  if ((nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE) ||
+      (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_LISTEN_ACTIVE)) {
+    nfa_dm_cb.flags |= NFA_DM_FLAGS_RAW_FRAME;
+    NFC_SetReassemblyFlag(false);
+    /* If not in exclusive mode, and not activated for LISTEN, then forward raw
+     * data to NFA_RW to send */
+    if (!(nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE) &&
+        !(nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_LISTEN_ACTIVE) &&
+        ((nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_T1T) ||
+         (nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_T2T) ||
+         (nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_T3T) ||
+         (nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_ISO_DEP) ||
+         (nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_ISO15693))) {
+      /* if RW is checking presence then it will put into pending queue */
+      status = nfa_rw_send_raw_frame((NFC_HDR*)p_data);
+    } else {
+      status = NFC_SendData(NFC_RF_CONN_ID, (NFC_HDR*)p_data);
+      if (status != NFC_STATUS_OK) {
+        NFC_SetReassemblyFlag(true);
+      }
+      /* Already freed or NCI layer will free buffer */
+      return false;
+    }
+  }
+
+  if (status == NFC_STATUS_FAILED) {
+    NFC_SetReassemblyFlag(true);
+    /* free the buffer */
+    return true;
+  } else {
+    /* NCI layer will free buffer */
+    return false;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_set_p2p_listen_tech
+**
+** Description      Notify change of P2P listen technologies to NFA P2P
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_dm_set_p2p_listen_tech(tNFA_DM_MSG* p_data) {
+  NFA_TRACE_DEBUG1("nfa_dm_set_p2p_listen_tech ()  tech_mask = %d",
+                   p_data->set_p2p_listen_tech.tech_mask);
+
+  nfa_p2p_update_listen_tech(p_data->set_p2p_listen_tech.tech_mask);
+  nfa_dm_conn_cback_event_notify(NFA_SET_P2P_LISTEN_TECH_EVT, NULL);
+
+  return (true);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_start_rf_discovery
+**
+** Description      Process start RF discovery command
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_dm_act_start_rf_discovery(tNFA_DM_MSG* p_data) {
+  tNFA_CONN_EVT_DATA evt_data;
+  (void)p_data;
+
+  NFA_TRACE_DEBUG0("nfa_dm_act_start_rf_discovery ()");
+
+  if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_ENABLED) {
+    evt_data.status = NFA_STATUS_OK;
+    nfa_dm_conn_cback_event_notify(NFA_RF_DISCOVERY_STARTED_EVT, &evt_data);
+  } else if (nfa_dm_cb.disc_cb.disc_state != NFA_DM_RFST_IDLE) {
+    evt_data.status = NFA_STATUS_SEMANTIC_ERROR;
+    nfa_dm_conn_cback_event_notify(NFA_RF_DISCOVERY_STARTED_EVT, &evt_data);
+  } else {
+    nfa_dm_cb.disc_cb.disc_flags |=
+        (NFA_DM_DISC_FLAGS_ENABLED | NFA_DM_DISC_FLAGS_NOTIFY);
+    nfa_dm_start_rf_discover();
+  }
+
+  return (true);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_stop_rf_discovery
+**
+** Description      Process stop RF discovery command
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_dm_act_stop_rf_discovery(tNFA_DM_MSG* p_data) {
+  tNFA_CONN_EVT_DATA evt_data;
+  (void)p_data;
+
+  NFA_TRACE_DEBUG0("nfa_dm_act_stop_rf_discovery ()");
+
+#if (NXP_EXTNS == TRUE)
+  /* Reset P2P prio logic if deactivate is called from app layer */
+  nfa_dm_p2p_prio_logic_disable();
+#endif
+  if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_ENABLED) ||
+      (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_IDLE)) {
+    nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_ENABLED;
+
+    /* if discover command has been sent in IDLE state and waiting for response
+     */
+    if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP) {
+      nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_STOPPING;
+    } else {
+      evt_data.status = NFA_STATUS_OK;
+      nfa_dm_conn_cback_event_notify(NFA_RF_DISCOVERY_STOPPED_EVT, &evt_data);
+    }
+  } else {
+    nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_ENABLED;
+    nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_STOPPING;
+
+    if (nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_IDLE) == NFA_STATUS_OK) {
+      if (nfa_dm_cb.disc_cb.kovio_tle.in_use)
+        nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.kovio_tle);
+      nfa_rw_stop_presence_check_timer();
+    }
+  }
+  return (true);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_set_rf_disc_duration
+**
+** Description      Set duration for RF discovery
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_dm_act_set_rf_disc_duration(tNFA_DM_MSG* p_data) {
+  nfa_dm_cb.disc_cb.disc_duration = p_data->disc_duration.rf_disc_dur_ms;
+  return (true);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_get_rf_disc_duration
+**
+** Description      Get duration for RF discovery
+**
+** Returns          uint16_t
+**
+*******************************************************************************/
+uint16_t nfa_dm_act_get_rf_disc_duration() {
+  return (nfa_dm_cb.disc_cb.disc_duration);
+}
+/*******************************************************************************
+**
+** Function         nfa_dm_act_select
+**
+** Description      Process RF select command
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_dm_act_select(tNFA_DM_MSG* p_data) {
+  NFA_TRACE_DEBUG0("nfa_dm_act_select ()");
+
+  nfa_dm_rf_discover_select(p_data->select.rf_disc_id, p_data->select.protocol,
+                            p_data->select.rf_interface);
+  return (true);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_update_rf_params
+**
+** Description      Process update RF communication parameters command
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_dm_act_update_rf_params(tNFA_DM_MSG* p_data) {
+  tNFA_CONN_EVT_DATA conn_evt;
+
+  NFA_TRACE_DEBUG0("nfa_dm_act_update_rf_params ()");
+
+  if (NFC_UpdateRFCommParams(&p_data->update_rf_params.params) !=
+      NFC_STATUS_OK) {
+    conn_evt.status = NFA_STATUS_FAILED;
+    nfa_dm_conn_cback_event_notify(NFA_UPDATE_RF_PARAM_RESULT_EVT, &conn_evt);
+  }
+
+  return (true);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_disable_timeout
+**
+** Description      timeout on disable process. Shutdown immediately
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_dm_act_disable_timeout(tNFA_DM_MSG* p_data) {
+  tNFA_DM_API_DISABLE disable;
+  (void)p_data;
+
+  disable.graceful = false;
+  nfa_dm_disable((void*)&disable);
+  return (true);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_conn_cback_notify
+**
+** Description      Notify app of reader/writer/ndef events
+**
+** Returns          nothing
+**
+*******************************************************************************/
+void nfa_dm_act_conn_cback_notify(uint8_t event, tNFA_CONN_EVT_DATA* p_data) {
+  NFA_TRACE_DEBUG1("nfa_dm_act_conn_cback_notify (): event:0x%X", event);
+
+  /* Notify event using appropriate CONN_CBACK */
+  nfa_dm_conn_cback_event_notify(event, p_data);
+
+  /* If not in exclusive RF mode, then read NDEF message from tag (if automatic
+   * reading is enabled) */
+  if (!(nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE)) {
+    if ((event == NFA_NDEF_DETECT_EVT) &&
+        (nfa_dm_cb.flags & NFA_DM_FLAGS_AUTO_READING_NDEF)) {
+      /* read NDEF message from tag */
+      if (p_data->ndef_detect.status == NFA_STATUS_OK) {
+        NFA_RwReadNDef();
+      } else if (p_data->ndef_detect.status == NFA_STATUS_FAILED) {
+        nfa_dm_cb.flags &= ~NFA_DM_FLAGS_AUTO_READING_NDEF;
+      }
+      /* ignore NFA_STATUS_BUSY */
+    } else if ((event == NFA_READ_CPLT_EVT) &&
+               (nfa_dm_cb.flags & NFA_DM_FLAGS_AUTO_READING_NDEF)) {
+      /* reading NDEF message is done */
+      nfa_dm_cb.flags &= ~NFA_DM_FLAGS_AUTO_READING_NDEF;
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_data_cback
+**
+** Description      Processing data from RF link
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_dm_act_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
+                                  tNFC_CONN* p_data) {
+  NFC_HDR* p_msg;
+  tNFA_CONN_EVT_DATA evt_data;
+  (void)conn_id;
+
+  NFA_TRACE_DEBUG1("nfa_dm_act_data_cback (): event = 0x%X", event);
+
+  if (event == NFC_DATA_CEVT) {
+    p_msg = (NFC_HDR*)p_data->data.p_data;
+
+    if (p_msg) {
+      evt_data.data.status = p_data->data.status;
+      evt_data.data.p_data = (uint8_t*)(p_msg + 1) + p_msg->offset;
+      evt_data.data.len = p_msg->len;
+
+      nfa_dm_conn_cback_event_notify(NFA_DATA_EVT, &evt_data);
+
+      GKI_freebuf(p_msg);
+    } else {
+      NFA_TRACE_ERROR0(
+          "nfa_dm_act_data_cback (): received NFC_DATA_CEVT with NULL data "
+          "pointer");
+    }
+  } else if (event == NFC_DEACTIVATE_CEVT) {
+    NFC_SetStaticRfCback(NULL);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_excl_disc_cback
+**
+** Description      Processing event from discovery callback
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_dm_excl_disc_cback(tNFA_DM_RF_DISC_EVT event,
+                                   tNFC_DISCOVER* p_data) {
+  tNFA_CONN_EVT_DATA evt_data;
+
+  NFA_TRACE_DEBUG1("nfa_dm_excl_disc_cback (): event:0x%02X", event);
+
+  switch (event) {
+    case NFA_DM_RF_DISC_START_EVT:
+      evt_data.status = NFA_STATUS_OK;
+      nfa_dm_conn_cback_event_notify(NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT,
+                                     &evt_data);
+      break;
+
+    case NFA_DM_RF_DISC_ACTIVATED_EVT:
+      if (nfa_dm_cb.disc_cb.activated_tech_mode == NFC_DISCOVERY_TYPE_POLL_A) {
+        /* store SEL_RES response */
+        nfa_dm_cb.disc_cb.activated_sel_res =
+            p_data->activate.rf_tech_param.param.pa.sel_rsp;
+      }
+
+      if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_LISTEN_ACTIVE) {
+        /* Set data callback to receive raw frame */
+        NFC_SetStaticRfCback(nfa_dm_act_data_cback);
+
+        memset(&(evt_data.activated.params), 0x00, sizeof(tNFA_TAG_PARAMS));
+        memcpy(&(evt_data.activated.activate_ntf), &(p_data->activate),
+               sizeof(tNFC_ACTIVATE_DEVT));
+
+        nfa_dm_conn_cback_event_notify(NFA_ACTIVATED_EVT, &evt_data);
+      } else {
+        /* holding activation notification until sub-module is ready */
+        nfa_dm_cb.p_activate_ntf =
+            (uint8_t*)GKI_getbuf(sizeof(tNFC_ACTIVATE_DEVT));
+
+        if (nfa_dm_cb.p_activate_ntf) {
+          memcpy(nfa_dm_cb.p_activate_ntf, &(p_data->activate),
+                 sizeof(tNFC_ACTIVATE_DEVT));
+
+          if ((nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_T1T) ||
+              (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_T2T) ||
+              (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_T3T) ||
+              (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_ISO_DEP) ||
+              (nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_ISO15693) ||
+              (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_KOVIO)) {
+            /* Notify NFA tag sub-system */
+            nfa_rw_proc_disc_evt(NFA_DM_RF_DISC_ACTIVATED_EVT, p_data, false);
+          } else /* if NFC-DEP, ISO-DEP with frame interface or others */
+          {
+            /* Set data callback to receive raw frame */
+            NFC_SetStaticRfCback(nfa_dm_act_data_cback);
+            nfa_dm_notify_activation_status(NFA_STATUS_OK, NULL);
+          }
+        } else {
+          /* deactivate and restart RF discovery */
+          nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY);
+        }
+      }
+      break;
+
+    case NFA_DM_RF_DISC_DEACTIVATED_EVT:
+
+      /* if deactivated to idle or discovery */
+      if ((p_data->deactivate.type == NFC_DEACTIVATE_TYPE_IDLE) ||
+          (p_data->deactivate.type == NFC_DEACTIVATE_TYPE_DISCOVERY)) {
+        /* clear stored NFCID/UID/KOVIO bar code */
+        nfa_dm_cb.activated_nfcid_len = 0;
+      }
+
+      if (nfa_dm_cb.disc_cb.activated_protocol != NFC_PROTOCOL_NFC_DEP) {
+        /* Notify NFA RW sub-systems */
+        nfa_rw_proc_disc_evt(NFA_DM_RF_DISC_DEACTIVATED_EVT, NULL, false);
+      }
+
+      /* if deactivated as sleep mode */
+      if ((p_data->deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP) ||
+          (p_data->deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP_AF)) {
+        evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_SLEEP;
+      } else {
+        evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE;
+      }
+
+      /* notify deactivation to upper layer */
+      nfa_dm_conn_cback_event_notify(NFA_DEACTIVATED_EVT, &evt_data);
+
+      /* clean up SEL_RES response */
+      nfa_dm_cb.disc_cb.activated_sel_res = 0;
+      break;
+
+    default:
+      NFA_TRACE_ERROR0("Unexpected event");
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_poll_disc_cback
+**
+** Description      Processing event from discovery callback
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_dm_poll_disc_cback(tNFA_DM_RF_DISC_EVT event,
+                                   tNFC_DISCOVER* p_data) {
+  tNFA_CONN_EVT_DATA evt_data;
+
+  NFA_TRACE_DEBUG1("nfa_dm_poll_disc_cback (): event:0x%02X", event);
+
+  switch (event) {
+    case NFA_DM_RF_DISC_START_EVT:
+      break;
+
+    case NFA_DM_RF_DISC_ACTIVATED_EVT:
+
+      if (nfa_dm_cb.disc_cb.activated_tech_mode == NFC_DISCOVERY_TYPE_POLL_A) {
+        /* store SEL_RES response */
+        nfa_dm_cb.disc_cb.activated_sel_res =
+            p_data->activate.rf_tech_param.param.pa.sel_rsp;
+      }
+
+      /* holding activation notification until sub-module is ready */
+      nfa_dm_cb.p_activate_ntf =
+          (uint8_t*)GKI_getbuf(sizeof(tNFC_ACTIVATE_DEVT));
+
+      if (nfa_dm_cb.p_activate_ntf) {
+        memcpy(nfa_dm_cb.p_activate_ntf, &(p_data->activate),
+               sizeof(tNFC_ACTIVATE_DEVT));
+
+        if ((nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_NFC_DEP) &&
+            ((nfa_dm_cb.disc_cb.activated_rf_interface ==
+              NFC_INTERFACE_NFC_DEP))) {
+#if (NXP_EXTNS == TRUE)
+          /*For P2P mode(Default DTA mode) open Raw channel to bypass LLCP
+           * layer. For LLCP DTA mode activate LLCP*/
+          if ((appl_dta_mode_flag == 1) &&
+              ((nfa_dm_cb.eDtaMode & 0x0F) == NFA_DTA_DEFAULT_MODE)) {
+            /* Open raw channel in case of p2p for DTA testing */
+            NFC_SetStaticRfCback(nfa_dm_act_data_cback);
+            nfa_dm_notify_activation_status(NFA_STATUS_OK, NULL);
+
+          } else {
+#endif
+            if (!(nfa_dm_cb.flags & NFA_DM_FLAGS_P2P_PAUSED)) {
+              /* activate LLCP */
+              nfa_p2p_activate_llcp(p_data);
+              if (nfa_dm_cb.p_activate_ntf) {
+                GKI_freebuf(nfa_dm_cb.p_activate_ntf);
+                nfa_dm_cb.p_activate_ntf = NULL;
+              }
+            } else {
+              NFA_TRACE_DEBUG0("P2P is paused");
+              nfa_dm_notify_activation_status(NFA_STATUS_OK, NULL);
+            }
+#if (NXP_EXTNS == TRUE)
+          }
+#endif
+        } else if ((nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_T1T) ||
+                   (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_T2T) ||
+                   (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_T3T) ||
+                   (nfa_dm_cb.disc_cb.activated_protocol ==
+                    NFC_PROTOCOL_ISO_DEP) ||
+                   (nfa_dm_cb.disc_cb.activated_protocol ==
+                    NFC_PROTOCOL_15693) ||
+                   (nfa_dm_cb.disc_cb.activated_protocol ==
+                    NFC_PROTOCOL_KOVIO) ||
+                   (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_MIFARE)
+#if (NXP_EXTNS == TRUE)
+                   ||
+                   (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_T3BT)
+#endif
+                       ) {
+          /* Notify NFA tag sub-system */
+          nfa_rw_proc_disc_evt(NFA_DM_RF_DISC_ACTIVATED_EVT, p_data, true);
+        } else /* if NFC-DEP/ISO-DEP with frame interface */
+        {
+          /* Set data callback to receive raw frame */
+          NFC_SetStaticRfCback(nfa_dm_act_data_cback);
+          nfa_dm_notify_activation_status(NFA_STATUS_OK, NULL);
+        }
+      } else {
+        /* deactivate and restart RF discovery */
+        nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY);
+      }
+      break;
+
+    case NFA_DM_RF_DISC_DEACTIVATED_EVT:
+
+      /* if deactivated to idle or discovery */
+      if ((p_data->deactivate.type == NFC_DEACTIVATE_TYPE_IDLE) ||
+          (p_data->deactivate.type == NFC_DEACTIVATE_TYPE_DISCOVERY)) {
+        /* clear stored NFCID/UID/KOVIO bar code */
+        nfa_dm_cb.activated_nfcid_len = 0;
+      }
+
+      if ((nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_NFC_DEP) &&
+          ((nfa_dm_cb.disc_cb.activated_rf_interface ==
+            NFC_INTERFACE_NFC_DEP))) {
+        /*
+        ** If LLCP link is not deactivated yet,
+        ** LLCP will receive deactivation ntf through data callback.
+        ** NFA P2P will receive callback event from LLCP.
+        */
+      } else {
+        /* Notify NFA RW sub-systems */
+        nfa_rw_proc_disc_evt(NFA_DM_RF_DISC_DEACTIVATED_EVT, NULL, true);
+      }
+
+      /* if NFA sent NFA_ACTIVATED_EVT earlier */
+      if (nfa_dm_cb.flags & NFA_DM_FLAGS_SEND_DEACTIVATED_EVT) {
+        nfa_dm_cb.flags &= ~NFA_DM_FLAGS_SEND_DEACTIVATED_EVT;
+
+        /* if deactivated as sleep mode */
+        if ((p_data->deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP) ||
+            (p_data->deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP_AF)) {
+          evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_SLEEP;
+        } else {
+          evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE;
+        }
+        /* notify deactivation to application */
+        nfa_dm_conn_cback_event_notify(NFA_DEACTIVATED_EVT, &evt_data);
+      }
+
+      /* clean up SEL_RES response */
+      nfa_dm_cb.disc_cb.activated_sel_res = 0;
+
+      if (!(nfa_dm_cb.flags & NFA_DM_FLAGS_POLLING_ENABLED)) {
+        /* deregister discovery callback from NFA DM Discovery */
+        nfa_dm_delete_rf_discover(nfa_dm_cb.poll_disc_handle);
+        nfa_dm_cb.poll_disc_handle = NFA_HANDLE_INVALID;
+
+        /* this is for disable polling */
+        if (nfa_dm_cb.flags & NFA_DM_FLAGS_SEND_POLL_STOP_EVT) {
+          nfa_dm_cb.flags &= ~NFA_DM_FLAGS_SEND_POLL_STOP_EVT;
+
+          evt_data.status = NFA_STATUS_OK;
+          nfa_dm_conn_cback_event_notify(NFA_POLL_DISABLED_EVT, &evt_data);
+        }
+      }
+      break;
+  }
+}
+
+/*******************************************************************************
+** Function         nfa_dm_poll_disc_cback_dta_wrapper
+**
+** Description      Accessing the nfa_dm_poll_disc_cback for DTA wrapper
+**
+** Returns          None
+**
+*******************************************************************************/
+#if (NXP_EXTNS == TRUE)
+void nfa_dm_poll_disc_cback_dta_wrapper(tNFA_DM_RF_DISC_EVT event,
+                                        tNFC_DISCOVER* p_data) {
+  nfa_dm_poll_disc_cback(event, p_data);
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         nfa_dm_notify_activation_status
+**
+** Description      Processing activation status from sub-modules
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_dm_notify_activation_status(tNFA_STATUS status,
+                                     tNFA_TAG_PARAMS* p_params) {
+  tNFA_CONN_EVT_DATA evt_data;
+  tNFC_RF_TECH_PARAMS* p_tech_params;
+  uint8_t* p_nfcid = NULL, nfcid_len;
+
+  NFA_TRACE_DEBUG1("nfa_dm_notify_activation_status (): status:0x%X", status);
+
+  if (!nfa_dm_cb.p_activate_ntf) {
+    /* this is for NFA P2P listen */
+    return;
+  }
+
+  if (status == NFA_STATUS_OK
+#if (NXP_EXTNS == TRUE)
+      && (nfa_dm_cb.disc_cb.disc_state != NFA_DM_RFST_IDLE &&
+          nfa_dm_cb.disc_cb.disc_state != NFA_DM_RFST_DISCOVERY)
+#endif
+          ) {
+    /* notify NFC link activation */
+    memcpy(&(evt_data.activated.activate_ntf), nfa_dm_cb.p_activate_ntf,
+           sizeof(tNFC_ACTIVATE_DEVT));
+
+    p_tech_params = &evt_data.activated.activate_ntf.rf_tech_param;
+
+    memset(&(evt_data.activated.params), 0x00, sizeof(tNFA_TAG_PARAMS));
+    if (p_params) {
+      memcpy(&(evt_data.activated.params), p_params, sizeof(tNFA_TAG_PARAMS));
+    }
+
+    /* get length of NFCID and location */
+    if (p_tech_params->mode == NFC_DISCOVERY_TYPE_POLL_A) {
+      if ((p_tech_params->param.pa.nfcid1_len == 0) && (p_params != NULL)) {
+        nfcid_len = sizeof(p_params->t1t.uid);
+        p_nfcid = p_params->t1t.uid;
+        evt_data.activated.activate_ntf.rf_tech_param.param.pa.nfcid1_len =
+            nfcid_len;
+#if (NXP_EXTNS == TRUE)
+        if (nfcid_len > 0 && p_nfcid != NULL) {
+#endif
+          memcpy(evt_data.activated.activate_ntf.rf_tech_param.param.pa.nfcid1,
+                 p_nfcid, nfcid_len);
+#if (NXP_EXTNS == TRUE)
+        }
+#endif
+      } else {
+        nfcid_len = p_tech_params->param.pa.nfcid1_len;
+        p_nfcid = p_tech_params->param.pa.nfcid1;
+      }
+    } else if (p_tech_params->mode == NFC_DISCOVERY_TYPE_POLL_B) {
+      nfcid_len = NFC_NFCID0_MAX_LEN;
+      p_nfcid = p_tech_params->param.pb.nfcid0;
+#if (NXP_EXTNS == TRUE)
+      if (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_T3BT) {
+        if (p_tech_params->param.pb.pupiid_len != 0) {
+          tNFC_ACTIVATE_DEVT* activate_ntf =
+              (tNFC_ACTIVATE_DEVT*)nfa_dm_cb.p_activate_ntf;
+          p_nfcid = activate_ntf->rf_tech_param.param.pb.pupiid;
+          nfcid_len = activate_ntf->rf_tech_param.param.pb.pupiid_len;
+          NFA_TRACE_DEBUG1(
+              "nfa_dm_notify_activation_status (): update pupi_len=%x",
+              nfcid_len);
+          memcpy(evt_data.activated.activate_ntf.rf_tech_param.param.pb.pupiid,
+                 p_nfcid, nfcid_len);
+        }
+      }
+#endif
+    } else if (p_tech_params->mode == NFC_DISCOVERY_TYPE_POLL_F) {
+      nfcid_len = NFC_NFCID2_LEN;
+      p_nfcid = p_tech_params->param.pf.nfcid2;
+    } else if (p_tech_params->mode == NFC_DISCOVERY_TYPE_POLL_ISO15693) {
+      nfcid_len = NFC_ISO15693_UID_LEN;
+      p_nfcid = p_tech_params->param.pi93.uid;
+    } else if (p_tech_params->mode == NFC_DISCOVERY_TYPE_POLL_KOVIO) {
+      nfcid_len = p_tech_params->param.pk.uid_len;
+      p_nfcid = p_tech_params->param.pk.uid;
+    } else {
+      nfcid_len = 0;
+    }
+
+    /*
+    ** If not in exlusive RF mode, and
+    **      P2P activation, then push default NDEF message through SNEP
+    **      TAG activation, then read NDEF message
+    */
+    if (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_NFC_DEP) {
+      /*
+      ** Default NDEF message will be put to NFC Forum defualt SNEP server
+      ** after receiving NFA_LLCP_ACTIVATED_EVT.
+      */
+    } else if (!(nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE)) {
+      /*
+      ** if the same tag is activated then do not perform auto NDEF
+      ** detection. Application may put a tag into sleep mode and
+      ** reactivate the same tag.
+      */
+
+      if ((p_tech_params->mode != nfa_dm_cb.activated_tech_mode) ||
+          (nfcid_len != nfa_dm_cb.activated_nfcid_len) ||
+          (memcmp(p_nfcid, nfa_dm_cb.activated_nfcid, nfcid_len))) {
+        if ((nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_T1T) ||
+            (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_T2T) ||
+            (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_T3T) ||
+            ((nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_ISO_DEP) &&
+             (nfa_dm_cb.disc_cb.activated_rf_interface ==
+              NFC_INTERFACE_ISO_DEP)) ||
+            (nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_ISO15693)) {
+          if (p_nfa_dm_cfg->auto_detect_ndef) {
+            if (p_nfa_dm_cfg->auto_read_ndef) {
+              nfa_dm_cb.flags |= NFA_DM_FLAGS_AUTO_READING_NDEF;
+            }
+            NFA_RwDetectNDef();
+          } else if (p_nfa_dm_cfg->auto_read_ndef) {
+            NFA_RwReadNDef();
+          }
+        }
+      }
+    }
+
+    /* store activated tag information */
+    nfa_dm_cb.activated_tech_mode = p_tech_params->mode;
+    nfa_dm_cb.activated_nfcid_len = nfcid_len;
+    if (nfcid_len) memcpy(nfa_dm_cb.activated_nfcid, p_nfcid, nfcid_len);
+
+    nfa_dm_cb.flags |= NFA_DM_FLAGS_SEND_DEACTIVATED_EVT;
+    if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING))
+      nfa_dm_conn_cback_event_notify(NFA_ACTIVATED_EVT, &evt_data);
+  } else {
+    /* if NFC_DEP, NFA P2P will deactivate */
+    if (nfa_dm_cb.disc_cb.activated_protocol != NFC_PROTOCOL_NFC_DEP) {
+      nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY);
+    }
+  }
+
+  GKI_freebuf(nfa_dm_cb.p_activate_ntf);
+  nfa_dm_cb.p_activate_ntf = NULL;
+}
+
+#if (BT_TRACE_VERBOSE == true)
+/*******************************************************************************
+**
+** Function         nfa_dm_nfc_revt_2_str
+**
+** Description      convert nfc revt to string
+**
+*******************************************************************************/
+char* nfa_dm_nfc_revt_2_str(tNFC_RESPONSE_EVT event) {
+  switch (event) {
+    case NFC_ENABLE_REVT:
+      return "NFC_ENABLE_REVT";
+
+    case NFC_DISABLE_REVT:
+      return "NFC_DISABLE_REVT";
+
+    case NFC_SET_CONFIG_REVT:
+      return "NFC_SET_CONFIG_REVT";
+
+    case NFC_GET_CONFIG_REVT:
+      return "NFC_GET_CONFIG_REVT";
+
+    case NFC_NFCEE_DISCOVER_REVT:
+      return "NFC_NFCEE_DISCOVER_REVT";
+
+    case NFC_NFCEE_INFO_REVT:
+      return "NFC_NFCEE_INFO_REVT";
+
+    case NFC_NFCEE_MODE_SET_REVT:
+      return "NFC_NFCEE_MODE_SET_REVT";
+
+    case NFC_RF_FIELD_REVT:
+      return "NFC_RF_FIELD_REVT";
+
+    case NFC_EE_ACTION_REVT:
+      return "NFC_EE_ACTION_REVT";
+
+    case NFC_EE_DISCOVER_REQ_REVT:
+      return "NFC_EE_DISCOVER_REQ_REVT";
+
+    case NFC_SET_ROUTING_REVT:
+      return "NFC_SET_ROUTING_REVT";
+
+    case NFC_GET_ROUTING_REVT:
+      return "NFC_GET_ROUTING_REVT";
+
+    case NFC_GEN_ERROR_REVT:
+      return "NFC_GEN_ERROR_REVT";
+
+    case NFC_NFCC_RESTART_REVT:
+      return "NFC_NFCC_RESTART_REVT";
+
+    case NFC_NFCC_TIMEOUT_REVT:
+      return "NFC_NFCC_TIMEOUT_REVT";
+
+    case NFC_NFCC_TRANSPORT_ERR_REVT:
+      return "NFC_NFCC_TRANSPORT_ERR_REVT";
+
+    case NFC_NFCC_POWER_OFF_REVT:
+      return "NFC_NFCC_POWER_OFF_REVT";
+
+    case NFC_NFCEE_STATUS_REVT:
+        return "NFC_NFCEE_STATUS_REVT";
+
+#if (NXP_EXTNS == TRUE)
+    case NFC_NFCEE_PWR_LNK_CTRL_REVT:
+        if(nfcFL.eseFL._WIRED_MODE_STANDBY) {
+            return "NFC_NFCEE_PWR_LNK_CTRL_REVT";
+        }
+#endif
+    default:
+      return "unknown revt";
+      break;
+  }
+}
+#endif /* BT_VERBOSE */
diff --git a/src/nfa/dm/nfa_dm_api.c b/src/nfa/dm/nfa_dm_api.c
new file mode 100644
index 0000000..e7ab5e9
--- /dev/null
+++ b/src/nfa/dm/nfa_dm_api.c
@@ -0,0 +1,1629 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  NFA interface for device management
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_api.h"
+#include "nfa_sys.h"
+#include "nfa_dm_int.h"
+#include "nfa_ce_int.h"
+#include "nfa_sys_int.h"
+#include "ndef_utils.h"
+#if (NXP_EXTNS == TRUE)
+uint32_t gFelicaReaderMode;
+tHAL_NFC_CONTEXT hal_Initcntxt;
+#endif
+
+/*****************************************************************************
+**  Constants
+*****************************************************************************/
+
+/*****************************************************************************
+**  APIs
+*****************************************************************************/
+/*******************************************************************************
+**
+** Function         NFA_Init
+**
+** Description      This function initializes control blocks for NFA
+**
+**                  p_hal_entry_tbl points to a table of HAL entry points
+**
+**                  NOTE: the buffer that p_hal_entry_tbl points must be
+**                  persistent until NFA is disabled.
+**
+** Returns          none
+**
+*******************************************************************************/
+void NFA_Init(tHAL_NFC_ENTRY* p_hal_entry_tbl) {
+  NFA_TRACE_API0("NFA_Init ()");
+#if (NXP_EXTNS == TRUE)
+  hal_Initcntxt.hal_entry_func = p_hal_entry_tbl;
+#endif
+  nfa_sys_init();
+  nfa_dm_init();
+#if (NXP_EXTNS == TRUE)
+  if (hal_Initcntxt.boot_mode != NFA_FAST_BOOT_MODE) {
+#endif
+    nfa_p2p_init();
+    nfa_snep_init(false);
+    nfa_rw_init();
+    nfa_ce_init();
+    nfa_ee_init();
+    if (nfa_ee_max_ee_cfg != 0) {
+      nfa_dm_cb.get_max_ee = p_hal_entry_tbl->get_max_ee;
+
+      nfa_hci_init();
+    }
+#if (NXP_EXTNS == TRUE)
+  }
+#endif
+/* Initialize NFC module */
+#if (NXP_EXTNS == TRUE)
+  NFC_Init(&hal_Initcntxt);
+#else
+  NFC_Init(p_hal_entry_tbl);
+#endif
+  nfa_ee_max_ee_cfg == nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED;
+}
+
+/*******************************************************************************
+**
+** Function         NFA_Enable
+**
+** Description      This function enables NFC. Prior to calling NFA_Enable,
+**                  the NFCC must be powered up, and ready to receive commands.
+**                  This function enables the tasks needed by NFC, opens the NCI
+**                  transport, resets the NFC controller, downloads patches to
+**                  the NFCC (if necessary), and initializes the NFC subsystems.
+**
+**                  This function should only be called once - typically when
+**                  NFC is enabled during boot-up, or when NFC is enabled from a
+**                  settings UI. Subsequent calls to NFA_Enable while NFA is
+**                  enabling or enabled will be ignored. When the NFC startup
+**                  procedure is completed, an NFA_DM_ENABLE_EVT is returned to
+**                  the application using the tNFA_DM_CBACK.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_Enable(tNFA_DM_CBACK* p_dm_cback,
+                       tNFA_CONN_CBACK* p_conn_cback) {
+  tNFA_DM_API_ENABLE* p_msg;
+
+  NFA_TRACE_API0("NFA_Enable ()");
+
+  /* Validate parameters */
+  if ((!p_dm_cback) || (!p_conn_cback)) {
+    NFA_TRACE_ERROR0("NFA_Enable (): error null callback");
+    return (NFA_STATUS_FAILED);
+  }
+
+  p_msg = (tNFA_DM_API_ENABLE*)GKI_getbuf(sizeof(tNFA_DM_API_ENABLE));
+  if (p_msg != NULL) {
+    p_msg->hdr.event = NFA_DM_API_ENABLE_EVT;
+    p_msg->p_dm_cback = p_dm_cback;
+    p_msg->p_conn_cback = p_conn_cback;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_Disable
+**
+** Description      This function is called to shutdown NFC. The tasks for NFC
+**                  are terminated, and clean up routines are performed. This
+**                  function is typically called during platform shut-down, or
+**                  when NFC is disabled from a settings UI. When the NFC
+**                  shutdown procedure is completed, an NFA_DM_DISABLE_EVT is
+**                  returned to the application using the tNFA_DM_CBACK.
+**
+**                  The platform should wait until the NFC_DISABLE_REVT is
+**                  received before powering down the NFC chip and NCI
+**                  transport. This is required to so that NFA can gracefully
+**                  shut down any open connections.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_Disable(bool graceful) {
+  tNFA_DM_API_DISABLE* p_msg;
+
+  NFA_TRACE_API1("NFA_Disable (graceful=%i)", graceful);
+
+  p_msg = (tNFA_DM_API_DISABLE*)GKI_getbuf(sizeof(tNFA_DM_API_DISABLE));
+  if (p_msg != NULL) {
+    p_msg->hdr.event = NFA_DM_API_DISABLE_EVT;
+    p_msg->graceful = graceful;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_SetPowerSubState
+**
+** Description      send the current screen state to NFCC
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_SetPowerSubState (uint8_t ScreenState)
+{
+  tNFA_DM_API_SET_POWER_SUB_STATE *p_msg;
+  uint8_t nci_scren_state = 0xFF;
+
+  NFA_TRACE_API1 ("NFA_SetPowerSubState (): state:0x%X", ScreenState);
+
+
+  if ((p_msg = (tNFA_DM_API_SET_POWER_SUB_STATE *) GKI_getbuf ((uint16_t) (sizeof (tNFA_DM_API_SET_POWER_SUB_STATE)))) != NULL)
+  {
+    p_msg->hdr.event = NFA_DM_API_SET_POWER_SUB_STATE_EVT;
+    switch (ScreenState){
+      case NFA_SCREEN_STATE_ON_UNLOCKED:
+         nci_scren_state = SCREEN_STATE_ON_UNLOCKED;
+         break;
+      case NFA_SCREEN_STATE_OFF_UNLOCKED:
+         nci_scren_state = SCREEN_STATE_OFF_UNLOCKED;
+         break;
+      case NFA_SCREEN_STATE_ON_LOCKED:
+         nci_scren_state = SCREEN_STATE_ON_LOCKED;
+         break;
+      case NFA_SCREEN_STATE_OFF_LOCKED:
+         nci_scren_state = SCREEN_STATE_OFF_LOCKED;
+         break;
+      default:
+         NFA_TRACE_API1("%s, unknown screen state", __FUNCTION__);
+         break;
+    }
+    if(nci_scren_state != 0xFF) {
+      p_msg->screen_state = nci_scren_state;
+
+      nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+  }
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_SetConfig
+**
+** Description      Set the configuration parameters to NFCC. The result is
+**                  reported with an NFA_DM_SET_CONFIG_EVT in the tNFA_DM_CBACK
+**                  callback.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function. Most Configuration
+**                  parameters are related to RF discovery.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BUSY if previous setting is on-going
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_SetConfig(tNFA_PMID param_id, uint8_t length, uint8_t* p_data) {
+  tNFA_DM_API_SET_CONFIG* p_msg;
+
+  NFA_TRACE_API1("NFA_SetConfig (): param_id:0x%X", param_id);
+
+  p_msg = (tNFA_DM_API_SET_CONFIG*)GKI_getbuf(
+      (uint16_t)(sizeof(tNFA_DM_API_SET_CONFIG) + length));
+  if (p_msg != NULL) {
+    p_msg->hdr.event = NFA_DM_API_SET_CONFIG_EVT;
+
+    p_msg->param_id = param_id;
+    p_msg->length = length;
+    p_msg->p_data = (uint8_t*)(p_msg + 1);
+
+    /* Copy parameter data */
+    memcpy(p_msg->p_data, p_data, length);
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_GetConfig
+**
+** Description      Get the configuration parameters from NFCC. The result is
+**                  reported with an NFA_DM_GET_CONFIG_EVT in the tNFA_DM_CBACK
+**                  callback.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_GetConfig(uint8_t num_ids, tNFA_PMID* p_param_ids) {
+  tNFA_DM_API_GET_CONFIG* p_msg;
+#if (NXP_EXTNS == TRUE)
+  uint8_t bytes;
+  uint8_t propConfigCnt;
+
+  NFA_TRACE_API1("NFA_GetConfig (): num_ids: %i", num_ids);
+  // NXP_EXTN code added to handle propritory config IDs
+  uint32_t idx = 0;
+  uint8_t* params = p_param_ids;
+  propConfigCnt = 0;
+
+  for (idx = 0; idx < num_ids; idx++) {
+    if (*params == 0xA0) {
+      params++;
+      propConfigCnt++;
+    }
+    params++;
+  }
+
+  bytes = (num_ids - propConfigCnt) + (propConfigCnt << 1);
+
+  p_msg = (tNFA_DM_API_GET_CONFIG*)GKI_getbuf(
+      (uint16_t)(sizeof(tNFA_DM_API_GET_CONFIG) + bytes));
+#else
+  NFA_TRACE_API1("NFA_GetConfig (): num_ids: %i", num_ids);
+  p_msg = (tNFA_DM_API_GET_CONFIG*)GKI_getbuf(
+      (uint16_t)(sizeof(tNFA_DM_API_GET_CONFIG) + num_ids));
+#endif
+  if (p_msg != NULL) {
+    p_msg->hdr.event = NFA_DM_API_GET_CONFIG_EVT;
+
+    p_msg->num_ids = num_ids;
+    p_msg->p_pmids = (tNFA_PMID*)(p_msg + 1);
+
+/* Copy the param IDs */
+#if (NXP_EXTNS == TRUE)
+    memcpy(p_msg->p_pmids, p_param_ids, bytes);
+#else
+    memcpy(p_msg->p_pmids, p_param_ids, num_ids);
+#endif
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RequestExclusiveRfControl
+**
+** Description      Request exclusive control of NFC.
+**                  - Previous behavior (polling/tag reading, DH card emulation)
+**                    will be suspended .
+**                  - Polling and listening will be done based on the specified
+**                    params
+**
+**                  The NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT event of
+**                  tNFA_CONN_CBACK indicates the status of the operation.
+**
+**                  NFA_ACTIVATED_EVT and NFA_DEACTIVATED_EVT indicates link
+**                  activation/deactivation.
+**
+**                  NFA_SendRawFrame is used to send data to the peer.
+**                  NFA_DATA_EVT indicates data from the peer.
+**
+**                  If a tag is activated, then the NFA_RW APIs may be used to
+**                  send commands to the tag. Incoming NDEF messages are sent to
+**                  the NDEF callback.
+**
+**                  Once exclusive RF control has started, NFA will not activate
+**                  LLCP internally. The application has exclusive control of
+**                  the link.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RequestExclusiveRfControl(tNFA_TECHNOLOGY_MASK poll_mask,
+                                          tNFA_LISTEN_CFG* p_listen_cfg,
+                                          tNFA_CONN_CBACK* p_conn_cback,
+                                          tNFA_NDEF_CBACK* p_ndef_cback) {
+  tNFA_DM_API_REQ_EXCL_RF_CTRL* p_msg;
+
+  NFA_TRACE_API1("NFA_RequestExclusiveRfControl () poll_mask=0x%x", poll_mask);
+
+  if (!p_conn_cback) {
+    NFA_TRACE_ERROR0("NFA_RequestExclusiveRfControl (): error null callback");
+    return (NFA_STATUS_FAILED);
+  }
+
+  p_msg = (tNFA_DM_API_REQ_EXCL_RF_CTRL*)GKI_getbuf(
+      sizeof(tNFA_DM_API_REQ_EXCL_RF_CTRL));
+  if (p_msg != NULL) {
+    p_msg->hdr.event = NFA_DM_API_REQUEST_EXCL_RF_CTRL_EVT;
+    p_msg->poll_mask = poll_mask;
+    p_msg->p_conn_cback = p_conn_cback;
+    p_msg->p_ndef_cback = p_ndef_cback;
+
+    if (p_listen_cfg)
+      memcpy(&p_msg->listen_cfg, p_listen_cfg, sizeof(tNFA_LISTEN_CFG));
+    else
+      memset(&p_msg->listen_cfg, 0x00, sizeof(tNFA_LISTEN_CFG));
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_ReleaseExclusiveRfControl
+**
+** Description      Release exclusive control of NFC. Once released, behavior
+**                  prior to obtaining exclusive RF control will resume.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_ReleaseExclusiveRfControl(void) {
+  NFC_HDR* p_msg;
+
+  NFA_TRACE_API0("NFA_ReleaseExclusiveRfControl ()");
+
+  if (!nfa_dm_cb.p_excl_conn_cback) {
+    NFA_TRACE_ERROR0(
+        "NFA_ReleaseExclusiveRfControl (): Exclusive rf control is not in "
+        "progress");
+    return (NFA_STATUS_FAILED);
+  }
+
+  p_msg = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR));
+  if (p_msg != NULL) {
+    p_msg->event = NFA_DM_API_RELEASE_EXCL_RF_CTRL_EVT;
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_EnablePolling
+**
+** Description      Enable polling for technologies specified by poll_mask.
+**
+**                  The following events (notified using the connection
+**                  callback registered with NFA_Enable) are generated during
+**                  polling:
+**
+**                  - NFA_POLL_ENABLED_EVT indicates whether or not polling
+**                    successfully enabled.
+**                  - NFA_DISC_RESULT_EVT indicates there are more than one
+**                    devices, so application must select one of tags by calling
+**                    NFA_Select().
+**                  - NFA_SELECT_RESULT_EVT indicates whether previous selection
+**                    was successful or not. If it was failed then application
+**                    must select again or deactivate by calling
+**                    NFA_Deactivate().
+**                  - NFA_ACTIVATED_EVT is generated when an NFC link is
+**                    activated.
+**                  - NFA_NDEF_DETECT_EVT is generated if tag is activated
+**                  - NFA_LLCP_ACTIVATED_EVT/NFA_LLCP_DEACTIVATED_EVT is
+**                    generated if NFC-DEP is activated
+**                  - NFA_DEACTIVATED_EVT will be returned after deactivating
+**                    NFC link.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EnablePolling(tNFA_TECHNOLOGY_MASK poll_mask) {
+  tNFA_DM_API_ENABLE_POLL* p_msg;
+
+  NFA_TRACE_API1("NFA_EnablePolling () 0x%X", poll_mask);
+
+  p_msg = (tNFA_DM_API_ENABLE_POLL*)GKI_getbuf(sizeof(tNFA_DM_API_ENABLE_POLL));
+  if (p_msg != NULL) {
+    p_msg->hdr.event = NFA_DM_API_ENABLE_POLLING_EVT;
+    p_msg->poll_mask = poll_mask;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_DisablePolling
+**
+** Description      Disable polling
+**                  NFA_POLL_DISABLED_EVT will be returned after stopping
+**                  polling.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_DisablePolling(void) {
+  NFC_HDR* p_msg;
+
+  NFA_TRACE_API0("NFA_DisablePolling ()");
+
+  p_msg = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR));
+  if (p_msg != NULL) {
+    p_msg->event = NFA_DM_API_DISABLE_POLLING_EVT;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_EnableListening
+**
+** Description      Enable listening.
+**                  NFA_LISTEN_ENABLED_EVT will be returned after listening is
+**                  allowed.
+**
+**                  The actual listening technologies are specified by other NFA
+**                  API functions. Such functions include (but not limited to)
+**                  NFA_CeConfigureUiccListenTech.
+**                  If NFA_DisableListening () is called to ignore the listening
+**                  technologies, NFA_EnableListening () is called to restore
+**                  the listening technologies set by these functions.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EnableListening(void) {
+  NFC_HDR* p_msg;
+
+  NFA_TRACE_API0("NFA_EnableListening ()");
+
+  p_msg = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR));
+  if (p_msg != NULL) {
+    p_msg->event = NFA_DM_API_ENABLE_LISTENING_EVT;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_DisableListening
+**
+** Description      Disable listening
+**                  NFA_LISTEN_DISABLED_EVT will be returned after stopping
+**                  listening. This function is called to exclude listen at RF
+**                  discovery.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_DisableListening(void) {
+  NFC_HDR* p_msg;
+
+  NFA_TRACE_API0("NFA_DisableListening ()");
+
+  p_msg = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR));
+  if (p_msg != NULL) {
+    p_msg->event = NFA_DM_API_DISABLE_LISTENING_EVT;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         NFA_DisablePassiveListening
+**
+** Description      Disable Passive listening
+**                  NFA_LISTEN_DISABLED_EVT will be returned after stopping
+*listening.
+**                  This function is called to exclude listen at eSE wired mode
+*session open.
+**
+** Note:            If RF discovery is started,
+*NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_DisablePassiveListening(void) {
+    NFA_TRACE_API0("NFA_DisablePassiveListening ()");
+    if(!nfcFL.eseFL._NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION) {
+        NFA_TRACE_DEBUG0(" NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION"
+                " feature is not available!!");
+        return (NFA_STATUS_FAILED);
+    }
+  NFC_HDR* p_msg;
+
+  NFA_TRACE_API0("NFA_DisablePassiveListening ()");
+
+  if ((p_msg = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR))) != NULL) {
+    p_msg->event = NFA_DM_API_DISABLE_PASSIVE_LISTENING_EVT;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function:        NFA_SetPreferredUiccId
+**
+** Description:     Set Preferred Uicc ID
+**                  0x02 - UICC1
+**                  0x81 - UICC2
+**
+** Returns:         none:
+**
+*******************************************************************************/
+void NFA_SetPreferredUiccId(uint8_t uicc_id) {
+    NFA_TRACE_API0("NFA_SetPreferredUiccId ()");
+    if(!nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH) {
+        NFA_TRACE_DEBUG0("NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH"
+                " feature is not available!!");
+        return;
+    }
+    nfa_dm_cb.selected_uicc_id = uicc_id;
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         NFA_PauseP2p
+**
+** Description      Pause P2P services.
+**                  NFA_P2P_PAUSED_EVT will be returned after P2P services are
+**                  disabled.
+**
+**                  The P2P services enabled by NFA_P2p* API functions are not
+**                  available. NFA_ResumeP2p() is called to resume the P2P
+**                  services.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_PauseP2p(void) {
+  NFC_HDR* p_msg;
+
+  NFA_TRACE_API0("NFA_PauseP2p ()");
+
+  p_msg = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR));
+  if (p_msg != NULL) {
+    p_msg->event = NFA_DM_API_PAUSE_P2P_EVT;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_ResumeP2p
+**
+** Description      Resume P2P services.
+**                  NFA_P2P_RESUMED_EVT will be returned after P2P services are.
+**                  enables again.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_ResumeP2p(void) {
+  NFC_HDR* p_msg;
+
+  NFA_TRACE_API0("NFA_ResumeP2p ()");
+
+  p_msg = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR));
+  if (p_msg != NULL) {
+    p_msg->event = NFA_DM_API_RESUME_P2P_EVT;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_SetP2pListenTech
+**
+** Description      This function is called to set listen technology for
+**                  NFC-DEP. This funtion may be called before or after starting
+**                  any server on NFA P2P/CHO/SNEP.
+**                  If there is no technology for NFC-DEP, P2P listening will be
+**                  stopped.
+**
+**                  NFA_SET_P2P_LISTEN_TECH_EVT without data will be returned.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_SetP2pListenTech(tNFA_TECHNOLOGY_MASK tech_mask) {
+  tNFA_DM_API_SET_P2P_LISTEN_TECH* p_msg;
+
+  NFA_TRACE_API1("NFA_P2pSetListenTech (): tech_mask:0x%X", tech_mask);
+
+  p_msg = (tNFA_DM_API_SET_P2P_LISTEN_TECH*)GKI_getbuf(
+      sizeof(tNFA_DM_API_SET_P2P_LISTEN_TECH));
+  if (p_msg != NULL) {
+    p_msg->hdr.event = NFA_DM_API_SET_P2P_LISTEN_TECH_EVT;
+    p_msg->tech_mask = tech_mask;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_StartRfDiscovery
+**
+** Description      Start RF discovery
+**                  RF discovery parameters shall be set by other APIs.
+**
+**                  An NFA_RF_DISCOVERY_STARTED_EVT indicates whether starting
+**                  was successful or not.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_StartRfDiscovery(void) {
+  NFC_HDR* p_msg;
+
+  NFA_TRACE_API0("NFA_StartRfDiscovery ()");
+
+  p_msg = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR));
+  if (p_msg != NULL) {
+    p_msg->event = NFA_DM_API_START_RF_DISCOVERY_EVT;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_StopRfDiscovery
+**
+** Description      Stop RF discovery
+**
+**                  An NFA_RF_DISCOVERY_STOPPED_EVT indicates whether stopping
+**                  was successful or not.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_StopRfDiscovery(void) {
+  NFC_HDR* p_msg;
+
+  NFA_TRACE_API0("NFA_StopRfDiscovery ()");
+
+  p_msg = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR));
+  if (p_msg != NULL) {
+    p_msg->event = NFA_DM_API_STOP_RF_DISCOVERY_EVT;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_SetRfDiscoveryDuration
+**
+** Description      Set the duration of the single discovery period in [ms].
+**                  Allowable range: 0 ms to 0xFFFF ms.
+**
+**                  If discovery is already started, the application should
+**                  call NFA_StopRfDiscovery prior to calling
+**                  NFA_SetRfDiscoveryDuration, and then call
+**                  NFA_StartRfDiscovery afterwards to restart discovery using
+**                  the new duration.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns:
+**                  NFA_STATUS_OK, if command accepted
+**                  NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_SetRfDiscoveryDuration(uint16_t discovery_period_ms) {
+  tNFA_DM_API_SET_RF_DISC_DUR* p_msg;
+
+  NFA_TRACE_API0("NFA_SetRfDiscoveryDuration ()");
+
+  /* Post the API message */
+  p_msg = (tNFA_DM_API_SET_RF_DISC_DUR*)GKI_getbuf(sizeof(NFC_HDR));
+  if (p_msg != NULL) {
+    p_msg->hdr.event = NFA_DM_API_SET_RF_DISC_DURATION_EVT;
+
+    /* Set discovery duration */
+    p_msg->rf_disc_dur_ms = discovery_period_ms;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_Select
+**
+** Description      Select one from detected devices during discovery
+**                  (from NFA_DISC_RESULT_EVTs). The application should wait for
+**                  the final NFA_DISC_RESULT_EVT before selecting.
+**
+**                  An NFA_SELECT_RESULT_EVT indicates whether selection was
+**                  successful or not. If failed then application must select
+**                  again or deactivate by NFA_Deactivate().
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_INVALID_PARAM if RF interface is not matched
+**                  protocol
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_Select(uint8_t rf_disc_id, tNFA_NFC_PROTOCOL protocol,
+                       tNFA_INTF_TYPE rf_interface) {
+  tNFA_DM_API_SELECT* p_msg;
+
+  NFA_TRACE_API3(
+      "NFA_Select (): rf_disc_id:0x%X, protocol:0x%X, rf_interface:0x%X",
+      rf_disc_id, protocol, rf_interface);
+
+  if (((rf_interface == NFA_INTERFACE_ISO_DEP) &&
+       (protocol != NFA_PROTOCOL_ISO_DEP)) ||
+      ((rf_interface == NFA_INTERFACE_NFC_DEP) &&
+       (protocol != NFA_PROTOCOL_NFC_DEP))) {
+    NFA_TRACE_ERROR0("NFA_Select (): RF interface is not matched protocol");
+    return (NFA_STATUS_INVALID_PARAM);
+  }
+
+  p_msg =
+      (tNFA_DM_API_SELECT*)GKI_getbuf((uint16_t)(sizeof(tNFA_DM_API_SELECT)));
+  if (p_msg != NULL) {
+    p_msg->hdr.event = NFA_DM_API_SELECT_EVT;
+    p_msg->rf_disc_id = rf_disc_id;
+    p_msg->protocol = protocol;
+    p_msg->rf_interface = rf_interface;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_UpdateRFCommParams
+**
+** Description      This function is called to update RF Communication
+**                  parameters once the Frame RF Interface has been activated.
+**
+**                  An NFA_UPDATE_RF_PARAM_RESULT_EVT indicates whether updating
+**                  was successful or not.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_UpdateRFCommParams(tNFA_RF_COMM_PARAMS* p_params) {
+  tNFA_DM_API_UPDATE_RF_PARAMS* p_msg;
+
+  NFA_TRACE_API0("NFA_UpdateRFCommParams ()");
+
+  p_msg = (tNFA_DM_API_UPDATE_RF_PARAMS*)GKI_getbuf(
+      (uint16_t)(sizeof(tNFA_DM_API_UPDATE_RF_PARAMS)));
+  if (p_msg != NULL) {
+    p_msg->hdr.event = NFA_DM_API_UPDATE_RF_PARAMS_EVT;
+    memcpy(&p_msg->params, p_params, sizeof(tNFA_RF_COMM_PARAMS));
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_Deactivate
+**
+** Description
+**                  If sleep_mode=true:
+**                      Deselect the activated device by deactivating into sleep
+**                      mode.
+**
+**                      An NFA_DEACTIVATE_FAIL_EVT indicates that selection was
+**                      not successful. Application can select another
+**                      discovered device or deactivate by NFA_Deactivate ()
+**                      after receiving NFA_DEACTIVATED_EVT.
+**
+**                      Deactivating to sleep mode is not allowed when NFCC is
+**                      in wait-for-host-select mode, or in listen-sleep states;
+**                      NFA will deactivate to idle or discovery state
+**                      for these cases respectively.
+**
+**
+**                  If sleep_mode=false:
+**                      Deactivate the connection (e.g. as a result of presence
+**                      check failure) NFA_DEACTIVATED_EVT will indicate that
+**                      link is deactivated. Polling/listening will resume
+**                      (unless the nfcc is in wait_for-all-discoveries state)
+**
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_Deactivate(bool sleep_mode) {
+  tNFA_DM_API_DEACTIVATE* p_msg;
+
+  NFA_TRACE_API1("NFA_Deactivate (): sleep_mode:%i", sleep_mode);
+
+  p_msg = (tNFA_DM_API_DEACTIVATE*)GKI_getbuf(
+      (uint16_t)(sizeof(tNFA_DM_API_DEACTIVATE)));
+  if (p_msg != NULL) {
+    p_msg->hdr.event = NFA_DM_API_DEACTIVATE_EVT;
+    p_msg->sleep_mode = sleep_mode;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_SendRawFrame
+**
+** Description      Send a raw frame over the activated interface with the NFCC.
+**                  This function can only be called after NFC link is
+**                  activated.
+**
+**                  If the activated interface is a tag and auto-presence check
+**                  is enabled then presence_check_start_delay can be used to
+**                  indicate the delay in msec after which the next auto
+**                  presence check command can be sent.
+**                  NFA_DM_DEFAULT_PRESENCE_CHECK_START_DELAY can be used as the
+**                  default value for the delay.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_SendRawFrame(uint8_t* p_raw_data, uint16_t data_len,
+                             uint16_t presence_check_start_delay) {
+  NFC_HDR* p_msg;
+  uint16_t size;
+  uint8_t* p;
+
+  NFA_TRACE_API1("NFA_SendRawFrame () data_len:%d", data_len);
+
+/* Validate parameters */
+  if ((nfcFL.nfccFL._NXP_NFCC_EMPTY_DATA_PACKET &&
+          (((data_len == 0) || (p_raw_data == NULL)) &&
+                  (!(nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_LISTEN_ACTIVE &&
+                          nfa_dm_cb.disc_cb.activated_protocol ==
+                                  NFA_PROTOCOL_T3T)))) ||
+          ((data_len == 0) || (p_raw_data == NULL))) {
+      return (NFA_STATUS_INVALID_PARAM);
+  }
+  size = NFC_HDR_SIZE + NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + data_len;
+  p_msg = (NFC_HDR*)GKI_getbuf(size);
+  if (p_msg != NULL) {
+    p_msg->event = NFA_DM_API_RAW_FRAME_EVT;
+    p_msg->layer_specific = presence_check_start_delay;
+    p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+    p_msg->len = data_len;
+
+    p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+    if (nfcFL.nfccFL._NXP_NFCC_EMPTY_DATA_PACKET) {
+        if (p_raw_data != NULL) {
+            memcpy(p, p_raw_data, data_len);
+        }
+    }
+    else {
+        memcpy(p, p_raw_data, data_len);
+    }
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+** NDEF Handler APIs
+*******************************************************************************/
+
+/*******************************************************************************
+**
+** Function         NFA_RegisterNDefTypeHandler
+**
+** Description      This function allows the applications to register for
+**                  specific types of NDEF records. When NDEF records are
+**                  received, NFA will parse the record-type field, and pass
+**                  the record to the registered tNFA_NDEF_CBACK.
+**
+**                  For records types which were not registered, the record will
+**                  be sent to the default handler. A default type-handler may
+**                  be registered by calling this NFA_RegisterNDefTypeHandler
+**                  with tnf=NFA_TNF_DEFAULT. In this case, all un-registered
+**                  record types will be sent to the callback. Only one default
+**                  handler may be registered at a time.
+**
+**                  An NFA_NDEF_REGISTER_EVT will be sent to the tNFA_NDEF_CBACK
+**                  to indicate that registration was successful, and provide a
+**                  handle for this record type.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RegisterNDefTypeHandler(bool handle_whole_message, tNFA_TNF tnf,
+                                        uint8_t* p_type_name,
+                                        uint8_t type_name_len,
+                                        tNFA_NDEF_CBACK* p_ndef_cback) {
+  tNFA_DM_API_REG_NDEF_HDLR* p_msg;
+
+  NFA_TRACE_API2(
+      "NFA_RegisterNDefTypeHandler (): handle whole ndef message: %i, "
+      "tnf=0x%02x",
+      handle_whole_message, tnf);
+
+  /* Check for NULL callback */
+  if (!p_ndef_cback) {
+    NFA_TRACE_ERROR0("NFA_RegisterNDefTypeHandler (): error - null callback");
+    return (NFA_STATUS_INVALID_PARAM);
+  }
+
+  p_msg = (tNFA_DM_API_REG_NDEF_HDLR*)GKI_getbuf(
+      (uint16_t)(sizeof(tNFA_DM_API_REG_NDEF_HDLR) + type_name_len));
+  if (p_msg != NULL) {
+    p_msg->hdr.event = NFA_DM_API_REG_NDEF_HDLR_EVT;
+
+    p_msg->flags =
+        (handle_whole_message ? NFA_NDEF_FLAGS_HANDLE_WHOLE_MESSAGE : 0);
+    p_msg->tnf = tnf;
+    p_msg->name_len = type_name_len;
+    p_msg->p_ndef_cback = p_ndef_cback;
+    memcpy(p_msg->name, p_type_name, type_name_len);
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RegisterNDefUriHandler
+**
+** Description      This API is a special-case of NFA_RegisterNDefTypeHandler
+**                  with TNF=NFA_TNF_WKT, and type_name='U' (URI record); and
+**                  allows registering for specific URI types (e.g. 'tel:' or
+**                  'mailto:').
+**
+**                  An NFA_NDEF_REGISTER_EVT will be sent to the tNFA_NDEF_CBACK
+**                  to indicate that registration was successful, and provide a
+**                  handle for this registration.
+**
+**                  If uri_id=NFA_NDEF_URI_ID_ABSOLUTE, then p_abs_uri contains
+**                  the unabridged URI. For all other uri_id values,
+**                  the p_abs_uri parameter is ignored (i.e the URI prefix is
+**                  implied by uri_id). See [NFC RTD URI] for more information.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RegisterNDefUriHandler(bool handle_whole_message,
+                                              tNFA_NDEF_URI_ID uri_id,
+                                              uint8_t* p_abs_uri,
+                                              uint8_t uri_id_len,
+                                              tNFA_NDEF_CBACK* p_ndef_cback) {
+  tNFA_DM_API_REG_NDEF_HDLR* p_msg;
+
+  NFA_TRACE_API2(
+      "NFA_RegisterNDefUriHandler (): handle whole ndef message: %i, "
+      "uri_id=0x%02x",
+      handle_whole_message, uri_id);
+
+  /* Check for NULL callback */
+  if (!p_ndef_cback) {
+    NFA_TRACE_ERROR0("NFA_RegisterNDefUriHandler (): error - null callback");
+    return (NFA_STATUS_INVALID_PARAM);
+  }
+
+  p_msg = (tNFA_DM_API_REG_NDEF_HDLR*)GKI_getbuf(
+      (uint16_t)(sizeof(tNFA_DM_API_REG_NDEF_HDLR) + uri_id_len));
+  if (p_msg != NULL) {
+    p_msg->hdr.event = NFA_DM_API_REG_NDEF_HDLR_EVT;
+
+    p_msg->flags = NFA_NDEF_FLAGS_WKT_URI;
+
+    if (handle_whole_message) {
+      p_msg->flags |= NFA_NDEF_FLAGS_HANDLE_WHOLE_MESSAGE;
+    }
+
+    /* abs_uri is only valid fir uri_id=NFA_NDEF_URI_ID_ABSOLUTE */
+    if (uri_id != NFA_NDEF_URI_ID_ABSOLUTE) {
+      uri_id_len = 0;
+    }
+
+    p_msg->tnf = NFA_TNF_WKT;
+    p_msg->uri_id = uri_id;
+    p_msg->name_len = uri_id_len;
+    p_msg->p_ndef_cback = p_ndef_cback;
+    memcpy(p_msg->name, p_abs_uri, uri_id_len);
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_DeregisterNDefTypeHandler
+**
+** Description      Deregister NDEF record type handler.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_DeregisterNDefTypeHandler(tNFA_HANDLE ndef_type_handle) {
+  tNFA_DM_API_DEREG_NDEF_HDLR* p_msg;
+
+  NFA_TRACE_API1("NFA_DeregisterNDefHandler (): handle 0x%08x",
+                 ndef_type_handle);
+
+  p_msg = (tNFA_DM_API_DEREG_NDEF_HDLR*)GKI_getbuf(
+      (uint16_t)(sizeof(tNFA_DM_API_DEREG_NDEF_HDLR)));
+  if (p_msg != NULL) {
+    p_msg->hdr.event = NFA_DM_API_DEREG_NDEF_HDLR_EVT;
+    p_msg->ndef_type_handle = ndef_type_handle;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_PowerOffSleepMode
+**
+** Description      This function is called to enter or leave NFCC Power Off
+**                  Sleep mode NFA_DM_PWR_MODE_CHANGE_EVT will be sent to
+**                  indicate status.
+**
+**                  start_stop : true if entering Power Off Sleep mode
+**                               false if leaving Power Off Sleep mode
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_PowerOffSleepMode(bool start_stop) {
+  NFC_HDR* p_msg;
+
+  NFA_TRACE_API1("NFA_PowerOffSleepState () start_stop=%d", start_stop);
+  if (nfa_dm_cb.flags & NFA_DM_FLAGS_SETTING_PWR_MODE) {
+    NFA_TRACE_ERROR0(
+        "NFA_PowerOffSleepState (): NFA DM is busy to update power mode");
+    return (NFA_STATUS_FAILED);
+  } else {
+    nfa_dm_cb.flags |= NFA_DM_FLAGS_SETTING_PWR_MODE;
+  }
+
+  p_msg = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR));
+  if (p_msg != NULL) {
+    p_msg->event = NFA_DM_API_POWER_OFF_SLEEP_EVT;
+    p_msg->layer_specific = start_stop;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RegVSCback
+**
+** Description      This function is called to register or de-register a
+**                  callback function to receive Proprietary NCI response and
+**                  notification events. The maximum number of callback
+**                  functions allowed is NFC_NUM_VS_CBACKS
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFA_RegVSCback(bool is_register, tNFA_VSC_CBACK* p_cback) {
+  tNFA_DM_API_REG_VSC* p_msg;
+
+  NFA_TRACE_API1("NFA_RegVSCback() is_register=%d", is_register);
+
+  if (p_cback == NULL) {
+    NFA_TRACE_ERROR0("NFA_RegVSCback() requires a valid callback function");
+    return (NFA_STATUS_FAILED);
+  }
+
+  p_msg = (tNFA_DM_API_REG_VSC*)GKI_getbuf(sizeof(tNFA_DM_API_REG_VSC));
+  if (p_msg != NULL) {
+    p_msg->hdr.event = NFA_DM_API_REG_VSC_EVT;
+    p_msg->is_register = is_register;
+    p_msg->p_cback = p_cback;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_SendVsCommand
+**
+** Description      This function is called to send an NCI Vendor Specific
+**                  command to NFCC.
+**
+**                  oid             - The opcode of the VS command.
+**                  cmd_params_len  - The command parameter len
+**                  p_cmd_params    - The command parameter
+**                  p_cback         - The callback function to receive the
+**                                    command status
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_SendVsCommand(uint8_t oid, uint8_t cmd_params_len,
+                              uint8_t* p_cmd_params, tNFA_VSC_CBACK* p_cback) {
+  tNFA_DM_API_SEND_VSC* p_msg;
+  uint16_t size = sizeof(tNFA_DM_API_SEND_VSC) + cmd_params_len;
+
+  NFA_TRACE_API1("NFA_SendVsCommand() oid=0x%x", oid);
+
+  p_msg = (tNFA_DM_API_SEND_VSC*)GKI_getbuf(size);
+  if (p_msg != NULL) {
+    p_msg->hdr.event = NFA_DM_API_SEND_VSC_EVT;
+    p_msg->oid = oid;
+    p_msg->p_cback = p_cback;
+    if (cmd_params_len && p_cmd_params) {
+      p_msg->cmd_params_len = cmd_params_len;
+      p_msg->p_cmd_params = (uint8_t*)(p_msg + 1);
+      memcpy(p_msg->p_cmd_params, p_cmd_params, cmd_params_len);
+    } else {
+      p_msg->cmd_params_len = 0;
+      p_msg->p_cmd_params = NULL;
+    }
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         NFA_SendNxpNciCommand
+**
+** Description      This function is called to send an NXP NCI Vendor Specific
+**                  command to NFCC.
+**
+**                  cmd_params_len  - The command parameter len
+**                  p_cmd_params    - The command parameter
+**                  p_cback         - The callback function to receive the
+*command
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_SendNxpNciCommand(uint8_t cmd_params_len, uint8_t* p_cmd_params,
+                                  tNFA_VSC_CBACK* p_cback) {
+  if (cmd_params_len == 0x00 || p_cmd_params == NULL || p_cback == NULL) {
+    return (NFA_STATUS_INVALID_PARAM);
+  }
+  tNFA_DM_API_SEND_VSC* p_msg;
+  uint16_t size = sizeof(tNFA_DM_API_SEND_VSC) + cmd_params_len;
+
+  if ((p_msg = (tNFA_DM_API_SEND_VSC*)GKI_getbuf(size)) != NULL) {
+    p_msg->hdr.event = NFA_DM_API_SEND_NXP_EVT;
+    p_msg->p_cback = p_cback;
+    if (cmd_params_len && p_cmd_params) {
+      p_msg->cmd_params_len = cmd_params_len;
+      p_msg->p_cmd_params = (uint8_t*)(p_msg + 1);
+      memcpy(p_msg->p_cmd_params, p_cmd_params, cmd_params_len);
+    } else {
+      p_msg->cmd_params_len = 0;
+      p_msg->p_cmd_params = NULL;
+    }
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         NFA_SetTraceLevel
+**
+** Description      This function sets the trace level for NFA.  If called with
+**                  a value of 0xFF, it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+uint8_t NFA_SetTraceLevel(uint8_t new_level) {
+  if (new_level != 0xFF) nfa_sys_set_trace_level(new_level);
+
+  return (nfa_sys_cb.trace_level);
+}
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         NFA_checkNfcStateBusy()
+**
+** Description      This function returns whether NFC process is busy or not
+
+**
+** Returns          if Nfc state busy return true otherwise false.
+**
+*******************************************************************************/
+bool NFA_checkNfcStateBusy() {
+  if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_DISCOVERY) return false;
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function       NFA_SetReaderMode
+**
+** Description:
+**    This function enable/disable  reader mode. In reader mode, even though if
+**    P2P & CE from UICC is detected, Priority will be given to TypeF UICC read.
+**    Its currently implemented for TypeF
+**
+**    ReaderModeFlag   Enable/Disable Reader Mode
+**    Technologies     Type of technologies to be set for Reader mode
+**                     Currently not used and reader mode is enabled for TypeF
+*Only
+**
+** Returns:
+**    void
+*******************************************************************************/
+void NFA_SetReaderMode(bool ReaderModeFlag, uint32_t Technologies) {
+  (void)Technologies;
+
+  NFA_TRACE_API1("NFA_SetReaderMode =0x%x", ReaderModeFlag);
+  gFelicaReaderMode = ReaderModeFlag;
+  return;
+}
+
+/*******************************************************************************
+**
+** Function         NFA_SetBootMode
+**
+** Description      This function enables the boot mode for NFC.
+**                  boot_mode  0 NORMAL_BOOT 1 FAST_BOOT
+**                  By default , the mode is set to NORMAL_BOOT.
+
+**
+** Returns          none
+**
+*******************************************************************************/
+void NFA_SetBootMode(uint8_t boot_mode) { hal_Initcntxt.boot_mode = boot_mode; }
+/*******************************************************************************
+**
+** Function:        NFA_EnableDtamode
+**
+** Description:     Enable DTA Mode
+**
+** Returns:         none:
+**
+*******************************************************************************/
+void NFA_EnableDtamode(tNFA_eDtaModes eDtaMode) {
+  NFA_TRACE_API1("0x%x: DTA Enabled", eDtaMode);
+  appl_dta_mode_flag = 0x01;
+  nfa_dm_cb.eDtaMode = eDtaMode;
+}
+tNFA_MW_VERSION NFA_GetMwVersion() {
+  tNFA_MW_VERSION mwVer;
+  mwVer.validation =
+      (NXP_EN_PN547C2 | (NXP_EN_PN65T << 1) | (NXP_EN_PN548C2 << 2) |
+       (NXP_EN_PN66T << 3) | (NXP_EN_PN551 << 4) | (NXP_EN_PN67T << 5) |
+       (NXP_EN_PN553 << 6) | (NXP_EN_PN80T << 7) | (NXP_EN_PN553_MR1 << 8)
+        | (NXP_EN_PN81A << 9) | (NXP_EN_PN553_MR2 << 10) | (NXP_EN_PN557 << 11)
+        | (NXP_EN_PN81T << 12));
+  mwVer.android_version = NXP_ANDROID_VER;
+  NFA_TRACE_API1("0x%x:NFC MW Major Version:", NFC_NXP_MW_VERSION_MAJ);
+  NFA_TRACE_API1("0x%x:NFC MW Minor Version:", NFC_NXP_MW_VERSION_MIN);
+  mwVer.major_version = NFC_NXP_MW_VERSION_MAJ;
+  mwVer.minor_version = NFC_NXP_MW_VERSION_MIN;
+  NFA_TRACE_API2("mwVer:Major=0x%x,Minor=0x%x", mwVer.major_version,
+                 mwVer.minor_version);
+  return mwVer;
+}
+
+/*******************************************************************************
+**
+** Function:        NFA_ResetNfcc
+**
+** Description:     Reset the NFCC
+**
+** Returns:         NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_ResetNfcc() {
+    NFA_TRACE_DEBUG0("NFA_ResetNfcc()");
+    if(!nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH) {
+        NFA_TRACE_DEBUG0("NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH"
+                " feature is not available!!");
+        return (NFA_STATUS_FAILED);
+    }
+  tNFA_STATUS status = NFA_STATUS_FAILED;
+  status = nfc_ncif_reset_nfcc();
+  return status;
+}
+/*******************************************************************************
+**
+** Function:        NFA_EE_HCI_Control
+**
+** Description:     Enable/Disable EE&HCI subsystem based on mode flag.
+**                  Since NFCC reset being done, to receive Ntf corresponding to
+**                  UICC/ESE, EE and HCI Network has to be reset.
+**                  In MW corresponding context will be cleared and
+*re-initialized
+**
+** Returns:         none:
+**
+*******************************************************************************/
+void NFA_EE_HCI_Control(bool flagEnable) {
+    NFA_TRACE_DEBUG0("NFA_EE_HCI_Control()");
+    if(!nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH) {
+        NFA_TRACE_DEBUG0("NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH"
+                " feature is not available!!");
+        return;
+    }
+  uint8_t id[2] = {NFA_ID_HCI, NFA_ID_EE};
+  uint8_t i = 0;
+  if (!flagEnable) {
+    NFA_TRACE_DEBUG0("NFA_EE_HCI_Control (); Disable system");
+    nfa_sys_cb.graceful_disable = true;
+    for (i = 0; i < 2; i++) {
+      if (nfa_sys_cb.is_reg[id[i]]) {
+        if (nfa_sys_cb.reg[id[i]]->disable != NULL) {
+          (*nfa_sys_cb.reg[id[i]]->disable)();
+        } else {
+          nfa_sys_deregister(id[i]);
+          ;
+        }
+      }
+    }
+  } else {
+    nfa_ee_init();
+    nfa_hci_init();
+
+    NFA_TRACE_DEBUG0("NFA_EE_HCI_Control (); Enable system");
+    for (i = 0; i < 2; i++) {
+      if (nfa_sys_cb.is_reg[id[i]]) {
+        if (nfa_sys_cb.reg[id[i]]->enable != NULL) {
+          (*nfa_sys_cb.reg[id[i]]->enable)();
+        } else {
+          nfa_sys_cback_notify_enable_complete(id[i]);
+        }
+      }
+    }
+  }
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         NFA_GetNCIVersion
+**
+** Description      Returns the NCI version of the NFCC to upper layer
+**
+**
+** Returns          NCI version NCI2.0 / NCI1.0
+**
+*******************************************************************************/
+uint8_t NFA_GetNCIVersion()
+{
+    return NFC_GetNCIVersion();
+}
+
+/*******************************************************************************
+**
+** Function         NFA_Send_Core_Reset
+**
+** Description      Performs NCI Core Reset dynamically based on NCI version
+**
+**
+** Returns          SUCCESS/FAIL
+**
+*******************************************************************************/
+tNFA_STATUS NFA_Send_Core_Reset() {
+    return nfc_hal_nfcc_reset();
+}
+
+/*******************************************************************************
+**
+** Function         NFA_Send_Core_Init
+**
+** Description      Performs NCI Core Init dynamically based on NCI version
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void NFA_Send_Core_Init(uint8_t** p) {
+    nfc_hal_nfcc_init(p);
+}
diff --git a/src/nfa/dm/nfa_dm_cfg.c b/src/nfa/dm/nfa_dm_cfg.c
new file mode 100644
index 0000000..2101855
--- /dev/null
+++ b/src/nfa/dm/nfa_dm_cfg.c
@@ -0,0 +1,136 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2011-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains compile-time configurable constants for NFA modules
+ *
+ ******************************************************************************/
+#include "nfa_api.h"
+
+/* the SetConfig for CE T3T/T4T */
+const uint8_t nfa_dm_ce_cfg[] = {
+    13,                  /* total length */
+    NFC_PMID_LF_T3T_PMM, /* Type-3 tag default PMM */
+    NCI_PARAM_LEN_LF_T3T_PMM,
+    0x01, /* This PAD0 is used to identify HCE-F on Android */
+    0xFE, /* This PAD0 is used to identify HCE-F on Android */
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, NFC_PMID_FWI, /* FWI for ISO-DEP */
+    1, CE_T4T_ISO_DEP_FWI};
+
+uint8_t* p_nfa_dm_ce_cfg = (uint8_t*)nfa_dm_ce_cfg;
+
+/* the SetConfig for optional general NFC stack functions */
+const uint8_t nfa_dm_gen_cfg[] = {
+    3, /* total length */
+    /* Instruct NFCC to report RF field generated by remote device (or not) */
+    NFC_PMID_RF_FIELD_INFO, 1, 0x01};
+
+uint8_t* p_nfa_dm_gen_cfg = NULL;
+
+/* the RF Discovery Frequency for each technology */
+const tNFA_DM_DISC_FREQ_CFG nfa_dm_rf_disc_freq_cfg = {
+    1, /* Frequency for NFC Technology A               */
+    1, /* Frequency for NFC Technology B               */
+    1, /* Frequency for NFC Technology F               */
+    1, /* Frequency for Proprietary Technology/15693   */
+    1, /* Frequency for Proprietary Technology/B-Prime */
+    1, /* Frequency for Proprietary Technology/Kovio   */
+    1, /* Frequency for NFC Technology A active mode   */
+    1  /* Frequency for NFC Technology F active mode   */
+};
+
+tNFA_DM_DISC_FREQ_CFG* p_nfa_dm_rf_disc_freq_cfg =
+    (tNFA_DM_DISC_FREQ_CFG*)&nfa_dm_rf_disc_freq_cfg;
+
+uint8_t nfa_ee_max_ee_cfg = NFA_EE_MAX_EE_SUPPORTED;
+
+const tNCI_DISCOVER_MAPS nfa_dm_interface_mapping[NFA_DM_NUM_INTERFACE_MAP] = {
+    /* Protocols that use Frame Interface do not need to be included in the
+       interface mapping */
+    {NCI_PROTOCOL_ISO_DEP, NCI_INTERFACE_MODE_POLL_N_LISTEN,
+     NCI_INTERFACE_ISO_DEP},
+    {NCI_PROTOCOL_NFC_DEP, NCI_INTERFACE_MODE_POLL_N_LISTEN,
+     NCI_INTERFACE_NFC_DEP}};
+/* set to NULL to use the default mapping set by stack */
+tNCI_DISCOVER_MAPS* p_nfa_dm_interface_mapping = NULL;
+uint8_t nfa_dm_num_dm_interface_mapping = 0;
+
+const tNFA_DM_CFG nfa_dm_cfg = {
+    /* Automatic NDEF detection (when not in exclusive RF mode) */
+    NFA_DM_AUTO_DETECT_NDEF,
+    /* Automatic NDEF read (when not in exclusive RF mode) */
+    NFA_DM_AUTO_READ_NDEF,
+    /* Automatic presence check */
+    NFA_DM_AUTO_PRESENCE_CHECK,
+    /* Use sleep/wake(last interface) for ISODEP presence check */
+    NFA_DM_PRESENCE_CHECK_OPTION,
+    /* Maximum time to wait for presence check response */
+    NFA_DM_MAX_PRESENCE_CHECK_TIMEOUT};
+
+tNFA_DM_CFG* p_nfa_dm_cfg = (tNFA_DM_CFG*)&nfa_dm_cfg;
+
+const uint8_t nfa_hci_whitelist[] = {0x02, 0x03, 0x04};
+
+const tNFA_HCI_CFG nfa_hci_cfg = {
+    /* Max HCI Network IDLE time to wait for EE DISC REQ Ntf(s) */
+    NFA_HCI_NETWK_INIT_IDLE_TIMEOUT,
+    /* Maximum HCP Response time to any HCP Command */
+    NFA_HCI_RESPONSE_TIMEOUT,
+    /* Number of host in the whitelist of Terminal host */
+    0x03,
+    /* Pointer to the Whitelist of Terminal Host */
+    (uint8_t*)nfa_hci_whitelist};
+
+tNFA_HCI_CFG* p_nfa_hci_cfg = (tNFA_HCI_CFG*)&nfa_hci_cfg;
+
+bool nfa_poll_bail_out_mode = false;
+const tNFA_PROPRIETARY_CFG nfa_proprietary_cfg = {
+#if (NXP_EXTNS == TRUE)
+    0x05, /* NCI_PROTOCOL_18092_ACTIVE */
+#else
+    0x80,
+#endif
+    0x81, /* NCI_PROTOCOL_B_PRIME */
+    0x82, /* NCI_PROTOCOL_DUAL */
+#if (NXP_EXTNS == TRUE)
+    0x06,
+#else
+    0x83, /* NCI_PROTOCOL_15693 */
+#endif
+#if (NXP_EXTNS == TRUE && NFC_NXP_CHIP_TYPE != PN547C2)
+    0x81,
+#else
+    0x8A, /* NCI_PROTOCOL_KOVIO */
+#endif
+#if (NXP_EXTNS == TRUE)
+    0x80,
+#else
+    0xFF, /* NCI_PROTOCOL_MIFARE */
+#endif
+#if (NXP_EXTNS == TRUE && NFC_NXP_CHIP_TYPE != PN547C2)
+    0x70,
+#else
+    0x77, /* NCI_DISCOVERY_TYPE_POLL_KOVIO */
+#endif
+    0x74, /* NCI_DISCOVERY_TYPE_POLL_B_PRIME */
+    0xF4, /* NCI_DISCOVERY_TYPE_LISTEN_B_PRIME */
+};
+
+tNFA_PROPRIETARY_CFG* p_nfa_proprietary_cfg =
+    (tNFA_PROPRIETARY_CFG*)&nfa_proprietary_cfg;
diff --git a/src/nfa/dm/nfa_dm_discover.c b/src/nfa/dm/nfa_dm_discover.c
new file mode 100644
index 0000000..13593eb
--- /dev/null
+++ b/src/nfa/dm/nfa_dm_discover.c
@@ -0,0 +1,3561 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  This file contains the action functions for device manager discovery
+ *  function.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_sys.h"
+#include "nfa_api.h"
+#include "nfa_dm_int.h"
+#include "nfa_p2p_int.h"
+#include "nfa_sys_int.h"
+#include "nci_hmsgs.h"
+#if (NFC_NFCEE_INCLUDED == true)
+#include "nfa_ee_api.h"
+#include "nfa_ee_int.h"
+#endif
+#include "nfa_rw_int.h"
+
+#include "nfc_int.h"
+#if (NXP_EXTNS == TRUE)
+#include <config.h>
+#endif
+/*
+**  static functions
+*/
+#if (NXP_EXTNS == TRUE)
+static bool reconnect_in_progress;
+static bool is_emvco_active;
+static uint8_t gLastSak = 0x00;
+#endif
+
+static uint8_t nfa_dm_get_rf_discover_config(
+    tNFA_DM_DISC_TECH_PROTO_MASK dm_disc_mask,
+    tNFC_DISCOVER_PARAMS disc_params[], uint8_t max_params);
+static tNFA_STATUS nfa_dm_set_rf_listen_mode_config(
+    tNFA_DM_DISC_TECH_PROTO_MASK tech_proto_mask);
+static void nfa_dm_set_rf_listen_mode_raw_config(
+    tNFA_DM_DISC_TECH_PROTO_MASK* p_disc_mask);
+static tNFA_DM_DISC_TECH_PROTO_MASK nfa_dm_disc_get_disc_mask(
+    tNFC_RF_TECH_N_MODE tech_n_mode, tNFC_PROTOCOL protocol);
+static void nfa_dm_notify_discovery(tNFA_DM_RF_DISC_DATA* p_data);
+static tNFA_STATUS nfa_dm_disc_notify_activation(tNFC_DISCOVER* p_data);
+static void nfa_dm_disc_notify_deactivation(tNFA_DM_RF_DISC_SM_EVENT sm_event,
+                                            tNFC_DISCOVER* p_data);
+static void nfa_dm_disc_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
+                                   tNFC_CONN* p_data);
+static void nfa_dm_disc_kovio_timeout_cback(TIMER_LIST_ENT* p_tle);
+static void nfa_dm_disc_report_kovio_presence_check(tNFC_STATUS status);
+
+#if (BT_TRACE_VERBOSE == true)
+static char* nfa_dm_disc_state_2_str(uint8_t state);
+static char* nfa_dm_disc_event_2_str(uint8_t event);
+#endif
+
+#if (NXP_EXTNS == TRUE)
+typedef struct nfa_dm_p2p_prio_logic {
+  bool isodep_detected;      /* flag to check if ISO-DEP is detected */
+  bool timer_expired;        /* flag to check whether timer is expired */
+  TIMER_LIST_ENT timer_list; /*timer structure pointer */
+  uint8_t first_tech_mode;
+} nfa_dm_p2p_prio_logic_t;
+
+static nfa_dm_p2p_prio_logic_t p2p_prio_logic_data;
+
+static void nfa_dm_send_tag_deselect_cmd(tNFA_NFC_PROTOCOL protocol);
+#define TAG_DESELECT_CMD 0xC2
+uint8_t T2T_SLP_REQ[] ={0x05,0x00};
+
+int getListenTechValue(int listenTechMask);
+#define P2P_RESUME_POLL_TIMEOUT 16 /*mili second timeout value*/
+static uint16_t P2P_PRIO_LOGIC_CLEANUP_TIMEOUT =
+    50; /*timeout value 500 ms for p2p_prio_logic_cleanup*/
+static uint16_t P2P_PRIO_LOGIC_DEACT_NTF_TIMEOUT =
+    200; /* timeout value 2 sec waiting for deactivate ntf */
+#endif
+
+#if (NXP_EXTNS == TRUE)
+bool etsi_reader_in_progress = false;
+#endif
+/*******************************************************************************
+**
+** Function         nfa_dm_get_rf_discover_config
+**
+** Description      Build RF discovery configurations from
+**                  tNFA_DM_DISC_TECH_PROTO_MASK
+**
+** Returns          number of RF discovery configurations
+**
+*******************************************************************************/
+static uint8_t nfa_dm_get_rf_discover_config(
+    tNFA_DM_DISC_TECH_PROTO_MASK dm_disc_mask,
+    tNFC_DISCOVER_PARAMS disc_params[], uint8_t max_params) {
+  uint8_t num_params = 0;
+
+  NFA_TRACE_DEBUG2("%s : dm_disc_mask = 0x%08X", __func__, dm_disc_mask);
+
+  if (nfa_dm_cb.flags & NFA_DM_FLAGS_LISTEN_DISABLED) {
+    NFA_TRACE_DEBUG1(
+        "nfa_dm_get_rf_discover_config() : listen disabled, remove listen from "
+        "0x%x",
+        dm_disc_mask);
+    dm_disc_mask &= NFA_DM_DISC_MASK_POLL;
+  }
+
+  if (nfa_dm_is_p2p_paused()) {
+    NFA_TRACE_DEBUG1(
+        "nfa_dm_get_rf_discover_config () removing active listen A/B 0x%x",
+        dm_disc_mask);
+    dm_disc_mask &= ~NFA_DM_DISC_MASK_NFC_DEP;
+  }
+#if (NXP_EXTNS == TRUE)
+  if (nfcFL.eseFL._NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION &&
+          (nfa_dm_cb.flags & NFA_DM_FLAGS_PASSIVE_LISTEN_DISABLED)) {
+    NFA_TRACE_DEBUG1(
+        "nfa_dm_get_rf_discover_config () passive listen disabled, rm listen "
+        "from 0x%x",
+        dm_disc_mask);
+    dm_disc_mask &= NFA_DM_DISC_MASK_ACTIVE_LISTEN;
+    dm_disc_mask |=
+        (NFA_DM_DISC_MASK_LAA_NFC_DEP | NFA_DM_DISC_MASK_LFA_NFC_DEP);
+  }
+#endif
+  /* Check polling A */
+  if (dm_disc_mask &
+      (NFA_DM_DISC_MASK_PA_T1T | NFA_DM_DISC_MASK_PA_T2T |
+       NFA_DM_DISC_MASK_PA_ISO_DEP | NFA_DM_DISC_MASK_PA_NFC_DEP |
+       NFA_DM_DISC_MASK_P_LEGACY)) {
+    disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_A;
+    disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pa;
+    num_params++;
+
+    if (num_params >= max_params) return num_params;
+  }
+
+  /* Check polling B */
+  if (dm_disc_mask & (NFA_DM_DISC_MASK_PB_ISO_DEP
+#if (NXP_EXTNS == TRUE)
+                      | NFA_DM_DISC_MASK_PB_T3BT
+#endif
+                      )) {
+    disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_B;
+    disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pb;
+    num_params++;
+
+    if (num_params >= max_params) return num_params;
+  }
+
+  /* Check polling F */
+  if (dm_disc_mask & (NFA_DM_DISC_MASK_PF_T3T | NFA_DM_DISC_MASK_PF_NFC_DEP)) {
+    disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_F;
+    disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pf;
+    num_params++;
+
+    if (num_params >= max_params) return num_params;
+  }
+
+  /* Check polling A Active mode  */
+  if (dm_disc_mask & NFA_DM_DISC_MASK_PAA_NFC_DEP) {
+    disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_A_ACTIVE;
+    disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->paa;
+    num_params++;
+
+    if (num_params >= max_params) return num_params;
+  }
+
+  /* Check polling F Active mode  */
+  if (dm_disc_mask & NFA_DM_DISC_MASK_PFA_NFC_DEP) {
+    disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_F_ACTIVE;
+    disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pfa;
+    num_params++;
+
+    if (num_params >= max_params) return num_params;
+  }
+
+  /* Check listening A */
+  if (dm_disc_mask &
+      (NFA_DM_DISC_MASK_LA_T1T | NFA_DM_DISC_MASK_LA_T2T |
+       NFA_DM_DISC_MASK_LA_ISO_DEP | NFA_DM_DISC_MASK_LA_NFC_DEP)) {
+    disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_A;
+    disc_params[num_params].frequency = 1;
+    num_params++;
+
+    if (num_params >= max_params) return num_params;
+  }
+
+  /* Check listening B */
+  if (dm_disc_mask & NFA_DM_DISC_MASK_LB_ISO_DEP) {
+    disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_B;
+    disc_params[num_params].frequency = 1;
+    num_params++;
+
+    if (num_params >= max_params) return num_params;
+  }
+
+  /* Check listening F */
+  if (dm_disc_mask & (NFA_DM_DISC_MASK_LF_T3T | NFA_DM_DISC_MASK_LF_NFC_DEP)) {
+    disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_F;
+    disc_params[num_params].frequency = 1;
+    num_params++;
+
+    if (num_params >= max_params) return num_params;
+  }
+
+  /* Check listening A Active mode */
+  if (dm_disc_mask & NFA_DM_DISC_MASK_LAA_NFC_DEP) {
+    disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE;
+    disc_params[num_params].frequency = 1;
+    num_params++;
+
+    if (num_params >= max_params) return num_params;
+  }
+
+  /* Check listening F Active mode */
+  if (dm_disc_mask & NFA_DM_DISC_MASK_LFA_NFC_DEP) {
+    disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE;
+    disc_params[num_params].frequency = 1;
+    num_params++;
+
+    if (num_params >= max_params) return num_params;
+  }
+
+  /* Check polling ISO 15693 */
+  if (dm_disc_mask & NFA_DM_DISC_MASK_P_ISO15693) {
+    disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_ISO15693;
+    disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pi93;
+    num_params++;
+
+    if (num_params >= max_params) return num_params;
+  }
+
+  /* Check polling B' */
+  if (dm_disc_mask & NFA_DM_DISC_MASK_P_B_PRIME) {
+    disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_B_PRIME;
+    disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pbp;
+    num_params++;
+
+    if (num_params >= max_params) return num_params;
+  }
+
+  /* Check polling KOVIO */
+  if (dm_disc_mask & NFA_DM_DISC_MASK_P_KOVIO) {
+    disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_KOVIO;
+    disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pk;
+    num_params++;
+
+    if (num_params >= max_params) return num_params;
+  }
+
+  /* Check listening ISO 15693 */
+  if (dm_disc_mask & NFA_DM_DISC_MASK_L_ISO15693) {
+    disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_ISO15693;
+    disc_params[num_params].frequency = 1;
+    num_params++;
+
+    if (num_params >= max_params) return num_params;
+  }
+
+  /* Check listening B' */
+  if (dm_disc_mask & NFA_DM_DISC_MASK_L_B_PRIME) {
+    disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_B_PRIME;
+    disc_params[num_params].frequency = 1;
+    num_params++;
+
+    if (num_params >= max_params) return num_params;
+  }
+
+  return num_params;
+}
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         nfa_dm_get_sak
+**
+** Description      provides the proper sak value based on nfcee id present and
+**                  HOST configuration.
+**
+** Returns          NFA_STATUS_OK if success
+**
+*******************************************************************************/
+static uint8_t nfa_dm_get_sak(tNFA_DM_DISC_TECH_PROTO_MASK tech_proto_mask) {
+  uint8_t sak = 0;
+  uint8_t tech_list = 0;
+  uint8_t hostListenMask = 0x00, fwdEnable = 0x00;
+
+  if ((GetNumValue(NAME_HOST_LISTEN_TECH_MASK, &hostListenMask,
+                   sizeof(hostListenMask)))) {
+    NFA_TRACE_DEBUG2("%s : HOST_LISTEN_TECH_MASK = 0x%X;", __func__,
+                     hostListenMask);
+  }
+  if ((GetNumValue(NAME_NXP_FWD_FUNCTIONALITY_ENABLE, &fwdEnable,
+                   sizeof(fwdEnable)))) {
+    NFA_TRACE_DEBUG2("%s:NXP_FWD_FUNCTIONALITY_ENABLE=0x0%lu;", __func__,
+                     fwdEnable);
+  }
+
+  tech_list = nfa_ee_get_supported_tech_list(nfa_dm_cb.selected_uicc_id);
+
+  if (hostListenMask == 0x03) {
+    if (!fwdEnable && (tech_list == NFA_TECHNOLOGY_MASK_B)) {
+      sak = 0x00;
+    } else {
+      if (tech_proto_mask & NFA_DM_DISC_MASK_LA_ISO_DEP) {
+        sak |= NCI_PARAM_SEL_INFO_ISODEP;
+      }
+      if (tech_proto_mask & NFA_DM_DISC_MASK_LA_NFC_DEP) {
+        sak |= NCI_PARAM_SEL_INFO_NFCDEP;
+      }
+    }
+  } else {
+    if (tech_list == NFA_TECHNOLOGY_MASK_B) {
+      sak = 0x00;
+    } else if (tech_proto_mask & NFA_DM_DISC_MASK_LA_NFC_DEP) {
+      sak |= NCI_PARAM_SEL_INFO_ISODEP;
+      sak |= NCI_PARAM_SEL_INFO_NFCDEP;
+    }
+  }
+
+  return sak;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_set_listen_mode_set_configs
+**
+** Description      Update listen mode set configs(LA_SEL_INFO & LB_SENSB_INFO)
+**                  for HCE-A only or HCE-B only functionality.
+**
+** Returns          NFA_STATUS_OK if success
+**
+*******************************************************************************/
+static tNFA_STATUS nfa_dm_set_listen_mode_set_configs(
+    tNFA_DM_DISC_TECH_PROTO_MASK tech_proto_mask) {
+  uint8_t params[40], *p;
+  uint8_t SAK = 0x00;
+  uint8_t SENSB_RES = 0x00;
+  uint8_t LF_PROTOTYPE = 0x00;
+  unsigned long hostListenMask = 0x00;
+
+  NFA_TRACE_DEBUG2("%s : tech_proto_mask = 0x%08X", __func__, tech_proto_mask);
+
+  if ((GetNumValue(NAME_HOST_LISTEN_TECH_MASK, &hostListenMask,
+                   sizeof(hostListenMask)))) {
+    NFA_TRACE_DEBUG2("%s : HOST_LISTEN_TECH_MASK = 0x0%lu;", __func__,
+                     hostListenMask);
+  }
+
+  p = params;
+
+  if ((tech_proto_mask & NFA_DM_DISC_MASK_LA_ISO_DEP) &&
+      ((hostListenMask & 0x01) == 0x01)) {
+    SAK |= 0x20;
+    gLastSak |= SAK;
+  } else {
+    SAK &= 0x00;
+  }
+  if (tech_proto_mask & NFA_DM_DISC_MASK_LA_NFC_DEP) {
+    NFA_TRACE_DEBUG2("%s : gLastSak = 0x%X;", __func__, gLastSak);
+    if (gLastSak) SAK |= gLastSak;
+    SAK |= NCI_PARAM_SEL_INFO_NFCDEP;
+    gLastSak &= 0x00;
+  }
+  NFA_TRACE_DEBUG2("%s : LA_SEL_INFO = 0x%X;", __func__, SAK);
+  UINT8_TO_STREAM(p, NFC_PMID_LA_SEL_INFO);
+  UINT8_TO_STREAM(p, NCI_PARAM_LEN_LA_SEL_INFO);
+  UINT8_TO_STREAM(p, SAK);
+
+  if ((tech_proto_mask & NFA_DM_DISC_MASK_LB_ISO_DEP) &&
+      ((hostListenMask & 0x02) == 0x02)) {
+    SENSB_RES |= 0x01;
+  } else {
+    SENSB_RES &= 0x00;
+  }
+  NFA_TRACE_DEBUG2("%s : LB_SENSB_INFO = 0x%X;", __func__, SENSB_RES);
+  UINT8_TO_STREAM(p, NFC_PMID_LB_SENSB_INFO);
+  UINT8_TO_STREAM(p, NCI_PARAM_LEN_LB_SENSB_INFO);
+  UINT8_TO_STREAM(p, SENSB_RES);
+
+  if ((tech_proto_mask & NFA_DM_DISC_MASK_LF_NFC_DEP) &&
+      !nfa_dm_is_p2p_paused()) {
+    LF_PROTOTYPE |= NCI_LISTEN_PROTOCOL_NFC_DEP;
+  } else {
+    LF_PROTOTYPE |= 0x00;
+  }
+
+  UINT8_TO_STREAM(p, NFC_PMID_LF_PROTOCOL);
+  UINT8_TO_STREAM(p, NCI_PARAM_LEN_LF_PROTOCOL);
+  UINT8_TO_STREAM(p, LF_PROTOTYPE);
+  NFA_TRACE_DEBUG2("%s : LF_PROTOCOL_TYPE = 0x%X;", __func__, LF_PROTOTYPE);
+
+  if (p > params) {
+    nfa_dm_check_set_config((uint8_t)(p - params), params, false);
+  }
+  return NFA_STATUS_OK;
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         nfa_dm_set_rf_listen_mode_config
+**
+** Description      Update listening protocol to NFCC
+**
+** Returns          NFA_STATUS_OK if success
+**
+*******************************************************************************/
+static tNFA_STATUS nfa_dm_set_rf_listen_mode_config(
+    tNFA_DM_DISC_TECH_PROTO_MASK tech_proto_mask) {
+  uint8_t params[40], *p;
+  uint8_t platform = 0;
+  uint8_t sens_info = 0;
+
+  NFA_TRACE_DEBUG1(
+      "nfa_dm_set_rf_listen_mode_config () tech_proto_mask = 0x%08X",
+      tech_proto_mask);
+
+  /*
+  ** T1T listen     LA_PROT 0x80, LA_SENS_RES byte1:0x00 byte2:0x0C
+  ** T2T listen     LA_PROT 0x00
+  ** T3T listen     No bit for T3T in LF_PROT (CE T3T set listen parameters,
+  **                system code, NFCID2, etc.)
+  ** ISO-DEP listen LA_PROT 0x01, LB_PROT 0x01
+  ** NFC-DEP listen LA_PROT 0x02, LF_PROT 0x02
+  */
+  p = params;
+  if (tech_proto_mask & NFA_DM_DISC_MASK_LA_T1T) {
+    platform = NCI_PARAM_PLATFORM_T1T;
+  } else if (tech_proto_mask & NFA_DM_DISC_MASK_LA_T2T) {
+    /* platform = 0 and sens_info = 0 */
+  } else {
+#if (NXP_EXTNS == FALSE)
+    if (tech_proto_mask & NFA_DM_DISC_MASK_LA_ISO_DEP) {
+      sens_info |= NCI_PARAM_SEL_INFO_ISODEP;
+    }
+
+    if (tech_proto_mask & NFA_DM_DISC_MASK_LA_NFC_DEP) {
+      sens_info |= NCI_PARAM_SEL_INFO_NFCDEP;
+    }
+#else
+    sens_info = nfa_dm_get_sak(tech_proto_mask);
+    NFA_TRACE_DEBUG2("%s: sens_info=0x0%x;", __func__, sens_info);
+#endif
+  }
+#if (NXP_EXTNS == TRUE)
+  /*
+   * SEL_INFO will be updated irrespective of UICC/eSE is selected or not
+   * This is required for P2P to work if UICC/ESE selected
+   * */
+  UINT8_TO_STREAM(p, NFC_PMID_LA_SEL_INFO);
+  UINT8_TO_STREAM(p, NCI_PARAM_LEN_LA_SEL_INFO);
+  UINT8_TO_STREAM(p, sens_info);
+#endif
+
+  /*
+  ** for Listen A
+  **
+  ** Set ATQA 0x0C00 for T1T listen
+  ** If the ATQA values are 0x0000, then the FW will use 0x0400
+  ** which works for ISODEP, T2T and NFCDEP.
+  */
+  if (nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_A] ==
+      NFA_DM_DISC_HOST_ID_DH) {
+    UINT8_TO_STREAM(p, NFC_PMID_LA_BIT_FRAME_SDD);
+    UINT8_TO_STREAM(p, NCI_PARAM_LEN_LA_BIT_FRAME_SDD);
+    UINT8_TO_STREAM(p, 0x04);
+    UINT8_TO_STREAM(p, NFC_PMID_LA_PLATFORM_CONFIG);
+    UINT8_TO_STREAM(p, NCI_PARAM_LEN_LA_PLATFORM_CONFIG);
+    UINT8_TO_STREAM(p, platform);
+#if (NXP_EXTNS != TRUE)
+    UINT8_TO_STREAM(p, NFC_PMID_LA_SEL_INFO);
+    UINT8_TO_STREAM(p, NCI_PARAM_LEN_LA_SEL_INFO);
+    UINT8_TO_STREAM(p, sens_info);
+#endif
+  } else /* Let NFCC use UICC configuration by configuring with length = 0 */
+  {
+    UINT8_TO_STREAM(p, NFC_PMID_LA_BIT_FRAME_SDD);
+    UINT8_TO_STREAM(p, 0);
+    UINT8_TO_STREAM(p, NFC_PMID_LA_PLATFORM_CONFIG);
+    UINT8_TO_STREAM(p, 0);
+#if (NXP_EXTNS != TRUE)
+    UINT8_TO_STREAM(p, NFC_PMID_LA_SEL_INFO);
+    UINT8_TO_STREAM(p, 0);
+#endif
+    UINT8_TO_STREAM(p, NFC_PMID_LA_NFCID1);
+    UINT8_TO_STREAM(p, 0);
+    UINT8_TO_STREAM(p, NFC_PMID_LA_HIST_BY);
+    UINT8_TO_STREAM(p, 0);
+  }
+
+  /* for Listen B */
+  if (nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_B] ==
+      NFA_DM_DISC_HOST_ID_DH) {
+    UINT8_TO_STREAM(p, NFC_PMID_LB_SENSB_INFO);
+    UINT8_TO_STREAM(p, NCI_PARAM_LEN_LB_SENSB_INFO);
+    if (tech_proto_mask & NFA_DM_DISC_MASK_LB_ISO_DEP) {
+      UINT8_TO_STREAM(p, NCI_LISTEN_PROTOCOL_ISO_DEP);
+    } else {
+      UINT8_TO_STREAM(p, 0x00);
+    }
+  } else /* Let NFCC use UICC configuration by configuring with length = 0 */
+  {
+    UINT8_TO_STREAM(p, NFC_PMID_LB_SENSB_INFO);
+    UINT8_TO_STREAM(p, 0);
+    UINT8_TO_STREAM(p, NFC_PMID_LB_NFCID0);
+    UINT8_TO_STREAM(p, 0);
+    UINT8_TO_STREAM(p, NFC_PMID_LB_APPDATA);
+    UINT8_TO_STREAM(p, 0);
+    UINT8_TO_STREAM(p, NFC_PMID_LB_ADC_FO);
+    UINT8_TO_STREAM(p, 0);
+    UINT8_TO_STREAM(p, NFC_PMID_LB_H_INFO);
+    UINT8_TO_STREAM(p, 0);
+  }
+
+#if (NXP_EXTNS == TRUE)
+  /** SEL_INFO will be updated irrespective of UICC/eSE is selected or not
+   *  This is required for P2P to work if UICC/ESE selected
+  **/
+  UINT8_TO_STREAM(p, NFC_PMID_LF_PROTOCOL);
+  UINT8_TO_STREAM(p, NCI_PARAM_LEN_LF_PROTOCOL);
+  if (tech_proto_mask & NFA_DM_DISC_MASK_LF_NFC_DEP) {
+    UINT8_TO_STREAM(p, NCI_LISTEN_PROTOCOL_NFC_DEP);
+  } else {
+    UINT8_TO_STREAM(p, 0x00);
+  }
+#endif
+
+/* for Listen F */
+#if (NXP_EXTNS == TRUE)
+  if (nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_F] ==
+      NFA_DM_DISC_HOST_ID_DH) {
+#endif
+    /* NFCC can support NFC-DEP and T3T listening based on NFCID routing
+     * regardless of NFC-F tech routing */
+    UINT8_TO_STREAM(p, NFC_PMID_LF_PROTOCOL);
+    UINT8_TO_STREAM(p, NCI_PARAM_LEN_LF_PROTOCOL);
+    if ((tech_proto_mask & NFA_DM_DISC_MASK_LF_NFC_DEP) &&
+        !nfa_dm_is_p2p_paused()) {
+      UINT8_TO_STREAM(p, NCI_LISTEN_PROTOCOL_NFC_DEP);
+    } else {
+      UINT8_TO_STREAM(p, 0x00);
+    }
+#if (NXP_EXTNS == TRUE)
+  } else {
+    /* If DH is not listening on T3T, let NFCC use UICC configuration by
+     * configuring with length = 0 */
+    if ((tech_proto_mask & NFA_DM_DISC_MASK_LF_T3T) == 0) {
+      UINT8_TO_STREAM(p, NFC_PMID_LF_PROTOCOL);
+      UINT8_TO_STREAM(p, 0);
+      UINT8_TO_STREAM(p, NFC_PMID_LF_T3T_FLAGS2);
+      UINT8_TO_STREAM(p, 0);
+    }
+  }
+#endif
+
+  if (p > params) {
+    nfa_dm_check_set_config((uint8_t)(p - params), params, false);
+  }
+
+  return NFA_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_set_total_duration
+**
+** Description      Update total duration to NFCC
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_set_total_duration(void) {
+  uint8_t params[10], *p;
+
+  NFA_TRACE_DEBUG0("nfa_dm_set_total_duration ()");
+
+  p = params;
+
+  /* for total duration */
+  UINT8_TO_STREAM(p, NFC_PMID_TOTAL_DURATION);
+  UINT8_TO_STREAM(p, NCI_PARAM_LEN_TOTAL_DURATION);
+  UINT16_TO_STREAM(p, nfa_dm_cb.disc_cb.disc_duration);
+
+  if (p > params) {
+    nfa_dm_check_set_config((uint8_t)(p - params), params, false);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_set_rf_listen_mode_raw_config
+**
+** Description      Set raw listen parameters
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_set_rf_listen_mode_raw_config(
+    tNFA_DM_DISC_TECH_PROTO_MASK* p_disc_mask) {
+  tNFA_DM_DISC_TECH_PROTO_MASK disc_mask = 0;
+  tNFA_LISTEN_CFG* p_cfg = &nfa_dm_cb.disc_cb.excl_listen_config;
+  uint8_t params[250], *p, xx;
+
+  NFA_TRACE_DEBUG0("nfa_dm_set_rf_listen_mode_raw_config ()");
+
+  /*
+  ** Discovery Configuration Parameters for Listen A
+  */
+  if ((nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_A] ==
+       NFA_DM_DISC_HOST_ID_DH) &&
+      (p_cfg->la_enable)) {
+    p = params;
+
+    UINT8_TO_STREAM(p, NFC_PMID_LA_BIT_FRAME_SDD);
+    UINT8_TO_STREAM(p, NCI_PARAM_LEN_LA_BIT_FRAME_SDD);
+    UINT8_TO_STREAM(p, p_cfg->la_bit_frame_sdd);
+
+    UINT8_TO_STREAM(p, NFC_PMID_LA_PLATFORM_CONFIG);
+    UINT8_TO_STREAM(p, NCI_PARAM_LEN_LA_PLATFORM_CONFIG);
+    UINT8_TO_STREAM(p, p_cfg->la_platform_config);
+
+    UINT8_TO_STREAM(p, NFC_PMID_LA_SEL_INFO);
+    UINT8_TO_STREAM(p, NCI_PARAM_LEN_LA_SEL_INFO);
+    UINT8_TO_STREAM(p, p_cfg->la_sel_info);
+
+    if (p_cfg->la_platform_config == NCI_PARAM_PLATFORM_T1T) {
+      disc_mask |= NFA_DM_DISC_MASK_LA_T1T;
+    } else {
+      /* If T4T or NFCDEP */
+      if (p_cfg->la_sel_info & NCI_PARAM_SEL_INFO_ISODEP) {
+        disc_mask |= NFA_DM_DISC_MASK_LA_ISO_DEP;
+      }
+
+      if (p_cfg->la_sel_info & NCI_PARAM_SEL_INFO_NFCDEP) {
+        disc_mask |= NFA_DM_DISC_MASK_LA_NFC_DEP;
+      }
+
+      /* If neither, T4T nor NFCDEP, then its T2T */
+      if (disc_mask == 0) {
+        disc_mask |= NFA_DM_DISC_MASK_LA_T2T;
+      }
+    }
+
+    UINT8_TO_STREAM(p, NFC_PMID_LA_NFCID1);
+    UINT8_TO_STREAM(p, p_cfg->la_nfcid1_len);
+    ARRAY_TO_STREAM(p, p_cfg->la_nfcid1, p_cfg->la_nfcid1_len);
+
+    nfa_dm_check_set_config((uint8_t)(p - params), params, false);
+  }
+
+  /*
+  ** Discovery Configuration Parameters for Listen B
+  */
+  if ((nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_B] ==
+       NFA_DM_DISC_HOST_ID_DH) &&
+      (p_cfg->lb_enable)) {
+    p = params;
+
+    UINT8_TO_STREAM(p, NFC_PMID_LB_SENSB_INFO);
+    UINT8_TO_STREAM(p, NCI_PARAM_LEN_LB_SENSB_INFO);
+    UINT8_TO_STREAM(p, p_cfg->lb_sensb_info);
+
+    UINT8_TO_STREAM(p, NFC_PMID_LB_NFCID0);
+    UINT8_TO_STREAM(p, p_cfg->lb_nfcid0_len);
+    ARRAY_TO_STREAM(p, p_cfg->lb_nfcid0, p_cfg->lb_nfcid0_len);
+
+    UINT8_TO_STREAM(p, NFC_PMID_LB_APPDATA);
+    UINT8_TO_STREAM(p, NCI_PARAM_LEN_LB_APPDATA);
+    ARRAY_TO_STREAM(p, p_cfg->lb_app_data, NCI_PARAM_LEN_LB_APPDATA);
+
+    UINT8_TO_STREAM(p, NFC_PMID_LB_SFGI);
+    UINT8_TO_STREAM(p, 1);
+    UINT8_TO_STREAM(p, p_cfg->lb_adc_fo);
+
+    UINT8_TO_STREAM(p, NFC_PMID_LB_ADC_FO);
+    UINT8_TO_STREAM(p, NCI_PARAM_LEN_LB_ADC_FO);
+    UINT8_TO_STREAM(p, p_cfg->lb_adc_fo);
+
+    nfa_dm_check_set_config((uint8_t)(p - params), params, false);
+
+    if (p_cfg->lb_sensb_info & NCI_LISTEN_PROTOCOL_ISO_DEP) {
+      disc_mask |= NFA_DM_DISC_MASK_LB_ISO_DEP;
+    }
+  }
+
+  /*
+  ** Discovery Configuration Parameters for Listen F
+  */
+  if ((nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_F] ==
+       NFA_DM_DISC_HOST_ID_DH) &&
+      (p_cfg->lf_enable)) {
+    p = params;
+
+    UINT8_TO_STREAM(p, NFC_PMID_LF_CON_BITR_F);
+    UINT8_TO_STREAM(p, 1);
+    UINT8_TO_STREAM(p, p_cfg->lf_con_bitr_f);
+
+    UINT8_TO_STREAM(p, NFC_PMID_LF_PROTOCOL);
+    UINT8_TO_STREAM(p, NCI_PARAM_LEN_LF_PROTOCOL);
+    UINT8_TO_STREAM(p, p_cfg->lf_protocol_type);
+
+    UINT8_TO_STREAM(p, NFC_PMID_LF_T3T_FLAGS2);
+    UINT8_TO_STREAM(p, NCI_PARAM_LEN_LF_T3T_FLAGS2);
+    UINT16_TO_STREAM(p, p_cfg->lf_t3t_flags);
+
+    /* if the bit at position X is set to 0, SC/NFCID2 with index X shall be
+     * ignored */
+    for (xx = 0; xx < NFA_LF_MAX_SC_NFCID2; xx++) {
+      if ((p_cfg->lf_t3t_flags & (0x0001 << xx)) != 0x0000) {
+        UINT8_TO_STREAM(p, NFC_PMID_LF_T3T_ID1 + xx);
+        UINT8_TO_STREAM(p, NCI_SYSTEMCODE_LEN + NCI_NFCID2_LEN);
+        ARRAY_TO_STREAM(p, p_cfg->lf_t3t_identifier[xx],
+                        NCI_SYSTEMCODE_LEN + NCI_NFCID2_LEN);
+      }
+    }
+
+#if (NXP_EXTNS != TRUE)
+    UINT8_TO_STREAM(p, NFC_PMID_LF_T3T_PMM);
+    UINT8_TO_STREAM(p, NCI_PARAM_LEN_LF_T3T_PMM);
+    ARRAY_TO_STREAM(p, p_cfg->lf_t3t_pmm, NCI_PARAM_LEN_LF_T3T_PMM);
+#endif
+
+    nfa_dm_check_set_config((uint8_t)(p - params), params, false);
+
+    if (p_cfg->lf_t3t_flags != NCI_LF_T3T_FLAGS2_ALL_DISABLED) {
+      disc_mask |= NFA_DM_DISC_MASK_LF_T3T;
+    }
+    if (p_cfg->lf_protocol_type & NCI_LISTEN_PROTOCOL_NFC_DEP) {
+      disc_mask |= NFA_DM_DISC_MASK_LF_NFC_DEP;
+    }
+  }
+
+  /*
+  ** Discovery Configuration Parameters for Listen ISO-DEP
+  */
+  if ((disc_mask &
+       (NFA_DM_DISC_MASK_LA_ISO_DEP | NFA_DM_DISC_MASK_LB_ISO_DEP)) &&
+      (p_cfg->li_enable)) {
+    p = params;
+
+    UINT8_TO_STREAM(p, NFC_PMID_FWI);
+    UINT8_TO_STREAM(p, NCI_PARAM_LEN_FWI);
+    UINT8_TO_STREAM(p, p_cfg->li_fwi);
+
+    if (disc_mask & NFA_DM_DISC_MASK_LA_ISO_DEP) {
+      UINT8_TO_STREAM(p, NFC_PMID_LA_HIST_BY);
+      UINT8_TO_STREAM(p, p_cfg->la_hist_bytes_len);
+      ARRAY_TO_STREAM(p, p_cfg->la_hist_bytes, p_cfg->la_hist_bytes_len);
+    }
+
+    if (disc_mask & NFA_DM_DISC_MASK_LB_ISO_DEP) {
+      UINT8_TO_STREAM(p, NFC_PMID_LB_H_INFO);
+      UINT8_TO_STREAM(p, p_cfg->lb_h_info_resp_len);
+      ARRAY_TO_STREAM(p, p_cfg->lb_h_info_resp, p_cfg->lb_h_info_resp_len);
+    }
+
+    nfa_dm_check_set_config((uint8_t)(p - params), params, false);
+  }
+
+  /*
+  ** Discovery Configuration Parameters for Listen NFC-DEP
+  */
+  if ((disc_mask &
+       (NFA_DM_DISC_MASK_LA_NFC_DEP | NFA_DM_DISC_MASK_LF_NFC_DEP)) &&
+      (p_cfg->ln_enable)) {
+    p = params;
+
+    UINT8_TO_STREAM(p, NFC_PMID_WT);
+    UINT8_TO_STREAM(p, NCI_PARAM_LEN_WT);
+    UINT8_TO_STREAM(p, p_cfg->ln_wt);
+
+    UINT8_TO_STREAM(p, NFC_PMID_ATR_RES_GEN_BYTES);
+    UINT8_TO_STREAM(p, p_cfg->ln_atr_res_gen_bytes_len);
+    ARRAY_TO_STREAM(p, p_cfg->ln_atr_res_gen_bytes,
+                    p_cfg->ln_atr_res_gen_bytes_len);
+
+    UINT8_TO_STREAM(p, NFC_PMID_ATR_RSP_CONFIG);
+    UINT8_TO_STREAM(p, 1);
+    UINT8_TO_STREAM(p, p_cfg->ln_atr_res_config);
+
+    nfa_dm_check_set_config((uint8_t)(p - params), params, false);
+  }
+
+  *p_disc_mask = disc_mask;
+
+  NFA_TRACE_DEBUG1("nfa_dm_set_rf_listen_mode_raw_config () disc_mask = 0x%x",
+                   disc_mask);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_get_disc_mask
+**
+** Description      Convert RF technology, mode and protocol to bit mask
+**
+** Returns          tNFA_DM_DISC_TECH_PROTO_MASK
+**
+*******************************************************************************/
+static tNFA_DM_DISC_TECH_PROTO_MASK nfa_dm_disc_get_disc_mask(
+    tNFC_RF_TECH_N_MODE tech_n_mode, tNFC_PROTOCOL protocol) {
+  /* Set initial disc_mask to legacy poll or listen */
+  tNFA_DM_DISC_TECH_PROTO_MASK disc_mask =
+      ((tech_n_mode & 0x80) ? NFA_DM_DISC_MASK_L_LEGACY
+                            : NFA_DM_DISC_MASK_P_LEGACY);
+
+  if (NFC_DISCOVERY_TYPE_POLL_A == tech_n_mode) {
+    switch (protocol) {
+      case NFC_PROTOCOL_T1T:
+        disc_mask = NFA_DM_DISC_MASK_PA_T1T;
+        break;
+      case NFC_PROTOCOL_T2T:
+        disc_mask = NFA_DM_DISC_MASK_PA_T2T;
+        break;
+      case NFC_PROTOCOL_ISO_DEP:
+        disc_mask = NFA_DM_DISC_MASK_PA_ISO_DEP;
+        break;
+      case NFC_PROTOCOL_NFC_DEP:
+        disc_mask = NFA_DM_DISC_MASK_PA_NFC_DEP;
+        break;
+    }
+  } else if (NFC_DISCOVERY_TYPE_POLL_B == tech_n_mode) {
+    if (protocol == NFC_PROTOCOL_ISO_DEP)
+      disc_mask = NFA_DM_DISC_MASK_PB_ISO_DEP;
+#if (NXP_EXTNS == TRUE)
+    else if (protocol == NFC_PROTOCOL_T3BT)
+      disc_mask = NFA_DM_DISC_MASK_PB_T3BT;
+#endif
+  } else if (NFC_DISCOVERY_TYPE_POLL_F == tech_n_mode) {
+    if (protocol == NFC_PROTOCOL_T3T)
+      disc_mask = NFA_DM_DISC_MASK_PF_T3T;
+    else if (protocol == NFC_PROTOCOL_NFC_DEP)
+      disc_mask = NFA_DM_DISC_MASK_PF_NFC_DEP;
+  } else if (NFC_DISCOVERY_TYPE_POLL_ISO15693 == tech_n_mode) {
+    disc_mask = NFA_DM_DISC_MASK_P_ISO15693;
+  } else if (NFC_DISCOVERY_TYPE_POLL_B_PRIME == tech_n_mode) {
+    disc_mask = NFA_DM_DISC_MASK_P_B_PRIME;
+  } else if (NFC_DISCOVERY_TYPE_POLL_KOVIO == tech_n_mode) {
+    disc_mask = NFA_DM_DISC_MASK_P_KOVIO;
+  } else if (NFC_DISCOVERY_TYPE_POLL_A_ACTIVE == tech_n_mode) {
+    disc_mask = NFA_DM_DISC_MASK_PAA_NFC_DEP;
+  } else if (NFC_DISCOVERY_TYPE_POLL_F_ACTIVE == tech_n_mode) {
+    disc_mask = NFA_DM_DISC_MASK_PFA_NFC_DEP;
+  } else if (NFC_DISCOVERY_TYPE_LISTEN_A == tech_n_mode) {
+    switch (protocol) {
+      case NFC_PROTOCOL_T1T:
+        disc_mask = NFA_DM_DISC_MASK_LA_T1T;
+        break;
+      case NFC_PROTOCOL_T2T:
+        disc_mask = NFA_DM_DISC_MASK_LA_T2T;
+        break;
+      case NFC_PROTOCOL_ISO_DEP:
+        disc_mask = NFA_DM_DISC_MASK_LA_ISO_DEP;
+        break;
+      case NFC_PROTOCOL_NFC_DEP:
+        disc_mask = NFA_DM_DISC_MASK_LA_NFC_DEP;
+        break;
+    }
+  } else if (NFC_DISCOVERY_TYPE_LISTEN_B == tech_n_mode) {
+    if (protocol == NFC_PROTOCOL_ISO_DEP)
+      disc_mask = NFA_DM_DISC_MASK_LB_ISO_DEP;
+  } else if (NFC_DISCOVERY_TYPE_LISTEN_F == tech_n_mode) {
+    if (protocol == NFC_PROTOCOL_T3T)
+      disc_mask = NFA_DM_DISC_MASK_LF_T3T;
+    else if (protocol == NFC_PROTOCOL_NFC_DEP)
+      disc_mask = NFA_DM_DISC_MASK_LF_NFC_DEP;
+  } else if (NFC_DISCOVERY_TYPE_LISTEN_ISO15693 == tech_n_mode) {
+    disc_mask = NFA_DM_DISC_MASK_L_ISO15693;
+  } else if (NFC_DISCOVERY_TYPE_LISTEN_B_PRIME == tech_n_mode) {
+    disc_mask = NFA_DM_DISC_MASK_L_B_PRIME;
+  } else if (NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE == tech_n_mode) {
+    disc_mask = NFA_DM_DISC_MASK_LAA_NFC_DEP;
+  } else if (NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE == tech_n_mode) {
+    disc_mask = NFA_DM_DISC_MASK_LFA_NFC_DEP;
+  }
+
+  NFA_TRACE_DEBUG3(
+      "nfa_dm_disc_get_disc_mask (): tech_n_mode:0x%X, protocol:0x%X, "
+      "disc_mask:0x%X",
+      tech_n_mode, protocol, disc_mask);
+  return (disc_mask);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_discovery_cback
+**
+** Description      Discovery callback event from NFC
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_disc_discovery_cback(tNFC_DISCOVER_EVT event,
+                                        tNFC_DISCOVER* p_data) {
+  tNFA_DM_RF_DISC_SM_EVENT dm_disc_event = NFA_DM_DISC_SM_MAX_EVENT;
+
+  NFA_TRACE_DEBUG1("nfa_dm_disc_discovery_cback (): event:0x%X", event);
+
+  switch (event) {
+    case NFC_START_DEVT:
+      dm_disc_event = NFA_DM_RF_DISCOVER_RSP;
+      break;
+    case NFC_RESULT_DEVT:
+      dm_disc_event = NFA_DM_RF_DISCOVER_NTF;
+      break;
+    case NFC_SELECT_DEVT:
+      dm_disc_event = NFA_DM_RF_DISCOVER_SELECT_RSP;
+      break;
+    case NFC_ACTIVATE_DEVT:
+      dm_disc_event = NFA_DM_RF_INTF_ACTIVATED_NTF;
+      break;
+    case NFC_DEACTIVATE_DEVT:
+      if (p_data->deactivate.is_ntf) {
+        dm_disc_event = NFA_DM_RF_DEACTIVATE_NTF;
+        if ((p_data->deactivate.type == NFC_DEACTIVATE_TYPE_IDLE) ||
+            (p_data->deactivate.type == NFC_DEACTIVATE_TYPE_DISCOVERY)) {
+          NFC_SetReassemblyFlag(true);
+          nfa_dm_cb.flags &= ~NFA_DM_FLAGS_RAW_FRAME;
+        }
+      } else
+        dm_disc_event = NFA_DM_RF_DEACTIVATE_RSP;
+      break;
+    default:
+      NFA_TRACE_ERROR0("Unexpected event");
+      return;
+  }
+
+  nfa_dm_disc_sm_execute(dm_disc_event, (tNFA_DM_RF_DISC_DATA*)p_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_notify_started
+**
+** Description      Report NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT or
+**                  NFA_RF_DISCOVERY_STARTED_EVT, if needed
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_disc_notify_started(tNFA_STATUS status) {
+  tNFA_CONN_EVT_DATA evt_data;
+
+  if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_NOTIFY) {
+    nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_NOTIFY;
+
+    evt_data.status = status;
+
+    if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use)
+      nfa_dm_conn_cback_event_notify(NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT,
+                                     &evt_data);
+    else
+      nfa_dm_conn_cback_event_notify(NFA_RF_DISCOVERY_STARTED_EVT, &evt_data);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_conn_event_notify
+**
+** Description      Notify application of CONN_CBACK event, using appropriate
+**                  callback
+**
+** Returns          nothing
+**
+*******************************************************************************/
+void nfa_dm_disc_conn_event_notify(uint8_t event, tNFA_STATUS status) {
+  tNFA_CONN_EVT_DATA evt_data;
+
+  if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_NOTIFY) {
+    nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_NOTIFY;
+    evt_data.status = status;
+
+    if (nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE) {
+      /* Use exclusive RF mode callback */
+      if (nfa_dm_cb.p_excl_conn_cback)
+        (*nfa_dm_cb.p_excl_conn_cback)(event, &evt_data);
+    } else {
+      (*nfa_dm_cb.p_conn_cback)(event, &evt_data);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_force_to_idle
+**
+** Description      Force NFCC to idle state while waiting for deactivation NTF
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+static tNFC_STATUS nfa_dm_disc_force_to_idle(void) {
+  tNFC_STATUS status = NFC_STATUS_SEMANTIC_ERROR;
+
+  NFA_TRACE_DEBUG1("nfa_dm_disc_force_to_idle() disc_flags = 0x%x",
+                   nfa_dm_cb.disc_cb.disc_flags);
+
+  /* do not execute more than one */
+  if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF) {
+    nfa_dm_cb.disc_cb.disc_flags &= ~(NFA_DM_DISC_FLAGS_W4_NTF);
+    nfa_dm_cb.disc_cb.disc_flags |= (NFA_DM_DISC_FLAGS_W4_RSP);
+    nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
+    status = NFC_Deactivate(NFC_DEACTIVATE_TYPE_IDLE);
+  }
+
+  return (status);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_deact_ntf_timeout_cback
+**
+** Description      Timeout while waiting for deactivation NTF
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_disc_deact_ntf_timeout_cback(TIMER_LIST_ENT* p_tle) {
+    (void)p_tle;
+
+    NFA_TRACE_ERROR0("nfa_dm_disc_deact_ntf_timeout_cback()");
+    if (nfcFL.nfcNxpEse && nfcFL.eseFL._ESE_ETSI_READER_ENABLE &&
+            (nfc_cb.num_disc_maps == 1)) {
+        NFC_TRACE_ERROR0("reset Nfc..!!");
+        etsi_reader_in_progress = true;
+        nfc_ncif_cmd_timeout();
+
+    } else {
+        nfa_dm_disc_force_to_idle();
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_send_deactivate_cmd
+**
+** Description      Send deactivate command to NFCC, if needed.
+**
+** Returns          NFC_STATUS_OK             - deactivate cmd is sent
+**                  NCI_STATUS_FAILED         - no buffers
+**                  NFC_STATUS_SEMANTIC_ERROR - this function does not attempt
+**                                              to send deactivate cmd
+**
+*******************************************************************************/
+static tNFC_STATUS nfa_dm_send_deactivate_cmd(tNFC_DEACT_TYPE deactivate_type) {
+  tNFC_STATUS status = NFC_STATUS_SEMANTIC_ERROR;
+  tNFA_DM_DISC_FLAGS w4_flags =
+      nfa_dm_cb.disc_cb.disc_flags &
+      (NFA_DM_DISC_FLAGS_W4_RSP | NFA_DM_DISC_FLAGS_W4_NTF);
+#if (NXP_EXTNS == TRUE)
+  unsigned long num = 0;
+#endif
+
+  if (!w4_flags) {
+    /* if deactivate CMD was not sent to NFCC */
+    nfa_dm_cb.disc_cb.disc_flags |=
+        (NFA_DM_DISC_FLAGS_W4_RSP | NFA_DM_DISC_FLAGS_W4_NTF);
+
+    status = NFC_Deactivate(deactivate_type);
+
+    if (!nfa_dm_cb.disc_cb.tle.in_use) {
+      nfa_dm_cb.disc_cb.tle.p_cback =
+          (TIMER_CBACK*)nfa_dm_disc_deact_ntf_timeout_cback;
+#if (NXP_EXTNS == TRUE)
+      num = NFA_DM_DISC_TIMEOUT_W4_DEACT_NTF;
+      NFA_TRACE_DEBUG1("num_disc_maps=%d", nfc_cb.num_disc_maps);
+      if (nfc_cb.num_disc_maps == 1) {
+        NFA_TRACE_DEBUG1(
+            "Reading NAME_NFA_DM_DISC_NTF_TIMEOUT val   "
+            "nfc_cb.num_disc_maps = %d",
+            nfc_cb.num_disc_maps);
+        if (GetNumValue(NAME_NFA_DM_DISC_NTF_TIMEOUT, &num, sizeof(num))) {
+          num *= 1000;
+        } else {
+          num = NFA_DM_DISC_TIMEOUT_W4_DEACT_NTF;
+          NFA_TRACE_DEBUG1("Overriding NFA_DM_DISC_NTF_TIMEOUT to use %d", num);
+        }
+      }
+      NFA_TRACE_DEBUG1("Starting timer value %d", num);
+      /*wait infinite time for deactivate NTF, if the timeout is configured to
+       * 0*/
+      if (num != 0) nfa_sys_start_timer(&nfa_dm_cb.disc_cb.tle, 0, num);
+#else
+      nfa_sys_start_timer(&nfa_dm_cb.disc_cb.tle, 0,
+                          NFA_DM_DISC_TIMEOUT_W4_DEACT_NTF);
+#endif
+    }
+  } else {
+    if (deactivate_type == NFC_DEACTIVATE_TYPE_SLEEP) {
+      status = NFC_STATUS_SEMANTIC_ERROR;
+    } else if (nfa_dm_cb.disc_cb.tle.in_use) {
+      status = NFC_STATUS_OK;
+    } else {
+      status = nfa_dm_disc_force_to_idle();
+    }
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_start_rf_discover
+**
+** Description      Start RF discovery
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_start_rf_discover(void) {
+  tNFC_DISCOVER_PARAMS disc_params[NFA_DM_MAX_DISC_PARAMS];
+  tNFA_DM_DISC_TECH_PROTO_MASK dm_disc_mask = 0x00, poll_mask = 0x00,
+                               listen_mask = 0x00;
+  uint8_t config_params[10], *p;
+  uint8_t num_params, xx;
+  uint8_t tech_list = 0x00;
+  unsigned long fwdEnable = 0x00;
+  unsigned long hostListenMask = 0x00;
+  unsigned long uiccListenMask = 0x00;
+  unsigned long eseListenMask  = 0x00;
+  unsigned long p2pListenMask = 0x00;
+
+  NFA_TRACE_DEBUG0("nfa_dm_start_rf_discover (): enter");
+  /* Make sure that RF discovery was enabled, or some app has exclusive control
+   */
+  if ((!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_ENABLED)) &&
+      (nfa_dm_cb.disc_cb.excl_disc_entry.in_use == false)) {
+    NFA_TRACE_DEBUG0("nfa_dm_start_rf_discover (): return");
+    return;
+  }
+
+  /* get listen mode routing table for technology */
+  nfa_ee_get_tech_route(NFA_EE_PWR_STATE_ON, nfa_dm_cb.disc_cb.listen_RT);
+
+  if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use) {
+    nfa_dm_set_rf_listen_mode_raw_config(&dm_disc_mask);
+    dm_disc_mask |= (nfa_dm_cb.disc_cb.excl_disc_entry.requested_disc_mask &
+                     NFA_DM_DISC_MASK_POLL);
+    nfa_dm_cb.disc_cb.excl_disc_entry.selected_disc_mask = dm_disc_mask;
+  } else {
+    /* Collect RF discovery request from sub-modules */
+    for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++) {
+      if (nfa_dm_cb.disc_cb.entry[xx].in_use) {
+        NFA_TRACE_DEBUG2("requested_disc_mask = 0x%x, xx=%d",
+                         nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask, xx);
+        poll_mask = (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
+                     NFA_DM_DISC_MASK_POLL);
+
+        /* clear poll mode technologies and protocols which are already used by
+         * others */
+        poll_mask &= ~(dm_disc_mask & NFA_DM_DISC_MASK_POLL);
+        /* reset listen mask before updating it for every discovery callback
+         * entry */
+        listen_mask = 0;
+        /*
+         ** add listen mode technologies and protocols if host ID is
+         ** matched to listen mode routing table
+         */
+        NFA_TRACE_DEBUG2("poll_mask=0x%X listen_mask=0x%X", poll_mask,
+                         listen_mask);
+        /* NFC-A */
+        if (nfa_dm_cb.disc_cb.entry[xx].host_id ==
+            nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_A]) {
+          listen_mask |=
+              nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
+              (NFA_DM_DISC_MASK_LA_T1T | NFA_DM_DISC_MASK_LA_T2T |
+               NFA_DM_DISC_MASK_LA_ISO_DEP | NFA_DM_DISC_MASK_LA_NFC_DEP |
+               NFA_DM_DISC_MASK_LAA_NFC_DEP);
+        } else {
+          /* host can listen ISO-DEP based on AID routing */
+          listen_mask |= (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
+                          NFA_DM_DISC_MASK_LA_ISO_DEP);
+
+          /* host can listen NFC-DEP based on protocol routing */
+          listen_mask |= (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
+                          NFA_DM_DISC_MASK_LA_NFC_DEP);
+          listen_mask |= (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
+                          NFA_DM_DISC_MASK_LAA_NFC_DEP);
+        }
+        NFA_TRACE_DEBUG1("listen_mask value after NFC-A = 0x%x", listen_mask);
+
+        /* NFC-B */
+        /* multiple hosts can listen ISO-DEP based on AID routing */
+        listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
+                       NFA_DM_DISC_MASK_LB_ISO_DEP;
+        NFA_TRACE_DEBUG1("listen_mask value after NFC-B = 0x%x", listen_mask);
+
+        /* NFC-F */
+        listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
+                       (NFA_DM_DISC_MASK_LF_T3T | NFA_DM_DISC_MASK_LF_NFC_DEP |
+                        NFA_DM_DISC_MASK_LFA_NFC_DEP);
+        NFA_TRACE_DEBUG1("listen_mask value after NFC-F = 0x%x", listen_mask);
+
+        /* NFC-B Prime */
+        if (nfa_dm_cb.disc_cb.entry[xx].host_id ==
+            nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_BP]) {
+          listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
+                         NFA_DM_DISC_MASK_L_B_PRIME;
+        }
+        NFA_TRACE_DEBUG1("listen_mask value after NFC-B Prime = 0x%x",
+                         listen_mask);
+        /*
+        ** clear listen mode technolgies and protocols which are already
+        ** used by others
+        */
+
+        /* Check if other modules are listening T1T or T2T */
+        NFA_TRACE_DEBUG1("dm_disc_mask = 0x%x", dm_disc_mask);
+        if (dm_disc_mask &
+            (NFA_DM_DISC_MASK_LA_T1T | NFA_DM_DISC_MASK_LA_T2T)) {
+          listen_mask &=
+              ~(NFA_DM_DISC_MASK_LA_T1T | NFA_DM_DISC_MASK_LA_T2T |
+                NFA_DM_DISC_MASK_LA_ISO_DEP | NFA_DM_DISC_MASK_LA_NFC_DEP);
+        }
+        NFA_TRACE_DEBUG1("listen_mask value after T1T and T2T = 0x%x",
+                         listen_mask);
+
+        /* T1T/T2T has priority on NFC-A */
+        if ((dm_disc_mask &
+             (NFA_DM_DISC_MASK_LA_ISO_DEP | NFA_DM_DISC_MASK_LA_NFC_DEP)) &&
+            (listen_mask &
+             (NFA_DM_DISC_MASK_LA_T1T | NFA_DM_DISC_MASK_LA_T2T))) {
+          dm_disc_mask &=
+              ~(NFA_DM_DISC_MASK_LA_ISO_DEP | NFA_DM_DISC_MASK_LA_NFC_DEP);
+        }
+
+        /* Don't remove ISO-DEP because multiple hosts can listen ISO-DEP based
+         * on AID routing */
+
+        /* Check if other modules are listening NFC-DEP */
+        if (dm_disc_mask &
+            (NFA_DM_DISC_MASK_LA_NFC_DEP | NFA_DM_DISC_MASK_LAA_NFC_DEP)) {
+          listen_mask &=
+              ~(NFA_DM_DISC_MASK_LA_NFC_DEP | NFA_DM_DISC_MASK_LAA_NFC_DEP);
+        }
+
+        NFA_TRACE_DEBUG1("listen_mask value after NFC-DEP = 0x%x", listen_mask);
+
+        nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask =
+            poll_mask | listen_mask;
+
+        NFA_TRACE_DEBUG2(
+            "nfa_dm_cb.disc_cb.entry[%d].selected_disc_mask = 0x%x", xx,
+            nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask);
+
+        dm_disc_mask |= nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask;
+
+        NFA_TRACE_DEBUG2("selected dm_disc_mask 0x%X for entry[%d]",
+                         dm_disc_mask, xx);
+      }
+    }
+    NFA_TRACE_DEBUG1("dm_disc_mask calculated finally for discovery: 0x%X",
+                     dm_disc_mask);
+
+#if (NXP_EXTNS == TRUE)
+    if ((GetNumValue(NAME_NXP_FWD_FUNCTIONALITY_ENABLE, &fwdEnable,
+                     sizeof(fwdEnable))) == false) {
+      fwdEnable = 0x01;  // default value
+      NFA_TRACE_DEBUG2("%s:NXP_FWD_FUNCTIONALITY_ENABLE=0x0%X;", __func__,
+                       fwdEnable);
+    }
+    if (GetNumValue(NAME_HOST_LISTEN_TECH_MASK, &hostListenMask,
+                    sizeof(hostListenMask))) {
+      NFA_TRACE_DEBUG2("%s:HOST_LISTEN_TECH_MASK = 0x0%X;", __func__,
+                       hostListenMask);
+    }
+    if (GetNumValue(NAME_UICC_LISTEN_TECH_MASK, &uiccListenMask,
+                    sizeof(uiccListenMask))) {
+      NFA_TRACE_DEBUG2("%s:UICC_LISTEN_TECH_MASK = 0x0%X;", __func__,
+                       uiccListenMask);
+    }
+    if (GetNumValue(NAME_NXP_ESE_LISTEN_TECH_MASK, &eseListenMask,
+                    sizeof(eseListenMask))) {
+      NFA_TRACE_DEBUG2("%s:NXP_ESE_LISTEN_TECH_MASK = 0x0%X;", __func__,
+                       eseListenMask);
+    }
+    if (GetNumValue(NAME_P2P_LISTEN_TECH_MASK, &p2pListenMask,
+                    sizeof(p2pListenMask))) {
+      NFA_TRACE_DEBUG2("%s:P2P_LISTEN_TECH_MASK = 0x0%X;", __func__,
+                       p2pListenMask);
+    }
+
+    tech_list = nfa_ee_get_supported_tech_list(nfa_dm_cb.selected_uicc_id);
+
+    if ((fwdEnable == 0x00) || (hostListenMask == 0x00)) {
+      if (tech_list == NFA_TECHNOLOGY_MASK_B) {
+        NFA_TRACE_DEBUG0(
+            "TypeB only sim handling in case of no FWD functionality");
+        dm_disc_mask &=
+            ~(NFA_DM_DISC_MASK_LA_ISO_DEP | NFA_DM_DISC_MASK_LA_NFC_DEP);
+      } else if (tech_list == NFA_TECHNOLOGY_MASK_A) {
+        NFA_TRACE_DEBUG0(
+            "TypeA only sim handling in case of no FWD functionality");
+        dm_disc_mask &= ~(NFA_DM_DISC_MASK_LB_ISO_DEP);
+      }
+    }
+#endif
+
+    /* Let P2P set GEN bytes for LLCP to NFCC */
+    if (dm_disc_mask & NFA_DM_DISC_MASK_NFC_DEP) {
+      nfa_p2p_set_config(dm_disc_mask);
+    }
+
+    if (dm_disc_mask &
+        (NFA_DM_DISC_MASK_PF_NFC_DEP | NFA_DM_DISC_MASK_PF_T3T)) {
+      /* According to the NFC Forum Activity spec, controllers must:
+       * 1) Poll with RC=0 and SC=FFFF to find NFC-DEP targets
+       * 2) Poll with RC=1 and SC=FFFF to find T3T targets
+       * Many controllers don't do this yet, and seem to be activating
+       * NFC-DEP by default.
+       *
+       * We can at least fix the scenario where we're not interested
+       * in NFC-DEP, by setting RC=1 in that case. Otherwise, keep
+       * the default of RC=0. */
+      p = config_params;
+      UINT8_TO_STREAM(p, NFC_PMID_PF_RC);
+      UINT8_TO_STREAM(p, NCI_PARAM_LEN_PF_RC);
+      if ((dm_disc_mask & NFA_DM_DISC_MASK_PF_NFC_DEP) &&
+          !nfa_dm_is_p2p_paused()) {
+        UINT8_TO_STREAM(p, 0x00);  // RC=0
+      } else {
+        UINT8_TO_STREAM(p, 0x01);  // RC=1
+      }
+      nfa_dm_check_set_config(p - config_params, config_params, false);
+    }
+  }
+#if (NXP_EXTNS == TRUE)
+  NFA_TRACE_DEBUG1("dm_disc_mask before masking = 0x%x", dm_disc_mask);
+  if (((hostListenMask & 0x1) == 0x0) && ((uiccListenMask & 0x1) == 0x0) && ((eseListenMask & 0x1) == 0x0)) {
+    NFA_TRACE_DEBUG0(
+        "nfa_dm_start_rf_discover (): try removing A passive listen for "
+        "ISO-DEP");
+    dm_disc_mask &= ~(NFA_DM_DISC_MASK_LA_ISO_DEP);
+  }
+  if (((hostListenMask & 0x2) == 0x0) && ((uiccListenMask & 0x2) == 0x0) && ((eseListenMask & 0x2) == 0x0)) {
+    NFA_TRACE_DEBUG0(
+        "nfa_dm_start_rf_discover (): try removing B passive listen for "
+        "ISO-DEP");
+    dm_disc_mask &= ~(NFA_DM_DISC_MASK_LB_ISO_DEP);
+  }
+  if (((hostListenMask & 0x4) == 0x0) && ((uiccListenMask & 0x4) == 0x0) && ((eseListenMask & 0x4) == 0x0)) {
+    NFA_TRACE_DEBUG0(
+        "nfa_dm_start_rf_discover (): try removing F passive listen for T3T");
+    dm_disc_mask &= ~(NFA_DM_DISC_MASK_LF_T3T);
+  }
+  if ((p2pListenMask & 0x84) == 0x0) {
+    NFA_TRACE_DEBUG0(
+        "nfa_dm_start_rf_discover (): try removing F passive listen for "
+        "NFC-DEP");
+    dm_disc_mask &= ~(NFA_DM_DISC_MASK_LF_NFC_DEP);
+    dm_disc_mask &= ~(NFA_DM_DISC_MASK_LFA_NFC_DEP);
+  }
+  NFA_TRACE_DEBUG1("dm_disc_mask after masking = 0x%x", dm_disc_mask);
+#endif
+
+  /* Get Discovery Technology parameters */
+  num_params = nfa_dm_get_rf_discover_config(dm_disc_mask, disc_params,
+                                             NFA_DM_MAX_DISC_PARAMS);
+
+  if (num_params) {
+/*
+** NFCC will abort programming personality slots if not available.
+** NFCC programs the personality slots in the following order of RF
+** technologies: NFC-A, NFC-B, NFC-BP, NFC-I93
+*/
+#if (NXP_EXTNS == TRUE)
+    nfa_dm_set_listen_mode_set_configs(dm_disc_mask);
+#else
+    /* if this is not for exclusive control */
+    if (!nfa_dm_cb.disc_cb.excl_disc_entry.in_use) {
+      /* update listening protocols in each NFC technology */
+      nfa_dm_set_rf_listen_mode_config(dm_disc_mask);
+    }
+#endif
+    /* Set polling duty cycle */
+    nfa_dm_set_total_duration();
+    nfa_dm_cb.disc_cb.dm_disc_mask = dm_disc_mask;
+
+    NFC_DiscoveryStart(num_params, disc_params, nfa_dm_disc_discovery_cback);
+    /* set flag about waiting for response in IDLE state */
+    nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
+
+    /* register callback to get interface error NTF */
+    NFC_SetStaticRfCback(nfa_dm_disc_data_cback);
+  } else {
+    /* RF discovery is started but there is no valid technology or protocol to
+     * discover */
+    nfa_dm_disc_notify_started(NFA_STATUS_OK);
+  }
+
+  /* if Kovio presence check timer is running, timeout callback will reset the
+   * activation information */
+  if ((nfa_dm_cb.disc_cb.activated_protocol != NFC_PROTOCOL_KOVIO) ||
+      (!nfa_dm_cb.disc_cb.kovio_tle.in_use)) {
+    /* reset protocol and hanlde of activated sub-module */
+    nfa_dm_cb.disc_cb.activated_protocol = NFA_PROTOCOL_INVALID;
+    nfa_dm_cb.disc_cb.activated_handle = NFA_HANDLE_INVALID;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_notify_discovery
+**
+** Description      Send RF discovery notification to upper layer
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_notify_discovery(tNFA_DM_RF_DISC_DATA* p_data) {
+  tNFA_CONN_EVT_DATA conn_evt;
+
+  /* let application select a device */
+  conn_evt.disc_result.status = NFA_STATUS_OK;
+  memcpy(&(conn_evt.disc_result.discovery_ntf), &(p_data->nfc_discover.result),
+         sizeof(tNFC_RESULT_DEVT));
+
+  nfa_dm_conn_cback_event_notify(NFA_DISC_RESULT_EVT, &conn_evt);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_handle_kovio_activation
+**
+** Description      Handle Kovio activation; whether it's new or repeated
+**                  activation
+**
+** Returns          true if repeated activation. No need to notify activated
+**                  event to upper layer
+**
+*******************************************************************************/
+bool nfa_dm_disc_handle_kovio_activation(tNFC_DISCOVER* p_data,
+                                         tNFA_DISCOVER_CBACK* p_disc_cback) {
+  tNFC_DISCOVER disc_data;
+
+  if (nfa_dm_cb.disc_cb.kovio_tle.in_use) {
+    /* if this is new Kovio bar code tag */
+    if ((nfa_dm_cb.activated_nfcid_len !=
+         p_data->activate.rf_tech_param.param.pk.uid_len) ||
+        (memcmp(p_data->activate.rf_tech_param.param.pk.uid,
+                nfa_dm_cb.activated_nfcid, nfa_dm_cb.activated_nfcid_len))) {
+      NFA_TRACE_DEBUG0("new Kovio tag is detected");
+
+      /* notify presence check failure for previous tag, if presence check is
+       * pending */
+      nfa_dm_disc_report_kovio_presence_check(NFA_STATUS_FAILED);
+
+      /* notify deactivation of previous activation before notifying new
+       * activation */
+      if (p_disc_cback) {
+        disc_data.deactivate.type = NFA_DEACTIVATE_TYPE_IDLE;
+        (*(p_disc_cback))(NFA_DM_RF_DISC_DEACTIVATED_EVT, &disc_data);
+      }
+
+      /* restart timer */
+      nfa_sys_start_timer(&nfa_dm_cb.disc_cb.kovio_tle, 0,
+                          NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
+    } else {
+      /* notify presence check ok, if presence check is pending */
+      nfa_dm_disc_report_kovio_presence_check(NFC_STATUS_OK);
+
+      /* restart timer and do not notify upper layer */
+      nfa_sys_start_timer(&nfa_dm_cb.disc_cb.kovio_tle, 0,
+                          NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
+      return (true);
+    }
+  } else {
+    /* this is the first activation, so start timer and notify upper layer */
+    nfa_dm_cb.disc_cb.kovio_tle.p_cback =
+        (TIMER_CBACK*)nfa_dm_disc_kovio_timeout_cback;
+    nfa_sys_start_timer(&nfa_dm_cb.disc_cb.kovio_tle, 0,
+                        NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
+  }
+
+  return (false);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_notify_activation
+**
+** Description      Send RF activation notification to sub-module
+**
+** Returns          NFA_STATUS_OK if success
+**
+*******************************************************************************/
+static tNFA_STATUS nfa_dm_disc_notify_activation(tNFC_DISCOVER* p_data) {
+  uint8_t xx, host_id_in_LRT;
+  uint8_t iso_dep_t3t__listen = NFA_DM_DISC_NUM_ENTRIES;
+
+  tNFC_RF_TECH_N_MODE tech_n_mode = p_data->activate.rf_tech_param.mode;
+  tNFC_PROTOCOL protocol = p_data->activate.protocol;
+
+  tNFA_DM_DISC_TECH_PROTO_MASK activated_disc_mask;
+
+  NFA_TRACE_DEBUG2(
+      "nfa_dm_disc_notify_activation (): tech_n_mode:0x%X, proto:0x%X",
+      tech_n_mode, protocol);
+
+  if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use) {
+    nfa_dm_cb.disc_cb.activated_tech_mode = tech_n_mode;
+    nfa_dm_cb.disc_cb.activated_rf_disc_id = p_data->activate.rf_disc_id;
+    nfa_dm_cb.disc_cb.activated_rf_interface = p_data->activate.intf_param.type;
+    nfa_dm_cb.disc_cb.activated_protocol = protocol;
+    nfa_dm_cb.disc_cb.activated_handle = NFA_HANDLE_INVALID;
+
+    if (protocol == NFC_PROTOCOL_KOVIO) {
+      /* check whether it's new or repeated activation */
+      if (nfa_dm_disc_handle_kovio_activation(
+              p_data, nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)) {
+        /* do not notify activation of Kovio to upper layer */
+        return (NFA_STATUS_OK);
+      }
+    }
+
+    if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)
+      (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback))(
+          NFA_DM_RF_DISC_ACTIVATED_EVT, p_data);
+
+    return (NFA_STATUS_OK);
+  }
+
+  /* if this is NFCEE direct RF interface, notify activation to whoever
+   * listening UICC */
+  if (p_data->activate.intf_param.type == NFC_INTERFACE_EE_DIRECT_RF) {
+    for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++) {
+      if ((nfa_dm_cb.disc_cb.entry[xx].in_use) &&
+          (nfa_dm_cb.disc_cb.entry[xx].host_id != NFA_DM_DISC_HOST_ID_DH)) {
+        nfa_dm_cb.disc_cb.activated_rf_disc_id = p_data->activate.rf_disc_id;
+        nfa_dm_cb.disc_cb.activated_rf_interface =
+            p_data->activate.intf_param.type;
+        nfa_dm_cb.disc_cb.activated_protocol = NFC_PROTOCOL_UNKNOWN;
+        nfa_dm_cb.disc_cb.activated_handle = xx;
+
+        NFA_TRACE_DEBUG2("activated_rf_interface:0x%x, activated_handle: 0x%x",
+                         nfa_dm_cb.disc_cb.activated_rf_interface,
+                         nfa_dm_cb.disc_cb.activated_handle);
+
+        if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
+          (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback))(
+              NFA_DM_RF_DISC_ACTIVATED_EVT, p_data);
+
+        return (NFA_STATUS_OK);
+      }
+    }
+    return (NFA_STATUS_FAILED);
+  }
+
+#if (NXP_EXTNS == TRUE)
+  /*
+   * if this is Proprietary RF interface, notify activation as START_READER_EVT.
+   *
+   * Code to handle the Reader over SWP.
+   * 1. Pass this info to JNI as START_READER_EVT.
+   * return (NFA_STATUS_OK)
+   */
+  if (p_data->activate.intf_param.type == nfcFL.nfcMwFL._NCI_INTERFACE_UICC_DIRECT ||
+      p_data->activate.intf_param.type == nfcFL.nfcMwFL._NCI_INTERFACE_ESE_DIRECT) {
+    for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++) {
+      if ((nfa_dm_cb.disc_cb.entry[xx].in_use)
+#if (NXP_EXTNS != TRUE)
+          && (nfa_dm_cb.disc_cb.entry[xx].host_id != NFA_DM_DISC_HOST_ID_DH)
+#endif
+              ) {
+        nfa_dm_cb.disc_cb.activated_rf_interface =
+            p_data->activate.intf_param.type;
+        nfa_dm_cb.disc_cb.activated_handle = xx;
+
+        NFA_TRACE_DEBUG2(
+            "activated_rf_uicc-ese_interface:0x%x, activated_handle: 0x%x",
+            nfa_dm_cb.disc_cb.activated_rf_interface,
+            nfa_dm_cb.disc_cb.activated_handle);
+
+        if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
+          (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback))(
+              NFA_DM_RF_DISC_ACTIVATED_EVT, p_data);
+
+        return (NFA_STATUS_OK);
+      }
+    }
+    return (NFA_STATUS_FAILED);
+  }
+#endif
+
+  /* get bit mask of technolgies/mode and protocol */
+  activated_disc_mask = nfa_dm_disc_get_disc_mask(tech_n_mode, protocol);
+
+  /* get host ID of technology from listen mode routing table */
+  if (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A) {
+    host_id_in_LRT = nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_A];
+  } else if (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B) {
+    host_id_in_LRT = nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_B];
+  } else if (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F) {
+    host_id_in_LRT = nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_F];
+  } else if (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) {
+    host_id_in_LRT = nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_BP];
+  } else /* DH only */
+  {
+    host_id_in_LRT = NFA_DM_DISC_HOST_ID_DH;
+  }
+
+  if (protocol == NFC_PROTOCOL_NFC_DEP) {
+    /* Force NFC-DEP to the host */
+    host_id_in_LRT = NFA_DM_DISC_HOST_ID_DH;
+  }
+
+  for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++) {
+    /* if any matching NFC technology and protocol */
+    if (nfa_dm_cb.disc_cb.entry[xx].in_use) {
+      if (nfa_dm_cb.disc_cb.entry[xx].host_id == host_id_in_LRT) {
+        if (nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask &
+            activated_disc_mask) {
+          break;
+        }
+      } else {
+        /* check ISO-DEP listening even if host in LRT is not matched */
+        if (protocol == NFC_PROTOCOL_ISO_DEP) {
+          if ((tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A) &&
+              (nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask &
+               NFA_DM_DISC_MASK_LA_ISO_DEP)) {
+            iso_dep_t3t__listen = xx;
+          } else if ((tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B) &&
+                     (nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask &
+                      NFA_DM_DISC_MASK_LB_ISO_DEP)) {
+            iso_dep_t3t__listen = xx;
+          }
+        }
+        /* check T3T listening even if host in LRT is not matched */
+        else if (protocol == NFC_PROTOCOL_T3T) {
+          if ((tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F) &&
+              (nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask &
+               NFA_DM_DISC_MASK_LF_T3T)) {
+            iso_dep_t3t__listen = xx;
+          }
+        }
+      }
+    }
+  }
+
+  if (xx >= NFA_DM_DISC_NUM_ENTRIES) {
+    /* if any ISO-DEP or T3T listening even if host in LRT is not matched */
+    xx = iso_dep_t3t__listen;
+  }
+
+#if (NXP_EXTNS == TRUE)
+  if (protocol == NFC_PROTOCOL_NFC_DEP &&
+      (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE ||
+       tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE ||
+       tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A)) {
+    if (appl_dta_mode_flag == 1 &&
+        (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A)) {
+      NFA_TRACE_DEBUG0("DTA Mode Enabled : NFC-A Passive Listen Mode");
+    } else {
+      extern tNFA_P2P_CB nfa_p2p_cb;
+      xx = nfa_p2p_cb.dm_disc_handle;
+    }
+  }
+
+#endif
+
+  if (xx < NFA_DM_DISC_NUM_ENTRIES) {
+    nfa_dm_cb.disc_cb.activated_tech_mode = tech_n_mode;
+    nfa_dm_cb.disc_cb.activated_rf_disc_id = p_data->activate.rf_disc_id;
+    nfa_dm_cb.disc_cb.activated_rf_interface = p_data->activate.intf_param.type;
+    nfa_dm_cb.disc_cb.activated_protocol = protocol;
+    nfa_dm_cb.disc_cb.activated_handle = xx;
+
+    NFA_TRACE_DEBUG2("activated_protocol:0x%x, activated_handle: 0x%x",
+                     nfa_dm_cb.disc_cb.activated_protocol,
+                     nfa_dm_cb.disc_cb.activated_handle);
+
+    if (protocol == NFC_PROTOCOL_KOVIO) {
+      /* check whether it's new or repeated activation */
+      if (nfa_dm_disc_handle_kovio_activation(
+              p_data, nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)) {
+        /* do not notify activation of Kovio to upper layer */
+        return (NFA_STATUS_OK);
+      }
+    }
+
+    if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
+      (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback))(
+          NFA_DM_RF_DISC_ACTIVATED_EVT, p_data);
+
+    return (NFA_STATUS_OK);
+  } else {
+    nfa_dm_cb.disc_cb.activated_protocol = NFA_PROTOCOL_INVALID;
+    nfa_dm_cb.disc_cb.activated_handle = NFA_HANDLE_INVALID;
+    return (NFA_STATUS_FAILED);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_notify_deactivation
+**
+** Description      Send deactivation notification to sub-module
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_dm_disc_notify_deactivation(tNFA_DM_RF_DISC_SM_EVENT sm_event,
+                                            tNFC_DISCOVER* p_data) {
+  tNFA_HANDLE xx;
+  tNFA_CONN_EVT_DATA evt_data;
+  tNFC_DISCOVER disc_data;
+
+  NFA_TRACE_DEBUG1("nfa_dm_disc_notify_deactivation (): activated_handle=%d",
+                   nfa_dm_cb.disc_cb.activated_handle);
+
+  if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING) {
+    NFA_TRACE_DEBUG0("nfa_dm_disc_notify_deactivation (): for sleep wakeup");
+    return;
+  }
+
+  if (sm_event == NFA_DM_RF_DEACTIVATE_RSP) {
+    /*
+    ** Activation has been aborted by upper layer in
+    ** NFA_DM_RFST_W4_ALL_DISCOVERIES or NFA_DM_RFST_W4_HOST_SELECT
+    ** Deactivation by upper layer or RF link loss in
+    ** NFA_DM_RFST_LISTEN_SLEEP
+    ** No sub-module is activated at this state.
+    */
+
+    if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_LISTEN_SLEEP) {
+      if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use) {
+        if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback) {
+          disc_data.deactivate.type = NFA_DEACTIVATE_TYPE_IDLE;
+          (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback))(
+              NFA_DM_RF_DISC_DEACTIVATED_EVT, &disc_data);
+        }
+      } else {
+        /* let each sub-module handle deactivation */
+        for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++) {
+          if ((nfa_dm_cb.disc_cb.entry[xx].in_use) &&
+              (nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask &
+               NFA_DM_DISC_MASK_LISTEN)) {
+            disc_data.deactivate.type = NFA_DEACTIVATE_TYPE_IDLE;
+            (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback))(
+                NFA_DM_RF_DISC_DEACTIVATED_EVT, &disc_data);
+          }
+        }
+      }
+    } else if ((!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING)) ||
+               (nfa_dm_cb.disc_cb.deact_notify_pending)) {
+      xx = nfa_dm_cb.disc_cb.activated_handle;
+
+      /* notify event to activated module if failed while reactivation */
+      if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use) {
+        if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback) {
+          disc_data.deactivate.type = NFA_DEACTIVATE_TYPE_IDLE;
+          (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback))(
+              NFA_DM_RF_DISC_DEACTIVATED_EVT, p_data);
+        }
+      } else if ((xx < NFA_DM_DISC_NUM_ENTRIES) &&
+                 (nfa_dm_cb.disc_cb.entry[xx].in_use) &&
+                 (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)) {
+        (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback))(
+            NFA_DM_RF_DISC_DEACTIVATED_EVT, p_data);
+      } else {
+        /* notify deactivation to application if there is no activated module */
+        evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE;
+        nfa_dm_conn_cback_event_notify(NFA_DEACTIVATED_EVT, &evt_data);
+      }
+    }
+  } else {
+    if (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_KOVIO) {
+      if (nfa_dm_cb.disc_cb.kovio_tle.in_use) {
+        /* restart timer and do not notify upper layer */
+        nfa_sys_start_timer(&nfa_dm_cb.disc_cb.kovio_tle, 0,
+                            NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
+        return;
+      }
+      /* Otherwise, upper layer initiated deactivation. */
+    }
+
+    /* notify event to activated module */
+    if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use) {
+      if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback) {
+        disc_data.deactivate.type = NFA_DEACTIVATE_TYPE_IDLE;
+        (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback))(
+            NFA_DM_RF_DISC_DEACTIVATED_EVT, p_data);
+      }
+    } else {
+      xx = nfa_dm_cb.disc_cb.activated_handle;
+
+      if ((xx < NFA_DM_DISC_NUM_ENTRIES) &&
+          (nfa_dm_cb.disc_cb.entry[xx].in_use)) {
+        if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
+          (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback))(
+              NFA_DM_RF_DISC_DEACTIVATED_EVT, p_data);
+      }
+    }
+  }
+
+  /* clear activated information */
+  nfa_dm_cb.disc_cb.activated_tech_mode = 0;
+  nfa_dm_cb.disc_cb.activated_rf_disc_id = 0;
+  nfa_dm_cb.disc_cb.activated_rf_interface = 0;
+  nfa_dm_cb.disc_cb.activated_protocol = NFA_PROTOCOL_INVALID;
+  nfa_dm_cb.disc_cb.activated_handle = NFA_HANDLE_INVALID;
+  nfa_dm_cb.disc_cb.deact_notify_pending = false;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_sleep_wakeup
+**
+** Description      Put tag to sleep, then wake it up. Can be used Perform
+**                  legacy presence check or to wake up tag that went to HALT
+**                  state
+**
+** Returns          true if operation started
+**
+*******************************************************************************/
+tNFC_STATUS nfa_dm_disc_sleep_wakeup(void) {
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+
+  if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE) {
+    /* Deactivate to sleep mode */
+    status = nfa_dm_send_deactivate_cmd(NFC_DEACTIVATE_TYPE_SLEEP);
+    if (status == NFC_STATUS_OK) {
+      /* deactivate to sleep is sent on behalf of sleep wakeup.
+       * set the sleep wakeup information in control block */
+      nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_CHECKING;
+      nfa_dm_cb.disc_cb.deact_pending = false;
+    }
+  }
+
+  return (status);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_is_raw_frame_session
+**
+** Description      If NFA_SendRawFrame is called since RF activation,
+**                  this function returns true.
+**
+** Returns          true if NFA_SendRawFrame is called
+**
+*******************************************************************************/
+bool nfa_dm_is_raw_frame_session(void) {
+  return ((nfa_dm_cb.flags & NFA_DM_FLAGS_RAW_FRAME) ? true : false);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_is_p2p_paused
+**
+** Description      If NFA_PauseP2p is called sand still effective,
+**                  this function returns true.
+**
+** Returns          true if NFA_SendRawFrame is called
+**
+*******************************************************************************/
+bool nfa_dm_is_p2p_paused(void) {
+  return ((nfa_dm_cb.flags & NFA_DM_FLAGS_P2P_PAUSED) ? true : false);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_end_sleep_wakeup
+**
+** Description      Sleep Wakeup is complete
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_dm_disc_end_sleep_wakeup(tNFC_STATUS status) {
+  if ((nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_KOVIO) &&
+      (nfa_dm_cb.disc_cb.kovio_tle.in_use)) {
+    /* ignore it while doing Kovio presence check */
+    return;
+  }
+
+  if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING) {
+    nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_CHECKING;
+
+    /* notify RW module that sleep wakeup is finished */
+    nfa_rw_handle_sleep_wakeup_rsp(status);
+
+    if (nfa_dm_cb.disc_cb.deact_pending) {
+      nfa_dm_cb.disc_cb.deact_pending = false;
+      /* Perform pending deactivate command and on response notfiy deactivation
+       */
+      nfa_dm_cb.disc_cb.deact_notify_pending = true;
+      nfa_dm_disc_sm_execute(NFA_DM_RF_DEACTIVATE_CMD,
+                             (void*)&nfa_dm_cb.disc_cb.pending_deact_type);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_kovio_timeout_cback
+**
+** Description      Timeout for Kovio bar code tag presence check
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_disc_kovio_timeout_cback(TIMER_LIST_ENT* p_tle) {
+  tNFC_DEACTIVATE_DEVT deact;
+  (void)p_tle;
+  NFA_TRACE_DEBUG0("nfa_dm_disc_kovio_timeout_cback()");
+
+  /* notify presence check failure, if presence check is pending */
+  nfa_dm_disc_report_kovio_presence_check(NFC_STATUS_FAILED);
+
+  if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE) {
+    /* restart timer in case that upper layer's presence check interval is too
+     * long */
+    nfa_sys_start_timer(&nfa_dm_cb.disc_cb.kovio_tle, 0,
+                        NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
+  } else {
+    /* notify upper layer deactivated event */
+    deact.status = NFC_STATUS_OK;
+    deact.type = NFC_DEACTIVATE_TYPE_DISCOVERY;
+    deact.is_ntf = true;
+    nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF, (void*)&deact);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_start_kovio_presence_check
+**
+** Description      Deactivate to discovery mode and wait for activation
+**
+** Returns          true if operation started
+**
+*******************************************************************************/
+tNFC_STATUS nfa_dm_disc_start_kovio_presence_check(void) {
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+
+  NFA_TRACE_DEBUG0("nfa_dm_disc_start_kovio_presence_check ()");
+
+  if ((nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_KOVIO) &&
+      (nfa_dm_cb.disc_cb.kovio_tle.in_use)) {
+    if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE) {
+      /* restart timer */
+      nfa_sys_start_timer(&nfa_dm_cb.disc_cb.kovio_tle, 0,
+                          NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
+
+      /* Deactivate to discovery mode */
+      status = nfa_dm_send_deactivate_cmd(NFC_DEACTIVATE_TYPE_DISCOVERY);
+
+      if (status == NFC_STATUS_OK) {
+        /* deactivate to sleep is sent on behalf of sleep wakeup.
+         * set the sleep wakeup information in control block */
+        nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_CHECKING;
+        nfa_dm_cb.disc_cb.deact_pending = false;
+      }
+    } else {
+      /* wait for next activation */
+      nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_CHECKING;
+      nfa_dm_cb.disc_cb.deact_pending = false;
+      status = NFC_STATUS_OK;
+    }
+  }
+
+  return (status);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_report_kovio_presence_check
+**
+** Description      Report Kovio presence check status
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_dm_disc_report_kovio_presence_check(tNFC_STATUS status) {
+  NFA_TRACE_DEBUG0("nfa_dm_disc_report_kovio_presence_check ()");
+
+  if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING) {
+    nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_CHECKING;
+
+    /* notify RW module that sleep wakeup is finished */
+    nfa_rw_handle_presence_check_rsp(status);
+
+    if (nfa_dm_cb.disc_cb.deact_pending) {
+      nfa_dm_cb.disc_cb.deact_pending = false;
+      nfa_dm_disc_sm_execute(NFA_DM_RF_DEACTIVATE_CMD,
+                             (void*)&nfa_dm_cb.disc_cb.pending_deact_type);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_data_cback
+**
+** Description      Monitoring interface error through data callback
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_disc_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
+                                   tNFC_CONN* p_data) {
+  (void)conn_id;
+  NFA_TRACE_DEBUG0("nfa_dm_disc_data_cback ()");
+
+  /* if selection failed */
+  if (event == NFC_ERROR_CEVT) {
+    nfa_dm_disc_sm_execute(NFA_DM_CORE_INTF_ERROR_NTF, NULL);
+  } else if (event == NFC_DATA_CEVT) {
+    GKI_freebuf(p_data->data.p_data);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_new_state
+**
+** Description      Processing discovery events in NFA_DM_RFST_IDLE state
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_disc_new_state(tNFA_DM_RF_DISC_STATE new_state) {
+  tNFA_CONN_EVT_DATA evt_data;
+  tNFA_DM_RF_DISC_STATE old_state = nfa_dm_cb.disc_cb.disc_state;
+
+#if (BT_TRACE_VERBOSE == true)
+  NFA_TRACE_DEBUG5(
+      "nfa_dm_disc_new_state (): old_state: %s (%d), new_state: %s (%d) "
+      "disc_flags: 0x%x",
+      nfa_dm_disc_state_2_str(nfa_dm_cb.disc_cb.disc_state),
+      nfa_dm_cb.disc_cb.disc_state, nfa_dm_disc_state_2_str(new_state),
+      new_state, nfa_dm_cb.disc_cb.disc_flags);
+#else
+  NFA_TRACE_DEBUG3(
+      "nfa_dm_disc_new_state(): old_state: %d, new_state: %d disc_flags: 0x%x",
+      nfa_dm_cb.disc_cb.disc_state, new_state, nfa_dm_cb.disc_cb.disc_flags);
+#endif
+
+  nfa_dm_cb.disc_cb.disc_state = new_state;
+
+  /* not error recovering */
+  if ((new_state == NFA_DM_RFST_IDLE) &&
+      (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP))) {
+    if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING) {
+      nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_STOPPING;
+
+      /* if exclusive RF control is stopping */
+      if (nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE) {
+        if (old_state > NFA_DM_RFST_DISCOVERY) {
+          /* notify deactivation to application */
+          evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE;
+          nfa_dm_conn_cback_event_notify(NFA_DEACTIVATED_EVT, &evt_data);
+        }
+
+        nfa_dm_rel_excl_rf_control_and_notify();
+      } else {
+        evt_data.status = NFA_STATUS_OK;
+        nfa_dm_conn_cback_event_notify(NFA_RF_DISCOVERY_STOPPED_EVT, &evt_data);
+      }
+    }
+    if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_DISABLING) {
+      nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_DISABLING;
+      nfa_sys_check_disabled();
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_sm_idle
+**
+** Description      Processing discovery events in NFA_DM_RFST_IDLE state
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_disc_sm_idle(tNFA_DM_RF_DISC_SM_EVENT event,
+                                tNFA_DM_RF_DISC_DATA* p_data) {
+  uint8_t xx;
+
+  switch (event) {
+    case NFA_DM_RF_DISCOVER_CMD:
+      nfa_dm_start_rf_discover();
+      break;
+
+    case NFA_DM_RF_DISCOVER_RSP:
+      nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
+
+      if (p_data->nfc_discover.status == NFC_STATUS_OK) {
+        nfa_dm_disc_new_state(NFA_DM_RFST_DISCOVERY);
+
+        /* if RF discovery was stopped while waiting for response */
+        if (nfa_dm_cb.disc_cb.disc_flags &
+            (NFA_DM_DISC_FLAGS_STOPPING | NFA_DM_DISC_FLAGS_DISABLING)) {
+          /* stop discovery */
+          nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
+          NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
+          break;
+        }
+
+        if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use) {
+          if (nfa_dm_cb.disc_cb.excl_disc_entry.disc_flags &
+              NFA_DM_DISC_FLAGS_NOTIFY) {
+            nfa_dm_cb.disc_cb.excl_disc_entry.disc_flags &=
+                ~NFA_DM_DISC_FLAGS_NOTIFY;
+
+            if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)
+              (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback))(
+                  NFA_DM_RF_DISC_START_EVT, (tNFC_DISCOVER*)p_data);
+          }
+        } else {
+          /* notify event to each module which is waiting for start */
+          for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++) {
+            /* if registered module is waiting for starting discovery */
+            if ((nfa_dm_cb.disc_cb.entry[xx].in_use) &&
+                (nfa_dm_cb.disc_cb.dm_disc_mask &
+                 nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask) &&
+                (nfa_dm_cb.disc_cb.entry[xx].disc_flags &
+                 NFA_DM_DISC_FLAGS_NOTIFY)) {
+              nfa_dm_cb.disc_cb.entry[xx].disc_flags &=
+                  ~NFA_DM_DISC_FLAGS_NOTIFY;
+
+              if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
+                (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback))(
+                    NFA_DM_RF_DISC_START_EVT, (tNFC_DISCOVER*)p_data);
+            }
+          }
+        }
+        nfa_dm_disc_notify_started(p_data->nfc_discover.status);
+      } else {
+        /* in rare case that the discovery states of NFCC and DH mismatch and
+         * NFCC rejects Discover Cmd
+         * deactivate idle and then start disvocery when got deactivate rsp */
+        nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
+        NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
+      }
+      break;
+
+    case NFA_DM_RF_DEACTIVATE_RSP:
+      nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
+
+      /* if NFCC goes to idle successfully */
+      if (p_data->nfc_discover.status == NFC_STATUS_OK) {
+        /* if DH forced to go idle while waiting for deactivation NTF */
+        if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF)) {
+          nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
+                                          &(p_data->nfc_discover));
+
+          /* check any pending flags like NFA_DM_DISC_FLAGS_STOPPING or
+           * NFA_DM_DISC_FLAGS_DISABLING */
+          nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
+          /* check if need to restart discovery after resync discovery state
+           * with NFCC */
+          nfa_dm_start_rf_discover();
+        }
+        /* Otherwise, deactivating when getting unexpected activation */
+      }
+#if (NXP_EXTNS == TRUE)
+      else if (p_data->nfc_discover.status == NCI_STATUS_SEMANTIC_ERROR) {
+        /* check any pending flags like NFA_DM_DISC_FLAGS_STOPPING or
+         * NFA_DM_DISC_FLAGS_DISABLING */
+        nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
+        /* check if need to restart discovery after resync discovery state with
+         * NFCC */
+        nfa_dm_start_rf_discover();
+      }
+#endif
+      /* Otherwise, wait for deactivation NTF */
+      break;
+
+    case NFA_DM_RF_DEACTIVATE_NTF:
+      /* if NFCC sent this after NFCC had rejected deactivate CMD to idle while
+       * deactivating */
+      if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF)) {
+        if (p_data->nfc_discover.deactivate.type ==
+            NFC_DEACTIVATE_TYPE_DISCOVERY) {
+          /* stop discovery */
+          nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
+          NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
+        } else {
+          nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
+                                          &(p_data->nfc_discover));
+          /* check any pending flags like NFA_DM_DISC_FLAGS_STOPPING or
+           * NFA_DM_DISC_FLAGS_DISABLING */
+          nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
+          /* check if need to restart discovery after resync discovery state
+           * with NFCC */
+          nfa_dm_start_rf_discover();
+        }
+      }
+      /* Otherwise, deactivated when received unexpected activation in idle
+       * state */
+      nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
+      break;
+
+    case NFA_DM_RF_INTF_ACTIVATED_NTF:
+      /* unexpected activation, deactivate to idle */
+      nfa_dm_cb.disc_cb.disc_flags |=
+          (NFA_DM_DISC_FLAGS_W4_RSP | NFA_DM_DISC_FLAGS_W4_NTF);
+      NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
+      break;
+
+    case NFA_DM_LP_LISTEN_CMD:
+      nfa_dm_disc_new_state(NFA_DM_RFST_LP_LISTEN);
+      break;
+
+    default:
+      NFA_TRACE_ERROR0("nfa_dm_disc_sm_idle (): Unexpected discovery event");
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_sm_discovery
+**
+** Description      Processing discovery events in NFA_DM_RFST_DISCOVERY state
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_disc_sm_discovery(tNFA_DM_RF_DISC_SM_EVENT event,
+                                     tNFA_DM_RF_DISC_DATA* p_data) {
+  switch (event) {
+    case NFA_DM_RF_DEACTIVATE_CMD:
+      /* if deactivate CMD was not sent to NFCC */
+      if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)) {
+        nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
+        NFC_Deactivate(p_data->deactivate_type);
+      }
+      break;
+    case NFA_DM_RF_DEACTIVATE_RSP:
+      nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
+
+      /* if it's not race condition between deactivate CMD and activate NTF */
+      if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF)) {
+        /* do not notify deactivated to idle in RF discovery state
+        ** because it is internal or stopping RF discovery
+        */
+
+        /* there was no activation while waiting for deactivation RSP */
+        nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
+        nfa_dm_start_rf_discover();
+      }
+      break;
+    case NFA_DM_RF_DISCOVER_NTF:
+#if (NXP_EXTNS == TRUE)
+      /* Notification Type = NCI_DISCOVER_NTF_LAST_ABORT */
+      if (p_data->nfc_discover.result.more == NCI_DISCOVER_NTF_LAST_ABORT) {
+        /* Fix for multiple tags: After receiving deactivate event, restart
+         * discovery */
+        NFA_TRACE_DEBUG0(
+            "Received NCI_DISCOVER_NTF_LAST_ABORT, sending deactivate command");
+        NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
+      } else {
+#endif
+        nfa_dm_disc_new_state(NFA_DM_RFST_W4_ALL_DISCOVERIES);
+#if (NXP_EXTNS == TRUE)
+      }
+#endif
+      nfa_dm_notify_discovery(p_data);
+      break;
+    case NFA_DM_RF_INTF_ACTIVATED_NTF:
+      if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP) {
+        NFA_TRACE_DEBUG0("RF Activated while waiting for deactivation RSP");
+        /* it's race condition. DH has to wait for deactivation NTF */
+        nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_NTF;
+      } else {
+        if (p_data->nfc_discover.activate.intf_param.type ==
+            NFC_INTERFACE_EE_DIRECT_RF) {
+          nfa_dm_disc_new_state(NFA_DM_RFST_LISTEN_ACTIVE);
+        }
+#if (NXP_EXTNS == TRUE)
+        /*
+         * Handle the Reader over SWP.
+         * Add condition UICC_DIRECT_INTF/ESE_DIRECT_INTF
+         * set new state NFA_DM_RFST_POLL_ACTIVE
+         * */
+        else if (p_data->nfc_discover.activate.intf_param.type ==
+                nfcFL.nfcMwFL._NCI_INTERFACE_UICC_DIRECT ||
+                 p_data->nfc_discover.activate.intf_param.type ==
+                         nfcFL.nfcMwFL._NCI_INTERFACE_ESE_DIRECT) {
+          nfa_dm_disc_new_state(NFA_DM_RFST_POLL_ACTIVE);
+        }
+#endif
+        else if (p_data->nfc_discover.activate.rf_tech_param.mode & 0x80) {
+          /* Listen mode */
+          nfa_dm_disc_new_state(NFA_DM_RFST_LISTEN_ACTIVE);
+        } else {
+          /* Poll mode */
+          nfa_dm_disc_new_state(NFA_DM_RFST_POLL_ACTIVE);
+        }
+
+        if (nfa_dm_disc_notify_activation(&(p_data->nfc_discover)) ==
+            NFA_STATUS_FAILED) {
+          NFA_TRACE_DEBUG0(
+              "Not matched, restart discovery after receiving deactivate ntf");
+
+          /* after receiving deactivate event, restart discovery */
+          nfa_dm_cb.disc_cb.disc_flags |=
+              (NFA_DM_DISC_FLAGS_W4_RSP | NFA_DM_DISC_FLAGS_W4_NTF);
+          NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
+        }
+      }
+      break;
+
+    case NFA_DM_RF_DEACTIVATE_NTF:
+      /* if there was race condition between deactivate CMD and activate NTF */
+      if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF) {
+        /* race condition is resolved */
+        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
+
+        if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)) {
+          /* do not notify deactivated to idle in RF discovery state
+          ** because it is internal or stopping RF discovery
+          */
+
+          nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
+          nfa_dm_start_rf_discover();
+        }
+      }
+      break;
+    case NFA_DM_LP_LISTEN_CMD:
+      break;
+    case NFA_DM_CORE_INTF_ERROR_NTF:
+      break;
+    default:
+      NFA_TRACE_ERROR0(
+          "nfa_dm_disc_sm_discovery (): Unexpected discovery event");
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_sm_w4_all_discoveries
+**
+** Description      Processing discovery events in
+**                  NFA_DM_RFST_W4_ALL_DISCOVERIES state
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_disc_sm_w4_all_discoveries(tNFA_DM_RF_DISC_SM_EVENT event,
+                                              tNFA_DM_RF_DISC_DATA* p_data) {
+  switch (event) {
+    case NFA_DM_RF_DEACTIVATE_CMD:
+      /* if deactivate CMD was not sent to NFCC */
+      if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)) {
+        nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
+        /* only IDLE mode is allowed */
+        NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
+      }
+      break;
+    case NFA_DM_RF_DEACTIVATE_RSP:
+      nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
+      /* notify exiting from w4 all discoverie state */
+      nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_RSP,
+                                      &(p_data->nfc_discover));
+
+      nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
+      nfa_dm_start_rf_discover();
+      break;
+    case NFA_DM_RF_DISCOVER_NTF:
+#if (NXP_EXTNS == TRUE)
+      if (p_data->nfc_discover.result.protocol == NCI_PROTOCOL_UNKNOWN) {
+        /* fix for p2p interop with Nexus5 */
+        NFA_TRACE_DEBUG0("Unknown protocol - Restart Discovery");
+        /* after receiving unknown protocol, restart discovery */
+        NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
+        return;
+      }
+#endif
+      /* if deactivate CMD is already sent then ignore discover NTF */
+      if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)) {
+        /* Notification Type = NCI_DISCOVER_NTF_LAST or
+         * NCI_DISCOVER_NTF_LAST_ABORT */
+        if (p_data->nfc_discover.result.more != NCI_DISCOVER_NTF_MORE) {
+          nfa_dm_disc_new_state(NFA_DM_RFST_W4_HOST_SELECT);
+        }
+        nfa_dm_notify_discovery(p_data);
+      }
+      break;
+    case NFA_DM_RF_INTF_ACTIVATED_NTF:
+      /*
+      ** This is only for ISO15693.
+      ** FW sends activation NTF when all responses are received from tags
+      ** without host selecting.
+      */
+      nfa_dm_disc_new_state(NFA_DM_RFST_POLL_ACTIVE);
+
+      if (nfa_dm_disc_notify_activation(&(p_data->nfc_discover)) ==
+          NFA_STATUS_FAILED) {
+        NFA_TRACE_DEBUG0(
+            "Not matched, restart discovery after receiving deactivate ntf");
+
+        /* after receiving deactivate event, restart discovery */
+        NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
+      }
+      break;
+    default:
+      NFA_TRACE_ERROR0(
+          "nfa_dm_disc_sm_w4_all_discoveries (): Unexpected discovery event");
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_sm_w4_host_select
+**
+** Description      Processing discovery events in NFA_DM_RFST_W4_HOST_SELECT
+**                  state
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_disc_sm_w4_host_select(tNFA_DM_RF_DISC_SM_EVENT event,
+                                          tNFA_DM_RF_DISC_DATA* p_data) {
+  tNFA_CONN_EVT_DATA conn_evt;
+  tNFA_DM_DISC_FLAGS old_sleep_wakeup_flag =
+      (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING);
+  bool sleep_wakeup_event = false;
+  bool sleep_wakeup_event_processed = false;
+  tNFA_STATUS status;
+
+  switch (event) {
+    case NFA_DM_RF_DISCOVER_SELECT_CMD:
+      /* if not waiting to deactivate */
+      if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)) {
+        NFC_DiscoverySelect(p_data->select.rf_disc_id, p_data->select.protocol,
+                            p_data->select.rf_interface);
+      } else {
+        nfa_dm_disc_conn_event_notify(NFA_SELECT_RESULT_EVT, NFA_STATUS_FAILED);
+      }
+      break;
+
+    case NFA_DM_RF_DISCOVER_SELECT_RSP:
+      sleep_wakeup_event = true;
+      /* notify application status of selection */
+      if (p_data->nfc_discover.status == NFC_STATUS_OK) {
+        sleep_wakeup_event_processed = true;
+        conn_evt.status = NFA_STATUS_OK;
+        /* register callback to get interface error NTF */
+        NFC_SetStaticRfCback(nfa_dm_disc_data_cback);
+      } else
+        conn_evt.status = NFA_STATUS_FAILED;
+
+      if (!old_sleep_wakeup_flag) {
+        nfa_dm_disc_conn_event_notify(NFA_SELECT_RESULT_EVT,
+                                      p_data->nfc_discover.status);
+      }
+      break;
+    case NFA_DM_RF_INTF_ACTIVATED_NTF:
+      nfa_dm_disc_new_state(NFA_DM_RFST_POLL_ACTIVE);
+#if (NXP_EXTNS == TRUE)
+      /* always call nfa_dm_disc_notify_activation to update protocol/interface
+       * information in NFA control blocks */
+      status = nfa_dm_disc_notify_activation(&(p_data->nfc_discover));
+#endif
+      if (old_sleep_wakeup_flag) {
+        /* Handle sleep wakeup success: notify RW module of sleep wakeup of tag;
+         * if deactivation is pending then deactivate  */
+        nfa_dm_disc_end_sleep_wakeup(NFC_STATUS_OK);
+#if (NXP_EXTNS == TRUE)
+        nfa_rw_set_cback(&(p_data->nfc_discover));
+#endif
+      } else if (status == NFA_STATUS_FAILED) {
+        NFA_TRACE_DEBUG0(
+            "Not matched, restart discovery after receiving deactivate ntf");
+
+        /* after receiving deactivate event, restart discovery */
+        NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
+      }
+      break;
+    case NFA_DM_RF_DEACTIVATE_CMD:
+      if (old_sleep_wakeup_flag) {
+        nfa_dm_cb.disc_cb.deact_pending = true;
+        nfa_dm_cb.disc_cb.pending_deact_type = p_data->deactivate_type;
+      }
+      /* if deactivate CMD was not sent to NFCC */
+      else if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)) {
+        nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
+        /* only IDLE mode is allowed */
+        NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
+      }
+      break;
+    case NFA_DM_RF_DEACTIVATE_RSP:
+      nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
+      /* notify exiting from host select state */
+      nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_RSP,
+                                      &(p_data->nfc_discover));
+
+      nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
+      nfa_dm_start_rf_discover();
+      break;
+
+    case NFA_DM_CORE_INTF_ERROR_NTF:
+      sleep_wakeup_event = true;
+      if (!old_sleep_wakeup_flag) {
+        /* target activation failed, upper layer may deactivate or select again
+         */
+        conn_evt.status = NFA_STATUS_FAILED;
+        nfa_dm_conn_cback_event_notify(NFA_SELECT_RESULT_EVT, &conn_evt);
+      }
+      break;
+    default:
+      NFA_TRACE_ERROR0(
+          "nfa_dm_disc_sm_w4_host_select (): Unexpected discovery event");
+#if (NXP_EXTNS == TRUE)
+      NFA_TRACE_ERROR0("nfa_dm_disc_sm_w4_host_select (): Restarted discovery");
+      NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
+#endif
+      break;
+  }
+
+  if (old_sleep_wakeup_flag && sleep_wakeup_event &&
+      !sleep_wakeup_event_processed) {
+    /* performing sleep wakeup and exception conditions happened
+     * clear sleep wakeup information and report failure */
+    nfa_dm_disc_end_sleep_wakeup(NFC_STATUS_FAILED);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_sm_poll_active
+**
+** Description      Processing discovery events in NFA_DM_RFST_POLL_ACTIVE state
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_disc_sm_poll_active(tNFA_DM_RF_DISC_SM_EVENT event,
+                                       tNFA_DM_RF_DISC_DATA* p_data) {
+  tNFC_STATUS status;
+  tNFA_DM_DISC_FLAGS old_sleep_wakeup_flag =
+      (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING);
+  bool sleep_wakeup_event = false;
+  bool sleep_wakeup_event_processed = false;
+  tNFC_DEACTIVATE_DEVT deact;
+
+  switch (event) {
+    case NFA_DM_RF_DEACTIVATE_CMD:
+      if(NFC_GetNCIVersion()== NCI_VERSION_2_0){
+          if((nfa_dm_cb.disc_cb.activated_rf_interface == NFC_INTERFACE_FRAME) &&
+                  (p_data->deactivate_type == NFC_DEACTIVATE_TYPE_SLEEP)) {
+             /* NCI 2.0- DH is responsible for sending deactivation commands before RF_DEACTIVATE_CMD */
+             nfa_dm_send_tag_deselect_cmd(nfa_dm_cb.disc_cb.activated_protocol);
+          }
+      }
+      if (nfa_dm_cb.disc_cb.activated_protocol == NCI_PROTOCOL_MIFARE) {
+        nfa_dm_cb.disc_cb.deact_pending = true;
+        nfa_dm_cb.disc_cb.pending_deact_type = p_data->deactivate_type;
+        status = nfa_dm_send_deactivate_cmd(p_data->deactivate_type);
+        break;
+      }
+
+      if (old_sleep_wakeup_flag) {
+        /* sleep wakeup is already enabled when deactivate cmd is requested,
+         * keep the information in control block to issue it later */
+        nfa_dm_cb.disc_cb.deact_pending = true;
+        nfa_dm_cb.disc_cb.pending_deact_type = p_data->deactivate_type;
+      } else {
+        status = nfa_dm_send_deactivate_cmd(p_data->deactivate_type);
+      }
+
+      break;
+    case NFA_DM_RF_DEACTIVATE_RSP:
+      nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
+      /* register callback to get interface error NTF */
+      NFC_SetStaticRfCback(nfa_dm_disc_data_cback);
+
+      if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF)) {
+        /* it's race condition. received deactivate NTF before receiving RSP */
+
+        deact.status = NFC_STATUS_OK;
+        deact.type = NFC_DEACTIVATE_TYPE_IDLE;
+        deact.is_ntf = true;
+        nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
+                                        (void*)&deact);
+
+        /* NFCC is in IDLE state */
+        nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
+        nfa_dm_start_rf_discover();
+      }
+      break;
+    case NFA_DM_RF_DEACTIVATE_NTF:
+      nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
+
+      nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.tle);
+
+      if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP) {
+        /* it's race condition. received deactivate NTF before receiving RSP */
+        /* notify deactivation after receiving deactivate RSP */
+        NFA_TRACE_DEBUG0("Rx deactivate NTF while waiting for deactivate RSP");
+        break;
+      }
+
+      sleep_wakeup_event = true;
+
+      nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
+                                      &(p_data->nfc_discover));
+
+      if ((p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP) ||
+          (p_data->nfc_discover.deactivate.type ==
+           NFC_DEACTIVATE_TYPE_SLEEP_AF)) {
+        nfa_dm_disc_new_state(NFA_DM_RFST_W4_HOST_SELECT);
+        if (old_sleep_wakeup_flag) {
+          sleep_wakeup_event_processed = true;
+          /* process pending deactivate request */
+          if (nfa_dm_cb.disc_cb.deact_pending) {
+            /* notify RW module that sleep wakeup is finished */
+            /* if deactivation is pending then deactivate  */
+            nfa_dm_disc_end_sleep_wakeup(NFC_STATUS_OK);
+
+            /* Notify NFA RW sub-systems because NFA_DM_RF_DEACTIVATE_RSP will
+             * not call this function */
+            nfa_rw_proc_disc_evt(NFA_DM_RF_DISC_DEACTIVATED_EVT, NULL, true);
+          } else {
+            /* Successfully went to sleep mode for sleep wakeup */
+            /* Now wake up the tag to complete the operation */
+            NFC_DiscoverySelect(nfa_dm_cb.disc_cb.activated_rf_disc_id,
+                                nfa_dm_cb.disc_cb.activated_protocol,
+                                nfa_dm_cb.disc_cb.activated_rf_interface);
+          }
+        }
+      } else if (p_data->nfc_discover.deactivate.type ==
+                 NFC_DEACTIVATE_TYPE_IDLE) {
+        nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
+        nfa_dm_start_rf_discover();
+      } else if (p_data->nfc_discover.deactivate.type ==
+                 NFC_DEACTIVATE_TYPE_DISCOVERY) {
+        nfa_dm_disc_new_state(NFA_DM_RFST_DISCOVERY);
+        if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING) {
+          /* stop discovery */
+          NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
+        }
+      }
+      break;
+
+    case NFA_DM_CORE_INTF_ERROR_NTF:
+#if (NXP_EXTNS != TRUE)
+      sleep_wakeup_event = true;
+      if ((!old_sleep_wakeup_flag) || (!nfa_dm_cb.disc_cb.deact_pending)) {
+        nfa_dm_send_deactivate_cmd(NFA_DEACTIVATE_TYPE_DISCOVERY);
+      }
+#endif
+      break;
+
+    default:
+      NFA_TRACE_ERROR0(
+          "nfa_dm_disc_sm_poll_active (): Unexpected discovery event");
+      break;
+  }
+
+  if (old_sleep_wakeup_flag && sleep_wakeup_event &&
+      !sleep_wakeup_event_processed) {
+    /* performing sleep wakeup and exception conditions happened
+     * clear sleep wakeup information and report failure */
+    nfa_dm_disc_end_sleep_wakeup(NFC_STATUS_FAILED);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_sm_listen_active
+**
+** Description      Processing discovery events in NFA_DM_RFST_LISTEN_ACTIVE
+**                  state
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_disc_sm_listen_active(tNFA_DM_RF_DISC_SM_EVENT event,
+                                         tNFA_DM_RF_DISC_DATA* p_data) {
+  tNFC_DEACTIVATE_DEVT deact;
+
+  switch (event) {
+    case NFA_DM_RF_DEACTIVATE_CMD:
+      nfa_dm_send_deactivate_cmd(p_data->deactivate_type);
+      break;
+    case NFA_DM_RF_DEACTIVATE_RSP:
+      nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
+      if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF)) {
+        /* it's race condition. received deactivate NTF before receiving RSP */
+
+        deact.status = NFC_STATUS_OK;
+        deact.type = NFC_DEACTIVATE_TYPE_IDLE;
+        deact.is_ntf = true;
+        nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
+                                        (void*)&deact);
+
+        /* NFCC is in IDLE state */
+        nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
+        nfa_dm_start_rf_discover();
+      }
+      break;
+    case NFA_DM_RF_DEACTIVATE_NTF:
+      nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
+
+      nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.tle);
+
+      if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP) {
+        /* it's race condition. received deactivate NTF before receiving RSP */
+        /* notify deactivation after receiving deactivate RSP */
+        NFA_TRACE_DEBUG0("Rx deactivate NTF while waiting for deactivate RSP");
+      } else {
+        nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
+                                        &(p_data->nfc_discover));
+
+        if (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_IDLE) {
+          nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
+          nfa_dm_start_rf_discover();
+        } else if ((p_data->nfc_discover.deactivate.type ==
+                    NFC_DEACTIVATE_TYPE_SLEEP) ||
+                   (p_data->nfc_discover.deactivate.type ==
+                    NFC_DEACTIVATE_TYPE_SLEEP_AF)) {
+          nfa_dm_disc_new_state(NFA_DM_RFST_LISTEN_SLEEP);
+        } else if (p_data->nfc_discover.deactivate.type ==
+                   NFC_DEACTIVATE_TYPE_DISCOVERY) {
+          /* Discovery */
+          nfa_dm_disc_new_state(NFA_DM_RFST_DISCOVERY);
+          if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING) {
+            /* stop discovery */
+            NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
+          }
+        }
+      }
+      break;
+
+    case NFA_DM_CORE_INTF_ERROR_NTF:
+      break;
+    default:
+      NFA_TRACE_ERROR0(
+          "nfa_dm_disc_sm_listen_active (): Unexpected discovery event");
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_sm_listen_sleep
+**
+** Description      Processing discovery events in NFA_DM_RFST_LISTEN_SLEEP
+**                  state
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_disc_sm_listen_sleep(tNFA_DM_RF_DISC_SM_EVENT event,
+                                        tNFA_DM_RF_DISC_DATA* p_data) {
+  switch (event) {
+    case NFA_DM_RF_DEACTIVATE_CMD:
+      nfa_dm_send_deactivate_cmd(p_data->deactivate_type);
+
+      /* if deactivate type is not discovery then NFCC will not sent
+       * deactivation NTF */
+      if (p_data->deactivate_type != NFA_DEACTIVATE_TYPE_DISCOVERY) {
+        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
+        nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.tle);
+      }
+      break;
+    case NFA_DM_RF_DEACTIVATE_RSP:
+      nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
+      /* if deactivate type in CMD was IDLE */
+      if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF)) {
+        nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_RSP,
+                                        &(p_data->nfc_discover));
+
+        nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
+        nfa_dm_start_rf_discover();
+      }
+      break;
+    case NFA_DM_RF_DEACTIVATE_NTF:
+      /* clear both W4_RSP and W4_NTF because of race condition between
+       * deactivat CMD and link loss */
+      nfa_dm_cb.disc_cb.disc_flags &=
+          ~(NFA_DM_DISC_FLAGS_W4_RSP | NFA_DM_DISC_FLAGS_W4_NTF);
+      nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.tle);
+
+      /* there is no active protocol in this state, so broadcast to all by using
+       * NFA_DM_RF_DEACTIVATE_RSP */
+      nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_RSP,
+                                      &(p_data->nfc_discover));
+
+      if (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_IDLE) {
+        nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
+        nfa_dm_start_rf_discover();
+      } else if (p_data->nfc_discover.deactivate.type ==
+                 NFA_DEACTIVATE_TYPE_DISCOVERY) {
+        nfa_dm_disc_new_state(NFA_DM_RFST_DISCOVERY);
+      } else {
+        NFA_TRACE_ERROR0("Unexpected deactivation type");
+        nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
+        nfa_dm_start_rf_discover();
+      }
+      break;
+    case NFA_DM_RF_INTF_ACTIVATED_NTF:
+      nfa_dm_disc_new_state(NFA_DM_RFST_LISTEN_ACTIVE);
+      if (nfa_dm_disc_notify_activation(&(p_data->nfc_discover)) ==
+          NFA_STATUS_FAILED) {
+        NFA_TRACE_DEBUG0(
+            "Not matched, restart discovery after receiving deactivate ntf");
+
+        /* after receiving deactivate event, restart discovery */
+        NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
+      }
+      break;
+    default:
+      NFA_TRACE_ERROR0(
+          "nfa_dm_disc_sm_listen_sleep (): Unexpected discovery event");
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_sm_lp_listen
+**
+** Description      Processing discovery events in NFA_DM_RFST_LP_LISTEN state
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_disc_sm_lp_listen(tNFA_DM_RF_DISC_SM_EVENT event,
+                                     tNFA_DM_RF_DISC_DATA* p_data) {
+  switch (event) {
+    case NFA_DM_RF_INTF_ACTIVATED_NTF:
+      nfa_dm_disc_new_state(NFA_DM_RFST_LP_ACTIVE);
+      if (nfa_dm_disc_notify_activation(&(p_data->nfc_discover)) ==
+          NFA_STATUS_FAILED) {
+        NFA_TRACE_DEBUG0("Not matched, unexpected activation");
+      }
+      break;
+
+    default:
+      NFA_TRACE_ERROR0(
+          "nfa_dm_disc_sm_lp_listen (): Unexpected discovery event");
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_sm_lp_active
+**
+** Description      Processing discovery events in NFA_DM_RFST_LP_ACTIVE state
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_disc_sm_lp_active(tNFA_DM_RF_DISC_SM_EVENT event,
+                                     tNFA_DM_RF_DISC_DATA* p_data) {
+  switch (event) {
+    case NFA_DM_RF_DEACTIVATE_NTF:
+      nfa_dm_disc_new_state(NFA_DM_RFST_LP_LISTEN);
+      nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
+                                      &(p_data->nfc_discover));
+      break;
+    default:
+      NFA_TRACE_ERROR0(
+          "nfa_dm_disc_sm_lp_active (): Unexpected discovery event");
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_sm_execute
+**
+** Description      Processing discovery related events
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_disc_sm_execute(tNFA_DM_RF_DISC_SM_EVENT event,
+                            tNFA_DM_RF_DISC_DATA* p_data) {
+#if (BT_TRACE_VERBOSE == true)
+  NFA_TRACE_DEBUG5(
+      "nfa_dm_disc_sm_execute (): state: %s (%d), event: %s(%d) disc_flags: "
+      "0x%x",
+      nfa_dm_disc_state_2_str(nfa_dm_cb.disc_cb.disc_state),
+      nfa_dm_cb.disc_cb.disc_state, nfa_dm_disc_event_2_str(event), event,
+      nfa_dm_cb.disc_cb.disc_flags);
+#else
+  NFA_TRACE_DEBUG3(
+      "nfa_dm_disc_sm_execute(): state: %d, event:%d disc_flags: 0x%x",
+      nfa_dm_cb.disc_cb.disc_state, event, nfa_dm_cb.disc_cb.disc_flags);
+#endif
+
+  switch (nfa_dm_cb.disc_cb.disc_state) {
+    /*  RF Discovery State - Idle */
+    case NFA_DM_RFST_IDLE:
+      nfa_dm_disc_sm_idle(event, p_data);
+      break;
+
+    /* RF Discovery State - Discovery */
+    case NFA_DM_RFST_DISCOVERY:
+      nfa_dm_disc_sm_discovery(event, p_data);
+      break;
+
+    /*RF Discovery State - Wait for all discoveries */
+    case NFA_DM_RFST_W4_ALL_DISCOVERIES:
+      nfa_dm_disc_sm_w4_all_discoveries(event, p_data);
+      break;
+
+    /* RF Discovery State - Wait for host selection */
+    case NFA_DM_RFST_W4_HOST_SELECT:
+      nfa_dm_disc_sm_w4_host_select(event, p_data);
+      break;
+
+    /* RF Discovery State - Poll mode activated */
+    case NFA_DM_RFST_POLL_ACTIVE:
+      nfa_dm_disc_sm_poll_active(event, p_data);
+      break;
+
+    /* RF Discovery State - listen mode activated */
+    case NFA_DM_RFST_LISTEN_ACTIVE:
+      nfa_dm_disc_sm_listen_active(event, p_data);
+      break;
+
+    /* RF Discovery State - listen mode sleep */
+    case NFA_DM_RFST_LISTEN_SLEEP:
+      nfa_dm_disc_sm_listen_sleep(event, p_data);
+      break;
+
+    /* Listening in Low Power mode    */
+    case NFA_DM_RFST_LP_LISTEN:
+      nfa_dm_disc_sm_lp_listen(event, p_data);
+      break;
+
+    /* Activated in Low Power mode    */
+    case NFA_DM_RFST_LP_ACTIVE:
+      nfa_dm_disc_sm_lp_active(event, p_data);
+      break;
+  }
+#if (BT_TRACE_VERBOSE == true)
+  NFA_TRACE_DEBUG3(
+      "nfa_dm_disc_sm_execute (): new state: %s (%d), disc_flags: 0x%x",
+      nfa_dm_disc_state_2_str(nfa_dm_cb.disc_cb.disc_state),
+      nfa_dm_cb.disc_cb.disc_state, nfa_dm_cb.disc_cb.disc_flags);
+#else
+  NFA_TRACE_DEBUG2("nfa_dm_disc_sm_execute(): new state: %d,  disc_flags: 0x%x",
+                   nfa_dm_cb.disc_cb.disc_state, nfa_dm_cb.disc_cb.disc_flags);
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_add_rf_discover
+**
+** Description      Add discovery configuration and callback function
+**
+** Returns          valid handle if success
+**
+*******************************************************************************/
+tNFA_HANDLE nfa_dm_add_rf_discover(tNFA_DM_DISC_TECH_PROTO_MASK disc_mask,
+                                   tNFA_DM_DISC_HOST_ID host_id,
+                                   tNFA_DISCOVER_CBACK* p_disc_cback) {
+  uint8_t xx;
+
+  NFA_TRACE_DEBUG2("nfa_dm_add_rf_discover ():host_id=0x%X disc_mask=0x%x",
+                   host_id, disc_mask);
+
+  for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++) {
+    if (!nfa_dm_cb.disc_cb.entry[xx].in_use) {
+      NFA_TRACE_DEBUG2(
+          "nfa_dm_add_rf_discover ():disc_mask=0x%x, cback entry:[%d]",
+          disc_mask, xx);
+      nfa_dm_cb.disc_cb.entry[xx].in_use = true;
+      nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask = disc_mask;
+      nfa_dm_cb.disc_cb.entry[xx].host_id = host_id;
+      nfa_dm_cb.disc_cb.entry[xx].p_disc_cback = p_disc_cback;
+      nfa_dm_cb.disc_cb.entry[xx].disc_flags = NFA_DM_DISC_FLAGS_NOTIFY;
+      return xx;
+    }
+  }
+
+  return NFA_HANDLE_INVALID;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_start_excl_discovery
+**
+** Description      Start exclusive RF discovery
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_start_excl_discovery(tNFA_TECHNOLOGY_MASK poll_tech_mask,
+                                 tNFA_LISTEN_CFG* p_listen_cfg,
+                                 tNFA_DISCOVER_CBACK* p_disc_cback) {
+  tNFA_DM_DISC_TECH_PROTO_MASK poll_disc_mask = 0;
+
+  NFA_TRACE_DEBUG0("nfa_dm_start_excl_discovery ()");
+
+  if (poll_tech_mask & NFA_TECHNOLOGY_MASK_A) {
+    poll_disc_mask |= NFA_DM_DISC_MASK_PA_T1T;
+    poll_disc_mask |= NFA_DM_DISC_MASK_PA_T2T;
+    poll_disc_mask |= NFA_DM_DISC_MASK_PA_ISO_DEP;
+    poll_disc_mask |= NFA_DM_DISC_MASK_PA_NFC_DEP;
+    poll_disc_mask |= NFA_DM_DISC_MASK_P_LEGACY;
+  }
+  if (poll_tech_mask & NFA_TECHNOLOGY_MASK_A_ACTIVE) {
+    poll_disc_mask |= NFA_DM_DISC_MASK_PAA_NFC_DEP;
+  }
+  if (poll_tech_mask & NFA_TECHNOLOGY_MASK_B) {
+    poll_disc_mask |= NFA_DM_DISC_MASK_PB_ISO_DEP;
+  }
+  if (poll_tech_mask & NFA_TECHNOLOGY_MASK_F) {
+    poll_disc_mask |= NFA_DM_DISC_MASK_PF_T3T;
+    poll_disc_mask |= NFA_DM_DISC_MASK_PF_NFC_DEP;
+  }
+  if (poll_tech_mask & NFA_TECHNOLOGY_MASK_F_ACTIVE) {
+    poll_disc_mask |= NFA_DM_DISC_MASK_PFA_NFC_DEP;
+  }
+  if (poll_tech_mask & NFA_TECHNOLOGY_MASK_ISO15693) {
+    poll_disc_mask |= NFA_DM_DISC_MASK_P_ISO15693;
+  }
+  if (poll_tech_mask & NFA_TECHNOLOGY_MASK_B_PRIME) {
+    poll_disc_mask |= NFA_DM_DISC_MASK_P_B_PRIME;
+  }
+  if (poll_tech_mask & NFA_TECHNOLOGY_MASK_KOVIO) {
+    poll_disc_mask |= NFA_DM_DISC_MASK_P_KOVIO;
+  }
+
+  nfa_dm_cb.disc_cb.excl_disc_entry.in_use = true;
+  nfa_dm_cb.disc_cb.excl_disc_entry.requested_disc_mask = poll_disc_mask;
+  nfa_dm_cb.disc_cb.excl_disc_entry.host_id = NFA_DM_DISC_HOST_ID_DH;
+  nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback = p_disc_cback;
+  nfa_dm_cb.disc_cb.excl_disc_entry.disc_flags = NFA_DM_DISC_FLAGS_NOTIFY;
+
+  memcpy(&nfa_dm_cb.disc_cb.excl_listen_config, p_listen_cfg,
+         sizeof(tNFA_LISTEN_CFG));
+
+  nfa_dm_disc_sm_execute(NFA_DM_RF_DISCOVER_CMD, NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_stop_excl_discovery
+**
+** Description      Stop exclusive RF discovery
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_stop_excl_discovery(void) {
+  NFA_TRACE_DEBUG0("nfa_dm_stop_excl_discovery ()");
+
+  nfa_dm_cb.disc_cb.excl_disc_entry.in_use = false;
+  nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback = NULL;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_delete_rf_discover
+**
+** Description      Remove discovery configuration and callback function
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_delete_rf_discover(tNFA_HANDLE handle) {
+  NFA_TRACE_DEBUG1("nfa_dm_delete_rf_discover () handle=0x%x", handle);
+
+  if (handle < NFA_DM_DISC_NUM_ENTRIES) {
+    nfa_dm_cb.disc_cb.entry[handle].in_use = false;
+  } else {
+    NFA_TRACE_ERROR0("Invalid discovery handle");
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_rf_discover_select
+**
+** Description      Select target, protocol and RF interface
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_rf_discover_select(uint8_t rf_disc_id, tNFA_NFC_PROTOCOL protocol,
+                               tNFA_INTF_TYPE rf_interface) {
+  tNFA_DM_DISC_SELECT_PARAMS select_params;
+  tNFA_CONN_EVT_DATA conn_evt;
+
+  NFA_TRACE_DEBUG3(
+      "nfa_dm_disc_select () rf_disc_id:0x%X, protocol:0x%X, rf_interface:0x%X",
+      rf_disc_id, protocol, rf_interface);
+
+  if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_W4_HOST_SELECT) {
+    /* state is OK: notify the status when the response is received from NFCC */
+    select_params.rf_disc_id = rf_disc_id;
+    select_params.protocol = protocol;
+    select_params.rf_interface = rf_interface;
+
+    nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_NOTIFY;
+    nfa_dm_disc_sm_execute(NFA_DM_RF_DISCOVER_SELECT_CMD,
+                           (void*)&select_params);
+  } else {
+    /* Wrong state: notify failed status right away */
+    conn_evt.status = NFA_STATUS_FAILED;
+    nfa_dm_conn_cback_event_notify(NFA_SELECT_RESULT_EVT, &conn_evt);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_rf_deactivate
+**
+** Description      Deactivate NFC link
+**
+** Returns          NFA_STATUS_OK if success
+**
+*******************************************************************************/
+tNFA_STATUS nfa_dm_rf_deactivate(tNFA_DEACTIVATE_TYPE deactivate_type) {
+  NFA_TRACE_DEBUG1("nfa_dm_rf_deactivate () deactivate_type:0x%X",
+                   deactivate_type);
+
+  if (deactivate_type == NFA_DEACTIVATE_TYPE_SLEEP) {
+    if (nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_NFC_DEP)
+      deactivate_type = NFC_DEACTIVATE_TYPE_SLEEP_AF;
+    else
+      deactivate_type = NFC_DEACTIVATE_TYPE_SLEEP;
+  }
+
+  if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_IDLE) {
+    return NFA_STATUS_FAILED;
+  } else if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_DISCOVERY) {
+    if (deactivate_type == NFA_DEACTIVATE_TYPE_DISCOVERY) {
+      if (nfa_dm_cb.disc_cb.kovio_tle.in_use) {
+        nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.kovio_tle);
+        nfa_dm_disc_kovio_timeout_cback(&nfa_dm_cb.disc_cb.kovio_tle);
+        return NFA_STATUS_OK;
+      } else {
+        /* it could be race condition. */
+        NFA_TRACE_DEBUG0("nfa_dm_rf_deactivate (): already in discovery state");
+        return NFA_STATUS_FAILED;
+      }
+    } else if (deactivate_type == NFA_DEACTIVATE_TYPE_IDLE) {
+      if (nfa_dm_cb.disc_cb.kovio_tle.in_use) {
+        nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.kovio_tle);
+        nfa_dm_disc_kovio_timeout_cback(&nfa_dm_cb.disc_cb.kovio_tle);
+      }
+      nfa_dm_disc_sm_execute(NFA_DM_RF_DEACTIVATE_CMD, (void*)&deactivate_type);
+      return NFA_STATUS_OK;
+    } else {
+      return NFA_STATUS_FAILED;
+    }
+  } else {
+#if (NXP_EXTNS == TRUE)
+    if (nfa_dm_cb.disc_cb.kovio_tle.in_use) {
+      nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.kovio_tle);
+      nfa_dm_disc_kovio_timeout_cback(&nfa_dm_cb.disc_cb.kovio_tle);
+    }
+#endif
+    nfa_dm_disc_sm_execute(NFA_DM_RF_DEACTIVATE_CMD, (void*)&deactivate_type);
+    return NFA_STATUS_OK;
+  }
+}
+
+#if (BT_TRACE_VERBOSE == true)
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_state_2_str
+**
+** Description      convert nfc discovery state to string
+**
+*******************************************************************************/
+static char* nfa_dm_disc_state_2_str(uint8_t state) {
+  switch (state) {
+    case NFA_DM_RFST_IDLE:
+      return "IDLE";
+
+    case NFA_DM_RFST_DISCOVERY:
+      return "DISCOVERY";
+
+    case NFA_DM_RFST_W4_ALL_DISCOVERIES:
+      return "W4_ALL_DISCOVERIES";
+
+    case NFA_DM_RFST_W4_HOST_SELECT:
+      return "W4_HOST_SELECT";
+
+    case NFA_DM_RFST_POLL_ACTIVE:
+      return "POLL_ACTIVE";
+
+    case NFA_DM_RFST_LISTEN_ACTIVE:
+      return "LISTEN_ACTIVE";
+
+    case NFA_DM_RFST_LISTEN_SLEEP:
+      return "LISTEN_SLEEP";
+
+    case NFA_DM_RFST_LP_LISTEN:
+      return "LP_LISTEN";
+
+    case NFA_DM_RFST_LP_ACTIVE:
+      return "LP_ACTIVE";
+  }
+  return "Unknown";
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_event_2_str
+**
+** Description      convert nfc discovery RSP/NTF to string
+**
+*******************************************************************************/
+static char* nfa_dm_disc_event_2_str(uint8_t event) {
+  switch (event) {
+    case NFA_DM_RF_DISCOVER_CMD:
+      return "DISCOVER_CMD";
+
+    case NFA_DM_RF_DISCOVER_RSP:
+      return "DISCOVER_RSP";
+
+    case NFA_DM_RF_DISCOVER_NTF:
+      return "DISCOVER_NTF";
+
+    case NFA_DM_RF_DISCOVER_SELECT_CMD:
+      return "SELECT_CMD";
+
+    case NFA_DM_RF_DISCOVER_SELECT_RSP:
+      return "SELECT_RSP";
+
+    case NFA_DM_RF_INTF_ACTIVATED_NTF:
+      return "ACTIVATED_NTF";
+
+    case NFA_DM_RF_DEACTIVATE_CMD:
+      return "DEACTIVATE_CMD";
+
+    case NFA_DM_RF_DEACTIVATE_RSP:
+      return "DEACTIVATE_RSP";
+
+    case NFA_DM_RF_DEACTIVATE_NTF:
+      return "DEACTIVATE_NTF";
+
+    case NFA_DM_LP_LISTEN_CMD:
+      return "NFA_DM_LP_LISTEN_CMD";
+
+    case NFA_DM_CORE_INTF_ERROR_NTF:
+      return "INTF_ERROR_NTF";
+  }
+  return "Unknown";
+}
+#endif /* BT_TRACE_VERBOSE */
+
+/*******************************************************************************
+**
+** Function         P2P_Prio_Logic
+**
+** Description      Implements algorithm for NFC-DEP protocol priority over
+**                  ISO-DEP protocol.
+**
+** Returns          True if success
+**
+*******************************************************************************/
+bool nfa_dm_p2p_prio_logic(uint8_t event, uint8_t* p, uint8_t event_type) {
+  if (!nfa_poll_bail_out_mode) {
+    NFA_TRACE_DEBUG0("p2p priority is running under bail out mode ONLY.");
+    return true;
+  }
+
+  if ((nfa_dm_cb.flags & NFA_DM_FLAGS_P2P_PAUSED) &&
+      (nfa_dm_cb.flags & NFA_DM_FLAGS_LISTEN_DISABLED)) {
+    NFA_TRACE_DEBUG0(
+        "returning from nfa_dm_p2p_prio_logic  Disable p2p_prio_logic");
+    return true;
+  }
+#if (NXP_EXTNS == TRUE)
+  if ((true == reconnect_in_progress) || (true == is_emvco_active)) {
+    NFA_TRACE_DEBUG0(
+        "returning from nfa_dm_p2p_prio_logic  reconnect_in_progress");
+    return true;
+  }
+  if (0x01 == appl_dta_mode_flag) {
+    /*Disable the P2P Prio Logic when DTA is running*/
+    return true;
+  }
+#endif
+  if (event == NCI_MSG_RF_DISCOVER &&
+      p2p_prio_logic_data.timer_expired == true &&
+      event_type == NFA_DM_P2P_PRIO_RSP) {
+    NFA_TRACE_DEBUG0(
+        "nfa_dm_p2p_prio_logic starting a timer for next rf intf activated "
+        "ntf");
+    nfc_start_quick_timer(&p2p_prio_logic_data.timer_list,
+                          NFC_TTYPE_P2P_PRIO_LOGIC_CLEANUP,
+                          ((uint32_t)nfa_dm_act_get_rf_disc_duration() *
+                           QUICK_TIMER_TICKS_PER_SEC) /
+                              1000);
+    return true;
+  }
+
+  if (event == NCI_MSG_RF_INTF_ACTIVATED &&
+      p2p_prio_logic_data.timer_expired == true) {
+    NFA_TRACE_DEBUG0(
+        "nfa_dm_p2p_prio_logic stopping a timer for next rf intf activated "
+        "ntf");
+    nfc_stop_quick_timer(&p2p_prio_logic_data.timer_list);
+  }
+
+  if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_DISCOVERY) {
+    uint8_t rf_disc_id = 0xFF;
+    uint8_t type = 0xFF;
+    uint8_t protocol = 0xFF;
+    uint8_t tech_mode = 0xFF;
+
+    NFA_TRACE_DEBUG0("P2P_Prio_Logic");
+
+    if (event == NCI_MSG_RF_INTF_ACTIVATED) {
+      rf_disc_id = *p++;
+      type = *p++;
+      protocol = *p++;
+      tech_mode = *p++;
+    }
+    NFA_TRACE_DEBUG1("nfa_dm_p2p_prio_logic event_type = 0x%x", event_type);
+
+#if (NXP_EXTNS == TRUE)
+    if (type == nfcFL.nfcMwFL._NCI_INTERFACE_UICC_DIRECT || type == nfcFL.nfcMwFL._NCI_INTERFACE_ESE_DIRECT) {
+      NFA_TRACE_DEBUG0("Disable the p2p prio logic RDR_SWP");
+      return true;
+    }
+#endif
+    if (event == NCI_MSG_RF_INTF_ACTIVATED && tech_mode >= 0x80) {
+      NFA_TRACE_DEBUG0(
+          "nfa_dm_p2p_prio_logic listen mode activated reset all the "
+          "nfa_dm_p2p_prio_logic variables ");
+      nfa_dm_p2p_prio_logic_cleanup();
+    }
+
+    if ((tech_mode < 0x80) && event == NCI_MSG_RF_INTF_ACTIVATED &&
+        protocol == NCI_PROTOCOL_ISO_DEP &&
+        p2p_prio_logic_data.isodep_detected == false) {
+      nfa_dm_p2p_prio_logic_cleanup();
+      p2p_prio_logic_data.isodep_detected = true;
+      p2p_prio_logic_data.first_tech_mode = tech_mode;
+      NFA_TRACE_DEBUG0("ISO-DEP Detected First Time  Resume the Polling Loop");
+      nci_snd_deactivate_cmd(NFA_DEACTIVATE_TYPE_DISCOVERY);
+      nfc_start_quick_timer(&p2p_prio_logic_data.timer_list,
+                            NFC_TTYPE_P2P_PRIO_LOGIC_DEACT_NTF_TIMEOUT,
+                            P2P_PRIO_LOGIC_DEACT_NTF_TIMEOUT);
+      return false;
+    }
+
+    else if (event == NCI_MSG_RF_INTF_ACTIVATED &&
+             protocol == NCI_PROTOCOL_ISO_DEP &&
+             p2p_prio_logic_data.isodep_detected == true &&
+             p2p_prio_logic_data.first_tech_mode != tech_mode) {
+      p2p_prio_logic_data.isodep_detected = true;
+      p2p_prio_logic_data.timer_expired = false;
+      NFA_TRACE_DEBUG0(
+          "ISO-DEP Detected Second Time Other Techmode  Resume the Polling "
+          "Loop");
+      nfc_stop_quick_timer(&p2p_prio_logic_data.timer_list);
+      nci_snd_deactivate_cmd(NFA_DEACTIVATE_TYPE_DISCOVERY);
+      nfc_start_quick_timer(&p2p_prio_logic_data.timer_list,
+                            NFC_TTYPE_P2P_PRIO_LOGIC_DEACT_NTF_TIMEOUT,
+                            P2P_PRIO_LOGIC_DEACT_NTF_TIMEOUT);
+      return false;
+    }
+
+    else if (event == NCI_MSG_RF_INTF_ACTIVATED &&
+             protocol == NCI_PROTOCOL_ISO_DEP &&
+             p2p_prio_logic_data.isodep_detected == true &&
+             p2p_prio_logic_data.timer_expired == true) {
+      NFA_TRACE_DEBUG0(
+          "ISO-DEP Detected TimerExpired, Final Notifying the Event");
+      nfc_stop_quick_timer(&p2p_prio_logic_data.timer_list);
+      nfa_dm_p2p_prio_logic_cleanup();
+    }
+
+    else if (event == NCI_MSG_RF_INTF_ACTIVATED &&
+             protocol == NCI_PROTOCOL_ISO_DEP &&
+             p2p_prio_logic_data.isodep_detected == true &&
+             p2p_prio_logic_data.first_tech_mode == tech_mode) {
+      NFA_TRACE_DEBUG0(
+          "ISO-DEP Detected Same Techmode, Final Notifying the Event");
+      nfc_stop_quick_timer(&p2p_prio_logic_data.timer_list);
+      NFA_TRACE_DEBUG0("P2P_Stop_Timer");
+      nfa_dm_p2p_prio_logic_cleanup();
+    }
+
+    else if (event == NCI_MSG_RF_INTF_ACTIVATED &&
+             protocol != NCI_PROTOCOL_ISO_DEP &&
+             p2p_prio_logic_data.isodep_detected == true) {
+      NFA_TRACE_DEBUG0(
+          "ISO-DEP Not Detected  Giving Priority for other Technology");
+      nfc_stop_quick_timer(&p2p_prio_logic_data.timer_list);
+      NFA_TRACE_DEBUG0("P2P_Stop_Timer");
+      nfa_dm_p2p_prio_logic_cleanup();
+    }
+
+    else if (event == NCI_MSG_RF_DEACTIVATE &&
+             p2p_prio_logic_data.isodep_detected == true &&
+             p2p_prio_logic_data.timer_expired == false &&
+             event_type == NFA_DM_P2P_PRIO_RSP) {
+      NFA_TRACE_DEBUG0("NFA_DM_RF_DEACTIVATE_RSP");
+      return false;
+    }
+
+    else if (event == NCI_MSG_RF_DEACTIVATE &&
+             p2p_prio_logic_data.isodep_detected == true &&
+             p2p_prio_logic_data.timer_expired == false &&
+             event_type == NFA_DM_P2P_PRIO_NTF) {
+      NFA_TRACE_DEBUG0("NFA_DM_RF_DEACTIVATE_NTF");
+      if (p2p_prio_logic_data.timer_list.in_use) {
+        nfc_stop_quick_timer(&p2p_prio_logic_data.timer_list);
+      }
+      nfc_start_quick_timer(&p2p_prio_logic_data.timer_list,
+                            NFC_TTYPE_P2P_PRIO_RESPONSE,
+                            ((uint32_t)160 * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+
+      NFA_TRACE_DEBUG0("P2P_Start_Timer");
+
+      return false;
+    }
+  }
+
+  NFA_TRACE_DEBUG0("returning true");
+  return true;
+}
+
+#if (NXP_EXTNS == TRUE)
+void nfa_dm_p2p_prio_logic_disable() {
+  if (p2p_prio_logic_data.timer_list.in_use)
+    nfc_stop_quick_timer(&p2p_prio_logic_data.timer_list);
+  memset(&p2p_prio_logic_data, 0x00, sizeof(nfa_dm_p2p_prio_logic_t));
+}
+
+void NFA_SetReconnectState(bool flag) {
+  reconnect_in_progress = flag;
+  NFA_TRACE_DEBUG1("NFA_SetReconnectState = 0x%x", reconnect_in_progress);
+}
+void NFA_SetEmvCoState(bool flag) {
+  is_emvco_active = flag;
+  NFA_TRACE_DEBUG1("NFA_SetEmvCoState = 0x%x", is_emvco_active);
+}
+#endif
+/*******************************************************************************
+**
+** Function         p2p_prio_logic_timeout
+**
+** Description      Callback function for p2p timer
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_p2p_timer_event() {
+  NFA_TRACE_DEBUG0("P2P_Timer_timeout NFC-DEP Not Discovered!!");
+
+  p2p_prio_logic_data.timer_expired = 1;
+
+  if (p2p_prio_logic_data.isodep_detected == 1) {
+    NFA_TRACE_DEBUG0("Deactivate and Restart RF discovery");
+    nci_snd_deactivate_cmd(NFC_DEACTIVATE_TYPE_IDLE);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_p2p_prio_logic_cleanup
+**
+** Description      Callback function for p2p prio logic cleanup timer
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_p2p_prio_logic_cleanup() {
+  NFA_TRACE_DEBUG0(
+      " p2p_prio_logic_cleanup timeout no activated intf notification "
+      "received ");
+  memset(&p2p_prio_logic_data, 0x00, sizeof(nfa_dm_p2p_prio_logic_t));
+}
+
+void nfa_dm_deact_ntf_timeout() {
+  memset(&p2p_prio_logic_data, 0x00, sizeof(nfa_dm_p2p_prio_logic_t));
+  nfc_ncif_cmd_timeout();
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_send_tag_deselect_cmd
+**
+** Description      Send command to send tag in sleep state
+**
+** Returns          void
+**
++*******************************************************************************/
+static void nfa_dm_send_tag_deselect_cmd(tNFA_NFC_PROTOCOL protocol) {
+  NFC_HDR* p_msg;
+  uint8_t* p;
+
+  NFA_TRACE_DEBUG0("nfa_dm_send_tag_deselect_cmd!!");
+  p_msg = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (p_msg) {
+    if(protocol == NFC_PROTOCOL_ISO_DEP)
+    {
+      /* send one byte of 0xc2 as as deselect command to Tag */
+      p_msg->len = 1;
+      p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+      p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+      *p = TAG_DESELECT_CMD;
+    }
+    else if(protocol == NFC_PROTOCOL_T2T)
+    {
+      p_msg->len = sizeof(T2T_SLP_REQ);
+      p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+      p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+      memcpy((uint8_t*)(p_msg + 1) + p_msg->offset, T2T_SLP_REQ, p_msg->len);
+    }
+    else
+    {
+      GKI_freebuf(p_msg);
+      return;
+    }
+
+    NFC_SendData(NFC_RF_CONN_ID, p_msg);
+  }
+}
diff --git a/src/nfa/dm/nfa_dm_main.c b/src/nfa/dm/nfa_dm_main.c
new file mode 100644
index 0000000..688de0e
--- /dev/null
+++ b/src/nfa/dm/nfa_dm_main.c
@@ -0,0 +1,648 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the main implementation file for the NFA device manager.
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include "nfa_api.h"
+#include "nfa_sys.h"
+#include "nfa_dm_int.h"
+#include "nfa_sys_int.h"
+#if (NXP_EXTNS == TRUE)
+#include "nfc_int.h"
+#endif
+
+/*****************************************************************************
+** Constants and types
+*****************************************************************************/
+static const tNFA_SYS_REG nfa_dm_sys_reg = {nfa_dm_sys_enable, nfa_dm_evt_hdlr,
+                                            nfa_dm_sys_disable,
+                                            nfa_dm_proc_nfcc_power_mode};
+
+#if (NXP_EXTNS == TRUE)
+tNFA_DM_CB nfa_dm_cb;
+#else
+tNFA_DM_CB nfa_dm_cb = {
+    0,
+};
+#endif
+
+#define NFA_DM_NUM_ACTIONS (NFA_DM_MAX_EVT & 0x00ff)
+
+/* type for action functions */
+typedef bool (*tNFA_DM_ACTION)(tNFA_DM_MSG* p_data);
+
+/* action function list */
+const tNFA_DM_ACTION nfa_dm_action[] = {
+    /* device manager local device API events */
+    nfa_dm_enable,                   /* NFA_DM_API_ENABLE_EVT                */
+    nfa_dm_disable,                  /* NFA_DM_API_DISABLE_EVT               */
+    nfa_dm_set_config,               /* NFA_DM_API_SET_CONFIG_EVT            */
+    nfa_dm_get_config,               /* NFA_DM_API_GET_CONFIG_EVT            */
+    nfa_dm_act_request_excl_rf_ctrl, /* NFA_DM_API_REQUEST_EXCL_RF_CTRL_EVT  */
+    nfa_dm_act_release_excl_rf_ctrl, /* NFA_DM_API_RELEASE_EXCL_RF_CTRL_EVT  */
+    nfa_dm_act_enable_polling,       /* NFA_DM_API_ENABLE_POLLING_EVT        */
+    nfa_dm_act_disable_polling,      /* NFA_DM_API_DISABLE_POLLING_EVT       */
+    nfa_dm_act_enable_listening,     /* NFA_DM_API_ENABLE_LISTENING_EVT      */
+    nfa_dm_act_disable_listening,    /* NFA_DM_API_DISABLE_LISTENING_EVT     */
+#if (NXP_EXTNS == TRUE)
+    nfa_dm_act_disable_passive_listening, /* NFA_DM_API_DISABLE_PASSIVE_LISTENING_EVT
+                                             */
+#endif
+    nfa_dm_act_pause_p2p,            /* NFA_DM_API_PAUSE_P2P_EVT             */
+    nfa_dm_act_resume_p2p,           /* NFA_DM_API_RESUME_P2P_EVT            */
+    nfa_dm_act_send_raw_frame,       /* NFA_DM_API_RAW_FRAME_EVT             */
+    nfa_dm_set_p2p_listen_tech,      /* NFA_DM_API_SET_P2P_LISTEN_TECH_EVT   */
+    nfa_dm_act_start_rf_discovery,   /* NFA_DM_API_START_RF_DISCOVERY_EVT    */
+    nfa_dm_act_stop_rf_discovery,    /* NFA_DM_API_STOP_RF_DISCOVERY_EVT     */
+    nfa_dm_act_set_rf_disc_duration, /* NFA_DM_API_SET_RF_DISC_DURATION_EVT  */
+    nfa_dm_act_select,               /* NFA_DM_API_SELECT_EVT                */
+    nfa_dm_act_update_rf_params,     /* NFA_DM_API_UPDATE_RF_PARAMS_EVT      */
+    nfa_dm_act_deactivate,           /* NFA_DM_API_DEACTIVATE_EVT            */
+    nfa_dm_act_power_off_sleep,      /* NFA_DM_API_POWER_OFF_SLEEP_EVT       */
+    nfa_dm_ndef_reg_hdlr,            /* NFA_DM_API_REG_NDEF_HDLR_EVT         */
+    nfa_dm_ndef_dereg_hdlr,          /* NFA_DM_API_DEREG_NDEF_HDLR_EVT       */
+    nfa_dm_act_reg_vsc,              /* NFA_DM_API_REG_VSC_EVT               */
+    nfa_dm_act_send_vsc,             /* NFA_DM_API_SEND_VSC_EVT              */
+    nfa_dm_act_disable_timeout       /* NFA_DM_TIMEOUT_DISABLE_EVT           */
+#if (NXP_EXTNS == TRUE)
+    ,
+    nfa_dm_act_send_nxp /* NFA_DM_API_SEND_NXP_EVT              */
+#endif
+    ,nfa_dm_set_power_sub_state /* NFA_DM_API_SET_POWER_SUB_STATE_EVT  */
+};
+
+/*****************************************************************************
+** Local function prototypes
+*****************************************************************************/
+#if (BT_TRACE_VERBOSE == true)
+static char* nfa_dm_evt_2_str(uint16_t event);
+#endif
+#if (NXP_EXTNS == TRUE)
+void nfa_dm_init_cfgs(phNxpNci_getCfg_info_t* mGetCfg_info);
+#endif
+/*******************************************************************************
+**
+** Function         nfa_dm_init
+**
+** Description      Initialises the NFC device manager
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_init(void) {
+  NFA_TRACE_DEBUG0("nfa_dm_init ()");
+  memset(&nfa_dm_cb, 0, sizeof(tNFA_DM_CB));
+  nfa_dm_cb.poll_disc_handle = NFA_HANDLE_INVALID;
+  nfa_dm_cb.disc_cb.disc_duration = NFA_DM_DISC_DURATION_POLL;
+  nfa_dm_cb.nfcc_pwr_mode = NFA_DM_PWR_MODE_FULL;
+#if (NXP_EXTNS == TRUE)
+  nfa_dm_cb.selected_uicc_id = UICC1_HOST;
+#endif
+  /* register message handler on NFA SYS */
+  nfa_sys_register(NFA_ID_DM, &nfa_dm_sys_reg);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_evt_hdlr
+**
+** Description      Event handling function for DM
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+bool nfa_dm_evt_hdlr(NFC_HDR* p_msg) {
+  bool freebuf = true;
+  uint16_t event = p_msg->event & 0x00ff;
+
+#if (BT_TRACE_VERBOSE == true)
+  NFA_TRACE_EVENT2("nfa_dm_evt_hdlr event: %s (0x%02x)",
+                   nfa_dm_evt_2_str(event), event);
+#else
+  NFA_TRACE_EVENT1("nfa_dm_evt_hdlr event: 0x%x", event);
+#endif
+
+  /* execute action functions */
+  if (event < NFA_DM_NUM_ACTIONS) {
+    freebuf = (*nfa_dm_action[event])((tNFA_DM_MSG*)p_msg);
+  }
+  return freebuf;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_sys_disable
+**
+** Description      This function is called after all subsystems have been
+**                  disabled.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_sys_disable(void) {
+  /* Disable the DM sub-system */
+  /* If discovery state is not IDLE or DEACTIVATED and graceful disable, */
+  /* then we need to deactivate link or stop discovery                   */
+
+  if (nfa_sys_is_graceful_disable()) {
+    if ((nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_IDLE) &&
+        ((nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_DISABLING) == 0)) {
+      /* discovery is not started */
+      nfa_dm_disable_complete();
+    } else {
+      /* probably waiting to be disabled */
+      NFA_TRACE_WARNING2("DM disc_state state = %d disc_flags:0x%x",
+                         nfa_dm_cb.disc_cb.disc_state,
+                         nfa_dm_cb.disc_cb.disc_flags);
+    }
+
+  } else {
+    nfa_dm_disable_complete();
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_is_protocol_supported
+**
+** Description      Check if protocol is supported by RW module
+**
+** Returns          true if protocol is supported by NFA
+**
+*******************************************************************************/
+bool nfa_dm_is_protocol_supported(tNFC_PROTOCOL protocol, uint8_t sel_res) {
+  return ((protocol == NFC_PROTOCOL_T1T) ||
+          ((protocol == NFC_PROTOCOL_T2T) &&
+           (sel_res == NFC_SEL_RES_NFC_FORUM_T2T)) ||
+          (protocol == NFC_PROTOCOL_T3T) ||
+          (protocol == NFC_PROTOCOL_ISO_DEP) ||
+          (protocol == NFC_PROTOCOL_NFC_DEP) || (protocol == NFC_PROTOCOL_15693)
+#if (NXP_EXTNS == TRUE)
+          || (protocol == NFC_PROTOCOL_T3BT)
+#endif
+              );
+}
+/*******************************************************************************
+**
+** Function         nfa_dm_is_active
+**
+** Description      check if all modules of NFA is done with enable process and
+**                  NFA is not restoring NFCC.
+**
+** Returns          true, if NFA_DM_ENABLE_EVT is reported and it is not
+**                  restoring NFCC
+**
+*******************************************************************************/
+bool nfa_dm_is_active(void) {
+  NFA_TRACE_DEBUG1("nfa_dm_is_active () flags:0x%x", nfa_dm_cb.flags);
+  if ((nfa_dm_cb.flags & NFA_DM_FLAGS_DM_IS_ACTIVE) &&
+      ((nfa_dm_cb.flags &
+        (NFA_DM_FLAGS_ENABLE_EVT_PEND | NFA_DM_FLAGS_NFCC_IS_RESTORING |
+         NFA_DM_FLAGS_POWER_OFF_SLEEP)) == 0)) {
+    return true;
+  } else
+    return false;
+}
+/*******************************************************************************
+**
+** Function         nfa_dm_check_set_config
+**
+** Description      Update config parameters only if it's different from NFCC
+**
+**
+** Returns          tNFA_STATUS
+**
+*******************************************************************************/
+tNFA_STATUS nfa_dm_check_set_config(uint8_t tlv_list_len, uint8_t* p_tlv_list,
+                                    bool app_init) {
+#if (NXP_EXTNS == TRUE)
+  uint8_t type, len, *p_value, * p_stored = NULL, max_len = 0;
+#else
+  uint8_t type, len, *p_value, *p_stored, max_len;
+#endif
+  uint8_t xx = 0, updated_len = 0, *p_cur_len;
+  bool update;
+  tNFC_STATUS nfc_status;
+  uint32_t cur_bit;
+
+  NFA_TRACE_DEBUG1("nfa_dm_check_set_config () tlv_len=%d", tlv_list_len);
+
+  /* We only allow 32 pending SET_CONFIGs */
+  if (nfa_dm_cb.setcfg_pending_num >= NFA_DM_SETCONFIG_PENDING_MAX) {
+    NFA_TRACE_ERROR0(
+        "nfa_dm_check_set_config () error: pending number of SET_CONFIG "
+        "exceeded");
+    return NFA_STATUS_FAILED;
+  }
+
+  while (tlv_list_len - xx >= 2) /* at least type and len */
+  {
+    update = false;
+    type = *(p_tlv_list + xx);
+    len = *(p_tlv_list + xx + 1);
+    p_value = p_tlv_list + xx + 2;
+    p_cur_len = NULL;
+
+    switch (type) {
+      /*
+      **  Poll F Configuration
+      */
+      case NFC_PMID_PF_RC:
+        p_stored = nfa_dm_cb.params.pf_rc;
+        max_len = NCI_PARAM_LEN_PF_RC;
+        break;
+      case NFC_PMID_TOTAL_DURATION:
+        p_stored = nfa_dm_cb.params.total_duration;
+        max_len = NCI_PARAM_LEN_TOTAL_DURATION;
+        break;
+
+      /*
+      **  Listen A Configuration
+      */
+      case NFC_PMID_LA_BIT_FRAME_SDD:
+        p_stored = nfa_dm_cb.params.la_bit_frame_sdd;
+        max_len = NCI_PARAM_LEN_LA_BIT_FRAME_SDD;
+        p_cur_len = &nfa_dm_cb.params.la_bit_frame_sdd_len;
+        break;
+      case NFC_PMID_LA_PLATFORM_CONFIG:
+        p_stored = nfa_dm_cb.params.la_platform_config;
+        max_len = NCI_PARAM_LEN_LA_PLATFORM_CONFIG;
+        p_cur_len = &nfa_dm_cb.params.la_platform_config_len;
+        break;
+      case NFC_PMID_LA_SEL_INFO:
+        p_stored = nfa_dm_cb.params.la_sel_info;
+        max_len = NCI_PARAM_LEN_LA_SEL_INFO;
+        p_cur_len = &nfa_dm_cb.params.la_sel_info_len;
+        break;
+      case NFC_PMID_LA_NFCID1:
+        p_stored = nfa_dm_cb.params.la_nfcid1;
+        max_len = NCI_NFCID1_MAX_LEN;
+        p_cur_len = &nfa_dm_cb.params.la_nfcid1_len;
+        break;
+      case NFC_PMID_LA_HIST_BY:
+        p_stored = nfa_dm_cb.params.la_hist_by;
+        max_len = NCI_MAX_HIS_BYTES_LEN;
+        p_cur_len = &nfa_dm_cb.params.la_hist_by_len;
+        break;
+
+      /*
+      **  Listen B Configuration
+      */
+      case NFC_PMID_LB_SENSB_INFO:
+#if (NXP_EXTNS == TRUE)
+        if (app_init == true) {
+#endif
+          p_stored = nfa_dm_cb.params.lb_sensb_info;
+          max_len = NCI_PARAM_LEN_LB_SENSB_INFO;
+          p_cur_len = &nfa_dm_cb.params.lb_sensb_info_len;
+#if (NXP_EXTNS == TRUE)
+        } else {
+          update = false;
+        }
+#endif
+        break;
+      case NFC_PMID_LB_NFCID0:
+        p_stored = nfa_dm_cb.params.lb_nfcid0;
+        max_len = NCI_PARAM_LEN_LB_NFCID0;
+        p_cur_len = &nfa_dm_cb.params.lb_nfcid0_len;
+        break;
+      case NFC_PMID_LB_APPDATA:
+        p_stored = nfa_dm_cb.params.lb_appdata;
+        max_len = NCI_PARAM_LEN_LB_APPDATA;
+        p_cur_len = &nfa_dm_cb.params.lb_appdata_len;
+        break;
+      case NFC_PMID_LB_ADC_FO:
+        p_stored = nfa_dm_cb.params.lb_adc_fo;
+        max_len = NCI_PARAM_LEN_LB_ADC_FO;
+        p_cur_len = &nfa_dm_cb.params.lb_adc_fo_len;
+        break;
+      case NFC_PMID_LB_H_INFO:
+        p_stored = nfa_dm_cb.params.lb_h_info;
+        max_len = NCI_MAX_ATTRIB_LEN;
+        p_cur_len = &nfa_dm_cb.params.lb_h_info_len;
+        break;
+
+      /*
+      **  Listen F Configuration
+      */
+      case NFC_PMID_LF_PROTOCOL:
+        p_stored = nfa_dm_cb.params.lf_protocol;
+        max_len = NCI_PARAM_LEN_LF_PROTOCOL;
+        p_cur_len = &nfa_dm_cb.params.lf_protocol_len;
+        break;
+      case NFC_PMID_LF_T3T_FLAGS2:
+        p_stored = nfa_dm_cb.params.lf_t3t_flags2;
+        max_len = NCI_PARAM_LEN_LF_T3T_FLAGS2;
+        p_cur_len = &nfa_dm_cb.params.lf_t3t_flags2_len;
+        break;
+#if (NXP_EXTNS != TRUE)
+      case NFC_PMID_LF_T3T_PMM:
+        p_stored = nfa_dm_cb.params.lf_t3t_pmm;
+        max_len = NCI_PARAM_LEN_LF_T3T_PMM;
+        break;
+      /*
+      **  ISO-DEP and NFC-DEP Configuration
+      */
+      case NFC_PMID_FWI:
+        p_stored = nfa_dm_cb.params.fwi;
+        max_len = NCI_PARAM_LEN_FWI;
+        break;
+#endif
+      case NFC_PMID_WT:
+        p_stored = nfa_dm_cb.params.wt;
+        max_len = NCI_PARAM_LEN_WT;
+        break;
+      case NFC_PMID_ATR_REQ_GEN_BYTES:
+        p_stored = nfa_dm_cb.params.atr_req_gen_bytes;
+        max_len = NCI_MAX_GEN_BYTES_LEN;
+        p_cur_len = &nfa_dm_cb.params.atr_req_gen_bytes_len;
+        break;
+      case NFC_PMID_ATR_RES_GEN_BYTES:
+        p_stored = nfa_dm_cb.params.atr_res_gen_bytes;
+        max_len = NCI_MAX_GEN_BYTES_LEN;
+        p_cur_len = &nfa_dm_cb.params.atr_res_gen_bytes_len;
+        break;
+      default:
+        /*
+        **  Listen F Configuration
+        */
+        if ((type >= NFC_PMID_LF_T3T_ID1) &&
+            (type < NFC_PMID_LF_T3T_ID1 + NFA_CE_LISTEN_INFO_MAX)) {
+          p_stored = nfa_dm_cb.params.lf_t3t_id[type - NFC_PMID_LF_T3T_ID1];
+          max_len = NCI_PARAM_LEN_LF_T3T_ID(NFC_GetNCIVersion());
+        } else {
+          /* we don't stored this config items */
+          update = true;
+          p_stored = NULL;
+        }
+        break;
+    }
+
+    if ((p_stored) && (len <= max_len)) {
+      if (p_cur_len) {
+        if (*p_cur_len != len) {
+          *p_cur_len = len;
+          update = true;
+        } else if (memcmp(p_value, p_stored, len)) {
+          update = true;
+        }
+#if (NXP_EXTNS == TRUE)
+        else if (appl_dta_mode_flag &&
+                 app_init) { /*In DTA mode, config update is forced so that
+                              length of config params
+                              (i.e update_len) is updated accordingly even for
+                              setconfig have only one tlv*/
+          update = true;
+        }
+#endif
+      } else if (len == max_len) /* fixed length */
+      {
+        if (memcmp(p_value, p_stored, len)) {
+          update = true;
+        }
+#if (NXP_EXTNS == TRUE)
+        else if (appl_dta_mode_flag &&
+                 app_init) { /*In DTA mode, config update is forced so that
+                              length of config params
+                              (i.e update_len) is updated accordingly even for
+                              setconfig have only one tlv*/
+          update = true;
+        }
+#endif
+      }
+    }
+
+    if (update) {
+      /* we don't store this type */
+      if (p_stored) {
+        memcpy(p_stored, p_value, len);
+      }
+
+      /* If need to change TLV in the original list. (Do not modify list if
+       * app_init) */
+      if ((updated_len != xx) && (!app_init)) {
+        memcpy(p_tlv_list + updated_len, p_tlv_list + xx, (len + 2));
+      }
+      updated_len += (len + 2);
+    }
+    xx += len + 2; /* move to next TLV */
+  }
+
+  /* If any TVLs to update, or if the SetConfig was initiated by the
+   * application, then send the SET_CONFIG command */
+  /*if (updated_len || app_init) app_init is true when setconfig is invoked from
+  application. For extra setconfigs from internal to
+  stack, updated_len will be true. To avoid extra setconfigs from stack which is
+  NOT required by DTA, condition is modified*/
+  if
+#if (NXP_EXTNS == TRUE)
+      ((
+#endif
+           (updated_len || app_init)
+#if (NXP_EXTNS == TRUE)
+           && (appl_dta_mode_flag == 0x00 ||
+               (nfa_dm_cb.eDtaMode & 0x0F) == NFA_DTA_HCEF_MODE)) ||
+       ((appl_dta_mode_flag) && (app_init)))
+#endif
+  {
+#if (NXP_EXTNS == TRUE)
+    NFA_TRACE_DEBUG1("nfa_dm_check_set_config () updated_len=%d", updated_len);
+    if (!updated_len) {
+      return NFA_STATUS_OK;
+    }
+#endif
+    nfc_status = NFC_SetConfig(updated_len, p_tlv_list);
+    if (nfc_status == NFC_STATUS_OK) {
+      if ((nfa_dm_cb.eDtaMode & 0x0F) == NFA_DTA_HCEF_MODE) {
+        nfa_dm_cb.eDtaMode &= ~NFA_DTA_HCEF_MODE;
+        nfa_dm_cb.eDtaMode |= NFA_DTA_DEFAULT_MODE;
+      }
+      /* Keep track of whether we will need to notify NFA_DM_SET_CONFIG_EVT on
+       * NFC_SET_CONFIG_REVT */
+
+      /* Get the next available bit offset for this setconfig (based on how many
+       * SetConfigs are outstanding) */
+      cur_bit = (uint32_t)(1 << nfa_dm_cb.setcfg_pending_num);
+
+      /* If setconfig is due to NFA_SetConfig: then set the bit
+       * (NFA_DM_SET_CONFIG_EVT needed on NFC_SET_CONFIG_REVT) */
+      if (app_init) {
+        nfa_dm_cb.setcfg_pending_mask |= cur_bit;
+      }
+      /* Otherwise setconfig is internal: clear the bit (NFA_DM_SET_CONFIG_EVT
+         not needed on NFC_SET_CONFIG_REVT) */
+      else {
+        nfa_dm_cb.setcfg_pending_mask &= ~cur_bit;
+      }
+
+      /* Increment setcfg_pending counter */
+      nfa_dm_cb.setcfg_pending_num++;
+    }
+    return (nfc_status);
+
+  } else {
+    return NFA_STATUS_OK;
+  }
+}
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         nfa_dm_init_cfgs
+**
+** Description      Initialise config params
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_dm_init_cfgs(phNxpNci_getCfg_info_t* mGetCfg_info) {
+  NFA_TRACE_DEBUG1("%s Enter", __func__);
+
+  memcpy(&nfa_dm_cb.params.atr_req_gen_bytes, mGetCfg_info->atr_req_gen_bytes,
+         mGetCfg_info->atr_req_gen_bytes_len);
+  nfa_dm_cb.params.atr_req_gen_bytes_len =
+      (int)mGetCfg_info->atr_req_gen_bytes_len;
+  memcpy(&nfa_dm_cb.params.atr_res_gen_bytes, mGetCfg_info->atr_res_gen_bytes,
+         mGetCfg_info->atr_res_gen_bytes_len);
+  nfa_dm_cb.params.atr_res_gen_bytes_len =
+      (int)mGetCfg_info->atr_res_gen_bytes_len;
+  memcpy(&nfa_dm_cb.params.total_duration, mGetCfg_info->total_duration,
+         mGetCfg_info->total_duration_len);
+  memcpy(&nfa_dm_cb.params.wt, mGetCfg_info->pmid_wt,
+         mGetCfg_info->pmid_wt_len);
+}
+#endif
+#if (BT_TRACE_VERBOSE == true)
+/*******************************************************************************
+**
+** Function         nfa_dm_nfc_revt_2_str
+**
+** Description      convert nfc revt to string
+**
+*******************************************************************************/
+static char* nfa_dm_evt_2_str(uint16_t event) {
+  switch (NFA_SYS_EVT_START(NFA_ID_DM) | event) {
+    case NFA_DM_API_ENABLE_EVT:
+      return "NFA_DM_API_ENABLE_EVT";
+
+    case NFA_DM_API_DISABLE_EVT:
+      return "NFA_DM_API_DISABLE_EVT";
+
+    case NFA_DM_API_SET_CONFIG_EVT:
+      return "NFA_DM_API_SET_CONFIG_EVT";
+
+    case NFA_DM_API_GET_CONFIG_EVT:
+      return "NFA_DM_API_GET_CONFIG_EVT";
+
+    case NFA_DM_API_REQUEST_EXCL_RF_CTRL_EVT:
+      return "NFA_DM_API_REQUEST_EXCL_RF_CTRL_EVT";
+
+    case NFA_DM_API_RELEASE_EXCL_RF_CTRL_EVT:
+      return "NFA_DM_API_RELEASE_EXCL_RF_CTRL_EVT";
+
+    case NFA_DM_API_ENABLE_POLLING_EVT:
+      return "NFA_DM_API_ENABLE_POLLING_EVT";
+
+    case NFA_DM_API_DISABLE_POLLING_EVT:
+      return "NFA_DM_API_DISABLE_POLLING_EVT";
+
+    case NFA_DM_API_ENABLE_LISTENING_EVT:
+      return "NFA_DM_API_ENABLE_LISTENING_EVT";
+
+    case NFA_DM_API_DISABLE_LISTENING_EVT:
+      return "NFA_DM_API_DISABLE_LISTENING_EVT";
+
+#if (NXP_EXTNS == TRUE)
+    case NFA_DM_API_DISABLE_PASSIVE_LISTENING_EVT:
+      return "NFA_DM_API_DISABLE_PASSIVE_LISTENING_EVT";
+#endif
+
+    case NFA_DM_API_PAUSE_P2P_EVT:
+      return "NFA_DM_API_PAUSE_P2P_EVT";
+
+    case NFA_DM_API_RESUME_P2P_EVT:
+      return "NFA_DM_API_RESUME_P2P_EVT";
+
+    case NFA_DM_API_RAW_FRAME_EVT:
+      return "NFA_DM_API_RAW_FRAME_EVT";
+
+    case NFA_DM_API_SET_P2P_LISTEN_TECH_EVT:
+      return "NFA_DM_API_SET_P2P_LISTEN_TECH_EVT";
+
+    case NFA_DM_API_START_RF_DISCOVERY_EVT:
+      return "NFA_DM_API_START_RF_DISCOVERY_EVT";
+
+    case NFA_DM_API_STOP_RF_DISCOVERY_EVT:
+      return "NFA_DM_API_STOP_RF_DISCOVERY_EVT";
+
+    case NFA_DM_API_SET_RF_DISC_DURATION_EVT:
+      return "NFA_DM_API_SET_RF_DISC_DURATION_EVT";
+
+    case NFA_DM_API_SELECT_EVT:
+      return "NFA_DM_API_SELECT_EVT";
+
+    case NFA_DM_API_UPDATE_RF_PARAMS_EVT:
+      return "NFA_DM_API_UPDATE_RF_PARAMS_EVT";
+
+    case NFA_DM_API_DEACTIVATE_EVT:
+      return "NFA_DM_API_DEACTIVATE_EVT";
+
+    case NFA_DM_API_POWER_OFF_SLEEP_EVT:
+      return "NFA_DM_API_POWER_OFF_SLEEP_EVT";
+
+    case NFA_DM_API_REG_NDEF_HDLR_EVT:
+      return "NFA_DM_API_REG_NDEF_HDLR_EVT";
+
+    case NFA_DM_API_DEREG_NDEF_HDLR_EVT:
+      return "NFA_DM_API_DEREG_NDEF_HDLR_EVT";
+
+    case NFA_DM_TIMEOUT_DISABLE_EVT:
+      return "NFA_DM_TIMEOUT_DISABLE_EVT";
+
+    case NFA_DM_API_SET_POWER_SUB_STATE_EVT:
+      return "NFA_DM_API_SET_POWER_SUB_STATE_EVT";
+  }
+
+  return "Unknown or Vendor Specific";
+}
+#endif /* BT_TRACE_VERBOSE */
diff --git a/src/nfa/dm/nfa_dm_ndef.c b/src/nfa/dm/nfa_dm_ndef.c
new file mode 100644
index 0000000..eeba9e8
--- /dev/null
+++ b/src/nfa/dm/nfa_dm_ndef.c
@@ -0,0 +1,528 @@
+/******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Handle ndef messages
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_sys.h"
+#include "nfa_api.h"
+#include "nfa_dm_int.h"
+#include "nfa_sys_int.h"
+#include "nfc_api.h"
+#include "ndef_utils.h"
+
+/*******************************************************************************
+* URI Well-known-type prefixes
+*******************************************************************************/
+const uint8_t* nfa_dm_ndef_wkt_uri_str_tbl[] = {
+    NULL,                                          /* 0x00 */
+    (const uint8_t*) "http://www.",                /* 0x01 */
+    (const uint8_t*) "https://www.",               /* 0x02 */
+    (const uint8_t*) "http://",                    /* 0x03 */
+    (const uint8_t*) "https://",                   /* 0x04 */
+    (const uint8_t*) "tel:",                       /* 0x05 */
+    (const uint8_t*) "mailto:",                    /* 0x06 */
+    (const uint8_t*) "ftp://anonymous:anonymous@", /* 0x07 */
+    (const uint8_t*) "ftp://ftp.",                 /* 0x08 */
+    (const uint8_t*) "ftps://",                    /* 0x09 */
+    (const uint8_t*) "sftp://",                    /* 0x0A */
+    (const uint8_t*) "smb://",                     /* 0x0B */
+    (const uint8_t*) "nfs://",                     /* 0x0C */
+    (const uint8_t*) "ftp://",                     /* 0x0D */
+    (const uint8_t*) "dav://",                     /* 0x0E */
+    (const uint8_t*) "news:",                      /* 0x0F */
+    (const uint8_t*) "telnet://",                  /* 0x10 */
+    (const uint8_t*) "imap:",                      /* 0x11 */
+    (const uint8_t*) "rtsp://",                    /* 0x12 */
+    (const uint8_t*) "urn:",                       /* 0x13 */
+    (const uint8_t*) "pop:",                       /* 0x14 */
+    (const uint8_t*) "sip:",                       /* 0x15 */
+    (const uint8_t*) "sips:",                      /* 0x16 */
+    (const uint8_t*) "tftp:",                      /* 0x17 */
+    (const uint8_t*) "btspp://",                   /* 0x18 */
+    (const uint8_t*) "btl2cap://",                 /* 0x19 */
+    (const uint8_t*) "btgoep://",                  /* 0x1A */
+    (const uint8_t*) "tcpobex://",                 /* 0x1B */
+    (const uint8_t*) "irdaobex://",                /* 0x1C */
+    (const uint8_t*) "file://",                    /* 0x1D */
+    (const uint8_t*) "urn:epc:id:",                /* 0x1E */
+    (const uint8_t*) "urn:epc:tag:",               /* 0x1F */
+    (const uint8_t*) "urn:epc:pat:",               /* 0x20 */
+    (const uint8_t*) "urn:epc:raw:",               /* 0x21 */
+    (const uint8_t*) "urn:epc:",                   /* 0x22 */
+    (const uint8_t*) "urn:nfc:"                    /* 0x23 */
+};
+#define NFA_DM_NDEF_WKT_URI_STR_TBL_SIZE \
+  (sizeof(nfa_dm_ndef_wkt_uri_str_tbl) / sizeof(uint8_t*))
+
+/*******************************************************************************
+**
+** Function         nfa_dm_ndef_dereg_hdlr_by_handle
+**
+** Description      Deregister NDEF record type handler
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+void nfa_dm_ndef_dereg_hdlr_by_handle(tNFA_HANDLE ndef_type_handle) {
+  tNFA_DM_CB* p_cb = &nfa_dm_cb;
+  uint16_t hdlr_idx;
+  hdlr_idx = (uint16_t)(ndef_type_handle & NFA_HANDLE_MASK);
+
+  if (p_cb->p_ndef_handler[hdlr_idx]) {
+    GKI_freebuf(p_cb->p_ndef_handler[hdlr_idx]);
+    p_cb->p_ndef_handler[hdlr_idx] = NULL;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_ndef_dereg_all
+**
+** Description      Deregister all NDEF record type handlers (called during
+**                  shutdown(.
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void nfa_dm_ndef_dereg_all(void) {
+  tNFA_DM_CB* p_cb = &nfa_dm_cb;
+  uint32_t i;
+
+  for (i = 0; i < NFA_NDEF_MAX_HANDLERS; i++) {
+    /* If this is a free slot, then remember it */
+    if (p_cb->p_ndef_handler[i] != NULL) {
+      GKI_freebuf(p_cb->p_ndef_handler[i]);
+      p_cb->p_ndef_handler[i] = NULL;
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_ndef_reg_hdlr
+**
+** Description      Register NDEF record type handler
+**
+** Returns          true if message buffer is to be freed by caller
+**
+*******************************************************************************/
+bool nfa_dm_ndef_reg_hdlr(tNFA_DM_MSG* p_data) {
+  tNFA_DM_CB* p_cb = &nfa_dm_cb;
+  uint32_t hdlr_idx, i;
+  tNFA_DM_API_REG_NDEF_HDLR* p_reg_info = (tNFA_DM_API_REG_NDEF_HDLR*)p_data;
+  tNFA_NDEF_REGISTER ndef_register;
+
+  /* If registering default handler, check to see if one is already registered
+   */
+  if (p_reg_info->tnf == NFA_TNF_DEFAULT) {
+    /* check if default handler is already registered */
+    if (p_cb->p_ndef_handler[NFA_NDEF_DEFAULT_HANDLER_IDX]) {
+      NFA_TRACE_WARNING0("Default NDEF handler being changed.");
+
+      /* Free old registration info */
+      nfa_dm_ndef_dereg_hdlr_by_handle(
+          (tNFA_HANDLE)NFA_NDEF_DEFAULT_HANDLER_IDX);
+    }
+    NFA_TRACE_DEBUG0("Default NDEF handler successfully registered.");
+    hdlr_idx = NFA_NDEF_DEFAULT_HANDLER_IDX;
+  }
+  /* Get available entry in ndef_handler table, and check if requested type is
+     already registered */
+  else {
+    hdlr_idx = NFA_HANDLE_INVALID;
+
+    /* Check if this type is already registered */
+    for (i = (NFA_NDEF_DEFAULT_HANDLER_IDX + 1); i < NFA_NDEF_MAX_HANDLERS;
+         i++) {
+      /* If this is a free slot, then remember it */
+      if (p_cb->p_ndef_handler[i] == NULL) {
+        hdlr_idx = i;
+        break;
+      }
+    }
+  }
+
+  if (hdlr_idx != NFA_HANDLE_INVALID) {
+    /* Update the table */
+    p_cb->p_ndef_handler[hdlr_idx] = p_reg_info;
+
+    p_reg_info->ndef_type_handle =
+        (tNFA_HANDLE)(NFA_HANDLE_GROUP_NDEF_HANDLER | hdlr_idx);
+
+    ndef_register.ndef_type_handle = p_reg_info->ndef_type_handle;
+    ndef_register.status = NFA_STATUS_OK;
+
+    NFA_TRACE_DEBUG1("NDEF handler successfully registered. Handle=0x%08x",
+                     p_reg_info->ndef_type_handle);
+    (*(p_reg_info->p_ndef_cback))(NFA_NDEF_REGISTER_EVT, (void*)&ndef_register);
+
+    /* indicate that we will free message buffer when type_handler is
+     * deregistered */
+    return false;
+  } else {
+    /* Error */
+    NFA_TRACE_ERROR0("NDEF handler failed to register.");
+    ndef_register.ndef_type_handle = NFA_HANDLE_INVALID;
+    ndef_register.status = NFA_STATUS_FAILED;
+    (*(p_reg_info->p_ndef_cback))(NFA_NDEF_REGISTER_EVT, (void*)&ndef_register);
+
+    return true;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_ndef_dereg_hdlr
+**
+** Description      Deregister NDEF record type handler
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_dm_ndef_dereg_hdlr(tNFA_DM_MSG* p_data) {
+  tNFA_DM_API_DEREG_NDEF_HDLR* p_dereginfo =
+      (tNFA_DM_API_DEREG_NDEF_HDLR*)p_data;
+
+  /* Make sure this is a NDEF_HDLR handle */
+  if (((p_dereginfo->ndef_type_handle & NFA_HANDLE_GROUP_MASK) !=
+       NFA_HANDLE_GROUP_NDEF_HANDLER) ||
+      ((p_dereginfo->ndef_type_handle & NFA_HANDLE_MASK) >=
+       NFA_NDEF_MAX_HANDLERS)) {
+    NFA_TRACE_ERROR1("Invalid handle for NDEF type handler: 0x%08x",
+                     p_dereginfo->ndef_type_handle);
+  } else {
+    nfa_dm_ndef_dereg_hdlr_by_handle(p_dereginfo->ndef_type_handle);
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_ndef_find_next_handler
+**
+** Description      Find next ndef handler for a given record type
+**
+** Returns          void
+**
+*******************************************************************************/
+tNFA_DM_API_REG_NDEF_HDLR* nfa_dm_ndef_find_next_handler(
+    tNFA_DM_API_REG_NDEF_HDLR* p_init_handler, uint8_t tnf,
+    uint8_t* p_type_name, uint8_t type_name_len, uint8_t* p_payload,
+    uint32_t payload_len) {
+  tNFA_DM_CB* p_cb = &nfa_dm_cb;
+  uint8_t i;
+
+  /* if init_handler is NULL, then start with the first non-default handler */
+  if (!p_init_handler)
+    i = NFA_NDEF_DEFAULT_HANDLER_IDX + 1;
+  else {
+    /* Point to handler index after p_init_handler */
+    i = (p_init_handler->ndef_type_handle & NFA_HANDLE_MASK) + 1;
+  }
+
+  /* Look for next handler */
+  for (; i < NFA_NDEF_MAX_HANDLERS; i++) {
+    /* Check if TNF matches */
+    if ((p_cb->p_ndef_handler[i]) && (p_cb->p_ndef_handler[i]->tnf == tnf) &&
+        (p_type_name != NULL)) {
+      /* TNF matches. */
+      /* If handler is for a specific URI type, check if type is WKT URI, */
+      /* and that the URI prefix abrieviation for this handler matches */
+      if (p_cb->p_ndef_handler[i]->flags & NFA_NDEF_FLAGS_WKT_URI) {
+        /* This is a handler for a specific URI type */
+        /* Check if this recurd is WKT URI */
+        if ((p_payload) && (type_name_len == 1) && (*p_type_name == 'U')) {
+          /* Check if URI prefix abrieviation matches */
+          if ((payload_len > 1) &&
+              (p_payload[0] == p_cb->p_ndef_handler[i]->uri_id)) {
+            /* URI prefix abrieviation matches */
+            /* If handler does not specify an absolute URI, then match found. */
+            /* If absolute URI, then compare URI for match (skip over uri_id in
+             * ndef payload) */
+            if ((p_cb->p_ndef_handler[i]->uri_id != NFA_NDEF_URI_ID_ABSOLUTE) ||
+                (memcmp(&p_payload[1], p_cb->p_ndef_handler[i]->name,
+                        p_cb->p_ndef_handler[i]->name_len) == 0)) {
+              /* Handler found. */
+              break;
+            }
+          }
+          /* Check if handler is absolute URI but NDEF is using prefix
+             abrieviation */
+          else if ((p_cb->p_ndef_handler[i]->uri_id ==
+                    NFA_NDEF_URI_ID_ABSOLUTE) &&
+                   (p_payload[0] != NFA_NDEF_URI_ID_ABSOLUTE)) {
+            /* Handler is absolute URI but NDEF is using prefix abrieviation.
+             * Compare URI prefix */
+            if ((p_payload[0] < NFA_DM_NDEF_WKT_URI_STR_TBL_SIZE) &&
+                (memcmp(p_cb->p_ndef_handler[i]->name,
+                        (char*)nfa_dm_ndef_wkt_uri_str_tbl[p_payload[0]],
+                        p_cb->p_ndef_handler[i]->name_len) == 0)) {
+              /* Handler found. */
+              break;
+            }
+          }
+          /* Check if handler is using prefix abrieviation, but NDEF is using
+             absolute URI */
+          else if ((p_cb->p_ndef_handler[i]->uri_id !=
+                    NFA_NDEF_URI_ID_ABSOLUTE) &&
+                   (p_payload[0] == NFA_NDEF_URI_ID_ABSOLUTE)) {
+            /* Handler is using prefix abrieviation, but NDEF is using absolute
+             * URI. Compare URI prefix */
+            if ((p_cb->p_ndef_handler[i]->uri_id <
+                 NFA_DM_NDEF_WKT_URI_STR_TBL_SIZE) &&
+                (memcmp(&p_payload[1],
+                        nfa_dm_ndef_wkt_uri_str_tbl[p_cb->p_ndef_handler[i]
+                                                        ->uri_id],
+                        strlen((const char*)nfa_dm_ndef_wkt_uri_str_tbl
+                                   [p_cb->p_ndef_handler[i]->uri_id])) == 0)) {
+              /* Handler found. */
+              break;
+            }
+          }
+        }
+      }
+      /* Not looking for specific URI. Check if type_name for this handler
+         matches the NDEF record's type_name */
+      else if (p_cb->p_ndef_handler[i]->name_len == type_name_len) {
+        if ((type_name_len == 0) || (memcmp(p_cb->p_ndef_handler[i]->name,
+                                            p_type_name, type_name_len) == 0)) {
+          /* Handler found */
+          break;
+        }
+      }
+    }
+  }
+
+  if (i < NFA_NDEF_MAX_HANDLERS)
+    return (p_cb->p_ndef_handler[i]);
+  else
+    return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_ndef_clear_notified_flag
+**
+** Description      Clear 'whole_message_notified' flag for all the handlers
+**                  (flag used to indicate that this handler has already
+**                  handled the entire incoming NDEF message)
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_ndef_clear_notified_flag(void) {
+  tNFA_DM_CB* p_cb = &nfa_dm_cb;
+  uint8_t i;
+
+  for (i = 0; i < NFA_NDEF_MAX_HANDLERS; i++) {
+    if (p_cb->p_ndef_handler[i]) {
+      p_cb->p_ndef_handler[i]->flags &= ~NFA_NDEF_FLAGS_WHOLE_MESSAGE_NOTIFIED;
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_ndef_handle_message
+**
+** Description      Handle incoming ndef message
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_ndef_handle_message(tNFA_STATUS status, uint8_t* p_msg_buf,
+                                uint32_t len) {
+  tNFA_DM_CB* p_cb = &nfa_dm_cb;
+  tNDEF_STATUS ndef_status;
+  uint8_t* p_rec, *p_ndef_start, *p_type, *p_payload, *p_rec_end;
+  uint32_t payload_len;
+  uint8_t tnf, type_len, rec_hdr_flags, id_len;
+  tNFA_DM_API_REG_NDEF_HDLR* p_handler;
+  tNFA_NDEF_DATA ndef_data;
+  uint8_t rec_count = 0;
+  bool record_handled, entire_message_handled;
+
+  NFA_TRACE_DEBUG3("nfa_dm_ndef_handle_message status=%i, msgbuf=%08x, len=%i",
+                   status, p_msg_buf, len);
+
+  if (status != NFA_STATUS_OK) {
+    /* If problem reading NDEF message, then exit (no action required) */
+    return;
+  }
+
+  /* If in exclusive RF mode is activer, then route NDEF message callback
+   * registered with NFA_StartExclusiveRfControl */
+  if ((p_cb->flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE) &&
+      (p_cb->p_excl_ndef_cback)) {
+    /* No ndef-handler handle, since this callback is not from
+     * RegisterNDefHandler */
+    ndef_data.ndef_type_handle = 0;
+    ndef_data.p_data = p_msg_buf;
+    ndef_data.len = len;
+    (*p_cb->p_excl_ndef_cback)(NFA_NDEF_DATA_EVT, (void*)&ndef_data);
+    return;
+  }
+
+  /* Handle zero length - notify default handler */
+  if (len == 0) {
+    p_handler = p_cb->p_ndef_handler[NFA_NDEF_DEFAULT_HANDLER_IDX];
+    if (p_handler != NULL) {
+      NFA_TRACE_DEBUG0(
+          "Notifying default handler of zero-length NDEF message...");
+      ndef_data.ndef_type_handle = p_handler->ndef_type_handle;
+      ndef_data.p_data = NULL; /* Start of record */
+      ndef_data.len = 0;
+      (*p_handler->p_ndef_cback)(NFA_NDEF_DATA_EVT, (void*)&ndef_data);
+    }
+    return;
+  }
+
+  /* Validate the NDEF message */
+  ndef_status = NDEF_MsgValidate(p_msg_buf, len, true);
+  if (ndef_status != NDEF_OK) {
+    NFA_TRACE_ERROR1("Received invalid NDEF message. NDEF status=0x%x",
+                     ndef_status);
+    return;
+  }
+
+  /* NDEF message received from backgound polling. Pass the NDEF message to the
+   * NDEF handlers */
+
+  /* New NDEF message. Clear 'notified' flag for all the handlers */
+  nfa_dm_ndef_clear_notified_flag();
+
+  /* Indicate that no handler has handled this entire NDEF message (e.g.
+   * connection-handover handler *) */
+  entire_message_handled = false;
+
+  /* Get first record in message */
+  p_rec = p_ndef_start = p_msg_buf;
+
+  /* Check each record in the NDEF message */
+  while (p_rec != NULL) {
+    /* Get record type */
+    p_type = NDEF_RecGetType(p_rec, &tnf, &type_len);
+
+    /* Indicate record not handled yet */
+    record_handled = false;
+
+    /* Get pointer to record payload */
+    p_payload = NDEF_RecGetPayload(p_rec, &payload_len);
+
+    /* Find first handler for this type */
+    p_handler = nfa_dm_ndef_find_next_handler(NULL, tnf, p_type, type_len,
+                                              p_payload, payload_len);
+    if (p_handler == NULL) {
+      /* Not a registered NDEF type. Use default handler */
+      p_handler = p_cb->p_ndef_handler[NFA_NDEF_DEFAULT_HANDLER_IDX];
+      if (p_handler != NULL) {
+        NFA_TRACE_DEBUG0("No handler found. Using default handler...");
+      }
+    }
+
+    while (p_handler) {
+      /* If handler is for whole NDEF message, and it has already been notified,
+       * then skip notification */
+      if (p_handler->flags & NFA_NDEF_FLAGS_WHOLE_MESSAGE_NOTIFIED) {
+        /* Look for next handler */
+        p_handler = nfa_dm_ndef_find_next_handler(
+            p_handler, tnf, p_type, type_len, p_payload, payload_len);
+        continue;
+      }
+
+      /* Get pointer to record payload */
+      NFA_TRACE_DEBUG1("Calling ndef type handler (%x)",
+                       p_handler->ndef_type_handle);
+
+      ndef_data.ndef_type_handle = p_handler->ndef_type_handle;
+      ndef_data.p_data = p_rec; /* Start of record */
+
+      /* Calculate length of NDEF record */
+      if (p_payload != NULL)
+        ndef_data.len = payload_len + (uint32_t)(p_payload - p_rec);
+      else {
+        /* If no payload, calculate length of ndef record header */
+        p_rec_end = p_rec;
+
+        /* First byte is the header flags */
+        rec_hdr_flags = *p_rec_end++;
+
+        /* Next byte is the type field length */
+        type_len = *p_rec_end++;
+
+        /* Next is the payload length (1 or 4 bytes) */
+        if (rec_hdr_flags & NDEF_SR_MASK) {
+          p_rec_end++;
+        } else {
+          p_rec_end += 4;
+        }
+
+        /* ID field Length */
+        if (rec_hdr_flags & NDEF_IL_MASK)
+          id_len = *p_rec_end++;
+        else
+          id_len = 0;
+        p_rec_end += id_len;
+
+        ndef_data.len = (uint32_t)(p_rec_end - p_rec);
+      }
+
+      /* If handler wants entire ndef message, then pass pointer to start of
+       * message and  */
+      /* set 'notified' flag so handler won't get notified on subsequent records
+       * for this */
+      /* NDEF message. */
+      if (p_handler->flags & NFA_NDEF_FLAGS_HANDLE_WHOLE_MESSAGE) {
+        ndef_data.p_data = p_ndef_start; /* Start of NDEF message */
+        ndef_data.len = len;
+        p_handler->flags |= NFA_NDEF_FLAGS_WHOLE_MESSAGE_NOTIFIED;
+
+        /* Indicate that at least one handler has received entire NDEF message
+         */
+        entire_message_handled = true;
+      }
+
+      /* Notify NDEF type handler */
+      (*p_handler->p_ndef_cback)(NFA_NDEF_DATA_EVT, (void*)&ndef_data);
+
+      /* Indicate that at lease one handler has received this record */
+      record_handled = true;
+
+      /* Look for next handler */
+      p_handler = nfa_dm_ndef_find_next_handler(
+          p_handler, tnf, p_type, type_len, p_payload, payload_len);
+    }
+
+    /* Check if at least one handler was notified of this record (only happens
+     * if no default handler was register) */
+    if ((!record_handled) && (!entire_message_handled)) {
+      /* Unregistered NDEF record type; no default handler */
+      NFA_TRACE_WARNING1("Unhandled NDEF record (#%i)", rec_count);
+    }
+
+    rec_count++;
+    p_rec = NDEF_MsgGetNextRec(p_rec);
+  }
+}
diff --git a/src/nfa/ee/nfa_ee_act.c b/src/nfa/ee/nfa_ee_act.c
new file mode 100644
index 0000000..2b46d69
--- /dev/null
+++ b/src/nfa/ee/nfa_ee_act.c
@@ -0,0 +1,3973 @@
+/******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the action functions for NFA-EE
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_sys.h"
+#include "nfa_api.h"
+#include "nfa_dm_int.h"
+#include "nfa_sys_int.h"
+#include "nfc_api.h"
+#include "nfa_ee_int.h"
+#include "nci_hmsgs.h"
+#if (NXP_EXTNS == TRUE)
+#include "nfa_hci_int.h"
+#endif
+#include <config.h>
+
+/* the de-bounce timer:
+ * The NFA-EE API functions are called to set the routing and VS configuration.
+ * When this timer expires, the configuration is sent to NFCC all at once.
+ * This is the timeout value for the de-bounce timer. */
+#ifndef NFA_EE_ROUT_TIMEOUT_VAL
+#define NFA_EE_ROUT_TIMEOUT_VAL 1000
+#endif
+
+/* the following 2 tables convert the technology mask in API and control block
+ * to the command for NFCC */
+const uint8_t nfa_ee_tech_mask_list[NFA_EE_NUM_TECH] = {
+    NFA_TECHNOLOGY_MASK_A, NFA_TECHNOLOGY_MASK_B, NFA_TECHNOLOGY_MASK_F};
+
+const uint8_t nfa_ee_tech_list[NFA_EE_NUM_TECH] = {
+    NFC_RF_TECHNOLOGY_A, NFC_RF_TECHNOLOGY_B, NFC_RF_TECHNOLOGY_F};
+
+/* the following 2 tables convert the protocol mask in API and control block to
+ * the command for NFCC */
+static void add_route_tech_proto_tlv(uint8_t** pp, uint8_t tlv_type,
+                                     uint8_t nfcee_id, uint8_t pwr_cfg,
+                                     uint8_t tech_proto) {
+  *(*pp)++ = tlv_type;
+  *(*pp)++ = 3;
+  *(*pp)++ = nfcee_id;
+  *(*pp)++ = pwr_cfg;
+  *(*pp)++ = tech_proto;
+}
+
+static void add_route_aid_tlv(uint8_t** pp, uint8_t* pa, uint8_t aid_rt_loc,
+                              uint8_t pwr_cfg, uint8_t tag) {
+  pa++;                /* EMV tag */
+  uint8_t len = *pa++; /* aid_len */
+  *(*pp)++ = tag;
+  *(*pp)++ = len + 2;
+  *(*pp)++ = aid_rt_loc;
+  *(*pp)++ = pwr_cfg;
+  /* copy the AID */
+  memcpy(*pp, pa, len);
+  *pp += len;
+}
+const uint8_t nfa_ee_proto_mask_list[NFA_EE_NUM_PROTO] = {
+    NFA_PROTOCOL_MASK_T1T, NFA_PROTOCOL_MASK_T2T, NFA_PROTOCOL_MASK_T3T,
+    NFA_PROTOCOL_MASK_ISO_DEP, NFA_PROTOCOL_MASK_NFC_DEP
+#if (NXP_EXTNS == TRUE)
+    ,
+    NFC_PROTOCOL_MASK_ISO7816
+#endif
+};
+
+const uint8_t nfa_ee_proto_list[NFA_EE_NUM_PROTO] = {
+    NFC_PROTOCOL_T1T, NFC_PROTOCOL_T2T, NFC_PROTOCOL_T3T, NFC_PROTOCOL_ISO_DEP,
+    NFC_PROTOCOL_NFC_DEP
+#if (NXP_EXTNS == TRUE)
+    ,
+    NFC_PROTOCOL_ISO7816
+#endif
+};
+
+#if (NXP_EXTNS == TRUE)
+static uint8_t* proto_route_buff;
+static uint8_t* tech_route_buff;
+static uint8_t* proto_pp;
+static uint8_t* tech_pp;
+static uint8_t proto_tlv_ctr;
+static uint8_t tech_tlv_ctr;
+/* Ex: num of proto= 6, proto_mask =5 and num of EEs 4, total  size = (6x5x4) */
+#define NFA_EE_PROTO_BUFF_SIZE \
+  (NFA_EE_NUM_PROTO * NFA_EE_PROTO_ROUTE_ENTRY_SIZE * NFA_EE_MAX_EE_SUPPORTED)
+/* Ex: num of tech =3 , tech_mask =5 and num of EEs 4, total  size = (3x5x4) */
+#define NFA_EE_TECH_BUFF_SIZE \
+  (NFA_EE_NUM_TECH * NFA_EE_TECH_ROUTE_ENTRY_SIZE * NFA_EE_MAX_EE_SUPPORTED)
+#endif /* - Routing entries optimization */
+
+#if (NXP_EXTNS == TRUE)
+uint8_t NFA_REMOVE_ALL_AID[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+uint8_t NFA_REMOVE_ALL_APDU[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF};
+uint8_t nfa_ee_ce_route_strict_disable = 0x01;
+bool gNfaProvisionMode =
+    false; /* to know if device is set to provision mode or not */
+uint8_t nfa_ee_ce_p61_active = 0x00;
+static uint16_t max_routing_table_size;
+static uint16_t max_aid_config_length;
+static uint16_t max_aid_entries;
+#endif
+
+static void nfa_ee_report_discover_req_evt(void);
+static void nfa_ee_build_discover_req_evt(tNFA_EE_DISCOVER_REQ* p_evt_data);
+void nfa_ee_check_set_routing(uint16_t new_size, int* p_max_len, uint8_t* p,
+                              int* p_cur_offset);
+/*******************************************************************************
+**
+** Function         nfa_ee_trace_aid
+**
+** Description      trace AID
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_ee_trace_aid(char* p_str, uint8_t id, uint8_t aid_len,
+                             uint8_t* p) {
+  int len = aid_len;
+  int xx, yy = 0;
+  char buff[100];
+
+  buff[0] = 0;
+  if (aid_len > NFA_MAX_AID_LEN) {
+    NFA_TRACE_ERROR2("aid_len: %d exceeds max(%d)", aid_len, NFA_MAX_AID_LEN);
+    len = NFA_MAX_AID_LEN;
+  }
+  for (xx = 0; xx < len; xx++) {
+    yy += snprintf(&buff[yy], 100, "%02x ", *p);
+    p++;
+  }
+  NFA_TRACE_DEBUG4("%s id:0x%x len=%d aid:%s", p_str, id, aid_len, buff);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_trace_apdu
+**
+** Description      trace AID
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_ee_trace_apdu(char* p_str, tNFA_EE_API_ADD_APDU* p_apdu) {
+  int apdu_len = p_apdu->apdu_len;
+  int mask_len = p_apdu->mask_len;
+  int xx, yy = 0;
+  char apdu[125];
+  char mask[125];
+  apdu[0] = 0;
+  mask[0] = 0;
+  uint8_t* p;
+  if (apdu_len > NFA_MAX_APDU_DATA_LEN) {
+    NFA_TRACE_ERROR2("apdu_len: %d exceeds max(%d)", apdu_len, NFA_MAX_APDU_DATA_LEN);
+    apdu_len = NFA_MAX_APDU_DATA_LEN;
+    p_apdu->apdu_len = apdu_len;
+  }
+
+  if (mask_len > NFA_MAX_APDU_MASK_LEN) {
+    NFA_TRACE_ERROR2("mask_len: %d exceeds max(%d)", mask_len, NFA_MAX_APDU_MASK_LEN);
+    mask_len = NFA_MAX_APDU_MASK_LEN;
+    p_apdu->mask_len = mask_len;
+  }
+
+  p =  p_apdu->p_apdu;
+  for (xx = 0; xx < apdu_len; xx++) {
+    yy += snprintf(&apdu[yy], 125, "%02x ", *p);
+    p++;
+  }
+
+  p =  p_apdu->p_mask;
+  yy = 0;
+  for (xx = 0; xx < mask_len; xx++) {
+    yy += snprintf(&mask[yy], 125, "%02x ", *p);
+    p++;
+  }
+  NFA_TRACE_DEBUG6("%s id:0x%x apdu_len=%d apdu:%s mask_len=%d mask:%s", p_str, p_apdu->nfcee_id, apdu_len, apdu,mask_len,mask);
+}
+/*******************************************************************************
+**
+** Function         nfa_ee_update_route_size
+**
+** Description      Update the size required for technology and protocol routing
+**                  of the given NFCEE ID.
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_ee_update_route_size(tNFA_EE_ECB* p_cb) {
+  int xx;
+  uint8_t power_cfg = 0;
+
+  p_cb->size_mask = 0;
+  /* add the Technology based routing */
+  for (xx = 0; xx < NFA_EE_NUM_TECH; xx++) {
+    power_cfg = 0;
+    if (p_cb->tech_switch_on & nfa_ee_tech_mask_list[xx])
+      power_cfg |= NCI_ROUTE_PWR_STATE_ON;
+    if (p_cb->tech_switch_off & nfa_ee_tech_mask_list[xx])
+      power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF;
+    if (p_cb->tech_battery_off & nfa_ee_tech_mask_list[xx])
+      power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF;
+    if (power_cfg) {
+      /* 5 = 1 (tag) + 1 (len) + 1(nfcee_id) + 1(power cfg) + 1 (techonogy) */
+      p_cb->size_mask += 5;
+    }
+  }
+
+  /* add the Protocol based routing */
+  for (xx = 0; xx < NFA_EE_NUM_PROTO; xx++) {
+    power_cfg = 0;
+    if (p_cb->proto_switch_on & nfa_ee_proto_mask_list[xx])
+      power_cfg |= NCI_ROUTE_PWR_STATE_ON;
+    if (p_cb->proto_switch_off & nfa_ee_proto_mask_list[xx])
+      power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF;
+    if (p_cb->proto_battery_off & nfa_ee_proto_mask_list[xx])
+      power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF;
+    if (power_cfg) {
+      /* 5 = 1 (tag) + 1 (len) + 1(nfcee_id) + 1(power cfg) + 1 (protocol) */
+      p_cb->size_mask += 5;
+    }
+  }
+  NFA_TRACE_DEBUG2("nfa_ee_update_route_size nfcee_id:0x%x size_mask:%d",
+                   p_cb->nfcee_id, p_cb->size_mask);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_update_route_apdu_size
+**
+** Description      Update the size required for APDU routing
+**                  of the given NFCEE ID.
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_ee_update_route_apdu_size(tNFA_EE_ECB* p_cb) {
+  uint8_t* pa, len;
+  int start_offset;
+  int xx;
+
+  p_cb->size_apdu = 0;
+  if (p_cb->apdu_pattern_entries) {
+    start_offset = 0;
+    for (xx = 0; xx < p_cb->apdu_pattern_entries; xx++) {
+      /* add one APDU entry */
+      if (p_cb->apdu_rt_info[xx] & NFA_EE_AE_ROUTE) {
+        pa = &p_cb->apdu_cfg[start_offset];
+        pa++;        /* EMV tag */
+        len = *pa++; /* apdu_len */
+        /* 4 = 1 (tag) + 1 (len) + 1(nfcee_id) + 1(power cfg) */
+        p_cb->size_apdu += 4;
+        p_cb->size_apdu += len;
+      }
+      start_offset += p_cb->apdu_len[xx];
+    }
+  }
+  NFA_TRACE_DEBUG2("nfa_ee_update_route_apdu_size nfcee_id:0x%x size_apdu:%d",
+                   p_cb->nfcee_id, p_cb->size_apdu);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_update_route_aid_size
+**
+** Description      Update the size required for AID routing
+**                  of the given NFCEE ID.
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_ee_update_route_aid_size(tNFA_EE_ECB* p_cb) {
+  uint8_t* pa, len;
+  int start_offset;
+  int xx;
+
+  p_cb->size_aid = 0;
+  if (p_cb->aid_entries) {
+    start_offset = 0;
+    for (xx = 0; xx < p_cb->aid_entries; xx++) {
+      /* add one AID entry */
+      if (p_cb->aid_rt_info[xx] & NFA_EE_AE_ROUTE) {
+        pa = &p_cb->aid_cfg[start_offset];
+        pa++;        /* EMV tag */
+        len = *pa++; /* aid_len */
+        /* 4 = 1 (tag) + 1 (len) + 1(nfcee_id) + 1(power cfg) */
+        p_cb->size_aid += 4;
+        p_cb->size_aid += len;
+      }
+      start_offset += p_cb->aid_len[xx];
+    }
+  }
+  NFA_TRACE_DEBUG2("nfa_ee_update_route_aid_size nfcee_id:0x%x size_aid:%d",
+                   p_cb->nfcee_id, p_cb->size_aid);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_total_lmrt_size
+**
+** Description      the total listen mode routing table size
+**
+** Returns          uint16_t
+**
+*******************************************************************************/
+static uint16_t nfa_ee_total_lmrt_size(void) {
+  int xx;
+  uint16_t lmrt_size = 0;
+  tNFA_EE_ECB* p_cb;
+
+  p_cb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH];
+  lmrt_size += p_cb->size_mask;
+  lmrt_size += p_cb->size_aid;
+  lmrt_size += p_cb->size_apdu;
+  p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1];
+  for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb--) {
+    if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE) {
+      lmrt_size += p_cb->size_mask;
+      lmrt_size += p_cb->size_aid;
+      lmrt_size += p_cb->size_apdu;
+    }
+  }
+  NFA_TRACE_DEBUG1("nfa_ee_total_lmrt_size size:%d", lmrt_size);
+  return lmrt_size;
+}
+
+static void nfa_ee_add_tech_route_to_ecb(tNFA_EE_ECB* p_cb, uint8_t* pp,
+                                         uint8_t* p, uint8_t* ps,
+                                         int* p_cur_offset) {
+  uint8_t num_tlv = *ps;
+
+  /* add the Technology based routing */
+  for (int xx = 0; xx < NFA_EE_NUM_TECH; xx++) {
+    uint8_t power_cfg = 0;
+    if (p_cb->tech_switch_on & nfa_ee_tech_mask_list[xx])
+      power_cfg |= NCI_ROUTE_PWR_STATE_ON;
+    if (p_cb->tech_switch_off & nfa_ee_tech_mask_list[xx])
+      power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF;
+    if (p_cb->tech_battery_off & nfa_ee_tech_mask_list[xx])
+      power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF;
+    if (power_cfg & NCI_ROUTE_PWR_STATE_ON) {
+       if (p_cb->tech_screen_lock & nfa_ee_tech_mask_list[xx])
+          power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_ON_LOCK();
+       if (p_cb->tech_screen_off & nfa_ee_tech_mask_list[xx])
+          power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_OFF_UNLOCK();
+       if (p_cb->tech_screen_off_lock & nfa_ee_tech_mask_list[xx])
+          power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_OFF_LOCK();
+       }
+    if (power_cfg) {
+      add_route_tech_proto_tlv(&pp, NFC_ROUTE_TAG_TECH, p_cb->nfcee_id,
+                               power_cfg, nfa_ee_tech_list[xx]);
+      num_tlv++;
+      if (power_cfg != NCI_ROUTE_PWR_STATE_ON)
+        nfa_ee_cb.ee_cfged |= NFA_EE_CFGED_OFF_ROUTING;
+    }
+  }
+
+  /* update the num_tlv and current offset */
+  uint8_t entry_size = (uint8_t)(pp - p);
+  *p_cur_offset += entry_size;
+  *ps = num_tlv;
+}
+
+static void nfa_ee_add_proto_route_to_ecb(tNFA_EE_ECB* p_cb, uint8_t* pp,
+                                          uint8_t* p, uint8_t* ps,
+                                          int* p_cur_offset) {
+  uint8_t num_tlv = *ps;
+
+  /* add the Protocol based routing */
+  for (int xx = 0; xx < NFA_EE_NUM_PROTO; xx++) {
+    uint8_t power_cfg = 0, proto_tag = 0;
+    if (p_cb->proto_switch_on & nfa_ee_proto_mask_list[xx])
+      power_cfg |= NCI_ROUTE_PWR_STATE_ON;
+    if (p_cb->proto_switch_off & nfa_ee_proto_mask_list[xx])
+      power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF;
+    if (p_cb->proto_battery_off & nfa_ee_proto_mask_list[xx])
+      power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF;
+    if (power_cfg) {
+      /* Applying Route Block for ISO DEP Protocol, so that AIDs
+       * which are not in the routing table can also be blocked */
+      if (nfa_ee_proto_mask_list[xx] == NFA_PROTOCOL_MASK_ISO_DEP||nfa_ee_proto_mask_list[xx] == NFC_PROTOCOL_MASK_ISO7816) {
+        proto_tag = NFC_ROUTE_TAG_PROTO | nfa_ee_cb.route_block_control;
+
+        /* Enable screen on lock power state for ISO-DEP protocol to
+           enable HCE screen lock */
+       if (p_cb->nfcee_id == NFC_DH_ID)
+          power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_ON_LOCK();
+      else
+      {
+        if (p_cb->proto_screen_lock & nfa_ee_proto_mask_list[xx])
+           power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_ON_LOCK();
+        if (p_cb->proto_screen_off & nfa_ee_proto_mask_list[xx])
+           power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_OFF_UNLOCK();
+        if (p_cb->proto_screen_off_lock & nfa_ee_proto_mask_list[xx])
+           power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_OFF_LOCK();
+       }
+      } else {
+        proto_tag = NFC_ROUTE_TAG_PROTO;
+      }
+
+      add_route_tech_proto_tlv(&pp, proto_tag, p_cb->nfcee_id, power_cfg,
+                               nfa_ee_proto_list[xx]);
+      num_tlv++;
+      if (power_cfg != NCI_ROUTE_PWR_STATE_ON)
+        nfa_ee_cb.ee_cfged |= NFA_EE_CFGED_OFF_ROUTING;
+    }
+  }
+
+  /* add NFC-DEP routing to HOST */
+  if (p_cb->nfcee_id == NFC_DH_ID) {
+    add_route_tech_proto_tlv(&pp, NFC_ROUTE_TAG_PROTO, NFC_DH_ID,
+                             NCI_ROUTE_PWR_STATE_ON, NFC_PROTOCOL_NFC_DEP);
+
+    num_tlv++;
+    NFA_TRACE_DEBUG1("%s - NFC DEP added for DH!!!", __func__);
+  }
+  /* update the num_tlv and current offset */
+  uint8_t entry_size = (uint8_t)(pp - p);
+  *p_cur_offset += entry_size;
+  *ps = num_tlv;
+}
+
+static void nfa_ee_add_aid_route_to_ecb(tNFA_EE_ECB* p_cb, uint8_t* pp,
+                                        uint8_t* p, uint8_t* ps,
+                                        int* p_cur_offset, int* p_max_len) {
+  uint8_t num_tlv = *ps;
+
+  /* add the AID routing */
+  if (p_cb->aid_entries) {
+    int start_offset = 0;
+    for (int xx = 0; xx < p_cb->aid_entries; xx++) {
+      /* remember the beginning of this AID routing entry, just in case we
+       * need to put it in next command */
+      uint8_t route_qual = 0;
+      uint8_t* p_start = pp;
+      /* add one AID entry */
+      if (p_cb->aid_rt_info[xx] & NFA_EE_AE_ROUTE) {
+        uint8_t* pa = &p_cb->aid_cfg[start_offset];
+
+        NFA_TRACE_DEBUG2("%s -  p_cb->aid_info%x", __func__,
+                         p_cb->aid_info[xx]);
+        if (p_cb->aid_info[xx] & NCI_ROUTE_QUAL_LONG_SELECT) {
+          NFA_TRACE_DEBUG2("%s - %x", __func__,
+                           p_cb->aid_info[xx] & NCI_ROUTE_QUAL_LONG_SELECT);
+          route_qual |= NCI_ROUTE_QUAL_LONG_SELECT;
+        }
+        if (p_cb->aid_info[xx] & NCI_ROUTE_QUAL_SHORT_SELECT) {
+          NFA_TRACE_DEBUG2("%s - %x", __func__,
+                           p_cb->aid_info[xx] & NCI_ROUTE_QUAL_SHORT_SELECT);
+          route_qual |= NCI_ROUTE_QUAL_SHORT_SELECT;
+        }
+
+        uint8_t tag =
+            NFC_ROUTE_TAG_AID | nfa_ee_cb.route_block_control | route_qual;
+            if(nfa_ee_is_active(p_cb->aid_rt_loc[xx]|NFA_HANDLE_GROUP_EE)) {
+                add_route_aid_tlv(&pp, pa, p_cb->aid_rt_loc[xx], p_cb->aid_pwr_cfg[xx], tag);
+                num_tlv++;
+            } else {
+                NFA_TRACE_DEBUG2("%s -  ignoring route loc%x", __func__,p_cb->aid_rt_loc[xx]);
+            }
+      }
+      start_offset += p_cb->aid_len[xx];
+      uint8_t new_size = (uint8_t)(pp - p_start);
+      nfa_ee_check_set_routing(new_size, p_max_len, ps, p_cur_offset);
+      if (*ps == 0 && (num_tlv > 0x00)) {
+        /* just sent routing command, update local */
+        *ps = 1;
+        num_tlv = *ps;
+        *p_cur_offset = new_size;
+        pp = ps + 1;
+        p = pp;
+        memcpy(p, p_start, new_size);
+        pp += new_size;
+      } else {
+        /* add the new entry */
+        *ps = num_tlv;
+        *p_cur_offset += new_size;
+      }
+    }
+  } else {
+    NFA_TRACE_DEBUG1("%s - No AID entries available", __func__);
+  }
+}
+static void nfa_ee_add_apdu_route_to_ecb(tNFA_EE_ECB* p_cb, uint8_t* pp,
+                                        uint8_t* p, uint8_t* ps,
+                                        int* p_cur_offset, int* p_max_len) {
+    uint8_t num_tlv = *ps, len;
+    uint16_t tlv_size;
+    tlv_size = (uint8_t)*p_cur_offset;
+    int start_offset, xx;
+    uint8_t  *pa;
+    uint8_t* p_start;
+    uint8_t new_size;
+    uint8_t max_tlv;
+
+    /* add the AID routing */
+          if (p_cb->apdu_pattern_entries) {
+            start_offset = 0;
+            for (xx = 0; xx < p_cb->apdu_pattern_entries; xx++) {
+                p_start = pp;
+                /* add one APDU entry */
+                if (p_cb->apdu_rt_info[xx] & NFA_EE_AE_ROUTE) {
+                    num_tlv++;
+                    pa = &p_cb->apdu_cfg[start_offset];
+                    pa++;        /* EMV tag */
+                    len = *pa++; /* apdu_len */
+                    *pp++ = NFC_ROUTE_TAG_APDU;
+                    *pp++ = len + 2;
+                    *pp++ = (p_cb->apdu_rt_info[xx] >> NFA_EE_APDU_ROUTE_MASK);
+                    NFA_TRACE_DEBUG1("nfa_ee_route_add_one_ecb_by_route_order p_cb->apdu_rt_info[xx] %x", p_cb->apdu_rt_info[xx]);
+                    *pp++ = p_cb->apdu_pwr_cfg[xx];
+                    /* copy the APDU */
+                    memcpy(pp, pa, len);
+                    pp += len;
+                }
+                start_offset += p_cb->apdu_len[xx];
+                new_size = (uint8_t)(pp - p_start);
+                NFA_TRACE_DEBUG1("nfa_ee_route_add_one_ecb_by_route_order --before num_tlv:- %d", num_tlv);
+                NFA_TRACE_DEBUG1("nfa_ee_route_add_one_ecb_by_route_order --before new_size:- %d",new_size);
+                nfa_ee_check_set_routing(new_size, p_max_len, ps, p_cur_offset);
+                if (*ps == 0) {
+                  /* just sent routing command, update local */
+                  *ps = 1;
+                   num_tlv = *ps;
+                   *p_cur_offset = new_size;
+                   pp = ps + 1;
+                   p = pp;
+                   tlv_size = (uint8_t)*p_cur_offset;
+                   max_tlv = (uint8_t)((*p_max_len > NFA_EE_ROUT_MAX_TLV_SIZE)
+                                        ? NFA_EE_ROUT_MAX_TLV_SIZE
+                                        : *p_max_len);
+                   memcpy(p, p_start, new_size);
+                   pp += new_size;
+                   } else {
+                    /* add the new entry */
+                     *ps = num_tlv;
+                     *p_cur_offset += new_size;
+                }
+            }
+            NFA_TRACE_DEBUG1("nfa_ee_route_add_one_ecb_by_route_order --num_tlv:- %d", num_tlv);
+            NFA_TRACE_DEBUG1("nfa_ee_route_add_one_ecb_by_route_order --new_size:- %d",new_size);
+          }
+}
+/*******************************************************************************
+**
+** Function         nfa_ee_conn_cback
+**
+** Description      process connection callback event from stack
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_ee_conn_cback(uint8_t conn_id, tNFC_CONN_EVT event,
+                              tNFC_CONN* p_data) {
+  tNFA_EE_NCI_CONN cbk;
+
+  NFA_TRACE_DEBUG2("nfa_ee_conn_cback: conn_id: %d, event=0x%02x", conn_id,
+                   event);
+
+  cbk.hdr.event = NFA_EE_NCI_CONN_EVT;
+  if (event == NFC_DATA_CEVT) {
+    /* Treat data event specially to avoid potential memory leak */
+    cbk.hdr.event = NFA_EE_NCI_DATA_EVT;
+  }
+  cbk.conn_id = conn_id;
+  cbk.event = event;
+  cbk.p_data = p_data;
+
+  nfa_ee_evt_hdlr((void*)&cbk);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_find_total_aid_len
+**
+** Description      Find the total len in aid_cfg from start_entry to the last
+**
+** Returns          void
+**
+*******************************************************************************/
+int nfa_ee_find_total_aid_len(tNFA_EE_ECB* p_cb, int start_entry) {
+  int len = 0, xx;
+
+  if (p_cb->aid_entries > start_entry) {
+    for (xx = start_entry; xx < p_cb->aid_entries; xx++) {
+      len += p_cb->aid_len[xx];
+    }
+  }
+  return len;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_find_total_apdu_len
+**
+** Description      Find the total len in apdu_cfg from start_entry to the last
+**
+** Returns          void
+**
+*******************************************************************************/
+int nfa_ee_find_total_apdu_len(tNFA_EE_ECB* p_cb, int start_entry) {
+  int len = 0, xx;
+
+  if (p_cb->apdu_pattern_entries > start_entry) {
+    for (xx = start_entry; xx < p_cb->apdu_pattern_entries; xx++) {
+      len += p_cb->apdu_len[xx];
+    }
+  }
+  return len;
+}
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         nfa_all_ee_find_total_aid_len
+**
+** Description      Find the total len in aid_cfg from start_entry to the last
+**                  for all EE and DH.
+**
+** Returns          total length
+**
+*******************************************************************************/
+int nfa_all_ee_find_total_aid_len() {
+  uint32_t xx;
+  int total_len = 0;
+  tNFA_EE_ECB* p_cb = nfa_ee_cb.ecb;
+  for (xx = 0; xx < nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED; xx++, p_cb++) {
+    total_len += nfa_ee_find_total_aid_len(p_cb, 0);
+    total_len += (p_cb->aid_entries * 2); /*Adding tag/len */
+  }
+
+  tNFA_EE_ECB* p_ecb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH];
+  total_len += nfa_ee_find_total_aid_len(p_ecb, 0);
+  total_len += (p_ecb->aid_entries * 2); /*Adding tag/len */
+
+  return total_len;
+}
+/*******************************************************************************
+**
+** Function         nfa_all_ee_find_total_apdu_pattern_len
+**
+** Description      Find the total len in apdu_cfg from start_entry to the last
+**                  for all EE and DH.
+**
+** Returns          total length
+**
+*******************************************************************************/
+int nfa_all_ee_find_total_apdu_pattern_len() {
+  uint32_t xx;
+  int total_len = 0;
+  tNFA_EE_ECB* p_cb = nfa_ee_cb.ecb;
+  for (xx = 0; xx < NFA_EE_MAX_EE_SUPPORTED; xx++, p_cb++) {
+    total_len += nfa_ee_find_total_apdu_len(p_cb, 0);
+    total_len += (p_cb->apdu_pattern_entries * 2); /*Adding nfceeid/power_state */
+  }
+  return total_len;
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         nfa_ee_find_aid_offset
+**
+** Description      Given the AID, find the associated tNFA_EE_ECB and the
+**                  offset in aid_cfg[]. *p_entry is the index.
+**
+** Returns          void
+**
+*******************************************************************************/
+tNFA_EE_ECB* nfa_ee_find_aid_offset(uint8_t aid_len, uint8_t* p_aid,
+                                    int* p_offset, int* p_entry) {
+  int xx, yy, aid_len_offset, offset;
+  tNFA_EE_ECB* p_ret = NULL, *p_ecb;
+
+  p_ecb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH];
+  aid_len_offset = 1; /* skip the tag */
+  for (yy = 0; yy < nfa_ee_cb.cur_ee; yy++, p_ecb++) {
+    if (p_ecb->aid_entries) {
+      offset = 0;
+      for (xx = 0; xx < p_ecb->aid_entries; xx++) {
+        if ((p_ecb->aid_cfg[offset + aid_len_offset] == aid_len) &&
+            (memcmp(&p_ecb->aid_cfg[offset + aid_len_offset + 1], p_aid,
+                    aid_len) == 0)) {
+          p_ret = p_ecb;
+          if (p_offset) *p_offset = offset;
+          if (p_entry) *p_entry = xx;
+          break;
+        }
+        offset += p_ecb->aid_len[xx];
+      }
+
+      if (p_ret) {
+        /* found the entry already */
+        break;
+      }
+    }
+    p_ecb = &nfa_ee_cb.ecb[yy];
+  }
+
+  return p_ret;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_find_apdu_offset
+**
+** Description      Given the APDU, find the associated tNFA_EE_ECB and the
+**                  offset in apdu_cfg[]. *p_entry is the index.
+**
+** Returns          void
+**
+*******************************************************************************/
+tNFA_EE_ECB* nfa_ee_find_apdu_offset(uint8_t apdu_len, uint8_t* p_apdu,
+                                    int* p_offset, int* p_entry) {
+  int xx, yy, apdu_len_offset = 1, offset;
+  tNFA_EE_ECB* p_ret = NULL, *p_ecb;
+  p_ecb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH];
+  for (yy = 0; yy < nfa_ee_cb.cur_ee; yy++, p_ecb++) {
+    if (p_ecb->apdu_pattern_entries) {
+      offset = 0;
+      for (xx = 0; xx < p_ecb->apdu_pattern_entries; xx++) {
+        if (((p_ecb->apdu_cfg[offset + apdu_len_offset]/2) == apdu_len) &&
+            (memcmp(&p_ecb->apdu_cfg[offset + apdu_len_offset + 1], p_apdu,
+                    apdu_len) == 0)) {
+          p_ret = p_ecb;
+          if (p_offset) *p_offset = offset;
+            if (p_entry) *p_entry = xx;
+          break;
+        }
+        offset += p_ecb->aid_len[xx];
+      }
+
+      if (p_ret) {
+        /* found the entry already */
+        break;
+      }
+    }
+    p_ecb = &nfa_ee_cb.ecb[yy];
+  }
+  return p_ret;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_report_event
+**
+** Description      report the given event to the callback
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_report_event(tNFA_EE_CBACK* p_cback, tNFA_EE_EVT event,
+                         tNFA_EE_CBACK_DATA* p_data) {
+  int xx;
+
+  /* use the given callback, if not NULL */
+  if (p_cback) {
+    (*p_cback)(event, p_data);
+    return;
+  }
+  /* if the given is NULL, report to all registered ones */
+  for (xx = 0; xx < NFA_EE_MAX_CBACKS; xx++) {
+    if (nfa_ee_cb.p_ee_cback[xx] != NULL) {
+      (*nfa_ee_cb.p_ee_cback[xx])(event, p_data);
+    }
+  }
+}
+/*******************************************************************************
+**
+** Function         nfa_ee_start_timer
+**
+** Description      start the de-bounce timer
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_start_timer(void) {
+  if (nfa_dm_is_active())
+    nfa_sys_start_timer(&nfa_ee_cb.timer, NFA_EE_ROUT_TIMEOUT_EVT,
+                        NFA_EE_ROUT_TIMEOUT_VAL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_api_discover
+**
+** Description      process discover command from user
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_api_discover(tNFA_EE_MSG* p_data) {
+  tNFA_EE_CBACK* p_cback = p_data->ee_discover.p_cback;
+  tNFA_EE_CBACK_DATA evt_data = {0};
+
+  NFA_TRACE_DEBUG1("nfa_ee_api_discover() in_use:%d",
+                   nfa_ee_cb.discv_timer.in_use);
+  if (nfa_ee_cb.discv_timer.in_use) {
+    nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
+    if(NFA_GetNCIVersion() != NCI_VERSION_2_0)
+      NFC_NfceeDiscover(false);
+    else {
+        evt_data.status = NFA_STATUS_FAILED;
+        nfa_ee_report_event(p_cback, NFA_EE_DISCOVER_EVT, &evt_data);
+        return;
+    }
+  }
+  if (nfa_ee_cb.p_ee_disc_cback == NULL &&
+      NFC_NfceeDiscover(true) == NFC_STATUS_OK) {
+    nfa_ee_cb.p_ee_disc_cback = p_cback;
+  } else {
+    evt_data.status = NFA_STATUS_FAILED;
+    nfa_ee_report_event(p_cback, NFA_EE_DISCOVER_EVT, &evt_data);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_api_register
+**
+** Description      process register command from user
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_api_register(tNFA_EE_MSG* p_data) {
+  int xx;
+  tNFA_EE_CBACK* p_cback = p_data->ee_register.p_cback;
+  tNFA_EE_CBACK_DATA evt_data = {0};
+  bool found = false;
+
+  evt_data.ee_register = NFA_STATUS_FAILED;
+  /* loop through all entries to see if there's a matching callback */
+  for (xx = 0; xx < NFA_EE_MAX_CBACKS; xx++) {
+    if (nfa_ee_cb.p_ee_cback[xx] == p_cback) {
+      evt_data.ee_register = NFA_STATUS_OK;
+      found = true;
+      break;
+    }
+  }
+
+  /* If no matching callback, allocated an entry */
+  if (!found) {
+    for (xx = 0; xx < NFA_EE_MAX_CBACKS; xx++) {
+      if (nfa_ee_cb.p_ee_cback[xx] == NULL) {
+        nfa_ee_cb.p_ee_cback[xx] = p_cback;
+        evt_data.ee_register = NFA_STATUS_OK;
+        break;
+      }
+    }
+  }
+
+#if (NXP_EXTNS == TRUE)
+  if((nfcFL.chipType != pn547C2) &&
+          (nfcFL.nfcMwFL._NFC_NXP_AID_MAX_SIZE_DYN == true)) {
+      max_routing_table_size = nfc_ncif_getMaxRoutingTableSize();
+      if (max_routing_table_size <
+              (NFA_EE_TOTAL_TECH_ROUTE_SIZE + NFA_EE_TOTAL_PROTO_ROUTE_SIZE)) {
+          max_routing_table_size = NFA_EE_ROUT_BUF_SIZE;
+      }
+      max_aid_config_length = nfa_ee_find_max_aid_config_length();
+      max_aid_entries = max_aid_config_length / NFA_EE_MIN_AID_ENTRY_SIZE;
+      NFA_TRACE_DEBUG3(
+              "max_routing_table_size = %d max_aid_config_length: %d and "
+              "max_aid_entries: %d",
+              max_routing_table_size, max_aid_config_length, max_aid_entries);
+      /* Dynamic ecb allocation based on max aid entry calculated from max. routing
+       * table size( from core_init rsp )*/
+      for (xx = 0; xx < NFA_EE_NUM_ECBS; xx++) {
+          nfa_ee_cb.ecb[xx].aid_len = GKI_getbuf(max_aid_entries);
+          nfa_ee_cb.ecb[xx].aid_pwr_cfg = GKI_getbuf(max_aid_entries);
+          nfa_ee_cb.ecb[xx].aid_rt_info = GKI_getbuf(max_aid_entries);
+          nfa_ee_cb.ecb[xx].aid_rt_loc = GKI_getbuf(max_aid_entries);
+          nfa_ee_cb.ecb[xx].aid_info    = GKI_getbuf(max_aid_entries);
+          nfa_ee_cb.ecb[xx].aid_cfg = GKI_getbuf(max_aid_config_length);
+          if ((NULL != nfa_ee_cb.ecb[xx].aid_len) &&
+                  (NULL != nfa_ee_cb.ecb[xx].aid_pwr_cfg) &&
+                  (NULL != nfa_ee_cb.ecb[xx].aid_rt_info) &&
+                  (NULL != nfa_ee_cb.ecb[xx].aid_rt_loc) &&
+                  (NULL != nfa_ee_cb.ecb[xx].aid_info) &&
+                  (NULL != nfa_ee_cb.ecb[xx].aid_cfg)) {
+              memset(nfa_ee_cb.ecb[xx].aid_len, 0, max_aid_entries);
+              memset(nfa_ee_cb.ecb[xx].aid_pwr_cfg, 0, max_aid_entries);
+              memset(nfa_ee_cb.ecb[xx].aid_rt_info, 0, max_aid_entries);
+              memset(nfa_ee_cb.ecb[xx].aid_rt_loc, 0, max_aid_entries);
+              memset(nfa_ee_cb.ecb[xx].aid_info, 0, max_aid_entries);
+              memset(nfa_ee_cb.ecb[xx].aid_cfg, 0, max_aid_config_length);
+          } else {
+              NFA_TRACE_ERROR0("GKI_getbuf allocation for ECB failed !");
+          }
+      }
+  }
+  else {
+      for (xx = 0; xx < NFA_EE_NUM_ECBS; xx++) {
+          nfa_ee_cb.ecb[xx].aid_len = nfa_ee_cb.ecb[xx].aid_len_stat;
+          nfa_ee_cb.ecb[xx].aid_pwr_cfg = nfa_ee_cb.ecb[xx].aid_pwr_cfg_stat;
+          nfa_ee_cb.ecb[xx].aid_rt_info = nfa_ee_cb.ecb[xx].aid_rt_info_stat;
+          nfa_ee_cb.ecb[xx].aid_rt_loc = nfa_ee_cb.ecb[xx].aid_rt_loc_stat;
+          nfa_ee_cb.ecb[xx].aid_cfg = nfa_ee_cb.ecb[xx].aid_cfg_stat;
+      }
+  }
+#endif
+
+  /* This callback is verified (not NULL) in NFA_EeRegister() */
+  (*p_cback)(NFA_EE_REGISTER_EVT, &evt_data);
+
+  /* report NFCEE Discovery Request collected during booting up */
+  nfa_ee_build_discover_req_evt(&evt_data.discover_req);
+  (*p_cback)(NFA_EE_DISCOVER_REQ_EVT, &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_api_deregister
+**
+** Description      process de-register command from user
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_api_deregister(tNFA_EE_MSG* p_data) {
+  tNFA_EE_CBACK* p_cback = NULL;
+#if (NXP_EXTNS == TRUE)
+  int index = p_data->deregister.index, xx = 0;
+#else
+  int index = p_data->deregister.index;
+#endif
+  tNFA_EE_CBACK_DATA evt_data = {0};
+
+  NFA_TRACE_DEBUG0("nfa_ee_api_deregister");
+#if (NXP_EXTNS == TRUE)
+  if((nfcFL.chipType != pn547C2) &&
+          (nfcFL.nfcMwFL._NFC_NXP_AID_MAX_SIZE_DYN == true)) {
+      for (xx = 0; xx < NFA_EE_NUM_ECBS; xx++) {
+          GKI_freebuf(nfa_ee_cb.ecb[xx].aid_len);
+          GKI_freebuf(nfa_ee_cb.ecb[xx].aid_pwr_cfg);
+          GKI_freebuf(nfa_ee_cb.ecb[xx].aid_rt_info);
+          GKI_freebuf(nfa_ee_cb.ecb[xx].aid_rt_loc);
+          GKI_freebuf(nfa_ee_cb.ecb[xx].aid_info);
+          GKI_freebuf(nfa_ee_cb.ecb[xx].aid_cfg);
+      }
+  }
+#endif
+  p_cback = nfa_ee_cb.p_ee_cback[index];
+  nfa_ee_cb.p_ee_cback[index] = NULL;
+  if (p_cback) (*p_cback)(NFA_EE_DEREGISTER_EVT, &evt_data);
+}
+/*******************************************************************************
+**
+** Function         nfa_ee_api_power_link_set
+**
+** Description      process power link command request
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_api_power_link_set(tNFA_EE_MSG* p_data) {
+    tNFA_EE_ECB* p_cb = p_data->cfg_hdr.p_cb;
+    NFC_Nfcee_PwrLinkCtrl(p_data->pwr_lnk_ctrl_set.nfcee_id, p_data->pwr_lnk_ctrl_set.cfg_value);
+    return;
+}
+/*******************************************************************************
+**
+** Function         nfa_ee_api_mode_set
+**
+** Description      process mode set command from user
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_api_mode_set(tNFA_EE_MSG* p_data) {
+  tNFA_EE_ECB* p_cb = p_data->cfg_hdr.p_cb;
+  tNFA_EE_MODE_SET         mode_set;
+  NFA_TRACE_DEBUG2("nfa_ee_api_mode_set() handle:0x%02x mode:%d",
+                   p_cb->nfcee_id, p_data->mode_set.mode);
+  if(NFA_GetNCIVersion() != NCI_VERSION_2_0)
+  {
+      NFC_NfceeModeSet(p_cb->nfcee_id, p_data->mode_set.mode);
+  }else {
+      mode_set.status = NFC_NfceeModeSet(p_cb->nfcee_id, p_data->mode_set.mode);
+      if (mode_set.status != NFC_STATUS_OK)
+      {
+        /* the api is rejected at NFC layer, report the failure status right away */
+        mode_set.ee_handle  = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE;
+        mode_set.ee_status  = p_data->mode_set.mode;
+        nfa_ee_report_event(NULL, NFA_EE_MODE_SET_EVT, (tNFA_EE_CBACK_DATA *)&mode_set);
+        return;
+      }
+  }
+  /* set the NFA_EE_STATUS_PENDING bit to indicate the status is not exactly
+   * active */
+  if (p_data->mode_set.mode == NFC_MODE_ACTIVATE
+#if (NXP_EXTNS == TRUE)
+      && (p_cb->ee_status != NFA_EE_STATUS_REMOVED)
+#endif
+          )
+#if (NXP_EXTNS == TRUE)
+    p_cb->ee_status = NFA_EE_STATUS_ACTIVE;
+#else
+    p_cb->ee_status = NFA_EE_STATUS_PENDING | NFA_EE_STATUS_ACTIVE;
+#endif
+  else {
+#if (NXP_EXTNS == TRUE)
+    if (p_cb->ee_status != NFA_EE_STATUS_REMOVED)
+#endif
+      p_cb->ee_status = NFA_EE_STATUS_INACTIVE;
+    /* DH should release the NCI connection before deactivate the NFCEE */
+    if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) {
+      p_cb->conn_st = NFA_EE_CONN_ST_DISC;
+      NFC_ConnClose(p_cb->conn_id);
+    }
+  }
+  /* report the NFA_EE_MODE_SET_EVT status on the response from NFCC */
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_api_set_tech_cfg
+**
+** Description      process set technology routing configuration from user
+**                  start a 1 second timer. When the timer expires,
+**                  the configuration collected in control block is sent to NFCC
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_api_set_tech_cfg(tNFA_EE_MSG* p_data) {
+  tNFA_EE_ECB* p_cb = p_data->cfg_hdr.p_cb;
+  tNFA_EE_CBACK_DATA evt_data = {0};
+  tNFA_TECHNOLOGY_MASK old_tech_switch_on = p_cb->tech_switch_on;
+  tNFA_TECHNOLOGY_MASK old_tech_switch_off = p_cb->tech_switch_off;
+  tNFA_TECHNOLOGY_MASK old_tech_battery_off = p_cb->tech_battery_off;
+#if (NXP_EXTNS == TRUE)
+  tNFA_TECHNOLOGY_MASK old_tech_screen_lock = p_cb->tech_screen_lock;
+  tNFA_TECHNOLOGY_MASK old_tech_screen_off = p_cb->tech_screen_off;
+  tNFA_TECHNOLOGY_MASK old_tech_screen_off_lock = p_cb->tech_screen_off_lock;
+#endif
+  uint8_t old_size_mask = p_cb->size_mask;
+
+  if ((p_cb->tech_switch_on == p_data->set_tech.technologies_switch_on) &&
+      (p_cb->tech_switch_off == p_data->set_tech.technologies_switch_off) &&
+      (p_cb->tech_battery_off == p_data->set_tech.technologies_battery_off)
+#if (NXP_EXTNS == TRUE)
+      &&
+      (p_cb->tech_screen_lock == p_data->set_tech.technologies_screen_lock) &&
+      (p_cb->tech_screen_off == p_data->set_tech.technologies_screen_off) &&
+      (p_cb->tech_screen_off_lock == p_data->set_tech.technologies_screen_off_lock)
+#endif
+          ) {
+    /* nothing to change */
+    evt_data.status = NFA_STATUS_OK;
+    nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_SET_TECH_CFG_EVT, &evt_data);
+    return;
+  }
+  p_cb->tech_switch_on = p_data->set_tech.technologies_switch_on;
+  p_cb->tech_switch_off = p_data->set_tech.technologies_switch_off;
+  p_cb->tech_battery_off = p_data->set_tech.technologies_battery_off;
+#if (NXP_EXTNS == TRUE)
+  p_cb->tech_screen_lock = p_data->set_tech.technologies_screen_lock;
+  p_cb->tech_screen_off = p_data->set_tech.technologies_screen_off;
+  p_cb->tech_screen_off_lock = p_data->set_tech.technologies_screen_off_lock;
+#endif
+  nfa_ee_update_route_size(p_cb);
+  if (nfa_ee_total_lmrt_size() > NFC_GetLmrtSize()) {
+    NFA_TRACE_ERROR0("nfa_ee_api_set_tech_cfg Exceed LMRT size");
+    evt_data.status = NFA_STATUS_BUFFER_FULL;
+    p_cb->tech_switch_on = old_tech_switch_on;
+    p_cb->tech_switch_off = old_tech_switch_off;
+    p_cb->tech_battery_off = old_tech_battery_off;
+#if (NXP_EXTNS == TRUE)
+    p_cb->tech_screen_lock = old_tech_screen_lock;
+    p_cb->tech_screen_off = old_tech_screen_off;
+    p_cb->tech_screen_off_lock = old_tech_screen_off_lock;
+#endif
+    p_cb->size_mask = old_size_mask;
+  } else {
+    p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_TECH;
+    if (p_cb->tech_switch_on | p_cb->tech_switch_off | p_cb->tech_battery_off
+#if (NXP_EXTNS == TRUE)
+        | p_cb->tech_screen_lock | p_cb->tech_screen_off | p_cb->tech_screen_off_lock
+#endif
+        ) {
+      /* if any technology in any power mode is configured, mark this entry as
+       * configured */
+      nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb);
+    }
+    nfa_ee_start_timer();
+  }
+  nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_SET_TECH_CFG_EVT, &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_api_set_proto_cfg
+**
+** Description      process set protocol routing configuration from user
+**                  start a 1 second timer. When the timer expires,
+**                  the configuration collected in control block is sent to NFCC
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_api_set_proto_cfg(tNFA_EE_MSG* p_data) {
+  tNFA_EE_ECB* p_cb = p_data->cfg_hdr.p_cb;
+  tNFA_EE_CBACK_DATA evt_data = {0};
+  tNFA_PROTOCOL_MASK old_proto_switch_on = p_cb->proto_switch_on;
+  tNFA_PROTOCOL_MASK old_proto_switch_off = p_cb->proto_switch_off;
+  tNFA_PROTOCOL_MASK old_proto_battery_off = p_cb->proto_battery_off;
+#if (NXP_EXTNS == TRUE)
+  tNFA_PROTOCOL_MASK old_proto_screen_lock = p_cb->proto_screen_lock;
+  tNFA_PROTOCOL_MASK old_proto_screen_off = p_cb->proto_screen_off;
+  tNFA_PROTOCOL_MASK old_proto_screen_off_lock = p_cb->proto_screen_off_lock;
+#endif
+  uint8_t old_size_mask = p_cb->size_mask;
+
+  if ((p_cb->proto_switch_on == p_data->set_proto.protocols_switch_on) &&
+      (p_cb->proto_switch_off == p_data->set_proto.protocols_switch_off) &&
+      (p_cb->proto_battery_off == p_data->set_proto.protocols_battery_off)
+#if (NXP_EXTNS == TRUE)
+      && (p_cb->proto_screen_lock == p_data->set_proto.protocols_screen_lock) &&
+      (p_cb->proto_screen_off == p_data->set_proto.protocols_screen_off) &&
+      (p_cb->proto_screen_off_lock == p_data->set_proto.protocols_screen_off_lock)
+#endif
+          ) {
+    /* nothing to change */
+    evt_data.status = NFA_STATUS_OK;
+    nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_SET_PROTO_CFG_EVT, &evt_data);
+    return;
+  }
+  p_cb->proto_switch_on = p_data->set_proto.protocols_switch_on;
+  p_cb->proto_switch_off = p_data->set_proto.protocols_switch_off;
+  p_cb->proto_battery_off = p_data->set_proto.protocols_battery_off;
+#if (NXP_EXTNS == TRUE)
+  p_cb->proto_screen_lock = p_data->set_proto.protocols_screen_lock;
+  p_cb->proto_screen_off = p_data->set_proto.protocols_screen_off;
+  p_cb->proto_screen_off_lock = p_data->set_proto.protocols_screen_off_lock;
+#endif
+  nfa_ee_update_route_size(p_cb);
+  if (nfa_ee_total_lmrt_size() > NFC_GetLmrtSize()) {
+    NFA_TRACE_ERROR0("nfa_ee_api_set_proto_cfg Exceed LMRT size");
+    evt_data.status = NFA_STATUS_BUFFER_FULL;
+    p_cb->proto_switch_on = old_proto_switch_on;
+    p_cb->proto_switch_off = old_proto_switch_off;
+    p_cb->proto_battery_off = old_proto_battery_off;
+#if (NXP_EXTNS == TRUE)
+    p_cb->proto_screen_lock = old_proto_screen_lock;
+    p_cb->proto_screen_off = old_proto_screen_off;
+    p_cb->proto_screen_off_lock = old_proto_screen_off_lock;
+#endif
+    p_cb->size_mask = old_size_mask;
+  } else {
+    p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_PROTO;
+    if (p_cb->proto_switch_on | p_cb->proto_switch_off | p_cb->proto_battery_off
+#if (NXP_EXTNS == TRUE)
+        | p_cb->proto_screen_lock | p_cb->proto_screen_off | p_cb->proto_screen_off_lock
+#endif
+        ) {
+      /* if any protocol in any power mode is configured, mark this entry as
+       * configured */
+      nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb);
+    }
+    nfa_ee_start_timer();
+  }
+  nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_SET_PROTO_CFG_EVT, &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_api_add_aid
+**
+** Description      process add an AID routing configuration from user
+**                  start a 1 second timer. When the timer expires,
+**                  the configuration collected in control block is sent to NFCC
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_api_add_aid(tNFA_EE_MSG* p_data) {
+  tNFA_EE_API_ADD_AID* p_add = &p_data->add_aid;
+  tNFA_EE_ECB* p_cb = p_data->cfg_hdr.p_cb;
+
+#if (NXP_EXTNS == TRUE)
+  tNFA_EE_ECB* dh_ecb = NULL;
+  uint8_t aid_info = p_add->aid_info;
+  uint16_t aid_config_length_max = 0;
+  uint16_t aid_entries_max = 0;
+#endif
+  tNFA_EE_ECB* p_chk_cb;
+  uint8_t* p, *p_start;
+  int len, len_needed;
+  tNFA_EE_CBACK_DATA evt_data = {0};
+  int offset = 0, entry = 0;
+  uint16_t new_size;
+
+  nfa_ee_trace_aid("nfa_ee_api_add_aid", p_cb->nfcee_id, p_add->aid_len,
+                   p_add->p_aid);
+  p_chk_cb =
+      nfa_ee_find_aid_offset(p_add->aid_len, p_add->p_aid, &offset, &entry);
+  if(NFA_GetNCIVersion() == NCI_VERSION_1_0) {
+    if((p_add->power_state & 0x08) || (p_add->power_state & 0x20)) {
+      p_add->power_state &= ~0x08;
+      p_add->power_state &= ~0x20;
+      p_add->power_state |= NCI_ROUTE_PWR_STATE_SCREEN_OFF_UNLOCK();
+    }
+    if(p_add->power_state & 0x10){
+      p_add->power_state &= ~0x10;
+      p_add->power_state |= NCI_ROUTE_PWR_STATE_SCREEN_ON_LOCK();
+    }
+  }
+  if (p_chk_cb) {
+    NFA_TRACE_DEBUG0(
+        "nfa_ee_api_add_aid The AID entry is already in the database");
+    if (p_chk_cb == p_cb) {
+      p_cb->aid_rt_info[entry] |= NFA_EE_AE_ROUTE;
+      p_cb->aid_info[entry] = p_add->aid_info;
+      new_size = nfa_ee_total_lmrt_size();
+      if (new_size > NFC_GetLmrtSize()) {
+        NFA_TRACE_ERROR1("Exceed LMRT size:%d (add ROUTE)", new_size);
+        evt_data.status = NFA_STATUS_BUFFER_FULL;
+        p_cb->aid_rt_info[entry] &= ~NFA_EE_AE_ROUTE;
+      } else {
+        p_cb->aid_pwr_cfg[entry] = p_add->power_state;
+        p_cb->aid_info[entry] = p_add->aid_info;
+      }
+    } else {
+      NFA_TRACE_ERROR1(
+          "The AID entry is already in the database for different NFCEE "
+          "ID:0x%02x",
+          p_chk_cb->nfcee_id);
+      evt_data.status = NFA_STATUS_SEMANTIC_ERROR;
+    }
+  } else {
+/* Find the total length so far */
+#if (NXP_EXTNS == TRUE)
+    len = nfa_all_ee_find_total_aid_len();
+    len += nfa_all_ee_find_total_apdu_pattern_len();
+    dh_ecb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH];
+#else
+    len = nfa_ee_find_total_aid_len(p_cb, 0);
+#endif
+
+    /* make sure the control block has enough room to hold this entry */
+    len_needed = p_add->aid_len + 2; /* tag/len */
+    if((nfcFL.chipType != pn547C2) &&
+            (nfcFL.nfcMwFL._NFC_NXP_AID_MAX_SIZE_DYN == true)) {
+        aid_config_length_max = max_aid_config_length;
+        aid_entries_max = max_aid_entries;
+    }
+    else{
+        aid_config_length_max = NFA_EE_MAX_AID_CFG_LEN_STAT;
+        aid_entries_max = nfcFL.nfcMwFL._NFA_EE_MAX_AID_ENTRIES;
+    }
+    if ((len_needed + len) >
+#if (NXP_EXTNS == TRUE)
+    aid_config_length_max
+#else
+    NFA_EE_MAX_AID_CFG_LEN
+#endif
+        ) {
+#if (NXP_EXTNS == TRUE)
+      NFA_TRACE_ERROR3(
+          "Exceed capacity: (len_needed:%d + len:%d) > "
+          "max_aid_config_length:%d",
+          len_needed, len, aid_config_length_max);
+#else
+      NFA_TRACE_ERROR3(
+          "Exceed capacity: (len_needed:%d + len:%d) > "
+          "NFA_EE_MAX_AID_CFG_LEN:%d",
+          len_needed, len, NFA_EE_MAX_AID_CFG_LEN);
+#endif
+      evt_data.status = NFA_STATUS_BUFFER_FULL;
+    }
+#if (NXP_EXTNS == TRUE)
+    else if (dh_ecb->aid_entries < aid_entries_max)
+#else
+    else if (p_cb->aid_entries < NFA_EE_MAX_AID_ENTRIES)
+#endif
+    {
+      /* 4 = 1 (tag) + 1 (len) + 1(nfcee_id) + 1(power cfg) */
+      new_size = nfa_ee_total_lmrt_size() + 4 + p_add->aid_len;
+      if (new_size > NFC_GetLmrtSize()) {
+        NFA_TRACE_ERROR1("Exceed LMRT size:%d", new_size);
+        evt_data.status = NFA_STATUS_BUFFER_FULL;
+      } else {
+/* add AID */
+#if (NXP_EXTNS == TRUE)
+        len = nfa_ee_find_total_aid_len(dh_ecb, 0);
+        // Always use single aid_cfg buffer to keep the aid order intact.
+        dh_ecb->aid_pwr_cfg[dh_ecb->aid_entries] = p_add->power_state;
+        dh_ecb->aid_rt_info[dh_ecb->aid_entries] = NFA_EE_AE_ROUTE;
+        dh_ecb->aid_rt_loc[dh_ecb->aid_entries] = p_cb->nfcee_id;
+        dh_ecb->aid_info[dh_ecb->aid_entries] = p_add->aid_info;
+        p = dh_ecb->aid_cfg + len;
+#else
+        p_cb->aid_pwr_cfg[p_cb->aid_entries] = p_add->power_state;
+        p_cb->aid_info[p_cb->aid_entries] = p_add->aid_info;
+        p_cb->aid_rt_info[p_cb->aid_entries] = NFA_EE_AE_ROUTE;
+        p = p_cb->aid_cfg + len;
+#endif
+
+        p_start = p;
+        *p++ = NFA_EE_AID_CFG_TAG_NAME;
+        *p++ = p_add->aid_len;
+        memcpy(p, p_add->p_aid, p_add->aid_len);
+        p += p_add->aid_len;
+
+#if (NXP_EXTNS == TRUE)
+        dh_ecb->aid_len[dh_ecb->aid_entries++] = (uint8_t)(p - p_start);
+#else
+        p_cb->aid_len[p_cb->aid_entries++] = (uint8_t)(p - p_start);
+#endif
+      }
+    } else {
+#if (NXP_EXTNS == TRUE)
+            NFA_TRACE_ERROR1("Exceed NFA_EE_MAX_AID_ENTRIES:%d", aid_entries_max);
+#else
+        NFA_TRACE_ERROR1("Exceed NFA_EE_MAX_AID_ENTRIES:%d",
+                NFA_EE_MAX_AID_ENTRIES);
+#endif
+      evt_data.status = NFA_STATUS_BUFFER_FULL;
+    }
+  }
+
+  if (evt_data.status == NFA_STATUS_OK) {
+    /* mark AID changed */
+    p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_AID;
+    nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb);
+    nfa_ee_update_route_aid_size(p_cb);
+    nfa_ee_start_timer();
+  }
+  NFA_TRACE_DEBUG2("status:%d ee_cfged:0x%02x ", evt_data.status,
+                   nfa_ee_cb.ee_cfged);
+  /* report the status of this operation */
+  nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_ADD_AID_EVT, &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_api_remove_aid
+**
+** Description      process remove an AID routing configuration from user
+**                  start a 1 second timer. When the timer expires,
+**                  the configuration collected in control block is sent to NFCC
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_api_remove_aid(tNFA_EE_MSG* p_data) {
+  tNFA_EE_ECB* p_cb;
+  tNFA_EE_CBACK_DATA evt_data = {0};
+  int offset = 0, entry = 0, len;
+  int rest_len;
+  tNFA_EE_CBACK* p_cback = NULL;
+
+  nfa_ee_trace_aid("nfa_ee_api_remove_aid", 0, p_data->rm_aid.aid_len,
+                   p_data->rm_aid.p_aid);
+  p_cb = nfa_ee_find_aid_offset(p_data->rm_aid.aid_len, p_data->rm_aid.p_aid,
+                                &offset, &entry);
+  if (p_cb && p_cb->aid_entries) {
+    NFA_TRACE_DEBUG2("aid_rt_info[%d]: 0x%02x", entry,
+                     p_cb->aid_rt_info[entry]);
+    /* mark routing and VS changed */
+    if (p_cb->aid_rt_info[entry] & NFA_EE_AE_ROUTE)
+      p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_AID;
+
+    if (p_cb->aid_rt_info[entry] & NFA_EE_AE_VS)
+      p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_VS;
+
+    /* remove the aid */
+    if ((entry + 1) < p_cb->aid_entries) {
+      /* not the last entry, move the aid entries in control block */
+      /* Find the total len from the next entry to the last one */
+      rest_len = nfa_ee_find_total_aid_len(p_cb, entry + 1);
+
+      len = p_cb->aid_len[entry];
+      NFA_TRACE_DEBUG2("nfa_ee_api_remove_aid len:%d, rest_len:%d", len,
+                       rest_len);
+      GKI_shiftup(&p_cb->aid_cfg[offset], &p_cb->aid_cfg[offset + len],
+                  rest_len);
+      rest_len = p_cb->aid_entries - entry;
+      GKI_shiftup(&p_cb->aid_len[entry], &p_cb->aid_len[entry + 1], rest_len);
+      GKI_shiftup(&p_cb->aid_pwr_cfg[entry], &p_cb->aid_pwr_cfg[entry + 1],
+                  rest_len);
+      GKI_shiftup(&p_cb->aid_info[entry], &p_cb->aid_info[entry + 1],
+                  rest_len);
+      GKI_shiftup(&p_cb->aid_rt_info[entry], &p_cb->aid_rt_info[entry + 1],
+                  rest_len);
+#if (NXP_EXTNS == TRUE)
+      GKI_shiftup(&p_cb->aid_rt_loc[entry], &p_cb->aid_rt_loc[entry + 1],
+                  rest_len);
+#endif
+    }
+    /* else the last entry, just reduce the aid_entries by 1 */
+    p_cb->aid_entries--;
+    nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb);
+    nfa_ee_update_route_aid_size(p_cb);
+    nfa_ee_start_timer();
+    /* report NFA_EE_REMOVE_AID_EVT to the callback associated the NFCEE */
+    p_cback = p_cb->p_ee_cback;
+  }
+#if (NXP_EXTNS == TRUE)
+  /*Clear All AIDs*/
+  else if (0 == memcmp(NFA_REMOVE_ALL_AID, p_data->rm_aid.p_aid,
+                       p_data->rm_aid.aid_len)) {
+    uint32_t xx;
+    tNFA_EE_ECB* p_cb = nfa_ee_cb.ecb;
+    for (xx = 0; xx < nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED; xx++, p_cb++) {
+#if (NXP_EXTNS == TRUE)
+        if((nfcFL.chipType != pn547C2) &&
+                (nfcFL.nfcMwFL._NFC_NXP_AID_MAX_SIZE_DYN == true)) {
+            memset(&p_cb->aid_cfg[0], 0x00, max_aid_config_length);
+            memset(&p_cb->aid_len[0], 0x00, max_aid_entries);
+            memset(&p_cb->aid_pwr_cfg[0], 0x00, max_aid_entries);
+            memset(&p_cb->aid_info[0], 0x00, max_aid_entries);
+            memset(&p_cb->aid_rt_info[0], 0x00, max_aid_entries);
+        }
+        else {
+            memset(&p_cb->aid_cfg[0], 0x00, sizeof(p_cb->aid_cfg));
+            memset(&p_cb->aid_len[0], 0x00, NFA_EE_MAX_AID_ENTRIES);
+            memset(&p_cb->aid_pwr_cfg[0], 0x00, NFA_EE_MAX_AID_ENTRIES);
+            memset(&p_cb->aid_rt_info[0], 0x00, NFA_EE_MAX_AID_ENTRIES);
+        }
+#else
+        memset(&p_cb->aid_cfg[0], 0x00, sizeof(p_cb->aid_cfg));
+        memset(&p_cb->aid_len[0], 0x00, NFA_EE_MAX_AID_ENTRIES);
+        memset(&p_cb->aid_pwr_cfg[0], 0x00, NFA_EE_MAX_AID_ENTRIES);
+        memset(&p_cb->aid_rt_info[0], 0x00, NFA_EE_MAX_AID_ENTRIES);
+        memset(&p_cb->aid_info[0], 0x00, NFA_EE_MAX_AID_ENTRIES);
+#endif
+        p_cb->aid_entries = 0;
+        nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb);
+    }
+
+    tNFA_EE_ECB* p_ecb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH];
+
+#if (NXP_EXTNS == TRUE)
+    if((nfcFL.chipType != pn547C2) &&
+            (nfcFL.nfcMwFL._NFC_NXP_AID_MAX_SIZE_DYN == true)) {
+        memset(&p_ecb->aid_cfg[0], 0x00, max_aid_config_length);
+        memset(&p_ecb->aid_len[0], 0x00, max_aid_entries);
+        memset(&p_ecb->aid_pwr_cfg[0], 0x00, max_aid_entries);
+        memset(&p_ecb->aid_info[0], 0x00, max_aid_entries);
+        memset(&p_ecb->aid_rt_info[0], 0x00, max_aid_entries);
+    }
+    else {
+        memset(&p_ecb->aid_cfg[0], 0x00, sizeof(p_ecb->aid_cfg));
+        memset(&p_ecb->aid_len[0], 0x00, NFA_EE_MAX_AID_ENTRIES);
+        memset(&p_ecb->aid_pwr_cfg[0], 0x00, NFA_EE_MAX_AID_ENTRIES);
+        memset(&p_ecb->aid_rt_info[0], 0x00, NFA_EE_MAX_AID_ENTRIES);
+    }
+#else
+    memset(&p_ecb->aid_cfg[0], 0x00, sizeof(p_ecb->aid_cfg));
+    memset(&p_ecb->aid_len[0], 0x00, NFA_EE_MAX_AID_ENTRIES);
+    memset(&p_ecb->aid_pwr_cfg[0], 0x00, NFA_EE_MAX_AID_ENTRIES);
+    memset(&p_ecb->aid_rt_info[0], 0x00, NFA_EE_MAX_AID_ENTRIES);
+    memset(&p_ecb->aid_info[0], 0x00, NFA_EE_MAX_AID_ENTRIES);
+#endif
+    p_ecb->aid_entries = 0;
+    p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_AID;
+    nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_ecb);
+  }
+#endif
+  else {
+    NFA_TRACE_ERROR0(
+        "nfa_ee_api_remove_aid The AID entry is not in the database");
+    evt_data.status = NFA_STATUS_INVALID_PARAM;
+  }
+  nfa_ee_report_event(p_cback, NFA_EE_REMOVE_AID_EVT, &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_api_add_apdu
+**
+** Description      process add an APDU pattern data configuration from user
+**                  start a 1 second timer. When the timer expires,
+**                  the configuration collected in control block is sent to NFCC
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_api_add_apdu(tNFA_EE_MSG* p_data) {
+  tNFA_EE_API_ADD_APDU* p_add = &p_data->add_apdu;
+  tNFA_EE_ECB* p_cb = p_data->cfg_hdr.p_cb;
+
+#if (NXP_EXTNS == TRUE)
+  tNFA_EE_ECB* dh_ecb = NULL;
+#endif
+  tNFA_EE_ECB* p_chk_cb;
+  uint8_t* p, *p_start;
+  int aid_len,apdu_len, len_needed;
+  tNFA_EE_CBACK_DATA evt_data = {0};
+  int offset = 0, entry = 0;
+  uint16_t new_size;
+
+  nfa_ee_trace_apdu("nfa_ee_api_add_apdu", p_add);
+  p_chk_cb =
+      nfa_ee_find_apdu_offset(p_add->apdu_len, p_add->p_apdu, &offset, &entry);
+  if(NFA_GetNCIVersion() == NCI_VERSION_1_0) {
+    if((p_add->power_state & 0x08) || (p_add->power_state & 0x20)) {
+      p_add->power_state &= ~0x08;
+      p_add->power_state &= ~0x20;
+      p_add->power_state |= NCI_ROUTE_PWR_STATE_SCREEN_OFF_UNLOCK();
+    } else if(p_add->power_state & 0x10){
+      p_add->power_state &= ~0x10;
+      p_add->power_state |= NCI_ROUTE_PWR_STATE_SCREEN_ON_LOCK();
+    }
+  }
+  if (p_chk_cb) {
+    NFA_TRACE_DEBUG0(
+        "nfa_ee_api_add_apdu The APDU entry is already in the database");
+    if (p_chk_cb == p_cb) {
+      p_cb->apdu_rt_info[entry] |= NFA_EE_AE_ROUTE;
+      new_size = nfa_ee_total_lmrt_size();
+#if (NXP_EXTNS == TRUE)
+      if (((nfcFL.chipType != pn547C2) &&
+              nfcFL.nfcMwFL._NFC_NXP_AID_MAX_SIZE_DYN) && new_size > max_aid_config_length ||
+              ((nfcFL.chipType == pn547C2) &&
+                      !nfcFL.nfcMwFL._NFC_NXP_AID_MAX_SIZE_DYN) && (new_size > NFC_GetLmrtSize())) {
+#else
+      if (new_size > NFC_GetLmrtSize()) {
+#endif
+        NFA_TRACE_ERROR1("Exceed LMRT size:%d (add ROUTE)", new_size);
+        evt_data.status = NFA_STATUS_BUFFER_FULL;
+        p_cb->apdu_rt_info[entry] &= ~NFA_EE_AE_ROUTE;
+      } else {
+        p_cb->apdu_pwr_cfg[entry] = p_add->power_state;
+      }
+    } else {
+      NFA_TRACE_ERROR1(
+          "The APDU entry is already in the database for different NFCEE "
+          "ID:0x%02x",
+          p_chk_cb->nfcee_id);
+      evt_data.status = NFA_STATUS_SEMANTIC_ERROR;
+    }
+  } else {
+/* Find the total length so far */
+#if (NXP_EXTNS == TRUE)
+    aid_len = nfa_all_ee_find_total_aid_len();
+    dh_ecb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH];
+#else
+    aid_len = nfa_ee_find_total_aid_len(p_cb, 0);
+#endif
+    apdu_len = nfa_all_ee_find_total_apdu_pattern_len();
+    /* make sure the control block has enough room to hold this entry */
+    len_needed = p_add->apdu_len + p_add->mask_len + 2 + 2; /*tag/len/apdu_mask/apdu/power_state/nfceeid*/
+
+    if ((len_needed + aid_len + apdu_len) >
+#if (NXP_EXTNS == TRUE)
+    ((((nfcFL.chipType != pn547C2) &&
+            nfcFL.nfcMwFL._NFC_NXP_AID_MAX_SIZE_DYN) && max_aid_config_length) ||
+            (((nfcFL.chipType == pn547C2) &&
+                    !nfcFL.nfcMwFL._NFC_NXP_AID_MAX_SIZE_DYN) && NFC_GetLmrtSize()))
+#else
+        NFC_GetLmrtSize()
+#endif
+        ||((dh_ecb->size_apdu + p_add->apdu_len + p_add->mask_len + 2) >= NFA_EE_TOTAL_APDU_PATTERN_SIZE)) {
+#if (NXP_EXTNS == TRUE)
+        if((nfcFL.chipType != pn547C2) &&
+                nfcFL.nfcMwFL._NFC_NXP_AID_MAX_SIZE_DYN) {
+            NFA_TRACE_ERROR4(
+                    "Exceed capacity: (len_needed:%d + len:%d) > "
+                    "max_aid_config_length:%d",
+                    len_needed, aid_len,apdu_len, max_aid_config_length);
+        }
+        else {
+            NFA_TRACE_ERROR4(
+                    "Exceed capacity: (len_needed:%d + len:%d) > "
+                    "NFA_EE_TOTAL_APDU_PATTERN_SIZE:%d",
+                    len_needed, aid_len,apdu_len, NFA_EE_TOTAL_APDU_PATTERN_SIZE);
+        }
+#else
+      NFA_TRACE_ERROR4(
+          "Exceed capacity: (len_needed:%d + len:%d) > "
+          "NFA_EE_TOTAL_APDU_PATTERN_SIZE:%d",
+          len_needed, aid_len,apdu_len, NFA_EE_TOTAL_APDU_PATTERN_SIZE);
+#endif
+      evt_data.status = NFA_STATUS_BUFFER_FULL;
+    }
+#if (NXP_EXTNS == TRUE)
+    else if (dh_ecb->apdu_pattern_entries < NFA_EE_MAX_APDU_PATTERN_ENTRIES)
+#else
+    else if (p_cb->apdu_pattern_entries < NFA_EE_MAX_APDU_PATTERN_ENTRIES)
+#endif
+    {
+/* add APDU */
+#if (NXP_EXTNS == TRUE)
+        apdu_len = nfa_ee_find_total_apdu_len(dh_ecb, 0);
+        // Always use single apdu_cfg buffer to keep the apdu order intact.
+        dh_ecb->apdu_pwr_cfg[dh_ecb->apdu_pattern_entries] = p_add->power_state;
+        dh_ecb->apdu_rt_info[dh_ecb->apdu_pattern_entries] = NFA_EE_AE_ROUTE;
+        dh_ecb->apdu_rt_loc[dh_ecb->apdu_pattern_entries] = p_cb->nfcee_id;
+        p = dh_ecb->apdu_cfg + apdu_len;
+#else
+        p_cb->apdu_pwr_cfg[p_cb->apdu_pattern_entries] = p_add->power_state;
+        p_cb->apdu_rt_info[p_cb->apdu_pattern_entries] = NFA_EE_AE_ROUTE;
+        p = p_cb->apdu_cfg + apdu_len;
+#endif
+
+        p_start = p;
+        *p++ = NFA_EE_AID_CFG_TAG_NAME;
+        *p++ = p_add->apdu_len + p_add->mask_len;
+        memcpy(p, p_add->p_apdu, p_add->apdu_len);
+        p += p_add->apdu_len;
+        memcpy(p, p_add->p_mask, p_add->mask_len);
+        p += p_add->mask_len;
+
+#if (NXP_EXTNS == TRUE)
+        dh_ecb->apdu_len[dh_ecb->apdu_pattern_entries++] = (uint8_t)(p - p_start);
+#else
+        p_cb->apdu_len[p_cb->apdu_pattern_entries++] = (uint8_t)(p - p_start);
+#endif
+    }
+    else
+    {
+       NFA_TRACE_ERROR1("Exceed NFA_EE_MAX_APDU_PATTERN_ENTRIES:%d", NFA_EE_MAX_APDU_PATTERN_ENTRIES);
+       evt_data.status = NFA_STATUS_BUFFER_FULL;
+    }
+  }
+
+  if (evt_data.status == NFA_STATUS_OK) {
+    /* mark APDU changed */
+    p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_APDU;
+    nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb);
+    nfa_ee_update_route_apdu_size(p_cb);
+    nfa_ee_start_timer();
+  }
+  NFA_TRACE_DEBUG2("status:%d ee_cfged:0x%02x ", evt_data.status,
+                   nfa_ee_cb.ee_cfged);
+  /* report the status of this operation */
+  nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_ADD_APDU_EVT, &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_api_remove_apdu
+**
+** Description      process remove an APDU routing configuration from user
+**                  start a 1 second timer. When the timer expires,
+**                  the configuration collected in control block is sent to NFCC
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_api_remove_apdu(tNFA_EE_MSG* p_data) {
+  tNFA_EE_ECB* p_cb;
+  tNFA_EE_CBACK_DATA evt_data = {0};
+  int offset = 0, entry = 0, len;
+  int rest_len;
+  tNFA_EE_CBACK* p_cback = NULL;
+
+  p_cb = nfa_ee_find_apdu_offset(p_data->rm_apdu.apdu_len, p_data->rm_apdu.p_apdu,
+                                    &offset, &entry);
+  if (p_cb && p_cb->apdu_pattern_entries) {
+    NFA_TRACE_DEBUG2("apdu_rt_info[%d]: 0x%02x", entry,
+                         p_cb->apdu_rt_info[entry]);
+   /* mark routing and VS changed */
+    if (p_cb->apdu_rt_info[entry] & NFA_EE_AE_ROUTE)
+      p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_APDU;
+
+    if (p_cb->apdu_rt_info[entry] & NFA_EE_AE_VS)
+      p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_VS;
+
+    /* remove the apdu */
+    if ((entry + 1) < p_cb->apdu_pattern_entries) {
+      /* not the last entry, move the apdu entries in control block */
+      /* Find the total len from the next entry to the last one */
+      rest_len = nfa_ee_find_total_apdu_len(p_cb, entry + 1);
+
+      len = p_cb->apdu_len[entry];
+      NFA_TRACE_DEBUG2("nfa_ee_api_remove_apdu len:%d, rest_len:%d", len,
+                       rest_len);
+      GKI_shiftup(&p_cb->apdu_cfg[offset], &p_cb->apdu_cfg[offset + len],
+                 rest_len);
+      rest_len = p_cb->apdu_pattern_entries - entry;
+      GKI_shiftup(&p_cb->apdu_len[entry], &p_cb->apdu_len[entry + 1], rest_len);
+      GKI_shiftup(&p_cb->apdu_pwr_cfg[entry], &p_cb->apdu_pwr_cfg[entry + 1],
+                 rest_len);
+      GKI_shiftup(&p_cb->apdu_rt_info[entry], &p_cb->apdu_rt_info[entry + 1],
+                      rest_len);
+      GKI_shiftup(&p_cb->apdu_rt_loc[entry], &p_cb->apdu_rt_loc[entry + 1],
+                      rest_len);
+    }
+    /* else the last entry, just reduce the apdu_entries by 1 */
+    p_cb->apdu_pattern_entries--;
+    nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb);
+    nfa_ee_update_route_apdu_size(p_cb);
+    nfa_ee_start_timer();
+   /* report NFA_EE_REMOVE_APDU_EVT to the callback associated the NFCEE */
+    p_cback = p_cb->p_ee_cback;
+  }
+#if (NXP_EXTNS == TRUE)
+      /*Clear All APDUs*/
+    else if (0 == memcmp(NFA_REMOVE_ALL_APDU, p_data->rm_apdu.p_apdu,
+                           p_data->rm_apdu.apdu_len)) {
+      uint32_t xx;
+      for (xx = 0; xx < NFA_EE_NUM_ECBS; xx++) {
+        memset(&nfa_ee_cb.ecb[xx].apdu_cfg[0], 0x00, sizeof(nfa_ee_cb.ecb[xx].apdu_cfg));
+        memset(&nfa_ee_cb.ecb[xx].apdu_len[0], 0x00, NFA_EE_MAX_APDU_PATTERN_ENTRIES);
+        memset(&nfa_ee_cb.ecb[xx].apdu_pwr_cfg[0], 0x00, NFA_EE_MAX_APDU_PATTERN_ENTRIES);
+        memset(&nfa_ee_cb.ecb[xx].apdu_rt_info[0], 0x00, NFA_EE_MAX_APDU_PATTERN_ENTRIES);
+        memset(&nfa_ee_cb.ecb[xx].apdu_rt_loc[0], 0x00, NFA_EE_MAX_APDU_PATTERN_ENTRIES);
+        nfa_ee_cb.ecb[xx].apdu_pattern_entries = 0;
+        nfa_ee_cb.ecb[xx].ecb_flags |= NFA_EE_ECB_FLAGS_APDU;
+        nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(&nfa_ee_cb.ecb[xx]);
+      }
+    }
+#endif
+    else {
+      NFA_TRACE_ERROR0(
+          "nfa_ee_api_remove_apdu The APDU entry is not in the database");
+      evt_data.status = NFA_STATUS_INVALID_PARAM;
+    }
+    nfa_ee_report_event(p_cback, NFA_EE_REMOVE_APDU_EVT, &evt_data);
+  }
+
+/*******************************************************************************
+**
+** Function         nfa_ee_api_lmrt_size
+**
+** Description      Reports the remaining size in the Listen Mode Routing Table
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_api_lmrt_size(tNFA_EE_MSG* p_data) {
+  tNFA_EE_CBACK_DATA evt_data = {0};
+  uint16_t total_size = NFC_GetLmrtSize();
+  (void)p_data;
+  evt_data.size = total_size - nfa_ee_total_lmrt_size();
+  NFA_TRACE_DEBUG2("nfa_ee_api_lmrt_size total size:%d remaining size:%d",
+                   total_size, evt_data.size);
+
+  nfa_ee_report_event(NULL, NFA_EE_REMAINING_SIZE_EVT, &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_api_update_now
+**
+** Description      Initiates connection creation process to the given NFCEE
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_api_update_now(tNFA_EE_MSG* p_data) {
+  tNFA_EE_CBACK_DATA evt_data;
+
+  if (nfa_ee_cb.ee_wait_evt & NFA_EE_WAIT_UPDATE_ALL) {
+    NFA_TRACE_ERROR2(
+        "nfa_ee_api_update_now still waiting for update complete "
+        "ee_wait_evt:0x%x wait_rsp:%d",
+        nfa_ee_cb.ee_wait_evt, nfa_ee_cb.wait_rsp);
+    evt_data.status = NFA_STATUS_SEMANTIC_ERROR;
+    nfa_ee_report_event(NULL, NFA_EE_UPDATED_EVT, &evt_data);
+    return;
+  }
+  nfa_sys_stop_timer(&nfa_ee_cb.timer);
+  nfa_ee_cb.ee_cfged |= NFA_EE_CFGED_UPDATE_NOW;
+  nfa_ee_rout_timeout(p_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_api_connect
+**
+** Description      Initiates connection creation process to the given NFCEE
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_api_connect(tNFA_EE_MSG* p_data) {
+  tNFA_EE_ECB* p_cb = p_data->connect.p_cb;
+  int xx;
+  tNFA_EE_CBACK_DATA evt_data = {0};
+
+  evt_data.connect.status = NFA_STATUS_FAILED;
+  if (p_cb->conn_st == NFA_EE_CONN_ST_NONE) {
+    for (xx = 0; xx < p_cb->num_interface; xx++) {
+      if (p_data->connect.ee_interface == p_cb->ee_interface[xx]) {
+        p_cb->p_ee_cback = p_data->connect.p_cback;
+        p_cb->conn_st = NFA_EE_CONN_ST_WAIT;
+        p_cb->use_interface = p_data->connect.ee_interface;
+        evt_data.connect.status =
+            NFC_ConnCreate(NCI_DEST_TYPE_NFCEE, p_data->connect.nfcee_id,
+#if (NXP_EXTNS == TRUE)
+                           p_data->connect.ee_interface, nfa_hci_conn_cback);
+#else
+                           p_data->connect.ee_interface, nfa_ee_conn_cback);
+#endif
+        /* report the NFA_EE_CONNECT_EVT status on the response from NFCC */
+        break;
+      }
+    }
+  }
+
+  if (evt_data.connect.status != NCI_STATUS_OK) {
+    evt_data.connect.ee_handle =
+        (tNFA_HANDLE)p_data->connect.nfcee_id | NFA_HANDLE_GROUP_EE;
+    evt_data.connect.status = NFA_STATUS_INVALID_PARAM;
+    evt_data.connect.ee_interface = p_data->connect.ee_interface;
+    nfa_ee_report_event(p_data->connect.p_cback, NFA_EE_CONNECT_EVT, &evt_data);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_api_send_data
+**
+** Description      Send the given data packet to the given NFCEE
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_api_send_data(tNFA_EE_MSG* p_data) {
+  tNFA_EE_ECB* p_cb = p_data->send_data.p_cb;
+  NFC_HDR* p_pkt;
+  uint16_t size = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE +
+                  p_data->send_data.data_len + NFC_HDR_SIZE;
+  uint8_t* p;
+  tNFA_STATUS status = NFA_STATUS_FAILED;
+
+  if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) {
+    p_pkt = (NFC_HDR*)GKI_getbuf(size);
+    if (p_pkt) {
+      p_pkt->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+      p_pkt->len = p_data->send_data.data_len;
+      p = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
+      memcpy(p, p_data->send_data.p_data, p_pkt->len);
+      NFC_SendData(p_cb->conn_id, p_pkt);
+    } else {
+      nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_NO_MEM_ERR_EVT,
+                          (void*)&status);
+    }
+  } else {
+    nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_NO_CB_ERR_EVT, (void*)&status);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_api_disconnect
+**
+** Description      Initiates closing of the connection to the given NFCEE
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_api_disconnect(tNFA_EE_MSG* p_data) {
+  tNFA_EE_ECB* p_cb = p_data->disconnect.p_cb;
+  tNFA_EE_CBACK_DATA evt_data = {0};
+
+#if(NXP_EXTNS == TRUE)
+  nfa_ee_cb.ee_flags |= NFA_EE_HCI_CONN_CLOSE;
+#endif
+
+  if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) {
+    p_cb->conn_st = NFA_EE_CONN_ST_DISC;
+    NFC_ConnClose(p_cb->conn_id);
+  }
+  evt_data.handle = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE;
+  nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_DISCONNECT_EVT, &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_report_disc_done
+**
+** Description      Process the callback for NFCEE discovery response
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_report_disc_done(bool notify_enable_done) {
+  tNFA_EE_CBACK* p_cback;
+  tNFA_EE_CBACK_DATA evt_data = {0};
+
+  NFA_TRACE_DEBUG3(
+      "nfa_ee_report_disc_done() em_state:%d num_ee_expecting:%d "
+      "notify_enable_done:%d",
+      nfa_ee_cb.em_state, nfa_ee_cb.num_ee_expecting, notify_enable_done);
+  if (nfa_ee_cb.num_ee_expecting == 0) {
+    if (notify_enable_done) {
+      if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_INIT_DONE) {
+        if (nfa_ee_cb.discv_timer.in_use && NFA_GetNCIVersion() == NCI_VERSION_2_0) {
+          nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
+        }
+        nfa_sys_cback_notify_enable_complete(NFA_ID_EE);
+        if (nfa_ee_cb.p_enable_cback)
+          (*nfa_ee_cb.p_enable_cback)(NFA_EE_DISC_STS_ON);
+      } else if ((nfa_ee_cb.em_state == NFA_EE_EM_STATE_RESTORING) &&
+                 (nfa_ee_cb.ee_flags & NFA_EE_FLAG_NOTIFY_HCI)) {
+        nfa_ee_cb.ee_flags &= ~NFA_EE_FLAG_NOTIFY_HCI;
+        if (nfa_ee_cb.p_enable_cback)
+          (*nfa_ee_cb.p_enable_cback)(NFA_EE_DISC_STS_ON);
+      }
+    }
+
+    if (nfa_ee_cb.p_ee_disc_cback) {
+      /* notify API callback */
+      p_cback = nfa_ee_cb.p_ee_disc_cback;
+      nfa_ee_cb.p_ee_disc_cback = NULL;
+      evt_data.status = NFA_STATUS_OK;
+      evt_data.ee_discover.num_ee = nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED;
+      NFA_EeGetInfo(&evt_data.ee_discover.num_ee, evt_data.ee_discover.ee_info);
+      nfa_ee_report_event(p_cback, NFA_EE_DISCOVER_EVT, &evt_data);
+    }
+#if (NXP_EXTNS == TRUE)
+    else if(nfcFL.nfccFL._NFCEE_REMOVED_NTF_RECOVERY == true) {
+      evt_data.status = NFA_STATUS_OK;
+      evt_data.ee_discover.num_ee = nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED;
+      NFA_AllEeGetInfo(&evt_data.ee_discover.num_ee,
+                       evt_data.ee_discover.ee_info);
+      nfa_ee_report_event(NULL, NFA_EE_DISCOVER_EVT, &evt_data);
+    }
+    if (nfa_ee_cb.p_enable_cback)
+                (*nfa_ee_cb.p_enable_cback) (NFA_EE_MODE_SET_COMPLETE);
+#endif
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_restore_ntf_done
+**
+** Description      check if any ee_status still has NFA_EE_STATUS_PENDING bit
+**
+** Returns          true, if all NFA_EE_STATUS_PENDING bits are removed
+**
+*******************************************************************************/
+bool nfa_ee_restore_ntf_done(void) {
+  tNFA_EE_ECB* p_cb;
+  bool is_done = true;
+  int xx;
+
+  p_cb = nfa_ee_cb.ecb;
+  for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) {
+    if ((p_cb->nfcee_id != NFA_EE_INVALID) &&
+        (p_cb->ee_old_status & NFA_EE_STATUS_RESTORING)) {
+      is_done = false;
+      break;
+    }
+  }
+  return is_done;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_remove_pending
+**
+** Description      check if any ee_status still has NFA_EE_STATUS_RESTORING bit
+**
+** Returns          true, if all NFA_EE_STATUS_RESTORING bits are removed
+**
+*******************************************************************************/
+static void nfa_ee_remove_pending(void) {
+  tNFA_EE_ECB* p_cb;
+  tNFA_EE_ECB* p_cb_n, *p_cb_end;
+  int xx, num_removed = 0;
+  int first_removed = nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED;
+
+  p_cb = nfa_ee_cb.ecb;
+  for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) {
+    if ((p_cb->nfcee_id != NFA_EE_INVALID) &&
+        (p_cb->ee_status & NFA_EE_STATUS_RESTORING)) {
+      p_cb->nfcee_id = NFA_EE_INVALID;
+      num_removed++;
+      if (first_removed == nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED) first_removed = xx;
+    }
+  }
+
+  NFA_TRACE_DEBUG3(
+      "nfa_ee_remove_pending() cur_ee:%d, num_removed:%d first_removed:%d",
+      nfa_ee_cb.cur_ee, num_removed, first_removed);
+  if (num_removed && (first_removed != (nfa_ee_cb.cur_ee - num_removed))) {
+    /* if the removes ECB entried are not at the end, move the entries up */
+    p_cb_end = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1];
+    p_cb = &nfa_ee_cb.ecb[first_removed];
+    for (p_cb_n = p_cb + 1; p_cb_n <= p_cb_end;) {
+      while ((p_cb_n->nfcee_id == NFA_EE_INVALID) && (p_cb_n <= p_cb_end)) {
+        p_cb_n++;
+      }
+
+      if (p_cb_n <= p_cb_end) {
+        memcpy(p_cb, p_cb_n, sizeof(tNFA_EE_ECB));
+        p_cb_n->nfcee_id = NFA_EE_INVALID;
+      }
+      p_cb++;
+      p_cb_n++;
+    }
+  }
+  nfa_ee_cb.cur_ee -= (uint8_t)num_removed;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_nci_disc_rsp
+**
+** Description      Process the callback for NFCEE discovery response
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_nci_disc_rsp(tNFA_EE_MSG* p_data) {
+  tNFC_NFCEE_DISCOVER_REVT* p_evt = p_data->disc_rsp.p_data;
+  tNFA_EE_ECB* p_cb;
+  uint8_t xx;
+  uint8_t num_nfcee = p_evt->num_nfcee;
+  bool notify_enable_done = false;
+
+  NFA_TRACE_DEBUG3("nfa_ee_nci_disc_rsp() em_state:%d cur_ee:%d, num_nfcee:%d",
+                   nfa_ee_cb.em_state, nfa_ee_cb.cur_ee, num_nfcee);
+  switch (nfa_ee_cb.em_state) {
+    case NFA_EE_EM_STATE_INIT:
+      nfa_ee_cb.cur_ee = 0;
+      nfa_ee_cb.num_ee_expecting = 0;
+      if (num_nfcee == 0) {
+        nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
+        notify_enable_done = true;
+        if (p_evt->status != NFC_STATUS_OK) {
+          nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
+        }
+      }
+      break;
+
+    case NFA_EE_EM_STATE_INIT_DONE:
+      if (num_nfcee) {
+        /* if this is initiated by api function,
+         * check if the number of NFCEE expected is more than what's currently
+         * in CB */
+        if (num_nfcee > nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED)
+          num_nfcee = nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED;
+        if (nfa_ee_cb.cur_ee < num_nfcee) {
+          p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee];
+          for (xx = nfa_ee_cb.cur_ee; xx < num_nfcee; xx++, p_cb++) {
+            /* mark the new entries as a new one */
+            p_cb->nfcee_id = NFA_EE_INVALID;
+          }
+        }
+        nfa_ee_cb.cur_ee = num_nfcee;
+      }
+      break;
+
+    case NFA_EE_EM_STATE_RESTORING:
+      if (num_nfcee == 0) {
+        nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
+        nfa_ee_remove_pending();
+        nfa_ee_check_restore_complete();
+        if (p_evt->status != NFC_STATUS_OK) {
+          nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
+        }
+      }
+      break;
+  }
+
+  if (p_evt->status == NFC_STATUS_OK) {
+    nfa_ee_cb.num_ee_expecting = p_evt->num_nfcee;
+    if (nfa_ee_cb.num_ee_expecting > nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED) {
+      NFA_TRACE_ERROR2("NFA-EE num_ee_expecting:%d > max:%d",
+                       nfa_ee_cb.num_ee_expecting, nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED);
+    }
+  }
+  nfa_ee_report_disc_done(notify_enable_done);
+  NFA_TRACE_DEBUG3(
+      "nfa_ee_nci_disc_rsp() em_state:%d cur_ee:%d num_ee_expecting:%d",
+      nfa_ee_cb.em_state, nfa_ee_cb.cur_ee, nfa_ee_cb.num_ee_expecting);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_nci_disc_ntf
+**
+** Description      Process the callback for NFCEE discovery notification
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_nci_disc_ntf(tNFA_EE_MSG* p_data) {
+  tNFC_NFCEE_INFO_REVT* p_ee = p_data->disc_ntf.p_data;
+  tNFA_EE_ECB* p_cb = NULL;
+  bool notify_enable_done = false;
+  bool notify_new_ee = false;
+  tNFA_EE_CBACK_DATA evt_data = {0};
+  tNFA_EE_INFO* p_info;
+  tNFA_EE_EM_STATE new_em_state = NFA_EE_EM_STATE_MAX;
+
+  NFA_TRACE_DEBUG5(
+      "nfa_ee_nci_disc_ntf() em_state:%d ee_flags:0x%x cur_ee:%d "
+      "num_ee_expecting:%d, nfa_ee_max_ee_cfg : %d",
+      nfa_ee_cb.em_state, nfa_ee_cb.ee_flags, nfa_ee_cb.cur_ee,
+      nfa_ee_cb.num_ee_expecting, nfa_ee_max_ee_cfg);
+  if (nfa_ee_cb.num_ee_expecting) {
+    nfa_ee_cb.num_ee_expecting--;
+    if ((nfa_ee_cb.num_ee_expecting == 0) &&
+        (nfa_ee_cb.p_ee_disc_cback != NULL)) {
+      /* Discovery triggered by API function */
+      if(NFA_GetNCIVersion() != NCI_VERSION_2_0)
+          NFC_NfceeDiscover(false);
+    }
+  }
+  switch (nfa_ee_cb.em_state) {
+    case NFA_EE_EM_STATE_INIT:
+      if (nfa_ee_cb.cur_ee < nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED) {
+        /* the cb can collect up to NFA_EE_MAX_EE_SUPPORTED ee_info */
+        p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee++];
+      }
+
+      if (nfa_ee_cb.num_ee_expecting == 0) {
+        /* notify init_done callback */
+        nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
+        notify_enable_done = true;
+      }
+      break;
+
+    case NFA_EE_EM_STATE_INIT_DONE:
+      p_cb = nfa_ee_find_ecb(p_ee->nfcee_id);
+      if (p_cb == NULL) {
+        /* the NFCEE ID is not in the last NFCEE discovery
+         * maybe it's a new one */
+        p_cb = nfa_ee_find_ecb(NFA_EE_INVALID);
+        if (p_cb) {
+          nfa_ee_cb.cur_ee++;
+          notify_new_ee = true;
+        }
+      } else if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ORDER) {
+        nfa_ee_cb.cur_ee++;
+        notify_new_ee = true;
+      } else {
+        NFA_TRACE_DEBUG3("cur_ee:%d ecb_flags=0x%02x  ee_status=0x%x",
+                         nfa_ee_cb.cur_ee, p_cb->ecb_flags, p_cb->ee_status);
+      }
+      break;
+
+    case NFA_EE_EM_STATE_RESTORING:
+      p_cb = nfa_ee_find_ecb(p_ee->nfcee_id);
+      if (p_cb == NULL) {
+        /* the NFCEE ID is not in the last NFCEE discovery
+         * maybe it's a new one */
+        p_cb = nfa_ee_find_ecb(NFA_EE_INVALID);
+        if (p_cb) {
+          nfa_ee_cb.cur_ee++;
+          notify_new_ee = true;
+        }
+      }
+      if (nfa_ee_cb.num_ee_expecting == 0) {
+        /* notify init_done callback */
+        notify_enable_done = true;
+        if (nfa_ee_restore_ntf_done()) {
+          new_em_state = NFA_EE_EM_STATE_INIT_DONE;
+        }
+      }
+      break;
+  }
+  NFA_TRACE_DEBUG1("nfa_ee_nci_disc_ntf cur_ee:%d", nfa_ee_cb.cur_ee);
+
+  if (p_cb) {
+    p_cb->nfcee_id = p_ee->nfcee_id;
+    p_cb->ee_status = p_ee->ee_status;
+    p_cb->num_interface = p_ee->num_interface;
+    memcpy(p_cb->ee_interface, p_ee->ee_interface, p_ee->num_interface);
+    p_cb->num_tlvs = p_ee->num_tlvs;
+    memcpy(p_cb->ee_tlv, p_ee->ee_tlv, p_ee->num_tlvs * sizeof(tNFA_EE_TLV));
+
+
+    p_cb->ee_power_supply_status = p_ee->nfcee_power_ctrl;
+    if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_RESTORING) {
+      /* NCI spec says: An NFCEE_DISCOVER_NTF that contains a Protocol type of
+       * "HCI Access"
+       * SHALL NOT contain any other additional Protocol
+       * i.e. check only first supported NFCEE interface is HCI access */
+      /* NFA_HCI module handles restoring configurations for HCI access */
+      if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) {
+        if ((nfa_ee_cb.ee_flags & NFA_EE_FLAG_WAIT_HCI) == 0) {
+          nfa_ee_restore_one_ecb(p_cb);
+        }
+        /* else wait for NFA-HCI module to restore the HCI network information
+         * before enabling the NFCEE */
+      }
+    }
+    NFA_TRACE_DEBUG4("nfa_ee_cb.p_ee_disc_cback : %d notify_new_ee :%d "
+    "nfa_dm_is_active() : %d p_cb->ee_status : %d", nfa_ee_cb.p_ee_disc_cback, notify_new_ee,
+     nfa_dm_is_active(), p_cb->ee_status);
+
+    if ((nfa_ee_cb.p_ee_disc_cback == NULL) && (notify_new_ee == true)) {
+      if (nfa_dm_is_active() && (p_cb->ee_status != NFA_EE_STATUS_REMOVED)) {
+        /* report this NFA_EE_NEW_EE_EVT only after NFA_DM_ENABLE_EVT is
+         * reported */
+        p_info = &evt_data.new_ee;
+        p_info->ee_handle = NFA_HANDLE_GROUP_EE | (tNFA_HANDLE)p_cb->nfcee_id;
+        p_info->ee_status = p_cb->ee_status;
+        p_info->num_interface = p_cb->num_interface;
+        p_info->num_tlvs = p_cb->num_tlvs;
+        memcpy(p_info->ee_interface, p_cb->ee_interface, p_cb->num_interface);
+        memcpy(p_info->ee_tlv, p_cb->ee_tlv,
+               p_cb->num_tlvs * sizeof(tNFA_EE_TLV));
+        if(NFA_GetNCIVersion() == NCI_VERSION_2_0)
+          p_info->ee_power_supply_status = p_cb->ee_power_supply_status;
+        nfa_ee_report_event(NULL, NFA_EE_NEW_EE_EVT, &evt_data);
+      }
+
+#if (NXP_EXTNS == TRUE)
+      if (nfa_dm_is_active()) {
+        evt_data.status = p_cb->ee_status;
+        evt_data.ee_discover.num_ee = nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED;
+        NFA_EeGetInfo(&evt_data.ee_discover.num_ee,
+                      evt_data.ee_discover.ee_info);
+        nfa_ee_report_event(NULL, NFA_EE_DISCOVER_EVT, &evt_data);
+      }
+#endif
+    } else
+      nfa_ee_report_disc_done(notify_enable_done);
+
+    if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ORDER) {
+      NFA_TRACE_DEBUG0("NFA_EE_ECB_FLAGS_ORDER");
+      p_cb->ecb_flags &= ~NFA_EE_ECB_FLAGS_ORDER;
+      nfa_ee_report_discover_req_evt();
+    }
+  }
+
+  if (new_em_state != NFA_EE_EM_STATE_MAX) {
+    nfa_ee_cb.em_state = new_em_state;
+    nfa_ee_check_restore_complete();
+  }
+
+  if ((nfa_ee_cb.cur_ee == nfa_ee_max_ee_cfg) &&
+      (nfa_ee_cb.em_state == NFA_EE_EM_STATE_INIT_DONE)) {
+    if (nfa_ee_cb.discv_timer.in_use) {
+      nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
+      p_data->hdr.event = NFA_EE_DISCV_TIMEOUT_EVT;
+      nfa_ee_evt_hdlr((NFC_HDR*)p_data);
+    }
+  }
+#if (NXP_EXTNS == TRUE)
+  if (p_cb) {
+    if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) &&
+        (p_cb->ee_status != NFA_EE_STATUS_ACTIVE)) {
+      NFA_TRACE_DEBUG2(
+          "nfa_ee_nci_disc_ntf hci_state : 0x%02x  ee_status : 0x%02x",
+          nfa_hci_cb.hci_state, p_cb->ee_status);
+      nfa_sys_stop_timer(&nfa_hci_cb.timer);
+      nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, 150);
+    }
+  }
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_nci_nfcee_status_ntf
+**
+** Description      Process the callback for NFCEE status notification
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_nci_nfcee_status_ntf(tNFA_EE_MSG* p_data) {
+  tNFC_NFCEE_STATUS_REVT* p_ee = p_data->nfcee_status_ntf.p_data;
+  NFA_TRACE_DEBUG3(
+      "nfa_ee_nci_nfcee_status_ntf() em_state:%d, nfcee_id:%d nfcee_status:%d",
+      nfa_ee_cb.em_state, p_ee->nfcee_id, p_ee->status);
+  tNFA_EE_ECB* p_cb = nfa_ee_find_ecb(p_ee->nfcee_id);
+  if(p_ee->status == NFC_NFCEE_STS_UNRECOVERABLE_ERROR) {
+    if(p_cb != NULL) {
+        if (nfa_ee_cb.p_enable_cback)
+                    (*nfa_ee_cb.p_enable_cback) (NFA_EE_RECOVERY);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_check_restore_complete
+**
+** Description      Check if restore the NFA-EE related configuration to the
+**                  state prior to low power mode is complete.
+**                  If complete, notify sys.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_check_restore_complete(void) {
+  uint32_t xx;
+  tNFA_EE_ECB* p_cb;
+  bool proc_complete = true;
+
+  p_cb = nfa_ee_cb.ecb;
+  for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) {
+    if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE) {
+      /* NFA_HCI module handles restoring configurations for HCI access.
+       * ignore the restoring status for HCI Access */
+      if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) {
+        proc_complete = false;
+        break;
+      }
+    }
+  }
+
+  NFA_TRACE_DEBUG2(
+      "nfa_ee_check_restore_complete nfa_ee_cb.ee_cfg_sts:0x%02x "
+      "proc_complete:%d",
+      nfa_ee_cb.ee_cfg_sts, proc_complete);
+  if (proc_complete) {
+    /* update routing table when NFA_EE_ROUT_TIMEOUT_EVT is received */
+    if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_PREV_ROUTING)
+      nfa_ee_api_update_now(NULL);
+
+    nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
+    nfa_sys_cback_notify_nfcc_power_mode_proc_complete(NFA_ID_EE);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_build_discover_req_evt
+**
+** Description      Build NFA_EE_DISCOVER_REQ_EVT for all active NFCEE
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_ee_build_discover_req_evt(tNFA_EE_DISCOVER_REQ* p_evt_data) {
+  tNFA_EE_ECB* p_cb;
+  tNFA_EE_DISCOVER_INFO* p_info;
+  uint8_t xx;
+
+  if (!p_evt_data) return;
+
+  p_evt_data->num_ee = 0;
+  p_cb = nfa_ee_cb.ecb;
+  p_info = p_evt_data->ee_disc_info;
+
+  for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) {
+    if ((p_cb->ee_status & NFA_EE_STATUS_INT_MASK) ||
+        (p_cb->ee_status != NFA_EE_STATUS_ACTIVE) ||
+        ((p_cb->ecb_flags & NFA_EE_ECB_FLAGS_DISC_REQ) == 0)) {
+      continue;
+    }
+    p_info->ee_handle = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE;
+    p_info->la_protocol = p_cb->la_protocol;
+    p_info->lb_protocol = p_cb->lb_protocol;
+    p_info->lf_protocol = p_cb->lf_protocol;
+    p_info->lbp_protocol = p_cb->lbp_protocol;
+#if (NXP_EXTNS == TRUE)
+    // code to handle and store Reader type(A/B) requested for Reader over SWP.
+    /*Reader over SWP*/
+    p_info->pa_protocol = p_cb->pa_protocol;
+    p_info->pb_protocol = p_cb->pb_protocol;
+    p_info->ee_req_op = p_cb->ee_req_op;
+#endif
+    p_evt_data->num_ee++;
+    p_info++;
+
+    NFA_TRACE_DEBUG6(
+        "[%d] ee_handle:0x%x, listen protocol A:%d, B:%d, F:%d, BP:%d",
+        p_evt_data->num_ee, p_cb->nfcee_id, p_cb->la_protocol,
+        p_cb->lb_protocol, p_cb->lf_protocol, p_cb->lbp_protocol);
+  }
+
+  p_evt_data->status = NFA_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_report_discover_req_evt
+**
+** Description      Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_ee_report_discover_req_evt(void) {
+  tNFA_EE_DISCOVER_REQ evt_data;
+
+  if (nfa_ee_cb.p_enable_cback)
+    (*nfa_ee_cb.p_enable_cback)(NFA_EE_DISC_STS_REQ);
+
+  /* if this is restoring NFCC */
+  if (!nfa_dm_is_active()) {
+    NFA_TRACE_DEBUG0("nfa_ee_report_discover_req_evt DM is not active");
+    return;
+  }
+
+  nfa_ee_build_discover_req_evt(&evt_data);
+  nfa_ee_report_event(NULL, NFA_EE_DISCOVER_REQ_EVT, (void*)&evt_data);
+}
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         nfa_ee_nci_pwr_link_ctrl_rsp
+**
+** Description      Process the result for NFCEE PWR and link ctrl response
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_nci_pwr_link_ctrl_rsp(tNFA_EE_MSG* p_data) {
+    NFA_TRACE_DEBUG0(" nfa_ee_nci_pwr_link_ctrl_rsp()");
+    if(nfcFL.eseFL._WIRED_MODE_STANDBY != true) {
+        NFA_TRACE_DEBUG0(" WIRED_MODE_STANDBY() not available. Returning");
+        return;
+    }
+    tNFA_EE_ECB* p_cb;
+    tNFA_EE_PWR_LNK_CTRL pwr_lnk_ctrl;
+    tNFC_NFCEE_EE_PWR_LNK_REVT* p_rsp = p_data->pwr_lnk_ctrl_rsp.p_data;
+    pwr_lnk_ctrl.status = p_rsp->status;
+    NFA_TRACE_DEBUG1(" nfa_ee_nci_pwr_link_ctrl_rsp: status = %d ",
+            pwr_lnk_ctrl.status);
+    nfa_ee_report_event(NULL, NFA_EE_PWR_LINK_CTRL_EVT,
+            (tNFA_EE_CBACK_DATA*)&pwr_lnk_ctrl);
+}
+/*******************************************************************************
+**
+** Function         nfa_ee_nci_set_mode_info
+**
+** Description      Process the result for NFCEE PWR and link ctrl response
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_nci_set_mode_info(tNFA_EE_MSG* p_data) {
+  tNFA_EE_SET_MODE_INFO ee_set_mode_info;
+  tNFC_NFCEE_MODE_SET_INFO* p_rsp = p_data->mode_set_info.p_data;
+  ee_set_mode_info.status = p_rsp->status;
+  ee_set_mode_info.nfcee_id = p_rsp->nfcee_id;
+  NFA_TRACE_DEBUG1(" nfa_ee_nci_set_mode_info: status = %d ",
+                   ee_set_mode_info.status);
+  if (nfa_ee_cb.p_enable_cback)
+    (*nfa_ee_cb.p_enable_cback)(NFA_EE_MODE_SET_NTF);
+  nfa_ee_report_event(NULL, NFA_EE_SET_MODE_INFO_EVT,
+                      (tNFA_EE_CBACK_DATA*)&ee_set_mode_info);
+}
+
+#endif
+/*******************************************************************************
+**
+** Function         nfa_ee_nci_mode_set_rsp
+**
+** Description      Process the result for NFCEE ModeSet response
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_nci_mode_set_rsp(tNFA_EE_MSG* p_data) {
+  tNFA_EE_ECB* p_cb;
+  tNFA_EE_MODE_SET mode_set;
+  tNFC_NFCEE_MODE_SET_REVT* p_rsp = p_data->mode_set_rsp.p_data;
+
+  NFA_TRACE_DEBUG3("nfa_ee_nci_mode_set_rsp() handle:0x%02x mode:%d statu : %d",
+                   p_rsp->nfcee_id, p_rsp->mode, p_rsp->status);
+  p_cb = nfa_ee_find_ecb(p_rsp->nfcee_id);
+
+  if (p_cb == NULL) {
+    NFA_TRACE_ERROR1(
+        "nfa_ee_nci_mode_set_rsp() Can not find cb for handle:0x%02x",
+        p_rsp->nfcee_id);
+    return;
+  }
+#if (NXP_EXTNS == TRUE)
+/* Do not update routing table on secure element enable/disable. */
+#else
+  /* update routing table and vs on mode change */
+  nfa_ee_start_timer();
+#endif
+  if (p_rsp->status == NFA_STATUS_OK) {
+    if (p_rsp->mode == NFA_EE_MD_ACTIVATE) {
+#if (NXP_EXTNS == TRUE)
+      if (p_cb->ee_status != NFC_NFCEE_STATUS_REMOVED)
+#endif
+        p_cb->ee_status = NFC_NFCEE_STATUS_ACTIVE;
+    } else {
+#if (NXP_EXTNS == TRUE)
+/* Do not update routing table on secure element enable/disable. */
+#else
+      if (p_cb->tech_switch_on | p_cb->tech_switch_off |
+          p_cb->tech_battery_off | p_cb->proto_switch_on |
+          p_cb->proto_switch_off | p_cb->proto_battery_off |
+          p_cb->aid_entries | p_cb->apdu_pattern_entries) {
+        /* this NFCEE still has configuration when deactivated. clear the
+         * configuration */
+        nfa_ee_cb.ee_cfged &= ~nfa_ee_ecb_to_mask(p_cb);
+        nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_CHANGED_ROUTING;
+        NFA_TRACE_DEBUG0("deactivating/still configured. Force update");
+      }
+      p_cb->tech_switch_on = p_cb->tech_switch_off = p_cb->tech_battery_off = 0;
+      p_cb->proto_switch_on = p_cb->proto_switch_off = p_cb->proto_battery_off =
+          0;
+      p_cb->apdu_pattern_entries = p_cb->aid_entries = 0;
+#endif
+#if (NXP_EXTNS == TRUE)
+      if (p_cb->ee_status != NFC_NFCEE_STATUS_REMOVED)
+#endif
+        p_cb->ee_status = NFC_NFCEE_STATUS_INACTIVE;
+    }
+  } else {
+    if (p_rsp->mode == NFA_EE_MD_ACTIVATE) {
+      p_cb->ee_status = NFC_NFCEE_STATUS_REMOVED;
+    }
+  }
+  NFA_TRACE_DEBUG4("status:%d ecb_flags  :0x%02x ee_cfged:0x%02x ee_status:%d",
+                   p_rsp->status, p_cb->ecb_flags, nfa_ee_cb.ee_cfged,
+                   p_cb->ee_status);
+  if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE) {
+    if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) {
+      /* NFA_HCI module handles restoring configurations for HCI access */
+      if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) {
+        NFC_ConnCreate(NCI_DEST_TYPE_NFCEE, p_cb->nfcee_id, p_cb->use_interface,
+                       nfa_ee_conn_cback);
+      }
+    } else {
+      p_cb->ecb_flags &= ~NFA_EE_ECB_FLAGS_RESTORE;
+      nfa_ee_check_restore_complete();
+    }
+  } else {
+    mode_set.status = p_rsp->status;
+    mode_set.ee_handle = (tNFA_HANDLE)p_rsp->nfcee_id | NFA_HANDLE_GROUP_EE;
+    mode_set.ee_status = p_cb->ee_status;
+
+    nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_MODE_SET_EVT,
+                        (void*)&mode_set);
+
+#ifdef NXP_NCI20_DUAL_UICC
+    if ((p_cb->ee_status == NFC_NFCEE_STATUS_INACTIVE) ||
+        (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE)) {
+      /* Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE */
+      nfa_ee_report_discover_req_evt();
+    }
+#endif
+  }
+  if(NFA_GetNCIVersion() == NCI_VERSION_2_0)
+  {
+      if (nfa_ee_cb.p_enable_cback)
+                  (*nfa_ee_cb.p_enable_cback) (NFA_EE_MODE_SET_COMPLETE);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_report_update_evt
+**
+** Description      Check if need to report NFA_EE_UPDATED_EVT
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_report_update_evt(void) {
+  tNFA_EE_CBACK_DATA evt_data;
+
+  NFA_TRACE_DEBUG2("nfa_ee_report_update_evt ee_wait_evt:0x%x wait_rsp:%d",
+                   nfa_ee_cb.ee_wait_evt, nfa_ee_cb.wait_rsp);
+  if (nfa_ee_cb.wait_rsp == 0) {
+    nfa_ee_cb.ee_wait_evt &= ~NFA_EE_WAIT_UPDATE_RSP;
+
+    if (nfa_ee_cb.ee_wait_evt & NFA_EE_WAIT_UPDATE) {
+      nfa_ee_cb.ee_wait_evt &= ~NFA_EE_WAIT_UPDATE;
+      /* finished updating NFCC; report NFA_EE_UPDATED_EVT now */
+      evt_data.status = NFA_STATUS_OK;
+      nfa_ee_report_event(NULL, NFA_EE_UPDATED_EVT, &evt_data);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_nci_wait_rsp
+**
+** Description      Process the result for NCI response
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_nci_wait_rsp(tNFA_EE_MSG* p_data) {
+  tNFA_EE_NCI_WAIT_RSP* p_rsp = &p_data->wait_rsp;
+
+  NFA_TRACE_DEBUG2("nfa_ee_nci_wait_rsp() ee_wait_evt:0x%x wait_rsp:%d",
+                   nfa_ee_cb.ee_wait_evt, nfa_ee_cb.wait_rsp);
+  if (nfa_ee_cb.wait_rsp) {
+    if (p_rsp->opcode == NCI_MSG_RF_SET_ROUTING) nfa_ee_cb.wait_rsp--;
+  }
+  nfa_ee_report_update_evt();
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_nci_conn
+**
+** Description      process the connection callback events
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_nci_conn(tNFA_EE_MSG* p_data) {
+  tNFA_EE_ECB* p_cb;
+  tNFA_EE_NCI_CONN* p_cbk = &p_data->conn;
+  tNFC_CONN* p_conn = p_data->conn.p_data;
+  NFC_HDR* p_pkt = NULL;
+  tNFA_EE_CBACK_DATA evt_data = {0};
+  tNFA_EE_EVT event = NFA_EE_INVALID;
+  tNFA_EE_CBACK* p_cback = NULL;
+
+  if (p_cbk->event == NFC_CONN_CREATE_CEVT) {
+    p_cb = nfa_ee_find_ecb(p_cbk->p_data->conn_create.id);
+  } else {
+    p_cb = nfa_ee_find_ecb_by_conn_id(p_cbk->conn_id);
+    if (p_cbk->event == NFC_DATA_CEVT) p_pkt = p_conn->data.p_data;
+  }
+
+  if (p_cb) {
+    p_cback = p_cb->p_ee_cback;
+    evt_data.handle = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE;
+    switch (p_cbk->event) {
+      case NFC_CONN_CREATE_CEVT:
+        if (p_conn->conn_create.status == NFC_STATUS_OK) {
+          p_cb->conn_id = p_cbk->conn_id;
+          p_cb->conn_st = NFA_EE_CONN_ST_CONN;
+        } else {
+          p_cb->conn_st = NFA_EE_CONN_ST_NONE;
+        }
+        if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE) {
+          p_cb->ecb_flags &= ~NFA_EE_ECB_FLAGS_RESTORE;
+          nfa_ee_check_restore_complete();
+        } else {
+          evt_data.connect.status = p_conn->conn_create.status;
+          evt_data.connect.ee_interface = p_cb->use_interface;
+          event = NFA_EE_CONNECT_EVT;
+        }
+        break;
+
+      case NFC_CONN_CLOSE_CEVT:
+        if (p_cb->conn_st != NFA_EE_CONN_ST_DISC) event = NFA_EE_DISCONNECT_EVT;
+        p_cb->conn_st = NFA_EE_CONN_ST_NONE;
+        p_cb->p_ee_cback = NULL;
+        p_cb->conn_id = 0;
+
+#if(NXP_EXTNS == TRUE)
+        nfa_ee_cb.ee_flags &= ~NFA_EE_HCI_CONN_CLOSE;
+#endif
+        if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_DISABLING) {
+          if (nfa_ee_cb.ee_flags & NFA_EE_FLAG_WAIT_DISCONN) {
+            if (nfa_ee_cb.num_ee_expecting) {
+              nfa_ee_cb.num_ee_expecting--;
+            }
+          }
+          if (nfa_ee_cb.num_ee_expecting == 0) {
+            nfa_ee_cb.ee_flags &= ~NFA_EE_FLAG_WAIT_DISCONN;
+            nfa_ee_check_disable();
+          }
+        }
+        break;
+
+      case NFC_DATA_CEVT:
+        if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) {
+          /* report data event only in connected state */
+          if (p_cb->p_ee_cback && p_pkt) {
+            evt_data.data.len = p_pkt->len;
+            evt_data.data.p_buf = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
+            event = NFA_EE_DATA_EVT;
+            p_pkt = NULL; /* so this function does not free this GKI buffer */
+          }
+        }
+        break;
+    }
+
+    if ((event != NFA_EE_INVALID) && (p_cback)) (*p_cback)(event, &evt_data);
+  }
+  if (p_pkt) GKI_freebuf(p_pkt);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_nci_action_ntf
+**
+** Description      process the NFCEE action callback event
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_nci_action_ntf(tNFA_EE_MSG* p_data) {
+  tNFC_EE_ACTION_REVT* p_cbk = p_data->act.p_data;
+  tNFA_EE_ACTION evt_data;
+
+  evt_data.ee_handle = (tNFA_HANDLE)p_cbk->nfcee_id | NFA_HANDLE_GROUP_EE;
+  evt_data.trigger = p_cbk->act_data.trigger;
+  memcpy(&(evt_data.param), &(p_cbk->act_data.param),
+         sizeof(tNFA_EE_ACTION_PARAM));
+#if (NXP_EXTNS == TRUE)
+  /*If DWP CL started inform to HCI*/
+  if (evt_data.ee_handle == 0x4C0) {
+    nfa_ee_ce_p61_active = 0x01;
+  }
+#endif
+  nfa_ee_report_event(NULL, NFA_EE_ACTION_EVT, (void*)&evt_data);
+}
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         nfa_ee_get_supported_tech_list
+**
+** Description      provides the supported technology list of given nfcee id
+**
+** Returns          uint8_t
+**
+*******************************************************************************/
+uint8_t nfa_ee_get_supported_tech_list(uint8_t nfcee_id) {
+  uint8_t tech_list = 0;
+  tNFA_EE_ECB* p_cb = NULL;
+
+  p_cb = nfa_ee_find_ecb(nfcee_id);
+  if (p_cb) {
+    if (p_cb->la_protocol) tech_list |= NFA_TECHNOLOGY_MASK_A;
+    if (p_cb->lb_protocol) tech_list |= NFA_TECHNOLOGY_MASK_B;
+    if (p_cb->lf_protocol) tech_list |= NFA_TECHNOLOGY_MASK_F;
+  } else {
+    NFA_TRACE_DEBUG1("Cannot find cb for given nfcee_id: 0x%x", nfcee_id);
+  }
+  NFA_TRACE_DEBUG2("supported tech list is 0x0%x for given nfcee_id: 0x%x ",
+                   tech_list, nfcee_id);
+  return tech_list;
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         nfa_ee_nci_disc_req_ntf
+**
+** Description      process the NFCEE discover request callback event
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_nci_disc_req_ntf(tNFA_EE_MSG* p_data) {
+  tNFC_EE_DISCOVER_REQ_REVT* p_cbk = p_data->disc_req.p_data;
+  tNFA_HANDLE ee_handle;
+  tNFA_EE_ECB* p_cb = NULL;
+  uint8_t report_ntf = 0;
+  uint8_t xx;
+
+  NFA_TRACE_DEBUG2("nfa_ee_nci_disc_req_ntf () num_info: %d cur_ee:%d",
+                   p_cbk->num_info, nfa_ee_cb.cur_ee);
+
+  for (xx = 0; xx < p_cbk->num_info; xx++) {
+    ee_handle = NFA_HANDLE_GROUP_EE | p_cbk->info[xx].nfcee_id;
+
+    p_cb = nfa_ee_find_ecb(p_cbk->info[xx].nfcee_id);
+    if (!p_cb) {
+      NFA_TRACE_DEBUG1("Cannot find cb for NFCEE: 0x%x",
+                       p_cbk->info[xx].nfcee_id);
+      p_cb = nfa_ee_find_ecb(NFA_EE_INVALID);
+      if (p_cb) {
+        p_cb->nfcee_id = p_cbk->info[xx].nfcee_id;
+        p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_ORDER;
+      } else {
+        NFA_TRACE_ERROR1("Cannot allocate cb for NFCEE: 0x%x",
+                         p_cbk->info[xx].nfcee_id);
+        continue;
+      }
+    } else {
+      report_ntf |= nfa_ee_ecb_to_mask(p_cb);
+    }
+
+    p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_DISC_REQ;
+#if (NXP_EXTNS == TRUE)
+    p_cb->ee_req_op = p_cbk->info[xx].op;
+#endif
+    if (p_cbk->info[xx].op == NFC_EE_DISC_OP_ADD) {
+      if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A) {
+        p_cb->la_protocol = p_cbk->info[xx].protocol;
+      } else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B) {
+        p_cb->lb_protocol = p_cbk->info[xx].protocol;
+      } else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F) {
+        p_cb->lf_protocol = p_cbk->info[xx].protocol;
+      } else if (p_cbk->info[xx].tech_n_mode ==
+                 NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) {
+        p_cb->lbp_protocol = p_cbk->info[xx].protocol;
+      }
+#if (NXP_EXTNS == TRUE)
+      // code to handle and store Reader type(A/B) requested for Reader over
+      // SWP.
+      /*Reader over SWP*/
+      else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_POLL_A) {
+        p_cb->pa_protocol = p_cbk->info[xx].protocol;
+      } else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_POLL_B) {
+        p_cb->pb_protocol = p_cbk->info[xx].protocol;
+      }
+#endif
+      NFA_TRACE_DEBUG6(
+          "nfcee_id=0x%x ee_status=0x%x ecb_flags=0x%x la_protocol=0x%x "
+          "lb_protocol=0x%x lf_protocol=0x%x",
+          p_cb->nfcee_id, p_cb->ee_status, p_cb->ecb_flags, p_cb->la_protocol,
+          p_cb->lb_protocol, p_cb->lf_protocol);
+    } else {
+      if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A) {
+        p_cb->la_protocol = 0;
+      } else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B) {
+        p_cb->lb_protocol = 0;
+      } else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F) {
+        p_cb->lf_protocol = 0;
+      } else if (p_cbk->info[xx].tech_n_mode ==
+                 NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) {
+        p_cb->lbp_protocol = 0;
+      }
+#if (NXP_EXTNS == TRUE)
+      // code to handle and store Reader type(A/B) requested for Reader over
+      // SWP.
+      /*Reader over SWP*/
+      else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_POLL_A) {
+        p_cb->pa_protocol = 0xFF;
+      } else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_POLL_B) {
+        p_cb->pb_protocol = 0xFF;
+      }
+#endif
+    }
+  }
+
+  /* Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE */
+  if (report_ntf) nfa_ee_report_discover_req_evt();
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_is_active
+**
+** Description      Check if the given NFCEE is active
+**
+** Returns          true if the given NFCEE is active
+**
+*******************************************************************************/
+bool nfa_ee_is_active(tNFA_HANDLE nfcee_id) {
+  bool is_active = false;
+  int xx;
+  tNFA_EE_ECB* p_cb = nfa_ee_cb.ecb;
+
+#if (NXP_EXTNS == TRUE)
+  // Added case for NFCEE_DH.
+  if (nfcee_id == NFA_EE_HANDLE_DH) {
+    is_active = true;
+    goto TheEnd;
+  }
+#endif
+  if ((NFA_HANDLE_GROUP_MASK & nfcee_id) == NFA_HANDLE_GROUP_EE)
+    nfcee_id &= NFA_HANDLE_MASK;
+
+  /* compose output */
+  for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) {
+    if ((tNFA_HANDLE)p_cb->nfcee_id == nfcee_id) {
+      if (p_cb->ee_status == NFA_EE_STATUS_ACTIVE) {
+        is_active = true;
+      }
+      break;
+    }
+  }
+#if (NXP_EXTNS == TRUE)
+TheEnd:
+#endif
+  return is_active;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_get_tech_route
+**
+** Description      Given a power state, find the technology routing
+**                  destination. The result is filled in the given p_handles
+**                  in the order of A, B, F, Bprime
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_ee_get_tech_route(uint8_t power_state, uint8_t* p_handles) {
+  int xx, yy;
+  tNFA_EE_ECB* p_cb;
+  uint8_t tech_mask_list[NFA_EE_MAX_TECH_ROUTE] = {
+      NFA_TECHNOLOGY_MASK_A, NFA_TECHNOLOGY_MASK_B, NFA_TECHNOLOGY_MASK_F,
+      NFA_TECHNOLOGY_MASK_B_PRIME};
+
+  NFA_TRACE_DEBUG1("nfa_ee_get_tech_route(): power state : %d", power_state);
+
+  for (xx = 0; xx < NFA_EE_MAX_TECH_ROUTE; xx++) {
+    p_handles[xx] = NFC_DH_ID;
+    p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1];
+    for (yy = 0; yy < nfa_ee_cb.cur_ee; yy++, p_cb--) {
+      if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE) {
+        switch (power_state) {
+          case NFA_EE_PWR_STATE_ON:
+            if (p_cb->tech_switch_on & tech_mask_list[xx])
+              p_handles[xx] = p_cb->nfcee_id;
+            break;
+          case NFA_EE_PWR_STATE_SWITCH_OFF:
+            if (p_cb->tech_switch_off & tech_mask_list[xx])
+              p_handles[xx] = p_cb->nfcee_id;
+            break;
+          case NFA_EE_PWR_STATE_BATT_OFF:
+            if (p_cb->tech_battery_off & tech_mask_list[xx])
+              p_handles[xx] = p_cb->nfcee_id;
+            break;
+        }
+      }
+    }
+  }
+  NFA_TRACE_DEBUG4(
+      "TechA route: 0x%x, TechB route: 0x%x, TechF route: 0x%x, TechB' route: "
+      "0x%x",
+      p_handles[0], p_handles[1], p_handles[2], p_handles[3]);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_check_set_routing
+**
+** Description      If the new size exceeds the capacity of next block,
+**                  send the routing command now and reset the related
+**                  parameters.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_check_set_routing(uint16_t new_size, int* p_max_len, uint8_t* p,
+                              int* p_cur_offset) {
+  uint8_t max_tlv = (uint8_t)((*p_max_len > NFA_EE_ROUT_MAX_TLV_SIZE)
+                                  ? NFA_EE_ROUT_MAX_TLV_SIZE
+                                  : *p_max_len);
+  tNFA_STATUS status = NFA_STATUS_OK;
+
+  if (new_size + *p_cur_offset > max_tlv) {
+    if (NFC_SetRouting(true, *p, *p_cur_offset, p + 1) == NFA_STATUS_OK) {
+      nfa_ee_cb.wait_rsp++;
+    }
+    /* after the routing command is sent, re-use the same buffer to send the
+     * next routing command.
+     * reset the related parameters */
+    if (*p_max_len > *p_cur_offset)
+      *p_max_len -= *p_cur_offset; /* the max is reduced */
+    else
+      *p_max_len = 0;
+    *p_cur_offset = 0; /* nothing is in queue any more */
+    *p = 0;            /* num_tlv=0 */
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_route_add_one_ecb
+**
+** Description      Add the routing entries for one NFCEE/DH
+**
+** Returns          NFA_STATUS_OK, if ok to continue
+**
+*******************************************************************************/
+tNFA_STATUS nfa_ee_route_add_one_ecb(tNFA_EE_ECB* p_cb, int* p_max_len,
+                                     bool more, uint8_t* ps,
+                                     int* p_cur_offset) {
+  uint8_t* p, *pa;
+  uint16_t tlv_size;
+  uint8_t num_tlv, len;
+  int xx;
+  int start_offset;
+  uint8_t power_cfg = 0;
+  uint8_t* pp = ps + *p_cur_offset;
+  uint8_t entry_size;
+  uint8_t max_tlv;
+  uint8_t* p_start;
+  uint8_t new_size;
+  tNFA_STATUS status = NFA_STATUS_OK;
+
+  nfa_ee_check_set_routing(p_cb->size_mask, p_max_len, ps, p_cur_offset);
+  max_tlv = (uint8_t)((*p_max_len > NFA_EE_ROUT_MAX_TLV_SIZE)
+                          ? NFA_EE_ROUT_MAX_TLV_SIZE
+                          : *p_max_len);
+  /* use the first byte of the buffer (ps) to keep the num_tlv */
+  num_tlv = *ps;
+  NFA_TRACE_DEBUG5(
+      "nfa_ee_route_add_one_ecb max_len:%d, max_tlv:%d, cur_offset:%d, "
+      "more:%d, num_tlv:%d",
+      *p_max_len, max_tlv, *p_cur_offset, more, num_tlv);
+  pp = ps + 1 + *p_cur_offset;
+  p = pp;
+  tlv_size = (uint8_t)*p_cur_offset;
+/* Routing entries in the order of AID entries,protocol entries  and technology
+ * entries*/
+#if ((NXP_EXTNS == TRUE) && (NFC_NXP_LISTEN_ROUTE_TBL_OPTIMIZATION == TRUE))
+  /* add the AID routing */
+  if (p_cb->nfcee_id == NFC_DH_ID && p_cb->aid_entries) {
+    start_offset = 0;
+    for (xx = 0; xx < p_cb->aid_entries; xx++) {
+      /* rememebr the beginning of this AID routing entry, just in case we need
+       * to put it in next command */
+      uint8_t route_qual = 0;
+      p_start = pp;
+      /* add one AID entry */
+      if ((p_cb->aid_rt_info[xx] & NFA_EE_AE_ROUTE) &&
+          ((nfa_ee_nfeeid_active(p_cb->aid_rt_loc[xx]) == true) ||
+           (p_cb->aid_rt_loc[xx] == NFC_DH_ID))) {
+        num_tlv++;
+        pa = &p_cb->aid_cfg[start_offset];
+        pa++;        /* EMV tag */
+        len = *pa++; /* aid_len */
+        if(p_cb->aid_info[xx] & NCI_ROUTE_QUAL_LONG_SELECT)
+          route_qual |= NCI_ROUTE_QUAL_LONG_SELECT;
+        if(p_cb->aid_info[xx] & NCI_ROUTE_QUAL_SHORT_SELECT)
+          route_qual |= NCI_ROUTE_QUAL_SHORT_SELECT;
+        *pp = NFC_ROUTE_TAG_AID | route_qual;
+         pp++;
+        *pp++ = len + 2;
+        *pp++ = p_cb->aid_rt_loc[xx];
+        *pp++ = p_cb->aid_pwr_cfg[xx];
+        /* copy the AID */
+        memcpy(pp, pa, len);
+        pp += len;
+      }
+      start_offset += p_cb->aid_len[xx];
+      new_size = (uint8_t)(pp - p_start);
+      nfa_ee_check_set_routing(new_size, p_max_len, ps, p_cur_offset);
+      if (*ps == 0 && num_tlv > 0x00) {
+        /* just sent routing command, update local */
+        *ps = 1;
+        num_tlv = *ps;
+        *p_cur_offset = new_size;
+        pp = ps + 1;
+        p = pp;
+        tlv_size = (uint8_t)*p_cur_offset;
+        max_tlv = (uint8_t)((*p_max_len > NFA_EE_ROUT_MAX_TLV_SIZE)
+                                ? NFA_EE_ROUT_MAX_TLV_SIZE
+                                : *p_max_len);
+        memcpy(p, p_start, new_size);
+        pp += new_size;
+      } else {
+        /* add the new entry */
+        *ps = num_tlv;
+        *p_cur_offset += new_size;
+      }
+    }
+  }
+
+  /* Store the Protocol based routing in temporary buffer */
+  for (xx = 0; xx < NFA_EE_NUM_PROTO; xx++) {
+    power_cfg = 0;
+    if (p_cb->proto_switch_on & nfa_ee_proto_mask_list[xx])
+      power_cfg |= NCI_ROUTE_PWR_STATE_ON;
+    if (p_cb->proto_switch_off & nfa_ee_proto_mask_list[xx])
+      power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF;
+    if (p_cb->proto_battery_off & nfa_ee_proto_mask_list[xx])
+      power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF;
+
+    if (power_cfg != 0x00) {
+        if ((nfcFL.chipType == pn547C2) && (p_cb->nfcee_id == NFC_DH_ID)) {
+            power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_ON_LOCK();
+        }
+        else {
+            if (p_cb->proto_screen_lock & nfa_ee_proto_mask_list[xx])
+                power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_ON_LOCK();
+            if (p_cb->proto_screen_off & nfa_ee_proto_mask_list[xx])
+                power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_OFF_UNLOCK();
+            if (p_cb->proto_screen_off_lock & nfa_ee_proto_mask_list[xx])
+                power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_OFF_LOCK();
+        }
+    }
+    if (power_cfg) {
+        *proto_pp = NFC_ROUTE_TAG_PROTO;
+        proto_pp++;
+        *proto_pp++ = 3;
+        *proto_pp++ = p_cb->nfcee_id;
+        *proto_pp++ = power_cfg;
+        *proto_pp++ = nfa_ee_proto_list[xx];
+        proto_tlv_ctr++;
+        if (power_cfg != NCI_ROUTE_PWR_STATE_ON)
+            nfa_ee_cb.ee_cfged |= NFA_EE_CFGED_OFF_ROUTING;
+    }
+  }
+
+  /* add NFC-DEP routing to HOST */
+  if ((p_cb->nfcee_id == NFC_DH_ID) &&
+      !(nfa_ee_cb.ee_flags & NFA_EE_FLAG_CFG_NFC_DEP)) {
+    nfa_ee_cb.ee_flags |= NFA_EE_FLAG_CFG_NFC_DEP;
+    *proto_pp++ = NFC_ROUTE_TAG_PROTO;
+    *proto_pp++ = 3;
+    *proto_pp++ = NFC_DH_ID;
+    if (gNfaProvisionMode) {
+      /* only if device is in provision mode, set power state to screen locked
+       */
+      *proto_pp++ = 0x41;
+    } else {
+      *proto_pp++ = 1;
+    }
+    *proto_pp++ = NFC_PROTOCOL_NFC_DEP;
+    proto_tlv_ctr++;
+  }
+  /* store  the Technology based routing entries in temporary buffer */
+  for (xx = 0; xx < NFA_EE_NUM_TECH; xx++) {
+    power_cfg = 0;
+    if (p_cb->tech_switch_on & nfa_ee_tech_mask_list[xx])
+      power_cfg |= NCI_ROUTE_PWR_STATE_ON;
+    if (p_cb->tech_switch_off & nfa_ee_tech_mask_list[xx])
+      power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF;
+    if (p_cb->tech_battery_off & nfa_ee_tech_mask_list[xx])
+      power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF;
+
+    if (power_cfg & NCI_ROUTE_PWR_STATE_ON) {
+      if (p_cb->tech_screen_lock & nfa_ee_tech_mask_list[xx])
+        power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_ON_LOCK();
+      if (p_cb->tech_screen_off & nfa_ee_tech_mask_list[xx])
+        power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_OFF_UNLOCK();
+      if (p_cb->tech_screen_off_lock & nfa_ee_tech_mask_list[xx])
+          power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_OFF_LOCK();
+    }
+    if (power_cfg) {
+      *tech_pp++ = NFC_ROUTE_TAG_TECH;
+      *tech_pp++ = 3;
+      *tech_pp++ = p_cb->nfcee_id;
+      *tech_pp++ = power_cfg;
+      *tech_pp++ = nfa_ee_tech_list[xx];
+      tech_tlv_ctr++;
+      if (power_cfg != NCI_ROUTE_PWR_STATE_ON)
+        nfa_ee_cb.ee_cfged |= NFA_EE_CFGED_OFF_ROUTING;
+    }
+  }
+#else /* +Routing Entries in the order: Technology, protocol and AID entries \
+         */
+  /* add the Technology based routing */
+  for (xx = 0; xx < NFA_EE_NUM_TECH; xx++) {
+    power_cfg = 0;
+    if (p_cb->tech_switch_on & nfa_ee_tech_mask_list[xx])
+      power_cfg |= NCI_ROUTE_PWR_STATE_ON;
+    if (p_cb->tech_switch_off & nfa_ee_tech_mask_list[xx])
+      power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF;
+    if (p_cb->tech_battery_off & nfa_ee_tech_mask_list[xx])
+      power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF;
+#if (NXP_EXTNS == TRUE)
+
+    if (power_cfg & NCI_ROUTE_PWR_STATE_ON) {
+      if (p_cb->tech_screen_lock & nfa_ee_tech_mask_list[xx])
+        power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_ON_LOCK();
+      if (p_cb->tech_screen_off & nfa_ee_tech_mask_list[xx])
+        power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_OFF;
+      if (p_cb->tech_screen_off_lock & nfa_ee_tech_mask_list[xx])
+          power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_OFF_LOCK();
+    }
+#endif
+    if (power_cfg) {
+      *pp++ = NFC_ROUTE_TAG_TECH;
+      *pp++ = 3;
+      *pp++ = p_cb->nfcee_id;
+      *pp++ = power_cfg;
+      *pp++ = nfa_ee_tech_list[xx];
+      num_tlv++;
+      if (power_cfg != NCI_ROUTE_PWR_STATE_ON)
+        nfa_ee_cb.ee_cfged |= NFA_EE_CFGED_OFF_ROUTING;
+    }
+  }
+
+  /* add the Protocol based routing */
+  for (xx = 0; xx < NFA_EE_NUM_PROTO; xx++) {
+    power_cfg = 0;
+    if (p_cb->proto_switch_on & nfa_ee_proto_mask_list[xx])
+      power_cfg |= NCI_ROUTE_PWR_STATE_ON;
+    if (p_cb->proto_switch_off & nfa_ee_proto_mask_list[xx])
+      power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF;
+    if (p_cb->proto_battery_off & nfa_ee_proto_mask_list[xx])
+      power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF;
+#if (NXP_EXTNS == TRUE)
+
+    if (power_cfg != 0x00) {
+        /* Blocking codes to enable protocol routing to host when screen is off.*/
+        if ((nfcFL.chipType == pn547C2) && (p_cb->nfcee_id == NFC_DH_ID)) {
+            power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_ON_LOCK();
+        }
+        else
+        {
+            if (p_cb->proto_screen_lock & nfa_ee_proto_mask_list[xx])
+                power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_ON_LOCK();
+            if (p_cb->proto_screen_off & nfa_ee_proto_mask_list[xx])
+                power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_OFF_UNLOCK();
+            if (p_cb->proto_screen_off_lock & nfa_ee_proto_mask_list[xx])
+                power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_OFF_LOCK();
+        }
+    }
+#endif
+
+    if (power_cfg) {
+      *pp = NFC_ROUTE_TAG_PROTO;
+      *pp++;
+      *pp++ = 3;
+      *pp++ = p_cb->nfcee_id;
+      *pp++ = power_cfg;
+      *pp++ = nfa_ee_proto_list[xx];
+      num_tlv++;
+      if (power_cfg != NCI_ROUTE_PWR_STATE_ON)
+        nfa_ee_cb.ee_cfged |= NFA_EE_CFGED_OFF_ROUTING;
+    }
+  }
+
+  /* add NFC-DEP routing to HOST */
+  if ((p_cb->nfcee_id == NFC_DH_ID)
+#if (NXP_EXTNS == TRUE)
+      && !(nfa_ee_cb.ee_flags & NFA_EE_FLAG_CFG_NFC_DEP)
+#endif
+          ) {
+#if (NXP_EXTNS == TRUE)
+    nfa_ee_cb.ee_flags |= NFA_EE_FLAG_CFG_NFC_DEP;
+#endif
+    *pp++ = NFC_ROUTE_TAG_PROTO;
+    *pp++ = 3;
+    *pp++ = NFC_DH_ID;
+    *pp++ = NCI_ROUTE_PWR_STATE_ON;
+    *pp++ = NFC_PROTOCOL_NFC_DEP;
+    num_tlv++;
+  }
+
+  /* update the num_tlv and current offset */
+  entry_size = (uint8_t)(pp - p);
+  *p_cur_offset += entry_size;
+  *ps = num_tlv;
+/* add the AID routing */
+#if (NXP_EXTNS == TRUE)
+  if (p_cb->nfcee_id == NFC_DH_ID && p_cb->aid_entries)
+#else
+  if (p_cb->aid_entries)
+#endif
+  {
+    start_offset = 0;
+    for (xx = 0; xx < p_cb->aid_entries; xx++) {
+      p_start =
+          pp; /* rememebr the beginning of this AID routing entry, just in case
+                 we need to put it in next command */
+/* add one AID entry */
+#if (NXP_EXTNS == TRUE)
+      if ((p_cb->aid_rt_info[xx] & NFA_EE_AE_ROUTE) &&
+          ((nfa_ee_nfeeid_active(p_cb->aid_rt_loc[xx]) == true) ||
+           (p_cb->aid_rt_loc[xx] == NFC_DH_ID)))
+#else
+      if (p_cb->aid_rt_info[xx] & NFA_EE_AE_ROUTE)
+#endif
+      {
+        num_tlv++;
+        pa = &p_cb->aid_cfg[start_offset];
+        pa++;        /* EMV tag */
+        len = *pa++; /* aid_len */
+#if (NXP_EXTNS == TRUE)
+        if(p_cb->aid_info[xx] & NCI_ROUTE_QUAL_LONG_SELECT)
+          route_qual |= NCI_ROUTE_QUAL_LONG_SELECT;
+        if(p_cb->aid_info[xx] & NCI_ROUTE_QUAL_SHORT_SELECT)
+          route_qual |= NCI_ROUTE_QUAL_SHORT_SELECT;
+        *pp = NFC_ROUTE_TAG_AID | route_qual;
+         pp++;
+#else
+        *pp++ = NFC_ROUTE_TAG_AID;
+#endif
+        *pp++ = len + 2;
+#if (NXP_EXTNS == TRUE)
+        *pp++ = p_cb->aid_rt_loc[xx];
+#else
+        *pp++ = p_cb->nfcee_id;
+#endif
+        *pp++ = p_cb->aid_pwr_cfg[xx];
+        /* copy the AID */
+        memcpy(pp, pa, len);
+        pp += len;
+      }
+      start_offset += p_cb->aid_len[xx];
+      new_size = (uint8_t)(pp - p_start);
+      nfa_ee_check_set_routing(new_size, p_max_len, ps, p_cur_offset);
+      if (*ps == 0) {
+        /* just sent routing command, update local */
+        *ps = 1;
+        num_tlv = *ps;
+        *p_cur_offset = new_size;
+        pp = ps + 1;
+        p = pp;
+        tlv_size = (uint8_t)*p_cur_offset;
+        max_tlv = (uint8_t)((*p_max_len > NFA_EE_ROUT_MAX_TLV_SIZE)
+                                ? NFA_EE_ROUT_MAX_TLV_SIZE
+                                : *p_max_len);
+        memcpy(p, p_start, new_size);
+        pp += new_size;
+      } else {
+        /* add the new entry */
+        *ps = num_tlv;
+        *p_cur_offset += new_size;
+      }
+    }
+  }
+#endif /* - Routing Entries in the order: Technology, protocol and AID entries \
+          */
+  tlv_size = nfa_ee_total_lmrt_size();
+  if (tlv_size) {
+    nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb);
+  }
+  if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ROUTING) {
+    nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_CHANGED_ROUTING;
+  }
+  NFA_TRACE_DEBUG2("ee_cfg_sts:0x%02x lmrt_size:%d", nfa_ee_cb.ee_cfg_sts,
+                   tlv_size);
+
+  if (more == false) {
+#if ((NXP_EXTNS == TRUE) && (NFC_NXP_LISTEN_ROUTE_TBL_OPTIMIZATION == TRUE))
+    /* add the protocol entries and technology entries  after AID entries*/
+    new_size = (uint8_t)(proto_pp - proto_route_buff);
+    new_size += (uint8_t)(tech_pp - tech_route_buff);
+    nfa_ee_check_set_routing(new_size, p_max_len, ps, p_cur_offset);
+    if (*ps == 0) {
+      p = ps + 1;
+      num_tlv = (proto_tlv_ctr + tech_tlv_ctr);
+    } else {
+      num_tlv += proto_tlv_ctr;
+      num_tlv += tech_tlv_ctr;
+      p = ps + 1 + *p_cur_offset;
+    }
+    if (proto_tlv_ctr != 0) {
+      new_size = (uint8_t)(proto_pp - proto_route_buff);
+      memcpy(p, proto_route_buff, new_size);
+      *p_cur_offset += new_size;
+      p = p + new_size;
+    }
+    if (tech_tlv_ctr != 0) {
+      new_size = (uint8_t)(tech_pp - tech_route_buff);
+      memcpy(p, tech_route_buff, new_size);
+      *p_cur_offset += new_size;
+    }
+#endif /* - Routing entries optimization */
+
+    /* last entry. update routing table now */
+    if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_CHANGED_ROUTING) {
+      if (tlv_size) {
+        nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_PREV_ROUTING;
+      } else {
+        nfa_ee_cb.ee_cfg_sts &= ~NFA_EE_STS_PREV_ROUTING;
+      }
+      NFA_TRACE_DEBUG2(
+          "nfa_ee_route_add_one_ecb: set routing num_tlv:%d tlv_size:%d",
+          num_tlv, tlv_size);
+      if (NFC_SetRouting(more, num_tlv, (uint8_t)(*p_cur_offset), ps + 1) ==
+          NFA_STATUS_OK) {
+        nfa_ee_cb.wait_rsp++;
+      }
+    } else if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_PREV_ROUTING) {
+      if (tlv_size == 0) {
+        nfa_ee_cb.ee_cfg_sts &= ~NFA_EE_STS_PREV_ROUTING;
+        /* indicated routing is configured to NFCC */
+        nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_CHANGED_ROUTING;
+        if (NFC_SetRouting(more, 0, 0, ps + 1) == NFA_STATUS_OK) {
+          nfa_ee_cb.wait_rsp++;
+        }
+      }
+    }
+  }
+
+  return status;
+}
+/*******************************************************************************
+**
+** Function         nfa_ee_route_add_one_ecb_order
+**
+** Description      Add the routing entries for NFCEE/DH in order defined
+**
+** Returns          NFA_STATUS_OK, if ok to continue
+**
+*******************************************************************************/
+void nfa_ee_route_add_one_ecb_by_route_order(tNFA_EE_ECB* p_cb, int rout_type,
+                                             int* p_max_len, bool more,
+                                             uint8_t* ps, int* p_cur_offset) {
+  nfa_ee_check_set_routing(p_cb->size_mask, p_max_len, ps, p_cur_offset);
+
+  /* use the first byte of the buffer (ps) to keep the num_tlv */
+  uint8_t num_tlv = *ps;
+  NFA_TRACE_DEBUG6(
+      "%s - max_len:%d, cur_offset:%d, more:%d, num_tlv:%d,rout_type:- %d",
+      __func__, *p_max_len, *p_cur_offset, more, num_tlv, rout_type);
+  uint8_t* pp = ps + 1 + *p_cur_offset;
+  uint8_t* p = pp;
+  uint16_t tlv_size = (uint8_t)*p_cur_offset;
+
+  switch (rout_type) {
+    case NCI_ROUTE_ORDER_TECHNOLOGY: {
+      nfa_ee_add_tech_route_to_ecb(p_cb, pp, p, ps, p_cur_offset);
+    } break;
+
+    case NCI_ROUTE_ORDER_PROTOCOL: {
+      nfa_ee_add_proto_route_to_ecb(p_cb, pp, p, ps, p_cur_offset);
+    } break;
+    case NCI_ROUTE_ORDER_AID: {
+      nfa_ee_add_aid_route_to_ecb(p_cb, pp, p, ps, p_cur_offset, p_max_len);
+    } break;
+        case NCI_ROUTE_ORDER_PATTERN: {
+        nfa_ee_add_apdu_route_to_ecb(p_cb, pp, p, ps, p_cur_offset, p_max_len);
+    } break;
+    default: {
+      NFA_TRACE_DEBUG2("%s -  Route type - NA:- %d", __func__, rout_type);
+    }
+  }
+
+  /* update the total number of entries */
+  num_tlv = *ps;
+
+  tlv_size = nfa_ee_total_lmrt_size();
+  if (tlv_size) {
+    nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb);
+  }
+  if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ROUTING) {
+    nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_CHANGED_ROUTING;
+  }
+  NFA_TRACE_DEBUG2("ee_cfg_sts:0x%02x lmrt_size:%d", nfa_ee_cb.ee_cfg_sts,
+                   tlv_size);
+
+  if (more == false) {
+    /* last entry. update routing table now */
+    if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_CHANGED_ROUTING) {
+      if (tlv_size) {
+        nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_PREV_ROUTING;
+      } else {
+        nfa_ee_cb.ee_cfg_sts &= ~NFA_EE_STS_PREV_ROUTING;
+      }
+      NFA_TRACE_DEBUG3("%s : set routing num_tlv:%d tlv_size:%d", __func__,
+                       num_tlv, tlv_size);
+      if (NFC_SetRouting(more, num_tlv, (uint8_t)(*p_cur_offset), ps + 1) ==
+          NFA_STATUS_OK) {
+        nfa_ee_cb.wait_rsp++;
+      }
+    } else if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_PREV_ROUTING) {
+      if (tlv_size == 0) {
+        nfa_ee_cb.ee_cfg_sts &= ~NFA_EE_STS_PREV_ROUTING;
+        /* indicated routing is configured to NFCC */
+        nfa_ee_cb.ee_cfg_sts |= NFA_EE_STS_CHANGED_ROUTING;
+        if (NFC_SetRouting(more, 0, 0, ps + 1) == NFA_STATUS_OK) {
+          nfa_ee_cb.wait_rsp++;
+        }
+      }
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_need_recfg
+**
+** Description      Check if any API function to configure the routing table or
+**                  VS is called since last update
+**
+**                  The algorithm for the NFCEE configuration handling is as
+**                  follows:
+**
+**                  Each NFCEE_ID/DH has its own control block - tNFA_EE_ECB
+**                  Each control block uses ecb_flags to keep track if an API
+**                  that changes routing/VS is invoked. This ecb_flags is
+**                  cleared at the end of nfa_ee_update_rout().
+**
+**                  nfa_ee_cb.ee_cfged is the bitmask of the control blocks with
+**                  routing/VS configuration and NFA_EE_CFGED_UPDATE_NOW.
+**                  nfa_ee_cb.ee_cfged is cleared and re-calculated at the end
+**                  of nfa_ee_update_rout().
+**
+**                  nfa_ee_cb.ee_cfg_sts is used to check is any status is
+**                  changed and the associated command is issued to NFCC.
+**                  nfa_ee_cb.ee_cfg_sts is AND with NFA_EE_STS_PREV at the end
+**                  of nfa_ee_update_rout() to clear the NFA_EE_STS_CHANGED bits
+**                  (except NFA_EE_STS_CHANGED_CANNED_VS is cleared in
+**                  nfa_ee_vs_cback)
+**
+** Returns          true if any configuration is changed
+**
+*******************************************************************************/
+static bool nfa_ee_need_recfg(void) {
+  bool needed = false;
+  uint32_t xx;
+  tNFA_EE_ECB* p_cb;
+  uint8_t mask;
+
+  NFA_TRACE_DEBUG2("nfa_ee_need_recfg() ee_cfged: 0x%02x ee_cfg_sts: 0x%02x",
+                   nfa_ee_cb.ee_cfged, nfa_ee_cb.ee_cfg_sts);
+  /* if no routing/vs is configured, do not need to send the info to NFCC */
+  if (nfa_ee_cb.ee_cfged || nfa_ee_cb.ee_cfg_sts) {
+    if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_CHANGED) {
+      NFA_TRACE_DEBUG1("%s:Routing table dirty, update required...", __func__);
+      needed = true;
+    } else {
+      p_cb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH];
+      mask = 1 << NFA_EE_CB_4_DH;
+      for (xx = 0; xx <= nfa_ee_cb.cur_ee; xx++) {
+        NFA_TRACE_DEBUG3("%d: ecb_flags  : 0x%02x, mask: 0x%02x", xx,
+                         p_cb->ecb_flags, mask);
+        if ((p_cb->ecb_flags) && (nfa_ee_cb.ee_cfged & mask)) {
+          NFA_TRACE_DEBUG1("%s:Routing table dirty, update required...",
+                           __func__);
+          needed = true;
+          break;
+        }
+        p_cb = &nfa_ee_cb.ecb[xx];
+        mask = 1 << xx;
+      }
+    }
+  }
+
+  return needed;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_rout_timeout
+**
+** Description      Anytime VS or routing entries are changed,
+**                  a 1 second timer is started. This function is called when
+**                  the timer expires or NFA_EeUpdateNow() is called.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_rout_timeout(tNFA_EE_MSG* p_data) {
+  uint8_t ee_cfged = nfa_ee_cb.ee_cfged;
+  (void)p_data;
+
+  NFA_TRACE_DEBUG0("nfa_ee_rout_timeout()");
+  if (nfa_ee_need_recfg()) {
+    /* Send deactivated to idle command if already not sent */
+    if (nfa_dm_cb.disc_cb.disc_state != NFA_DM_RFST_IDLE)
+      nci_snd_deactivate_cmd(NFC_DEACTIVATE_TYPE_IDLE);
+    nfa_ee_update_rout();
+  }
+
+  if (nfa_ee_cb.wait_rsp) nfa_ee_cb.ee_wait_evt |= NFA_EE_WAIT_UPDATE_RSP;
+  if (ee_cfged & NFA_EE_CFGED_UPDATE_NOW) {
+    /* need to report NFA_EE_UPDATED_EVT when done updating NFCC */
+    nfa_ee_cb.ee_wait_evt |= NFA_EE_WAIT_UPDATE;
+    if (!nfa_ee_cb.wait_rsp) {
+      nfa_ee_report_update_evt();
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_discv_timeout
+**
+** Description
+**
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_discv_timeout(tNFA_EE_MSG* p_data) {
+  (void)p_data;
+  NFA_TRACE_DEBUG0("nfa_ee_discv_timeout ()");
+  if(NFA_GetNCIVersion() != NCI_VERSION_2_0)
+      NFC_NfceeDiscover(false);
+  if (nfa_ee_cb.p_enable_cback)
+    (*nfa_ee_cb.p_enable_cback)(NFA_EE_DISC_STS_OFF);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_lmrt_to_nfcc
+**
+** Description      This function would set the listen mode routing table
+**                  to NFCC.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_lmrt_to_nfcc(tNFA_EE_MSG* p_data) {
+  int xx;
+  tNFA_EE_ECB* p_cb;
+  uint8_t* p = NULL;
+  bool more = true;
+  bool check = true;
+  uint8_t last_active = NFA_EE_INVALID;
+  int max_len;
+  tNFA_STATUS status = NFA_STATUS_FAILED;
+  int cur_offset;
+  uint8_t max_tlv;
+  int rt;
+#if (NXP_EXTNS == TRUE)
+  tNFA_EE_CBACK_DATA evt_data = {0};
+#endif
+  (void)p_data;
+
+#if (NXP_EXTNS == TRUE)
+  if((nfcFL.chipType != pn547C2) &&
+          (nfcFL.nfcMwFL._NFC_NXP_AID_MAX_SIZE_DYN == true)) {
+      NFA_TRACE_DEBUG1("max supported routing table size: %d",
+              max_routing_table_size);
+      /* update routing table: DH and the activated NFCEEs */
+      p = (uint8_t*)GKI_getbuf(max_routing_table_size);
+  }
+  else {
+      p = (uint8_t*)GKI_getbuf(NFA_EE_ROUT_BUF_SIZE_STAT);
+  }
+#else
+  /* update routing table: DH and the activated NFCEEs */
+  p = (uint8_t*)GKI_getbuf(NFA_EE_ROUT_BUF_SIZE);
+#endif
+
+  if (p == NULL) {
+    NFA_TRACE_ERROR0("nfa_ee_lmrt_to_nfcc() no buffer to send routing info.");
+#if (NXP_EXTNS == TRUE)
+    evt_data.status = status;
+    nfa_ee_report_event(NULL, NFA_EE_NO_MEM_ERR_EVT,
+                        (tNFA_EE_CBACK_DATA*)&evt_data);
+#else
+    nfa_ee_report_event(NULL, NFA_EE_NO_MEM_ERR_EVT,
+                        (tNFA_EE_CBACK_DATA*)&status);
+#endif
+    return;
+  }
+
+#if ((NXP_EXTNS == TRUE) && (NFC_NXP_LISTEN_ROUTE_TBL_OPTIMIZATION == TRUE))
+  proto_route_buff = (uint8_t*)GKI_getbuf(
+      NFA_EE_PROTO_BUFF_SIZE); /* Temporary buffer to store proto route
+                                  entries */
+  tech_route_buff = (uint8_t*)GKI_getbuf(
+      NFA_EE_TECH_BUFF_SIZE); /* Temporary buffer to store tech route entries */
+
+  if (proto_route_buff == NULL || tech_route_buff == NULL) {
+    NFA_TRACE_ERROR0(
+        "nfa_ee_lmrt_to_nfcc() no temp buffer to send routing info.");
+    evt_data.status = status;
+    nfa_ee_report_event(NULL, NFA_EE_NO_MEM_ERR_EVT,
+                        (tNFA_EE_CBACK_DATA*)&evt_data);
+    return;
+  }
+  proto_tlv_ctr = 0;
+  tech_tlv_ctr = 0;
+  proto_pp = proto_route_buff;
+  tech_pp = tech_route_buff;
+#endif /* - Routing entries optimization */
+
+  /* find the last active NFCEE. */
+  p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1];
+  for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb--) {
+    if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE) {
+      if (last_active == NFA_EE_INVALID) {
+        last_active = p_cb->nfcee_id;
+        NFA_TRACE_DEBUG1("last_active: 0x%x", last_active);
+      }
+    }
+  }
+  if (last_active == NFA_EE_INVALID) {
+     check = false;
+  }
+  if(nfcFL.chipType != pn547C2) {
+      find_and_resolve_tech_conflict();
+  }
+
+  max_len = NFC_GetLmrtSize();
+  max_tlv =
+      (uint8_t)((max_len > NFA_EE_ROUT_MAX_TLV_SIZE) ? NFA_EE_ROUT_MAX_TLV_SIZE
+                                                     : max_len);
+  cur_offset = 0;
+  /* use the first byte of the buffer (p) to keep the num_tlv */
+  *p = 0;
+  for (int rt = NCI_ROUTE_ORDER_AID; rt <= NCI_ROUTE_ORDER_TECHNOLOGY; rt++) {
+    /* add the routing entries for NFCEEs */
+    p_cb = &nfa_ee_cb.ecb[0];
+  for (xx = 0; (xx < nfa_ee_cb.cur_ee) && check; xx++, p_cb++) {
+    if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE) {
+        NFA_TRACE_DEBUG1("%s --add the routing for NFCEEs!!", __func__);
+        nfa_ee_route_add_one_ecb_by_route_order(p_cb, rt, &max_len, more, p,
+                                                &cur_offset);
+      }
+    }
+    if (rt == NCI_ROUTE_ORDER_TECHNOLOGY) more = false;
+    /* add the routing entries for DH */
+    NFA_TRACE_DEBUG1("%s --add the routing for DH!!", __func__);
+    nfa_ee_route_add_one_ecb_by_route_order(&nfa_ee_cb.ecb[NFA_EE_CB_4_DH], rt,
+                                            &max_len, more, p, &cur_offset);
+  }
+#if (NXP_EXTNS == TRUE)
+  nfa_ee_cb.ee_flags &= ~NFA_EE_FLAG_CFG_NFC_DEP;
+  evt_data.status = status;
+#endif
+  if (status != NFA_STATUS_OK) {
+#if (NXP_EXTNS == TRUE)
+    nfa_ee_report_event(NULL, NFA_EE_ROUT_ERR_EVT,
+                        (tNFA_EE_CBACK_DATA*)&evt_data);
+#else
+    nfa_ee_report_event(NULL, NFA_EE_ROUT_ERR_EVT,
+                        (tNFA_EE_CBACK_DATA*)&status);
+#endif
+  }
+  GKI_freebuf(p);
+#if ((NXP_EXTNS == TRUE) && (NFC_NXP_LISTEN_ROUTE_TBL_OPTIMIZATION == TRUE))
+  GKI_freebuf(proto_route_buff);
+  GKI_freebuf(tech_route_buff);
+  proto_tlv_ctr = 0;
+  tech_tlv_ctr = 0;
+  proto_pp = 0;
+  tech_pp = 0;
+#endif /* - Routing entries optimization */
+}
+
+/*******************************************************************************
+**
+** Function         find_and_resolve_tech_conflict
+**
+** Description      This function prefer the SE to resolve the technology
+*conflict.
+**
+** Returns          void
+**
+*******************************************************************************/
+
+void find_and_resolve_tech_conflict() {
+    if(nfcFL.chipType == pn547C2) {
+        NFA_TRACE_DEBUG1("%s: chipType : pn547C2. Returning", __func__);
+    }
+  int yy, xx;
+  tNFA_EE_ECB* p_cb = nfa_ee_cb.ecb;
+  uint8_t techA_found = 0, techF_found = 0;
+  uint8_t techA_ee = 0, techF_ee = 0;
+  unsigned long preferred_se = 0x01;
+  bool conflict = false;
+  uint8_t tech_to_rm, ee_from_rm;
+
+  NFA_TRACE_DEBUG1("%s:Enter", __func__);
+
+  // Finding the Technology and nfcee_id supported
+  for (yy = 0; yy < nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED; yy++, p_cb++) {
+    for (xx = 0; xx < 3; xx++) {
+      if ((p_cb->tech_switch_on & nfa_ee_tech_mask_list[xx]) ==
+          NFA_TECHNOLOGY_MASK_A) {
+        techA_found |= NFA_TECHNOLOGY_MASK_A;
+        techA_ee = p_cb->nfcee_id;
+      }
+      if ((p_cb->tech_switch_off & nfa_ee_tech_mask_list[xx]) ==
+          NFA_TECHNOLOGY_MASK_A) {
+        techA_found |= NFA_TECHNOLOGY_MASK_A;
+        techA_ee = p_cb->nfcee_id;
+      }
+      if ((p_cb->tech_battery_off & nfa_ee_tech_mask_list[xx]) ==
+          NFA_TECHNOLOGY_MASK_A) {
+        techA_found |= NFA_TECHNOLOGY_MASK_A;
+        techA_ee = p_cb->nfcee_id;
+      }
+      if ((p_cb->tech_switch_on & nfa_ee_tech_mask_list[xx]) ==
+          NFA_TECHNOLOGY_MASK_F) {
+        techF_found |= NFA_TECHNOLOGY_MASK_F;
+        techF_ee = p_cb->nfcee_id;
+      }
+      if ((p_cb->tech_switch_off & nfa_ee_tech_mask_list[xx]) ==
+          NFA_TECHNOLOGY_MASK_F) {
+        techF_found |= NFA_TECHNOLOGY_MASK_F;
+        techF_ee = p_cb->nfcee_id;
+      }
+      if ((p_cb->tech_battery_off & nfa_ee_tech_mask_list[xx]) ==
+          NFA_TECHNOLOGY_MASK_F) {
+        techF_found |= NFA_TECHNOLOGY_MASK_F;
+        techF_ee = p_cb->nfcee_id;
+      }
+    }
+  }
+
+  NFA_TRACE_DEBUG5(
+      "%s:p_cb->nfcee_id=0x%x,p_cb->tech_switch_on= "
+      "0x%x,p_cb->tech_switch_off= 0x%x,p_cb->tech_battery_off= 0x%x",
+      __func__, p_cb->nfcee_id, p_cb->tech_switch_on, p_cb->tech_switch_off,
+      p_cb->tech_battery_off);
+
+  // Preferred SE Selected.
+  if ((GetNumValue(NAME_DEFAULT_OFFHOST_ROUTE, &preferred_se,
+                   sizeof(preferred_se)))) {
+    NFA_TRACE_DEBUG2("%s:NXP_DEFAULT_OFFHOST_ROUTE=0x0%lu;", __func__,
+                     preferred_se);
+    if (preferred_se == 0x01)
+      preferred_se = 0xc0;  // Ese
+    else if (preferred_se == 0x02)
+      preferred_se = 0x02;  // UICC
+  }
+  NFA_TRACE_DEBUG3("%s:techF_found=0x%x,techF_ee= 0x%x;", __func__, techF_found,
+                   techF_ee);
+  NFA_TRACE_DEBUG3("%s:techA_found=0x%x,techA_ee= 0x%x;", __func__, techA_found,
+                   techA_ee);
+
+  if (techA_found == NFA_TECHNOLOGY_MASK_A &&
+      techF_found == NFA_TECHNOLOGY_MASK_F) {
+    if (techA_ee != 0x00 && techF_ee != 0x00) {
+      // Conflict occurs when techF and techA on Different SE.
+      if (techA_ee != techF_ee) conflict = true;
+    }
+  }
+
+  if (conflict == true) {
+    NFA_TRACE_DEBUG0("Conflict true");
+
+    if (techF_ee == preferred_se) {
+      tech_to_rm = NFA_TECHNOLOGY_MASK_A;
+      ee_from_rm = techA_ee;
+    } else {
+      tech_to_rm = NFA_TECHNOLOGY_MASK_F;
+      ee_from_rm = techF_ee;
+    }
+
+    p_cb = nfa_ee_cb.ecb;
+    for (yy = 0; yy < nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED; yy++, p_cb++) {
+      if (p_cb->nfcee_id == ee_from_rm) {
+        for (xx = 0; xx < 3; xx++) {
+          if (((p_cb->tech_switch_on & nfa_ee_tech_mask_list[xx]) ==
+               tech_to_rm))
+            p_cb->tech_switch_on &= ~tech_to_rm;
+          if ((p_cb->tech_switch_off & nfa_ee_tech_mask_list[xx]) == tech_to_rm)
+            p_cb->tech_switch_off &= ~tech_to_rm;
+          if ((p_cb->tech_battery_off & nfa_ee_tech_mask_list[xx]) ==
+              tech_to_rm)
+            p_cb->tech_battery_off &= ~tech_to_rm;
+        }
+      }
+    }
+    NFA_TRACE_DEBUG1("%s:Exit", __func__);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_update_rout
+**
+** Description      This function would set the VS and listen mode routing table
+**                  to NFCC.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_update_rout(void) {
+  int xx;
+  tNFA_EE_ECB* p_cb;
+  uint8_t mask;
+  NFC_HDR msg;
+
+  NFA_TRACE_DEBUG1("nfa_ee_update_rout ee_cfg_sts:0x%02x",
+                   nfa_ee_cb.ee_cfg_sts);
+
+  /* use action function to send routing and VS configuration to NFCC */
+  msg.event = NFA_EE_CFG_TO_NFCC_EVT;
+  nfa_ee_evt_hdlr(&msg);
+
+  /* all configuration is updated to NFCC, clear the status mask */
+  nfa_ee_cb.ee_cfg_sts &= NFA_EE_STS_PREV;
+  nfa_ee_cb.ee_cfged = 0;
+  p_cb = &nfa_ee_cb.ecb[0];
+  for (xx = 0; xx < NFA_EE_NUM_ECBS; xx++, p_cb++) {
+    p_cb->ecb_flags = 0;
+    mask = (1 << xx);
+    if (p_cb->tech_switch_on | p_cb->tech_switch_off | p_cb->tech_battery_off |
+        p_cb->proto_switch_on | p_cb->proto_switch_off |
+        p_cb->proto_battery_off | p_cb->aid_entries | p_cb->apdu_pattern_entries) {
+      /* this entry has routing configuration. mark it configured */
+      nfa_ee_cb.ee_cfged |= mask;
+    }
+  }
+  NFA_TRACE_DEBUG2("nfa_ee_update_rout ee_cfg_sts:0x%02x ee_cfged:0x%02x",
+                   nfa_ee_cb.ee_cfg_sts, nfa_ee_cb.ee_cfged);
+}
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         nfa_ee_lmrt_size
+**
+** Description      This function is called to get the AID routing table size.
+**
+** Returns          AID routing table currently used size.
+**
+*******************************************************************************/
+uint16_t nfa_ee_lmrt_size() {
+  NFA_TRACE_DEBUG0("nfa_ee_lmrt_size");
+  int len;
+  len = nfa_all_ee_find_total_aid_len() + 2 /* tag/len */ +
+        2 /*route/power state*/;
+  if((nfcFL.chipType != pn547C2) &&
+          (nfcFL.nfcMwFL._NFC_NXP_AID_MAX_SIZE_DYN == true)) {
+      return len < max_aid_config_length ? len : max_aid_config_length;
+  }
+  else {
+      return len < NFA_EE_MAX_AID_CFG_LEN_STAT ? len : NFA_EE_MAX_AID_CFG_LEN_STAT;
+  }
+}
+
+bool nfa_ee_nfeeid_active(uint8_t nfee_id) {
+  int xx;
+  tNFA_EE_ECB* p_cb;
+  bool status = false;
+  p_cb = &nfa_ee_cb.ecb[0];
+  for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) {
+    if ((p_cb->nfcee_id == nfee_id) &&
+        (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE)) {
+      status = true;
+      break;
+    }
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_find_max_aid_config_length
+**
+** Description      This function is called to find the max AID config length.
+**
+** Returns          max AID config length.
+**
+*******************************************************************************/
+uint16_t nfa_ee_find_max_aid_config_length() {
+    NFA_TRACE_DEBUG0("nfa_ee_find_max_aid_config_length");
+  /**
+   * Max Routing Table Size = 720
+   * After allocating size for Technology based routing and Protocol based
+   *routing,
+   * the remaining size can be used for AID based routing
+   *
+   * Size for 1 Technology route entry = 5 bytes (includes Type(1 byte),
+   * Length (1 byte), Value (3 bytes - Power state, Tech Type, Location)
+   * TOTAL TECH ROUTE SIZE = 5 * 3  = 15 (For Tech A, B, F)
+   *
+   * Size for 1 Protocol route entry = 5 bytes (includes Type(1 byte),
+   * Length (1 byte), Value (3 bytes - Power state, Tech Type, Location)
+   * TOTAL PROTOCOL ROUTE SIZE = 5 * 6 = 30 (Protocols ISO-DEP, NFC-DEP,
+   *ISO-7816, T1T, T2T, T3T)
+   *
+   * SIZE FOR AID = 720 - 15 - 30 = 675
+   * BUFFER for future extensions = 15
+   * TOTAL SIZE FOR AID = 675 - 15 = 660
+   */
+    if((nfcFL.chipType != pn547C2) &&
+            (nfcFL.nfcMwFL._NFC_NXP_AID_MAX_SIZE_DYN == true)) {
+        return (max_routing_table_size -
+                NFA_EE_TOTAL_PROTO_TECH_FUTURE_EXT_ROUTE_SIZE);
+    }
+    else{
+        NFA_TRACE_DEBUG0("Not allowed for chip type. Returning");
+        return 0;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_get_max_aid_config_length
+**
+** Description      This function is called to get the max AID config length.
+**
+** Returns          max AID config length.
+**
+*******************************************************************************/
+uint16_t nfa_ee_api_get_max_aid_config_length() {
+    NFA_TRACE_DEBUG0("nfa_ee_api_get_max_aid_config_length");
+    if((nfcFL.chipType != pn547C2) &&
+            (nfcFL.nfcMwFL._NFC_NXP_AID_MAX_SIZE_DYN == true)) {
+        NFA_TRACE_DEBUG1("nfa_ee_api_get_max_aid_config_length: %d",
+                max_aid_config_length);
+        return max_aid_config_length;
+    }
+    else{
+        NFA_TRACE_DEBUG0("Not allowed for chip type. Returning");
+        return 0;
+    }
+}
+#endif
diff --git a/src/nfa/ee/nfa_ee_api.c b/src/nfa/ee/nfa_ee_api.c
new file mode 100644
index 0000000..0768366
--- /dev/null
+++ b/src/nfa/ee/nfa_ee_api.c
@@ -0,0 +1,1094 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  NFA interface to NFCEE - API functions
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_ee_api.h"
+#include "nfa_ee_int.h"
+#include "nfa_sys_int.h"
+#include "nfa_dm_int.h"
+
+/*****************************************************************************
+**  APIs
+*****************************************************************************/
+/*******************************************************************************
+**
+** Function         NFA_EeDiscover
+**
+** Description      This function retrieves the NFCEE information from NFCC.
+**                  The NFCEE information is reported in NFA_EE_DISCOVER_EVT.
+**
+**                  This function may be called when a system supports removable
+**                  NFCEEs,
+**
+** Returns          NFA_STATUS_OK if information is retrieved successfully
+**                  NFA_STATUS_FAILED If wrong state (retry later)
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeDiscover(tNFA_EE_CBACK* p_cback) {
+  tNFA_EE_API_DISCOVER* p_msg;
+  tNFA_STATUS status = NFA_STATUS_FAILED;
+
+  NFA_TRACE_API0("NFA_EeDiscover()");
+
+  if (nfa_ee_cb.em_state != NFA_EE_EM_STATE_INIT_DONE) {
+    NFA_TRACE_ERROR1("NFA_EeDiscover bad em state: %d", nfa_ee_cb.em_state);
+    status = NFA_STATUS_FAILED;
+  } else if ((nfa_ee_cb.p_ee_disc_cback != NULL) || (p_cback == NULL)) {
+    NFA_TRACE_ERROR0("NFA_EeDiscover() in progress or NULL callback function");
+    status = NFA_STATUS_INVALID_PARAM;
+  } else {
+    p_msg = (tNFA_EE_API_DISCOVER*)GKI_getbuf(sizeof(tNFA_EE_API_DISCOVER));
+    if (p_msg != NULL) {
+      p_msg->hdr.event = NFA_EE_API_DISCOVER_EVT;
+      p_msg->p_cback = p_cback;
+
+      nfa_sys_sendmsg(p_msg);
+
+      status = NFA_STATUS_OK;
+    }
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFA_EeGetInfo
+**
+** Description      This function retrieves the NFCEE information from NFA.
+**                  The actual number of NFCEE is returned in p_num_nfcee
+**                  and NFCEE information is returned in p_info
+**
+** Returns          NFA_STATUS_OK if information is retrieved successfully
+**                  NFA_STATUS_FAILED If wrong state (retry later)
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeGetInfo(uint8_t* p_num_nfcee, tNFA_EE_INFO* p_info) {
+  int xx, ret = nfa_ee_cb.cur_ee;
+  tNFA_EE_ECB* p_cb = nfa_ee_cb.ecb;
+  uint8_t max_ret;
+  uint8_t num_ret = 0;
+
+  NFA_TRACE_DEBUG2("NFA_EeGetInfo em_state:%d cur_ee:%d", nfa_ee_cb.em_state,
+                   nfa_ee_cb.cur_ee);
+  /* validate parameters */
+  if (p_info == NULL || p_num_nfcee == NULL) {
+    NFA_TRACE_ERROR0("NFA_EeGetInfo bad parameter");
+    return (NFA_STATUS_INVALID_PARAM);
+  }
+  max_ret = *p_num_nfcee;
+  *p_num_nfcee = 0;
+  if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_INIT) {
+    NFA_TRACE_ERROR1("NFA_EeGetInfo bad em state: %d", nfa_ee_cb.em_state);
+    return (NFA_STATUS_FAILED);
+  }
+
+  /* compose output */
+  for (xx = 0; (xx < ret) && (num_ret < max_ret); xx++, p_cb++) {
+    NFA_TRACE_DEBUG4("xx:%d max_ret:%d, num_ret:%d ee_status:0x%x", xx, max_ret,
+                     num_ret, p_cb->ee_status);
+    if ((p_cb->ee_status & NFA_EE_STATUS_INT_MASK) ||
+        (p_cb->ee_status == NFA_EE_STATUS_REMOVED)) {
+      continue;
+    }
+    p_info->ee_handle = NFA_HANDLE_GROUP_EE | (tNFA_HANDLE)p_cb->nfcee_id;
+    p_info->ee_status = p_cb->ee_status;
+    p_info->num_interface = p_cb->num_interface;
+    p_info->num_tlvs = p_cb->num_tlvs;
+
+#if (NXP_EXTNS == TRUE)
+    p_info->la_protocol = p_cb->la_protocol;
+    p_info->lb_protocol = p_cb->lb_protocol;
+    p_info->lf_protocol = p_cb->lf_protocol;
+    p_info->lbp_protocol = p_cb->lbp_protocol;
+#endif
+    memcpy(p_info->ee_interface, p_cb->ee_interface, p_cb->num_interface);
+    memcpy(p_info->ee_tlv, p_cb->ee_tlv, p_cb->num_tlvs * sizeof(tNFA_EE_TLV));
+    p_info->ee_power_supply_status =  p_cb->ee_power_supply_status;
+    p_info++;
+    num_ret++;
+  }
+  NFA_TRACE_DEBUG1("num_ret:%d", num_ret);
+  *p_num_nfcee = num_ret;
+  return (NFA_STATUS_OK);
+}
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         NFA_AllEeGetInfo
+**
+** Description      This function retrieves the NFCEE information from NFA.
+**                  The actual number of NFCEE independent of their status
+**                  is returned in p_num_nfcee and NFCEE information is returned
+**                  in p_info
+**
+** Returns          NFA_STATUS_OK if information is retrieved successfully
+**                  NFA_STATUS_FAILED If wrong state (retry later)
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_AllEeGetInfo(uint8_t* p_num_nfcee, tNFA_EE_INFO* p_info) {
+  int xx, ret = nfa_ee_cb.cur_ee;
+  tNFA_EE_ECB* p_cb = nfa_ee_cb.ecb;
+  uint8_t max_ret;
+  uint8_t num_ret = 0;
+
+  NFA_TRACE_DEBUG2("NFA_AllEeGetInfo em_state:%d cur_ee:%d", nfa_ee_cb.em_state,
+                   nfa_ee_cb.cur_ee);
+  /* validate parameters */
+  if (p_info == NULL || p_num_nfcee == NULL) {
+    NFA_TRACE_ERROR0("NFA_AllEeGetInfo bad parameter");
+    return (NFA_STATUS_INVALID_PARAM);
+  }
+  max_ret = *p_num_nfcee;
+  *p_num_nfcee = 0;
+  if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_INIT) {
+    NFA_TRACE_ERROR1("NFA_AllEeGetInfo bad em state: %d", nfa_ee_cb.em_state);
+    return (NFA_STATUS_FAILED);
+  }
+
+  /* compose output */
+  for (xx = 0; (xx < ret) && (num_ret < max_ret); xx++, p_cb++) {
+    NFA_TRACE_DEBUG6("xx:%d max_ret:%d, num_ret:%d ee_status:0x%x num_interface :%d p_cb->nfcee_id : %d", xx, max_ret,
+                     num_ret, p_cb->ee_status, p_cb->num_interface, p_cb->nfcee_id);
+    if (p_cb->ee_status & NFA_EE_STATUS_INT_MASK) {
+      continue;
+    }
+    p_info->ee_handle = NFA_HANDLE_GROUP_EE | (tNFA_HANDLE)p_cb->nfcee_id;
+    p_info->ee_status = p_cb->ee_status;
+    p_info->num_interface = p_cb->num_interface;
+    p_info->num_tlvs = p_cb->num_tlvs;
+
+    p_info->la_protocol = p_cb->la_protocol;
+    p_info->lb_protocol = p_cb->lb_protocol;
+    p_info->lf_protocol = p_cb->lf_protocol;
+    p_info->lbp_protocol = p_cb->lbp_protocol;
+
+      memcpy(p_info->ee_interface, p_cb->ee_interface, p_cb->num_interface);
+
+    memcpy(p_info->ee_tlv, p_cb->ee_tlv, p_cb->num_tlvs * sizeof(tNFA_EE_TLV));
+    p_info++;
+    num_ret++;
+  }
+  NFA_TRACE_DEBUG1("num_ret:%d", num_ret);
+  *p_num_nfcee = num_ret;
+  return (NFA_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_setProvisionMode
+**
+** Description      This function is used to set/reset the provision mode info
+**
+** Returns          None
+**
+*******************************************************************************/
+void NFA_setProvisionMode(bool provisionMode) {
+  NFA_TRACE_API1("NFA_setProvisionMode(), provisionMode:%d", provisionMode);
+  gNfaProvisionMode = provisionMode;
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         NFA_EeRegister
+**
+** Description      This function registers a callback function to receive the
+**                  events from NFA-EE module.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeRegister(tNFA_EE_CBACK* p_cback) {
+  tNFA_EE_API_REGISTER* p_msg;
+  tNFA_STATUS status = NFA_STATUS_FAILED;
+
+  NFA_TRACE_API0("NFA_EeRegister()");
+
+  if (p_cback == NULL) {
+    NFA_TRACE_ERROR0("NFA_EeRegister(): with NULL callback function");
+    status = NFA_STATUS_INVALID_PARAM;
+  } else {
+    p_msg = (tNFA_EE_API_REGISTER*)GKI_getbuf(sizeof(tNFA_EE_API_REGISTER));
+    if (p_msg != NULL) {
+      p_msg->hdr.event = NFA_EE_API_REGISTER_EVT;
+      p_msg->p_cback = p_cback;
+
+      nfa_sys_sendmsg(p_msg);
+
+      status = NFA_STATUS_OK;
+    }
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFA_EeDeregister
+**
+** Description      This function de-registers the callback function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeDeregister(tNFA_EE_CBACK* p_cback) {
+  tNFA_EE_API_DEREGISTER* p_msg;
+  tNFA_STATUS status = NFA_STATUS_INVALID_PARAM;
+  int index = NFA_EE_MAX_CBACKS;
+  int xx;
+
+  for (xx = 0; xx < NFA_EE_MAX_CBACKS; xx++) {
+    if (nfa_ee_cb.p_ee_cback[xx] == p_cback) {
+      index = xx;
+      status = NFA_STATUS_FAILED;
+      break;
+    }
+  }
+
+  NFA_TRACE_API2("NFA_EeDeregister() %d, status:%d", index, status);
+  if ((status != NFA_STATUS_INVALID_PARAM) &&
+      (p_msg = (tNFA_EE_API_DEREGISTER*)GKI_getbuf(
+           sizeof(tNFA_EE_API_DEREGISTER))) != NULL) {
+    p_msg->hdr.event = NFA_EE_API_DEREGISTER_EVT;
+    p_msg->index = index;
+
+    nfa_sys_sendmsg(p_msg);
+
+    status = NFA_STATUS_OK;
+  }
+
+  return status;
+}
+/*******************************************************************************
+**
+** Function         NFA_SendPowerLinkCommand
+**
+** Description      This function is called to send an NCI Vendor Specific
+**                  command to NFCC.
+**
+**                  nfcee_id             - The NFCEE id.
+**                  cfg_value            - The config value
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_SendPowerLinkCommand(uint8_t nfcee_id, uint8_t cfg_value) {
+  tNFA_EE_API_POWER_LINK_EVT* p_msg;
+
+  NFA_TRACE_API1("NFA_SendPowerLinkCommand() nfcee_id=0x%x", nfcee_id);
+
+  if ((p_msg = (tNFA_EE_API_POWER_LINK_EVT*)GKI_getbuf(sizeof(tNFA_EE_API_POWER_LINK_EVT))) != NULL) {
+    p_msg->hdr.event = NFA_EE_NCI_PWR_LNK_CTRL_SET_EVT;
+    p_msg->nfcee_id= nfcee_id;
+    p_msg->cfg_value = cfg_value;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+/*******************************************************************************
+**
+** Function         NFA_EeModeSet
+**
+** Description      This function is called to activate
+**                  (mode = NFA_EE_MD_ACTIVATE) or deactivate
+**                  (mode = NFA_EE_MD_DEACTIVATE) the NFCEE identified by the
+**                  given ee_handle. The result of this operation is reported
+**                  with the NFA_EE_MODE_SET_EVT.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeModeSet(tNFA_HANDLE ee_handle, tNFA_EE_MD mode) {
+  tNFA_EE_API_MODE_SET* p_msg;
+  tNFA_STATUS status = NFA_STATUS_FAILED;
+  tNFA_EE_ECB* p_cb, * p_found = NULL;
+  uint32_t xx;
+  uint8_t nfcee_id = (ee_handle & 0xFF);
+
+  p_cb = nfa_ee_cb.ecb;
+  for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) {
+    if (nfcee_id == p_cb->nfcee_id) {
+      p_found = p_cb;
+      break;
+    }
+  }
+  NFA_TRACE_API2("NFA_EeModeSet(): handle:<0x%x>, mode:0x%02X", ee_handle,
+                 mode);
+
+  if (p_found == NULL) {
+    NFA_TRACE_ERROR1("NFA_EeModeSet() invalid NFCEE:0x%04x", ee_handle);
+    status = NFA_STATUS_INVALID_PARAM;
+  } else {
+    p_msg = (tNFA_EE_API_MODE_SET*)GKI_getbuf(sizeof(tNFA_EE_API_MODE_SET));
+    if (p_msg != NULL) {
+      p_msg->hdr.event = NFA_EE_API_MODE_SET_EVT;
+      p_msg->nfcee_id = nfcee_id;
+      p_msg->mode = mode;
+      p_msg->p_cb = p_found;
+
+      nfa_sys_sendmsg(p_msg);
+
+      status = NFA_STATUS_OK;
+    }
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFA_EeSetDefaultTechRouting
+**
+** Description      This function is called to add, change or remove the
+**                  default routing based on RF technology in the listen mode
+**                  routing table for the given ee_handle. The status of this
+**                  operation is reported as the NFA_EE_SET_TECH_CFG_EVT.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Note:            NFA_EeUpdateNow() should be called after last NFA-EE
+**                  function to change the listen mode routing is called.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeSetDefaultTechRouting(
+    tNFA_HANDLE ee_handle, tNFA_TECHNOLOGY_MASK technologies_switch_on,
+    tNFA_TECHNOLOGY_MASK technologies_switch_off,
+    tNFA_TECHNOLOGY_MASK technologies_battery_off
+#if (NXP_EXTNS == TRUE)
+    ,
+    tNFA_TECHNOLOGY_MASK technologies_screen_lock,
+    tNFA_TECHNOLOGY_MASK technologies_screen_off,
+    tNFA_TECHNOLOGY_MASK technologies_screen_off_lock
+#endif
+    ) {
+  tNFA_EE_API_SET_TECH_CFG* p_msg;
+  tNFA_STATUS status = NFA_STATUS_FAILED;
+  uint8_t nfcee_id = (uint8_t)(ee_handle & 0xFF);
+  tNFA_EE_ECB* p_cb;
+
+#if (NXP_EXTNS == TRUE)
+  NFA_TRACE_API6(
+      "NFA_EeSetDefaultTechRouting(): "
+      "handle:<0x%x>technology_mask:<0x%x>/<0x%x>/<0x%x><0x%x><0x%x>",
+      ee_handle, technologies_switch_on, technologies_switch_off,
+      technologies_battery_off, technologies_screen_lock,
+      technologies_screen_off);
+#else
+  NFA_TRACE_API4(
+      "NFA_EeSetDefaultTechRouting(): "
+      "handle:<0x%x>technology_mask:<0x%x>/<0x%x>/<0x%x>",
+      ee_handle, technologies_switch_on, technologies_switch_off,
+      technologies_battery_off);
+#endif
+
+  p_cb = nfa_ee_find_ecb(nfcee_id);
+
+  if (p_cb == NULL) {
+    NFA_TRACE_ERROR0("Bad ee_handle");
+    status = NFA_STATUS_INVALID_PARAM;
+  } else {
+    p_msg =
+        (tNFA_EE_API_SET_TECH_CFG*)GKI_getbuf(sizeof(tNFA_EE_API_SET_TECH_CFG));
+    if (p_msg != NULL) {
+      p_msg->hdr.event = NFA_EE_API_SET_TECH_CFG_EVT;
+      p_msg->nfcee_id = nfcee_id;
+      p_msg->p_cb = p_cb;
+      p_msg->technologies_switch_on = technologies_switch_on;
+      p_msg->technologies_switch_off = technologies_switch_off;
+      p_msg->technologies_battery_off = technologies_battery_off;
+#if (NXP_EXTNS == TRUE)
+      p_msg->technologies_screen_lock = technologies_screen_lock;
+      p_msg->technologies_screen_off = technologies_screen_off;
+      p_msg->technologies_screen_off_lock = technologies_screen_off_lock;
+#endif
+      nfa_sys_sendmsg(p_msg);
+
+      status = NFA_STATUS_OK;
+    }
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFA_EeSetDefaultProtoRouting
+**
+** Description      This function is called to add, change or remove the
+**                  default routing based on Protocol in the listen mode routing
+**                  table for the given ee_handle. The status of this
+**                  operation is reported as the NFA_EE_SET_PROTO_CFG_EVT.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Note:            NFA_EeUpdateNow() should be called after last NFA-EE
+**                  function to change the listen mode routing is called.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeSetDefaultProtoRouting(
+    tNFA_HANDLE ee_handle, tNFA_PROTOCOL_MASK protocols_switch_on,
+    tNFA_PROTOCOL_MASK protocols_switch_off,
+    tNFA_PROTOCOL_MASK protocols_battery_off
+#if (NXP_EXTNS == TRUE)
+    ,
+    tNFA_PROTOCOL_MASK protocols_screen_lock,
+    tNFA_PROTOCOL_MASK protocols_screen_off,
+    tNFA_PROTOCOL_MASK protocols_screen_off_lock
+#endif
+    ) {
+  tNFA_EE_API_SET_PROTO_CFG* p_msg;
+  tNFA_STATUS status = NFA_STATUS_FAILED;
+  uint8_t nfcee_id = (uint8_t)(ee_handle & 0xFF);
+  tNFA_EE_ECB* p_cb;
+
+#if (NXP_EXTNS == TRUE)
+  NFA_TRACE_API6(
+      "NFA_EeSetDefaultProtoRouting(): "
+      "handle:<0x%x>protocol_mask:<0x%x>/<0x%x>/<0x%x><0x%x><0x%x>",
+      ee_handle, protocols_switch_on, protocols_switch_off,
+      protocols_battery_off, protocols_screen_lock, protocols_screen_off);
+#else
+  NFA_TRACE_API4(
+      "NFA_EeSetDefaultProtoRouting(): "
+      "handle:<0x%x>protocol_mask:<0x%x>/<0x%x>/<0x%x>",
+      ee_handle, protocols_switch_on, protocols_switch_off,
+      protocols_battery_off);
+#endif
+
+  p_cb = nfa_ee_find_ecb(nfcee_id);
+
+  if (p_cb == NULL) {
+    NFA_TRACE_ERROR0("Bad ee_handle");
+    status = NFA_STATUS_INVALID_PARAM;
+  } else {
+    p_msg = (tNFA_EE_API_SET_PROTO_CFG*)GKI_getbuf(
+        sizeof(tNFA_EE_API_SET_PROTO_CFG));
+    if (p_msg != NULL) {
+      p_msg->hdr.event = NFA_EE_API_SET_PROTO_CFG_EVT;
+      p_msg->nfcee_id = nfcee_id;
+      p_msg->p_cb = p_cb;
+      p_msg->protocols_switch_on = protocols_switch_on;
+      p_msg->protocols_switch_off = protocols_switch_off;
+      p_msg->protocols_battery_off = protocols_battery_off;
+#if (NXP_EXTNS == TRUE)
+      p_msg->protocols_screen_lock = protocols_screen_lock;
+      p_msg->protocols_screen_off = protocols_screen_off;
+      p_msg->protocols_screen_off_lock = protocols_screen_off_lock;
+#endif
+      nfa_sys_sendmsg(p_msg);
+
+      status = NFA_STATUS_OK;
+    }
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFA_EeAddAidRouting
+**
+** Description      This function is called to add an AID entry in the
+**                  listen mode routing table in NFCC. The status of this
+**                  operation is reported as the NFA_EE_ADD_AID_EVT.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Note:            NFA_EeUpdateNow() should be called after last NFA-EE
+**                  function to change the listen mode routing is called.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeAddAidRouting(tNFA_HANDLE ee_handle, uint8_t aid_len,
+                                uint8_t* p_aid, tNFA_EE_PWR_STATE power_state
+#if (NXP_EXTNS == TRUE)
+                                ,
+                                uint8_t aidInfo)
+#else
+                                )
+#endif
+{
+  tNFA_EE_API_ADD_AID* p_msg;
+  tNFA_STATUS status = NFA_STATUS_FAILED;
+  uint16_t size = sizeof(tNFA_EE_API_ADD_AID) + aid_len;
+  uint8_t nfcee_id = (uint8_t)(ee_handle & 0xFF);
+  tNFA_EE_ECB* p_cb;
+  NFA_TRACE_API1("NFA_EeAddAidRouting(): handle:<0x%x>", ee_handle);
+  p_cb = nfa_ee_find_ecb(nfcee_id);
+
+  /* validate parameters - make sure the AID is in valid length range */
+  if ((p_cb == NULL) || ((NFA_GetNCIVersion() == NCI_VERSION_2_0) && (aid_len != 0) && (p_aid == NULL)) ||
+          ((NFA_GetNCIVersion() != NCI_VERSION_2_0) &&
+                  ((aid_len == 0) || (p_aid == NULL) || (aid_len < NFA_MIN_AID_LEN))) ||
+                  (aid_len > NFA_MAX_AID_LEN)) {
+    NFA_TRACE_ERROR1("Bad ee_handle or AID (len=%d)", aid_len);
+    status = NFA_STATUS_INVALID_PARAM;
+  } else {
+    p_msg = (tNFA_EE_API_ADD_AID*)GKI_getbuf(size);
+    if (p_msg != NULL) {
+        if(p_aid != NULL) {
+            NFA_TRACE_DEBUG2("aid:<%02x%02x>", p_aid[0], p_aid[1]);
+        }
+      p_msg->hdr.event = NFA_EE_API_ADD_AID_EVT;
+      p_msg->nfcee_id = nfcee_id;
+      p_msg->p_cb = p_cb;
+      p_msg->aid_len = aid_len;
+      p_msg->power_state = power_state;
+      p_msg->p_aid = (uint8_t*)(p_msg + 1);
+#if (NXP_EXTNS == TRUE)
+      p_msg->aid_info = aidInfo;
+#endif
+      if(p_aid != NULL) {
+      memcpy(p_msg->p_aid, p_aid, aid_len);
+      }
+      nfa_sys_sendmsg(p_msg);
+
+      status = NFA_STATUS_OK;
+    }
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFA_EeAddApduPatternRouting
+**
+** Description      This function is called to add an APDU pattern entry in the
+**                  listen mode routing table in NFCC. The status of this
+**                  operation is reported as the NFA_EE_ADD_APDU_EVT.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Note:            NFA_EeUpdateNow() should be called after last NFA-EE
+**                  function to change the listen mode routing is called.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeAddApduPatternRouting(uint8_t apdu_data_len,uint8_t* apdu_data, uint8_t apdu_mask_len,
+  uint8_t* apdu_mask, tNFA_HANDLE ee_handle, uint8_t power_state) {
+  tNFA_EE_API_ADD_APDU* p_msg;
+  tNFA_STATUS status = NFA_STATUS_FAILED;
+  tNFA_EE_ECB* p_cb;
+  uint16_t size = sizeof(tNFA_EE_API_ADD_AID) + apdu_data_len + apdu_mask_len;
+  uint8_t nfcee_id = (uint8_t)(ee_handle & 0xFF);
+
+  NFA_TRACE_API1("NFA_EeAddApduRouting(): handle:<0x%x>", ee_handle);
+  p_cb = nfa_ee_find_ecb(nfcee_id);
+  if(p_cb == NULL || apdu_data_len == 0 || apdu_mask_len == 0 || apdu_data == NULL
+      || apdu_mask == NULL || apdu_data_len > NFC_MAX_APDU_DATA_LEN
+      || apdu_mask_len > NFC_MAX_APDU_MASK_LEN || apdu_data_len != apdu_mask_len) {
+    NFA_TRACE_ERROR1("Bad ee_handle or AID (len=%d)", apdu_data_len+apdu_mask_len);
+    status = NFA_STATUS_INVALID_PARAM;
+  } else {
+      p_msg = (tNFA_EE_API_ADD_APDU*)GKI_getbuf(size);
+      p_msg->hdr.event = NFA_EE_API_ADD_APDU_EVT;
+      p_msg->apdu_len = apdu_data_len;
+      p_msg->mask_len = apdu_mask_len;
+      p_msg->power_state = power_state;
+      p_msg->nfcee_id = nfcee_id;
+      p_msg->p_cb = p_cb;
+      p_msg->p_apdu = (uint8_t*)(p_msg + 1);
+      memcpy(p_msg->p_apdu, apdu_data, apdu_data_len);
+      p_msg->p_mask = (uint8_t*)(p_msg->p_apdu + apdu_data_len);
+      memcpy(p_msg->p_mask, apdu_mask, apdu_mask_len);
+      nfa_sys_sendmsg(p_msg);
+
+      status = NFA_STATUS_OK;
+  }
+  return status;
+}
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         NFA_AddEePowerState
+**
+** Description      This function is called to add power state in the
+**                  listen mode routing table in NFCC.
+**
+** Note:            If RF discovery is started,
+*NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Note:            NFA_EeUpdateNow() should be called after last NFA-EE
+*function
+**                  to change the listen mode routing is called.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_AddEePowerState(tNFA_HANDLE ee_handle,
+                                tNFA_EE_PWR_STATE power_state_mask) {
+  tNFA_STATUS status = NFA_STATUS_FAILED;
+  uint8_t nfcee_id = (uint8_t)(ee_handle & 0xFF);
+  tNFA_EE_ECB* p_cb;
+  uint8_t xx = 0;
+
+  NFA_TRACE_API1("NFA_AddEePowerState(): handle:<0x%x>", ee_handle);
+  p_cb = nfa_ee_find_ecb(nfcee_id);
+
+  /* validate parameters */
+  if (p_cb == NULL) {
+    status = NFA_STATUS_INVALID_PARAM;
+    return status;
+  }
+
+  if ((power_state_mask & NFA_EE_PWR_STATE_SWITCH_OFF) != 0x00) {
+    for (xx = 0; xx < p_cb->aid_entries; xx++) {
+      p_cb->aid_pwr_cfg[xx] |= power_state_mask;
+      p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_AID;
+    }
+
+    /* For tech and proto only enable power off mode*/
+    p_cb->proto_switch_off |= p_cb->proto_switch_on;
+    p_cb->tech_switch_off |= p_cb->tech_switch_on;
+  } else {
+    for (xx = 0; xx < p_cb->aid_entries; xx++) {
+      p_cb->aid_pwr_cfg[xx] &= power_state_mask;
+      p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_AID;
+    }
+
+    p_cb->proto_switch_off &= 0x00;
+    p_cb->tech_switch_off &= 0x00;
+  }
+
+  p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_TECH | NFA_EE_ECB_FLAGS_PROTO;
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFA_GetAidTableSize
+**
+** Description      This function is called to get the Maximum AID routing table
+*size.
+**
+** Returns          AID routing table maximum size
+**
+*******************************************************************************/
+uint16_t NFA_GetAidTableSize() {
+    if((nfcFL.chipType != pn547C2) &&
+            (nfcFL.nfcMwFL._NFC_NXP_AID_MAX_SIZE_DYN == true)) {
+        return nfa_ee_api_get_max_aid_config_length();
+    }
+    else {
+        return NFA_EE_MAX_AID_CFG_LEN_STAT;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         NFA_GetRemainingAidTableSize
+**
+** Description      This function is called to get the remaining AID routing
+**                  table size.
+**
+** Returns          Remaining AID routing table size.
+**
+*******************************************************************************/
+uint16_t NFA_GetRemainingAidTableSize() {
+    uint16_t size = 0;
+    if((nfcFL.chipType != pn547C2) &&
+            (nfcFL.nfcMwFL._NFC_NXP_AID_MAX_SIZE_DYN == true)) {
+        size = nfa_ee_api_get_max_aid_config_length() - nfa_ee_lmrt_size();
+    }
+    else {
+        size = NFA_EE_MAX_AID_CFG_LEN_STAT - nfa_ee_lmrt_size();
+    }
+    return size;
+}
+/*******************************************************************************
+**
+** Function         NFA_SetCEStrictDisable
+**
+** Description      This function is called to set the flag for Strict CE.
+**
+** Returns          None.
+**
+*******************************************************************************/
+void NFA_SetCEStrictDisable(uint32_t state) {
+  nfa_ee_ce_route_strict_disable = (uint8_t)state;
+}
+
+/*******************************************************************************
+**
+** Function         NFA_checkDwpCl_Activated
+**
+** Description      This function to check dwp cl is active through p61.
+**
+** Returns          None.
+**
+*******************************************************************************/
+uint8_t NFA_check_p61_CL_Activated() { return nfa_ee_ce_p61_active; }
+#endif
+/*******************************************************************************
+**
+** Function         NFA_EeRemoveAidRouting
+**
+** Description      This function is called to remove the given AID entry from
+**                  the listen mode routing table. If the entry configures VS,
+**                  it is also removed. The status of this operation is reported
+**                  as the NFA_EE_REMOVE_AID_EVT.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Note:            NFA_EeUpdateNow() should be called after last NFA-EE
+**                  function to change the listen mode routing is called.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeRemoveAidRouting(uint8_t aid_len, uint8_t* p_aid) {
+  tNFA_EE_API_REMOVE_AID* p_msg;
+  tNFA_STATUS status = NFA_STATUS_FAILED;
+  uint16_t size = sizeof(tNFA_EE_API_REMOVE_AID) + aid_len;
+
+  NFA_TRACE_API0("NFA_EeRemoveAidRouting()");
+  if ((aid_len == 0) || (p_aid == NULL) || (aid_len > NFA_MAX_AID_LEN)) {
+    NFA_TRACE_ERROR0("Bad AID");
+    status = NFA_STATUS_INVALID_PARAM;
+  } else {
+    p_msg = (tNFA_EE_API_REMOVE_AID*)GKI_getbuf(size);
+    if (p_msg != NULL) {
+      p_msg->hdr.event = NFA_EE_API_REMOVE_AID_EVT;
+      p_msg->aid_len = aid_len;
+      p_msg->p_aid = (uint8_t*)(p_msg + 1);
+      memcpy(p_msg->p_aid, p_aid, aid_len);
+
+      nfa_sys_sendmsg(p_msg);
+
+      status = NFA_STATUS_OK;
+    }
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFA_EeRemoveApduPatternRouting
+**
+** Description      This function is called to remove the given APDU entry from
+**                  the listen mode routing table. If the entry configures VS,
+**                  it is also removed. The status of this operation is reported
+**                  as the NFA_EE_REMOVE_APDU_EVT.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Note:            NFA_EeUpdateNow() should be called after last NFA-EE
+**                  function to change the listen mode routing is called.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeRemoveApduPatternRouting(uint8_t apdu_len, uint8_t* p_apdu) {
+  tNFA_EE_API_REMOVE_APDU* p_msg;
+  tNFA_STATUS status = NFA_STATUS_FAILED;
+  uint16_t size = sizeof(tNFA_EE_API_REMOVE_APDU) + apdu_len;
+
+  NFA_TRACE_API0("NFA_EeRemoveApduPatternRouting()");
+  if ((apdu_len == 0) || (p_apdu == NULL) || (apdu_len > NFC_MAX_APDU_DATA_LEN)) {
+    NFA_TRACE_ERROR0("Bad handle");
+    status = NFA_STATUS_INVALID_PARAM;
+  } else {
+    p_msg = (tNFA_EE_API_REMOVE_APDU*)GKI_getbuf(size);
+    if (p_msg != NULL) {
+      p_msg->hdr.event = NFA_EE_API_REMOVE_APDU_EVT;
+      p_msg->apdu_len = apdu_len;
+      p_msg->p_apdu = (uint8_t*)(p_msg + 1);
+      memcpy(p_msg->p_apdu, p_apdu, apdu_len);
+
+      nfa_sys_sendmsg(p_msg);
+
+      status = NFA_STATUS_OK;
+    }
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFA_EeGetLmrtRemainingSize
+**
+** Description      This function is called to get remaining size of the
+**                  Listen Mode Routing Table.
+**                  The remaining size is reported in NFA_EE_REMAINING_SIZE_EVT
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeGetLmrtRemainingSize(void) {
+  tNFA_EE_API_LMRT_SIZE* p_msg;
+  tNFA_STATUS status = NFA_STATUS_FAILED;
+
+  NFA_TRACE_API0("NFA_EeGetLmrtRemainingSize()");
+  p_msg = (tNFA_EE_API_LMRT_SIZE*)GKI_getbuf(sizeof(tNFA_EE_API_LMRT_SIZE));
+  if (p_msg != NULL) {
+    p_msg->event = NFA_EE_API_LMRT_SIZE_EVT;
+    nfa_sys_sendmsg(p_msg);
+    status = NFA_STATUS_OK;
+  }
+
+  return status;
+}
+
+/******************************************************************************
+**
+** Function         NFA_EeUpdateNow
+**
+** Description      This function is called to send the current listen mode
+**                  routing table and VS configuration to the NFCC (without
+**                  waiting for NFA_EE_ROUT_TIMEOUT_VAL).
+**
+**                  The status of this operation is
+**                  reported with the NFA_EE_UPDATED_EVT.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_SEMANTIC_ERROR is update is currently in progress
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeUpdateNow(void) {
+  NFC_HDR* p_msg;
+  tNFA_STATUS status = NFA_STATUS_FAILED;
+
+  NFA_TRACE_API0("NFA_EeUpdateNow()");
+  if (nfa_ee_cb.ee_wait_evt & NFA_EE_WAIT_UPDATE_ALL) {
+    NFA_TRACE_ERROR0("update in progress");
+    status = NFA_STATUS_SEMANTIC_ERROR;
+  } else {
+    p_msg = (NFC_HDR*)GKI_getbuf(NFC_HDR_SIZE);
+    if (p_msg != NULL) {
+      p_msg->event = NFA_EE_API_UPDATE_NOW_EVT;
+
+      nfa_sys_sendmsg(p_msg);
+
+      status = NFA_STATUS_OK;
+    }
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFA_EeConnect
+**
+** Description      Open connection to an NFCEE attached to the NFCC
+**
+**                  The status of this operation is
+**                  reported with the NFA_EE_CONNECT_EVT.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeConnect(tNFA_HANDLE ee_handle, uint8_t ee_interface,
+                          tNFA_EE_CBACK* p_cback) {
+  tNFA_EE_API_CONNECT* p_msg;
+  tNFA_STATUS status = NFA_STATUS_FAILED;
+  uint8_t nfcee_id = (uint8_t)(ee_handle & 0xFF);
+  tNFA_EE_ECB* p_cb;
+
+  NFA_TRACE_API2("NFA_EeConnect(): handle:<0x%x> ee_interface:0x%x", ee_handle,
+                 ee_interface);
+  p_cb = nfa_ee_find_ecb(nfcee_id);
+
+  if ((p_cb == NULL) || (p_cback == NULL)) {
+    NFA_TRACE_ERROR0("Bad ee_handle or NULL callback function");
+    status = NFA_STATUS_INVALID_PARAM;
+  } else {
+    p_msg = (tNFA_EE_API_CONNECT*)GKI_getbuf(sizeof(tNFA_EE_API_CONNECT));
+    if (p_msg != NULL) {
+      p_msg->hdr.event = NFA_EE_API_CONNECT_EVT;
+      p_msg->nfcee_id = nfcee_id;
+      p_msg->p_cb = p_cb;
+      p_msg->ee_interface = ee_interface;
+      p_msg->p_cback = p_cback;
+
+      nfa_sys_sendmsg(p_msg);
+
+      status = NFA_STATUS_OK;
+    }
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFA_EeSendData
+**
+** Description      Send data to the given NFCEE.
+**                  This function shall be called after NFA_EE_CONNECT_EVT is
+**                  reported and before NFA_EeDisconnect is called on the given
+**                  ee_handle.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeSendData(tNFA_HANDLE ee_handle, uint16_t data_len,
+                           uint8_t* p_data) {
+  tNFA_EE_API_SEND_DATA* p_msg;
+  tNFA_STATUS status = NFA_STATUS_FAILED;
+  uint8_t nfcee_id = (uint8_t)(ee_handle & 0xFF);
+  tNFA_EE_ECB* p_cb;
+
+  NFA_TRACE_API1("NFA_EeSendData(): handle:<0x%x>", ee_handle);
+
+  p_cb = nfa_ee_find_ecb(nfcee_id);
+
+  if ((p_cb == NULL) || (p_cb->conn_st != NFA_EE_CONN_ST_CONN) ||
+      (p_data == NULL)) {
+    NFA_TRACE_ERROR0("Bad ee_handle or NULL data");
+    status = NFA_STATUS_INVALID_PARAM;
+  } else {
+    p_msg = (tNFA_EE_API_SEND_DATA*)GKI_getbuf(
+        (uint16_t)(sizeof(tNFA_EE_API_SEND_DATA) + data_len));
+    if (p_msg != NULL) {
+      p_msg->hdr.event = NFA_EE_API_SEND_DATA_EVT;
+      p_msg->nfcee_id = nfcee_id;
+      p_msg->p_cb = p_cb;
+      p_msg->data_len = data_len;
+      p_msg->p_data = (uint8_t*)(p_msg + 1);
+      memcpy(p_msg->p_data, p_data, data_len);
+
+      nfa_sys_sendmsg(p_msg);
+
+      status = NFA_STATUS_OK;
+    }
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFA_EeDisconnect
+**
+** Description      Disconnect (if a connection is currently open) from an
+**                  NFCEE interface. The result of this operation is reported
+**                  with the NFA_EE_DISCONNECT_EVT.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeDisconnect(tNFA_HANDLE ee_handle) {
+  tNFA_EE_API_DISCONNECT* p_msg;
+  tNFA_STATUS status = NFA_STATUS_FAILED;
+  uint8_t nfcee_id = (uint8_t)(ee_handle & 0xFF);
+  tNFA_EE_ECB* p_cb;
+
+  NFA_TRACE_API1("NFA_EeDisconnect(): handle:<0x%x>", ee_handle);
+  p_cb = nfa_ee_find_ecb(nfcee_id);
+
+  if ((p_cb == NULL) || (p_cb->conn_st != NFA_EE_CONN_ST_CONN)) {
+    NFA_TRACE_ERROR0("NFA_EeDisconnect() Bad ee_handle");
+    status = NFA_STATUS_INVALID_PARAM;
+  } else {
+    p_msg = (tNFA_EE_API_DISCONNECT*)GKI_getbuf(sizeof(tNFA_EE_API_DISCONNECT));
+    if (p_msg != NULL) {
+      p_msg->hdr.event = NFA_EE_API_DISCONNECT_EVT;
+      p_msg->nfcee_id = nfcee_id;
+      p_msg->p_cb = p_cb;
+
+      nfa_sys_sendmsg(p_msg);
+
+      status = NFA_STATUS_OK;
+    }
+  }
+
+  return status;
+}
diff --git a/src/nfa/ee/nfa_ee_main.c b/src/nfa/ee/nfa_ee_main.c
new file mode 100644
index 0000000..da58a54
--- /dev/null
+++ b/src/nfa/ee/nfa_ee_main.c
@@ -0,0 +1,764 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  This is the main implementation file for the NFA EE.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_api.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "nfa_dm_int.h"
+#include "nfa_ee_int.h"
+#include "config.h"
+
+extern void nfa_ee_vs_cback(tNFC_VS_EVT event, NFC_HDR* p_data);
+/*****************************************************************************
+**  Global Variables
+*****************************************************************************/
+
+/* system manager control block definition */
+tNFA_EE_CB nfa_ee_cb;
+
+#if (NXP_EXTNS == TRUE)
+#ifndef NFA_EE_DISCV_TIMEOUT_VAL
+#define NFA_EE_DISCV_TIMEOUT_VAL 4000  // Wait for UICC Init complete.
+#endif
+#endif
+
+/*****************************************************************************
+**  Constants
+*****************************************************************************/
+static const tNFA_SYS_REG nfa_ee_sys_reg = {nfa_ee_sys_enable, nfa_ee_evt_hdlr,
+                                            nfa_ee_sys_disable,
+                                            nfa_ee_proc_nfcc_power_mode};
+
+#define NFA_EE_NUM_ACTIONS (NFA_EE_MAX_EVT & 0x00ff)
+
+const tNFA_EE_SM_ACT nfa_ee_actions[] = {
+    /* NFA-EE action function/ internal events */
+    nfa_ee_api_discover,      /* NFA_EE_API_DISCOVER_EVT      */
+    nfa_ee_api_register,      /* NFA_EE_API_REGISTER_EVT      */
+    nfa_ee_api_deregister,    /* NFA_EE_API_DEREGISTER_EVT    */
+    nfa_ee_api_mode_set,      /* NFA_EE_API_MODE_SET_EVT      */
+    nfa_ee_api_set_tech_cfg,  /* NFA_EE_API_SET_TECH_CFG_EVT  */
+    nfa_ee_api_set_proto_cfg, /* NFA_EE_API_SET_PROTO_CFG_EVT */
+    nfa_ee_api_add_aid,       /* NFA_EE_API_ADD_AID_EVT       */
+    nfa_ee_api_remove_aid,    /* NFA_EE_API_REMOVE_AID_EVT    */
+    nfa_ee_api_lmrt_size,     /* NFA_EE_API_LMRT_SIZE_EVT     */
+    nfa_ee_api_update_now,    /* NFA_EE_API_UPDATE_NOW_EVT    */
+    nfa_ee_api_connect,       /* NFA_EE_API_CONNECT_EVT       */
+    nfa_ee_api_send_data,     /* NFA_EE_API_SEND_DATA_EVT     */
+    nfa_ee_api_disconnect,    /* NFA_EE_API_DISCONNECT_EVT    */
+    nfa_ee_nci_disc_rsp,      /* NFA_EE_NCI_DISC_RSP_EVT      */
+    nfa_ee_nci_disc_ntf,      /* NFA_EE_NCI_DISC_NTF_EVT      */
+    nfa_ee_nci_mode_set_rsp,  /* NFA_EE_NCI_MODE_SET_RSP_EVT  */
+#if (NXP_EXTNS == TRUE)
+    nfa_ee_nci_set_mode_info, /* NFA_EE_NCI_MODE_SET_INFO*/
+	nfa_ee_api_power_link_set, /* NFA_EE_NCI_PWR_LNK_CTRL_SET_EVT */
+    nfa_ee_nci_pwr_link_ctrl_rsp, /*NFA_EE_NCI_PWR_LNK_CTRL_RSP_EVT*/
+#endif
+    nfa_ee_nci_conn,         /* NFA_EE_NCI_CONN_EVT          */
+    nfa_ee_nci_conn,         /* NFA_EE_NCI_DATA_EVT          */
+    nfa_ee_nci_action_ntf,   /* NFA_EE_NCI_ACTION_NTF_EVT    */
+    nfa_ee_nci_disc_req_ntf, /* NFA_EE_NCI_DISC_REQ_NTF_EVT  */
+    nfa_ee_nci_wait_rsp,     /* NFA_EE_NCI_WAIT_RSP_EVT      */
+    nfa_ee_rout_timeout,     /* NFA_EE_ROUT_TIMEOUT_EVT      */
+    nfa_ee_discv_timeout,    /* NFA_EE_DISCV_TIMEOUT_EVT     */
+    nfa_ee_lmrt_to_nfcc,      /* NFA_EE_CFG_TO_NFCC_EVT       */
+    nfa_ee_api_add_apdu,       /* NFA_EE_API_ADD_AID_EVT       */
+    nfa_ee_api_remove_apdu,    /* NFA_EE_API_REMOVE_AID_EVT    */
+    nfa_ee_nci_nfcee_status_ntf        /*NFA_EE_NCI_NFCEE_STATUS_NTF_EVT*/
+};
+
+/*******************************************************************************
+**
+** Function         nfa_ee_init
+**
+** Description      Initialize NFA EE control block
+**                  register to NFA SYS
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_ee_init(void) {
+  int xx;
+
+  NFA_TRACE_DEBUG0("nfa_ee_init ()");
+
+  /* initialize control block */
+  memset(&nfa_ee_cb, 0, sizeof(tNFA_EE_CB));
+  for (xx = 0; xx < NFA_EE_MAX_EE_SUPPORTED; xx++) {
+    nfa_ee_cb.ecb[xx].nfcee_id = NFA_EE_INVALID;
+    nfa_ee_cb.ecb[xx].ee_status = NFC_NFCEE_STATUS_INACTIVE;
+  }
+
+  nfa_ee_cb.ecb[NFA_EE_CB_4_DH].ee_status = NFC_NFCEE_STATUS_ACTIVE;
+  nfa_ee_cb.ecb[NFA_EE_CB_4_DH].nfcee_id = NFC_DH_ID;
+#if (NXP_EXTNS == TRUE)
+  /*clear the p61 ce*/
+  nfa_ee_ce_p61_active = 0;
+#endif
+  /* register message handler on NFA SYS */
+  nfa_sys_register(NFA_ID_EE, &nfa_ee_sys_reg);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_sys_enable
+**
+** Description      Enable NFA EE
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_ee_sys_enable(void) {
+
+  unsigned long retlen = 0;
+
+  NFA_TRACE_DEBUG1("%s", __func__);
+
+  nfa_ee_cb.route_block_control = 0x00;
+
+  if (GetNumValue(NAME_NFA_BLOCK_ROUTE, (void*)&retlen, sizeof(retlen))) {
+    if ((retlen == 0x01) && ((NFC_GetNCIVersion() == NCI_VERSION_2_0)
+        || (nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT == true))) {
+      nfa_ee_cb.route_block_control = NCI_ROUTE_QUAL_BLOCK_ROUTE;
+      NFA_TRACE_DEBUG1("nfa_ee_cb.route_block_control=0x%x",
+                       nfa_ee_cb.route_block_control);
+    }
+  }
+
+  if (nfa_ee_max_ee_cfg) {
+    /* collect NFCEE information */
+    NFC_NfceeDiscover(true);
+    nfa_sys_start_timer(&nfa_ee_cb.discv_timer, NFA_EE_DISCV_TIMEOUT_EVT,
+                        NFA_EE_DISCV_TIMEOUT_VAL);
+  } else {
+    nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
+    nfa_sys_cback_notify_enable_complete(NFA_ID_EE);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_restore_one_ecb
+**
+** Description      activate the NFCEE and restore the routing when
+**                  changing power state from low power mode to full power mode
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_ee_restore_one_ecb(tNFA_EE_ECB* p_cb) {
+  uint8_t mask;
+  tNFC_NFCEE_MODE_SET_REVT rsp;
+  tNFA_EE_NCI_MODE_SET ee_msg;
+
+  NFA_TRACE_DEBUG4(
+      "nfa_ee_restore_one_ecb () nfcee_id:0x%x, ecb_flags:0x%x ee_status:0x%x "
+      "ee_old_status: 0x%x",
+      p_cb->nfcee_id, p_cb->ecb_flags, p_cb->ee_status, p_cb->ee_old_status);
+  if ((p_cb->nfcee_id != NFA_EE_INVALID) &&
+      (p_cb->ee_status & NFA_EE_STATUS_RESTORING) == 0 &&
+      (p_cb->ee_old_status & NFA_EE_STATUS_RESTORING) != 0) {
+    p_cb->ee_old_status &= ~NFA_EE_STATUS_RESTORING;
+    mask = nfa_ee_ecb_to_mask(p_cb);
+    if (p_cb->ee_status != p_cb->ee_old_status) {
+      p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_RESTORE;
+      if (p_cb->ee_old_status == NFC_NFCEE_STATUS_ACTIVE) {
+        NFC_NfceeModeSet(p_cb->nfcee_id, NFC_MODE_ACTIVATE);
+
+        if (nfa_ee_cb.ee_cfged & mask) {
+          /* if any routing is configured on this NFCEE. need to mark this NFCEE
+           * as changed
+           * to cause the configuration to be sent to NFCC again */
+          p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_ROUTING;
+          p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_VS;
+        }
+      } else {
+        NFC_NfceeModeSet(p_cb->nfcee_id, NFC_MODE_DEACTIVATE);
+      }
+    } else if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE) {
+      /* the initial NFCEE status after start up is the same as the current
+       * status and it's active:
+       * process the same as the host gets activate rsp */
+      p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_RESTORE;
+      if (nfa_ee_cb.ee_cfged & mask) {
+        /* if any routing is configured on this NFCEE. need to mark this NFCEE
+         * as changed
+         * to cause the configuration to be sent to NFCC again */
+        p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_ROUTING;
+        p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_VS;
+      }
+      rsp.mode = NFA_EE_MD_ACTIVATE;
+      rsp.nfcee_id = p_cb->nfcee_id;
+      rsp.status = NFA_STATUS_OK;
+      ee_msg.p_data = &rsp;
+      nfa_ee_nci_mode_set_rsp((void*)&ee_msg);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_proc_nfcc_power_mode
+**
+** Description      Restore NFA EE sub-module
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_ee_proc_nfcc_power_mode(uint8_t nfcc_power_mode) {
+  uint32_t xx;
+  tNFA_EE_ECB* p_cb;
+  bool proc_complete = true;
+
+  NFA_TRACE_DEBUG1("nfa_ee_proc_nfcc_power_mode (): nfcc_power_mode=%d",
+                   nfcc_power_mode);
+  /* if NFCC power state is change to full power */
+  if (nfcc_power_mode == NFA_DM_PWR_MODE_FULL) {
+    if (nfa_ee_max_ee_cfg) {
+      p_cb = nfa_ee_cb.ecb;
+      for (xx = 0; xx < nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED; xx++, p_cb++) {
+        p_cb->ee_old_status = 0;
+        if (xx >= nfa_ee_cb.cur_ee) p_cb->nfcee_id = NFA_EE_INVALID;
+
+        if ((p_cb->nfcee_id != NFA_EE_INVALID) &&
+            (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) &&
+            (p_cb->ee_status != NFA_EE_STATUS_REMOVED)) {
+          proc_complete = false;
+          /* NFA_EE_STATUS_RESTORING bit makes sure the ee_status restore to
+           * ee_old_status
+           * NFA_EE_STATUS_RESTORING bit is cleared in ee_status at
+           * NFCEE_DISCOVER NTF.
+           * NFA_EE_STATUS_RESTORING bit is cleared in ee_old_status at
+           * restoring the activate/inactive status after NFCEE_DISCOVER NTF */
+          p_cb->ee_status |= NFA_EE_STATUS_RESTORING;
+          p_cb->ee_old_status = p_cb->ee_status;
+          /* NFA_EE_FLAGS_RESTORE bit makes sure the routing/nci logical
+           * connection is restore to prior to entering low power mode */
+          p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_RESTORE;
+        }
+      }
+      nfa_ee_cb.em_state = NFA_EE_EM_STATE_RESTORING;
+      nfa_ee_cb.num_ee_expecting = 0;
+      if (nfa_sys_is_register(NFA_ID_HCI)) {
+        nfa_ee_cb.ee_flags |= NFA_EE_FLAG_WAIT_HCI;
+        nfa_ee_cb.ee_flags |= NFA_EE_FLAG_NOTIFY_HCI;
+      }
+      NFC_NfceeDiscover(true);
+      nfa_sys_start_timer(&nfa_ee_cb.discv_timer, NFA_EE_DISCV_TIMEOUT_EVT,
+                          NFA_EE_DISCV_TIMEOUT_VAL);
+    }
+  } else {
+    nfa_sys_stop_timer(&nfa_ee_cb.timer);
+    nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
+    nfa_ee_cb.num_ee_expecting = 0;
+  }
+
+  if (proc_complete)
+    nfa_sys_cback_notify_nfcc_power_mode_proc_complete(NFA_ID_EE);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_proc_hci_info_cback
+**
+** Description      HCI initialization complete from power off sleep mode
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_ee_proc_hci_info_cback(void) {
+  uint32_t xx;
+  tNFA_EE_ECB* p_cb;
+  tNFA_EE_MSG data;
+
+  NFA_TRACE_DEBUG0("nfa_ee_proc_hci_info_cback ()");
+  /* if NFCC power state is change to full power */
+  nfa_ee_cb.ee_flags &= ~NFA_EE_FLAG_WAIT_HCI;
+
+  p_cb = nfa_ee_cb.ecb;
+  for (xx = 0; xx < nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED; xx++, p_cb++) {
+    /* NCI spec says: An NFCEE_DISCOVER_NTF that contains a Protocol type of
+     * "HCI Access"
+     * SHALL NOT contain any other additional Protocol
+     * i.e. check only first supported NFCEE interface is HCI access */
+    /* NFA_HCI module handles restoring configurations for HCI access */
+    if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) {
+      nfa_ee_restore_one_ecb(p_cb);
+    }
+  }
+
+  if (nfa_ee_restore_ntf_done()) {
+    nfa_ee_check_restore_complete();
+    if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_INIT_DONE) {
+      if (nfa_ee_cb.discv_timer.in_use) {
+        nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
+        data.hdr.event = NFA_EE_DISCV_TIMEOUT_EVT;
+        nfa_ee_evt_hdlr((void*)&data);
+      }
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_proc_evt
+**
+** Description      Process NFCEE related events from NFC stack
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_ee_proc_evt(tNFC_RESPONSE_EVT event, void* p_data) {
+  tNFA_EE_INT_EVT int_event = 0;
+  tNFA_EE_NCI_WAIT_RSP cbk;
+
+  switch (event) {
+    case NFC_NFCEE_DISCOVER_REVT: /* 4  NFCEE Discover response */
+      int_event = NFA_EE_NCI_DISC_RSP_EVT;
+      break;
+
+    case NFC_NFCEE_INFO_REVT: /* 5  NFCEE Discover Notification */
+      int_event = NFA_EE_NCI_DISC_NTF_EVT;
+      break;
+
+    case NFC_NFCEE_MODE_SET_REVT: /* 6  NFCEE Mode Set response */
+      int_event = NFA_EE_NCI_MODE_SET_RSP_EVT;
+      break;
+
+    case NFC_EE_ACTION_REVT:
+      int_event = NFA_EE_NCI_ACTION_NTF_EVT;
+      break;
+
+    case NFC_EE_DISCOVER_REQ_REVT: /* 10 EE Discover Req notification */
+      int_event = NFA_EE_NCI_DISC_REQ_NTF_EVT;
+      break;
+
+    case NFC_SET_ROUTING_REVT:
+      int_event = NFA_EE_NCI_WAIT_RSP_EVT;
+      cbk.opcode = NCI_MSG_RF_SET_ROUTING;
+      break;
+
+#if (NXP_EXTNS == TRUE)
+    case NFC_NFCEE_MODE_SET_INFO:
+      int_event = NFA_EE_NCI_MODE_SET_INFO;
+      break;
+    case NFC_NFCEE_PWR_LNK_CTRL_REVT: /* 6  NFCEE PWR LNK CTRL response */
+        if(nfcFL.eseFL._WIRED_MODE_STANDBY) {
+            int_event = NFA_EE_NCI_PWR_LNK_CTRL_RSP_EVT;
+        }
+      break;
+#endif
+
+    case NFC_NFCEE_STATUS_REVT:
+      int_event = NFA_EE_NCI_NFCEE_STATUS_NTF_EVT;
+      break;
+  }
+
+  NFA_TRACE_DEBUG2("nfa_ee_proc_evt: event=0x%02x int_event:0x%x", event,
+                   int_event);
+  if (int_event) {
+    cbk.hdr.event = int_event;
+    cbk.p_data = p_data;
+
+    nfa_ee_evt_hdlr((void*)&cbk);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_ecb_to_mask
+**
+** Description      Given a ecb, return the bit mask to be used in
+**                  nfa_ee_cb.ee_cfged
+**
+** Returns          the bitmask for the given ecb.
+**
+*******************************************************************************/
+uint8_t nfa_ee_ecb_to_mask(tNFA_EE_ECB* p_cb) {
+  uint8_t mask;
+  uint8_t index;
+
+  index = (uint8_t)(p_cb - nfa_ee_cb.ecb);
+  mask = 1 << index;
+
+  return mask;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_find_ecb
+**
+** Description      Return the ecb associated with the given nfcee_id
+**
+** Returns          tNFA_EE_ECB
+**
+*******************************************************************************/
+tNFA_EE_ECB* nfa_ee_find_ecb(uint8_t nfcee_id) {
+  uint32_t xx;
+  tNFA_EE_ECB* p_ret = NULL, *p_cb;
+  NFA_TRACE_DEBUG0("nfa_ee_find_ecb ()");
+
+  if (nfcee_id == NFC_DH_ID) {
+    p_ret = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH];
+  } else {
+    p_cb = nfa_ee_cb.ecb;
+    for (xx = 0; xx < nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED; xx++, p_cb++) {
+      if (nfcee_id == p_cb->nfcee_id) {
+        p_ret = p_cb;
+        break;
+      }
+    }
+  }
+
+  return p_ret;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_find_ecb_by_conn_id
+**
+** Description      Return the ecb associated with the given connection id
+**
+** Returns          tNFA_EE_ECB
+**
+*******************************************************************************/
+tNFA_EE_ECB* nfa_ee_find_ecb_by_conn_id(uint8_t conn_id) {
+  uint32_t xx;
+  tNFA_EE_ECB* p_ret = NULL, *p_cb;
+  NFA_TRACE_DEBUG0("nfa_ee_find_ecb_by_conn_id ()");
+
+  p_cb = nfa_ee_cb.ecb;
+  for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) {
+    if (conn_id == p_cb->conn_id) {
+      p_ret = p_cb;
+      break;
+    }
+  }
+
+  return p_ret;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_sys_disable
+**
+** Description      Deregister NFA EE from NFA SYS/DM
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_ee_sys_disable(void) {
+  uint32_t xx;
+  tNFA_EE_ECB* p_cb;
+  tNFA_EE_MSG msg;
+
+  NFA_TRACE_DEBUG0("nfa_ee_sys_disable ()");
+
+  nfa_ee_cb.em_state = NFA_EE_EM_STATE_DISABLED;
+  /* report NFA_EE_DEREGISTER_EVT to all registered to EE */
+  for (xx = 0; xx < NFA_EE_MAX_CBACKS; xx++) {
+    if (nfa_ee_cb.p_ee_cback[xx]) {
+      msg.deregister.index = xx;
+      nfa_ee_api_deregister(&msg);
+    }
+  }
+
+  nfa_ee_cb.num_ee_expecting = 0;
+  p_cb = nfa_ee_cb.ecb;
+  for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) {
+    if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) {
+      if (nfa_sys_is_graceful_disable()) {
+        /* Disconnect NCI connection on graceful shutdown */
+        msg.disconnect.p_cb = p_cb;
+#if(NXP_EXTNS == TRUE)
+        if(p_cb->conn_id == 0x03){
+            msg.conn.conn_id = p_cb->conn_id;
+            msg.conn.event = NFC_CONN_CLOSE_CEVT;
+            nfa_ee_nci_conn(&msg);
+        }
+        else{
+            nfa_ee_api_disconnect (&msg);
+            nfa_ee_cb.num_ee_expecting++;
+        }
+#else
+        nfa_ee_api_disconnect(&msg);
+        nfa_ee_cb.num_ee_expecting++;
+#endif
+      } else {
+        /* fake NFA_EE_DISCONNECT_EVT on ungraceful shutdown */
+        msg.conn.conn_id = p_cb->conn_id;
+        msg.conn.event = NFC_CONN_CLOSE_CEVT;
+        nfa_ee_nci_conn(&msg);
+      }
+    }
+  }
+
+  if (nfa_ee_cb.num_ee_expecting) {
+    nfa_ee_cb.ee_flags |= NFA_EE_FLAG_WAIT_DISCONN;
+    nfa_ee_cb.em_state = NFA_EE_EM_STATE_DISABLING;
+  }
+
+  nfa_sys_stop_timer(&nfa_ee_cb.timer);
+  nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
+
+  /* If Application initiated NFCEE discovery, fake/report the event */
+  nfa_ee_report_disc_done(false);
+
+  /* deregister message handler on NFA SYS */
+  if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_DISABLED)
+    nfa_sys_deregister(NFA_ID_EE);
+}
+#if(NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         nfa_ee_connectionClosed
+**
+** Description      Check if EE's HCI connection is closed or not
+**
+** Returns          EE connection closed status
+**
+*******************************************************************************/
+uint8_t nfa_ee_connectionClosed(void)
+{
+
+  return (!(nfa_ee_cb.ee_flags & NFA_EE_HCI_CONN_CLOSE));
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         nfa_ee_check_disable
+**
+** Description      Check if it is safe to move to disabled state
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_ee_check_disable(void) {
+  if (!(nfa_ee_cb.ee_flags & NFA_EE_FLAG_WAIT_DISCONN)) {
+    nfa_ee_cb.em_state = NFA_EE_EM_STATE_DISABLED;
+    nfa_sys_deregister(NFA_ID_EE);
+  }
+}
+/*******************************************************************************
+**
+** Function         nfa_ee_reg_cback_enable_done
+**
+** Description      Allow a module to register to EE to be notified when NFA-EE
+**                  finishes enable process
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_ee_reg_cback_enable_done(tNFA_EE_ENABLE_DONE_CBACK* p_cback) {
+  nfa_ee_cb.p_enable_cback = p_cback;
+}
+
+#if (BT_TRACE_VERBOSE == true)
+/*******************************************************************************
+**
+** Function         nfa_ee_sm_st_2_str
+**
+** Description      convert nfa-ee state to string
+**
+*******************************************************************************/
+static char* nfa_ee_sm_st_2_str(uint8_t state) {
+  switch (state) {
+    case NFA_EE_EM_STATE_INIT:
+      return "INIT";
+
+    case NFA_EE_EM_STATE_INIT_DONE:
+      return "INIT_DONE";
+
+    case NFA_EE_EM_STATE_RESTORING:
+      return "RESTORING";
+
+    case NFA_EE_EM_STATE_DISABLING:
+      return "DISABLING";
+
+    case NFA_EE_EM_STATE_DISABLED:
+      return "DISABLED";
+
+    default:
+      return "Unknown";
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_sm_evt_2_str
+**
+** Description      convert nfa-ee evt to string
+**
+*******************************************************************************/
+static char* nfa_ee_sm_evt_2_str(uint16_t event) {
+  switch (event) {
+    case NFA_EE_API_DISCOVER_EVT:
+      return "API_DISCOVER";
+    case NFA_EE_API_REGISTER_EVT:
+      return "API_REGISTER";
+    case NFA_EE_API_DEREGISTER_EVT:
+      return "API_DEREGISTER";
+    case NFA_EE_API_MODE_SET_EVT:
+      return "API_MODE_SET";
+    case NFA_EE_API_SET_TECH_CFG_EVT:
+      return "API_SET_TECH_CFG";
+    case NFA_EE_API_SET_PROTO_CFG_EVT:
+      return "API_SET_PROTO_CFG";
+    case NFA_EE_API_ADD_AID_EVT:
+      return "API_ADD_AID";
+    case NFA_EE_API_REMOVE_AID_EVT:
+      return "API_REMOVE_AID";
+    case NFA_EE_API_LMRT_SIZE_EVT:
+      return "API_LMRT_SIZE";
+    case NFA_EE_API_UPDATE_NOW_EVT:
+      return "API_UPDATE_NOW";
+    case NFA_EE_API_CONNECT_EVT:
+      return "API_CONNECT";
+    case NFA_EE_API_SEND_DATA_EVT:
+      return "API_SEND_DATA";
+    case NFA_EE_API_DISCONNECT_EVT:
+      return "API_DISCONNECT";
+    case NFA_EE_NCI_DISC_RSP_EVT:
+      return "NCI_DISC_RSP";
+    case NFA_EE_NCI_DISC_NTF_EVT:
+      return "NCI_DISC_NTF";
+    case NFA_EE_NCI_MODE_SET_RSP_EVT:
+      return "NCI_MODE_SET";
+#if (NXP_EXTNS == TRUE)
+    case NFA_EE_NCI_MODE_SET_INFO:
+      return "NFA_EE_NCI_MODE_SET_INFO";
+	case NFA_EE_NCI_PWR_LNK_CTRL_SET_EVT:
+      return "NFA_EE_NCI_PWR_LNK_CTRL_SET_EVT,";
+    case NFA_EE_NCI_PWR_LNK_CTRL_RSP_EVT:
+        if(nfcFL.eseFL._WIRED_MODE_STANDBY) {
+            return "NCI_PWR_LNK_CTRL";
+        }
+        else {
+            return "Unknown";
+        }
+#endif
+    case NFA_EE_NCI_CONN_EVT:
+      return "NCI_CONN";
+    case NFA_EE_NCI_DATA_EVT:
+      return "NCI_DATA";
+    case NFA_EE_NCI_ACTION_NTF_EVT:
+      return "NCI_ACTION";
+    case NFA_EE_NCI_DISC_REQ_NTF_EVT:
+      return "NCI_DISC_REQ";
+    case NFA_EE_NCI_WAIT_RSP_EVT:
+      return "NCI_WAIT_RSP";
+    case NFA_EE_ROUT_TIMEOUT_EVT:
+      return "ROUT_TIMEOUT";
+    case NFA_EE_DISCV_TIMEOUT_EVT:
+      return "NFA_EE_DISCV_TIMEOUT_EVT";
+    case NFA_EE_CFG_TO_NFCC_EVT:
+      return "CFG_TO_NFCC";
+    default:
+      return "Unknown";
+  }
+}
+#endif /* BT_TRACE_VERBOSE */
+
+/*******************************************************************************
+**
+** Function         nfa_ee_evt_hdlr
+**
+** Description      Processing event for NFA EE
+**
+**
+** Returns          true if p_msg needs to be deallocated
+**
+*******************************************************************************/
+bool nfa_ee_evt_hdlr(NFC_HDR* p_msg) {
+  tNFA_EE_MSG* p_evt_data = (tNFA_EE_MSG*)p_msg;
+  uint16_t event = p_msg->event & 0x00ff;
+  bool act = false;
+
+#if (BT_TRACE_VERBOSE == true)
+  NFA_TRACE_DEBUG4("nfa_ee_evt_hdlr (): Event %s(0x%02x), State: %s(%d)",
+                   nfa_ee_sm_evt_2_str(p_evt_data->hdr.event),
+                   p_evt_data->hdr.event,
+                   nfa_ee_sm_st_2_str(nfa_ee_cb.em_state), nfa_ee_cb.em_state);
+#else
+  NFA_TRACE_DEBUG2("nfa_ee_evt_hdlr (): Event 0x%02x, State: %d",
+                   p_evt_data->hdr.event, nfa_ee_cb.em_state);
+#endif
+
+#if 0
+    /*This is required to receive Reader Over SWP event*/
+    if(p_evt_data->hdr.event == NFA_EE_NCI_DISC_NTF_EVT)
+    {
+        NFA_TRACE_DEBUG0("recived dis_ntf; stopping timer");
+        nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
+    }
+#endif
+
+  switch (nfa_ee_cb.em_state) {
+    case NFA_EE_EM_STATE_INIT_DONE:
+    case NFA_EE_EM_STATE_RESTORING:
+      act = true;
+      break;
+    case NFA_EE_EM_STATE_INIT:
+      if ((p_msg->event == NFA_EE_NCI_DISC_NTF_EVT) ||
+          (p_msg->event == NFA_EE_NCI_DISC_RSP_EVT))
+        act = true;
+      break;
+    case NFA_EE_EM_STATE_DISABLING:
+      if (p_msg->event == NFA_EE_NCI_CONN_EVT) act = true;
+      break;
+  }
+  if (act) {
+    if (event < NFA_EE_NUM_ACTIONS) {
+      (*nfa_ee_actions[event])(p_evt_data);
+    }
+  } else {
+    /* if the data event is not handled by action function, free the data packet
+     */
+    if (p_msg->event == NFA_EE_NCI_DATA_EVT)
+      GKI_freebuf(p_evt_data->conn.p_data);
+  }
+
+  return true;
+}
diff --git a/src/nfa/hci/nfa_hci_act.c b/src/nfa/hci/nfa_hci_act.c
new file mode 100644
index 0000000..6718a1d
--- /dev/null
+++ b/src/nfa/hci/nfa_hci_act.c
@@ -0,0 +1,3385 @@
+/******************************************************************************
+ *  Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  This file contains the action functions for the NFA HCI.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "trace_api.h"
+#include "nfc_api.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "nfa_hci_api.h"
+#include "nfa_hci_int.h"
+#include "nfa_dm_int.h"
+#include "nfa_nv_co.h"
+#include "nfa_mem_co.h"
+#include "nfa_hci_defs.h"
+#if (NXP_EXTNS == TRUE)
+#include "nfa_ee_int.h"
+#endif
+
+/* Static local functions       */
+static void nfa_hci_api_register(tNFA_HCI_EVENT_DATA* p_evt_data);
+static void nfa_hci_api_get_gate_pipe_list(tNFA_HCI_EVENT_DATA* p_evt_data);
+static void nfa_hci_api_alloc_gate(tNFA_HCI_EVENT_DATA* p_evt_data);
+static void nfa_hci_api_get_host_list(tNFA_HCI_EVENT_DATA* p_evt_data);
+static bool nfa_hci_api_get_reg_value(tNFA_HCI_EVENT_DATA* p_evt_data);
+static bool nfa_hci_api_set_reg_value(tNFA_HCI_EVENT_DATA* p_evt_data);
+static bool nfa_hci_api_create_pipe(tNFA_HCI_EVENT_DATA* p_evt_data);
+static void nfa_hci_api_open_pipe(tNFA_HCI_EVENT_DATA* p_evt_data);
+static void nfa_hci_api_close_pipe(tNFA_HCI_EVENT_DATA* p_evt_data);
+static void nfa_hci_api_delete_pipe(tNFA_HCI_EVENT_DATA* p_evt_data);
+static bool nfa_hci_api_send_event(tNFA_HCI_EVENT_DATA* p_evt_data);
+static bool nfa_hci_api_send_cmd(tNFA_HCI_EVENT_DATA* p_evt_data);
+static void nfa_hci_api_send_rsp(tNFA_HCI_EVENT_DATA* p_evt_data);
+static void nfa_hci_api_add_static_pipe(tNFA_HCI_EVENT_DATA* p_evt_data);
+
+static void nfa_hci_handle_identity_mgmt_gate_pkt(uint8_t* p_data,
+                                                  tNFA_HCI_DYN_PIPE* p_pipe);
+static void nfa_hci_handle_loopback_gate_pkt(uint8_t* p_data, uint16_t data_len,
+                                             tNFA_HCI_DYN_PIPE* p_pipe);
+static void nfa_hci_handle_connectivity_gate_pkt(uint8_t* p_data,
+                                                 uint16_t data_len,
+                                                 tNFA_HCI_DYN_PIPE* p_pipe);
+static void nfa_hci_handle_generic_gate_cmd(uint8_t* p_data, uint8_t data_len,
+                                            tNFA_HCI_DYN_GATE* p_gate,
+                                            tNFA_HCI_DYN_PIPE* p_pipe);
+static void nfa_hci_handle_generic_gate_rsp(uint8_t* p_data, uint8_t data_len,
+                                            tNFA_HCI_DYN_GATE* p_gate,
+                                            tNFA_HCI_DYN_PIPE* p_pipe);
+static void nfa_hci_handle_generic_gate_evt(uint8_t* p_data, uint16_t data_len,
+                                            tNFA_HCI_DYN_GATE* p_gate,
+                                            tNFA_HCI_DYN_PIPE* p_pipe);
+
+#if (NXP_EXTNS == TRUE)
+static void nfa_hci_api_get_host_id(tNFA_HCI_EVENT_DATA* p_evt_data);
+static void nfa_hci_api_get_host_type(tNFA_HCI_EVENT_DATA* p_evt_data);
+static tNFA_STATUS nfa_hci_api_get_host_type_list();
+static void nfa_hci_api_getnoofhosts(uint8_t* p_data, uint8_t data_len);
+static void nfa_hci_handle_Nfcee_admpipe_rsp(uint8_t* p_data, uint8_t data_len);
+static void nfa_hci_handle_Nfcee_dynpipe_rsp(uint8_t pipeId, uint8_t* p_data,
+                                             uint8_t data_len);
+static bool nfa_hci_api_checkforAPDUGate(uint8_t* p_data, uint8_t data_len);
+static bool nfa_hci_api_IspipePresent(uint8_t nfceeId, uint8_t gateId);
+static bool nfa_hci_api_GetpipeId(uint8_t nfceeId, uint8_t gateId,
+                                  uint8_t* pipeId);
+static void nfa_hci_poll_session_id_cb(uint8_t event, uint16_t param_len,
+                                       uint8_t* p_param);
+static void nfa_hci_read_num_nfcee_config_cb(uint8_t event, uint16_t param_len,
+                                             uint8_t* p_param);
+static tNFA_STATUS nfa_hci_poll_session_id(uint8_t host_type);
+static void nfa_hci_get_pipe_state_cb(uint8_t event, uint16_t param_len, uint8_t* p_param);
+static void nfa_hci_update_pipe_status(uint8_t gateId, uint8_t pipeId);
+#endif
+
+/*******************************************************************************
+**
+** Function         nfa_hci_check_pending_api_requests
+**
+** Description      This function handles pending API requests
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_hci_check_pending_api_requests(void) {
+  NFC_HDR* p_msg;
+  tNFA_HCI_EVENT_DATA* p_evt_data;
+  bool b_free;
+
+  /* If busy, or API queue is empty, then exit */
+  if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_IDLE) ||
+      ((p_msg = (NFC_HDR*)GKI_dequeue(&nfa_hci_cb.hci_host_reset_api_q)) ==
+       NULL))
+    return;
+
+  /* Process API request */
+  p_evt_data = (tNFA_HCI_EVENT_DATA*)p_msg;
+
+  /* Save the application handle */
+  nfa_hci_cb.app_in_use = p_evt_data->comm.hci_handle;
+
+  b_free = true;
+  switch (p_msg->event) {
+    case NFA_HCI_API_CREATE_PIPE_EVT:
+      if (nfa_hci_api_create_pipe(p_evt_data) == false) b_free = false;
+      break;
+
+    case NFA_HCI_API_GET_REGISTRY_EVT:
+      if (nfa_hci_api_get_reg_value(p_evt_data) == false) b_free = false;
+      break;
+
+    case NFA_HCI_API_SET_REGISTRY_EVT:
+      if (nfa_hci_api_set_reg_value(p_evt_data) == false) b_free = false;
+      break;
+
+    case NFA_HCI_API_SEND_CMD_EVT:
+      if (nfa_hci_api_send_cmd(p_evt_data) == false) b_free = false;
+      break;
+    case NFA_HCI_API_SEND_EVENT_EVT:
+      if (nfa_hci_api_send_event(p_evt_data) == false) b_free = false;
+      break;
+#if (NXP_EXTNS == TRUE)
+    case NFA_HCI_API_CONFIGURE_EVT:
+      if (nfa_hci_api_config_nfcee(
+              p_evt_data->config_info.config_nfcee_event) == false)
+        b_free = false;
+      break;
+#endif
+  }
+
+  if (b_free) GKI_freebuf(p_msg);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_check_api_requests
+**
+** Description      This function handles API requests
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_hci_check_api_requests(void) {
+  NFC_HDR* p_msg;
+  tNFA_HCI_EVENT_DATA* p_evt_data;
+
+  for (;;) {
+    /* If busy, or API queue is empty, then exit */
+    if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_IDLE) ||
+        ((p_msg = (NFC_HDR*)GKI_dequeue(&nfa_hci_cb.hci_api_q)) == NULL))
+      break;
+
+    /* Process API request */
+    p_evt_data = (tNFA_HCI_EVENT_DATA*)p_msg;
+
+    /* Save the application handle */
+    nfa_hci_cb.app_in_use = p_evt_data->comm.hci_handle;
+
+    switch (p_msg->event) {
+      case NFA_HCI_API_REGISTER_APP_EVT:
+        nfa_hci_api_register(p_evt_data);
+        break;
+
+      case NFA_HCI_API_DEREGISTER_APP_EVT:
+        nfa_hci_api_deregister(p_evt_data);
+        break;
+
+      case NFA_HCI_API_GET_APP_GATE_PIPE_EVT:
+        nfa_hci_api_get_gate_pipe_list(p_evt_data);
+        break;
+
+      case NFA_HCI_API_ALLOC_GATE_EVT:
+        nfa_hci_api_alloc_gate(p_evt_data);
+        break;
+
+      case NFA_HCI_API_DEALLOC_GATE_EVT:
+        nfa_hci_api_dealloc_gate(p_evt_data);
+        break;
+
+      case NFA_HCI_API_GET_HOST_LIST_EVT:
+        nfa_hci_api_get_host_list(p_evt_data);
+        break;
+
+      case NFA_HCI_API_GET_REGISTRY_EVT:
+        if (nfa_hci_api_get_reg_value(p_evt_data) == false) continue;
+        break;
+
+      case NFA_HCI_API_SET_REGISTRY_EVT:
+        if (nfa_hci_api_set_reg_value(p_evt_data) == false) continue;
+        break;
+
+      case NFA_HCI_API_CREATE_PIPE_EVT:
+        if (nfa_hci_api_create_pipe(p_evt_data) == false) continue;
+        break;
+
+      case NFA_HCI_API_OPEN_PIPE_EVT:
+        nfa_hci_api_open_pipe(p_evt_data);
+        break;
+
+      case NFA_HCI_API_CLOSE_PIPE_EVT:
+        nfa_hci_api_close_pipe(p_evt_data);
+        break;
+
+      case NFA_HCI_API_DELETE_PIPE_EVT:
+        nfa_hci_api_delete_pipe(p_evt_data);
+        break;
+
+      case NFA_HCI_API_SEND_CMD_EVT:
+        if (nfa_hci_api_send_cmd(p_evt_data) == false) continue;
+        break;
+
+      case NFA_HCI_API_SEND_RSP_EVT:
+        nfa_hci_api_send_rsp(p_evt_data);
+        break;
+
+      case NFA_HCI_API_SEND_EVENT_EVT:
+        if (nfa_hci_api_send_event(p_evt_data) == false) continue;
+        break;
+
+      case NFA_HCI_API_ADD_STATIC_PIPE_EVT:
+        nfa_hci_api_add_static_pipe(p_evt_data);
+        break;
+#if (NXP_EXTNS == TRUE)
+      case NFA_HCI_API_CONFIGURE_EVT:
+        nfa_hci_handle_nfcee_config_evt(
+            p_evt_data->config_info.config_nfcee_event);
+        break;
+#endif
+      default:
+        NFA_TRACE_ERROR1("nfa_hci_check_api_requests ()  Unknown event: 0x%04x",
+                         p_msg->event);
+        break;
+    }
+
+    GKI_freebuf(p_msg);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_register
+**
+** Description      action function to register the events for the given AID
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_api_register(tNFA_HCI_EVENT_DATA* p_evt_data) {
+  tNFA_HCI_EVT_DATA evt_data;
+  char* p_app_name = p_evt_data->app_info.app_name;
+  tNFA_HCI_CBACK* p_cback = p_evt_data->app_info.p_cback;
+  int xx, yy;
+  uint8_t num_gates = 0, num_pipes = 0;
+  tNFA_HCI_DYN_GATE* pg = nfa_hci_cb.cfg.dyn_gates;
+
+  /* First, see if the application was already registered */
+  for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) {
+    if ((nfa_hci_cb.cfg.reg_app_names[xx][0] != 0) &&
+        !strncmp(p_app_name, &nfa_hci_cb.cfg.reg_app_names[xx][0],
+                 strlen(p_app_name))) {
+      NFA_TRACE_EVENT2("nfa_hci_api_register (%s)  Reusing: %u", p_app_name,
+                       xx);
+      break;
+    }
+  }
+
+  if (xx != NFA_HCI_MAX_APP_CB) {
+    nfa_hci_cb.app_in_use = (tNFA_HANDLE)(xx | NFA_HANDLE_GROUP_HCI);
+    /* The app was registered, find the number of gates and pipes associated to
+     * the app */
+
+    for (yy = 0; yy < NFA_HCI_MAX_GATE_CB; yy++, pg++) {
+      if (pg->gate_owner == nfa_hci_cb.app_in_use) {
+        num_gates++;
+        num_pipes += nfa_hciu_count_pipes_on_gate(pg);
+      }
+    }
+  } else {
+    /* Not registered, look for a free entry */
+    for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) {
+      if (nfa_hci_cb.cfg.reg_app_names[xx][0] == 0) {
+        memset(&nfa_hci_cb.cfg.reg_app_names[xx][0], 0,
+               sizeof(nfa_hci_cb.cfg.reg_app_names[xx]));
+        NQ_STRLCPY_S (&nfa_hci_cb.cfg.reg_app_names[xx][0], sizeof (nfa_hci_cb.cfg.reg_app_names[xx]), p_app_name,
+                NFA_MAX_HCI_APP_NAME_LEN);
+        nfa_hci_cb.nv_write_needed = true;
+        NFA_TRACE_EVENT2("nfa_hci_api_register (%s)  Allocated: %u", p_app_name,
+                         xx);
+        break;
+      }
+    }
+
+    if (xx == NFA_HCI_MAX_APP_CB) {
+      NFA_TRACE_ERROR1("nfa_hci_api_register (%s)  NO ENTRIES", p_app_name);
+
+      evt_data.hci_register.status = NFA_STATUS_FAILED;
+      p_evt_data->app_info.p_cback(NFA_HCI_REGISTER_EVT, &evt_data);
+      return;
+    }
+  }
+
+  evt_data.hci_register.num_pipes = num_pipes;
+  evt_data.hci_register.num_gates = num_gates;
+  nfa_hci_cb.p_app_cback[xx] = p_cback;
+
+  nfa_hci_cb.cfg.b_send_conn_evts[xx] = p_evt_data->app_info.b_send_conn_evts;
+
+  evt_data.hci_register.hci_handle = (tNFA_HANDLE)(xx | NFA_HANDLE_GROUP_HCI);
+
+  evt_data.hci_register.status = NFA_STATUS_OK;
+
+  /* notify NFA_HCI_REGISTER_EVT to the application */
+  p_evt_data->app_info.p_cback(NFA_HCI_REGISTER_EVT, &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_deregister
+**
+** Description      action function to deregister the given application
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hci_api_deregister(tNFA_HCI_EVENT_DATA* p_evt_data) {
+  tNFA_HCI_EVT_DATA evt_data;
+  tNFA_HCI_CBACK* p_cback = NULL;
+  int xx;
+  tNFA_HCI_DYN_PIPE* p_pipe;
+  tNFA_HCI_DYN_GATE* p_gate;
+
+  /* If needed, find the application registration handle */
+  if (p_evt_data != NULL) {
+    for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) {
+      if ((nfa_hci_cb.cfg.reg_app_names[xx][0] != 0) &&
+          !strncmp(p_evt_data->app_info.app_name,
+                   &nfa_hci_cb.cfg.reg_app_names[xx][0],
+                   strlen(p_evt_data->app_info.app_name))) {
+        NFA_TRACE_EVENT2("nfa_hci_api_deregister (%s) inx: %u",
+                         p_evt_data->app_info.app_name, xx);
+        break;
+      }
+    }
+
+    if (xx == NFA_HCI_MAX_APP_CB) {
+      NFA_TRACE_WARNING1("nfa_hci_api_deregister () Unknown app: %s",
+                         p_evt_data->app_info.app_name);
+      return;
+    }
+    nfa_hci_cb.app_in_use = (tNFA_HANDLE)(xx | NFA_HANDLE_GROUP_HCI);
+    p_cback = nfa_hci_cb.p_app_cback[xx];
+  } else {
+    nfa_sys_stop_timer(&nfa_hci_cb.timer);
+    /* We are recursing through deleting all the app's pipes and gates */
+    p_cback = nfa_hci_cb.p_app_cback[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK];
+  }
+
+  /* See if any pipe is owned by this app */
+  if (nfa_hciu_find_pipe_by_owner(nfa_hci_cb.app_in_use) == NULL) {
+    /* No pipes, release all gates owned by this app */
+    while ((p_gate = nfa_hciu_find_gate_by_owner(nfa_hci_cb.app_in_use)) !=
+           NULL)
+      nfa_hciu_release_gate(p_gate->gate_id);
+
+    memset(&nfa_hci_cb.cfg
+                .reg_app_names[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK][0],
+           0, NFA_MAX_HCI_APP_NAME_LEN + 1);
+    nfa_hci_cb.p_app_cback[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK] = NULL;
+
+    nfa_hci_cb.nv_write_needed = true;
+
+    evt_data.hci_deregister.status = NFC_STATUS_OK;
+
+    if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
+      nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+
+    /* notify NFA_HCI_DEREGISTER_EVT to the application */
+    if (p_cback) p_cback(NFA_HCI_DEREGISTER_EVT, &evt_data);
+  } else if ((p_pipe = nfa_hciu_find_active_pipe_by_owner(
+                  nfa_hci_cb.app_in_use)) == NULL) {
+    /* No pipes, release all gates owned by this app */
+    while ((p_gate = nfa_hciu_find_gate_with_nopipes_by_owner(
+                nfa_hci_cb.app_in_use)) != NULL)
+      nfa_hciu_release_gate(p_gate->gate_id);
+
+    nfa_hci_cb.p_app_cback[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK] = NULL;
+
+    nfa_hci_cb.nv_write_needed = true;
+
+    evt_data.hci_deregister.status = NFC_STATUS_FAILED;
+
+    if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
+      nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+
+    /* notify NFA_HCI_DEREGISTER_EVT to the application */
+    if (p_cback) p_cback(NFA_HCI_DEREGISTER_EVT, &evt_data);
+  } else {
+    /* Delete all active pipes created for the application before de registering
+    **/
+    nfa_hci_cb.hci_state = NFA_HCI_STATE_APP_DEREGISTER;
+
+    nfa_hciu_send_delete_pipe_cmd(p_pipe->pipe_id);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_get_gate_pipe_list
+**
+** Description      action function to get application allocated gates and
+**                  application created pipes
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_api_get_gate_pipe_list(tNFA_HCI_EVENT_DATA* p_evt_data) {
+  tNFA_HCI_EVT_DATA evt_data;
+  int xx, yy;
+  tNFA_HCI_DYN_GATE* pg = nfa_hci_cb.cfg.dyn_gates;
+  tNFA_HCI_DYN_PIPE* pp = nfa_hci_cb.cfg.dyn_pipes;
+
+  evt_data.gates_pipes.num_gates = 0;
+  evt_data.gates_pipes.num_pipes = 0;
+
+  for (xx = 0; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++) {
+    if (pg->gate_owner == p_evt_data->get_gate_pipe_list.hci_handle) {
+      evt_data.gates_pipes.gate[evt_data.gates_pipes.num_gates++] = pg->gate_id;
+
+      pp = nfa_hci_cb.cfg.dyn_pipes;
+
+      /* Loop through looking for a match */
+      for (yy = 0; yy < NFA_HCI_MAX_PIPE_CB; yy++, pp++) {
+        if (pp->local_gate == pg->gate_id)
+          evt_data.gates_pipes.pipe[evt_data.gates_pipes.num_pipes++] =
+              *(tNFA_HCI_PIPE_INFO*)pp;
+      }
+    }
+  }
+
+  evt_data.gates_pipes.num_uicc_created_pipes = 0;
+  /* Loop through all pipes that are connected to connectivity gate */
+  for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
+       xx++, pp++) {
+    if (pp->pipe_id != 0 && pp->local_gate == NFA_HCI_CONNECTIVITY_GATE) {
+      memcpy(&evt_data.gates_pipes.uicc_created_pipe
+                  [evt_data.gates_pipes.num_uicc_created_pipes++],
+             pp, sizeof(tNFA_HCI_PIPE_INFO));
+    } else if (pp->pipe_id != 0 && pp->local_gate == NFA_HCI_LOOP_BACK_GATE) {
+      memcpy(&evt_data.gates_pipes.uicc_created_pipe
+                  [evt_data.gates_pipes.num_uicc_created_pipes++],
+             pp, sizeof(tNFA_HCI_PIPE_INFO));
+    } else if (pp->pipe_id >= NFA_HCI_FIRST_DYNAMIC_PIPE &&
+               pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE && pp->pipe_id &&
+               pp->local_gate >= NFA_HCI_FIRST_PROP_GATE &&
+               pp->local_gate <= NFA_HCI_LAST_PROP_GATE) {
+      for (xx = 0, pg = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB;
+           xx++, pg++) {
+        if (pp->local_gate == pg->gate_id) {
+          if (!pg->gate_owner)
+            memcpy(&evt_data.gates_pipes.uicc_created_pipe
+                        [evt_data.gates_pipes.num_uicc_created_pipes++],
+                   pp, sizeof(tNFA_HCI_PIPE_INFO));
+          break;
+        }
+      }
+    }
+  }
+
+  evt_data.gates_pipes.status = NFA_STATUS_OK;
+
+  /* notify NFA_HCI_GET_GATE_PIPE_LIST_EVT to the application */
+  nfa_hciu_send_to_app(NFA_HCI_GET_GATE_PIPE_LIST_EVT, &evt_data,
+                       p_evt_data->get_gate_pipe_list.hci_handle);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_alloc_gate
+**
+** Description      action function to allocate gate
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_api_alloc_gate(tNFA_HCI_EVENT_DATA* p_evt_data) {
+  tNFA_HANDLE app_handle = p_evt_data->comm.hci_handle;
+  tNFA_HCI_EVT_DATA evt_data;
+  tNFA_HCI_DYN_GATE* p_gate;
+
+  p_gate = nfa_hciu_alloc_gate(p_evt_data->gate_info.gate, app_handle);
+
+  if (p_gate) {
+    if (!p_gate->gate_owner) {
+      /* No app owns the gate yet */
+      p_gate->gate_owner = app_handle;
+    } else if (p_gate->gate_owner != app_handle) {
+      /* Some other app owns the gate */
+      p_gate = NULL;
+      NFA_TRACE_ERROR1(
+          "nfa_hci_api_alloc_gate (): The Gate (0X%02x) already taken!",
+          p_evt_data->gate_info.gate);
+    }
+  }
+
+  evt_data.allocated.gate = p_gate ? p_gate->gate_id : 0;
+  evt_data.allocated.status = p_gate ? NFA_STATUS_OK : NFA_STATUS_FAILED;
+
+  /* notify NFA_HCI_ALLOCATE_GATE_EVT to the application */
+  nfa_hciu_send_to_app(NFA_HCI_ALLOCATE_GATE_EVT, &evt_data, app_handle);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_dealloc_gate
+**
+** Description      action function to deallocate the given generic gate
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hci_api_dealloc_gate(tNFA_HCI_EVENT_DATA* p_evt_data) {
+  tNFA_HCI_EVT_DATA evt_data;
+  uint8_t gate_id;
+  tNFA_HCI_DYN_GATE* p_gate;
+  tNFA_HCI_DYN_PIPE* p_pipe;
+  tNFA_HANDLE app_handle;
+
+  /* p_evt_data may be NULL if we are recursively deleting pipes */
+  if (p_evt_data) {
+    gate_id = p_evt_data->gate_dealloc.gate;
+    app_handle = p_evt_data->gate_dealloc.hci_handle;
+
+  } else {
+    nfa_sys_stop_timer(&nfa_hci_cb.timer);
+    gate_id = nfa_hci_cb.local_gate_in_use;
+    app_handle = nfa_hci_cb.app_in_use;
+  }
+
+  evt_data.deallocated.gate = gate_id;
+  ;
+
+  p_gate = nfa_hciu_find_gate_by_gid(gate_id);
+
+  if (p_gate == NULL) {
+    evt_data.deallocated.status = NFA_STATUS_UNKNOWN_GID;
+  } else if (p_gate->gate_owner != app_handle) {
+    evt_data.deallocated.status = NFA_STATUS_FAILED;
+  } else {
+    /* See if any pipe is owned by this app */
+    if (nfa_hciu_find_pipe_on_gate(p_gate->gate_id) == NULL) {
+      nfa_hciu_release_gate(p_gate->gate_id);
+
+      nfa_hci_cb.nv_write_needed = true;
+      evt_data.deallocated.status = NFA_STATUS_OK;
+
+      if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
+        nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+    } else if ((p_pipe = nfa_hciu_find_active_pipe_on_gate(p_gate->gate_id)) ==
+               NULL) {
+      /* UICC is not active at the moment and cannot delete the pipe */
+      nfa_hci_cb.nv_write_needed = true;
+      evt_data.deallocated.status = NFA_STATUS_FAILED;
+
+      if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
+        nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+    } else {
+      /* Delete pipes on the gate */
+      nfa_hci_cb.local_gate_in_use = gate_id;
+      nfa_hci_cb.app_in_use = app_handle;
+      nfa_hci_cb.hci_state = NFA_HCI_STATE_REMOVE_GATE;
+
+      nfa_hciu_send_delete_pipe_cmd(p_pipe->pipe_id);
+      return;
+    }
+  }
+
+  nfa_hciu_send_to_app(NFA_HCI_DEALLOCATE_GATE_EVT, &evt_data, app_handle);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_get_host_list
+**
+** Description      action function to get the host list from HCI network
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_api_get_host_list(tNFA_HCI_EVENT_DATA* p_evt_data) {
+  uint8_t app_inx = p_evt_data->get_host_list.hci_handle & NFA_HANDLE_MASK;
+
+  nfa_hci_cb.app_in_use = p_evt_data->get_host_list.hci_handle;
+
+  /* Send Get Host List command on "Internal request" or requested by registered
+   * application with valid handle and callback function */
+  if ((nfa_hci_cb.app_in_use == NFA_HANDLE_INVALID) ||
+      ((app_inx < NFA_HCI_MAX_APP_CB) &&
+       (nfa_hci_cb.p_app_cback[app_inx] != NULL))) {
+    nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE, NFA_HCI_HOST_LIST_INDEX);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_create_pipe
+**
+** Description      action function to create a pipe
+**
+** Returns          true, if the command is processed
+**                  false, if command is queued for processing later
+**
+*******************************************************************************/
+static bool nfa_hci_api_create_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) {
+  tNFA_HCI_DYN_GATE* p_gate =
+      nfa_hciu_find_gate_by_gid(p_evt_data->create_pipe.source_gate);
+  tNFA_HCI_EVT_DATA evt_data;
+  bool report_failed = false;
+
+  /* Verify that the app owns the gate that the pipe is being created on */
+  if ((p_gate == NULL) ||
+      (p_gate->gate_owner != p_evt_data->create_pipe.hci_handle)) {
+    report_failed = true;
+    NFA_TRACE_ERROR2(
+        "nfa_hci_api_create_pipe Cannot create pipe! APP: 0x%02x does not own "
+        "the gate:0x%x",
+        p_evt_data->create_pipe.hci_handle,
+        p_evt_data->create_pipe.source_gate);
+  } else if (nfa_hciu_check_pipe_between_gates(
+                 p_evt_data->create_pipe.source_gate,
+                 p_evt_data->create_pipe.dest_host,
+                 p_evt_data->create_pipe.dest_gate)) {
+    report_failed = true;
+    NFA_TRACE_ERROR0(
+        "nfa_hci_api_create_pipe : Cannot create multiple pipe between the "
+        "same two gates!");
+  }
+
+  if (report_failed) {
+    evt_data.created.source_gate = p_evt_data->create_pipe.source_gate;
+    evt_data.created.status = NFA_STATUS_FAILED;
+
+    nfa_hciu_send_to_app(NFA_HCI_CREATE_PIPE_EVT, &evt_data,
+                         p_evt_data->open_pipe.hci_handle);
+  } else {
+    if (nfa_hciu_is_host_reseting(p_evt_data->create_pipe.dest_gate)) {
+      GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data);
+      return false;
+    }
+
+    nfa_hci_cb.local_gate_in_use = p_evt_data->create_pipe.source_gate;
+    nfa_hci_cb.remote_gate_in_use = p_evt_data->create_pipe.dest_gate;
+    nfa_hci_cb.remote_host_in_use = p_evt_data->create_pipe.dest_host;
+    nfa_hci_cb.app_in_use = p_evt_data->create_pipe.hci_handle;
+
+    nfa_hciu_send_create_pipe_cmd(p_evt_data->create_pipe.source_gate,
+                                  p_evt_data->create_pipe.dest_host,
+                                  p_evt_data->create_pipe.dest_gate);
+  }
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_open_pipe
+**
+** Description      action function to open a pipe
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_api_open_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) {
+  tNFA_HCI_EVT_DATA evt_data;
+  tNFA_HCI_DYN_PIPE* p_pipe =
+      nfa_hciu_find_pipe_by_pid(p_evt_data->open_pipe.pipe);
+  tNFA_HCI_DYN_GATE* p_gate = NULL;
+
+  if (p_pipe != NULL) p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
+
+  if ((p_pipe != NULL) && (p_gate != NULL) &&
+      (nfa_hciu_is_active_host(p_pipe->dest_host)) &&
+      (p_gate->gate_owner == p_evt_data->open_pipe.hci_handle)) {
+    if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED) {
+      nfa_hciu_send_open_pipe_cmd(p_evt_data->open_pipe.pipe);
+    } else {
+      evt_data.opened.pipe = p_evt_data->open_pipe.pipe;
+      evt_data.opened.status = NFA_STATUS_OK;
+
+      nfa_hciu_send_to_app(NFA_HCI_OPEN_PIPE_EVT, &evt_data,
+                           p_evt_data->open_pipe.hci_handle);
+    }
+  } else {
+    evt_data.opened.pipe = p_evt_data->open_pipe.pipe;
+    evt_data.opened.status = NFA_STATUS_FAILED;
+
+    nfa_hciu_send_to_app(NFA_HCI_OPEN_PIPE_EVT, &evt_data,
+                         p_evt_data->open_pipe.hci_handle);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_get_reg_value
+**
+** Description      action function to get the reg value of the specified index
+**
+** Returns          true, if the command is processed
+**                  false, if command is queued for processing later
+**
+*******************************************************************************/
+static bool nfa_hci_api_get_reg_value(tNFA_HCI_EVENT_DATA* p_evt_data) {
+  tNFA_HCI_DYN_PIPE* p_pipe =
+      nfa_hciu_find_pipe_by_pid(p_evt_data->get_registry.pipe);
+  tNFA_HCI_DYN_GATE* p_gate;
+  tNFA_STATUS status = NFA_STATUS_FAILED;
+  tNFA_HCI_EVT_DATA evt_data;
+
+  if (p_pipe != NULL) {
+    p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
+
+    if ((p_gate != NULL) && (nfa_hciu_is_active_host(p_pipe->dest_host)) &&
+        (p_gate->gate_owner == p_evt_data->get_registry.hci_handle)) {
+      nfa_hci_cb.app_in_use = p_evt_data->get_registry.hci_handle;
+
+      if (nfa_hciu_is_host_reseting(p_pipe->dest_host)) {
+        GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data);
+        return false;
+      }
+
+      if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED) {
+        NFA_TRACE_WARNING1("nfa_hci_api_get_reg_value pipe:%d not open",
+                           p_evt_data->get_registry.pipe);
+      } else {
+        status = nfa_hciu_send_get_param_cmd(p_evt_data->get_registry.pipe,
+                                             p_evt_data->get_registry.reg_inx);
+        if (status == NFA_STATUS_OK) return true;
+      }
+    }
+  }
+
+  evt_data.cmd_sent.status = status;
+
+  /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
+  nfa_hciu_send_to_app(NFA_HCI_CMD_SENT_EVT, &evt_data,
+                       p_evt_data->get_registry.hci_handle);
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_set_reg_value
+**
+** Description      action function to set the reg value at specified index
+**
+** Returns          true, if the command is processed
+**                  false, if command is queued for processing later
+**
+*******************************************************************************/
+static bool nfa_hci_api_set_reg_value(tNFA_HCI_EVENT_DATA* p_evt_data) {
+  tNFA_HCI_DYN_PIPE* p_pipe =
+      nfa_hciu_find_pipe_by_pid(p_evt_data->set_registry.pipe);
+  tNFA_HCI_DYN_GATE* p_gate;
+  tNFA_STATUS status = NFA_STATUS_FAILED;
+  tNFA_HCI_EVT_DATA evt_data;
+
+  if (p_pipe != NULL) {
+    p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
+
+    if ((p_gate != NULL) && (nfa_hciu_is_active_host(p_pipe->dest_host)) &&
+        (p_gate->gate_owner == p_evt_data->set_registry.hci_handle)) {
+      nfa_hci_cb.app_in_use = p_evt_data->set_registry.hci_handle;
+
+      if (nfa_hciu_is_host_reseting(p_pipe->dest_host)) {
+        GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data);
+        return false;
+      }
+
+      if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED) {
+        NFA_TRACE_WARNING1("nfa_hci_api_set_reg_value pipe:%d not open",
+                           p_evt_data->set_registry.pipe);
+      } else {
+        status = nfa_hciu_send_set_param_cmd(
+            p_evt_data->set_registry.pipe, p_evt_data->set_registry.reg_inx,
+            p_evt_data->set_registry.size, p_evt_data->set_registry.data);
+        if (status == NFA_STATUS_OK) return true;
+      }
+    }
+  }
+  evt_data.cmd_sent.status = status;
+
+  /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
+  nfa_hciu_send_to_app(NFA_HCI_CMD_SENT_EVT, &evt_data,
+                       p_evt_data->set_registry.hci_handle);
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_close_pipe
+**
+** Description      action function to close a pipe
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_api_close_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) {
+  tNFA_HCI_EVT_DATA evt_data;
+  tNFA_HCI_DYN_PIPE* p_pipe =
+      nfa_hciu_find_pipe_by_pid(p_evt_data->close_pipe.pipe);
+  tNFA_HCI_DYN_GATE* p_gate = NULL;
+
+  if (p_pipe != NULL) p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
+
+  if ((p_pipe != NULL) && (p_gate != NULL) &&
+      (nfa_hciu_is_active_host(p_pipe->dest_host)) &&
+      (p_gate->gate_owner == p_evt_data->close_pipe.hci_handle)) {
+    if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) {
+      nfa_hciu_send_close_pipe_cmd(p_evt_data->close_pipe.pipe);
+    } else {
+      evt_data.closed.status = NFA_STATUS_OK;
+      evt_data.closed.pipe = p_evt_data->close_pipe.pipe;
+
+      nfa_hciu_send_to_app(NFA_HCI_CLOSE_PIPE_EVT, &evt_data,
+                           p_evt_data->close_pipe.hci_handle);
+    }
+  } else {
+    evt_data.closed.status = NFA_STATUS_FAILED;
+    evt_data.closed.pipe = 0x00;
+
+    nfa_hciu_send_to_app(NFA_HCI_CLOSE_PIPE_EVT, &evt_data,
+                         p_evt_data->close_pipe.hci_handle);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_delete_pipe
+**
+** Description      action function to delete a pipe
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_api_delete_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) {
+  tNFA_HCI_EVT_DATA evt_data;
+  tNFA_HCI_DYN_PIPE* p_pipe =
+      nfa_hciu_find_pipe_by_pid(p_evt_data->delete_pipe.pipe);
+  tNFA_HCI_DYN_GATE* p_gate = NULL;
+
+  if (p_pipe != NULL) {
+    p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
+    if ((p_gate != NULL) &&
+        (p_gate->gate_owner == p_evt_data->delete_pipe.hci_handle) &&
+        (nfa_hciu_is_active_host(p_pipe->dest_host))) {
+      nfa_hciu_send_delete_pipe_cmd(p_evt_data->delete_pipe.pipe);
+      return;
+    }
+  }
+
+  evt_data.deleted.status = NFA_STATUS_FAILED;
+  evt_data.deleted.pipe = 0x00;
+  nfa_hciu_send_to_app(NFA_HCI_DELETE_PIPE_EVT, &evt_data,
+                       p_evt_data->close_pipe.hci_handle);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_send_cmd
+**
+** Description      action function to send command on the given pipe
+**
+** Returns          true, if the command is processed
+**                  false, if command is queued for processing later
+**
+*******************************************************************************/
+static bool nfa_hci_api_send_cmd(tNFA_HCI_EVENT_DATA* p_evt_data) {
+  tNFA_STATUS status = NFA_STATUS_FAILED;
+  tNFA_HCI_DYN_PIPE* p_pipe;
+  tNFA_HCI_EVT_DATA evt_data;
+  tNFA_HANDLE app_handle;
+
+  if ((p_pipe = nfa_hciu_find_pipe_by_pid(p_evt_data->send_cmd.pipe)) != NULL) {
+    app_handle = nfa_hciu_get_pipe_owner(p_evt_data->send_cmd.pipe);
+
+    if ((nfa_hciu_is_active_host(p_pipe->dest_host)) &&
+        ((app_handle == p_evt_data->send_cmd.hci_handle ||
+          p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE))) {
+      if (nfa_hciu_is_host_reseting(p_pipe->dest_host)) {
+        GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data);
+        return false;
+      }
+
+      if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) {
+        nfa_hci_cb.pipe_in_use = p_evt_data->send_cmd.pipe;
+        status = nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_COMMAND_TYPE,
+                                   p_evt_data->send_cmd.cmd_code,
+                                   p_evt_data->send_cmd.cmd_len,
+                                   p_evt_data->send_cmd.data);
+        if (status == NFA_STATUS_OK) return true;
+      } else {
+        NFA_TRACE_WARNING1("nfa_hci_api_send_cmd pipe:%d not open",
+                           p_pipe->pipe_id);
+      }
+    } else {
+      NFA_TRACE_WARNING1(
+          "nfa_hci_api_send_cmd pipe:%d Owned by different application or "
+          "Destination host is not active",
+          p_pipe->pipe_id);
+    }
+  } else {
+    NFA_TRACE_WARNING1("nfa_hci_api_send_cmd pipe:%d not found",
+                       p_evt_data->send_cmd.pipe);
+  }
+
+  evt_data.cmd_sent.status = status;
+
+  /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
+  nfa_hciu_send_to_app(NFA_HCI_CMD_SENT_EVT, &evt_data,
+                       p_evt_data->send_cmd.hci_handle);
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_send_rsp
+**
+** Description      action function to send response on the given pipe
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_api_send_rsp(tNFA_HCI_EVENT_DATA* p_evt_data) {
+  tNFA_STATUS status = NFA_STATUS_FAILED;
+  tNFA_HCI_DYN_PIPE* p_pipe;
+  tNFA_HCI_EVT_DATA evt_data;
+  tNFA_HANDLE app_handle;
+
+  if ((p_pipe = nfa_hciu_find_pipe_by_pid(p_evt_data->send_rsp.pipe)) != NULL) {
+    app_handle = nfa_hciu_get_pipe_owner(p_evt_data->send_rsp.pipe);
+
+    if ((nfa_hciu_is_active_host(p_pipe->dest_host)) &&
+        ((app_handle == p_evt_data->send_rsp.hci_handle ||
+          p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE))) {
+      if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) {
+        status = nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE,
+                                   p_evt_data->send_rsp.response,
+                                   p_evt_data->send_rsp.size,
+                                   p_evt_data->send_rsp.data);
+        if (status == NFA_STATUS_OK) return;
+      } else {
+        NFA_TRACE_WARNING1("nfa_hci_api_send_rsp pipe:%d not open",
+                           p_pipe->pipe_id);
+      }
+    } else {
+      NFA_TRACE_WARNING1(
+          "nfa_hci_api_send_rsp pipe:%d Owned by different application or "
+          "Destination host is not active",
+          p_pipe->pipe_id);
+    }
+  } else {
+    NFA_TRACE_WARNING1("nfa_hci_api_send_rsp pipe:%d not found",
+                       p_evt_data->send_rsp.pipe);
+  }
+
+  evt_data.rsp_sent.status = status;
+
+  /* Send NFA_HCI_RSP_SENT_EVT to notify failure */
+  nfa_hciu_send_to_app(NFA_HCI_RSP_SENT_EVT, &evt_data,
+                       p_evt_data->send_rsp.hci_handle);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_send_event
+**
+** Description      action function to send an event to the given pipe
+**
+** Returns          true, if the event is processed
+**                  false, if event is queued for processing later
+**
+*******************************************************************************/
+static bool nfa_hci_api_send_event(tNFA_HCI_EVENT_DATA* p_evt_data) {
+  tNFA_STATUS status = NFA_STATUS_FAILED;
+  tNFA_HCI_DYN_PIPE* p_pipe;
+  tNFA_HCI_EVT_DATA evt_data;
+  tNFA_HANDLE app_handle;
+
+  if ((p_pipe = nfa_hciu_find_pipe_by_pid(p_evt_data->send_evt.pipe)) != NULL) {
+    app_handle = nfa_hciu_get_pipe_owner(p_evt_data->send_evt.pipe);
+
+    if ((nfa_hciu_is_active_host(p_pipe->dest_host)) &&
+        ((app_handle == p_evt_data->send_evt.hci_handle ||
+          p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE))) {
+      if (nfa_hciu_is_host_reseting(p_pipe->dest_host)) {
+        GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data);
+        return false;
+      }
+
+      if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) {
+        status = nfa_hciu_send_msg(
+            p_pipe->pipe_id, NFA_HCI_EVENT_TYPE, p_evt_data->send_evt.evt_code,
+            p_evt_data->send_evt.evt_len, p_evt_data->send_evt.p_evt_buf);
+
+        if (status == NFA_STATUS_OK) {
+          if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) {
+            nfa_hci_cb.w4_rsp_evt = true;
+            nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_RSP;
+          }
+
+          if (p_evt_data->send_evt.rsp_len) {
+            nfa_hci_cb.pipe_in_use = p_evt_data->send_evt.pipe;
+            nfa_hci_cb.rsp_buf_size = p_evt_data->send_evt.rsp_len;
+            nfa_hci_cb.p_rsp_buf = p_evt_data->send_evt.p_rsp_buf;
+            if (p_evt_data->send_evt.rsp_timeout) {
+              nfa_hci_cb.w4_rsp_evt = true;
+              nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_RSP;
+#if (NXP_EXTNS == TRUE)
+              nfa_hci_cb.hciResponseTimeout = p_evt_data->send_evt.rsp_timeout;
+#endif
+              nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
+                                  p_evt_data->send_evt.rsp_timeout);
+            } else if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) {
+              nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
+                                  p_nfa_hci_cfg->hcp_response_timeout);
+            }
+          } else {
+            if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) {
+              nfa_hci_cb.pipe_in_use = p_evt_data->send_evt.pipe;
+              nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
+                                  p_nfa_hci_cfg->hcp_response_timeout);
+            }
+            nfa_hci_cb.rsp_buf_size = 0;
+            nfa_hci_cb.p_rsp_buf = NULL;
+          }
+        }
+      } else {
+        NFA_TRACE_WARNING1("nfa_hci_api_send_event pipe:%d not open",
+                           p_pipe->pipe_id);
+      }
+    } else {
+      NFA_TRACE_WARNING1(
+          "nfa_hci_api_send_event pipe:%d Owned by different application or "
+          "Destination host is not active",
+          p_pipe->pipe_id);
+    }
+  } else {
+    NFA_TRACE_WARNING1("nfa_hci_api_send_event pipe:%d not found",
+                       p_evt_data->send_evt.pipe);
+  }
+
+  evt_data.evt_sent.status = status;
+
+  /* Send NFC_HCI_EVENT_SENT_EVT to notify status */
+  nfa_hciu_send_to_app(NFA_HCI_EVENT_SENT_EVT, &evt_data,
+                       p_evt_data->send_evt.hci_handle);
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_add_static_pipe
+**
+** Description      action function to add static pipe
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_api_add_static_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) {
+  tNFA_HCI_DYN_GATE* pg;
+  tNFA_HCI_DYN_PIPE* pp;
+  tNFA_HCI_EVT_DATA evt_data;
+
+  /* Allocate a proprietary gate */
+  pg = nfa_hciu_alloc_gate(p_evt_data->add_static_pipe.gate,
+                           p_evt_data->add_static_pipe.hci_handle);
+  if (pg != NULL) {
+    /* Assign new owner to the gate */
+    pg->gate_owner = p_evt_data->add_static_pipe.hci_handle;
+
+    /* Add the dynamic pipe to the proprietary gate */
+    if (nfa_hciu_add_pipe_to_gate(p_evt_data->add_static_pipe.pipe, pg->gate_id,
+                                  p_evt_data->add_static_pipe.host,
+                                  p_evt_data->add_static_pipe.gate) !=
+        NFA_HCI_ANY_OK) {
+      /* Unable to add the dynamic pipe, so release the gate */
+      nfa_hciu_release_gate(pg->gate_id);
+      evt_data.pipe_added.status = NFA_STATUS_FAILED;
+      nfa_hciu_send_to_app(NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data,
+                           p_evt_data->add_static_pipe.hci_handle);
+      return;
+    }
+    pp = nfa_hciu_find_pipe_by_pid(p_evt_data->add_static_pipe.pipe);
+    if (pp != NULL) {
+      /* This pipe is always opened */
+      pp->pipe_state = NFA_HCI_PIPE_OPENED;
+      evt_data.pipe_added.status = NFA_STATUS_OK;
+      nfa_hciu_send_to_app(NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data,
+                           p_evt_data->add_static_pipe.hci_handle);
+      return;
+    }
+  }
+  /* Unable to add static pipe */
+  evt_data.pipe_added.status = NFA_STATUS_FAILED;
+  nfa_hciu_send_to_app(NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data,
+                       p_evt_data->add_static_pipe.hci_handle);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_link_mgm_gate_cmd
+**
+** Description      This function handles incoming link management gate hci
+**                  commands
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_hci_handle_link_mgm_gate_cmd(uint8_t* p_data) {
+  uint8_t index;
+  uint8_t data[2];
+  uint8_t rsp_len = 0;
+  uint8_t response = NFA_HCI_ANY_OK;
+
+  if ((nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state != NFA_HCI_PIPE_OPENED) &&
+      (nfa_hci_cb.inst != NFA_HCI_ANY_OPEN_PIPE)) {
+    nfa_hciu_send_msg(NFA_HCI_LINK_MANAGEMENT_PIPE, NFA_HCI_RESPONSE_TYPE,
+                      NFA_HCI_ANY_E_PIPE_NOT_OPENED, 0, NULL);
+    return;
+  }
+
+  switch (nfa_hci_cb.inst) {
+    case NFA_HCI_ANY_SET_PARAMETER:
+      STREAM_TO_UINT8(index, p_data);
+
+      if (index == 1) {
+        STREAM_TO_UINT16(nfa_hci_cb.cfg.link_mgmt_gate.rec_errors, p_data);
+      } else
+        response = NFA_HCI_ANY_E_REG_PAR_UNKNOWN;
+      break;
+
+    case NFA_HCI_ANY_GET_PARAMETER:
+      STREAM_TO_UINT8(index, p_data);
+      if (index == 1) {
+        data[0] =
+            (uint8_t)((nfa_hci_cb.cfg.link_mgmt_gate.rec_errors >> 8) & 0x00FF);
+        data[1] = (uint8_t)(nfa_hci_cb.cfg.link_mgmt_gate.rec_errors & 0x000F);
+        rsp_len = 2;
+      } else
+        response = NFA_HCI_ANY_E_REG_PAR_UNKNOWN;
+      break;
+
+    case NFA_HCI_ANY_OPEN_PIPE:
+      data[0] = 0;
+      rsp_len = 1;
+      nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_OPENED;
+      break;
+
+    case NFA_HCI_ANY_CLOSE_PIPE:
+      nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
+      break;
+
+    default:
+      response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
+      break;
+  }
+
+  nfa_hciu_send_msg(NFA_HCI_LINK_MANAGEMENT_PIPE, NFA_HCI_RESPONSE_TYPE,
+                    response, rsp_len, data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_pipe_open_close_cmd
+**
+** Description      This function handles all generic gates (excluding
+**                  connectivity gate) commands
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_hci_handle_pipe_open_close_cmd(tNFA_HCI_DYN_PIPE* p_pipe) {
+  uint8_t data[1];
+  uint8_t rsp_len = 0;
+  tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
+  tNFA_HCI_DYN_GATE* p_gate;
+
+  if (nfa_hci_cb.inst == NFA_HCI_ANY_OPEN_PIPE) {
+    if ((p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate)) != NULL)
+      data[0] = nfa_hciu_count_open_pipes_on_gate(p_gate);
+    else
+      data[0] = 0;
+
+    p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
+    rsp_len = 1;
+  } else if (nfa_hci_cb.inst == NFA_HCI_ANY_CLOSE_PIPE) {
+    p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
+  }
+#if (NXP_EXTNS == TRUE)
+  nfa_hci_cb.nv_write_needed = true;
+#endif
+  nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len,
+                    data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_admin_gate_cmd
+**
+** Description      This function handles incoming commands on ADMIN gate
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_hci_handle_admin_gate_cmd(uint8_t* p_data) {
+  uint8_t source_host, source_gate, dest_host, dest_gate, pipe;
+  uint8_t data = 0;
+  uint8_t rsp_len = 0;
+  tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
+  tNFA_HCI_DYN_GATE* pgate;
+  tNFA_HCI_EVT_DATA evt_data;
+
+  switch (nfa_hci_cb.inst) {
+    case NFA_HCI_ANY_OPEN_PIPE:
+      nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_OPENED;
+      data = 0;
+      rsp_len = 1;
+      break;
+
+    case NFA_HCI_ANY_CLOSE_PIPE:
+      nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
+      /* Reopen the pipe immediately */
+      nfa_hciu_send_msg(NFA_HCI_ADMIN_PIPE, NFA_HCI_RESPONSE_TYPE, response,
+                        rsp_len, &data);
+      nfa_hci_cb.app_in_use = NFA_HANDLE_INVALID;
+      nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
+      return;
+      break;
+
+    case NFA_HCI_ADM_NOTIFY_PIPE_CREATED:
+      STREAM_TO_UINT8(source_host, p_data);
+      STREAM_TO_UINT8(source_gate, p_data);
+      STREAM_TO_UINT8(dest_host, p_data);
+      STREAM_TO_UINT8(dest_gate, p_data);
+      STREAM_TO_UINT8(pipe, p_data);
+
+      if ((dest_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE) ||
+          (dest_gate == NFA_HCI_LOOP_BACK_GATE)
+#if (NXP_EXTNS == TRUE)
+          || ((nfcFL.nfccFL._GEMALTO_SE_SUPPORT) && ((dest_gate == NFC_HCI_DEFAULT_DEST_GATE) ||
+          (dest_gate == NFA_HCI_CONNECTIVITY_GATE)))
+#endif
+              )
+#if (NXP_EXTNS == TRUE)
+          if(nfcFL.eseFL._BLOCK_PROPRIETARY_APDU_GATE) {
+              if (dest_gate == NFC_HCI_DEFAULT_DEST_GATE) {
+                  response = NFA_HCI_ANY_E_NOK;
+              } else {
+                  response = nfa_hciu_add_pipe_to_static_gate(dest_gate, pipe,
+                          source_host, source_gate);
+              }
+          }
+          else{
+              response = nfa_hciu_add_pipe_to_static_gate(dest_gate, pipe,
+                      source_host, source_gate);
+          }
+#else
+    response = nfa_hciu_add_pipe_to_static_gate(dest_gate, pipe,
+            source_host, source_gate);
+#endif
+      else {
+        if ((pgate = nfa_hciu_find_gate_by_gid(dest_gate)) != NULL) {
+          /* If the gate is valid, add the pipe to it  */
+          if (nfa_hciu_check_pipe_between_gates(dest_gate, source_host,
+                                                source_gate)) {
+            /* Already, there is a pipe between these two gates, so will reject
+             */
+            response = NFA_HCI_ANY_E_NOK;
+          } else {
+            response = nfa_hciu_add_pipe_to_gate(pipe, dest_gate, source_host,
+                                                 source_gate);
+            if (response == NFA_HCI_ANY_OK) {
+              /* Tell the application a pipe was created with its gate */
+
+              evt_data.created.status = NFA_STATUS_OK;
+              evt_data.created.pipe = pipe;
+              evt_data.created.source_gate = dest_gate;
+              evt_data.created.dest_host = source_host;
+              evt_data.created.dest_gate = source_gate;
+
+              nfa_hciu_send_to_app(NFA_HCI_CREATE_PIPE_EVT, &evt_data,
+                                   pgate->gate_owner);
+            }
+          }
+        } else {
+          response = NFA_HCI_ANY_E_NOK;
+          if ((dest_gate >= NFA_HCI_FIRST_PROP_GATE) &&
+              (dest_gate <= NFA_HCI_LAST_PROP_GATE)) {
+            if (nfa_hciu_alloc_gate(dest_gate, 0))
+              response = nfa_hciu_add_pipe_to_gate(pipe, dest_gate, source_host,
+                                                   source_gate);
+          }
+        }
+      }
+      break;
+
+    case NFA_HCI_ADM_NOTIFY_PIPE_DELETED:
+      STREAM_TO_UINT8(pipe, p_data);
+      response = nfa_hciu_release_pipe(pipe);
+      break;
+
+    case NFA_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED:
+      STREAM_TO_UINT8(source_host, p_data);
+
+      nfa_hciu_remove_all_pipes_from_host(source_host);
+
+      if (source_host == NFA_HCI_HOST_CONTROLLER) {
+        nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
+        nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
+
+        /* Reopen the admin pipe immediately */
+        nfa_hci_cb.app_in_use = NFA_HANDLE_INVALID;
+        nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
+        return;
+      } else {
+        if ((source_host >= NFA_HCI_HOST_ID_UICC0) &&
+            (source_host <
+             (NFA_HCI_HOST_ID_UICC0 + NFA_HCI_MAX_HOST_IN_NETWORK))) {
+          nfa_hci_cb.reset_host[source_host - NFA_HCI_HOST_ID_UICC0] =
+              source_host;
+        }
+#if (NXP_EXTNS == TRUE)
+        nfa_hciu_send_msg(NFA_HCI_ADMIN_PIPE, NFA_HCI_RESPONSE_TYPE, response,
+                          rsp_len, &data);
+        nfa_hciu_set_nfceeid_config_mask(NFA_HCI_CLEAR_CONFIG_EVENT,
+                                         source_host);
+        nfa_hciu_set_nfceeid_poll_mask(NFA_HCI_CLEAR_CONFIG_EVENT, source_host);
+        if (nfa_hci_cb.nfcee_cfg.nfc_init_state == false)
+          nfa_hci_handle_nfcee_config_evt(NFA_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED);
+        return;
+#endif
+      }
+      break;
+
+    default:
+      response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
+      break;
+  }
+
+  nfa_hciu_send_msg(NFA_HCI_ADMIN_PIPE, NFA_HCI_RESPONSE_TYPE, response,
+                    rsp_len, &data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_admin_gate_rsp
+**
+** Description      This function handles response received on admin gate
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_hci_handle_admin_gate_rsp(uint8_t* p_data, uint8_t data_len) {
+  uint8_t source_host;
+  uint8_t source_gate = nfa_hci_cb.local_gate_in_use;
+  uint8_t dest_host = nfa_hci_cb.remote_host_in_use;
+  uint8_t dest_gate = nfa_hci_cb.remote_gate_in_use;
+  uint8_t pipe = 0;
+  tNFA_STATUS status;
+  tNFA_HCI_EVT_DATA evt_data;
+  uint8_t default_session[NFA_HCI_SESSION_ID_LEN] = {0xFF, 0xFF, 0xFF, 0xFF,
+                                                     0xFF, 0xFF, 0xFF, 0xFF};
+  uint8_t host_count = 0;
+  uint8_t host_id = 0;
+  uint32_t os_tick;
+#if (NXP_EXTNS == TRUE)
+  // Terminal Host Type as ETSI12  Byte1 -Host Id Byte2 - 00
+  uint8_t terminal_host_type[NFA_HCI_HOST_TYPE_LEN] = {0x01, 0x00};
+  uint8_t count = 0;
+#endif
+
+#if (BT_TRACE_VERBOSE == true)
+  NFA_TRACE_DEBUG4(
+      "nfa_hci_handle_admin_gate_rsp - LastCmdSent: %s  App: 0x%04x  Gate: "
+      "0x%02x  Pipe: 0x%02x",
+      nfa_hciu_instr_2_str(nfa_hci_cb.cmd_sent), nfa_hci_cb.app_in_use,
+      nfa_hci_cb.local_gate_in_use, nfa_hci_cb.pipe_in_use);
+#else
+  NFA_TRACE_DEBUG4(
+      "nfa_hci_handle_admin_gate_rsp LastCmdSent: %u  App: 0x%04x  Gate: "
+      "0x%02x  Pipe: 0x%02x",
+      nfa_hci_cb.cmd_sent, nfa_hci_cb.app_in_use, nfa_hci_cb.local_gate_in_use,
+      nfa_hci_cb.pipe_in_use);
+#endif
+
+  /* If starting up, handle events here */
+  if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) ||
+      (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE) ||
+      (nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
+      (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
+    if (nfa_hci_cb.inst == NFA_HCI_ANY_E_PIPE_NOT_OPENED) {
+      nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
+      return;
+    }
+
+    if (nfa_hci_cb.inst != NFA_HCI_ANY_OK) {
+#if (NXP_EXTNS == TRUE)
+      if (nfa_hci_cb.param_in_use == NFA_HCI_HOST_TYPE_INDEX) {
+        if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_GET_PARAMETER) {
+          NFA_TRACE_DEBUG0(
+              "nfa_hci_handle_admin_gate_rsp - HCI Controller is ETSI 9 !!!");
+          // Set a variable to set ETSI version of HCI Controller
+          nfa_hci_cb.host_controller_version = NFA_HCI_CONTROLLER_VERSION_9;
+        }
+      } else {
+        NFA_TRACE_ERROR0(
+            "nfa_hci_handle_admin_gate_rsp - Initialization failed");
+        nfa_hci_startup_complete(NFA_STATUS_FAILED);
+        return;
+      }
+#else
+      NFA_TRACE_ERROR0("nfa_hci_handle_admin_gate_rsp - Initialization failed");
+      nfa_hci_startup_complete(NFA_STATUS_FAILED);
+      return;
+#endif
+    }
+
+    switch (nfa_hci_cb.cmd_sent) {
+      case NFA_HCI_ANY_SET_PARAMETER:
+#if (NXP_EXTNS != TRUE)
+        if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX) {
+          /* Set WHITELIST */
+          nfa_hciu_send_set_param_cmd(
+              NFA_HCI_ADMIN_PIPE, NFA_HCI_WHITELIST_INDEX,
+              p_nfa_hci_cfg->num_whitelist_host, p_nfa_hci_cfg->p_whitelist);
+        } else if (nfa_hci_cb.param_in_use == NFA_HCI_WHITELIST_INDEX) {
+          if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) ||
+              (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE))
+            nfa_hci_dh_startup_complete();
+        }
+#else
+        if (nfa_hci_cb.param_in_use == NFA_HCI_WHITELIST_INDEX) {
+          NFA_TRACE_DEBUG0(
+              "nfa_hci_handle_admin_gate_rsp - Set the HOST_TYPE as per ETSI "
+              "12 !!!");
+          /* Set the HOST_TYPE as per ETSI 12 */
+          nfa_hciu_send_set_param_cmd(
+              NFA_HCI_ADMIN_PIPE, NFA_HCI_HOST_TYPE_INDEX,
+              NFA_HCI_HOST_TYPE_LEN, terminal_host_type);
+          return;
+        }
+
+        if (nfa_hci_cb.param_in_use == NFA_HCI_HOST_TYPE_INDEX) {
+          if (nfa_hci_cb.inst == NFA_HCI_ANY_OK) {
+            NFA_TRACE_DEBUG0(
+                "nfa_hci_handle_admin_gate_rsp - HCI Controller is ETSI 12 "
+                "!!!");
+            // Set a variable  to set ETSI version of HCI Controller
+            nfa_hci_cb.host_controller_version = NFA_HCI_CONTROLLER_VERSION_12;
+          }
+          if (nfa_hci_cb.b_hci_netwk_reset) {
+            nfa_hci_cb.b_hci_netwk_reset = false;
+            /* Session ID is reset, Set New session id */
+            memcpy(&nfa_hci_cb.cfg.admin_gate
+                        .session_id[NFA_HCI_SESSION_ID_LEN / 2],
+                   nfa_hci_cb.cfg.admin_gate.session_id,
+                   (NFA_HCI_SESSION_ID_LEN / 2));
+            os_tick = GKI_get_os_tick_count();
+            memcpy(nfa_hci_cb.cfg.admin_gate.session_id, (uint8_t*)&os_tick,
+                   (NFA_HCI_SESSION_ID_LEN / 2));
+            nfa_hciu_send_set_param_cmd(
+                NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX,
+                NFA_HCI_SESSION_ID_LEN,
+                (uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id);
+          } else {
+            /* First thing is to get the session ID */
+            nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
+                                        NFA_HCI_SESSION_IDENTITY_INDEX);
+          }
+        } else if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX) {
+            nfa_hci_network_enable();
+          if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) ||
+              (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE))
+          {
+            if(NFA_GetNCIVersion() == NCI_VERSION_2_0)
+            {
+                NFA_EeGetInfo(&nfa_hci_cb.num_nfcee, nfa_hci_cb.ee_info);
+                nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_NETWK_ENABLE;
+                nfa_hci_cb.w4_nfcee_enable = true;
+                nfa_hci_enable_one_nfcee();
+            }
+            else
+            {
+                nfa_hci_dh_startup_complete();
+            }
+          }
+        }
+#endif
+        break;
+
+      case NFA_HCI_ANY_GET_PARAMETER:
+        if (nfa_hci_cb.param_in_use == NFA_HCI_HOST_LIST_INDEX) {
+          host_count = 0;
+          while (host_count < NFA_HCI_MAX_HOST_IN_NETWORK) {
+            nfa_hci_cb.inactive_host[host_count] =
+                NFA_HCI_HOST_ID_UICC0 + host_count;
+            host_count++;
+          }
+          host_count = 0;
+          /* Collect active host in the Host Network */
+          while (host_count < data_len) {
+            host_id = (uint8_t)*p_data++;
+            if ((host_id >= NFA_HCI_HOST_ID_UICC0) &&
+                (host_id <
+                 NFA_HCI_HOST_ID_UICC0 + NFA_HCI_MAX_HOST_IN_NETWORK)) {
+              nfa_hci_cb.inactive_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00;
+              nfa_hci_cb.reset_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00;
+            }
+            host_count++;
+          }
+            nfa_hci_startup_complete(NFA_STATUS_OK);
+        } else if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX) {
+          /* The only parameter we get when initializing is the session ID.
+           * Check for match. */
+          if (!memcmp((uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id, p_data,
+                      NFA_HCI_SESSION_ID_LEN)) {
+#if (NXP_EXTNS == TRUE)
+            nfa_hci_network_enable();
+            NFA_EeGetInfo(&nfa_hci_cb.num_nfcee, nfa_hci_cb.ee_info);
+            if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) ||
+                (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE))
+            {
+              if(NFA_GetNCIVersion() == NCI_VERSION_2_0)
+              {
+                  nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_NETWK_ENABLE;
+                  nfa_hci_cb.w4_nfcee_enable = true;
+                  nfa_hci_enable_one_nfcee();
+              }
+              else
+              {
+                  nfa_hci_dh_startup_complete();
+              }
+            }
+#else
+            /* Session has not changed, Set WHITELIST */
+            nfa_hciu_send_set_param_cmd(
+                NFA_HCI_ADMIN_PIPE, NFA_HCI_WHITELIST_INDEX,
+                p_nfa_hci_cfg->num_whitelist_host, p_nfa_hci_cfg->p_whitelist);
+#endif
+          } else {
+#if (NXP_EXTNS == TRUE)
+            /* Session ID is reset, Set New session id */
+            memcpy(&nfa_hci_cb.cfg.admin_gate
+                        .session_id[NFA_HCI_SESSION_ID_LEN / 2],
+                   nfa_hci_cb.cfg.admin_gate.session_id,
+                   (NFA_HCI_SESSION_ID_LEN / 2));
+            os_tick = GKI_get_os_tick_count();
+            memcpy(nfa_hci_cb.cfg.admin_gate.session_id, (uint8_t*)&os_tick,
+                   (NFA_HCI_SESSION_ID_LEN / 2));
+            nfa_hciu_send_set_param_cmd(
+                NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX,
+                NFA_HCI_SESSION_ID_LEN,
+                (uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id);
+#else
+            /* Something wrong, NVRAM data could be corrupt or first start with
+             * default session id */
+            nfa_hciu_send_clear_all_pipe_cmd();
+            nfa_hci_cb.b_hci_netwk_reset = true;
+#endif
+          }
+        }
+        break;
+      case NFA_HCI_ANY_OPEN_PIPE:
+        nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_OPENED;
+
+#if (NXP_EXTNS != TRUE)
+        if (nfa_hci_cb.b_hci_netwk_reset) {
+          nfa_hci_cb.b_hci_netwk_reset = false;
+          /* Session ID is reset, Set New session id */
+          memcpy(
+              &nfa_hci_cb.cfg.admin_gate.session_id[NFA_HCI_SESSION_ID_LEN / 2],
+              nfa_hci_cb.cfg.admin_gate.session_id,
+              (NFA_HCI_SESSION_ID_LEN / 2));
+          os_tick = GKI_get_os_tick_count();
+          memcpy(nfa_hci_cb.cfg.admin_gate.session_id, (uint8_t*)&os_tick,
+                 (NFA_HCI_SESSION_ID_LEN / 2));
+          nfa_hciu_send_set_param_cmd(
+              NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX,
+              NFA_HCI_SESSION_ID_LEN,
+              (uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id);
+        } else {
+          /* First thing is to get the session ID */
+          nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
+                                      NFA_HCI_SESSION_IDENTITY_INDEX);
+        }
+#else
+        nfa_hciu_send_set_param_cmd(NFA_HCI_ADMIN_PIPE, NFA_HCI_WHITELIST_INDEX,
+                                    p_nfa_hci_cfg->num_whitelist_host,
+                                    p_nfa_hci_cfg->p_whitelist);
+#endif
+        break;
+
+      case NFA_HCI_ADM_CLEAR_ALL_PIPE:
+        nfa_hciu_remove_all_pipes_from_host(0);
+        nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
+        nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
+        nfa_hci_cb.nv_write_needed = true;
+
+        /* Open admin */
+        nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
+        break;
+    }
+  }
+#if (NXP_EXTNS == TRUE)
+  else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_NFCEE_ENABLE) {
+    nfa_hci_handle_Nfcee_admpipe_rsp(p_data, data_len);
+  }
+#endif
+  else {
+    status =
+        (nfa_hci_cb.inst == NFA_HCI_ANY_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED;
+
+    switch (nfa_hci_cb.cmd_sent) {
+      case NFA_HCI_ANY_SET_PARAMETER:
+        if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
+          nfa_hci_api_deregister(NULL);
+        else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
+          nfa_hci_api_dealloc_gate(NULL);
+        break;
+
+      case NFA_HCI_ANY_GET_PARAMETER:
+        if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX) {
+          if (!memcmp((uint8_t*)default_session, p_data,
+                      NFA_HCI_SESSION_ID_LEN)) {
+            memcpy(&nfa_hci_cb.cfg.admin_gate
+                        .session_id[(NFA_HCI_SESSION_ID_LEN / 2)],
+                   nfa_hci_cb.cfg.admin_gate.session_id,
+                   (NFA_HCI_SESSION_ID_LEN / 2));
+            os_tick = GKI_get_os_tick_count();
+            memcpy(nfa_hci_cb.cfg.admin_gate.session_id, (uint8_t*)&os_tick,
+                   (NFA_HCI_SESSION_ID_LEN / 2));
+            nfa_hci_cb.nv_write_needed = true;
+            nfa_hciu_send_set_param_cmd(
+                NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX,
+                NFA_HCI_SESSION_ID_LEN,
+                (uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id);
+          } else {
+            if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
+              nfa_hci_api_deregister(NULL);
+            else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
+              nfa_hci_api_dealloc_gate(NULL);
+          }
+        } else if (nfa_hci_cb.param_in_use == NFA_HCI_HOST_LIST_INDEX) {
+          evt_data.hosts.status = status;
+          evt_data.hosts.num_hosts = data_len;
+          memcpy(evt_data.hosts.host, p_data, data_len);
+
+          host_count = 0;
+          while (host_count < NFA_HCI_MAX_HOST_IN_NETWORK) {
+            nfa_hci_cb.inactive_host[host_count] =
+                NFA_HCI_HOST_ID_UICC0 + host_count;
+            host_count++;
+          }
+
+          host_count = 0;
+          /* Collect active host in the Host Network */
+          while (host_count < data_len) {
+            host_id = (uint8_t)*p_data++;
+
+            if ((host_id >= NFA_HCI_HOST_ID_UICC0) &&
+                (host_id <
+                 NFA_HCI_HOST_ID_UICC0 + NFA_HCI_MAX_HOST_IN_NETWORK)) {
+              nfa_hci_cb.inactive_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00;
+              nfa_hci_cb.reset_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00;
+            }
+            host_count++;
+          }
+
+          if (nfa_hciu_is_no_host_resetting())
+            nfa_hci_check_pending_api_requests();
+          nfa_hciu_send_to_app(NFA_HCI_HOST_LIST_EVT, &evt_data,
+                               nfa_hci_cb.app_in_use);
+        }
+        break;
+
+      case NFA_HCI_ADM_CREATE_PIPE:
+        if (status == NFA_STATUS_OK) {
+          STREAM_TO_UINT8(source_host, p_data);
+          STREAM_TO_UINT8(source_gate, p_data);
+          STREAM_TO_UINT8(dest_host, p_data);
+          STREAM_TO_UINT8(dest_gate, p_data);
+          STREAM_TO_UINT8(pipe, p_data);
+          /* Sanity check */
+          if (source_gate != nfa_hci_cb.local_gate_in_use) {
+            NFA_TRACE_WARNING2(
+                "nfa_hci_handle_admin_gate_rsp sent create pipe with gate: %u "
+                "got back: %u",
+                nfa_hci_cb.local_gate_in_use, source_gate);
+            break;
+          }
+          nfa_hciu_add_pipe_to_gate(pipe, source_gate, dest_host, dest_gate);
+        }
+        /* Tell the application his pipe was created or not */
+        evt_data.created.status = status;
+        evt_data.created.pipe = pipe;
+        evt_data.created.source_gate = source_gate;
+        evt_data.created.dest_host = dest_host;
+        evt_data.created.dest_gate = dest_gate;
+
+        nfa_hciu_send_to_app(NFA_HCI_CREATE_PIPE_EVT, &evt_data,
+                             nfa_hci_cb.app_in_use);
+        break;
+
+      case NFA_HCI_ADM_DELETE_PIPE:
+        if (status == NFA_STATUS_OK) {
+          nfa_hciu_release_pipe(nfa_hci_cb.pipe_in_use);
+
+          /* If only deleting one pipe, tell the app we are done */
+          if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) {
+            evt_data.deleted.status = status;
+            evt_data.deleted.pipe = nfa_hci_cb.pipe_in_use;
+
+            nfa_hciu_send_to_app(NFA_HCI_DELETE_PIPE_EVT, &evt_data,
+                                 nfa_hci_cb.app_in_use);
+          } else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
+            nfa_hci_api_deregister(NULL);
+          else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
+            nfa_hci_api_dealloc_gate(NULL);
+        } else {
+          /* If only deleting one pipe, tell the app we are done */
+          if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) {
+            evt_data.deleted.status = status;
+            evt_data.deleted.pipe = nfa_hci_cb.pipe_in_use;
+
+            nfa_hciu_send_to_app(NFA_HCI_DELETE_PIPE_EVT, &evt_data,
+                                 nfa_hci_cb.app_in_use);
+          } else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER) {
+            nfa_hciu_release_pipe(nfa_hci_cb.pipe_in_use);
+            nfa_hci_api_deregister(NULL);
+          } else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE) {
+            nfa_hciu_release_pipe(nfa_hci_cb.pipe_in_use);
+            nfa_hci_api_dealloc_gate(NULL);
+          }
+        }
+        break;
+
+      case NFA_HCI_ANY_OPEN_PIPE:
+        nfa_hci_cb.cfg.admin_gate.pipe01_state =
+            status ? NFA_HCI_PIPE_CLOSED : NFA_HCI_PIPE_OPENED;
+        nfa_hci_cb.nv_write_needed = true;
+        if (nfa_hci_cb.cfg.admin_gate.pipe01_state == NFA_HCI_PIPE_OPENED) {
+          /* First thing is to get the session ID */
+          nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
+                                      NFA_HCI_SESSION_IDENTITY_INDEX);
+        }
+        break;
+
+      case NFA_HCI_ADM_CLEAR_ALL_PIPE:
+        nfa_hciu_remove_all_pipes_from_host(0);
+        nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
+        nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
+        nfa_hci_cb.nv_write_needed = true;
+        /* Open admin */
+        nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
+        break;
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_admin_gate_evt
+**
+** Description      This function handles events received on admin gate
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_hci_handle_admin_gate_evt(uint8_t* p_data) {
+  tNFA_HCI_EVT_DATA evt_data;
+  tNFA_HCI_API_GET_HOST_LIST* p_msg;
+  (void)p_data;
+  if (nfa_hci_cb.inst != NFA_HCI_EVT_HOT_PLUG) {
+    NFA_TRACE_ERROR0(
+        "nfa_hci_handle_admin_gate_evt - Unknown event on ADMIN Pipe");
+    return;
+  }
+
+  NFA_TRACE_DEBUG0(
+      "nfa_hci_handle_admin_gate_evt - HOT PLUG EVT event on ADMIN Pipe");
+  nfa_hci_cb.num_hot_plug_evts++;
+
+  if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
+      (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
+    /* Received Hot Plug evt while waiting for other Host in the network to
+     * bootup after DH host bootup is complete */
+    if ((nfa_hci_cb.ee_disable_disc) &&
+        (nfa_hci_cb.num_hot_plug_evts == (nfa_hci_cb.num_nfcee - 1)) &&
+        (nfa_hci_cb.num_ee_dis_req_ntf < (nfa_hci_cb.num_nfcee - 1))) {
+      /* Received expected number of Hot Plug event(s) before as many number of
+       * EE DISC REQ Ntf(s) are received */
+      nfa_sys_stop_timer(&nfa_hci_cb.timer);
+      /* Received HOT PLUG EVT(s), now wait some more time for EE DISC REQ
+       * Ntf(s) */
+      nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
+                          p_nfa_hci_cfg->hci_netwk_enable_timeout);
+    }
+  } else if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) ||
+             (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE)) {
+    /* Received Hot Plug evt during DH host bootup */
+    if ((nfa_hci_cb.ee_disable_disc) &&
+        (nfa_hci_cb.num_hot_plug_evts == (nfa_hci_cb.num_nfcee - 1)) &&
+        (nfa_hci_cb.num_ee_dis_req_ntf < (nfa_hci_cb.num_nfcee - 1))) {
+      /* Received expected number of Hot Plug event(s) before as many number of
+       * EE DISC REQ Ntf(s) are received */
+      nfa_hci_cb.w4_hci_netwk_init = false;
+    }
+  } else {
+    /* Received Hot Plug evt on UICC self reset */
+    evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
+    /* Notify all registered application with the HOT_PLUG_EVT */
+    nfa_hciu_send_to_all_apps(NFA_HCI_EVENT_RCVD_EVT, &evt_data);
+
+    /* Send Get Host List after receiving any pending response */
+    p_msg = (tNFA_HCI_API_GET_HOST_LIST*)GKI_getbuf(
+        sizeof(tNFA_HCI_API_GET_HOST_LIST));
+    if (p_msg != NULL) {
+      p_msg->hdr.event = NFA_HCI_API_GET_HOST_LIST_EVT;
+      /* Set Invalid handle to identify this Get Host List command is internal
+       */
+      p_msg->hci_handle = NFA_HANDLE_INVALID;
+
+      nfa_sys_sendmsg(p_msg);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_dyn_pipe_pkt
+**
+** Description      This function handles data received via dynamic pipe
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_hci_handle_dyn_pipe_pkt(uint8_t pipe_id, uint8_t* p_data,
+                                 uint16_t data_len) {
+  tNFA_HCI_DYN_PIPE* p_pipe = nfa_hciu_find_pipe_by_pid(pipe_id);
+  tNFA_HCI_DYN_GATE* p_gate;
+  tNFA_HCI_EVT_DATA  evt_data;
+
+  if (p_pipe == NULL) {
+    /* Invalid pipe ID */
+    NFA_TRACE_ERROR1("nfa_hci_handle_dyn_pipe_pkt - Unknown pipe %d", pipe_id);
+    if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
+      nfa_hciu_send_msg(pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_NOK, 0,
+                        NULL);
+#if(NXP_EXTNS == TRUE)
+    if(nfa_hci_cb.hci_state == NFA_HCI_STATE_NFCEE_ENABLE){
+      nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+      evt_data.config_rsp_rcvd.status = NFA_STATUS_FAILED;
+      /*Notify failure*/
+      nfa_hciu_send_to_all_apps(NFA_HCI_CONFIG_DONE_EVT, &evt_data);
+    }
+#endif
+    return;
+  }
+#if (NXP_EXTNS == TRUE)
+  if (nfa_hci_cb.hci_state == NFA_HCI_STATE_NFCEE_ENABLE) {
+    nfa_hci_handle_Nfcee_dynpipe_rsp(pipe_id, p_data, data_len);
+  }
+#endif
+  if (p_pipe->local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE) {
+    nfa_hci_handle_identity_mgmt_gate_pkt(p_data, p_pipe);
+  } else if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) {
+    nfa_hci_handle_loopback_gate_pkt(p_data, data_len, p_pipe);
+  } else if (p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE) {
+    nfa_hci_handle_connectivity_gate_pkt(p_data, data_len, p_pipe);
+  }
+#if (NXP_EXTNS == TRUE)
+  else if ((nfcFL.nfccFL._GEMALTO_SE_SUPPORT) &&
+          (p_pipe->local_gate == NFC_HCI_DEFAULT_DEST_GATE)) {
+    /* Check if data packet is a command, response or event */
+    p_gate = nfa_hci_cb.cfg.dyn_gates;
+    p_gate->gate_owner = 0x0800;
+
+    switch (nfa_hci_cb.type) {
+      case NFA_HCI_COMMAND_TYPE:
+        nfa_hci_handle_generic_gate_cmd(p_data, (uint8_t)data_len, p_gate,
+                                        p_pipe);
+        break;
+
+      case NFA_HCI_RESPONSE_TYPE:
+        nfa_hci_handle_generic_gate_rsp(p_data, (uint8_t)data_len, p_gate,
+                                        p_pipe);
+        break;
+
+      case NFA_HCI_EVENT_TYPE:
+        nfa_hci_handle_generic_gate_evt(p_data, data_len, p_gate, p_pipe);
+        break;
+    }
+  }
+#endif
+  else {
+    p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
+    if (p_gate == NULL) {
+      NFA_TRACE_ERROR1(
+          "nfa_hci_handle_dyn_pipe_pkt - Pipe's gate %d is corrupt",
+          p_pipe->local_gate);
+      if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
+        nfa_hciu_send_msg(pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_NOK, 0,
+                          NULL);
+      return;
+    }
+    /* Check if data packet is a command, response or event */
+    switch (nfa_hci_cb.type) {
+      case NFA_HCI_COMMAND_TYPE:
+        nfa_hci_handle_generic_gate_cmd(p_data, (uint8_t)data_len, p_gate,
+                                        p_pipe);
+        break;
+
+      case NFA_HCI_RESPONSE_TYPE:
+        nfa_hci_handle_generic_gate_rsp(p_data, (uint8_t)data_len, p_gate,
+                                        p_pipe);
+        break;
+
+      case NFA_HCI_EVENT_TYPE:
+        nfa_hci_handle_generic_gate_evt(p_data, data_len, p_gate, p_pipe);
+        break;
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_identity_mgmt_gate_pkt
+**
+** Description      This function handles incoming Identity Management gate hci
+**                  commands
+**
+** Returns          none
+**
+*******************************************************************************/
+static void nfa_hci_handle_identity_mgmt_gate_pkt(uint8_t* p_data,
+                                                  tNFA_HCI_DYN_PIPE* p_pipe) {
+  uint8_t data[20];
+  uint8_t index;
+  uint8_t gate_rsp[3 + NFA_HCI_MAX_GATE_CB], num_gates;
+  uint16_t rsp_len = 0;
+  uint8_t* p_rsp = data;
+  tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
+
+  /* We never send commands on a pipe where the local gate is the identity
+   * management
+   * gate, so only commands should be processed.
+   */
+  if (nfa_hci_cb.type != NFA_HCI_COMMAND_TYPE) return;
+
+  switch (nfa_hci_cb.inst) {
+    case NFA_HCI_ANY_GET_PARAMETER:
+      index = *(p_data++);
+      if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) {
+        switch (index) {
+          case NFA_HCI_VERSION_SW_INDEX:
+            data[0] = (uint8_t)((NFA_HCI_VERSION_SW >> 16) & 0xFF);
+            data[1] = (uint8_t)((NFA_HCI_VERSION_SW >> 8) & 0xFF);
+            data[2] = (uint8_t)((NFA_HCI_VERSION_SW)&0xFF);
+            rsp_len = 3;
+            break;
+
+          case NFA_HCI_HCI_VERSION_INDEX:
+            data[0] = NFA_HCI_VERSION;
+            rsp_len = 1;
+            break;
+
+          case NFA_HCI_VERSION_HW_INDEX:
+            data[0] = (uint8_t)((NFA_HCI_VERSION_HW >> 16) & 0xFF);
+            data[1] = (uint8_t)((NFA_HCI_VERSION_HW >> 8) & 0xFF);
+            data[2] = (uint8_t)((NFA_HCI_VERSION_HW)&0xFF);
+            rsp_len = 3;
+            break;
+
+          case NFA_HCI_VENDOR_NAME_INDEX:
+            memcpy(data, NFA_HCI_VENDOR_NAME, strlen(NFA_HCI_VENDOR_NAME));
+            rsp_len = (uint8_t)strlen(NFA_HCI_VENDOR_NAME);
+            break;
+
+          case NFA_HCI_MODEL_ID_INDEX:
+            data[0] = NFA_HCI_MODEL_ID;
+            rsp_len = 1;
+            break;
+
+          case NFA_HCI_GATES_LIST_INDEX:
+            gate_rsp[0] = NFA_HCI_LOOP_BACK_GATE;
+            gate_rsp[1] = NFA_HCI_IDENTITY_MANAGEMENT_GATE;
+            gate_rsp[2] = NFA_HCI_CONNECTIVITY_GATE;
+            num_gates = nfa_hciu_get_allocated_gate_list(&gate_rsp[3]);
+            rsp_len = num_gates + 3;
+            p_rsp = gate_rsp;
+            break;
+
+          default:
+            response = NFA_HCI_ANY_E_NOK;
+            break;
+        }
+      } else {
+        response = NFA_HCI_ANY_E_PIPE_NOT_OPENED;
+      }
+      break;
+
+    case NFA_HCI_ANY_OPEN_PIPE:
+      data[0] = 0;
+      rsp_len = 1;
+      p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
+      break;
+
+    case NFA_HCI_ANY_CLOSE_PIPE:
+      p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
+      break;
+
+    default:
+      response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
+      break;
+  }
+
+  nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len,
+                    p_rsp);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_generic_gate_cmd
+**
+** Description      This function handles all generic gates (excluding
+**                  connectivity gate) commands
+**
+** Returns          none
+**
+*******************************************************************************/
+static void nfa_hci_handle_generic_gate_cmd(uint8_t* p_data, uint8_t data_len,
+                                            tNFA_HCI_DYN_GATE* p_gate,
+                                            tNFA_HCI_DYN_PIPE* p_pipe) {
+  tNFA_HCI_EVT_DATA evt_data;
+  tNFA_HANDLE app_handle = nfa_hciu_get_pipe_owner(p_pipe->pipe_id);
+  (void)p_gate;
+
+  switch (nfa_hci_cb.inst) {
+    case NFA_HCI_ANY_SET_PARAMETER:
+      evt_data.registry.pipe = p_pipe->pipe_id;
+      evt_data.registry.index = *p_data++;
+      if (data_len > 0) data_len--;
+      evt_data.registry.data_len = data_len;
+
+      memcpy(evt_data.registry.reg_data, p_data, data_len);
+
+      nfa_hciu_send_to_app(NFA_HCI_SET_REG_CMD_EVT, &evt_data, app_handle);
+      break;
+
+    case NFA_HCI_ANY_GET_PARAMETER:
+      evt_data.registry.pipe = p_pipe->pipe_id;
+      evt_data.registry.index = *p_data;
+      evt_data.registry.data_len = 0;
+
+      nfa_hciu_send_to_app(NFA_HCI_GET_REG_CMD_EVT, &evt_data, app_handle);
+      break;
+
+    case NFA_HCI_ANY_OPEN_PIPE:
+      nfa_hci_handle_pipe_open_close_cmd(p_pipe);
+
+      evt_data.opened.pipe = p_pipe->pipe_id;
+      evt_data.opened.status = NFA_STATUS_OK;
+
+      nfa_hciu_send_to_app(NFA_HCI_OPEN_PIPE_EVT, &evt_data, app_handle);
+      break;
+
+    case NFA_HCI_ANY_CLOSE_PIPE:
+      nfa_hci_handle_pipe_open_close_cmd(p_pipe);
+
+      evt_data.closed.pipe = p_pipe->pipe_id;
+      evt_data.opened.status = NFA_STATUS_OK;
+
+      nfa_hciu_send_to_app(NFA_HCI_CLOSE_PIPE_EVT, &evt_data, app_handle);
+      break;
+
+    default:
+      /* Could be application specific command, pass it on */
+      evt_data.cmd_rcvd.status = NFA_STATUS_OK;
+      evt_data.cmd_rcvd.pipe = p_pipe->pipe_id;
+      ;
+      evt_data.cmd_rcvd.cmd_code = nfa_hci_cb.inst;
+      evt_data.cmd_rcvd.cmd_len = data_len;
+
+      if (data_len <= NFA_MAX_HCI_CMD_LEN)
+        memcpy(evt_data.cmd_rcvd.cmd_data, p_data, data_len);
+
+      nfa_hciu_send_to_app(NFA_HCI_CMD_RCVD_EVT, &evt_data, app_handle);
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_generic_gate_rsp
+**
+** Description      This function handles all generic gates (excluding
+**                  connectivity) response
+**
+** Returns          none
+**
+*******************************************************************************/
+static void nfa_hci_handle_generic_gate_rsp(uint8_t* p_data, uint8_t data_len,
+                                            tNFA_HCI_DYN_GATE* p_gate,
+                                            tNFA_HCI_DYN_PIPE* p_pipe) {
+  tNFA_HCI_EVT_DATA evt_data;
+  tNFA_STATUS status = NFA_STATUS_OK;
+  (void)p_gate;
+
+  if (nfa_hci_cb.inst != NFA_HCI_ANY_OK) status = NFA_STATUS_FAILED;
+
+  if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) {
+    if (status == NFA_STATUS_OK) p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
+
+    nfa_hci_cb.nv_write_needed = true;
+    /* Tell application */
+    evt_data.opened.status = status;
+    evt_data.opened.pipe = p_pipe->pipe_id;
+
+    nfa_hciu_send_to_app(NFA_HCI_OPEN_PIPE_EVT, &evt_data,
+                         nfa_hci_cb.app_in_use);
+  } else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE) {
+    p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
+
+    nfa_hci_cb.nv_write_needed = true;
+    /* Tell application */
+    evt_data.opened.status = status;
+    ;
+    evt_data.opened.pipe = p_pipe->pipe_id;
+
+    nfa_hciu_send_to_app(NFA_HCI_CLOSE_PIPE_EVT, &evt_data,
+                         nfa_hci_cb.app_in_use);
+  } else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_GET_PARAMETER) {
+    /* Tell application */
+    evt_data.registry.status = status;
+    evt_data.registry.pipe = p_pipe->pipe_id;
+    evt_data.registry.data_len = data_len;
+    evt_data.registry.index = nfa_hci_cb.param_in_use;
+
+    memcpy(evt_data.registry.reg_data, p_data, data_len);
+
+    nfa_hciu_send_to_app(NFA_HCI_GET_REG_RSP_EVT, &evt_data,
+                         nfa_hci_cb.app_in_use);
+  } else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_SET_PARAMETER) {
+    /* Tell application */
+    evt_data.registry.status = status;
+    ;
+    evt_data.registry.pipe = p_pipe->pipe_id;
+
+    nfa_hciu_send_to_app(NFA_HCI_SET_REG_RSP_EVT, &evt_data,
+                         nfa_hci_cb.app_in_use);
+  } else {
+    /* Could be a response to application specific command sent, pass it on */
+    evt_data.rsp_rcvd.status = NFA_STATUS_OK;
+    evt_data.rsp_rcvd.pipe = p_pipe->pipe_id;
+    ;
+    evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
+    evt_data.rsp_rcvd.rsp_len = data_len;
+
+    if (data_len <= NFA_MAX_HCI_RSP_LEN)
+      memcpy(evt_data.rsp_rcvd.rsp_data, p_data, data_len);
+
+    nfa_hciu_send_to_app(NFA_HCI_RSP_RCVD_EVT, &evt_data,
+                         nfa_hci_cb.app_in_use);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_connectivity_gate_pkt
+**
+** Description      This function handles incoming connectivity gate packets
+**
+** Returns          none
+**
+*******************************************************************************/
+static void nfa_hci_handle_connectivity_gate_pkt(uint8_t* p_data,
+                                                 uint16_t data_len,
+                                                 tNFA_HCI_DYN_PIPE* p_pipe) {
+  tNFA_HCI_EVT_DATA evt_data;
+
+  if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) {
+    switch (nfa_hci_cb.inst) {
+      case NFA_HCI_ANY_OPEN_PIPE:
+      case NFA_HCI_ANY_CLOSE_PIPE:
+        nfa_hci_handle_pipe_open_close_cmd(p_pipe);
+        break;
+
+      case NFA_HCI_CON_PRO_HOST_REQUEST:
+        /* A request to the DH to activate another host. This is not supported
+         * for */
+        /* now, we will implement it when the spec is clearer and UICCs need it.
+         */
+        nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE,
+                          NFA_HCI_ANY_E_CMD_NOT_SUPPORTED, 0, NULL);
+        break;
+
+      default:
+        nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE,
+                          NFA_HCI_ANY_E_CMD_NOT_SUPPORTED, 0, NULL);
+        break;
+    }
+  } else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) {
+    if ((nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) &&
+        (nfa_hci_cb.inst == NFA_HCI_ANY_OK))
+      p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
+    else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE)
+      p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
+
+    /* Could be a response to application specific command sent, pass it on */
+    evt_data.rsp_rcvd.status = NFA_STATUS_OK;
+    evt_data.rsp_rcvd.pipe = p_pipe->pipe_id;
+    ;
+    evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
+    evt_data.rsp_rcvd.rsp_len = data_len;
+
+    if (data_len <= NFA_MAX_HCI_RSP_LEN)
+      memcpy(evt_data.rsp_rcvd.rsp_data, p_data, data_len);
+
+    nfa_hciu_send_to_app(NFA_HCI_RSP_RCVD_EVT, &evt_data,
+                         nfa_hci_cb.app_in_use);
+  } else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE) {
+    evt_data.rcvd_evt.pipe = p_pipe->pipe_id;
+    evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
+    evt_data.rcvd_evt.evt_len = data_len;
+    evt_data.rcvd_evt.p_evt_buf = p_data;
+
+    /* notify NFA_HCI_EVENT_RCVD_EVT to the application */
+    nfa_hciu_send_to_apps_handling_connectivity_evts(NFA_HCI_EVENT_RCVD_EVT,
+                                                     &evt_data);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_loopback_gate_pkt
+**
+** Description      This function handles incoming loopback gate hci events
+**
+** Returns          none
+**
+*******************************************************************************/
+static void nfa_hci_handle_loopback_gate_pkt(uint8_t* p_data, uint16_t data_len,
+                                             tNFA_HCI_DYN_PIPE* p_pipe) {
+  uint8_t data[1];
+  uint8_t rsp_len = 0;
+  tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
+  tNFA_HCI_EVT_DATA evt_data;
+
+  /* Check if data packet is a command, response or event */
+  if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) {
+    if (nfa_hci_cb.inst == NFA_HCI_ANY_OPEN_PIPE) {
+      data[0] = 0;
+      rsp_len = 1;
+      p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
+    } else if (nfa_hci_cb.inst == NFA_HCI_ANY_CLOSE_PIPE) {
+      p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
+    } else
+      response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
+
+    nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len,
+                      data);
+  } else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) {
+    if ((nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) &&
+        (nfa_hci_cb.inst == NFA_HCI_ANY_OK))
+      p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
+    else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE)
+      p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
+
+    /* Could be a response to application specific command sent, pass it on */
+    evt_data.rsp_rcvd.status = NFA_STATUS_OK;
+    evt_data.rsp_rcvd.pipe = p_pipe->pipe_id;
+    ;
+    evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
+    evt_data.rsp_rcvd.rsp_len = data_len;
+
+    if (data_len <= NFA_MAX_HCI_RSP_LEN)
+      memcpy(evt_data.rsp_rcvd.rsp_data, p_data, data_len);
+
+    nfa_hciu_send_to_app(NFA_HCI_RSP_RCVD_EVT, &evt_data,
+                         nfa_hci_cb.app_in_use);
+  } else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE) {
+    if (nfa_hci_cb.w4_rsp_evt) {
+      evt_data.rcvd_evt.pipe = p_pipe->pipe_id;
+      evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
+      evt_data.rcvd_evt.evt_len = data_len;
+      evt_data.rcvd_evt.p_evt_buf = p_data;
+
+      nfa_hciu_send_to_app(NFA_HCI_EVENT_RCVD_EVT, &evt_data,
+                           nfa_hci_cb.app_in_use);
+    } else if (nfa_hci_cb.inst == NFA_HCI_EVT_POST_DATA) {
+      /* Send back the same data we got */
+      nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_EVENT_TYPE,
+                        NFA_HCI_EVT_POST_DATA, data_len, p_data);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_generic_gate_evt
+**
+** Description      This function handles incoming Generic gate hci events
+**
+** Returns          none
+**
+*******************************************************************************/
+static void nfa_hci_handle_generic_gate_evt(uint8_t* p_data, uint16_t data_len,
+                                            tNFA_HCI_DYN_GATE* p_gate,
+                                            tNFA_HCI_DYN_PIPE* p_pipe) {
+  tNFA_HCI_EVT_DATA evt_data;
+
+  evt_data.rcvd_evt.pipe = p_pipe->pipe_id;
+  evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
+  evt_data.rcvd_evt.evt_len = data_len;
+
+  if (nfa_hci_cb.assembly_failed)
+    evt_data.rcvd_evt.status = NFA_STATUS_BUFFER_FULL;
+  else
+    evt_data.rcvd_evt.status = NFA_STATUS_OK;
+
+  evt_data.rcvd_evt.p_evt_buf = p_data;
+#if (NXP_EXTNS == TRUE)
+  if (nfa_hci_cb.inst != NFA_HCI_EVT_WTX) {
+#endif
+    nfa_hci_cb.rsp_buf_size = 0;
+    nfa_hci_cb.p_rsp_buf = NULL;
+#if (NXP_EXTNS == TRUE)
+  }
+  if (nfa_hci_cb.IsEventAbortSent) {
+    nfa_hci_cb.IsEventAbortSent = false;
+    if (nfa_hci_cb.evt_sent.evt_type != NFA_EVT_ABORT) {
+      evt_data.rcvd_evt.evt_code = nfa_hci_cb.evt_sent.evt_type;
+      evt_data.rcvd_evt.evt_len = 0;
+    }
+  }
+#endif
+
+  /* notify NFA_HCI_EVENT_RCVD_EVT to the application */
+  nfa_hciu_send_to_app(NFA_HCI_EVENT_RCVD_EVT, &evt_data, p_gate->gate_owner);
+}
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         nfa_hci_api_get_host_id
+**
+** Description      action function to get the host id from HCI controller
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_api_get_host_id(tNFA_HCI_EVENT_DATA* p_evt_data) {
+  uint8_t app_inx = p_evt_data->get_host_list.hci_handle & NFA_HANDLE_MASK;
+
+  nfa_hci_cb.app_in_use = p_evt_data->get_host_list.hci_handle;
+
+  /* Send Get Host List command on "Internal request" or requested by registered
+   * application with valid handle and callback function */
+  if ((nfa_hci_cb.app_in_use == NFA_HANDLE_INVALID) ||
+      ((app_inx < NFA_HCI_MAX_APP_CB) &&
+       (nfa_hci_cb.p_app_cback[app_inx] != NULL))) {
+    nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE, NFA_HCI_HOST_ID_INDEX);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_get_host_type
+**
+** Description      action function to get the host type from HCI controller
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_api_get_host_type(tNFA_HCI_EVENT_DATA* p_evt_data) {
+  uint8_t app_inx = p_evt_data->get_host_list.hci_handle & NFA_HANDLE_MASK;
+
+  nfa_hci_cb.app_in_use = p_evt_data->get_host_list.hci_handle;
+
+  /* Send Get Host List command on "Internal request" or requested by registered
+   * application with valid handle and callback function */
+  if ((nfa_hci_cb.app_in_use == NFA_HANDLE_INVALID) ||
+      ((app_inx < NFA_HCI_MAX_APP_CB) &&
+       (nfa_hci_cb.p_app_cback[app_inx] != NULL))) {
+    if (nfa_hci_cb.cfg.admin_gate.pipe01_state == NFA_HCI_PIPE_OPENED) {
+      nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE, NFA_HCI_HOST_TYPE_INDEX);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_get_host_type_list
+**
+** Description      action function to get the host type list from HCI
+*controller
+**
+** Returns          Status
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hci_api_get_host_type_list() {
+  tNFA_STATUS status = NFA_STATUS_FAILED;
+  tNFA_HCI_EVT_DATA evt_data;
+  tNFA_HANDLE app_handle;
+  NFA_TRACE_DEBUG0("nfa_hci_api_get_host_type_list - enter!!");
+  if ((nfa_hci_cb.host_controller_version == NFA_HCI_CONTROLLER_VERSION_12) &&
+      (nfa_hci_cb.hci_state == NFA_HCI_STATE_NFCEE_ENABLE)) {
+    NFA_TRACE_DEBUG0(
+        "nfa_hci_api_get_host_type_list - Sending get_host_type_list!!!");
+    if ((status = nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
+                                              NFA_HCI_HOST_TYPE_LIST_INDEX)) ==
+        NFA_STATUS_OK)
+      return NFA_STATUS_OK;
+  }
+  evt_data.admin_rsp_rcvd.status = status;
+  evt_data.admin_rsp_rcvd.NoHostsPresent = 0;
+  /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
+  nfa_hciu_send_to_all_apps(NFA_HCI_HOST_TYPE_LIST_READ_EVT, &evt_data);
+  return NFA_STATUS_OK;
+}
+/*******************************************************************************
+**
+** Function         nfa_hci_api_config_nfcee
+**
+** Description      action function to configure NFCEE found in network as per
+*ETSI12
+**
+** Returns          if success NFA_STATUS_OK or NFA_STATUS_FAILED
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hci_api_config_nfcee(uint8_t hostId) {
+  tNFA_STATUS status = NFA_STATUS_OK;
+  tNFA_HCI_EVT_DATA evt_data;
+  uint8_t count = 0;
+  uint8_t pipeId = 0;
+  bool bCreatepipe = false;
+  NFA_TRACE_DEBUG0("nfa_hci_api_config_nfcee - enter!!");
+
+  nfa_hciu_set_nfceeid_config_mask(NFA_HCI_SET_CONFIG_EVENT, hostId);
+  if ((nfa_hci_cb.host_controller_version == NFA_HCI_CONTROLLER_VERSION_12) &&
+      (nfa_hci_cb.hci_state == NFA_HCI_STATE_NFCEE_ENABLE)) {
+    NFA_TRACE_DEBUG0("nfa_hci_api_config_nfcee -Entry");
+    if ((nfa_hci_api_IspipePresent(hostId, NFA_HCI_ETSI12_APDU_GATE) ==
+         false)) {
+      nfa_hci_cb.current_nfcee = hostId;
+      NFA_TRACE_DEBUG0 ("nfa_hci_api_config_nfcee - creating APDU gate pipe!!!");
+      nfa_hciu_alloc_gate(NFA_HCI_ETSI12_APDU_GATE, NFA_HANDLE_GROUP_HCI);
+      nfa_hciu_send_create_pipe_cmd (NFA_HCI_ETSI12_APDU_GATE, nfa_hci_cb.current_nfcee, NFA_HCI_ETSI12_APDU_GATE);
+
+      return (NFA_STATUS_OK);
+    } else {
+      status = NFA_STATUS_OK;
+      NFA_TRACE_DEBUG0(
+          "nfa_hci_api_config_nfcee - APDU Gate is present and pipe is already "
+          "created!!!");
+    }
+  }
+  NFA_TRACE_DEBUG0("nfa_hci_api_config_nfcee - No NFCEE Config is needed!!!");
+  evt_data.config_rsp_rcvd.status = status;
+  /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
+  nfa_hciu_send_to_all_apps(NFA_HCI_CONFIG_DONE_EVT, &evt_data);
+  return NFA_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_nfcee_config
+**
+** Description      handle  NFCEE configuration of discovered ETSI 12 host.
+**
+** Returns          if success NFA_STATUS_OK or NFA_STATUS_FAILED
+**
+*********************************************************************************/
+static bool nfa_hci_handle_nfcee_config() {
+  bool status = false;
+  int xx;
+  for (xx = 00; xx < nfa_hci_cb.host_count; xx++) {
+    if (nfa_hciu_check_nfcee_config_done(nfa_hci_cb.host_id[xx]) == false) {
+      NFC_NfceeModeSet(nfa_hci_cb.host_id[xx], NFC_MODE_ACTIVATE);
+      nfa_hci_cb.current_nfcee = nfa_hci_cb.host_id[xx];
+#if(NXP_NFC_UICC_ETSI12 == true)
+      if(NFA_HCI_HOST_ID_ESE != nfa_hci_cb.host_id[xx])
+      {
+        nfa_hci_api_config_nfcee(nfa_hci_cb.current_nfcee);
+      }
+#endif
+      break;
+    }
+  }
+  if (xx == nfa_hci_cb.host_count) status = true;
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_get_num_nfcee_configured
+**
+** Description      Read the number of NFCEE configured by the user.
+**
+** Returns          if success NFA_STATUS_OK or NFA_STATUS_FAILED
+**
+*********************************************************************************/
+static tNFA_STATUS nfa_hci_get_num_nfcee_configured() {
+  tNFA_STATUS status = NFA_STATUS_OK;
+  uint8_t p_data[NFA_MAX_HCI_CMD_LEN];
+  uint8_t* p = p_data, *parm_len, *num_param;
+
+  memset(p_data, 0, sizeof(p_data));
+  NCI_MSG_BLD_HDR0(p, NCI_MT_CMD, NCI_GID_CORE);
+  NCI_MSG_BLD_HDR1(p, NCI_MSG_CORE_GET_CONFIG);
+  parm_len = p++;
+  num_param = p++;
+  UINT8_TO_STREAM(p, NXP_NFC_SET_CONFIG_PARAM_EXT);
+  UINT8_TO_STREAM(p, NXP_NFC_PARAM_ID_SWP1);
+  (*num_param)++;
+  UINT8_TO_STREAM(p, NXP_NFC_SET_CONFIG_PARAM_EXT);
+  UINT8_TO_STREAM(p, NXP_NFC_PARAM_ID_SWP2);
+  (*num_param)++;
+
+  if ((nfcFL.chipType == pn551) || (nfcFL.chipType == pn553) || (nfcFL.chipType == pn557)) {
+      UINT8_TO_STREAM(p, NXP_NFC_SET_CONFIG_PARAM_EXT);
+      UINT8_TO_STREAM(p, NXP_NFC_PARAM_ID_SWP1A);
+      (*num_param)++;
+  }
+
+  *parm_len = (p - num_param);
+  if (*num_param != 0x00) {
+    status = nfa_hciu_send_raw_cmd(p - p_data, p_data,
+                                   nfa_hci_read_num_nfcee_config_cb);
+  }
+  NFA_TRACE_DEBUG1("nfa_hci_get_num_nfcee_configured %x", *num_param);
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_read_num_nfcee_config_cb
+**
+** Description      Callback function to handle the response of num of NFCEE
+*configured cmd.
+**
+** Returns          None
+**
+*********************************************************************************/
+static void nfa_hci_read_num_nfcee_config_cb(uint8_t event, uint16_t param_len,
+                                             uint8_t* p_param) {
+  uint8_t num_param_id = 0x00, xx;
+  uint8_t configured_num_nfcee = 0x00;
+  uint8_t NFA_PARAM_ID_INDEX = 0x04;
+  uint8_t param_id1 = 0x00;
+  uint8_t param_id2 = 0x00;
+  uint8_t status = 0x00;
+
+  nfa_sys_stop_timer(&nfa_hci_cb.timer);
+  nfa_hci_cb.num_nfcee = NFA_HCI_MAX_HOST_IN_NETWORK;
+  NFA_AllEeGetInfo(&nfa_hci_cb.num_nfcee, nfa_hci_cb.hci_ee_info);
+
+  for (xx = 0; xx < nfa_hci_cb.num_nfcee; xx++) {
+    if(nfa_hci_cb.hci_ee_info[xx].ee_interface[0] ==
+            NCI_NFCEE_INTERFACE_HCI_ACCESS)
+    {
+      /*If NFCEE_HCI_NETWORK ID exists*/
+      configured_num_nfcee = 1;
+      break;
+    }
+  }
+
+  if (param_len == 0x00 || p_param == NULL ||
+      p_param[NFA_PARAM_ID_INDEX - 1] != NFA_STATUS_OK) {
+    for (xx = 0; xx < nfa_hci_cb.num_nfcee; xx++) {
+      if ((((nfa_hci_cb.hci_ee_info[xx].ee_interface[0] !=
+           NCI_NFCEE_INTERFACE_HCI_ACCESS) &&
+	          nfa_hci_cb.hci_ee_info[xx].ee_status == NFA_EE_STATUS_ACTIVE))  &&
+          (nfa_hci_cb.hci_ee_info[xx].ee_handle != 0x410)) {
+        nfa_hci_cb.nfcee_cfg.host_cb[num_param_id++] =
+            nfa_hci_cb.hci_ee_info[xx].ee_handle;
+      }
+    }
+    nfa_hci_handle_nfcee_config_evt(NFA_HCI_READ_SESSIONID);
+    return;
+  }
+  p_param += NFA_PARAM_ID_INDEX;
+  STREAM_TO_UINT8(num_param_id, p_param);
+
+  while (num_param_id > 0x00) {
+    STREAM_TO_UINT8(param_id1, p_param);
+    STREAM_TO_UINT8(param_id2, p_param);
+    p_param++;
+    STREAM_TO_UINT8(status, p_param);
+    if (param_id1 == NXP_NFC_SET_CONFIG_PARAM_EXT &&
+        param_id2 == NXP_NFC_PARAM_ID_SWP1 && status != 0x00)
+      configured_num_nfcee++;
+    else if (param_id1 == NXP_NFC_SET_CONFIG_PARAM_EXT &&
+             param_id2 == NXP_NFC_PARAM_ID_SWP2 && status != 0x00)
+      configured_num_nfcee++;
+    else if (param_id1 == NXP_NFC_SET_CONFIG_PARAM_EXT &&
+             param_id2 == NXP_NFC_PARAM_ID_SWP1A && status != 0x00)
+      configured_num_nfcee++;
+    else if (param_id1 == NXP_NFC_SET_CONFIG_PARAM_EXT &&
+             param_id2 == NXP_NFC_PARAM_ID_NDEF_NFCEE && status != 0x00)
+      configured_num_nfcee++;
+    num_param_id--;
+  }
+  NFA_TRACE_DEBUG1("nfa_hci_read_num_nfcee_config_cb %x", configured_num_nfcee);
+  NFA_TRACE_DEBUG1("nfa_hci_read_num_nfcee_config_cb %x", nfa_hci_cb.num_nfcee);
+  if (configured_num_nfcee > nfa_hci_cb.num_nfcee)
+    nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_NFCEE_DISCOVER_TIMEOUT_EVT,
+                        nfa_hci_cb.max_nfcee_disc_timeout);
+  else {
+    num_param_id = 0x00;
+    for (xx = 0; xx < nfa_hci_cb.num_nfcee; xx++) {
+      if ((((nfa_hci_cb.hci_ee_info[xx].ee_interface[0] !=
+          NCI_NFCEE_INTERFACE_HCI_ACCESS) &&
+          nfa_hci_cb.hci_ee_info[xx].ee_status == NFA_EE_STATUS_ACTIVE)) &&
+          (nfa_hci_cb.hci_ee_info[xx].ee_handle != 0x410)) {
+        nfa_hci_cb.nfcee_cfg.host_cb[num_param_id++] =
+            nfa_hci_cb.hci_ee_info[xx].ee_handle;
+      }
+    }
+    nfa_hci_handle_nfcee_config_evt(NFA_HCI_READ_SESSIONID);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_poll_all_nfcee_session_id
+**
+** Description      poll continuously for session ID for all discovered hosts.
+**
+** Returns          if success NFA_STATUS_OK or NFA_STATUS_FAILED
+**
+*********************************************************************************/
+static tNFA_STATUS nfa_hci_poll_all_nfcee_session_id() {
+  uint8_t discovered_num_nfcee = NFA_HCI_MAX_HOST_IN_NETWORK, xx;
+  tNFA_STATUS status = NFA_STATUS_OK;
+  uint8_t host_index = 0x00;
+  for (xx = 0; xx < nfa_hci_cb.num_nfcee; xx++) {
+    NFA_TRACE_DEBUG1("nfa_hci_pollsession_id   -%x",
+                     nfa_hci_cb.hci_ee_info[xx].ee_handle);
+    if ((((nfa_hci_cb.hci_ee_info[xx].ee_interface[0] !=
+        NCI_NFCEE_INTERFACE_HCI_ACCESS)&& nfa_hci_cb.hci_ee_info[xx].ee_status == NFA_EE_STATUS_ACTIVE))&&
+        (nfa_hci_cb.hci_ee_info[xx].ee_handle != 0x410)) {
+      if (nfa_hciu_check_nfcee_poll_done(nfa_hci_cb.hci_ee_info[xx].ee_handle &
+                                         ~(NFA_HANDLE_GROUP_EE)) == false) {
+        if (nfa_hci_cb.nfcee_cfg.session_id_retry <=
+            nfa_hci_cb.max_hci_session_id_read_count) {
+          status = nfa_hci_poll_session_id(
+              nfa_hci_cb.hci_ee_info[xx].ee_handle & ~(NFA_HANDLE_GROUP_EE));
+          if (status == NFA_STATUS_OK) break;
+        } else {
+          nfa_hci_cb.nfcee_cfg.session_id_retry = 0x00;
+          nfa_hciu_set_nfceeid_poll_mask(
+              NFA_HCI_SET_CONFIG_EVENT,
+              nfa_hci_cb.hci_ee_info[xx].ee_handle & ~(NFA_HANDLE_GROUP_EE));
+        }
+      }
+    }
+  }
+  if (xx == nfa_hci_cb.num_nfcee)
+    nfa_hci_handle_nfcee_config_evt(NFA_HCI_HOST_TYPE_LIST_INDEX);
+  NFA_TRACE_DEBUG0("nfa_hci_poll_all_nfcee_session_id - exit!!");
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_poll_session_id
+**
+** Description      poll continuously for session ID of particular host
+**
+** Returns          if success NFA_STATUS_OK or NFA_STATUS_FAILED
+**
+*********************************************************************************/
+static tNFA_STATUS nfa_hci_poll_session_id(uint8_t host_type) {
+  uint8_t p_data[NFA_MAX_HCI_CMD_LEN];
+  uint8_t* p = p_data;
+  tNFA_STATUS status = NFA_STATUS_OK;
+
+  NCI_MSG_BLD_HDR0(p, NCI_MT_CMD, NCI_GID_CORE);
+  NCI_MSG_BLD_HDR1(p, NCI_MSG_CORE_GET_CONFIG);
+  UINT8_TO_STREAM(p, 0x03);
+  UINT8_TO_STREAM(p, 0x01);
+  UINT8_TO_STREAM(p, NXP_NFC_SET_CONFIG_PARAM_EXT);
+
+  if (NFA_HCI_HOST_ID_UICC0 == host_type || NFA_HCI_HOST_ID_UICC0_NCI2 == host_type) {
+    UINT8_TO_STREAM(p, NXP_NFC_PARAM_SWP_SESSIONID_INT1);
+  } else if (NFA_HCI_HOST_ID_UICC1 == host_type) {
+    UINT8_TO_STREAM(p, NXP_NFC_PARAM_SWP_SESSIONID_INT1A);
+  } else if (NFA_HCI_HOST_ID_ESE == host_type) {
+    UINT8_TO_STREAM(p, NXP_NFC_PARAM_SWP_SESSIONID_INT2);
+  } else
+    status = NFA_STATUS_BAD_HANDLE;
+
+  if (status == NFA_STATUS_OK && ((p - p_data) > 0x00)) {
+    NFA_TRACE_DEBUG0("nfa_hci_clear_all_pipe_ntf session id read");
+    nfa_hci_cb.nfcee_cfg.session_id_retry++;
+    status =
+        nfa_hciu_send_raw_cmd(p - p_data, p_data, nfa_hci_poll_session_id_cb);
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_poll_session_id_cb
+**
+** Description      callback handler for session ID read commands response.
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_poll_session_id_cb(uint8_t event, uint16_t param_len,
+                                       uint8_t* p_param) {
+  uint8_t default_session[NFA_HCI_SESSION_ID_LEN] = {0xFF, 0xFF, 0xFF, 0xFF,
+                                                     0xFF, 0xFF, 0xFF, 0xFF};
+  nfa_sys_stop_timer(&nfa_hci_cb.timer);
+  uint8_t SESSION_ID_INDEX = 0x08;
+
+  if (param_len < NFA_HCI_SESSION_ID_LEN || p_param == NULL ||
+      p_param[3] != NFA_STATUS_OK) {
+    nfa_hci_handle_nfcee_config_evt(NFA_HCI_READ_SESSIONID);
+    return;
+  }
+
+  if (!memcmp((uint8_t*)default_session, p_param + SESSION_ID_INDEX,
+              NFA_HCI_SESSION_ID_LEN)) {
+    NFA_TRACE_DEBUG0("nfa_hci_poll_session_id_cb invalid session id");
+    if (nfa_hci_cb.nfcee_cfg.session_id_retry <=
+        nfa_hci_cb.max_hci_session_id_read_count) {
+      nfa_sys_start_timer(&nfa_hci_cb.timer,
+                          NFA_HCI_SESSION_ID_POLL_DELAY_TIMEOUT_EVT,
+                          NFA_HCI_SESSION_ID_POLL_DELAY);
+    } else {
+      nfa_hci_handle_nfcee_config_evt(NFA_HCI_READ_SESSIONID);
+    }
+  } else {
+    NFA_TRACE_DEBUG0("nfa_hci_poll_session_id_cb valid session id");
+    nfa_hci_cb.nfcee_cfg.session_id_retry =
+        nfa_hci_cb.max_hci_session_id_read_count + 1;
+    nfa_hci_handle_nfcee_config_evt(NFA_HCI_READ_SESSIONID);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_nfcee_config_evt
+**
+** Description      In case of NFCEE CONFIG EVT , the following sequence of
+*commands are sent.
+**                  This function also handles the CLEAR_ALL_PIPE_NTF from
+*respective host.
+**                      a.Get the number of secelement configured and
+*discovered, in case of less than configured wait for
+**                        for all the secelement to be discovered.
+**                      b.Poll for session ID of all the discovered secure
+*Element to check whether
+**                        the secure Element is initialized or not.
+**                      c.Read the HOST_TYPE_LIST_INDEX to get the number of
+*hosts configured.
+**                      d.Check for APDU gate discovered or not.
+**                      e.Create identity management pipe and APDU pipe and open
+*the pipe.
+**                      f.Read parameters from APDU gate.
+**
+**
+** Returns              None
+**
+*******************************************************************************/
+void nfa_hci_handle_nfcee_config_evt(uint16_t event) {
+  NFA_TRACE_DEBUG1("nfa_hci_handle_nfcee_config_evt enter %x", event);
+  switch (event) {
+    case NFA_HCI_GET_NUM_NFCEE_CONFIGURED:
+      nfa_hci_cb.nfcee_cfg.nfc_init_state = true;
+      if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) {
+        nfa_hci_cb.hci_state = NFA_HCI_STATE_NFCEE_ENABLE;
+        nfa_hci_cb.nfcee_cfg.config_nfcee_state =
+            NFA_HCI_GET_NUM_NFCEE_CONFIGURED;
+        if (nfa_hci_get_num_nfcee_configured() != NFA_STATUS_OK) {
+          tNFA_HCI_API_CONFIGURE_EVT* p_msg;
+          /* Send read session event to continue with other initialization*/
+          if ((p_msg = (tNFA_HCI_API_CONFIGURE_EVT*)GKI_getbuf(
+                   sizeof(tNFA_HCI_API_CONFIGURE_EVT))) != NULL) {
+            p_msg->hdr.event = NFA_HCI_API_CONFIGURE_EVT;
+            p_msg->config_nfcee_event = NFA_HCI_READ_SESSIONID;
+            nfa_sys_sendmsg(p_msg);
+          } else
+            event = NFA_HCI_NFCEE_CONFIG_COMPLETE;
+        }
+      } else {
+        event = NFA_HCI_NFCEE_CONFIG_COMPLETE;
+      }
+      break;
+    case NFA_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED:
+      /* Stop RF discovery if running and update state*/
+      if (nfa_hci_cb.hci_state < NFA_HCI_STATE_IDLE) {
+        NFA_TRACE_DEBUG0(
+            "nfa_hci_handle_nfcee_config_evt  will be handled later");
+        return;
+      }
+      if (NFA_DM_RFST_DISCOVERY == nfa_dm_cb.disc_cb.disc_state) {
+        nfa_hci_cb.nfcee_cfg.discovery_stopped =
+            nfa_dm_act_stop_rf_discovery(NULL);
+      }
+
+    case NFA_HCI_READ_SESSIONID:
+      /*Read the session ID of the host discovered */
+      nfa_hci_cb.nfcee_cfg.config_nfcee_state = NFA_HCI_READ_SESSIONID;
+      nfa_hci_poll_all_nfcee_session_id();
+      break;
+    case NFA_HCI_HOST_TYPE_LIST_INDEX:
+      /*Read the host type list index to get ETSI Host configured*/
+      nfa_hci_cb.nfcee_cfg.config_nfcee_state = NFA_HCI_HOST_TYPE_LIST_INDEX;
+      nfa_hci_cb.hci_state = NFA_HCI_STATE_NFCEE_ENABLE;
+      if (nfa_hci_api_get_host_type_list() != NFA_STATUS_OK)
+        event = NFA_HCI_NFCEE_CONFIG_COMPLETE;
+      break;
+    case NFA_HCI_INIT_NFCEE_CONFIG:
+      /*Perform nfcee configuration of all nfcee list found */
+      nfa_hci_cb.nfcee_cfg.config_nfcee_state = NFA_HCI_INIT_NFCEE_CONFIG;
+      nfa_hci_cb.hci_state = NFA_HCI_STATE_NFCEE_ENABLE;
+      if (nfa_hci_cb.nfcee_cfg.nfc_init_state == true ||
+          nfa_hci_handle_nfcee_config() == true)
+        event = NFA_HCI_NFCEE_CONFIG_COMPLETE;
+      break;
+    default:
+      break;
+  }
+  if (NFA_HCI_NFCEE_CONFIG_COMPLETE == event ||
+      NFA_HCI_RSP_TIMEOUT_EVT == event) {
+    if (true == nfa_hci_cb.nfcee_cfg.discovery_stopped)
+      nfa_dm_act_start_rf_discovery(NULL);
+    nfa_hci_cb.nfcee_cfg.discovery_stopped = false;
+    nfa_hci_cb.nfcee_cfg.session_id_retry = false;
+    nfa_hci_cb.nfcee_cfg.config_nfcee_state = NFA_HCI_NFCEE_CONFIG_COMPLETE;
+    nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+
+    NFA_TRACE_DEBUG0(
+        "nfa_hci_handle_nfcee_config_evt  complete , notify upper layer");
+    if (nfa_hci_cb.nfcee_cfg.nfc_init_state == true) {
+      if (nfa_hciu_check_any_host_reset_pending()) {
+        tNFA_HCI_API_CONFIGURE_EVT* p_msg;
+        /* Send read session event to continue with other initialization*/
+        if ((p_msg = (tNFA_HCI_API_CONFIGURE_EVT*)GKI_getbuf(
+                 sizeof(tNFA_HCI_API_CONFIGURE_EVT))) != NULL) {
+          p_msg->hdr.event = NFA_HCI_API_CONFIGURE_EVT;
+          p_msg->config_nfcee_event = NFA_HCI_READ_SESSIONID;
+          nfa_sys_sendmsg(p_msg);
+        }
+      } else {
+        nfa_hci_cb.nfcee_cfg.nfc_init_state = false;
+        nfa_sys_cback_notify_enable_complete(NFA_ID_HCI);
+      }
+    }
+
+    if (nfa_hciu_is_no_host_resetting()) nfa_hci_check_pending_api_requests();
+  }
+  NFA_TRACE_DEBUG0("nfa_hci_handle_nfcee_config_evt exit");
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_nfcee_config_rsp_handler
+**
+** Description      Function to handle response of nfcee config
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hci_nfcee_config_rsp_handler(tNFA_HCI_EVT event,
+                                      tNFA_HCI_EVT_DATA* p_evt) {
+  if (NFA_HCI_CONFIG_DONE_EVT == event) {
+    nfa_hci_handle_nfcee_config_evt(NFA_HCI_INIT_NFCEE_CONFIG);
+  } else if (NFA_HCI_HOST_TYPE_LIST_READ_EVT == event) {
+    if (p_evt->admin_rsp_rcvd.status != NFA_STATUS_OK ||
+        nfa_hci_cb.nfcee_cfg.nfc_init_state == true) {
+      nfa_hci_handle_nfcee_config_evt(NFA_HCI_NFCEE_CONFIG_COMPLETE);
+    } else
+      nfa_hci_handle_nfcee_config_evt(NFA_HCI_INIT_NFCEE_CONFIG);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_getnoofhosts
+**
+** Description      action function to get the host type from HCI controller
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_api_getnoofhosts(uint8_t* p_data, uint8_t data_len) {
+  uint8_t noofhosts = 0;
+  uint8_t count = 0;
+  uint8_t host_id = 0;
+
+  nfa_hci_cb.host_count = host_id;
+  noofhosts = ((data_len / NFA_HCI_HOST_TYPE_LEN) - 2);
+  NFA_TRACE_DEBUG1("nfa_hci_api_getnoofhosts :-no of hosts in HCI Network-%d",
+                   noofhosts);
+  for (count = 0; count < data_len; count++) {
+    NFA_TRACE_DEBUG2("nfa_hci_api_getnoofhosts :data[%d] - %d\n", count,
+                     p_data[count]);
+  }
+  for (count = 0; count < noofhosts; count++) {
+    host_id = (((count + 1) * NFA_HCI_HOST_TYPE_LEN) + NFA_HCI_HOST_TYPE_LEN);
+    NFA_TRACE_DEBUG1(
+        "nfa_hci_api_getnoofhosts -NFA_HCI_HOST_TYPE_LIST_INDEX id -- %d !!!",
+        host_id);
+    if ((p_data[host_id] & p_data[host_id + 1]) != 0xFF) {
+      if ((p_data[host_id] == NFA_HCI_HOST_ID_UICC0) &&
+          (p_data[host_id + 1] == 0x00)) {
+        NFA_TRACE_DEBUG0("nfa_hci_api_getnoofhosts :- UICC !!!!");
+        nfa_hci_cb.host_id[nfa_hci_cb.host_count] = p_data[host_id];
+        nfa_hci_cb.host_count++;
+      } else if ((p_data[host_id] == 0x03) && (p_data[host_id + 1] == 0x00)) {
+        NFA_TRACE_DEBUG0("nfa_hci_api_getnoofhosts :- eSE !!!!");
+        nfa_hci_cb.host_id[nfa_hci_cb.host_count] = 0xC0;
+        nfa_hci_cb.host_count++;
+      }
+    }
+  }
+}
+/*******************************************************************************
+**
+** Function         nfa_hci_api_checkforAPDUGate
+**
+** Description      action function to get the host type from HCI controller
+**
+** Returns          None
+**
+*******************************************************************************/
+static bool nfa_hci_api_checkforAPDUGate(uint8_t* p_data, uint8_t data_len) {
+  uint8_t count = 0;
+  bool status = false;
+  for (count = 0; count < data_len; count++) {
+    NFA_TRACE_DEBUG1("nfa_hci_api_checkforAPDUGate -Gate id -- %d !!!",
+                     p_data[count]);
+    if (p_data[count] == NFA_HCI_ETSI12_APDU_GATE) {
+      NFA_TRACE_DEBUG1("nfa_hci_api_checkforAPDUGate -count -- %d !!!", count);
+      status = true;
+      break;
+    }
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_Nfcee_admpipe_rsp
+**
+** Description      This function handles responses received for commands during
+*NFCEE init
+**                  on Admin pipe
+**
+** Returns          none
+**
+*******************************************************************************/
+static void nfa_hci_handle_Nfcee_admpipe_rsp(uint8_t* p_data,
+                                             uint8_t data_len) {
+  uint8_t source_host;
+  uint8_t source_gate = nfa_hci_cb.local_gate_in_use;
+  uint8_t dest_host = nfa_hci_cb.remote_host_in_use;
+  uint8_t dest_gate = nfa_hci_cb.remote_gate_in_use;
+  uint8_t pipe = 0;
+  uint8_t count = 0;
+  tNFA_HCI_EVT_DATA evt_data;
+  tNFA_STATUS status = NFA_STATUS_OK;
+#if (BT_TRACE_VERBOSE == true)
+  NFA_TRACE_DEBUG4(
+      "nfa_hci_handle_Nfcee_admpipe_rsp - LastCmdSent: %s  App: 0x%04x  Gate: "
+      "0x%02x  Pipe: 0x%02x",
+      nfa_hciu_instr_2_str(nfa_hci_cb.cmd_sent), nfa_hci_cb.app_in_use,
+      nfa_hci_cb.local_gate_in_use, nfa_hci_cb.pipe_in_use);
+#else
+  NFA_TRACE_DEBUG4(
+      "nfa_hci_handle_Nfcee_admpipe_rsp LastCmdSent: %u  App: 0x%04x  Gate: "
+      "0x%02x  Pipe: 0x%02x",
+      nfa_hci_cb.cmd_sent, nfa_hci_cb.app_in_use, nfa_hci_cb.local_gate_in_use,
+      nfa_hci_cb.pipe_in_use);
+#endif
+  if (nfa_hci_cb.inst != NFA_HCI_ANY_OK) {
+
+    nfa_sys_stop_timer(&nfa_hci_cb.timer);
+
+    nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+    /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
+    if ((nfa_hci_cb.cmd_sent == NFA_HCI_ANY_GET_PARAMETER) &&
+        (nfa_hci_cb.param_in_use == NFA_HCI_HOST_TYPE_LIST_INDEX)) {
+      evt_data.admin_rsp_rcvd.status = NFA_STATUS_FAILED;
+      evt_data.admin_rsp_rcvd.NoHostsPresent = 0;
+      nfa_hciu_send_to_all_apps(NFA_HCI_HOST_TYPE_LIST_READ_EVT, &evt_data);
+    } else {
+      evt_data.config_rsp_rcvd.status = NFA_STATUS_FAILED;
+      nfa_hciu_send_to_all_apps(NFA_HCI_CONFIG_DONE_EVT, &evt_data);
+    }
+  } else if ((nfa_hci_cb.cmd_sent == NFA_HCI_ANY_GET_PARAMETER) &&
+             (nfa_hci_cb.inst == NFA_HCI_ANY_OK)) {
+    if (nfa_hci_cb.param_in_use == NFA_HCI_HOST_TYPE_LIST_INDEX) {
+      nfa_sys_stop_timer(&nfa_hci_cb.timer);
+      NFA_TRACE_DEBUG0(
+          "nfa_hci_handle_admin_gate_rsp - Received the HOST_TYPE_LIST as per "
+          "ETSI 12 !!!");
+      if (data_len > 4) {
+        nfa_hci_api_getnoofhosts(p_data, data_len);
+        NFA_TRACE_DEBUG0(
+            "nfa_hci_handle_admin_gate_rsp - Calling complete here !!!");
+        evt_data.admin_rsp_rcvd.status = NFA_STATUS_OK;
+        evt_data.admin_rsp_rcvd.NoHostsPresent = nfa_hci_cb.host_count;
+        NFA_TRACE_DEBUG1(
+            "nfa_hci_handle_admin_gate_rsp -nfa_hci_cb.host_countt --%d !",
+            nfa_hci_cb.host_count);
+        if (nfa_hci_cb.host_count > 0) {
+          for (count = 0; count < nfa_hci_cb.host_count; count++) {
+            evt_data.admin_rsp_rcvd.HostIds[count] = nfa_hci_cb.host_id[count];
+            NFA_TRACE_DEBUG1(
+                "nfa_hci_handle_admin_gate_rsp -nfa_hci_cb.host_iddd --%d !",
+                nfa_hci_cb.host_id[count]);
+          }
+        }
+        nfa_hciu_send_to_all_apps(NFA_HCI_HOST_TYPE_LIST_READ_EVT, &evt_data);
+
+      } else {
+        NFA_TRACE_DEBUG0(
+            "nfa_hci_handle_admin_gate_rsp -No host is connected!!");
+        evt_data.admin_rsp_rcvd.status = status;
+        evt_data.admin_rsp_rcvd.NoHostsPresent = 0;
+        nfa_hciu_send_to_all_apps(NFA_HCI_HOST_TYPE_LIST_READ_EVT, &evt_data);
+      }
+    }
+  } else if ((nfa_hci_cb.cmd_sent == NFA_HCI_ADM_CREATE_PIPE) &&
+             (nfa_hci_cb.inst == NFA_HCI_ANY_OK)) {
+    STREAM_TO_UINT8(source_host, p_data);
+    STREAM_TO_UINT8(source_gate, p_data);
+    STREAM_TO_UINT8(dest_host, p_data);
+    STREAM_TO_UINT8(dest_gate, p_data);
+    STREAM_TO_UINT8(pipe, p_data);
+
+    nfa_hciu_add_pipe_to_static_gate(source_gate, pipe, dest_host, dest_gate);
+    NFA_TRACE_DEBUG0("nfa_hci_handle_Nfcee_admpipe_rsp - Opening pipe!!!");
+    nfa_hciu_send_open_pipe_cmd(pipe);
+  } else {
+    nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+    evt_data.config_rsp_rcvd.status = NFA_STATUS_FAILED;
+    /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
+    nfa_hciu_send_to_all_apps(NFA_HCI_CONFIG_DONE_EVT, &evt_data);
+  }
+}
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_Nfcee_dynpipe_rsp
+**
+** Description      This function handles response received for commands during
+*NFCEE init
+**                   on dynamic pipe
+**
+** Returns          none
+**
+*******************************************************************************/
+static void nfa_hci_handle_Nfcee_dynpipe_rsp(uint8_t pipeId, uint8_t* p_data,
+                                             uint8_t data_len) {
+  tNFA_HCI_DYN_PIPE* p_pipe = nfa_hciu_find_pipe_by_pid(pipeId);
+  tNFA_HCI_DYN_GATE* p_gate;
+  tNFA_STATUS status = NFA_STATUS_FAILED;
+  bool wStatus = false;
+  tNFA_HCI_EVT_DATA evt_data;
+
+  if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) {
+    nfa_sys_stop_timer(&nfa_hci_cb.timer);
+    NFA_TRACE_DEBUG0("nfa_hci_handle_Nfcee_dynpipe_rsp - HCI Timer stopped!!!");
+    if (nfa_hci_cb.inst != NFA_HCI_ANY_OK) {
+      nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+      evt_data.config_rsp_rcvd.status = status;
+      /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
+      nfa_hciu_send_to_all_apps(NFA_HCI_CONFIG_DONE_EVT, &evt_data);
+      return;
+    }
+  }
+  if (pipeId == NULL) {
+    /* Invalid pipe ID */
+    NFA_TRACE_ERROR1("nfa_hci_handle_Nfcee_dynpipe_rsp - Unknown pipe %d",
+                     pipeId);
+    if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
+      nfa_hciu_send_msg(pipeId, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_NOK, 0,
+                        NULL);
+    evt_data.config_rsp_rcvd.status = status;
+    /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
+    nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+    nfa_hciu_send_to_all_apps(NFA_HCI_CONFIG_DONE_EVT, &evt_data);
+    return;
+  }
+  switch (nfa_hci_cb.cmd_sent) {
+    case NFA_HCI_ANY_OPEN_PIPE:
+      NFA_TRACE_DEBUG0(
+          "nfa_hci_handle_Nfcee_dynpipe_rsp - Response received open Pipe get "
+          "the Gate List on Id Gate!!!");
+      if (!p_pipe) {
+        NFA_TRACE_ERROR1(
+            "nfa_hci_handle_Nfcee_dynpipe_rsp - NULL pipe for PipeId %d",
+            pipeId);
+        break;
+      }
+      if ((p_pipe->dest_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE) &&
+          (p_pipe->local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE)) {
+        p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
+        nfa_hciu_send_get_param_cmd(pipeId, NFA_HCI_GATES_LIST_INDEX);
+      }
+      break;
+    case NFA_HCI_ANY_GET_PARAMETER:
+      if (nfa_hci_cb.param_in_use == NFA_HCI_GATES_LIST_INDEX) {
+        NFA_TRACE_DEBUG0(
+            "nfa_hci_handle_Nfcee_dynpipe_rsp - Response received Gate List on "
+            "Id Gate!!!");
+        if (data_len > 0) {
+          wStatus = nfa_hci_api_checkforAPDUGate(p_data, data_len);
+          if (wStatus == true) {
+            NFA_TRACE_DEBUG0(
+                "nfa_hci_handle_Nfcee_dynpipe_rsp - creating APDU pipee!!!");
+            nfa_hciu_alloc_gate(NFA_HCI_ETSI12_APDU_GATE, NFA_HANDLE_GROUP_HCI);
+            nfa_hciu_send_create_pipe_cmd(NFA_HCI_ETSI12_APDU_GATE,
+                                          nfa_hci_cb.current_nfcee,
+                                          NFA_HCI_ETSI12_APDU_GATE);
+          } else {
+            nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+            evt_data.config_rsp_rcvd.status = NFA_STATUS_OK;
+            /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
+            nfa_hciu_send_to_all_apps(NFA_HCI_CONFIG_DONE_EVT, &evt_data);
+          }
+        }
+      } else if (nfa_hci_cb.param_in_use == NFA_HCI_MAX_C_APDU_SIZE_INDEX) {
+        // Read the parameter and save in Non volatile Memory
+        NFA_TRACE_DEBUG0(
+            "nfa_hci_handle_Nfcee_dynpipe_rsp - Read HCI Max Wait time!!!");
+        nfa_hciu_send_get_param_cmd(pipeId, NFA_HCI_MAX_WAIT_TIME_INDEX);
+      } else if (nfa_hci_cb.param_in_use == NFA_HCI_MAX_WAIT_TIME_INDEX) {
+        // Read the parameter and save in Non volatile Memory
+        evt_data.admin_rsp_rcvd.status = NFA_STATUS_OK;
+        /* Send NFA_HCI_CMD_SENT_EVT to notify success */
+        nfa_hciu_send_to_all_apps(NFA_HCI_CONFIG_DONE_EVT, &evt_data);
+      }
+      break;
+  }
+  if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE) {
+    if (nfa_hci_cb.inst == NFA_HCI_ABORT) {
+      // display atr and read first parameter on APDU Gate
+      NFA_TRACE_DEBUG0(
+          "nfa_hci_handle_Nfcee_dynpipe_rsp - ATR received read APDU Size!!!");
+      NFA_TRACE_DEBUG0 (
+          "nfa_hci_handle_Nfcee_dynpipe_rsp - ETSI12 init complete");
+      evt_data.admin_rsp_rcvd.status = NFA_STATUS_OK;
+      nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+      nfa_hciu_send_to_all_apps(NFA_HCI_CONFIG_DONE_EVT, &evt_data);
+    }
+  }
+}
+/*******************************************************************************
+**
+** Function         nfa_hci_api_IspipePresent
+**
+** Description      Check if APDU Pipe is already present or needs to created
+**
+** Returns          None
+**
+*******************************************************************************/
+static bool nfa_hci_api_IspipePresent(uint8_t nfceeId, uint8_t gateId) {
+  uint8_t count = 0;
+  bool status = false;
+  NFA_TRACE_DEBUG0("nfa_hci_api_IspipePresent");
+  for (count = 0; count < NFA_HCI_MAX_PIPE_CB; count++) {
+    if (((nfa_hci_cb.cfg.dyn_pipes[count].dest_host) == nfceeId) &&
+        ((nfa_hci_cb.cfg.dyn_pipes[count].dest_gate) == gateId) &&
+        ((nfa_hci_cb.cfg.dyn_pipes[count].local_gate) == gateId)) {
+      NFA_TRACE_DEBUG1("nfa_hci_api_IspipePresent -count -- %d !!!", count);
+      status = true;
+      break;
+    }
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_GetpipeId
+**
+** Description      Check if APDU Pipe is already present or needs to created
+**
+** Returns          None
+**
+*******************************************************************************/
+static bool nfa_hci_api_GetpipeId(uint8_t nfceeId, uint8_t gateId,
+                                  uint8_t* pipeId) {
+  uint8_t count = 0;
+  bool status = false;
+  NFA_TRACE_DEBUG0("nfa_hci_api_GetpipeId");
+  for (count = 0; count < NFA_HCI_MAX_PIPE_CB; count++) {
+    if (((nfa_hci_cb.cfg.dyn_pipes[count].dest_host) == nfceeId) &&
+        ((nfa_hci_cb.cfg.dyn_pipes[count].dest_gate) == gateId) &&
+        ((nfa_hci_cb.cfg.dyn_pipes[count].local_gate) == gateId)) {
+      NFA_TRACE_DEBUG1("nfa_hci_api_GetpipeId -count -- %d !!!",
+                       nfa_hci_cb.cfg.dyn_pipes[count].pipe_id);
+      *pipeId = nfa_hci_cb.cfg.dyn_pipes[count].pipe_id;
+      status = true;
+      break;
+    }
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_getApduAndConnectivity_PipeStatus
+**
+** Description      API to retrieve APDU & Connectivity pipe created status from
+**                  FirmWare
+**
+** Returns          If NCI command is SUCCESS/FAILED
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hci_getApduAndConnectivity_PipeStatus()
+{
+    tNFA_STATUS         status = NFA_STATUS_OK;
+    uint8_t p_data[NFA_MAX_HCI_CMD_LEN];
+    uint8_t *p = p_data, *parm_len , *num_param;
+    memset(p_data, 0, sizeof(p_data));
+    NCI_MSG_BLD_HDR0 (p, NCI_MT_CMD, NCI_GID_CORE);
+    NCI_MSG_BLD_HDR1 (p, NCI_MSG_CORE_GET_CONFIG);
+    parm_len  = p++;
+    num_param = p++;
+    UINT8_TO_STREAM (p, NXP_NFC_SET_CONFIG_PARAM_EXT);
+    UINT8_TO_STREAM (p, NXP_NFC_ESE_APDU_PIPE_STATUS);
+    (*num_param)++;
+    UINT8_TO_STREAM (p, NXP_NFC_SET_CONFIG_PARAM_EXT);
+    UINT8_TO_STREAM (p, NXP_NFC_ESE_CONN_PIPE_STATUS);
+    (*num_param)++;
+
+    *parm_len = (p - num_param);
+    if(*num_param != 0x00)
+    {
+        status = nfa_hciu_send_raw_cmd(p-p_data, p_data, nfa_hci_get_pipe_state_cb);
+    }
+    NFA_TRACE_DEBUG1 ("nfa_hci_getApduConnectivity_PipeStatus %x",*num_param);
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_get_pipe_state_cb
+**
+** Description      Callback API to retrieve APDU & Connectivity pipe created
+**                  status from FirmWare
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_get_pipe_state_cb(uint8_t event, uint16_t param_len, uint8_t* p_param)
+{
+    uint8_t num_param_id         = 0x00, xx;
+    uint8_t NFA_PARAM_ID_INDEX   = 0x04;
+    uint8_t param_id1 = 0x00;
+    uint8_t param_id2 = 0x00;
+    uint8_t status    = 0x00;
+
+    nfa_sys_stop_timer (&nfa_hci_cb.timer);
+    p_param += NFA_PARAM_ID_INDEX;
+    STREAM_TO_UINT8(num_param_id , p_param);
+    while(num_param_id > 0x00)
+    {
+        STREAM_TO_UINT8(param_id1 , p_param);
+        STREAM_TO_UINT8(param_id2 , p_param);
+        p_param++;
+        STREAM_TO_UINT8(status    , p_param);
+        if(param_id1 == NXP_NFC_SET_CONFIG_PARAM_EXT
+                && param_id2 == NXP_NFC_ESE_APDU_PIPE_STATUS)
+        {
+            /*Update eSE APDU pipe status*/
+            if(status == 1)
+            {
+                /*UINT8 local_gate, UINT8 pipe_id, UINT8 dest_host, UINT8 dest_gate*/
+                if(!nfa_hci_api_IspipePresent(NFA_HCI_HOST_ID_ESE, NFA_HCI_ETSI12_APDU_GATE))
+                {
+                    nfa_hci_update_pipe_status(NFA_HCI_ETSI12_APDU_GATE, NFA_HCI_APDU_PIPE);
+                    if(nfa_hciu_find_gate_by_gid (NFA_HCI_ETSI12_APDU_GATE) == NULL)
+                    {
+                        tNFA_HCI_DYN_GATE   *pg;
+                        int                 xx;
+                        for (xx = 0, pg = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
+                        {
+                            if (pg->gate_id == 0)
+                            {
+                                /* Found a free gate control block */
+                                pg->gate_id       = NFA_HCI_ETSI12_APDU_GATE;
+                                pg->gate_owner    = NFA_HANDLE_GROUP_HCI;
+                                pg->pipe_inx_mask = 0;
+
+                                NFA_TRACE_DEBUG2 ("nfa_hci_alloc_apdu_gate id:%d  app_handle: 0x%04x",
+                                NFA_HCI_ETSI12_APDU_GATE, NFA_HANDLE_GROUP_HCI);
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+            else
+            {
+                nfa_hciu_release_pipe (NFA_HCI_APDU_PIPE);
+            }
+        }
+        else if(param_id1 == NXP_NFC_SET_CONFIG_PARAM_EXT
+                && param_id2 == NXP_NFC_ESE_CONN_PIPE_STATUS)
+        {
+            /*Update eSE Connectivity pipe status*/
+            if(status == 1)
+            {
+                if(!nfa_hci_api_IspipePresent(NFA_HCI_HOST_ID_ESE, NFA_HCI_CONNECTIVITY_GATE))
+                {
+                    nfa_hci_update_pipe_status(NFA_HCI_CONNECTIVITY_GATE, NFA_HCI_CONN_ESE_PIPE);
+                }
+            }
+            else
+            {
+                nfa_hciu_release_pipe (NFA_HCI_CONN_ESE_PIPE);
+            }
+        }
+        num_param_id--;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_update_pipe_status
+**
+** Description      API to update APDU & Connectivity pipe hci_cfg status
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_update_pipe_status(uint8_t gateId, uint8_t pipeId)
+{
+    uint8_t count = 0;
+    nfa_hciu_add_pipe_to_static_gate(gateId, pipeId, NFA_HCI_HOST_ID_ESE, gateId);
+
+    /*Set the pipe status HCI_OPENED*/
+    for (count = 0;count < NFA_HCI_MAX_PIPE_CB;count++)
+    {
+        if(((nfa_hci_cb.cfg.dyn_pipes[count].dest_host) == NFA_HCI_HOST_ID_ESE) &&
+        ((nfa_hci_cb.cfg.dyn_pipes[count].dest_gate) == gateId)
+        &&((nfa_hci_cb.cfg.dyn_pipes[count].local_gate) == gateId))
+        {
+            NFA_TRACE_DEBUG1 ("Set the pipe state to open  -- %d !!!",nfa_hci_cb.cfg.dyn_pipes[count].pipe_id);
+            nfa_hci_cb.cfg.dyn_pipes[count].pipe_state = NFA_HCI_PIPE_OPENED;
+            break;
+        }
+    }
+}
+#endif
diff --git a/src/nfa/hci/nfa_hci_api.c b/src/nfa/hci/nfa_hci_api.c
new file mode 100644
index 0000000..0c499c7
--- /dev/null
+++ b/src/nfa/hci/nfa_hci_api.c
@@ -0,0 +1,1097 @@
+/******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  NFA interface to HCI
+ *
+ ******************************************************************************/
+#include <string.h>
+#include <unistd.h>
+#include "nfc_api.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "nfa_hci_api.h"
+#include "nfa_hci_int.h"
+#include "nfa_hci_defs.h"
+
+/*******************************************************************************
+**
+** Function         NFA_HciRegister
+**
+** Description      This function will register an application with hci and
+**                  returns an application handle and provides a mechanism to
+**                  register a callback with HCI to receive NFA HCI event
+**                  notification. When the application is registered (or if an
+**                  error occurs), the app will be notified with
+**                  NFA_HCI_REGISTER_EVT. Previous session information including
+**                  allocated gates, created pipes and pipes states will be
+**                  returned as part of tNFA_HCI_REGISTER data.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciRegister(char* p_app_name, tNFA_HCI_CBACK* p_cback,
+                            bool b_send_conn_evts) {
+  tNFA_HCI_API_REGISTER_APP* p_msg;
+  uint8_t app_name_len;
+
+  if (p_app_name == NULL) {
+    NFA_TRACE_API0("NFA_HciRegister (): Invalid Application name");
+    return (NFA_STATUS_FAILED);
+  }
+
+  if (p_cback == NULL) {
+    NFA_TRACE_API0(
+        "NFA_HciRegister (): Application should provide callback function to "
+        "register!");
+    return (NFA_STATUS_FAILED);
+  }
+
+  NFA_TRACE_API1("NFA_HciRegister (): Application Name: %s", p_app_name);
+
+  app_name_len = (uint8_t)strlen(p_app_name);
+
+  /* Register the application with HCI */
+  if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) &&
+      (p_app_name != NULL) && (app_name_len <= NFA_MAX_HCI_APP_NAME_LEN) &&
+      ((p_msg = (tNFA_HCI_API_REGISTER_APP*)GKI_getbuf(
+            sizeof(tNFA_HCI_API_REGISTER_APP))) != NULL)) {
+    p_msg->hdr.event = NFA_HCI_API_REGISTER_APP_EVT;
+
+        /* Save application name and callback */
+        memset (p_msg->app_name, 0, sizeof (p_msg->app_name));
+        NQ_STRLCPY_S (p_msg->app_name, sizeof (p_msg->app_name), p_app_name, NFA_MAX_HCI_APP_NAME_LEN);
+        p_msg->p_cback          = p_cback;
+        p_msg->b_send_conn_evts = b_send_conn_evts;
+
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciGetGateAndPipeList
+**
+** Description      This function will get the list of gates allocated to the
+**                  application and list of dynamic pipes created by the
+**                  application. The app will be notified with
+**                  NFA_HCI_GET_GATE_PIPE_LIST_EVT. List of allocated dynamic
+**                  gates to the application and list of pipes created by the
+**                  application will be returned as part of
+**                  tNFA_HCI_GET_GATE_PIPE_LIST data.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciGetGateAndPipeList(tNFA_HANDLE hci_handle) {
+  tNFA_HCI_API_GET_APP_GATE_PIPE* p_msg;
+
+  if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) {
+    NFA_TRACE_API1("NFA_HciGetGateAndPipeList (): Invalid hci_handle:0x%04x",
+                   hci_handle);
+    return (NFA_STATUS_FAILED);
+  }
+
+  NFA_TRACE_API1("NFA_HciGetGateAndPipeList (): hci_handle:0x%04x", hci_handle);
+
+  /* Register the application with HCI */
+  if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) &&
+      ((p_msg = (tNFA_HCI_API_GET_APP_GATE_PIPE*)GKI_getbuf(
+            sizeof(tNFA_HCI_API_GET_APP_GATE_PIPE))) != NULL)) {
+    p_msg->hdr.event = NFA_HCI_API_GET_APP_GATE_PIPE_EVT;
+    p_msg->hci_handle = hci_handle;
+
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciDeregister
+**
+** Description      This function is called to deregister an application
+**                  from HCI. The app will be notified by NFA_HCI_DEREGISTER_EVT
+**                  after deleting all the pipes owned by the app and
+**                  deallocating all the gates allocated to the app or if an
+**                  error occurs. Even if deregistration fails, the app has to
+**                  register again to provide a new cback function.
+**
+** Returns          NFA_STATUS_OK if the application is deregistered
+**                  successfully
+**                  NFA_STATUS_FAILED otherwise
+
+*******************************************************************************/
+tNFA_STATUS NFA_HciDeregister(char* p_app_name) {
+  tNFA_HCI_API_DEREGISTER_APP* p_msg;
+  int xx;
+  uint8_t app_name_len;
+
+  if (p_app_name == NULL) {
+    NFA_TRACE_API0("NFA_HciDeregister (): Invalid Application");
+    return (NFA_STATUS_FAILED);
+  }
+
+  NFA_TRACE_API1("NFA_HciDeregister (): Application Name: %s", p_app_name);
+  app_name_len = (uint8_t)strlen(p_app_name);
+
+  if (app_name_len > NFA_MAX_HCI_APP_NAME_LEN) return (NFA_STATUS_FAILED);
+
+  /* Find the application registration */
+  for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) {
+    if ((nfa_hci_cb.cfg.reg_app_names[xx][0] != 0) &&
+        (!strncmp(p_app_name, &nfa_hci_cb.cfg.reg_app_names[xx][0],
+                  app_name_len)))
+      break;
+  }
+
+  if (xx == NFA_HCI_MAX_APP_CB) {
+    NFA_TRACE_ERROR1("NFA_HciDeregister (): Application Name: %s  NOT FOUND",
+                     p_app_name);
+    return (NFA_STATUS_FAILED);
+  }
+
+  /* Deregister the application with HCI */
+  if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) &&
+      ((p_msg = (tNFA_HCI_API_DEREGISTER_APP*)GKI_getbuf(
+            sizeof(tNFA_HCI_API_DEREGISTER_APP))) != NULL)) {
+    p_msg->hdr.event = NFA_HCI_API_DEREGISTER_APP_EVT;
+
+        memset (p_msg->app_name, 0, sizeof (p_msg->app_name));
+        NQ_STRLCPY_S (p_msg->app_name, sizeof (p_msg->app_name), p_app_name, NFA_MAX_HCI_APP_NAME_LEN);
+
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciAllocGate
+**
+** Description      This function will allocate the gate if any specified or an
+**                  available generic gate for the app to provide an entry point
+**                  for a particular service to other host or to establish
+**                  communication with other host. When the gate is
+**                  allocated (or if an error occurs), the app will be notified
+**                  with NFA_HCI_ALLOCATE_GATE_EVT with the gate id. The
+**                  allocated Gate information will be stored in non volatile
+**                  memory.
+**
+** Returns          NFA_STATUS_OK if this API started
+**                  NFA_STATUS_FAILED if no generic gate is available
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciAllocGate(tNFA_HANDLE hci_handle, uint8_t gate) {
+  tNFA_HCI_API_ALLOC_GATE* p_msg;
+
+  if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) {
+    NFA_TRACE_API1("NFA_HciAllocGate (): Invalid hci_handle:0x%04x",
+                   hci_handle);
+    return (NFA_STATUS_FAILED);
+  }
+
+  if ((gate) && ((gate < NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE) ||
+                 (gate > NFA_HCI_LAST_PROP_GATE) ||
+                 (gate == NFA_HCI_CONNECTIVITY_GATE))) {
+    NFA_TRACE_API1("NFA_HciAllocGate (): Cannot allocate gate:0x%02x", gate);
+    return (NFA_STATUS_FAILED);
+  }
+
+  NFA_TRACE_API2("NFA_HciAllocGate (): hci_handle:0x%04x, Gate:0x%02x",
+                 hci_handle, gate);
+
+  /* Request HCI to allocate gate to the application */
+  if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) &&
+      ((p_msg = (tNFA_HCI_API_ALLOC_GATE*)GKI_getbuf(
+            sizeof(tNFA_HCI_API_ALLOC_GATE))) != NULL)) {
+    p_msg->hdr.event = NFA_HCI_API_ALLOC_GATE_EVT;
+    p_msg->hci_handle = hci_handle;
+    p_msg->gate = gate;
+
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciDeallocGate
+**
+** Description      This function will release the specified gate that was
+**                  previously allocated to the application. When the generic
+**                  gate is released (or if an error occurs), the app will be
+**                  notified with NFA_HCI_DEALLOCATE_GATE_EVT with the gate id.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciDeallocGate(tNFA_HANDLE hci_handle, uint8_t gate) {
+  tNFA_HCI_API_DEALLOC_GATE* p_msg;
+
+  if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) {
+    NFA_TRACE_API1("NFA_HciDeallocGate (): Invalid hci_handle:0x%04x",
+                   hci_handle);
+    return (NFA_STATUS_FAILED);
+  }
+
+  if ((gate < NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE) ||
+      (gate > NFA_HCI_LAST_PROP_GATE) || (gate == NFA_HCI_CONNECTIVITY_GATE)) {
+    NFA_TRACE_API1("NFA_HciDeallocGate (): Cannot deallocate the gate:0x%02x",
+                   gate);
+    return (NFA_STATUS_FAILED);
+  }
+
+  NFA_TRACE_API2("NFA_HciDeallocGate (): hci_handle:0x%04x, gate:0x%02X",
+                 hci_handle, gate);
+
+  /* Request HCI to deallocate the gate that was previously allocated to the
+   * application */
+  if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) &&
+      ((p_msg = (tNFA_HCI_API_DEALLOC_GATE*)GKI_getbuf(
+            sizeof(tNFA_HCI_API_DEALLOC_GATE))) != NULL)) {
+    p_msg->hdr.event = NFA_HCI_API_DEALLOC_GATE_EVT;
+    p_msg->hci_handle = hci_handle;
+    p_msg->gate = gate;
+
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciGetHostList
+**
+** Description      This function will request the host controller to return the
+**                  list of hosts that are present in the host network. When
+**                  host controller responds with the host list (or if an error
+**                  occurs), the app will be notified with NFA_HCI_HOST_LIST_EVT
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciGetHostList(tNFA_HANDLE hci_handle) {
+  tNFA_HCI_API_GET_HOST_LIST* p_msg;
+
+  if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) {
+    NFA_TRACE_API1("NFA_HciGetHostList (): Invalid hci_handle:0x%04x",
+                   hci_handle);
+    return (NFA_STATUS_FAILED);
+  }
+
+  NFA_TRACE_API1("NFA_HciGetHostList (): hci_handle:0x%04x", hci_handle);
+
+  /* Request HCI to get list of host in the hci network */
+  if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) &&
+      ((p_msg = (tNFA_HCI_API_GET_HOST_LIST*)GKI_getbuf(
+            sizeof(tNFA_HCI_API_GET_HOST_LIST))) != NULL)) {
+    p_msg->hdr.event = NFA_HCI_API_GET_HOST_LIST_EVT;
+    p_msg->hci_handle = hci_handle;
+
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciCreatePipe
+**
+** Description      This function is called to create a dynamic pipe with the
+**                  specified host. When the dynamic pipe is created (or
+**                  if an error occurs), the app will be notified with
+**                  NFA_HCI_CREATE_PIPE_EVT with the pipe id. If a pipe exists
+**                  between the two gates passed as argument and if it was
+**                  created earlier by the calling application then the pipe
+**                  id of the existing pipe will be returned and a new pipe
+**                  will not be created. After successful creation of pipe,
+**                  registry entry will be created for the dynamic pipe and
+**                  all information related to the pipe will be stored in non
+**                  volatile memory.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciCreatePipe(tNFA_HANDLE hci_handle, uint8_t source_gate_id,
+                              uint8_t dest_host, uint8_t dest_gate) {
+  tNFA_HCI_API_CREATE_PIPE_EVT* p_msg;
+  uint8_t xx;
+
+  NFA_TRACE_API4(
+      "NFA_HciCreatePipe (): hci_handle:0x%04x, source gate:0x%02X, "
+      "destination host:0x%02X , destination gate:0x%02X",
+      hci_handle, source_gate_id, dest_host, dest_gate);
+
+  if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) {
+    NFA_TRACE_API1("NFA_HciCreatePipe (): Invalid hci_handle:0x%04x",
+                   hci_handle);
+    return (NFA_STATUS_FAILED);
+  }
+
+  if ((source_gate_id < NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE) ||
+      (source_gate_id > NFA_HCI_LAST_PROP_GATE)) {
+    NFA_TRACE_API1("NFA_HciCreatePipe (): Invalid local Gate:0x%02x",
+                   source_gate_id);
+    return (NFA_STATUS_FAILED);
+  }
+
+  if (((dest_gate < NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE) &&
+       (dest_gate != NFA_HCI_LOOP_BACK_GATE) &&
+       (dest_gate != NFA_HCI_IDENTITY_MANAGEMENT_GATE)) ||
+      (dest_gate > NFA_HCI_LAST_PROP_GATE)) {
+    NFA_TRACE_API1("NFA_HciCreatePipe (): Invalid Destination Gate:0x%02x",
+                   dest_gate);
+    return (NFA_STATUS_FAILED);
+  }
+
+  for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++)
+    if (nfa_hci_cb.inactive_host[xx] == dest_host) break;
+
+  if (xx != NFA_HCI_MAX_HOST_IN_NETWORK) {
+    NFA_TRACE_API1("NFA_HciCreatePipe (): Host not active:0x%02x", dest_host);
+    return (NFA_STATUS_FAILED);
+  }
+
+  /* Request HCI to create a pipe between two specified gates */
+  if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) &&
+      (!nfa_hci_cb.b_low_power_mode) &&
+      ((p_msg = (tNFA_HCI_API_CREATE_PIPE_EVT*)GKI_getbuf(
+            sizeof(tNFA_HCI_API_CREATE_PIPE_EVT))) != NULL)) {
+    p_msg->hdr.event = NFA_HCI_API_CREATE_PIPE_EVT;
+    p_msg->hci_handle = hci_handle;
+    p_msg->source_gate = source_gate_id;
+    p_msg->dest_host = dest_host; /* Host id of the destination host */
+    p_msg->dest_gate = dest_gate; /* Gate id of the destination gate */
+
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciOpenPipe
+**
+** Description      This function is called to open a dynamic pipe.
+**                  When the dynamic pipe is opened (or
+**                  if an error occurs), the app will be notified with
+**                  NFA_HCI_OPEN_PIPE_EVT with the pipe id.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciOpenPipe(tNFA_HANDLE hci_handle, uint8_t pipe) {
+  tNFA_HCI_API_OPEN_PIPE_EVT* p_msg;
+
+  if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) {
+    NFA_TRACE_API1("NFA_HciOpenPipe (): Invalid hci_handle:0x%04x", hci_handle);
+    return (NFA_STATUS_FAILED);
+  }
+
+  if ((pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) ||
+      (pipe > NFA_HCI_LAST_DYNAMIC_PIPE)) {
+    NFA_TRACE_API1("NFA_HciOpenPipe (): Invalid Pipe:0x%02x", pipe);
+    return (NFA_STATUS_FAILED);
+  }
+
+  NFA_TRACE_API2("NFA_HciOpenPipe (): hci_handle:0x%04x, pipe:0x%02X",
+                 hci_handle, pipe);
+
+  /* Request HCI to open a pipe if it is in closed state */
+  if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) &&
+      (!nfa_hci_cb.b_low_power_mode) &&
+      ((p_msg = (tNFA_HCI_API_OPEN_PIPE_EVT*)GKI_getbuf(
+            sizeof(tNFA_HCI_API_OPEN_PIPE_EVT))) != NULL)) {
+    p_msg->hdr.event = NFA_HCI_API_OPEN_PIPE_EVT;
+    p_msg->hci_handle = hci_handle;
+    p_msg->pipe = pipe; /* Pipe ID of the pipe to open */
+
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciGetRegistry
+**
+** Description      This function requests a peer host to return the desired
+**                  registry field value for the gate that the pipe is on.
+**
+**                  When the peer host responds,the app is notified with
+**                  NFA_HCI_GET_REG_RSP_EVT or
+**                  if an error occurs in sending the command the app will be
+**                  notified by NFA_HCI_CMD_SENT_EVT
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciGetRegistry(tNFA_HANDLE hci_handle, uint8_t pipe,
+                               uint8_t reg_inx) {
+  tNFA_HCI_API_GET_REGISTRY* p_msg;
+
+  if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) {
+    NFA_TRACE_API1("NFA_HciGetRegistry (): Invalid hci_handle:0x%04x",
+                   hci_handle);
+    return (NFA_STATUS_FAILED);
+  }
+
+  if (pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) {
+    NFA_TRACE_API1("NFA_HciGetRegistry (): Invalid Pipe:0x%02x", pipe);
+    return (NFA_STATUS_FAILED);
+  }
+
+  NFA_TRACE_API2("NFA_HciGetRegistry (): hci_handle:0x%04x  Pipe: 0x%02x",
+                 hci_handle, pipe);
+
+  /* Request HCI to get list of gates supported by the specified host */
+  if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) &&
+      ((p_msg = (tNFA_HCI_API_GET_REGISTRY*)GKI_getbuf(
+            sizeof(tNFA_HCI_API_GET_REGISTRY))) != NULL)) {
+    p_msg->hdr.event = NFA_HCI_API_GET_REGISTRY_EVT;
+    p_msg->hci_handle = hci_handle;
+    p_msg->pipe = pipe;
+    p_msg->reg_inx = reg_inx;
+
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciSetRegistry
+**
+** Description      This function requests a peer host to set the desired
+**                  registry field value for the gate that the pipe is on.
+**
+**                  When the peer host responds,the app is notified with
+**                  NFA_HCI_SET_REG_RSP_EVT or
+**                  if an error occurs in sending the command the app will be
+**                  notified by NFA_HCI_CMD_SENT_EVT
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_HciSetRegistry(tNFA_HANDLE hci_handle, uint8_t pipe,
+                                      uint8_t reg_inx, uint8_t data_size,
+                                      uint8_t* p_data) {
+  tNFA_HCI_API_SET_REGISTRY* p_msg;
+
+  if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) {
+    NFA_TRACE_API1("NFA_HciSetRegistry (): Invalid hci_handle:0x%04x",
+                   hci_handle);
+    return (NFA_STATUS_FAILED);
+  }
+
+  if (pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) {
+    NFA_TRACE_API1("NFA_HciSetRegistry (): Invalid Pipe:0x%02x", pipe);
+    return (NFA_STATUS_FAILED);
+  }
+
+  if ((data_size == 0) || (p_data == NULL) ||
+      (data_size > NFA_MAX_HCI_CMD_LEN)) {
+    NFA_TRACE_API1("NFA_HciSetRegistry (): Invalid data size:0x%02x",
+                   data_size);
+    return (NFA_STATUS_FAILED);
+  }
+
+  NFA_TRACE_API2("NFA_HciSetRegistry (): hci_handle:0x%04x  Pipe: 0x%02x",
+                 hci_handle, pipe);
+
+  /* Request HCI to get list of gates supported by the specified host */
+  if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) &&
+      ((p_msg = (tNFA_HCI_API_SET_REGISTRY*)GKI_getbuf(
+            sizeof(tNFA_HCI_API_SET_REGISTRY))) != NULL)) {
+    p_msg->hdr.event = NFA_HCI_API_SET_REGISTRY_EVT;
+    p_msg->hci_handle = hci_handle;
+    p_msg->pipe = pipe;
+    p_msg->reg_inx = reg_inx;
+    p_msg->size = data_size;
+
+    memcpy(p_msg->data, p_data, data_size);
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciSendCommand
+**
+** Description      This function is called to send a command on a pipe created
+**                  by the application.
+**                  The app will be notified by NFA_HCI_CMD_SENT_EVT if an error
+**                  occurs.
+**                  When the peer host responds,the app is notified with
+**                  NFA_HCI_RSP_RCVD_EVT
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciSendCommand(tNFA_HANDLE hci_handle, uint8_t pipe,
+                               uint8_t cmd_code, uint16_t cmd_size,
+                               uint8_t* p_data) {
+  tNFA_HCI_API_SEND_CMD_EVT* p_msg;
+
+  if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) {
+    NFA_TRACE_API1("NFA_HciSendCommand (): Invalid hci_handle:0x%04x",
+                   hci_handle);
+    return (NFA_STATUS_FAILED);
+  }
+
+  if (pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) {
+    NFA_TRACE_API1("NFA_HciSendCommand (): Invalid Pipe:0x%02x", pipe);
+    return (NFA_STATUS_FAILED);
+  }
+
+  if ((cmd_size && (p_data == NULL)) || (cmd_size > NFA_MAX_HCI_CMD_LEN)) {
+    NFA_TRACE_API1("NFA_HciSendCommand (): Invalid cmd size:0x%02x", cmd_size);
+    return (NFA_STATUS_FAILED);
+  }
+
+  NFA_TRACE_API3(
+      "NFA_HciSendCommand (): hci_handle:0x%04x, pipe:0x%02x  Code: 0x%02x",
+      hci_handle, pipe, cmd_code);
+
+  /* Request HCI to post event data on a particular pipe */
+  if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) &&
+      ((p_msg = (tNFA_HCI_API_SEND_CMD_EVT*)GKI_getbuf(
+            sizeof(tNFA_HCI_API_SEND_CMD_EVT))) != NULL)) {
+    p_msg->hdr.event = NFA_HCI_API_SEND_CMD_EVT;
+    p_msg->hci_handle = hci_handle;
+    p_msg->pipe = pipe;
+    p_msg->cmd_code = cmd_code;
+    p_msg->cmd_len = cmd_size;
+
+    if (cmd_size) memcpy(p_msg->data, p_data, cmd_size);
+
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciSendResponse
+**
+** Description      This function is called to send a response on a pipe created
+**                  by the application.
+**                  The app will be notified by NFA_HCI_RSP_SENT_EVT if an error
+**                  occurs.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_HciSendResponse(tNFA_HANDLE hci_handle, uint8_t pipe,
+                                       uint8_t response, uint8_t data_size,
+                                       uint8_t* p_data) {
+  tNFA_HCI_API_SEND_RSP_EVT* p_msg;
+
+  if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) {
+    NFA_TRACE_API1("NFA_HciSendResponse (): Invalid hci_handle:0x%04x",
+                   hci_handle);
+    return (NFA_STATUS_FAILED);
+  }
+
+  if (pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) {
+    NFA_TRACE_API1("NFA_HciSendResponse (): Invalid Pipe:0x%02x", pipe);
+    return (NFA_STATUS_FAILED);
+  }
+
+  if ((data_size && (p_data == NULL)) || (data_size > NFA_MAX_HCI_RSP_LEN)) {
+    NFA_TRACE_API1("NFA_HciSendResponse (): Invalid data size:0x%02x",
+                   data_size);
+    return (NFA_STATUS_FAILED);
+  }
+
+  NFA_TRACE_API3(
+      "NFA_HciSendResponse (): hci_handle:0x%04x  Pipe: 0x%02x  Response: "
+      "0x%02x",
+      hci_handle, pipe, response);
+
+  /* Request HCI to get list of gates supported by the specified host */
+  if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) &&
+      ((p_msg = (tNFA_HCI_API_SEND_RSP_EVT*)GKI_getbuf(
+            sizeof(tNFA_HCI_API_SEND_RSP_EVT))) != NULL)) {
+    p_msg->hdr.event = NFA_HCI_API_SEND_RSP_EVT;
+    p_msg->hci_handle = hci_handle;
+    p_msg->response = response;
+    p_msg->size = data_size;
+
+    if (data_size) memcpy(p_msg->data, p_data, data_size);
+
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciSendEvent
+**
+** Description      This function is called to send any event on a pipe created
+**                  by the application.
+**                  The app will be notified by NFA_HCI_EVENT_SENT_EVT
+**                  after successfully sending the event on the specified pipe
+**                  or if an error occurs. The application should wait for this
+**                  event before releasing event buffer passed as argument.
+**                  If the app is expecting a response to the event then it can
+**                  provide response buffer for collecting the response. If it
+**                  provides a response buffer it can also provide response
+**                  timeout indicating maximum timeout for the response.
+**                  Maximum of NFA_MAX_HCI_EVENT_LEN bytes APDU can be received
+**                  using internal buffer if no response buffer is provided by
+**                  the application. The app will be notified by
+**                  NFA_HCI_EVENT_RCVD_EVT after receiving the response event
+**                  or on timeout if app provided response buffer and response
+**                  timeout. If response buffer and response timeout is provided
+**                  by the application, it should wait for this event before
+**                  releasing the response buffer. If the application did not
+**                  provide response timeout then it should not release the
+**                  response buffer until it receives NFA_HCI_EVENT_RCVD_EVT or
+**                  after timeout it sends next event on the same pipe
+**                  and receives NFA_HCI_EVENT_SENT_EVT for that event.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciSendEvent(tNFA_HANDLE hci_handle, uint8_t pipe,
+                             uint8_t evt_code, uint16_t evt_size,
+                             uint8_t* p_data, uint16_t rsp_size,
+                             uint8_t* p_rsp_buf,
+#if (NXP_EXTNS == TRUE)
+                             uint32_t rsp_timeout)
+#else
+                             uint16_t rsp_timeout)
+#endif
+{
+  tNFA_HCI_API_SEND_EVENT_EVT* p_msg;
+
+  NFA_TRACE_API3(
+      "NFA_HciSendEvent(): hci_handle:0x%04x, pipe:0x%02x  Code: 0x%02x",
+      hci_handle, pipe, evt_code);
+
+  if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) {
+    NFA_TRACE_API1("NFA_HciSendEvent (): Invalid hci_handle:0x%04x",
+                   hci_handle);
+    return (NFA_STATUS_FAILED);
+  }
+
+  if (pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) {
+    NFA_TRACE_API1("NFA_HciSendEvent (): Invalid Pipe:0x%02x", pipe);
+    return (NFA_STATUS_FAILED);
+  }
+
+  if (evt_size && (p_data == NULL)) {
+    NFA_TRACE_API1("NFA_HciSendEvent (): Invalid Event size:0x%02x", evt_size);
+    return (NFA_STATUS_FAILED);
+  }
+
+  if (rsp_size && (p_rsp_buf == NULL)) {
+    NFA_TRACE_API1(
+        "NFA_HciSendEvent (): No Event buffer, but invalid event buffer size "
+        ":%u",
+        rsp_size);
+    return (NFA_STATUS_FAILED);
+  }
+
+  /* Request HCI to post event data on a particular pipe */
+  if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) &&
+      ((p_msg = (tNFA_HCI_API_SEND_EVENT_EVT*)GKI_getbuf(
+            sizeof(tNFA_HCI_API_SEND_EVENT_EVT))) != NULL)) {
+    p_msg->hdr.event = NFA_HCI_API_SEND_EVENT_EVT;
+    p_msg->hci_handle = hci_handle;
+    p_msg->pipe = pipe;
+    p_msg->evt_code = evt_code;
+    p_msg->evt_len = evt_size;
+    p_msg->p_evt_buf = p_data;
+    p_msg->rsp_len = rsp_size;
+    p_msg->p_rsp_buf = p_rsp_buf;
+    p_msg->rsp_timeout = rsp_timeout;
+
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciClosePipe
+**
+** Description      This function is called to close a dynamic pipe.
+**                  When the dynamic pipe is closed (or
+**                  if an error occurs), the app will be notified with
+**                  NFA_HCI_CLOSE_PIPE_EVT with the pipe id.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciClosePipe(tNFA_HANDLE hci_handle, uint8_t pipe) {
+  tNFA_HCI_API_CLOSE_PIPE_EVT* p_msg;
+
+  NFA_TRACE_API2("NFA_HciClosePipe (): hci_handle:0x%04x, pipe:0x%02X",
+                 hci_handle, pipe);
+
+  if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) {
+    NFA_TRACE_API1("NFA_HciClosePipe (): Invalid hci_handle:0x%04x",
+                   hci_handle);
+    return (NFA_STATUS_FAILED);
+  }
+
+  if ((pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) ||
+      (pipe > NFA_HCI_LAST_DYNAMIC_PIPE)) {
+    NFA_TRACE_API1("NFA_HciClosePipe (): Invalid Pipe:0x%02x", pipe);
+    return (NFA_STATUS_FAILED);
+  }
+
+  /* Request HCI to close a pipe if it is in opened state */
+  if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) &&
+      (!nfa_hci_cb.b_low_power_mode) &&
+      ((p_msg = (tNFA_HCI_API_CLOSE_PIPE_EVT*)GKI_getbuf(
+            sizeof(tNFA_HCI_API_CLOSE_PIPE_EVT))) != NULL)) {
+    p_msg->hdr.event = NFA_HCI_API_CLOSE_PIPE_EVT;
+    p_msg->hci_handle = hci_handle;
+    p_msg->pipe = pipe;
+
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciDeletePipe
+**
+** Description      This function is called to delete a particular dynamic pipe.
+**                  When the dynamic pipe is deleted (or if an error occurs),
+**                  the app will be notified with NFA_HCI_DELETE_PIPE_EVT with
+**                  the pipe id. After successful deletion of pipe, registry
+**                  entry will be deleted for the dynamic pipe and all
+**                  information related to the pipe will be deleted from non
+**                  volatile memory.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciDeletePipe(tNFA_HANDLE hci_handle, uint8_t pipe) {
+  tNFA_HCI_API_DELETE_PIPE_EVT* p_msg;
+
+  if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) {
+    NFA_TRACE_API1("NFA_HciDeletePipe (): Invalid hci_handle:0x%04x",
+                   hci_handle);
+    return (NFA_STATUS_FAILED);
+  }
+
+  if ((pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) ||
+      (pipe > NFA_HCI_LAST_DYNAMIC_PIPE)) {
+    NFA_TRACE_API1("NFA_HciDeletePipe (): Invalid Pipe:0x%02x", pipe);
+    return (NFA_STATUS_FAILED);
+  }
+
+  NFA_TRACE_API2("NFA_HciDeletePipe (): hci_handle:0x%04x, pipe:0x%02X",
+                 hci_handle, pipe);
+
+  /* Request HCI to delete a pipe created by the application identified by hci
+   * handle */
+  if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) &&
+      (!nfa_hci_cb.b_low_power_mode) &&
+      ((p_msg = (tNFA_HCI_API_DELETE_PIPE_EVT*)GKI_getbuf(
+            sizeof(tNFA_HCI_API_DELETE_PIPE_EVT))) != NULL)) {
+    p_msg->hdr.event = NFA_HCI_API_DELETE_PIPE_EVT;
+    p_msg->hci_handle = hci_handle;
+    p_msg->pipe = pipe;
+
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciAddStaticPipe
+**
+** Description      This function is called to add a static pipe for sending
+**                  7816 APDUs. When the static pipe is added (or if an error
+**                  occurs), the app will be notified with
+**                  NFA_HCI_ADD_STATIC_PIPE_EVT with the status.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciAddStaticPipe(tNFA_HANDLE hci_handle, uint8_t host,
+                                 uint8_t gate, uint8_t pipe) {
+  tNFA_HCI_API_ADD_STATIC_PIPE_EVT* p_msg;
+  uint8_t xx;
+
+  if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI) {
+    NFA_TRACE_API1("NFA_HciAddStaticPipe (): Invalid hci_handle:0x%04x",
+                   hci_handle);
+    return (NFA_STATUS_FAILED);
+  }
+
+  for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++)
+    if (nfa_hci_cb.inactive_host[xx] == host) break;
+
+  if (xx != NFA_HCI_MAX_HOST_IN_NETWORK) {
+    NFA_TRACE_API1("NFA_HciAddStaticPipe (): Host not active:0x%02x", host);
+    return (NFA_STATUS_FAILED);
+  }
+
+  if ((gate <= NFA_HCI_LAST_HOST_SPECIFIC_GATE)
+#if (NXP_EXTNS == TRUE)
+      && ((nfcFL.nfccFL._UICC_CREATE_CONNECTIVITY_PIPE) &&
+              (gate != NFA_HCI_CONNECTIVITY_GATE))
+#endif
+          ) {
+    NFA_TRACE_API1("NFA_HciAddStaticPipe (): Invalid Gate:0x%02x", gate);
+    return (NFA_STATUS_FAILED);
+  }
+#if (NXP_EXTNS != TRUE)
+  if (pipe <= NFA_HCI_LAST_DYNAMIC_PIPE) {
+    NFA_TRACE_API1("NFA_HciAddStaticPipe (): Invalid Pipe:0x%02x", pipe);
+    return (NFA_STATUS_FAILED);
+  }
+#endif
+  NFA_TRACE_API2("NFA_HciAddStaticPipe (): hci_handle:0x%04x, pipe:0x%02X",
+                 hci_handle, pipe);
+
+  /* Request HCI to delete a pipe created by the application identified by hci
+   * handle */
+  if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) &&
+      ((p_msg = (tNFA_HCI_API_ADD_STATIC_PIPE_EVT*)GKI_getbuf(
+            sizeof(tNFA_HCI_API_ADD_STATIC_PIPE_EVT))) != NULL)) {
+    p_msg->hdr.event = NFA_HCI_API_ADD_STATIC_PIPE_EVT;
+    p_msg->hci_handle = hci_handle;
+    p_msg->host = host;
+    p_msg->gate = gate;
+    p_msg->pipe = pipe;
+
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+  /* Unable to add static pipe */
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciDebug
+**
+** Description      Debug function.
+**
+*******************************************************************************/
+void NFA_HciDebug(uint8_t action, uint8_t size, uint8_t* p_data) {
+  int xx;
+  tNFA_HCI_DYN_GATE* pg = nfa_hci_cb.cfg.dyn_gates;
+  tNFA_HCI_DYN_PIPE* pp = nfa_hci_cb.cfg.dyn_pipes;
+  NFC_HDR* p_msg;
+  uint8_t* p;
+
+  switch (action) {
+    case NFA_HCI_DEBUG_DISPLAY_CB:
+      NFA_TRACE_API0("NFA_HciDebug  Host List:");
+      for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) {
+        if (nfa_hci_cb.cfg.reg_app_names[xx][0] != 0) {
+          NFA_TRACE_API2("              Host Inx:  %u   Name: %s", xx,
+                         &nfa_hci_cb.cfg.reg_app_names[xx][0]);
+        }
+      }
+
+      NFA_TRACE_API0("NFA_HciDebug  Gate List:");
+      for (xx = 0; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++) {
+        if (pg->gate_id != 0) {
+          NFA_TRACE_API4(
+              "              Gate Inx: %x  ID: 0x%02x  Owner: 0x%04x  "
+              "PipeInxMask: 0x%08x",
+              xx, pg->gate_id, pg->gate_owner, pg->pipe_inx_mask);
+        }
+      }
+
+      NFA_TRACE_API0("NFA_HciDebug  Pipe List:");
+      for (xx = 0; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++) {
+        if (pp->pipe_id != 0) {
+          NFA_TRACE_API6(
+              "              Pipe Inx: %x  ID: 0x%02x  State: %u  LocalGate: "
+              "0x%02x  Dest Gate: 0x%02x  Host: 0x%02x",
+              xx, pp->pipe_id, pp->pipe_state, pp->local_gate, pp->dest_gate,
+              pp->dest_host);
+        }
+      }
+      break;
+
+    case NFA_HCI_DEBUG_SIM_HCI_EVENT:
+      p_msg = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+      if (p_msg != NULL) {
+        p = (uint8_t*)(p_msg + 1);
+
+        p_msg->event = NFA_HCI_CHECK_QUEUE_EVT;
+        p_msg->len = size;
+        p_msg->offset = 0;
+
+        memcpy(p, p_data, size);
+
+        nfa_sys_sendmsg(p_msg);
+      }
+      break;
+
+    case NFA_HCI_DEBUG_ENABLE_LOOPBACK:
+      NFA_TRACE_API0("NFA_HciDebug  HCI_LOOPBACK_DEBUG = true");
+      HCI_LOOPBACK_DEBUG = true;
+      break;
+
+    case NFA_HCI_DEBUG_DISABLE_LOOPBACK:
+      NFA_TRACE_API0("NFA_HciDebug  HCI_LOOPBACK_DEBUG = false");
+      HCI_LOOPBACK_DEBUG = false;
+      break;
+  }
+}
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         NFA_MW_Fwdnlwd_Recovery
+**
+** Description      This function is called to make the MW_RCVRY_FW_DNLD_ALLOWED
+*true
+**                  not allowing the FW download while MW recovery.
+**
+** Returns          None
+**
+*******************************************************************************/
+bool NFA_MW_Fwdnlwd_Recovery(bool mw_fwdnld_recovery) {
+    if(!nfcFL.nfccFL._NFCC_MW_RCVRY_BLK_FW_DNLD) {
+        NFA_TRACE_API0("NFA_MW_Fwdnlwd_Recovery"
+                "  NFCC_MW_RCVRY_BLK_FW_DNLD not available. Returning");
+        return false;
+    }
+    if (mw_fwdnld_recovery) {
+        MW_RCVRY_FW_DNLD_ALLOWED = true;
+    } else {
+        MW_RCVRY_FW_DNLD_ALLOWED = false;
+    }
+    return mw_fwdnld_recovery;
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciW4eSETransaction_Complete
+**
+** Description      This function is called to wait for eSE transaction
+**                  to complete before NFCC shutdown or NFC service turn OFF
+**
+** Returns          None
+**
+*******************************************************************************/
+void NFA_HciW4eSETransaction_Complete(tNFA_HCI_TRANSCV_STATE type) {
+  NFA_TRACE_API1("NFA_HciW4eSETransaction_Complete; type=%u", type);
+  uint8_t retry_cnt = 0;
+  uint8_t max_time = NFA_HCI_MAX_RSP_WAIT_TIME;
+
+  if (type == Release) {
+    nfa_hci_release_transcieve();
+  } else {
+    do {
+      if (nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_RSP) {
+        sleep(1);
+      } else
+        break;
+    } while (retry_cnt++ < max_time);
+  }
+  NFA_TRACE_API0("NFA_HciW4eSETransaction_Complete; End");
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciConfigureNfceeETSI12
+**
+** Description      This function is called to configure individual NFCEE to
+**                  according HCI ETSI12 standard.
+**
+**                  When the peer host responds,the app is notified with
+**                  NFA_HCI_RSP_RCVD_EVT
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciConfigureNfceeETSI12() {
+  tNFA_HCI_API_CONFIGURE_EVT* p_msg;
+  NFA_TRACE_API0("NFA_HciConfigureNfceeETSI12 (): Entry");
+
+  /* Request HCI to post event data on a Admin pipe */
+  /* Register the application with HCI */
+  if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED) &&
+      (nfa_hci_cb.host_count != 0) &&
+      ((p_msg = (tNFA_HCI_API_CONFIGURE_EVT*)GKI_getbuf(
+            sizeof(tNFA_HCI_API_CONFIGURE_EVT))) != NULL)) {
+    NFA_TRACE_API1("NFA_HciConfigureNfceeETSI12 (): Entry HCI state - %d",
+                   nfa_hci_cb.hci_state);
+    p_msg->hdr.event = NFA_HCI_API_CONFIGURE_EVT;
+    p_msg->config_nfcee_event = NFA_HCI_INIT_NFCEE_CONFIG;
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+#endif
diff --git a/src/nfa/hci/nfa_hci_ci.c b/src/nfa/hci/nfa_hci_ci.c
new file mode 100644
index 0000000..0cdcf93
--- /dev/null
+++ b/src/nfa/hci/nfa_hci_ci.c
@@ -0,0 +1,76 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the call-in functions for NFA HCI
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_sys.h"
+#include "nfa_hci_api.h"
+#include "nfa_hci_int.h"
+#include "nfa_nv_co.h"
+
+/*******************************************************************************
+**
+** Function         nfa_nv_ci_read
+**
+** Description      call-in function for non volatile memory read acess
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_nv_ci_read(uint16_t num_bytes_read, tNFA_NV_CO_STATUS status,
+                    uint8_t block) {
+  tNFA_HCI_EVENT_DATA* p_msg;
+
+  p_msg = (tNFA_HCI_EVENT_DATA*)GKI_getbuf(sizeof(tNFA_HCI_EVENT_DATA));
+  if (p_msg != NULL) {
+    p_msg->nv_read.hdr.event = NFA_HCI_RSP_NV_READ_EVT;
+
+    if ((status == NFA_STATUS_OK) && (num_bytes_read != 0))
+      p_msg->nv_read.status = NFA_STATUS_OK;
+    else
+      p_msg->nv_read.status = NFA_STATUS_FAILED;
+
+    p_msg->nv_read.size = num_bytes_read;
+    p_msg->nv_read.block = block;
+    nfa_sys_sendmsg(p_msg);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_nv_ci_write
+**
+** Description      call-in function for non volatile memory write acess
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_nv_ci_write(tNFA_NV_CO_STATUS status) {
+  tNFA_HCI_EVENT_DATA* p_msg;
+  (void)status;
+  p_msg = (tNFA_HCI_EVENT_DATA*)GKI_getbuf(sizeof(tNFA_HCI_EVENT_DATA));
+  if (p_msg != NULL) {
+    p_msg->nv_write.hdr.event = NFA_HCI_RSP_NV_WRITE_EVT;
+    p_msg->nv_write.status = 0;
+    nfa_sys_sendmsg(p_msg);
+  }
+}
diff --git a/src/nfa/hci/nfa_hci_main.c b/src/nfa/hci/nfa_hci_main.c
new file mode 100644
index 0000000..56399fd
--- /dev/null
+++ b/src/nfa/hci/nfa_hci_main.c
@@ -0,0 +1,1988 @@
+/******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the main implementation file for the NFA HCI.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_api.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "nfa_dm_int.h"
+#include "nfa_hci_api.h"
+#include "nfa_hci_int.h"
+#include "nfa_ee_api.h"
+#include "nfa_ee_int.h"
+#include "nfa_nv_co.h"
+#include "nfa_mem_co.h"
+#include "nfa_hci_defs.h"
+#include "trace_api.h"
+
+#if (NXP_EXTNS == TRUE)
+#ifndef __CONFIG_H
+#include <config.h>
+#include <stdlib.h>
+#endif
+#endif
+/*****************************************************************************
+**  Global Variables
+*****************************************************************************/
+
+tNFA_HCI_CB nfa_hci_cb;
+
+#ifndef NFA_HCI_NV_READ_TIMEOUT_VAL
+#define NFA_HCI_NV_READ_TIMEOUT_VAL 1000
+#endif
+
+#ifndef NFA_HCI_CON_CREATE_TIMEOUT_VAL
+#define NFA_HCI_CON_CREATE_TIMEOUT_VAL 1000
+#endif
+
+/*****************************************************************************
+**  Static Functions
+*****************************************************************************/
+
+/* event handler function type */
+static bool nfa_hci_evt_hdlr(NFC_HDR* p_msg);
+
+static void nfa_hci_sys_enable(void);
+static void nfa_hci_sys_disable(void);
+extern void nfa_hci_conn_cback(uint8_t conn_id, tNFC_CONN_EVT event,
+                               tNFC_CONN* p_data);
+static void nfa_hci_set_receive_buf(uint8_t pipe);
+#if (NXP_EXTNS == TRUE)
+void nfa_hci_rsp_timeout(tNFA_HCI_EVENT_DATA* p_evt_data);
+static void nfa_hci_assemble_msg(uint8_t* p_data, uint16_t data_len,
+                                 uint8_t pipe);
+static uint8_t nfa_ee_ce_p61_completed = 0x00;
+static void nfa_hci_reset_session_rsp_cb(uint8_t event, uint16_t param_len,
+                                         uint8_t* p_param);
+bool nfa_hci_is_valid_ese_cfg(void);
+static void read_config_timeout_param_values();
+#else
+static void nfa_hci_assemble_msg(uint8_t* p_data, uint16_t data_len);
+#endif
+static void nfa_hci_handle_nv_read(uint8_t block, tNFA_STATUS status);
+void nfa_hci_network_enable(void);
+
+/*****************************************************************************
+**  Constants
+*****************************************************************************/
+static const tNFA_SYS_REG nfa_hci_sys_reg = {
+    nfa_hci_sys_enable, nfa_hci_evt_hdlr, nfa_hci_sys_disable,
+    nfa_hci_proc_nfcc_power_mode};
+
+/*******************************************************************************
+**
+** Function         nfa_hci_ee_info_cback
+**
+** Description      Callback function
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hci_ee_info_cback(tNFA_EE_DISC_STS status) {
+  uint8_t xx;
+  uint8_t host_index = 0x00;
+
+  NFA_TRACE_DEBUG1("nfa_hci_ee_info_cback (): %d", status);
+
+  switch (status) {
+    case NFA_EE_DISC_STS_ON:
+      if ((!nfa_hci_cb.ee_disc_cmplt) &&
+          ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) ||
+           (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE))) {
+        /* NFCEE Discovery is in progress */
+        nfa_hci_cb.ee_disc_cmplt = true;
+        nfa_hci_cb.num_ee_dis_req_ntf = 0;
+        nfa_hci_cb.num_hot_plug_evts = 0;
+        nfa_hci_cb.conn_id = 0;
+        nfa_hci_startup();
+      }
+      break;
+
+    case NFA_EE_DISC_STS_OFF:
+      if (nfa_hci_cb.ee_disable_disc) break;
+      nfa_hci_cb.ee_disable_disc = true;
+      /* Discovery operation is complete, retrieve discovery result */
+      NFA_EeGetInfo(&nfa_hci_cb.num_nfcee, nfa_hci_cb.ee_info);
+
+      if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
+          (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
+        if ((nfa_hci_cb.num_nfcee <= 1) ||
+            (nfa_hci_cb.num_ee_dis_req_ntf == (nfa_hci_cb.num_nfcee - 1)) ||
+            (nfa_hci_cb.num_hot_plug_evts == (nfa_hci_cb.num_nfcee - 1))) {
+          /* No UICC Host is detected or
+           * HOT_PLUG_EVT(s) and or EE DISC REQ Ntf(s) are already received
+           * Get Host list and notify SYS on Initialization complete */
+          nfa_sys_stop_timer(&nfa_hci_cb.timer);
+          if ((nfa_hci_cb.num_nfcee > 1) &&
+              (nfa_hci_cb.num_ee_dis_req_ntf != (nfa_hci_cb.num_nfcee - 1))) {
+            /* Received HOT PLUG EVT, we will also wait for EE DISC REQ Ntf(s)
+             */
+            nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
+                                p_nfa_hci_cfg->hci_netwk_enable_timeout);
+          } else {
+              nfa_hci_cb.w4_hci_netwk_init = false;
+              nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
+                                        NFA_HCI_HOST_LIST_INDEX);
+          }
+        }
+#if (NXP_EXTNS == TRUE)
+        /* All the EE_DISC_NTF's received
+         * Avoid 4sec delay during HCI initialization
+         */
+        if (nfa_hci_cb.w4_hci_netwk_init && nfa_hci_cb.timer.in_use) {
+          nfa_sys_stop_timer(&nfa_hci_cb.timer);
+          nfa_hci_cb.w4_hci_netwk_init = false;
+          nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
+                                      NFA_HCI_HOST_LIST_INDEX);
+        }
+#endif
+      } else if (nfa_hci_cb.num_nfcee <= 1) {
+        /* No UICC Host is detected, HCI NETWORK is enabled */
+        nfa_hci_cb.w4_hci_netwk_init = false;
+      }
+      NFA_TRACE_DEBUG1("nfa_hci_ee_info_cback (): %d  nfa_hci_cb.num_nfcee",  nfa_hci_cb.num_nfcee);
+
+#if (NXP_EXTNS == TRUE)
+      if (nfa_hci_cb.hci_state == NFA_HCI_STATE_NFCEE_ENABLE &&
+          nfa_hci_cb.nfcee_cfg.config_nfcee_state ==
+              NFA_HCI_GET_NUM_NFCEE_CONFIGURED) {
+        nfa_sys_stop_timer(&nfa_hci_cb.timer);
+        /* New EE discovered , update the result*/
+        nfa_hci_cb.num_nfcee = NFA_HCI_MAX_HOST_IN_NETWORK;
+        NFA_AllEeGetInfo(&nfa_hci_cb.num_nfcee, nfa_hci_cb.hci_ee_info);
+        for (xx = 0; xx < nfa_hci_cb.num_nfcee; xx++) {
+          if ((((nfa_hci_cb.hci_ee_info[xx].ee_interface[0] !=
+              NCI_NFCEE_INTERFACE_HCI_ACCESS)&&
+              nfa_hci_cb.hci_ee_info[xx].ee_status == NFA_EE_STATUS_ACTIVE)) &&
+              (nfa_hci_cb.hci_ee_info[xx].ee_handle != 0x410)) {
+            nfa_hci_cb.nfcee_cfg.host_cb[host_index++] =
+                nfa_hci_cb.hci_ee_info[xx].ee_handle;
+            NFA_TRACE_DEBUG1(" handle id   -%x",
+                             nfa_hci_cb.hci_ee_info[xx].ee_handle);
+          }
+        }
+        nfa_hci_handle_nfcee_config_evt(NFA_HCI_READ_SESSIONID);
+      }
+#endif
+      break;
+#if (NXP_EXTNS == TRUE)
+    case NFA_EE_MODE_SET_NTF:
+      if (nfa_hci_cb.hci_state == NFA_HCI_STATE_NFCEE_ENABLE) {
+        NFA_TRACE_DEBUG0("ETSI12 pipe creation configured");
+        nfa_hci_api_config_nfcee(nfa_hci_cb.current_nfcee);
+      }
+      break;
+#endif
+    case NFA_EE_DISC_STS_REQ:
+      nfa_hci_cb.num_ee_dis_req_ntf++;
+    if(nfa_hci_cb.w4_nfcee_enable == true)
+      break;
+#if (NXP_EXTNS == TRUE)
+      if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
+          (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
+        nfa_sys_stop_timer(&nfa_hci_cb.timer);
+        nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, 150);
+      }
+#endif
+      if (nfa_hci_cb.ee_disable_disc) {
+        /* Already received Discovery Ntf */
+        if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
+            (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
+          /* Received DISC REQ Ntf while waiting for other Host in the network
+           * to bootup after DH host bootup is complete */
+            if (nfa_hci_cb.num_ee_dis_req_ntf == (nfa_hci_cb.num_nfcee - 1)) {
+              /* Received expected number of EE DISC REQ Ntf(s) */
+              nfa_sys_stop_timer(&nfa_hci_cb.timer);
+              nfa_hci_cb.w4_hci_netwk_init = false;
+              nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
+                                        NFA_HCI_HOST_LIST_INDEX);
+            }
+        } else if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) ||
+                   (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE)) {
+          /* Received DISC REQ Ntf during DH host bootup */
+          if (nfa_hci_cb.num_ee_dis_req_ntf == (nfa_hci_cb.num_nfcee - 1)) {
+            /* Received expected number of EE DISC REQ Ntf(s) */
+            nfa_hci_cb.w4_hci_netwk_init = false;
+          }
+        }
+      }
+      break;
+    case NFA_EE_MODE_SET_COMPLETE:
+        /*received mode set Ntf */
+        NFA_TRACE_DEBUG1("nfa_hci_ee_info_cback (): %d  nfa_hci_cb.hci_state", nfa_hci_cb.hci_state);
+        if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
+            (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)||
+            (nfa_hci_cb.hci_state == NFA_HCI_STATE_EE_RECOVERY)
+            ) {
+            /* Discovery operation is complete, retrieve discovery result */
+          NFA_EeGetInfo(&nfa_hci_cb.num_nfcee, nfa_hci_cb.ee_info);
+          nfa_hci_enable_one_nfcee();
+        }
+        else if(nfa_hci_cb.hci_state == NFA_HCI_STATE_NFCEE_ENABLE)
+        {
+            nfa_hci_api_config_nfcee(nfa_hci_cb.current_nfcee);
+        }
+      break;
+    case NFA_EE_RECOVERY:
+        /*NFCEE recovery in progress*/
+        if (!((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
+            (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE))) {
+          if (NFA_DM_RFST_DISCOVERY == nfa_dm_cb.disc_cb.disc_state)
+            nfa_hci_cb.nfcee_cfg.discovery_stopped = nfa_dm_act_stop_rf_discovery(NULL);
+          if(NFC_NfceeDiscover(true) == NFC_STATUS_FAILED){
+            if(nfa_hci_cb.nfcee_cfg.discovery_stopped == true) {
+              nfa_dm_act_start_rf_discovery(NULL);
+              nfa_hci_cb.nfcee_cfg.discovery_stopped = false;
+            }
+          } else {
+              nfa_hci_cb.hci_state = NFA_HCI_STATE_EE_RECOVERY;
+          }
+        }
+        break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_init
+**
+** Description      Initialize NFA HCI
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hci_init(void) {
+  NFA_TRACE_DEBUG0("nfa_hci_init ()");
+
+  /* initialize control block */
+  memset(&nfa_hci_cb, 0, sizeof(tNFA_HCI_CB));
+  nfa_hci_cb.hci_state = NFA_HCI_STATE_STARTUP;
+  nfa_hci_cb.num_nfcee = NFA_HCI_MAX_HOST_IN_NETWORK;
+#if (NXP_EXTNS == TRUE)
+  nfa_ee_ce_p61_completed = 0;
+  nfa_hci_cb.bIsHciResponseTimedout = false;
+  nfa_hci_cb.IsHciTimerChanged = false;
+  nfa_hci_cb.IsWiredSessionAborted = false;
+  nfa_hci_cb.IsLastEvtAbortFailed = false;
+  read_config_timeout_param_values();
+#endif
+  /* register message handler on NFA SYS */
+  nfa_sys_register(NFA_ID_HCI, &nfa_hci_sys_reg);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_is_valid_cfg
+**
+** Description      Validate hci control block config parameters
+**
+** Returns          None
+**
+*******************************************************************************/
+bool nfa_hci_is_valid_cfg(void) {
+  uint8_t xx, yy, zz;
+  tNFA_HANDLE reg_app[NFA_HCI_MAX_APP_CB];
+  uint8_t valid_gate[NFA_HCI_MAX_GATE_CB];
+  uint8_t app_count = 0;
+  uint8_t gate_count = 0;
+  uint32_t pipe_inx_mask = 0;
+  uint8_t validated_gate_count = 0;
+
+  /* First, see if valid values are stored in app names, send connectivity
+   * events flag */
+  for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) {
+    /* Check if app name is valid with null terminated string */
+    if (strlen(&nfa_hci_cb.cfg.reg_app_names[xx][0]) > NFA_MAX_HCI_APP_NAME_LEN)
+      return false;
+
+    /* Send Connectivity event flag can be either true or false */
+    if ((nfa_hci_cb.cfg.b_send_conn_evts[xx] != true) &&
+        (nfa_hci_cb.cfg.b_send_conn_evts[xx] != false))
+      return false;
+
+    if (nfa_hci_cb.cfg.reg_app_names[xx][0] != 0) {
+      /* Check if the app name is present more than one time in the control
+       * block */
+      for (yy = xx + 1; yy < NFA_HCI_MAX_APP_CB; yy++) {
+        if ((nfa_hci_cb.cfg.reg_app_names[yy][0] != 0) &&
+            (!strncmp(&nfa_hci_cb.cfg.reg_app_names[xx][0],
+                      &nfa_hci_cb.cfg.reg_app_names[yy][0],
+                      strlen(nfa_hci_cb.cfg.reg_app_names[xx])))) {
+          /* Two app cannot have the same name , NVRAM is corrupted */
+          NFA_TRACE_EVENT2("nfa_hci_is_valid_cfg (%s)  Reusing: %u",
+                           &nfa_hci_cb.cfg.reg_app_names[xx][0], xx);
+          return false;
+        }
+      }
+      /* Collect list of hci handle */
+      reg_app[app_count++] = (tNFA_HANDLE)(xx | NFA_HANDLE_GROUP_HCI);
+    }
+  }
+
+  /* Validate Gate Control block */
+  for (xx = 0; xx < NFA_HCI_MAX_GATE_CB; xx++) {
+    if (nfa_hci_cb.cfg.dyn_gates[xx].gate_id != 0) {
+      if (((nfa_hci_cb.cfg.dyn_gates[xx].gate_id != NFA_HCI_LOOP_BACK_GATE) &&
+           (nfa_hci_cb.cfg.dyn_gates[xx].gate_id !=
+            NFA_HCI_IDENTITY_MANAGEMENT_GATE) &&
+           (nfa_hci_cb.cfg.dyn_gates[xx].gate_id <
+            NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE)) ||
+          (nfa_hci_cb.cfg.dyn_gates[xx].gate_id > NFA_HCI_LAST_PROP_GATE))
+        return false;
+
+      /* Check if the same gate id is present more than once in the control
+       * block */
+      for (yy = xx + 1; yy < NFA_HCI_MAX_GATE_CB; yy++) {
+        if ((nfa_hci_cb.cfg.dyn_gates[yy].gate_id != 0) &&
+            (nfa_hci_cb.cfg.dyn_gates[xx].gate_id ==
+             nfa_hci_cb.cfg.dyn_gates[yy].gate_id)) {
+          NFA_TRACE_EVENT1("nfa_hci_is_valid_cfg  Reusing: %u",
+                           nfa_hci_cb.cfg.dyn_gates[xx].gate_id);
+          return false;
+        }
+      }
+      if ((nfa_hci_cb.cfg.dyn_gates[xx].gate_owner & (~NFA_HANDLE_GROUP_HCI)) >=
+          NFA_HCI_MAX_APP_CB) {
+        NFA_TRACE_EVENT1("nfa_hci_is_valid_cfg  Invalid Gate owner: %u",
+                         nfa_hci_cb.cfg.dyn_gates[xx].gate_owner);
+        return false;
+      }
+      if (!((nfa_hci_cb.cfg.dyn_gates[xx].gate_id == NFA_HCI_CONNECTIVITY_GATE)||
+           (nfa_hci_cb.cfg.dyn_gates[xx].gate_id >= NFA_HCI_FIRST_PROP_GATE) ||
+            ((nfa_hci_cb.cfg.dyn_gates[xx].gate_id <= NFA_HCI_LAST_PROP_GATE)))) {
+        /* The gate owner should be one of the registered application */
+        for (zz = 0; zz < app_count; zz++) {
+          if (nfa_hci_cb.cfg.dyn_gates[xx].gate_owner == reg_app[zz]) break;
+        }
+        if (zz == app_count) {
+          NFA_TRACE_EVENT1("nfa_hci_is_valid_cfg  Invalid Gate owner: %u",
+                           nfa_hci_cb.cfg.dyn_gates[xx].gate_owner);
+          return false;
+        }
+      }
+      /* Collect list of allocated gates */
+      valid_gate[gate_count++] = nfa_hci_cb.cfg.dyn_gates[xx].gate_id;
+
+      /* No two gates can own a same pipe */
+      if ((pipe_inx_mask & nfa_hci_cb.cfg.dyn_gates[xx].pipe_inx_mask) != 0)
+        return false;
+      /* Collect the list of pipes on this gate */
+      pipe_inx_mask |= nfa_hci_cb.cfg.dyn_gates[xx].pipe_inx_mask;
+    }
+  }
+
+  for (xx = 0; (pipe_inx_mask && (xx < NFA_HCI_MAX_PIPE_CB));
+       xx++, pipe_inx_mask >>= 1) {
+    /* Every bit set in pipe increment mask indicates a valid pipe */
+    if (pipe_inx_mask & 1) {
+      /* Check if the pipe is valid one */
+      if (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id < NFA_HCI_FIRST_DYNAMIC_PIPE)
+        return false;
+    }
+  }
+
+  if (xx == NFA_HCI_MAX_PIPE_CB) return false;
+
+  /* Validate Gate Control block */
+  for (xx = 0; xx < NFA_HCI_MAX_PIPE_CB; xx++) {
+    if (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id != 0) {
+      /* Check if pipe id is valid */
+      if (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id < NFA_HCI_FIRST_DYNAMIC_PIPE)
+        return false;
+
+      /* Check if pipe state is valid */
+      if ((nfa_hci_cb.cfg.dyn_pipes[xx].pipe_state != NFA_HCI_PIPE_OPENED) &&
+          (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_state != NFA_HCI_PIPE_CLOSED))
+        return false;
+
+      /* Check if local gate on which the pipe is created is valid */
+      if ((((nfa_hci_cb.cfg.dyn_pipes[xx].local_gate !=
+             NFA_HCI_LOOP_BACK_GATE) &&
+            (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate !=
+             NFA_HCI_IDENTITY_MANAGEMENT_GATE)) &&
+           (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate <
+            NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE)) ||
+          (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate > NFA_HCI_LAST_PROP_GATE))
+        return false;
+
+      /* Check if the peer gate on which the pipe is created is valid */
+      if ((((nfa_hci_cb.cfg.dyn_pipes[xx].dest_gate !=
+             NFA_HCI_LOOP_BACK_GATE) &&
+            (nfa_hci_cb.cfg.dyn_pipes[xx].dest_gate !=
+             NFA_HCI_IDENTITY_MANAGEMENT_GATE)) &&
+           (nfa_hci_cb.cfg.dyn_pipes[xx].dest_gate <
+            NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE)) ||
+          (nfa_hci_cb.cfg.dyn_pipes[xx].dest_gate > NFA_HCI_LAST_PROP_GATE))
+        return false;
+
+      if ((xx + 1) < NFA_HCI_MAX_PIPE_CB) {
+        /* Check if the same pipe is present more than once in the control block
+         */
+        for (yy = xx + 1; yy < NFA_HCI_MAX_PIPE_CB; yy++) {
+          if ((nfa_hci_cb.cfg.dyn_pipes[yy].pipe_id != 0) &&
+              (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id ==
+               nfa_hci_cb.cfg.dyn_pipes[yy].pipe_id)) {
+            NFA_TRACE_EVENT1("nfa_hci_is_valid_cfg  Reusing: %u",
+                             nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id);
+            return false;
+          }
+        }
+      }
+#if (NXP_EXTNS == FALSE)
+      /* The local gate should be one of the element in gate control block */
+      for (zz = 0; zz < gate_count; zz++) {
+        if (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate == valid_gate[zz]) break;
+      }
+      if (zz == gate_count) {
+        NFA_TRACE_EVENT1("nfa_hci_is_valid_cfg  Invalid Gate: %u",
+                         nfa_hci_cb.cfg.dyn_pipes[xx].local_gate);
+        return false;
+      }
+#else
+      /* The local gate should be one of the element in gate control block */
+      for (zz = 0; zz < gate_count; zz++) {
+        if (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate == valid_gate[zz]) {
+          validated_gate_count++;
+          break;
+        }
+      }
+
+#endif
+    }
+  }
+#if (NXP_EXTNS == TRUE)
+  if (validated_gate_count != gate_count && xx > NFA_HCI_MAX_PIPE_CB) {
+    NFA_TRACE_EVENT1("nfa_hci_is_valid_cfg  Invalid Gate: %u",
+                     nfa_hci_cb.cfg.dyn_pipes[xx].local_gate);
+    return false;
+  }
+#endif
+
+  /* Check if admin pipe state is valid */
+  if ((nfa_hci_cb.cfg.admin_gate.pipe01_state != NFA_HCI_PIPE_OPENED) &&
+      (nfa_hci_cb.cfg.admin_gate.pipe01_state != NFA_HCI_PIPE_CLOSED))
+    return false;
+
+  /* Check if link management pipe state is valid */
+  if ((nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state != NFA_HCI_PIPE_OPENED) &&
+      (nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state != NFA_HCI_PIPE_CLOSED))
+    return false;
+
+  pipe_inx_mask = nfa_hci_cb.cfg.id_mgmt_gate.pipe_inx_mask;
+  for (xx = 0; (pipe_inx_mask && (xx < NFA_HCI_MAX_PIPE_CB));
+       xx++, pipe_inx_mask >>= 1) {
+    /* Every bit set in pipe increment mask indicates a valid pipe */
+    if (pipe_inx_mask & 1) {
+      /* Check if the pipe is valid one */
+      if (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id < NFA_HCI_FIRST_DYNAMIC_PIPE)
+        return false;
+      /* Check if the pipe is connected to Identity management gate */
+      if (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate !=
+          NFA_HCI_IDENTITY_MANAGEMENT_GATE)
+        return false;
+    }
+  }
+  if (xx == NFA_HCI_MAX_PIPE_CB) return false;
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_cfg_default
+**
+** Description      Configure default values for hci control block
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hci_restore_default_config(uint8_t* p_session_id) {
+  memset(&nfa_hci_cb.cfg, 0, sizeof(nfa_hci_cb.cfg));
+  memcpy(nfa_hci_cb.cfg.admin_gate.session_id, p_session_id,
+         NFA_HCI_SESSION_ID_LEN);
+  nfa_hci_cb.nv_write_needed = true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_proc_nfcc_power_mode
+**
+** Description      Restore NFA HCI sub-module
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hci_proc_nfcc_power_mode(uint8_t nfcc_power_mode) {
+  NFA_TRACE_DEBUG1("nfa_hci_proc_nfcc_power_mode () nfcc_power_mode=%d",
+                   nfcc_power_mode);
+
+  /* if NFCC power mode is change to full power */
+  if (nfcc_power_mode == NFA_DM_PWR_MODE_FULL) {
+    nfa_hci_cb.b_low_power_mode = false;
+    if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) {
+      nfa_hci_cb.hci_state = NFA_HCI_STATE_RESTORE;
+      nfa_hci_cb.ee_disc_cmplt = false;
+      nfa_hci_cb.ee_disable_disc = true;
+      if (nfa_hci_cb.num_nfcee > 1)
+        nfa_hci_cb.w4_hci_netwk_init = true;
+      else
+        nfa_hci_cb.w4_hci_netwk_init = false;
+      nfa_hci_cb.conn_id = 0;
+      nfa_hci_cb.num_ee_dis_req_ntf = 0;
+      nfa_hci_cb.num_hot_plug_evts = 0;
+    } else {
+      NFA_TRACE_ERROR0("nfa_hci_proc_nfcc_power_mode (): Cannot restore now");
+      nfa_sys_cback_notify_nfcc_power_mode_proc_complete(NFA_ID_HCI);
+    }
+  } else {
+    nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+    nfa_hci_cb.w4_rsp_evt = false;
+    nfa_hci_cb.conn_id = 0;
+    nfa_sys_stop_timer(&nfa_hci_cb.timer);
+    nfa_hci_cb.b_low_power_mode = true;
+    nfa_sys_cback_notify_nfcc_power_mode_proc_complete(NFA_ID_HCI);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_dh_startup_complete
+**
+** Description      Initialization of terminal host in HCI Network is completed
+**                  Wait for other host in the network to initialize
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hci_dh_startup_complete(void) {
+  int ee_entry_index = 0;
+// NFC-INIT MACH
+#if (NXP_EXTNS == TRUE)
+  bool send_host_list = true;
+  if (nfa_hci_cb.ee_disable_disc) {
+    if (nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP &&
+        nfa_hci_cb.num_nfcee >= 1) {
+      NFA_TRACE_DEBUG0("nfa_hci_dh_startup_complete");
+      nfa_hci_cb.w4_hci_netwk_init = false;
+      /* Received EE DISC REQ Ntf(s) */
+      nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE, NFA_HCI_HOST_LIST_INDEX);
+      send_host_list = false;
+    }
+  }
+#endif
+  // NFC_INIT MACH
+
+  if (nfa_hci_cb.w4_hci_netwk_init) {
+    if (nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) {
+      nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_NETWK_ENABLE;
+      /* Check if all EEs are discovered already and minimum 1 disc_req_ntf is
+       * received
+       * If atleast 1 disc_req_ntf is received then 150ms time will be started
+       * for the next disc_req_ntf
+       * So no need to start 2s timer to wait for first disc_req_ntf.
+       * */
+      if (nfa_ee_cb.cur_ee == nfa_ee_max_ee_cfg) {
+        while (ee_entry_index < nfa_ee_max_ee_cfg) {
+          /*Check if host discovered is inactive*/
+          if ((nfa_ee_cb.ecb[ee_entry_index].nfcee_id ==
+               NFA_EE_INTERFACE_HCI_ACCESS) &&
+              (nfa_ee_cb.ecb[ee_entry_index].ee_status ==
+               NFA_EE_STATUS_INACTIVE)) {
+            break;
+          }
+          if ((nfa_ee_cb.ecb[ee_entry_index].nfcee_id !=
+               NFA_EE_INTERFACE_HCI_ACCESS) &&
+              (nfa_ee_cb.ecb[ee_entry_index].ee_status ==
+               NFA_EE_STATUS_ACTIVE) &&
+              (nfa_hci_cb.num_ee_dis_req_ntf == 0)) {
+            break;
+          }
+          ee_entry_index++;
+        }
+        if (ee_entry_index == nfa_ee_max_ee_cfg) {
+          nfa_sys_stop_timer(&nfa_hci_cb.timer);
+          nfa_hci_cb.w4_hci_netwk_init = false;
+          nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
+                                      NFA_HCI_HOST_LIST_INDEX);
+        } else {
+          /* Wait for EE Discovery to complete */
+          nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
+                              NFA_EE_DISCV_TIMEOUT_VAL);
+        }
+      } else {
+        /* Wait for EE Discovery to complete */
+        nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
+                            NFA_EE_DISCV_TIMEOUT_VAL);
+      }
+    } else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE) {
+      nfa_hci_cb.hci_state = NFA_HCI_STATE_RESTORE_NETWK_ENABLE;
+      /* No HCP packet to DH for a specified period of time indicates all host
+       * in the network is initialized */
+      nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
+                          p_nfa_hci_cfg->hci_netwk_enable_timeout);
+    }
+  } else if ((nfa_hci_cb.num_nfcee > 1) &&
+             (nfa_hci_cb.num_ee_dis_req_ntf != (nfa_hci_cb.num_nfcee - 1))) {
+    if (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE)
+      nfa_hci_cb.ee_disable_disc = true;
+    /* Received HOT PLUG EVT, we will also wait for EE DISC REQ Ntf(s) */
+    nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
+                        p_nfa_hci_cfg->hci_netwk_enable_timeout);
+  } else {
+/* Received EE DISC REQ Ntf(s) */
+#if (NXP_EXTNS == TRUE)
+    if (send_host_list)
+#endif
+    {
+         /* Received EE DISC REQ Ntf(s) */
+         nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE, NFA_HCI_HOST_LIST_INDEX);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_startup_complete
+**
+** Description      HCI network initialization is completed
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hci_startup_complete(tNFA_STATUS status) {
+  tNFA_HCI_EVT_DATA evt_data;
+
+  NFA_TRACE_EVENT1("nfa_hci_startup_complete (): Status: %u", status);
+  nfa_sys_stop_timer(&nfa_hci_cb.timer);
+
+  if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE) ||
+      (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
+    nfa_ee_proc_hci_info_cback();
+    nfa_sys_cback_notify_nfcc_power_mode_proc_complete(NFA_ID_HCI);
+  }
+#if (NXP_EXTNS == TRUE)
+  else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_NFCEE_ENABLE) {
+    nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+
+    if(nfa_hci_cb.cmd_sent == NFA_HCI_ANY_GET_PARAMETER &&
+      nfa_hci_cb.param_in_use == NFA_HCI_HOST_LIST_INDEX){
+
+        evt_data.admin_rsp_rcvd.NoHostsPresent = 0;
+    }
+    else{
+      evt_data.admin_rsp_rcvd.status = status;
+      nfa_hciu_send_to_all_apps (NFA_HCI_CONFIG_DONE_EVT, &evt_data);
+    }
+    return;
+  }
+#endif
+  else {
+    evt_data.hci_init.status = status;
+
+    nfa_hciu_send_to_all_apps(NFA_HCI_INIT_EVT, &evt_data);
+#if (NXP_EXTNS == TRUE)
+
+#else
+    nfa_sys_cback_notify_enable_complete(NFA_ID_HCI);
+#endif
+  }
+
+  if (status == NFA_STATUS_OK) {
+    nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+#if (NXP_EXTNS == TRUE)
+    nfa_hci_handle_nfcee_config_evt(NFA_HCI_GET_NUM_NFCEE_CONFIGURED);
+    if(nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH) {
+        nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+        NFA_TRACE_EVENT0("hci_state = NFA_HCI_STATE_IDLE");
+        if ((nfa_sys_cb.enable_cplt_flags == nfa_sys_cb.enable_cplt_mask) &&
+                (!(nfa_sys_cb.p_enable_cback))) {
+            if ((nfa_dm_cb.p_dm_cback))
+                (*nfa_dm_cb.p_dm_cback)(NFA_DM_EE_HCI_ENABLE, NULL);
+        }
+    }
+#endif
+  } else {
+#if (NXP_EXTNS == TRUE)
+       nfa_hci_handle_nfcee_config_evt(NFA_HCI_NFCEE_CONFIG_COMPLETE);
+#endif
+    nfa_hci_cb.hci_state = NFA_HCI_STATE_DISABLED;
+#if (NXP_EXTNS == true)
+    if(nfcFL.eseFL._EXCLUDE_NV_MEM_DEPENDENCY == false) {
+      nfa_hci_getApduAndConnectivity_PipeStatus();
+    }
+#endif
+  }
+}
+
+/*******************************************************************************
+**
++** Function         nfa_hci_enable_one_nfcee
+**
+** Description      Enable NFCEE Hosts which are discovered.
++**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hci_enable_one_nfcee(void) {
+  uint8_t xx;
+  uint8_t nfceeid = 0;
+
+  NFA_TRACE_DEBUG1("nfa_hci_enable_one_nfcee () %d",nfa_hci_cb.num_nfcee);
+
+  for (xx = 0; xx < nfa_hci_cb.num_nfcee; xx++) {
+    nfceeid = nfa_hci_cb.ee_info[xx].ee_handle & ~NFA_HANDLE_GROUP_EE;
+    if ((nfa_hci_cb.ee_info[xx].ee_status == NFA_EE_STATUS_INACTIVE)) {
+      NFC_NfceeModeSet(nfceeid, NFC_MODE_ACTIVATE);
+      return;
+    }
+  }
+
+  if(xx == nfa_hci_cb.num_nfcee) {
+    if((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
+                  (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
+      nfa_hci_cb.w4_nfcee_enable = false;
+      nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,NFA_HCI_HOST_LIST_INDEX);
+    } else if(nfa_hci_cb.hci_state == NFA_HCI_STATE_EE_RECOVERY) {
+        nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+        if (true == nfa_hci_cb.nfcee_cfg.discovery_stopped) {
+          nfa_hci_cb.nfcee_cfg.discovery_stopped = false;
+          nfa_dm_act_start_rf_discovery(NULL);
+        }
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_startup
+**
+** Description      Perform HCI startup
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hci_startup(void) {
+  tNFA_STATUS status = NFA_STATUS_FAILED;
+  tNFA_EE_INFO ee_info[2];
+  uint8_t num_nfcee = 2;
+  uint8_t target_handle;
+  uint8_t count = 0;
+  bool found = false;
+
+  nfa_ee_max_ee_cfg = nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED;
+
+  if (HCI_LOOPBACK_DEBUG) {
+      /* First step in initialization is to open the admin pipe */
+      nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
+      return;
+  }
+
+  /* We can only start up if NV Ram is read and EE discovery is complete */
+  if (nfa_hci_cb.nv_read_cmplt && nfa_hci_cb.ee_disc_cmplt &&
+      (nfa_hci_cb.conn_id == 0)) {
+    if(NFC_GetNCIVersion() == NCI_VERSION_2_0) {
+      NFC_SetStaticHciCback (nfa_hci_conn_cback);
+    } else {
+        NFA_EeGetInfo(&nfa_hci_cb.num_nfcee, nfa_hci_cb.ee_info);
+
+       while ((count < nfa_hci_cb.num_nfcee) && (!found)) {
+         target_handle = (uint8_t)nfa_hci_cb.ee_info[count].ee_handle;
+
+       if (nfa_hci_cb.ee_info[count].ee_interface[0] == NFA_EE_INTERFACE_HCI_ACCESS) {
+         found = true;
+#if (NXP_EXTNS != TRUE)
+        if (nfa_hci_cb.num_nfcee[count].ee_status == NFA_EE_STATUS_INACTIVE) {
+          NFC_NfceeModeSet(target_handle, NFC_MODE_ACTIVATE);
+        }
+#endif
+        status =
+            NFC_ConnCreate(NCI_DEST_TYPE_NFCEE, target_handle,
+                           NFA_EE_INTERFACE_HCI_ACCESS, nfa_hci_conn_cback);
+        if (status == NFA_STATUS_OK)
+          nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
+                              NFA_HCI_CON_CREATE_TIMEOUT_VAL);
+        else {
+          nfa_hci_cb.hci_state = NFA_HCI_STATE_DISABLED;
+          NFA_TRACE_ERROR0(
+              "nfa_hci_startup - Failed to Create Logical connection. HCI "
+              "Initialization/Restore failed");
+          nfa_hci_startup_complete(NFA_STATUS_FAILED);
+        }
+#if (NXP_EXTNS == TRUE)
+/*if (ee_info[count].ee_status == NFA_EE_STATUS_INACTIVE)
+{
+    NFC_NfceeModeSet (target_handle, NFC_MODE_ACTIVATE);
+}*/
+#endif
+      }
+      count++;
+    }
+    if (!found) {
+      NFA_TRACE_ERROR0(
+          "nfa_hci_startup - HCI ACCESS Interface not discovered. HCI "
+          "Initialization/Restore failed");
+      nfa_hci_startup_complete(NFA_STATUS_FAILED);
+    }
+  }
+ }
+}
+
+#if (NXP_EXTNS == TRUE)
+void nfa_hci_network_enable(void) {
+  tNFA_EE_INFO ee_info[2];
+  uint8_t num_nfcee = 2;
+  uint8_t target_handle;
+  bool found = false;
+  uint8_t count = 0;
+
+    NFA_EeGetInfo(&num_nfcee, ee_info);
+    while ((count < num_nfcee) && (!found)) {
+      target_handle = (uint8_t)ee_info[count].ee_handle;
+
+      if (ee_info[count].ee_interface[0] == NFA_EE_INTERFACE_HCI_ACCESS) {
+        found = true;
+        if (ee_info[count].ee_status == NFA_EE_STATUS_INACTIVE) {
+          NFC_NfceeModeSet(target_handle, NFC_MODE_ACTIVATE);
+          /*HCI network is Inactive wait*/
+                nfa_hci_cb.w4_hci_netwk_init = true;
+            }
+            else
+            {
+                /*HCI network is already active*/
+                nfa_hci_cb.w4_hci_netwk_init = false;
+        }
+      }
+      count++;
+    }
+}
+#endif
+/*******************************************************************************
+**
+** Function         nfa_hci_sys_enable
+**
+** Description      Enable NFA HCI
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_sys_enable(void) {
+  NFA_TRACE_DEBUG0("nfa_hci_sys_enable ()");
+  nfa_ee_reg_cback_enable_done(&nfa_hci_ee_info_cback);
+
+  nfa_nv_co_read((uint8_t*)&nfa_hci_cb.cfg, sizeof(nfa_hci_cb.cfg),
+                 DH_NV_BLOCK);
+  nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
+                      NFA_HCI_NV_READ_TIMEOUT_VAL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_sys_disable
+**
+** Description      Disable NFA HCI
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_sys_disable(void) {
+  tNFA_HCI_EVT_DATA evt_data;
+
+  nfa_sys_stop_timer(&nfa_hci_cb.timer);
+
+  if (nfa_hci_cb.conn_id) {
+    if (nfa_sys_is_graceful_disable()) {
+      /* Tell all applications stack is down */
+      if(NFC_GetNCIVersion() == NCI_VERSION_1_0) {
+        nfa_hciu_send_to_all_apps(NFA_HCI_EXIT_EVT, &evt_data);
+        NFC_ConnClose(nfa_hci_cb.conn_id);
+      }
+      return;
+    }
+    nfa_hci_cb.conn_id = 0;
+  }
+
+  nfa_hci_cb.hci_state = NFA_HCI_STATE_DISABLED;
+  /* deregister message handler on NFA SYS */
+  nfa_sys_deregister(NFA_ID_HCI);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_conn_cback
+**
+** Description      This function Process event from NCI
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hci_conn_cback(uint8_t conn_id, tNFC_CONN_EVT event,
+                        tNFC_CONN* p_data) {
+  uint8_t* p;
+  NFC_HDR* p_pkt = (NFC_HDR*)p_data->data.p_data;
+  uint8_t chaining_bit;
+  uint8_t pipe;
+  uint16_t pkt_len;
+#if (BT_TRACE_VERBOSE == true)
+  char buff[VERBOSE_BUFF_SIZE];
+  static bool is_first_chain_pkt = true;
+#endif
+#if (NXP_EXTNS == TRUE)
+  if(nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME ==
+          nfcFL.eseFL._ESE_WIRED_MODE_RESUME) {
+      if (event == NFC_HCI_RESTART_TIMER) {
+          if (nfa_hci_cb.IsHciTimerChanged) {
+              nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
+                      NFA_HCI_DWP_RSP_WAIT_TIMEOUT);
+              nfa_hci_cb.IsHciTimerChanged = false;
+          } else if (nfa_hci_cb.IsWiredSessionAborted) {
+              nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
+                      NFA_HCI_DWP_SESSION_ABORT_TIMEOUT);
+              nfa_hci_cb.IsWiredSessionAborted = false;
+          } else {
+              nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
+                      nfa_hci_cb.hciResponseTimeout);
+          }
+          return;
+      }
+  }
+#endif
+  if (event == NFC_CONN_CREATE_CEVT) {
+#if(NXP_EXTNS == TRUE)
+    tNFA_EE_MSG p_msgdata;
+    p_msgdata.conn.conn_id = conn_id;
+    p_msgdata.conn.event = event;
+    p_msgdata.conn.p_data = p_data;
+    nfa_ee_nci_conn(&p_msgdata);
+#endif
+    nfa_hci_cb.conn_id = conn_id;
+    nfa_hci_cb.buff_size = p_data->conn_create.buff_size;
+
+    if (nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) {
+      nfa_hci_cb.w4_hci_netwk_init = true;
+      nfa_hciu_alloc_gate(NFA_HCI_CONNECTIVITY_GATE, 0);
+    }
+#if(NXP_EXTNS == TRUE)
+    if (nfa_hci_cb.hci_state == NFA_HCI_STATE_DISABLED){
+      nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+      return;
+    }
+#endif
+
+    if (nfa_hci_cb.cfg.admin_gate.pipe01_state == NFA_HCI_PIPE_CLOSED) {
+      /* First step in initialization/restore is to open the admin pipe */
+      nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
+    } else {
+#if (NXP_EXTNS == TRUE)
+      nfa_hciu_send_set_param_cmd(NFA_HCI_ADMIN_PIPE, NFA_HCI_WHITELIST_INDEX,
+                                  p_nfa_hci_cfg->num_whitelist_host,
+                                  p_nfa_hci_cfg->p_whitelist);
+#else
+      /* Read session id, to know DH session id is correct */
+      nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
+                                  NFA_HCI_SESSION_IDENTITY_INDEX);
+#endif
+    }
+  } else if (event == NFC_CONN_CLOSE_CEVT) {
+      nfa_hci_cb.conn_id = 0;
+      nfa_hci_cb.hci_state = NFA_HCI_STATE_DISABLED;
+#if(NXP_EXTNS == TRUE)
+      if(nfa_ee_connectionClosed())
+#endif
+      /* deregister message handler on NFA SYS */
+        nfa_sys_deregister (NFA_ID_HCI);
+      NFA_TRACE_DEBUG0("NFC_CONN_CLOSE_CEVT handled");
+
+#if(NXP_EXTNS == TRUE)
+      tNFA_EE_MSG p_msgdata;
+      p_msgdata.conn.conn_id = conn_id;
+      p_msgdata.conn.event = event;
+      p_msgdata.conn.p_data = p_data;
+      nfa_ee_nci_conn(&p_msgdata);
+#endif
+  }
+
+  if ((event != NFC_DATA_CEVT) || (p_pkt == NULL)) return;
+
+  if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
+      (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
+    /* Received HCP Packet before timeout, Other Host initialization is not
+     * complete */
+    nfa_sys_stop_timer(&nfa_hci_cb.timer);
+    if (nfa_hci_cb.w4_hci_netwk_init)
+      nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
+                          p_nfa_hci_cfg->hci_netwk_enable_timeout);
+  }
+
+  p = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
+  pkt_len = p_pkt->len;
+
+#if (BT_TRACE_PROTOCOL == true)
+  DispHcp(p, pkt_len, true, (bool)!nfa_hci_cb.assembling);
+#endif
+
+  chaining_bit = ((*p) >> 0x07) & 0x01;
+  pipe = (*p++) & 0x7F;
+  if (pkt_len != 0) pkt_len--;
+
+#if (NXP_EXTNS == TRUE)
+  uint8_t is_assembling_on_current_pipe = 0;
+
+  if (nfa_hci_cb.assembling_flags & NFA_HCI_FL_CONN_PIPE) {
+    if (pipe == NFA_HCI_CONN_ESE_PIPE || (pipe == NFA_HCI_CONN_UICC_PIPE)
+        || ((nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH) &&
+                (pipe == NFA_HCI_CONN_UICC2_PIPE))) {
+      is_assembling_on_current_pipe = 1;
+    }
+  } else if (nfa_hci_cb.assembling_flags & NFA_HCI_FL_APDU_PIPE) {
+    if (pipe == NFA_HCI_APDU_PIPE) {
+      is_assembling_on_current_pipe = 1;
+    }
+  }
+
+  if (is_assembling_on_current_pipe == 0)
+#else
+  if (nfa_hci_cb.assembling == false)
+#endif
+  {
+    /* First Segment of a packet */
+    nfa_hci_cb.type = ((*p) >> 0x06) & 0x03;
+    nfa_hci_cb.inst = (*p++ & 0x3F);
+
+#if (NXP_EXTNS == TRUE)
+    if (pipe == NFA_HCI_CONN_ESE_PIPE || (pipe == NFA_HCI_CONN_UICC_PIPE)
+        || ((nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH) &&
+                (pipe == NFA_HCI_CONN_UICC2_PIPE))) {
+        nfa_hci_cb.type_evt = nfa_hci_cb.type;
+        nfa_hci_cb.inst_evt = nfa_hci_cb.inst;
+    } else if (pipe == NFA_HCI_APDU_PIPE) {
+        nfa_hci_cb.type_msg = nfa_hci_cb.type;
+        nfa_hci_cb.inst_msg = nfa_hci_cb.inst;
+    }
+#endif
+    if (pkt_len != 0) pkt_len--;
+    nfa_hci_cb.assembly_failed = false;
+    nfa_hci_cb.msg_len = 0;
+#if (NXP_EXTNS == TRUE)
+    nfa_hci_cb.evt_len = 0;
+#endif
+    if (chaining_bit == NFA_HCI_MESSAGE_FRAGMENTATION) {
+      nfa_hci_cb.assembling = true;
+      nfa_hci_set_receive_buf(pipe);
+#if (NXP_EXTNS == TRUE)
+      is_assembling_on_current_pipe = 1;
+      nfa_hci_assemble_msg(p, pkt_len, pipe);
+#else
+      nfa_hci_assemble_msg(p, pkt_len);
+#endif
+    } else {
+      if ((pipe >= NFA_HCI_FIRST_DYNAMIC_PIPE) &&
+          (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)
+#if (NXP_EXTNS == TRUE)
+          && (nfa_hci_cb.inst != NFA_HCI_EVT_WTX)
+#endif
+              ) {
+        nfa_hci_set_receive_buf(pipe);
+#if (NXP_EXTNS == TRUE)
+        nfa_hci_assemble_msg(p, pkt_len, pipe);
+        if (pipe == NFA_HCI_APDU_PIPE) {
+          nfa_hci_cb.assembling_flags &= ~NFA_HCI_FL_APDU_PIPE;
+          nfa_hci_cb.assembly_failed_flags &= ~NFA_HCI_FL_APDU_PIPE;
+
+          p = nfa_hci_cb.p_msg_data;
+        } else if ((pipe == NFA_HCI_CONN_UICC_PIPE) ||
+                (pipe == NFA_HCI_CONN_ESE_PIPE)
+                || ((nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH) &&
+                        (pipe == NFA_HCI_CONN_UICC2_PIPE))) {
+            nfa_hci_cb.assembling_flags &= ~NFA_HCI_FL_CONN_PIPE;
+            nfa_hci_cb.assembly_failed_flags &= ~NFA_HCI_FL_CONN_PIPE;
+
+            p = nfa_hci_cb.p_evt_data;
+        }
+#else
+        nfa_hci_assemble_msg(p, pkt_len);
+        p = nfa_hci_cb.p_msg_data;
+#endif
+      }
+    }
+  } else {
+#if (NXP_EXTNS == TRUE)
+    uint8_t is_assembly_failed_on_current_pipe = 0;
+    if (nfa_hci_cb.assembly_failed_flags & NFA_HCI_FL_CONN_PIPE) {
+        if ((pipe == NFA_HCI_CONN_ESE_PIPE) || (pipe == NFA_HCI_CONN_UICC_PIPE)
+                || ((nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH) &&
+                        (pipe == NFA_HCI_CONN_UICC2_PIPE))) {
+            is_assembly_failed_on_current_pipe = 1;
+        }
+    } else if (nfa_hci_cb.assembly_failed_flags & NFA_HCI_FL_APDU_PIPE) {
+      if (pipe == NFA_HCI_APDU_PIPE) {
+        is_assembly_failed_on_current_pipe = 1;
+      }
+    }
+
+    if (is_assembly_failed_on_current_pipe == 1)
+#else
+    if (nfa_hci_cb.assembly_failed)
+#endif
+    {
+      /* If Reassembly failed because of insufficient buffer, just drop the new
+       * segmented packets */
+      NFA_TRACE_ERROR1(
+          "nfa_hci_conn_cback (): Insufficient buffer to Reassemble HCP "
+          "packet! Dropping :%u bytes",
+          pkt_len);
+    } else {
+#if (NXP_EXTNS == TRUE)
+      nfa_hci_assemble_msg(p, pkt_len, pipe);
+#else
+      /* Reassemble the packet */
+      nfa_hci_assemble_msg(p, pkt_len);
+#endif
+    }
+
+    if (chaining_bit == NFA_HCI_NO_MESSAGE_FRAGMENTATION) {
+      /* Just added the last segment in the chain. Reset pointers */
+      nfa_hci_cb.assembling = false;
+#if (NXP_EXTNS == TRUE)
+      is_assembling_on_current_pipe = 0;
+      if (pipe == NFA_HCI_APDU_PIPE) {
+        nfa_hci_cb.assembling_flags &= ~NFA_HCI_FL_APDU_PIPE;
+        nfa_hci_cb.assembly_failed_flags &= ~NFA_HCI_FL_APDU_PIPE;
+
+        p = nfa_hci_cb.p_msg_data;
+        pkt_len = nfa_hci_cb.msg_len;
+      } else if ((pipe == NFA_HCI_CONN_UICC_PIPE) ||
+              (pipe == NFA_HCI_CONN_ESE_PIPE)
+              || ((nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH) &&
+                      (pipe == NFA_HCI_CONN_UICC2_PIPE))) {
+        nfa_hci_cb.assembling_flags &= ~NFA_HCI_FL_CONN_PIPE;
+        nfa_hci_cb.assembly_failed_flags &= ~NFA_HCI_FL_CONN_PIPE;
+
+        p = nfa_hci_cb.p_evt_data;
+        pkt_len = nfa_hci_cb.evt_len;
+      }
+#else
+      p = nfa_hci_cb.p_msg_data;
+      pkt_len = nfa_hci_cb.msg_len;
+#endif
+    }
+  }
+
+#if (NXP_EXTNS == TRUE)
+  if (pipe == NFA_HCI_CONN_ESE_PIPE || (pipe == NFA_HCI_CONN_UICC_PIPE)
+          || ((nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH) &&
+                  (pipe == NFA_HCI_CONN_UICC2_PIPE))) {
+      nfa_hci_cb.type = nfa_hci_cb.type_evt;
+      nfa_hci_cb.inst = nfa_hci_cb.inst_evt;
+  } else if (pipe == NFA_HCI_APDU_PIPE) {
+      nfa_hci_cb.type = nfa_hci_cb.type_msg;
+      nfa_hci_cb.inst = nfa_hci_cb.inst_msg;
+  }
+#endif
+
+#if (BT_TRACE_VERBOSE == true)
+  NFA_TRACE_EVENT5(
+      "nfa_hci_conn_cback Recvd data pipe:%d  %s  chain:%d  assmbl:%d  len:%d",
+      (uint8_t)pipe, nfa_hciu_get_type_inst_names(pipe, nfa_hci_cb.type,
+                                                  nfa_hci_cb.inst, buff),
+      (uint8_t)chaining_bit, (uint8_t)nfa_hci_cb.assembling, p_pkt->len);
+#else
+  NFA_TRACE_EVENT6(
+      "nfa_hci_conn_cback Recvd data pipe:%d  Type: %u  Inst: %u  chain:%d "
+      "reassm:%d len:%d",
+      pipe, nfa_hci_cb.type, nfa_hci_cb.inst, chaining_bit,
+      nfa_hci_cb.assembling, p_pkt->len);
+#endif
+
+#if (NXP_EXTNS == TRUE)
+  /*After the reception of WTX, if the next response is chained
+   * the timer value should be big enough to hold the complete packet*/
+  if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_RSP) &&
+      (nfa_hci_cb.assembling && is_first_chain_pkt)) {
+    is_first_chain_pkt = false;
+    nfa_sys_stop_timer(&nfa_hci_cb.timer);
+    nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
+                        NFA_HCI_CHAIN_PKT_RSP_TIMEOUT);
+  }
+#endif
+
+#if (NXP_EXTNS == TRUE)
+  if (is_assembling_on_current_pipe == 1)
+#else
+  /* If still reassembling fragments, just return */
+  if (nfa_hci_cb.assembling)
+#endif
+  {
+    /* if not last packet, release GKI buffer */
+    GKI_freebuf(p_pkt);
+    return;
+  }
+#if (NXP_EXTNS == TRUE)
+  if ((pipe == NFA_HCI_APDU_PIPE) && nfa_hci_cb.IsLastEvtAbortFailed) {
+    if (nfa_hci_cb.inst == NFA_HCI_ABORT) {
+      nfa_hci_cb.IsLastEvtAbortFailed = false;
+    }
+    if (nfa_hci_cb.evt_sent.evt_type != NFA_EVT_ABORT) {
+      /*Ignore the response after rsp timeout due to ese/uicc concurrency
+       * scenarios*/
+      GKI_freebuf(p_pkt);
+      return;
+    }
+  }
+
+#endif
+  /* If we got a response, cancel the response timer. Also, if waiting for */
+  /* a single response, we can go back to idle state                       */
+  if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_RSP) &&
+      ((nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) ||
+       (nfa_hci_cb.w4_rsp_evt && (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)))) {
+#if (NXP_EXTNS == TRUE)
+    if (pipe == NFA_HCI_APDU_PIPE) {
+      nfa_sys_stop_timer(&nfa_hci_cb.timer);
+      is_first_chain_pkt = true;
+      if (nfa_hci_cb.inst == NFA_HCI_EVT_WTX) {
+        if (nfa_hci_cb.w4_rsp_evt == true) {
+          const int32_t rsp_timeout = NFA_HCI_WTX_RESP_TIMEOUT;  // 3-sec
+          nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
+                              rsp_timeout);
+        }
+      } else {
+        nfa_hci_cb.IsChainedPacket = false;
+        nfa_ee_ce_p61_completed = 0;
+        nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+      }
+    } else {
+        if (!((pipe == NFA_HCI_CONN_UICC_PIPE || pipe == NFA_HCI_CONN_ESE_PIPE
+                || ((nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH) &&
+                        (pipe == NFA_HCI_CONN_UICC2_PIPE))) &&
+                (nfa_hci_cb.inst_evt == NFA_HCI_EVT_TRANSACTION ||
+                        nfa_hci_cb.inst_evt == NFA_HCI_EVT_CONNECTIVITY))) {
+            /*Stop timer and goto IDLE state when pipe is not connectivity but event
+             * received is connectivity*/
+            nfa_sys_stop_timer(&nfa_hci_cb.timer);
+            nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+        }
+    }
+#else
+    nfa_sys_stop_timer(&nfa_hci_cb.timer);
+    nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+#endif
+  }
+
+  switch (pipe) {
+    case NFA_HCI_ADMIN_PIPE:
+      /* Check if data packet is a command, response or event */
+      if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) {
+        nfa_hci_handle_admin_gate_cmd(p);
+      } else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) {
+        nfa_hci_handle_admin_gate_rsp(p, (uint8_t)pkt_len);
+      } else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE) {
+        nfa_hci_handle_admin_gate_evt(p);
+      }
+      break;
+
+    case NFA_HCI_LINK_MANAGEMENT_PIPE:
+      /* We don't send Link Management commands, we only get them */
+      if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
+        nfa_hci_handle_link_mgm_gate_cmd(p);
+      break;
+
+    default:
+      if (pipe >= NFA_HCI_FIRST_DYNAMIC_PIPE)
+        nfa_hci_handle_dyn_pipe_pkt(pipe, p, pkt_len);
+      break;
+  }
+
+  if ((nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) ||
+      (nfa_hci_cb.w4_rsp_evt && (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)
+#if (NXP_EXTNS == TRUE)
+       && (nfa_hci_cb.inst != NFA_HCI_EVT_WTX)
+#endif
+           )) {
+#if (NXP_EXTNS == TRUE)
+    if (pipe == NFA_HCI_APDU_PIPE)
+#endif
+    {
+      nfa_hci_cb.w4_rsp_evt = false;
+    }
+  }
+
+  /* Send a message to ouselves to check for anything to do */
+  p_pkt->event = NFA_HCI_CHECK_QUEUE_EVT;
+  p_pkt->len = 0;
+  nfa_sys_sendmsg(p_pkt);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_nv_read
+**
+** Description      handler function for nv read complete event
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hci_handle_nv_read(uint8_t block, tNFA_STATUS status) {
+  uint8_t session_id[NFA_HCI_SESSION_ID_LEN];
+  uint8_t default_session[NFA_HCI_SESSION_ID_LEN] = {0xFF, 0xFF, 0xFF, 0xFF,
+                                                     0xFF, 0xFF, 0xFF, 0xFF};
+  uint8_t reset_session[NFA_HCI_SESSION_ID_LEN] = {0x00, 0x00, 0x00, 0x00,
+                                                   0x00, 0x00, 0x00, 0x00};
+  uint32_t os_tick;
+
+  if (block == DH_NV_BLOCK) {
+    /* Stop timer as NVDATA Read Completed */
+    nfa_sys_stop_timer(&nfa_hci_cb.timer);
+    nfa_hci_cb.nv_read_cmplt = true;
+    if ((status != NFA_STATUS_OK) || (!nfa_hci_is_valid_cfg()) ||
+        (!(memcmp(nfa_hci_cb.cfg.admin_gate.session_id, default_session,
+                  NFA_HCI_SESSION_ID_LEN))) ||
+        (!(memcmp(nfa_hci_cb.cfg.admin_gate.session_id, reset_session,
+                  NFA_HCI_SESSION_ID_LEN)))) {
+#if (NXP_EXTNS == TRUE)
+      if(nfcFL.eseFL._EXCLUDE_NV_MEM_DEPENDENCY == true) {
+        nfa_hci_getApduAndConnectivity_PipeStatus();
+      }
+#endif
+      nfa_hci_cb.b_hci_netwk_reset = true;
+      /* Set a new session id so that we clear all pipes later after seeing a
+       * difference with the HC Session ID */
+      memcpy(&session_id[(NFA_HCI_SESSION_ID_LEN / 2)],
+             nfa_hci_cb.cfg.admin_gate.session_id,
+             (NFA_HCI_SESSION_ID_LEN / 2));
+      os_tick = GKI_get_os_tick_count();
+      memcpy(session_id, (uint8_t*)&os_tick, (NFA_HCI_SESSION_ID_LEN / 2));
+      nfa_hci_restore_default_config(session_id);
+    }
+#if (NXP_EXTNS == TRUE)
+    else {
+      if (!nfa_hci_is_valid_ese_cfg() &&
+          (nfa_hci_cb.cfg.retry_cnt < NFA_HCI_INIT_MAX_RETRY)) {
+        nfa_hci_cb.cfg.retry_cnt++;
+        NFA_TRACE_DEBUG0(" nfa_hci_handle_nv_read; reset ese session");
+        nfa_hciu_reset_session_id(nfa_hci_reset_session_rsp_cb);
+      } else {
+        NXP_NFC_RESET_MSB(nfa_hci_cb.cfg.retry_cnt);
+#endif
+        nfa_hci_startup();
+#if (NXP_EXTNS == TRUE)
+      }
+    }
+#endif
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_rsp_timeout
+**
+** Description      action function to process timeout
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hci_rsp_timeout(tNFA_HCI_EVENT_DATA* p_evt_data) {
+  tNFA_HCI_EVT evt = 0;
+  tNFA_HCI_EVT_DATA evt_data;
+  uint8_t delete_pipe;
+  (void)p_evt_data;
+#if (NXP_EXTNS == TRUE)
+  NFC_HDR* p_buf;
+  uint8_t* p_data;
+  uint8_t temp[] = {0xFF, 0xFF};
+  uint16_t msg_len;
+#endif
+  NFA_TRACE_EVENT2("nfa_hci_rsp_timeout () State: %u  Cmd: %u",
+                   nfa_hci_cb.hci_state, nfa_hci_cb.cmd_sent);
+
+  evt_data.status = NFA_STATUS_FAILED;
+
+  switch (nfa_hci_cb.hci_state) {
+    case NFA_HCI_STATE_STARTUP:
+    case NFA_HCI_STATE_RESTORE:
+#if (NXP_EXTNS == TRUE)
+    case NFA_HCI_STATE_NFCEE_ENABLE:
+#endif
+      NFA_TRACE_ERROR0("nfa_hci_rsp_timeout - Initialization failed!");
+      nfa_hci_startup_complete(NFA_STATUS_TIMEOUT);
+      break;
+
+    case NFA_HCI_STATE_WAIT_NETWK_ENABLE:
+    case NFA_HCI_STATE_RESTORE_NETWK_ENABLE:
+
+      if (nfa_hci_cb.w4_hci_netwk_init) {
+        /* HCI Network is enabled */
+        nfa_hci_cb.w4_hci_netwk_init = false;
+        nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
+                                  NFA_HCI_HOST_LIST_INDEX);
+      } else {
+        nfa_hci_startup_complete(NFA_STATUS_FAILED);
+      }
+      break;
+
+    case NFA_HCI_STATE_REMOVE_GATE:
+      /* Something wrong, NVRAM data could be corrupt */
+      if (nfa_hci_cb.cmd_sent == NFA_HCI_ADM_DELETE_PIPE) {
+        nfa_hciu_send_clear_all_pipe_cmd();
+      } else {
+        nfa_hciu_remove_all_pipes_from_host(0);
+        nfa_hci_api_dealloc_gate(NULL);
+      }
+      break;
+
+    case NFA_HCI_STATE_APP_DEREGISTER:
+      /* Something wrong, NVRAM data could be corrupt */
+      if (nfa_hci_cb.cmd_sent == NFA_HCI_ADM_DELETE_PIPE) {
+        nfa_hciu_send_clear_all_pipe_cmd();
+      } else {
+        nfa_hciu_remove_all_pipes_from_host(0);
+        nfa_hci_api_deregister(NULL);
+      }
+      break;
+    case NFA_HCI_STATE_WAIT_RSP:
+      nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+#if (NXP_EXTNS == TRUE)
+      if (nfa_hci_cb.w4_rsp_evt) {
+        NFA_TRACE_DEBUG0(
+            "NxpNci:nfa_hci_rsp_timeout () Timeout: NFC_FlushData");
+        nfa_hci_cb.bIsHciResponseTimedout = true;
+        if (nfa_ee_nfeeid_active(NFA_HCI_HOST_ID_ESE)) {
+          if ((nfa_hci_cb.IsChainedPacket) &&
+              (!(NFC_Queue_Is_empty(nfa_hci_cb.conn_id)))) {
+            /* send the dummy packet */
+            NFC_FlushData(nfa_hci_cb.conn_id);
+            msg_len = (((nfa_hci_cb.hci_packet_len + 1) % 2) == 0) ? 1 : 2;
+            NFA_TRACE_DEBUG1("NxpNci: Queue is not empty: %d", msg_len);
+            if ((p_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID)) != NULL) {
+              p_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+              p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
+              *p_data++ = (NFA_HCI_NO_MESSAGE_FRAGMENTATION << 7) |
+                          (nfa_hci_cb.pipe_in_use & 0x7F);
+              p_buf->len = 1;
+              memcpy(p_data, &temp, msg_len);
+              p_buf->len += msg_len;
+              NFC_SendData(nfa_hci_cb.conn_id, p_buf);
+              // nfa_sys_start_timer (&nfa_hci_cb.timer,
+              // NFA_HCI_RSP_TIMEOUT_EVT, 3000);
+              nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_RSP;
+              evt = 0;
+              nfa_hci_cb.IsChainedPacket = false;
+              break;
+            }
+          } else if (!nfa_hci_cb.IsEventAbortSent) {
+            NFC_FlushData(nfa_hci_cb.conn_id);
+            /* send EVT_ABORT command */
+            if ((p_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID)) != NULL) {
+              NFA_TRACE_DEBUG0("EVT_ABORT sent");
+              p_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+              p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
+              *p_data++ = (NFA_HCI_NO_MESSAGE_FRAGMENTATION << 7) |
+                          (nfa_hci_cb.pipe_in_use & 0x7F);
+              *p_data++ = (NFA_HCI_EVENT_TYPE << 6) | NFA_EVT_ABORT;
+              p_buf->len = 2;
+              NFC_SendData(nfa_hci_cb.conn_id, p_buf);
+              nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
+                                  3000);
+              nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_RSP;
+            }
+            nfa_hci_cb.IsChainedPacket = false;
+            nfa_hci_cb.IsEventAbortSent = true;
+            evt = 0;
+            break;
+          }
+        }
+        if (nfa_hci_cb.IsEventAbortSent) {
+          nfa_hci_cb.IsLastEvtAbortFailed = true;
+        }
+        NFC_FlushData(nfa_hci_cb.conn_id);
+        nfa_hci_cb.IsEventAbortSent = false;
+#endif
+        nfa_hci_cb.w4_rsp_evt = false;
+        evt = NFA_HCI_EVENT_RCVD_EVT;
+        evt_data.rcvd_evt.pipe = nfa_hci_cb.pipe_in_use;
+        evt_data.rcvd_evt.evt_code = 0;
+        evt_data.rcvd_evt.evt_len = 0;
+        evt_data.rcvd_evt.p_evt_buf = NULL;
+        nfa_hci_cb.rsp_buf_size = 0;
+        nfa_hci_cb.p_rsp_buf = NULL;
+#if (NXP_EXTNS == TRUE)
+        evt_data.rcvd_evt.last_SentEvtType = nfa_hci_cb.evt_sent.evt_type;
+#endif
+        break;
+      }
+
+      delete_pipe = 0;
+      switch (nfa_hci_cb.cmd_sent) {
+        case NFA_HCI_ANY_SET_PARAMETER:
+          /*
+           * As no response to the command sent on this pipe, we may assume the
+           * pipe is
+           * deleted already and release the pipe. But still send delete pipe
+           * command to be safe.
+           */
+          delete_pipe = nfa_hci_cb.pipe_in_use;
+          evt_data.registry.pipe = nfa_hci_cb.pipe_in_use;
+          evt_data.registry.data_len = 0;
+          evt_data.registry.index = nfa_hci_cb.param_in_use;
+          evt = NFA_HCI_SET_REG_RSP_EVT;
+          break;
+
+        case NFA_HCI_ANY_GET_PARAMETER:
+          /*
+           * As no response to the command sent on this pipe, we may assume the
+           * pipe is
+           * deleted already and release the pipe. But still send delete pipe
+           * command to be safe.
+           */
+          delete_pipe = nfa_hci_cb.pipe_in_use;
+          evt_data.registry.pipe = nfa_hci_cb.pipe_in_use;
+          evt_data.registry.data_len = 0;
+          evt_data.registry.index = nfa_hci_cb.param_in_use;
+#if (NXP_EXTNS == TRUE)
+          evt_data.registry.status = NFA_HCI_ANY_E_TIMEOUT;
+#endif
+          evt = NFA_HCI_GET_REG_RSP_EVT;
+          break;
+
+        case NFA_HCI_ANY_OPEN_PIPE:
+          /*
+           * As no response to the command sent on this pipe, we may assume the
+           * pipe is
+           * deleted already and release the pipe. But still send delete pipe
+           * command to be safe.
+           */
+          delete_pipe = nfa_hci_cb.pipe_in_use;
+          evt_data.opened.pipe = nfa_hci_cb.pipe_in_use;
+          evt = NFA_HCI_OPEN_PIPE_EVT;
+          break;
+
+        case NFA_HCI_ANY_CLOSE_PIPE:
+          /*
+           * As no response to the command sent on this pipe, we may assume the
+           * pipe is
+           * deleted already and release the pipe. But still send delete pipe
+           * command to be safe.
+           */
+          delete_pipe = nfa_hci_cb.pipe_in_use;
+          evt_data.closed.pipe = nfa_hci_cb.pipe_in_use;
+          evt = NFA_HCI_CLOSE_PIPE_EVT;
+          break;
+
+        case NFA_HCI_ADM_CREATE_PIPE:
+          evt_data.created.pipe = nfa_hci_cb.pipe_in_use;
+          evt_data.created.source_gate = nfa_hci_cb.local_gate_in_use;
+          evt_data.created.dest_host = nfa_hci_cb.remote_host_in_use;
+          evt_data.created.dest_gate = nfa_hci_cb.remote_gate_in_use;
+          evt = NFA_HCI_CREATE_PIPE_EVT;
+          break;
+
+        case NFA_HCI_ADM_DELETE_PIPE:
+          /*
+           * As no response to the command sent on this pipe, we may assume the
+           * pipe is
+           * deleted already. Just release the pipe.
+           */
+          if (nfa_hci_cb.pipe_in_use <= NFA_HCI_LAST_DYNAMIC_PIPE)
+            nfa_hciu_release_pipe(nfa_hci_cb.pipe_in_use);
+          evt_data.deleted.pipe = nfa_hci_cb.pipe_in_use;
+          evt = NFA_HCI_DELETE_PIPE_EVT;
+          break;
+
+        default:
+          /*
+           * As no response to the command sent on this pipe, we may assume the
+           * pipe is
+           * deleted already and release the pipe. But still send delete pipe
+           * command to be safe.
+           */
+          delete_pipe = nfa_hci_cb.pipe_in_use;
+          break;
+      }
+#if (NXP_EXTNS != TRUE)
+      if (delete_pipe && (delete_pipe <= NFA_HCI_LAST_DYNAMIC_PIPE)) {
+        nfa_hciu_send_delete_pipe_cmd(delete_pipe);
+        nfa_hciu_release_pipe(delete_pipe);
+      }
+#endif
+      break;
+    case NFA_HCI_STATE_DISABLED:
+    default:
+      NFA_TRACE_DEBUG0(
+          "nfa_hci_rsp_timeout () Timeout in DISABLED/ Invalid state");
+      break;
+  }
+  if (evt != 0) nfa_hciu_send_to_app(evt, &evt_data, nfa_hci_cb.app_in_use);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_set_receive_buf
+**
+** Description      Set reassembly buffer for incoming message
+**
+** Returns          status
+**
+*******************************************************************************/
+static void nfa_hci_set_receive_buf(uint8_t pipe) {
+  if ((pipe >= NFA_HCI_FIRST_DYNAMIC_PIPE) &&
+      (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)) {
+#if (NXP_EXTNS == TRUE)
+      if (pipe == NFA_HCI_CONN_ESE_PIPE || pipe == NFA_HCI_CONN_UICC_PIPE
+              || ((nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH) &&
+                      (pipe == NFA_HCI_CONN_UICC2_PIPE))) {
+          /* Connectivity or transaction events are received
+           * from SE. will be assembled and sent to application.
+           * */
+          nfa_hci_cb.assembling_flags |= NFA_HCI_FL_CONN_PIPE;
+          nfa_hci_cb.p_evt_data = nfa_hci_cb.evt_data;
+          nfa_hci_cb.max_evt_len = NFA_MAX_HCI_EVENT_LEN;
+          return;
+      } else if (pipe == NFA_HCI_APDU_PIPE) {
+      /* Here APDU response is received, for the APDU
+       * sent from JNI layer using transceive.
+       * */
+      nfa_hci_cb.assembling_flags |= NFA_HCI_FL_APDU_PIPE;
+      if ((nfa_hci_cb.rsp_buf_size) && (nfa_hci_cb.p_rsp_buf != NULL)) {
+        nfa_hci_cb.p_msg_data = nfa_hci_cb.p_rsp_buf;
+        nfa_hci_cb.max_msg_len = nfa_hci_cb.rsp_buf_size;
+        return;
+      }
+    } else {
+      nfa_hci_cb.assembling_flags |= NFA_HCI_FL_OTHER_PIPE;
+      if ((nfa_hci_cb.rsp_buf_size) && (nfa_hci_cb.p_rsp_buf != NULL)) {
+        nfa_hci_cb.p_msg_data = nfa_hci_cb.p_rsp_buf;
+        nfa_hci_cb.max_msg_len = nfa_hci_cb.rsp_buf_size;
+        return;
+      }
+    }
+#else
+    if ((nfa_hci_cb.rsp_buf_size) && (nfa_hci_cb.p_rsp_buf != NULL)) {
+      nfa_hci_cb.p_msg_data = nfa_hci_cb.p_rsp_buf;
+      nfa_hci_cb.max_msg_len = nfa_hci_cb.rsp_buf_size;
+      return;
+    }
+#endif
+  }
+  nfa_hci_cb.p_msg_data = nfa_hci_cb.msg_data;
+  nfa_hci_cb.max_msg_len = NFA_MAX_HCI_EVENT_LEN;
+}
+
+#if (NXP_EXTNS == TRUE)
+static void read_config_timeout_param_values() {
+  if (GetNumValue(NAME_NXP_DEFAULT_NFCEE_TIMEOUT,
+                  (void*)&nfa_hci_cb.max_hci_session_id_read_count,
+                  sizeof(nfa_hci_cb.max_hci_session_id_read_count)) == false) {
+    nfa_hci_cb.max_hci_session_id_read_count =
+        NFA_HCI_MAX_SESSION_ID_RETRY_CNT; /*Default  maximum session ID read
+                                             count*/
+  }
+  NFA_TRACE_DEBUG1("nfa_hci_init() %d",
+                   nfa_hci_cb.max_hci_session_id_read_count);
+  if (GetNumValue(NAME_NXP_DEFAULT_NFCEE_DISC_TIMEOUT,
+                  (void*)&nfa_hci_cb.max_nfcee_disc_timeout,
+                  sizeof(nfa_hci_cb.max_nfcee_disc_timeout)) == false) {
+    nfa_hci_cb.max_nfcee_disc_timeout =
+        NFA_HCI_NFCEE_DISC_TIMEOUT; /*Default nfcee discover timeout*/
+  }
+  nfa_hci_cb.max_nfcee_disc_timeout = nfa_hci_cb.max_nfcee_disc_timeout * 1000;
+  NFA_TRACE_DEBUG1("nfa_hci_init() %d", nfa_hci_cb.max_nfcee_disc_timeout);
+}
+#endif
+/*******************************************************************************
+**
+** Function         nfa_hci_assemble_msg
+**
+** Description      Reassemble the incoming message
+**
+** Returns          None
+**
+*******************************************************************************/
+#if (NXP_EXTNS == TRUE)
+static void nfa_hci_assemble_msg(uint8_t* p_data, uint16_t data_len,
+                                 uint8_t pipe)
+#else
+static void nfa_hci_assemble_msg(uint8_t* p_data, uint16_t data_len)
+#endif
+{
+#if (NXP_EXTNS == TRUE)
+  if (pipe == NFA_HCI_APDU_PIPE) {
+    if ((nfa_hci_cb.msg_len + data_len) > nfa_hci_cb.max_msg_len) {
+      /* Fill the buffer as much it can hold */
+      NFA_TRACE_ERROR1(
+          "nfa_hci_assemble_msg (): Insufficient buffer to Reassemble APDU HCP "
+          "packet! Dropping :%u bytes",
+          ((nfa_hci_cb.msg_len + data_len) - nfa_hci_cb.max_msg_len));
+      memcpy(&nfa_hci_cb.p_msg_data[nfa_hci_cb.msg_len], p_data,
+             (nfa_hci_cb.max_msg_len - nfa_hci_cb.msg_len));
+      nfa_hci_cb.msg_len = nfa_hci_cb.max_msg_len;
+      /* Set Reassembly failed */
+      nfa_hci_cb.assembly_failed = true;
+      nfa_hci_cb.assembly_failed_flags |= NFA_HCI_FL_APDU_PIPE;
+    } else {
+      memcpy(&nfa_hci_cb.p_msg_data[nfa_hci_cb.msg_len], p_data, data_len);
+      nfa_hci_cb.msg_len += data_len;
+    }
+  } else if ((pipe == NFA_HCI_CONN_ESE_PIPE) || (pipe == NFA_HCI_CONN_UICC_PIPE)
+          || ((nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH) &&
+                  (pipe == NFA_HCI_CONN_UICC2_PIPE))) {
+    if ((nfa_hci_cb.evt_len + data_len) > nfa_hci_cb.max_evt_len) {
+      /* Fill the buffer as much it can hold */
+      NFA_TRACE_ERROR1(
+          "nfa_hci_assemble_msg (): Insufficient buffer to Reassemble Event "
+          "HCP packet! Dropping :%u bytes",
+          ((nfa_hci_cb.msg_len + data_len) - nfa_hci_cb.max_msg_len));
+      memcpy(&nfa_hci_cb.p_evt_data[nfa_hci_cb.evt_len], p_data,
+             (nfa_hci_cb.max_evt_len - nfa_hci_cb.evt_len));
+      nfa_hci_cb.evt_len = nfa_hci_cb.max_evt_len;
+      /* Set Reassembly failed */
+      nfa_hci_cb.assembly_failed = true;
+      nfa_hci_cb.assembly_failed_flags |= NFA_HCI_FL_CONN_PIPE;
+    } else {
+      memcpy(&nfa_hci_cb.p_evt_data[nfa_hci_cb.evt_len], p_data, data_len);
+      nfa_hci_cb.evt_len += data_len;
+    }
+  }
+#else
+  if ((nfa_hci_cb.msg_len + data_len) > nfa_hci_cb.max_msg_len) {
+    /* Fill the buffer as much it can hold */
+    memcpy(&nfa_hci_cb.p_msg_data[nfa_hci_cb.msg_len], p_data,
+           (nfa_hci_cb.max_msg_len - nfa_hci_cb.msg_len));
+    nfa_hci_cb.msg_len = nfa_hci_cb.max_msg_len;
+    /* Set Reassembly failed */
+    nfa_hci_cb.assembly_failed = true;
+    NFA_TRACE_ERROR1(
+        "nfa_hci_assemble_msg (): Insufficient buffer to Reassemble HCP "
+        "packet! Dropping :%u bytes",
+        ((nfa_hci_cb.msg_len + data_len) - nfa_hci_cb.max_msg_len));
+  } else {
+    memcpy(&nfa_hci_cb.p_msg_data[nfa_hci_cb.msg_len], p_data, data_len);
+    nfa_hci_cb.msg_len += data_len;
+  }
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_evt_hdlr
+**
+** Description      Processing all event for NFA HCI
+**
+** Returns          true if p_msg needs to be deallocated
+**
+*******************************************************************************/
+static bool nfa_hci_evt_hdlr(NFC_HDR* p_msg) {
+  tNFA_HCI_EVENT_DATA* p_evt_data = (tNFA_HCI_EVENT_DATA*)p_msg;
+
+#if (BT_TRACE_VERBOSE == true)
+  NFA_TRACE_EVENT4(
+      "nfa_hci_evt_hdlr state: %s (%d) event: %s (0x%04x)",
+      nfa_hciu_get_state_name(nfa_hci_cb.hci_state), nfa_hci_cb.hci_state,
+      nfa_hciu_get_event_name(p_evt_data->hdr.event), p_evt_data->hdr.event);
+#else
+  NFA_TRACE_EVENT2("nfa_hci_evt_hdlr state: %d event: 0x%04x",
+                   nfa_hci_cb.hci_state, p_evt_data->hdr.event);
+#endif
+
+  /* If this is an API request, queue it up */
+  if ((p_msg->event >= NFA_HCI_FIRST_API_EVENT) &&
+      (p_msg->event <= NFA_HCI_LAST_API_EVENT)) {
+    GKI_enqueue(&nfa_hci_cb.hci_api_q, p_msg);
+  } else {
+    switch (p_msg->event) {
+      case NFA_HCI_RSP_NV_READ_EVT:
+        nfa_hci_handle_nv_read(p_evt_data->nv_read.block,
+                               p_evt_data->nv_read.status);
+        break;
+
+      case NFA_HCI_RSP_NV_WRITE_EVT:
+        /* NV Ram write completed - nothing to do... */
+        break;
+
+      case NFA_HCI_RSP_TIMEOUT_EVT:
+#if (NXP_EXTNS == TRUE)
+          if(nfcFL.nfcNxpEse) {
+              if(nfcFL.eseFL._JCOP_WA_ENABLE) {
+                  if (nfa_ee_ce_p61_completed != 0) {
+                      NFA_TRACE_EVENT0(
+                              "nfa_hci_evt_hdlr Restart timer expired for wired transceive");
+                      nfa_ee_ce_p61_completed = 0;
+                  } else {
+                      uint32_t p61_access_status = 0x0000;
+                      if (NFC_GetP61Status((void*)&p61_access_status) < 0) {
+                          NFA_TRACE_EVENT0(
+                                  "nfa_hci_evt_hdlr : Check dual mode : NFC_GetP61Status failed");
+                      } else {
+                          if (((p61_access_status == 0x400) ||
+                                  (p61_access_status == 0x1000)) &&
+                                  (NFA_check_p61_CL_Activated() != 0)) {
+                              NFA_TRACE_EVENT0(
+                                      "nfa_hci_evt_hdlr Restart timer for wired transceive");
+                              nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
+                                      NFA_HCI_WTX_RESP_TIMEOUT);
+                              /*situation occurred*/
+                              nfa_ee_ce_p61_completed = 1;
+                              break;
+                          }
+                      }
+                  }
+              }
+          }
+#endif
+        nfa_hci_rsp_timeout((tNFA_HCI_EVENT_DATA*)p_msg);
+        break;
+
+      case NFA_HCI_CHECK_QUEUE_EVT:
+        if (HCI_LOOPBACK_DEBUG) {
+          if (p_msg->len != 0) {
+            tNFC_DATA_CEVT xx;
+            xx.p_data = p_msg;
+            nfa_hci_conn_cback(0, NFC_DATA_CEVT, (void*)&xx);
+            return false;
+          }
+        }
+        break;
+#if (NXP_EXTNS == TRUE)
+      case NFA_HCI_SESSION_ID_POLL_DELAY_TIMEOUT_EVT:
+      case NFA_HCI_NFCEE_DISCOVER_TIMEOUT_EVT:
+        nfa_hci_handle_nfcee_config_evt(NFA_HCI_READ_SESSIONID);
+        break;
+#endif
+    }
+  }
+
+  if ((p_msg->event > NFA_HCI_LAST_API_EVENT)) GKI_freebuf(p_msg);
+
+  nfa_hci_check_api_requests();
+
+  if (nfa_hciu_is_no_host_resetting()) nfa_hci_check_pending_api_requests();
+
+  if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) &&
+      (nfa_hci_cb.nv_write_needed)) {
+    nfa_hci_cb.nv_write_needed = false;
+    nfa_nv_co_write((uint8_t*)&nfa_hci_cb.cfg, sizeof(nfa_hci_cb.cfg),
+                    DH_NV_BLOCK);
+  }
+  return false;
+}
+
+#if (NXP_EXTNS == TRUE)
+void nfa_hci_release_transcieve() {
+  NFA_TRACE_DEBUG0("nfa_hci_release_transcieve (); Release ongoing transcieve");
+  if (nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_RSP) {
+    nfa_sys_stop_timer(&nfa_hci_cb.timer);
+    nfa_hci_rsp_timeout(NULL);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_is_valid_ese_cfg
+**
+** Description      Validate ESE control block config parameters
+**
++** Returns          true/false
+**
+*******************************************************************************/
+bool nfa_hci_is_valid_ese_cfg(void) {
+  /* Validate Gate Control block */
+  bool isFoundidGate = true;
+  bool isFoundEtsi12 = true;
+  uint8_t xx;
+  for (xx = 0; xx < NFA_HCI_MAX_PIPE_CB; xx++) {
+    if (((nfa_hci_cb.cfg.dyn_pipes[xx].dest_host) == 0xC0) &&
+        ((nfa_hci_cb.cfg.dyn_pipes[xx].dest_gate) ==
+         NFA_HCI_IDENTITY_MANAGEMENT_GATE) &&
+        ((nfa_hci_cb.cfg.dyn_pipes[xx].local_gate) ==
+         NFA_HCI_IDENTITY_MANAGEMENT_GATE)) {
+      NFA_TRACE_DEBUG0(
+          "nfa_hci_is_valid_ese_cfg()  Validate ID Management Gate Pipe Data");
+      NFA_TRACE_DEBUG1("nfa_hci_is_valid_ese_cfg()  Pipe id: %u",
+                       nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id);
+      NFA_TRACE_DEBUG1("nfa_hci_is_valid_ese_cfg()  Pipe state: %u",
+                       nfa_hci_cb.cfg.dyn_pipes[xx].pipe_state);
+      if ((nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id) != 0x00) {
+        NFA_TRACE_DEBUG0(
+            "nfa_hci_is_valid_ese_cfg()  Validate ID Management Gate Pipe "
+            "State");
+        if ((nfa_hci_cb.cfg.dyn_pipes[xx].pipe_state) != NFA_HCI_PIPE_OPENED) {
+          isFoundidGate = false;
+        }
+      }
+    }
+    if (((nfa_hci_cb.cfg.dyn_pipes[xx].dest_host) == 0xC0) &&
+        ((nfa_hci_cb.cfg.dyn_pipes[xx].dest_gate) ==
+         NFA_HCI_ETSI12_APDU_GATE) &&
+        ((nfa_hci_cb.cfg.dyn_pipes[xx].local_gate) ==
+         NFA_HCI_ETSI12_APDU_GATE)) {
+      NFA_TRACE_DEBUG0(
+          "nfa_hci_is_valid_ese_cfg()  Validate APDU Gate Pipe Data");
+      NFA_TRACE_DEBUG1("nfa_hci_is_valid_ese_cfg()  Pipe id: %u",
+                       nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id);
+      NFA_TRACE_DEBUG1("nfa_hci_is_valid_ese_cfg()  Pipe state: %u",
+                       nfa_hci_cb.cfg.dyn_pipes[xx].pipe_state);
+      if ((nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id) != 0x00) {
+        NFA_TRACE_DEBUG0(
+            "nfa_hci_is_valid_ese_cfg()  Validate APDU Gate Pipe State");
+        if ((nfa_hci_cb.cfg.dyn_pipes[xx].pipe_state) != NFA_HCI_PIPE_OPENED) {
+          isFoundEtsi12 = false;
+        }
+      }
+    }
+  }
+
+  if (!(isFoundidGate && isFoundEtsi12)) {
+    return false;
+  }
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_reset_session_rsp_cb
+**
+** Description      Callback function for ESE session ID reset
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_reset_session_rsp_cb(uint8_t event, uint16_t param_len,
+                                         uint8_t* p_param) {
+  (void)event;
+  NFA_TRACE_DEBUG2(
+      "nfa_hci_reset_session_rsp_cb: Received length data = 0x%x status = 0x%x",
+      param_len, p_param[3]);
+
+  if (p_param[3] == NFA_STATUS_OK) {
+    NXP_NFC_SET_MSB(nfa_hci_cb.cfg.retry_cnt);
+    nfa_nv_co_write((uint8_t*)&nfa_hci_cb.cfg, sizeof(nfa_hci_cb.cfg),
+                    DH_NV_BLOCK);
+    exit(0);
+  } else {
+    nfa_hci_startup();
+  }
+}
+#endif
diff --git a/src/nfa/hci/nfa_hci_utils.c b/src/nfa/hci/nfa_hci_utils.c
new file mode 100644
index 0000000..3cede30
--- /dev/null
+++ b/src/nfa/hci/nfa_hci_utils.c
@@ -0,0 +1,1643 @@
+/******************************************************************************
+ *
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the utility functions for the NFA HCI.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "trace_api.h"
+#include "nfc_api.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "nfa_dm_int.h"
+#include "nfa_hci_api.h"
+#include "nfa_hci_int.h"
+#include "nfa_nv_co.h"
+#include "nfa_mem_co.h"
+#include "nfa_hci_defs.h"
+
+static void handle_debug_loopback(NFC_HDR* p_buf, uint8_t pipe, uint8_t type,
+                                  uint8_t instruction);
+uint8_t HCI_LOOPBACK_DEBUG = false;
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_find_pipe_by_pid
+**
+** Description      look for the pipe control block based on pipe id
+**
+** Returns          pointer to the pipe control block, or NULL if not found
+**
+*******************************************************************************/
+tNFA_HCI_DYN_PIPE* nfa_hciu_find_pipe_by_pid(uint8_t pipe_id) {
+  tNFA_HCI_DYN_PIPE* pp = nfa_hci_cb.cfg.dyn_pipes;
+  int xx = 0;
+
+  /* Loop through looking for a match */
+  for (; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++) {
+    if (pp->pipe_id == pipe_id) return (pp);
+  }
+
+  /* If here, not found */
+  return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_find_gate_by_gid
+**
+** Description      Find the gate control block for the given gate id
+**
+** Returns          pointer to the gate control block, or NULL if not found
+**
+*******************************************************************************/
+tNFA_HCI_DYN_GATE* nfa_hciu_find_gate_by_gid(uint8_t gate_id) {
+  tNFA_HCI_DYN_GATE* pg = nfa_hci_cb.cfg.dyn_gates;
+  int xx = 0;
+
+  for (; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++) {
+    if (pg->gate_id == gate_id) return (pg);
+  }
+
+  return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_find_gate_by_owner
+**
+** Description      Find the the first gate control block for the given owner
+**
+** Returns          pointer to the gate control block, or NULL if not found
+**
+*******************************************************************************/
+tNFA_HCI_DYN_GATE* nfa_hciu_find_gate_by_owner(tNFA_HANDLE app_handle) {
+  tNFA_HCI_DYN_GATE* pg = nfa_hci_cb.cfg.dyn_gates;
+  int xx = 0;
+
+  for (; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++) {
+    if (pg->gate_owner == app_handle) return (pg);
+  }
+
+  return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_find_gate_with_nopipes_by_owner
+**
+** Description      Find the the first gate control block with no pipes
+**                  for the given owner
+**
+** Returns          pointer to the gate control block, or NULL if not found
+**
+*******************************************************************************/
+tNFA_HCI_DYN_GATE* nfa_hciu_find_gate_with_nopipes_by_owner(
+    tNFA_HANDLE app_handle) {
+  tNFA_HCI_DYN_GATE* pg = nfa_hci_cb.cfg.dyn_gates;
+  int xx = 0;
+
+  for (; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++) {
+    if ((pg->gate_owner == app_handle) && (pg->pipe_inx_mask == 0)) return (pg);
+  }
+
+  return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_count_pipes_on_gate
+**
+** Description      Count the number of pipes on the given gate
+**
+** Returns          the number of pipes on the gate
+**
+*******************************************************************************/
+uint8_t nfa_hciu_count_pipes_on_gate(tNFA_HCI_DYN_GATE* p_gate) {
+  int xx = 0;
+  uint32_t mask = 1;
+  uint8_t count = 0;
+
+  for (; xx < NFA_HCI_MAX_PIPE_CB; xx++) {
+    if (p_gate->pipe_inx_mask & mask) count++;
+
+    mask = mask << 1;
+  }
+
+  return (count);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_count_open_pipes_on_gate
+**
+** Description      Count the number of opened pipes on the given gate
+**
+** Returns          the number of pipes in OPENED state on the gate
+**
+*******************************************************************************/
+uint8_t nfa_hciu_count_open_pipes_on_gate(tNFA_HCI_DYN_GATE* p_gate) {
+  tNFA_HCI_DYN_PIPE* pp = nfa_hci_cb.cfg.dyn_pipes;
+  int xx = 0;
+  uint32_t mask = 1;
+  uint8_t count = 0;
+
+  for (; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++) {
+    /* For each pipe on this gate, check if it is open */
+    if ((p_gate->pipe_inx_mask & mask) &&
+        (pp->pipe_state == NFA_HCI_PIPE_OPENED))
+      count++;
+
+    mask = mask << 1;
+  }
+
+  return (count);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_get_gate_owner
+**
+** Description      Find the application that owns a gate
+**
+** Returns          application handle
+**
+*******************************************************************************/
+tNFA_HANDLE nfa_hciu_get_gate_owner(uint8_t gate_id) {
+  tNFA_HCI_DYN_GATE* pg;
+
+  pg = nfa_hciu_find_gate_by_gid(gate_id);
+  if (pg == NULL) return (NFA_HANDLE_INVALID);
+
+  return (pg->gate_owner);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_get_pipe_owner
+**
+** Description      Find the application that owns a pipe
+**
+** Returns          application handle
+**
+*******************************************************************************/
+tNFA_HANDLE nfa_hciu_get_pipe_owner(uint8_t pipe_id) {
+  tNFA_HCI_DYN_PIPE* pp;
+  tNFA_HCI_DYN_GATE* pg;
+
+  pp = nfa_hciu_find_pipe_by_pid(pipe_id);
+  if (pp == NULL) return (NFA_HANDLE_INVALID);
+
+  pg = nfa_hciu_find_gate_by_gid(pp->local_gate);
+  if (pg == NULL) return (NFA_HANDLE_INVALID);
+
+  return (pg->gate_owner);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_alloc_gate
+**
+** Description      Allocate an gate control block
+**
+** Returns          pointer to the allocated gate, or NULL if cannot allocate
+**
+*******************************************************************************/
+tNFA_HCI_DYN_GATE* nfa_hciu_alloc_gate(uint8_t gate_id,
+                                       tNFA_HANDLE app_handle) {
+  tNFA_HCI_DYN_GATE* pg;
+  int xx;
+  uint8_t app_inx = app_handle & NFA_HANDLE_MASK;
+
+  /* First, check if the application handle is valid */
+  if ((gate_id != NFA_HCI_CONNECTIVITY_GATE) &&
+      (gate_id < NFA_HCI_FIRST_PROP_GATE) &&
+      (((app_handle & NFA_HANDLE_GROUP_MASK) != NFA_HANDLE_GROUP_HCI) ||
+       (app_inx >= NFA_HCI_MAX_APP_CB) ||
+       (nfa_hci_cb.p_app_cback[app_inx] == NULL))) {
+    return (NULL);
+  }
+
+  if (gate_id != 0) {
+    pg = nfa_hciu_find_gate_by_gid(gate_id);
+    if (pg != NULL) return (pg);
+  } else {
+    /* If gate_id is 0, we need to assign a free one */
+    /* Loop through all possible gate IDs checking if they are already used */
+    for (gate_id = NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE;
+         gate_id <= NFA_HCI_LAST_PROP_GATE; gate_id++) {
+      /* Skip connectivity gate */
+      if (gate_id == NFA_HCI_CONNECTIVITY_GATE) gate_id++;
+
+      /* Check if the gate is already allocated */
+      if (nfa_hciu_find_gate_by_gid(gate_id) == NULL) break;
+    }
+#if (NXP_EXTNS == TRUE)
+#else
+    if (gate_id > NFA_HCI_LAST_PROP_GATE) {
+      NFA_TRACE_ERROR2(
+          "nfa_hci_alloc_gate - no free Gate ID: %u  App Handle: 0x%04x",
+          gate_id, app_handle);
+      return (NULL);
+    }
+#endif
+  }
+
+  /* Now look for a free control block */
+  for (xx = 0, pg = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB;
+       xx++, pg++) {
+    if (pg->gate_id == 0) {
+      /* Found a free gate control block */
+      pg->gate_id = gate_id;
+      pg->gate_owner = app_handle;
+      pg->pipe_inx_mask = 0;
+
+      NFA_TRACE_DEBUG2("nfa_hciu_alloc_gate id:%d  app_handle: 0x%04x", gate_id,
+                       app_handle);
+
+      nfa_hci_cb.nv_write_needed = true;
+      return (pg);
+    }
+  }
+
+  /* If here, no free gate control block */
+  NFA_TRACE_ERROR2(
+      "nfa_hci_alloc_gate - no CB  Gate ID: %u  App Handle: 0x%04x", gate_id,
+      app_handle);
+  return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_send_msg
+**
+** Description      This function will fragment the given packet, if necessary
+**                  and send it on the given pipe.
+**
+** Returns          status
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hciu_send_msg(uint8_t pipe_id, uint8_t type,
+                              uint8_t instruction, uint16_t msg_len,
+                              uint8_t* p_msg) {
+  NFC_HDR* p_buf;
+  uint8_t* p_data;
+  bool first_pkt = true;
+  uint16_t data_len;
+  tNFA_STATUS status = NFA_STATUS_OK;
+  uint16_t max_seg_hcp_pkt_size = nfa_hci_cb.buff_size;
+#if (NXP_EXTNS == TRUE)
+  nfa_hci_cb.IsChainedPacket = false;
+#endif
+#if (BT_TRACE_VERBOSE == true)
+  char buff[VERBOSE_BUFF_SIZE];
+
+  NFA_TRACE_DEBUG3(
+      "nfa_hciu_send_msg pipe_id:%d   %s  len:%d", pipe_id,
+      nfa_hciu_get_type_inst_names(pipe_id, type, instruction, buff), msg_len);
+#else
+  NFA_TRACE_DEBUG4("nfa_hciu_send_msg pipe_id:%d   Type: %u  Inst: %u  len: %d",
+                   pipe_id, type, instruction, msg_len);
+#endif
+
+  if (instruction == NFA_HCI_ANY_GET_PARAMETER)
+    nfa_hci_cb.param_in_use = *p_msg;
+
+#if (NXP_EXTNS == TRUE)
+  if (type == NFA_HCI_EVENT_TYPE) {
+    nfa_hci_cb.hci_packet_len = msg_len;
+    nfa_hci_cb.IsEventAbortSent = false;
+    if (instruction == NFA_EVT_ABORT) {
+      NFA_TRACE_DEBUG0("Flush the queue!!!");
+      NFC_FlushData(nfa_hci_cb.conn_id);
+    } else if (nfa_hci_cb.IsLastEvtAbortFailed) {
+      /* send EVT_ABORT command */
+      if ((p_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID)) != NULL) {
+        p_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+        p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
+        *p_data++ = (NFA_HCI_NO_MESSAGE_FRAGMENTATION << 7) |
+                    (nfa_hci_cb.pipe_in_use & 0x7F);
+        *p_data++ = (NFA_HCI_EVENT_TYPE << 6) | NFA_EVT_ABORT;
+        p_buf->len = 2;
+        NFC_SendData(nfa_hci_cb.conn_id, p_buf);
+      }
+    }
+  }
+#endif
+
+  while ((first_pkt == true) || (msg_len != 0)) {
+    p_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+    if (p_buf != NULL) {
+      p_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+      /* First packet has a 2-byte header, subsequent fragments have a 1-byte
+       * header */
+      data_len =
+          first_pkt ? (max_seg_hcp_pkt_size - 2) : (max_seg_hcp_pkt_size - 1);
+
+      p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
+
+      /* Last or only segment has "no fragmentation" bit set */
+      if (msg_len > data_len) {
+        *p_data++ = (NFA_HCI_MESSAGE_FRAGMENTATION << 7) | (pipe_id & 0x7F);
+#if (NXP_EXTNS == TRUE)
+        nfa_hci_cb.IsChainedPacket = true;
+#endif
+      } else {
+        data_len = msg_len;
+        *p_data++ = (NFA_HCI_NO_MESSAGE_FRAGMENTATION << 7) | (pipe_id & 0x7F);
+      }
+
+      p_buf->len = 1;
+
+      /* Message header only goes in the first segment */
+      if (first_pkt) {
+        first_pkt = false;
+        *p_data++ = (type << 6) | instruction;
+        p_buf->len++;
+      }
+
+      if ((data_len != 0) && (p_msg != NULL)) {
+        memcpy(p_data, p_msg, data_len);
+
+        p_buf->len += data_len;
+        msg_len -= data_len;
+        if (msg_len > 0) p_msg += data_len;
+      }
+
+#if (BT_TRACE_PROTOCOL == true)
+      DispHcp(((uint8_t*)(p_buf + 1) + p_buf->offset), p_buf->len, false,
+              (bool)((p_buf->len - data_len) == 2));
+#endif
+
+      if (HCI_LOOPBACK_DEBUG)
+        handle_debug_loopback(p_buf, pipe_id, type, instruction);
+      else
+        status = NFC_SendData(nfa_hci_cb.conn_id, p_buf);
+    } else {
+      NFA_TRACE_ERROR0("nfa_hciu_send_data_packet no buffers");
+      status = NFA_STATUS_NO_BUFFERS;
+      break;
+    }
+  }
+
+  /* Start timer if response to wait for a particular time for the response  */
+  if (type == NFA_HCI_COMMAND_TYPE) {
+    nfa_hci_cb.cmd_sent = instruction;
+
+    if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE)
+      nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_RSP;
+    nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
+                        p_nfa_hci_cfg->hcp_response_timeout);
+  }
+#if (NXP_EXTNS == TRUE)
+  else if (type == NFA_HCI_EVENT_TYPE) {
+    nfa_hci_cb.evt_sent.evt_type = instruction;
+  }
+#endif
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_get_allocated_gate_list
+**
+** Description      fills in a list of allocated gates
+**
+** Returns          the number of gates
+**
+*******************************************************************************/
+uint8_t nfa_hciu_get_allocated_gate_list(uint8_t* p_gate_list) {
+  tNFA_HCI_DYN_GATE* p_cb;
+  int xx;
+  uint8_t count = 0;
+
+  for (xx = 0, p_cb = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB;
+       xx++, p_cb++) {
+    if (p_cb->gate_id != 0) {
+      *p_gate_list++ = p_cb->gate_id;
+      count++;
+    }
+  }
+
+  NFA_TRACE_DEBUG1("nfa_hciu_get_allocated_gate_list () returns: %u", count);
+
+  return (count);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_alloc_pipe
+**
+** Description      Allocate a pipe control block
+**
+** Returns          pointer to the pipe control block, or NULL if
+**                  cannot allocate
+**
+*******************************************************************************/
+tNFA_HCI_DYN_PIPE* nfa_hciu_alloc_pipe(uint8_t pipe_id) {
+  uint8_t xx;
+  tNFA_HCI_DYN_PIPE* pp;
+
+  /* If we already have a pipe of the same ID, release it first it */
+  pp = nfa_hciu_find_pipe_by_pid(pipe_id);
+  if (pp != NULL) {
+    if (pipe_id > NFA_HCI_LAST_DYNAMIC_PIPE) return pp;
+    nfa_hciu_release_pipe(pipe_id);
+  }
+
+  /* Look for a free pipe control block */
+  for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
+       xx++, pp++) {
+    if (pp->pipe_id == 0) {
+      NFA_TRACE_DEBUG2("nfa_hciu_alloc_pipe:%d, index:%d", pipe_id, xx);
+      pp->pipe_id = pipe_id;
+
+      nfa_hci_cb.nv_write_needed = true;
+      return (pp);
+    }
+  }
+
+  NFA_TRACE_DEBUG1("nfa_hciu_alloc_pipe:%d, NO free entries !!", pipe_id);
+  return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_release_gate
+**
+** Description      Remove a generic gate from gate list
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_hciu_release_gate(uint8_t gate_id) {
+  tNFA_HCI_DYN_GATE* p_gate = nfa_hciu_find_gate_by_gid(gate_id);
+
+  if (p_gate != NULL) {
+    NFA_TRACE_DEBUG3(
+        "nfa_hciu_release_gate () ID: %d  owner: 0x%04x  pipe_inx_mask: 0x%04x",
+        gate_id, p_gate->gate_owner, p_gate->pipe_inx_mask);
+
+    p_gate->gate_id = 0;
+    p_gate->gate_owner = 0;
+    p_gate->pipe_inx_mask = 0;
+
+    nfa_hci_cb.nv_write_needed = true;
+  } else {
+    NFA_TRACE_WARNING1("nfa_hciu_release_gate () ID: %d  NOT FOUND", gate_id);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_add_pipe_to_gate
+**
+** Description      Add pipe to generic gate
+**
+** Returns          NFA_STATUS_OK, if successfully add the pipe on to the gate
+**                  NFA_HCI_ADM_E_NO_PIPES_AVAILABLE, otherwise
+**
+*******************************************************************************/
+tNFA_HCI_RESPONSE nfa_hciu_add_pipe_to_gate(uint8_t pipe_id, uint8_t local_gate,
+                                            uint8_t dest_host,
+                                            uint8_t dest_gate) {
+  tNFA_HCI_DYN_GATE* p_gate;
+  tNFA_HCI_DYN_PIPE* p_pipe;
+  uint8_t pipe_index;
+
+  p_gate = nfa_hciu_find_gate_by_gid(local_gate);
+
+  if (p_gate != NULL) {
+    /* Allocate a pipe control block */
+    p_pipe = nfa_hciu_alloc_pipe(pipe_id);
+    if (p_pipe != NULL) {
+      p_pipe->pipe_id = pipe_id;
+      p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
+      p_pipe->dest_host = dest_host;
+      p_pipe->dest_gate = dest_gate;
+      p_pipe->local_gate = local_gate;
+
+      /* Save the pipe in the gate that it belongs to */
+      pipe_index = (uint8_t)(p_pipe - nfa_hci_cb.cfg.dyn_pipes);
+      p_gate->pipe_inx_mask |= (uint32_t)(1 << pipe_index);
+
+      NFA_TRACE_DEBUG4(
+          "nfa_hciu_add_pipe_to_gate  Gate ID: 0x%02x  Pipe ID: 0x%02x  "
+          "pipe_index: %u  App Handle: 0x%08x",
+          local_gate, pipe_id, pipe_index, p_gate->gate_owner);
+      return (NFA_HCI_ANY_OK);
+    }
+  }
+
+  NFA_TRACE_DEBUG1("nfa_hciu_add_pipe_to_gate: 0x%02x  NOT FOUND", local_gate);
+
+  return (NFA_HCI_ADM_E_NO_PIPES_AVAILABLE);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_add_pipe_to_static_gate
+**
+** Description      Add pipe to identity management gate
+**
+** Returns          NFA_HCI_ANY_OK, if successfully add the pipe on to the gate
+**                  NFA_HCI_ADM_E_NO_PIPES_AVAILABLE, otherwise
+**
+*******************************************************************************/
+tNFA_HCI_RESPONSE nfa_hciu_add_pipe_to_static_gate(uint8_t local_gate,
+                                                   uint8_t pipe_id,
+                                                   uint8_t dest_host,
+                                                   uint8_t dest_gate) {
+  tNFA_HCI_DYN_PIPE* p_pipe;
+  uint8_t pipe_index;
+
+  NFA_TRACE_EVENT4(
+      "nfa_hciu_add_pipe_to_static_gate (%u)  Pipe: 0x%02x  Dest Host: 0x%02x  "
+      "Dest Gate: 0x%02x)",
+      local_gate, pipe_id, dest_host, dest_gate);
+
+  /* Allocate a pipe control block */
+  p_pipe = nfa_hciu_alloc_pipe(pipe_id);
+  if (p_pipe != NULL) {
+    p_pipe->pipe_id = pipe_id;
+    p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
+    p_pipe->dest_host = dest_host;
+    p_pipe->dest_gate = dest_gate;
+    p_pipe->local_gate = local_gate;
+
+    /* If this is the ID gate, save the pipe index in the ID gate info     */
+    /* block. Note that for loopback, it is enough to just create the pipe */
+    if (local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE) {
+      pipe_index = (uint8_t)(p_pipe - nfa_hci_cb.cfg.dyn_pipes);
+      nfa_hci_cb.cfg.id_mgmt_gate.pipe_inx_mask |= (uint32_t)(1 << pipe_index);
+    }
+    return NFA_HCI_ANY_OK;
+  }
+
+  return NFA_HCI_ADM_E_NO_PIPES_AVAILABLE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_find_active_pipe_by_owner
+**
+** Description      Find the first pipe associated with the given app
+**
+** Returns          pointer to pipe, or NULL if none found
+**
+*******************************************************************************/
+tNFA_HCI_DYN_PIPE* nfa_hciu_find_active_pipe_by_owner(tNFA_HANDLE app_handle) {
+  tNFA_HCI_DYN_GATE* pg;
+  tNFA_HCI_DYN_PIPE* pp;
+  int xx;
+
+  NFA_TRACE_DEBUG1("nfa_hciu_find_pipe_by_owner () app_handle:0x%x",
+                   app_handle);
+
+  /* Loop through all pipes looking for the owner */
+  for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
+       xx++, pp++) {
+    if ((pp->pipe_id != 0) && (pp->pipe_id >= NFA_HCI_FIRST_DYNAMIC_PIPE) &&
+        (pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE) &&
+        (nfa_hciu_is_active_host(pp->dest_host))) {
+      if (((pg = nfa_hciu_find_gate_by_gid(pp->local_gate)) != NULL) &&
+          (pg->gate_owner == app_handle))
+        return (pp);
+    }
+  }
+
+  /* If here, not found */
+  return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_check_pipe_between_gates
+**
+** Description      Check if there is a pipe between specified Terminal host
+**                  gate and and the specified UICC gate
+**
+** Returns          true, if there exists a pipe between the two specified gated
+**                  false, otherwise
+**
+*******************************************************************************/
+bool nfa_hciu_check_pipe_between_gates(uint8_t local_gate, uint8_t dest_host,
+                                       uint8_t dest_gate) {
+  tNFA_HCI_DYN_PIPE* pp;
+  int xx;
+
+  NFA_TRACE_DEBUG3(
+      "nfa_hciu_check_pipe_between_gates () Local gate: 0x%02X, Host[0x%02X] "
+      "gate: 0x%02X",
+      local_gate, dest_host, dest_gate);
+
+  /* Loop through all pipes looking for the owner */
+  for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
+       xx++, pp++) {
+    if ((pp->pipe_id != 0) && (pp->pipe_id >= NFA_HCI_FIRST_DYNAMIC_PIPE) &&
+        (pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE) &&
+        (pp->local_gate == local_gate) && (pp->dest_host == dest_host) &&
+        (pp->dest_gate == dest_gate)) {
+      return (true);
+    }
+  }
+
+  /* If here, not found */
+  return (false);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_find_pipe_by_owner
+**
+** Description      Find the first pipe associated with the given app
+**
+** Returns          pointer to pipe, or NULL if none found
+**
+*******************************************************************************/
+tNFA_HCI_DYN_PIPE* nfa_hciu_find_pipe_by_owner(tNFA_HANDLE app_handle) {
+  tNFA_HCI_DYN_GATE* pg;
+  tNFA_HCI_DYN_PIPE* pp;
+  int xx;
+
+  NFA_TRACE_DEBUG1("nfa_hciu_find_pipe_by_owner () app_handle:0x%x",
+                   app_handle);
+
+  /* Loop through all pipes looking for the owner */
+  for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
+       xx++, pp++) {
+    if (pp->pipe_id != 0) {
+      if (((pg = nfa_hciu_find_gate_by_gid(pp->local_gate)) != NULL) &&
+          (pg->gate_owner == app_handle))
+        return (pp);
+    }
+  }
+
+  /* If here, not found */
+  return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_find_pipe_on_gate
+**
+** Description      Find the first pipe associated with the given gate
+**
+** Returns          pointer to pipe, or NULL if none found
+**
+*******************************************************************************/
+tNFA_HCI_DYN_PIPE* nfa_hciu_find_pipe_on_gate(uint8_t gate_id) {
+  tNFA_HCI_DYN_GATE* pg;
+  tNFA_HCI_DYN_PIPE* pp;
+  int xx;
+
+  NFA_TRACE_DEBUG1("nfa_hciu_find_pipe_on_gate () Gate:0x%x", gate_id);
+
+  /* Loop through all pipes looking for the owner */
+  for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
+       xx++, pp++) {
+    if (pp->pipe_id != 0) {
+      if (((pg = nfa_hciu_find_gate_by_gid(pp->local_gate)) != NULL) &&
+          (pg->gate_id == gate_id))
+        return (pp);
+    }
+  }
+
+  /* If here, not found */
+  return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_is_active_host
+**
+** Description      Check if the host is currently active
+**
+** Returns          true, if the host is active in the host network
+**                  false, if the host is not active in the host network
+**
+*******************************************************************************/
+bool nfa_hciu_is_active_host(uint8_t host_id) {
+  uint8_t xx;
+
+  for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++) {
+    if (nfa_hci_cb.inactive_host[xx] == host_id) return false;
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_is_host_reseting
+**
+** Description      Check if the host is currently reseting
+**
+** Returns          true, if the host is reseting
+**                  false, if the host is not reseting
+**
+*******************************************************************************/
+bool nfa_hciu_is_host_reseting(uint8_t host_id) {
+  uint8_t xx;
+
+  for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++) {
+    if (nfa_hci_cb.reset_host[xx] == host_id) return true;
+  }
+
+  return false;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_is_no_host_resetting
+**
+** Description      Check if no host is reseting
+**
+** Returns          true, if no host is resetting at this time
+**                  false, if one or more host is resetting
+**
+*******************************************************************************/
+bool nfa_hciu_is_no_host_resetting(void) {
+  uint8_t xx;
+
+  for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++) {
+    if (nfa_hci_cb.reset_host[xx] != 0) return false;
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_find_active_pipe_on_gate
+**
+** Description      Find the first active pipe associated with the given gate
+**
+** Returns          pointer to pipe, or NULL if none found
+**
+*******************************************************************************/
+tNFA_HCI_DYN_PIPE* nfa_hciu_find_active_pipe_on_gate(uint8_t gate_id) {
+  tNFA_HCI_DYN_GATE* pg;
+  tNFA_HCI_DYN_PIPE* pp;
+  int xx;
+
+  NFA_TRACE_DEBUG1("nfa_hciu_find_active_pipe_on_gate () Gate:0x%x", gate_id);
+
+  /* Loop through all pipes looking for the owner */
+  for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
+       xx++, pp++) {
+    if ((pp->pipe_id != 0) && (pp->pipe_id >= NFA_HCI_FIRST_DYNAMIC_PIPE) &&
+        (pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE) &&
+        (nfa_hciu_is_active_host(pp->dest_host))) {
+      if (((pg = nfa_hciu_find_gate_by_gid(pp->local_gate)) != NULL) &&
+          (pg->gate_id == gate_id))
+        return (pp);
+    }
+  }
+
+  /* If here, not found */
+  return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_release_pipe
+**
+** Description      remove the specified pipe
+**
+** Returns          NFA_HCI_ANY_OK, if removed
+**                  NFA_HCI_ANY_E_NOK, if otherwise
+**
+*******************************************************************************/
+tNFA_HCI_RESPONSE nfa_hciu_release_pipe(uint8_t pipe_id) {
+  tNFA_HCI_DYN_GATE* p_gate;
+  tNFA_HCI_DYN_PIPE* p_pipe;
+  uint8_t pipe_index;
+
+  NFA_TRACE_EVENT1("nfa_hciu_release_pipe: %u", pipe_id);
+
+  p_pipe = nfa_hciu_find_pipe_by_pid(pipe_id);
+  if (p_pipe == NULL) return (NFA_HCI_ANY_E_NOK);
+
+  if (pipe_id > NFA_HCI_LAST_DYNAMIC_PIPE) {
+    NFA_TRACE_DEBUG1("ignore pipe: %d", pipe_id);
+    return (NFA_HCI_ANY_E_NOK);
+  }
+
+  pipe_index = (uint8_t)(p_pipe - nfa_hci_cb.cfg.dyn_pipes);
+
+  if (p_pipe->local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE) {
+    /* Remove pipe from ID management gate */
+    nfa_hci_cb.cfg.id_mgmt_gate.pipe_inx_mask &= ~(uint32_t)(1 << pipe_index);
+  } else {
+    p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
+    if (p_gate == NULL) {
+      /* Mark the pipe control block as free */
+      p_pipe->pipe_id = 0;
+      return (NFA_HCI_ANY_E_NOK);
+    }
+
+    /* Remove pipe from gate */
+    p_gate->pipe_inx_mask &= ~(uint32_t)(1 << pipe_index);
+  }
+
+  /* Reset pipe control block */
+  memset(p_pipe, 0, sizeof(tNFA_HCI_DYN_PIPE));
+  nfa_hci_cb.nv_write_needed = true;
+  return NFA_HCI_ANY_OK;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_remove_all_pipes_from_host
+**
+** Description      remove all the pipes that are connected to a specific host
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hciu_remove_all_pipes_from_host(uint8_t host) {
+  tNFA_HCI_DYN_GATE* pg;
+  tNFA_HCI_DYN_PIPE* pp;
+  int xx;
+  tNFA_HCI_EVT_DATA evt_data;
+
+  NFA_TRACE_EVENT1("nfa_hciu_remove_all_pipes_from_host (0x%02x)", host);
+
+  /* Remove all pipes from the specified host connected to all generic gates */
+  for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
+       xx++, pp++) {
+    if ((pp->pipe_id == 0) ||
+        ((host != 0) && ((pp->dest_host != host) ||
+                         (pp->pipe_id > NFA_HCI_LAST_DYNAMIC_PIPE))))
+      continue;
+
+    pg = nfa_hciu_find_gate_by_gid(pp->local_gate);
+    if (pg != NULL) {
+      evt_data.deleted.status = NFA_STATUS_OK;
+      evt_data.deleted.pipe = pp->pipe_id;
+#if (NXP_EXTNS == TRUE)
+      evt_data.deleted.host = host;
+#endif
+      nfa_hciu_send_to_app(NFA_HCI_DELETE_PIPE_EVT, &evt_data, pg->gate_owner);
+    }
+    nfa_hciu_release_pipe(pp->pipe_id);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_send_create_pipe_cmd
+**
+** Description      Create dynamic pipe between the specified gates
+**
+** Returns          status
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hciu_send_create_pipe_cmd(uint8_t source_gate,
+                                          uint8_t dest_host,
+                                          uint8_t dest_gate) {
+  tNFA_STATUS status;
+  uint8_t data[3];
+
+  data[0] = source_gate;
+  data[1] = dest_host;
+  data[2] = dest_gate;
+
+  NFA_TRACE_DEBUG3(
+      "nfa_hciu_send_create_pipe_cmd source_gate:%d, dest_host:%d, "
+      "dest_gate:%d",
+      source_gate, dest_host, dest_gate);
+
+  status = nfa_hciu_send_msg(NFA_HCI_ADMIN_PIPE, NFA_HCI_COMMAND_TYPE,
+                             NFA_HCI_ADM_CREATE_PIPE, 3, data);
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_send_delete_pipe_cmd
+**
+** Description      Delete the dynamic pipe
+**
+** Returns          None
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hciu_send_delete_pipe_cmd(uint8_t pipe) {
+  tNFA_STATUS status;
+
+  NFA_TRACE_DEBUG1("nfa_hciu_send_delete_pipe_cmd: %d", pipe);
+
+  if (pipe > NFA_HCI_LAST_DYNAMIC_PIPE) {
+    NFA_TRACE_DEBUG1("ignore pipe: %d", pipe);
+    return (NFA_HCI_ANY_E_NOK);
+  }
+  nfa_hci_cb.pipe_in_use = pipe;
+
+  status = nfa_hciu_send_msg(NFA_HCI_ADMIN_PIPE, NFA_HCI_COMMAND_TYPE,
+                             NFA_HCI_ADM_DELETE_PIPE, 1, &pipe);
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_send_clear_all_pipe_cmd
+**
+** Description      delete all the dynamic pipe connected to device host,
+**                  to close all static pipes connected to device host,
+**                  and to set registry values related to static pipes to
+**                  theri default values.
+**
+** Returns          None
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hciu_send_clear_all_pipe_cmd(void) {
+  tNFA_STATUS status;
+  uint16_t id_ref_data = 0x0102;
+
+  NFA_TRACE_DEBUG0("nfa_hciu_send_clear_all_pipe_cmd");
+
+  status =
+      nfa_hciu_send_msg(NFA_HCI_ADMIN_PIPE, NFA_HCI_COMMAND_TYPE,
+                        NFA_HCI_ADM_CLEAR_ALL_PIPE, 2, (uint8_t*)&id_ref_data);
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_send_open_pipe_cmd
+**
+** Description      Open a closed pipe
+**
+** Returns          status
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hciu_send_open_pipe_cmd(uint8_t pipe) {
+  tNFA_STATUS status;
+
+  nfa_hci_cb.pipe_in_use = pipe;
+
+  status = nfa_hciu_send_msg(pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_OPEN_PIPE,
+                             0, NULL);
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_send_close_pipe_cmd
+**
+** Description      Close an opened pipe
+**
+** Returns          status
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hciu_send_close_pipe_cmd(uint8_t pipe) {
+  tNFA_STATUS status;
+
+  nfa_hci_cb.pipe_in_use = pipe;
+
+  status = nfa_hciu_send_msg(pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_CLOSE_PIPE,
+                             0, NULL);
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_send_get_param_cmd
+**
+** Description      Read a parameter value from gate registry
+**
+** Returns          None
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hciu_send_get_param_cmd(uint8_t pipe, uint8_t index) {
+  tNFA_STATUS status;
+
+  status = nfa_hciu_send_msg(pipe, NFA_HCI_COMMAND_TYPE,
+                             NFA_HCI_ANY_GET_PARAMETER, 1, &index);
+  if (status == NFC_STATUS_OK) nfa_hci_cb.param_in_use = index;
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_send_set_param_cmd
+**
+** Description      Set a parameter value in a gate registry
+**
+** Returns          None
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hciu_send_set_param_cmd(uint8_t pipe, uint8_t index,
+                                        uint8_t length, uint8_t* p_data) {
+  tNFA_STATUS status;
+  uint8_t data[255];
+
+  data[0] = index;
+
+  memcpy(&data[1], p_data, length);
+
+  status =
+      nfa_hciu_send_msg(pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_SET_PARAMETER,
+                        (uint16_t)(length + 1), data);
+  if (status == NFC_STATUS_OK) nfa_hci_cb.param_in_use = index;
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_send_to_app
+**
+** Description      Send an event back to an application
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_hciu_send_to_app(tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA* p_evt,
+                          tNFA_HANDLE app_handle) {
+  uint8_t app_inx = app_handle & NFA_HANDLE_MASK;
+
+  /* First, check if the application handle is valid */
+  if (((app_handle & NFA_HANDLE_GROUP_MASK) == NFA_HANDLE_GROUP_HCI) &&
+      (app_inx < NFA_HCI_MAX_APP_CB)) {
+    if (nfa_hci_cb.p_app_cback[app_inx] != NULL) {
+      nfa_hci_cb.p_app_cback[app_inx](event, p_evt);
+      return;
+    }
+  }
+
+  if (app_handle != NFA_HANDLE_INVALID) {
+    NFA_TRACE_WARNING2(
+        "nfa_hciu_send_to_app no callback,  event: 0x%04x  app_handle: 0x%04x",
+        event, app_handle);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_send_to_all_apps
+**
+** Description      Send an event back to all applications
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_hciu_send_to_all_apps(tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA* p_evt) {
+  uint8_t app_inx;
+
+  for (app_inx = 0; app_inx < NFA_HCI_MAX_APP_CB; app_inx++) {
+    if (nfa_hci_cb.p_app_cback[app_inx] != NULL)
+      nfa_hci_cb.p_app_cback[app_inx](event, p_evt);
+  }
+#if (NXP_EXTNS == TRUE)
+  nfa_hci_nfcee_config_rsp_handler(event, p_evt);
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_send_to_apps_handling_connectivity_evts
+**
+** Description      Send a connectivity event to all the application interested
+**                  in connectivity events
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_hciu_send_to_apps_handling_connectivity_evts(
+    tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA* p_evt) {
+  uint8_t app_inx;
+
+  for (app_inx = 0; app_inx < NFA_HCI_MAX_APP_CB; app_inx++) {
+    if ((nfa_hci_cb.p_app_cback[app_inx] != NULL) &&
+        (nfa_hci_cb.cfg.b_send_conn_evts[app_inx]))
+
+      nfa_hci_cb.p_app_cback[app_inx](event, p_evt);
+  }
+}
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         nfa_hciu_send_raw_cmd
+**
+** Description      send raw command from the HCI module
+**
+** Returns          tNFA_STATUS  NFA_STATUS_OK or NFA_STATUS_FAILED
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hciu_send_raw_cmd(uint8_t param_len, uint8_t* p_data,
+                                  tNFA_VSC_CBACK* p_cback) {
+  tNFA_STATUS status = NFA_STATUS_OK;
+  status = NFA_SendNxpNciCommand(param_len, p_data, p_cback);
+  if (NFA_STATUS_OK == status) {
+    nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
+                        p_nfa_hci_cfg->hcp_response_timeout);
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_check_nfcee_init_done
+**
+** Description      Check whether nfcee id session id poll is complete or not
+**
+** Returns          true/false
+**
+*******************************************************************************/
+bool nfa_hciu_check_nfcee_poll_done(uint8_t host_id) {
+  NFA_TRACE_DEBUG1("nfa_hciu_check_nfcee_poll_done enter: %x", host_id);
+  uint8_t xx;
+  for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++) {
+    if ((nfa_hci_cb.nfcee_cfg.host_cb[xx] & NFA_HANDLE_MASK) == host_id) {
+      if (nfa_hci_cb.nfcee_cfg.host_cb[xx] & NFA_HCI_SESSION_ID_MASK)
+        return true;
+      break;
+    }
+  }
+  return false;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_check_nfcee_config_done
+**
+** Description      Check whether nfcee config is done or not.
+**
+** Returns          true/false
+**
+*******************************************************************************/
+bool nfa_hciu_check_nfcee_config_done(uint8_t host_id) {
+  NFA_TRACE_DEBUG1("nfa_hciu_check_nfcee_config_done: %x", host_id);
+  uint8_t xx;
+  for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++) {
+    if ((nfa_hci_cb.nfcee_cfg.host_cb[xx] & NFA_HANDLE_MASK) == host_id) {
+      if (nfa_hci_cb.nfcee_cfg.host_cb[xx] & NFA_HCI_NFCEE_CONFIG_MASK)
+        return true;
+      break;
+    }
+  }
+  return false;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_set_nfceeid_config_mask
+**
+** Description      set the bit which host is resetting
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hciu_set_nfceeid_config_mask(uint8_t event, uint8_t host_id) {
+  NFA_TRACE_DEBUG1("nfa_hciu_set_nfceeid_config_mask: %x", host_id);
+  uint8_t xx;
+  for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++) {
+    if ((nfa_hci_cb.nfcee_cfg.host_cb[xx] & NFA_HANDLE_MASK) == host_id) {
+      if (event == NFA_HCI_SET_CONFIG_EVENT)
+        nfa_hci_cb.nfcee_cfg.host_cb[xx] |= NFA_HCI_NFCEE_CONFIG_MASK;
+      else if (event == NFA_HCI_CLEAR_CONFIG_EVENT)
+        nfa_hci_cb.nfcee_cfg.host_cb[xx] &= ~NFA_HCI_NFCEE_CONFIG_MASK;
+      break;
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_set_nfceeid_poll_mask
+**
+** Description      set the bit which host is resetting
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hciu_set_nfceeid_poll_mask(uint8_t event, uint8_t host_id) {
+  NFA_TRACE_DEBUG1("nfa_hciu_set_nfceeid_config_mask: %x", host_id);
+  uint8_t xx;
+  for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++) {
+    if ((nfa_hci_cb.nfcee_cfg.host_cb[xx] & NFA_HANDLE_MASK) == host_id) {
+      if (event == NFA_HCI_SET_CONFIG_EVENT)
+        nfa_hci_cb.nfcee_cfg.host_cb[xx] |= NFA_HCI_SESSION_ID_MASK;
+      else if (event == NFA_HCI_CLEAR_CONFIG_EVENT)
+        nfa_hci_cb.nfcee_cfg.host_cb[xx] &= ~NFA_HCI_SESSION_ID_MASK;
+      break;
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_check_any_host_reset_pending
+**
+** Description      checks if any host clear all pipe handling is pending
+**
+** Returns          true/false
+**
+*******************************************************************************/
+bool nfa_hciu_check_any_host_reset_pending() {
+  uint8_t xx;
+  bool status = false;
+  for (xx = 0; xx < nfa_hci_cb.num_nfcee; xx++) {
+    if ((((nfa_hci_cb.hci_ee_info[xx].ee_interface[0] !=
+        NCI_NFCEE_INTERFACE_HCI_ACCESS)&&
+        nfa_hci_cb.hci_ee_info[xx].ee_status == NFA_EE_STATUS_ACTIVE )&&
+        (nfa_hci_cb.hci_ee_info[xx].ee_handle != 0x410))) {
+      if (nfa_hciu_check_nfcee_poll_done(nfa_hci_cb.hci_ee_info[xx].ee_handle &
+                                         ~(NFA_HANDLE_GROUP_EE)) == false) {
+        status = true;
+        break;
+      }
+    }
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_reset_session_id
+**
++** Description      reset ESE session ID to FF
+**
+** Returns          tNFA_STATUS
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hciu_reset_session_id(tNFA_VSC_CBACK* p_cback) {
+  tNFA_STATUS status = NFA_STATUS_FAILED;
+  uint8_t* pp, *p_start;
+  uint8_t cmd_len = 0;
+  tNFA_DM_API_SEND_VSC* p_data;
+  NFC_HDR* p_cmd;
+  uint8_t id_buf[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+  NFA_TRACE_DEBUG1("%s: enter", __func__);
+
+  p_data = (tNFA_DM_API_SEND_VSC*)GKI_getbuf(sizeof(tNFA_DM_API_SEND_VSC) +
+                                             NXP_NFC_PROP_MAX_CMD_BUF_SIZE);
+  if (p_data != NULL) {
+    p_cmd = (NFC_HDR*)p_data;
+    p_cmd->offset = sizeof(tNFA_DM_API_SEND_VSC) - NFC_HDR_SIZE;
+    pp = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
+    NCI_MSG_BLD_HDR0(pp, NCI_MT_CMD, NCI_GID_CORE);
+    NCI_MSG_BLD_HDR1(pp, NCI_MSG_CORE_SET_CONFIG);
+    p_start = pp;
+    pp++;
+    UINT8_TO_STREAM(pp, 0x01);
+    UINT8_TO_STREAM(pp, NXP_NFC_SET_CONFIG_PARAM_EXT);
+    UINT8_TO_STREAM(pp, NXP_NFC_PARAM_SWP_SESSIONID_INT2);
+    UINT8_TO_STREAM(pp, NXP_NFC_PARAM_SWP_SESSION_ID_LEN);
+    memcpy(pp, id_buf, NXP_NFC_PARAM_SWP_SESSION_ID_LEN);
+    pp = pp + NXP_NFC_PARAM_SWP_SESSION_ID_LEN;
+    cmd_len = (pp - p_start) - 1; /*skip len byte filed*/
+    pp = p_start;
+    UINT8_TO_STREAM(pp, cmd_len);
+    p_cmd->len = cmd_len + NCI_DATA_HDR_SIZE;
+    status = NFC_SendNxpNciCommand(p_cmd, p_cback);
+  }
+  return status;
+}
+#endif
+#if (BT_TRACE_VERBOSE == true)
+/*******************************************************************************
+**
+** Function         nfa_hciu_get_response_name
+**
+** Description      This function returns the error code name.
+**
+** NOTE             conditionally compiled to save memory.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+char* nfa_hciu_get_response_name(uint8_t rsp_code) {
+  switch (rsp_code) {
+    case NFA_HCI_ANY_OK:
+      return ("ANY_OK");
+    case NFA_HCI_ANY_E_NOT_CONNECTED:
+      return ("ANY_E_NOT_CONNECTED");
+    case NFA_HCI_ANY_E_CMD_PAR_UNKNOWN:
+      return ("ANY_E_CMD_PAR_UNKNOWN");
+    case NFA_HCI_ANY_E_NOK:
+      return ("ANY_E_NOK");
+    case NFA_HCI_ADM_E_NO_PIPES_AVAILABLE:
+      return ("ADM_E_NO_PIPES_AVAILABLE");
+    case NFA_HCI_ANY_E_REG_PAR_UNKNOWN:
+      return ("ANY_E_REG_PAR_UNKNOWN");
+    case NFA_HCI_ANY_E_PIPE_NOT_OPENED:
+      return ("ANY_E_PIPE_NOT_OPENED");
+    case NFA_HCI_ANY_E_CMD_NOT_SUPPORTED:
+      return ("ANY_E_CMD_NOT_SUPPORTED");
+    case NFA_HCI_ANY_E_INHIBITED:
+      return ("ANY_E_INHIBITED");
+    case NFA_HCI_ANY_E_TIMEOUT:
+      return ("ANY_E_TIMEOUT");
+    case NFA_HCI_ANY_E_REG_ACCESS_DENIED:
+      return ("ANY_E_REG_ACCESS_DENIED");
+    case NFA_HCI_ANY_E_PIPE_ACCESS_DENIED:
+      return ("ANY_E_PIPE_ACCESS_DENIED");
+    default:
+      return ("UNKNOWN");
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_type_2_str
+**
+** Description      This function returns the type name.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+char* nfa_hciu_type_2_str(uint8_t type) {
+  switch (type) {
+    case NFA_HCI_COMMAND_TYPE:
+      return ("COMMAND");
+    case NFA_HCI_EVENT_TYPE:
+      return ("EVENT");
+    case NFA_HCI_RESPONSE_TYPE:
+      return ("RESPONSE");
+    default:
+      return ("UNKNOWN");
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_instr_2_str
+**
+** Description      This function returns the instruction name.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+char* nfa_hciu_instr_2_str(uint8_t instruction) {
+  switch (instruction) {
+    case NFA_HCI_ANY_SET_PARAMETER:
+      return ("ANY_SET_PARAMETER");
+    case NFA_HCI_ANY_GET_PARAMETER:
+      return ("ANY_GET_PARAMETER");
+    case NFA_HCI_ANY_OPEN_PIPE:
+      return ("ANY_OPEN_PIPE");
+    case NFA_HCI_ANY_CLOSE_PIPE:
+      return ("ANY_CLOSE_PIPE");
+    case NFA_HCI_ADM_CREATE_PIPE:
+      return ("ADM_CREATE_PIPE");
+    case NFA_HCI_ADM_DELETE_PIPE:
+      return ("ADM_DELETE_PIPE");
+    case NFA_HCI_ADM_NOTIFY_PIPE_CREATED:
+      return ("ADM_NOTIFY_PIPE_CREATED");
+    case NFA_HCI_ADM_NOTIFY_PIPE_DELETED:
+      return ("ADM_NOTIFY_PIPE_DELETED");
+    case NFA_HCI_ADM_CLEAR_ALL_PIPE:
+      return ("ADM_CLEAR_ALL_PIPE");
+    case NFA_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED:
+      return ("ADM_NOTIFY_ALL_PIPE_CLEARED");
+    default:
+      return ("UNKNOWN");
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_get_event_name
+**
+** Description      This function returns the event code name.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+char* nfa_hciu_get_event_name(uint16_t event) {
+  switch (event) {
+    case NFA_HCI_API_REGISTER_APP_EVT:
+      return ("API_REGISTER");
+    case NFA_HCI_API_DEREGISTER_APP_EVT:
+      return ("API_DEREGISTER");
+    case NFA_HCI_API_GET_APP_GATE_PIPE_EVT:
+      return ("API_GET_GATE_LIST");
+    case NFA_HCI_API_ALLOC_GATE_EVT:
+      return ("API_ALLOC_GATE");
+    case NFA_HCI_API_DEALLOC_GATE_EVT:
+      return ("API_DEALLOC_GATE");
+    case NFA_HCI_API_GET_HOST_LIST_EVT:
+      return ("API_GET_HOST_LIST");
+    case NFA_HCI_API_GET_REGISTRY_EVT:
+      return ("API_GET_REG_VALUE");
+    case NFA_HCI_API_SET_REGISTRY_EVT:
+      return ("API_SET_REG_VALUE");
+    case NFA_HCI_API_CREATE_PIPE_EVT:
+      return ("API_CREATE_PIPE");
+    case NFA_HCI_API_OPEN_PIPE_EVT:
+      return ("API_OPEN_PIPE");
+    case NFA_HCI_API_CLOSE_PIPE_EVT:
+      return ("API_CLOSE_PIPE");
+    case NFA_HCI_API_DELETE_PIPE_EVT:
+      return ("API_DELETE_PIPE");
+    case NFA_HCI_API_SEND_CMD_EVT:
+      return ("API_SEND_COMMAND_EVT");
+    case NFA_HCI_API_SEND_RSP_EVT:
+      return ("API_SEND_RESPONSE_EVT");
+    case NFA_HCI_API_SEND_EVENT_EVT:
+      return ("API_SEND_EVENT_EVT");
+    case NFA_HCI_RSP_NV_READ_EVT:
+      return ("NV_READ_EVT");
+    case NFA_HCI_RSP_NV_WRITE_EVT:
+      return ("NV_WRITE_EVT");
+    case NFA_HCI_RSP_TIMEOUT_EVT:
+      return ("RESPONSE_TIMEOUT_EVT");
+    case NFA_HCI_CHECK_QUEUE_EVT:
+      return ("CHECK_QUEUE");
+    case NFA_HCI_HOST_TYPE_LIST_READ_EVT:
+      return ("NFA_HCI_HOST_TYPE_LIST_READ_EVT");
+    case NFA_HCI_API_CONFIGURE_EVT:
+      return ("API_SEND_CONFIGURE_EVT");
+    default:
+      return ("UNKNOWN");
+  }
+}
+/*******************************************************************************
+**
+** Function         nfa_hciu_get_state_name
+**
+** Description      This function returns the state name.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+char* nfa_hciu_get_state_name(uint8_t state) {
+  switch (state) {
+    case NFA_HCI_STATE_DISABLED:
+      return ("DISABLED");
+    case NFA_HCI_STATE_STARTUP:
+      return ("STARTUP");
+    case NFA_HCI_STATE_WAIT_NETWK_ENABLE:
+      return ("WAIT_NETWK_ENABLE");
+    case NFA_HCI_STATE_IDLE:
+      return ("IDLE");
+    case NFA_HCI_STATE_WAIT_RSP:
+      return ("WAIT_RSP");
+    case NFA_HCI_STATE_REMOVE_GATE:
+      return ("REMOVE_GATE");
+    case NFA_HCI_STATE_APP_DEREGISTER:
+      return ("APP_DEREGISTER");
+    case NFA_HCI_STATE_RESTORE:
+      return ("RESTORE");
+    case NFA_HCI_STATE_RESTORE_NETWK_ENABLE:
+      return ("WAIT_NETWK_ENABLE_AFTER_RESTORE");
+    case NFA_HCI_STATE_NFCEE_ENABLE:
+      return ("WAIT_NFCEE_ENABLE");
+
+    default:
+      return ("UNKNOWN");
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_get_type_inst_names
+**
+** Description      This function returns command/response/event name.
+**
+** Returns          none
+**
+*******************************************************************************/
+char* nfa_hciu_get_type_inst_names(uint8_t pipe, uint8_t type, uint8_t inst,
+                                   char* p_buff) {
+  int xx;
+
+  xx = snprintf(p_buff, VERBOSE_BUFF_SIZE, "Type: %s [0x%02x] ", nfa_hciu_type_2_str(type), type);
+
+  switch (type) {
+    case NFA_HCI_COMMAND_TYPE:
+      snprintf(&p_buff[xx], VERBOSE_BUFF_SIZE, "Inst: %s [0x%02x] ", nfa_hciu_instr_2_str(inst),
+              inst);
+      break;
+    case NFA_HCI_EVENT_TYPE:
+      snprintf(&p_buff[xx], VERBOSE_BUFF_SIZE, "Evt: %s [0x%02x] ", nfa_hciu_evt_2_str(pipe, inst),
+              inst);
+      break;
+    case NFA_HCI_RESPONSE_TYPE:
+      snprintf(&p_buff[xx], VERBOSE_BUFF_SIZE, "Resp: %s [0x%02x] ",
+              nfa_hciu_get_response_name(inst), inst);
+      break;
+    default:
+      snprintf(&p_buff[xx], VERBOSE_BUFF_SIZE, "Inst: %u ", inst);
+      break;
+  }
+  return (p_buff);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_evt_2_str
+**
+** Description      This function returns the event name.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+char* nfa_hciu_evt_2_str(uint8_t pipe_id, uint8_t evt) {
+  tNFA_HCI_DYN_PIPE* p_pipe;
+
+  if ((pipe_id != NFA_HCI_ADMIN_PIPE) &&
+      (pipe_id != NFA_HCI_LINK_MANAGEMENT_PIPE) &&
+      ((p_pipe = nfa_hciu_find_pipe_by_pid(pipe_id)) != NULL)) {
+    if (p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE) {
+      switch (evt) {
+        case NFA_HCI_EVT_CONNECTIVITY:
+          return ("EVT_CONNECTIVITY");
+        case NFA_HCI_EVT_TRANSACTION:
+          return ("EVT_TRANSACTION");
+        case NFA_HCI_EVT_OPERATION_ENDED:
+          return ("EVT_OPERATION_ENDED");
+        default:
+          return ("UNKNOWN");
+      }
+    }
+  }
+
+  switch (evt) {
+    case NFA_HCI_EVT_HCI_END_OF_OPERATION:
+      return ("EVT_END_OF_OPERATION");
+    case NFA_HCI_EVT_POST_DATA:
+      return ("EVT_POST_DATA");
+    case NFA_HCI_EVT_HOT_PLUG:
+      return ("EVT_HOT_PLUG");
+#if (NXP_EXTNS == TRUE)
+    case NFA_HCI_ABORT:
+      return ("EVT_ABORT");
+#endif
+    default:
+      return ("UNKNOWN");
+  }
+}
+#endif
+
+static void handle_debug_loopback(NFC_HDR* p_buf, uint8_t pipe, uint8_t type,
+                                  uint8_t instruction) {
+  uint8_t* p = (uint8_t*)(p_buf + 1) + p_buf->offset;
+  static uint8_t next_pipe = 0x10;
+  (void)pipe;
+
+  if (type == NFA_HCI_COMMAND_TYPE) {
+    switch (instruction) {
+      case NFA_HCI_ADM_CREATE_PIPE:
+        p[6] = next_pipe++;
+        p[5] = p[4];
+        p[4] = p[3];
+        p[3] = p[2];
+        p[2] = 3;
+        p[1] = (NFA_HCI_RESPONSE_TYPE << 6) | NFA_HCI_ANY_OK;
+        p_buf->len = p_buf->offset + 7;
+        break;
+
+      case NFA_HCI_ANY_GET_PARAMETER:
+        p[1] = (NFA_HCI_RESPONSE_TYPE << 6) | NFA_HCI_ANY_OK;
+        memcpy(&p[2], (uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id,
+               NFA_HCI_SESSION_ID_LEN);
+        p_buf->len = p_buf->offset + 2 + NFA_HCI_SESSION_ID_LEN;
+        break;
+
+      default:
+        p[1] = (NFA_HCI_RESPONSE_TYPE << 6) | NFA_HCI_ANY_OK;
+        p_buf->len = p_buf->offset + 2;
+        break;
+    }
+  } else if (type == NFA_HCI_RESPONSE_TYPE) {
+    GKI_freebuf(p_buf);
+    return;
+  }
+
+  p_buf->event = NFA_HCI_CHECK_QUEUE_EVT;
+  nfa_sys_sendmsg(p_buf);
+}
diff --git a/src/nfa/include/nfa_api.h b/src/nfa/include/nfa_api.h
new file mode 100644
index 0000000..e2f23f2
--- /dev/null
+++ b/src/nfa/include/nfa_api.h
@@ -0,0 +1,1675 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the public interface file for NFA, Broadcom's NFC application
+ *  layer for mobile phones.
+ *
+ ******************************************************************************/
+#ifndef NFA_API_H
+#define NFA_API_H
+
+#include "nfc_target.h"
+#include "nci_defs.h"
+#include "tags_defs.h"
+#include "nfc_api.h"
+#include "rw_api.h"
+#include "nfc_hal_api.h"
+#include "gki.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+/* Max length of Appliction ID in 7816-4 */
+#define NFA_MAX_AID_LEN NFC_MAX_AID_LEN
+#define NFA_MIN_AID_LEN 5 /* per NCI specification */
+/* Result of NFA_SetPowerSubState */
+#define NFA_DM_SET_POWER_SUB_STATE_EVT 13
+/* NFA API return status codes */
+/* Command succeeded    */
+#define NFA_STATUS_OK NCI_STATUS_OK
+/* Command is rejected. */
+#define NFA_STATUS_REJECTED NCI_STATUS_REJECTED
+/* Message is corrupted */
+#define NFA_STATUS_MSG_CORRUPTED NCI_STATUS_MESSAGE_CORRUPTED
+/* buffer full          */
+#define NFA_STATUS_BUFFER_FULL NCI_STATUS_BUFFER_FULL
+/* failed               */
+#define NFA_STATUS_FAILED NCI_STATUS_FAILED
+/* not initialized      */
+#define NFA_STATUS_NOT_INITIALIZED NCI_STATUS_NOT_INITIALIZED
+/* Syntax error         */
+#define NFA_STATUS_SYNTAX_ERROR NCI_STATUS_SYNTAX_ERROR
+/* Semantic error       */
+#define NFA_STATUS_SEMANTIC_ERROR NCI_STATUS_SEMANTIC_ERROR
+/* Unknown NCI Group ID */
+#define NFA_STATUS_UNKNOWN_GID NCI_STATUS_UNKNOWN_GID
+/* Unknown NCI Opcode   */
+#define NFA_STATUS_UNKNOWN_OID NCI_STATUS_UNKNOWN_OID
+/* Invalid Parameter    */
+#define NFA_STATUS_INVALID_PARAM NCI_STATUS_INVALID_PARAM
+/* Message size too big */
+#define NFA_STATUS_MSG_SIZE_TOO_BIG NCI_STATUS_MSG_SIZE_TOO_BIG
+/* Already started      */
+#define NFA_STATUS_ALREADY_STARTED NCI_STATUS_ALREADY_STARTED
+/* Activation Failed    */
+#define NFA_STATUS_ACTIVATION_FAILED NCI_STATUS_ACTIVATION_FAILED
+/* Tear Down Error      */
+#define NFA_STATUS_TEAR_DOWN NCI_STATUS_TEAR_DOWN
+/* RF transmission error*/
+#define NFA_STATUS_RF_TRANSMISSION_ERR NCI_STATUS_RF_TRANSMISSION_ERR
+/* RF protocol error    */
+#define NFA_STATUS_RF_PROTOCOL_ERR NCI_STATUS_RF_PROTOCOL_ERR
+/* RF Timeout           */
+#define NFA_STATUS_TIMEOUT NCI_STATUS_TIMEOUT
+/* EE Intf activate err */
+#define NFA_STATUS_EE_INTF_ACTIVE_FAIL NCI_STATUS_EE_INTF_ACTIVE_FAIL
+/* EE transmission error*/
+#define NFA_STATUS_EE_TRANSMISSION_ERR NCI_STATUS_EE_TRANSMISSION_ERR
+/* EE protocol error    */
+#define NFA_STATUS_EE_PROTOCOL_ERR NCI_STATUS_EE_PROTOCOL_ERR
+/* EE Timeout           */
+#define NFA_STATUS_EE_TIMEOUT NCI_STATUS_EE_TIMEOUT
+
+/* Command started successfully */
+#define NFA_STATUS_CMD_STARTED NFC_STATUS_CMD_STARTED
+/* NFCC Timeout in responding to an NCI command */
+#define NFA_STATUS_HW_TIMEOUT NFC_STATUS_HW_TIMEOUT
+/* More NFA_CE_GET_ROUTING_REVT to follow */
+#define NFA_STATUS_CONTINUE NFC_STATUS_CONTINUE
+/* API is called to perform illegal function */
+#define NFA_STATUS_REFUSED NFC_STATUS_REFUSED
+/* Wrong format of R-APDU, CC file or NDEF file */
+#define NFA_STATUS_BAD_RESP NFC_STATUS_BAD_RESP
+/* 7816 Status Word is not command complete(0x9000) */
+#define NFA_STATUS_CMD_NOT_CMPLTD NFC_STATUS_CMD_NOT_CMPLTD
+/* Out of GKI buffers */
+#define NFA_STATUS_NO_BUFFERS NFC_STATUS_NO_BUFFERS
+/* Protocol mismatch between API and activated one */
+#define NFA_STATUS_WRONG_PROTOCOL NFC_STATUS_WRONG_PROTOCOL
+/* Another Tag command is already in progress */
+#define NFA_STATUS_BUSY NFC_STATUS_BUSY
+
+/* data len exceeds MIU                             */
+#define NFA_STATUS_BAD_LENGTH NFC_STATUS_BAD_LENGTH
+/* invalid handle                                   */
+#define NFA_STATUS_BAD_HANDLE NFC_STATUS_BAD_HANDLE
+/* congested                                        */
+#define NFA_STATUS_CONGESTED NFC_STATUS_CONGESTED
+#if (NXP_EXTNS == TRUE)
+#define NFA_STATUS_WIRED_SESSION_ABORTED \
+  NFC_STATUS_WIRED_SESSION_ABORTED /* WIRED_SESSION_ABORTED error */
+#define NFA_STATUS_ALREADY_INITIALIZED NFC_STATUS_ALREADY_INITIALIZED
+#endif
+typedef uint8_t tNFA_STATUS;
+
+/* Handle for NFA registrations and connections */
+typedef uint16_t tNFA_HANDLE;
+#define NFA_HANDLE_INVALID (0xFFFF)
+/* NFA Handle definitions */
+
+/* The upper byte of NFA_HANDLE signifies the handle group */
+/* Connection handles           */
+#define NFA_HANDLE_GROUP_CONNECTION 0x0100
+/* NDEF Type Handler handles    */
+#define NFA_HANDLE_GROUP_NDEF_HANDLER 0x0200
+/* DH Card Emulation handles    */
+#define NFA_HANDLE_GROUP_CE 0x0300
+/* Handles to identify NFCEE    */
+#define NFA_HANDLE_GROUP_EE 0x0400
+/* P2P handles                  */
+#define NFA_HANDLE_GROUP_P2P 0x0500
+/* SNEP handles                 */
+#define NFA_HANDLE_GROUP_SNEP 0x0700
+/* HCI handles                  */
+#define NFA_HANDLE_GROUP_HCI 0x0800
+/* Local NDEF message handle    */
+#define NFA_HANDLE_GROUP_LOCAL_NDEF 0x0900
+#define NFA_HANDLE_GROUP_MASK 0xFF00
+#define NFA_HANDLE_MASK 0x00FF
+
+/* NCI Parameter IDs */
+typedef uint8_t tNFA_PMID;
+
+/* Definitions for tNFA_TECHNOLOGY_MASK */
+#define NFA_TECHNOLOGY_MASK_A 0x01        /* NFC Technology A             */
+#define NFA_TECHNOLOGY_MASK_B 0x02        /* NFC Technology B             */
+#define NFA_TECHNOLOGY_MASK_F 0x04        /* NFC Technology F             */
+#define NFA_TECHNOLOGY_MASK_ISO15693 0x08 /* Proprietary Technology       */
+#define NFA_TECHNOLOGY_MASK_B_PRIME 0x10  /* Proprietary Technology       */
+#define NFA_TECHNOLOGY_MASK_KOVIO 0x20    /* Proprietary Technology       */
+/* NFC Technology A active mode */
+#define NFA_TECHNOLOGY_MASK_A_ACTIVE 0x40
+/* NFC Technology F active mode */
+#define NFA_TECHNOLOGY_MASK_F_ACTIVE 0x80
+/* All supported technologies   */
+#define NFA_TECHNOLOGY_MASK_ALL 0xFF
+typedef uint8_t tNFA_TECHNOLOGY_MASK;
+
+/* Definitions for NFC protocol for RW, CE and P2P APIs */
+/* Type1Tag - NFC-A */
+#define NFA_PROTOCOL_T1T NFC_PROTOCOL_T1T
+/* MIFARE/Type2Tag - NFC-A */
+#define NFA_PROTOCOL_T2T NFC_PROTOCOL_T2T
+/* Felica/Type3Tag - NFC-F */
+#define NFA_PROTOCOL_T3T NFC_PROTOCOL_T3T
+/* Type 4A,4B - NFC-A or NFC-B */
+#define NFA_PROTOCOL_ISO_DEP NFC_PROTOCOL_ISO_DEP
+/* NFCDEP/LLCP - NFC-A or NFC-F */
+#define NFA_PROTOCOL_NFC_DEP NFC_PROTOCOL_NFC_DEP
+#define NFA_PROTOCOL_ISO15693 NFC_PROTOCOL_15693
+#define NFA_PROTOCOL_B_PRIME NFC_PROTOCOL_B_PRIME
+#define NFA_PROTOCOL_KOVIO NFC_PROTOCOL_KOVIO
+#define NFA_PROTOCOL_MIFARE NFC_PROTOCOL_MIFARE
+#if (NXP_EXTNS == TRUE)
+#define NFA_PROTOCOL_T3BT NFC_PROTOCOL_T3BT
+#define NFA_NORMAL_BOOT_MODE NFC_NORMAL_BOOT_MODE
+#define NFA_FAST_BOOT_MODE NFC_FAST_BOOT_MODE
+#define NFA_OSU_BOOT_MODE NFC_OSU_BOOT_MODE
+#endif
+#define NFA_PROTOCOL_INVALID 0xFF
+#define NFA_MAX_NUM_PROTOCOLS 8
+typedef uint8_t tNFA_NFC_PROTOCOL;
+
+/* Definitions for tNFA_PROTOCOL_MASK */
+#define NFA_PROTOCOL_MASK_T1T 0x01     /* Type 1 tag          */
+#define NFA_PROTOCOL_MASK_T2T 0x02     /* MIFARE / Type 2 tag */
+#define NFA_PROTOCOL_MASK_T3T 0x04     /* FeliCa / Type 3 tag */
+#define NFA_PROTOCOL_MASK_ISO_DEP 0x08 /* ISODEP/4A,4B        */
+#define NFA_PROTOCOL_MASK_NFC_DEP 0x10 /* NFCDEP/LLCP         */
+#if (NXP_EXTNS == TRUE)
+#define NFC_PROTOCOL_MASK_ISO7816 0x20 /*ISO 7816 - Aid Default Route */
+#endif
+typedef uint8_t tNFA_PROTOCOL_MASK;
+
+/* NFA_DM callback events */
+/* Result of NFA_Enable             */
+#define NFA_DM_ENABLE_EVT 0
+/* Result of NFA_Disable            */
+#define NFA_DM_DISABLE_EVT 1
+/* Result of NFA_SetConfig          */
+#define NFA_DM_SET_CONFIG_EVT 2
+/* Result of NFA_GetConfig          */
+#define NFA_DM_GET_CONFIG_EVT 3
+/* Result of NFA_PowerOffSleepMode  */
+#define NFA_DM_PWR_MODE_CHANGE_EVT 4
+#define NFA_DM_RF_FIELD_EVT 5 /* Status of RF Field               */
+/* NFCC is not responding           */
+#define NFA_DM_NFCC_TIMEOUT_EVT 6
+/* NCI Tranport error               */
+#define NFA_DM_NFCC_TRANSPORT_ERR_EVT 7
+#if (NXP_EXTNS == TRUE)
+/* Collision event in case of EMV-CO Profile (Nxp)*/
+#define NFA_DM_EMVCO_PCD_COLLISION_EVT 8
+/* Status of EE Route config CMD (Nxp)*/
+#define NFA_DM_SET_ROUTE_CONFIG_REVT 9
+/* Result of NFA_GetRouting         */
+#define NFA_DM_GET_ROUTE_CONFIG_REVT 10
+/*Status when EE HCI subsystems disabled*/
+#define NFA_DM_EE_HCI_DISABLE 11
+/*Status when EE HCI susbsystems enabled*/
+#define NFA_DM_EE_HCI_ENABLE 12
+
+/* Reader over SWP Events*/
+#define NFA_RD_SWP_READER_REQUESTED 0
+#define NFA_RD_SWP_READER_START 1
+#define NFA_RD_SWP_READER_STOP 2
+#define NFA_RD_SWP_READER_START_FAIL 3
+#endif
+
+/* T1T HR length            */
+#define NFA_T1T_HR_LEN T1T_HR_LEN
+/* Max UID length of T1/T2  */
+#define NFA_MAX_UID_LEN TAG_MAX_UID_LEN
+/* T1T UID length           */
+#define NFA_T1T_UID_LEN T1T_UID_LEN
+/* UID len for T1T cmds     */
+#define NFA_T1T_CMD_UID_LEN T1T_CMD_UID_LEN
+/* T2T UID length           */
+#define NFA_T2T_UID_LEN T2T_UID_LEN
+
+/* Tag is read only */
+#define NFA_RW_NDEF_FL_READ_ONLY RW_NDEF_FL_READ_ONLY
+/* Tag formated for NDEF */
+#define NFA_RW_NDEF_FL_FORMATED RW_NDEF_FL_FORMATED
+/* NDEF supported by the tag */
+#define NFA_RW_NDEF_FL_SUPPORTED RW_NDEF_FL_SUPPORTED
+/* Unable to find if tag is ndef capable/formated/read only */
+#define NFA_RW_NDEF_FL_UNKNOWN RW_NDEF_FL_UNKNOWN
+/* Tag supports format operation */
+#define NFA_RW_NDEF_FL_FORMATABLE RW_NDEF_FL_FORMATABLE
+/* Tag can be soft locked */
+#define NFA_RW_NDEF_FL_SOFT_LOCKABLE RW_NDEF_FL_SOFT_LOCKABLE
+/* Tag can be hard locked */
+#define NFA_RW_NDEF_FL_HARD_LOCKABLE RW_NDEF_FL_HARD_LOCKABLE
+/* Tag is one time programmable */
+#define NFA_RW_NDEF_FL_OTP RW_NDEF_FL_OTP
+
+typedef uint8_t tNFA_RW_NDEF_FLAG;
+
+/* Data for NFA_DM_SET_CONFIG_EVT */
+typedef struct {
+  tNFA_STATUS status;                   /* NFA_STATUS_OK if successful  */
+  uint8_t num_param_id;                 /* Number of rejected Param ID  */
+  tNFA_PMID param_ids[NFC_MAX_NUM_IDS]; /* Rejected Param ID            */
+} tNFA_SET_CONFIG;
+
+/* Data for NFA_DM_GET_CONFIG_EVT */
+typedef struct {
+  tNFA_STATUS status;    /* NFA_STATUS_OK if successful              */
+  uint16_t tlv_size;     /* The length of TLV                        */
+  uint8_t param_tlvs[1]; /* TLV (Parameter ID-Len-Value byte stream) */
+} tNFA_GET_CONFIG;
+
+#if (NXP_EXTNS == TRUE)
+/* Data for NFA_DM_GET_ROUTING_EVT */
+typedef struct {
+  tNFA_STATUS status;      /* NFA_STATUS_OK if successful              */
+  uint8_t num_tlvs;        /* number of TLVs                           */
+  uint8_t tlv_size;        /* the total len of all TLVs                */
+  uint8_t param_tlvs[150]; /* TLV (Parameter ID-Len-Value byte stream) */
+} tNFA_GET_ROUTING;
+#endif
+
+#define NFA_DM_PWR_MODE_FULL 0x04
+#define NFA_DM_PWR_MODE_OFF_SLEEP 0x00
+
+typedef uint8_t tNFA_DM_PWR_MODE;
+
+/* Data for NFA_DM_PWR_MODE_CHANGE_EVT */
+typedef struct {
+  tNFA_STATUS status; /* NFA_STATUS_OK if successful */
+  /* NFA_DM_PWR_MODE_FULL or NFA_DM_PWR_MODE_OFF_SLEEP */
+  tNFA_DM_PWR_MODE power_mode;
+} tNFA_DM_PWR_MODE_CHANGE;
+
+/* Structure to store screen state */
+typedef enum screen_state_NCI2
+{
+  NFA_SCREEN_STATE_UNKNOWN = 0x00,
+  NFA_SCREEN_STATE_OFF_UNLOCKED = 0x01,
+  NFA_SCREEN_STATE_OFF_LOCKED = 0x02,
+  NFA_SCREEN_STATE_ON_LOCKED = 0x04,
+  NFA_SCREEN_STATE_ON_UNLOCKED = 0x08
+}eScreenState_t;
+
+typedef enum power_substate
+{
+  SCREEN_STATE_ON_UNLOCKED = 0x00,
+  SCREEN_STATE_OFF_UNLOCKED,
+  SCREEN_STATE_ON_LOCKED,
+  SCREEN_STATE_OFF_LOCKED,
+}epower_substate_t;
+
+// CONN_DISCOVER_PARAM
+#define NFA_LISTEN_DH_NFCEE_ENABLE_MASK  NCI_LISTEN_DH_NFCEE_ENABLE_MASK
+#define NFA_LISTEN_DH_NFCEE_DISABLE_MASK NCI_LISTEN_DH_NFCEE_DISABLE_MASK
+#define NFA_POLLING_DH_DISABLE_MASK      NCI_POLLING_DH_DISABLE_MASK
+#define NFA_POLLING_DH_ENABLE_MASK       NCI_POLLING_DH_ENABLE_MASK
+
+#define NFA_SCREEN_STATE_MASK 0x0F
+
+typedef struct
+{
+  tNFA_STATUS status; /* NFA_STATUS_OK if successful  */
+  uint8_t power_state; /* current screen/power state */
+} tNFA_DM_POWER_STATE;
+
+/* Data for NFA_DM_RF_FIELD_EVT */
+#define NFA_DM_RF_FIELD_OFF 0x00
+#define NFA_DM_RF_FIELD_ON 0x01
+
+typedef struct {
+  tNFA_STATUS status; /* NFA_STATUS_OK if successful  */
+  /* NFA_DM_RF_FIELD_ON if operating field generated by remote */
+  uint8_t rf_field_status;
+} tNFA_DM_RF_FIELD;
+
+/* Union of all DM callback structures */
+typedef union {
+  tNFA_STATUS status;         /* NFA_DM_ENABLE_EVT        */
+  tNFA_SET_CONFIG set_config; /* NFA_DM_SET_CONFIG_EVT    */
+  tNFA_GET_CONFIG get_config; /* NFA_DM_GET_CONFIG_EVT    */
+#if (NXP_EXTNS == TRUE)
+  tNFA_GET_ROUTING get_routing; /* NFA_DM_GET_ROUTING_EVT    */
+#endif
+  tNFA_DM_PWR_MODE_CHANGE power_mode; /* NFA_DM_PWR_MODE_CHANGE_EVT   */
+  tNFA_DM_RF_FIELD rf_field;          /* NFA_DM_RF_FIELD_EVT      */
+  void* p_vs_evt_data;                /* Vendor-specific evt data */
+  tNFA_DM_POWER_STATE power_sub_state; /* power sub state */
+} tNFA_DM_CBACK_DATA;
+
+/* NFA_DM callback */
+typedef void(tNFA_DM_CBACK)(uint8_t event, tNFA_DM_CBACK_DATA* p_data);
+
+#if (NXP_EXTNS == TRUE)
+/* NFA Enable DTA Type Mode */
+typedef enum {
+  NFA_DTA_DEFAULT_MODE = 0x00000001,
+  NFA_DTA_LLCP_MODE = 0x00000002,
+  NFA_DTA_SNEP_MODE = 0x00000003,
+  NFA_DTA_HCEF_MODE = 0x00000004,
+  NFA_DTA_CR8 = 0x00000080,
+  NFA_DTA_CR9 = 0x00000090,
+  NFA_DTA_CR10 = 0x000000A0,
+  NFA_DTA_CR11 = 0x000000B0,
+  NFA_DTA_CR12 = 0x000000C0,
+} tNFA_eDtaModes;
+typedef struct {
+  uint32_t validation; /* indicates on which platform validation is done like
+                         pn547, pn548, pn65T, pn66T */
+  uint8_t android_version; /* Nxp's android version */
+  uint8_t major_version;   /* Major Version of MW*/
+  uint8_t minor_version;   /* Minor Version of Mw */
+} tNFA_MW_VERSION;
+#endif
+
+/* NFA Connection Callback Events */
+#define NFA_POLL_ENABLED_EVT 0  /* Polling enabled event */
+#define NFA_POLL_DISABLED_EVT 1 /* Polling disabled event */
+/* NFC link/protocol discovery notificaitonS */
+#define NFA_DISC_RESULT_EVT 2
+/* NFC link/protocol discovery select response */
+#define NFA_SELECT_RESULT_EVT 3
+#define NFA_DEACTIVATE_FAIL_EVT 4 /* NFA_Deactivate failure */
+/* NFC link/protocol activated */
+#define NFA_ACTIVATED_EVT 5
+/* NFC link/protocol deactivated */
+#define NFA_DEACTIVATED_EVT 6
+#define NFA_TLV_DETECT_EVT 7 /* TLV Detection complete */
+/* NDEF Detection complete */
+#define NFA_NDEF_DETECT_EVT 8
+#define NFA_DATA_EVT 9            /* Data message received */
+#define NFA_SELECT_CPLT_EVT 10    /* Select completed */
+#define NFA_READ_CPLT_EVT 11      /* Read completed */
+#define NFA_WRITE_CPLT_EVT 12     /* Write completed */
+#define NFA_LLCP_ACTIVATED_EVT 13 /* LLCP link is activated */
+/* LLCP link is deactivated */
+#define NFA_LLCP_DEACTIVATED_EVT 14
+/* Response to NFA_RwPresenceCheck */
+#define NFA_PRESENCE_CHECK_EVT 15
+/* Tag Formating completed */
+#define NFA_FORMAT_CPLT_EVT 16
+/* ISO 15693 command completed */
+#define NFA_I93_CMD_CPLT_EVT 17
+#define NFA_SET_TAG_RO_EVT 18 /* Tag set as Read only */
+/* Result for NFA_RequestExclusiveRfControl */
+#define NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT 19
+/* Result for NFA_ReleaseExclusiveRfControl */
+#define NFA_EXCLUSIVE_RF_CONTROL_STOPPED_EVT 20
+/* DH Card emulation: AID or System code reg'd */
+#define NFA_CE_REGISTERED_EVT 21
+/* DH Card emulation: AID or System code dereg'd */
+#define NFA_CE_DEREGISTERED_EVT 22
+/* DH Card emulation: data received event */
+#define NFA_CE_DATA_EVT 23
+/* DH Card emulation: activation event */
+#define NFA_CE_ACTIVATED_EVT 24
+/* DH Card emulation: deactivation event */
+#define NFA_CE_DEACTIVATED_EVT 25
+/* DH Card emulation: local NDEF configured */
+#define NFA_CE_LOCAL_TAG_CONFIGURED_EVT 26
+/* DH Card emulation: NDEF write started */
+#define NFA_CE_NDEF_WRITE_START_EVT 27
+/* DH Card emulation: NDEF write completed */
+#define NFA_CE_NDEF_WRITE_CPLT_EVT 28
+#define NFA_CE_UICC_LISTEN_CONFIGURED_EVT 29 /* UICC Listen configured */
+/* RF Discovery started event */
+#define NFA_RF_DISCOVERY_STARTED_EVT 30
+/* RF Discovery stopped event */
+#define NFA_RF_DISCOVERY_STOPPED_EVT 31
+/* status of updating RF communication paramters */
+#define NFA_UPDATE_RF_PARAM_RESULT_EVT 32
+/* RF Interface error event */
+#define NFA_RW_INTF_ERROR_EVT 34
+/* status of setting P2P listen technologies */
+#define NFA_SET_P2P_LISTEN_TECH_EVT 33
+/* First packet received over LLCP link */
+#define NFA_LLCP_FIRST_PACKET_RECEIVED_EVT 35
+/* Listening enabled event */
+#define NFA_LISTEN_ENABLED_EVT 36
+/* Listening disabled event */
+#define NFA_LISTEN_DISABLED_EVT 37
+/* P2P services paused event */
+#define NFA_P2P_PAUSED_EVT 38
+/* P2P services resumed event */
+#define NFA_P2P_RESUMED_EVT 39
+#if (NXP_EXTNS == TRUE)
+/* ESE Listen configured */
+#define NFA_CE_ESE_LISTEN_CONFIGURED_EVT 40
+/* Activated intf for updating the   tech variables */
+#define NFA_ACTIVATED_UPDATE_EVT 41
+#define NFA_RECOVERY_EVT 42 /*Recovery*/
+/* Passive Listening disabled event */
+#define NFA_PASSIVE_LISTEN_DISABLED_EVT 44
+#endif
+/* NFC deactivation type */
+#define NFA_DEACTIVATE_TYPE_IDLE NFC_DEACTIVATE_TYPE_IDLE
+#define NFA_DEACTIVATE_TYPE_SLEEP NFC_DEACTIVATE_TYPE_SLEEP
+#define NFA_DEACTIVATE_TYPE_DISCOVERY NFC_DEACTIVATE_TYPE_DISCOVERY
+
+typedef uint8_t tNFA_DEACTIVATE_TYPE;
+
+/* Data for NFA_DISC_RESULT_EVT */
+typedef struct {
+  tNFA_STATUS status;             /* NFA_STATUS_OK if successful       */
+  tNFC_RESULT_DEVT discovery_ntf; /* RF discovery notification details */
+} tNFA_DISC_RESULT;
+
+/* Data for NFA_ACTIVATED_EVT */
+typedef struct {
+  uint8_t hr[NFA_T1T_HR_LEN];       /* HR of Type 1 tag         */
+  uint8_t uid[NFA_T1T_CMD_UID_LEN]; /* UID used in T1T Commands */
+} tNFA_T1T_PARAMS;
+
+typedef struct {
+  uint8_t uid[NFA_MAX_UID_LEN]; /* UID of T2T tag           */
+} tNFA_T2T_PARAMS;
+
+typedef struct {
+  uint8_t num_system_codes; /* Number of system codes supporte by tag   */
+  uint16_t* p_system_codes; /* Pointer to list of system codes          */
+} tNFA_T3T_PARAMS;
+
+typedef struct {
+  uint8_t uid[I93_UID_BYTE_LEN]; /* UID[0]:MSB, ... UID[7]:LSB */
+  uint8_t info_flags;   /* information flags                            */
+  uint8_t dsfid;        /* DSFID if I93_INFO_FLAG_DSFID                 */
+  uint8_t afi;          /* AFI if I93_INFO_FLAG_AFI                     */
+  uint16_t num_block;   /* number of blocks if I93_INFO_FLAG_MEM_SIZE   */
+  uint8_t block_size;   /* block size in byte if I93_INFO_FLAG_MEM_SIZE */
+  uint8_t IC_reference; /* IC Reference if I93_INFO_FLAG_IC_REF         */
+} tNFA_I93_PARAMS;
+
+typedef union {
+  tNFA_T1T_PARAMS t1t; /* HR and UID of T1T                */
+  tNFA_T2T_PARAMS t2t; /* UID of T2T                       */
+  tNFA_T3T_PARAMS t3t; /* System codes                     */
+  tNFA_I93_PARAMS i93; /* System Information of ISO 15693  */
+} tNFA_TAG_PARAMS;
+
+typedef struct {
+  tNFC_ACTIVATE_DEVT activate_ntf; /* RF discovery activation details */
+  tNFA_TAG_PARAMS params;          /* additional informaiton of tag   */
+} tNFA_ACTIVATED;
+
+/* Data for NFA_DEACTIVATED_EVT */
+typedef struct {
+  /* NFA_DEACTIVATE_TYPE_IDLE or NFA_DEACTIVATE_TYPE_SLEEP */
+  tNFA_DEACTIVATE_TYPE type;
+} tNFA_DEACTIVATED;
+
+/* Structure for NFA_NDEF_DETECT_EVT event data */
+typedef struct {
+  tNFA_STATUS status;         /* Status of the ndef detecton */
+  tNFA_NFC_PROTOCOL protocol; /* protocol used to detect NDEF */
+  uint32_t max_size;          /* max number of bytes available for NDEF data */
+  uint32_t cur_size;          /* current size of stored NDEF data (in bytes) */
+  /* Flags to indicate NDEF capability, is formated, soft/hard lockable,
+   * formatable, otp and read only */
+  tNFA_RW_NDEF_FLAG flags;
+} tNFA_NDEF_DETECT;
+
+/* Structure for NFA_TLV_DETECT_EVT event data */
+typedef struct {
+  tNFA_STATUS status;         /* Status of the tlv detecton        */
+  tNFA_NFC_PROTOCOL protocol; /* protocol used to detect TLV       */
+  uint8_t num_tlvs;           /* number of tlvs present in the tag */
+  uint8_t num_bytes;          /* number of lock/reserved bytes     */
+} tNFA_TLV_DETECT;
+
+/* Structure for NFA_DATA_EVT data */
+typedef struct {
+  tNFA_STATUS status; /* Status of Data received          */
+  uint8_t* p_data;    /* Data buffer                      */
+  uint16_t len;       /* Length of data                   */
+} tNFA_RX_DATA;
+
+/* Structure for NFA_CE_NDEF_WRITE_CPLT_EVT data */
+typedef struct {
+  tNFA_STATUS status; /* Status of the ndef write op      */
+  uint32_t len;       /* Update length of NDEF data       */
+  uint8_t* p_data;    /* data buffer                      */
+} tNFA_CE_NDEF_WRITE_CPLT;
+
+/* Data for NFA_LLCP_ACTIVATED_EVT */
+typedef struct {
+  bool is_initiator;        /* true if initiator                */
+  uint16_t remote_wks;      /* Well-Known service mask of peer  */
+  uint8_t remote_lsc;       /* Link Service Class of peer       */
+  uint16_t remote_link_miu; /* Link MIU of peer                 */
+  uint16_t local_link_miu;  /* Link MIU of local                */
+  uint8_t remote_version;   /* LLCP version of remote           */
+} tNFA_LLCP_ACTIVATED;
+
+/* Data for NFA_LLCP_DEACTIVATED_EVT */
+typedef struct {
+  uint8_t reason; /* reason of deactivation           */
+} tNFA_LLCP_DEACTIVATED;
+
+/* Data for NFA_I93_CMD_CPLT_EVT */
+typedef struct {
+  uint8_t dsfid;                 /* DSFID                       */
+  uint8_t uid[I93_UID_BYTE_LEN]; /* UID[0]:MSB, ... UID[7]:LSB  */
+} tNFA_I93_INVENTORY;
+
+typedef struct /* RW_I93_SYS_INFO_EVT                          */
+    {
+  uint8_t info_flags; /* information flags                            */
+  uint8_t uid[I93_UID_BYTE_LEN]; /* UID */
+  uint8_t dsfid;        /* DSFID if I93_INFO_FLAG_DSFID                 */
+  uint8_t afi;          /* AFI if I93_INFO_FLAG_AFI                     */
+  uint16_t num_block;   /* number of blocks if I93_INFO_FLAG_MEM_SIZE   */
+  uint8_t block_size;   /* block size in byte if I93_INFO_FLAG_MEM_SIZE */
+  uint8_t IC_reference; /* IC Reference if I93_INFO_FLAG_IC_REF         */
+} tNFA_I93_SYS_INFO;
+
+typedef struct {
+  tNFA_STATUS status;   /* Status of sending command       */
+  uint8_t sent_command; /* sent command to tag             */
+  union {
+    uint8_t error_code;           /* error code defined in ISO 15693 */
+    tNFA_I93_INVENTORY inventory; /* inventory response              */
+    tNFA_I93_SYS_INFO sys_info;   /* system information              */
+  } params;
+} tNFA_I93_CMD_CPLT;
+
+/* Data for NFA_CE_REGISTERED_EVT */
+typedef struct {
+  tNFA_STATUS status; /* NFA_STATUS_OK if successful                      */
+  tNFA_HANDLE handle; /* handle for NFA_CeRegisterFelicaSystemCodeOnDH () */
+                      /*            NFA_CeRegisterT4tAidOnDH ()           */
+} tNFA_CE_REGISTERED;
+
+/* Data for NFA_CE_DEREGISTERED_EVT */
+typedef struct {
+  tNFA_HANDLE handle; /* handle from NFA_CE_REGISTERED_EVT   */
+} tNFA_CE_DEREGISTERED;
+
+/* Data for NFA_CE_ACTIVATED_EVT */
+typedef struct {
+  tNFA_STATUS status; /* NFA_STATUS_OK if successful              */
+  tNFA_HANDLE handle; /* handle from NFA_CE_REGISTERED_EVT        */
+  tNFC_ACTIVATE_DEVT activate_ntf; /* RF discovery activation details */
+} tNFA_CE_ACTIVATED;
+
+/* Data for NFA_CE_DEACTIVATED_EVT */
+typedef struct {
+  tNFA_HANDLE handle; /* handle from NFA_CE_REGISTERED_EVT   */
+  /* NFA_DEACTIVATE_TYPE_IDLE or NFA_DEACTIVATE_TYPE_SLEEP */
+  tNFA_DEACTIVATE_TYPE type;
+} tNFA_CE_DEACTIVATED;
+
+/* Structure for NFA_CE_DATA_EVT data */
+typedef struct {
+  tNFA_STATUS status; /* NFA_STATUS_OK if complete packet     */
+  tNFA_HANDLE handle; /* handle from NFA_CE_REGISTERED_EVT    */
+  uint8_t* p_data;    /* Data buffer                          */
+  uint16_t len;       /* Length of data                       */
+} tNFA_CE_DATA;
+
+/* Union of all connection callback structures */
+typedef union {
+  tNFA_STATUS status;           /* NFA_POLL_ENABLED_EVT                 */
+                                /* NFA_POLL_DISABLED_EVT                */
+                                /* NFA_CE_UICC_LISTEN_CONFIGURED_EVT    */
+                                /* NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT */
+                                /* NFA_EXCLUSIVE_RF_CONTROL_STOPPED_EVT */
+                                /* NFA_SELECT_RESULT_EVT                */
+                                /* NFA_DEACTIVATE_FAIL_EVT              */
+                                /* NFA_CE_NDEF_WRITE_START_EVT          */
+                                /* NFA_SELECT_CPLT_EVT                  */
+                                /* NFA_READ_CPLT_EVT                    */
+                                /* NFA_WRITE_CPLT_EVT                   */
+                                /* NFA_PRESENCE_CHECK_EVT               */
+                                /* NFA_FORMAT_CPLT_EVT                  */
+                                /* NFA_SET_TAG_RO_EVT                   */
+                                /* NFA_UPDATE_RF_PARAM_RESULT_EVT       */
+                                /* NFA_RW_INTF_ERROR_EVT                */
+  tNFA_DISC_RESULT disc_result; /* NFA_DISC_RESULT_EVT                  */
+  tNFA_ACTIVATED activated;     /* NFA_ACTIVATED_EVT                    */
+  tNFA_DEACTIVATED deactivated; /* NFA_DEACTIVATED_EVT                  */
+  tNFA_NDEF_DETECT ndef_detect; /* NFA_NDEF_DETECT_EVT                  */
+  tNFA_TLV_DETECT tlv_detect;   /* NFA_TLV_DETECT_EVT                   */
+  tNFA_RX_DATA data;            /* NFA_DATA_EVT                         */
+  tNFA_CE_NDEF_WRITE_CPLT ndef_write_cplt; /* NFA_CE_NDEF_WRITE_CPLT_EVT */
+  tNFA_LLCP_ACTIVATED llcp_activated; /* NFA_LLCP_ACTIVATED_EVT               */
+  tNFA_LLCP_DEACTIVATED llcp_deactivated; /* NFA_LLCP_DEACTIVATED_EVT */
+  tNFA_I93_CMD_CPLT i93_cmd_cplt;   /* NFA_I93_CMD_CPLT_EVT                 */
+  tNFA_CE_REGISTERED ce_registered; /* NFA_CE_REGISTERED_EVT                */
+  tNFA_CE_DEREGISTERED ce_deregistered; /* NFA_CE_DEREGISTERED_EVT */
+  tNFA_CE_ACTIVATED ce_activated;     /* NFA_CE_ACTIVATED_EVT                 */
+  tNFA_CE_DEACTIVATED ce_deactivated; /* NFA_CE_DEACTIVATED_EVT               */
+  tNFA_CE_DATA ce_data;               /* NFA_CE_DATA_EVT                      */
+
+} tNFA_CONN_EVT_DATA;
+
+/* NFA Connection Callback */
+typedef void(tNFA_CONN_CBACK)(uint8_t event, tNFA_CONN_EVT_DATA* p_data);
+
+#ifndef NFA_DM_NUM_INTERFACE_MAP
+#define NFA_DM_NUM_INTERFACE_MAP 3
+#endif
+
+/* compile-time configuration structure for the RF Discovery Frequency for each
+ * technology */
+typedef struct {
+  uint8_t pa;   /* Frequency for NFC Technology A               */
+  uint8_t pb;   /* Frequency for NFC Technology B               */
+  uint8_t pf;   /* Frequency for NFC Technology F               */
+  uint8_t pi93; /* Frequency for Proprietary Technology/15693   */
+  uint8_t pbp;  /* Frequency for Proprietary Technology/B-Prime */
+  uint8_t pk;   /* Frequency for Proprietary Technology/Kovio   */
+  uint8_t paa;  /* Frequency for NFC Technology A active mode   */
+  uint8_t pfa;  /* Frequency for NFC Technology F active mode   */
+} tNFA_DM_DISC_FREQ_CFG;
+
+/* definitions for tNFA_DM_CFG.presence_check_option */
+/* if NDEF is not supported by the tag, use sleep/wake(last interface) */
+#define NFA_DM_PCO_ISO_SLEEP_WAKE 0x01
+/* NFA_SendRawFrame() has been used, use empty I block for presence check
+ * if this bit is not set, use read-binary on channel 3 for presence check */
+#define NFA_DM_PCO_EMPTY_I_BLOCK 0x02
+
+/* compile-time configuration structure */
+typedef struct {
+  /* Automatic NDEF detection (when not in exclusive RF mode) */
+  bool auto_detect_ndef;
+  /* Automatic NDEF read (when not in exclusive RF mode)      */
+  bool auto_read_ndef;
+  /* Automatic presence check                                 */
+  bool auto_presence_check;
+  /* Use sleep/wake(last interface) for ISODEP presence check */
+  uint8_t presence_check_option;
+  /* Maximum time to wait for presence check response         */
+  uint16_t presence_check_timeout;
+} tNFA_DM_CFG;
+
+/* compile-time configuration structure for HCI */
+typedef struct {
+  /* Maximum idle(no HCP Pkt) time to wait for EE DISC REQ Ntf(s) */
+  uint16_t hci_netwk_enable_timeout;
+  /* Maximum time to wait for EE DISC REQ NTF(s) after HOT PLUG EVT(s) */
+  uint16_t hcp_response_timeout;
+  /* Number of host in the whitelist of Terminal host */
+  uint8_t num_whitelist_host;
+  /* Whitelist of Terminal Host */
+  uint8_t* p_whitelist;
+} tNFA_HCI_CFG;
+
+/*
+** Exclusive RF mode listen configuration
+*/
+
+#define NFA_LB_MAX_NFCID0_LEN 4
+#define NFA_LF_MAX_SC_NFCID2 1
+#define NFA_LA_MAX_HIST_BYTES 15
+#define NFA_LB_MAX_H_INFO_LEN 15
+
+typedef struct {
+  /*
+  ** Discovery Configuration Parameters for Listen A
+  */
+  bool la_enable;             /* true if listening A                      */
+  uint8_t la_bit_frame_sdd;   /* Bit Frame SDD in Byte 1 of SENS_RES      */
+  uint8_t la_platform_config; /* Platform Config in Byte 2 of SENS_RES    */
+  uint8_t la_sel_info;        /* Byte of SEL_RES                          */
+  uint8_t la_nfcid1_len;      /* NFCID1 (0, 4, 7 or 10 bytes)             */
+  uint8_t la_nfcid1[NCI_NFCID1_MAX_LEN]; /*        if empty, NFCC will decide */
+
+  /*
+  ** Discovery Configuration Parameters for Listen B
+  */
+  bool lb_enable;        /* true if listening B                      */
+  uint8_t lb_sensb_info; /* Byte 2 of Protocol Info within SENSB_RES */
+  uint8_t lb_nfcid0_len; /* NFCID0 (0, 1 or 4 bytes)                 */
+  uint8_t
+      lb_nfcid0[NFA_LB_MAX_NFCID0_LEN]; /*         if empty, NFCC will decide */
+  uint8_t lb_app_data[NCI_PARAM_LEN_LB_APPDATA]; /* Bytes 6 - 9 in SENSB_RES */
+  uint8_t lb_sfgi;   /* Start-Up Frame Guard Time                */
+  uint8_t lb_adc_fo; /* Byte 12 in SENSB_RES                     */
+
+  /*
+  ** Discovery Configuration Parameters for Listen F
+  */
+  bool lf_enable;           /* true if listening F          */
+  uint8_t lf_con_bitr_f;    /* bit rate to listen           */
+  uint8_t lf_protocol_type; /* Supported Protocols          */
+  /* bit field indicating which lf_t3t_identifier are enabled */
+  uint16_t lf_t3t_flags;
+  uint8_t lf_t3t_identifier[NFA_LF_MAX_SC_NFCID2][NCI_SYSTEMCODE_LEN +
+                                                  NCI_NFCID2_LEN];
+  /* System Code and NFCID2       */
+  uint8_t lf_t3t_pmm[NCI_T3T_PMM_LEN]; /* Bytes 10 - 17 in SENSF_RES   */
+
+  /*
+  ** Discovery Configuration Parameters for Listen ISO-DEP
+  */
+  bool li_enable;            /* true if listening ISO-DEP            */
+  uint8_t li_fwi;            /* Frame Waiting Time Integer           */
+  uint8_t la_hist_bytes_len; /* historical bytes for Listen-A        */
+  uint8_t la_hist_bytes[NFA_LA_MAX_HIST_BYTES];
+  uint8_t lb_h_info_resp_len; /* higher layer response for Listen-B   */
+  uint8_t lb_h_info_resp[NFA_LB_MAX_H_INFO_LEN];
+
+  /*
+  ** Discovery Configuration Parameters for Listen NFC-DEP
+  */
+  bool ln_enable;                   /* true if listening NFC-DEP            */
+  uint8_t ln_wt;                    /* Waiting Time Integer                 */
+  uint8_t ln_atr_res_gen_bytes_len; /* General bytes in ATR_RES             */
+  uint8_t ln_atr_res_gen_bytes[NCI_MAX_GEN_BYTES_LEN];
+  uint8_t ln_atr_res_config; /* Optional parameters (PPt) in ATR_RES */
+} tNFA_LISTEN_CFG;
+
+/* Data for NFA_UpdateRFCommParams () */
+typedef tNFC_RF_COMM_PARAMS tNFA_RF_COMM_PARAMS;
+
+/* RF Interface type */
+#define NFA_INTERFACE_FRAME NFC_INTERFACE_FRAME
+#define NFA_INTERFACE_ISO_DEP NFC_INTERFACE_ISO_DEP
+#define NFA_INTERFACE_NFC_DEP NFC_INTERFACE_NFC_DEP
+#define NFA_INTERFACE_MIFARE NFC_INTERFACE_MIFARE
+typedef tNFC_INTF_TYPE tNFA_INTF_TYPE;
+
+/*******************************************************************************
+** NDEF Definitions
+*******************************************************************************/
+
+/* Definitions for tNFA_TNF (NDEF type name format ID) */
+/* Empty or no type specified */
+#define NFA_TNF_EMPTY NDEF_TNF_EMPTY
+/* NFC Forum well-known type [NFC RTD] */
+#define NFA_TNF_WKT NDEF_TNF_WKT
+/* Media-type as defined in RFC 2046 [RFC 2046] */
+#define NFA_TNF_RFC2046_MEDIA NDEF_TNF_MEDIA
+/* Absolute URI as defined in RFC 3986 [RFC 3986] */
+#define NFA_TNF_RFC3986_URI NDEF_TNF_URI
+/* NFC Forum external type [NFC RTD] */
+#define NFA_TNF_EXTERNAL NDEF_TNF_EXT
+/* Unknown */
+#define NFA_TNF_UNKNOWN NDEF_TNF_UNKNOWN
+/* Unchanged */
+#define NFA_TNF_UNCHANGED NDEF_TNF_UNCHANGED
+/* Reserved */
+#define NFA_TNF_RESERVED NDEF_TNF_RESERVED
+/* Used to register default NDEF type handler */
+#define NFA_TNF_DEFAULT 0xFF
+typedef uint8_t tNFA_TNF;
+
+/* Definitions for tNFA_NDEF_URI_ID (Frequently used prefixes. For additional
+ * values, see [NFC RTD URI] */
+#define NFA_NDEF_URI_ID_ABSOLUTE 0x00 /* Unabridged URI.  */
+#define NFA_NDEF_URI_ID_HTTP 0x03     /* http://          */
+#define NFA_NDEF_URI_ID_HTTPS 0x04    /* https://         */
+#define NFA_NDEF_URI_ID_TEL 0x05      /* tel:             */
+#define NFA_NDEF_URI_ID_MAILTO 0x06   /* mailto:          */
+#define NFA_NDEF_URI_ID_FTP 0x0D      /* ftp://           */
+#define NFA_NDEF_URI_ID_FILE 0x1D     /* file://          */
+
+typedef uint8_t tNFA_NDEF_URI_ID;
+
+/* Events for tNFA_NDEF_CBACK */
+/* NDEF record type registered. (In response to NFA_RegisterNDefTypeHandler) */
+#define NFA_NDEF_REGISTER_EVT 0
+/* Received an NDEF message with the registered type. See [tNFA_NDEF_DATA] */
+#define NFA_NDEF_DATA_EVT 1
+typedef uint8_t tNFA_NDEF_EVT;
+
+/* Structure for NFA_NDEF_REGISTER_EVT event data */
+typedef struct {
+  tNFA_STATUS status;           /* Status of the registration               */
+  tNFA_HANDLE ndef_type_handle; /* Handle for this NDEF type registration.  */
+} tNFA_NDEF_REGISTER;
+
+/* Structure for NFA_NDEF_DATA_EVT event data */
+typedef struct {
+  tNFA_HANDLE ndef_type_handle; /* Handle for NDEF type registration.   */
+  uint8_t* p_data;              /* Data buffer                          */
+  uint32_t len;                 /* Length of data                       */
+} tNFA_NDEF_DATA;
+
+/* Union of all NDEF callback structures */
+typedef union {
+  /* Structure for NFA_NDEF_REGISTER_EVT event data */
+  tNFA_NDEF_REGISTER ndef_reg;
+  /* Structure for NFA_NDEF_DATA_EVT event data */
+  tNFA_NDEF_DATA ndef_data;
+} tNFA_NDEF_EVT_DATA;
+
+/* NFA_NDEF callback */
+typedef void(tNFA_NDEF_CBACK)(tNFA_NDEF_EVT event, tNFA_NDEF_EVT_DATA* p_data);
+
+/* NFA VSC Callback */
+typedef void(tNFA_VSC_CBACK)(uint8_t event, uint16_t param_len,
+                             uint8_t* p_param);
+
+/*****************************************************************************
+**  External Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+**
+** Function         NFA_Init
+**
+** Description      This function initializes control blocks for NFA
+**
+**                  p_hal_entry_tbl points to a table of HAL entry points
+**
+**                  NOTE: the buffer that p_hal_entry_tbl points must be
+**                  persistent until NFA is disabled.
+**
+**
+** Returns          none
+**
+*******************************************************************************/
+extern void NFA_Init(tHAL_NFC_ENTRY* p_hal_entry_tbl);
+
+/*******************************************************************************
+**
+** Function         NFA_Enable
+**
+** Description      This function enables NFC. Prior to calling NFA_Enable,
+**                  the NFCC must be powered up, and ready to receive commands.
+**                  This function enables the tasks needed by NFC, opens the NCI
+**                  transport, resets the NFC controller, downloads patches to
+**                  the NFCC (if necessary), and initializes the NFC subsystems.
+**
+**                  This function should only be called once - typically when
+**                  NFC is enabled during boot-up, or when NFC is enabled from a
+**                  settings UI. Subsequent calls to NFA_Enable while NFA is
+**                  enabling or enabled will be ignored. When the NFC startup
+**                  procedure is completed, an NFA_DM_ENABLE_EVT is returned to
+**                  the application using the tNFA_DM_CBACK.
+**
+**                  The tNFA_CONN_CBACK parameter is used to register a callback
+**                  for polling, p2p and card emulation events.
+**
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_Enable(tNFA_DM_CBACK* p_dm_cback,
+                              tNFA_CONN_CBACK* p_conn_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_Disable
+**
+** Description      This function is called to shutdown NFC. The tasks for NFC
+**                  are terminated, and clean up routines are performed. This
+**                  function is typically called during platform shut-down, or
+**                  when NFC is disabled from a settings UI. When the NFC
+**                  shutdown procedure is completed, an NFA_DM_DISABLE_EVT is
+**                  returned to the application using the tNFA_DM_CBACK.
+**
+**                  The platform should wait until the NFC_DISABLE_REVT is
+**                  received before powering down the NFC chip and NCI
+**                  transport. This is required to so that NFA can gracefully
+**                  shut down any open connections.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_Disable(bool graceful);
+
+/*******************************************************************************
+**
+** Function         NFA_SetConfig
+**
+** Description      Set the configuration parameters to NFCC. The result is
+**                  reported with an NFA_DM_SET_CONFIG_EVT in the tNFA_DM_CBACK
+**                  callback.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function. Most Configuration
+**                  parameters are related to RF discovery.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BUSY if previous setting is on-going
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_SetConfig(tNFA_PMID param_id, uint8_t length,
+                                 uint8_t* p_data);
+
+/*******************************************************************************
+**
+** Function         NFA_GetConfig
+**
+** Description      Get the configuration parameters from NFCC. The result is
+**                  reported with an NFA_DM_GET_CONFIG_EVT in the tNFA_DM_CBACK
+**                  callback.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_GetConfig(uint8_t num_ids, tNFA_PMID* p_param_ids);
+
+/*******************************************************************************
+**
+** Function         NFA_RequestExclusiveRfControl
+**
+** Description      Request exclusive control of NFC.
+**                  - Previous behavior (polling/tag reading, DH card emulation)
+**                    will be suspended .
+**                  - Polling and listening will be done based on the specified
+**                    params
+**
+**                  The NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT event of
+**                  tNFA_CONN_CBACK indicates the status of the operation.
+**
+**                  NFA_ACTIVATED_EVT and NFA_DEACTIVATED_EVT indicates link
+**                  activation/deactivation.
+**
+**                  NFA_SendRawFrame is used to send data to the peer.
+**                  NFA_DATA_EVT indicates data from the peer.
+**
+**                  If a tag is activated, then the NFA_RW APIs may be used to
+**                  send commands to the tag. Incoming NDEF messages are sent to
+**                  the NDEF callback.
+**
+**                  Once exclusive RF control has started, NFA will not activate
+**                  LLCP internally. The application has exclusive control of
+**                  the link.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RequestExclusiveRfControl(tNFA_TECHNOLOGY_MASK poll_mask,
+                                                 tNFA_LISTEN_CFG* p_listen_cfg,
+                                                 tNFA_CONN_CBACK* p_conn_cback,
+                                                 tNFA_NDEF_CBACK* p_ndef_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_ReleaseExclusiveRfControl
+**
+** Description      Release exclusive control of NFC. Once released, behavior
+**                  prior to obtaining exclusive RF control will resume.
+**
+Note??
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_ReleaseExclusiveRfControl(void);
+
+/*******************************************************************************
+**
+** Function         NFA_EnablePolling
+**
+** Description      Enable polling for technologies specified by poll_mask.
+**
+**                  The following events (notified using the connection
+**                  callback registered with NFA_Enable) are generated during
+**                  polling:
+**
+**                  - NFA_POLL_ENABLED_EVT indicates whether or not polling
+**                    successfully enabled.
+**                  - NFA_DISC_RESULT_EVT indicates there are more than one
+**                    devices, so application must select one of tags by calling
+**                    NFA_Select().
+**                  - NFA_SELECT_RESULT_EVT indicates whether previous selection
+**                    was successful or not. If it was failed then application
+**                    must select again or deactivate by calling
+**                    NFA_Deactivate().
+**                  - NFA_ACTIVATED_EVT is generated when an NFC link is
+**                    activated.
+**                  - NFA_NDEF_DETECT_EVT is generated if tag is activated
+**                  - NFA_LLCP_ACTIVATED_EVT/NFA_LLCP_DEACTIVATED_EVT is
+**                    generated if NFC-DEP is activated
+**                  - NFA_DEACTIVATED_EVT will be returned after deactivating
+**                    NFC link.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_EnablePolling(tNFA_TECHNOLOGY_MASK poll_mask);
+
+/*******************************************************************************
+**
+** Function         NFA_DisablePolling
+**
+** Description      Disable polling
+**                  NFA_POLL_DISABLED_EVT will be returned after stopping
+**                  polling.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_DisablePolling(void);
+
+/*******************************************************************************
+**
+** Function         NFA_EnableListening
+**
+** Description      Enable listening.
+**                  NFA_LISTEN_ENABLED_EVT will be returned after listening is
+**                  allowed.
+**
+**                  The actual listening technologies are specified by other NFA
+**                  API functions. Such functions include (but not limited to)
+**                  NFA_CeConfigureUiccListenTech.
+**                  If NFA_DisableListening () is called to ignore the listening
+**                  technologies, NFA_EnableListening () is called to restore
+**                  the listening technologies set by these functions.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_EnableListening(void);
+
+/*******************************************************************************
+**
+** Function         NFA_DisableListening
+**
+** Description      Disable listening
+**                  NFA_LISTEN_DISABLED_EVT will be returned after stopping
+**                  listening. This function is called to exclude listen at RF
+**                  discovery.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_DisableListening(void);
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         NFA_DisablePassiveListening
+**
+** Description      Disable Passive listening
+**                  NFA_PASSIVE_LISTEN_DISABLED_EVT will be returned after
+*stopping listening.
+**                  This function is called to exclude Passive listen at eSE
+*wired mode enable session.
+**
+** Note:            If RF discovery is started,
+*NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_DisablePassiveListening(void);
+#endif
+
+/*******************************************************************************
+**
+** Function         NFA_PauseP2p
+**
+** Description      Pause P2P services.
+**                  NFA_P2P_PAUSED_EVT will be returned after P2P services are
+**                  disabled.
+**
+**                  The P2P services enabled by NFA_P2p* API functions are not
+**                  available. NFA_ResumeP2p() is called to resume the P2P
+**                  services.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_PauseP2p(void);
+
+/*******************************************************************************
+**
+** Function         NFA_ResumeP2p
+**
+** Description      Resume P2P services.
+**                  NFA_P2P_RESUMED_EVT will be returned after P2P services are.
+**                  enables again.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_ResumeP2p(void);
+
+/*******************************************************************************
+**
+** Function         NFA_SetP2pListenTech
+**
+** Description      This function is called to set listen technology for
+**                  NFC-DEP. This funtion may be called before or after starting
+**                  any server on NFA P2P/CHO/SNEP.
+**                  If there is no technology for NFC-DEP, P2P listening will be
+**                  stopped.
+**
+**                  NFA_SET_P2P_LISTEN_TECH_EVT without data will be returned.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_SetP2pListenTech(tNFA_TECHNOLOGY_MASK tech_mask);
+
+/*******************************************************************************
+**
+** Function         NFA_StartRfDiscovery
+**
+** Description      Start RF discovery
+**                  RF discovery parameters shall be set by other APIs.
+**
+**                  An NFA_RF_DISCOVERY_STARTED_EVT indicates whether starting
+**                  was successful or not.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_StartRfDiscovery(void);
+
+/*******************************************************************************
+**
+** Function         NFA_StopRfDiscovery
+**
+** Description      Stop RF discovery
+**
+**                  An NFA_RF_DISCOVERY_STOPPED_EVT indicates whether stopping
+**                  was successful or not.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_StopRfDiscovery(void);
+
+/*******************************************************************************
+**
+** Function         NFA_SetRfDiscoveryDuration
+**
+** Description      Set the duration of the single discovery period in [ms].
+**                  Allowable range: 0 ms to 0xFFFF ms.
+**
+** Note:            If discovery is already started, the application should
+**                  call NFA_StopRfDiscovery prior to calling
+**                  NFA_SetRfDiscoveryDuration, and then call
+**                  NFA_StartRfDiscovery afterwards to restart discovery using
+**                  the new duration.
+**
+** Returns:
+**                  NFA_STATUS_OK, if command accepted
+**                  NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_SetRfDiscoveryDuration(uint16_t discovery_period_ms);
+
+/*******************************************************************************
+**
+** Function         NFA_Select
+**
+** Description      Select one from detected devices by NFA_DISC_RESULT_EVT
+**                  after the last discovery result is received.
+**                  An NFA_SELECT_RESULT_EVT indicates whether selection was
+**                  successful or not. If failed then application must select
+**                  again or deactivate by NFA_Deactivate ().
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_INVALID_PARAM if RF interface is not matched
+**                  protocol
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_Select(uint8_t rf_disc_id, tNFA_NFC_PROTOCOL protocol,
+                              tNFA_INTF_TYPE rf_interface);
+
+/*******************************************************************************
+**
+** Function         NFA_UpdateRFCommParams
+**
+** Description      This function is called to update RF Communication
+**                  parameters once the Frame RF Interface has been activated.
+**
+**                  An NFA_UPDATE_RF_PARAM_RESULT_EVT indicates whether updating
+**                  was successful or not.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_UpdateRFCommParams(tNFA_RF_COMM_PARAMS* p_params);
+
+/*******************************************************************************
+**
+** Function         NFA_Deactivate
+**
+** Description
+**                  If sleep_mode=true:
+**                      Deselect the activated device by deactivating into sleep
+**                      mode.
+**
+**                      An NFA_DEACTIVATE_FAIL_EVT indicates that selection was
+**                      not successful.Application can select another
+**                      discovered device or deactivate by NFA_Deactivate ()
+**                      after receiving NFA_DEACTIVATED_EVT.
+**
+**                      Deactivating to sleep mode is not allowed when NFCC is
+**                      in wait-for-host-select mode, or in listen-sleep states;
+**                      NFA will deactivate to idle or discovery state for these
+**                      cases respectively.
+**
+**
+**                  If sleep_mode=false:
+**                      Deactivate the connection (e.g. as a result of presence
+**                      check failure) NFA_DEACTIVATED_EVT will indicate that
+**                      link is deactivated.Polling/listening will resume
+**                      (unless the nfcc is in wait_for-all-discoveries state)
+**
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_Deactivate(bool sleep_mode);
+
+/*******************************************************************************
+**
+** Function         NFA_SendRawFrame
+**
+** Description      Send a raw frame over the activated interface with the NFCC.
+**                  This function can only be called after NFC link is
+**                  activated.
+**
+**                  If the activated interface is a tag and auto-presence check
+**                  is enabled then presence_check_start_delay can be used to
+**                  indicate the delay in msec after which the next auto
+**                  presence check command can be sent.
+**                  NFA_DM_DEFAULT_PRESENCE_CHECK_START_DELAY can be used as the
+**                  default value for the delay.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_SendRawFrame(uint8_t* p_raw_data, uint16_t data_len,
+                                    uint16_t presence_check_start_delay);
+
+/*******************************************************************************
+** NDEF APIs
+*******************************************************************************/
+
+/*******************************************************************************
+**
+** Function         NFA_RegisterNDefTypeHandler
+**
+** Description      This function allows the applications to register for
+**                  specific types of NDEF records. When NDEF records are
+**                  received, NFA will parse the record-type field, and pass
+**                  the record to the registered tNFA_NDEF_CBACK.
+**
+**                  For records types which were not registered, the record will
+**                  be sent to the default handler. A default type-handler may
+**                  be registered by calling this NFA_RegisterNDefTypeHandler
+**                  with tnf=NFA_TNF_DEFAULT. In this case, all un-registered
+**                  record types will be sent to the callback. Only one default
+**                  handler may be registered at a time.
+**
+**                  An NFA_NDEF_REGISTER_EVT will be sent to the tNFA_NDEF_CBACK
+**                  to indicate that registration was successful, and provide a
+**                  handle for this record type.
+**
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RegisterNDefTypeHandler(bool handle_whole_message,
+                                               tNFA_TNF tnf,
+                                               uint8_t* p_type_name,
+                                               uint8_t type_name_len,
+                                               tNFA_NDEF_CBACK* p_ndef_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_RegisterNDefUriHandler
+**
+** Description      This API is a special-case of NFA_RegisterNDefTypeHandler
+**                  with TNF=NFA_TNF_WKT, and type_name='U' (URI record); and
+**                  allows registering for specific URI types (e.g. 'tel:' or
+**                  'mailto:').
+**
+**                  An NFA_NDEF_REGISTER_EVT will be sent to the tNFA_NDEF_CBACK
+**                  to indicate that registration was successful, and provide a
+**                  handle for this registration.
+**
+**                  If uri_id=NFA_NDEF_URI_ID_ABSOLUTE, then p_abs_uri contains
+**                  the unabridged URI. For all other uri_id values, the
+**                  p_abs_uri parameter is ignored (i.e the URI prefix is
+**                  implied by uri_id).
+**
+**                  See [NFC RTD URI] for more information.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RegisterNDefUriHandler(bool handle_whole_message,
+                                              tNFA_NDEF_URI_ID uri_id,
+                                              uint8_t* p_abs_uri,
+                                              uint8_t uri_id_len,
+                                              tNFA_NDEF_CBACK* p_ndef_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_DeregisterNDefTypeHandler
+**
+** Description      Deregister NDEF record type handler.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_DeregisterNDefTypeHandler(tNFA_HANDLE ndef_type_handle);
+
+/*******************************************************************************
+**
+** Function         NFA_PowerOffSleepMode
+**
+** Description      This function is called to enter or leave NFCC Power Off
+**                  Sleep mode
+**                  NFA_DM_PWR_MODE_CHANGE_EVT will be sent to indicate status.
+**
+**                  start_stop : true if entering Power Off Sleep mode
+**                               false if leaving Power Off Sleep mode
+**
+Note??
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_PowerOffSleepMode(bool start_stop);
+
+/*******************************************************************************
+**
+** Function         NFA_RegVSCback
+**
+** Description      This function is called to register or de-register a
+**                  callback function to receive Proprietary NCI response and
+**                  notification events.
+**                  The maximum number of callback functions allowed is
+**                  NFC_NUM_VS_CBACKS
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS NFA_RegVSCback(bool is_register, tNFA_VSC_CBACK* p_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_SendVsCommand
+**
+** Description      This function is called to send an NCI Vendor Specific
+**                  command to NFCC.
+**
+**                  oid             - The opcode of the VS command.
+**                  cmd_params_len  - The command parameter len
+**                  p_cmd_params    - The command parameter
+**                  p_cback         - The callback function to receive the
+**                                    command status
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_SendVsCommand(uint8_t oid, uint8_t cmd_params_len,
+                                     uint8_t* p_cmd_params,
+                                     tNFA_VSC_CBACK* p_cback);
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         NFA_SendNxpNciCommand
+**
+** Description      This function is called to send NXP NCI Vendor Specific
+**                  command to NFCC.
+**
+**                  cmd_params_len  - The command parameter len
+**                  p_cmd_params    - The command parameter
+**                  p_cback         - The callback function to receive the
+*command
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+
+extern tNFA_STATUS NFA_SendNxpNciCommand(uint8_t cmd_params_len,
+                                         uint8_t* p_cmd_params,
+                                         tNFA_VSC_CBACK* p_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_Send_Core_Reset
+**
+** Description      Performs NCI Core Reset dynamically based on NCI version
+**
+**
+** Returns          SUCCESS/FAIL
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_Send_Core_Reset();
+
+/*******************************************************************************
+**
+** Function         NFA_Send_Core_Init
+**
+** Description      Performs NCI Core Init dynamically based on NCI version
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+extern void NFA_Send_Core_Init(uint8_t** p);
+#endif
+
+/*******************************************************************************
+**
+** Function         NFA_SetTraceLevel
+**
+** Description      This function sets the trace level for NFA.  If called with
+**                  a value of 0xFF, it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+extern uint8_t NFA_SetTraceLevel(uint8_t new_level);
+
+/*******************************************************************************
+**
+** Function:        NFA_SetPowerSubState
+**
+** Description:     This function send the current screen state
+**
+** Returns:        NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+*******************************************************************************/
+extern tNFA_STATUS NFA_SetPowerSubState (uint8_t  ScreenState);
+
+/*******************************************************************************
+**
+** Function:        NFA_EnableDTA_TypeMode
+**
+** Description:     Initialize and get global DTA type mode from .conf
+**
+** Returns:         none:
+**
+*******************************************************************************/
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         NFA_SetReaderMode
+**
+** Description:
+**      This function enable/disable  reader mode. In reader mode, even though
+*if
+**      P2P & CE from UICC is detected, Priority will be given to TypeF UICC
+*read.
+**      Its currently implemented for TypeF
+**
+**      ReaderModeFlag - Enable/Disable Reader Mode
+**      Technologies   - Type of technologies to be set for Reader mode
+**                       Currently not used and reader mode is enabled for TypeF
+*Only
+**
+** Returns:
+**      void
+*******************************************************************************/
+extern void NFA_SetReaderMode(bool ReaderModeFlag, uint32_t Technologies);
+
+/*******************************************************************************
+**
+** Function         NFA_SetBootMode
+**
+** Description      This function enables the boot mode for NFC.
+**                  boot_mode  0 NORMAL_BOOT 1 FAST_BOOT
+**                  By default , the mode is set to NORMAL_BOOT.
+
+**
+** Returns          none
+**
+*******************************************************************************/
+extern void NFA_SetBootMode(uint8_t boot_mode);
+
+extern void NFA_EnableDtamode(tNFA_eDtaModes eDtaMode);
+
+/*******************************************************************************
+**
+** Function:        NFA_GetMwVersion
+**
+** Description:     This function gets the Middleware Version
+**
+** Returns:         First 8 bit Major Version
+**                  Last 8 bit Minor Version
+**
+*******************************************************************************/
+extern tNFA_MW_VERSION NFA_GetMwVersion();
+
+/*******************************************************************************
+**
+** Function         NFA_checkNfcStateBusy()
+**
+** Description      This function returns whether NFC process is busy or not.
+**
+** Returns          if Nfc state busy return true otherwise false.
+**
++*******************************************************************************/
+extern bool NFA_checkNfcStateBusy();
+
+extern void NFA_EE_HCI_Control(bool mode);
+extern tNFA_STATUS NFA_ResetNfcc();
+
+/*******************************************************************************
+**
+** Function:        NFA_SetPreferredUiccId
+**
+** Description:     Set Preferred Uicc ID
+**                  0x02 - UICC1
+**                  0x81 - UICC2
+**
+** Returns:         none:
+**
+*******************************************************************************/
+extern void NFA_SetPreferredUiccId(uint8_t uicc_id);
+
+#endif
+
+/*******************************************************************************
+**
+** Function         NFA_GetNCIVersion
+**
+** Description      Called by higher layer to get the current nci
+**                  version of nfc.
+**
+** Returns          NCI version NCI2.0 / NCI1.0
+**
+*******************************************************************************/
+extern uint8_t NFA_GetNCIVersion();
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* NFA_API_H */
diff --git a/src/nfa/include/nfa_ce_api.h b/src/nfa/include/nfa_ce_api.h
new file mode 100644
index 0000000..28a5708
--- /dev/null
+++ b/src/nfa/include/nfa_ce_api.h
@@ -0,0 +1,288 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  NFA card emulation API functions
+ *
+ ******************************************************************************/
+#ifndef NFA_CE_API_H
+#define NFA_CE_API_H
+
+#include "nfc_target.h"
+#include "nfa_api.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+/*****************************************************************************
+**  External Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+**
+** Function         NFA_CeConfigureLocalTag
+**
+** Description      Configure local NDEF tag.
+**
+**                  Tag events will be notifed using the tNFA_CONN_CBACK
+**                  (registered during NFA_Enable)
+**
+**                  The NFA_CE_LOCAL_TAG_CONFIGURED_EVT reports the status of
+**                  the operation.
+**
+**                  Activation and deactivation are reported using the
+**                  NFA_ACTIVATED_EVT and NFA_DEACTIVATED_EVT events
+**
+**                  If a write-request is received to update the tag memory,
+**                  an NFA_CE_NDEF_WRITE_CPLT_EVT will notify the application,
+**                  along with a buffer containing the updated contents.
+**
+**                  To disable the local NDEF tag, set protocol_mask=0
+**
+**                  The NDEF data provided by p_ndef_data must be persistent
+**                  as long as the local NDEF tag is enabled. Also, Input
+**                  parameters p_uid and uid_len are reserved for future use.
+**
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function.
+**
+** Returns:
+**                  NFA_STATUS_OK,            if command accepted
+**                  NFA_STATUS_INVALID_PARAM,
+**                      if protocol_maks is not 0 and p_ndef_data is NULL
+**                  (or) uid_len is not 0
+**                  (or) if protocol mask is set for Type 1 or Type 2
+**
+**                  NFA_STATUS_FAILED:        otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_CeConfigureLocalTag(tNFA_PROTOCOL_MASK protocol_mask,
+                                           uint8_t* p_ndef_data,
+                                           uint16_t ndef_cur_size,
+                                           uint16_t ndef_max_size,
+                                           bool read_only, uint8_t uid_len,
+                                           uint8_t* p_uid);
+
+/*******************************************************************************
+**
+** Function         NFA_CeConfigureUiccListenTech
+**
+** Description      Configure listening for the UICC, using the specified
+**                  technologies.
+**
+**                  Events will be notifed using the tNFA_CONN_CBACK
+**                  (registered during NFA_Enable)
+**
+**                  The NFA_CE_UICC_LISTEN_CONFIGURED_EVT reports the status of
+**                  the operation.
+**
+**                  Activation and deactivation are reported using the
+**                  NFA_ACTIVATED_EVT and NFA_DEACTIVATED_EVT events
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns:
+**                  NFA_STATUS_OK, if command accepted
+**                  NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_CeConfigureUiccListenTech(
+    tNFA_HANDLE ee_handle, tNFA_TECHNOLOGY_MASK tech_mask);
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         NFA_CeConfigureEseListenTech
+**
+** Description      Configure listening for the Ese, using the specified
+**                  technologies.
+**
+**                  Events will be notifed using the tNFA_CONN_CBACK
+**                  (registered during NFA_Enable)
+**
+**                  The NFA_CE_ESE_LISTEN_CONFIGURED_EVT reports the status of
+*the
+**                  operation.
+**
+**                  Activation and deactivation are reported using the
+**                  NFA_ACTIVATED_EVT and NFA_DEACTIVATED_EVT events
+**
+** Note:            If RF discovery is started,
+*NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns:
+**                  NFA_STATUS_OK, if command accepted
+**                  NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_CeConfigureEseListenTech(tNFA_HANDLE ee_handle,
+                                                tNFA_TECHNOLOGY_MASK tech_mask);
+#endif
+/*******************************************************************************
+**
+** Function         NFA_CeRegisterFelicaSystemCodeOnDH
+**
+** Description      Register listening callback for Felica system code
+**
+**                  The NFA_CE_REGISTERED_EVT reports the status of the
+**                  operation.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns:
+**                  NFA_STATUS_OK, if command accepted
+**                  NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_CeRegisterFelicaSystemCodeOnDH(
+    uint16_t system_code, uint8_t nfcid2[NCI_RF_F_UID_LEN],
+    tNFA_CONN_CBACK* p_conn_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_CeDeregisterFelicaSystemCodeOnDH
+**
+** Description      Deregister listening callback for Felica
+**                  (previously registered using
+**                  NFA_CeRegisterFelicaSystemCodeOnDH)
+**
+**                  The NFA_CE_DEREGISTERED_EVT reports the status of the
+**                  operation.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if invalid handle
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_CeDeregisterFelicaSystemCodeOnDH(tNFA_HANDLE handle);
+
+/*******************************************************************************
+**
+** Function         NFA_CeRegisterAidOnDH
+**
+** Description      Register listening callback for the specified ISODEP AID
+**
+**                  The NFA_CE_REGISTERED_EVT reports the status of the
+**                  operation.
+**
+**                  If no AID is specified (aid_len=0), then p_conn_cback will
+**                  will get notifications for any AIDs routed to the DH. This
+**                  over-rides callbacks registered for specific AIDs.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns:
+**                  NFA_STATUS_OK, if command accepted
+**                  NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_CeRegisterAidOnDH(uint8_t aid[NFC_MAX_AID_LEN],
+                                         uint8_t aid_len,
+                                         tNFA_CONN_CBACK* p_conn_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_CeDeregisterAidOnDH
+**
+** Description      Deregister listening callback for ISODEP AID
+**                  (previously registered using NFA_CeRegisterAidOnDH)
+**
+**                  The NFA_CE_DEREGISTERED_EVT reports the status of the
+**                  operation.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if invalid handle
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_CeDeregisterAidOnDH(tNFA_HANDLE handle);
+
+/*******************************************************************************
+**
+** Function         NFA_CeSetIsoDepListenTech
+**
+** Description      Set the technologies (NFC-A and/or NFC-B) to listen for when
+**                  NFA_CeConfigureLocalTag or NFA_CeDeregisterAidOnDH are
+**                  called.
+**
+**                  By default (if this API is not called), NFA will listen
+**                  for both NFC-A and NFC-B for ISODEP.
+**
+** Note:            If listening for ISODEP on UICC, the DH listen callbacks
+**                  may still get activate notifications for ISODEP if the
+**                  reader/writer selects an AID that is not routed to the UICC
+**                  (regardless of whether A or B was disabled using
+**                  NFA_CeSetIsoDepListenTech)
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns:
+**                  NFA_STATUS_OK, if command accepted
+**                  NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_CeSetIsoDepListenTech(tNFA_TECHNOLOGY_MASK tech_mask);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFA_CE_API_H */
diff --git a/src/nfa/include/nfa_ee_api.h b/src/nfa/include/nfa_ee_api.h
new file mode 100644
index 0000000..787c15f
--- /dev/null
+++ b/src/nfa/include/nfa_ee_api.h
@@ -0,0 +1,741 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  NFA interface to NFCEE
+ *
+ ******************************************************************************/
+#ifndef NFA_EE_API_H
+#define NFA_EE_API_H
+
+#include "nfc_target.h"
+#include "nfa_api.h"
+#include "nfc_api.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+/* 16 per ISO 7816 specification    */
+#define NFA_MAX_AID_LEN NFC_MAX_AID_LEN
+#define NFA_MAX_APDU_DATA_LEN NFC_MAX_APDU_DATA_LEN
+#define NFA_MAX_APDU_MASK_LEN NFC_MAX_APDU_MASK_LEN
+
+#define NFA_EE_HANDLE_DH (NFA_HANDLE_GROUP_EE | NFC_DH_ID)
+#if (NXP_EXTNS == TRUE)
+extern uint8_t NFA_REMOVE_ALL_AID[];
+#define NFA_REMOVE_ALL_AID_LEN (0x08)
+extern uint8_t nfa_ee_ce_route_strict_disable;
+extern uint8_t nfa_ee_ce_p61_active;
+#define NFA_EE_AE_NXP_PREFIX_MATCH (0x10)
+#endif
+
+/* NFA EE callback events */
+enum {
+  NFA_EE_DISCOVER_EVT,   /* The status for NFA_EeDiscover () */
+  NFA_EE_REGISTER_EVT,   /* The status for NFA_EeRegister () */
+  NFA_EE_DEREGISTER_EVT, /* The status for NFA_EeDeregister () */
+  NFA_EE_MODE_SET_EVT, /* The status for activating or deactivating an NFCEE */
+  NFA_EE_ADD_AID_EVT,  /* The status for adding an AID to a routing table entry
+                          */
+  NFA_EE_REMOVE_AID_EVT, /* The status for removing an AID from a routing table
+                            */
+  NFA_EE_REMAINING_SIZE_EVT, /* The remaining size of the Listen Mode Routing
+                                Table   */
+  NFA_EE_SET_TECH_CFG_EVT,   /* The status for setting the routing based on RF
+                                tech.  */
+  NFA_EE_SET_PROTO_CFG_EVT,  /* The status for setting the routing based on
+                                protocols */
+  NFA_EE_UPDATED_EVT,        /* The status for NFA_EeUpdateNow */
+  NFA_EE_CONNECT_EVT,        /* Result of NFA_EeConnect */
+  NFA_EE_DATA_EVT, /* Received data from NFCEE.                             */
+  NFA_EE_DISCONNECT_EVT, /* NFCEE connection closed. */
+  NFA_EE_NEW_EE_EVT, /* A new NFCEE is discovered                             */
+  NFA_EE_ACTION_EVT, /* An action happened in NFCEE                           */
+  NFA_EE_DISCOVER_REQ_EVT, /* NFCEE Discover Request Notification */
+  NFA_EE_ROUT_ERR_EVT,     /* Error - exceed NFCC CE Routing size */
+  NFA_EE_NO_MEM_ERR_EVT,   /* Error - out of GKI buffers */
+  NFA_EE_NO_CB_ERR_EVT, /* Error - Can not find control block or wrong state */
+#if (NXP_EXTNS == TRUE)
+  NFA_EE_SET_MODE_INFO_EVT,
+  NFA_EE_PWR_LINK_CTRL_EVT, /* NFCEE Pwr and link cotnrol command Evt */
+#endif
+  NFA_EE_ADD_APDU_EVT,  /* The status for adding an APDU pattern to a routing table entry*/
+  NFA_EE_REMOVE_APDU_EVT /* The status for removing an APDU pattern from a routing table */
+};
+typedef uint8_t tNFA_EE_EVT;
+
+/* tNFA_NFCEE_INTERFACE values */
+/* APDU Interface       */
+#define NFA_EE_INTERFACE_APDU NFC_NFCEE_INTERFACE_APDU
+/* HCI Access Interface*/
+#define NFA_EE_INTERFACE_HCI_ACCESS NFC_NFCEE_INTERFACE_HCI_ACCESS
+/* T3T Command Interface*/
+#define NFA_EE_INTERFACE_T3T NFC_NFCEE_INTERFACE_T3T
+/* Transparent Interface*/
+#define NFA_EE_INTERFACE_TRANSPARENT NFC_NFCEE_INTERFACE_TRANSPARENT
+/* Proprietary          */
+#define NFA_EE_INTERFACE_PROPRIETARY NFC_NFCEE_INTERFACE_PROPRIETARY
+typedef uint8_t tNFA_EE_INTERFACE;
+
+/* HW/Registration ID   */
+#define NFA_EE_TAG_HW_ID NFC_NFCEE_TAG_HW_ID
+/* ATR Bytes            */
+#define NFA_EE_TAG_ATR_BYTES NFC_NFCEE_TAG_ATR_BYTES
+/* T3T Supplement. Info */
+#define NFA_EE_TAG_T3T_INFO NFC_NFCEE_TAG_T3T_INFO
+/* Broadcom Proprietary */
+#define NFA_EE_TAG_HCI_HOST_ID NFC_NFCEE_TAG_HCI_HOST_ID
+#if (NXP_EXTNS == TRUE)
+typedef uint16_t tNFA_EE_TAG;
+#else
+typedef uint8_t tNFA_EE_TAG;
+#endif
+
+/* for NFA_EeModeSet () */
+#define NFA_EE_MD_ACTIVATE NFC_MODE_ACTIVATE
+#define NFA_EE_MD_DEACTIVATE NFC_MODE_DEACTIVATE
+typedef uint8_t tNFA_EE_MD;
+
+/* The device is on                 */
+#define NFA_EE_PWR_STATE_ON 0x01
+/* The device is switched off       */
+#define NFA_EE_PWR_STATE_SWITCH_OFF 0x02
+/* The device's battery is removed  */
+#define NFA_EE_PWR_STATE_BATT_OFF 0x04
+/* used to remove a particular technology or protocol based routing cfg of a
+ * handle from the routing table. */
+#define NFA_EE_PWR_STATE_NONE 0
+typedef uint8_t tNFA_EE_PWR_STATE;
+
+/* NFCEE connected and inactive */
+#define NFA_EE_STATUS_INACTIVE NFC_NFCEE_STATUS_INACTIVE
+/* NFCEE connected and active   */
+#define NFA_EE_STATUS_ACTIVE NFC_NFCEE_STATUS_ACTIVE
+/* NFCEE removed                */
+#define NFA_EE_STATUS_REMOVED NFC_NFCEE_STATUS_REMOVED
+/* waiting for response from NFCC */
+#define NFA_EE_STATUS_PENDING 0x10
+#define NFA_EE_STATUS_ACTIVATING \
+  (NFA_EE_STATUS_PENDING + NFC_NFCEE_STATUS_ACTIVE)
+#define NFA_EE_STATUS_DEACTIVATING \
+  (NFA_EE_STATUS_PENDING + NFC_NFCEE_STATUS_INACTIVE)
+typedef uint8_t tNFA_EE_STATUS;
+
+/* list of events for controlling DWP transceive state */
+typedef enum {
+  NFCC_RF_FIELD_EVT,
+  NFCC_ACTIVATED_NTF,
+  NFCC_DEACTIVATED_NTF,
+  NFCC_ACTION_NTF,
+  NFCC_CE_DATA_EVT,
+#if (NXP_EXTNS == TRUE)
+  NFCC_RF_TIMEOUT_EVT
+#endif
+} tNFCC_EVTS_NTF;
+
+/* additional NFCEE Info */
+typedef struct {
+  tNFA_EE_TAG tag;
+  uint8_t len;
+  uint8_t info[NFC_MAX_EE_INFO];
+} tNFA_EE_TLV;
+
+typedef struct {
+  tNFA_HANDLE ee_handle;    /* handle for NFCEE oe DH   */
+  tNFA_EE_STATUS ee_status; /* The NFCEE status         */
+  uint8_t num_interface;    /* number of NFCEE interface*/
+  tNFA_EE_INTERFACE
+      ee_interface[NFC_MAX_EE_INTERFACE]; /* NFCEE supported interface */
+  uint8_t num_tlvs;                       /* number of TLVs           */
+  tNFA_EE_TLV ee_tlv[NFC_MAX_EE_TLVS];    /* the TLV                  */
+  uint8_t  ee_power_supply_status;/* The NFCEE Power supply */
+#if (NXP_EXTNS == TRUE)
+  tNFA_NFC_PROTOCOL la_protocol;  /* Listen A protocol    */
+  tNFA_NFC_PROTOCOL lb_protocol;  /* Listen B protocol    */
+  tNFA_NFC_PROTOCOL lf_protocol;  /* Listen F protocol    */
+  tNFA_NFC_PROTOCOL lbp_protocol; /* Listen B' protocol   */
+#endif
+} tNFA_EE_INFO;
+
+typedef struct {
+  tNFA_STATUS status; /* NFA_STATUS_OK is successful      */
+  uint8_t num_ee;     /* number of NFCEEs found           */
+  tNFA_EE_INFO ee_info[NFA_EE_MAX_EE_SUPPORTED]; /*NFCEE information */
+} tNFA_EE_DISCOVER;
+
+typedef struct {
+  tNFA_HANDLE ee_handle; /* Handle of NFCEE                                  */
+  tNFA_STATUS status;    /* NFA_STATUS_OK is successful                      */
+  tNFA_EE_INTERFACE
+      ee_interface; /* NFCEE interface associated with this connection  */
+} tNFA_EE_CONNECT;
+
+/* ISO 7816-4 SELECT command */
+#define NFA_EE_TRGR_SELECT NFC_EE_TRIG_SELECT
+/* RF Protocol changed       */
+#define NFA_EE_TRGR_RF_PROTOCOL NFC_EE_TRIG_RF_PROTOCOL
+/* RF Technology changed     */
+#define NFA_EE_TRGR_RF_TECHNOLOGY NFC_EE_TRIG_RF_TECHNOLOGY
+/* Application initiation    */
+#define NFA_EE_TRGR_APP_INIT NFC_EE_TRIG_APP_INIT
+typedef tNFC_EE_TRIGGER tNFA_EE_TRIGGER;
+
+/* Union of NFCEE action parameter depending on the associated trigger */
+typedef union {
+  tNFA_NFC_PROTOCOL protocol; /* NFA_EE_TRGR_RF_PROTOCOL: the protocol that
+                                 triggers this event */
+  tNFC_RF_TECH technology;    /* NFA_EE_TRGR_RF_TECHNOLOGY:the technology that
+                                 triggers this event */
+  tNFC_AID aid; /* NFA_EE_TRGR_SELECT      : the AID in the received SELECT AID
+                   command */
+  tNFC_APP_INIT app_init; /* NFA_EE_TRGR_APP_INIT:     The information for the
+                             application initiated trigger */
+} tNFA_EE_ACTION_PARAM;
+
+typedef struct {
+  tNFA_HANDLE ee_handle;   /* Handle of NFCEE                  */
+  tNFA_EE_TRIGGER trigger; /* the trigger of this event        */
+  tNFA_EE_ACTION_PARAM param;
+} tNFA_EE_ACTION;
+
+typedef struct {
+  tNFA_HANDLE ee_handle;    /* Handle of NFCEE              */
+  tNFA_STATUS status;       /* NFA_STATUS_OK is successful  */
+  tNFA_EE_STATUS ee_status; /* The NFCEE status             */
+} tNFA_EE_MODE_SET;
+
+#if (NXP_EXTNS == TRUE)
+typedef struct {
+  tNFA_STATUS status;
+  uint8_t nfcee_id;
+} tNFA_EE_SET_MODE_INFO;
+typedef struct {
+  tNFA_STATUS status;       /* NFA_STATUS_OK is successful  */
+  tNFA_EE_STATUS ee_status; /* The NFCEE status             */
+} tNFA_EE_PWR_LNK_CTRL;
+#endif
+typedef struct {
+  tNFA_HANDLE ee_handle;          /* Handle of MFCEE      */
+  tNFA_NFC_PROTOCOL la_protocol;  /* Listen A protocol    */
+  tNFA_NFC_PROTOCOL lb_protocol;  /* Listen B protocol    */
+  tNFA_NFC_PROTOCOL lf_protocol;  /* Listen F protocol    */
+  tNFA_NFC_PROTOCOL lbp_protocol; /* Listen B' protocol   */
+#if (NXP_EXTNS == TRUE)
+  tNFA_NFC_PROTOCOL pa_protocol; /* Passive poll A SWP Reader   */
+  tNFA_NFC_PROTOCOL pb_protocol; /* Passive poll B SWP Reader   */
+  uint8_t ee_req_op;             /* add or remove req ntf*/
+#endif
+} tNFA_EE_DISCOVER_INFO;
+
+/* Data for NFA_EE_DISCOVER_REQ_EVT */
+typedef struct {
+  uint8_t status; /* NFA_STATUS_OK if successful   */
+  uint8_t num_ee; /* number of MFCEE information   */
+  tNFA_EE_DISCOVER_INFO ee_disc_info[NFA_EE_MAX_EE_SUPPORTED -
+                                     1]; /* NFCEE DISCOVER Request info   */
+} tNFA_EE_DISCOVER_REQ;
+
+/* Data for NFA_EE_DATA_EVT */
+typedef struct {
+  tNFA_HANDLE handle; /* Connection handle */
+  uint16_t len;       /* Length of data    */
+  uint8_t* p_buf;     /* Data buffer       */
+} tNFA_EE_DATA;
+
+/* Union of all EE callback structures */
+typedef union {
+  tNFA_STATUS
+      status; /* NFA_STATUS_OK is successful; otherwise NFA_STATUS_FAILED */
+  tNFA_EE_DATA data;
+  tNFA_HANDLE handle;
+  tNFA_EE_DISCOVER ee_discover;
+  tNFA_STATUS ee_register;
+  tNFA_STATUS deregister;
+  tNFA_STATUS add_aid;
+  tNFA_STATUS remove_aid;
+  tNFA_STATUS set_tech;
+  tNFA_STATUS set_proto;
+  uint16_t size;
+  tNFA_EE_CONNECT connect;
+  tNFA_EE_ACTION action;
+  tNFA_EE_MODE_SET mode_set;
+#if (NXP_EXTNS == TRUE)
+  tNFA_EE_SET_MODE_INFO ee_set_mode_info;
+  tNFA_EE_PWR_LNK_CTRL pwr_lnk_ctrl;
+#endif
+  tNFA_EE_INFO new_ee;
+  tNFA_EE_DISCOVER_REQ discover_req;
+} tNFA_EE_CBACK_DATA;
+
+/* EE callback */
+typedef void(tNFA_EE_CBACK)(tNFA_EE_EVT event, tNFA_EE_CBACK_DATA* p_data);
+
+/*****************************************************************************
+**  External Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+**
+** Function         NFA_EeDiscover
+**
+** Description      This function retrieves the NFCEE information from NFCC.
+**                  The NFCEE information is reported in NFA_EE_DISCOVER_EVT.
+**
+**                  This function may be called when a system supports removable
+**                  NFCEEs,
+**
+** Returns          NFA_STATUS_OK if information is retrieved successfully
+**                  NFA_STATUS_FAILED If wrong state (retry later)
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_EeDiscover(tNFA_EE_CBACK* p_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_EeGetInfo
+**
+** Description      This function retrieves the NFCEE information from NFA.
+**                  The actual number of NFCEE is returned in p_num_nfcee
+**                  and NFCEE information is returned in p_info
+**
+** Returns          NFA_STATUS_OK if information is retrieved successfully
+**                  NFA_STATUS_FAILED If wrong state (retry later)
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_EeGetInfo(uint8_t* p_num_nfcee, tNFA_EE_INFO* p_info);
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         NFA_AllEeGetInfo
+**
+** Description      This function retrieves the All NFCEE's independent of
+**                  their status information from NFA.
+**                  The actual number of NFCEE is returned in p_num_nfcee
+**                  and NFCEE information is returned in p_info
+**
+** Returns          NFA_STATUS_OK if information is retrieved successfully
+**                  NFA_STATUS_FAILED If wrong state (retry later)
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_AllEeGetInfo(uint8_t* p_num_nfcee, tNFA_EE_INFO* p_info);
+#endif
+
+/*******************************************************************************
+**
+** Function         NFA_EeRegister
+**
+** Description      This function registers a callback function to receive the
+**                  events from NFA-EE module.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_EeRegister(tNFA_EE_CBACK* p_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_EeDeregister
+**
+** Description      This function de-registers the callback function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_EeDeregister(tNFA_EE_CBACK* p_cback);
+/*******************************************************************************
+**
+** Function         NFA_SendPowerLinkCommand
+**
+** Description      This function sends the power link control command
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_SendPowerLinkCommand(uint8_t nfcee_id, uint8_t cfg_value);
+/*******************************************************************************
+**
+** Function         NFA_EeModeSet
+**
+** Description      This function is called to activate
+**                  (mode = NFA_EE_MD_ACTIVATE) or deactivate
+**                  (mode = NFA_EE_MD_DEACTIVATE) the NFCEE identified by the
+**                  given ee_handle. The result of this operation is reported
+**                  with the NFA_EE_MODE_SET_EVT.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_EeModeSet(tNFA_HANDLE ee_handle, tNFA_EE_MD mode);
+
+/*******************************************************************************
+**
+** Function         NFA_EeSetDefaultTechRouting
+**
+** Description      This function is called to add, change or remove the
+**                  default routing based on RF technology in the listen mode
+**                  routing table for the given ee_handle. The status of this
+**                  operation is reported as the NFA_EE_SET_TECH_CFG_EVT.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Note:            NFA_EeUpdateNow() should be called after last NFA-EE
+**                  function to change the listen mode routing is called.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_EeSetDefaultTechRouting(
+    tNFA_HANDLE ee_handle, tNFA_TECHNOLOGY_MASK technologies_switch_on,
+    tNFA_TECHNOLOGY_MASK technologies_switch_off,
+    tNFA_TECHNOLOGY_MASK technologies_battery_off
+#if (NXP_EXTNS == TRUE)
+    ,
+    tNFA_TECHNOLOGY_MASK technologies_screen_lock,
+    tNFA_TECHNOLOGY_MASK technologies_screen_off,
+    tNFA_TECHNOLOGY_MASK technologies_screen_off_lock
+#endif
+
+    );
+
+/*******************************************************************************
+**
+** Function         NFA_EeSetDefaultProtoRouting
+**
+** Description      This function is called to add, change or remove the
+**                  default routing based on Protocol in the listen mode routing
+**                  table for the given ee_handle. The status of this
+**                  operation is reported as the NFA_EE_SET_PROTO_CFG_EVT.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Note:            NFA_EeUpdateNow() should be called after last NFA-EE
+**                  function to change the listen mode routing is called.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_EeSetDefaultProtoRouting(
+    tNFA_HANDLE ee_handle, tNFA_PROTOCOL_MASK protocols_switch_on,
+    tNFA_PROTOCOL_MASK protocols_switch_off,
+    tNFA_PROTOCOL_MASK protocols_battery_off
+#if (NXP_EXTNS == TRUE)
+    ,
+    tNFA_PROTOCOL_MASK protocols_screen_lock,
+    tNFA_PROTOCOL_MASK protocols_screen_off,
+    tNFA_PROTOCOL_MASK protocols_screen_off_lock
+#endif
+    );
+
+/*******************************************************************************
+**
+** Function         NFA_EeAddAidRouting
+**
+** Description      This function is called to add an AID entry in the
+**                  listen mode routing table in NFCC. The status of this
+**                  operation is reported as the NFA_EE_ADD_AID_EVT.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Note:            NFA_EeUpdateNow() should be called after last NFA-EE
+**                  function to change the listen mode routing is called.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_EeAddAidRouting(tNFA_HANDLE ee_handle, uint8_t aid_len,
+                                       uint8_t* p_aid,
+                                       tNFA_EE_PWR_STATE power_state
+#if (NXP_EXTNS == TRUE)
+                                       ,
+                                       uint8_t vs_info
+#endif
+                                       );
+
+/*******************************************************************************
+**
+** Function         NFA_EeRemoveAidRouting
+**
+** Description      This function is called to remove the given AID entry from
+**                  the listen mode routing table. If the entry configures VS,
+**                  it is also removed. The status of this operation is reported
+**                  as the NFA_EE_REMOVE_AID_EVT.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Note:            NFA_EeUpdateNow() should be called after last NFA-EE
+**                  function to change the listen mode routing is called.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_EeRemoveAidRouting(uint8_t aid_len, uint8_t* p_aid);
+
+/*******************************************************************************
+**
+** Function         NFA_EeAddApduPatternRouting
+**
+** Description      This function is called to add an APDU pattern entry in the
+**                  listen mode routing table in NFCC. The status of this
+**                  operation is reported as the NFA_EE_ADD_APDU_EVT.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Note:            NFA_EeUpdateNow() should be called after last NFA-EE
+**                  function to change the listen mode routing is called.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_EeAddApduPatternRouting(uint8_t apdu_data_len,uint8_t* apdu_data, uint8_t apdu_mask_len,
+  uint8_t* apdu_mask, tNFA_HANDLE ee_handle, uint8_t power_state);
+
+/*******************************************************************************
+**
+** Function         NFA_EeRemoveApduPatternRouting
+**
+** Description      This function is called to remove the given APDU pattern entry from
+**                  the listen mode routing table. If the entry configures VS,
+**                  it is also removed. The status of this operation is reported
+**                  as the NFA_EE_REMOVE_APDU_EVT.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Note:            NFA_EeUpdateNow() should be called after last NFA-EE
+**                  function to change the listen mode routing is called.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_EeRemoveApduPatternRouting(uint8_t apdu_len, uint8_t* p_apdu);
+
+/*******************************************************************************
+**
+** Function         NFA_EeGetLmrtRemainingSize
+**
+** Description      This function is called to get remaining size of the
+**                  Listen Mode Routing Table.
+**                  The remaining size is reported in NFA_EE_REMAINING_SIZE_EVT
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_EeGetLmrtRemainingSize(void);
+
+/*******************************************************************************
+**
+** Function         NFA_EeUpdateNow
+**
+** Description      This function is called to send the current listen mode
+**                  routing table and VS configuration to the NFCC (without
+**                  waiting for NFA_EE_ROUT_TIMEOUT_VAL).
+**
+**                  The status of this operation is
+**                  reported with the NFA_EE_UPDATED_EVT.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_SEMANTIC_ERROR is update is currently in progress
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_EeUpdateNow(void);
+
+/*******************************************************************************
+**
+** Function         NFA_EeConnect
+**
+** Description      Open connection to an NFCEE attached to the NFCC
+**
+**                  The status of this operation is
+**                  reported with the NFA_EE_CONNECT_EVT.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_EeConnect(tNFA_HANDLE ee_handle, uint8_t ee_interface,
+                                 tNFA_EE_CBACK* p_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_EeSendData
+**
+** Description      Send data to the given NFCEE.
+**                  This function shall be called after NFA_EE_CONNECT_EVT is
+**                  reported and before NFA_EeDisconnect is called on the given
+**                  ee_handle.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_EeSendData(tNFA_HANDLE ee_handle, uint16_t data_len,
+                                  uint8_t* p_data);
+
+/*******************************************************************************
+**
+** Function         NFA_EeDisconnect
+**
+** Description      Disconnect (if a connection is currently open) from an
+**                  NFCEE interface. The result of this operation is reported
+**                  with the NFA_EE_DISCONNECT_EVT.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_EeDisconnect(tNFA_HANDLE ee_handle);
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         NFA_AddEePowerState
+**
+** Description      This function is called to add power state in the
+**                  listen mode routing table in NFCC.
+**
+** Note:            If RF discovery is started,
+*NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Note:            NFA_EeUpdateNow() should be called after last NFA-EE
+*function
+**                  to change the listen mode routing is called.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_AddEePowerState(tNFA_HANDLE ee_handle,
+                                       tNFA_EE_PWR_STATE power_state_mask);
+
+/*******************************************************************************
+**
+** Function         NFA_GetAidTableSize
+**
+** Description      This function is called to get the AID routing table size.
+**
+** Returns          Maximum AID routing table size.
+**
+*******************************************************************************/
+extern uint16_t NFA_GetAidTableSize();
+
+/*******************************************************************************
+**
+** Function         NFA_GetRemainingAidTableSize
+**
+** Description      This function is called to get the remaining AID routing
+**                  table size.
+**
+** Returns          Remaining AID routing table size.
+**
+*******************************************************************************/
+extern uint16_t NFA_GetRemainingAidTableSize();
+
+/*******************************************************************************
+**
+** Function         NFA_SetCEStrictDisable
+**
+** Description      This function is called to set the flag for Strict CE.
+**
+** Returns          None.
+**
+*******************************************************************************/
+extern void NFA_SetCEStrictDisable(uint32_t state);
+
+/*******************************************************************************
+**
+** Function         NFA_setProvisionMode
+**
+** Description      This function is called to set/reset the provision mode
+*info.
+**
+** Returns          None.
+**
+*******************************************************************************/
+extern void NFA_setProvisionMode(bool provisionMode);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFA_EE_API_H */
diff --git a/src/nfa/include/nfa_hci_api.h b/src/nfa/include/nfa_hci_api.h
new file mode 100644
index 0000000..c7ec22b
--- /dev/null
+++ b/src/nfa/include/nfa_hci_api.h
@@ -0,0 +1,742 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the public interface file for NFA HCI, Broadcom's NFC
+ *  application layer for mobile phones.
+ *
+ ******************************************************************************/
+#ifndef NFA_HCI_API_H
+#define NFA_HCI_API_H
+
+#include "nfa_api.h"
+#if (NXP_EXTNS == TRUE)
+#include "nfa_ee_api.h"
+#endif
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+/* NFA HCI Debug constants */
+#define NFA_HCI_DEBUG_DISPLAY_CB 0
+#define NFA_HCI_DEBUG_SIM_HCI_EVENT 1
+#define NFA_HCI_DEBUG_ENABLE_LOOPBACK 101
+#define NFA_HCI_DEBUG_DISABLE_LOOPBACK 102
+
+/* NFA HCI callback events */
+#define NFA_HCI_REGISTER_EVT \
+  0x00 /* Application registered                       */
+/* Application deregistered                     */
+#define NFA_HCI_DEREGISTER_EVT 0x01
+/* Retrieved gates,pipes assoc. to application  */
+#define NFA_HCI_GET_GATE_PIPE_LIST_EVT 0x02
+/* A generic gate allocated to the application  */
+#define NFA_HCI_ALLOCATE_GATE_EVT 0x03
+#define NFA_HCI_DEALLOCATE_GATE_EVT \
+  0x04 /* A generic gate is released                   */
+#define NFA_HCI_CREATE_PIPE_EVT \
+  0x05 /* Pipe is created                              */
+#define NFA_HCI_OPEN_PIPE_EVT \
+  0x06 /* Pipe is opened / could not open              */
+#define NFA_HCI_CLOSE_PIPE_EVT \
+  0x07 /* Pipe is closed / could not close             */
+#define NFA_HCI_DELETE_PIPE_EVT \
+  0x08 /* Pipe is deleted                              */
+#define NFA_HCI_HOST_LIST_EVT \
+  0x09 /* Received list of Host from Host controller   */
+/* HCI subsytem initialized                     */
+#define NFA_HCI_INIT_EVT 0x0A
+/* HCI subsytem exited                          */
+#define NFA_HCI_EXIT_EVT 0x0B
+/* Response recvd to cmd sent on app owned pipe */
+#define NFA_HCI_RSP_RCVD_EVT 0x0C
+/* Response sent on app owned pipe              */
+#define NFA_HCI_RSP_SENT_EVT 0x0D
+/* Command sent on app owned pipe               */
+#define NFA_HCI_CMD_SENT_EVT 0x0E
+/* Event sent on app owned pipe                 */
+#define NFA_HCI_EVENT_SENT_EVT 0x0F
+/* Command received on app owned pipe           */
+#define NFA_HCI_CMD_RCVD_EVT 0x10
+/* Event received on app owned pipe             */
+#define NFA_HCI_EVENT_RCVD_EVT 0x11
+/* Registry read command sent                   */
+#define NFA_HCI_GET_REG_CMD_EVT 0x12
+/* Registry write command sent                  */
+#define NFA_HCI_SET_REG_CMD_EVT 0x13
+/* Received response to read registry command   */
+#define NFA_HCI_GET_REG_RSP_EVT 0x14
+/* Received response to write registry command  */
+#define NFA_HCI_SET_REG_RSP_EVT 0x15
+/* A static pipe is added                       */
+#define NFA_HCI_ADD_STATIC_PIPE_EVT 0x16
+#if (NXP_EXTNS == TRUE)
+/**Event to read host type list*/
+#define NFA_HCI_HOST_TYPE_LIST_READ_EVT 0x17
+#define NFA_HCI_CONFIG_DONE_EVT \
+  0x18 /* Configure NFCEE                              */
+#endif
+typedef uint8_t tNFA_HCI_EVT;
+
+/* Max application name length */
+#define NFA_MAX_HCI_APP_NAME_LEN 0x10
+/* Max HCI command length */
+#define NFA_MAX_HCI_CMD_LEN 255
+/* Max HCI event length */
+#define NFA_MAX_HCI_RSP_LEN 255
+#if (NXP_EXTNS == TRUE)
+/*
+ * increased the the buffer size, since as per HCI specification connectivity
+ * event may
+ * take up 271 bytes. (MAX AID length:16, MAX PARAMETERS length:255)
+ * */
+/* Max HCI event length */
+#define NFA_MAX_HCI_EVENT_LEN 300
+#else
+/* Max HCI event length */
+#define NFA_MAX_HCI_EVENT_LEN 260
+#endif
+/* Max HCI data length */
+#define NFA_MAX_HCI_DATA_LEN 260
+
+/* NFA HCI PIPE states */
+#define NFA_HCI_PIPE_CLOSED 0x00 /* Pipe is closed */
+#define NFA_HCI_PIPE_OPENED 0x01 /* Pipe is opened */
+
+typedef uint8_t tNFA_HCI_PIPE_STATE;
+/* Dynamic pipe control block */
+typedef struct {
+  uint8_t pipe_id;                /* Pipe ID */
+  tNFA_HCI_PIPE_STATE pipe_state; /* State of the Pipe */
+  uint8_t local_gate;             /* local gate id */
+  uint8_t dest_host; /* Peer host to which this pipe is connected */
+  uint8_t dest_gate; /* Peer gate to which this pipe is connected */
+} tNFA_HCI_PIPE_INFO;
+
+/* Data for NFA_HCI_REGISTER_EVT */
+typedef struct {
+  tNFA_STATUS status;     /* Status of registration */
+  tNFA_HANDLE hci_handle; /* Handle assigned to the application */
+  uint8_t num_pipes; /* Number of dynamic pipes exist for the application */
+  uint8_t num_gates; /* Number of generic gates exist for the application */
+} tNFA_HCI_REGISTER;
+
+/* Data for NFA_HCI_DEREGISTER_EVT */
+typedef struct {
+  tNFA_STATUS status; /* Status of deregistration */
+} tNFA_HCI_DEREGISTER;
+
+/* Data for NFA_HCI_GET_GATE_PIPE_LIST_EVT */
+typedef struct {
+  tNFA_STATUS status;
+  uint8_t num_pipes; /* Number of dynamic pipes exist for the application */
+  tNFA_HCI_PIPE_INFO
+      pipe[NFA_HCI_MAX_PIPE_CB]; /* List of pipe created for the application */
+  uint8_t num_gates; /* Number of generic gates exist for the application */
+  uint8_t gate[NFA_HCI_MAX_GATE_CB]; /* List of generic gates allocated to the
+                                        application */
+  uint8_t num_uicc_created_pipes;    /* Number of pipes created by UICC host */
+  tNFA_HCI_PIPE_INFO uicc_created_pipe
+      [NFA_HCI_MAX_PIPE_CB]; /* Pipe information of the UICC created pipe */
+} tNFA_HCI_GET_GATE_PIPE_LIST;
+
+/* Data for NFA_HCI_ALLOCATE_GATE_EVT */
+typedef struct {
+  tNFA_STATUS status; /* Status of response to allocate gate request */
+  uint8_t gate;       /* The gate allocated to the application */
+} tNFA_HCI_ALLOCATE_GATE;
+
+/* Data for NFA_HCI_DEALLOCATE_GATE_EVT */
+typedef struct {
+  tNFA_STATUS status; /* Status of response to deallocate gate request */
+  uint8_t gate;       /* The gate deallocated from the application */
+} tNFA_HCI_DEALLOCATE_GATE;
+
+/* Data for NFA_HCI_CREATE_PIPE_EVT */
+typedef struct {
+  tNFA_STATUS status; /* Status of creating dynamic pipe for the application */
+  uint8_t pipe;       /* The pipe created for the application */
+  uint8_t
+      source_gate; /* DH host gate to which the one end of pipe is attached */
+  uint8_t
+      dest_host; /* Destination host whose gate is the other end of the pipe is
+                    attached to */
+  uint8_t dest_gate; /* Destination host gate to which the other end of pipe is
+                        attached */
+} tNFA_HCI_CREATE_PIPE;
+
+/* Data for NFA_HCI_OPEN_PIPE_EVT */
+typedef struct {
+  tNFA_STATUS status; /* Status of open pipe operation */
+  uint8_t pipe;       /* The dynamic pipe for open operation */
+} tNFA_HCI_OPEN_PIPE;
+
+/* Data for NFA_HCI_CLOSE_PIPE_EVT */
+typedef struct {
+  tNFA_STATUS status; /* Status of close pipe operation */
+  uint8_t pipe;       /* The dynamic pipe for close operation */
+} tNFA_HCI_CLOSE_PIPE;
+
+/* Data for NFA_HCI_DELETE_PIPE_EVT */
+typedef struct {
+  tNFA_STATUS status; /* Status of delete pipe operation */
+  uint8_t pipe;       /* The dynamic pipe for delete operation */
+#if (NXP_EXTNS == TRUE)
+  uint8_t host; /* The host Id for delete pipe operation */
+#endif
+} tNFA_HCI_DELETE_PIPE;
+
+/* Data for NFA_HCI_HOST_LIST_EVT */
+typedef struct {
+  tNFA_STATUS status; /* Status og get host list operation */
+  uint8_t num_hosts;  /* Number of hosts in the host network */
+  uint8_t
+      host[NFA_HCI_MAX_HOST_IN_NETWORK]; /* List of host in the host network */
+} tNFA_HCI_HOST_LIST;
+
+/* Data for NFA_HCI_RSP_RCVD_EVT */
+typedef struct {
+  tNFA_STATUS status; /* Status of RSP to HCP CMD sent */
+  uint8_t pipe;       /* The pipe on which HCP packet is exchanged */
+  uint8_t rsp_code;   /* Response id */
+  uint16_t rsp_len;   /* Response parameter length */
+  uint8_t rsp_data[NFA_MAX_HCI_RSP_LEN]; /* Response received */
+} tNFA_HCI_RSP_RCVD;
+
+/* Data for NFA_HCI_EVENT_RCVD_EVT */
+typedef struct {
+  tNFA_STATUS status; /* Status of Event received */
+  uint8_t pipe;       /* The pipe on which HCP EVT packet is received */
+  uint8_t evt_code;   /* HCP EVT id */
+  uint16_t evt_len;   /* HCP EVT parameter length */
+  uint8_t* p_evt_buf; /* HCP EVT Parameter */
+#if (NXP_EXTNS == TRUE)
+  uint8_t last_SentEvtType;
+#endif
+} tNFA_HCI_EVENT_RCVD;
+
+/* Data for NFA_HCI_CMD_RCVD_EVT */
+typedef struct {
+  tNFA_STATUS status; /* Status of Command received */
+  uint8_t pipe;       /* The pipe on which HCP CMD packet is received */
+  uint8_t cmd_code;   /* HCP CMD id */
+  uint16_t cmd_len;   /* HCP CMD parameter length */
+  uint8_t cmd_data[NFA_MAX_HCI_CMD_LEN]; /* HCP CMD Parameter */
+} tNFA_HCI_CMD_RCVD;
+
+/* Data for NFA_HCI_INIT_EVT */
+typedef struct {
+  tNFA_STATUS status; /* Status of Enabling HCI Network */
+} tNFA_HCI_INIT;
+
+/* Data for NFA_HCI_EXIT_EVT */
+typedef struct {
+  tNFA_STATUS status; /* Status of Disabling HCI Network */
+} tNFA_HCI_EXIT;
+
+/* Data for NFA_HCI_RSP_SENT_EVT */
+typedef struct {
+  tNFA_STATUS status; /* Status of HCP response send operation */
+} tNFA_HCI_RSP_SENT;
+
+/* Data for NFA_HCI_CMD_SENT_EVT */
+typedef struct {
+  tNFA_STATUS status; /* Status of Command send operation */
+} tNFA_HCI_CMD_SENT;
+
+/* Data for NFA_HCI_EVENT_SENT_EVT */
+typedef struct {
+  tNFA_STATUS status; /* Status of Event send operation */
+#if (NXP_EXTNS == TRUE)
+  uint8_t evt_type;
+#endif
+} tNFA_HCI_EVENT_SENT;
+
+/* Data for NFA_HCI_ADD_STATIC_PIPE_EVT */
+typedef struct {
+  tNFA_STATUS status; /* Status of adding proprietary pipe */
+} tNFA_HCI_ADD_STATIC_PIPE_EVT;
+
+/* data type for all registry-related events */
+typedef struct {
+  tNFA_STATUS status; /* Status of Registry operation */
+  uint8_t pipe;       /* Pipe on whose registry is of interest */
+  uint8_t index;      /* Index of the registry operated */
+  uint8_t data_len;   /* length of the registry parameter */
+  uint8_t reg_data[NFA_MAX_HCI_DATA_LEN]; /* Registry parameter */
+} tNFA_HCI_REGISTRY;
+#if (NXP_EXTNS == TRUE)
+/* Data for tNFA_HCI_ADMIN_RSP_RCVD */
+typedef struct {
+  tNFA_STATUS status;     /* Status of command on Admin pipe */
+  uint8_t NoHostsPresent; /* No of Hosts compliant to ETSI 12 */
+  uint8_t HostIds[5];     /* Host Ids compliant to ETSI 12 */
+} tNFA_HCI_ADMIN_RSP_RCVD;
+/* Data for tNFA_HCI_CONFIG_RSP_RCVD */
+typedef struct {
+  tNFA_STATUS status; /* Status for ETSI12 config for NFCEE*/
+} tNFA_HCI_CONFIG_RSP_RCVD;
+#endif
+/* Union of all hci callback structures */
+typedef union {
+  tNFA_HCI_REGISTER hci_register;          /* NFA_HCI_REGISTER_EVT           */
+  tNFA_HCI_DEREGISTER hci_deregister;      /* NFA_HCI_DEREGISTER_EVT         */
+  tNFA_HCI_GET_GATE_PIPE_LIST gates_pipes; /* NFA_HCI_GET_GATE_PIPE_LIST_EVT */
+  tNFA_HCI_ALLOCATE_GATE allocated;        /* NFA_HCI_ALLOCATE_GATE_EVT      */
+  tNFA_HCI_DEALLOCATE_GATE deallocated;    /* NFA_HCI_DEALLOCATE_GATE_EVT    */
+  tNFA_HCI_CREATE_PIPE created;            /* NFA_HCI_CREATE_PIPE_EVT        */
+  tNFA_HCI_OPEN_PIPE opened;               /* NFA_HCI_OPEN_PIPE_EVT          */
+  tNFA_HCI_CLOSE_PIPE closed;              /* NFA_HCI_CLOSE_PIPE_EVT         */
+  tNFA_HCI_DELETE_PIPE deleted;            /* NFA_HCI_DELETE_PIPE_EVT        */
+  tNFA_HCI_HOST_LIST hosts;                /* NFA_HCI_HOST_LIST_EVT          */
+  tNFA_HCI_RSP_RCVD rsp_rcvd;              /* NFA_HCI_RSP_RCVD_EVT           */
+  tNFA_HCI_RSP_SENT rsp_sent;              /* NFA_HCI_RSP_SENT_EVT           */
+  tNFA_HCI_CMD_SENT cmd_sent;              /* NFA_HCI_CMD_SENT_EVT           */
+  tNFA_HCI_EVENT_SENT evt_sent;            /* NFA_HCI_EVENT_SENT_EVT         */
+  tNFA_HCI_CMD_RCVD cmd_rcvd;              /* NFA_HCI_CMD_RCVD_EVT           */
+  tNFA_HCI_EVENT_RCVD rcvd_evt;            /* NFA_HCI_EVENT_RCVD_EVT         */
+  tNFA_STATUS status;                      /* status of api command request  */
+  tNFA_HCI_REGISTRY registry;              /* all registry-related events -
+                                              NFA_HCI_GET_REG_CMD_EVT,
+                                              NFA_HCI_SET_REG_CMD_EVT,
+                                              NFA_HCI_GET_REG_RSP_EVT,
+                                              NFA_HCI_SET_REG_RSP_EVT */
+  tNFA_HCI_INIT hci_init;                  /* NFA_HCI_INIT_EVT               */
+  tNFA_HCI_EXIT hci_exit;                  /* NFA_HCI_EXIT_EVT               */
+  tNFA_HCI_ADD_STATIC_PIPE_EVT pipe_added; /* NFA_HCI_ADD_STATIC_PIPE_EVT    */
+#if (NXP_EXTNS == TRUE)
+  tNFA_HCI_ADMIN_RSP_RCVD admin_rsp_rcvd;   /* NFA_HCI_ADMIN_RSP_RCVD         */
+  tNFA_HCI_CONFIG_RSP_RCVD config_rsp_rcvd; /* NFA_HCI_CONFIG_RSP_RCVD       */
+#endif
+} tNFA_HCI_EVT_DATA;
+
+#if (NXP_EXTNS == TRUE)
+typedef enum { Wait = 0, Release } tNFA_HCI_TRANSCV_STATE;
+#endif
+
+/* NFA HCI callback */
+typedef void(tNFA_HCI_CBACK)(tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA* p_data);
+
+/*****************************************************************************
+**  External Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+**
+** Function         NFA_HciRegister
+**
+** Description      This function will register an application with hci and
+**                  returns an application handle and provides a mechanism to
+**                  register a callback with HCI to receive NFA HCI event
+**                  notification. When the application is registered (or if an
+**                  error occurs), the app will be notified with
+**                  NFA_HCI_REGISTER_EVT. Previous session information
+**                  including allocated gates, created pipes and pipes states
+**                  will be returned as part of tNFA_HCI_REGISTER data.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_HciRegister(char* p_app_name, tNFA_HCI_CBACK* p_cback,
+                                   bool b_send_conn_evts);
+
+/*******************************************************************************
+**
+** Function         NFA_HciGetGateAndPipeList
+**
+** Description      This function will retrieve the list of gates allocated to
+**                  the application and list of dynamic pipes created for the
+**                  application. The app will be notified with
+**                  NFA_HCI_GET_GATE_PIPE_LIST_EVT. List of allocated dynamic
+**                  gates to the application and list of pipes created by the
+**                  application will be returned as part of
+**                  tNFA_HCI_GET_GATE_PIPE_LIST data.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_HciGetGateAndPipeList(tNFA_HANDLE hci_handle);
+
+/*******************************************************************************
+**
+** Function         NFA_HciDeregister
+**
+** Description      This function is called to deregister an application
+**                  from HCI. The app will be notified by NFA_HCI_DEREGISTER_EVT
+**                  after deleting all the pipes owned by the app and
+**                  deallocating all the gates allocated to the app or if an
+**                  error occurs. The app can release the buffer provided for
+**                  collecting long APDUs after receiving
+**                  NFA_HCI_DEREGISTER_EVT. Even if deregistration fails, the
+**                  app has to register again to provide a new cback function
+**                  and event buffer for receiving long APDUs.
+**
+** Returns          NFA_STATUS_OK if the application is deregistered
+**                  successfully
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_HciDeregister(char* p_app_name);
+
+/*******************************************************************************
+**
+** Function         NFA_HciAllocGate
+**
+** Description      This function will allocate the gate if any specified or an
+**                  available generic gate for the app to provide an entry point
+**                  for a particular service to other host or to establish
+**                  communication with other host. When the gate is
+**                  allocated (or if an error occurs), the app will be notified
+**                  with NFA_HCI_ALLOCATE_GATE_EVT with the gate id. The
+**                  allocated Gate information will be stored in non volatile
+**                  memory.
+**
+** Returns          NFA_STATUS_OK if this API started
+**                  NFA_STATUS_FAILED if no generic gate is available
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_HciAllocGate(tNFA_HANDLE hci_handle, uint8_t gate);
+
+/*******************************************************************************
+**
+** Function         NFA_HciDeallocGate
+**
+** Description      This function will release the specified gate that was
+**                  previously allocated to the application. When the generic
+**                  gate is released (or if an error occurs), the app will be
+**                  notified with NFA_HCI_DEALLOCATE_GATE_EVT with the gate id.
+**                  The allocated Gate information will be deleted from non
+**                  volatile memory and all the associated pipes are deleted
+**                  by informing host controller.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_HciDeallocGate(tNFA_HANDLE conn_handle, uint8_t gate);
+
+/*******************************************************************************
+**
+** Function         NFA_HciGetHostList
+**
+** Description      This function will request the host controller to return the
+**                  list of hosts that are present in the host network. When
+**                  host controller responds with the host list (or if an error
+**                  occurs), the app will be notified with NFA_HCI_HOST_LIST_EVT
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_HciGetHostList(tNFA_HANDLE hci_handle);
+
+/*******************************************************************************
+**
+** Function         NFA_HciCreatePipe
+**
+** Description      This function is called to create a dynamic pipe with the
+**                  specified host. When the dynamic pipe is created (or
+**                  if an error occurs), the app will be notified with
+**                  NFA_HCI_CREATE_PIPE_EVT with the pipe id. If a pipe exists
+**                  between the two gates passed as argument and if it was
+**                  created earlier by the calling application then the pipe
+**                  id of the existing pipe will be returned and a new pipe
+**                  will not be created. After successful creation of pipe,
+**                  registry entry will be created for the dynamic pipe and
+**                  all information related to the pipe will be stored in non
+**                  volatile memory.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_HciCreatePipe(tNFA_HANDLE hci_handle,
+                                     uint8_t source_gate_id, uint8_t dest_host,
+                                     uint8_t dest_gate);
+
+/*******************************************************************************
+**
+** Function         NFA_HciOpenPipe
+**
+** Description      This function is called to open a dynamic pipe.
+**                  When the dynamic pipe is opened (or
+**                  if an error occurs), the app will be notified with
+**                  NFA_HCI_OPEN_PIPE_EVT with the pipe id.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_HciOpenPipe(tNFA_HANDLE hci_handle, uint8_t pipe);
+
+/*******************************************************************************
+**
+** Function         NFA_HciGetRegistry
+**
+** Description      This function requests a peer host to return the desired
+**                  registry field value for the gate that the pipe is on.
+**
+**                  When the peer host responds,the app is notified with
+**                  NFA_HCI_GET_REG_RSP_EVT or
+**                  if an error occurs in sending the command the app will be
+**                  notified by NFA_HCI_CMD_SENT_EVT
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_HciGetRegistry(tNFA_HANDLE hci_handle, uint8_t pipe,
+                                      uint8_t reg_inx);
+
+/*******************************************************************************
+**
+** Function         NFA_HciSetRegistry
+**
+** Description      This function requests a peer host to set the desired
+**                  registry field value for the gate that the pipe is on.
+**
+**                  When the peer host responds,the app is notified with
+**                  NFA_HCI_SET_REG_RSP_EVT or
+**                  if an error occurs in sending the command the app will be
+**                  notified by NFA_HCI_CMD_SENT_EVT
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_HciSetRegistry(tNFA_HANDLE hci_handle, uint8_t pipe,
+                                      uint8_t reg_inx, uint8_t data_size,
+                                      uint8_t* p_data);
+
+/*******************************************************************************
+**
+** Function         NFA_HciSendCommand
+**
+** Description      This function is called to send a command on a pipe created
+**                  by the application.
+**                  The app will be notified by NFA_HCI_CMD_SENT_EVT if an error
+**                  occurs.
+**                  When the peer host responds,the app is notified with
+**                  NFA_HCI_RSP_RCVD_EVT
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_HciSendCommand(tNFA_HANDLE hci_handle, uint8_t pipe,
+                                      uint8_t cmd_code, uint16_t cmd_size,
+                                      uint8_t* p_data);
+
+/*******************************************************************************
+**
+** Function         NFA_HciSendResponse
+**
+** Description      This function is called to send a response on a pipe created
+**                  by the application.
+**                  The app will be notified by NFA_HCI_RSP_SENT_EVT if an error
+**                  occurs.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_HciSendResponse(tNFA_HANDLE hci_handle, uint8_t pipe,
+                                       uint8_t response, uint8_t data_size,
+                                       uint8_t* p_data);
+
+/*******************************************************************************
+**
+** Function         NFA_HciSendEvent
+**
+** Description      This function is called to send any event on a pipe created
+**                  by the application.
+**                  The app will be notified by NFA_HCI_EVENT_SENT_EVT
+**                  after successfully sending the event on the specified pipe
+**                  or if an error occurs. The application should wait for this
+**                  event before releasing event buffer passed as argument.
+**                  If the app is expecting a response to the event then it can
+**                  provide response buffer for collecting the response. If it
+**                  provides a response buffer it should also provide response
+**                  timeout indicating duration validity of the response buffer.
+**                  Maximum of NFA_MAX_HCI_EVENT_LEN bytes APDU can be received
+**                  using internal buffer if no response buffer is provided by
+**                  the application. The app will be notified by
+**                  NFA_HCI_EVENT_RCVD_EVT after receiving the response event
+**                  or on timeout if app provided response buffer.
+**                  If response buffer is provided by the application, it should
+**                  wait for this event before releasing the response buffer.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciSendEvent(tNFA_HANDLE hci_handle, uint8_t pipe,
+                             uint8_t evt_code, uint16_t evt_size,
+                             uint8_t* p_data, uint16_t rsp_size,
+                             uint8_t* p_rsp_buf,
+#if (NXP_EXTNS == TRUE)
+                             uint32_t rsp_timeout);
+#else
+                             uint16_t rsp_timeout);
+#endif
+
+/*******************************************************************************
+**
+** Function         NFA_HciClosePipe
+**
+** Description      This function is called to close a dynamic pipe.
+**                  When the dynamic pipe is closed (or
+**                  if an error occurs), the app will be notified with
+**                  NFA_HCI_CLOSE_PIPE_EVT with the pipe id.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_HciClosePipe(tNFA_HANDLE hci_handle, uint8_t pipe);
+
+/*******************************************************************************
+**
+** Function         NFA_HciDeletePipe
+**
+** Description      This function is called to delete a particular dynamic pipe.
+**                  When the dynamic pipe is deleted (or if an error occurs),
+**                  the app will be notified with NFA_HCI_DELETE_PIPE_EVT with
+**                  the pipe id. After successful deletion of pipe, registry
+**                  entry will be deleted for the dynamic pipe and all
+**                  information related to the pipe will be deleted from non
+**                  volatile memory.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_HciDeletePipe(tNFA_HANDLE hci_handle, uint8_t pipe);
+
+/*******************************************************************************
+**
+** Function         NFA_HciAddStaticPipe
+**
+** Description      This function is called to add a static pipe for sending
+**                  7816 APDUs. When the static pipe is added (or if an error
+**                  occurs), the app will be notified with
+**                  NFA_HCI_ADD_STATIC_PIPE_EVT with status.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_HciAddStaticPipe(tNFA_HANDLE hci_handle, uint8_t host,
+                                        uint8_t gate, uint8_t pipe);
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         NFA_MW_Fwdnlwd_Recovery
+**
+** Description      This function is called to make the MW_RCVRY_FW_DNLD_ALLOWED
+*true
+**                  not allowing the FW download while MW recovery.
+**
+*******************************************************************************/
+extern bool NFA_MW_Fwdnlwd_Recovery(bool mw_fwdnld_recovery);
+#endif
+/*******************************************************************************
+**
+** Function         NFA_HciDebug
+**
+** Description      Debug function.
+**
+*******************************************************************************/
+void NFA_HciDebug(uint8_t action, uint8_t size, uint8_t* p_data);
+#if (NXP_EXTNS == TRUE)
+extern tNFA_STATUS NFA_HciSendHostTypeListCommand(tNFA_HANDLE hci_handle);
+extern tNFA_STATUS NFA_HciConfigureNfceeETSI12();
+#endif
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         NFA_HciW4eSETransaction_Complete
+**
+** Description      This function is called to wait for eSE transaction
+**                  to complete before NFCC shutdown or NFC service turn OFF
+**
+** Returns          None
+**
+*******************************************************************************/
+extern void NFA_HciW4eSETransaction_Complete(tNFA_HCI_TRANSCV_STATE type);
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_nfcee_config_evt
+**
+** Description      This function handles clear all pipe and NFCEE config.
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+extern void nfa_hci_handle_nfcee_config_evt(uint16_t event);
+
+/*******************************************************************************
+**
+** Function         nfa_hci_clear_all_pipe_ntf_cb
+**
+** Description      Function to handle  cmd rsp of clear all pipe
+**
+** Returns          None
+**
+*******************************************************************************/
+extern void nfa_hci_nfcee_config_rsp_handler(tNFA_HCI_EVT event,
+                                             tNFA_HCI_EVT_DATA* p_evt);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFA_P2P_API_H */
diff --git a/src/nfa/include/nfa_hci_defs.h b/src/nfa/include/nfa_hci_defs.h
new file mode 100644
index 0000000..c245023
--- /dev/null
+++ b/src/nfa/include/nfa_hci_defs.h
@@ -0,0 +1,168 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  This file contains the NFA HCI related definitions from the
+ *  specification.
+ *
+ ******************************************************************************/
+
+#ifndef NFA_HCI_DEFS_H
+#define NFA_HCI_DEFS_H
+
+/* Static gates */
+#define NFA_HCI_LOOP_BACK_GATE 0x04
+#define NFA_HCI_IDENTITY_MANAGEMENT_GATE 0x05
+#if (NXP_EXTNS == TRUE)
+#define NFC_HCI_DEFAULT_DEST_GATE 0XF0
+#endif
+
+#define NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE 0x10
+#define NFA_HCI_LAST_HOST_SPECIFIC_GENERIC_GATE 0xEF
+#define NFA_HCI_FIRST_PROP_GATE 0xF0
+#define NFA_HCI_LAST_PROP_GATE 0xFF
+
+/* Generic Gates */
+#define NFA_HCI_CONNECTIVITY_GATE 0x41
+#if (NXP_EXTNS == TRUE)
+#define NFA_HCI_ETSI12_APDU_GATE 0x30
+#endif
+/* Proprietary Gates */
+#define NFA_HCI_PROP_GATE_MIN 0xF0
+#define NFA_HCI_PROP_GATE_MAX 0xFF
+
+/* Static pipes */
+#define NFA_HCI_LINK_MANAGEMENT_PIPE 0x00
+#define NFA_HCI_ADMIN_PIPE 0x01
+
+/* Dynamic pipe range */
+#define NFA_HCI_FIRST_DYNAMIC_PIPE 0x02
+#define NFA_HCI_LAST_DYNAMIC_PIPE 0x6F
+
+/* host_table */
+#define NFA_HCI_HOST_CONTROLLER 0x00
+#define NFA_HCI_DH_HOST 0x01
+#define NFA_HCI_UICC_HOST 0x02
+
+/* Type of instruction */
+#define NFA_HCI_COMMAND_TYPE 0x00
+#define NFA_HCI_EVENT_TYPE 0x01
+#define NFA_HCI_RESPONSE_TYPE 0x02
+
+/* Chaining bit value */
+#define NFA_HCI_MESSAGE_FRAGMENTATION 0x00
+#define NFA_HCI_NO_MESSAGE_FRAGMENTATION 0x01
+
+/* NFA HCI commands */
+
+/* Commands for all gates */
+#define NFA_HCI_ANY_SET_PARAMETER 0x01
+#define NFA_HCI_ANY_GET_PARAMETER 0x02
+#define NFA_HCI_ANY_OPEN_PIPE 0x03
+#define NFA_HCI_ANY_CLOSE_PIPE 0x04
+
+/* Admin gate commands */
+#define NFA_HCI_ADM_CREATE_PIPE 0x10
+#define NFA_HCI_ADM_DELETE_PIPE 0x11
+#define NFA_HCI_ADM_NOTIFY_PIPE_CREATED 0x12
+#define NFA_HCI_ADM_NOTIFY_PIPE_DELETED 0x13
+#define NFA_HCI_ADM_CLEAR_ALL_PIPE 0x14
+#define NFA_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED 0x15
+
+/* Connectivity gate command */
+#define NFA_HCI_CON_PRO_HOST_REQUEST 0x10
+
+/* NFA HCI responses */
+#define NFA_HCI_ANY_OK 0x00
+#define NFA_HCI_ANY_E_NOT_CONNECTED 0x01
+#define NFA_HCI_ANY_E_CMD_PAR_UNKNOWN 0x02
+#define NFA_HCI_ANY_E_NOK 0x03
+#define NFA_HCI_ADM_E_NO_PIPES_AVAILABLE 0x04
+#define NFA_HCI_ANY_E_REG_PAR_UNKNOWN 0x05
+#define NFA_HCI_ANY_E_PIPE_NOT_OPENED 0x06
+#define NFA_HCI_ANY_E_CMD_NOT_SUPPORTED 0x07
+#define NFA_HCI_ANY_E_INHIBITED 0x08
+#define NFA_HCI_ANY_E_TIMEOUT 0x09
+#define NFA_HCI_ANY_E_REG_ACCESS_DENIED 0x0A
+#define NFA_HCI_ANY_E_PIPE_ACCESS_DENIED 0x0B
+
+/* NFA HCI Events */
+#define NFA_HCI_EVT_HCI_END_OF_OPERATION 0x01
+#define NFA_HCI_EVT_POST_DATA 0x02
+#define NFA_HCI_EVT_HOT_PLUG 0x03
+
+#if (NXP_EXTNS == TRUE)
+#define NFA_HCI_EVT_WTX 0x11
+#define NFA_HCI_ABORT 0x12
+#define NFA_EVT_ABORT 0x11 /* ETSI12 */
+#endif
+
+/* NFA HCI Connectivity gate Events */
+#define NFA_HCI_EVT_CONNECTIVITY 0x10
+#define NFA_HCI_EVT_TRANSACTION 0x12
+#define NFA_HCI_EVT_OPERATION_ENDED 0x13
+
+/* Host controller Admin gate registry identifiers */
+#define NFA_HCI_SESSION_IDENTITY_INDEX 0x01
+#define NFA_HCI_MAX_PIPE_INDEX 0x02
+#define NFA_HCI_WHITELIST_INDEX 0x03
+#define NFA_HCI_HOST_LIST_INDEX 0x04
+#if (NXP_EXTNS == TRUE)
+#define NFA_HCI_HOST_ID_INDEX 0x05
+#define NFA_HCI_HOST_TYPE_INDEX 0x06
+#define NFA_HCI_HOST_TYPE_LIST_INDEX 0x07
+#endif
+
+/* Host controller and DH Link management gate registry identifier */
+#define NFA_HCI_REC_ERROR_INDEX 0x02
+
+/* DH Identity management gate registry identifier */
+#define NFA_HCI_VERSION_SW_INDEX 0x01
+#define NFA_HCI_VERSION_HW_INDEX 0x03
+#define NFA_HCI_VENDOR_NAME_INDEX 0x04
+#define NFA_HCI_MODEL_ID_INDEX 0x05
+#define NFA_HCI_HCI_VERSION_INDEX 0x02
+#define NFA_HCI_GATES_LIST_INDEX 0x06
+
+/* DH APDU ETSI  gate registry identifier */
+#if (NXP_EXTNS == TRUE)
+#define NFA_HCI_MAX_C_APDU_SIZE_INDEX 0x01
+#define NFA_HCI_MAX_WAIT_TIME_INDEX 0x02
+
+#endif
+
+#endif /* NFA_HCI_DEFS_H */
diff --git a/src/nfa/include/nfa_mem_co.h b/src/nfa/include/nfa_mem_co.h
new file mode 100644
index 0000000..decc5f3
--- /dev/null
+++ b/src/nfa/include/nfa_mem_co.h
@@ -0,0 +1,69 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Callout functions for memory allocation/deallocatoin
+ *
+ ******************************************************************************/
+#ifndef NFA_MEM_CO_H
+#define NFA_MEM_CO_H
+
+#include "nfc_target.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+/*****************************************************************************
+**  External Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+**
+** Function         nfa_mem_co_alloc
+**
+** Description      allocate a buffer from platform's memory pool
+**
+** Returns:
+**                  pointer to buffer if successful
+**                  NULL otherwise
+**
+*******************************************************************************/
+extern void* nfa_mem_co_alloc(uint32_t num_bytes);
+
+/*******************************************************************************
+**
+** Function         nfa_mem_co_free
+**
+** Description      free buffer previously allocated using nfa_mem_co_alloc
+**
+** Returns:
+**                  Nothing
+**
+*******************************************************************************/
+extern void nfa_mem_co_free(void* p_buf);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFA_MEM_CO_H */
diff --git a/src/nfa/include/nfa_nv_ci.h b/src/nfa/include/nfa_nv_ci.h
new file mode 100644
index 0000000..eb519d6
--- /dev/null
+++ b/src/nfa/include/nfa_nv_ci.h
@@ -0,0 +1,102 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2003-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the interface file for non valtile memory call-in functions.
+ *
+ ******************************************************************************/
+#ifndef NFA_NV_CI_H
+#define NFA_NV_CI_H
+
+#include "nfa_nv_co.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+/* Read Ready Event */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_NV_CO_STATUS status;
+  int fd;
+  uint16_t num_read;
+} tNFA_NV_CI_READ_EVT;
+
+/* Write Ready Event */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_NV_CO_STATUS status;
+  int fd;
+} tNFA_NV_CI_WRITE_EVT;
+
+/*****************************************************************************
+**  Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+**
+** Function         nfa_nv_ci_write
+**
+** Description      This function sends an event to NFAA indicating the phone
+**                  has written the number of bytes specified in the call-out
+**                  function, nfa_nv_co_write (), and is ready for more data.
+**                  This function is used to control the TX data flow.
+**                  Note: The data buffer is released by the stack aioer
+**                        calling this function.
+**
+** Parameters       status - NFA_NV_CO_OK, NFA_NV_CO_NOSPACE, or NFA_NV_CO_FAIL
+**                  evt - Used Internally by NFA -> MUST be same value passed
+**                       in call-out function.
+**
+** Returns          void
+**
+*******************************************************************************/
+extern void nfa_nv_ci_write(tNFA_NV_CO_STATUS status);
+
+/*******************************************************************************
+**
+** Function         nfa_nv_ci_read
+**
+** Description      This function sends an event to NFA indicating the phone has
+**                  read in the requested amount of data specified in the
+**                  nfa_nv_co_read () call-out function.  It should only be
+**                  called when the requested number of bytes has been read.
+**
+** Parameters       num_bytes_read - number of bytes read into the buffer
+**                      specified in the read callout-function.
+**                  status - NFA_NV_CO_OK if full buffer of data,
+**                           NFA_NV_CO_EOF if the end of file has been reached,
+**                           NFA_NV_CO_FAIL if an error has occurred.
+**                  evt - Used Internally by NFA -> MUST be same value passed
+**                       in call-out function.
+**
+** Returns          void
+**
+*******************************************************************************/
+extern void nfa_nv_ci_read(uint16_t num_bytes_read, tNFA_NV_CO_STATUS status,
+                           uint8_t block);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BTA_FS_CI_H */
diff --git a/src/nfa/include/nfa_nv_co.h b/src/nfa/include/nfa_nv_co.h
new file mode 100644
index 0000000..e183c3e
--- /dev/null
+++ b/src/nfa/include/nfa_nv_co.h
@@ -0,0 +1,113 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2003-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the interface file for the synchronization server call-out
+ *  functions.
+ *
+ ******************************************************************************/
+#ifndef NFA_NV_CO_H
+#define NFA_NV_CO_H
+
+#include <time.h>
+
+#include "nfa_api.h"
+
+/*****************************************************************************
+**  Constants and Data Types
+*****************************************************************************/
+
+/**************************
+**  Common Definitions
+***************************/
+
+/* Status codes returned by call-out functions, or in call-in functions as
+ * status */
+#define NFA_NV_CO_OK 0x00
+#define NFA_NV_CO_FAIL 0x01 /* Used to pass all other errors */
+#define NFA_NV_CO_EACCES 0x02
+#define NFA_NV_CO_ENOTEMPTY 0x03
+#define NFA_NV_CO_EOF 0x04
+#define NFA_NV_CO_EODIR 0x05
+#define NFA_NV_CO_ENOSPACE 0x06 /* Returned in nfa_nv_ci_open if no room */
+#define NFA_NV_CO_EIS_DIR 0x07
+#define NFA_NV_CO_RESUME 0x08 /* used in nfa_nv_ci_open, on resume */
+/* used in nfa_nv_ci_open, on resume (no file to resume) */
+#define NFA_NV_CO_NONE 0x09
+
+typedef uint8_t tNFA_NV_CO_STATUS;
+
+#define DH_NV_BLOCK 0x01
+#define HC_F3_NV_BLOCK 0x02
+#define HC_F4_NV_BLOCK 0x03
+#define HC_DH_NV_BLOCK 0x04
+#define HC_F5_NV_BLOCK 0x05
+
+/*****************************************************************************
+**  Function Declarations
+*****************************************************************************/
+/**************************
+**  Common Functions
+***************************/
+
+/*******************************************************************************
+**
+** Function         nfa_nv_co_read
+**
+** Description      This function is called by NFA to read in data from the
+**                  previously opened file.
+**
+** Parameters       p_buf   - buffer to read the data into.
+**                  nbytes  - number of bytes to read into the buffer.
+**
+** Returns          void
+**
+**                  Note: Upon completion of the request, nfa_nv_ci_read () is
+**                        called with the buffer of data, along with the number
+**                        of bytes read into the buffer, and a status.  The
+**                        call-in function should only be called when ALL
+**                        requested bytes have been read, the end of file has
+**                        been detected, or an error has occurred.
+**
+*******************************************************************************/
+extern void nfa_nv_co_read(uint8_t* p_buf, uint16_t nbytes, uint8_t block);
+
+/*******************************************************************************
+**
+** Function         nfa_nv_co_write
+**
+** Description      This function is called by io to send file data to the
+**                  phone.
+**
+** Parameters       p_buf   - buffer to read the data from.
+**                  nbytes  - number of bytes to write out to the file.
+**
+** Returns          void
+**
+**                  Note: Upon completion of the request, nfa_nv_ci_write () is
+**                        called with the file descriptor and the status.  The
+**                        call-in function should only be called when ALL
+**                        requested bytes have been written, or an error has
+**                        been detected,
+**
+*******************************************************************************/
+extern void nfa_nv_co_write(const uint8_t* p_buf, uint16_t nbytes,
+                            uint8_t block);
+
+#endif /* NFA_NV_CO_H */
diff --git a/src/nfa/include/nfa_p2p_api.h b/src/nfa/include/nfa_p2p_api.h
new file mode 100644
index 0000000..b66a072
--- /dev/null
+++ b/src/nfa/include/nfa_p2p_api.h
@@ -0,0 +1,579 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the public interface file for NFA P2P, Broadcom's NFC
+ *  application layer for mobile phones.
+ *
+ ******************************************************************************/
+#ifndef NFA_P2P_API_H
+#define NFA_P2P_API_H
+
+#include "llcp_api.h"
+#include "nfa_api.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+/* NFA P2P Reason of disconnection */
+#define NFA_P2P_DISC_REASON_REMOTE_INITIATE \
+  0x00 /* remote initiated to disconnect  */
+#define NFA_P2P_DISC_REASON_LOCAL_INITITATE \
+  0x01 /* local initiated to disconnect   */
+#define NFA_P2P_DISC_REASON_NO_SERVICE \
+  0x02 /* no service bound in remote      */
+#define NFA_P2P_DISC_REASON_REMOTE_REJECT \
+  0x03 /* remote rejected connection      */
+#define NFA_P2P_DISC_REASON_FRAME_ERROR \
+  0x04 /* sending or receiving FRMR PDU   */
+#define NFA_P2P_DISC_REASON_LLCP_DEACTIVATED \
+  0x05 /* LLCP link deactivated           */
+#define NFA_P2P_DISC_REASON_NO_RESOURCE \
+  0x06 /* Out of resource in local device */
+#define NFA_P2P_DISC_REASON_NO_INFORMATION \
+  0x80 /* Without information             */
+
+/* NFA P2P callback events */
+/* Server is registered                         */
+#define NFA_P2P_REG_SERVER_EVT 0x00
+/* Client is registered                         */
+#define NFA_P2P_REG_CLIENT_EVT 0x01
+/* LLCP Link has been activated                 */
+#define NFA_P2P_ACTIVATED_EVT 0x02
+#define NFA_P2P_DEACTIVATED_EVT \
+  0x03 /* LLCP Link has been deactivated               */
+/* Data link connection request from peer       */
+#define NFA_P2P_CONN_REQ_EVT 0x04
+/* Data link connection has been established    */
+#define NFA_P2P_CONNECTED_EVT 0x05
+/* Data link connection has been disconnected   */
+#define NFA_P2P_DISC_EVT 0x06
+/* Data received from peer                      */
+#define NFA_P2P_DATA_EVT 0x07
+/* Status indication of outgoing data           */
+#define NFA_P2P_CONGEST_EVT 0x08
+/* link MIU and Well-Known Service list         */
+#define NFA_P2P_LINK_INFO_EVT 0x09
+/* Remote SAP of SDP result                     */
+#define NFA_P2P_SDP_EVT 0x0A
+
+typedef uint8_t tNFA_P2P_EVT;
+
+/* NFA allocates a SAP for server */
+#define NFA_P2P_ANY_SAP LLCP_INVALID_SAP
+#define NFA_P2P_INVALID_SAP LLCP_INVALID_SAP
+
+/* Recommanded MIU's for connection-oriented */
+#define NFA_P2P_MIU_1 \
+  (NCI_NFC_DEP_MAX_DATA - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE)
+#define NFA_P2P_MIU_2 \
+  (2 * NCI_NFC_DEP_MAX_DATA - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE)
+#define NFA_P2P_MIU_3 \
+  (3 * NCI_NFC_DEP_MAX_DATA - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE)
+#define NFA_P2P_MIU_8 \
+  (8 * NCI_NFC_DEP_MAX_DATA - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE)
+
+#define NFA_P2P_LLINK_TYPE LLCP_LINK_TYPE_LOGICAL_DATA_LINK
+#define NFA_P2P_DLINK_TYPE LLCP_LINK_TYPE_DATA_LINK_CONNECTION
+typedef uint8_t tNFA_P2P_LINK_TYPE;
+
+/* Data for NFA_P2P_REG_SERVER_EVT */
+typedef struct {
+  tNFA_HANDLE server_handle; /* NFA_HANDLE_INVALID if failed */
+  char service_name[LLCP_MAX_SN_LEN + 1];
+  uint8_t server_sap;
+} tNFA_P2P_REG_SERVER;
+
+/* Data for NFA_P2P_REG_CLIENT_EVT */
+typedef struct {
+  tNFA_HANDLE client_handle; /* NFA_HANDLE_INVALID if failed */
+} tNFA_P2P_REG_CLIENT;
+
+/* Data for NFA_P2P_ACTIVATED_EVT */
+typedef struct {
+  tNFA_HANDLE handle;
+  uint16_t local_link_miu;
+  uint16_t remote_link_miu;
+} tNFA_P2P_ACTIVATED;
+
+/* Data for NFA_P2P_DEACTIVATED_EVT */
+typedef struct { tNFA_HANDLE handle; } tNFA_P2P_DEACTIVATED;
+
+/* Data for NFA_P2P_CONN_REQ_EVT */
+typedef struct {
+  tNFA_HANDLE server_handle;
+  tNFA_HANDLE conn_handle;
+  uint8_t remote_sap;
+  uint16_t remote_miu;
+  uint8_t remote_rw;
+} tNFA_P2P_CONN_REQ;
+
+/* Data for NFA_P2P_CONNECTED_EVT */
+typedef struct {
+  tNFA_HANDLE client_handle;
+  tNFA_HANDLE conn_handle;
+  uint8_t remote_sap;
+  uint16_t remote_miu;
+  uint8_t remote_rw;
+} tNFA_P2P_CONN;
+
+/* Data for NFA_P2P_DISC_EVT */
+typedef struct {
+  tNFA_HANDLE handle;
+  uint8_t reason;
+} tNFA_P2P_DISC;
+
+/* Data for NFA_P2P_DATA_EVT */
+typedef struct {
+  tNFA_HANDLE handle;
+  uint8_t remote_sap;
+  tNFA_P2P_LINK_TYPE link_type;
+} tNFA_P2P_DATA;
+
+/* Data for NFA_P2P_CONGEST_EVT */
+typedef struct {
+  tNFA_HANDLE handle;
+  bool is_congested;
+  tNFA_P2P_LINK_TYPE link_type;
+} tNFA_P2P_CONGEST;
+
+/* Data for NFA_P2P_LINK_INFO_EVT */
+typedef struct {
+  tNFA_HANDLE handle;
+  uint16_t wks; /* well-known service */
+  uint16_t local_link_miu;
+  uint16_t remote_link_miu;
+} tNFA_P2P_LINK_INFO;
+
+/* Data for NFA_P2P_SDP_EVT */
+typedef struct {
+  tNFA_HANDLE handle;
+  uint8_t remote_sap; /* 0x00 if failed */
+} tNFA_P2P_SDP;
+
+/* Union of all P2P callback structures */
+typedef union {
+  tNFA_P2P_REG_SERVER reg_server;   /* NFA_P2P_REG_SERVER_EVT   */
+  tNFA_P2P_REG_CLIENT reg_client;   /* NFA_P2P_REG_CLIENT_EVT   */
+  tNFA_P2P_ACTIVATED activated;     /* NFA_P2P_ACTIVATED_EVT    */
+  tNFA_P2P_DEACTIVATED deactivated; /* NFA_P2P_DEACTIVATED_EVT  */
+  tNFA_P2P_CONN_REQ conn_req;       /* NFA_P2P_CONN_REQ_EVT     */
+  tNFA_P2P_CONN connected;          /* NFA_P2P_CONNECTED_EVT    */
+  tNFA_P2P_DISC disc;               /* NFA_P2P_DISC_EVT         */
+  tNFA_P2P_DATA data;               /* NFA_P2P_DATA_EVT         */
+  tNFA_P2P_CONGEST congest;         /* NFA_P2P_CONGEST_EVT      */
+  tNFA_P2P_LINK_INFO link_info;     /* NFA_P2P_LINK_INFO_EVT    */
+  tNFA_P2P_SDP sdp;                 /* NFA_P2P_SDP_EVT          */
+} tNFA_P2P_EVT_DATA;
+
+/* NFA P2P callback */
+typedef void(tNFA_P2P_CBACK)(tNFA_P2P_EVT event, tNFA_P2P_EVT_DATA* p_data);
+
+/*****************************************************************************
+**  External Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+**
+** Function         NFA_P2pRegisterServer
+**
+** Description      This function is called to listen to a SAP as server on
+**                  LLCP.
+**
+**                  NFA_P2P_REG_SERVER_EVT will be returned with status and
+**                  handle.
+**
+**                  If server_sap is set to NFA_P2P_ANY_SAP, then NFA will
+**                  allocate a SAP between LLCP_LOWER_BOUND_SDP_SAP and
+**                  LLCP_UPPER_BOUND_SDP_SAP Otherwise, server_sap must be
+**                  between (LLCP_SDP_SAP + 1) and LLCP_UPPER_BOUND_SDP_SAP
+**
+**                  link_type : NFA_P2P_LLINK_TYPE and/or NFA_P2P_DLINK_TYPE
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_P2pRegisterServer(uint8_t server_sap,
+                                         tNFA_P2P_LINK_TYPE link_type,
+                                         char* p_service_name,
+                                         tNFA_P2P_CBACK* p_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pRegisterClient
+**
+** Description      This function is called to register a client service on
+**                  LLCP.
+**
+**                  NFA_P2P_REG_CLIENT_EVT will be returned with status and
+**                  handle.
+**
+**                  link_type : NFA_P2P_LLINK_TYPE and/or NFA_P2P_DLINK_TYPE
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_P2pRegisterClient(tNFA_P2P_LINK_TYPE link_type,
+                                         tNFA_P2P_CBACK* p_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pDeregister
+**
+** Description      This function is called to stop listening to a SAP as server
+**                  or stop client service on LLCP.
+**
+** Note:            If this function is called to de-register a server and RF
+**                  discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_P2pDeregister(tNFA_HANDLE handle);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pAcceptConn
+**
+** Description      This function is called to accept a request of data link
+**                  connection to a listening SAP on LLCP after receiving
+**                  NFA_P2P_CONN_REQ_EVT.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_P2pAcceptConn(tNFA_HANDLE conn_handle, uint16_t miu,
+                                     uint8_t rw);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pRejectConn
+**
+** Description      This function is called to reject a request of data link
+**                  connection to a listening SAP on LLCP after receiving
+**                  NFA_P2P_CONN_REQ_EVT.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_P2pRejectConn(tNFA_HANDLE conn_handle);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pDisconnect
+**
+** Description      This function is called to disconnect an existing or
+**                  connecting data link connection.
+**
+**                  discard any pending data on data link connection if flush is
+**                  set to true
+**
+**                  NFA_P2P_DISC_EVT will be returned after data link connection
+**                  is disconnected
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_P2pDisconnect(tNFA_HANDLE conn_handle, bool flush);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pConnectByName
+**
+** Description      This function is called to create a connection-oriented
+**                  transport by a service name.
+**                  NFA_P2P_CONNECTED_EVT if success
+**                  NFA_P2P_DISC_EVT if failed
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if client is not registered
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_P2pConnectByName(tNFA_HANDLE client_handle,
+                                        char* p_service_name, uint16_t miu,
+                                        uint8_t rw);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pConnectBySap
+**
+** Description      This function is called to create a connection-oriented
+**                  transport by a SAP.
+**                  NFA_P2P_CONNECTED_EVT if success
+**                  NFA_P2P_DISC_EVT if failed
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if client is not registered
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_P2pConnectBySap(tNFA_HANDLE client_handle, uint8_t dsap,
+                                       uint16_t miu, uint8_t rw);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pSendUI
+**
+** Description      This function is called to send data on connectionless
+**                  transport.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_BAD_LENGTH if data length is more than remote
+**                  link MIU
+**                  NFA_STATUS_CONGESTED  if congested
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_P2pSendUI(tNFA_HANDLE handle, uint8_t dsap,
+                                 uint16_t length, uint8_t* p_data);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pReadUI
+**
+** Description      This function is called to read data on connectionless
+**                  transport when receiving NFA_P2P_DATA_EVT with
+**                  NFA_P2P_LLINK_TYPE.
+**
+**                  - Remote SAP who sent UI PDU is returned.
+**                  - Information of UI PDU up to max_data_len is copied into
+**                    p_data.
+**                  - If more information of UI PDU or more UI PDU in queue then
+**                    more is returned to true.
+**                  - Information of next UI PDU is not concatenated.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_P2pReadUI(tNFA_HANDLE handle, uint32_t max_data_len,
+                                 uint8_t* p_remote_sap, uint32_t* p_data_len,
+                                 uint8_t* p_data, bool* p_more);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pFlushUI
+**
+** Description      This function is called to flush data on connectionless
+**                  transport.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_P2pFlushUI(tNFA_HANDLE handle, uint32_t* p_length);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pSendData
+**
+** Description      This function is called to send data on connection-oriented
+**                  transport.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_BAD_LENGTH if data length is more than remote MIU
+**                  NFA_STATUS_CONGESTED  if congested
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_P2pSendData(tNFA_HANDLE conn_handle, uint16_t length,
+                                   uint8_t* p_data);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pReadData
+**
+** Description      This function is called to read data on connection-oriented
+**                  transport when receiving NFA_P2P_DATA_EVT with
+**                  NFA_P2P_DLINK_TYPE.
+**
+**                  - Information of I PDU is copied into p_data up to
+**                    max_data_len.
+**                  - If more information of I PDU or more I PDU in queue, then
+**                    more is returned to true.
+**                  - Information of next I PDU is not concatenated.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_P2pReadData(tNFA_HANDLE handle, uint32_t max_data_len,
+                                   uint32_t* p_data_len, uint8_t* p_data,
+                                   bool* p_more);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pFlushData
+**
+** Description      This function is called to flush data on connection-oriented
+**                  transport.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_P2pFlushData(tNFA_HANDLE handle, uint32_t* p_length);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pSetLocalBusy
+**
+** Description      This function is called to stop or resume incoming data on
+**                  connection-oriented transport.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_P2pSetLocalBusy(tNFA_HANDLE conn_handle, bool is_busy);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pGetLinkInfo
+**
+** Description      This function is called to get local/remote link MIU and
+**                  Well-Known Service list encoded as a 16-bit field of
+**                  connected LLCP. NFA_P2P_LINK_INFO_EVT will be returned.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if server or client is not registered
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_P2pGetLinkInfo(tNFA_HANDLE handle);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pGetRemoteSap
+**
+** Description      This function is called to get SAP associated by service
+**                  name on connected remote LLCP.
+**                  NFA_P2P_SDP_EVT will be returned.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if server or client is not registered
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_P2pGetRemoteSap(tNFA_HANDLE handle,
+                                       char* p_service_name);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pSetLLCPConfig
+**
+** Description      This function is called to change LLCP config parameters.
+**                  Application must call while LLCP is not activated.
+**
+**                  Parameters descriptions (default value)
+**                  - Local Link MIU (LLCP_MIU)
+**                  - Option parameter (LLCP_OPT_VALUE)
+**                  - Response Waiting Time Index (LLCP_WAITING_TIME)
+**                  - Local Link Timeout (LLCP_LTO_VALUE)
+**                  - Inactivity Timeout as initiator role
+**                    (LLCP_INIT_INACTIVITY_TIMEOUT)
+**                  - Inactivity Timeout as target role
+**                    (LLCP_TARGET_INACTIVITY_TIMEOUT)
+**                  - Delay SYMM response (LLCP_DELAY_RESP_TIME)
+**                  - Data link connection timeout
+**                    (LLCP_DATA_LINK_CONNECTION_TOUT)
+**                  - Delay timeout to send first PDU as initiator
+**                    (LLCP_DELAY_TIME_TO_SEND_FIRST_PDU)
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_P2pSetLLCPConfig(uint16_t link_miu, uint8_t opt,
+                                        uint8_t wt, uint16_t link_timeout,
+                                        uint16_t inact_timeout_init,
+                                        uint16_t inact_timeout_target,
+                                        uint16_t symm_delay,
+                                        uint16_t data_link_timeout,
+                                        uint16_t delay_first_pdu_timeout);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pGetLLCPConfig
+**
+** Description      This function is called to read LLCP config parameters.
+**
+**                  Parameters descriptions
+**                  - Local Link MIU
+**                  - Option parameter
+**                  - Response Waiting Time Index
+**                  - Local Link Timeout
+**                  - Inactivity Timeout as initiator role
+**                  - Inactivity Timeout as target role
+**                  - Delay SYMM response
+**                  - Data link connection timeout
+**                  - Delay timeout to send first PDU as initiator
+**
+** Returns          None
+**
+*******************************************************************************/
+extern void NFA_P2pGetLLCPConfig(uint16_t* p_link_miu, uint8_t* p_opt,
+                                 uint8_t* p_wt, uint16_t* p_link_timeout,
+                                 uint16_t* p_inact_timeout_init,
+                                 uint16_t* p_inact_timeout_target,
+                                 uint16_t* p_symm_delay,
+                                 uint16_t* p_data_link_timeout,
+                                 uint16_t* p_delay_first_pdu_timeout);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pSetTraceLevel
+**
+** Description      This function sets the trace level for P2P.  If called with
+**                  a value of 0xFF, it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+extern uint8_t NFA_P2pSetTraceLevel(uint8_t new_level);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFA_P2P_API_H */
diff --git a/src/nfa/include/nfa_rw_api.h b/src/nfa/include/nfa_rw_api.h
new file mode 100644
index 0000000..b35cd8f
--- /dev/null
+++ b/src/nfa/include/nfa_rw_api.h
@@ -0,0 +1,799 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  NFA reader/writer API functions
+ *
+ ******************************************************************************/
+#ifndef NFA_RW_API_H
+#define NFA_RW_API_H
+
+#include "nfc_target.h"
+#include "nfa_api.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+enum {
+  NFA_RW_PRES_CHK_DEFAULT, /* The default behavior             */
+  NFA_RW_PRES_CHK_I_BLOCK, /* Empty I Block                    */
+  NFA_RW_PRES_CHK_RESET,   /* Deactivate to Sleep; Re-activate */
+  NFA_RW_PRES_CHK_RB_CH0,  /* ReadBinary on Channel 0          */
+  NFA_RW_PRES_CHK_RB_CH3,   /* ReadBinary on Channel 3          */
+  NFA_RW_PRES_CHK_ISO_DEP_NAK /*presence check command ISO-DEP NAK as per NCI2.0*/
+};
+typedef uint8_t tNFA_RW_PRES_CHK_OPTION;
+
+/*****************************************************************************
+**  NFA T3T Constants and definitions
+*****************************************************************************/
+
+/* Block descriptor. (For non-NDEF read/write */
+typedef struct {
+  uint16_t service_code; /* Service code for the block   */
+  uint16_t block_number; /* Block number.                */
+} tNFA_T3T_BLOCK_DESC;
+
+/*****************************************************************************
+**  External Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+**
+** Function         NFA_RwDetectNDef
+**
+** Description      Perform the NDEF detection procedure  using the appropriate
+**                  method for the currently activated tag.
+**
+**                  Upon successful completion of NDEF detection, a
+**                  NFA_NDEF_DETECT_EVT will be sent, to notify the application
+**                  of the NDEF attributes (NDEF total memory size, current
+**                  size, etc.).
+**
+**                  It is not mandatory to call this function -  NFA_RwReadNDef
+**                  and NFA_RwWriteNDef will perform NDEF detection internally
+**                  if not performed already. This API may be called to get a
+**                  tag's NDEF size before issuing a write-request.
+**
+** Returns:
+**                  NFA_STATUS_OK if successfully initiated
+**                  NFC_STATUS_REFUSED if tag does not support NDEF
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwDetectNDef(void);
+
+/*******************************************************************************
+**
+** Function         NFA_RwReadNDef
+**
+** Description      Read NDEF message from tag. This function will internally
+**                  perform the NDEF detection procedure (if not performed
+**                  previously), and read the NDEF tag data using the
+**                  appropriate method for the currently activated tag.
+**
+**                  Upon successful completion of NDEF detection (if performed),
+**                  a NFA_NDEF_DETECT_EVT will be sent, to notify the
+**                  application of the NDEF attributes (NDEF total memory size,
+**                  current size, etc.).
+**
+**                  Upon receiving the NDEF message, the message will be sent to
+**                  the handler registered with NFA_RegisterNDefTypeHandler or
+**                  NFA_RequestExclusiveRfControl (if exclusive RF mode is
+**                  active)
+**
+**
+** Returns:
+**                  NFA_STATUS_OK if successfully initiated
+**                  NFC_STATUS_REFUSED if tag does not support NDEF
+**                  NFC_STATUS_NOT_INITIALIZED if NULL NDEF was detected on the
+**                  tag
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwReadNDef(void);
+
+/*******************************************************************************
+**
+** Function         NFA_RwWriteNDef
+**
+** Description      Write NDEF data to the activated tag. This function will
+**                  internally perform NDEF detection if necessary, and write
+**                  the NDEF tag data using the appropriate method for the
+**                  currently activated tag.
+**
+**                  When the entire message has been written, or if an error
+**                  occurs, the app will be notified with NFA_RW_WRITE_CPLT_EVT.
+**
+**                  p_data needs to be persistent until NFA_RW_WRITE_CPLT_EVT
+**
+**
+** Returns:
+**                  NFA_STATUS_OK if successfully initiated
+**                  NFC_STATUS_REFUSED if tag does not support NDEF/locked
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwWriteNDef(uint8_t* p_data, uint32_t len);
+
+/*****************************************************************************
+**
+** Function         NFA_RwPresenceCheck
+**
+** Description      Check if the tag is still in the field.
+**
+**                  The NFA_RW_PRESENCE_CHECK_EVT w/ status is used to
+**                  indicate presence or non-presence.
+**
+**                  option is used only with ISO-DEP protocol
+**
+** Returns
+**                  NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*****************************************************************************/
+extern tNFA_STATUS NFA_RwPresenceCheck(tNFA_RW_PRES_CHK_OPTION option);
+
+/*****************************************************************************
+**
+** Function         NFA_RwFormatTag
+**
+** Description      Check if the tag is NDEF Formatable. If yes Format the
+**                  tag
+**
+**                  The NFA_RW_FORMAT_CPLT_EVT w/ status is used to
+**                  indicate if tag is formated or not.
+**
+** Returns
+**                  NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*****************************************************************************/
+extern tNFA_STATUS NFA_RwFormatTag(void);
+
+/*******************************************************************************
+** LEGACY / PROPRIETARY TAG READ AND WRITE APIs
+*******************************************************************************/
+
+/*******************************************************************************
+**
+** Function         NFA_RwLocateTlv
+**
+** Description:
+**      Search for the Lock/Memory contril TLV on the activated Type1/Type2 tag
+**
+**      Data is returned to the application using the NFA_TLV_DETECT_EVT. When
+**      search operation has completed, or if an error occurs, the app will be
+**      notified with NFA_TLV_DETECT_EVT.
+**
+** Description      Perform the TLV detection procedure  using the appropriate
+**                  method for the currently activated tag.
+**
+**                  Upon successful completion of TLV detection in T1/T2 tag, a
+**                  NFA_TLV_DETECT_EVT will be sent, to notify the application
+**                  of the TLV attributes (total lock/reserved bytes etc.).
+**                  However if the TLV type specified is NDEF then it is same as
+**                  calling NFA_RwDetectNDef and should expect to receive
+**                  NFA_NDEF_DETECT_EVT instead of NFA_TLV_DETECT_EVT
+**
+**                  It is not mandatory to call this function -
+**                  NFA_RwDetectNDef, NFA_RwReadNDef and NFA_RwWriteNDef will
+**                  perform TLV detection internally if not performed already.
+**                  An application may call this API to check the a
+**                  tag/card-emulator's total Reserved/ Lock bytes before
+**                  issuing a write-request.
+**
+** Returns:
+**                  NFA_STATUS_OK if successfully initiated
+**                  NFC_STATUS_REFUSED if tlv_type is NDEF & tag won't support
+**                  NDEF
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwLocateTlv(uint8_t tlv_type);
+
+/*******************************************************************************
+**
+** Function         NFA_RwSetTagReadOnly
+**
+** Description:
+**      Sets tag as read only.
+**
+**      When tag is set as read only, or if an error occurs, the app will be
+**      notified with NFA_SET_TAG_RO_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_REJECTED if protocol is not T1/T2/ISO15693
+**                 (or) if hard lock is not requested for protocol ISO15693
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwSetTagReadOnly(bool b_hard_lock);
+
+/*******************************************************************************
+**
+** Function         NFA_RwT1tRid
+**
+** Description:
+**      Send a RID command to the activated Type 1 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the
+**      read operation has completed, or if an error occurs, the app will be
+**      notified with NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_NOT_INITIALIZED: type 1 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwT1tRid(void);
+
+/*******************************************************************************
+**
+** Function         NFA_RwT1tReadAll
+**
+** Description:
+**      Send a RALL command to the activated Type 1 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the
+**      read operation has completed, or if an error occurs, the app will be
+**      notified with NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_NOT_INITIALIZED: type 1 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwT1tReadAll(void);
+
+/*******************************************************************************
+**
+** Function         NFA_RwT1tRead
+**
+** Description:
+**      Send a READ command to the activated Type 1 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the
+**      read operation has completed, or if an error occurs, the app will be
+**      notified with NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_NOT_INITIALIZED: type 1 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwT1tRead(uint8_t block_number, uint8_t index);
+
+/*******************************************************************************
+**
+** Function         NFA_RwT1tWrite
+**
+** Description:
+**      Send a WRITE command to the activated Type 1 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the
+**      write operation has completed, or if an error occurs, the app will be
+**      notified with NFA_WRITE_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_NOT_INITIALIZED: type 1 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwT1tWrite(uint8_t block_number, uint8_t index,
+                                  uint8_t data, bool b_erase);
+
+/*******************************************************************************
+**
+** Function         NFA_RwT1tReadSeg
+**
+** Description:
+**      Send a RSEG command to the activated Type 1 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the
+**      read operation has completed, or if an error occurs, the app will be
+**      notified with NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_NOT_INITIALIZED: type 1 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwT1tReadSeg(uint8_t segment_number);
+
+/*******************************************************************************
+**
+** Function         NFA_RwT1tRead8
+**
+** Description:
+**      Send a READ8 command to the activated Type 1 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the
+**      read operation has completed, or if an error occurs, the app will be
+**      notified with NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_NOT_INITIALIZED: type 1 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwT1tRead8(uint8_t block_number);
+
+/*******************************************************************************
+**
+** Function         NFA_RwT1tWrite8
+**
+** Description:
+**      Send a WRITE8_E / WRITE8_NE command to the activated Type 1 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the
+**      read operation has completed, or if an error occurs, the app will be
+**      notified with NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_NOT_INITIALIZED: type 1 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwT1tWrite8(uint8_t block_number, uint8_t* p_data,
+                                   bool b_erase);
+
+/*******************************************************************************
+**
+** Function         NFA_RwT2tRead
+**
+** Description:
+**      Send a READ command to the activated Type 2 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the
+**      read operation has completed, or if an error occurs, the app will be
+**      notified with NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_NOT_INITIALIZED: type 2 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwT2tRead(uint8_t block_number);
+
+/*******************************************************************************
+**
+** Function         NFA_RwT2tWrite
+**
+** Description:
+**      Send an WRITE command to the activated Type 2 tag.
+**
+**      When the write operation has completed (or if an error occurs), the
+**      app will be notified with NFA_WRITE_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_NOT_INITIALIZED: type 2 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwT2tWrite(uint8_t block_number, uint8_t* p_data);
+
+/*******************************************************************************
+**
+** Function         NFA_RwT2tSectorSelect
+**
+** Description:
+**      Send SECTOR SELECT command to the activated Type 2 tag.
+**
+**      When the sector select operation has completed (or if an error occurs),
+**      the app will be notified with NFA_SECTOR_SELECT_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_NOT_INITIALIZED: type 2 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwT2tSectorSelect(uint8_t sector_number);
+
+/*******************************************************************************
+**
+** Function         NFA_RwT3tRead
+**
+** Description:
+**      Send a CHECK (read) command to the activated Type 3 tag.
+**
+**      Data is returned to the application using the NFA_RW_DATA_EVT. When the
+**      read operation has completed, or if an error occurs, the app will be
+**      notified with NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_NOT_INITIALIZED: type 3 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwT3tRead(uint8_t num_blocks,
+                                 tNFA_T3T_BLOCK_DESC* t3t_blocks);
+
+/*******************************************************************************
+**
+** Function         NFA_RwT3tWrite
+**
+** Description:
+**      Send an UPDATE (write) command to the activated Type 3 tag.
+**
+**      When the write operation has completed (or if an error occurs), the
+**      app will be notified with NFA_WRITE_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_NOT_INITIALIZED: type 3 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwT3tWrite(uint8_t num_blocks,
+                                  tNFA_T3T_BLOCK_DESC* t3t_blocks,
+                                  uint8_t* p_data);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93Inventory
+**
+** Description:
+**      Send Inventory command to the activated ISO 15693 tag with/without AFI..
+**      If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
+**
+**      When the write operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_NOT_INITIALIZED: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwI93Inventory(bool afi_present, uint8_t afi,
+                                      uint8_t* p_uid);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93StayQuiet
+**
+** Description:
+**      Send Stay Quiet command to the activated ISO 15693 tag.
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwI93StayQuiet(void);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93ReadSingleBlock
+**
+** Description:
+**      Send Read Single Block command to the activated ISO 15693 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the
+**      read operation has completed, or if an error occurs, the app will be
+**      notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwI93ReadSingleBlock(uint8_t block_number);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93WriteSingleBlock
+**
+** Description:
+**      Send Write Single Block command to the activated ISO 15693 tag.
+**
+**      When the write operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwI93WriteSingleBlock(uint8_t block_number,
+                                             uint8_t* p_data);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93LockBlock
+**
+** Description:
+**      Send Lock block command to the activated ISO 15693 tag.
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwI93LockBlock(uint8_t block_number);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93ReadMultipleBlocks
+**
+** Description:
+**      Send Read Multiple Block command to the activated ISO 15693 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the
+**      read operation has completed, or if an error occurs, the app will be
+**      notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwI93ReadMultipleBlocks(uint8_t first_block_number,
+                                               uint16_t number_blocks);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93WriteMultipleBlocks
+**
+** Description:
+**      Send Write Multiple Block command to the activated ISO 15693 tag.
+**
+**      When the write operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwI93WriteMultipleBlocks(uint8_t first_block_number,
+                                                uint16_t number_blocks,
+                                                uint8_t* p_data);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93Select
+**
+** Description:
+**      Send Select command to the activated ISO 15693 tag.
+**
+**      UID[0]: 0xE0, MSB
+**      UID[1]: IC Mfg Code
+**      ...
+**      UID[7]: LSB
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwI93Select(uint8_t* p_uid);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93ResetToReady
+**
+** Description:
+**      Send Reset to ready command to the activated ISO 15693 tag.
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwI93ResetToReady(void);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93WriteAFI
+**
+** Description:
+**      Send Write AFI command to the activated ISO 15693 tag.
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwI93WriteAFI(uint8_t afi);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93LockAFI
+**
+** Description:
+**      Send Lock AFI command to the activated ISO 15693 tag.
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwI93LockAFI(void);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93WriteDSFID
+**
+** Description:
+**      Send Write DSFID command to the activated ISO 15693 tag.
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwI93WriteDSFID(uint8_t dsfid);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93LockDSFID
+**
+** Description:
+**      Send Lock DSFID command to the activated ISO 15693 tag.
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwI93LockDSFID(void);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93GetSysInfo
+**
+** Description:
+**      Send Get system information command to the activated ISO 15693 tag.
+**      If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwI93GetSysInfo(uint8_t* p_uid);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93GetMultiBlockSecurityStatus
+**
+** Description:
+**      Send Get Multiple block security status command to the activated ISO
+**      15693 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the
+**      read operation has completed, or if an error occurs, the app will be
+**      notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_RwI93GetMultiBlockSecurityStatus(
+    uint8_t first_block_number, uint16_t number_blocks);
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         NFA_SetReconnectState
+**
+** Description:
+**      This function enable/disable p2p prio logic if re-connect is in progress
+**
+** Returns:
+**      void
+*******************************************************************************/
+extern void NFA_SetReconnectState(bool flag);
+
+/*******************************************************************************
+**
+** Function         NFA_SetEmvCoState
+**
+** Description:
+**      This function enable/disable p2p prio logic if emvco polling is enabled.
+**
+** Returns:
+**      void
+*******************************************************************************/
+extern void NFA_SetEmvCoState(bool flag);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFA_RW_API_H */
diff --git a/src/nfa/include/nfa_snep_api.h b/src/nfa/include/nfa_snep_api.h
new file mode 100644
index 0000000..1e16c09
--- /dev/null
+++ b/src/nfa/include/nfa_snep_api.h
@@ -0,0 +1,489 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the public interface file for NFA SNEP, Broadcom's NFC
+ *  application layer for mobile phones.
+ *
+ ******************************************************************************/
+#ifndef NFA_SNEP_API_H
+#define NFA_SNEP_API_H
+
+#include "nfa_api.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+#define NFA_SNEP_VERSION 0x10 /* SNEP Version 1.0          */
+
+/* send remaining fragments         */
+#define NFA_SNEP_REQ_CODE_CONTINUE 0x00
+/* return an NDEF message           */
+#define NFA_SNEP_REQ_CODE_GET 0x01
+/* accept an NDEF message           */
+#define NFA_SNEP_REQ_CODE_PUT 0x02
+/* do not send remaining fragments  */
+#define NFA_SNEP_REQ_CODE_REJECT 0x7F
+
+#define tNFA_SNEP_REQ_CODE uint8_t
+
+/* continue send remaining fragments    */
+#define NFA_SNEP_RESP_CODE_CONTINUE 0x80
+/* the operation succeeded              */
+#define NFA_SNEP_RESP_CODE_SUCCESS 0x81
+/* resource not found                   */
+#define NFA_SNEP_RESP_CODE_NOT_FOUND 0xC0
+/* resource exceeds data size limit     */
+#define NFA_SNEP_RESP_CODE_EXCESS_DATA 0xC1
+/* malformed request not understood     */
+#define NFA_SNEP_RESP_CODE_BAD_REQ 0xC2
+/* unsupported functionality requested  */
+#define NFA_SNEP_RESP_CODE_NOT_IMPLM 0xE0
+/* unsupported protocol version         */
+#define NFA_SNEP_RESP_CODE_UNSUPP_VER 0xE1
+/* do not send remaining fragments      */
+#define NFA_SNEP_RESP_CODE_REJECT 0xFF
+
+#define tNFA_SNEP_RESP_CODE uint8_t
+
+/* NFA SNEP callback events */
+/* Server/client Registeration Status   */
+#define NFA_SNEP_REG_EVT 0x00
+/* LLCP link has been activated, client only   */
+#define NFA_SNEP_ACTIVATED_EVT 0x01
+/* LLCP link has been deactivated, client only */
+#define NFA_SNEP_DEACTIVATED_EVT 0x02
+/* Data link has been created           */
+#define NFA_SNEP_CONNECTED_EVT 0x03
+/* GET request from client              */
+#define NFA_SNEP_GET_REQ_EVT 0x04
+/* PUT request from client              */
+#define NFA_SNEP_PUT_REQ_EVT 0x05
+/* GET response from server             */
+#define NFA_SNEP_GET_RESP_EVT 0x06
+/* PUT response from server             */
+#define NFA_SNEP_PUT_RESP_EVT 0x07
+/* Failed to connect or disconnected    */
+#define NFA_SNEP_DISC_EVT 0x08
+
+#define NFA_SNEP_ALLOC_BUFF_EVT                                         \
+  0x09                              /* Request to allocate a buffer for \
+                                       NDEF*/
+#define NFA_SNEP_FREE_BUFF_EVT 0x0A /* Request to deallocate buffer for NDEF*/
+/* GET response sent to client          */
+#define NFA_SNEP_GET_RESP_CMPL_EVT 0x0B
+
+/* SNEP default server is started       */
+#define NFA_SNEP_DEFAULT_SERVER_STARTED_EVT 0x0C
+/* SNEP default server is stopped       */
+#define NFA_SNEP_DEFAULT_SERVER_STOPPED_EVT 0x0D
+
+typedef uint8_t tNFA_SNEP_EVT;
+
+#define NFA_SNEP_ANY_SAP LLCP_INVALID_SAP
+
+/* Data for NFA_SNEP_REG_EVT */
+typedef struct {
+  tNFA_STATUS status;
+  tNFA_HANDLE reg_handle; /* handle for registered server/client */
+  char service_name[LLCP_MAX_SN_LEN + 1]; /* only for server */
+} tNFA_SNEP_REG;
+
+/* Data for NFA_SNEP_ACTIVATED_EVT */
+typedef struct {
+  tNFA_HANDLE client_handle; /* handle for registered client    */
+} tNFA_SNEP_ACTIVATED;
+
+/* Data for NFA_SNEP_DEACTIVATED_EVT */
+typedef tNFA_SNEP_ACTIVATED tNFA_SNEP_DEACTIVATED;
+
+/* Data for NFA_SNEP_CONNECTED_EVT */
+/*
+** for server, new handle will be assigned for conn_handle
+** for client, handle used in NFA_SnepConnect () is returned in conn_handle
+*/
+typedef struct {
+  tNFA_HANDLE reg_handle;  /* server/client handle            */
+  tNFA_HANDLE conn_handle; /* handle for data link connection */
+} tNFA_SNEP_CONNECT;
+
+/* Data for NFA_SNEP_GET_REQ_EVT */
+typedef struct {
+  tNFA_HANDLE conn_handle;    /* handle for data link connection */
+  uint32_t acceptable_length; /* acceptable length from client   */
+  uint32_t ndef_length;       /* NDEF message length             */
+  uint8_t* p_ndef;            /* NDEF message                    */
+} tNFA_SNEP_GET_REQ;
+
+/* Data for NFA_SNEP_PUT_REQ_EVT */
+typedef struct {
+  tNFA_HANDLE conn_handle; /* handle for data link connection */
+  uint32_t ndef_length;    /* NDEF message length             */
+  uint8_t* p_ndef;         /* NDEF message                    */
+} tNFA_SNEP_PUT_REQ;
+
+/* Data for NFA_SNEP_GET_RESP_EVT */
+typedef struct {
+  tNFA_HANDLE conn_handle;       /* handle for data link connection */
+  tNFA_SNEP_RESP_CODE resp_code; /* response code from server       */
+  uint32_t ndef_length;          /* NDEF message length             */
+  uint8_t* p_ndef;               /* NDEF message                    */
+} tNFA_SNEP_GET_RESP;
+
+/* Data for NFA_SNEP_PUT_RESP_EVT */
+typedef struct {
+  tNFA_HANDLE conn_handle;       /* handle for data link connection */
+  tNFA_SNEP_RESP_CODE resp_code; /* response code from server       */
+} tNFA_SNEP_PUT_RESP;
+
+/* Data for NFA_SNEP_DISC_EVT */
+typedef struct {
+  tNFA_HANDLE conn_handle; /* handle for data link connection */
+                           /* client_handle if connection failed */
+} tNFA_SNEP_DISC;
+
+/* Data for NFA_SNEP_ALLOC_BUFF_EVT */
+typedef struct {
+  tNFA_HANDLE conn_handle; /* handle for data link connection                */
+  tNFA_SNEP_REQ_CODE
+      req_code; /* NFA_SNEP_REQ_CODE_GET or NFA_SNEP_REQ_CODE_PUT */
+  tNFA_SNEP_RESP_CODE resp_code; /* Response code if cannot allocate buffer */
+  uint32_t ndef_length; /* NDEF message length                            */
+  uint8_t* p_buff;      /* buffer for NDEF message                        */
+} tNFA_SNEP_ALLOC;
+
+/* Data for NFA_SNEP_FREE_BUFF_EVT */
+typedef struct {
+  tNFA_HANDLE conn_handle; /* handle for data link connection */
+  uint8_t* p_buff;         /* buffer to free                  */
+} tNFA_SNEP_FREE;
+
+/* Data for NFA_SNEP_GET_RESP_CMPL_EVT */
+typedef struct {
+  tNFA_HANDLE conn_handle; /* handle for data link connection */
+  uint8_t* p_buff;         /* buffer for NDEF message         */
+} tNFA_SNEP_GET_RESP_CMPL;
+
+/* Union of all SNEP callback structures */
+typedef union {
+  tNFA_SNEP_REG reg;                     /* NFA_SNEP_REG_EVT             */
+  tNFA_SNEP_ACTIVATED activated;         /* NFA_SNEP_ACTIVATED_EVT       */
+  tNFA_SNEP_DEACTIVATED deactivated;     /* NFA_SNEP_DEACTIVATED_EVT     */
+  tNFA_SNEP_CONNECT connect;             /* NFA_SNEP_CONNECTED_EVT       */
+  tNFA_SNEP_GET_REQ get_req;             /* NFA_SNEP_GET_REQ_EVT         */
+  tNFA_SNEP_PUT_REQ put_req;             /* NFA_SNEP_PUT_REQ_EVT         */
+  tNFA_SNEP_GET_RESP get_resp;           /* NFA_SNEP_GET_RESP_EVT        */
+  tNFA_SNEP_PUT_RESP put_resp;           /* NFA_SNEP_PUT_RESP_EVT        */
+  tNFA_SNEP_DISC disc;                   /* NFA_SNEP_DISC_EVT            */
+  tNFA_SNEP_ALLOC alloc;                 /* NFA_SNEP_ALLOC_BUFF_EVT      */
+  tNFA_SNEP_FREE free;                   /* NFA_SNEP_FREE_BUFF_EVT       */
+  tNFA_SNEP_GET_RESP_CMPL get_resp_cmpl; /* NFA_SNEP_GET_RESP_CMPL_EVT   */
+} tNFA_SNEP_EVT_DATA;
+
+/* NFA SNEP callback */
+typedef void(tNFA_SNEP_CBACK)(tNFA_SNEP_EVT event, tNFA_SNEP_EVT_DATA* p_data);
+
+/*****************************************************************************
+**  External Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+**
+** Function         NFA_SnepStartDefaultServer
+**
+** Description      This function is called to listen to SAP, 0x04 as SNEP
+**                  default server ("urn:nfc:sn:snep") on LLCP.
+**
+**                  NFA_SNEP_DEFAULT_SERVER_STARTED_EVT without data will be
+**                  returned.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_SnepStartDefaultServer(tNFA_SNEP_CBACK* p_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_SnepStopDefaultServer
+**
+** Description      This function is called to stop SNEP default server on LLCP.
+**
+**                  NFA_SNEP_DEFAULT_SERVER_STOPPED_EVT without data will be
+**                  returned.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_SnepStopDefaultServer(tNFA_SNEP_CBACK* p_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_SnepRegisterServer
+**
+** Description      This function is called to listen to a SAP as SNEP server.
+**
+**                  If server_sap is set to NFA_SNEP_ANY_SAP, then NFA will
+**                  allocate a SAP between LLCP_LOWER_BOUND_SDP_SAP and
+**                  LLCP_UPPER_BOUND_SDP_SAP
+**
+**                  NFC Forum default SNEP server ("urn:nfc:sn:snep") may be
+**                  launched by NFA_SnepStartDefaultServer ().
+**
+**                  NFA_SNEP_REG_EVT will be returned with status, handle and
+**                  service name.
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_INVALID_PARAM if p_service_name or p_cback is
+**                  NULL
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_SnepRegisterServer(uint8_t server_sap,
+                                          char* p_service_name,
+                                          tNFA_SNEP_CBACK* p_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_SnepRegisterClient
+**
+** Description      This function is called to register SNEP client.
+**                  NFA_SNEP_REG_EVT will be returned with status, handle
+**                  and zero-length service name.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_INVALID_PARAM if p_cback is NULL
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_SnepRegisterClient(tNFA_SNEP_CBACK* p_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_SnepDeregister
+**
+** Description      This function is called to stop listening as SNEP server
+**                  or SNEP client. Application shall use reg_handle returned in
+**                  NFA_SNEP_REG_EVT.
+**
+** Note:            If this function is called to de-register a SNEP server and
+**                  RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_SnepDeregister(tNFA_HANDLE reg_handle);
+
+/*******************************************************************************
+**
+** Function         NFA_SnepConnect
+**
+** Description      This function is called by client to create data link
+**                  connection to SNEP server on peer device.
+**
+**                  Client handle and service name of server to connect shall be
+**                  provided. A conn_handle will be returned in
+**                  NFA_SNEP_CONNECTED_EVT, if successfully connected. Otherwise
+**                  NFA_SNEP_DISC_EVT will be returned.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_INVALID_PARAM if p_service_name or p_cback is
+**                  NULL
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_SnepConnect(tNFA_HANDLE client_handle,
+                                   char* p_service_name);
+
+/*******************************************************************************
+**
+** Function         NFA_SnepGet
+**
+** Description      This function is called by client to send GET request.
+**
+**                  Application shall allocate a buffer and put NDEF message
+**                  with desired record type to get from server. NDEF message
+**                  from server will be returned in the same buffer with
+**                  NFA_SNEP_GET_RESP_EVT. The size of buffer will be used as
+**                  "Acceptable Length".
+**
+**                  NFA_SNEP_GET_RESP_EVT or NFA_SNEP_DISC_EVT will be returned
+**                  through registered p_cback. Application may free the buffer
+**                  after receiving these events.
+**
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_SnepGet(tNFA_HANDLE conn_handle, uint32_t buff_length,
+                               uint32_t ndef_length, uint8_t* p_ndef_buff);
+
+/*******************************************************************************
+**
+** Function         NFA_SnepPut
+**
+** Description      This function is called by client to send PUT request.
+**
+**                  Application shall allocate a buffer and put desired NDEF
+**                  message to send to server.
+**
+**                  NFA_SNEP_PUT_RESP_EVT or NFA_SNEP_DISC_EVT will be returned
+**                  through p_cback. Application may free the buffer after
+**                  receiving these events.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_INVALID_PARAM if p_service_name or p_cback is
+**                  NULL
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_SnepPut(tNFA_HANDLE conn_handle, uint32_t ndef_length,
+                               uint8_t* p_ndef_buff);
+
+/*******************************************************************************
+**
+** Function         NFA_SnepGetResponse
+**
+** Description      This function is called by server to send response of GET
+**                  request.
+**
+**                  When server application receives NFA_SNEP_ALLOC_BUFF_EVT,
+**                  it shall allocate a buffer for incoming NDEF message and
+**                  pass the pointer within callback context. This buffer will
+**                  be returned with NFA_SNEP_GET_REQ_EVT after receiving
+**                  complete NDEF message. If buffer is not allocated,
+**                  NFA_SNEP_RESP_CODE_NOT_FOUND (Note:There is no proper
+**                  response code for this case) or NFA_SNEP_RESP_CODE_REJECT
+**                  will be sent to client.
+**
+**                  Server application shall provide conn_handle which is
+**                  received in NFA_SNEP_GET_REQ_EVT.
+**
+**                  Server application shall allocate a buffer and put NDEF
+**                  message if response code is NFA_SNEP_RESP_CODE_SUCCESS.
+**                  Otherwise, ndef_length shall be set to zero.
+**
+**                  NFA_SNEP_GET_RESP_CMPL_EVT or NFA_SNEP_DISC_EVT will be
+**                  returned through registered callback function. Application
+**                  may free the buffer after receiving these events.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_SnepGetResponse(tNFA_HANDLE conn_handle,
+                                       tNFA_SNEP_RESP_CODE resp_code,
+                                       uint32_t ndef_length,
+                                       uint8_t* p_ndef_buff);
+
+/*******************************************************************************
+**
+** Function         NFA_SnepPutResponse
+**
+** Description      This function is called by server to send response of PUT
+**                  request.
+**
+**                  When server application receives NFA_SNEP_ALLOC_BUFF_EVT,
+**                  it shall allocate a buffer for incoming NDEF message and
+**                  pass the pointer within callback context. This buffer will
+**                  be returned with NFA_SNEP_PUT_REQ_EVT after receiving
+**                  complete NDEF message.  If buffer is not allocated,
+**                  NFA_SNEP_RESP_CODE_REJECT will be sent to client or NFA will
+**                  discard request and send NFA_SNEP_RESP_CODE_SUCCESS
+**                  (Note:There is no proper response code for this case).
+**
+**                  Server application shall provide conn_handle which is
+**                  received in NFA_SNEP_PUT_REQ_EVT.
+**
+**                  NFA_SNEP_DISC_EVT will be returned through registered
+**                  callback function when client disconnects data link
+**                  connection.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_SnepPutResponse(tNFA_HANDLE conn_handle,
+                                       tNFA_SNEP_RESP_CODE resp_code);
+
+/*******************************************************************************
+**
+** Function         NFA_SnepDisconnect
+**
+** Description      This function is called to disconnect data link connection.
+**                  discard any pending data if flush is set to true
+**
+**                  Client application shall provide conn_handle in
+**                  NFA_SNEP_GET_RESP_EVT or NFA_SNEP_PUT_RESP_EVT.
+**
+**                  Server application shall provide conn_handle in
+**                  NFA_SNEP_GET_REQ_EVT or NFA_SNEP_PUT_REQ_EVT.
+**
+**                  NFA_SNEP_DISC_EVT will be returned
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+extern tNFA_STATUS NFA_SnepDisconnect(tNFA_HANDLE conn_handle, bool flush);
+
+/*******************************************************************************
+**
+** Function         NFA_SnepSetTraceLevel
+**
+** Description      This function sets the trace level for SNEP.  If called with
+**                  a value of 0xFF, it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+extern uint8_t NFA_SnepSetTraceLevel(uint8_t new_level);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFA_P2P_API_H */
diff --git a/src/nfa/int/nfa_ce_int.h b/src/nfa/int/nfa_ce_int.h
new file mode 100644
index 0000000..1fb4528
--- /dev/null
+++ b/src/nfa/int/nfa_ce_int.h
@@ -0,0 +1,251 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2011-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the private interface file for NFA_CE
+ *
+ ******************************************************************************/
+#ifndef NFA_CE_INT_H
+#define NFA_CE_INT_H
+
+#include "nfa_sys.h"
+#include "nfa_api.h"
+#include "nfa_ce_api.h"
+#include "nfa_dm_int.h"
+#include "nfc_api.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+/* ce status callback */
+typedef void tNFA_CE_STATUS_CBACK(tNFA_STATUS status);
+
+/* CE events */
+enum {
+  /* device manager local device API events */
+  NFA_CE_API_CFG_LOCAL_TAG_EVT = NFA_SYS_EVT_START(NFA_ID_CE),
+  NFA_CE_API_REG_LISTEN_EVT,
+  NFA_CE_API_DEREG_LISTEN_EVT,
+  NFA_CE_API_CFG_ISODEP_TECH_EVT,
+  NFA_CE_ACTIVATE_NTF_EVT,
+  NFA_CE_DEACTIVATE_NTF_EVT,
+
+  NFA_CE_MAX_EVT
+};
+
+/* Listen registration types */
+enum {
+  NFA_CE_REG_TYPE_NDEF,
+  NFA_CE_REG_TYPE_ISO_DEP,
+  NFA_CE_REG_TYPE_FELICA,
+  NFA_CE_REG_TYPE_UICC
+#if (NXP_EXTNS == TRUE)
+  ,
+  NFA_CE_REG_TYPE_ESE
+#endif
+};
+typedef uint8_t tNFA_CE_REG_TYPE;
+
+/* data type for NFA_CE_API_CFG_LOCAL_TAG_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_PROTOCOL_MASK protocol_mask;
+  uint8_t* p_ndef_data;
+  uint16_t ndef_cur_size;
+  uint16_t ndef_max_size;
+  bool read_only;
+  uint8_t uid_len;
+  uint8_t uid[NFA_MAX_UID_LEN];
+} tNFA_CE_API_CFG_LOCAL_TAG;
+
+/* data type for NFA_CE_ACTIVATE_NTF_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFC_ACTIVATE_DEVT* p_activation_params;
+} tNFA_CE_ACTIVATE_NTF;
+
+/* data type for NFA_CE_API_REG_LISTEN_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_CONN_CBACK* p_conn_cback;
+
+  tNFA_CE_REG_TYPE listen_type;
+
+  /* For registering Felica */
+  uint16_t system_code;
+  uint8_t nfcid2[NCI_RF_F_UID_LEN];
+  uint8_t t3tPmm[NCI_T3T_PMM_LEN];
+
+  /* For registering Type-4 */
+  uint8_t aid[NFC_MAX_AID_LEN]; /* AID to listen for (For type-4 only)  */
+  uint8_t aid_len;              /* AID length                           */
+
+  /* For registering UICC */
+  tNFA_HANDLE ee_handle;
+  tNFA_TECHNOLOGY_MASK tech_mask;
+} tNFA_CE_API_REG_LISTEN;
+
+/* data type for NFA_CE_API_DEREG_LISTEN_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE handle;
+  uint32_t listen_info;
+} tNFA_CE_API_DEREG_LISTEN;
+
+/* union of all data types */
+typedef union {
+  /* GKI event buffer header */
+  NFC_HDR hdr;
+  tNFA_CE_API_CFG_LOCAL_TAG local_tag;
+  tNFA_CE_API_REG_LISTEN reg_listen;
+  tNFA_CE_API_DEREG_LISTEN dereg_listen;
+  tNFA_CE_ACTIVATE_NTF activate_ntf;
+} tNFA_CE_MSG;
+
+/****************************************************************************
+** LISTEN_INFO definitions
+*****************************************************************************/
+/* Entry 0 is reserved for local NDEF tag */
+#define NFA_CE_LISTEN_INFO_IDX_NDEF 0
+#define NFA_CE_LISTEN_INFO_IDX_INVALID (NFA_CE_LISTEN_INFO_MAX)
+
+/* Flags for listen request */
+/* LISTEN_INFO entry is in use                                      */
+#define NFA_CE_LISTEN_INFO_IN_USE 0x00000001
+/* NDEF is read-only                                                */
+#define NFC_CE_LISTEN_INFO_READONLY_NDEF 0x00000010
+/* App has not been notified of ACTIVATE_EVT yet for this T4T AID   */
+#define NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND 0x00000040
+/* This is a listen_info for T4T AID                                */
+#define NFA_CE_LISTEN_INFO_T4T_AID 0x00000080
+/* App has not been notified of LISTEN_START yet                    */
+#define NFA_CE_LISTEN_INFO_START_NTF_PND 0x00000100
+/* This is a listen_info for non-NDEF Felica                        */
+#define NFA_CE_LISTEN_INFO_FELICA 0x00000200
+/* This is a listen_info for UICC                                   */
+#define NFA_CE_LISTEN_INFO_UICC 0x00000400
+#if (NXP_EXTNS == TRUE)
+#define NFA_CE_LISTEN_INFO_ESE 0x00008000 /* This is a listen_info for ESE */
+#define NFA_CE_LISTEN_INFO_T3T_ACTIVATE_PND                                 \
+  0x00010000 /* App has not been notified of ACTIVATE_EVT yet for this HCEF \
+                NFCID2 */
+#endif
+
+/* Structure for listen look up table */
+typedef struct {
+  uint32_t flags;
+  tNFA_CONN_CBACK* p_conn_cback; /* Callback for this listen request */
+  tNFA_PROTOCOL_MASK
+      protocol_mask;          /* Mask of protocols for this listen request    */
+  tNFA_HANDLE rf_disc_handle; /* RF Discover handle */
+
+  /* For host tag emulation (NFA_CeRegisterVirtualT4tSE and
+   * NFA_CeRegisterT4tAidOnDH) */
+  uint8_t t3t_pmm[NCI_T3T_PMM_LEN];
+  uint8_t t3t_nfcid2[NCI_RF_F_UID_LEN];
+  uint16_t t3t_system_code; /* Type-3 system code */
+  uint8_t
+      t4t_aid_handle; /* Type-4 aid callback handle (from CE_T4tRegisterAID) */
+
+  /* For UICC */
+  tNFA_HANDLE ee_handle;
+  tNFA_TECHNOLOGY_MASK tech_mask; /* listening technologies               */
+  tNFA_DM_DISC_TECH_PROTO_MASK
+      tech_proto_mask; /* listening technologies and protocols */
+} tNFA_CE_LISTEN_INFO;
+
+/****************************************************************************/
+
+/* Internal flags for nfa_ce */
+/* Deactivation locally initiated by application */
+#define NFA_CE_FLAGS_APP_INIT_DEACTIVATION 0x00000001
+/* Tag is in listen active or sleep state        */
+#define NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP 0x00000002
+typedef uint32_t tNFA_CE_FLAGS;
+
+/* NFA_CE control block */
+typedef struct {
+  uint8_t* p_scratch_buf; /* Scratch buffer for write requests    */
+  uint32_t scratch_buf_size;
+
+  tNFC_ACTIVATE_DEVT activation_params; /* Activation params        */
+  tNFA_CE_FLAGS flags;                  /* internal flags           */
+  tNFA_CONN_CBACK* p_active_conn_cback; /* Callback of activated CE */
+
+  /* listen_info table (table of listen paramters and app callbacks) */
+  tNFA_CE_LISTEN_INFO
+      listen_info[NFA_CE_LISTEN_INFO_MAX]; /* listen info table */
+  uint8_t idx_cur_active; /* listen_info index for currently activated CE */
+  uint8_t idx_wild_card;  /* listen_info index for T4T wild card CE */
+
+  tNFA_DM_DISC_TECH_PROTO_MASK
+      isodep_disc_mask; /* the technology/protocol mask for ISO-DEP */
+
+  /* Local ndef tag info */
+  uint8_t* p_ndef_data;
+  uint16_t ndef_cur_size;
+  uint16_t ndef_max_size;
+
+  tNFA_SYS_EVT_HDLR* p_vs_evt_hdlr; /* VS event handler */
+} tNFA_CE_CB;
+extern tNFA_CE_CB nfa_ce_cb;
+
+/* type definition for action functions */
+typedef bool (*tNFA_CE_ACTION)(tNFA_CE_MSG* p_data);
+
+extern uint8_t NFC_GetNCIVersion();
+
+/* Action function prototypes */
+bool nfa_ce_api_cfg_local_tag(tNFA_CE_MSG* p_ce_msg);
+bool nfa_ce_api_reg_listen(tNFA_CE_MSG* p_ce_msg);
+bool nfa_ce_api_dereg_listen(tNFA_CE_MSG* p_ce_msg);
+bool nfa_ce_api_cfg_isodep_tech(tNFA_CE_MSG* p_ce_msg);
+bool nfa_ce_activate_ntf(tNFA_CE_MSG* p_ce_msg);
+bool nfa_ce_deactivate_ntf(tNFA_CE_MSG* p_ce_msg);
+
+/* Internal function prototypes */
+void nfa_ce_t3t_generate_rand_nfcid(uint8_t nfcid2[NCI_RF_F_UID_LEN]);
+bool nfa_ce_hdl_event(NFC_HDR* p_msg);
+tNFC_STATUS nfa_ce_set_content(void);
+tNFA_STATUS nfa_ce_start_listening(void);
+void nfa_ce_remove_listen_info_entry(uint8_t listen_info_idx, bool notify_app);
+void nfa_ce_sys_disable(void);
+void nfa_ce_free_scratch_buf(void);
+bool nfa_ce_restart_listen_check(void);
+#endif /* NFA_DM_INT_H */
diff --git a/src/nfa/int/nfa_dm_int.h b/src/nfa/int/nfa_dm_int.h
new file mode 100644
index 0000000..6eede26
--- /dev/null
+++ b/src/nfa/int/nfa_dm_int.h
@@ -0,0 +1,729 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2003-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the private interface file for the NFA device manager.
+ *
+ ******************************************************************************/
+#ifndef NFA_DM_INT_H
+#define NFA_DM_INT_H
+
+#include "nfc_api.h"
+#include "nfa_api.h"
+#include "nfa_sys.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+/* DM events */
+enum {
+  /* device manager local device API events */
+  NFA_DM_API_ENABLE_EVT = NFA_SYS_EVT_START(NFA_ID_DM),
+  NFA_DM_API_DISABLE_EVT,
+  NFA_DM_API_SET_CONFIG_EVT,
+  NFA_DM_API_GET_CONFIG_EVT,
+  NFA_DM_API_REQUEST_EXCL_RF_CTRL_EVT,
+  NFA_DM_API_RELEASE_EXCL_RF_CTRL_EVT,
+  NFA_DM_API_ENABLE_POLLING_EVT,
+  NFA_DM_API_DISABLE_POLLING_EVT,
+  NFA_DM_API_ENABLE_LISTENING_EVT,
+  NFA_DM_API_DISABLE_LISTENING_EVT,
+#if (NXP_EXTNS == TRUE)
+  NFA_DM_API_DISABLE_PASSIVE_LISTENING_EVT,
+#endif
+  NFA_DM_API_PAUSE_P2P_EVT,
+  NFA_DM_API_RESUME_P2P_EVT,
+  NFA_DM_API_RAW_FRAME_EVT,
+  NFA_DM_API_SET_P2P_LISTEN_TECH_EVT,
+  NFA_DM_API_START_RF_DISCOVERY_EVT,
+  NFA_DM_API_STOP_RF_DISCOVERY_EVT,
+  NFA_DM_API_SET_RF_DISC_DURATION_EVT,
+  NFA_DM_API_SELECT_EVT,
+  NFA_DM_API_UPDATE_RF_PARAMS_EVT,
+  NFA_DM_API_DEACTIVATE_EVT,
+  NFA_DM_API_POWER_OFF_SLEEP_EVT,
+  NFA_DM_API_REG_NDEF_HDLR_EVT,
+  NFA_DM_API_DEREG_NDEF_HDLR_EVT,
+  NFA_DM_API_REG_VSC_EVT,
+  NFA_DM_API_SEND_VSC_EVT,
+  NFA_DM_TIMEOUT_DISABLE_EVT,
+#if (NXP_EXTNS == TRUE)
+  NFA_DM_API_SEND_NXP_EVT,
+#endif
+  NFA_DM_API_SET_POWER_SUB_STATE_EVT,
+  NFA_DM_MAX_EVT
+};
+
+/* data type for NFA_DM_API_ENABLE_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_DM_CBACK* p_dm_cback;
+  tNFA_CONN_CBACK* p_conn_cback;
+} tNFA_DM_API_ENABLE;
+
+/* data type for NFA_DM_API_DISABLE_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  bool graceful;
+} tNFA_DM_API_DISABLE;
+
+/* data type for NFA_DM_API_SET_CONFIG_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_PMID param_id;
+  uint8_t length;
+  uint8_t* p_data;
+} tNFA_DM_API_SET_CONFIG;
+
+/* data type for NFA_DM_API_GET_CONFIG_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  uint8_t num_ids;
+  tNFA_PMID* p_pmids;
+} tNFA_DM_API_GET_CONFIG;
+
+/* data type for NFA_DM_API_REQ_EXCL_RF_CTRL_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_TECHNOLOGY_MASK poll_mask;
+  tNFA_LISTEN_CFG listen_cfg;
+  tNFA_CONN_CBACK* p_conn_cback;
+  tNFA_NDEF_CBACK* p_ndef_cback;
+} tNFA_DM_API_REQ_EXCL_RF_CTRL;
+
+/* data type for NFA_DM_API_ENABLE_POLLING_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_TECHNOLOGY_MASK poll_mask;
+} tNFA_DM_API_ENABLE_POLL;
+
+/* data type for NFA_DM_API_SET_P2P_LISTEN_TECH_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_TECHNOLOGY_MASK tech_mask;
+} tNFA_DM_API_SET_P2P_LISTEN_TECH;
+
+/* data type for NFA_DM_API_SELECT_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  uint8_t rf_disc_id;
+  tNFA_NFC_PROTOCOL protocol;
+  tNFA_INTF_TYPE rf_interface;
+} tNFA_DM_API_SELECT;
+
+/* data type for NFA_DM_API_UPDATE_RF_PARAMS_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_RF_COMM_PARAMS params;
+} tNFA_DM_API_UPDATE_RF_PARAMS;
+
+/* data type for NFA_DM_API_DEACTIVATE_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  bool sleep_mode;
+} tNFA_DM_API_DEACTIVATE;
+
+/* data type for NFA_DM_API_SET_RF_DISC_DURATION_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  uint16_t rf_disc_dur_ms;
+} tNFA_DM_API_SET_RF_DISC_DUR;
+#define NFA_RF_DISC_DURATION_MAX 0xFFFF
+
+/* data type for NFA_DM_API_REG_NDEF_HDLR_EVT */
+#define NFA_NDEF_FLAGS_HANDLE_WHOLE_MESSAGE 0x01
+#define NFA_NDEF_FLAGS_WKT_URI 0x02
+#define NFA_NDEF_FLAGS_WHOLE_MESSAGE_NOTIFIED 0x04
+
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE ndef_type_handle;
+  uint8_t flags;
+  tNFA_NDEF_CBACK* p_ndef_cback;
+  tNFA_TNF tnf; /* Type-name field of record-type that was registered. */
+  tNFA_NDEF_URI_ID
+      uri_id; /* URI prefix abrieviation (for NFA_RegisterNDefUriHandler) */
+  uint8_t name_len; /* Length of type name or absolute URI */
+  uint8_t name[1];  /* Type name or absolute URI of record-type that got was
+                       registered.    */
+} tNFA_DM_API_REG_NDEF_HDLR;
+
+
+/* data type for NFA_DM_API_SET_POWER_SUB_STATE_EVT */
+typedef struct
+{
+  NFC_HDR hdr;
+  uint8_t screen_state;
+} tNFA_DM_API_SET_POWER_SUB_STATE;
+
+/* data type for NFA_DM_API_DEREG_NDEF_HDLR_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE ndef_type_handle;
+} tNFA_DM_API_DEREG_NDEF_HDLR;
+
+/* data type for NFA_DM_API_REG_VSC_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_VSC_CBACK* p_cback;
+  bool is_register;
+} tNFA_DM_API_REG_VSC;
+
+/* data type for NFA_DM_API_SEND_VSC_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_VSC_CBACK* p_cback;
+  uint8_t oid;
+  uint8_t cmd_params_len;
+  uint16_t pad; /* add padding to ensure the size is big enough for
+                   offset=NCI_VSC_MSG_HDR_SIZE */
+  uint8_t* p_cmd_params;
+} tNFA_DM_API_SEND_VSC;
+
+/* union of all data types */
+typedef union {
+  /* GKI event buffer header */
+  NFC_HDR hdr;                      /* NFA_DM_API_RAW_FRAME_EVT             */
+                                    /* NFA_DM_API_MULTI_TECH_RSP_EVT        */
+                                    /* NFA_DM_API_RELEASE_EXCL_RF_CTRL      */
+                                    /* NFA_DM_API_DISABLE_POLLING_EVT       */
+                                    /* NFA_DM_API_START_RF_DISCOVERY_EVT    */
+                                    /* NFA_DM_API_STOP_RF_DISCOVERY_EVT     */
+  tNFA_DM_API_ENABLE enable;        /* NFA_DM_API_ENABLE_EVT                */
+  tNFA_DM_API_DISABLE disable;      /* NFA_DM_API_DISABLE_EVT               */
+  tNFA_DM_API_SET_CONFIG setconfig; /* NFA_DM_API_SET_CONFIG_EVT            */
+  tNFA_DM_API_GET_CONFIG getconfig; /* NFA_DM_API_GET_CONFIG_EVT            */
+  tNFA_DM_API_SET_RF_DISC_DUR
+      disc_duration; /* NFA_DM_API_SET_RF_DISC_DURATION_EVT  */
+  tNFA_DM_API_REG_NDEF_HDLR reg_ndef_hdlr; /* NFA_DM_API_REG_NDEF_HDLR_EVT */
+  tNFA_DM_API_DEREG_NDEF_HDLR
+      dereg_ndef_hdlr; /* NFA_DM_API_DEREG_NDEF_HDLR_EVT       */
+  tNFA_DM_API_REQ_EXCL_RF_CTRL
+      req_excl_rf_ctrl; /* NFA_DM_API_REQUEST_EXCL_RF_CTRL      */
+  tNFA_DM_API_ENABLE_POLL enable_poll; /* NFA_DM_API_ENABLE_POLLING_EVT */
+  tNFA_DM_API_SET_P2P_LISTEN_TECH
+      set_p2p_listen_tech;   /* NFA_DM_API_SET_P2P_LISTEN_TECH_EVT   */
+  tNFA_DM_API_SELECT select; /* NFA_DM_API_SELECT_EVT                */
+  tNFA_DM_API_UPDATE_RF_PARAMS
+      update_rf_params;              /* NFA_DM_API_UPDATE_RF_PARAMS_EVT      */
+  tNFA_DM_API_DEACTIVATE deactivate; /* NFA_DM_API_DEACTIVATE_EVT            */
+  tNFA_DM_API_SEND_VSC send_vsc;     /* NFA_DM_API_SEND_VSC_EVT              */
+  tNFA_DM_API_REG_VSC reg_vsc;       /* NFA_DM_API_REG_VSC_EVT               */
+  tNFA_DM_API_SET_POWER_SUB_STATE set_power_state; /* NFA_DM_API_SET_POWER_SUB_STATE_EVT   */
+} tNFA_DM_MSG;
+
+/* DM RF discovery state */
+enum {
+  NFA_DM_RFST_IDLE,               /* idle state                     */
+  NFA_DM_RFST_DISCOVERY,          /* discovery state                */
+  NFA_DM_RFST_W4_ALL_DISCOVERIES, /* wait for all discoveries state */
+  NFA_DM_RFST_W4_HOST_SELECT,     /* wait for host selection state  */
+  NFA_DM_RFST_POLL_ACTIVE,        /* poll mode activated state      */
+  NFA_DM_RFST_LISTEN_ACTIVE,      /* listen mode activated state    */
+  NFA_DM_RFST_LISTEN_SLEEP,       /* listen mode sleep state        */
+  NFA_DM_RFST_LP_LISTEN,          /* Listening in Low Power mode    */
+  NFA_DM_RFST_LP_ACTIVE           /* Activated in Low Power mode    */
+};
+typedef uint8_t tNFA_DM_RF_DISC_STATE;
+
+/* DM RF discovery state machine event */
+enum {
+  NFA_DM_RF_DISCOVER_CMD,        /* start RF discovery                    */
+  NFA_DM_RF_DISCOVER_RSP,        /* discover response from NFCC           */
+  NFA_DM_RF_DISCOVER_NTF,        /* RF discovery NTF from NFCC            */
+  NFA_DM_RF_DISCOVER_SELECT_CMD, /* select discovered target              */
+  NFA_DM_RF_DISCOVER_SELECT_RSP, /* select response from NFCC             */
+  NFA_DM_RF_INTF_ACTIVATED_NTF,  /* RF interface activation NTF from NFCC */
+  NFA_DM_RF_DEACTIVATE_CMD,      /* deactivate RF interface               */
+  NFA_DM_RF_DEACTIVATE_RSP,      /* deactivate response from NFCC         */
+  NFA_DM_RF_DEACTIVATE_NTF,      /* deactivate RF interface NTF from NFCC */
+  NFA_DM_LP_LISTEN_CMD,          /* NFCC is listening in low power mode   */
+  NFA_DM_CORE_INTF_ERROR_NTF,    /* RF interface error NTF from NFCC      */
+  NFA_DM_DISC_SM_MAX_EVENT
+};
+typedef uint8_t tNFA_DM_RF_DISC_SM_EVENT;
+
+/* DM RF discovery state machine data */
+typedef struct {
+  uint8_t rf_disc_id;
+  tNFA_NFC_PROTOCOL protocol;
+  tNFA_INTF_TYPE rf_interface;
+} tNFA_DM_DISC_SELECT_PARAMS;
+
+typedef union {
+  tNFC_DISCOVER nfc_discover;        /* discovery data from NFCC    */
+  tNFC_DEACT_TYPE deactivate_type;   /* deactivation type           */
+  tNFA_DM_DISC_SELECT_PARAMS select; /* selected target information */
+} tNFA_DM_RF_DISC_DATA;
+
+/* Callback event from NFA DM RF Discovery to other NFA sub-modules */
+enum {
+  NFA_DM_RF_DISC_START_EVT, /* discovery started with protocol, technology and
+                               mode       */
+  NFA_DM_RF_DISC_ACTIVATED_EVT,  /* activated with configured protocol,
+                                    technology and mode    */
+  NFA_DM_RF_DISC_DEACTIVATED_EVT /* deactivated sleep or idle */
+};
+typedef uint8_t tNFA_DM_RF_DISC_EVT;
+
+/* Combined NFC Technology and protocol bit mask */
+#define NFA_DM_DISC_MASK_PA_T1T 0x00000001
+#define NFA_DM_DISC_MASK_PA_T2T 0x00000002
+#define NFA_DM_DISC_MASK_PA_ISO_DEP 0x00000004
+#define NFA_DM_DISC_MASK_PA_NFC_DEP 0x00000008
+#define NFA_DM_DISC_MASK_PB_ISO_DEP 0x00000010
+#define NFA_DM_DISC_MASK_PF_T3T 0x00000020
+#define NFA_DM_DISC_MASK_PF_NFC_DEP 0x00000040
+#define NFA_DM_DISC_MASK_P_ISO15693 0x00000100
+#define NFA_DM_DISC_MASK_P_B_PRIME 0x00000200
+#define NFA_DM_DISC_MASK_P_KOVIO 0x00000400
+#define NFA_DM_DISC_MASK_PAA_NFC_DEP 0x00000800
+#define NFA_DM_DISC_MASK_PFA_NFC_DEP 0x00001000
+/* Legacy/proprietary/non-NFC Forum protocol (e.g Shanghai transit card) */
+#define NFA_DM_DISC_MASK_P_LEGACY 0x00002000
+#define NFA_DM_DISC_MASK_PB_T3BT 0x00004000
+#define NFA_DM_DISC_MASK_POLL 0x0000FFFF
+
+#define NFA_DM_DISC_MASK_LA_T1T 0x00010000
+#define NFA_DM_DISC_MASK_LA_T2T 0x00020000
+#define NFA_DM_DISC_MASK_LA_ISO_DEP 0x00040000
+#define NFA_DM_DISC_MASK_LA_NFC_DEP 0x00080000
+#define NFA_DM_DISC_MASK_LB_ISO_DEP 0x00100000
+#define NFA_DM_DISC_MASK_LF_T3T 0x00200000
+#define NFA_DM_DISC_MASK_LF_NFC_DEP 0x00400000
+#define NFA_DM_DISC_MASK_L_ISO15693 0x01000000
+#define NFA_DM_DISC_MASK_L_B_PRIME 0x02000000
+#define NFA_DM_DISC_MASK_LAA_NFC_DEP 0x04000000
+#define NFA_DM_DISC_MASK_LFA_NFC_DEP 0x08000000
+#define NFA_DM_DISC_MASK_L_LEGACY 0x10000000
+#define NFA_DM_DISC_MASK_LISTEN 0xFFFF0000
+#define NFA_DM_DISC_MASK_NFC_DEP 0x0C481848
+#if (NXP_EXTNS == TRUE)
+#define NFA_DM_DISC_MASK_ACTIVE_LISTEN 0xFF00FFFF
+#endif
+
+typedef uint32_t tNFA_DM_DISC_TECH_PROTO_MASK;
+
+/* DM RF discovery host ID */
+#define NFA_DM_DISC_HOST_ID_DH NFC_DH_ID
+typedef uint8_t tNFA_DM_DISC_HOST_ID;
+
+/* DM deactivation callback type */
+typedef void(tNFA_DISCOVER_CBACK)(tNFA_DM_RF_DISC_EVT event,
+                                  tNFC_DISCOVER* p_data);
+
+/* DM RF discovery action flags */
+/* RF discovery process has been started        */
+#define NFA_DM_DISC_FLAGS_ENABLED 0x0001
+/* Stop RF discovery is pending                 */
+#define NFA_DM_DISC_FLAGS_STOPPING 0x0002
+/* Disable NFA is pending                       */
+#define NFA_DM_DISC_FLAGS_DISABLING 0x0004
+/* Sleep wakeup in progress                     */
+#define NFA_DM_DISC_FLAGS_CHECKING 0x0008
+/* Notify sub-module that discovery is starting */
+#define NFA_DM_DISC_FLAGS_NOTIFY 0x0010
+/* command has been sent to NFCC in the state   */
+#define NFA_DM_DISC_FLAGS_W4_RSP 0x0020
+/* wait for NTF before changing discovery state */
+#define NFA_DM_DISC_FLAGS_W4_NTF 0x0040
+
+typedef uint16_t tNFA_DM_DISC_FLAGS;
+
+/* DM Discovery control block */
+typedef struct {
+  bool in_use;                       /* true if used          */
+  tNFA_DISCOVER_CBACK* p_disc_cback; /* discovery callback    */
+
+  tNFA_DM_DISC_FLAGS disc_flags; /* specific action flags */
+  tNFA_DM_DISC_HOST_ID host_id;  /* DH or UICC1/UICC2     */
+  tNFA_DM_DISC_TECH_PROTO_MASK
+      requested_disc_mask; /* technology and protocol requested              */
+  tNFA_DM_DISC_TECH_PROTO_MASK
+      selected_disc_mask; /* technology and protocol waiting for activation */
+} tNFA_DM_DISC_ENTRY;
+
+/* polling, raw listen, P2P listen, NDEF CE, 2xVSE, 2xUICC */
+#define NFA_DM_DISC_NUM_ENTRIES 8
+
+/* max discovery technology parameters */
+#define NFA_DM_MAX_DISC_PARAMS 16
+
+/* index of listen mode routing table for technologies */
+enum {
+  NFA_DM_DISC_LRT_NFC_A,
+  NFA_DM_DISC_LRT_NFC_B,
+  NFA_DM_DISC_LRT_NFC_F,
+  NFA_DM_DISC_LRT_NFC_BP
+};
+
+/* SLP_REQ (HLTA) command */
+#define SLP_REQ_CMD 0x5000
+/* NFA_EE_MAX_TECH_ROUTE. only A, B, F, Bprime are supported by UICC now */
+#define NFA_DM_MAX_TECH_ROUTE 4
+
+/* timeout for waiting deactivation NTF,
+** possible delay to send deactivate CMD if all credit wasn't returned
+** transport delay (1sec) and max RWT (5sec)
+*/
+#define NFA_DM_DISC_TIMEOUT_W4_DEACT_NTF (NFC_DEACTIVATE_TIMEOUT * 1000 + 6000)
+
+typedef struct {
+  uint16_t disc_duration; /* Disc duration                                    */
+  tNFA_DM_DISC_FLAGS disc_flags;    /* specific action flags */
+  tNFA_DM_RF_DISC_STATE disc_state; /* RF discovery state */
+
+  tNFC_RF_TECH_N_MODE activated_tech_mode; /* activated technology and mode */
+  uint8_t activated_rf_disc_id;            /* activated RF discovery ID */
+  tNFA_INTF_TYPE activated_rf_interface;   /* activated RF interface */
+  tNFA_NFC_PROTOCOL activated_protocol;    /* activated protocol */
+  tNFA_HANDLE activated_handle;            /* handle of activated sub-module */
+  uint8_t activated_sel_res; /* activated tag's SEL_RES response */
+
+  tNFA_DM_DISC_ENTRY entry[NFA_DM_DISC_NUM_ENTRIES];
+
+  tNFA_DM_DISC_ENTRY excl_disc_entry; /* exclusive RF discovery */
+  tNFA_LISTEN_CFG excl_listen_config; /* listen cfg for exclusive-rf mode */
+
+  uint8_t listen_RT[NFA_DM_MAX_TECH_ROUTE]; /* Host ID for A, B, F, B'
+                                               technology routing*/
+  tNFA_DM_DISC_TECH_PROTO_MASK
+      dm_disc_mask; /* technology and protocol waiting for activation   */
+
+  TIMER_LIST_ENT tle; /* timer for waiting deactivation NTF               */
+  TIMER_LIST_ENT kovio_tle; /* timer for Kovio bar code tag presence check */
+
+  bool deact_pending; /* true if deactivate while checking presence       */
+  bool deact_notify_pending; /* true if notify DEACTIVATED EVT while Stop rf
+                                discovery*/
+  tNFA_DEACTIVATE_TYPE pending_deact_type; /* pending deactivate type */
+} tNFA_DM_DISC_CB;
+
+/* NDEF Type Handler Definitions */
+/* Default handler entry in ndef_handler table      */
+#define NFA_NDEF_DEFAULT_HANDLER_IDX 0
+
+#define NFA_PARAM_ID_INVALID 0xFF
+
+/* Maximum number of pending SetConfigs */
+#define NFA_DM_SETCONFIG_PENDING_MAX 32
+
+/* NFA_DM flags */
+/* DM is enabled                                                        */
+#define NFA_DM_FLAGS_DM_IS_ACTIVE 0x00000001
+/* Exclusive RF mode is active                                          */
+#define NFA_DM_FLAGS_EXCL_RF_ACTIVE 0x00000002
+/* Polling is enabled (while not in exclusive RF mode                   */
+#define NFA_DM_FLAGS_POLLING_ENABLED 0x00000004
+/* send poll stop event                                                 */
+#define NFA_DM_FLAGS_SEND_POLL_STOP_EVT 0x00000008
+/* auto reading of NDEF in progress                                     */
+#define NFA_DM_FLAGS_AUTO_READING_NDEF 0x00000010
+/* NFA_DM_ENABLE_EVT is not reported yet                                */
+#define NFA_DM_FLAGS_ENABLE_EVT_PEND 0x00000020
+/* Send NFA_DEACTIVATED_EVT when deactivated                            */
+#define NFA_DM_FLAGS_SEND_DEACTIVATED_EVT 0x00000040
+/* NFCC is restoring after back to full power mode                      */
+#define NFA_DM_FLAGS_NFCC_IS_RESTORING 0x00000100
+/* NFCC power mode is updating                                          */
+#define NFA_DM_FLAGS_SETTING_PWR_MODE 0x00000200
+/* NFA DM is disabling NFC                                              */
+#define NFA_DM_FLAGS_DM_DISABLING_NFC 0x00000400
+/* NFA_SendRawFrame() is called since RF activation                     */
+#define NFA_DM_FLAGS_RAW_FRAME 0x00000800
+/* NFA_DisableListening() is called and engaged                         */
+#define NFA_DM_FLAGS_LISTEN_DISABLED 0x00001000
+/* NFA_PauseP2p() is called and engaged                         */
+#define NFA_DM_FLAGS_P2P_PAUSED 0x00002000
+/* Power Off Sleep                                                      */
+#define NFA_DM_FLAGS_POWER_OFF_SLEEP 0x00008000
+#if (NXP_EXTNS == TRUE)
+/* NFA_DisablePassiveListening() is called and engaged                  */
+#define NFA_DM_FLAGS_PASSIVE_LISTEN_DISABLED 0x00010000
+#endif
+/* stored parameters */
+typedef struct {
+  uint8_t total_duration[NCI_PARAM_LEN_TOTAL_DURATION];
+
+  uint8_t la_bit_frame_sdd[NCI_PARAM_LEN_LA_BIT_FRAME_SDD];
+  uint8_t la_bit_frame_sdd_len;
+  uint8_t la_platform_config[NCI_PARAM_LEN_LA_PLATFORM_CONFIG];
+  uint8_t la_platform_config_len;
+  uint8_t la_sel_info[NCI_PARAM_LEN_LA_SEL_INFO];
+  uint8_t la_sel_info_len;
+  uint8_t la_nfcid1[NCI_NFCID1_MAX_LEN];
+  uint8_t la_nfcid1_len;
+  uint8_t la_hist_by[NCI_MAX_HIS_BYTES_LEN];
+  uint8_t la_hist_by_len;
+
+  uint8_t lb_sensb_info[NCI_PARAM_LEN_LB_SENSB_INFO];
+  uint8_t lb_sensb_info_len;
+  uint8_t lb_nfcid0[NCI_PARAM_LEN_LB_NFCID0];
+  uint8_t lb_nfcid0_len;
+  uint8_t lb_appdata[NCI_PARAM_LEN_LB_APPDATA];
+  uint8_t lb_appdata_len;
+  uint8_t lb_adc_fo[NCI_PARAM_LEN_LB_ADC_FO];
+  uint8_t lb_adc_fo_len;
+  uint8_t lb_h_info[NCI_MAX_ATTRIB_LEN];
+  uint8_t lb_h_info_len;
+
+  uint8_t lf_protocol[NCI_PARAM_LEN_LF_PROTOCOL];
+  uint8_t lf_protocol_len;
+  uint8_t lf_t3t_flags2[NCI_PARAM_LEN_LF_T3T_FLAGS2];
+  uint8_t lf_t3t_flags2_len;
+  uint8_t lf_t3t_pmm[NCI_PARAM_LEN_LF_T3T_PMM];
+  uint8_t lf_t3t_id[NFA_CE_LISTEN_INFO_MAX][NCI_PARAM_LEN_LF_T3T_ID(NCI_VERSION_2_0)];
+
+  uint8_t fwi[NCI_PARAM_LEN_FWI];
+  uint8_t wt[NCI_PARAM_LEN_WT];
+  uint8_t atr_req_gen_bytes[NCI_MAX_GEN_BYTES_LEN];
+  uint8_t atr_req_gen_bytes_len;
+  uint8_t atr_res_gen_bytes[NCI_MAX_GEN_BYTES_LEN];
+  uint8_t atr_res_gen_bytes_len;
+
+  uint8_t pf_rc[NCI_PARAM_LEN_PF_RC];
+} tNFA_DM_PARAMS;
+
+/*
+**  NFA_NDEF CHO callback
+**  It returns true if NDEF is handled by connection handover module.
+*/
+typedef bool(tNFA_NDEF_CHO_CBACK)(uint32_t ndef_len, uint8_t* p_ndef_data);
+
+/* DM control block */
+typedef struct {
+  uint32_t flags; /* NFA_DM flags (see definitions for NFA_DM_FLAGS_*)    */
+  tNFA_DM_CBACK* p_dm_cback; /* NFA DM callback */
+  TIMER_LIST_ENT tle;
+
+#if (NXP_EXTNS == TRUE)
+  bool presence_check_deact_pending; /* true if deactivate while checking
+                                        presence */
+  tNFA_DEACTIVATE_TYPE presence_check_deact_type; /* deactivate type */
+#endif
+  /* NFC link connection management */
+  tNFA_CONN_CBACK* p_conn_cback;  /* callback for connection events       */
+  tNFA_TECHNOLOGY_MASK poll_mask; /* technologies being polled            */
+
+  tNFA_CONN_CBACK* p_excl_conn_cback; /* exclusive RF mode callback           */
+  tNFA_NDEF_CBACK* p_excl_ndef_cback; /* ndef callback for exclusive RF mdoe  */
+
+  tNFA_NDEF_CHO_CBACK*
+      p_ndef_cho_cback; /* NDEF callback for static connection handover */
+
+  tNFA_HANDLE poll_disc_handle; /* discovery handle for polling         */
+
+  uint8_t* p_activate_ntf; /* temp holding activation notfication  */
+  tHAL_API_GET_MAX_NFCEE* get_max_ee;
+
+  tNFC_RF_TECH_N_MODE
+      activated_tech_mode; /* previous activated technology and mode */
+  uint8_t activated_nfcid[NFC_KOVIO_MAX_LEN]; /* NFCID 0/1/2 or UID of
+                                                 ISO15694/Kovio  */
+  uint8_t activated_nfcid_len; /* length of NFCID or UID               */
+
+  /* NFC link discovery management */
+  tNFA_DM_DISC_CB disc_cb;
+
+  /* NDEF Type handler */
+  tNFA_DM_API_REG_NDEF_HDLR*
+      p_ndef_handler[NFA_NDEF_MAX_HANDLERS]; /* ndef handler table */
+
+  /* stored parameters */
+  tNFA_DM_PARAMS params;
+
+  /* SetConfig management */
+  uint32_t setcfg_pending_mask; /* Mask of to indicate whether pending
+                                   SET_CONFIGs require NFA_DM_SET_CONFIG_EVT.
+                                   LSB=oldest pending */
+  uint8_t setcfg_pending_num;   /* Number of setconfigs pending */
+
+  /* NFCC power mode */
+  uint8_t nfcc_pwr_mode; /* NFA_DM_PWR_MODE_FULL or NFA_DM_PWR_MODE_OFF_SLEEP */
+#if (NXP_EXTNS == TRUE)
+  uint32_t eDtaMode;        /* For enable the DTA type modes. */
+  uint8_t selected_uicc_id; /* Current selected UICC ID */
+#endif
+  uint8_t power_state;    /* current screen/power  state */
+} tNFA_DM_CB;
+
+/* Internal function prototypes */
+void nfa_dm_ndef_handle_message(tNFA_STATUS status, uint8_t* p_msg_buf,
+                                uint32_t len);
+void nfa_dm_ndef_dereg_all(void);
+void nfa_dm_act_conn_cback_notify(uint8_t event, tNFA_CONN_EVT_DATA* p_data);
+void nfa_dm_notify_activation_status(tNFA_STATUS status,
+                                     tNFA_TAG_PARAMS* p_params);
+void nfa_dm_disable_complete(void);
+
+/* Internal functions from nfa_rw */
+void nfa_rw_init(void);
+void nfa_rw_proc_disc_evt(tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER* p_data,
+                          bool excl_rf_not_active);
+tNFA_STATUS nfa_rw_send_raw_frame(NFC_HDR* p_data);
+
+/* Internal functions from nfa_ce */
+void nfa_ce_init(void);
+
+/* Pointer to compile-time configuration structure */
+extern tNFA_DM_DISC_FREQ_CFG* p_nfa_dm_rf_disc_freq_cfg;
+extern tNFA_HCI_CFG* p_nfa_hci_cfg;
+extern tNFA_DM_CFG* p_nfa_dm_cfg;
+extern uint8_t* p_nfa_dm_ce_cfg;
+extern uint8_t* p_nfa_dm_gen_cfg;
+extern uint8_t nfa_ee_max_ee_cfg;
+extern tNCI_DISCOVER_MAPS* p_nfa_dm_interface_mapping;
+extern uint8_t nfa_dm_num_dm_interface_mapping;
+extern bool nfa_poll_bail_out_mode;
+#if (NXP_EXTNS == TRUE)
+void nfa_dm_poll_disc_cback_dta_wrapper(tNFA_DM_RF_DISC_EVT event,
+                                        tNFC_DISCOVER* p_data);
+extern unsigned char appl_dta_mode_flag;
+#endif
+
+/* NFA device manager control block */
+extern tNFA_DM_CB nfa_dm_cb;
+
+void nfa_dm_init(void);
+void nfa_p2p_init(void);
+
+#if (NFA_SNEP_INCLUDED == true)
+void nfa_snep_init(bool is_dta_mode);
+#else
+#define nfa_snep_init(is_dta_mode)
+#endif
+
+void nfa_dta_init(void);
+#if (NFC_NFCEE_INCLUDED == true)
+void nfa_ee_init(void);
+void nfa_hci_init(void);
+#else
+#define nfa_ee_init()
+#define nfa_hci_init()
+#endif
+
+/* Action function prototypes */
+bool nfa_dm_enable(tNFA_DM_MSG* p_data);
+bool nfa_dm_disable(tNFA_DM_MSG* p_data);
+bool nfa_dm_set_config(tNFA_DM_MSG* p_data);
+bool nfa_dm_get_config(tNFA_DM_MSG* p_data);
+bool nfa_dm_act_request_excl_rf_ctrl(tNFA_DM_MSG* p_data);
+bool nfa_dm_act_release_excl_rf_ctrl(tNFA_DM_MSG* p_data);
+bool nfa_dm_act_enable_polling(tNFA_DM_MSG* p_data);
+bool nfa_dm_act_disable_polling(tNFA_DM_MSG* p_data);
+bool nfa_dm_act_enable_listening(tNFA_DM_MSG* p_data);
+bool nfa_dm_act_disable_listening(tNFA_DM_MSG* p_data);
+#if (NXP_EXTNS == TRUE)
+bool nfa_dm_act_disable_passive_listening(tNFA_DM_MSG* p_data);
+#endif
+bool nfa_dm_act_pause_p2p(tNFA_DM_MSG* p_data);
+bool nfa_dm_act_resume_p2p(tNFA_DM_MSG* p_data);
+bool nfa_dm_act_send_raw_frame(tNFA_DM_MSG* p_data);
+bool nfa_dm_set_p2p_listen_tech(tNFA_DM_MSG* p_data);
+bool nfa_dm_act_start_rf_discovery(tNFA_DM_MSG* p_data);
+bool nfa_dm_act_stop_rf_discovery(tNFA_DM_MSG* p_data);
+bool nfa_dm_act_set_rf_disc_duration(tNFA_DM_MSG* p_data);
+bool nfa_dm_act_select(tNFA_DM_MSG* p_data);
+bool nfa_dm_act_update_rf_params(tNFA_DM_MSG* p_data);
+bool nfa_dm_act_deactivate(tNFA_DM_MSG* p_data);
+bool nfa_dm_act_power_off_sleep(tNFA_DM_MSG* p_data);
+bool nfa_dm_ndef_reg_hdlr(tNFA_DM_MSG* p_data);
+bool nfa_dm_ndef_dereg_hdlr(tNFA_DM_MSG* p_data);
+bool nfa_dm_tout(tNFA_DM_MSG* p_data);
+bool nfa_dm_act_reg_vsc(tNFA_DM_MSG* p_data);
+bool nfa_dm_act_send_vsc(tNFA_DM_MSG* p_data);
+#if (NXP_EXTNS == TRUE)
+void nfa_dm_p2p_prio_logic_disable();
+bool nfa_dm_act_send_nxp(tNFA_DM_MSG* p_data);
+uint16_t nfa_dm_act_get_rf_disc_duration();
+#endif
+bool nfa_dm_act_disable_timeout(tNFA_DM_MSG* p_data);
+bool nfa_dm_act_nfc_cback_data(tNFA_DM_MSG* p_data);
+bool nfa_dm_set_power_sub_state (tNFA_DM_MSG *p_data);
+void nfa_dm_proc_nfcc_power_mode(uint8_t nfcc_power_mode);
+
+/* Main function prototypes */
+bool nfa_dm_evt_hdlr(NFC_HDR* p_msg);
+void nfa_dm_sys_enable(void);
+void nfa_dm_sys_disable(void);
+tNFA_STATUS nfa_dm_check_set_config(uint8_t tlv_list_len, uint8_t* p_tlv_list,
+                                    bool app_init);
+
+void nfa_dm_conn_cback_event_notify(uint8_t event, tNFA_CONN_EVT_DATA* p_data);
+
+/* Discovery function prototypes */
+void nfa_dm_disc_sm_execute(tNFA_DM_RF_DISC_SM_EVENT event,
+                            tNFA_DM_RF_DISC_DATA* p_data);
+tNFA_HANDLE nfa_dm_add_rf_discover(tNFA_DM_DISC_TECH_PROTO_MASK disc_mask,
+                                   tNFA_DM_DISC_HOST_ID host_id,
+                                   tNFA_DISCOVER_CBACK* p_disc_cback);
+void nfa_dm_delete_rf_discover(tNFA_HANDLE handle);
+void nfa_dm_start_excl_discovery(tNFA_TECHNOLOGY_MASK poll_tech_mask,
+                                 tNFA_LISTEN_CFG* p_listen_cfg,
+                                 tNFA_DISCOVER_CBACK* p_disc_cback);
+void nfa_dm_rel_excl_rf_control_and_notify(void);
+void nfa_dm_stop_excl_discovery(void);
+void nfa_dm_disc_new_state(tNFA_DM_RF_DISC_STATE new_state);
+
+void nfa_dm_start_rf_discover(void);
+void nfa_dm_rf_discover_select(uint8_t rf_disc_id, tNFA_NFC_PROTOCOL protocol,
+                               tNFA_INTF_TYPE rf_interface);
+tNFA_STATUS nfa_dm_rf_deactivate(tNFA_DEACTIVATE_TYPE deactivate_type);
+bool nfa_dm_is_protocol_supported(tNFA_NFC_PROTOCOL protocol, uint8_t sel_res);
+bool nfa_dm_is_active(void);
+tNFC_STATUS nfa_dm_disc_sleep_wakeup(void);
+tNFC_STATUS nfa_dm_disc_start_kovio_presence_check(void);
+bool nfa_dm_is_raw_frame_session(void);
+bool nfa_dm_is_p2p_paused(void);
+void nfa_dm_p2p_prio_logic_cleanup(void);
+void nfa_dm_deact_ntf_timeout();
+
+#if (NFC_NFCEE_INCLUDED == false)
+#define nfa_ee_get_tech_route(ps, ha) \
+  memset(ha, NFC_DH_ID, NFA_DM_MAX_TECH_ROUTE);
+#endif
+
+#if (BT_TRACE_VERBOSE == true)
+char* nfa_dm_nfc_revt_2_str(tNFC_RESPONSE_EVT event);
+#endif
+
+#if (NXP_EXTNS == TRUE)
+tNFC_STATUS nfc_ncif_reset_nfcc();
+#endif
+#endif /* NFA_DM_INT_H */
diff --git a/src/nfa/int/nfa_dta_int.h b/src/nfa/int/nfa_dta_int.h
new file mode 100644
index 0000000..2be5f96
--- /dev/null
+++ b/src/nfa/int/nfa_dta_int.h
@@ -0,0 +1,463 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2003-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the private interface file for the NFA DTA
+ *
+ ******************************************************************************/
+#ifndef NFA_DTA_INT_H
+#define NFA_DTA_INT_H
+
+#include "nfa_dta_api.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "nfc_api.h"
+#include "rw_api.h"
+#include "ce_api.h"
+
+#if (NFA_DTA_INCLUDED == true)
+
+/*****************************************************************************
+**  DTA definitions
+*****************************************************************************/
+#define NFA_DTA_PATTERN_NUMBER_INVALID 0xFFFF
+
+#define NFA_DTA_PATTERN_NUMBER_LLCP_CONNECT_BY_SAP 0x1200
+#define NFA_DTA_PATTERN_NUMBER_LLCP_CONNECT_BY_SN 0x1240
+#define NFA_DTA_PATTERN_NUMBER_LLCP_CONNECT_BY_SNL 0x1280
+
+#define NFA_DTA_PATTERN_NUMBER_SNEP_SERVER_ONLY 0x1300
+#define NFA_DTA_PATTERN_NUMBER_SNEP_DEFAULT_PUT_SHORT_NDEF 0x1301
+#define NFA_DTA_PATTERN_NUMBER_SNEP_DEFAULT_PUT_LONG_NDEF 0x1302
+#define NFA_DTA_PATTERN_NUMBER_SNEP_EXTENDED_GET 0x1303
+
+#define NFA_DTA_DISCOVER_PARAMS_MAX 6
+
+/* Header length for long NDEF text message */
+#define NDEF_WKT_TEXT_HDR_LEN 7
+/* Size of NDEF message for T3T write-tests ([DTA] $5.5.6) */
+#define NFA_DTA_T3T_WRITE_NDEF_SIZE 192
+/* System code to use for T3T Listen mode tests */
+#define NFA_DTA_T3T_LISTEN_SYSTEMCODE 0xBABE
+
+/* Maximum protocol preference rank */
+#define NFA_PROTOCOL_RANK_INVALID 0xFF
+
+#define NFA_DTA_SCRATCH_BUF_SIZE T3T_MSG_BLOCKSIZE
+
+#ifndef NFA_DTA_DEFAULT_CO_OUT_DSAP
+#if (NXP_EXTNS == TRUE)
+/* Default SAP[LT,CO-OUT-DEST] if SDP was not performed to get SAP from the LT
+ */
+#define NFA_DTA_DEFAULT_CO_OUT_DSAP 0x10
+#else
+/* Default SAP[LT,CO-OUT-DEST] if SDP was not performed to get SAP from the LT
+ */
+#define NFA_DTA_DEFAULT_CO_OUT_DSAP 0x12
+#endif
+#endif
+
+/*****************************************************************************
+* DTA state machine definitions
+*****************************************************************************/
+
+typedef struct {
+  bool tp_continue;                    /* NFA_DTA_CFG_TP_CONTINUE    */
+  tNFA_DTA_FL_POLL_LISTEN poll_listen; /* NFA_DTA_CFG_POLL_LISTEN    */
+  bool t4at_nfcdep_priority;           /* NFA_DTA_CFG_T4AT_NFCDEP_PRIORITY */
+  bool reactivation;                   /* NFA_DTA_CFG_REACTIVATION   */
+  uint16_t total_duration;             /* NFA_DTA_CFG_TOTAL_DURATION */
+#if (NXP_EXTNS == TRUE)
+  bool enable_dta_llcp;             /* NFA_DTA_CFG_LLCP */
+  tNFA_DTA_SNEP_MODE dta_snep_mode; /* NFA_DTA_CFG_SNEP */
+#endif
+  tNFA_DTA_EMVCO_PCD_MODE emvco_pcd_mode; /* NFA_DTA_CFG_EMVCO_PCD */
+} tNFA_DTA_CONFIG;
+
+/*****************************************************************************
+* DTA state machine definitions
+*****************************************************************************/
+/* DTA events */
+enum {
+  /* device manager local device API events */
+  NFA_DTA_API_ENABLE_EVT = NFA_SYS_EVT_START(NFA_ID_DTA),
+  NFA_DTA_API_DISABLE_EVT,
+  NFA_DTA_API_CONFIG_EVT,
+  NFA_DTA_API_START_EVT,
+  NFA_DTA_API_STOP_EVT,
+  NFA_DTA_ACTIVATE_EVT,
+  NFA_DTA_DEACTIVATE_EVT,
+  NFA_DTA_DATA_CBACK_EVT,
+
+  NFA_DTA_MAX_EVT
+};
+
+/* data type for NFA_DTA_API_ENABLE_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  bool auto_start;
+  tNFA_DTA_CBACK* p_cback;
+} tNFA_DTA_API_ENABLE;
+
+/* data type for NFA_DTA_API_START_EVT  */
+typedef struct {
+  NFC_HDR hdr;
+  uint16_t pattern_number;
+  uint8_t tlv_len;
+  uint8_t* p_tlv_params;
+} tNFA_DTA_API_START;
+
+/* data type for NFA_DTA_API_CONFIG  */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_DTA_CFG_ITEM item;
+  tNFA_DTA_CFG cfg_data;
+} tNFA_DTA_API_CONFIG;
+
+/* data type for NFA_DTA_DATA_CBACK_EVT */
+typedef struct {
+  uint8_t event;
+  tRW_DATA data;
+} tNFA_DTA_RW_DATA;
+
+typedef struct {
+  uint8_t event;
+  tCE_DATA data;
+} tNFA_DTA_CE_DATA;
+
+typedef struct {
+  tNFC_CONN_EVT event;
+  tNFC_CONN data;
+} tNFA_DTA_NFCDEP_DATA;
+
+enum { NFA_DTA_LLCP_CONNECT_CO_ECHO_OUT, NFA_DTA_LLCP_DISCONNECT_CO_ECHO_OUT };
+typedef uint8_t tNFA_DTA_LLCP_EVT;
+
+enum {
+  NFA_DTA_RW_DATA,
+  NFA_DTA_CE_DATA,
+  NFA_DTA_NFCDEP_DATA,
+  NFA_DTA_LLCP_DATA
+};
+
+typedef uint8_t tNFA_DTA_DATA_TYPE;
+
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_DTA_DATA_TYPE type;
+  union {
+    tNFA_DTA_RW_DATA rw;
+    tNFA_DTA_CE_DATA ce;
+    tNFA_DTA_NFCDEP_DATA nfcdep;
+    tNFA_DTA_LLCP_EVT llcp_evt;
+  } data;
+} tNFA_DTA_DATA_CBACK;
+
+/* All API message type */
+typedef union {
+  NFC_HDR hdr;
+  tNFA_DTA_API_ENABLE enable;
+  tNFA_DTA_API_CONFIG cfg;
+  tNFA_DTA_API_START start;
+  tNFA_DTA_DATA_CBACK data_cback;
+} tNFA_DTA_MSG;
+
+/* DTA states */
+enum {
+  NFA_DTA_ST_IDLE,
+  NFA_DTA_ST_DISCOVER, /* Polling/Listening */
+  NFA_DTA_ST_ACTIVATED /* Activated, listen mode */
+};
+typedef uint8_t tNFA_DTA_STATE;
+
+/* DTA Substates (while in ACTIVATED state) - substate enumerations are found in
+ * protocol-specific files (nfa_dta_XXX.c) */
+#define NFA_DTA_SST_IDLE 0
+typedef uint8_t tNFA_DTA_SUBSTATE;
+
+/* DTA discovery states */
+enum {
+  NFA_DTA_DISC_STATE_IDLE,
+  NFA_DTA_DISC_STATE_DISCOVERY,
+  NFA_DTA_DISC_STATE_POLL_ACTIVE,
+  NFA_DTA_DISC_STATE_W4_ALL_DISCOVERIES,
+  NFA_DTA_DISC_STATE_W4_HOST_SELECT,
+  NFA_DTA_DISC_STATE_LISTEN_ACTIVE,
+  NFA_DTA_DISC_STATE_LISTEN_SLEEP,
+  NFA_DTA_DISC_STATE_MAX
+};
+
+/*****************************************************************************
+* DTA control block definitions
+*****************************************************************************/
+
+/* NDEF buffer definitions */
+enum {
+  NFA_DTA_BUF_READ,  /* Buffer for RW Read requests */
+  NFA_DTA_BUF_WRITE, /* Buffer for RW Write requests */
+  NFA_DTA_BUF_MAX
+};
+
+typedef struct {
+  uint8_t* p_data;
+  uint32_t max_size;
+  uint32_t cur_size;
+  uint32_t offset; /* current read/write offset */
+} tNFA_DTA_BUF_CB;
+
+/* T4T listen mode test application */
+enum {
+  NFA_DTA_T4T_CE_APP_NONE,     /* Not selected */
+  NFA_DTA_T4T_CE_APP_LOOPBACK, /* loopback test applicaiton */
+  NFA_DTA_T4T_CE_APP_PROP      /* propretary test application */
+};
+
+/* DTA test step command */
+typedef tNFC_STATUS (*tNFA_DTA_CMD_FCN)(void*);
+
+/* dta control block flags */
+#define NFA_DTA_FL_ENABLED 0x00000001 /* DTA is enabled */
+/* Automatically start discovery when NFC is enabled */
+#define NFA_DTA_FL_AUTOSTART 0x00000002
+/* DTA is stopping (NFA_DtaStop called) */
+#define NFA_DTA_FL_STOPPING 0x00000004
+/* DTA is being disabled (NFA_DtaDisable called) */
+#define NFA_DTA_FL_DISABLING 0x00000008
+/* T4T/NFCDEP is deactivating to IDLE (need to DESELECT first) */
+#define NFA_DTA_FL_T4T_DESELECT_DEACT 0x00000010
+
+/* DTA control block */
+typedef struct {
+  uint32_t dta_flags; /* dta_flags must be first item in structure (statically
+                         intialized to 0 on startup) */
+
+  /* Configuration */
+  tNFA_DTA_CONFIG cfg;
+
+  /* DTA State Machine */
+  tNFA_DTA_STATE state;
+  tNFA_DTA_SUBSTATE substate; /* Current protocol-specific sub-state */
+  tNFA_DTA_CBACK* p_cback;    /* Applicatation for DTA event notification */
+
+  /* DTA test parameters */
+  uint16_t pattern_number;
+  uint16_t pattern_number_old;
+
+  /* Discovery Parameters */
+  uint8_t disc_state;
+  uint8_t disc_params_num;
+  tNFC_DISCOVER_PARAMS disc_params[NFA_DTA_DISCOVER_PARAMS_MAX];
+
+  /* Activation parameters */
+  tNFC_ACTIVATE_DEVT activate_params;
+  uint8_t cur_protocol_rank; /* perference ranking of currently discovered
+                                protocol */
+
+  tRW_CBACK* p_rw_cback;
+  tCE_CBACK* p_ce_cback;
+
+  TIMER_LIST_ENT
+  protocol_timer; /* timer for the activated protocol if needed */
+
+  uint8_t t4t_ce_app; /* T4T listen mode test application */
+  tCE_T4T_AID_HANDLE
+      t4t_dta_aid_hdl; /* T4T registration handle for proprietary dta aid */
+  tCE_T4T_AID_HANDLE
+      t4t_prop_aid_hdl; /* T4T registration handle for proprietary aid */
+  uint8_t nfc_dep_wt;
+
+  bool llcp_cl_more_to_read; /* true if there is more to read in llcp cl link*/
+  bool llcp_co_more_to_read; /* true if there is more to read in llcp recieve
+                                window*/
+  bool llcp_is_initiator;    /* TURE if IUT is LLCP initiator */
+  uint16_t llcp_local_link_miu;  /* link MIU of IUT               */
+  uint16_t llcp_remote_link_miu; /* link MIU of LT                */
+
+  uint8_t llcp_pattern_num_sap; /* SAP of pattern number exchange */
+
+  uint8_t llcp_cl_in_local_sap;   /* SAP of IUT-CL-IN-DEST */
+  uint8_t llcp_cl_out_local_sap;  /* SAP of IUT-CL-OUT-SRC */
+  uint8_t llcp_cl_out_remote_sap; /* SAP of LT-CL-OUT-DEST */
+
+  uint8_t llcp_co_in_local_sap;   /* SAP of IUT-CO-IN-DEST */
+  uint8_t llcp_co_in_remote_sap;  /* SAP of LT-CO-IN-SRC   */
+  uint8_t llcp_co_out_local_sap;  /* SAP of IUT-CO-OUT-SRC */
+  uint8_t llcp_co_out_remote_sap; /* SAP of LT-CO-OUT-DEST */
+
+  uint16_t llcp_co_out_remote_miu; /* MIU of LT-CO-OUT-DEST */
+  uint8_t llcp_co_out_remote_rw;   /* RW of LT-CO-OUT-DEST  */
+
+/* establishing outbound on connection-oriented */
+#define NFA_DTA_LLCP_FLAGS_CO_OUT_CONNECTING 0x01
+/* established outbound on connection-oriented  */
+#define NFA_DTA_LLCP_FLAGS_CO_OUT_CONNECTED 0x02
+
+  uint8_t llcp_flags;      /* internal flags for LLCP echo test */
+  uint8_t llcp_sdp_tid_cl; /* SDP transaction ID for outbound connectionless */
+  uint8_t
+      llcp_sdp_tid_co; /* SDP transaction ID for outbound connection-oriented */
+
+  TIMER_LIST_ENT llcp_cl_echo_timer; /* timer for the connectionless echo test
+                                        application      */
+  TIMER_LIST_ENT llcp_co_echo_timer; /* timer for the connection-oriented echo
+                                        test application */
+  BUFFER_Q
+  llcp_cl_buffer; /* buffer for the connectionless echo test application */
+  BUFFER_Q llcp_co_buffer; /* buffer for the connection-oriented echo test
+                              application*/
+
+  tNFA_HANDLE snep_server_handle;
+  tNFA_HANDLE snep_server_conn_handle;
+  tNFA_HANDLE snep_client_handle;
+#if (NXP_EXTNS == TRUE)
+#define NFA_DTA_SNEP_CLIENT_TEST_FLAGS_DEFAULT_SERVER 0x01
+#define NFA_DTA_SNEP_CLIENT_TEST_FLAGS_EXTENDED_SERVER 0x02
+#define NFA_DTA_SNEP_CLIENT_TEST_FLAGS_PUT_SHORT_NDEF 0x04
+#define NFA_DTA_SNEP_CLIENT_TEST_FLAGS_PUT_LONG_NDEF 0x08
+#define NFA_DTA_SNEP_CLIENT_TEST_FLAGS_GET 0x10
+
+  uint8_t snep_client_test_flags;
+#endif
+  uint8_t* p_snep_short_ndef;
+  uint32_t snep_short_ndef_size;
+  uint8_t* p_snep_long_ndef;
+  uint32_t snep_long_ndef_size;
+
+  /* DTA buffer for NDEF read/write */
+  tNFA_DTA_BUF_CB buf_cb[NFA_DTA_BUF_MAX];
+  uint32_t ndef_size; /* Size of NDEF message from NDEF detection */
+
+  /* Scratch buffer for miscelaneous use */
+  uint8_t scratch_buf[NFA_DTA_SCRATCH_BUF_SIZE];
+
+  /* DTA Test command table */
+  tNFA_DTA_CMD_FCN*
+      p_cur_cmd_tbl; /* Current table of commands for current test */
+  uint8_t cur_cmd_idx;
+} tNFA_DTA_CB;
+extern tNFA_DTA_CB nfa_dta_cb;
+
+/* NFA_SYS info for DTA */
+extern const tNFA_SYS_REG nfa_dta_sys_reg;
+
+/* DTA startup setconfig parameters */
+extern uint8_t* p_nfa_dta_start_up_cfg;
+extern uint8_t nfa_dta_start_up_cfg_len;
+
+/*****************************************************************************
+* DTA internal funciton protoytpes
+*****************************************************************************/
+/* Internal function prototypes */
+void nfa_dta_deactivate(uint8_t deactivate_type);
+void nfa_dta_shutdown(void);
+void nfa_dta_discover_start(void);
+
+/* nfa_sys handler for DTA */
+bool nfa_dta_evt_hdlr(NFC_HDR* p_msg);
+void nfa_dta_sys_disable(void);
+
+/* State machine action functions */
+bool nfa_dta_enable(tNFA_DTA_MSG* p_data);
+bool nfa_dta_disable(tNFA_DTA_MSG* p_data);
+bool nfa_dta_config(tNFA_DTA_MSG* p_data);
+bool nfa_dta_start(tNFA_DTA_MSG* p_data);
+bool nfa_dta_handle_deact(tNFA_DTA_MSG* p_data);
+bool nfa_dta_stop(tNFA_DTA_MSG* p_data);
+bool nfa_dta_run_test(tNFA_DTA_MSG* p_data);
+bool nfa_dta_proc_data(tNFA_DTA_MSG* p_msg_data);
+
+/* Utility functions */
+void nfa_dta_test_set_state(tNFA_DTA_STATE state);
+void nfa_dta_test_set_substate(tNFA_DTA_SUBSTATE substate);
+void nfa_dta_free_ndef_buf(uint8_t ndef_idx);
+uint8_t* nfa_dta_realloc_buf(uint8_t ndef_idx, uint32_t size);
+void nfa_dta_t3t_nfcid_rand(uint8_t nfcid2[NCI_RF_F_UID_LEN]);
+
+/* Test function entry points (in nfa_dta_XXX.c) */
+void nfa_dta_nfcdep_poll_test_start(void);
+void nfa_dta_nfcdep_proc_data(tNFC_CONN_EVT event, tNFC_CONN* p_data);
+void nfa_dta_t1t_poll_test_start(void);
+void nfa_dta_t2t_poll_test_start(void);
+void nfa_dta_t3t_poll_test_start(void);
+void nfa_dta_t4t_poll_test_start(void);
+
+void nfa_dta_nfcdep_listen_test_start(void);
+void nfa_dta_t3t_listen_test_start(void);
+void nfa_dta_t4t_listen_test_start(void);
+
+void nfa_dta_t1t_rw_cback(uint8_t event, tRW_DATA* p_data);
+void nfa_dta_t2t_rw_cback(uint8_t event, tRW_DATA* p_data);
+void nfa_dta_t3t_rw_cback(uint8_t event, tRW_DATA* p_data);
+void nfa_dta_t4t_rw_cback(uint8_t event, tRW_DATA* p_data);
+
+void nfa_dta_t3t_ce_cback(uint8_t event, tCE_DATA* p_data);
+void nfa_dta_t4t_ce_cback(uint8_t event, tCE_DATA* p_data);
+
+void nfa_dta_ce_cback(uint8_t event, tCE_DATA* p_ce_data);
+
+void nfa_dta_t4t_register_apps(void);
+void nfa_dta_t4t_deregister_apps(void);
+
+void nfa_dta_llcp_init(void);
+void nfa_dta_llcp_set_gen_bytes(void);
+void nfa_dta_llcp_clear_gen_bytes(void);
+void nfa_dta_llcp_register_pattern_number_service(void);
+void nfa_dta_llcp_deregister_pattern_number_service(void);
+void nfa_dta_llcp_register_echo(void);
+void nfa_dta_llcp_deregister_echo(void);
+void nfa_dta_llcp_activate_link(void);
+void nfa_dta_llcp_connect_co_echo_out(void);
+void nfa_dta_llcp_disconnect_co_echo_out(void);
+
+void nfa_dta_snep_init(void);
+void nfa_dta_snep_register(void);
+void nfa_dta_snep_deregister(void);
+#if (NXP_EXTNS == TRUE)
+void nfa_dta_snep_mode(tNFA_DTA_SNEP_MODE mode);
+#endif
+
+void nfa_dta_emvco_pcd_config_nfcc(bool enable);
+void nfa_dta_emvco_pcd_start(void);
+void nfa_dta_emvco_pcd_cback(uint8_t event, tRW_DATA* p_data);
+
+extern uint8_t* p_nfa_dta_brcm_start_up_cfg;
+extern uint8_t nfa_dta_brcm_start_up_cfg_len;
+extern uint8_t* p_nfa_dta_start_up_vsc_cfg;
+
+#endif /* (NFA_DTA_INCLUDED == true) */
+#endif /* NFA_DTA_INT_H */
diff --git a/src/nfa/int/nfa_ee_int.h b/src/nfa/int/nfa_ee_int.h
new file mode 100644
index 0000000..547dd7a
--- /dev/null
+++ b/src/nfa/int/nfa_ee_int.h
@@ -0,0 +1,753 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the private interface file for the NFA EE.
+ *
+ ******************************************************************************/
+#ifndef NFA_EE_INT_H
+#define NFA_EE_INT_H
+#include "nfc_api.h"
+#include "nfa_ee_api.h"
+#include "nfa_sys.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+#define NFA_EE_DEBUG BT_TRACE_VERBOSE
+/* the number of tNFA_EE_ECBs (for NFCEEs and DH) */
+#define NFA_EE_NUM_ECBS (NFA_EE_MAX_EE_SUPPORTED + 1)
+/* The index for DH in nfa_ee_cb.ee_cb[] */
+#define NFA_EE_CB_4_DH NFA_EE_MAX_EE_SUPPORTED
+#define NFA_EE_INVALID 0xFF
+/* only A, B, F, Bprime are supported by UICC now */
+#define NFA_EE_MAX_TECH_ROUTE 4
+
+#ifndef NFA_EE_AID_CFG_TAG_NAME
+/* AID                             */
+#define NFA_EE_AID_CFG_TAG_NAME 0x4F
+
+#endif
+
+/* NFA EE events */
+enum {
+  NFA_EE_API_DISCOVER_EVT = NFA_SYS_EVT_START(NFA_ID_EE),
+  NFA_EE_API_REGISTER_EVT,
+  NFA_EE_API_DEREGISTER_EVT,
+  NFA_EE_API_MODE_SET_EVT,
+  NFA_EE_API_SET_TECH_CFG_EVT,
+  NFA_EE_API_SET_PROTO_CFG_EVT,
+  NFA_EE_API_ADD_AID_EVT,
+  NFA_EE_API_REMOVE_AID_EVT,
+  NFA_EE_API_LMRT_SIZE_EVT,
+  NFA_EE_API_UPDATE_NOW_EVT,
+  NFA_EE_API_CONNECT_EVT,
+  NFA_EE_API_SEND_DATA_EVT,
+  NFA_EE_API_DISCONNECT_EVT,
+
+  NFA_EE_NCI_DISC_RSP_EVT,
+  NFA_EE_NCI_DISC_NTF_EVT,
+  NFA_EE_NCI_MODE_SET_RSP_EVT,
+#if (NXP_EXTNS == TRUE)
+  NFA_EE_NCI_MODE_SET_INFO,
+  NFA_EE_NCI_PWR_LNK_CTRL_SET_EVT,
+  NFA_EE_NCI_PWR_LNK_CTRL_RSP_EVT,
+#endif
+  NFA_EE_NCI_CONN_EVT,
+  NFA_EE_NCI_DATA_EVT,
+  NFA_EE_NCI_ACTION_NTF_EVT,
+  NFA_EE_NCI_DISC_REQ_NTF_EVT,
+  NFA_EE_NCI_WAIT_RSP_EVT,
+
+  NFA_EE_ROUT_TIMEOUT_EVT,
+  NFA_EE_DISCV_TIMEOUT_EVT,
+  NFA_EE_CFG_TO_NFCC_EVT,
+  NFA_EE_API_ADD_APDU_EVT,
+  NFA_EE_API_REMOVE_APDU_EVT,
+  NFA_EE_NCI_NFCEE_STATUS_NTF_EVT,
+  NFA_EE_MAX_EVT
+};
+
+typedef uint16_t tNFA_EE_INT_EVT;
+/* for listen mode routing table*/
+#define NFA_EE_AE_ROUTE 0x80
+#define NFA_EE_AE_VS 0x40
+
+/* NFA EE Management state */
+enum {
+  NFA_EE_EM_STATE_INIT = 0,
+  NFA_EE_EM_STATE_INIT_DONE,
+  NFA_EE_EM_STATE_RESTORING,
+  NFA_EE_EM_STATE_DISABLING,
+  NFA_EE_EM_STATE_DISABLED,
+
+  NFA_EE_EM_STATE_MAX
+};
+typedef uint8_t tNFA_EE_EM_STATE;
+
+/* NFA EE connection status */
+enum {
+  NFA_EE_CONN_ST_NONE, /* not connected */
+  NFA_EE_CONN_ST_WAIT, /* connection is initiated; waiting for ack */
+  NFA_EE_CONN_ST_CONN, /* connected; can send/receive data */
+  NFA_EE_CONN_ST_DISC, /* disconnecting; waiting for ack */
+  NFA_EE_CONN_ST_MAX
+};
+typedef uint8_t tNFA_EE_CONN_ST;
+#if (NXP_EXTNS == TRUE)
+#define NFA_EE_ROUT_BUF_SIZE 720
+#define NFA_EE_ROUT_BUF_SIZE_STAT 200
+#else
+#define NFA_EE_ROUT_BUF_SIZE 540
+#endif
+
+#define NFA_EE_ROUT_MAX_TLV_SIZE 0xFD
+
+#if (NXP_EXTNS == TRUE)
+#define NFA_EE_NUM_PROTO 6
+#else
+#define NFA_EE_NUM_PROTO 5
+#endif
+
+#define NFA_EE_NUM_TECH 3
+#if (NXP_EXTNS == TRUE)
+#define NFA_UICC_ID 0x02
+#define NFA_ESE_ID 0xC0
+#define NFA_EE_BUFFER_FUTURE_EXT 15
+#define NFA_EE_PROTO_ROUTE_ENTRY_SIZE 5
+#define NFA_EE_TECH_ROUTE_ENTRY_SIZE 5
+
+/**
+ * Max Routing Table Size = 720
+ * After allocating size for Technology based routing and Protocol based
+ *routing,
+ * the remaining size can be used for AID based routing
+ *
+ * Size for 1 Technology route entry = 5 bytes (includes Type(1 byte),
+ * Length (1 byte), Value (3 bytes - Power state, Tech Type, Location)
+ * TOTAL TECH ROUTE SIZE = 5 * 3  = 15 (For Tech A, B, F)
+ *
+ * Size for 1 Protocol route entry = 5 bytes (includes Type(1 byte),
+ * Length (1 byte), Value (3 bytes - Power state, Tech Type, Location)
+ * TOTAL PROTOCOL ROUTE SIZE = 5 * 6 = 30 (Protocols ISO-DEP, NFC-DEP, ISO-7816,
+ *T1T, T2T, T3T)
+ *
+ * SIZE FOR AID = 720 - 15 - 30 = 675
+ * BUFFER for future extensions = 15
+ * TOTAL SIZE FOR AID = 675 - 15 = 660
+ */
+#define NFA_EE_TOTAL_TECH_ROUTE_SIZE \
+  (NFA_EE_PROTO_ROUTE_ENTRY_SIZE * NFA_EE_NUM_TECH)
+#define NFA_EE_TOTAL_PROTO_ROUTE_SIZE \
+  (NFA_EE_PROTO_ROUTE_ENTRY_SIZE * NFA_EE_NUM_PROTO)
+
+#define NFA_EE_TOTAL_PROTO_TECH_FUTURE_EXT_ROUTE_SIZE             \
+  (NFA_EE_TOTAL_TECH_ROUTE_SIZE + NFA_EE_TOTAL_PROTO_ROUTE_SIZE + \
+   NFA_EE_BUFFER_FUTURE_EXT)
+#define NFA_EE_MAX_AID_CFG_LEN \
+  (NFA_EE_ROUT_BUF_SIZE - NFA_EE_TOTAL_PROTO_TECH_FUTURE_EXT_ROUTE_SIZE)
+#define NFA_EE_MAX_AID_CFG_LEN_STAT (160)
+#else
+#define NFA_EE_MAX_AID_CFG_LEN (510)
+#endif
+#define NFA_EE_TOTAL_APDU_PATTERN_SIZE 250
+#define NFA_EE_APDU_ROUTE_MASK 8 /* APDU route location mask*/
+/* NFA EE control block flags:
+ * use to indicate an API function has changed the configuration of the
+ * associated NFCEE
+ * The flags are cleared when the routing table/VS is updated */
+/* technology routing changed         */
+#define NFA_EE_ECB_FLAGS_TECH 0x02
+/* protocol routing changed           */
+#define NFA_EE_ECB_FLAGS_PROTO 0x04
+/* AID routing changed                */
+#define NFA_EE_ECB_FLAGS_AID 0x08
+/* VS changed                         */
+#define NFA_EE_ECB_FLAGS_VS 0x10
+/* Restore related                    */
+#define NFA_EE_ECB_FLAGS_RESTORE 0x20
+/* routing flags changed              */
+#define NFA_EE_ECB_FLAGS_ROUTING 0x0E
+/* NFCEE Discover Request NTF is set  */
+#define NFA_EE_ECB_FLAGS_DISC_REQ 0x40
+/* DISC_REQ N reported before DISC N  */
+#define NFA_EE_ECB_FLAGS_ORDER 0x80
+/* APDU routing changed                */
+#define NFA_EE_ECB_FLAGS_APDU 0x0100
+typedef uint16_t tNFA_EE_ECB_FLAGS;
+
+/* part of tNFA_EE_STATUS; for internal use only  */
+/* waiting for restore to full power mode to complete */
+#define NFA_EE_STATUS_RESTORING 0x20
+
+/* this bit is in ee_status for internal use only */
+#define NFA_EE_STATUS_INT_MASK 0x20
+
+/* NFA-EE information for a particular NFCEE Entity (including DH) */
+typedef struct {
+  tNFA_TECHNOLOGY_MASK
+      tech_switch_on; /* default routing - technologies switch_on  */
+  tNFA_TECHNOLOGY_MASK
+      tech_switch_off; /* default routing - technologies switch_off */
+  tNFA_TECHNOLOGY_MASK
+      tech_battery_off; /* default routing - technologies battery_off*/
+  tNFA_PROTOCOL_MASK
+      proto_switch_on; /* default routing - protocols switch_on     */
+  tNFA_PROTOCOL_MASK
+      proto_switch_off; /* default routing - protocols switch_off    */
+  tNFA_PROTOCOL_MASK
+      proto_battery_off; /* default routing - protocols battery_off   */
+#if (NXP_EXTNS == TRUE)
+  tNFA_PROTOCOL_MASK
+      proto_screen_lock; /* default routing - protocols screen_lock    */
+  tNFA_PROTOCOL_MASK
+      proto_screen_off; /* default routing - protocols screen_off  */
+  tNFA_PROTOCOL_MASK
+      proto_screen_off_lock; /* default routing - protocols screen_off  */
+  tNFA_TECHNOLOGY_MASK
+      tech_screen_lock; /* default routing - technologies screen_lock*/
+  tNFA_TECHNOLOGY_MASK
+      tech_screen_off; /* default routing - technologies screen_off*/
+  tNFA_TECHNOLOGY_MASK
+      tech_screen_off_lock; /* default routing - technologies screen_off*/
+#endif
+  tNFA_EE_CONN_ST conn_st;   /* connection status */
+  uint8_t conn_id;           /* connection id */
+  tNFA_EE_CBACK* p_ee_cback; /* the callback function */
+/* Each APDU entry has an associated apdu_pwr_cfg ,apdu_rt_info ,apdu_len
+ * apdu_cfg[] contains APDU and APDU mask and maybe some other VS information in TLV format
+ * The first T is always NFA_EE_APDU_CFG_TAG_NAME, the L is the actual APDU length and mask length
+ * the apdu_len is the total length of all the TLVs associated with this AID
+ * entry
+ */
+  uint8_t apdu_len[NFA_EE_MAX_APDU_PATTERN_ENTRIES]; /* the actual lengths in apdu_cfg */
+  uint8_t apdu_pwr_cfg[NFA_EE_MAX_APDU_PATTERN_ENTRIES]; /* power configuration of this APDU Pattern entry */
+  uint8_t apdu_rt_info[NFA_EE_MAX_APDU_PATTERN_ENTRIES]; /* route/vs info for this APDU PATTERN entry */
+  uint8_t apdu_rt_loc[NFA_EE_MAX_APDU_PATTERN_ENTRIES];/* route location info for this APDU Pattern entry */
+  uint8_t apdu_cfg[NFA_EE_TOTAL_APDU_PATTERN_SIZE];     /* routing entries based on APDU PATTERN */
+  uint8_t apdu_pattern_entries;   /* The number of APDU PATTERN entries in aid_cfg */
+/* Each AID entry has an ssociated aid_len, aid_pwr_cfg, aid_rt_info.
+ * aid_cfg[] contains AID and maybe some other VS information in TLV format
+ * The first T is always NFA_EE_AID_CFG_TAG_NAME, the L is the actual AID length
+ * the aid_len is the total length of all the TLVs associated with this AID
+ * entry
+ */
+#if (NXP_EXTNS == TRUE)
+  uint8_t* aid_len;     /* the actual lengths in aid_cfg */
+  uint8_t* aid_pwr_cfg; /* power configuration of this AID entry */
+  uint8_t* aid_rt_info; /* route/vs info for this AID entry */
+  uint8_t* aid_rt_loc;  /* route location info for this AID entry */
+  uint8_t* aid_cfg;     /* routing entries based on AID */
+  uint8_t* aid_info;    /* AID info prefix/subset routing */
+  uint8_t aid_rt_loc_stat[NFA_EE_MAX_AID_ENTRIES]; /* route location info for this
+                                                    AID entry */
+  uint8_t aid_len_stat[NFA_EE_MAX_AID_ENTRIES]; /* the actual lengths in aid_cfg */
+  uint8_t aid_pwr_cfg_stat[NFA_EE_MAX_AID_ENTRIES]; /* power configuration of this
+                                                     AID entry */
+  uint8_t aid_rt_info_stat[NFA_EE_MAX_AID_ENTRIES]; /* route/vs info for this AID
+                                                     entry */
+  uint8_t aid_cfg_stat[NFA_EE_MAX_AID_CFG_LEN];     /* routing entries based on AID */
+#else
+  uint8_t aid_len[NFA_EE_MAX_AID_ENTRIES]; /* the actual lengths in aid_cfg */
+  uint8_t aid_pwr_cfg[NFA_EE_MAX_AID_ENTRIES]; /* power configuration of this
+                                                  AID entry */
+  uint8_t aid_rt_info[NFA_EE_MAX_AID_ENTRIES]; /* route/vs info for this AID
+                                                  entry */
+  uint8_t aid_cfg[NFA_EE_MAX_AID_CFG_LEN];     /* routing entries based on AID */
+  uint8_t aid_info[NFA_EE_MAX_AID_ENTRIES]; /* route/vs info for this AID
+                                                  entry */
+#endif
+  uint8_t aid_entries;
+  uint8_t nfcee_id;      /* ID for this NFCEE */
+  uint8_t ee_status;     /* The NFCEE status */
+  uint8_t ee_old_status; /* The NFCEE status before going to low power mode */
+  tNFA_EE_INTERFACE
+      ee_interface[NFC_MAX_EE_INTERFACE]; /* NFCEE supported interface */
+  tNFA_EE_TLV ee_tlv[NFC_MAX_EE_TLVS];    /* the TLV */
+  uint8_t num_interface;                  /* number of Target interface */
+  uint8_t num_tlvs;                       /* number of TLVs */
+  uint8_t ee_power_supply_status; /* power supply of NFCEE*/
+  tNFA_EE_ECB_FLAGS ecb_flags;            /* the flags of this control block */
+  tNFA_EE_INTERFACE use_interface; /* NFCEE interface used for the connection */
+  tNFA_NFC_PROTOCOL la_protocol;   /* Listen A protocol    */
+  tNFA_NFC_PROTOCOL lb_protocol;   /* Listen B protocol    */
+  tNFA_NFC_PROTOCOL lf_protocol;   /* Listen F protocol    */
+  tNFA_NFC_PROTOCOL lbp_protocol;  /* Listen B' protocol   */
+  uint8_t size_mask; /* the size for technology and protocol routing */
+  uint16_t size_aid; /* the size for aid routing */
+  uint16_t size_apdu;/* the size for apdu routing */
+#if (NXP_EXTNS == TRUE)
+  tNFA_NFC_PROTOCOL pa_protocol; /* Passive poll A SWP Reader   */
+  tNFA_NFC_PROTOCOL pb_protocol; /* Passive poll B SWP Reader   */
+  uint8_t ee_req_op;             /* add or remove req ntf*/
+#endif
+} tNFA_EE_ECB;
+
+/* data type for NFA_EE_API_DISCOVER_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_EE_CBACK* p_cback;
+} tNFA_EE_API_DISCOVER;
+
+/* data type for NFA_EE_API_REGISTER_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_EE_CBACK* p_cback;
+} tNFA_EE_API_REGISTER;
+
+/* data type for NFA_EE_API_DEREGISTER_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  int index;
+} tNFA_EE_API_DEREGISTER;
+
+/* data type for NFA_EE_API_MODE_SET_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_EE_ECB* p_cb;
+  uint8_t nfcee_id;
+  uint8_t mode;
+} tNFA_EE_API_MODE_SET;
+/* data type for NFA_EE_API_POWER_LINK_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  uint8_t nfcee_id;
+  uint8_t cfg_value;
+} tNFA_EE_API_POWER_LINK_EVT;
+
+/* data type for NFA_EE_API_SET_TECH_CFG_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_EE_ECB* p_cb;
+  uint8_t nfcee_id;
+  tNFA_TECHNOLOGY_MASK technologies_switch_on;
+  tNFA_TECHNOLOGY_MASK technologies_switch_off;
+  tNFA_TECHNOLOGY_MASK technologies_battery_off;
+#if (NXP_EXTNS == TRUE)
+  tNFA_TECHNOLOGY_MASK technologies_screen_lock;
+  tNFA_TECHNOLOGY_MASK technologies_screen_off;
+  tNFA_TECHNOLOGY_MASK technologies_screen_off_lock;
+#endif
+} tNFA_EE_API_SET_TECH_CFG;
+
+/* data type for NFA_EE_API_SET_PROTO_CFG_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_EE_ECB* p_cb;
+  uint8_t nfcee_id;
+  tNFA_PROTOCOL_MASK protocols_switch_on;
+  tNFA_PROTOCOL_MASK protocols_switch_off;
+  tNFA_PROTOCOL_MASK protocols_battery_off;
+#if (NXP_EXTNS == TRUE)
+  tNFA_PROTOCOL_MASK protocols_screen_lock;
+  tNFA_PROTOCOL_MASK protocols_screen_off;
+  tNFA_PROTOCOL_MASK protocols_screen_off_lock;
+#endif
+
+} tNFA_EE_API_SET_PROTO_CFG;
+
+/* data type for NFA_EE_API_ADD_AID_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_EE_ECB* p_cb;
+  uint8_t nfcee_id;
+  uint8_t aid_len;
+  uint8_t* p_aid;
+  tNFA_EE_PWR_STATE power_state;
+#if (NXP_EXTNS == TRUE)
+  uint8_t aid_info;
+#endif
+} tNFA_EE_API_ADD_AID;
+
+/* data type for NFA_EE_API_REMOVE_AID_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  uint8_t aid_len;
+  uint8_t* p_aid;
+} tNFA_EE_API_REMOVE_AID;
+
+/* data type for NFA_EE_API_ADD_APDU_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_EE_ECB* p_cb;
+  uint8_t nfcee_id;
+  uint8_t* p_apdu;
+  uint8_t apdu_len;
+  uint8_t* p_mask;
+  uint8_t mask_len;
+  tNFA_EE_PWR_STATE power_state;
+} tNFA_EE_API_ADD_APDU;
+
+/* data type for NFA_EE_API_REMOVE_APDU_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  uint8_t apdu_len;
+  uint8_t* p_apdu;
+} tNFA_EE_API_REMOVE_APDU;
+
+/* data type for NFA_EE_API_LMRT_SIZE_EVT */
+typedef NFC_HDR tNFA_EE_API_LMRT_SIZE;
+
+/* data type for NFA_EE_API_CONNECT_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_EE_ECB* p_cb;
+  uint8_t nfcee_id;
+  uint8_t ee_interface;
+  tNFA_EE_CBACK* p_cback;
+} tNFA_EE_API_CONNECT;
+
+/* data type for NFA_EE_API_SEND_DATA_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_EE_ECB* p_cb;
+  uint8_t nfcee_id;
+  uint16_t data_len;
+  uint8_t* p_data;
+} tNFA_EE_API_SEND_DATA;
+
+/* data type for NFA_EE_API_DISCONNECT_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_EE_ECB* p_cb;
+  uint8_t nfcee_id;
+} tNFA_EE_API_DISCONNECT;
+
+typedef struct {
+  NFC_HDR hdr;
+  tNFC_STATUS status; /* The event status. */
+} tNFA_EE_MSG_STATUS;
+
+/* common data type for internal events with nfa_ee_use_cfg_cb[] as true */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_EE_ECB* p_cb;
+  uint8_t nfcee_id;
+} tNFA_EE_CFG_HDR;
+
+/* data type for tNFC_RESPONSE_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  void* p_data;
+} tNFA_EE_NCI_RESPONSE;
+
+/* data type for NFA_EE_NCI_DISC_RSP_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFC_NFCEE_DISCOVER_REVT* p_data;
+} tNFA_EE_NCI_DISC_RSP;
+
+/* data type for NFA_EE_NCI_DISC_NTF_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFC_NFCEE_INFO_REVT* p_data;
+} tNFA_EE_NCI_DISC_NTF;
+
+/* data type for NFA_EE_NCI_MODE_SET_RSP_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFC_NFCEE_MODE_SET_REVT* p_data;
+} tNFA_EE_NCI_MODE_SET;
+
+#if (NXP_EXTNS == TRUE)
+typedef struct {
+  NFC_HDR hdr;
+  tNFC_NFCEE_MODE_SET_INFO* p_data;
+} tNFA_EE_NCI_SET_MODE_INFO;
+
+/* data type for NFA_EE_NCI_MODE_SET_RSP_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFC_NFCEE_EE_PWR_LNK_REVT* p_data;
+} tNFA_EE_NCI_PWR_LNK_CTRL;
+#endif
+
+/* data type for NFA_EE_NCI_WAIT_RSP_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  void* p_data;
+  uint8_t opcode;
+} tNFA_EE_NCI_WAIT_RSP;
+
+/* data type for NFA_EE_NCI_CONN_EVT and NFA_EE_NCI_DATA_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  uint8_t conn_id;
+  tNFC_CONN_EVT event;
+  tNFC_CONN* p_data;
+} tNFA_EE_NCI_CONN;
+
+/* data type for NFA_EE_NCI_ACTION_NTF_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFC_EE_ACTION_REVT* p_data;
+} tNFA_EE_NCI_ACTION;
+
+/* data type for NFA_EE_NCI_DISC_REQ_NTF_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFC_EE_DISCOVER_REQ_REVT* p_data;
+} tNFA_EE_NCI_DISC_REQ;
+
+/* data type for NFA_EE_NCI_NFCEE_STATUS_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFC_NFCEE_STATUS_REVT* p_data;
+} tNFA_EE_NCI_NFCEE_STATUS_NTF;
+
+/* union of all event data types */
+typedef union {
+  NFC_HDR hdr;
+  tNFA_EE_CFG_HDR cfg_hdr;
+  tNFA_EE_API_DISCOVER ee_discover;
+  tNFA_EE_API_REGISTER ee_register;
+  tNFA_EE_API_DEREGISTER deregister;
+  tNFA_EE_API_MODE_SET mode_set;
+  tNFA_EE_API_SET_TECH_CFG set_tech;
+  tNFA_EE_API_SET_PROTO_CFG set_proto;
+  tNFA_EE_API_ADD_AID add_aid;
+  tNFA_EE_API_REMOVE_AID rm_aid;
+  tNFA_EE_API_ADD_APDU add_apdu;
+  tNFA_EE_API_REMOVE_APDU rm_apdu;
+  tNFA_EE_API_LMRT_SIZE lmrt_size;
+  tNFA_EE_API_CONNECT connect;
+  tNFA_EE_API_SEND_DATA send_data;
+  tNFA_EE_API_DISCONNECT disconnect;
+  tNFA_EE_NCI_DISC_RSP disc_rsp;
+  tNFA_EE_NCI_DISC_NTF disc_ntf;
+  tNFA_EE_NCI_MODE_SET mode_set_rsp;
+#if (NXP_EXTNS == TRUE)
+  tNFA_EE_NCI_SET_MODE_INFO mode_set_info;
+  tNFA_EE_API_POWER_LINK_EVT pwr_lnk_ctrl_set;
+  tNFA_EE_NCI_PWR_LNK_CTRL pwr_lnk_ctrl_rsp;
+#endif
+  tNFA_EE_NCI_WAIT_RSP wait_rsp;
+  tNFA_EE_NCI_CONN conn;
+  tNFA_EE_NCI_ACTION act;
+  tNFA_EE_NCI_DISC_REQ disc_req;
+  tNFA_EE_NCI_NFCEE_STATUS_NTF nfcee_status_ntf;
+} tNFA_EE_MSG;
+
+/* type for State Machine (SM) action functions */
+typedef void (*tNFA_EE_SM_ACT)(tNFA_EE_MSG* p_data);
+
+/*****************************************************************************
+**  control block
+*****************************************************************************/
+#define NFA_EE_CFGED_UPDATE_NOW 0x80
+/* either switch off or battery off is configured */
+#define NFA_EE_CFGED_OFF_ROUTING 0x40
+
+/* the following status are the definition used in ee_cfg_sts */
+#define NFA_EE_STS_CHANGED_ROUTING 0x01
+#define NFA_EE_STS_CHANGED_VS 0x02
+#define NFA_EE_STS_CHANGED 0x0f
+#define NFA_EE_STS_PREV_ROUTING 0x10
+#define NFA_EE_STS_PREV 0xf0
+
+/* need to report NFA_EE_UPDATED_EVT */
+#define NFA_EE_WAIT_UPDATE 0x10
+/* waiting for the rsp of set routing commands */
+#define NFA_EE_WAIT_UPDATE_RSP 0x20
+#define NFA_EE_WAIT_UPDATE_ALL 0xF0
+
+typedef uint8_t tNFA_EE_WAIT;
+
+/* set this bit when waiting for HCI to finish the initialization process in
+ * NFA_EE_EM_STATE_RESTORING */
+#define NFA_EE_FLAG_WAIT_HCI 0x01
+/* set this bit when EE needs to notify the p_enable_cback at the end of NFCEE
+ * discover process in NFA_EE_EM_STATE_RESTORING */
+#define NFA_EE_FLAG_NOTIFY_HCI 0x02
+/* set this bit when gracefully disable with outstanding NCI connections */
+#define NFA_EE_FLAG_WAIT_DISCONN 0x04
+#if (NXP_EXTNS == TRUE)
+/* set this bit when NFC-DEP is configured in the routing table */
+#define NFA_EE_FLAG_CFG_NFC_DEP 0x05
+#endif
+#if(NXP_EXTNS == TRUE)
+#define NFA_EE_HCI_CONN_CLOSE  0x8
+#endif
+typedef uint8_t tNFA_EE_FLAGS;
+
+/* NFCEE DISCOVER in progress       */
+#define NFA_EE_DISC_STS_ON 0x00
+/* disable NFCEE DISCOVER           */
+#define NFA_EE_DISC_STS_OFF 0x01
+/* received NFCEE DISCOVER REQ NTF  */
+#define NFA_EE_DISC_STS_REQ 0x02
+/* received NFA_EE_MODE_SET_COMPLETE  */
+#define NFA_EE_MODE_SET_COMPLETE 0x03
+#if (NXP_EXTNS == TRUE)
+/* received NFCEE_MODE_SET NTF  */
+#define NFA_EE_MODE_SET_NTF 0x04
+#define NFA_EE_RECOVERY 0x05
+#endif
+
+typedef uint8_t tNFA_EE_DISC_STS;
+
+typedef void(tNFA_EE_ENABLE_DONE_CBACK)(tNFA_EE_DISC_STS status);
+
+#if (NXP_EXTNS == TRUE)
+typedef void(tNFA_EE_CLEAR_ALL_PIPES_CBACK)(uint8_t source_host);
+#endif
+
+/* NFA EE Management control block */
+typedef struct {
+  tNFA_EE_ECB ecb[NFA_EE_NUM_ECBS]; /* control block for DH and NFCEEs  */
+  TIMER_LIST_ENT timer;             /* timer to send info to NFCC       */
+  TIMER_LIST_ENT discv_timer;       /* timer to end NFCEE discovery     */
+  tNFA_EE_CBACK* p_ee_cback[NFA_EE_MAX_CBACKS]; /* to report EE events       */
+  tNFA_EE_CBACK* p_ee_disc_cback; /* to report EE discovery result    */
+  tNFA_EE_ENABLE_DONE_CBACK*
+      p_enable_cback; /* callback to notify on enable done*/
+#if (NXP_EXTNS == TRUE)
+  tNFA_EE_CLEAR_ALL_PIPES_CBACK*
+      p_clear_all_pipes_cback; /* callback to notify UICC CAP */
+#endif
+  tNFA_EE_EM_STATE em_state; /* NFA-EE state initialized or not  */
+  uint8_t wait_rsp;          /* num of NCI rsp expected (update) */
+  uint8_t num_ee_expecting;  /* number of ee_info still expecting*/
+  uint8_t cur_ee;            /* the number of ee_info in cb      */
+  uint8_t ee_cfged;          /* the bit mask of configured ECBs  */
+  uint8_t ee_cfg_sts;        /* configuration status             */
+  tNFA_EE_WAIT ee_wait_evt;  /* Pending event(s) to be reported  */
+  tNFA_EE_FLAGS ee_flags;    /* flags                            */
+  uint8_t nfcee_id;
+  uint8_t mode;
+  uint8_t route_block_control; /* controls route block feature   */
+} tNFA_EE_CB;
+
+/* Order of Routing entries in Routing Table */
+#define NCI_ROUTE_ORDER_AID  0x01/* AID routing order */
+#define NCI_ROUTE_ORDER_PATTERN 0x02 /* Pattern routing order*/
+#define NCI_ROUTE_ORDER_SYS_CODE 0x03/* System Code routing order*/
+#define NCI_ROUTE_ORDER_PROTOCOL 0x04/* Protocol routing order*/
+#define NCI_ROUTE_ORDER_TECHNOLOGY 0x05/* Technology routing order*/
+
+/*****************************************************************************
+**  External variables
+*****************************************************************************/
+
+/* NFA EE control block */
+
+extern tNFA_EE_CB nfa_ee_cb;
+#if (NXP_EXTNS == TRUE)
+extern bool gNfaProvisionMode;
+#endif
+
+/*****************************************************************************
+**  External functions
+*****************************************************************************/
+/* function prototypes - exported from nfa_ee_main.c */
+void nfa_ee_sys_enable(void);
+void nfa_ee_sys_disable(void);
+
+/* event handler function type */
+bool nfa_ee_evt_hdlr(NFC_HDR* p_msg);
+void nfa_ee_proc_nfcc_power_mode(uint8_t nfcc_power_mode);
+#if (NFC_NFCEE_INCLUDED == true)
+void nfa_ee_get_tech_route(uint8_t power_state, uint8_t* p_handles);
+#endif
+void nfa_ee_proc_evt(tNFC_RESPONSE_EVT event, void* p_data);
+tNFA_EE_ECB* nfa_ee_find_ecb(uint8_t nfcee_id);
+tNFA_EE_ECB* nfa_ee_find_ecb_by_conn_id(uint8_t conn_id);
+#if (NXP_EXTNS == TRUE)
+uint16_t nfa_ee_lmrt_size();
+uint8_t nfa_ee_get_supported_tech_list(uint8_t nfcee_id);
+bool nfa_ee_nfeeid_active(uint8_t nfee_id);
+uint8_t NFA_check_p61_CL_Activated();
+uint16_t nfa_ee_find_max_aid_config_length();
+uint16_t nfa_ee_api_get_max_aid_config_length();
+extern uint8_t nfa_ee_connectionClosed();
+#endif
+uint8_t nfa_ee_ecb_to_mask(tNFA_EE_ECB* p_cb);
+void nfa_ee_restore_one_ecb(tNFA_EE_ECB* p_cb);
+bool nfa_ee_is_active(tNFA_HANDLE nfcee_id);
+
+/* Action function prototypes - nfa_ee_act.c */
+void nfa_ee_api_discover(tNFA_EE_MSG* p_data);
+void nfa_ee_api_register(tNFA_EE_MSG* p_data);
+void nfa_ee_api_deregister(tNFA_EE_MSG* p_data);
+void nfa_ee_api_mode_set(tNFA_EE_MSG* p_data);
+void nfa_ee_api_power_link_set(tNFA_EE_MSG* p_data);
+void nfa_ee_api_set_tech_cfg(tNFA_EE_MSG* p_data);
+void nfa_ee_api_set_proto_cfg(tNFA_EE_MSG* p_data);
+void nfa_ee_api_add_aid(tNFA_EE_MSG* p_data);
+void nfa_ee_api_remove_aid(tNFA_EE_MSG* p_data);
+void nfa_ee_api_lmrt_size(tNFA_EE_MSG* p_data);
+void nfa_ee_api_update_now(tNFA_EE_MSG* p_data);
+void nfa_ee_api_connect(tNFA_EE_MSG* p_data);
+void nfa_ee_api_send_data(tNFA_EE_MSG* p_data);
+void nfa_ee_api_disconnect(tNFA_EE_MSG* p_data);
+void nfa_ee_report_disc_done(bool notify_sys);
+void nfa_ee_nci_disc_rsp(tNFA_EE_MSG* p_data);
+void nfa_ee_nci_disc_ntf(tNFA_EE_MSG* p_data);
+void nfa_ee_nci_mode_set_rsp(tNFA_EE_MSG* p_data);
+#if (NXP_EXTNS == TRUE)
+extern void nfa_hci_conn_cback(uint8_t conn_id, tNFC_CONN_EVT event,
+                               tNFC_CONN* p_data);
+void nfa_ee_nci_set_mode_info(tNFA_EE_MSG* p_data);
+void nfa_ee_nci_pwr_link_ctrl_rsp(tNFA_EE_MSG* p_data);
+#endif
+void nfa_ee_nci_nfcee_status_ntf(tNFA_EE_MSG* p_data);
+void nfa_ee_nci_wait_rsp(tNFA_EE_MSG* p_data);
+void nfa_ee_nci_conn(tNFA_EE_MSG* p_data);
+void nfa_ee_nci_action_ntf(tNFA_EE_MSG* p_data);
+void nfa_ee_nci_disc_req_ntf(tNFA_EE_MSG* p_data);
+void nfa_ee_rout_timeout(tNFA_EE_MSG* p_data);
+void nfa_ee_discv_timeout(tNFA_EE_MSG* p_data);
+void nfa_ee_lmrt_to_nfcc(tNFA_EE_MSG* p_data);
+void nfa_ee_update_rout(void);
+void nfa_ee_report_event(tNFA_EE_CBACK* p_cback, tNFA_EE_EVT event,
+                         tNFA_EE_CBACK_DATA* p_data);
+tNFA_EE_ECB* nfa_ee_find_aid_offset(uint8_t aid_len, uint8_t* p_aid,
+                                    int* p_offset, int* p_entry);
+void nfa_ee_remove_labels(void);
+int nfa_ee_find_total_aid_len(tNFA_EE_ECB* p_cb, int start_entry);
+void nfa_ee_start_timer(void);
+void nfa_ee_reg_cback_enable_done(tNFA_EE_ENABLE_DONE_CBACK* p_cback);
+void nfa_ee_report_update_evt(void);
+void find_and_resolve_tech_conflict();
+extern void nfa_ee_proc_hci_info_cback(void);
+void nfa_ee_check_disable(void);
+bool nfa_ee_restore_ntf_done(void);
+void nfa_ee_check_restore_complete(void);
+void nfa_ee_api_add_apdu(tNFA_EE_MSG* p_data);
+void nfa_ee_api_remove_apdu(tNFA_EE_MSG* p_data);
+#endif /* NFA_P2P_INT_H */
diff --git a/src/nfa/int/nfa_hci_int.h b/src/nfa/int/nfa_hci_int.h
new file mode 100644
index 0000000..66f3cb3
--- /dev/null
+++ b/src/nfa/int/nfa_hci_int.h
@@ -0,0 +1,709 @@
+/******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the private interface file for the NFA HCI.
+ *
+ ******************************************************************************/
+#ifndef NFA_HCI_INT_H
+#define NFA_HCI_INT_H
+
+#include "nfa_hci_api.h"
+#include "nfa_sys.h"
+#include "nfa_ee_api.h"
+
+extern uint8_t HCI_LOOPBACK_DEBUG;
+
+/* NFA HCI DEBUG states */
+#define NFA_HCI_DEBUG_ON 0x01
+#define NFA_HCI_DEBUG_OFF 0x00
+
+#if (NXP_EXTNS == TRUE)
+bool MW_RCVRY_FW_DNLD_ALLOWED;
+#endif
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+#define NFA_HCI_HOST_ID_UICC0 0x02 /* Host ID for UICC 0 */
+
+#define NFA_HCI_HOST_ID_UICC0_NCI2 0x80 /* Host ID for UICC 0 */
+/* Lost host specific gate */
+#define NFA_HCI_LAST_HOST_SPECIFIC_GATE 0xEF
+
+#define NFA_HCI_SESSION_ID_LEN 8 /* HCI Session ID length */
+/* Maximum pipes that can be created on a generic pipe  */
+#define NFA_MAX_PIPES_IN_GENERIC_GATE 0x0F
+
+#if (NXP_EXTNS == TRUE)
+/* HCI Host Type length */
+#define NFA_HCI_HOST_TYPE_LEN 2
+/* HCI controller ETSI Version 9 */
+#define NFA_HCI_CONTROLLER_VERSION_9 9
+/* HCI controller ETSI Version 12 */
+#define NFA_HCI_CONTROLLER_VERSION_12 12
+/* Host ID for UICC 1 */
+#define NFA_HCI_HOST_ID_UICC1 0x81
+/* Host ID for ESE    */
+#define NFA_HCI_HOST_ID_ESE 0xC0
+/* Bit Mask to indicate session ID poll is done or not*/
+#define NFA_HCI_SESSION_ID_MASK 0x0100
+/* Bit mask to indicate ETSI12 config done or not*/
+#define NFA_HCI_NFCEE_CONFIG_MASK 0x0200
+/* event to set the nfcee config bit*/
+#define NFA_HCI_SET_CONFIG_EVENT 0x01
+/* event to clear the nfcee config bit*/
+#define NFA_HCI_CLEAR_CONFIG_EVENT 0x02
+#endif
+
+/* HCI SW Version number                       */
+#define NFA_HCI_VERSION_SW 0x090000
+/* HCI HW Version number                       */
+#define NFA_HCI_VERSION_HW 0x000000
+#define NFA_HCI_VENDOR_NAME \
+  "HCI" /* Vendor Name                                 */
+/* Model ID                                    */
+#define NFA_HCI_MODEL_ID 00
+/* HCI Version                                 */
+#define NFA_HCI_VERSION 90
+
+/* NFA HCI states */
+/* HCI is disabled  */
+#define NFA_HCI_STATE_DISABLED 0x00
+/* HCI performing Initialization sequence */
+#define NFA_HCI_STATE_STARTUP 0x01
+/* HCI is waiting for initialization of other host in the network */
+#define NFA_HCI_STATE_WAIT_NETWK_ENABLE 0x02
+/* HCI is waiting to handle api commands  */
+#define NFA_HCI_STATE_IDLE 0x03
+/* HCI is waiting for response to command sent */
+#define NFA_HCI_STATE_WAIT_RSP 0x04
+/* Removing all pipes prior to removing the gate */
+#define NFA_HCI_STATE_REMOVE_GATE 0x05
+/* Removing all pipes and gates prior to deregistering the app */
+#define NFA_HCI_STATE_APP_DEREGISTER 0x06
+#define NFA_HCI_STATE_RESTORE 0x07 /* HCI restore */
+/* HCI is waiting for initialization of other host in the network after restore
+ */
+#define NFA_HCI_STATE_RESTORE_NETWK_ENABLE 0x08
+#if (NXP_EXTNS == TRUE)
+/* HCI is waiting for NFCEE initialization */
+#define NFA_HCI_STATE_NFCEE_ENABLE 0x09
+#define NFA_HCI_STATE_EE_RECOVERY 0x0A
+#endif
+
+#if (NXP_EXTNS == TRUE)
+#define NFA_HCI_MAX_RSP_WAIT_TIME 0x0C
+/* After the reception of WTX, maximum response timeout value is 30 sec */
+#define NFA_HCI_CHAIN_PKT_RSP_TIMEOUT 30000
+/* Wait time to give response timeout to application if WTX not received*/
+#define NFA_HCI_WTX_RESP_TIMEOUT 3000
+/* time out for wired mode response after RF deativation */
+#define NFA_HCI_DWP_RSP_WAIT_TIMEOUT 2000
+/* time out for wired session aborted(0xE6 ntf) due to SWP switched to UICC*/
+#define NFA_HCI_DWP_SESSION_ABORT_TIMEOUT 5000
+/* delay between session ID poll to check if the reset host is initilized or not
+ */
+#define NFA_HCI_SESSION_ID_POLL_DELAY 50
+/* retry count for session ID poll*/
+#define NFA_HCI_MAX_SESSION_ID_RETRY_CNT 0x0A
+/* NFCEE disc timeout default value in sec*/
+#define NFA_HCI_NFCEE_DISC_TIMEOUT 0x02
+/*  NXP specific events */
+/* Event to read the number of NFCEE configured in NFCC*/
+#define NFA_HCI_GET_NUM_NFCEE_CONFIGURED 0xF1
+/* Event to read the session ID of all the Secure Element*/
+#define NFA_HCI_READ_SESSIONID 0xF2
+/* Event to start ETSI 12 configuration*/
+#define NFA_HCI_INIT_NFCEE_CONFIG 0xF3
+/* NFCEE ETSI 12 configuration complete*/
+#define NFA_HCI_NFCEE_CONFIG_COMPLETE 0xF9
+#endif
+
+typedef uint8_t tNFA_HCI_STATE;
+
+/* NFA HCI PIPE states */
+#define NFA_HCI_PIPE_CLOSED 0x00 /* Pipe is closed */
+#define NFA_HCI_PIPE_OPENED 0x01 /* Pipe is opened */
+
+#define NFA_HCI_INVALID_INX 0xFF
+
+typedef uint8_t tNFA_HCI_COMMAND;
+typedef uint8_t tNFA_HCI_RESPONSE;
+
+/* NFA HCI Internal events */
+enum {
+  NFA_HCI_API_REGISTER_APP_EVT =
+      NFA_SYS_EVT_START(NFA_ID_HCI), /* Register APP with HCI */
+  NFA_HCI_API_DEREGISTER_APP_EVT,    /* Deregister an app from HCI */
+  NFA_HCI_API_GET_APP_GATE_PIPE_EVT, /* Get the list of gate and pipe associated
+                                        to the application */
+  NFA_HCI_API_ALLOC_GATE_EVT, /* Allocate a dyanmic gate for the application */
+  NFA_HCI_API_DEALLOC_GATE_EVT, /* Deallocate a previously allocated gate to the
+                                   application */
+  NFA_HCI_API_GET_HOST_LIST_EVT,   /* Get the list of Host in the network */
+  NFA_HCI_API_GET_REGISTRY_EVT,    /* Get a registry entry from a host */
+  NFA_HCI_API_SET_REGISTRY_EVT,    /* Set a registry entry on a host */
+  NFA_HCI_API_CREATE_PIPE_EVT,     /* Create a pipe between two gates */
+  NFA_HCI_API_OPEN_PIPE_EVT,       /* Open a pipe */
+  NFA_HCI_API_CLOSE_PIPE_EVT,      /* Close a pipe */
+  NFA_HCI_API_DELETE_PIPE_EVT,     /* Delete a pipe */
+  NFA_HCI_API_ADD_STATIC_PIPE_EVT, /* Add a static pipe */
+  NFA_HCI_API_SEND_CMD_EVT,        /* Send command via pipe */
+  NFA_HCI_API_SEND_RSP_EVT,        /* Application Response to a command */
+#if (NXP_EXTNS == TRUE)
+  NFA_HCI_API_CONFIGURE_EVT, /* Configure NFCEE as per ETSI 12 standards */
+#endif
+  NFA_HCI_API_SEND_EVENT_EVT, /* Send event via pipe */
+
+  NFA_HCI_RSP_NV_READ_EVT,  /* Non volatile read complete event */
+  NFA_HCI_RSP_NV_WRITE_EVT, /* Non volatile write complete event */
+  NFA_HCI_RSP_TIMEOUT_EVT,  /* Timeout to response for the HCP Command packet */
+  NFA_HCI_CHECK_QUEUE_EVT
+#if (NXP_EXTNS == TRUE)
+  ,
+  NFA_HCI_SESSION_ID_POLL_DELAY_TIMEOUT_EVT /*timeout event to read session id
+                                               on timeout*/
+  ,
+  NFA_HCI_NFCEE_DISCOVER_TIMEOUT_EVT /*timeout event for waiting for all
+                                        configured nfcee to be discovered*/
+#endif
+};
+
+#define NFA_HCI_FIRST_API_EVENT NFA_HCI_API_REGISTER_APP_EVT
+#define NFA_HCI_LAST_API_EVENT NFA_HCI_API_SEND_EVENT_EVT
+
+typedef uint16_t tNFA_HCI_INT_EVT;
+
+/* Internal event structures.
+**
+** Note, every internal structure starts with a NFC_HDR and an app handle
+*/
+
+/* data type for NFA_HCI_API_REGISTER_APP_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE hci_handle;
+  char app_name[NFA_MAX_HCI_APP_NAME_LEN + 1];
+  tNFA_HCI_CBACK* p_cback;
+  bool b_send_conn_evts;
+} tNFA_HCI_API_REGISTER_APP;
+
+/* data type for NFA_HCI_API_DEREGISTER_APP_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE hci_handle;
+  char app_name[NFA_MAX_HCI_APP_NAME_LEN + 1];
+} tNFA_HCI_API_DEREGISTER_APP;
+
+/* data type for NFA_HCI_API_GET_APP_GATE_PIPE_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE hci_handle;
+} tNFA_HCI_API_GET_APP_GATE_PIPE;
+
+/* data type for NFA_HCI_API_ALLOC_GATE_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE hci_handle;
+  uint8_t gate;
+} tNFA_HCI_API_ALLOC_GATE;
+
+/* data type for NFA_HCI_API_DEALLOC_GATE_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE hci_handle;
+  uint8_t gate;
+} tNFA_HCI_API_DEALLOC_GATE;
+
+/* data type for NFA_HCI_API_GET_HOST_LIST_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE hci_handle;
+  tNFA_STATUS status;
+} tNFA_HCI_API_GET_HOST_LIST;
+
+/* data type for NFA_HCI_API_GET_REGISTRY_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE hci_handle;
+  uint8_t pipe;
+  uint8_t reg_inx;
+} tNFA_HCI_API_GET_REGISTRY;
+
+/* data type for NFA_HCI_API_SET_REGISTRY_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE hci_handle;
+  uint8_t pipe;
+  uint8_t reg_inx;
+  uint8_t size;
+  uint8_t data[NFA_MAX_HCI_CMD_LEN];
+} tNFA_HCI_API_SET_REGISTRY;
+
+/* data type for NFA_HCI_API_CREATE_PIPE_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE hci_handle;
+  tNFA_STATUS status;
+  uint8_t source_gate;
+  uint8_t dest_host;
+  uint8_t dest_gate;
+} tNFA_HCI_API_CREATE_PIPE_EVT;
+
+/* data type for NFA_HCI_API_OPEN_PIPE_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE hci_handle;
+  tNFA_STATUS status;
+  uint8_t pipe;
+} tNFA_HCI_API_OPEN_PIPE_EVT;
+
+/* data type for NFA_HCI_API_CLOSE_PIPE_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE hci_handle;
+  tNFA_STATUS status;
+  uint8_t pipe;
+} tNFA_HCI_API_CLOSE_PIPE_EVT;
+
+/* data type for NFA_HCI_API_DELETE_PIPE_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE hci_handle;
+  tNFA_STATUS status;
+  uint8_t pipe;
+} tNFA_HCI_API_DELETE_PIPE_EVT;
+
+/* data type for NFA_HCI_API_ADD_STATIC_PIPE_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE hci_handle;
+  tNFA_STATUS status;
+  uint8_t host;
+  uint8_t gate;
+  uint8_t pipe;
+} tNFA_HCI_API_ADD_STATIC_PIPE_EVT;
+
+/* data type for NFA_HCI_API_SEND_EVENT_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE hci_handle;
+  uint8_t pipe;
+  uint8_t evt_code;
+  uint16_t evt_len;
+  uint8_t* p_evt_buf;
+  uint16_t rsp_len;
+  uint8_t* p_rsp_buf;
+#if (NXP_EXTNS == TRUE)
+  uint32_t rsp_timeout;
+#else
+  uint16_t rsp_timeout;
+#endif
+} tNFA_HCI_API_SEND_EVENT_EVT;
+
+#if (NXP_EXTNS == TRUE)
+/* data type for tNFA_HCI_API_CONFIGURE_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  uint16_t config_nfcee_event;
+} tNFA_HCI_API_CONFIGURE_EVT;
+
+typedef uint16_t tNFA_CONFIG_STATE;
+#endif
+
+/* data type for NFA_HCI_API_SEND_CMD_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE hci_handle;
+  uint8_t pipe;
+  uint8_t cmd_code;
+  uint16_t cmd_len;
+  uint8_t data[NFA_MAX_HCI_CMD_LEN];
+} tNFA_HCI_API_SEND_CMD_EVT;
+
+/* data type for NFA_HCI_RSP_NV_READ_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  uint8_t block;
+  uint16_t size;
+  tNFA_STATUS status;
+} tNFA_HCI_RSP_NV_READ_EVT;
+
+/* data type for NFA_HCI_RSP_NV_WRITE_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_STATUS status;
+} tNFA_HCI_RSP_NV_WRITE_EVT;
+
+/* data type for NFA_HCI_API_SEND_RSP_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE hci_handle;
+  uint8_t pipe;
+  uint8_t response;
+  uint8_t size;
+  uint8_t data[NFA_MAX_HCI_RSP_LEN];
+} tNFA_HCI_API_SEND_RSP_EVT;
+
+/* common data type for internal events */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE hci_handle;
+} tNFA_HCI_COMM_DATA;
+
+/* union of all event data types */
+typedef union {
+  NFC_HDR hdr;
+  tNFA_HCI_COMM_DATA comm;
+
+  /* API events */
+  tNFA_HCI_API_REGISTER_APP app_info; /* Register/Deregister an application */
+  tNFA_HCI_API_GET_APP_GATE_PIPE get_gate_pipe_list; /* Get the list of gates
+                                                        and pipes created for
+                                                        the application */
+  tNFA_HCI_API_ALLOC_GATE
+      gate_info; /* Allocate a dynamic gate to the application */
+  tNFA_HCI_API_DEALLOC_GATE
+      gate_dealloc; /* Deallocate the gate allocated to the application */
+  tNFA_HCI_API_CREATE_PIPE_EVT create_pipe;         /* Create a pipe */
+  tNFA_HCI_API_OPEN_PIPE_EVT open_pipe;             /* Open a pipe */
+  tNFA_HCI_API_CLOSE_PIPE_EVT close_pipe;           /* Close a pipe */
+  tNFA_HCI_API_DELETE_PIPE_EVT delete_pipe;         /* Delete a pipe */
+  tNFA_HCI_API_ADD_STATIC_PIPE_EVT add_static_pipe; /* Add a static pipe */
+  tNFA_HCI_API_GET_HOST_LIST
+      get_host_list; /* Get the list of Host in the network */
+  tNFA_HCI_API_GET_REGISTRY get_registry; /* Get a registry entry on a host */
+  tNFA_HCI_API_SET_REGISTRY set_registry; /* Set a registry entry on a host */
+  tNFA_HCI_API_SEND_CMD_EVT send_cmd;     /* Send a event on a pipe to a host */
+  tNFA_HCI_API_SEND_RSP_EVT
+      send_rsp; /* Response to a command sent on a pipe to a host */
+  tNFA_HCI_API_SEND_EVENT_EVT send_evt; /* Send a command on a pipe to a host */
+
+  /* Internal events */
+  tNFA_HCI_RSP_NV_READ_EVT nv_read;   /* Read Non volatile data */
+  tNFA_HCI_RSP_NV_WRITE_EVT nv_write; /* Write Non volatile data */
+
+#if (NXP_EXTNS == TRUE)
+  tNFA_HCI_API_CONFIGURE_EVT
+      config_info; /* Configuration of NFCEE for ETSI12 */
+#endif
+} tNFA_HCI_EVENT_DATA;
+
+/*****************************************************************************
+**  control block
+*****************************************************************************/
+
+/* Dynamic pipe control block */
+typedef struct {
+  uint8_t pipe_id;                /* Pipe ID */
+  tNFA_HCI_PIPE_STATE pipe_state; /* State of the Pipe */
+  uint8_t local_gate;             /* local gate id */
+  uint8_t dest_host; /* Peer host to which this pipe is connected */
+  uint8_t dest_gate; /* Peer gate to which this pipe is connected */
+} tNFA_HCI_DYN_PIPE;
+
+/* Dynamic gate control block */
+typedef struct {
+  uint8_t gate_id;        /* local gate id */
+  tNFA_HANDLE gate_owner; /* NFA-HCI handle assigned to the application which
+                             owns the gate */
+  uint32_t pipe_inx_mask; /* Bit 0 == pipe inx 0, etc */
+} tNFA_HCI_DYN_GATE;
+
+/* Admin gate control block */
+typedef struct {
+  tNFA_HCI_PIPE_STATE pipe01_state; /* State of Pipe '01' */
+  uint8_t
+      session_id[NFA_HCI_SESSION_ID_LEN]; /* Session ID of the host network */
+} tNFA_ADMIN_GATE_INFO;
+
+/* Link management gate control block */
+typedef struct {
+  tNFA_HCI_PIPE_STATE pipe00_state; /* State of Pipe '00' */
+  uint16_t rec_errors;              /* Receive errors */
+} tNFA_LINK_MGMT_GATE_INFO;
+
+/* Identity management gate control block */
+typedef struct {
+  uint32_t pipe_inx_mask;  /* Bit 0 == pipe inx 0, etc */
+  uint16_t version_sw;     /* Software version number */
+  uint16_t version_hw;     /* Hardware version number */
+  uint8_t vendor_name[20]; /* Vendor name */
+  uint8_t model_id;        /* Model ID */
+  uint8_t hci_version;     /* HCI Version */
+} tNFA_ID_MGMT_GATE_INFO;
+
+/* Internal flags */
+/* sub system is being disabled */
+#define NFA_HCI_FL_DISABLING 0x01
+#define NFA_HCI_FL_NV_CHANGED 0x02 /* NV Ram changed */
+#if (NXP_EXTNS == TRUE)
+#define NFA_HCI_FL_CONN_PIPE 0x01
+#define NFA_HCI_FL_APDU_PIPE 0x02
+#define NFA_HCI_FL_OTHER_PIPE 0x04
+#define NFA_HCI_CONN_UICC_PIPE 0x0A
+#define NFA_HCI_CONN_ESE_PIPE 0x16
+#define NFA_HCI_APDU_PIPE 0x19
+#define NFA_HCI_CONN_UICC2_PIPE 0x23 /*Connectivity pipe no of UICC2*/
+#define NFA_HCI_INIT_MAX_RETRY 20
+#endif
+/* NFA HCI control block */
+typedef struct {
+  tNFA_HCI_STATE hci_state;   /* state of the HCI */
+  uint8_t num_nfcee;          /* Number of NFCEE ID Discovered */
+  tNFA_EE_INFO ee_info[NFA_HCI_MAX_HOST_IN_NETWORK];    /*NFCEE ID Info*/
+  uint8_t num_ee_dis_req_ntf; /* Number of ee discovery request ntf received */
+  uint8_t num_hot_plug_evts;  /* Number of Hot plug events received after ee
+                                 discovery disable ntf */
+  uint8_t inactive_host[NFA_HCI_MAX_HOST_IN_NETWORK]; /* Inactive host in the
+                                                         host network */
+  uint8_t reset_host[NFA_HCI_MAX_HOST_IN_NETWORK]; /* List of host reseting */
+  bool b_low_power_mode;  /* Host controller in low power mode */
+  bool b_hci_netwk_reset; /* Command sent to reset HCI Network */
+  bool w4_hci_netwk_init; /* Wait for other host in network to initialize */
+  TIMER_LIST_ENT timer;   /* Timer to avoid indefinitely waiting for response */
+  uint8_t conn_id;        /* Connection ID */
+  uint8_t buff_size;      /* Connection buffer size */
+  bool nv_read_cmplt;     /* NV Read completed */
+  bool nv_write_needed;   /* Something changed - NV write is needed */
+  bool assembling;        /* Set true if in process of assembling a message  */
+  bool assembly_failed;   /* Set true if Insufficient buffer to Reassemble
+                             incoming message */
+  bool w4_rsp_evt;        /* Application command sent on HCP Event */
+  tNFA_HANDLE
+      app_in_use; /* Index of the application that is waiting for response */
+  uint8_t local_gate_in_use;  /* Local gate currently working with */
+  uint8_t remote_gate_in_use; /* Remote gate currently working with */
+  uint8_t remote_host_in_use; /* The remote host to which a command is sent */
+  uint8_t pipe_in_use;        /* The pipe currently working with */
+  uint8_t param_in_use;      /* The registry parameter currently working with */
+  tNFA_HCI_COMMAND cmd_sent; /* The last command sent */
+  bool ee_disc_cmplt;        /* EE Discovery operation completed */
+  bool ee_disable_disc;      /* EE Discovery operation is disabled */
+  uint16_t msg_len;     /* For segmentation - length of the combined message */
+  uint16_t max_msg_len; /* Maximum reassembled message size */
+  uint8_t msg_data[NFA_MAX_HCI_EVENT_LEN]; /* For segmentation - the combined
+                                              message data */
+  uint8_t* p_msg_data; /* For segmentation - reassembled message */
+#if (NXP_EXTNS == TRUE)
+  uint8_t assembling_flags; /* the flags to keep track of assembling status*/
+  uint8_t assembly_failed_flags; /* the flags to keep track of failed assembly*/
+  uint8_t* p_evt_data;           /* For segmentation - reassembled event data */
+  uint16_t evt_len; /* For segmentation - length of the combined event data */
+  uint16_t max_evt_len; /* Maximum reassembled message size */
+  uint8_t evt_data[NFA_MAX_HCI_EVENT_LEN]; /* For segmentation - the combined
+                                              event data */
+  uint8_t type_evt;   /* Instruction type of incoming message */
+  uint8_t inst_evt;   /* Instruction of incoming message */
+  uint8_t type_msg;   /* Instruction type of incoming message */
+  uint8_t inst_msg;   /* Instruction of incoming message */
+  uint8_t host_count; /* no of Hosts ETSI 12 compliant */
+  uint8_t host_id[NFA_HCI_MAX_NO_HOST_ETSI12]; /* Host id ETSI 12 compliant */
+  uint8_t host_controller_version; /* no of host controller version */
+  uint8_t current_nfcee;           /* current Nfcee under execution  */
+  bool IsHciTimerChanged;
+  bool IsWiredSessionAborted;
+  uint32_t hciResponseTimeout;
+  bool IsChainedPacket;
+  bool bIsHciResponseTimedout;
+  uint16_t hci_packet_len;
+  bool IsEventAbortSent;
+  bool IsLastEvtAbortFailed;
+  bool w4_nfcee_enable;
+  tNFA_HCI_EVENT_SENT evt_sent;
+  struct {
+    tNFA_CONFIG_STATE
+        config_nfcee_state;   /*state change during config nfcee handling*/
+    uint8_t session_id_retry; /*retry count for session ID*/
+    tNFA_HANDLE host_cb[NFA_HCI_MAX_HOST_IN_NETWORK]; /*host_cb which stores
+                                                         information on config
+                                                         complete ,session ID
+                                                         poll and other
+                                                         information*/
+    bool discovery_stopped; /*discovery stopped during config nfcee process*/
+    bool nfc_init_state;    /*handling clear all pipe*/
+  } nfcee_cfg;
+
+  uint32_t max_hci_session_id_read_count; /*Count for maximum  session id retry
+                                             value */
+  uint32_t
+      max_nfcee_disc_timeout; /*Config file timeout value for all the NFCEE to
+                                 be discovered */
+  tNFA_EE_INFO hci_ee_info[NFA_HCI_MAX_HOST_IN_NETWORK];
+#endif
+  uint8_t type; /* Instruction type of incoming message */
+  uint8_t inst; /* Instruction of incoming message */
+
+  BUFFER_Q hci_api_q;            /* Buffer Q to hold incoming API commands */
+  BUFFER_Q hci_host_reset_api_q; /* Buffer Q to hold incoming API commands to a
+                                    host that is reactivating */
+  tNFA_HCI_CBACK* p_app_cback[NFA_HCI_MAX_APP_CB]; /* Callback functions
+                                                      registered by the
+                                                      applications */
+  uint16_t rsp_buf_size; /* Maximum size of APDU buffer */
+  uint8_t* p_rsp_buf;    /* Buffer to hold response to sent event */
+  struct                 /* Persistent information for Device Host */
+      {
+    char reg_app_names[NFA_HCI_MAX_APP_CB][NFA_MAX_HCI_APP_NAME_LEN + 1];
+
+    tNFA_HCI_DYN_GATE dyn_gates[NFA_HCI_MAX_GATE_CB];
+    tNFA_HCI_DYN_PIPE dyn_pipes[NFA_HCI_MAX_PIPE_CB];
+
+    bool b_send_conn_evts[NFA_HCI_MAX_APP_CB];
+    tNFA_ADMIN_GATE_INFO admin_gate;
+    tNFA_LINK_MGMT_GATE_INFO link_mgmt_gate;
+    tNFA_ID_MGMT_GATE_INFO id_mgmt_gate;
+#if (NXP_EXTNS == TRUE)
+    uint8_t retry_cnt;
+#endif
+  } cfg;
+
+} tNFA_HCI_CB;
+
+/*****************************************************************************
+**  External variables
+*****************************************************************************/
+
+/* NFA HCI control block */
+extern tNFA_HCI_CB nfa_hci_cb;
+
+/*****************************************************************************
+**  External functions
+*****************************************************************************/
+
+/* Functions in nfa_hci_main.c
+*/
+extern void nfa_hci_init(void);
+extern void nfa_hci_proc_nfcc_power_mode(uint8_t nfcc_power_mode);
+extern void nfa_hci_dh_startup_complete(void);
+extern void nfa_hci_startup_complete(tNFA_STATUS status);
+extern void nfa_hci_startup(void);
+extern void nfa_hci_restore_default_config(uint8_t* p_session_id);
+extern void nfa_hci_enable_one_nfcee(void);
+#if (NXP_EXTNS == TRUE)
+extern void nfa_hci_release_transcieve();
+extern void nfa_hci_network_enable(void);
+extern tNFA_STATUS nfa_hciu_reset_session_id(tNFA_VSC_CBACK* p_cback);
+extern tNFA_STATUS nfa_hciu_send_raw_cmd(uint8_t param_len, uint8_t* p_data,
+                                         tNFA_VSC_CBACK* p_cback);
+extern bool nfa_hciu_check_nfcee_poll_done(uint8_t host_id);
+extern bool nfa_hciu_check_nfcee_config_done(uint8_t host_id);
+extern void nfa_hciu_set_nfceeid_config_mask(uint8_t event, uint8_t host_id);
+extern void nfa_hciu_set_nfceeid_poll_mask(uint8_t event, uint8_t host_id);
+extern bool nfa_hciu_check_any_host_reset_pending();
+extern tNFA_STATUS nfa_hci_api_config_nfcee(uint8_t hostId);
+extern tNFA_STATUS nfa_hci_getApduAndConnectivity_PipeStatus();
+void nfa_hci_handle_clear_all_pipes_evt(uint8_t source_host);
+#endif
+
+/* Action functions in nfa_hci_act.c
+*/
+extern void nfa_hci_check_pending_api_requests(void);
+extern void nfa_hci_check_api_requests(void);
+extern void nfa_hci_handle_admin_gate_cmd(uint8_t* p_data);
+extern void nfa_hci_handle_admin_gate_rsp(uint8_t* p_data, uint8_t data_len);
+extern void nfa_hci_handle_admin_gate_evt(uint8_t* p_data);
+extern void nfa_hci_handle_link_mgm_gate_cmd(uint8_t* p_data);
+extern void nfa_hci_handle_dyn_pipe_pkt(uint8_t pipe, uint8_t* p_data,
+                                        uint16_t data_len);
+extern void nfa_hci_handle_pipe_open_close_cmd(tNFA_HCI_DYN_PIPE* p_pipe);
+extern void nfa_hci_api_dealloc_gate(tNFA_HCI_EVENT_DATA* p_evt_data);
+extern void nfa_hci_api_deregister(tNFA_HCI_EVENT_DATA* p_evt_data);
+
+/* Utility functions in nfa_hci_utils.c
+*/
+extern tNFA_HCI_DYN_GATE* nfa_hciu_alloc_gate(uint8_t gate_id,
+                                              tNFA_HANDLE app_handle);
+extern tNFA_HCI_DYN_GATE* nfa_hciu_find_gate_by_gid(uint8_t gate_id);
+extern tNFA_HCI_DYN_GATE* nfa_hciu_find_gate_by_owner(tNFA_HANDLE app_handle);
+extern tNFA_HCI_DYN_GATE* nfa_hciu_find_gate_with_nopipes_by_owner(
+    tNFA_HANDLE app_handle);
+extern tNFA_HCI_DYN_PIPE* nfa_hciu_find_pipe_by_pid(uint8_t pipe_id);
+extern tNFA_HCI_DYN_PIPE* nfa_hciu_find_pipe_by_owner(tNFA_HANDLE app_handle);
+extern tNFA_HCI_DYN_PIPE* nfa_hciu_find_active_pipe_by_owner(
+    tNFA_HANDLE app_handle);
+extern tNFA_HCI_DYN_PIPE* nfa_hciu_find_pipe_on_gate(uint8_t gate_id);
+extern tNFA_HANDLE nfa_hciu_get_gate_owner(uint8_t gate_id);
+extern bool nfa_hciu_check_pipe_between_gates(uint8_t local_gate,
+                                              uint8_t dest_host,
+                                              uint8_t dest_gate);
+extern bool nfa_hciu_is_active_host(uint8_t host_id);
+extern bool nfa_hciu_is_host_reseting(uint8_t host_id);
+extern bool nfa_hciu_is_no_host_resetting(void);
+extern tNFA_HCI_DYN_PIPE* nfa_hciu_find_active_pipe_on_gate(uint8_t gate_id);
+extern tNFA_HANDLE nfa_hciu_get_pipe_owner(uint8_t pipe_id);
+extern uint8_t nfa_hciu_count_open_pipes_on_gate(tNFA_HCI_DYN_GATE* p_gate);
+extern uint8_t nfa_hciu_count_pipes_on_gate(tNFA_HCI_DYN_GATE* p_gate);
+extern tNFA_STATUS nfa_hciu_asmbl_dyn_pipe_pkt(uint8_t* p_data,
+                                               uint8_t data_len);
+
+extern tNFA_HCI_RESPONSE nfa_hciu_add_pipe_to_gate(uint8_t pipe,
+                                                   uint8_t local_gate,
+                                                   uint8_t dest_host,
+                                                   uint8_t dest_gate);
+extern tNFA_HCI_RESPONSE nfa_hciu_add_pipe_to_static_gate(uint8_t local_gate,
+                                                          uint8_t pipe_id,
+                                                          uint8_t dest_host,
+                                                          uint8_t dest_gate);
+
+extern tNFA_HCI_RESPONSE nfa_hciu_release_pipe(uint8_t pipe_id);
+extern void nfa_hciu_release_gate(uint8_t gate);
+extern void nfa_hciu_remove_all_pipes_from_host(uint8_t host);
+extern uint8_t nfa_hciu_get_allocated_gate_list(uint8_t* p_gate_list);
+
+extern void nfa_hciu_send_to_app(tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA* p_evt,
+                                 tNFA_HANDLE app_handle);
+extern void nfa_hciu_send_to_all_apps(tNFA_HCI_EVT event,
+                                      tNFA_HCI_EVT_DATA* p_evt);
+extern void nfa_hciu_send_to_apps_handling_connectivity_evts(
+    tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA* p_evt);
+
+extern tNFA_STATUS nfa_hciu_send_close_pipe_cmd(uint8_t pipe);
+extern tNFA_STATUS nfa_hciu_send_delete_pipe_cmd(uint8_t pipe);
+extern tNFA_STATUS nfa_hciu_send_clear_all_pipe_cmd(void);
+extern tNFA_STATUS nfa_hciu_send_open_pipe_cmd(uint8_t pipe);
+extern tNFA_STATUS nfa_hciu_send_get_param_cmd(uint8_t pipe, uint8_t index);
+extern tNFA_STATUS nfa_hciu_send_create_pipe_cmd(uint8_t source_gate,
+                                                 uint8_t dest_host,
+                                                 uint8_t dest_gate);
+extern tNFA_STATUS nfa_hciu_send_set_param_cmd(uint8_t pipe, uint8_t index,
+                                               uint8_t length, uint8_t* p_data);
+extern tNFA_STATUS nfa_hciu_send_msg(uint8_t pipe_id, uint8_t type,
+                                     uint8_t instruction, uint16_t pkt_len,
+                                     uint8_t* p_pkt);
+
+#if (BT_TRACE_VERBOSE == true)
+extern char* nfa_hciu_type_2_str(uint8_t type);
+extern char* nfa_hciu_instr_2_str(uint8_t type);
+extern char* nfa_hciu_get_event_name(uint16_t event);
+extern char* nfa_hciu_get_response_name(uint8_t rsp_code);
+extern char* nfa_hciu_get_state_name(uint8_t state);
+extern char* nfa_hciu_get_type_inst_names(uint8_t pipe, uint8_t type,
+                                          uint8_t inst, char* p_buff);
+extern char* nfa_hciu_evt_2_str(uint8_t pipe_id, uint8_t evt);
+#define VERBOSE_BUFF_SIZE 100
+#endif
+
+#endif /* NFA_HCI_INT_H */
diff --git a/src/nfa/int/nfa_p2p_int.h b/src/nfa/int/nfa_p2p_int.h
new file mode 100644
index 0000000..8291112
--- /dev/null
+++ b/src/nfa/int/nfa_p2p_int.h
@@ -0,0 +1,323 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the private interface file for the NFA P2P.
+ *
+ ******************************************************************************/
+#ifndef NFA_P2P_INT_H
+#define NFA_P2P_INT_H
+
+#if (NFA_P2P_INCLUDED == true)
+#include "nfa_p2p_api.h"
+#include "nfa_dm_int.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+#define NFA_P2P_DEBUG BT_TRACE_VERBOSE
+
+/* NFA P2P LLCP link state */
+enum {
+  NFA_P2P_LLCP_STATE_IDLE,
+  NFA_P2P_LLCP_STATE_LISTENING,
+  NFA_P2P_LLCP_STATE_ACTIVATED,
+
+  NFA_P2P_LLCP_STATE_MAX
+};
+
+typedef uint8_t tNFA_P2P_LLCP_STATE;
+
+/* NFA P2P events */
+enum {
+  NFA_P2P_API_REG_SERVER_EVT = NFA_SYS_EVT_START(NFA_ID_P2P),
+  NFA_P2P_API_REG_CLIENT_EVT,
+  NFA_P2P_API_DEREG_EVT,
+  NFA_P2P_API_ACCEPT_CONN_EVT,
+  NFA_P2P_API_REJECT_CONN_EVT,
+  NFA_P2P_API_DISCONNECT_EVT,
+  NFA_P2P_API_CONNECT_EVT,
+  NFA_P2P_API_SEND_UI_EVT,
+  NFA_P2P_API_SEND_DATA_EVT,
+  NFA_P2P_API_SET_LOCAL_BUSY_EVT,
+  NFA_P2P_API_GET_LINK_INFO_EVT,
+  NFA_P2P_API_GET_REMOTE_SAP_EVT,
+  NFA_P2P_API_SET_LLCP_CFG_EVT,
+  NFA_P2P_INT_RESTART_RF_DISC_EVT,
+
+  NFA_P2P_LAST_EVT
+};
+
+/* data type for NFA_P2P_API_REG_SERVER_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  uint8_t server_sap;
+  tNFA_P2P_LINK_TYPE link_type;
+  char service_name[LLCP_MAX_SN_LEN + 1];
+  tNFA_P2P_CBACK* p_cback;
+} tNFA_P2P_API_REG_SERVER;
+
+/* data type for NFA_P2P_API_REG_CLIENT_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_P2P_LINK_TYPE link_type;
+  tNFA_P2P_CBACK* p_cback;
+} tNFA_P2P_API_REG_CLIENT;
+
+/* data type for NFA_P2P_API_DEREG_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE handle;
+} tNFA_P2P_API_DEREG;
+
+/* data type for NFA_P2P_API_ACCEPT_CONN_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE conn_handle;
+  uint16_t miu;
+  uint8_t rw;
+} tNFA_P2P_API_ACCEPT_CONN;
+
+/* data type for NFA_P2P_API_REJECT_CONN_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE conn_handle;
+} tNFA_P2P_API_REJECT_CONN;
+
+/* data type for NFA_P2P_API_DISCONNECT_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE conn_handle;
+  bool flush;
+} tNFA_P2P_API_DISCONNECT;
+
+/* data type for NFA_P2P_API_CONNECT_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE client_handle;
+  char service_name[LLCP_MAX_SN_LEN + 1];
+  uint8_t dsap;
+  uint16_t miu;
+  uint8_t rw;
+} tNFA_P2P_API_CONNECT;
+
+/* data type for NFA_P2P_API_SEND_UI_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE handle;
+  uint8_t dsap;
+  NFC_HDR* p_msg;
+} tNFA_P2P_API_SEND_UI;
+
+/* data type for NFA_P2P_API_SEND_DATA_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE conn_handle;
+  NFC_HDR* p_msg;
+} tNFA_P2P_API_SEND_DATA;
+
+/* data type for NFA_P2P_API_SET_LOCAL_BUSY_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE conn_handle;
+  bool is_busy;
+} tNFA_P2P_API_SET_LOCAL_BUSY;
+
+/* data type for NFA_P2P_API_GET_LINK_INFO_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE handle;
+} tNFA_P2P_API_GET_LINK_INFO;
+
+/* data type for NFA_P2P_API_GET_REMOTE_SAP_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE handle;
+  char service_name[LLCP_MAX_SN_LEN + 1];
+} tNFA_P2P_API_GET_REMOTE_SAP;
+
+/* data type for NFA_P2P_API_SET_LLCP_CFG_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  uint16_t link_miu;
+  uint8_t opt;
+  uint8_t wt;
+  uint16_t link_timeout;
+  uint16_t inact_timeout_init;
+  uint16_t inact_timeout_target;
+  uint16_t symm_delay;
+  uint16_t data_link_timeout;
+  uint16_t delay_first_pdu_timeout;
+} tNFA_P2P_API_SET_LLCP_CFG;
+
+/* union of all event data types */
+typedef union {
+  NFC_HDR hdr;
+  tNFA_P2P_API_REG_SERVER api_reg_server;
+  tNFA_P2P_API_REG_CLIENT api_reg_client;
+  tNFA_P2P_API_DEREG api_dereg;
+  tNFA_P2P_API_ACCEPT_CONN api_accept;
+  tNFA_P2P_API_REJECT_CONN api_reject;
+  tNFA_P2P_API_DISCONNECT api_disconnect;
+  tNFA_P2P_API_CONNECT api_connect;
+  tNFA_P2P_API_SEND_UI api_send_ui;
+  tNFA_P2P_API_SEND_DATA api_send_data;
+  tNFA_P2P_API_SET_LOCAL_BUSY api_local_busy;
+  tNFA_P2P_API_GET_LINK_INFO api_link_info;
+  tNFA_P2P_API_GET_REMOTE_SAP api_remote_sap;
+  tNFA_P2P_API_SET_LLCP_CFG api_set_llcp_cfg;
+} tNFA_P2P_MSG;
+
+/*****************************************************************************
+**  control block
+*****************************************************************************/
+/* Bit flag for connection handle           */
+#define NFA_P2P_HANDLE_FLAG_CONN 0x80
+
+/* NFA P2P Connection block */
+/* Connection control block is used         */
+#define NFA_P2P_CONN_FLAG_IN_USE 0x01
+/* Remote set RW to 0 (flow off)            */
+#define NFA_P2P_CONN_FLAG_REMOTE_RW_ZERO 0x02
+/* data link connection is congested        */
+#define NFA_P2P_CONN_FLAG_CONGESTED 0x04
+
+typedef struct {
+  uint8_t flags;             /* internal flags for data link connection  */
+  uint8_t local_sap;         /* local SAP of data link connection        */
+  uint8_t remote_sap;        /* remote SAP of data link connection       */
+  uint16_t remote_miu;       /* MIU of remote end point                  */
+  uint8_t num_pending_i_pdu; /* number of tx I PDU not processed by NFA  */
+} tNFA_P2P_CONN_CB;
+
+/* NFA P2P SAP control block */
+/* registered server                        */
+#define NFA_P2P_SAP_FLAG_SERVER 0x01
+/* registered client                        */
+#define NFA_P2P_SAP_FLAG_CLIENT 0x02
+/* logical link connection is congested     */
+#define NFA_P2P_SAP_FLAG_LLINK_CONGESTED 0x04
+
+typedef struct {
+  uint8_t flags;              /* internal flags for local SAP             */
+  tNFA_P2P_CBACK* p_cback;    /* callback function for local SAP          */
+  uint8_t num_pending_ui_pdu; /* number of tx UI PDU not processed by NFA */
+} tNFA_P2P_SAP_CB;
+
+/* NFA P2P SDP control block */
+typedef struct {
+  uint8_t tid; /* transaction ID */
+  uint8_t local_sap;
+} tNFA_P2P_SDP_CB;
+
+#define NFA_P2P_NUM_SAP 64
+
+/* NFA P2P control block */
+typedef struct {
+  tNFA_HANDLE dm_disc_handle;
+
+  tNFA_DM_RF_DISC_STATE rf_disc_state;
+  tNFA_P2P_LLCP_STATE llcp_state;
+  bool is_initiator;
+  bool is_active_mode;
+  uint16_t local_link_miu;
+  uint16_t remote_link_miu;
+
+  tNFA_TECHNOLOGY_MASK listen_tech_mask; /* for P2P listening */
+  tNFA_TECHNOLOGY_MASK
+      listen_tech_mask_to_restore; /* to retry without active listen mode */
+  TIMER_LIST_ENT
+  active_listen_restore_timer; /* timer to restore active listen mode */
+  bool is_p2p_listening;
+  bool is_snep_listening;
+
+  tNFA_P2P_SAP_CB sap_cb[NFA_P2P_NUM_SAP];
+  tNFA_P2P_CONN_CB conn_cb[LLCP_MAX_DATA_LINK];
+  tNFA_P2P_SDP_CB sdp_cb[LLCP_MAX_SDP_TRANSAC];
+
+  uint8_t
+      total_pending_ui_pdu; /* total number of tx UI PDU not processed by NFA */
+  uint8_t
+      total_pending_i_pdu; /* total number of tx I PDU not processed by NFA */
+
+  uint8_t trace_level;
+} tNFA_P2P_CB;
+
+/*****************************************************************************
+**  External variables
+*****************************************************************************/
+
+/* NFA P2P control block */
+extern tNFA_P2P_CB nfa_p2p_cb;
+
+/*****************************************************************************
+**  External functions
+*****************************************************************************/
+/*
+**  nfa_p2p_main.c
+*/
+void nfa_p2p_init(void);
+void nfa_p2p_update_listen_tech(tNFA_TECHNOLOGY_MASK tech_mask);
+void nfa_p2p_enable_listening(tNFA_SYS_ID sys_id, bool update_wks);
+void nfa_p2p_disable_listening(tNFA_SYS_ID sys_id, bool update_wks);
+void nfa_p2p_activate_llcp(tNFC_DISCOVER* p_data);
+void nfa_p2p_deactivate_llcp(void);
+void nfa_p2p_set_config(tNFA_DM_DISC_TECH_PROTO_MASK disc_mask);
+
+/*
+**  nfa_p2p_act.c
+*/
+void nfa_p2p_proc_llcp_data_ind(tLLCP_SAP_CBACK_DATA* p_data);
+void nfa_p2p_proc_llcp_connect_ind(tLLCP_SAP_CBACK_DATA* p_data);
+void nfa_p2p_proc_llcp_connect_resp(tLLCP_SAP_CBACK_DATA* p_data);
+void nfa_p2p_proc_llcp_disconnect_ind(tLLCP_SAP_CBACK_DATA* p_data);
+void nfa_p2p_proc_llcp_disconnect_resp(tLLCP_SAP_CBACK_DATA* p_data);
+void nfa_p2p_proc_llcp_congestion(tLLCP_SAP_CBACK_DATA* p_data);
+void nfa_p2p_proc_llcp_link_status(tLLCP_SAP_CBACK_DATA* p_data);
+
+bool nfa_p2p_start_sdp(char* p_service_name, uint8_t local_sap);
+
+bool nfa_p2p_reg_server(tNFA_P2P_MSG* p_msg);
+bool nfa_p2p_reg_client(tNFA_P2P_MSG* p_msg);
+bool nfa_p2p_dereg(tNFA_P2P_MSG* p_msg);
+bool nfa_p2p_accept_connection(tNFA_P2P_MSG* p_msg);
+bool nfa_p2p_reject_connection(tNFA_P2P_MSG* p_msg);
+bool nfa_p2p_disconnect(tNFA_P2P_MSG* p_msg);
+bool nfa_p2p_create_data_link_connection(tNFA_P2P_MSG* p_msg);
+bool nfa_p2p_send_ui(tNFA_P2P_MSG* p_msg);
+bool nfa_p2p_send_data(tNFA_P2P_MSG* p_msg);
+bool nfa_p2p_set_local_busy(tNFA_P2P_MSG* p_msg);
+bool nfa_p2p_get_link_info(tNFA_P2P_MSG* p_msg);
+bool nfa_p2p_get_remote_sap(tNFA_P2P_MSG* p_msg);
+bool nfa_p2p_set_llcp_cfg(tNFA_P2P_MSG* p_msg);
+bool nfa_p2p_restart_rf_discovery(tNFA_P2P_MSG* p_msg);
+
+#if (BT_TRACE_VERBOSE == true)
+char* nfa_p2p_evt_code(uint16_t evt_code);
+#endif
+
+#else
+
+#define nfa_p2p_init ()
+#define nfa_p2p_activate_llcp (a){};
+#define nfa_p2p_deactivate_llcp ()
+#define nfa_p2p_set_config ()
+
+#endif /* (NFA_P2P_INCLUDED==true) */
+#endif /* NFA_P2P_INT_H */
diff --git a/src/nfa/int/nfa_rw_int.h b/src/nfa/int/nfa_rw_int.h
new file mode 100644
index 0000000..4260a69
--- /dev/null
+++ b/src/nfa/int/nfa_rw_int.h
@@ -0,0 +1,361 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2003-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the private interface file for NFA_RW
+ *
+ ******************************************************************************/
+#ifndef NFA_RW_INT_H
+#define NFA_RW_INT_H
+
+#include "nfa_sys.h"
+#include "nfa_api.h"
+#include "nfa_rw_api.h"
+#include "nfc_api.h"
+#include "rw_api.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+/* Interval for performing presence check (in ms) */
+#ifndef NFA_RW_PRESENCE_CHECK_INTERVAL
+#define NFA_RW_PRESENCE_CHECK_INTERVAL 750
+#endif
+
+/* TLV detection status */
+#define NFA_RW_TLV_DETECT_ST_OP_NOT_STARTED 0x00 /* No Tlv detected */
+/* Lock control tlv detected */
+#define NFA_RW_TLV_DETECT_ST_LOCK_TLV_OP_COMPLETE 0x01
+/* Memory control tlv detected */
+#define NFA_RW_TLV_DETECT_ST_MEM_TLV_OP_COMPLETE 0x02
+/* Both Lock and Memory control Tlvs are detected */
+#define NFA_RW_TLV_DETECT_ST_COMPLETE 0x03
+
+typedef uint8_t tNFA_RW_TLV_ST;
+
+/* RW events */
+enum {
+  NFA_RW_OP_REQUEST_EVT = NFA_SYS_EVT_START(NFA_ID_RW),
+  NFA_RW_ACTIVATE_NTF_EVT,
+  NFA_RW_DEACTIVATE_NTF_EVT,
+  NFA_RW_PRESENCE_CHECK_TICK_EVT,
+  NFA_RW_PRESENCE_CHECK_TIMEOUT_EVT,
+  NFA_RW_MAX_EVT
+};
+
+/* BTA_RW operations */
+enum {
+  NFA_RW_OP_DETECT_NDEF,
+  NFA_RW_OP_READ_NDEF,
+  NFA_RW_OP_WRITE_NDEF,
+  NFA_RW_OP_PRESENCE_CHECK,
+  NFA_RW_OP_FORMAT_TAG,
+  NFA_RW_OP_SEND_RAW_FRAME,
+
+  /* Exclusive Type-1,Type-2 tag operations */
+  NFA_RW_OP_DETECT_LOCK_TLV,
+  NFA_RW_OP_DETECT_MEM_TLV,
+  NFA_RW_OP_SET_TAG_RO,
+
+  /* Exclusive Type-1 tag operations */
+  NFA_RW_OP_T1T_RID,
+  NFA_RW_OP_T1T_RALL,
+  NFA_RW_OP_T1T_READ,
+  NFA_RW_OP_T1T_WRITE,
+  NFA_RW_OP_T1T_RSEG,
+  NFA_RW_OP_T1T_READ8,
+  NFA_RW_OP_T1T_WRITE8,
+
+  /* Exclusive Type-2 tag operations */
+  NFA_RW_OP_T2T_READ,
+  NFA_RW_OP_T2T_WRITE,
+  NFA_RW_OP_T2T_SECTOR_SELECT,
+
+  /* Exclusive Type-3 tag operations */
+  NFA_RW_OP_T3T_READ,
+  NFA_RW_OP_T3T_WRITE,
+  NFA_RW_OP_T3T_GET_SYSTEM_CODES,
+
+  /* Exclusive ISO 15693 tag operations */
+  NFA_RW_OP_I93_INVENTORY,
+  NFA_RW_OP_I93_STAY_QUIET,
+  NFA_RW_OP_I93_READ_SINGLE_BLOCK,
+  NFA_RW_OP_I93_WRITE_SINGLE_BLOCK,
+  NFA_RW_OP_I93_LOCK_BLOCK,
+  NFA_RW_OP_I93_READ_MULTI_BLOCK,
+  NFA_RW_OP_I93_WRITE_MULTI_BLOCK,
+  NFA_RW_OP_I93_SELECT,
+  NFA_RW_OP_I93_RESET_TO_READY,
+  NFA_RW_OP_I93_WRITE_AFI,
+  NFA_RW_OP_I93_LOCK_AFI,
+  NFA_RW_OP_I93_WRITE_DSFID,
+  NFA_RW_OP_I93_LOCK_DSFID,
+  NFA_RW_OP_I93_GET_SYS_INFO,
+  NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS,
+
+#if (NXP_EXTNS == TRUE)
+  NFA_RW_OP_T3BT_PUPI,
+#endif
+
+  NFA_RW_OP_MAX
+};
+typedef uint8_t tNFA_RW_OP;
+
+/* Enumeration of parameter structios for nfa_rw operations */
+
+/* NFA_RW_OP_WRITE_NDEF params */
+typedef struct {
+  uint32_t len;
+  uint8_t* p_data;
+} tNFA_RW_OP_PARAMS_WRITE_NDEF;
+
+/* NFA_RW_OP_SEND_RAW_FRAME params */
+typedef struct { NFC_HDR* p_data; } tNFA_RW_OP_PARAMS_SEND_RAW_FRAME;
+
+/* NFA_RW_OP_SET_TAG_RO params */
+typedef struct { bool b_hard_lock; } tNFA_RW_OP_PARAMS_CONFIG_READ_ONLY;
+
+/* NFA_RW_OP_T1T_READ params */
+typedef struct {
+  uint8_t segment_number;
+  uint8_t block_number;
+  uint8_t index;
+} tNFA_RW_OP_PARAMS_T1T_READ;
+
+/* NFA_RW_OP_T1T_WRITE_E8,NFA_RW_OP_T1T_WRITE_NE8
+   NFA_RW_OP_T1T_WRITE_E, NFA_RW_OP_T1T_WRITE_NE params  */
+typedef struct {
+  bool b_erase;
+  uint8_t block_number;
+  uint8_t index;
+  uint8_t p_block_data[8];
+} tNFA_RW_OP_PARAMS_T1T_WRITE;
+
+/* NFA_RW_OP_T2T_READ params */
+typedef struct { uint8_t block_number; } tNFA_RW_OP_PARAMS_T2T_READ;
+
+/* NFA_RW_OP_T2T_WRITE params */
+typedef struct {
+  uint8_t block_number;
+  uint8_t p_block_data[4];
+} tNFA_RW_OP_PARAMS_T2T_WRITE;
+
+/* NFA_RW_OP_T2T_SECTOR_SELECT params */
+typedef struct { uint8_t sector_number; } tNFA_RW_OP_PARAMS_T2T_SECTOR_SELECT;
+
+/* NFA_RW_OP_T3T_READ params */
+typedef struct {
+  uint8_t num_blocks;
+  tNFA_T3T_BLOCK_DESC* p_block_desc;
+} tNFA_RW_OP_PARAMS_T3T_READ;
+
+/* NFA_RW_OP_T3T_WRITE params */
+typedef struct {
+  uint8_t num_blocks;
+  tNFA_T3T_BLOCK_DESC* p_block_desc;
+  uint8_t* p_block_data;
+} tNFA_RW_OP_PARAMS_T3T_WRITE;
+
+/* NFA_RW_OP_I93_XXX params */
+typedef struct {
+  bool uid_present;
+  uint8_t uid[I93_UID_BYTE_LEN];
+  bool afi_present;
+  uint8_t afi;
+  uint8_t dsfid;
+  uint16_t first_block_number;
+  uint16_t number_blocks;
+  uint8_t* p_data;
+} tNFA_RW_OP_PARAMS_I93_CMD;
+
+/* Union of params for all reader/writer operations */
+typedef union {
+  /* params for NFA_RW_OP_WRITE_NDEF */
+  tNFA_RW_OP_PARAMS_WRITE_NDEF write_ndef;
+
+  /* params for NFA_RW_OP_SEND_RAW_FRAME */
+  tNFA_RW_OP_PARAMS_SEND_RAW_FRAME send_raw_frame;
+
+  /* params for NFA_RW_OP_SET_TAG_RO */
+  tNFA_RW_OP_PARAMS_CONFIG_READ_ONLY set_readonly;
+
+  /* params for NFA_RW_OP_T2T_READ and NFA_RW_OP_T1T_WRITE */
+  tNFA_RW_OP_PARAMS_T1T_READ t1t_read;
+  tNFA_RW_OP_PARAMS_T1T_WRITE t1t_write;
+
+  /* params for NFA_RW_OP_T2T_READ,NFA_RW_OP_T2T_WRITE and
+   * NFA_RW_OP_T2T_SECTOR_SELECT */
+  tNFA_RW_OP_PARAMS_T2T_READ t2t_read;
+  tNFA_RW_OP_PARAMS_T2T_WRITE t2t_write;
+  tNFA_RW_OP_PARAMS_T2T_SECTOR_SELECT t2t_sector_select;
+
+  /* params for NFA_RW_OP_T3T_READ and NFA_RW_OP_T3T_WRITE */
+  tNFA_RW_OP_PARAMS_T3T_READ t3t_read;
+  tNFA_RW_OP_PARAMS_T3T_WRITE t3t_write;
+
+  /* params for NFA_RW_OP_PRESENCE_CHECK */
+  tNFA_RW_PRES_CHK_OPTION option;
+
+  /* params for ISO 15693 */
+  tNFA_RW_OP_PARAMS_I93_CMD i93_cmd;
+
+} tNFA_RW_OP_PARAMS;
+
+/* data type for NFA_RW_op_req_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_RW_OP op; /* NFA RW operation */
+  tNFA_RW_OP_PARAMS params;
+} tNFA_RW_OPERATION;
+
+/* data type for NFA_RW_ACTIVATE_NTF */
+typedef struct {
+  NFC_HDR hdr;
+  tNFC_ACTIVATE_DEVT* p_activate_params; /* Data from NFC_ACTIVATE_DEVT      */
+  bool excl_rf_not_active;               /* true if not in exclusive RF mode */
+} tNFA_RW_ACTIVATE_NTF;
+
+/* union of all data types */
+typedef union {
+  /* GKI event buffer header */
+  NFC_HDR hdr;
+  tNFA_RW_OPERATION op_req;
+  tNFA_RW_ACTIVATE_NTF activate_ntf;
+} tNFA_RW_MSG;
+
+/* NDEF detection status */
+enum {
+  NFA_RW_NDEF_ST_UNKNOWN = 0, /* NDEF detection not performed yet */
+  NFA_RW_NDEF_ST_TRUE,        /* Tag is NDEF */
+  NFA_RW_NDEF_ST_FALSE        /* Tag is not NDEF */
+};
+typedef uint8_t tNFA_RW_NDEF_ST;
+
+/* flags for RW control block */
+/* Activation while not in exclusive RF mode                                */
+#define NFA_RW_FL_NOT_EXCL_RF_MODE 0x01
+/* Waiting for response from tag for auto-presence check                    */
+#define NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY 0x02
+/* Read only tag                                                            */
+#define NFA_RW_FL_TAG_IS_READONLY 0x04
+/* Busy retrieving additional tag information                               */
+#define NFA_RW_FL_ACTIVATION_NTF_PENDING 0x08
+/* Tag operation is in progress                                             */
+#define NFA_RW_FL_API_BUSY 0x10
+/* Tag is been activated                                                    */
+#define NFA_RW_FL_ACTIVATED 0x20
+/* NDEF DETECTed OK                                                         */
+#define NFA_RW_FL_NDEF_OK 0x40
+
+/* NFA RW control block */
+typedef struct {
+  tNFA_RW_OP cur_op; /* Current operation */
+
+  TIMER_LIST_ENT tle; /* list entry for nfa_rw timer */
+  tNFA_RW_MSG*
+      p_pending_msg; /* Pending API (if busy performing presence check) */
+
+  /* Tag info */
+  tNFC_PROTOCOL protocol;
+  tNFC_INTF_TYPE intf_type;
+  uint8_t pa_sel_res;
+  tNFC_RF_TECH_N_MODE activated_tech_mode; /* activated technology and mode */
+
+  bool b_hard_lock;
+
+  tNFA_RW_MSG*
+      p_buffer_rw_msg; /* Buffer to hold incoming cmd while reading tag id */
+
+  /* TLV info */
+  tNFA_RW_TLV_ST tlv_st; /* TLV detection status */
+
+  /* NDEF info */
+  tNFA_RW_NDEF_ST ndef_st; /* NDEF detection status */
+  uint32_t ndef_max_size;  /* max number of bytes available for NDEF data */
+  uint32_t ndef_cur_size;  /* current size of stored NDEF data (in bytes) */
+  uint8_t* p_ndef_buf;
+  uint32_t ndef_rd_offset; /* current read-offset of incoming NDEF data */
+
+  /* Current NDEF Write info */
+  uint8_t* p_ndef_wr_buf; /* Pointer to NDEF data being written */
+  uint32_t ndef_wr_len;   /* Length of NDEF data being written */
+
+  /* Reactivating type 2 tag after NACK rsp */
+  tRW_EVENT halt_event; /* Event ID from stack after NACK response */
+  tRW_DATA rw_data;     /* Event Data from stack after NACK response */
+  bool skip_dyn_locks;  /* To skip reading dynamic locks during NDEF Detect */
+
+  /* Flags (see defintions for NFA_RW_FL_* ) */
+  uint8_t flags;
+
+  /* ISO 15693 tag memory information */
+  uint16_t i93_afi_location;
+  uint8_t i93_dsfid;
+  uint8_t i93_block_size;
+  uint16_t i93_num_block;
+  uint8_t i93_uid[I93_UID_BYTE_LEN];
+} tNFA_RW_CB;
+extern tNFA_RW_CB nfa_rw_cb;
+
+/* type definition for action functions */
+typedef bool (*tNFA_RW_ACTION)(tNFA_RW_MSG* p_data);
+
+/* Internal nfa_rw function prototypes */
+extern void nfa_rw_stop_presence_check_timer(void);
+
+/* Action function prototypes */
+extern bool nfa_rw_handle_op_req(tNFA_RW_MSG* p_data);
+extern bool nfa_rw_activate_ntf(tNFA_RW_MSG* p_data);
+extern bool nfa_rw_deactivate_ntf(tNFA_RW_MSG* p_data);
+extern bool nfa_rw_presence_check_tick(tNFA_RW_MSG* p_data);
+extern bool nfa_rw_presence_check_timeout(tNFA_RW_MSG* p_data);
+extern void nfa_rw_handle_sleep_wakeup_rsp(tNFC_STATUS status);
+extern void nfa_rw_handle_presence_check_rsp(tNFC_STATUS status);
+extern void nfa_rw_command_complete(void);
+extern bool nfa_rw_handle_event(NFC_HDR* p_msg);
+
+extern void nfa_rw_free_ndef_rx_buf(void);
+extern void nfa_rw_sys_disable(void);
+
+#if (NXP_EXTNS == TRUE)
+extern void nfa_rw_set_cback(tNFC_DISCOVER* p_data);
+extern void nfa_rw_update_pupi_id(uint8_t* p, uint8_t len);
+#endif
+
+#endif /* NFA_DM_INT_H */
diff --git a/src/nfa/int/nfa_snep_int.h b/src/nfa/int/nfa_snep_int.h
new file mode 100644
index 0000000..8b8ba91
--- /dev/null
+++ b/src/nfa/int/nfa_snep_int.h
@@ -0,0 +1,273 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the private interface file for the NFA SNEP.
+ *
+ ******************************************************************************/
+#ifndef NFA_SNEP_INT_H
+#define NFA_SNEP_INT_H
+
+#if (NFA_SNEP_INCLUDED == true)
+#include "llcp_api.h"
+#include "nfa_snep_api.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+#define NFA_SNEP_DEFAULT_SERVER_SAP 0x04 /* SNEP default server SAP   */
+#define NFA_SNEP_HEADER_SIZE 6           /* SNEP header size          */
+/* SNEP Acceptable Length size */
+#define NFA_SNEP_ACCEPT_LEN_SIZE 4
+#define NFA_SNEP_CLIENT_TIMEOUT 1000 /* ms, waiting for response  */
+
+/* NFA SNEP events */
+enum {
+  NFA_SNEP_API_START_DEFAULT_SERVER_EVT = NFA_SYS_EVT_START(NFA_ID_SNEP),
+  NFA_SNEP_API_STOP_DEFAULT_SERVER_EVT,
+  NFA_SNEP_API_REG_SERVER_EVT,
+  NFA_SNEP_API_REG_CLIENT_EVT,
+  NFA_SNEP_API_DEREG_EVT,
+  NFA_SNEP_API_CONNECT_EVT,
+  NFA_SNEP_API_GET_REQ_EVT,
+  NFA_SNEP_API_PUT_REQ_EVT,
+  NFA_SNEP_API_GET_RESP_EVT,
+  NFA_SNEP_API_PUT_RESP_EVT,
+  NFA_SNEP_API_DISCONNECT_EVT,
+
+  NFA_SNEP_LAST_EVT
+};
+
+/* data type for NFA_SNEP_API_START_DEFAULT_SERVER_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_SNEP_CBACK* p_cback;
+} tNFA_SNEP_API_START_DEFAULT_SERVER;
+
+/* data type for NFA_SNEP_API_STOP_DEFAULT_SERVER_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_SNEP_CBACK* p_cback;
+} tNFA_SNEP_API_STOP_DEFAULT_SERVER;
+
+/* data type for NFA_SNEP_API_REG_SERVER_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  uint8_t server_sap;
+  char service_name[LLCP_MAX_SN_LEN + 1];
+  tNFA_SNEP_CBACK* p_cback;
+} tNFA_SNEP_API_REG_SERVER;
+
+/* data type for NFA_SNEP_API_REG_CLIENT_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_SNEP_CBACK* p_cback;
+} tNFA_SNEP_API_REG_CLIENT;
+
+/* data type for NFA_SNEP_API_DEREG_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE reg_handle; /* handle for registered server/client */
+} tNFA_SNEP_API_DEREG;
+
+/* data type for NFA_SNEP_API_CONNECT_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE client_handle; /* handle for client                   */
+  char service_name[LLCP_MAX_SN_LEN + 1];
+} tNFA_SNEP_API_CONNECT;
+
+/* data type for NFA_SNEP_API_GET_REQ_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE conn_handle; /* handle for data link connection      */
+  uint32_t buff_length;    /* length of buffer; acceptable length  */
+  uint32_t ndef_length;    /* length of current NDEF message       */
+  uint8_t* p_ndef_buff;    /* buffer for NDEF message              */
+} tNFA_SNEP_API_GET_REQ;
+
+/* data type for NFA_SNEP_API_PUT_REQ_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE conn_handle; /* handle for data link connection */
+  uint32_t ndef_length;    /* length of NDEF message          */
+  uint8_t* p_ndef_buff;    /* buffer for NDEF message         */
+} tNFA_SNEP_API_PUT_REQ;
+
+/* data type for NFA_SNEP_API_GET_RESP_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE conn_handle;       /* handle for data link connection */
+  tNFA_SNEP_RESP_CODE resp_code; /* response code                   */
+  uint32_t ndef_length;          /* length of NDEF message          */
+  uint8_t* p_ndef_buff;          /* buffer for NDEF message         */
+} tNFA_SNEP_API_GET_RESP;
+
+/* data type for NFA_SNEP_API_PUT_RESP_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE conn_handle;       /* handle for data link connection */
+  tNFA_SNEP_RESP_CODE resp_code; /* response code                   */
+} tNFA_SNEP_API_PUT_RESP;
+
+/* data type for NFA_SNEP_API_DISCONNECT_EVT */
+typedef struct {
+  NFC_HDR hdr;
+  tNFA_HANDLE conn_handle; /* response code                   */
+  bool flush;              /* true if discard pending data    */
+} tNFA_SNEP_API_DISCONNECT;
+
+/* union of all event data types */
+typedef union {
+  NFC_HDR hdr;
+  tNFA_SNEP_API_START_DEFAULT_SERVER
+      api_start_default_server; /* NFA_SNEP_API_START_DEFAULT_SERVER_EVT */
+  tNFA_SNEP_API_STOP_DEFAULT_SERVER
+      api_stop_default_server; /* NFA_SNEP_API_STOP_DEFAULT_SERVER_EVT  */
+  tNFA_SNEP_API_REG_SERVER api_reg_server; /* NFA_SNEP_API_REG_SERVER_EVT   */
+  tNFA_SNEP_API_REG_CLIENT api_reg_client; /* NFA_SNEP_API_REG_CLIENT_EVT   */
+  tNFA_SNEP_API_DEREG api_dereg;           /* NFA_SNEP_API_DEREG_EVT        */
+  tNFA_SNEP_API_CONNECT api_connect;       /* NFA_SNEP_API_CONNECT_EVT      */
+  tNFA_SNEP_API_GET_REQ api_get_req;       /* NFA_SNEP_API_GET_REQ_EVT      */
+  tNFA_SNEP_API_PUT_REQ api_put_req;       /* NFA_SNEP_API_PUT_REQ_EVT      */
+  tNFA_SNEP_API_GET_RESP api_get_resp;     /* NFA_SNEP_API_GET_RESP_EVT     */
+  tNFA_SNEP_API_PUT_RESP api_put_resp;     /* NFA_SNEP_API_PUT_RESP_EVT     */
+  tNFA_SNEP_API_DISCONNECT api_disc;       /* NFA_SNEP_API_DISCONNECT_EVT   */
+} tNFA_SNEP_MSG;
+
+/*****************************************************************************
+**  control block
+*****************************************************************************/
+
+/* NFA SNEP service control block */
+/* ignore flags while searching   */
+#define NFA_SNEP_FLAG_ANY 0x00
+#define NFA_SNEP_FLAG_SERVER 0x01 /* server */
+#define NFA_SNEP_FLAG_CLIENT 0x02 /* client */
+/* waiting for connection confirm */
+#define NFA_SNEP_FLAG_CONNECTING 0x04
+/* data link connected            */
+#define NFA_SNEP_FLAG_CONNECTED 0x08
+/* Waiting for continue response  */
+#define NFA_SNEP_FLAG_W4_RESP_CONTINUE 0x10
+/* Waiting for continue request   */
+#define NFA_SNEP_FLAG_W4_REQ_CONTINUE 0x20
+
+typedef struct {
+  uint8_t local_sap;        /* local SAP of service */
+  uint8_t remote_sap;       /* local SAP of service */
+  uint8_t flags;            /* internal flags       */
+  tNFA_SNEP_CBACK* p_cback; /* callback for event   */
+  TIMER_LIST_ENT timer;     /* timer for client     */
+
+  uint16_t tx_miu;   /* adjusted MIU for throughput              */
+  bool congest;      /* true if data link connection is congested */
+  bool rx_fragments; /* true if waiting more fragments            */
+
+  uint8_t tx_code; /* transmitted code in request/response */
+  uint8_t rx_code; /* received code in request/response    */
+
+  uint32_t acceptable_length;
+  uint32_t buff_length; /* size of buffer for NDEF message   */
+  uint32_t ndef_length; /* length of NDEF message            */
+  uint32_t cur_length;  /* currently sent or received length */
+  uint8_t* p_ndef_buff; /* NDEF message buffer               */
+} tNFA_SNEP_CONN;
+
+/*
+** NFA SNEP control block
+*/
+typedef struct {
+  tNFA_SNEP_CONN conn[NFA_SNEP_MAX_CONN];
+  bool listen_enabled;
+  bool is_dta_mode;
+  uint8_t trace_level;
+} tNFA_SNEP_CB;
+
+/*
+** NFA SNEP default server control block
+*/
+
+/* multiple data link connections for default server */
+typedef struct {
+  tNFA_HANDLE conn_handle; /* connection handle for default server   */
+  uint8_t* p_rx_ndef;      /* buffer to receive NDEF                 */
+} tNFA_SNEP_DEFAULT_CONN;
+
+#define NFA_SNEP_DEFAULT_MAX_CONN 3
+
+typedef struct {
+  tNFA_HANDLE server_handle; /* registered handle for default server   */
+  tNFA_SNEP_DEFAULT_CONN
+      conn[NFA_SNEP_DEFAULT_MAX_CONN]; /* connections for default server */
+
+} tNFA_SNEP_DEFAULT_CB;
+
+/*****************************************************************************
+**  External variables
+*****************************************************************************/
+
+/* NFA SNEP control block */
+extern tNFA_SNEP_CB nfa_snep_cb;
+
+/* NFA SNEP default server control block */
+extern tNFA_SNEP_DEFAULT_CB nfa_snep_default_cb;
+
+/*****************************************************************************
+**  External functions
+*****************************************************************************/
+/*
+**  nfa_snep_main.c
+*/
+void nfa_snep_init(bool is_dta_mode);
+/*
+**  nfa_snep_default.c
+*/
+void nfa_snep_default_init(void);
+bool nfa_snep_start_default_server(tNFA_SNEP_MSG* p_msg);
+bool nfa_snep_stop_default_server(tNFA_SNEP_MSG* p_msg);
+/*
+**  nfa_snep_srv.c
+*/
+uint8_t nfa_snep_allocate_cb(void);
+void nfa_snep_deallocate_cb(uint8_t xx);
+void nfa_snep_send_msg(uint8_t opcode, uint8_t dlink);
+
+void nfa_snep_llcp_cback(tLLCP_SAP_CBACK_DATA* p_data);
+void nfa_snep_proc_llcp_data_ind(tLLCP_SAP_CBACK_DATA* p_data);
+void nfa_snep_proc_llcp_connect_ind(tLLCP_SAP_CBACK_DATA* p_data);
+void nfa_snep_proc_llcp_connect_resp(tLLCP_SAP_CBACK_DATA* p_data);
+void nfa_snep_proc_llcp_disconnect_ind(tLLCP_SAP_CBACK_DATA* p_data);
+void nfa_snep_proc_llcp_disconnect_resp(tLLCP_SAP_CBACK_DATA* p_data);
+void nfa_snep_proc_llcp_congest(tLLCP_SAP_CBACK_DATA* p_data);
+void nfa_snep_proc_llcp_link_status(tLLCP_SAP_CBACK_DATA* p_data);
+void nfa_snep_proc_llcp_tx_complete(tLLCP_SAP_CBACK_DATA* p_data);
+
+bool nfa_snep_reg_server(tNFA_SNEP_MSG* p_msg);
+bool nfa_snep_reg_client(tNFA_SNEP_MSG* p_msg);
+bool nfa_snep_dereg(tNFA_SNEP_MSG* p_msg);
+bool nfa_snep_connect(tNFA_SNEP_MSG* p_msg);
+bool nfa_snep_put_resp(tNFA_SNEP_MSG* p_msg);
+bool nfa_snep_get_resp(tNFA_SNEP_MSG* p_msg);
+bool nfa_snep_put_req(tNFA_SNEP_MSG* p_msg);
+bool nfa_snep_get_req(tNFA_SNEP_MSG* p_msg);
+bool nfa_snep_disconnect(tNFA_SNEP_MSG* p_msg);
+
+#endif /* #if (NFA_SNEP_INCLUDED==true) */
+#endif /* NFA_SNEP_INT_H */
diff --git a/src/nfa/int/nfa_sys.h b/src/nfa/int/nfa_sys.h
new file mode 100644
index 0000000..f55aae8
--- /dev/null
+++ b/src/nfa/int/nfa_sys.h
@@ -0,0 +1,136 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2003-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the public interface file for the BTA system manager.
+ *
+ ******************************************************************************/
+#ifndef NFA_SYS_H
+#define NFA_SYS_H
+
+#include "nfc_target.h"
+#include "gki.h"
+#include "nfa_api.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+/* SW sub-systems */
+enum {
+  NFA_ID_SYS,  /* system manager                      */
+  NFA_ID_DM,   /* device manager                      */
+  NFA_ID_EE,   /* NFCEE sub-system                    */
+  NFA_ID_P2P,  /* Peer-to-Peer sub-system             */
+  NFA_ID_SNEP, /* SNEP sub-system                     */
+  NFA_ID_RW,   /* Reader/writer sub-system            */
+  NFA_ID_CE,   /* Card-emulation sub-system           */
+  NFA_ID_HCI,  /* Host controller interface sub-system*/
+#if (NFA_DTA_INCLUDED == true)
+  NFA_ID_DTA, /* Device Test Application sub-system  */
+#endif
+  NFA_ID_MAX
+};
+typedef uint8_t tNFA_SYS_ID;
+
+/* enable function type */
+typedef void(tNFA_SYS_ENABLE)(void);
+
+/* event handler function type */
+typedef bool(tNFA_SYS_EVT_HDLR)(NFC_HDR* p_msg);
+
+/* disable function type */
+typedef void(tNFA_SYS_DISABLE)(void);
+
+/* function type for processing the change of NFCC power mode */
+typedef void(tNFA_SYS_PROC_NFCC_PWR_MODE)(uint8_t nfcc_power_mode);
+
+typedef void(tNFA_SYS_CBACK)(void);
+typedef void(tNFA_SYS_ENABLE_CBACK)(void);
+typedef void(tNFA_SYS_PROC_NFCC_PWR_MODE_CMPL)(void);
+
+/* registration structure */
+typedef struct {
+  tNFA_SYS_ENABLE* enable;
+  tNFA_SYS_EVT_HDLR* evt_hdlr;
+  tNFA_SYS_DISABLE* disable;
+  tNFA_SYS_PROC_NFCC_PWR_MODE* proc_nfcc_pwr_mode;
+} tNFA_SYS_REG;
+
+/* system manager configuration structure */
+typedef struct {
+  uint16_t mbox_evt;   /* GKI mailbox event */
+  uint8_t mbox;        /* GKI mailbox id */
+  uint8_t timer;       /* GKI timer id */
+  uint8_t trace_level; /* initial trace level */
+} tNFA_SYS_CFG;
+
+/*****************************************************************************
+**  Global data
+*****************************************************************************/
+
+/*****************************************************************************
+**  Macros
+*****************************************************************************/
+
+/* Calculate start of event enumeration; id is top 8 bits of event */
+#define NFA_SYS_EVT_START(id) ((id) << 8)
+
+/*****************************************************************************
+**  Function declarations
+*****************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void nfa_sys_init(void);
+extern void nfa_sys_event(NFC_HDR* p_msg);
+extern void nfa_sys_timer_update(void);
+extern void nfa_sys_disable_timers(void);
+extern void nfa_sys_set_trace_level(uint8_t level);
+
+extern void nfa_sys_register(uint8_t id, const tNFA_SYS_REG* p_reg);
+extern void nfa_sys_deregister(uint8_t id);
+extern void nfa_sys_check_disabled(void);
+extern bool nfa_sys_is_register(uint8_t id);
+extern void nfa_sys_disable_subsystems(bool graceful);
+extern void nfa_sys_enable_subsystems(void);
+
+extern bool nfa_sys_is_graceful_disable(void);
+extern void nfa_sys_sendmsg(void* p_msg);
+extern void nfa_sys_start_timer(TIMER_LIST_ENT* p_tle, uint16_t type,
+                                int32_t timeout);
+extern void nfa_sys_stop_timer(TIMER_LIST_ENT* p_tle);
+
+extern void nfa_sys_cback_reg_enable_complete(tNFA_SYS_ENABLE_CBACK* p_cback);
+extern void nfa_sys_cback_notify_enable_complete(uint8_t id);
+
+extern void nfa_sys_notify_nfcc_power_mode(uint8_t nfcc_power_mode);
+extern void nfa_sys_cback_reg_nfcc_power_mode_proc_complete(
+    tNFA_SYS_PROC_NFCC_PWR_MODE_CMPL* p_cback);
+extern void nfa_sys_cback_notify_nfcc_power_mode_proc_complete(uint8_t id);
+#if (NXP_EXTNS == TRUE)
+extern void nfa_sys_cback_notify_MinEnable_complete(uint8_t id);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFA_SYS_H */
diff --git a/src/nfa/int/nfa_sys_int.h b/src/nfa/int/nfa_sys_int.h
new file mode 100644
index 0000000..a5e974a
--- /dev/null
+++ b/src/nfa/int/nfa_sys_int.h
@@ -0,0 +1,71 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the private interface file for the NFA system manager.
+ *
+ ******************************************************************************/
+#ifndef NFA_SYS_INT_H
+#define NFA_SYS_INT_H
+
+#include "nfa_sys_ptim.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+/* nfa_sys flags */
+#define NFA_SYS_FL_INITIALIZED 0x00000001 /* nfa_sys initialized */
+
+/*****************************************************************************
+**  state table
+*****************************************************************************/
+
+/* system manager control block */
+typedef struct {
+  uint32_t flags; /* nfa_sys flags (must be first element of structure) */
+  tNFA_SYS_REG* reg[NFA_ID_MAX]; /* registration structures */
+  bool is_reg[NFA_ID_MAX];       /* registration structures */
+  tPTIM_CB ptim_cb;              /* protocol timer list */
+  tNFA_SYS_ENABLE_CBACK* p_enable_cback;
+  uint16_t enable_cplt_flags;
+  uint16_t enable_cplt_mask;
+
+  tNFA_SYS_PROC_NFCC_PWR_MODE_CMPL* p_proc_nfcc_pwr_mode_cmpl_cback;
+  uint16_t proc_nfcc_pwr_mode_cplt_flags;
+  uint16_t proc_nfcc_pwr_mode_cplt_mask;
+
+  bool graceful_disable; /* true if NFA_Disable () is called with true */
+  bool timers_disabled;  /* true if sys timers disabled */
+  uint8_t trace_level;   /* Trace level */
+} tNFA_SYS_CB;
+
+/*****************************************************************************
+**  Global variables
+*****************************************************************************/
+
+/* system manager control block */
+extern tNFA_SYS_CB nfa_sys_cb;
+
+/* system manager configuration structure */
+extern tNFA_SYS_CFG* p_nfa_sys_cfg;
+
+bool nfa_sys_sm_execute(NFC_HDR* p_msg);
+
+#endif /* NFA_SYS_INT_H */
diff --git a/src/nfa/int/nfa_sys_ptim.h b/src/nfa/int/nfa_sys_ptim.h
new file mode 100644
index 0000000..0549f63
--- /dev/null
+++ b/src/nfa/int/nfa_sys_ptim.h
@@ -0,0 +1,99 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2003-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Protocol timer services.
+ *
+ ******************************************************************************/
+#ifndef NFA_SYS_PTIM_H
+#define NFA_SYS_PTIM_H
+
+#include "gki.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+typedef struct {
+  TIMER_LIST_Q timer_queue; /* GKI timer queue */
+  int32_t period;           /* Timer period in milliseconds */
+  uint32_t last_gki_ticks;  /* GKI ticks since last time update called */
+  uint8_t timer_id;         /* GKI timer id */
+} tPTIM_CB;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*****************************************************************************
+**  Function Declarations
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         nfa_sys_ptim_init
+**
+** Description      Initialize a protocol timer service control block.
+**
+** Returns          void
+**
+*******************************************************************************/
+extern void nfa_sys_ptim_init(tPTIM_CB* p_cb, uint16_t period,
+                              uint8_t timer_id);
+
+/*******************************************************************************
+**
+** Function         nfa_sys_ptim_timer_update
+**
+** Description      Update the protocol timer list and handle expired timers.
+**
+** Returns          void
+**
+*******************************************************************************/
+extern void nfa_sys_ptim_timer_update(tPTIM_CB* p_cb);
+
+/*******************************************************************************
+**
+** Function         nfa_sys_ptim_start_timer
+**
+** Description      Start a protocol timer for the specified amount
+**                  of time in milliseconds.
+**
+** Returns          void
+**
+*******************************************************************************/
+extern void nfa_sys_ptim_start_timer(tPTIM_CB* p_cb, TIMER_LIST_ENT* p_tle,
+                                     uint16_t type, int32_t timeout);
+
+/*******************************************************************************
+**
+** Function         nfa_sys_ptim_stop_timer
+**
+** Description      Stop a protocol timer.
+**
+** Returns          void
+**
+*******************************************************************************/
+extern void nfa_sys_ptim_stop_timer(tPTIM_CB* p_cb, TIMER_LIST_ENT* p_tle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFA_SYS_PTIM_H */
diff --git a/src/nfa/p2p/nfa_p2p_act.c b/src/nfa/p2p/nfa_p2p_act.c
new file mode 100644
index 0000000..f0dfa9a
--- /dev/null
+++ b/src/nfa/p2p/nfa_p2p_act.c
@@ -0,0 +1,1143 @@
+/******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the implementation file for the NFA P2P.
+ *
+ ******************************************************************************/
+
+#include "string.h"
+#include "nfc_api.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "nfa_dm_int.h"
+#include "llcp_defs.h"
+#include "llcp_api.h"
+#include "nfa_p2p_api.h"
+#include "nfa_p2p_int.h"
+
+/*****************************************************************************
+**  Global Variables
+*****************************************************************************/
+
+/*****************************************************************************
+**  Static Functions
+*****************************************************************************/
+
+/*****************************************************************************
+**  Constants
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_allocate_conn_cb
+**
+** Description      Allocate data link connection control block
+**
+**
+** Returns          uint8_t
+**
+*******************************************************************************/
+static uint8_t nfa_p2p_allocate_conn_cb(uint8_t local_sap) {
+  uint8_t xx;
+
+  for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++) {
+    if (nfa_p2p_cb.conn_cb[xx].flags == 0) {
+      nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_IN_USE;
+      nfa_p2p_cb.conn_cb[xx].local_sap = local_sap;
+
+      return (xx);
+    }
+  }
+
+  P2P_TRACE_ERROR0("nfa_p2p_allocate_conn_cb (): No resource");
+
+  return LLCP_MAX_DATA_LINK;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_deallocate_conn_cb
+**
+** Description      Deallocate data link connection control block
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_p2p_deallocate_conn_cb(uint8_t xx) {
+  if (xx < LLCP_MAX_DATA_LINK) {
+    nfa_p2p_cb.conn_cb[xx].flags = 0;
+  } else {
+    P2P_TRACE_ERROR1("nfa_p2p_deallocate_conn_cb (): Invalid index (%d)", xx);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_find_conn_cb
+**
+** Description      Find data link connection control block by local/remote SAP
+**
+**
+** Returns          uint8_t
+**
+*******************************************************************************/
+static uint8_t nfa_p2p_find_conn_cb(uint8_t local_sap, uint8_t remote_sap) {
+  uint8_t xx;
+
+  for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++) {
+    if ((nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_IN_USE) &&
+        (nfa_p2p_cb.conn_cb[xx].local_sap == local_sap) &&
+        (nfa_p2p_cb.conn_cb[xx].remote_sap == remote_sap)) {
+      return (xx);
+    }
+  }
+
+  return (LLCP_MAX_DATA_LINK);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_llcp_cback
+**
+** Description      Processing SAP callback events from LLCP
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_p2p_llcp_cback(tLLCP_SAP_CBACK_DATA* p_data) {
+  P2P_TRACE_DEBUG2("nfa_p2p_llcp_cback (): event:0x%02X, local_sap:0x%02X",
+                   p_data->hdr.event, p_data->hdr.local_sap);
+
+  switch (p_data->hdr.event) {
+    case LLCP_SAP_EVT_DATA_IND:
+      nfa_p2p_proc_llcp_data_ind(p_data);
+      break;
+
+    case LLCP_SAP_EVT_CONNECT_IND:
+      nfa_p2p_proc_llcp_connect_ind(p_data);
+      break;
+
+    case LLCP_SAP_EVT_CONNECT_RESP:
+      nfa_p2p_proc_llcp_connect_resp(p_data);
+      break;
+
+    case LLCP_SAP_EVT_DISCONNECT_IND:
+      nfa_p2p_proc_llcp_disconnect_ind(p_data);
+      break;
+
+    case LLCP_SAP_EVT_DISCONNECT_RESP:
+      nfa_p2p_proc_llcp_disconnect_resp(p_data);
+      break;
+
+    case LLCP_SAP_EVT_CONGEST:
+      nfa_p2p_proc_llcp_congestion(p_data);
+      break;
+
+    case LLCP_SAP_EVT_LINK_STATUS:
+      nfa_p2p_proc_llcp_link_status(p_data);
+      break;
+
+    default:
+      P2P_TRACE_ERROR1("nfa_p2p_llcp_cback (): Unknown event:0x%02X",
+                       p_data->hdr.event);
+      return;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_sdp_cback
+**
+** Description      Process SDP callback event from LLCP
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_p2p_sdp_cback(uint8_t tid, uint8_t remote_sap) {
+  uint8_t local_sap;
+  uint8_t xx;
+  tNFA_P2P_EVT_DATA evt_data;
+
+  P2P_TRACE_DEBUG2("nfa_p2p_sdp_cback (): tid:0x%02X, remote_sap:0x%02X", tid,
+                   remote_sap);
+
+  /* search for callback function to process */
+  for (xx = 0; xx < LLCP_MAX_SDP_TRANSAC; xx++) {
+    if ((nfa_p2p_cb.sdp_cb[xx].local_sap != LLCP_INVALID_SAP) &&
+        (nfa_p2p_cb.sdp_cb[xx].tid == tid)) {
+      local_sap = nfa_p2p_cb.sdp_cb[xx].local_sap;
+
+      evt_data.sdp.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+      evt_data.sdp.remote_sap = remote_sap;
+      nfa_p2p_cb.sap_cb[local_sap].p_cback(NFA_P2P_SDP_EVT, &evt_data);
+
+      nfa_p2p_cb.sdp_cb[xx].local_sap = LLCP_INVALID_SAP;
+      break;
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_start_sdp
+**
+** Description      Initiate SDP
+**
+**
+** Returns          true if success
+**
+*******************************************************************************/
+bool nfa_p2p_start_sdp(char* p_service_name, uint8_t local_sap) {
+  int xx;
+
+  P2P_TRACE_DEBUG1("nfa_p2p_start_sdp (): SN:<%s>", p_service_name);
+
+  /* search for empty slot */
+  for (xx = 0; xx < LLCP_MAX_SDP_TRANSAC; xx++) {
+    if (nfa_p2p_cb.sdp_cb[xx].local_sap == LLCP_INVALID_SAP) {
+      if (LLCP_DiscoverService(p_service_name, nfa_p2p_sdp_cback,
+                               &(nfa_p2p_cb.sdp_cb[xx].tid)) ==
+          LLCP_STATUS_SUCCESS) {
+        nfa_p2p_cb.sdp_cb[xx].local_sap = local_sap;
+        return true;
+      } else {
+        /* failure of SDP */
+        return false;
+      }
+    }
+  }
+  return false;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_proc_llcp_data_ind
+**
+** Description      Processing incoming data event from LLCP
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_p2p_proc_llcp_data_ind(tLLCP_SAP_CBACK_DATA* p_data) {
+  uint8_t local_sap, xx;
+  tNFA_P2P_EVT_DATA evt_data;
+
+  P2P_TRACE_DEBUG0("nfa_p2p_proc_llcp_data_ind ()");
+
+  local_sap = p_data->data_ind.local_sap;
+
+  if (nfa_p2p_cb.sap_cb[local_sap].p_cback) {
+    evt_data.data.handle = 0;
+    /* if connectionless */
+    if (p_data->data_ind.link_type == NFA_P2P_LLINK_TYPE) {
+      evt_data.data.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+    } else {
+      xx = nfa_p2p_find_conn_cb(p_data->data_ind.local_sap,
+                                p_data->data_ind.remote_sap);
+
+      if (xx != LLCP_MAX_DATA_LINK) {
+        evt_data.data.handle =
+            (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
+      }
+    }
+
+    evt_data.data.remote_sap = p_data->data_ind.remote_sap;
+    evt_data.data.link_type = p_data->data_ind.link_type;
+
+    /* notify upper layer that there are data at LLCP */
+    nfa_p2p_cb.sap_cb[local_sap].p_cback(NFA_P2P_DATA_EVT, &evt_data);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_proc_llcp_connect_ind
+**
+** Description      Processing connection request from peer
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_p2p_proc_llcp_connect_ind(tLLCP_SAP_CBACK_DATA* p_data) {
+  uint8_t server_sap, local_sap;
+  tNFA_P2P_EVT_DATA evt_data;
+  uint8_t xx;
+
+  P2P_TRACE_DEBUG1("nfa_p2p_proc_llcp_connect_ind () server_sap:0x%x",
+                   p_data->connect_ind.server_sap);
+
+  server_sap = p_data->connect_ind.server_sap;
+  local_sap = p_data->connect_ind.local_sap;
+
+  if (nfa_p2p_cb.sap_cb[server_sap].p_cback) {
+    xx = nfa_p2p_allocate_conn_cb(server_sap);
+
+    if (xx != LLCP_MAX_DATA_LINK) {
+      nfa_p2p_cb.conn_cb[xx].remote_sap = p_data->connect_ind.remote_sap;
+      nfa_p2p_cb.conn_cb[xx].remote_miu = p_data->connect_ind.miu;
+
+      /* peer will not receive any data */
+      if (p_data->connect_ind.rw == 0)
+        nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_REMOTE_RW_ZERO;
+
+      evt_data.conn_req.server_handle = (NFA_HANDLE_GROUP_P2P | server_sap);
+      evt_data.conn_req.conn_handle =
+          (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
+      evt_data.conn_req.remote_sap = p_data->connect_ind.remote_sap;
+      evt_data.conn_req.remote_miu = p_data->connect_ind.miu;
+      evt_data.conn_req.remote_rw = p_data->connect_ind.rw;
+
+      nfa_p2p_cb.sap_cb[server_sap].p_cback(NFA_P2P_CONN_REQ_EVT, &evt_data);
+    }
+  } else {
+    P2P_TRACE_ERROR0("nfa_p2p_proc_llcp_connect_ind (): Not registered");
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_proc_llcp_connect_resp
+**
+** Description      Processing connection response from peer
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_p2p_proc_llcp_connect_resp(tLLCP_SAP_CBACK_DATA* p_data) {
+  uint8_t local_sap, xx;
+  tNFA_P2P_EVT_DATA evt_data;
+
+  P2P_TRACE_DEBUG0("nfa_p2p_proc_llcp_connect_resp ()");
+
+  local_sap = p_data->connect_resp.local_sap;
+
+  if (nfa_p2p_cb.sap_cb[local_sap].p_cback) {
+    xx = nfa_p2p_allocate_conn_cb(local_sap);
+
+    if (xx != LLCP_MAX_DATA_LINK) {
+      nfa_p2p_cb.conn_cb[xx].remote_sap = p_data->connect_resp.remote_sap;
+      nfa_p2p_cb.conn_cb[xx].remote_miu = p_data->connect_resp.miu;
+
+      /* peer will not receive any data */
+      if (p_data->connect_resp.rw == 0)
+        nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_REMOTE_RW_ZERO;
+
+      evt_data.connected.client_handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+      evt_data.connected.conn_handle =
+          (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
+      evt_data.connected.remote_sap = p_data->connect_resp.remote_sap;
+      evt_data.connected.remote_miu = p_data->connect_resp.miu;
+      evt_data.connected.remote_rw = p_data->connect_resp.rw;
+
+      nfa_p2p_cb.sap_cb[local_sap].p_cback(NFA_P2P_CONNECTED_EVT, &evt_data);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_proc_llcp_disconnect_ind
+**
+** Description      Processing disconnection request from peer
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_p2p_proc_llcp_disconnect_ind(tLLCP_SAP_CBACK_DATA* p_data) {
+  uint8_t local_sap, xx;
+  tNFA_P2P_EVT_DATA evt_data;
+
+  P2P_TRACE_DEBUG0("nfa_p2p_proc_llcp_disconnect_ind ()");
+
+  local_sap = p_data->disconnect_ind.local_sap;
+
+  if (nfa_p2p_cb.sap_cb[local_sap].p_cback) {
+    xx = nfa_p2p_find_conn_cb(p_data->disconnect_ind.local_sap,
+                              p_data->disconnect_ind.remote_sap);
+
+    if (xx != LLCP_MAX_DATA_LINK) {
+      evt_data.disc.handle =
+          (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
+      evt_data.disc.reason = NFA_P2P_DISC_REASON_REMOTE_INITIATE;
+
+      nfa_p2p_deallocate_conn_cb(xx);
+
+      nfa_p2p_cb.sap_cb[local_sap].p_cback(NFA_P2P_DISC_EVT, &evt_data);
+    } else {
+      /*
+      ** LLCP link has been deactivated before receiving CC or DM.
+      ** Return NFA_P2P_DISC_EVT to indicate failure of creating
+      ** connection
+      */
+
+      evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+      evt_data.disc.reason = NFA_P2P_DISC_REASON_LLCP_DEACTIVATED;
+
+      nfa_p2p_cb.sap_cb[local_sap].p_cback(NFA_P2P_DISC_EVT, &evt_data);
+
+      P2P_TRACE_ERROR0("nfa_p2p_proc_llcp_disconnect_ind (): Link deactivated");
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_proc_llcp_disconnect_resp
+**
+** Description      Processing rejected connection from peer
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_p2p_proc_llcp_disconnect_resp(tLLCP_SAP_CBACK_DATA* p_data) {
+  uint8_t local_sap, xx;
+  tNFA_P2P_EVT_DATA evt_data;
+
+  P2P_TRACE_DEBUG0("nfa_p2p_proc_llcp_disconnect_resp ()");
+
+  local_sap = p_data->disconnect_resp.local_sap;
+
+  if (nfa_p2p_cb.sap_cb[local_sap].p_cback) {
+    if (p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_RESP_DISC) {
+      evt_data.disc.reason = NFA_P2P_DISC_REASON_LOCAL_INITITATE;
+    } else if ((p_data->disconnect_resp.reason ==
+                LLCP_SAP_DM_REASON_APP_REJECTED) ||
+               (p_data->disconnect_resp.reason ==
+                LLCP_SAP_DM_REASON_PERM_REJECT_THIS) ||
+               (p_data->disconnect_resp.reason ==
+                LLCP_SAP_DM_REASON_PERM_REJECT_ANY) ||
+               (p_data->disconnect_resp.reason ==
+                LLCP_SAP_DM_REASON_TEMP_REJECT_THIS) ||
+               (p_data->disconnect_resp.reason ==
+                LLCP_SAP_DM_REASON_TEMP_REJECT_ANY)) {
+      evt_data.disc.reason = NFA_P2P_DISC_REASON_REMOTE_REJECT;
+    } else if (p_data->disconnect_resp.reason ==
+               LLCP_SAP_DM_REASON_NO_SERVICE) {
+      evt_data.disc.reason = NFA_P2P_DISC_REASON_NO_SERVICE;
+    } else if (p_data->disconnect_resp.reason ==
+               LLCP_SAP_DM_REASON_NO_ACTIVE_CONNECTION) {
+      evt_data.disc.reason = NFA_P2P_DISC_REASON_LLCP_DEACTIVATED;
+    } else {
+      evt_data.disc.reason = NFA_P2P_DISC_REASON_NO_INFORMATION;
+    }
+
+    if (evt_data.disc.reason == NFA_P2P_DISC_REASON_LOCAL_INITITATE) {
+      xx = nfa_p2p_find_conn_cb(p_data->disconnect_resp.local_sap,
+                                p_data->disconnect_resp.remote_sap);
+
+      if (xx != LLCP_MAX_DATA_LINK) {
+        evt_data.disc.handle =
+            (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
+
+        nfa_p2p_deallocate_conn_cb(xx);
+
+        nfa_p2p_cb.sap_cb[local_sap].p_cback(NFA_P2P_DISC_EVT, &evt_data);
+      } else {
+        P2P_TRACE_ERROR0(
+            "nfa_p2p_proc_llcp_disconnect_resp (): No connection found");
+      }
+    } else {
+      evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+      nfa_p2p_cb.sap_cb[local_sap].p_cback(NFA_P2P_DISC_EVT, &evt_data);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_proc_llcp_congest
+**
+** Description      Processing LLCP congestion event
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_p2p_proc_llcp_congestion(tLLCP_SAP_CBACK_DATA* p_data) {
+  uint8_t local_sap, remote_sap, xx;
+  tNFA_P2P_EVT_DATA evt_data;
+
+  local_sap = p_data->congest.local_sap;
+  remote_sap = p_data->congest.remote_sap;
+
+  evt_data.congest.link_type = p_data->congest.link_type;
+  evt_data.congest.is_congested = p_data->congest.is_congested;
+
+  if (p_data->congest.is_congested) {
+    P2P_TRACE_DEBUG2("nfa_p2p_proc_llcp_congestion () START SAP=(0x%x,0x%x)",
+                     local_sap, remote_sap);
+
+  } else {
+    P2P_TRACE_DEBUG2("nfa_p2p_proc_llcp_congestion () END SAP=(0x%x,0x%x)",
+                     local_sap, remote_sap);
+  }
+
+  if (nfa_p2p_cb.sap_cb[local_sap].p_cback) {
+    if (evt_data.congest.link_type == NFA_P2P_LLINK_TYPE) {
+      evt_data.congest.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+
+      if ((evt_data.congest.is_congested == false) &&
+          (nfa_p2p_cb.sap_cb[local_sap].flags &
+           NFA_P2P_SAP_FLAG_LLINK_CONGESTED)) {
+        nfa_p2p_cb.sap_cb[local_sap].flags &= ~NFA_P2P_SAP_FLAG_LLINK_CONGESTED;
+        nfa_p2p_cb.sap_cb[local_sap].p_cback(NFA_P2P_CONGEST_EVT, &evt_data);
+      } else if ((evt_data.congest.is_congested == true) &&
+                 (!(nfa_p2p_cb.sap_cb[local_sap].flags &
+                    NFA_P2P_SAP_FLAG_LLINK_CONGESTED))) {
+        /* this is overall congestion due to high usage of buffer pool */
+        nfa_p2p_cb.sap_cb[local_sap].flags |= NFA_P2P_SAP_FLAG_LLINK_CONGESTED;
+        nfa_p2p_cb.sap_cb[local_sap].p_cback(NFA_P2P_CONGEST_EVT, &evt_data);
+      }
+    } else {
+      xx = nfa_p2p_find_conn_cb(local_sap, remote_sap);
+
+      if (xx != LLCP_MAX_DATA_LINK) {
+        evt_data.congest.handle =
+            (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
+
+        if ((evt_data.congest.is_congested == false) &&
+            (nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_CONGESTED)) {
+          nfa_p2p_cb.conn_cb[xx].flags &= ~NFA_P2P_CONN_FLAG_CONGESTED;
+          nfa_p2p_cb.sap_cb[local_sap].p_cback(NFA_P2P_CONGEST_EVT, &evt_data);
+        } else if ((evt_data.congest.is_congested == true) &&
+                   (!(nfa_p2p_cb.conn_cb[xx].flags &
+                      NFA_P2P_CONN_FLAG_CONGESTED))) {
+          /* this is overall congestion due to high usage of buffer pool */
+          nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_CONGESTED;
+          nfa_p2p_cb.sap_cb[local_sap].p_cback(NFA_P2P_CONGEST_EVT, &evt_data);
+        }
+      } else {
+        P2P_TRACE_ERROR0(
+            "nfa_p2p_proc_llcp_congestion (): No connection found");
+      }
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_proc_llcp_link_status
+**
+** Description      Processing LLCP link status
+**
+**
+** Returns          next state after processing this event
+**
+*******************************************************************************/
+void nfa_p2p_proc_llcp_link_status(tLLCP_SAP_CBACK_DATA* p_data) {
+  uint8_t local_sap, xx;
+  tNFA_P2P_EVT_DATA evt_data;
+
+  P2P_TRACE_DEBUG1("nfa_p2p_proc_llcp_link_status () is_activated:%d",
+                   p_data->link_status.is_activated);
+
+  local_sap = p_data->link_status.local_sap;
+
+  if (nfa_p2p_cb.sap_cb[local_sap].p_cback) {
+    if (p_data->link_status.is_activated) {
+      /* only for server */
+      evt_data.activated.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+      evt_data.activated.local_link_miu = nfa_p2p_cb.local_link_miu;
+      evt_data.activated.remote_link_miu = nfa_p2p_cb.remote_link_miu;
+
+      nfa_p2p_cb.sap_cb[local_sap].p_cback(NFA_P2P_ACTIVATED_EVT, &evt_data);
+    } else /* if LLCP link is deactivated */
+    {
+      for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++) {
+        if ((nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_IN_USE) &&
+            (nfa_p2p_cb.conn_cb[xx].local_sap == local_sap)) {
+          evt_data.disc.handle =
+              (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
+          evt_data.disc.reason = NFA_P2P_DISC_REASON_LLCP_DEACTIVATED;
+
+          nfa_p2p_deallocate_conn_cb(xx);
+          nfa_p2p_cb.sap_cb[local_sap].p_cback(NFA_P2P_DISC_EVT, &evt_data);
+        }
+      }
+
+      /* notify deactivation and clear flags */
+      if (nfa_p2p_cb.sap_cb[local_sap].flags & NFA_P2P_SAP_FLAG_SERVER) {
+        evt_data.deactivated.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+        nfa_p2p_cb.sap_cb[local_sap].p_cback(NFA_P2P_DEACTIVATED_EVT,
+                                             &evt_data);
+
+        nfa_p2p_cb.sap_cb[local_sap].flags = NFA_P2P_SAP_FLAG_SERVER;
+      } else if (nfa_p2p_cb.sap_cb[local_sap].flags & NFA_P2P_SAP_FLAG_CLIENT) {
+        evt_data.deactivated.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+        nfa_p2p_cb.sap_cb[local_sap].p_cback(NFA_P2P_DEACTIVATED_EVT,
+                                             &evt_data);
+
+        nfa_p2p_cb.sap_cb[local_sap].flags = NFA_P2P_SAP_FLAG_CLIENT;
+      } else /* if this is not registered service */
+      {
+        nfa_p2p_cb.sap_cb[local_sap].p_cback = NULL;
+      }
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_reg_server
+**
+** Description      Allocate a service as server and register to LLCP
+**
+**
+** Returns          false if need to keep buffer
+**
+*******************************************************************************/
+bool nfa_p2p_reg_server(tNFA_P2P_MSG* p_msg) {
+  tNFA_P2P_EVT_DATA evt_data;
+  uint8_t server_sap;
+
+  P2P_TRACE_DEBUG0("nfa_p2p_reg_server ()");
+
+  server_sap = LLCP_RegisterServer(
+      p_msg->api_reg_server.server_sap, p_msg->api_reg_server.link_type,
+      p_msg->api_reg_server.service_name, nfa_p2p_llcp_cback);
+
+    if (server_sap == LLCP_INVALID_SAP)
+    {
+        evt_data.reg_server.server_handle = NFA_HANDLE_INVALID;
+        evt_data.reg_server.server_sap    = NFA_P2P_INVALID_SAP;
+        NQ_STRLCPY_S (evt_data.reg_server.service_name, sizeof (evt_data.reg_server.service_name),
+                       p_msg->api_reg_server.service_name, LLCP_MAX_SN_LEN);
+        evt_data.reg_server.service_name[LLCP_MAX_SN_LEN] = 0;
+
+    p_msg->api_reg_server.p_cback(NFA_P2P_REG_SERVER_EVT, &evt_data);
+
+    return true;
+  }
+
+  /* if need to update WKS in LLCP Gen bytes */
+  if (server_sap <= LLCP_UPPER_BOUND_WK_SAP) {
+    nfa_p2p_enable_listening(NFA_ID_P2P, true);
+  } else if (!nfa_p2p_cb.is_p2p_listening) {
+    nfa_p2p_enable_listening(NFA_ID_P2P, false);
+  }
+
+  nfa_p2p_cb.sap_cb[server_sap].p_cback = p_msg->api_reg_server.p_cback;
+  nfa_p2p_cb.sap_cb[server_sap].flags = NFA_P2P_SAP_FLAG_SERVER;
+
+    evt_data.reg_server.server_handle = (NFA_HANDLE_GROUP_P2P | server_sap);
+    evt_data.reg_server.server_sap    = server_sap;
+    NQ_STRLCPY_S (evt_data.reg_server.service_name, sizeof (evt_data.reg_server.service_name),
+                   p_msg->api_reg_server.service_name, LLCP_MAX_SN_LEN);
+    evt_data.reg_server.service_name[LLCP_MAX_SN_LEN] = 0;
+
+  /* notify NFA_P2P_REG_SERVER_EVT to server */
+  nfa_p2p_cb.sap_cb[server_sap].p_cback(NFA_P2P_REG_SERVER_EVT, &evt_data);
+
+  /* if LLCP is already activated */
+  if (nfa_p2p_cb.llcp_state == NFA_P2P_LLCP_STATE_ACTIVATED) {
+    evt_data.activated.handle = (NFA_HANDLE_GROUP_P2P | server_sap);
+    evt_data.activated.local_link_miu = nfa_p2p_cb.local_link_miu;
+    evt_data.activated.remote_link_miu = nfa_p2p_cb.remote_link_miu;
+
+    /* notify NFA_P2P_ACTIVATED_EVT to server */
+    nfa_p2p_cb.sap_cb[server_sap].p_cback(NFA_P2P_ACTIVATED_EVT, &evt_data);
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_reg_client
+**
+** Description      Allocate a service as client and register to LLCP
+**
+**
+** Returns          true to deallocate buffer
+**
+*******************************************************************************/
+bool nfa_p2p_reg_client(tNFA_P2P_MSG* p_msg) {
+  tNFA_P2P_EVT_DATA evt_data;
+  uint8_t local_sap;
+
+  P2P_TRACE_DEBUG0("nfa_p2p_reg_client ()");
+
+  local_sap =
+      LLCP_RegisterClient(p_msg->api_reg_client.link_type, nfa_p2p_llcp_cback);
+
+  if (local_sap == LLCP_INVALID_SAP) {
+    evt_data.reg_client.client_handle = NFA_HANDLE_INVALID;
+    p_msg->api_reg_client.p_cback(NFA_P2P_REG_CLIENT_EVT, &evt_data);
+    return true;
+  }
+
+  nfa_p2p_cb.sap_cb[local_sap].p_cback = p_msg->api_reg_client.p_cback;
+  nfa_p2p_cb.sap_cb[local_sap].flags = NFA_P2P_SAP_FLAG_CLIENT;
+
+  evt_data.reg_client.client_handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+  nfa_p2p_cb.sap_cb[local_sap].p_cback(NFA_P2P_REG_CLIENT_EVT, &evt_data);
+
+  /* if LLCP is already activated */
+  if (nfa_p2p_cb.llcp_state == NFA_P2P_LLCP_STATE_ACTIVATED) {
+    evt_data.activated.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+    evt_data.activated.local_link_miu = nfa_p2p_cb.local_link_miu;
+    evt_data.activated.remote_link_miu = nfa_p2p_cb.remote_link_miu;
+
+    /* notify NFA_P2P_ACTIVATED_EVT to client */
+    nfa_p2p_cb.sap_cb[local_sap].p_cback(NFA_P2P_ACTIVATED_EVT, &evt_data);
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_dereg
+**
+** Description      Deallocate a service as server or client and deregister to
+**                  LLCP. LLCP will deallocate data link connection created by
+**                  this server
+**
+** Returns          true to deallocate buffer
+**
+*******************************************************************************/
+bool nfa_p2p_dereg(tNFA_P2P_MSG* p_msg) {
+  uint8_t local_sap, xx;
+
+  P2P_TRACE_DEBUG0("nfa_p2p_dereg ()");
+
+  local_sap = (uint8_t)(p_msg->api_dereg.handle & NFA_HANDLE_MASK);
+
+  if (nfa_p2p_cb.sap_cb[local_sap].p_cback) {
+    for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++) {
+      if ((nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_IN_USE) &&
+          (nfa_p2p_cb.conn_cb[xx].local_sap == local_sap)) {
+        nfa_p2p_deallocate_conn_cb(xx);
+      }
+    }
+  }
+
+  LLCP_Deregister(local_sap);
+  nfa_p2p_cb.sap_cb[local_sap].p_cback = NULL;
+
+  if (nfa_p2p_cb.is_p2p_listening) {
+    /* check if this is the last server on NFA P2P */
+    for (xx = 0; xx < NFA_P2P_NUM_SAP; xx++) {
+      if ((nfa_p2p_cb.sap_cb[xx].p_cback) &&
+          (nfa_p2p_cb.sap_cb[xx].flags & NFA_P2P_SAP_FLAG_SERVER)) {
+        break;
+      }
+    }
+
+    if (xx >= NFA_P2P_NUM_SAP) {
+      /* if need to update WKS in LLCP Gen bytes */
+      if (local_sap <= LLCP_UPPER_BOUND_WK_SAP)
+        nfa_p2p_disable_listening(NFA_ID_P2P, true);
+      else
+        nfa_p2p_disable_listening(NFA_ID_P2P, false);
+    }
+    /* if need to update WKS in LLCP Gen bytes */
+    else if (local_sap <= LLCP_UPPER_BOUND_WK_SAP) {
+      nfa_p2p_enable_listening(NFA_ID_P2P, true);
+    }
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_accept_connection
+**
+** Description      Connection Confirm from local application
+**
+**
+** Returns          true to deallocate buffer
+**
+*******************************************************************************/
+bool nfa_p2p_accept_connection(tNFA_P2P_MSG* p_msg) {
+  uint8_t xx;
+  tLLCP_CONNECTION_PARAMS params;
+
+  P2P_TRACE_DEBUG0("nfa_p2p_accept_connection ()");
+
+  xx = (uint8_t)(p_msg->api_accept.conn_handle & NFA_HANDLE_MASK);
+  xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+
+  params.miu = p_msg->api_accept.miu;
+  params.rw = p_msg->api_accept.rw;
+  params.sn[0] = 0;
+
+  LLCP_ConnectCfm(nfa_p2p_cb.conn_cb[xx].local_sap,
+                  nfa_p2p_cb.conn_cb[xx].remote_sap, &params);
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_reject_connection
+**
+** Description      Reject connection by local application
+**
+**
+** Returns          true to deallocate buffer
+**
+*******************************************************************************/
+bool nfa_p2p_reject_connection(tNFA_P2P_MSG* p_msg) {
+  uint8_t xx;
+
+  P2P_TRACE_DEBUG0("nfa_p2p_reject_connection ()");
+
+  xx = (uint8_t)(p_msg->api_reject.conn_handle & NFA_HANDLE_MASK);
+  xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+
+  LLCP_ConnectReject(nfa_p2p_cb.conn_cb[xx].local_sap,
+                     nfa_p2p_cb.conn_cb[xx].remote_sap,
+                     LLCP_SAP_DM_REASON_APP_REJECTED);
+
+  /* no need to deregister service on LLCP */
+  nfa_p2p_deallocate_conn_cb(xx);
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_disconnect
+**
+** Description      Disconnect data link connection by local application
+**
+**
+** Returns          true to deallocate buffer
+**
+*******************************************************************************/
+bool nfa_p2p_disconnect(tNFA_P2P_MSG* p_msg) {
+  uint8_t local_sap, xx;
+  tLLCP_STATUS status;
+  tNFA_P2P_EVT_DATA evt_data;
+
+  P2P_TRACE_DEBUG0("nfa_p2p_disconnect ()");
+
+  xx = (uint8_t)(p_msg->api_disconnect.conn_handle & NFA_HANDLE_MASK);
+
+  /* if this is for data link connection */
+  if (xx & NFA_P2P_HANDLE_FLAG_CONN) {
+    xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+
+    status = LLCP_DisconnectReq(nfa_p2p_cb.conn_cb[xx].local_sap,
+                                nfa_p2p_cb.conn_cb[xx].remote_sap,
+                                p_msg->api_disconnect.flush);
+
+    if (status == LLCP_STATUS_SUCCESS) {
+      /* wait for disconnect response if successful */
+      return true;
+    } else {
+      /*
+      ** while we are waiting for connect confirm,
+      ** we cannot sent DISC because we don't know DSAP yet
+      */
+      local_sap = nfa_p2p_cb.conn_cb[xx].local_sap;
+
+      if (nfa_p2p_cb.sap_cb[local_sap].p_cback) {
+        evt_data.disc.handle =
+            (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
+        evt_data.disc.reason = NFA_P2P_DISC_REASON_LOCAL_INITITATE;
+
+        nfa_p2p_deallocate_conn_cb(xx);
+        nfa_p2p_cb.sap_cb[local_sap].p_cback(NFA_P2P_DISC_EVT, &evt_data);
+      }
+    }
+  } else {
+    P2P_TRACE_ERROR0("Handle is not for Data link connection");
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_create_data_link_connection
+**
+** Description      Create data link connection
+**
+**
+** Returns          true to deallocate buffer
+**
+*******************************************************************************/
+bool nfa_p2p_create_data_link_connection(tNFA_P2P_MSG* p_msg) {
+  uint8_t local_sap;
+  tNFA_P2P_EVT_DATA evt_data;
+  tLLCP_CONNECTION_PARAMS conn_params;
+  tLLCP_STATUS status;
+
+  P2P_TRACE_DEBUG0("nfa_p2p_create_data_link_connection ()");
+
+  local_sap = (uint8_t)(p_msg->api_connect.client_handle & NFA_HANDLE_MASK);
+
+  conn_params.miu = p_msg->api_connect.miu;
+  conn_params.rw = p_msg->api_connect.rw;
+
+    /* NFA_P2pConnectBySap () */
+    if (p_msg->api_connect.dsap != LLCP_INVALID_SAP)
+    {
+        conn_params.sn[0] = 0;
+        status = LLCP_ConnectReq (local_sap, p_msg->api_connect.dsap, &conn_params);
+    }
+    /* NFA_P2pConnectByName () */
+    else
+    {
+        NQ_STRLCPY_S (conn_params.sn, sizeof (conn_params.sn),
+                       p_msg->api_connect.service_name, LLCP_MAX_SN_LEN);
+        conn_params.sn[LLCP_MAX_SN_LEN] = 0;
+
+    status = LLCP_ConnectReq(local_sap, LLCP_SAP_SDP, &conn_params);
+  }
+
+  if (status != LLCP_STATUS_SUCCESS) {
+    evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+    evt_data.disc.reason = NFA_P2P_DISC_REASON_NO_INFORMATION;
+
+    nfa_p2p_cb.sap_cb[local_sap].p_cback(NFA_P2P_DISC_EVT, &evt_data);
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_send_ui
+**
+** Description      Send UI PDU
+**
+**
+** Returns          true to deallocate buffer
+**
+*******************************************************************************/
+bool nfa_p2p_send_ui(tNFA_P2P_MSG* p_msg) {
+  uint8_t local_sap;
+  tLLCP_STATUS status;
+  tNFA_P2P_EVT_DATA evt_data;
+
+  P2P_TRACE_DEBUG0("nfa_p2p_send_ui ()");
+
+  local_sap = (uint8_t)(p_msg->api_send_ui.handle & NFA_HANDLE_MASK);
+
+  /* decrease number of tx UI PDU which is not processed by NFA for congestion
+   * control */
+  if (nfa_p2p_cb.sap_cb[local_sap].num_pending_ui_pdu)
+    nfa_p2p_cb.sap_cb[local_sap].num_pending_ui_pdu--;
+
+  if (nfa_p2p_cb.total_pending_ui_pdu) nfa_p2p_cb.total_pending_ui_pdu--;
+
+  status =
+      LLCP_SendUI(local_sap, p_msg->api_send_ui.dsap, p_msg->api_send_ui.p_msg);
+
+  if (status == LLCP_STATUS_CONGESTED) {
+    if (!(nfa_p2p_cb.sap_cb[local_sap].flags &
+          NFA_P2P_SAP_FLAG_LLINK_CONGESTED)) {
+      nfa_p2p_cb.sap_cb[local_sap].flags |= NFA_P2P_SAP_FLAG_LLINK_CONGESTED;
+
+      /* notify that this logical link is congested */
+      evt_data.congest.link_type = NFA_P2P_LLINK_TYPE;
+      evt_data.congest.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+      evt_data.congest.is_congested = true;
+
+      nfa_p2p_cb.sap_cb[local_sap].p_cback(NFA_P2P_CONGEST_EVT, &evt_data);
+    }
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_send_data
+**
+** Description      Send I PDU
+**
+**
+** Returns          true to deallocate buffer
+**
+*******************************************************************************/
+bool nfa_p2p_send_data(tNFA_P2P_MSG* p_msg) {
+  tNFA_P2P_EVT_DATA evt_data;
+  tLLCP_STATUS status;
+  uint8_t xx;
+
+  P2P_TRACE_DEBUG0("nfa_p2p_send_data ()");
+
+  xx = (uint8_t)(p_msg->api_send_data.conn_handle & NFA_HANDLE_MASK);
+  xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+
+  /* decrease number of tx I PDU which is not processed by NFA for congestion
+   * control */
+  if (nfa_p2p_cb.conn_cb[xx].num_pending_i_pdu)
+    nfa_p2p_cb.conn_cb[xx].num_pending_i_pdu--;
+
+  if (nfa_p2p_cb.total_pending_i_pdu) nfa_p2p_cb.total_pending_i_pdu--;
+
+  status = LLCP_SendData(nfa_p2p_cb.conn_cb[xx].local_sap,
+                         nfa_p2p_cb.conn_cb[xx].remote_sap,
+                         p_msg->api_send_data.p_msg);
+
+  if (status == LLCP_STATUS_CONGESTED) {
+    if (!(nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_CONGESTED)) {
+      nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_CONGESTED;
+
+      /* notify that this data link is congested */
+      evt_data.congest.link_type = NFA_P2P_DLINK_TYPE;
+      evt_data.congest.handle =
+          (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
+      evt_data.congest.is_congested = true;
+
+      nfa_p2p_cb.sap_cb[nfa_p2p_cb.conn_cb[xx].local_sap].p_cback(
+          NFA_P2P_CONGEST_EVT, &evt_data);
+    }
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_set_local_busy
+**
+** Description      Set or reset local busy
+**
+**
+** Returns          true to deallocate buffer
+**
+*******************************************************************************/
+bool nfa_p2p_set_local_busy(tNFA_P2P_MSG* p_msg) {
+  uint8_t xx;
+
+  P2P_TRACE_DEBUG0("nfa_p2p_set_local_busy ()");
+
+  xx = (uint8_t)(p_msg->api_local_busy.conn_handle & NFA_HANDLE_MASK);
+  xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+
+  LLCP_SetLocalBusyStatus(nfa_p2p_cb.conn_cb[xx].local_sap,
+                          nfa_p2p_cb.conn_cb[xx].remote_sap,
+                          p_msg->api_local_busy.is_busy);
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_get_link_info
+**
+** Description      Get WKS of remote and link MIU
+**
+**
+** Returns          true to deallocate buffer
+**
+*******************************************************************************/
+bool nfa_p2p_get_link_info(tNFA_P2P_MSG* p_msg) {
+  tNFA_P2P_EVT_DATA evt_data;
+  uint8_t local_sap;
+
+  P2P_TRACE_DEBUG0("nfa_p2p_get_link_info ()");
+
+  evt_data.link_info.handle = p_msg->api_link_info.handle;
+  evt_data.link_info.wks = LLCP_GetRemoteWKS();
+  evt_data.link_info.local_link_miu = nfa_p2p_cb.local_link_miu;
+  evt_data.link_info.remote_link_miu = nfa_p2p_cb.remote_link_miu;
+
+  local_sap = (uint8_t)(p_msg->api_link_info.handle & NFA_HANDLE_MASK);
+  nfa_p2p_cb.sap_cb[local_sap].p_cback(NFA_P2P_LINK_INFO_EVT, &evt_data);
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_get_remote_sap
+**
+** Description      Get remote SAP
+**
+**
+** Returns          true to deallocate buffer
+**
+*******************************************************************************/
+bool nfa_p2p_get_remote_sap(tNFA_P2P_MSG* p_msg) {
+  tNFA_P2P_EVT_DATA evt_data;
+  uint8_t local_sap;
+
+  P2P_TRACE_DEBUG0("nfa_p2p_get_remote_sap ()");
+
+  local_sap = (uint8_t)(p_msg->api_remote_sap.handle & NFA_HANDLE_MASK);
+
+  if (!nfa_p2p_start_sdp(p_msg->api_remote_sap.service_name, local_sap)) {
+    evt_data.sdp.handle = p_msg->api_remote_sap.handle;
+    evt_data.sdp.remote_sap = 0x00;
+    nfa_p2p_cb.sap_cb[local_sap].p_cback(NFA_P2P_SDP_EVT, &evt_data);
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_set_llcp_cfg
+**
+** Description      Set LLCP configuration
+**
+**
+** Returns          true to deallocate buffer
+**
+*******************************************************************************/
+bool nfa_p2p_set_llcp_cfg(tNFA_P2P_MSG* p_msg) {
+  LLCP_SetConfig(p_msg->api_set_llcp_cfg.link_miu, p_msg->api_set_llcp_cfg.opt,
+                 p_msg->api_set_llcp_cfg.wt,
+                 p_msg->api_set_llcp_cfg.link_timeout,
+                 p_msg->api_set_llcp_cfg.inact_timeout_init,
+                 p_msg->api_set_llcp_cfg.inact_timeout_target,
+                 p_msg->api_set_llcp_cfg.symm_delay,
+                 p_msg->api_set_llcp_cfg.data_link_timeout,
+                 p_msg->api_set_llcp_cfg.delay_first_pdu_timeout);
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_restart_rf_discovery
+**
+** Description      Restart RF discovery by deactivating to IDLE
+**
+**
+** Returns          true to deallocate buffer
+**
+*******************************************************************************/
+bool nfa_p2p_restart_rf_discovery(tNFA_P2P_MSG* p_msg) {
+  (void)p_msg;
+  P2P_TRACE_DEBUG0("nfa_p2p_restart_rf_discovery ()");
+
+  nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_IDLE);
+
+  return true;
+}
diff --git a/src/nfa/p2p/nfa_p2p_api.c b/src/nfa/p2p/nfa_p2p_api.c
new file mode 100644
index 0000000..fb98795
--- /dev/null
+++ b/src/nfa/p2p/nfa_p2p_api.c
@@ -0,0 +1,1077 @@
+/******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  NFA interface to LLCP
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_api.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "llcp_defs.h"
+#include "llcp_api.h"
+#include "nfa_p2p_api.h"
+#include "nfa_p2p_int.h"
+
+/*****************************************************************************
+**  Constants
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         NFA_P2pRegisterServer
+**
+** Description      This function is called to listen to a SAP as server on
+**                  LLCP.
+**
+**                  NFA_P2P_REG_SERVER_EVT will be returned with status and
+**                  handle.
+**
+**                  If server_sap is set to NFA_P2P_ANY_SAP, then NFA will
+**                  allocate a SAP between LLCP_LOWER_BOUND_SDP_SAP and
+**                  LLCP_UPPER_BOUND_SDP_SAP Otherwise, server_sap must be
+**                  between (LLCP_SDP_SAP + 1) and LLCP_UPPER_BOUND_SDP_SAP
+**
+**                  link_type : NFA_P2P_LLINK_TYPE and/or NFA_P2P_DLINK_TYPE
+**
+** Note:            If RF discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pRegisterServer(uint8_t server_sap,
+                                  tNFA_P2P_LINK_TYPE link_type,
+                                  char* p_service_name,
+                                  tNFA_P2P_CBACK* p_cback) {
+  tNFA_P2P_API_REG_SERVER* p_msg;
+
+  P2P_TRACE_API3(
+      "NFA_P2pRegisterServer (): server_sap:0x%02x, link_type:0x%x, SN:<%s>",
+      server_sap, link_type, p_service_name);
+
+  if ((server_sap != NFA_P2P_ANY_SAP) &&
+      ((server_sap <= LLCP_SAP_SDP) ||
+       (server_sap > LLCP_UPPER_BOUND_SDP_SAP))) {
+    P2P_TRACE_ERROR2(
+        "NFA_P2pRegisterServer (): server_sap must be between %d and %d",
+        LLCP_SAP_SDP + 1, LLCP_UPPER_BOUND_SDP_SAP);
+    return (NFA_STATUS_FAILED);
+  } else if (((link_type & NFA_P2P_LLINK_TYPE) == 0x00) &&
+             ((link_type & NFA_P2P_DLINK_TYPE) == 0x00)) {
+    P2P_TRACE_ERROR1(
+        "NFA_P2pRegisterServer(): link type (0x%x) must be specified",
+        link_type);
+    return (NFA_STATUS_FAILED);
+  }
+
+  if ((p_msg = (tNFA_P2P_API_REG_SERVER*)GKI_getbuf(
+           sizeof(tNFA_P2P_API_REG_SERVER))) != NULL) {
+    p_msg->hdr.event = NFA_P2P_API_REG_SERVER_EVT;
+
+    p_msg->server_sap = server_sap;
+    p_msg->link_type = link_type;
+
+        NQ_STRLCPY_S (p_msg->service_name, sizeof (p_msg->service_name), p_service_name, LLCP_MAX_SN_LEN);
+        p_msg->service_name[LLCP_MAX_SN_LEN] = 0;
+
+    p_msg->p_cback = p_cback;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pRegisterClient
+**
+** Description      This function is called to register a client service on
+**                  LLCP.
+**
+**                  NFA_P2P_REG_CLIENT_EVT will be returned with status and
+**                  handle.
+**
+**                  link_type : NFA_P2P_LLINK_TYPE and/or NFA_P2P_DLINK_TYPE
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pRegisterClient(tNFA_P2P_LINK_TYPE link_type,
+                                  tNFA_P2P_CBACK* p_cback) {
+  tNFA_P2P_API_REG_CLIENT* p_msg;
+
+  P2P_TRACE_API1("NFA_P2pRegisterClient (): link_type:0x%x", link_type);
+
+  if (((link_type & NFA_P2P_LLINK_TYPE) == 0x00) &&
+      ((link_type & NFA_P2P_DLINK_TYPE) == 0x00)) {
+    P2P_TRACE_ERROR1(
+        "NFA_P2pRegisterClient (): link type (0x%x) must be specified",
+        link_type);
+    return (NFA_STATUS_FAILED);
+  }
+
+  if ((p_msg = (tNFA_P2P_API_REG_CLIENT*)GKI_getbuf(
+           sizeof(tNFA_P2P_API_REG_CLIENT))) != NULL) {
+    p_msg->hdr.event = NFA_P2P_API_REG_CLIENT_EVT;
+
+    p_msg->p_cback = p_cback;
+    p_msg->link_type = link_type;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pDeregister
+**
+** Description      This function is called to stop listening to a SAP as server
+**                  or stop client service on LLCP.
+**
+** Note:            If this function is called to de-register a server and RF
+**                  discovery is started,
+**                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
+**                  happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pDeregister(tNFA_HANDLE handle) {
+  tNFA_P2P_API_DEREG* p_msg;
+  tNFA_HANDLE xx;
+
+  P2P_TRACE_API1("NFA_P2pDeregister (): handle:0x%02X", handle);
+
+  xx = handle & NFA_HANDLE_MASK;
+
+  if ((xx >= NFA_P2P_NUM_SAP) || (nfa_p2p_cb.sap_cb[xx].p_cback == NULL)) {
+    P2P_TRACE_ERROR0(
+        "NFA_P2pDeregister (): Handle is invalid or not registered");
+    return (NFA_STATUS_BAD_HANDLE);
+  }
+
+  if ((p_msg = (tNFA_P2P_API_DEREG*)GKI_getbuf(sizeof(tNFA_P2P_API_DEREG))) !=
+      NULL) {
+    p_msg->hdr.event = NFA_P2P_API_DEREG_EVT;
+
+    p_msg->handle = handle;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pAcceptConn
+**
+** Description      This function is called to accept a request of data link
+**                  connection to a listening SAP on LLCP after receiving
+**                  NFA_P2P_CONN_REQ_EVT.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pAcceptConn(tNFA_HANDLE handle, uint16_t miu, uint8_t rw) {
+  tNFA_P2P_API_ACCEPT_CONN* p_msg;
+  tNFA_HANDLE xx;
+
+  P2P_TRACE_API3("NFA_P2pAcceptConn (): handle:0x%02X, MIU:%d, RW:%d", handle,
+                 miu, rw);
+
+  xx = handle & NFA_HANDLE_MASK;
+
+  if (!(xx & NFA_P2P_HANDLE_FLAG_CONN)) {
+    P2P_TRACE_ERROR0("NFA_P2pAcceptConn (): Connection Handle is not valid");
+    return (NFA_STATUS_BAD_HANDLE);
+  } else {
+    xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+  }
+
+  if ((xx >= LLCP_MAX_DATA_LINK) || (nfa_p2p_cb.conn_cb[xx].flags == 0)) {
+    P2P_TRACE_ERROR0("NFA_P2pAcceptConn (): Connection Handle is not valid");
+    return (NFA_STATUS_BAD_HANDLE);
+  }
+
+  if ((miu < LLCP_DEFAULT_MIU) || (nfa_p2p_cb.local_link_miu < miu)) {
+    P2P_TRACE_ERROR3("NFA_P2pAcceptConn (): MIU(%d) must be between %d and %d",
+                     miu, LLCP_DEFAULT_MIU, nfa_p2p_cb.local_link_miu);
+  } else if ((p_msg = (tNFA_P2P_API_ACCEPT_CONN*)GKI_getbuf(
+                  sizeof(tNFA_P2P_API_ACCEPT_CONN))) != NULL) {
+    p_msg->hdr.event = NFA_P2P_API_ACCEPT_CONN_EVT;
+
+    p_msg->conn_handle = handle;
+    p_msg->miu = miu;
+    p_msg->rw = rw;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pRejectConn
+**
+** Description      This function is called to reject a request of data link
+**                  connection to a listening SAP on LLCP after receiving
+**                  NFA_P2P_CONN_REQ_EVT.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pRejectConn(tNFA_HANDLE handle) {
+  tNFA_P2P_API_REJECT_CONN* p_msg;
+  tNFA_HANDLE xx;
+
+  P2P_TRACE_API1("NFA_P2pRejectConn (): handle:0x%02X", handle);
+
+  xx = handle & NFA_HANDLE_MASK;
+
+  if (!(xx & NFA_P2P_HANDLE_FLAG_CONN)) {
+    P2P_TRACE_ERROR0("NFA_P2pRejectConn (): Connection Handle is not valid");
+    return (NFA_STATUS_BAD_HANDLE);
+  } else {
+    xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+  }
+
+  if ((xx >= LLCP_MAX_DATA_LINK) || (nfa_p2p_cb.conn_cb[xx].flags == 0)) {
+    P2P_TRACE_ERROR0("NFA_P2pRejectConn (): Connection Handle is not valid");
+    return (NFA_STATUS_BAD_HANDLE);
+  }
+
+  if ((p_msg = (tNFA_P2P_API_REJECT_CONN*)GKI_getbuf(
+           sizeof(tNFA_P2P_API_REJECT_CONN))) != NULL) {
+    p_msg->hdr.event = NFA_P2P_API_REJECT_CONN_EVT;
+
+    p_msg->conn_handle = handle;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pDisconnect
+**
+** Description      This function is called to disconnect an existing or
+**                  connecting data link connection.
+**
+**                  discard any pending data on data link connection if flush is
+**                  set to true
+**
+**                  NFA_P2P_DISC_EVT will be returned after data link connection
+**                  is disconnected
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pDisconnect(tNFA_HANDLE handle, bool flush) {
+  tNFA_P2P_API_DISCONNECT* p_msg;
+  tNFA_HANDLE xx;
+
+  P2P_TRACE_API2("NFA_P2pDisconnect (): handle:0x%02X, flush=%d", handle,
+                 flush);
+
+  xx = handle & NFA_HANDLE_MASK;
+
+  if (xx & NFA_P2P_HANDLE_FLAG_CONN) {
+    xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+
+    if ((xx >= LLCP_MAX_DATA_LINK) || (nfa_p2p_cb.conn_cb[xx].flags == 0)) {
+      P2P_TRACE_ERROR0("NFA_P2pDisconnect (): Connection Handle is not valid");
+      return (NFA_STATUS_BAD_HANDLE);
+    }
+  } else {
+    P2P_TRACE_ERROR0("NFA_P2pDisconnect (): Handle is not valid");
+    return (NFA_STATUS_BAD_HANDLE);
+  }
+
+  if ((p_msg = (tNFA_P2P_API_DISCONNECT*)GKI_getbuf(
+           sizeof(tNFA_P2P_API_DISCONNECT))) != NULL) {
+    p_msg->hdr.event = NFA_P2P_API_DISCONNECT_EVT;
+
+    p_msg->conn_handle = handle;
+    p_msg->flush = flush;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pConnectByName
+**
+** Description      This function is called to create a connection-oriented
+**                  transport by a service name.
+**                  NFA_P2P_CONNECTED_EVT if success
+**                  NFA_P2P_DISC_EVT if failed
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if client is not registered
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pConnectByName(tNFA_HANDLE client_handle,
+                                 char* p_service_name, uint16_t miu,
+                                 uint8_t rw) {
+  tNFA_P2P_API_CONNECT* p_msg;
+  tNFA_HANDLE xx;
+
+  P2P_TRACE_API4(
+      "NFA_P2pConnectByName (): client_handle:0x%x, SN:<%s>, MIU:%d, RW:%d",
+      client_handle, p_service_name, miu, rw);
+
+  xx = client_handle & NFA_HANDLE_MASK;
+
+  if ((xx >= NFA_P2P_NUM_SAP) || (nfa_p2p_cb.sap_cb[xx].p_cback == NULL)) {
+    P2P_TRACE_ERROR0("NFA_P2pConnectByName (): Client Handle is not valid");
+    return (NFA_STATUS_BAD_HANDLE);
+  }
+
+  if ((miu < LLCP_DEFAULT_MIU) ||
+      (nfa_p2p_cb.llcp_state != NFA_P2P_LLCP_STATE_ACTIVATED) ||
+      (nfa_p2p_cb.local_link_miu < miu)) {
+    P2P_TRACE_ERROR3(
+        "NFA_P2pConnectByName (): MIU(%d) must be between %d and %d or LLCP "
+        "link is not activated",
+        miu, LLCP_DEFAULT_MIU, nfa_p2p_cb.local_link_miu);
+  } else if ((p_msg = (tNFA_P2P_API_CONNECT*)GKI_getbuf(
+                  sizeof(tNFA_P2P_API_CONNECT))) != NULL) {
+    p_msg->hdr.event = NFA_P2P_API_CONNECT_EVT;
+
+        NQ_STRLCPY_S (p_msg->service_name, sizeof (p_msg->service_name), p_service_name, LLCP_MAX_SN_LEN);
+        p_msg->service_name[LLCP_MAX_SN_LEN] = 0;
+
+    p_msg->dsap = LLCP_INVALID_SAP;
+    p_msg->miu = miu;
+    p_msg->rw = rw;
+    p_msg->client_handle = client_handle;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pConnectBySap
+**
+** Description      This function is called to create a connection-oriented
+**                  transport by a SAP.
+**                  NFA_P2P_CONNECTED_EVT if success
+**                  NFA_P2P_DISC_EVT if failed
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if client is not registered
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pConnectBySap(tNFA_HANDLE client_handle, uint8_t dsap,
+                                uint16_t miu, uint8_t rw) {
+  tNFA_P2P_API_CONNECT* p_msg;
+  tNFA_HANDLE xx;
+
+  P2P_TRACE_API4(
+      "NFA_P2pConnectBySap (): client_handle:0x%x, DSAP:0x%02X, MIU:%d, RW:%d",
+      client_handle, dsap, miu, rw);
+
+  xx = client_handle & NFA_HANDLE_MASK;
+
+  if ((xx >= NFA_P2P_NUM_SAP) || (nfa_p2p_cb.sap_cb[xx].p_cback == NULL)) {
+    P2P_TRACE_ERROR0("NFA_P2pConnectBySap (): Client Handle is not valid");
+    return (NFA_STATUS_BAD_HANDLE);
+  }
+
+  if ((miu < LLCP_DEFAULT_MIU) ||
+      (nfa_p2p_cb.llcp_state != NFA_P2P_LLCP_STATE_ACTIVATED) ||
+      (nfa_p2p_cb.local_link_miu < miu)) {
+    P2P_TRACE_ERROR3(
+        "NFA_P2pConnectBySap (): MIU(%d) must be between %d and %d, or LLCP "
+        "link is not activated",
+        miu, LLCP_DEFAULT_MIU, nfa_p2p_cb.local_link_miu);
+  } else if ((p_msg = (tNFA_P2P_API_CONNECT*)GKI_getbuf(
+                  sizeof(tNFA_P2P_API_CONNECT))) != NULL) {
+    p_msg->hdr.event = NFA_P2P_API_CONNECT_EVT;
+
+    p_msg->service_name[LLCP_MAX_SN_LEN] = 0;
+
+    p_msg->dsap = dsap;
+    p_msg->miu = miu;
+    p_msg->rw = rw;
+    p_msg->client_handle = client_handle;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pSendUI
+**
+** Description      This function is called to send data on connectionless
+**                  transport.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_BAD_LENGTH if data length is more than remote
+**                  link MIU
+**                  NFA_STATUS_CONGESTED  if congested
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pSendUI(tNFA_HANDLE handle, uint8_t dsap, uint16_t length,
+                          uint8_t* p_data) {
+  tNFA_P2P_API_SEND_UI* p_msg;
+  tNFA_STATUS ret_status = NFA_STATUS_FAILED;
+  tNFA_HANDLE xx;
+
+  P2P_TRACE_API3("NFA_P2pSendUI (): handle:0x%X, DSAP:0x%02X, length:%d",
+                 handle, dsap, length);
+
+  GKI_sched_lock();
+
+  xx = handle & NFA_HANDLE_MASK;
+
+  if ((xx >= NFA_P2P_NUM_SAP) || (nfa_p2p_cb.sap_cb[xx].p_cback == NULL)) {
+    P2P_TRACE_ERROR1("NFA_P2pSendUI (): Handle (0x%X) is not valid", handle);
+    ret_status = NFA_STATUS_BAD_HANDLE;
+  } else if (length > nfa_p2p_cb.remote_link_miu) {
+    P2P_TRACE_ERROR3(
+        "NFA_P2pSendUI (): handle:0x%X, length(%d) must be less than remote "
+        "link MIU(%d)",
+        handle, length, nfa_p2p_cb.remote_link_miu);
+    ret_status = NFA_STATUS_BAD_LENGTH;
+  } else if (nfa_p2p_cb.sap_cb[xx].flags & NFA_P2P_SAP_FLAG_LLINK_CONGESTED) {
+    P2P_TRACE_WARNING1(
+        "NFA_P2pSendUI (): handle:0x%X, logical data link is already congested",
+        handle);
+    ret_status = NFA_STATUS_CONGESTED;
+  } else if (LLCP_IsLogicalLinkCongested(
+                 (uint8_t)xx, nfa_p2p_cb.sap_cb[xx].num_pending_ui_pdu,
+                 nfa_p2p_cb.total_pending_ui_pdu,
+                 nfa_p2p_cb.total_pending_i_pdu)) {
+    nfa_p2p_cb.sap_cb[xx].flags |= NFA_P2P_SAP_FLAG_LLINK_CONGESTED;
+
+    P2P_TRACE_WARNING1(
+        "NFA_P2pSendUI(): handle:0x%X, logical data link is congested", handle);
+    ret_status = NFA_STATUS_CONGESTED;
+  } else if ((p_msg = (tNFA_P2P_API_SEND_UI*)GKI_getbuf(
+                  sizeof(tNFA_P2P_API_SEND_UI))) != NULL) {
+    p_msg->hdr.event = NFA_P2P_API_SEND_UI_EVT;
+
+    p_msg->handle = handle;
+    p_msg->dsap = dsap;
+
+    p_msg->p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
+    if (p_msg->p_msg != NULL) {
+      p_msg->p_msg->len = length;
+      p_msg->p_msg->offset = LLCP_MIN_OFFSET;
+      memcpy(((uint8_t*)(p_msg->p_msg + 1) + p_msg->p_msg->offset), p_data,
+             length);
+
+      /* increase number of tx UI PDU which is not processed by NFA for
+       * congestion control */
+      nfa_p2p_cb.sap_cb[xx].num_pending_ui_pdu++;
+      nfa_p2p_cb.total_pending_ui_pdu++;
+      nfa_sys_sendmsg(p_msg);
+
+      ret_status = NFA_STATUS_OK;
+    } else {
+      GKI_freebuf(p_msg);
+
+      nfa_p2p_cb.sap_cb[xx].flags |= NFA_P2P_SAP_FLAG_LLINK_CONGESTED;
+      ret_status = NFA_STATUS_CONGESTED;
+    }
+  }
+
+  GKI_sched_unlock();
+
+  return (ret_status);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pReadUI
+**
+** Description      This function is called to read data on connectionless
+**                  transport when receiving NFA_P2P_DATA_EVT with
+**                  NFA_P2P_LLINK_TYPE.
+**
+**                  - Remote SAP who sent UI PDU is returned.
+**                  - Information of UI PDU up to max_data_len is copied into
+**                    p_data.
+**                  - If more information of UI PDU or more UI PDU in queue then
+**                    more is returned to true.
+**                  - Information of next UI PDU is not concatenated.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pReadUI(tNFA_HANDLE handle, uint32_t max_data_len,
+                          uint8_t* p_remote_sap, uint32_t* p_data_len,
+                          uint8_t* p_data, bool* p_more) {
+  tNFA_STATUS ret_status;
+  tNFA_HANDLE xx;
+
+  P2P_TRACE_API1("NFA_P2pReadUI (): handle:0x%X", handle);
+
+  GKI_sched_lock();
+
+  xx = handle & NFA_HANDLE_MASK;
+
+  if ((xx >= NFA_P2P_NUM_SAP) || (nfa_p2p_cb.sap_cb[xx].p_cback == NULL)) {
+    P2P_TRACE_ERROR1("NFA_P2pReadUI (): Handle (0x%X) is not valid", handle);
+    ret_status = NFA_STATUS_BAD_HANDLE;
+  } else {
+    *p_more = LLCP_ReadLogicalLinkData((uint8_t)xx, max_data_len, p_remote_sap,
+                                       p_data_len, p_data);
+    ret_status = NFA_STATUS_OK;
+  }
+
+  GKI_sched_unlock();
+
+  return (ret_status);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pFlushUI
+**
+** Description      This function is called to flush data on connectionless
+**                  transport.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pFlushUI(tNFA_HANDLE handle, uint32_t* p_length) {
+  tNFA_STATUS ret_status;
+  tNFA_HANDLE xx;
+
+  P2P_TRACE_API1("NFA_P2pReadUI (): handle:0x%X", handle);
+
+  GKI_sched_lock();
+
+  xx = handle & NFA_HANDLE_MASK;
+
+  if ((xx >= NFA_P2P_NUM_SAP) || (nfa_p2p_cb.sap_cb[xx].p_cback == NULL)) {
+    P2P_TRACE_ERROR1("NFA_P2pFlushUI (): Handle (0x%X) is not valid", handle);
+    ret_status = NFA_STATUS_BAD_HANDLE;
+    *p_length = 0;
+  } else {
+    *p_length = LLCP_FlushLogicalLinkRxData((uint8_t)xx);
+    ret_status = NFA_STATUS_OK;
+  }
+
+  GKI_sched_unlock();
+
+  return (ret_status);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pSendData
+**
+** Description      This function is called to send data on connection-oriented
+**                  transport.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_BAD_LENGTH if data length is more than remote MIU
+**                  NFA_STATUS_CONGESTED  if congested
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pSendData(tNFA_HANDLE handle, uint16_t length,
+                            uint8_t* p_data) {
+  tNFA_P2P_API_SEND_DATA* p_msg;
+  tNFA_STATUS ret_status = NFA_STATUS_FAILED;
+  tNFA_HANDLE xx;
+
+  P2P_TRACE_API2("NFA_P2pSendData (): handle:0x%X, length:%d", handle, length);
+
+  GKI_sched_lock();
+
+  xx = handle & NFA_HANDLE_MASK;
+  xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+
+  if ((!(handle & NFA_P2P_HANDLE_FLAG_CONN)) || (xx >= LLCP_MAX_DATA_LINK) ||
+      (nfa_p2p_cb.conn_cb[xx].flags == 0)) {
+    P2P_TRACE_ERROR1("NFA_P2pSendData (): Handle(0x%X) is not valid", handle);
+    ret_status = NFA_STATUS_BAD_HANDLE;
+  } else if (nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_REMOTE_RW_ZERO) {
+    P2P_TRACE_ERROR1(
+        "NFA_P2pSendData (): handle:0x%X, Remote set RW to 0 (flow off)",
+        handle);
+    ret_status = NFA_STATUS_FAILED;
+  } else if (nfa_p2p_cb.conn_cb[xx].remote_miu < length) {
+    P2P_TRACE_ERROR2(
+        "NFA_P2pSendData (): handle:0x%X, Data more than remote MIU(%d)",
+        handle, nfa_p2p_cb.conn_cb[xx].remote_miu);
+    ret_status = NFA_STATUS_BAD_LENGTH;
+  } else if (nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_CONGESTED) {
+    P2P_TRACE_WARNING1(
+        "NFA_P2pSendData (): handle:0x%X, data link connection is already "
+        "congested",
+        handle);
+    ret_status = NFA_STATUS_CONGESTED;
+  } else if (LLCP_IsDataLinkCongested(nfa_p2p_cb.conn_cb[xx].local_sap,
+                                      nfa_p2p_cb.conn_cb[xx].remote_sap,
+                                      nfa_p2p_cb.conn_cb[xx].num_pending_i_pdu,
+                                      nfa_p2p_cb.total_pending_ui_pdu,
+                                      nfa_p2p_cb.total_pending_i_pdu)) {
+    nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_CONGESTED;
+
+    P2P_TRACE_WARNING1(
+        "NFA_P2pSendData (): handle:0x%X, data link connection is congested",
+        handle);
+    ret_status = NFA_STATUS_CONGESTED;
+  } else if ((p_msg = (tNFA_P2P_API_SEND_DATA*)GKI_getbuf(
+                  sizeof(tNFA_P2P_API_SEND_DATA))) != NULL) {
+    p_msg->hdr.event = NFA_P2P_API_SEND_DATA_EVT;
+
+    p_msg->conn_handle = handle;
+
+    p_msg->p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
+    if (p_msg->p_msg != NULL) {
+      p_msg->p_msg->len = length;
+      p_msg->p_msg->offset = LLCP_MIN_OFFSET;
+      memcpy(((uint8_t*)(p_msg->p_msg + 1) + p_msg->p_msg->offset), p_data,
+             length);
+
+      /* increase number of tx I PDU which is not processed by NFA for
+       * congestion control */
+      nfa_p2p_cb.conn_cb[xx].num_pending_i_pdu++;
+      nfa_p2p_cb.total_pending_i_pdu++;
+      nfa_sys_sendmsg(p_msg);
+
+      ret_status = NFA_STATUS_OK;
+    } else {
+      GKI_freebuf(p_msg);
+      nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_CONGESTED;
+      ret_status = NFA_STATUS_CONGESTED;
+    }
+  }
+
+  GKI_sched_unlock();
+
+  return (ret_status);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pReadData
+**
+** Description      This function is called to read data on connection-oriented
+**                  transport when receiving NFA_P2P_DATA_EVT with
+**                  NFA_P2P_DLINK_TYPE.
+**
+**                  - Information of I PDU is copied into p_data up to
+**                    max_data_len.
+**                  - If more information of I PDU or more I PDU in queue, then
+**                    more is returned to true.
+**                  - Information of next I PDU is not concatenated.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pReadData(tNFA_HANDLE handle, uint32_t max_data_len,
+                            uint32_t* p_data_len, uint8_t* p_data,
+                            bool* p_more) {
+  tNFA_STATUS ret_status;
+  tNFA_HANDLE xx;
+
+  P2P_TRACE_API1("NFA_P2pReadData (): handle:0x%X", handle);
+
+  GKI_sched_lock();
+
+  xx = handle & NFA_HANDLE_MASK;
+  xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+
+  if ((!(handle & NFA_P2P_HANDLE_FLAG_CONN)) || (xx >= LLCP_MAX_DATA_LINK) ||
+      (nfa_p2p_cb.conn_cb[xx].flags == 0)) {
+    P2P_TRACE_ERROR1("NFA_P2pReadData (): Handle(0x%X) is not valid", handle);
+    ret_status = NFA_STATUS_BAD_HANDLE;
+  } else {
+    *p_more = LLCP_ReadDataLinkData(nfa_p2p_cb.conn_cb[xx].local_sap,
+                                    nfa_p2p_cb.conn_cb[xx].remote_sap,
+                                    max_data_len, p_data_len, p_data);
+    ret_status = NFA_STATUS_OK;
+  }
+
+  GKI_sched_unlock();
+
+  return (ret_status);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pFlushData
+**
+** Description      This function is called to flush data on connection-oriented
+**                  transport.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pFlushData(tNFA_HANDLE handle, uint32_t* p_length) {
+  tNFA_STATUS ret_status;
+  tNFA_HANDLE xx;
+
+  P2P_TRACE_API1("NFA_P2pFlushData (): handle:0x%X", handle);
+
+  GKI_sched_lock();
+
+  xx = handle & NFA_HANDLE_MASK;
+  xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+
+  if ((!(handle & NFA_P2P_HANDLE_FLAG_CONN)) || (xx >= LLCP_MAX_DATA_LINK) ||
+      (nfa_p2p_cb.conn_cb[xx].flags == 0)) {
+    P2P_TRACE_ERROR1("NFA_P2pFlushData (): Handle(0x%X) is not valid", handle);
+    ret_status = NFA_STATUS_BAD_HANDLE;
+  } else {
+    *p_length = LLCP_FlushDataLinkRxData(nfa_p2p_cb.conn_cb[xx].local_sap,
+                                         nfa_p2p_cb.conn_cb[xx].remote_sap);
+    ret_status = NFA_STATUS_OK;
+  }
+
+  GKI_sched_unlock();
+
+  return (ret_status);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pSetLocalBusy
+**
+** Description      This function is called to stop or resume incoming data on
+**                  connection-oriented transport.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pSetLocalBusy(tNFA_HANDLE conn_handle, bool is_busy) {
+  tNFA_P2P_API_SET_LOCAL_BUSY* p_msg;
+  tNFA_HANDLE xx;
+
+  P2P_TRACE_API2("NFA_P2pSetLocalBusy (): conn_handle:0x%02X, is_busy:%d",
+                 conn_handle, is_busy);
+
+  xx = conn_handle & NFA_HANDLE_MASK;
+
+  if (!(xx & NFA_P2P_HANDLE_FLAG_CONN)) {
+    P2P_TRACE_ERROR0("NFA_P2pSetLocalBusy (): Connection Handle is not valid");
+    return (NFA_STATUS_BAD_HANDLE);
+  } else {
+    xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+  }
+
+  if ((xx >= LLCP_MAX_DATA_LINK) || (nfa_p2p_cb.conn_cb[xx].flags == 0)) {
+    P2P_TRACE_ERROR0("NFA_P2pSetLocalBusy (): Connection Handle is not valid");
+    return (NFA_STATUS_BAD_HANDLE);
+  }
+
+  if ((p_msg = (tNFA_P2P_API_SET_LOCAL_BUSY*)GKI_getbuf(
+           sizeof(tNFA_P2P_API_SET_LOCAL_BUSY))) != NULL) {
+    p_msg->hdr.event = NFA_P2P_API_SET_LOCAL_BUSY_EVT;
+
+    p_msg->conn_handle = conn_handle;
+    p_msg->is_busy = is_busy;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pGetLinkInfo
+**
+** Description      This function is called to get local/remote link MIU and
+**                  Well-Known Service list encoded as a 16-bit field of
+**                  connected LLCP. NFA_P2P_LINK_INFO_EVT will be returned.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if server or client is not registered
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pGetLinkInfo(tNFA_HANDLE handle) {
+  tNFA_P2P_API_GET_LINK_INFO* p_msg;
+  tNFA_HANDLE xx;
+
+  P2P_TRACE_API1("NFA_P2pGetLinkInfo (): handle:0x%x", handle);
+
+  if (nfa_p2p_cb.llcp_state != NFA_P2P_LLCP_STATE_ACTIVATED) {
+    P2P_TRACE_ERROR0("NFA_P2pGetLinkInfo (): LLCP link is not activated");
+    return (NFA_STATUS_FAILED);
+  }
+
+  xx = handle & NFA_HANDLE_MASK;
+
+  if ((xx >= NFA_P2P_NUM_SAP) || (nfa_p2p_cb.sap_cb[xx].p_cback == NULL)) {
+    P2P_TRACE_ERROR0(
+        "NFA_P2pGetLinkInfo (): Handle is invalid or not registered");
+    return (NFA_STATUS_BAD_HANDLE);
+  }
+
+  if ((p_msg = (tNFA_P2P_API_GET_LINK_INFO*)GKI_getbuf(
+           sizeof(tNFA_P2P_API_GET_LINK_INFO))) != NULL) {
+    p_msg->hdr.event = NFA_P2P_API_GET_LINK_INFO_EVT;
+
+    p_msg->handle = handle;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pGetRemoteSap
+**
+** Description      This function is called to get SAP associated by service
+**                  name on connected remote LLCP.
+**                  NFA_P2P_SDP_EVT will be returned.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if server or client is not registered
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pGetRemoteSap(tNFA_HANDLE handle, char* p_service_name) {
+  tNFA_P2P_API_GET_REMOTE_SAP* p_msg;
+  tNFA_HANDLE xx;
+
+  P2P_TRACE_API2("NFA_P2pGetRemoteSap(): handle:0x%x, SN:<%s>", handle,
+                 p_service_name);
+
+  if (nfa_p2p_cb.llcp_state != NFA_P2P_LLCP_STATE_ACTIVATED) {
+    P2P_TRACE_ERROR0("NFA_P2pGetRemoteSap(): LLCP link is not activated");
+    return (NFA_STATUS_FAILED);
+  }
+
+  xx = handle & NFA_HANDLE_MASK;
+
+  if ((xx >= NFA_P2P_NUM_SAP) || (nfa_p2p_cb.sap_cb[xx].p_cback == NULL)) {
+    P2P_TRACE_ERROR0(
+        "NFA_P2pGetRemoteSap (): Handle is invalid or not registered");
+    return (NFA_STATUS_BAD_HANDLE);
+  }
+
+  if ((p_msg = (tNFA_P2P_API_GET_REMOTE_SAP*)GKI_getbuf(
+           sizeof(tNFA_P2P_API_GET_REMOTE_SAP))) != NULL) {
+    p_msg->hdr.event = NFA_P2P_API_GET_REMOTE_SAP_EVT;
+
+    p_msg->handle = handle;
+
+        NQ_STRLCPY_S (p_msg->service_name, sizeof (p_msg->service_name), p_service_name, LLCP_MAX_SN_LEN);
+        p_msg->service_name[LLCP_MAX_SN_LEN] = 0;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pSetLLCPConfig
+**
+** Description      This function is called to change LLCP config parameters.
+**                  Application must call while LLCP is not activated.
+**
+**                  Parameters descriptions (default value)
+**                  - Local Link MIU (LLCP_MIU)
+**                  - Option parameter (LLCP_OPT_VALUE)
+**                  - Response Waiting Time Index (LLCP_WAITING_TIME)
+**                  - Local Link Timeout (LLCP_LTO_VALUE)
+**                  - Inactivity Timeout as initiator role
+**                    (LLCP_INIT_INACTIVITY_TIMEOUT)
+**                  - Inactivity Timeout as target role
+**                    (LLCP_TARGET_INACTIVITY_TIMEOUT)
+**                  - Delay SYMM response (LLCP_DELAY_RESP_TIME)
+**                  - Data link connection timeout
+**                    (LLCP_DATA_LINK_CONNECTION_TOUT)
+**                  - Delay timeout to send first PDU as initiator
+**                    (LLCP_DELAY_TIME_TO_SEND_FIRST_PDU)
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pSetLLCPConfig(uint16_t link_miu, uint8_t opt, uint8_t wt,
+                                 uint16_t link_timeout,
+                                 uint16_t inact_timeout_init,
+                                 uint16_t inact_timeout_target,
+                                 uint16_t symm_delay,
+                                 uint16_t data_link_timeout,
+                                 uint16_t delay_first_pdu_timeout) {
+  tNFA_P2P_API_SET_LLCP_CFG* p_msg;
+
+  P2P_TRACE_API4(
+      "NFA_P2pSetLLCPConfig ():link_miu:%d, opt:0x%02X, wt:%d, link_timeout:%d",
+      link_miu, opt, wt, link_timeout);
+  P2P_TRACE_API4(
+      "                       inact_timeout(init:%d, target:%d), "
+      "symm_delay:%d, data_link_timeout:%d",
+      inact_timeout_init, inact_timeout_target, symm_delay, data_link_timeout);
+  P2P_TRACE_API1("                       delay_first_pdu_timeout:%d",
+                 delay_first_pdu_timeout);
+
+  if (nfa_p2p_cb.llcp_state == NFA_P2P_LLCP_STATE_ACTIVATED) {
+    P2P_TRACE_ERROR0("NFA_P2pSetLLCPConfig (): LLCP link is activated");
+    return (NFA_STATUS_FAILED);
+  }
+
+  if ((p_msg = (tNFA_P2P_API_SET_LLCP_CFG*)GKI_getbuf(
+           sizeof(tNFA_P2P_API_SET_LLCP_CFG))) != NULL) {
+    p_msg->hdr.event = NFA_P2P_API_SET_LLCP_CFG_EVT;
+
+    p_msg->link_miu = link_miu;
+    p_msg->opt = opt;
+    p_msg->wt = wt;
+    p_msg->link_timeout = link_timeout;
+    p_msg->inact_timeout_init = inact_timeout_init;
+    p_msg->inact_timeout_target = inact_timeout_target;
+    p_msg->symm_delay = symm_delay;
+    p_msg->data_link_timeout = data_link_timeout;
+    p_msg->delay_first_pdu_timeout = delay_first_pdu_timeout;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pGetLLCPConfig
+**
+** Description      This function is called to read LLCP config parameters.
+**
+**                  Parameters descriptions
+**                  - Local Link MIU
+**                  - Option parameter
+**                  - Response Waiting Time Index
+**                  - Local Link Timeout
+**                  - Inactivity Timeout as initiator role
+**                  - Inactivity Timeout as target role
+**                  - Delay SYMM response
+**                  - Data link connection timeout
+**                  - Delay timeout to send first PDU as initiator
+**
+** Returns          None
+**
+*******************************************************************************/
+void NFA_P2pGetLLCPConfig(uint16_t* p_link_miu, uint8_t* p_opt, uint8_t* p_wt,
+                          uint16_t* p_link_timeout,
+                          uint16_t* p_inact_timeout_init,
+                          uint16_t* p_inact_timeout_target,
+                          uint16_t* p_symm_delay, uint16_t* p_data_link_timeout,
+                          uint16_t* p_delay_first_pdu_timeout) {
+  LLCP_GetConfig(p_link_miu, p_opt, p_wt, p_link_timeout, p_inact_timeout_init,
+                 p_inact_timeout_target, p_symm_delay, p_data_link_timeout,
+                 p_delay_first_pdu_timeout);
+
+  P2P_TRACE_API4(
+      "NFA_P2pGetLLCPConfig () link_miu:%d, opt:0x%02X, wt:%d, link_timeout:%d",
+      *p_link_miu, *p_opt, *p_wt, *p_link_timeout);
+  P2P_TRACE_API4(
+      "                       inact_timeout(init:%d, target:%d), "
+      "symm_delay:%d, data_link_timeout:%d",
+      *p_inact_timeout_init, *p_inact_timeout_target, *p_symm_delay,
+      *p_data_link_timeout);
+  P2P_TRACE_API1("delay_first_pdu_timeout:%d", *p_delay_first_pdu_timeout);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pSetTraceLevel
+**
+** Description      This function sets the trace level for P2P.  If called with
+**                  a value of 0xFF, it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+uint8_t NFA_P2pSetTraceLevel(uint8_t new_level) {
+  if (new_level != 0xFF) nfa_p2p_cb.trace_level = new_level;
+
+  return (nfa_p2p_cb.trace_level);
+}
diff --git a/src/nfa/p2p/nfa_p2p_main.c b/src/nfa/p2p/nfa_p2p_main.c
new file mode 100644
index 0000000..a6207a1
--- /dev/null
+++ b/src/nfa/p2p/nfa_p2p_main.c
@@ -0,0 +1,811 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the main implementation file for the NFA P2P.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_api.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "nfa_dm_int.h"
+#include "llcp_api.h"
+#include "llcp_defs.h"
+#include "nfa_p2p_api.h"
+#include "nfa_p2p_int.h"
+
+/*****************************************************************************
+**  Global Variables
+*****************************************************************************/
+
+/* system manager control block definition */
+tNFA_P2P_CB nfa_p2p_cb;
+
+/*****************************************************************************
+**  Static Functions
+*****************************************************************************/
+
+/* event handler function type */
+static bool nfa_p2p_evt_hdlr(NFC_HDR* p_msg);
+
+/* disable function type */
+static void nfa_p2p_sys_disable(void);
+static void nfa_p2p_update_active_listen(void);
+
+/* debug functions type */
+#if (BT_TRACE_VERBOSE == true)
+static char* nfa_p2p_llcp_state_code(tNFA_P2P_LLCP_STATE state_code);
+#endif
+
+/*****************************************************************************
+**  Constants
+*****************************************************************************/
+/* timeout to restore active listen mode if no RF activation on passive mode */
+#define NFA_P2P_RESTORE_ACTIVE_LISTEN_TIMEOUT 5000
+
+static const tNFA_SYS_REG nfa_p2p_sys_reg = {NULL, nfa_p2p_evt_hdlr,
+                                             nfa_p2p_sys_disable, NULL};
+
+#define NFA_P2P_NUM_ACTIONS (NFA_P2P_LAST_EVT & 0x00ff)
+
+/* type for action functions */
+typedef bool (*tNFA_P2P_ACTION)(tNFA_P2P_MSG* p_data);
+
+/* action function list */
+const tNFA_P2P_ACTION nfa_p2p_action[] = {
+    nfa_p2p_reg_server,                  /* NFA_P2P_API_REG_SERVER_EVT       */
+    nfa_p2p_reg_client,                  /* NFA_P2P_API_REG_CLIENT_EVT       */
+    nfa_p2p_dereg,                       /* NFA_P2P_API_DEREG_EVT            */
+    nfa_p2p_accept_connection,           /* NFA_P2P_API_ACCEPT_CONN_EVT      */
+    nfa_p2p_reject_connection,           /* NFA_P2P_API_REJECT_CONN_EVT      */
+    nfa_p2p_disconnect,                  /* NFA_P2P_API_DISCONNECT_EVT       */
+    nfa_p2p_create_data_link_connection, /* NFA_P2P_API_CONNECT_EVT          */
+    nfa_p2p_send_ui,                     /* NFA_P2P_API_SEND_UI_EVT          */
+    nfa_p2p_send_data,                   /* NFA_P2P_API_SEND_DATA_EVT        */
+    nfa_p2p_set_local_busy,              /* NFA_P2P_API_SET_LOCAL_BUSY_EVT   */
+    nfa_p2p_get_link_info,               /* NFA_P2P_API_GET_LINK_INFO_EVT    */
+    nfa_p2p_get_remote_sap,              /* NFA_P2P_API_GET_REMOTE_SAP_EVT   */
+    nfa_p2p_set_llcp_cfg,                /* NFA_P2P_API_SET_LLCP_CFG_EVT     */
+    nfa_p2p_restart_rf_discovery         /* NFA_P2P_INT_RESTART_RF_DISC_EVT  */
+};
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_discovery_cback
+**
+** Description      Processing event from discovery callback for listening
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_p2p_discovery_cback(tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER* p_data) {
+  tNFA_CONN_EVT_DATA evt_data;
+
+  P2P_TRACE_DEBUG1("nfa_p2p_discovery_cback (): event:0x%02X", event);
+
+  switch (event) {
+    case NFA_DM_RF_DISC_START_EVT:
+      if (p_data->status == NFC_STATUS_OK) {
+        nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_LISTENING;
+        nfa_p2p_cb.rf_disc_state = NFA_DM_RFST_DISCOVERY;
+      }
+      break;
+
+    case NFA_DM_RF_DISC_ACTIVATED_EVT:
+
+      nfa_p2p_cb.rf_disc_state = NFA_DM_RFST_LISTEN_ACTIVE;
+
+      /* notify NFC link activation */
+      memcpy(&(evt_data.activated.activate_ntf), &(p_data->activate),
+             sizeof(tNFC_ACTIVATE_DEVT));
+      nfa_dm_conn_cback_event_notify(NFA_ACTIVATED_EVT, &evt_data);
+
+      if ((p_data->activate.protocol == NFC_PROTOCOL_NFC_DEP) &&
+          ((p_data->activate.intf_param.type == NFC_INTERFACE_NFC_DEP))) {
+        nfa_p2p_activate_llcp(p_data);
+
+        /* stop timer not to deactivate LLCP link on passive mode */
+        nfa_sys_stop_timer(&nfa_p2p_cb.active_listen_restore_timer);
+      }
+      break;
+
+    case NFA_DM_RF_DISC_DEACTIVATED_EVT:
+
+      if ((nfa_p2p_cb.rf_disc_state != NFA_DM_RFST_LISTEN_ACTIVE) &&
+          (nfa_p2p_cb.rf_disc_state != NFA_DM_RFST_LISTEN_SLEEP)) {
+        /* this is not for P2P listen
+        ** DM broadcasts deactivaiton event in listen sleep state.
+        */
+        break;
+      }
+
+      /* notify deactivation */
+      if ((p_data->deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP) ||
+          (p_data->deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP_AF)) {
+        nfa_p2p_cb.rf_disc_state = NFA_DM_RFST_LISTEN_SLEEP;
+        evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_SLEEP;
+      } else {
+        nfa_p2p_cb.rf_disc_state = NFA_DM_RFST_DISCOVERY;
+        evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE;
+      }
+      nfa_dm_conn_cback_event_notify(NFA_DEACTIVATED_EVT, &evt_data);
+      break;
+
+    default:
+      P2P_TRACE_ERROR0("Unexpected event");
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_update_active_listen_timeout_cback
+**
+** Description      Timeout while waiting for passive mode activation
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_p2p_update_active_listen_timeout_cback(TIMER_LIST_ENT* p_tle) {
+  (void)p_tle;
+
+  NFA_TRACE_ERROR0("nfa_p2p_update_active_listen_timeout_cback()");
+
+  /* restore active listen mode */
+  nfa_p2p_update_active_listen();
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_update_active_listen
+**
+** Description      Remove active listen mode temporarily or restore it
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_p2p_update_active_listen(void) {
+  tNFA_DM_DISC_TECH_PROTO_MASK p2p_listen_mask = 0;
+  NFC_HDR* p_msg;
+
+  P2P_TRACE_DEBUG1(
+      "nfa_p2p_update_active_listen (): listen_tech_mask_to_restore:0x%x",
+      nfa_p2p_cb.listen_tech_mask_to_restore);
+
+  /* if active listen mode was removed temporarily */
+  if (nfa_p2p_cb.listen_tech_mask_to_restore) {
+    /* restore listen technologies */
+    nfa_p2p_cb.listen_tech_mask = nfa_p2p_cb.listen_tech_mask_to_restore;
+    nfa_p2p_cb.listen_tech_mask_to_restore = 0;
+    nfa_sys_stop_timer(&nfa_p2p_cb.active_listen_restore_timer);
+  } else {
+    /* start timer in case of no passive activation */
+    nfa_p2p_cb.active_listen_restore_timer.p_cback =
+        (TIMER_CBACK*)nfa_p2p_update_active_listen_timeout_cback;
+    nfa_sys_start_timer(&nfa_p2p_cb.active_listen_restore_timer, 0,
+                        NFA_P2P_RESTORE_ACTIVE_LISTEN_TIMEOUT);
+
+    /* save listen techonologies */
+    nfa_p2p_cb.listen_tech_mask_to_restore = nfa_p2p_cb.listen_tech_mask;
+
+    /* remove active listen mode */
+    nfa_p2p_cb.listen_tech_mask &=
+        ~(NFA_TECHNOLOGY_MASK_A_ACTIVE | NFA_TECHNOLOGY_MASK_F_ACTIVE);
+  }
+
+  if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID) {
+    nfa_dm_delete_rf_discover(nfa_p2p_cb.dm_disc_handle);
+    nfa_p2p_cb.dm_disc_handle = NFA_HANDLE_INVALID;
+  }
+
+  /* collect listen technologies with NFC-DEP protocol */
+  if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_A)
+    p2p_listen_mask |= NFA_DM_DISC_MASK_LA_NFC_DEP;
+
+  if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_F)
+    p2p_listen_mask |= NFA_DM_DISC_MASK_LF_NFC_DEP;
+
+  if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_A_ACTIVE)
+    p2p_listen_mask |= NFA_DM_DISC_MASK_LAA_NFC_DEP;
+
+  if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_F_ACTIVE)
+    p2p_listen_mask |= NFA_DM_DISC_MASK_LFA_NFC_DEP;
+
+#if (NXP_EXTNS == TRUE)
+  /*For P2P mode(Default DTA mode) open Raw channel to bypass LLCP layer. For
+   * LLCP DTA mode activate LLCP
+   * Bypassing LLCP is handled in nfa_dm_poll_disc_cback*/
+  if ((appl_dta_mode_flag == 1) &&
+      ((nfa_dm_cb.eDtaMode & 0x0F) == NFA_DTA_DEFAULT_MODE)) {
+    /* Configure listen technologies and protocols and register callback to NFA
+     * DM discovery */
+    P2P_TRACE_DEBUG0(
+        "DTA mode1:Registering nfa_dm_poll_disc_cback to avoid LLCP in P2P ");
+    nfa_p2p_cb.dm_disc_handle =
+        nfa_dm_add_rf_discover(p2p_listen_mask, NFA_DM_DISC_HOST_ID_DH,
+                               nfa_dm_poll_disc_cback_dta_wrapper);
+  } else
+#endif
+  {
+    /* Configure listen technologies and protocols and register callback to NFA
+     * DM discovery */
+    nfa_p2p_cb.dm_disc_handle = nfa_dm_add_rf_discover(
+        p2p_listen_mask, NFA_DM_DISC_HOST_ID_DH, nfa_p2p_discovery_cback);
+  }
+
+  /* restart RF discovery to update RF technologies */
+  p_msg = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR));
+  if (p_msg != NULL) {
+    p_msg->event = NFA_P2P_INT_RESTART_RF_DISC_EVT;
+    nfa_sys_sendmsg(p_msg);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_llcp_link_cback
+**
+** Description      Processing event from LLCP link management callback
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_p2p_llcp_link_cback(uint8_t event, uint8_t reason) {
+  tNFA_LLCP_ACTIVATED llcp_activated;
+  tNFA_LLCP_DEACTIVATED llcp_deactivated;
+
+  P2P_TRACE_DEBUG2("nfa_p2p_llcp_link_cback () event:0x%x, reason:0x%x", event,
+                   reason);
+
+  if (event == LLCP_LINK_ACTIVATION_COMPLETE_EVT) {
+    LLCP_GetLinkMIU(&nfa_p2p_cb.local_link_miu, &nfa_p2p_cb.remote_link_miu);
+    nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_ACTIVATED;
+
+    if (nfa_p2p_cb.is_initiator) {
+      /* notify NFA DM to send Activate Event to applicaiton with status  */
+      nfa_dm_notify_activation_status(NFA_STATUS_OK, NULL);
+    }
+
+    llcp_activated.is_initiator = nfa_p2p_cb.is_initiator;
+    llcp_activated.local_link_miu = nfa_p2p_cb.local_link_miu;
+    llcp_activated.remote_link_miu = nfa_p2p_cb.remote_link_miu;
+    llcp_activated.remote_lsc = LLCP_GetRemoteLSC();
+    llcp_activated.remote_wks = LLCP_GetRemoteWKS();
+    llcp_activated.remote_version = LLCP_GetRemoteVersion();
+
+    nfa_dm_act_conn_cback_notify(NFA_LLCP_ACTIVATED_EVT,
+                                 (void*)&llcp_activated);
+
+  } else if (event == LLCP_LINK_ACTIVATION_FAILED_EVT) {
+    nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_IDLE;
+
+    if (nfa_p2p_cb.is_initiator) {
+      /* notify NFA DM to send Activate Event to applicaiton with status  */
+      nfa_dm_notify_activation_status(NFA_STATUS_FAILED, NULL);
+    }
+
+    nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY);
+  } else if (event == LLCP_LINK_FIRST_PACKET_RECEIVED_EVT) {
+    nfa_dm_act_conn_cback_notify(NFA_LLCP_FIRST_PACKET_RECEIVED_EVT, NULL);
+  } else /* LLCP_LINK_DEACTIVATED_EVT       */
+  {
+    nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_IDLE;
+
+    /* if got RF link loss without any rx LLC PDU */
+    if (reason == LLCP_LINK_RF_LINK_LOSS_NO_RX_LLC) {
+      /* if it was active listen mode */
+      if ((nfa_p2p_cb.is_active_mode) && (!nfa_p2p_cb.is_initiator)) {
+        /* if it didn't retry without active listen mode and passive mode is
+         * available */
+        if ((nfa_p2p_cb.listen_tech_mask_to_restore == 0x00) &&
+            (nfa_p2p_cb.listen_tech_mask &
+             (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_F))) {
+          P2P_TRACE_DEBUG0("Retry without active listen mode");
+
+          /* retry without active listen mode */
+          nfa_p2p_update_active_listen();
+        }
+      } else if (nfa_p2p_cb.listen_tech_mask_to_restore) {
+        nfa_sys_start_timer(&nfa_p2p_cb.active_listen_restore_timer, 0,
+                            NFA_P2P_RESTORE_ACTIVE_LISTEN_TIMEOUT);
+      }
+
+      reason = LLCP_LINK_RF_LINK_LOSS_ERR;
+    } else {
+      if (nfa_p2p_cb.listen_tech_mask_to_restore) {
+        /* restore active listen mode */
+        nfa_p2p_update_active_listen();
+      }
+    }
+
+    llcp_deactivated.reason = reason;
+    nfa_dm_act_conn_cback_notify(NFA_LLCP_DEACTIVATED_EVT,
+                                 (void*)&llcp_deactivated);
+
+    if (reason != LLCP_LINK_RF_LINK_LOSS_ERR) /* if NFC link is still up */
+    {
+      if (nfa_p2p_cb.is_initiator) {
+#if (NXP_EXTNS == TRUE)
+        /*For LLCP DTA test, Deactivate to Sleep is needed to send DSL_REQ*/
+        if ((appl_dta_mode_flag == 1) &&
+            ((nfa_dm_cb.eDtaMode & 0x0F) == NFA_DTA_LLCP_MODE)) {
+          nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_SLEEP);
+        } else {
+#endif
+          nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY);
+#if (NXP_EXTNS == TRUE)
+        }
+#endif
+      } else if ((nfa_p2p_cb.is_active_mode) && (reason == LLCP_LINK_TIMEOUT)) {
+        /*
+        ** target needs to trun off RF in case of receiving invalid
+        ** frame from initiator
+        */
+        P2P_TRACE_DEBUG0("Got LLCP_LINK_TIMEOUT in active mode on target");
+        nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY);
+      }
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_activate_llcp
+**
+** Description      Activate LLCP link
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_p2p_activate_llcp(tNFC_DISCOVER* p_data) {
+  tLLCP_ACTIVATE_CONFIG config;
+
+  P2P_TRACE_DEBUG0("nfa_p2p_activate_llcp ()");
+
+  if ((p_data->activate.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A) ||
+      (p_data->activate.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_F) ||
+      (p_data->activate.rf_tech_param.mode ==
+       NFC_DISCOVERY_TYPE_POLL_A_ACTIVE) ||
+      (p_data->activate.rf_tech_param.mode ==
+       NFC_DISCOVERY_TYPE_POLL_F_ACTIVE)) {
+    config.is_initiator = true;
+  } else {
+    config.is_initiator = false;
+  }
+
+  if ((p_data->activate.rf_tech_param.mode ==
+       NFC_DISCOVERY_TYPE_POLL_A_ACTIVE) ||
+      (p_data->activate.rf_tech_param.mode ==
+       NFC_DISCOVERY_TYPE_POLL_F_ACTIVE) ||
+      (p_data->activate.rf_tech_param.mode ==
+       NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE) ||
+      (p_data->activate.rf_tech_param.mode ==
+       NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE)) {
+    nfa_p2p_cb.is_active_mode = true;
+  } else {
+    nfa_p2p_cb.is_active_mode = false;
+  }
+
+  nfa_p2p_cb.is_initiator = config.is_initiator;
+
+  config.max_payload_size =
+      p_data->activate.intf_param.intf_param.pa_nfc.max_payload_size;
+  config.waiting_time =
+      p_data->activate.intf_param.intf_param.pa_nfc.waiting_time;
+  config.p_gen_bytes = p_data->activate.intf_param.intf_param.pa_nfc.gen_bytes;
+  config.gen_bytes_len =
+      p_data->activate.intf_param.intf_param.pa_nfc.gen_bytes_len;
+
+  LLCP_ActivateLink(config, nfa_p2p_llcp_link_cback);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_deactivate_llcp
+**
+** Description      Deactivate LLCP link
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_p2p_deactivate_llcp(void) {
+  P2P_TRACE_DEBUG0("nfa_p2p_deactivate_llcp ()");
+
+  LLCP_DeactivateLink();
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_init
+**
+** Description      Initialize NFA P2P
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_p2p_init(void) {
+  uint8_t xx;
+
+  P2P_TRACE_DEBUG0("nfa_p2p_init ()");
+
+  /* initialize control block */
+  memset(&nfa_p2p_cb, 0, sizeof(tNFA_P2P_CB));
+  nfa_p2p_cb.dm_disc_handle = NFA_HANDLE_INVALID;
+  nfa_p2p_cb.trace_level = APPL_INITIAL_TRACE_LEVEL;
+
+  for (xx = 0; xx < LLCP_MAX_SDP_TRANSAC; xx++) {
+    nfa_p2p_cb.sdp_cb[xx].local_sap = LLCP_INVALID_SAP;
+  }
+
+  /* register message handler on NFA SYS */
+  nfa_sys_register(NFA_ID_P2P, &nfa_p2p_sys_reg);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_sys_disable
+**
+** Description      Deregister NFA P2P from NFA SYS/DM
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_p2p_sys_disable(void) {
+  P2P_TRACE_DEBUG0("nfa_p2p_sys_disable()");
+
+  nfa_sys_stop_timer(&nfa_p2p_cb.active_listen_restore_timer);
+
+  /* deregister message handler on NFA SYS */
+  nfa_sys_deregister(NFA_ID_P2P);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_set_config
+**
+** Description      Set General bytes and WT parameters for LLCP
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_p2p_set_config(tNFA_DM_DISC_TECH_PROTO_MASK disc_mask) {
+  uint8_t wt, gen_bytes_len = LLCP_MAX_GEN_BYTES;
+  uint8_t params[LLCP_MAX_GEN_BYTES + 5], *p, length;
+
+  P2P_TRACE_DEBUG0("nfa_p2p_set_config ()");
+
+  LLCP_GetDiscoveryConfig(&wt, params + 2, &gen_bytes_len);
+  if (nfa_dm_is_p2p_paused()) {
+    gen_bytes_len = 0;
+  }
+
+  if (disc_mask &
+      (NFA_DM_DISC_MASK_PA_NFC_DEP | NFA_DM_DISC_MASK_PF_NFC_DEP |
+       NFA_DM_DISC_MASK_PAA_NFC_DEP | NFA_DM_DISC_MASK_PFA_NFC_DEP)) {
+    p = params;
+
+    UINT8_TO_BE_STREAM(p, NFC_PMID_ATR_REQ_GEN_BYTES);
+    UINT8_TO_BE_STREAM(p, gen_bytes_len);
+
+    p += gen_bytes_len;
+    length = gen_bytes_len + 2;
+
+    nfa_dm_check_set_config(length, params, false);
+  }
+
+  if (disc_mask &
+      (NFA_DM_DISC_MASK_LA_NFC_DEP | NFA_DM_DISC_MASK_LF_NFC_DEP |
+       NFA_DM_DISC_MASK_LAA_NFC_DEP | NFA_DM_DISC_MASK_LFA_NFC_DEP)) {
+    p = params;
+
+    UINT8_TO_BE_STREAM(p, NFC_PMID_ATR_RES_GEN_BYTES);
+    UINT8_TO_BE_STREAM(p, gen_bytes_len);
+
+    p += gen_bytes_len;
+    length = gen_bytes_len + 2;
+
+    UINT8_TO_BE_STREAM(p, NFC_PMID_WT);
+    UINT8_TO_BE_STREAM(p, NCI_PARAM_LEN_WT);
+    UINT8_TO_BE_STREAM(p, wt);
+
+    length += 3;
+
+    nfa_dm_check_set_config(length, params, false);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_enable_listening
+**
+** Description      Configure listen technologies and protocols for LLCP
+**                  If LLCP WKS is changed then LLCP Gen bytes will be updated.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_p2p_enable_listening(tNFA_SYS_ID sys_id, bool update_wks) {
+  tNFA_DM_DISC_TECH_PROTO_MASK p2p_listen_mask = 0;
+
+  P2P_TRACE_DEBUG2("nfa_p2p_enable_listening () sys_id = %d, update_wks = %d",
+                   sys_id, update_wks);
+
+  if (sys_id == NFA_ID_P2P)
+    nfa_p2p_cb.is_p2p_listening = true;
+  else if (sys_id == NFA_ID_SNEP)
+    nfa_p2p_cb.is_snep_listening = true;
+
+  if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID) {
+    /* if need to update WKS in LLCP Gen bytes */
+    if (update_wks) {
+      /* update LLCP Gen Bytes */
+      nfa_p2p_set_config(NFA_DM_DISC_MASK_PA_NFC_DEP |
+                         NFA_DM_DISC_MASK_LA_NFC_DEP);
+    }
+    return;
+  }
+
+  /* collect listen technologies with NFC-DEP protocol */
+  if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_A)
+    p2p_listen_mask |= NFA_DM_DISC_MASK_LA_NFC_DEP;
+
+  if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_F)
+    p2p_listen_mask |= NFA_DM_DISC_MASK_LF_NFC_DEP;
+
+  if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_A_ACTIVE)
+    p2p_listen_mask |= NFA_DM_DISC_MASK_LAA_NFC_DEP;
+
+  if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_F_ACTIVE)
+    p2p_listen_mask |= NFA_DM_DISC_MASK_LFA_NFC_DEP;
+
+  if (p2p_listen_mask) {
+#if (NXP_EXTNS == TRUE)
+    /*For P2P mode(Default DTA mode) open Raw channel to bypass LLCP layer. For
+     * LLCP DTA mode activate LLCP
+     * Bypassing LLCP is handled in nfa_dm_poll_disc_cback*/
+    if ((appl_dta_mode_flag == 1) &&
+        ((nfa_dm_cb.eDtaMode & 0x0F) == NFA_DTA_DEFAULT_MODE)) {
+      /* Configure listen technologies and protocols and register callback to
+       * NFA DM discovery */
+      P2P_TRACE_DEBUG0(
+          "DTA mode2:Registering nfa_dm_poll_disc_cback to avoid LLCP in P2P ");
+      nfa_p2p_cb.dm_disc_handle =
+          nfa_dm_add_rf_discover(p2p_listen_mask, NFA_DM_DISC_HOST_ID_DH,
+                                 nfa_dm_poll_disc_cback_dta_wrapper);
+    } else
+#endif
+    {
+      /* Configure listen technologies and protocols and register callback to
+       * NFA DM discovery */
+      nfa_p2p_cb.dm_disc_handle = nfa_dm_add_rf_discover(
+          p2p_listen_mask, NFA_DM_DISC_HOST_ID_DH, nfa_p2p_discovery_cback);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_disable_listening
+**
+** Description      Remove listen technologies and protocols for LLCP and
+**                  deregister callback from NFA DM discovery if all of
+**                  P2P/CHO/SNEP doesn't listen LLCP any more.
+**                  If LLCP WKS is changed then ATR_RES will be updated.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_p2p_disable_listening(tNFA_SYS_ID sys_id, bool update_wks) {
+  P2P_TRACE_DEBUG2("nfa_p2p_disable_listening ()  sys_id = %d, update_wks = %d",
+                   sys_id, update_wks);
+
+  if (sys_id == NFA_ID_P2P)
+    nfa_p2p_cb.is_p2p_listening = false;
+  else if (sys_id == NFA_ID_SNEP)
+    nfa_p2p_cb.is_snep_listening = false;
+
+  if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID) {
+    if ((nfa_p2p_cb.is_p2p_listening == false) &&
+        (nfa_p2p_cb.is_snep_listening == false)) {
+      nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_IDLE;
+      nfa_p2p_cb.rf_disc_state = NFA_DM_RFST_IDLE;
+
+      nfa_dm_delete_rf_discover(nfa_p2p_cb.dm_disc_handle);
+      nfa_p2p_cb.dm_disc_handle = NFA_HANDLE_INVALID;
+    } else if (update_wks) {
+      /* update LLCP Gen Bytes */
+      nfa_p2p_set_config(NFA_DM_DISC_MASK_PA_NFC_DEP |
+                         NFA_DM_DISC_MASK_LA_NFC_DEP);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_update_listen_tech
+**
+** Description      Update P2P listen technologies. If there is change then
+**                  restart or stop P2P listen.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_p2p_update_listen_tech(tNFA_TECHNOLOGY_MASK tech_mask) {
+  P2P_TRACE_DEBUG1("nfa_p2p_update_listen_tech ()  tech_mask = 0x%x",
+                   tech_mask);
+
+  if (nfa_p2p_cb.listen_tech_mask_to_restore) {
+    nfa_p2p_cb.listen_tech_mask_to_restore = 0;
+    nfa_sys_stop_timer(&nfa_p2p_cb.active_listen_restore_timer);
+  }
+
+  if (nfa_p2p_cb.listen_tech_mask != tech_mask) {
+    nfa_p2p_cb.listen_tech_mask = tech_mask;
+
+    if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID) {
+      nfa_p2p_cb.rf_disc_state = NFA_DM_RFST_IDLE;
+
+      nfa_dm_delete_rf_discover(nfa_p2p_cb.dm_disc_handle);
+      nfa_p2p_cb.dm_disc_handle = NFA_HANDLE_INVALID;
+    }
+
+    /* restart discovery without updating sub-module status */
+    if (nfa_p2p_cb.is_p2p_listening
+#if (NXP_EXTNS == TRUE)
+        || appl_dta_mode_flag
+#endif
+        )
+      nfa_p2p_enable_listening(NFA_ID_P2P, false);
+    else if (nfa_p2p_cb.is_snep_listening)
+      nfa_p2p_enable_listening(NFA_ID_SNEP, false);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_evt_hdlr
+**
+** Description      Processing event for NFA P2P
+**
+**
+** Returns          true if p_msg needs to be deallocated
+**
+*******************************************************************************/
+static bool nfa_p2p_evt_hdlr(NFC_HDR* p_hdr) {
+  bool delete_msg = true;
+  uint16_t event;
+
+  tNFA_P2P_MSG* p_msg = (tNFA_P2P_MSG*)p_hdr;
+
+#if (BT_TRACE_VERBOSE == true)
+  P2P_TRACE_DEBUG2("nfa_p2p_evt_hdlr (): LLCP State [%s], Event [%s]",
+                   nfa_p2p_llcp_state_code(nfa_p2p_cb.llcp_state),
+                   nfa_p2p_evt_code(p_msg->hdr.event));
+#else
+  P2P_TRACE_DEBUG2("nfa_p2p_evt_hdlr (): State 0x%02x, Event 0x%02x",
+                   nfa_p2p_cb.llcp_state, p_msg->hdr.event);
+#endif
+
+  event = p_msg->hdr.event & 0x00ff;
+
+  /* execute action functions */
+  if (event < NFA_P2P_NUM_ACTIONS) {
+    delete_msg = (*nfa_p2p_action[event])(p_msg);
+  } else {
+    P2P_TRACE_ERROR0("Unhandled event");
+  }
+
+  return delete_msg;
+}
+
+#if (BT_TRACE_VERBOSE == true)
+/*******************************************************************************
+**
+** Function         nfa_p2p_llcp_state_code
+**
+** Description
+**
+** Returns          string of state
+**
+*******************************************************************************/
+static char* nfa_p2p_llcp_state_code(tNFA_P2P_LLCP_STATE state_code) {
+  switch (state_code) {
+    case NFA_P2P_LLCP_STATE_IDLE:
+      return "Link IDLE";
+    case NFA_P2P_LLCP_STATE_LISTENING:
+      return "Link LISTENING";
+    case NFA_P2P_LLCP_STATE_ACTIVATED:
+      return "Link ACTIVATED";
+    default:
+      return "Unknown state";
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_evt_code
+**
+** Description
+**
+** Returns          string of event
+**
+*******************************************************************************/
+char* nfa_p2p_evt_code(uint16_t evt_code) {
+  switch (evt_code) {
+    case NFA_P2P_API_REG_SERVER_EVT:
+      return "API_REG_SERVER";
+    case NFA_P2P_API_REG_CLIENT_EVT:
+      return "API_REG_CLIENT";
+    case NFA_P2P_API_DEREG_EVT:
+      return "API_DEREG";
+    case NFA_P2P_API_ACCEPT_CONN_EVT:
+      return "API_ACCEPT_CONN";
+    case NFA_P2P_API_REJECT_CONN_EVT:
+      return "API_REJECT_CONN";
+    case NFA_P2P_API_DISCONNECT_EVT:
+      return "API_DISCONNECT";
+    case NFA_P2P_API_CONNECT_EVT:
+      return "API_CONNECT";
+    case NFA_P2P_API_SEND_UI_EVT:
+      return "API_SEND_UI";
+    case NFA_P2P_API_SEND_DATA_EVT:
+      return "API_SEND_DATA";
+    case NFA_P2P_API_SET_LOCAL_BUSY_EVT:
+      return "API_SET_LOCAL_BUSY";
+    case NFA_P2P_API_GET_LINK_INFO_EVT:
+      return "API_GET_LINK_INFO";
+    case NFA_P2P_API_GET_REMOTE_SAP_EVT:
+      return "API_GET_REMOTE_SAP";
+    case NFA_P2P_API_SET_LLCP_CFG_EVT:
+      return "API_SET_LLCP_CFG_EVT";
+    case NFA_P2P_INT_RESTART_RF_DISC_EVT:
+      return "RESTART_RF_DISC_EVT";
+    default:
+      return "Unknown event";
+  }
+}
+#endif /* Debug Functions */
diff --git a/src/nfa/rw/nfa_rw_act.c b/src/nfa/rw/nfa_rw_act.c
new file mode 100644
index 0000000..2f34910
--- /dev/null
+++ b/src/nfa/rw/nfa_rw_act.c
@@ -0,0 +1,3085 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  This file contains the action functions the NFA_RW state machine.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_rw_int.h"
+#include "nfa_dm_int.h"
+#include "nfa_sys_int.h"
+#include "nfa_mem_co.h"
+#include "ndef_utils.h"
+#include "rw_api.h"
+
+#define NFA_RW_OPTION_INVALID 0xFF
+
+/* Local static function prototypes */
+static tNFC_STATUS nfa_rw_start_ndef_read(void);
+static tNFC_STATUS nfa_rw_start_ndef_write(void);
+static tNFC_STATUS nfa_rw_start_ndef_detection(void);
+static tNFC_STATUS nfa_rw_config_tag_ro(bool b_hard_lock);
+static bool nfa_rw_op_req_while_busy(tNFA_RW_MSG* p_data);
+static void nfa_rw_error_cleanup(uint8_t event);
+static void nfa_rw_presence_check(tNFA_RW_MSG* p_data);
+static void nfa_rw_handle_t2t_evt(tRW_EVENT event, tRW_DATA* p_rw_data);
+static bool nfa_rw_detect_ndef(tNFA_RW_MSG* p_data);
+static void nfa_rw_cback(tRW_EVENT event, tRW_DATA* p_rw_data);
+
+/*******************************************************************************
+**
+** Function         nfa_rw_free_ndef_rx_buf
+**
+** Description      Free buffer allocated to hold incoming NDEF message
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void nfa_rw_free_ndef_rx_buf(void) {
+  if (nfa_rw_cb.p_ndef_buf) {
+    nfa_mem_co_free(nfa_rw_cb.p_ndef_buf);
+    nfa_rw_cb.p_ndef_buf = NULL;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_store_ndef_rx_buf
+**
+** Description      Store data into NDEF buffer
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static void nfa_rw_store_ndef_rx_buf(tRW_DATA* p_rw_data) {
+  uint8_t* p;
+
+  if (NULL == p_rw_data) {
+    NFA_TRACE_DEBUG0("nfa_rw_store_ndef_rx_buf;  p_rw_data is NULL");
+    return;
+  }
+
+  if (NULL == p_rw_data->data.p_data) {
+    NFA_TRACE_DEBUG0(
+        "nfa_rw_store_ndef_rx_buf;  p_rw_data->data.p_data is NULL");
+    return;
+  }
+  p = (uint8_t*)(p_rw_data->data.p_data + 1) + p_rw_data->data.p_data->offset;
+
+  /* Save data into buffer */
+  memcpy(&nfa_rw_cb.p_ndef_buf[nfa_rw_cb.ndef_rd_offset], p,
+         p_rw_data->data.p_data->len);
+  nfa_rw_cb.ndef_rd_offset += p_rw_data->data.p_data->len;
+
+  GKI_freebuf(p_rw_data->data.p_data);
+  p_rw_data->data.p_data = NULL;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_send_data_to_upper
+**
+** Description      Send data to upper layer
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static void nfa_rw_send_data_to_upper(tRW_DATA* p_rw_data) {
+  tNFA_CONN_EVT_DATA conn_evt_data;
+
+  if ((p_rw_data->status == NFC_STATUS_TIMEOUT) ||
+      (p_rw_data->data.p_data == NULL))
+    return;
+
+#if (BT_TRACE_VERBOSE == true)
+  NFA_TRACE_DEBUG2("nfa_rw_send_data_to_upper: Len [0x%X] Status [%s]",
+                   p_rw_data->data.p_data->len,
+                   NFC_GetStatusName(p_rw_data->data.status));
+#else
+  NFA_TRACE_DEBUG2("nfa_rw_send_data_to_upper: Len [0x%X] Status [0x%X]",
+                   p_rw_data->data.p_data->len, p_rw_data->data.status);
+#endif
+
+  /* Notify conn cback of NFA_DATA_EVT */
+  conn_evt_data.data.status = p_rw_data->data.status;
+  conn_evt_data.data.p_data =
+      (uint8_t*)(p_rw_data->data.p_data + 1) + p_rw_data->data.p_data->offset;
+  conn_evt_data.data.len = p_rw_data->data.p_data->len;
+
+  nfa_dm_act_conn_cback_notify(NFA_DATA_EVT, &conn_evt_data);
+
+  GKI_freebuf(p_rw_data->data.p_data);
+  p_rw_data->data.p_data = NULL;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_error_cleanup
+**
+** Description      Handle failure - signal command complete and notify app
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static void nfa_rw_error_cleanup(uint8_t event) {
+  tNFA_CONN_EVT_DATA conn_evt_data;
+
+  nfa_rw_command_complete();
+
+  conn_evt_data.status = NFA_STATUS_FAILED;
+
+  nfa_dm_act_conn_cback_notify(event, &conn_evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_check_start_presence_check_timer
+**
+** Description      Start timer to wait for specified time before presence check
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static void nfa_rw_check_start_presence_check_timer(
+    uint16_t presence_check_start_delay) {
+  if (!p_nfa_dm_cfg->auto_presence_check) return;
+
+  if (nfa_rw_cb.flags & NFA_RW_FL_NOT_EXCL_RF_MODE) {
+    if (presence_check_start_delay) {
+      NFA_TRACE_DEBUG0("Starting presence check timer...");
+      nfa_sys_start_timer(&nfa_rw_cb.tle, NFA_RW_PRESENCE_CHECK_TICK_EVT,
+                          presence_check_start_delay);
+    } else {
+      /* Presence check now */
+      nfa_rw_presence_check(NULL);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_stop_presence_check_timer
+**
+** Description      Stop timer for presence check
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void nfa_rw_stop_presence_check_timer(void) {
+  nfa_sys_stop_timer(&nfa_rw_cb.tle);
+  NFA_TRACE_DEBUG0("Stopped presence check timer (if started)");
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_handle_ndef_detect
+**
+** Description      Handler for NDEF detection reader/writer event
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static void nfa_rw_handle_ndef_detect(tRW_EVENT event, tRW_DATA* p_rw_data) {
+  tNFA_CONN_EVT_DATA conn_evt_data;
+  (void)event;
+  NFA_TRACE_DEBUG3(
+      "NDEF Detection completed: cur_size=%i, max_size=%i, flags=0x%x",
+      p_rw_data->ndef.cur_size, p_rw_data->ndef.max_size,
+      p_rw_data->ndef.flags);
+
+  /* Check if NDEF detection succeeded */
+  if (p_rw_data->ndef.status == NFC_STATUS_OK) {
+    /* Set NDEF detection state */
+    nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_TRUE;
+    nfa_rw_cb.flags |= NFA_RW_FL_NDEF_OK;
+
+    /* Store ndef properties */
+    conn_evt_data.ndef_detect.status = NFA_STATUS_OK;
+    conn_evt_data.ndef_detect.protocol = p_rw_data->ndef.protocol;
+    conn_evt_data.ndef_detect.cur_size = nfa_rw_cb.ndef_cur_size =
+        p_rw_data->ndef.cur_size;
+    conn_evt_data.ndef_detect.max_size = nfa_rw_cb.ndef_max_size =
+        p_rw_data->ndef.max_size;
+    conn_evt_data.ndef_detect.flags = p_rw_data->ndef.flags;
+
+    if (p_rw_data->ndef.flags & RW_NDEF_FL_READ_ONLY)
+      nfa_rw_cb.flags |= NFA_RW_FL_TAG_IS_READONLY;
+    else
+      nfa_rw_cb.flags &= ~NFA_RW_FL_TAG_IS_READONLY;
+
+    /* Determine what operation triggered the NDEF detection procedure */
+    if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
+      /* if ndef detection was done as part of ndef-read operation, then perform
+       * ndef read now */
+      conn_evt_data.status = nfa_rw_start_ndef_read();
+      if (conn_evt_data.status != NFA_STATUS_OK) {
+        /* Failed to start NDEF Read */
+
+        /* Command complete - perform cleanup, notify app */
+        nfa_rw_command_complete();
+        nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+      }
+    } else if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) {
+      /* if ndef detection was done as part of ndef-write operation, then
+       * perform ndef write now */
+      conn_evt_data.status = nfa_rw_start_ndef_write();
+      if (conn_evt_data.status != NFA_STATUS_OK) {
+        /* Failed to start NDEF Write.  */
+
+        /* Command complete - perform cleanup, notify app */
+        nfa_rw_command_complete();
+        nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
+      }
+    } else {
+      /* current op was stand-alone NFA_DetectNDef. Command complete - perform
+       * cleanup and notify app */
+      nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
+      nfa_rw_command_complete();
+
+      nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data);
+    }
+  } else {
+    /* NDEF detection failed... */
+
+    /* Command complete - perform cleanup, notify app */
+    nfa_rw_command_complete();
+    nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_FALSE;
+    conn_evt_data.status = p_rw_data->ndef.status;
+
+    if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
+      /* if ndef detection was done as part of ndef-read operation, then notify
+       * NDEF handlers of failure */
+      nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
+
+      /* Notify app of read status */
+      nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+    } else if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) {
+      /* if ndef detection was done as part of ndef-write operation, then notify
+       * app of failure */
+      nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
+    } else if (nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_NDEF) {
+      conn_evt_data.ndef_detect.protocol = p_rw_data->ndef.protocol;
+      /* current op was stand-alone NFA_DetectNDef. Notify app of failure */
+      if (p_rw_data->ndef.status == NFC_STATUS_TIMEOUT) {
+        /* Tag could have moved away */
+        conn_evt_data.ndef_detect.cur_size = 0;
+        conn_evt_data.ndef_detect.max_size = 0;
+        conn_evt_data.ndef_detect.flags = RW_NDEF_FL_UNKNOWN;
+        conn_evt_data.ndef_detect.status = NFA_STATUS_TIMEOUT;
+      } else {
+        /* NDEF Detection failed for other reasons */
+        conn_evt_data.ndef_detect.cur_size = nfa_rw_cb.ndef_cur_size =
+            p_rw_data->ndef.cur_size;
+        conn_evt_data.ndef_detect.max_size = nfa_rw_cb.ndef_max_size =
+            p_rw_data->ndef.max_size;
+        conn_evt_data.ndef_detect.flags = p_rw_data->ndef.flags;
+      }
+      nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data);
+    }
+
+    nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_handle_tlv_detect
+**
+** Description      Handler for TLV detection reader/writer event
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static void nfa_rw_handle_tlv_detect(tRW_EVENT event, tRW_DATA* p_rw_data) {
+  tNFA_CONN_EVT_DATA conn_evt_data;
+  (void)event;
+  /* Set TLV detection state */
+  if (nfa_rw_cb.cur_op == NFA_RW_OP_SET_TAG_RO) {
+    if (nfa_rw_cb.tlv_st == NFA_RW_TLV_DETECT_ST_OP_NOT_STARTED) {
+      nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_LOCK_TLV_OP_COMPLETE;
+    } else {
+      nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE;
+    }
+  } else {
+    if (nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_LOCK_TLV) {
+      nfa_rw_cb.tlv_st |= NFA_RW_TLV_DETECT_ST_LOCK_TLV_OP_COMPLETE;
+    } else if (nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_MEM_TLV) {
+      nfa_rw_cb.tlv_st |= NFA_RW_TLV_DETECT_ST_MEM_TLV_OP_COMPLETE;
+    }
+  }
+
+  /* Check if TLV detection succeeded */
+  if (p_rw_data->tlv.status == NFC_STATUS_OK) {
+    NFA_TRACE_DEBUG1("TLV Detection succeeded: num_bytes=%i",
+                     p_rw_data->tlv.num_bytes);
+
+    /* Store tlv properties */
+    conn_evt_data.tlv_detect.status = NFA_STATUS_OK;
+    conn_evt_data.tlv_detect.protocol = p_rw_data->tlv.protocol;
+    conn_evt_data.tlv_detect.num_bytes = p_rw_data->tlv.num_bytes;
+
+    /* Determine what operation triggered the TLV detection procedure */
+    if (nfa_rw_cb.cur_op == NFA_RW_OP_SET_TAG_RO) {
+      if (nfa_rw_config_tag_ro(nfa_rw_cb.b_hard_lock) != NFC_STATUS_OK) {
+        /* Failed to set tag read only */
+        conn_evt_data.tlv_detect.status = NFA_STATUS_FAILED;
+        nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
+      }
+    } else {
+      /* current op was stand-alone NFA_DetectTlv. Command complete - perform
+       * cleanup and notify app */
+      nfa_rw_command_complete();
+      nfa_dm_act_conn_cback_notify(NFA_TLV_DETECT_EVT, &conn_evt_data);
+    }
+  }
+
+  /* Handle failures */
+  if (p_rw_data->tlv.status != NFC_STATUS_OK) {
+    /* Command complete - perform cleanup, notify the app */
+    nfa_rw_command_complete();
+
+    conn_evt_data.tlv_detect.status = NFA_STATUS_FAILED;
+    if ((nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_LOCK_TLV) ||
+        (nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_MEM_TLV)) {
+      nfa_dm_act_conn_cback_notify(NFA_TLV_DETECT_EVT, &conn_evt_data);
+    } else if (nfa_rw_cb.cur_op == NFA_RW_OP_SET_TAG_RO) {
+      if (nfa_rw_config_tag_ro(nfa_rw_cb.b_hard_lock) != NFC_STATUS_OK) {
+        /* Failed to set tag read only */
+        conn_evt_data.tlv_detect.status = NFA_STATUS_FAILED;
+        nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
+      }
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_handle_sleep_wakeup_rsp
+**
+** Description      Handl sleep wakeup
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void nfa_rw_handle_sleep_wakeup_rsp(tNFC_STATUS status) {
+  tNFC_ACTIVATE_DEVT activate_params;
+  tRW_EVENT event;
+
+  if ((nfa_rw_cb.halt_event != RW_T2T_MAX_EVT) &&
+      (nfa_rw_cb.activated_tech_mode == NFC_DISCOVERY_TYPE_POLL_A) &&
+      (nfa_rw_cb.protocol == NFC_PROTOCOL_T2T) &&
+      (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)) {
+    NFA_TRACE_DEBUG0(
+        "nfa_rw_handle_sleep_wakeup_rsp; Attempt to wake up Type 2 tag from "
+        "HALT State is complete");
+    if (status == NFC_STATUS_OK) {
+      /* Type 2 Tag is wakeup from HALT state */
+      NFA_TRACE_DEBUG0(
+          "nfa_rw_handle_sleep_wakeup_rsp; Handle the NACK rsp received now");
+      /* Initialize control block */
+      activate_params.protocol = nfa_rw_cb.protocol;
+      activate_params.rf_tech_param.param.pa.sel_rsp = nfa_rw_cb.pa_sel_res;
+      activate_params.rf_tech_param.mode = nfa_rw_cb.activated_tech_mode;
+
+      /* Initialize RW module */
+      if ((RW_SetActivatedTagType(&activate_params, nfa_rw_cback)) !=
+          NFC_STATUS_OK) {
+        /* Log error (stay in NFA_RW_ST_ACTIVATED state until deactivation) */
+        NFA_TRACE_ERROR0("RW_SetActivatedTagType failed.");
+        if (nfa_rw_cb.halt_event == RW_T2T_READ_CPLT_EVT) {
+          if (nfa_rw_cb.rw_data.data.p_data)
+            GKI_freebuf(nfa_rw_cb.rw_data.data.p_data);
+          nfa_rw_cb.rw_data.data.p_data = NULL;
+        }
+        /* Do not try to detect NDEF again but just notify current operation
+         * failed */
+        nfa_rw_cb.halt_event = RW_T2T_MAX_EVT;
+      }
+    }
+
+    /* The current operation failed with NACK rsp from type 2 tag */
+    nfa_rw_cb.rw_data.status = NFC_STATUS_FAILED;
+    event = nfa_rw_cb.halt_event;
+
+    /* Got NACK rsp during presence check and legacy presence check performed */
+    if (nfa_rw_cb.cur_op == NFA_RW_OP_PRESENCE_CHECK)
+      nfa_rw_cb.rw_data.status = status;
+
+    /* If cannot Sleep wakeup tag, then NDEF Detect operation is complete */
+    if ((status != NFC_STATUS_OK) &&
+        (nfa_rw_cb.halt_event == RW_T2T_NDEF_DETECT_EVT))
+      nfa_rw_cb.halt_event = RW_T2T_MAX_EVT;
+
+    nfa_rw_handle_t2t_evt(event, &nfa_rw_cb.rw_data);
+    nfa_rw_cb.halt_event = RW_T2T_MAX_EVT;
+
+    /* If Type 2 tag sleep wakeup failed and If in normal mode (not-exclusive RF
+     * mode) then deactivate the link if sleep wakeup failed */
+    if ((nfa_rw_cb.flags & NFA_RW_FL_NOT_EXCL_RF_MODE) &&
+        (status != NFC_STATUS_OK)) {
+      NFA_TRACE_DEBUG0("Sleep wakeup failed. Deactivating...");
+      nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY);
+    }
+  } else {
+    NFA_TRACE_DEBUG0(
+        "nfa_rw_handle_sleep_wakeup_rsp; Legacy presence check performed");
+    /* Legacy presence check performed */
+    nfa_rw_handle_presence_check_rsp(status);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_handle_presence_check_rsp
+**
+** Description      Handler RW_T#t_PRESENCE_CHECK_EVT
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void nfa_rw_handle_presence_check_rsp(tNFC_STATUS status) {
+  NFC_HDR* p_pending_msg;
+
+  /* Stop the presence check timer - timer may have been started when presence
+   * check started */
+  nfa_rw_stop_presence_check_timer();
+  if (status == NFA_STATUS_OK) {
+    /* Clear the BUSY flag and restart the presence-check timer */
+    nfa_rw_command_complete();
+  } else {
+    /* If presence check failed just clear the BUSY flag */
+    nfa_rw_cb.flags &= ~NFA_RW_FL_API_BUSY;
+  }
+
+  /* Handle presence check due to auto-presence-check  */
+  if (nfa_rw_cb.flags & NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY) {
+    nfa_rw_cb.flags &= ~NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY;
+
+    /* If an API was called during auto-presence-check, then handle it now */
+    if (nfa_rw_cb.p_pending_msg) {
+      /* If NFA_RwPresenceCheck was called during auto-presence-check, notify
+       * app of result */
+      if (nfa_rw_cb.p_pending_msg->op_req.op == NFA_RW_OP_PRESENCE_CHECK) {
+        /* Notify app of presence check status */
+        nfa_dm_act_conn_cback_notify(NFA_PRESENCE_CHECK_EVT, (void*)&status);
+        GKI_freebuf(nfa_rw_cb.p_pending_msg);
+        nfa_rw_cb.p_pending_msg = NULL;
+      }
+      /* For all other APIs called during auto-presence check, perform the
+         command now (if tag is still present) */
+      else if (status == NFC_STATUS_OK) {
+        NFA_TRACE_DEBUG0(
+            "Performing deferred operation after presence check...");
+        p_pending_msg = (NFC_HDR*)nfa_rw_cb.p_pending_msg;
+        nfa_rw_cb.p_pending_msg = NULL;
+        nfa_rw_handle_event(p_pending_msg);
+        GKI_freebuf(p_pending_msg);
+      } else {
+        /* Tag no longer present. Free command for pending API command */
+        GKI_freebuf(nfa_rw_cb.p_pending_msg);
+        nfa_rw_cb.p_pending_msg = NULL;
+      }
+    }
+
+    /* Auto-presence check failed. Deactivate */
+    if (status != NFC_STATUS_OK) {
+      NFA_TRACE_DEBUG0("Auto presence check failed. Deactivating...");
+      nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY);
+    }
+  }
+  /* Handle presence check due to NFA_RwPresenceCheck API call */
+  else {
+    /* Notify app of presence check status */
+    nfa_dm_act_conn_cback_notify(NFA_PRESENCE_CHECK_EVT, (void*)&status);
+
+    /* If in normal mode (not-exclusive RF mode) then deactivate the link if
+     * presence check failed */
+    if ((nfa_rw_cb.flags & NFA_RW_FL_NOT_EXCL_RF_MODE) &&
+        (status != NFC_STATUS_OK)) {
+      NFA_TRACE_DEBUG0("Presence check failed. Deactivating...");
+      nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_handle_t1t_evt
+**
+** Description      Handler for Type-1 tag reader/writer events
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static void nfa_rw_handle_t1t_evt(tRW_EVENT event, tRW_DATA* p_rw_data) {
+  tNFA_CONN_EVT_DATA conn_evt_data;
+  tNFA_TAG_PARAMS tag_params;
+  uint8_t* p_rid_rsp;
+  tNFA_STATUS activation_status;
+
+  conn_evt_data.status = p_rw_data->data.status;
+  switch (event) {
+    case RW_T1T_RID_EVT:
+      if (p_rw_data->data.p_data != NULL) {
+        /* Assume the data is just the response byte sequence */
+        p_rid_rsp = (uint8_t*)(p_rw_data->data.p_data + 1) +
+                    p_rw_data->data.p_data->offset;
+        /* Fetch HR from RID response message */
+        STREAM_TO_ARRAY(tag_params.t1t.hr, p_rid_rsp, T1T_HR_LEN);
+        /* Fetch UID0-3 from RID response message */
+        STREAM_TO_ARRAY(tag_params.t1t.uid, p_rid_rsp, T1T_CMD_UID_LEN);
+        GKI_freebuf(p_rw_data->data.p_data);
+        p_rw_data->data.p_data = NULL;
+      }
+      /* Command complete - perform cleanup, notify the app */
+      nfa_rw_command_complete();
+
+      if (p_rw_data->status == NFC_STATUS_TIMEOUT) {
+        activation_status = NFA_STATUS_TIMEOUT;
+      } else {
+        activation_status = NFA_STATUS_OK;
+      }
+      nfa_dm_notify_activation_status(activation_status, &tag_params);
+      break;
+
+    case RW_T1T_RALL_CPLT_EVT:
+    case RW_T1T_READ_CPLT_EVT:
+    case RW_T1T_RSEG_CPLT_EVT:
+    case RW_T1T_READ8_CPLT_EVT:
+      nfa_rw_send_data_to_upper(p_rw_data);
+
+      /* Command complete - perform cleanup, notify the app */
+      nfa_rw_command_complete();
+      nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+      break;
+
+    case RW_T1T_WRITE_E_CPLT_EVT:
+    case RW_T1T_WRITE_NE_CPLT_EVT:
+    case RW_T1T_WRITE_E8_CPLT_EVT:
+    case RW_T1T_WRITE_NE8_CPLT_EVT:
+      nfa_rw_send_data_to_upper(p_rw_data);
+
+      /* Command complete - perform cleanup, notify the app */
+      nfa_rw_command_complete();
+      nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
+      break;
+
+    case RW_T1T_TLV_DETECT_EVT:
+      nfa_rw_handle_tlv_detect(event, p_rw_data);
+      break;
+
+    case RW_T1T_NDEF_DETECT_EVT:
+      nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE;
+
+      if ((p_rw_data->status != NFC_STATUS_OK) &&
+          (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) &&
+          (p_rw_data->ndef.flags & NFA_RW_NDEF_FL_FORMATABLE) &&
+          (!(p_rw_data->ndef.flags & NFA_RW_NDEF_FL_FORMATED)) &&
+          (p_rw_data->ndef.flags & NFA_RW_NDEF_FL_SUPPORTED)) {
+        /* Tag is in Initialized state, Format the tag first and then Write NDEF
+         */
+        if (RW_T1tFormatNDef() == NFC_STATUS_OK) break;
+      }
+
+      nfa_rw_handle_ndef_detect(event, p_rw_data);
+
+      break;
+
+    case RW_T1T_NDEF_READ_EVT:
+      nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE;
+      if (p_rw_data->status == NFC_STATUS_OK) {
+        /* Process the ndef record */
+        nfa_dm_ndef_handle_message(NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf,
+                                   nfa_rw_cb.ndef_cur_size);
+      } else {
+        /* Notify app of failure */
+        if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
+          /* If current operation is READ_NDEF, then notify ndef handlers of
+           * failure */
+          nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
+        }
+      }
+
+      /* Command complete - perform cleanup, notify the app */
+      nfa_rw_command_complete();
+      nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+
+      /* Free ndef buffer */
+      nfa_rw_free_ndef_rx_buf();
+      break;
+
+    case RW_T1T_NDEF_WRITE_EVT:
+      if (p_rw_data->data.status != NFA_STATUS_OK)
+        nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
+      nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE;
+
+      /* Command complete - perform cleanup, notify the app */
+      nfa_rw_command_complete();
+
+      /* Notify app */
+      conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK)
+                                 ? NFA_STATUS_OK
+                                 : NFA_STATUS_FAILED;
+      if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) {
+        /* Update local cursize of ndef message */
+        nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len;
+      }
+
+      /* Notify app of ndef write complete status */
+      nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
+      break;
+
+    case RW_T1T_SET_TAG_RO_EVT:
+      /* Command complete - perform cleanup, notify the app */
+      nfa_rw_command_complete();
+      nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
+      break;
+
+    case RW_T1T_RAW_FRAME_EVT:
+      nfa_rw_send_data_to_upper(p_rw_data);
+      /* Command complete - perform cleanup */
+      nfa_rw_command_complete();
+      break;
+
+    case RW_T1T_PRESENCE_CHECK_EVT: /* Presence check completed */
+      nfa_rw_handle_presence_check_rsp(p_rw_data->status);
+      break;
+
+    case RW_T1T_FORMAT_CPLT_EVT:
+
+      if (p_rw_data->data.status == NFA_STATUS_OK)
+        nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
+
+      if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) {
+        /* if format operation was done as part of ndef-write operation, now
+         * start NDEF Write */
+        if ((p_rw_data->data.status != NFA_STATUS_OK) ||
+            ((conn_evt_data.status = RW_T1tDetectNDef()) != NFC_STATUS_OK)) {
+          /* Command complete - perform cleanup, notify app */
+          nfa_rw_command_complete();
+          nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_FALSE;
+
+          /* if format operation failed or ndef detection did not start, then
+           * notify app of ndef-write operation failure */
+          conn_evt_data.status = NFA_STATUS_FAILED;
+          nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
+        }
+      } else {
+        /* Command complete - perform cleanup, notify the app */
+        nfa_rw_command_complete();
+        nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data);
+      }
+      break;
+
+    case RW_T1T_INTF_ERROR_EVT:
+      nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data);
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_handle_t2t_evt
+**
+** Description      Handler for Type-2 tag reader/writer events
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static void nfa_rw_handle_t2t_evt(tRW_EVENT event, tRW_DATA* p_rw_data) {
+  tNFA_CONN_EVT_DATA conn_evt_data;
+
+  conn_evt_data.status = p_rw_data->status;
+
+  if (p_rw_data->status == NFC_STATUS_REJECTED) {
+    NFA_TRACE_DEBUG0(
+        "nfa_rw_handle_t2t_evt(); Waking the tag first before handling the "
+        "response!");
+    /* Received NACK. Let DM wakeup the tag first (by putting tag to sleep and
+     * then waking it up) */
+    p_rw_data->status = nfa_dm_disc_sleep_wakeup();
+    if (p_rw_data->status == NFC_STATUS_OK) {
+      nfa_rw_cb.halt_event = event;
+      memcpy(&nfa_rw_cb.rw_data, p_rw_data, sizeof(tRW_DATA));
+      return;
+    }
+  }
+
+  switch (event) {
+    case RW_T2T_READ_CPLT_EVT: /* Read completed          */
+      nfa_rw_send_data_to_upper(p_rw_data);
+      /* Command complete - perform cleanup, notify the app */
+      nfa_rw_command_complete();
+      nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+      break;
+
+    case RW_T2T_WRITE_CPLT_EVT: /* Write completed         */
+      /* Command complete - perform cleanup, notify the app */
+      nfa_rw_command_complete();
+      nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
+      break;
+
+    case RW_T2T_SELECT_CPLT_EVT: /* Sector select completed */
+      /* Command complete - perform cleanup, notify the app */
+      nfa_rw_command_complete();
+      nfa_dm_act_conn_cback_notify(NFA_SELECT_CPLT_EVT, &conn_evt_data);
+      break;
+
+    case RW_T2T_NDEF_DETECT_EVT: /* NDEF detection complete */
+      if ((p_rw_data->status == NFC_STATUS_OK) ||
+          ((p_rw_data->status == NFC_STATUS_FAILED) &&
+           ((p_rw_data->ndef.flags == NFA_RW_NDEF_FL_UNKNOWN) ||
+            (nfa_rw_cb.halt_event == RW_T2T_MAX_EVT))) ||
+          (nfa_rw_cb.skip_dyn_locks == true)) {
+        /* NDEF Detection is complete */
+        nfa_rw_cb.skip_dyn_locks = false;
+        nfa_rw_handle_ndef_detect(event, p_rw_data);
+      } else {
+        /* Try to detect NDEF again, this time without reading dynamic lock
+         * bytes */
+        nfa_rw_cb.skip_dyn_locks = true;
+        nfa_rw_detect_ndef(NULL);
+      }
+      break;
+
+    case RW_T2T_TLV_DETECT_EVT: /* Lock control/Mem/Prop tlv detection complete
+                                   */
+      nfa_rw_handle_tlv_detect(event, p_rw_data);
+      break;
+
+    case RW_T2T_NDEF_READ_EVT: /* NDEF read completed     */
+      if (p_rw_data->status == NFC_STATUS_OK) {
+        /* Process the ndef record */
+        nfa_dm_ndef_handle_message(NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf,
+                                   nfa_rw_cb.ndef_cur_size);
+      } else {
+        /* Notify app of failure */
+        if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
+          /* If current operation is READ_NDEF, then notify ndef handlers of
+           * failure */
+          nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
+        }
+      }
+
+      /* Notify app of read status */
+      conn_evt_data.status = p_rw_data->status;
+      nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+      /* Free ndef buffer */
+      nfa_rw_free_ndef_rx_buf();
+
+      /* Command complete - perform cleanup */
+      nfa_rw_command_complete();
+      break;
+
+    case RW_T2T_NDEF_WRITE_EVT: /* NDEF write complete     */
+
+      /* Command complete - perform cleanup, notify the app */
+      nfa_rw_command_complete();
+
+      /* Notify app */
+      conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK)
+                                 ? NFA_STATUS_OK
+                                 : NFA_STATUS_FAILED;
+      if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) {
+        /* Update local cursize of ndef message */
+        nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len;
+      }
+
+      /* Notify app of ndef write complete status */
+      nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
+
+      break;
+
+    case RW_T2T_SET_TAG_RO_EVT:
+      /* Command complete - perform cleanup, notify the app */
+      nfa_rw_command_complete();
+      nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
+      break;
+
+    case RW_T2T_RAW_FRAME_EVT:
+      nfa_rw_send_data_to_upper(p_rw_data);
+      /* Command complete - perform cleanup */
+      if (p_rw_data->status != NFC_STATUS_CONTINUE) {
+        nfa_rw_command_complete();
+      }
+      break;
+
+    case RW_T2T_PRESENCE_CHECK_EVT: /* Presence check completed */
+      nfa_rw_handle_presence_check_rsp(p_rw_data->status);
+      break;
+
+    case RW_T2T_FORMAT_CPLT_EVT:
+      if (p_rw_data->data.status == NFA_STATUS_OK)
+        nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
+
+      /* Command complete - perform cleanup, notify the app */
+      nfa_rw_command_complete();
+      nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data);
+      break;
+
+    case RW_T2T_INTF_ERROR_EVT:
+      nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data);
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_handle_t3t_evt
+**
+** Description      Handler for Type-3 tag reader/writer events
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static void nfa_rw_handle_t3t_evt(tRW_EVENT event, tRW_DATA* p_rw_data) {
+  tNFA_CONN_EVT_DATA conn_evt_data;
+  tNFA_TAG_PARAMS tag_params;
+
+  switch (event) {
+    case RW_T3T_NDEF_DETECT_EVT: /* NDEF detection complete */
+      nfa_rw_handle_ndef_detect(event, p_rw_data);
+      break;
+
+    case RW_T3T_UPDATE_CPLT_EVT: /* Write completed */
+      /* Command complete - perform cleanup, notify the app */
+      nfa_rw_command_complete();
+
+      /* Notify app */
+      conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK)
+                                 ? NFA_STATUS_OK
+                                 : NFA_STATUS_FAILED;
+      if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) {
+        /* Update local cursize of ndef message */
+        nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len;
+      }
+
+      /* Notify app of ndef write complete status */
+      nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
+
+      break;
+
+    case RW_T3T_CHECK_CPLT_EVT: /* Read completed */
+      if (p_rw_data->status == NFC_STATUS_OK) {
+        /* Process the ndef record */
+        nfa_dm_ndef_handle_message(NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf,
+                                   nfa_rw_cb.ndef_cur_size);
+      } else {
+        /* Notify app of failure */
+        if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
+          /* If current operation is READ_NDEF, then notify ndef handlers of
+           * failure */
+          nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
+        }
+      }
+
+      /* Free ndef buffer */
+      nfa_rw_free_ndef_rx_buf();
+
+      /* Command complete - perform cleanup, notify the app */
+      nfa_rw_command_complete();
+      conn_evt_data.status = p_rw_data->status;
+      nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+      break;
+
+    case RW_T3T_CHECK_EVT: /* Segment of data received from type 3 tag */
+      if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
+        nfa_rw_store_ndef_rx_buf(p_rw_data);
+      } else {
+        nfa_rw_send_data_to_upper(p_rw_data);
+      }
+      break;
+
+    case RW_T3T_RAW_FRAME_EVT: /* SendRawFrame response */
+      nfa_rw_send_data_to_upper(p_rw_data);
+
+      if (p_rw_data->status != NFC_STATUS_CONTINUE) {
+        /* Command complete - perform cleanup */
+        nfa_rw_command_complete();
+      }
+      break;
+
+    case RW_T3T_PRESENCE_CHECK_EVT: /* Presence check completed */
+      nfa_rw_handle_presence_check_rsp(p_rw_data->status);
+      break;
+
+    case RW_T3T_GET_SYSTEM_CODES_EVT: /* Presence check completed */
+      /* Command complete - perform cleanup */
+      nfa_rw_command_complete();
+
+      /* System codes retrieved - notify app of ACTIVATION */
+      if (p_rw_data->status == NFC_STATUS_OK) {
+        tag_params.t3t.num_system_codes = p_rw_data->t3t_sc.num_system_codes;
+        tag_params.t3t.p_system_codes = p_rw_data->t3t_sc.p_system_codes;
+      } else {
+        tag_params.t3t.num_system_codes = 0;
+        tag_params.t3t.p_system_codes = NULL;
+      }
+
+#if(NXP_EXTNS == TRUE)
+      nfa_dm_notify_activation_status(p_rw_data->status, &tag_params);
+#else
+      nfa_dm_notify_activation_status(NFA_STATUS_OK, &tag_params);
+#endif
+      break;
+
+    case RW_T3T_FORMAT_CPLT_EVT: /* Format completed */
+      /* Command complete - perform cleanup, notify the app */
+      nfa_rw_command_complete();
+
+      /* Notify app */
+      conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK)
+                                 ? NFA_STATUS_OK
+                                 : NFA_STATUS_FAILED;
+
+      /* Notify app of ndef write complete status */
+      nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data);
+      break;
+
+    case RW_T3T_INTF_ERROR_EVT:
+      conn_evt_data.status = p_rw_data->status;
+      nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data);
+      break;
+
+    case RW_T3T_SET_READ_ONLY_CPLT_EVT:
+      /* Command complete - perform cleanup, notify the app */
+      nfa_rw_command_complete();
+
+      conn_evt_data.status = p_rw_data->status;
+      nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
+      break;
+
+    default:
+      NFA_TRACE_DEBUG1("nfa_rw_handle_t3t_evt(); Unhandled RW event 0x%X",
+                       event);
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_handle_t4t_evt
+**
+** Description      Handler for Type-4 tag reader/writer events
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static void nfa_rw_handle_t4t_evt(tRW_EVENT event, tRW_DATA* p_rw_data) {
+  tNFA_CONN_EVT_DATA conn_evt_data;
+
+  switch (event) {
+    case RW_T4T_NDEF_DETECT_EVT: /* Result of NDEF detection procedure */
+      nfa_rw_handle_ndef_detect(event, p_rw_data);
+      break;
+
+    case RW_T4T_NDEF_FORMAT_CPLT_EVT:
+      /* Command complete - perform cleanup, notify the app */
+      nfa_rw_command_complete();
+      nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
+      nfa_rw_cb.ndef_cur_size = p_rw_data->ndef.cur_size;
+      nfa_rw_cb.ndef_max_size = p_rw_data->ndef.max_size;
+      conn_evt_data.status = (p_rw_data->status == NFC_STATUS_OK)
+                                 ? NFA_STATUS_OK
+                                 : NFA_STATUS_FAILED;
+
+      nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data);
+      break;
+#if (NXP_EXTNS == TRUE)
+    case RW_T3BT_RAW_READ_CPLT_EVT:
+      nfa_rw_command_complete();
+      nfa_dm_act_conn_cback_notify(NFA_ACTIVATED_EVT, &conn_evt_data);
+      break;
+#endif
+
+    case RW_T4T_NDEF_READ_EVT: /* Segment of data received from type 4 tag */
+      if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
+        nfa_rw_store_ndef_rx_buf(p_rw_data);
+      } else {
+        nfa_rw_send_data_to_upper(p_rw_data);
+      }
+      break;
+
+    case RW_T4T_NDEF_READ_CPLT_EVT: /* Read operation completed           */
+      if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
+        nfa_rw_store_ndef_rx_buf(p_rw_data);
+
+        /* Process the ndef record */
+        nfa_dm_ndef_handle_message(NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf,
+                                   nfa_rw_cb.ndef_cur_size);
+
+        /* Free ndef buffer */
+        nfa_rw_free_ndef_rx_buf();
+      } else {
+        nfa_rw_send_data_to_upper(p_rw_data);
+      }
+
+      /* Command complete - perform cleanup, notify the app */
+      nfa_rw_command_complete();
+      nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
+      conn_evt_data.status = NFC_STATUS_OK;
+      nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+      break;
+
+    case RW_T4T_NDEF_READ_FAIL_EVT: /* Read operation failed              */
+      if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
+        /* If current operation is READ_NDEF, then notify ndef handlers of
+         * failure */
+        nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
+
+        /* Free ndef buffer */
+        nfa_rw_free_ndef_rx_buf();
+      }
+
+      /* Command complete - perform cleanup, notify the app */
+      nfa_rw_command_complete();
+      nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
+      conn_evt_data.status = NFA_STATUS_FAILED;
+      nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+      break;
+
+    case RW_T4T_NDEF_UPDATE_CPLT_EVT: /* Update operation completed         */
+    case RW_T4T_NDEF_UPDATE_FAIL_EVT: /* Update operation failed            */
+
+      if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) {
+        /* Update local cursize of ndef message */
+        nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len;
+      }
+
+      /* Notify app */
+      if (event == RW_T4T_NDEF_UPDATE_CPLT_EVT)
+        conn_evt_data.status = NFA_STATUS_OK;
+      else
+        conn_evt_data.status = NFA_STATUS_FAILED;
+
+      /* Command complete - perform cleanup, notify the app */
+      nfa_rw_command_complete();
+      nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
+      nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
+      break;
+
+    case RW_T4T_RAW_FRAME_EVT: /* Raw Frame data event         */
+      nfa_rw_send_data_to_upper(p_rw_data);
+
+      if (p_rw_data->status != NFC_STATUS_CONTINUE) {
+        /* Command complete - perform cleanup */
+        nfa_rw_command_complete();
+        nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
+      }
+      break;
+
+#if (NXP_EXTNS == TRUE)
+    case RW_T4T_RAW_FRAME_RF_WTX_EVT:
+      /* Stop the presence check timer */
+      nfa_rw_stop_presence_check_timer();
+      nfa_rw_check_start_presence_check_timer(NFA_RW_PRESENCE_CHECK_INTERVAL);
+      break;
+#endif
+
+    case RW_T4T_SET_TO_RO_EVT: /* Tag is set as read only          */
+      conn_evt_data.status = p_rw_data->status;
+      nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
+
+      nfa_rw_command_complete();
+      nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
+      break;
+
+    case RW_T4T_INTF_ERROR_EVT: /* RF Interface error event         */
+      conn_evt_data.status = p_rw_data->status;
+      nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data);
+
+      nfa_rw_command_complete();
+      nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
+      break;
+
+    case RW_T4T_PRESENCE_CHECK_EVT: /* Presence check completed */
+      nfa_rw_handle_presence_check_rsp(p_rw_data->status);
+      break;
+
+    default:
+      NFA_TRACE_DEBUG1("nfa_rw_handle_t4t_evt(); Unhandled RW event 0x%X",
+                       event);
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_handle_i93_evt
+**
+** Description      Handler for ISO 15693 tag reader/writer events
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static void nfa_rw_handle_i93_evt(tRW_EVENT event, tRW_DATA* p_rw_data) {
+  tNFA_CONN_EVT_DATA conn_evt_data;
+  tNFA_TAG_PARAMS i93_params;
+
+  switch (event) {
+    case RW_I93_NDEF_DETECT_EVT: /* Result of NDEF detection procedure */
+      nfa_rw_handle_ndef_detect(event, p_rw_data);
+      break;
+
+    case RW_I93_NDEF_READ_EVT: /* Segment of data received from type 4 tag */
+      if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
+        nfa_rw_store_ndef_rx_buf(p_rw_data);
+      } else {
+        nfa_rw_send_data_to_upper(p_rw_data);
+      }
+      break;
+
+    case RW_I93_NDEF_READ_CPLT_EVT: /* Read operation completed           */
+      if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
+        nfa_rw_store_ndef_rx_buf(p_rw_data);
+
+        /* Process the ndef record */
+        nfa_dm_ndef_handle_message(NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf,
+                                   nfa_rw_cb.ndef_cur_size);
+
+        /* Free ndef buffer */
+        nfa_rw_free_ndef_rx_buf();
+      } else {
+        nfa_rw_send_data_to_upper(p_rw_data);
+      }
+
+      /* Command complete - perform cleanup, notify app */
+      nfa_rw_command_complete();
+      nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
+      conn_evt_data.status = NFC_STATUS_OK;
+      nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+      break;
+
+    case RW_I93_NDEF_READ_FAIL_EVT: /* Read operation failed              */
+      if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
+        /* If current operation is READ_NDEF, then notify ndef handlers of
+         * failure */
+        nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
+
+        /* Free ndef buffer */
+        nfa_rw_free_ndef_rx_buf();
+      }
+
+      /* Command complete - perform cleanup, notify app */
+      nfa_rw_command_complete();
+      nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
+      conn_evt_data.status = NFA_STATUS_FAILED;
+      nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+      break;
+
+    case RW_I93_NDEF_UPDATE_CPLT_EVT: /* Update operation completed         */
+    case RW_I93_NDEF_UPDATE_FAIL_EVT: /* Update operation failed            */
+
+      if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) {
+        /* Update local cursize of ndef message */
+        nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len;
+      }
+
+      /* Command complete - perform cleanup, notify app */
+      nfa_rw_command_complete();
+      nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
+
+      if (event == RW_I93_NDEF_UPDATE_CPLT_EVT)
+        conn_evt_data.status = NFA_STATUS_OK;
+      else
+        conn_evt_data.status = NFA_STATUS_FAILED;
+
+      /* Notify app of ndef write complete status */
+      nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
+      break;
+
+    case RW_I93_RAW_FRAME_EVT: /* Raw Frame data event         */
+      nfa_rw_send_data_to_upper(p_rw_data);
+      if (p_rw_data->status != NFC_STATUS_CONTINUE) {
+        /* Command complete - perform cleanup */
+        nfa_rw_command_complete();
+      }
+      break;
+
+    case RW_I93_INTF_ERROR_EVT: /* RF Interface error event         */
+      /* Command complete - perform cleanup, notify app */
+      nfa_rw_command_complete();
+
+      if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING) {
+        nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
+
+        memset(&i93_params, 0x00, sizeof(tNFA_TAG_PARAMS));
+        memcpy(i93_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN);
+
+        nfa_dm_notify_activation_status(NFA_STATUS_OK, &i93_params);
+      } else {
+        conn_evt_data.status = p_rw_data->status;
+        nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data);
+      }
+
+      nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
+      break;
+
+    case RW_I93_PRESENCE_CHECK_EVT: /* Presence check completed */
+      nfa_rw_handle_presence_check_rsp(p_rw_data->status);
+      break;
+
+    case RW_I93_FORMAT_CPLT_EVT: /* Format procedure complete          */
+      if (p_rw_data->data.status == NFA_STATUS_OK)
+        nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
+
+      /* Command complete - perform cleanup, notify app */
+      nfa_rw_command_complete();
+      nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
+      conn_evt_data.status = p_rw_data->status;
+      nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data);
+      break;
+
+    case RW_I93_SET_TAG_RO_EVT: /* Set read-only procedure complete   */
+      nfa_rw_cb.flags |= NFA_RW_FL_TAG_IS_READONLY;
+
+      /* Command complete - perform cleanup, notify app */
+      nfa_rw_command_complete();
+      nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
+      conn_evt_data.status = p_rw_data->status;
+      nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
+      break;
+
+    case RW_I93_INVENTORY_EVT: /* Response of Inventory              */
+
+      /* Command complete - perform cleanup, notify app */
+      nfa_rw_command_complete();
+
+      conn_evt_data.i93_cmd_cplt.status = p_rw_data->i93_inventory.status;
+      conn_evt_data.i93_cmd_cplt.sent_command = I93_CMD_INVENTORY;
+
+      conn_evt_data.i93_cmd_cplt.params.inventory.dsfid =
+          p_rw_data->i93_inventory.dsfid;
+      memcpy(conn_evt_data.i93_cmd_cplt.params.inventory.uid,
+             p_rw_data->i93_inventory.uid, I93_UID_BYTE_LEN);
+
+      nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data);
+
+      nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
+      break;
+
+    case RW_I93_DATA_EVT: /* Response of Read, Get Multi Security */
+
+      /* Command complete - perform cleanup, notify app */
+      nfa_rw_command_complete();
+
+      conn_evt_data.data.p_data = (uint8_t*)(p_rw_data->i93_data.p_data + 1) +
+                                  p_rw_data->i93_data.p_data->offset;
+
+      if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING) {
+        nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
+
+        i93_params.i93.info_flags =
+            (I93_INFO_FLAG_DSFID | I93_INFO_FLAG_MEM_SIZE | I93_INFO_FLAG_AFI);
+        i93_params.i93.afi =
+            *(conn_evt_data.data.p_data +
+              nfa_rw_cb.i93_afi_location % nfa_rw_cb.i93_block_size);
+        i93_params.i93.dsfid = nfa_rw_cb.i93_dsfid;
+        i93_params.i93.block_size = nfa_rw_cb.i93_block_size;
+        i93_params.i93.num_block = nfa_rw_cb.i93_num_block;
+        memcpy(i93_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN);
+
+        nfa_dm_notify_activation_status(NFA_STATUS_OK, &i93_params);
+      } else {
+        conn_evt_data.data.len = p_rw_data->i93_data.p_data->len;
+
+        nfa_dm_act_conn_cback_notify(NFA_DATA_EVT, &conn_evt_data);
+      }
+
+      GKI_freebuf(p_rw_data->i93_data.p_data);
+      p_rw_data->i93_data.p_data = NULL;
+
+      nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
+      break;
+
+    case RW_I93_SYS_INFO_EVT: /* Response of System Information     */
+
+      /* Command complete - perform cleanup, notify app */
+      nfa_rw_command_complete();
+
+      if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING) {
+        nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
+
+        nfa_rw_cb.i93_block_size = p_rw_data->i93_sys_info.block_size;
+        nfa_rw_cb.i93_num_block = p_rw_data->i93_sys_info.num_block;
+
+        i93_params.i93.info_flags = p_rw_data->i93_sys_info.info_flags;
+        i93_params.i93.dsfid = p_rw_data->i93_sys_info.dsfid;
+        i93_params.i93.afi = p_rw_data->i93_sys_info.afi;
+        i93_params.i93.num_block = p_rw_data->i93_sys_info.num_block;
+        i93_params.i93.block_size = p_rw_data->i93_sys_info.block_size;
+        i93_params.i93.IC_reference = p_rw_data->i93_sys_info.IC_reference;
+        memcpy(i93_params.i93.uid, p_rw_data->i93_sys_info.uid,
+               I93_UID_BYTE_LEN);
+
+        nfa_dm_notify_activation_status(NFA_STATUS_OK, &i93_params);
+      } else {
+        conn_evt_data.i93_cmd_cplt.status = p_rw_data->i93_sys_info.status;
+        conn_evt_data.i93_cmd_cplt.sent_command = I93_CMD_GET_SYS_INFO;
+
+        conn_evt_data.i93_cmd_cplt.params.sys_info.info_flags =
+            p_rw_data->i93_sys_info.info_flags;
+        memcpy(conn_evt_data.i93_cmd_cplt.params.sys_info.uid,
+               p_rw_data->i93_sys_info.uid, I93_UID_BYTE_LEN);
+        conn_evt_data.i93_cmd_cplt.params.sys_info.dsfid =
+            p_rw_data->i93_sys_info.dsfid;
+        conn_evt_data.i93_cmd_cplt.params.sys_info.afi =
+            p_rw_data->i93_sys_info.afi;
+        conn_evt_data.i93_cmd_cplt.params.sys_info.num_block =
+            p_rw_data->i93_sys_info.num_block;
+        conn_evt_data.i93_cmd_cplt.params.sys_info.block_size =
+            p_rw_data->i93_sys_info.block_size;
+        conn_evt_data.i93_cmd_cplt.params.sys_info.IC_reference =
+            p_rw_data->i93_sys_info.IC_reference;
+
+        /* store tag memory information for writing blocks */
+        nfa_rw_cb.i93_block_size = p_rw_data->i93_sys_info.block_size;
+        nfa_rw_cb.i93_num_block = p_rw_data->i93_sys_info.num_block;
+
+        nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data);
+      }
+
+      nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
+      break;
+
+    case RW_I93_CMD_CMPL_EVT: /* Command complete                   */
+      /* Command complete - perform cleanup, notify app */
+      nfa_rw_command_complete();
+
+      if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING) {
+        /* Reader got error code from tag */
+
+        nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
+
+        memset(&i93_params, 0x00, sizeof(i93_params));
+        memcpy(i93_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN);
+
+        nfa_dm_notify_activation_status(NFA_STATUS_OK, &i93_params);
+      } else {
+        conn_evt_data.i93_cmd_cplt.status = p_rw_data->i93_cmd_cmpl.status;
+        conn_evt_data.i93_cmd_cplt.sent_command =
+            p_rw_data->i93_cmd_cmpl.command;
+
+        if (conn_evt_data.i93_cmd_cplt.status != NFC_STATUS_OK)
+          conn_evt_data.i93_cmd_cplt.params.error_code =
+              p_rw_data->i93_cmd_cmpl.error_code;
+
+        nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data);
+      }
+
+      nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
+      break;
+
+    default:
+      NFA_TRACE_DEBUG1("nfa_rw_handle_i93_evt(); Unhandled RW event 0x%X",
+                       event);
+      break;
+  }
+}
+#if (NXP_EXTNS == TRUE)
+static void nfa_rw_handle_t3bt_evt(tRW_EVENT event, tRW_DATA* p_rw_data) {
+  (void)p_rw_data;
+
+  // tNFC_ACTIVATE_DEVT *activate_ntf =
+  // (tNFC_ACTIVATE_DEVT*)nfa_dm_cb.p_activate_ntf;
+  NFA_TRACE_DEBUG0("nfa_rw_handle_t3bt_evt:");
+
+  switch (event) {
+    case RW_T3BT_RAW_READ_CPLT_EVT:
+      nfa_rw_command_complete();
+      break;
+    default:
+      NFA_TRACE_DEBUG0("nfa_rw_handle_t3bt_evt: default event");
+      break;
+  }
+  nfa_dm_notify_activation_status(NFA_STATUS_OK, NULL);
+}
+#endif
+/*******************************************************************************
+**
+** Function         nfa_rw_cback
+**
+** Description      Callback for reader/writer event notification
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static void nfa_rw_cback(tRW_EVENT event, tRW_DATA* p_rw_data) {
+  NFA_TRACE_DEBUG1("nfa_rw_cback: event=0x%02x", event);
+  if (NULL == p_rw_data) {
+    NFA_TRACE_ERROR0("nfa_rw_cback: p_rw_data is NULL");
+    return;
+  }
+  /* Call appropriate event handler for tag type */
+  if (event < RW_T1T_MAX_EVT) {
+    /* Handle Type-1 tag events */
+    nfa_rw_handle_t1t_evt(event, p_rw_data);
+  } else if (event < RW_T2T_MAX_EVT) {
+    /* Handle Type-2 tag events */
+    nfa_rw_handle_t2t_evt(event, p_rw_data);
+  } else if (event < RW_T3T_MAX_EVT) {
+    /* Handle Type-3 tag events */
+    nfa_rw_handle_t3t_evt(event, p_rw_data);
+  } else if (event < RW_T4T_MAX_EVT) {
+    /* Handle Type-4 tag events */
+    nfa_rw_handle_t4t_evt(event, p_rw_data);
+  } else if (event < RW_I93_MAX_EVT) {
+    /* Handle ISO 15693 tag events */
+    nfa_rw_handle_i93_evt(event, p_rw_data);
+  }
+#if (NXP_EXTNS == TRUE)
+  else if (event < RW_T3BT_MAX_EVT) {
+    /* Handle ISO 14443-3B tag events */
+    nfa_rw_handle_t3bt_evt(event, p_rw_data);
+  }
+#endif
+  else {
+    NFA_TRACE_ERROR1("nfa_rw_cback: unhandled event=0x%02x", event);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_start_ndef_detection
+**
+** Description      Start NDEF detection on activated tag
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static tNFC_STATUS nfa_rw_start_ndef_detection(void) {
+  tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+
+  if (NFC_PROTOCOL_T1T == protocol) {
+    /* Type1Tag    - NFC-A */
+    status = RW_T1tDetectNDef();
+  } else if (NFC_PROTOCOL_T2T == protocol) {
+    /* Type2Tag    - NFC-A */
+    if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) {
+      status = RW_T2tDetectNDef(nfa_rw_cb.skip_dyn_locks);
+    }
+  } else if (NFC_PROTOCOL_T3T == protocol) {
+    /* Type3Tag    - NFC-F */
+    status = RW_T3tDetectNDef();
+  } else if (NFC_PROTOCOL_ISO_DEP ==
+             protocol) { /* ISODEP/4A,4B- NFC-A or NFC-B */
+    status = RW_T4tDetectNDef();
+  } else if (NFC_PROTOCOL_15693 == protocol) { /* ISO 15693 */
+    status = RW_I93DetectNDef();
+  }
+
+  return (status);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_start_ndef_read
+**
+** Description      Start NDEF read on activated tag
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static tNFC_STATUS nfa_rw_start_ndef_read(void) {
+  tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  tNFA_CONN_EVT_DATA conn_evt_data;
+
+  /* Handle zero length NDEF message */
+  if (nfa_rw_cb.ndef_cur_size == 0) {
+    NFA_TRACE_DEBUG0("NDEF message is zero-length");
+
+    /* Send zero-lengh NDEF message to ndef callback */
+    nfa_dm_ndef_handle_message(NFA_STATUS_OK, NULL, 0);
+
+    /* Command complete - perform cleanup, notify app */
+    nfa_rw_command_complete();
+    conn_evt_data.status = NFA_STATUS_OK;
+    nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+    return NFC_STATUS_OK;
+  }
+
+  /* Allocate buffer for incoming NDEF message (free previous NDEF rx buffer, if
+   * needed) */
+  nfa_rw_free_ndef_rx_buf();
+  nfa_rw_cb.p_ndef_buf = (uint8_t*)nfa_mem_co_alloc(nfa_rw_cb.ndef_cur_size);
+  if (nfa_rw_cb.p_ndef_buf == NULL) {
+    NFA_TRACE_ERROR1("Unable to allocate a buffer for reading NDEF (size=%i)",
+                     nfa_rw_cb.ndef_cur_size);
+
+    /* Command complete - perform cleanup, notify app */
+    nfa_rw_command_complete();
+    conn_evt_data.status = NFA_STATUS_FAILED;
+    nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+    return NFC_STATUS_FAILED;
+  }
+  nfa_rw_cb.ndef_rd_offset = 0;
+
+  if (NFC_PROTOCOL_T1T == protocol) { /* Type1Tag    - NFC-A */
+    status =
+        RW_T1tReadNDef(nfa_rw_cb.p_ndef_buf, (uint16_t)nfa_rw_cb.ndef_cur_size);
+  } else if (NFC_PROTOCOL_T2T == protocol) { /* Type2Tag    - NFC-A */
+    if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) {
+      status = RW_T2tReadNDef(nfa_rw_cb.p_ndef_buf,
+                              (uint16_t)nfa_rw_cb.ndef_cur_size);
+    }
+  } else if (NFC_PROTOCOL_T3T == protocol) { /* Type3Tag    - NFC-F */
+    status = RW_T3tCheckNDef();
+  } else if (NFC_PROTOCOL_ISO_DEP ==
+             protocol) { /* ISODEP/4A,4B- NFC-A or NFC-B */
+    status = RW_T4tReadNDef();
+  } else if (NFC_PROTOCOL_15693 == protocol) { /* ISO 15693 */
+    status = RW_I93ReadNDef();
+  }
+  return (status);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_detect_ndef
+**
+** Description      Handler for NFA_RW_API_DETECT_NDEF_EVT
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static bool nfa_rw_detect_ndef(tNFA_RW_MSG* p_data) {
+  tNFA_CONN_EVT_DATA conn_evt_data;
+  (void)p_data;
+  NFA_TRACE_DEBUG0("nfa_rw_detect_ndef");
+
+  conn_evt_data.ndef_detect.status = nfa_rw_start_ndef_detection();
+  if (conn_evt_data.ndef_detect.status != NFC_STATUS_OK) {
+    /* Command complete - perform cleanup, notify app */
+    nfa_rw_command_complete();
+    conn_evt_data.ndef_detect.cur_size = 0;
+    conn_evt_data.ndef_detect.max_size = 0;
+    conn_evt_data.ndef_detect.flags = RW_NDEF_FL_UNKNOWN;
+    nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data);
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_start_ndef_write
+**
+** Description      Start NDEF write on activated tag
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static tNFC_STATUS nfa_rw_start_ndef_write(void) {
+  tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+
+  if (nfa_rw_cb.flags & NFA_RW_FL_TAG_IS_READONLY) {
+    /* error: ndef tag is read-only */
+    status = NFC_STATUS_FAILED;
+    NFA_TRACE_ERROR0("Unable to write NDEF. Tag is read-only")
+  } else if (nfa_rw_cb.ndef_max_size < nfa_rw_cb.ndef_wr_len) {
+    /* error: ndef tag size is too small */
+    status = NFC_STATUS_BUFFER_FULL;
+    NFA_TRACE_ERROR2(
+        "Unable to write NDEF. Tag maxsize=%i, request write size=%i",
+        nfa_rw_cb.ndef_max_size, nfa_rw_cb.ndef_wr_len)
+  } else {
+    if (NFC_PROTOCOL_T1T == protocol) { /* Type1Tag    - NFC-A */
+      status = RW_T1tWriteNDef((uint16_t)nfa_rw_cb.ndef_wr_len,
+                               nfa_rw_cb.p_ndef_wr_buf);
+    } else if (NFC_PROTOCOL_T2T == protocol) { /* Type2Tag    - NFC-A */
+      if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) {
+        status = RW_T2tWriteNDef((uint16_t)nfa_rw_cb.ndef_wr_len,
+                                 nfa_rw_cb.p_ndef_wr_buf);
+      }
+    } else if (NFC_PROTOCOL_T3T == protocol) { /* Type3Tag    - NFC-F */
+      status = RW_T3tUpdateNDef(nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf);
+    } else if (NFC_PROTOCOL_ISO_DEP ==
+               protocol) { /* ISODEP/4A,4B- NFC-A or NFC-B */
+      status = RW_T4tUpdateNDef((uint16_t)nfa_rw_cb.ndef_wr_len,
+                                nfa_rw_cb.p_ndef_wr_buf);
+    } else if (NFC_PROTOCOL_15693 == protocol) { /* ISO 15693 */
+      status = RW_I93UpdateNDef((uint16_t)nfa_rw_cb.ndef_wr_len,
+                                nfa_rw_cb.p_ndef_wr_buf);
+    }
+  }
+
+  return (status);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_read_ndef
+**
+** Description      Handler for NFA_RW_API_READ_NDEF_EVT
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static bool nfa_rw_read_ndef(tNFA_RW_MSG* p_data) {
+  tNFA_STATUS status = NFA_STATUS_OK;
+  tNFA_CONN_EVT_DATA conn_evt_data;
+  (void)p_data;
+
+  NFA_TRACE_DEBUG0("nfa_rw_read_ndef");
+
+  /* Check if ndef detection has been performed yet */
+  if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_UNKNOWN) {
+    /* Perform ndef detection first */
+    status = nfa_rw_start_ndef_detection();
+  } else if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_FALSE) {
+    /* Tag is not NDEF */
+    status = NFA_STATUS_FAILED;
+  } else {
+    /* Perform the NDEF read operation */
+    status = nfa_rw_start_ndef_read();
+  }
+
+  /* Handle failure */
+  if (status != NFA_STATUS_OK) {
+    /* Command complete - perform cleanup, notify app */
+    nfa_rw_command_complete();
+    conn_evt_data.status = status;
+    nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_write_ndef
+**
+** Description      Handler for NFA_RW_API_WRITE_NDEF_EVT
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static bool nfa_rw_write_ndef(tNFA_RW_MSG* p_data) {
+  tNDEF_STATUS ndef_status;
+  tNFA_STATUS write_status = NFA_STATUS_OK;
+  tNFA_CONN_EVT_DATA conn_evt_data;
+  NFA_TRACE_DEBUG0("nfa_rw_write_ndef");
+
+  /* Validate NDEF message */
+  ndef_status = NDEF_MsgValidate(p_data->op_req.params.write_ndef.p_data,
+                                 p_data->op_req.params.write_ndef.len, false);
+  if (ndef_status != NDEF_OK) {
+    NFA_TRACE_ERROR1("Invalid NDEF message. NDEF_MsgValidate returned %i",
+                     ndef_status);
+
+    /* Command complete - perform cleanup, notify app */
+    nfa_rw_command_complete();
+    conn_evt_data.status = NFA_STATUS_FAILED;
+    nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
+    return true;
+  }
+
+  /* Store pointer to source NDEF */
+  nfa_rw_cb.p_ndef_wr_buf = p_data->op_req.params.write_ndef.p_data;
+  nfa_rw_cb.ndef_wr_len = p_data->op_req.params.write_ndef.len;
+
+  /* Check if ndef detection has been performed yet */
+  if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_UNKNOWN) {
+    /* Perform ndef detection first */
+    write_status = nfa_rw_start_ndef_detection();
+  } else if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_FALSE) {
+    if (nfa_rw_cb.protocol == NFC_PROTOCOL_T1T) {
+      /* For Type 1 tag, NDEF can be written on Initialized tag
+      *  Perform ndef detection first to check if tag is in Initialized state to
+      * Write NDEF */
+      write_status = nfa_rw_start_ndef_detection();
+    } else {
+      /* Tag is not NDEF */
+      write_status = NFA_STATUS_FAILED;
+    }
+  } else {
+    /* Perform the NDEF read operation */
+    write_status = nfa_rw_start_ndef_write();
+  }
+
+  /* Handle failure */
+  if (write_status != NFA_STATUS_OK) {
+    /* Command complete - perform cleanup, notify app */
+    nfa_rw_command_complete();
+    conn_evt_data.status = write_status;
+    nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_presence_check
+**
+** Description      Handler for NFA_RW_API_PRESENCE_CHECK
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void nfa_rw_presence_check(tNFA_RW_MSG* p_data) {
+  tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
+  uint8_t sel_res = nfa_rw_cb.pa_sel_res;
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  bool unsupported = false;
+  uint8_t option = NFA_RW_OPTION_INVALID;
+  tNFA_RW_PRES_CHK_OPTION op_param = NFA_RW_PRES_CHK_DEFAULT;
+#if (NXP_EXTNS == TRUE)
+  uint16_t iso_15693_max_presence_check_timeout =
+      NFA_DM_ISO_15693_MAX_PRESENCE_CHECK_TIMEOUT + RW_I93_MAX_RSP_TIMEOUT;
+#endif
+  if (NFC_PROTOCOL_T1T == protocol) { /* Type1Tag    - NFC-A */
+    status = RW_T1tPresenceCheck();
+  } else if (NFC_PROTOCOL_T2T == protocol) {
+    /* If T2T NFC-Forum, then let RW handle presence check */
+    if (sel_res == NFC_SEL_RES_NFC_FORUM_T2T) {
+      /* Type 2 tag have not sent NACK after activation */
+      status = RW_T2tPresenceCheck();
+    } else {
+      /* Will fall back to deactivate/reactivate */
+      unsupported = true;
+    }
+  } else if (NFC_PROTOCOL_T3T == protocol) { /* Type3Tag    - NFC-F */
+    status = RW_T3tPresenceCheck();
+  } else if (NFC_PROTOCOL_ISO_DEP ==
+             protocol) { /* ISODEP/4A,4B- NFC-A or NFC-B */
+    if (p_data) {
+      op_param = p_data->op_req.params.option;
+    }
+
+    switch (op_param) {
+      case NFA_RW_PRES_CHK_I_BLOCK:
+        option = RW_T4T_CHK_EMPTY_I_BLOCK;
+        break;
+
+      case NFA_RW_PRES_CHK_RESET:
+        /* option is initialized to NFA_RW_OPTION_INVALID, which will Deactivate
+         * to Sleep; Re-activate */
+        break;
+
+      case NFA_RW_PRES_CHK_RB_CH0:
+        option = RW_T4T_CHK_READ_BINARY_CH0;
+        break;
+
+      case NFA_RW_PRES_CHK_RB_CH3:
+        option = RW_T4T_CHK_READ_BINARY_CH3;
+        break;
+
+      case NFA_RW_PRES_CHK_ISO_DEP_NAK:
+        if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
+          option = RW_T4T_CHK_ISO_DEP_NAK_PRES_CHK;
+        }
+        break;
+      default:
+        if (nfa_rw_cb.flags & NFA_RW_FL_NDEF_OK) {
+          /* read binary on channel 0 */
+          option = RW_T4T_CHK_READ_BINARY_CH0;
+        } else {
+          /* NDEF DETECT failed.*/
+          if (nfa_dm_is_raw_frame_session()) {
+            /* NFA_SendRawFrame() is called */
+            if (p_nfa_dm_cfg->presence_check_option &
+                NFA_DM_PCO_EMPTY_I_BLOCK) {
+              /* empty I block */
+              option = RW_T4T_CHK_EMPTY_I_BLOCK;
+            } else {
+              /* read binary on channel 3 */
+              option = RW_T4T_CHK_READ_BINARY_CH3;
+            }
+          } else if (!(p_nfa_dm_cfg->presence_check_option &
+                       NFA_DM_PCO_ISO_SLEEP_WAKE) &&
+                     (nfa_rw_cb.intf_type == NFC_INTERFACE_ISO_DEP)) {
+            /* the option indicates to use empty I block && ISODEP interface is
+             * activated */
+            option = RW_T4T_CHK_EMPTY_I_BLOCK;
+          }
+        }
+    }
+
+    if (option != NFA_RW_OPTION_INVALID) {
+      /* use the presence check with the chosen option */
+      status = RW_T4tPresenceCheck(option);
+    } else {
+      /* use sleep/wake for presence check */
+      unsupported = true;
+    }
+
+  } else if (NFC_PROTOCOL_15693 == protocol) { /* ISO 15693 */
+    status = RW_I93PresenceCheck();
+  } else {
+    /* Protocol unsupported by RW module... */
+    unsupported = true;
+  }
+
+  if (unsupported) {
+    if (nfa_rw_cb.activated_tech_mode == NFC_DISCOVERY_TYPE_POLL_KOVIO) {
+      /* start Kovio presence check (deactivate and wait for activation) */
+      status = nfa_dm_disc_start_kovio_presence_check();
+    } else {
+      /* Let DM perform presence check (by putting tag to sleep and then waking
+       * it up) */
+      status = nfa_dm_disc_sleep_wakeup();
+    }
+  }
+
+  /* Handle presence check failure */
+  if (status != NFC_STATUS_OK)
+    nfa_rw_handle_presence_check_rsp(NFC_STATUS_FAILED);
+  else if (!unsupported) {
+#if (NXP_EXTNS == TRUE)
+    if (protocol == NFC_PROTOCOL_15693) {
+      nfa_sys_start_timer(&nfa_rw_cb.tle, NFA_RW_PRESENCE_CHECK_TIMEOUT_EVT,
+                          iso_15693_max_presence_check_timeout);
+    } else
+#endif
+    {
+      nfa_sys_start_timer(&nfa_rw_cb.tle, NFA_RW_PRESENCE_CHECK_TIMEOUT_EVT,
+                          p_nfa_dm_cfg->presence_check_timeout);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_presence_check_tick
+**
+** Description      Called on expiration of NFA_RW_PRESENCE_CHECK_INTERVAL
+**                  Initiate presence check
+**
+** Returns          true (caller frees message buffer)
+**
+*******************************************************************************/
+bool nfa_rw_presence_check_tick(tNFA_RW_MSG* p_data) {
+  (void)p_data;
+
+  /* Store the current operation */
+  nfa_rw_cb.cur_op = NFA_RW_OP_PRESENCE_CHECK;
+  nfa_rw_cb.flags |= NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY;
+  NFA_TRACE_DEBUG0("Auto-presence check starting...");
+
+  /* Perform presence check */
+  nfa_rw_presence_check(NULL);
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_presence_check_timeout
+**
+** Description      presence check timeout: report presence check failure
+**
+** Returns          true (caller frees message buffer)
+**
+*******************************************************************************/
+bool nfa_rw_presence_check_timeout(tNFA_RW_MSG* p_data) {
+  (void)p_data;
+
+  nfa_rw_handle_presence_check_rsp(NFC_STATUS_FAILED);
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_format_tag
+**
+** Description      Handler for NFA_RW_API_FORMAT_TAG
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static void nfa_rw_format_tag(tNFA_RW_MSG* p_data) {
+  tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  (void)p_data;
+
+  if (protocol == NFC_PROTOCOL_T1T) {
+    status = RW_T1tFormatNDef();
+  } else if ((protocol == NFC_PROTOCOL_T2T) &&
+             (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)) {
+    status = RW_T2tFormatNDef();
+  } else if (protocol == NFC_PROTOCOL_T3T) {
+    status = RW_T3tFormatNDef();
+  } else if (protocol == NFC_PROTOCOL_15693) {
+    status = RW_I93FormatNDef();
+  } else if (protocol == NFC_PROTOCOL_ISO_DEP) {
+    status = RW_T4tFormatNDef();
+  }
+
+  /* If unable to format NDEF, notify the app */
+  if (status != NFC_STATUS_OK) nfa_rw_error_cleanup(NFA_FORMAT_CPLT_EVT);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_detect_tlv
+**
+** Description      Handler for NFA_RW_API_DETECT_NDEF_EVT
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static bool nfa_rw_detect_tlv(tNFA_RW_MSG* p_data, uint8_t tlv) {
+  (void)p_data;
+
+  NFA_TRACE_DEBUG0("nfa_rw_detect_tlv");
+
+  switch (nfa_rw_cb.protocol) {
+    case NFC_PROTOCOL_T1T:
+      if (RW_T1tLocateTlv(tlv) != NFC_STATUS_OK)
+        nfa_rw_error_cleanup(NFA_TLV_DETECT_EVT);
+      break;
+
+    case NFC_PROTOCOL_T2T:
+      if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) {
+        if (RW_T2tLocateTlv(tlv) != NFC_STATUS_OK)
+          nfa_rw_error_cleanup(NFA_TLV_DETECT_EVT);
+      }
+      break;
+
+    default:
+      break;
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_config_tag_ro
+**
+** Description      Handler for NFA_RW_OP_SET_TAG_RO
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static tNFC_STATUS nfa_rw_config_tag_ro(bool b_hard_lock) {
+  tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+
+  NFA_TRACE_DEBUG0("nfa_rw_config_tag_ro ()");
+
+  if (NFC_PROTOCOL_T1T == protocol) { /* Type1Tag    - NFC-A */
+    if ((nfa_rw_cb.tlv_st == NFA_RW_TLV_DETECT_ST_OP_NOT_STARTED) ||
+        (nfa_rw_cb.tlv_st == NFA_RW_TLV_DETECT_ST_MEM_TLV_OP_COMPLETE)) {
+      status = RW_T1tLocateTlv(TAG_LOCK_CTRL_TLV);
+      return (status);
+    } else {
+      status = RW_T1tSetTagReadOnly(b_hard_lock);
+    }
+  } else if (NFC_PROTOCOL_T2T == protocol) { /* Type2Tag    - NFC-A */
+    if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) {
+      status = RW_T2tSetTagReadOnly(b_hard_lock);
+    }
+  } else if (NFC_PROTOCOL_T3T == protocol) {
+    /* Type3Tag    - NFC-F */
+    status = RW_T3tSetReadOnly(b_hard_lock);
+  } else if (NFC_PROTOCOL_ISO_DEP == protocol) {
+    /* ISODEP/4A,4B- NFC-A or NFC-B */
+    status = RW_T4tSetNDefReadOnly();
+  } else if (NFC_PROTOCOL_15693 == protocol) {
+    /* ISO 15693 */
+    status = RW_I93SetTagReadOnly();
+  }
+
+  if (status == NFC_STATUS_OK) {
+    nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
+  } else {
+    nfa_rw_error_cleanup(NFA_SET_TAG_RO_EVT);
+  }
+
+  return (status);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_t1t_rid
+**
+** Description      Handler for T1T_RID API
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static bool nfa_rw_t1t_rid(tNFA_RW_MSG* p_data) {
+  (void)p_data;
+
+  if (RW_T1tRid() != NFC_STATUS_OK) nfa_rw_error_cleanup(NFA_READ_CPLT_EVT);
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_t1t_rall
+**
+** Description      Handler for T1T_ReadAll API
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static bool nfa_rw_t1t_rall(tNFA_RW_MSG* p_data) {
+  (void)p_data;
+
+  if (RW_T1tReadAll() != NFC_STATUS_OK) nfa_rw_error_cleanup(NFA_READ_CPLT_EVT);
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_t1t_read
+**
+** Description      Handler for T1T_Read API
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static bool nfa_rw_t1t_read(tNFA_RW_MSG* p_data) {
+  tNFA_RW_OP_PARAMS_T1T_READ* p_t1t_read =
+      (tNFA_RW_OP_PARAMS_T1T_READ*)&(p_data->op_req.params.t1t_read);
+
+  if (RW_T1tRead(p_t1t_read->block_number, p_t1t_read->index) != NFC_STATUS_OK)
+    nfa_rw_error_cleanup(NFA_READ_CPLT_EVT);
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_t1t_write
+**
+** Description      Handler for T1T_WriteErase/T1T_WriteNoErase API
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static bool nfa_rw_t1t_write(tNFA_RW_MSG* p_data) {
+  tNFA_RW_OP_PARAMS_T1T_WRITE* p_t1t_write =
+      (tNFA_RW_OP_PARAMS_T1T_WRITE*)&(p_data->op_req.params.t1t_write);
+  tNFC_STATUS status;
+
+  if (p_t1t_write->b_erase) {
+    status = RW_T1tWriteErase(p_t1t_write->block_number, p_t1t_write->index,
+                              p_t1t_write->p_block_data[0]);
+  } else {
+    status = RW_T1tWriteNoErase(p_t1t_write->block_number, p_t1t_write->index,
+                                p_t1t_write->p_block_data[0]);
+  }
+
+  if (status != NFC_STATUS_OK) {
+    nfa_rw_error_cleanup(NFA_WRITE_CPLT_EVT);
+  } else {
+    if (p_t1t_write->block_number == 0x01)
+      nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_t1t_rseg
+**
+** Description      Handler for T1t_ReadSeg API
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static bool nfa_rw_t1t_rseg(tNFA_RW_MSG* p_data) {
+  tNFA_RW_OP_PARAMS_T1T_READ* p_t1t_read =
+      (tNFA_RW_OP_PARAMS_T1T_READ*)&(p_data->op_req.params.t1t_read);
+
+  if (RW_T1tReadSeg(p_t1t_read->segment_number) != NFC_STATUS_OK)
+    nfa_rw_error_cleanup(NFA_READ_CPLT_EVT);
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_t1t_read8
+**
+** Description      Handler for T1T_Read8 API
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static bool nfa_rw_t1t_read8(tNFA_RW_MSG* p_data) {
+  tNFA_RW_OP_PARAMS_T1T_READ* p_t1t_read =
+      (tNFA_RW_OP_PARAMS_T1T_READ*)&(p_data->op_req.params.t1t_read);
+
+  if (RW_T1tRead8(p_t1t_read->block_number) != NFC_STATUS_OK)
+    nfa_rw_error_cleanup(NFA_READ_CPLT_EVT);
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_t1t_write8
+**
+** Description      Handler for T1T_WriteErase8/T1T_WriteNoErase8 API
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static bool nfa_rw_t1t_write8(tNFA_RW_MSG* p_data) {
+  tNFA_RW_OP_PARAMS_T1T_WRITE* p_t1t_write =
+      (tNFA_RW_OP_PARAMS_T1T_WRITE*)&(p_data->op_req.params.t1t_write);
+  tNFC_STATUS status;
+
+  if (p_t1t_write->b_erase) {
+    status =
+        RW_T1tWriteErase8(p_t1t_write->block_number, p_t1t_write->p_block_data);
+  } else {
+    status = RW_T1tWriteNoErase8(p_t1t_write->block_number,
+                                 p_t1t_write->p_block_data);
+  }
+
+  if (status != NFC_STATUS_OK) {
+    nfa_rw_error_cleanup(NFA_WRITE_CPLT_EVT);
+  } else {
+    if (p_t1t_write->block_number == 0x01)
+      nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_t2t_read
+**
+** Description      Handler for T2T_Read API
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static bool nfa_rw_t2t_read(tNFA_RW_MSG* p_data) {
+  tNFA_RW_OP_PARAMS_T2T_READ* p_t2t_read =
+      (tNFA_RW_OP_PARAMS_T2T_READ*)&(p_data->op_req.params.t2t_read);
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+
+  if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
+    status = RW_T2tRead(p_t2t_read->block_number);
+
+  if (status != NFC_STATUS_OK) nfa_rw_error_cleanup(NFA_READ_CPLT_EVT);
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_t2t_write
+**
+** Description      Handler for T2T_Write API
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static bool nfa_rw_t2t_write(tNFA_RW_MSG* p_data) {
+  tNFA_RW_OP_PARAMS_T2T_WRITE* p_t2t_write =
+      (tNFA_RW_OP_PARAMS_T2T_WRITE*)&(p_data->op_req.params.t2t_write);
+
+  if (RW_T2tWrite(p_t2t_write->block_number, p_t2t_write->p_block_data) !=
+      NFC_STATUS_OK) {
+    nfa_rw_error_cleanup(NFA_WRITE_CPLT_EVT);
+  } else {
+    if (p_t2t_write->block_number == 0x03)
+      nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_t2t_sector_select
+**
+** Description      Handler for T2T_Sector_Select API
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static bool nfa_rw_t2t_sector_select(tNFA_RW_MSG* p_data) {
+  tNFA_RW_OP_PARAMS_T2T_SECTOR_SELECT* p_t2t_sector_select =
+      (tNFA_RW_OP_PARAMS_T2T_SECTOR_SELECT*)&(
+          p_data->op_req.params.t2t_sector_select);
+
+  if (RW_T2tSectorSelect(p_t2t_sector_select->sector_number) != NFC_STATUS_OK)
+    nfa_rw_error_cleanup(NFA_SELECT_CPLT_EVT);
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_t3t_read
+**
+** Description      Handler for T3T_Read API
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static bool nfa_rw_t3t_read(tNFA_RW_MSG* p_data) {
+  tNFA_RW_OP_PARAMS_T3T_READ* p_t3t_read =
+      (tNFA_RW_OP_PARAMS_T3T_READ*)&(p_data->op_req.params.t3t_read);
+
+  if (RW_T3tCheck(p_t3t_read->num_blocks,
+                  (tT3T_BLOCK_DESC*)p_t3t_read->p_block_desc) != NFC_STATUS_OK)
+    nfa_rw_error_cleanup(NFA_READ_CPLT_EVT);
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_t3t_write
+**
+** Description      Handler for T3T_Write API
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static bool nfa_rw_t3t_write(tNFA_RW_MSG* p_data) {
+  tNFA_RW_OP_PARAMS_T3T_WRITE* p_t3t_write =
+      (tNFA_RW_OP_PARAMS_T3T_WRITE*)&(p_data->op_req.params.t3t_write);
+
+  if (RW_T3tUpdate(p_t3t_write->num_blocks,
+                   (tT3T_BLOCK_DESC*)p_t3t_write->p_block_desc,
+                   p_t3t_write->p_block_data) != NFC_STATUS_OK)
+    nfa_rw_error_cleanup(NFA_WRITE_CPLT_EVT);
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_t3t_get_system_codes
+**
+** Description      Get system codes (initiated by NFA after activation)
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static bool nfa_rw_t3t_get_system_codes(tNFA_RW_MSG* p_data) {
+  tNFC_STATUS status;
+  tNFA_TAG_PARAMS tag_params;
+  (void)p_data;
+
+  status = RW_T3tGetSystemCodes();
+
+  if (status != NFC_STATUS_OK) {
+    /* Command complete - perform cleanup, notify app */
+    nfa_rw_command_complete();
+    tag_params.t3t.num_system_codes = 0;
+    tag_params.t3t.p_system_codes = NULL;
+
+    nfa_dm_notify_activation_status(NFA_STATUS_OK, &tag_params);
+  }
+
+  return true;
+}
+
+#if (NXP_EXTNS == TRUE)
+static bool nfa_rw_t3bt_get_pupi(tNFA_RW_MSG* p_data) {
+  tNFC_STATUS status;
+  (void)p_data;
+
+  status = RW_T3BtGetPupiID();
+
+  if (status != NFC_STATUS_OK) {
+    nfa_rw_command_complete();
+  }
+
+  return true;
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         nfa_rw_i93_command
+**
+** Description      Handler for ISO 15693 command
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static bool nfa_rw_i93_command(tNFA_RW_MSG* p_data) {
+  tNFA_CONN_EVT_DATA conn_evt_data;
+  tNFC_STATUS status = NFC_STATUS_OK;
+  uint8_t i93_command = I93_CMD_STAY_QUIET;
+
+  switch (p_data->op_req.op) {
+    case NFA_RW_OP_I93_INVENTORY:
+      i93_command = I93_CMD_INVENTORY;
+      if (p_data->op_req.params.i93_cmd.uid_present) {
+        status = RW_I93Inventory(p_data->op_req.params.i93_cmd.afi_present,
+                                 p_data->op_req.params.i93_cmd.afi,
+                                 p_data->op_req.params.i93_cmd.uid);
+      } else {
+        status = RW_I93Inventory(p_data->op_req.params.i93_cmd.afi_present,
+                                 p_data->op_req.params.i93_cmd.afi, NULL);
+      }
+      break;
+
+    case NFA_RW_OP_I93_STAY_QUIET:
+      i93_command = I93_CMD_STAY_QUIET;
+      status = RW_I93StayQuiet();
+      break;
+
+    case NFA_RW_OP_I93_READ_SINGLE_BLOCK:
+      i93_command = I93_CMD_READ_SINGLE_BLOCK;
+      status = RW_I93ReadSingleBlock(
+          p_data->op_req.params.i93_cmd.first_block_number);
+      break;
+
+    case NFA_RW_OP_I93_WRITE_SINGLE_BLOCK:
+      i93_command = I93_CMD_WRITE_SINGLE_BLOCK;
+      status = RW_I93WriteSingleBlock(
+          p_data->op_req.params.i93_cmd.first_block_number,
+          p_data->op_req.params.i93_cmd.p_data);
+      break;
+
+    case NFA_RW_OP_I93_LOCK_BLOCK:
+      i93_command = I93_CMD_LOCK_BLOCK;
+      status = RW_I93LockBlock(
+          (uint8_t)p_data->op_req.params.i93_cmd.first_block_number);
+      break;
+
+    case NFA_RW_OP_I93_READ_MULTI_BLOCK:
+      i93_command = I93_CMD_READ_MULTI_BLOCK;
+      status = RW_I93ReadMultipleBlocks(
+          p_data->op_req.params.i93_cmd.first_block_number,
+          p_data->op_req.params.i93_cmd.number_blocks);
+      break;
+
+    case NFA_RW_OP_I93_WRITE_MULTI_BLOCK:
+      i93_command = I93_CMD_WRITE_MULTI_BLOCK;
+      status = RW_I93WriteMultipleBlocks(
+          (uint8_t)p_data->op_req.params.i93_cmd.first_block_number,
+          p_data->op_req.params.i93_cmd.number_blocks,
+          p_data->op_req.params.i93_cmd.p_data);
+      break;
+
+    case NFA_RW_OP_I93_SELECT:
+      i93_command = I93_CMD_SELECT;
+      status = RW_I93Select(p_data->op_req.params.i93_cmd.p_data);
+      break;
+
+    case NFA_RW_OP_I93_RESET_TO_READY:
+      i93_command = I93_CMD_RESET_TO_READY;
+      status = RW_I93ResetToReady();
+      break;
+
+    case NFA_RW_OP_I93_WRITE_AFI:
+      i93_command = I93_CMD_WRITE_AFI;
+      status = RW_I93WriteAFI(p_data->op_req.params.i93_cmd.afi);
+      break;
+
+    case NFA_RW_OP_I93_LOCK_AFI:
+      i93_command = I93_CMD_LOCK_AFI;
+      status = RW_I93LockAFI();
+      break;
+
+    case NFA_RW_OP_I93_WRITE_DSFID:
+      i93_command = I93_CMD_WRITE_DSFID;
+      status = RW_I93WriteDSFID(p_data->op_req.params.i93_cmd.dsfid);
+      break;
+
+    case NFA_RW_OP_I93_LOCK_DSFID:
+      i93_command = I93_CMD_LOCK_DSFID;
+      status = RW_I93LockDSFID();
+      break;
+
+    case NFA_RW_OP_I93_GET_SYS_INFO:
+      i93_command = I93_CMD_GET_SYS_INFO;
+      if (p_data->op_req.params.i93_cmd.uid_present) {
+        status = RW_I93GetSysInfo(p_data->op_req.params.i93_cmd.uid);
+      } else {
+        status = RW_I93GetSysInfo(NULL);
+      }
+      break;
+
+    case NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS:
+      i93_command = I93_CMD_GET_MULTI_BLK_SEC;
+      status = RW_I93GetMultiBlockSecurityStatus(
+          p_data->op_req.params.i93_cmd.first_block_number,
+          p_data->op_req.params.i93_cmd.number_blocks);
+      break;
+
+    default:
+      break;
+  }
+
+  if (status != NFC_STATUS_OK) {
+    /* Command complete - perform cleanup, notify app */
+    nfa_rw_command_complete();
+
+    conn_evt_data.i93_cmd_cplt.status = NFA_STATUS_FAILED;
+    conn_evt_data.i93_cmd_cplt.sent_command = i93_command;
+
+    nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data);
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_raw_mode_data_cback
+**
+** Description      Handler for incoming tag data for unsupported tag protocols
+**                  (forward data to upper layer)
+**
+** Returns          nothing
+**
+*******************************************************************************/
+static void nfa_rw_raw_mode_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
+                                       tNFC_CONN* p_data) {
+  NFC_HDR* p_msg;
+  tNFA_CONN_EVT_DATA evt_data;
+  (void)conn_id;
+
+  NFA_TRACE_DEBUG1("nfa_rw_raw_mode_data_cback(): event = 0x%X", event);
+
+  if ((event == NFC_DATA_CEVT) &&
+      ((p_data->data.status == NFC_STATUS_OK) ||
+       (p_data->data.status == NFC_STATUS_CONTINUE))) {
+    p_msg = (NFC_HDR*)p_data->data.p_data;
+
+    if (p_msg) {
+      evt_data.data.status = p_data->data.status;
+      evt_data.data.p_data = (uint8_t*)(p_msg + 1) + p_msg->offset;
+      evt_data.data.len = p_msg->len;
+
+      nfa_dm_conn_cback_event_notify(NFA_DATA_EVT, &evt_data);
+
+      GKI_freebuf(p_msg);
+    } else {
+      NFA_TRACE_ERROR0(
+          "nfa_rw_raw_mode_data_cback (): received NFC_DATA_CEVT with NULL "
+          "data pointer");
+    }
+  } else if (event == NFC_DEACTIVATE_CEVT) {
+    NFC_SetStaticRfCback(NULL);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_activate_ntf
+**
+** Description      Handler for NFA_RW_ACTIVATE_NTF
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_rw_activate_ntf(tNFA_RW_MSG* p_data) {
+  tNFC_ACTIVATE_DEVT* p_activate_params =
+      p_data->activate_ntf.p_activate_params;
+  tNFA_TAG_PARAMS tag_params;
+  tNFA_RW_OPERATION msg;
+  bool activate_notify = true;
+  uint8_t* p;
+
+  if ((nfa_rw_cb.halt_event != RW_T2T_MAX_EVT) &&
+      (nfa_rw_cb.activated_tech_mode == NFC_DISCOVERY_TYPE_POLL_A) &&
+      (nfa_rw_cb.protocol == NFC_PROTOCOL_T2T) &&
+      (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)) {
+    /* Type 2 tag is wake up from HALT State */
+    if (nfa_dm_cb.p_activate_ntf != NULL) {
+      GKI_freebuf(nfa_dm_cb.p_activate_ntf);
+      nfa_dm_cb.p_activate_ntf = NULL;
+    }
+    NFA_TRACE_DEBUG0(
+        "nfa_rw_activate_ntf () - Type 2 tag wake up from HALT State");
+    return true;
+  }
+
+  NFA_TRACE_DEBUG0("nfa_rw_activate_ntf");
+
+  /* Initialize control block */
+  nfa_rw_cb.protocol = p_activate_params->protocol;
+  nfa_rw_cb.intf_type = p_activate_params->intf_param.type;
+  nfa_rw_cb.pa_sel_res = p_activate_params->rf_tech_param.param.pa.sel_rsp;
+  nfa_rw_cb.activated_tech_mode = p_activate_params->rf_tech_param.mode;
+  nfa_rw_cb.flags = NFA_RW_FL_ACTIVATED;
+  nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
+  nfa_rw_cb.halt_event = RW_T2T_MAX_EVT;
+  nfa_rw_cb.skip_dyn_locks = false;
+  nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
+  nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_OP_NOT_STARTED;
+
+  memset(&tag_params, 0, sizeof(tNFA_TAG_PARAMS));
+
+  /* Check if we are in exclusive RF mode */
+  if (p_data->activate_ntf.excl_rf_not_active) {
+    /* Not in exclusive RF mode */
+    nfa_rw_cb.flags |= NFA_RW_FL_NOT_EXCL_RF_MODE;
+  }
+
+  /* check if the protocol is activated with supported interface */
+  if (p_activate_params->intf_param.type == NCI_INTERFACE_FRAME) {
+    if ((p_activate_params->protocol != NFA_PROTOCOL_T1T) &&
+        (p_activate_params->protocol != NFA_PROTOCOL_T2T) &&
+        (p_activate_params->protocol != NFA_PROTOCOL_T3T) &&
+        (p_activate_params->protocol != NFC_PROTOCOL_15693)
+#if (NXP_EXTNS == TRUE)
+        && (p_activate_params->protocol != NFA_PROTOCOL_T3BT)
+#endif
+            ) {
+      nfa_rw_cb.protocol = NFA_PROTOCOL_INVALID;
+    }
+  } else if (p_activate_params->intf_param.type == NCI_INTERFACE_ISO_DEP) {
+    if (p_activate_params->protocol != NFA_PROTOCOL_ISO_DEP) {
+      nfa_rw_cb.protocol = NFA_PROTOCOL_INVALID;
+    }
+  }
+
+  if (nfa_rw_cb.protocol == NFA_PROTOCOL_INVALID) {
+    /* Only sending raw frame and presence check are supported in this state */
+
+    NFC_SetStaticRfCback(nfa_rw_raw_mode_data_cback);
+
+    /* Notify app of NFA_ACTIVATED_EVT and start presence check timer */
+    nfa_dm_notify_activation_status(NFA_STATUS_OK, NULL);
+    nfa_rw_check_start_presence_check_timer(NFA_RW_PRESENCE_CHECK_INTERVAL);
+    return true;
+  }
+
+  /* If protocol not supported by RW module, notify app of NFA_ACTIVATED_EVT and
+   * start presence check if needed */
+  if (!nfa_dm_is_protocol_supported(
+          p_activate_params->protocol,
+          p_activate_params->rf_tech_param.param.pa.sel_rsp)) {
+    /* Notify upper layer of NFA_ACTIVATED_EVT if needed, and start presence
+     * check timer */
+    /* Set data callback (pass all incoming data to upper layer using
+     * NFA_DATA_EVT) */
+    NFC_SetStaticRfCback(nfa_rw_raw_mode_data_cback);
+
+    /* Notify app of NFA_ACTIVATED_EVT and start presence check timer */
+    nfa_dm_notify_activation_status(NFA_STATUS_OK, NULL);
+    nfa_rw_check_start_presence_check_timer(NFA_RW_PRESENCE_CHECK_INTERVAL);
+    return true;
+  }
+
+  /* Initialize RW module */
+  if ((RW_SetActivatedTagType(p_activate_params, nfa_rw_cback)) !=
+      NFC_STATUS_OK) {
+    /* Log error (stay in NFA_RW_ST_ACTIVATED state until deactivation) */
+    NFA_TRACE_ERROR0("RW_SetActivatedTagType failed.");
+    return true;
+  }
+
+  /* Perform protocol-specific actions */
+  if (NFC_PROTOCOL_T1T == nfa_rw_cb.protocol) {
+    /* Retrieve HR and UID fields from activation notification */
+    memcpy(tag_params.t1t.hr, p_activate_params->rf_tech_param.param.pa.hr,
+           NFA_T1T_HR_LEN);
+    memcpy(tag_params.t1t.uid, p_activate_params->rf_tech_param.param.pa.nfcid1,
+           p_activate_params->rf_tech_param.param.pa.nfcid1_len);
+    msg.op = NFA_RW_OP_T1T_RID;
+    nfa_rw_handle_op_req((void*)&msg);
+    activate_notify = false; /* Delay notifying upper layer of NFA_ACTIVATED_EVT
+                                until HR0/HR1 is received */
+  } else if (NFC_PROTOCOL_T2T == nfa_rw_cb.protocol) {
+    /* Retrieve UID fields from activation notification */
+    memcpy(tag_params.t2t.uid, p_activate_params->rf_tech_param.param.pa.nfcid1,
+           p_activate_params->rf_tech_param.param.pa.nfcid1_len);
+  } else if (NFC_PROTOCOL_T3T == nfa_rw_cb.protocol) {
+#if (NXP_EXTNS == TRUE)
+    if (appl_dta_mode_flag) {
+      /*Incase of DTA mode Dont send commands to get system code. Just notify
+       * activation*/
+      activate_notify = true;
+    } else {
+#endif
+      /* Delay notifying upper layer of NFA_ACTIVATED_EVT until system codes are
+       * retrieved */
+      activate_notify = false;
+      /* Issue command to get Felica system codes */
+      msg.op = NFA_RW_OP_T3T_GET_SYSTEM_CODES;
+      nfa_rw_handle_op_req((void*)&msg);
+#if (NXP_EXTNS == TRUE)
+    }
+#endif
+  }
+#if (NXP_EXTNS == TRUE)
+  else if (NFC_PROTOCOL_T3BT == nfa_rw_cb.protocol) {
+
+    activate_notify =
+        false; /* Delay notifying upper layer of NFA_ACTIVATED_EVT until system
+                  codes are retrieved */
+    msg.op = NFA_RW_OP_T3BT_PUPI;
+    nfa_rw_handle_op_req((void*)&msg);
+  }
+#endif
+  else if (NFC_PROTOCOL_15693 == nfa_rw_cb.protocol) {
+    /* Delay notifying upper layer of NFA_ACTIVATED_EVT to retrieve additional
+     * tag infomation */
+    nfa_rw_cb.flags |= NFA_RW_FL_ACTIVATION_NTF_PENDING;
+    activate_notify = false;
+
+    /* store DSFID and UID from activation NTF */
+    nfa_rw_cb.i93_dsfid = p_activate_params->rf_tech_param.param.pi93.dsfid;
+
+    p = nfa_rw_cb.i93_uid;
+    ARRAY8_TO_STREAM(p, p_activate_params->rf_tech_param.param.pi93.uid);
+
+    if ((nfa_rw_cb.i93_uid[1] == I93_UID_IC_MFG_CODE_TI) &&
+        (((nfa_rw_cb.i93_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
+          I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY) ||
+         ((nfa_rw_cb.i93_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
+          I93_UID_TAG_IT_HF_I_PRO_CHIP_INLAY))) {
+      /* these don't support Get System Information Command */
+      nfa_rw_cb.i93_block_size = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_BLK_SIZE;
+      nfa_rw_cb.i93_afi_location =
+          I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION;
+
+      if ((nfa_rw_cb.i93_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
+          I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY) {
+        nfa_rw_cb.i93_num_block = I93_TAG_IT_HF_I_STD_CHIP_INLAY_NUM_TOTAL_BLK;
+      } else {
+        nfa_rw_cb.i93_num_block = I93_TAG_IT_HF_I_PRO_CHIP_INLAY_NUM_TOTAL_BLK;
+      }
+
+      /* read AFI */
+      if (RW_I93ReadSingleBlock((uint8_t)(nfa_rw_cb.i93_afi_location /
+                                          nfa_rw_cb.i93_block_size)) !=
+          NFC_STATUS_OK) {
+        /* notify activation without AFI/IC-Ref */
+        nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
+        activate_notify = true;
+
+        tag_params.i93.info_flags =
+            (I93_INFO_FLAG_DSFID | I93_INFO_FLAG_MEM_SIZE);
+        tag_params.i93.dsfid = nfa_rw_cb.i93_dsfid;
+        tag_params.i93.block_size = nfa_rw_cb.i93_block_size;
+        tag_params.i93.num_block = nfa_rw_cb.i93_num_block;
+        memcpy(tag_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN);
+      }
+    } else {
+      /* All of ICODE supports Get System Information Command */
+      /* Tag-it HF-I Plus Chip/Inlay supports Get System Information Command */
+      /* just try for others */
+
+      if (RW_I93GetSysInfo(nfa_rw_cb.i93_uid) != NFC_STATUS_OK) {
+        /* notify activation without AFI/MEM size/IC-Ref */
+        nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
+        activate_notify = true;
+
+        tag_params.i93.info_flags = I93_INFO_FLAG_DSFID;
+        tag_params.i93.dsfid = nfa_rw_cb.i93_dsfid;
+        tag_params.i93.block_size = 0;
+        tag_params.i93.num_block = 0;
+        memcpy(tag_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN);
+      } else {
+        /* reset memory size */
+        nfa_rw_cb.i93_block_size = 0;
+        nfa_rw_cb.i93_num_block = 0;
+      }
+    }
+  }
+
+  /* Notify upper layer of NFA_ACTIVATED_EVT if needed, and start presence check
+   * timer */
+  if (activate_notify) {
+    nfa_dm_notify_activation_status(NFA_STATUS_OK, &tag_params);
+    nfa_rw_check_start_presence_check_timer(NFA_RW_PRESENCE_CHECK_INTERVAL);
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_deactivate_ntf
+**
+** Description      Handler for NFA_RW_DEACTIVATE_NTF
+**
+** Returns          true (message buffer to be freed by caller)
+**
+*******************************************************************************/
+bool nfa_rw_deactivate_ntf(tNFA_RW_MSG* p_data) {
+  (void)p_data;
+
+  /* Clear the activated flag */
+  nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATED;
+
+  /* Free buffer for incoming NDEF message, in case we were in the middle of a
+   * read operation */
+  nfa_rw_free_ndef_rx_buf();
+
+  /* If there is a pending command message, then free it */
+  if (nfa_rw_cb.p_pending_msg) {
+    if ((nfa_rw_cb.p_pending_msg->op_req.op == NFA_RW_OP_SEND_RAW_FRAME) &&
+        (nfa_rw_cb.p_pending_msg->op_req.params.send_raw_frame.p_data)) {
+      GKI_freebuf(nfa_rw_cb.p_pending_msg->op_req.params.send_raw_frame.p_data);
+    }
+
+    GKI_freebuf(nfa_rw_cb.p_pending_msg);
+    nfa_rw_cb.p_pending_msg = NULL;
+  }
+
+  /* If we are in the process of waking up tag from HALT state */
+  if (nfa_rw_cb.halt_event == RW_T2T_READ_CPLT_EVT) {
+    if (nfa_rw_cb.rw_data.data.p_data)
+      GKI_freebuf(nfa_rw_cb.rw_data.data.p_data);
+    nfa_rw_cb.rw_data.data.p_data = NULL;
+  }
+
+  /* Stop presence check timer (if started) */
+  nfa_rw_stop_presence_check_timer();
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_handle_op_req
+**
+** Description      Handler for NFA_RW_OP_REQUEST_EVT, operation request
+**
+** Returns          true if caller should free p_data
+**                  false if caller does not need to free p_data
+**
+*******************************************************************************/
+bool nfa_rw_handle_op_req(tNFA_RW_MSG* p_data) {
+  bool freebuf = true;
+  uint16_t presence_check_start_delay = 0;
+
+  /* Check if activated */
+  if (!(nfa_rw_cb.flags & NFA_RW_FL_ACTIVATED)) {
+    NFA_TRACE_ERROR0("nfa_rw_handle_op_req: not activated");
+    return true;
+  }
+  /* Check if currently busy with another API call */
+  else if (nfa_rw_cb.flags & NFA_RW_FL_API_BUSY) {
+    return (nfa_rw_op_req_while_busy(p_data));
+  }
+  /* Check if currently busy with auto-presence check */
+  else if (nfa_rw_cb.flags & NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY) {
+    /* Cache the command (will be handled once auto-presence check is completed)
+     */
+    NFA_TRACE_DEBUG1(
+        "Deferring operation %i until after auto-presence check is completed",
+        p_data->op_req.op);
+    nfa_rw_cb.p_pending_msg = p_data;
+    nfa_rw_cb.flags |= NFA_RW_FL_API_BUSY;
+    return (false);
+  }
+
+  NFA_TRACE_DEBUG1("nfa_rw_handle_op_req: op=0x%02x", p_data->op_req.op);
+
+  nfa_rw_cb.flags |= NFA_RW_FL_API_BUSY;
+
+  /* Stop the presence check timer */
+  nfa_rw_stop_presence_check_timer();
+
+  /* Store the current operation */
+  nfa_rw_cb.cur_op = p_data->op_req.op;
+
+  /* Call appropriate handler for requested operation */
+  switch (p_data->op_req.op) {
+    case NFA_RW_OP_DETECT_NDEF:
+      nfa_rw_cb.skip_dyn_locks = false;
+      nfa_rw_detect_ndef(p_data);
+      break;
+
+    case NFA_RW_OP_READ_NDEF:
+      nfa_rw_read_ndef(p_data);
+      break;
+
+    case NFA_RW_OP_WRITE_NDEF:
+      nfa_rw_write_ndef(p_data);
+      break;
+
+    case NFA_RW_OP_SEND_RAW_FRAME:
+      presence_check_start_delay =
+          p_data->op_req.params.send_raw_frame.p_data->layer_specific;
+
+      NFC_SendData(NFC_RF_CONN_ID, p_data->op_req.params.send_raw_frame.p_data);
+
+      /* Clear the busy flag */
+      nfa_rw_cb.flags &= ~NFA_RW_FL_API_BUSY;
+
+      /* Start presence_check after specified delay */
+      nfa_rw_check_start_presence_check_timer(presence_check_start_delay);
+      break;
+
+    case NFA_RW_OP_PRESENCE_CHECK:
+      nfa_rw_presence_check(p_data);
+      break;
+
+    case NFA_RW_OP_FORMAT_TAG:
+      nfa_rw_format_tag(p_data);
+      break;
+
+    case NFA_RW_OP_DETECT_LOCK_TLV:
+      nfa_rw_detect_tlv(p_data, TAG_LOCK_CTRL_TLV);
+      break;
+
+    case NFA_RW_OP_DETECT_MEM_TLV:
+      nfa_rw_detect_tlv(p_data, TAG_MEM_CTRL_TLV);
+      break;
+
+    case NFA_RW_OP_SET_TAG_RO:
+      nfa_rw_cb.b_hard_lock = p_data->op_req.params.set_readonly.b_hard_lock;
+      nfa_rw_config_tag_ro(nfa_rw_cb.b_hard_lock);
+      break;
+
+    case NFA_RW_OP_T1T_RID:
+      nfa_rw_t1t_rid(p_data);
+      break;
+
+    case NFA_RW_OP_T1T_RALL:
+      nfa_rw_t1t_rall(p_data);
+      break;
+
+    case NFA_RW_OP_T1T_READ:
+      nfa_rw_t1t_read(p_data);
+      break;
+
+    case NFA_RW_OP_T1T_WRITE:
+      nfa_rw_t1t_write(p_data);
+      break;
+
+    case NFA_RW_OP_T1T_RSEG:
+      nfa_rw_t1t_rseg(p_data);
+      break;
+
+    case NFA_RW_OP_T1T_READ8:
+      nfa_rw_t1t_read8(p_data);
+      break;
+
+    case NFA_RW_OP_T1T_WRITE8:
+      nfa_rw_t1t_write8(p_data);
+      break;
+
+    /* Type-2 tag commands */
+    case NFA_RW_OP_T2T_READ:
+      nfa_rw_t2t_read(p_data);
+      break;
+
+    case NFA_RW_OP_T2T_WRITE:
+      nfa_rw_t2t_write(p_data);
+      break;
+
+    case NFA_RW_OP_T2T_SECTOR_SELECT:
+      nfa_rw_t2t_sector_select(p_data);
+      break;
+
+    /* Type-3 tag commands */
+    case NFA_RW_OP_T3T_READ:
+      nfa_rw_t3t_read(p_data);
+      break;
+
+    case NFA_RW_OP_T3T_WRITE:
+      nfa_rw_t3t_write(p_data);
+      break;
+
+    case NFA_RW_OP_T3T_GET_SYSTEM_CODES:
+      nfa_rw_t3t_get_system_codes(p_data);
+      break;
+
+    /* ISO 15693 tag commands */
+    case NFA_RW_OP_I93_INVENTORY:
+    case NFA_RW_OP_I93_STAY_QUIET:
+    case NFA_RW_OP_I93_READ_SINGLE_BLOCK:
+    case NFA_RW_OP_I93_WRITE_SINGLE_BLOCK:
+    case NFA_RW_OP_I93_LOCK_BLOCK:
+    case NFA_RW_OP_I93_READ_MULTI_BLOCK:
+    case NFA_RW_OP_I93_WRITE_MULTI_BLOCK:
+    case NFA_RW_OP_I93_SELECT:
+    case NFA_RW_OP_I93_RESET_TO_READY:
+    case NFA_RW_OP_I93_WRITE_AFI:
+    case NFA_RW_OP_I93_LOCK_AFI:
+    case NFA_RW_OP_I93_WRITE_DSFID:
+    case NFA_RW_OP_I93_LOCK_DSFID:
+    case NFA_RW_OP_I93_GET_SYS_INFO:
+    case NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS:
+      nfa_rw_i93_command(p_data);
+      break;
+
+#if (NXP_EXTNS == TRUE)
+    case NFA_RW_OP_T3BT_PUPI:
+      nfa_rw_t3bt_get_pupi(p_data);
+      break;
+#endif
+
+    default:
+      NFA_TRACE_ERROR1("nfa_rw_handle_api: unhandled operation: %i",
+                       p_data->op_req.op);
+      break;
+  }
+
+  return (freebuf);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_op_req_while_busy
+**
+** Description      Handle operation request while busy
+**
+** Returns          true if caller should free p_data
+**                  false if caller does not need to free p_data
+**
+*******************************************************************************/
+static bool nfa_rw_op_req_while_busy(tNFA_RW_MSG* p_data) {
+  bool freebuf = true;
+  tNFA_CONN_EVT_DATA conn_evt_data;
+  uint8_t event;
+
+  NFA_TRACE_ERROR0("nfa_rw_op_req_while_busy: unable to handle API");
+
+  /* Return appropriate event for requested API, with status=BUSY */
+  conn_evt_data.status = NFA_STATUS_BUSY;
+
+  switch (p_data->op_req.op) {
+    case NFA_RW_OP_DETECT_NDEF:
+      conn_evt_data.ndef_detect.cur_size = 0;
+      conn_evt_data.ndef_detect.max_size = 0;
+      conn_evt_data.ndef_detect.flags = RW_NDEF_FL_UNKNOWN;
+      event = NFA_NDEF_DETECT_EVT;
+      break;
+    case NFA_RW_OP_READ_NDEF:
+    case NFA_RW_OP_T1T_RID:
+    case NFA_RW_OP_T1T_RALL:
+    case NFA_RW_OP_T1T_READ:
+    case NFA_RW_OP_T1T_RSEG:
+    case NFA_RW_OP_T1T_READ8:
+    case NFA_RW_OP_T2T_READ:
+    case NFA_RW_OP_T3T_READ:
+      event = NFA_READ_CPLT_EVT;
+      break;
+    case NFA_RW_OP_WRITE_NDEF:
+    case NFA_RW_OP_T1T_WRITE:
+    case NFA_RW_OP_T1T_WRITE8:
+    case NFA_RW_OP_T2T_WRITE:
+    case NFA_RW_OP_T3T_WRITE:
+      event = NFA_WRITE_CPLT_EVT;
+      break;
+    case NFA_RW_OP_FORMAT_TAG:
+      event = NFA_FORMAT_CPLT_EVT;
+      break;
+    case NFA_RW_OP_DETECT_LOCK_TLV:
+    case NFA_RW_OP_DETECT_MEM_TLV:
+      event = NFA_TLV_DETECT_EVT;
+      break;
+    case NFA_RW_OP_SET_TAG_RO:
+      event = NFA_SET_TAG_RO_EVT;
+      break;
+    case NFA_RW_OP_T2T_SECTOR_SELECT:
+      event = NFA_SELECT_CPLT_EVT;
+      break;
+    case NFA_RW_OP_I93_INVENTORY:
+    case NFA_RW_OP_I93_STAY_QUIET:
+    case NFA_RW_OP_I93_READ_SINGLE_BLOCK:
+    case NFA_RW_OP_I93_WRITE_SINGLE_BLOCK:
+    case NFA_RW_OP_I93_LOCK_BLOCK:
+    case NFA_RW_OP_I93_READ_MULTI_BLOCK:
+    case NFA_RW_OP_I93_WRITE_MULTI_BLOCK:
+    case NFA_RW_OP_I93_SELECT:
+    case NFA_RW_OP_I93_RESET_TO_READY:
+    case NFA_RW_OP_I93_WRITE_AFI:
+    case NFA_RW_OP_I93_LOCK_AFI:
+    case NFA_RW_OP_I93_WRITE_DSFID:
+    case NFA_RW_OP_I93_LOCK_DSFID:
+    case NFA_RW_OP_I93_GET_SYS_INFO:
+    case NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS:
+      event = NFA_I93_CMD_CPLT_EVT;
+      break;
+    default:
+      return (freebuf);
+  }
+  nfa_dm_act_conn_cback_notify(event, &conn_evt_data);
+
+  return (freebuf);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_command_complete
+**
+** Description      Handle command complete: clear the busy flag,
+**                  and start the presence check timer if applicable.
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_rw_command_complete(void) {
+  /* Clear the busy flag */
+  nfa_rw_cb.flags &= ~NFA_RW_FL_API_BUSY;
+
+  /* Restart presence_check timer */
+  nfa_rw_check_start_presence_check_timer(NFA_RW_PRESENCE_CHECK_INTERVAL);
+}
+
+#if (NXP_EXTNS == TRUE)
+void nfa_rw_set_cback(tNFC_DISCOVER* p_data) {
+  NFA_TRACE_DEBUG0("nfa_rw_set_cback:");
+  if ((p_data != NULL) &&
+      !nfa_dm_is_protocol_supported(
+          p_data->activate.protocol,
+          p_data->activate.rf_tech_param.param.pa.sel_rsp)) {
+    NFA_TRACE_DEBUG0("nfa_rw_set_cback: nfa_rw_raw_mode_data_cback");
+    /* Set data callback (pass all incoming data to upper layer using
+     * NFA_DATA_EVT) */
+    NFC_SetStaticRfCback(nfa_rw_raw_mode_data_cback);
+  }
+}
+
+void nfa_rw_update_pupi_id(uint8_t* p, uint8_t len) {
+  tNFC_ACTIVATE_DEVT* activate_ntf =
+      (tNFC_ACTIVATE_DEVT*)nfa_dm_cb.p_activate_ntf;
+
+  NFA_TRACE_DEBUG0("nfa_rw_update_pupi_id:");
+  if (len != 0) {
+    activate_ntf->rf_tech_param.param.pb.pupiid_len = len;
+    memcpy(activate_ntf->rf_tech_param.param.pb.pupiid, p, len);
+  } else {
+    NFA_TRACE_DEBUG1("nfa_rw_update_pupi_id: invalid resp_len=%d", len);
+  }
+}
+#endif
diff --git a/src/nfa/rw/nfa_rw_api.c b/src/nfa/rw/nfa_rw_api.c
new file mode 100644
index 0000000..7b36343
--- /dev/null
+++ b/src/nfa/rw/nfa_rw_api.c
@@ -0,0 +1,1463 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  NFA interface for tag Reader/Writer
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_api.h"
+#include "nfa_sys.h"
+#include "nfa_rw_int.h"
+#include "nfa_sys_int.h"
+
+/*****************************************************************************
+**  Constants
+*****************************************************************************/
+
+/*****************************************************************************
+**  APIs
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         NFA_RwDetectNDef
+**
+** Description      Perform the NDEF detection procedure  using the appropriate
+**                  method for the currently activated tag.
+**
+**                  Upon successful completion of NDEF detection, a
+**                  NFA_NDEF_DETECT_EVT will be sent, to notify the application
+**                  of the NDEF attributes (NDEF total memory size, current
+**                  size, etc.).
+**
+**                  It is not mandatory to call this function -  NFA_RwReadNDef
+**                  and NFA_RwWriteNDef will perform NDEF detection internally
+**                  if not performed already. This API may be called to get a
+**                  tag's NDEF size before issuing a write-request.
+**
+** Returns:
+**                  NFA_STATUS_OK if successfully initiated
+**                  NFC_STATUS_REFUSED if tag does not support NDEF
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwDetectNDef(void) {
+  tNFA_RW_OPERATION* p_msg;
+
+  NFA_TRACE_API0("NFA_RwDetectNDef");
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_DETECT_NDEF;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwReadNDef
+**
+** Description      Read NDEF message from tag. This function will internally
+**                  perform the NDEF detection procedure (if not performed
+**                  previously), and read the NDEF tag data using the
+**                  appropriate method for the currently activated tag.
+**
+**                  Upon successful completion of NDEF detection (if performed),
+**                  a NFA_NDEF_DETECT_EVT will be sent, to notify the
+**                  application of the NDEF attributes (NDEF total memory size,
+**                  current size, etc.).
+**
+**                  Upon receiving the NDEF message, the message will be sent to
+**                  the handler registered with NFA_RegisterNDefTypeHandler or
+**                  NFA_RequestExclusiveRfControl (if exclusive RF mode is
+**                  active)
+**
+** Returns:
+**                  NFA_STATUS_OK if successfully initiated
+**                  NFC_STATUS_REFUSED if tag does not support NDEF
+**                  NFC_STATUS_NOT_INITIALIZED if NULL NDEF was detected on the
+**                  tag
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwReadNDef(void) {
+  tNFA_RW_OPERATION* p_msg;
+
+  NFA_TRACE_API0("NFA_RwReadNDef");
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_READ_NDEF;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwWriteNDef
+**
+** Description      Write NDEF data to the activated tag. This function will
+**                  internally perform NDEF detection if necessary, and write
+**                  the NDEF tag data using the appropriate method for the
+**                  currently activated tag.
+**
+**                  When the entire message has been written, or if an error
+**                  occurs, the app will be notified with NFA_WRITE_CPLT_EVT.
+**
+**                  p_data needs to be persistent until NFA_WRITE_CPLT_EVT
+**
+**
+** Returns:
+**                  NFA_STATUS_OK if successfully initiated
+**                  NFC_STATUS_REFUSED if tag does not support NDEF/locked
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwWriteNDef(uint8_t* p_data, uint32_t len) {
+  tNFA_RW_OPERATION* p_msg;
+
+  NFA_TRACE_API2("NFA_RwWriteNDef (): ndef p_data=%08x, len: %i", p_data, len);
+
+  /* Validate parameters */
+  if (p_data == NULL) return (NFA_STATUS_INVALID_PARAM);
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_WRITE_NDEF;
+    p_msg->params.write_ndef.len = len;
+    p_msg->params.write_ndef.p_data = p_data;
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*****************************************************************************
+**
+** Function         NFA_RwPresenceCheck
+**
+** Description      Check if the tag is still in the field.
+**
+**                  The NFA_RW_PRESENCE_CHECK_EVT w/ status is used to
+**                  indicate presence or non-presence.
+**
+**                  option is used only with ISO-DEP protocol
+**
+** Returns
+**                  NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*****************************************************************************/
+tNFA_STATUS NFA_RwPresenceCheck(tNFA_RW_PRES_CHK_OPTION option) {
+  tNFA_RW_OPERATION* p_msg;
+
+  NFA_TRACE_API0("NFA_RwPresenceCheck");
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_PRESENCE_CHECK;
+    p_msg->params.option = option;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*****************************************************************************
+**
+** Function         NFA_RwFormatTag
+**
+** Description      Check if the tag is NDEF Formatable. If yes Format the tag
+**
+**                  The NFA_RW_FORMAT_CPLT_EVT w/ status is used to
+**                  indicate if tag is successfully formated or not
+**
+** Returns
+**                  NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*****************************************************************************/
+tNFA_STATUS NFA_RwFormatTag(void) {
+  tNFA_RW_OPERATION* p_msg;
+
+  NFA_TRACE_API0("NFA_RwFormatTag");
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_FORMAT_TAG;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwSetTagReadOnly
+**
+** Description:
+**      Sets tag as read only.
+**
+**      When tag is set as read only, or if an error occurs, the app will be
+**      notified with NFA_SET_TAG_RO_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_REJECTED if protocol is not T1/T2/ISO15693
+**                 (or) if hard lock is not requested for protocol ISO15693
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwSetTagReadOnly(bool b_hard_lock) {
+  tNFA_RW_OPERATION* p_msg;
+  tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
+
+  if ((protocol != NFC_PROTOCOL_T1T) && (protocol != NFC_PROTOCOL_T2T) &&
+      (protocol != NFC_PROTOCOL_15693) && (protocol != NFC_PROTOCOL_ISO_DEP) &&
+      (protocol != NFC_PROTOCOL_T3T)) {
+    NFA_TRACE_API1(
+        "NFA_RwSetTagReadOnly (): Cannot Configure as read only for Protocol: "
+        "%d",
+        protocol);
+    return (NFA_STATUS_REJECTED);
+  }
+
+  if ((!b_hard_lock && (protocol == NFC_PROTOCOL_15693)) ||
+      (b_hard_lock && (protocol == NFC_PROTOCOL_ISO_DEP))) {
+    NFA_TRACE_API2("NFA_RwSetTagReadOnly (): Cannot %s for Protocol: %d",
+                   b_hard_lock ? "Hard lock" : "Soft lock", protocol);
+    return (NFA_STATUS_REJECTED);
+  }
+
+  NFA_TRACE_API1("NFA_RwSetTagReadOnly (): %s",
+                 b_hard_lock ? "Hard lock" : "Soft lock");
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    /* Fill in tNFA_RW_OPERATION struct */
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_SET_TAG_RO;
+    p_msg->params.set_readonly.b_hard_lock = b_hard_lock;
+
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+** Tag specific APIs
+** (note: for Type-4 tags, use NFA_SendRawFrame to exchange APDUs)
+*******************************************************************************/
+
+/*******************************************************************************
+**
+** Function         NFA_RwLocateTlv
+**
+** Description:
+**      Search for the Lock/Memory contril TLV on the activated Type1/Type2 tag
+**
+**      Data is returned to the application using the NFA_TLV_DETECT_EVT. When
+**      search operation has completed, or if an error occurs, the app will be
+**      notified with NFA_TLV_DETECT_EVT.
+**
+** Description      Perform the TLV detection procedure  using the appropriate
+**                  method for the currently activated tag.
+**
+**                  Upon successful completion of TLV detection in T1/T2 tag, a
+**                  NFA_TLV_DETECT_EVT will be sent, to notify the application
+**                  of the TLV attributes (total lock/reserved bytes etc.).
+**                  However if the TLV type specified is NDEF then it is same as
+**                  calling NFA_RwDetectNDef and should expect to receive
+**                  NFA_NDEF_DETECT_EVT instead of NFA_TLV_DETECT_EVT
+**
+**                  It is not mandatory to call this function -
+**                  NFA_RwDetectNDef, NFA_RwReadNDef and NFA_RwWriteNDef will
+**                  perform TLV detection internally if not performed already.
+**                  An application may call this API to check the a
+**                  tag/card-emulator's total Reserved/
+**                  Lock bytes before issuing a write-request.
+**
+** Returns:
+**                  NFA_STATUS_OK if successfully initiated
+**                  NFC_STATUS_REFUSED if tlv_type is NDEF & tag won't support
+**                  NDEF
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwLocateTlv(uint8_t tlv_type) {
+  tNFA_RW_OPERATION* p_msg;
+
+  NFA_TRACE_API0("NFA_RwLocateTlv");
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+
+    if (tlv_type == TAG_LOCK_CTRL_TLV) {
+      p_msg->op = NFA_RW_OP_DETECT_LOCK_TLV;
+    } else if (tlv_type == TAG_MEM_CTRL_TLV) {
+      p_msg->op = NFA_RW_OP_DETECT_MEM_TLV;
+    } else if (tlv_type == TAG_NDEF_TLV) {
+      p_msg->op = NFA_RW_OP_DETECT_NDEF;
+    } else
+      return (NFA_STATUS_FAILED);
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwT1tRid
+**
+** Description:
+**      Send a RID command to the activated Type 1 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the
+**      read operation has completed, or if an error occurs, the app will be
+**      notified with NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT1tRid(void) {
+  tNFA_RW_OPERATION* p_msg;
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    /* Fill in tNFA_RW_OPERATION struct */
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_T1T_RID;
+
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwT1tReadAll
+**
+** Description:
+**      Send a RALL command to the activated Type 1 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the
+**      read operation has completed, or if an error occurs, the app will be
+**      notified with NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT1tReadAll(void) {
+  tNFA_RW_OPERATION* p_msg;
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    /* Fill in tNFA_RW_OPERATION struct */
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_T1T_RALL;
+
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwT1tRead
+**
+** Description:
+**      Send a READ command to the activated Type 1 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the
+**      read operation has completed, or if an error occurs, the app will be
+**      notified with NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT1tRead(uint8_t block_number, uint8_t index) {
+  tNFA_RW_OPERATION* p_msg;
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    /* Fill in tNFA_RW_OPERATION struct */
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_T1T_READ;
+    p_msg->params.t1t_read.block_number = block_number;
+    p_msg->params.t1t_read.index = index;
+
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwT1tWrite
+**
+** Description:
+**      Send a WRITE command to the activated Type 1 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the
+**      write operation has completed, or if an error occurs, the app will be
+**      notified with NFA_WRITE_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT1tWrite(uint8_t block_number, uint8_t index, uint8_t data,
+                           bool b_erase) {
+  tNFA_RW_OPERATION* p_msg;
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    /* Fill in tNFA_RW_OPERATION struct */
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->params.t1t_write.b_erase = b_erase;
+    p_msg->op = NFA_RW_OP_T1T_WRITE;
+    p_msg->params.t1t_write.block_number = block_number;
+    p_msg->params.t1t_write.index = index;
+    p_msg->params.t1t_write.p_block_data[0] = data;
+
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwT1tReadSeg
+**
+** Description:
+**      Send a RSEG command to the activated Type 1 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the
+**      read operation has completed, or if an error occurs, the app will be
+**      notified with NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT1tReadSeg(uint8_t segment_number) {
+  tNFA_RW_OPERATION* p_msg;
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    /* Fill in tNFA_RW_OPERATION struct */
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_T1T_RSEG;
+    p_msg->params.t1t_read.segment_number = segment_number;
+
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwT1tRead8
+**
+** Description:
+**      Send a READ8 command to the activated Type 1 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the
+**      read operation has completed, or if an error occurs, the app will be
+**      notified with NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT1tRead8(uint8_t block_number) {
+  tNFA_RW_OPERATION* p_msg;
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    /* Fill in tNFA_RW_OPERATION struct */
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_T1T_READ8;
+    p_msg->params.t1t_write.block_number = block_number;
+
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwT1tWrite8
+**
+** Description:
+**      Send a WRITE8_E / WRITE8_NE command to the activated Type 1 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the
+**      read operation has completed, or if an error occurs, the app will be
+**      notified with NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT1tWrite8(uint8_t block_number, uint8_t* p_data,
+                            bool b_erase) {
+  tNFA_RW_OPERATION* p_msg;
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    /* Fill in tNFA_RW_OPERATION struct */
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->params.t1t_write.b_erase = b_erase;
+    p_msg->op = NFA_RW_OP_T1T_WRITE8;
+    p_msg->params.t1t_write.block_number = block_number;
+
+    memcpy(p_msg->params.t1t_write.p_block_data, p_data, 8);
+
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwT2tRead
+**
+** Description:
+**      Send a READ command to the activated Type 2 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the
+**      read operation has completed, or if an error occurs, the app will be
+**      notified with NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT2tRead(uint8_t block_number) {
+  tNFA_RW_OPERATION* p_msg;
+
+  NFA_TRACE_API1("NFA_RwT2tRead (): Block to read: %d", block_number);
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    /* Fill in tNFA_RW_OPERATION struct */
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_T2T_READ;
+    p_msg->params.t2t_read.block_number = block_number;
+
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwT2tWrite
+**
+** Description:
+**      Send an WRITE command to the activated Type 2 tag.
+**
+**      When the write operation has completed (or if an error occurs), the
+**      app will be notified with NFA_WRITE_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT2tWrite(uint8_t block_number, uint8_t* p_data) {
+  tNFA_RW_OPERATION* p_msg;
+
+  NFA_TRACE_API1("NFA_RwT2tWrite (): Block to write: %d", block_number);
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    /* Fill in tNFA_RW_OPERATION struct */
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_T2T_WRITE;
+
+    p_msg->params.t2t_write.block_number = block_number;
+
+    memcpy(p_msg->params.t2t_write.p_block_data, p_data, 4);
+
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwT2tSectorSelect
+**
+** Description:
+**      Send SECTOR SELECT command to the activated Type 2 tag.
+**
+**      When the sector select operation has completed (or if an error occurs),
+**      the app will be notified with NFA_SECTOR_SELECT_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT2tSectorSelect(uint8_t sector_number) {
+  tNFA_RW_OPERATION* p_msg;
+
+  NFA_TRACE_API1("NFA_RwT2tRead (): sector to select: %d", sector_number);
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    /* Fill in tNFA_RW_OPERATION struct */
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_T2T_SECTOR_SELECT;
+
+    p_msg->params.t2t_sector_select.sector_number = sector_number;
+
+    nfa_sys_sendmsg(p_msg);
+    return (NFA_STATUS_OK);
+  }
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwT3tRead
+**
+** Description:
+**      Send a CHECK (read) command to the activated Type 3 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the
+**      read operation has completed, or if an error occurs, the app will be
+**      notified with NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT3tRead(uint8_t num_blocks, tNFA_T3T_BLOCK_DESC* t3t_blocks) {
+  tNFA_RW_OPERATION* p_msg;
+  uint8_t* p_block_desc;
+
+  NFA_TRACE_API1("NFA_RwT3tRead (): num_blocks to read: %i", num_blocks);
+
+  /* Validate parameters */
+  if ((num_blocks == 0) || (t3t_blocks == NULL))
+    return (NFA_STATUS_INVALID_PARAM);
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(
+      sizeof(tNFA_RW_OPERATION) + (num_blocks * sizeof(tNFA_T3T_BLOCK_DESC))));
+  if (p_msg != NULL) {
+    /* point to area after tNFA_RW_OPERATION */
+    p_block_desc = (uint8_t*)(p_msg + 1);
+
+    /* Fill in tNFA_RW_OPERATION struct */
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_T3T_READ;
+
+    p_msg->params.t3t_read.num_blocks = num_blocks;
+    p_msg->params.t3t_read.p_block_desc = (tNFA_T3T_BLOCK_DESC*)p_block_desc;
+
+    /* Copy block descriptor list */
+    memcpy(p_block_desc, t3t_blocks,
+           (num_blocks * sizeof(tNFA_T3T_BLOCK_DESC)));
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwT3tWrite
+**
+** Description:
+**      Send an UPDATE (write) command to the activated Type 3 tag.
+**
+**      When the write operation has completed (or if an error occurs), the
+**      app will be notified with NFA_WRITE_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT3tWrite(uint8_t num_blocks, tNFA_T3T_BLOCK_DESC* t3t_blocks,
+                           uint8_t* p_data) {
+  tNFA_RW_OPERATION* p_msg;
+  uint8_t* p_block_desc, *p_data_area;
+
+  NFA_TRACE_API1("NFA_RwT3tWrite (): num_blocks to write: %i", num_blocks);
+
+  /* Validate parameters */
+  if ((num_blocks == 0) || (t3t_blocks == NULL) | (p_data == NULL))
+    return (NFA_STATUS_INVALID_PARAM);
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf(
+      (uint16_t)(sizeof(tNFA_RW_OPERATION) +
+                 (num_blocks * (sizeof(tNFA_T3T_BLOCK_DESC) + 16))));
+  if (p_msg != NULL) {
+    /* point to block descriptor and data areas after tNFA_RW_OPERATION */
+    p_block_desc = (uint8_t*)(p_msg + 1);
+    p_data_area = p_block_desc + (num_blocks * (sizeof(tNFA_T3T_BLOCK_DESC)));
+
+    /* Fill in tNFA_RW_OPERATION struct */
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_T3T_WRITE;
+
+    p_msg->params.t3t_write.num_blocks = num_blocks;
+    p_msg->params.t3t_write.p_block_desc = (tNFA_T3T_BLOCK_DESC*)p_block_desc;
+    p_msg->params.t3t_write.p_block_data = p_data_area;
+
+    /* Copy block descriptor list */
+    memcpy(p_block_desc, t3t_blocks,
+           (num_blocks * sizeof(tNFA_T3T_BLOCK_DESC)));
+
+    /* Copy data */
+    memcpy(p_data_area, p_data, (num_blocks * 16));
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93Inventory
+**
+** Description:
+**      Send Inventory command to the activated ISO 15693 tag with/without AFI
+**      If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93Inventory(bool afi_present, uint8_t afi, uint8_t* p_uid) {
+  tNFA_RW_OPERATION* p_msg;
+
+  NFA_TRACE_API2("NFA_RwI93Inventory (): afi_present:%d, AFI: 0x%02X",
+                 afi_present, afi);
+
+  if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693) {
+    return (NFA_STATUS_WRONG_PROTOCOL);
+  }
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    /* Fill in tNFA_RW_OPERATION struct */
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_I93_INVENTORY;
+
+    p_msg->params.i93_cmd.afi_present = afi_present;
+    p_msg->params.i93_cmd.afi = afi;
+
+    if (p_uid) {
+      p_msg->params.i93_cmd.uid_present = true;
+      memcpy(p_msg->params.i93_cmd.uid, p_uid, I93_UID_BYTE_LEN);
+    } else {
+      p_msg->params.i93_cmd.uid_present = false;
+    }
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93StayQuiet
+**
+** Description:
+**      Send Stay Quiet command to the activated ISO 15693 tag.
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93StayQuiet(void) {
+  tNFA_RW_OPERATION* p_msg;
+
+  NFA_TRACE_API0("NFA_RwI93StayQuiet ()");
+
+  if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693) {
+    return (NFA_STATUS_WRONG_PROTOCOL);
+  }
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    /* Fill in tNFA_RW_OPERATION struct */
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_I93_STAY_QUIET;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93ReadSingleBlock
+**
+** Description:
+**      Send Read Single Block command to the activated ISO 15693 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the
+**      read operation has completed, or if an error occurs, the app will be
+**      notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93ReadSingleBlock(uint8_t block_number) {
+  tNFA_RW_OPERATION* p_msg;
+
+  NFA_TRACE_API1("NFA_RwI93ReadSingleBlock (): block_number: 0x%02X",
+                 block_number);
+
+  if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693) {
+    return (NFA_STATUS_WRONG_PROTOCOL);
+  }
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    /* Fill in tNFA_RW_OPERATION struct */
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_I93_READ_SINGLE_BLOCK;
+
+    p_msg->params.i93_cmd.first_block_number = block_number;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93WriteSingleBlock
+**
+** Description:
+**      Send Write Single Block command to the activated ISO 15693 tag.
+**
+**      When the write operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93WriteSingleBlock(uint8_t block_number, uint8_t* p_data) {
+  tNFA_RW_OPERATION* p_msg;
+
+  NFA_TRACE_API1("NFA_RwI93WriteSingleBlock (): block_number: 0x%02X",
+                 block_number);
+
+  if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693) {
+    return (NFA_STATUS_WRONG_PROTOCOL);
+  }
+
+  /* we don't know block size of tag */
+  if ((nfa_rw_cb.i93_block_size == 0) || (nfa_rw_cb.i93_num_block == 0)) {
+    return (NFA_STATUS_FAILED);
+  }
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf(
+      (uint16_t)(sizeof(tNFA_RW_OPERATION) + nfa_rw_cb.i93_block_size));
+  if (p_msg != NULL) {
+    /* Fill in tNFA_RW_OPERATION struct */
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_I93_WRITE_SINGLE_BLOCK;
+
+    p_msg->params.i93_cmd.first_block_number = block_number;
+    p_msg->params.i93_cmd.p_data = (uint8_t*)(p_msg + 1);
+
+    memcpy(p_msg->params.i93_cmd.p_data, p_data, nfa_rw_cb.i93_block_size);
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93LockBlock
+**
+** Description:
+**      Send Lock block command to the activated ISO 15693 tag.
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93LockBlock(uint8_t block_number) {
+  tNFA_RW_OPERATION* p_msg;
+
+  NFA_TRACE_API1("NFA_RwI93LockBlock (): block_number: 0x%02X", block_number);
+
+  if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693) {
+    return (NFA_STATUS_WRONG_PROTOCOL);
+  }
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    /* Fill in tNFA_RW_OPERATION struct */
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_I93_LOCK_BLOCK;
+
+    p_msg->params.i93_cmd.first_block_number = block_number;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93ReadMultipleBlocks
+**
+** Description:
+**      Send Read Multiple Block command to the activated ISO 15693 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the
+**      read operation has completed, or if an error occurs, the app will be
+**      notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93ReadMultipleBlocks(uint8_t first_block_number,
+                                        uint16_t number_blocks) {
+  tNFA_RW_OPERATION* p_msg;
+
+  NFA_TRACE_API2("NFA_RwI93ReadMultipleBlocks(): %d, %d", first_block_number,
+                 number_blocks);
+
+  if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693) {
+    return (NFA_STATUS_WRONG_PROTOCOL);
+  }
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    /* Fill in tNFA_RW_OPERATION struct */
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_I93_READ_MULTI_BLOCK;
+
+    p_msg->params.i93_cmd.first_block_number = first_block_number;
+    p_msg->params.i93_cmd.number_blocks = number_blocks;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93WriteMultipleBlocks
+**
+** Description:
+**      Send Write Multiple Block command to the activated ISO 15693 tag.
+**
+**      When the write operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93WriteMultipleBlocks(uint8_t first_block_number,
+                                         uint16_t number_blocks,
+                                         uint8_t* p_data) {
+  tNFA_RW_OPERATION* p_msg;
+  uint16_t data_length;
+
+  NFA_TRACE_API2("NFA_RwI93WriteMultipleBlocks (): %d, %d", first_block_number,
+                 number_blocks);
+
+  if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693) {
+    return (NFA_STATUS_WRONG_PROTOCOL);
+  }
+
+  /* we don't know block size of tag */
+  if ((nfa_rw_cb.i93_block_size == 0) || (nfa_rw_cb.i93_num_block == 0)) {
+    return (NFA_STATUS_FAILED);
+  }
+
+  data_length = nfa_rw_cb.i93_block_size * number_blocks;
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf(
+      (uint16_t)(sizeof(tNFA_RW_OPERATION) + data_length));
+  if (p_msg != NULL) {
+    /* Fill in tNFA_RW_OPERATION struct */
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_I93_WRITE_MULTI_BLOCK;
+
+    p_msg->params.i93_cmd.first_block_number = first_block_number;
+    p_msg->params.i93_cmd.number_blocks = number_blocks;
+    p_msg->params.i93_cmd.p_data = (uint8_t*)(p_msg + 1);
+
+    memcpy(p_msg->params.i93_cmd.p_data, p_data, data_length);
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93Select
+**
+** Description:
+**      Send Select command to the activated ISO 15693 tag.
+**
+**      UID[0]: 0xE0, MSB
+**      UID[1]: IC Mfg Code
+**      ...
+**      UID[7]: LSB
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93Select(uint8_t* p_uid) {
+  tNFA_RW_OPERATION* p_msg;
+
+  NFA_TRACE_API3("NFA_RwI93Select (): UID: [%02X%02X%02X...]", *(p_uid),
+                 *(p_uid + 1), *(p_uid + 2));
+
+  if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693) {
+    return (NFA_STATUS_WRONG_PROTOCOL);
+  }
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf(
+      (uint16_t)(sizeof(tNFA_RW_OPERATION) + I93_UID_BYTE_LEN));
+  if (p_msg != NULL) {
+    /* Fill in tNFA_RW_OPERATION struct */
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_I93_SELECT;
+
+    p_msg->params.i93_cmd.p_data = (uint8_t*)(p_msg + 1);
+    memcpy(p_msg->params.i93_cmd.p_data, p_uid, I93_UID_BYTE_LEN);
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93ResetToReady
+**
+** Description:
+**      Send Reset to ready command to the activated ISO 15693 tag.
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93ResetToReady(void) {
+  tNFA_RW_OPERATION* p_msg;
+
+  NFA_TRACE_API0("NFA_RwI93ResetToReady ()");
+
+  if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693) {
+    return (NFA_STATUS_WRONG_PROTOCOL);
+  }
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    /* Fill in tNFA_RW_OPERATION struct */
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_I93_RESET_TO_READY;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93WriteAFI
+**
+** Description:
+**      Send Write AFI command to the activated ISO 15693 tag.
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93WriteAFI(uint8_t afi) {
+  tNFA_RW_OPERATION* p_msg;
+
+  NFA_TRACE_API1("NFA_RwI93WriteAFI (): AFI: 0x%02X", afi);
+
+  if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693) {
+    return (NFA_STATUS_WRONG_PROTOCOL);
+  }
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    /* Fill in tNFA_RW_OPERATION struct */
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_I93_WRITE_AFI;
+
+    p_msg->params.i93_cmd.afi = afi;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93LockAFI
+**
+** Description:
+**      Send Lock AFI command to the activated ISO 15693 tag.
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93LockAFI(void) {
+  tNFA_RW_OPERATION* p_msg;
+
+  NFA_TRACE_API0("NFA_RwI93LockAFI ()");
+
+  if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693) {
+    return (NFA_STATUS_WRONG_PROTOCOL);
+  }
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    /* Fill in tNFA_RW_OPERATION struct */
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_I93_LOCK_AFI;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93WriteDSFID
+**
+** Description:
+**      Send Write DSFID command to the activated ISO 15693 tag.
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93WriteDSFID(uint8_t dsfid) {
+  tNFA_RW_OPERATION* p_msg;
+
+  NFA_TRACE_API1("NFA_RwI93WriteDSFID (): DSFID: 0x%02X", dsfid);
+
+  if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693) {
+    return (NFA_STATUS_WRONG_PROTOCOL);
+  }
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    /* Fill in tNFA_RW_OPERATION struct */
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_I93_WRITE_DSFID;
+
+    p_msg->params.i93_cmd.dsfid = dsfid;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93LockDSFID
+**
+** Description:
+**      Send Lock DSFID command to the activated ISO 15693 tag.
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93LockDSFID(void) {
+  tNFA_RW_OPERATION* p_msg;
+
+  NFA_TRACE_API0("NFA_RwI93LockDSFID ()");
+
+  if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693) {
+    return (NFA_STATUS_WRONG_PROTOCOL);
+  }
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    /* Fill in tNFA_RW_OPERATION struct */
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_I93_LOCK_DSFID;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93GetSysInfo
+**
+** Description:
+**      Send Get system information command to the activated ISO 15693 tag.
+**      If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93GetSysInfo(uint8_t* p_uid) {
+  tNFA_RW_OPERATION* p_msg;
+
+  NFA_TRACE_API0("NFA_RwI93GetSysInfo ()");
+
+  if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693) {
+    return (NFA_STATUS_WRONG_PROTOCOL);
+  }
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    /* Fill in tNFA_RW_OPERATION struct */
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_I93_GET_SYS_INFO;
+
+    if (p_uid) {
+      p_msg->params.i93_cmd.uid_present = true;
+      memcpy(p_msg->params.i93_cmd.uid, p_uid, I93_UID_BYTE_LEN);
+    } else {
+      p_msg->params.i93_cmd.uid_present = false;
+    }
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93GetMultiBlockSecurityStatus
+**
+** Description:
+**      Send Get Multiple block security status command to the activated ISO
+**      15693 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the
+**      read operation has completed, or if an error occurs, the app will be
+**      notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93GetMultiBlockSecurityStatus(uint8_t first_block_number,
+                                                 uint16_t number_blocks) {
+  tNFA_RW_OPERATION* p_msg;
+
+  NFA_TRACE_API2("NFA_RwI93GetMultiBlockSecurityStatus(): %d, %d",
+                 first_block_number, number_blocks);
+
+  if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693) {
+    return (NFA_STATUS_WRONG_PROTOCOL);
+  }
+
+  p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
+  if (p_msg != NULL) {
+    /* Fill in tNFA_RW_OPERATION struct */
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op = NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS;
+
+    p_msg->params.i93_cmd.first_block_number = first_block_number;
+    p_msg->params.i93_cmd.number_blocks = number_blocks;
+
+    nfa_sys_sendmsg(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+
+  return (NFA_STATUS_FAILED);
+}
diff --git a/src/nfa/rw/nfa_rw_main.c b/src/nfa/rw/nfa_rw_main.c
new file mode 100644
index 0000000..3c409bf
--- /dev/null
+++ b/src/nfa/rw/nfa_rw_main.c
@@ -0,0 +1,224 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2003-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the main implementation file for the NFA_RW
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_rw_api.h"
+#include "nfa_sys.h"
+#include "nfa_rw_int.h"
+#include "nfa_dm_int.h"
+#include "nfa_sys_int.h"
+
+/* NFA_RW control block */
+tNFA_RW_CB nfa_rw_cb;
+
+/*****************************************************************************
+** Constants and types
+*****************************************************************************/
+static const tNFA_SYS_REG nfa_rw_sys_reg = {NULL, nfa_rw_handle_event,
+                                            nfa_rw_sys_disable, NULL};
+
+/* NFA_RW actions */
+const tNFA_RW_ACTION nfa_rw_action_tbl[] = {
+    nfa_rw_handle_op_req,         /* NFA_RW_OP_REQUEST_EVT            */
+    nfa_rw_activate_ntf,          /* NFA_RW_ACTIVATE_NTF_EVT          */
+    nfa_rw_deactivate_ntf,        /* NFA_RW_DEACTIVATE_NTF_EVT        */
+    nfa_rw_presence_check_tick,   /* NFA_RW_PRESENCE_CHECK_TICK_EVT   */
+    nfa_rw_presence_check_timeout /* NFA_RW_PRESENCE_CHECK_TIMEOUT_EVT*/
+};
+
+/*****************************************************************************
+** Local function prototypes
+*****************************************************************************/
+#if (BT_TRACE_VERBOSE == true)
+static char* nfa_rw_evt_2_str(uint16_t event);
+#endif
+
+/*******************************************************************************
+**
+** Function         nfa_rw_init
+**
+** Description      Initialize NFA RW
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_rw_init(void) {
+  NFA_TRACE_DEBUG0("nfa_rw_init ()");
+
+  /* initialize control block */
+  memset(&nfa_rw_cb, 0, sizeof(tNFA_RW_CB));
+
+  /* register message handler on NFA SYS */
+  nfa_sys_register(NFA_ID_RW, &nfa_rw_sys_reg);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_sys_disable
+**
+** Description      Clean up rw sub-system
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_rw_sys_disable(void) {
+  /* Return to idle */
+  NFC_SetStaticRfCback(NULL);
+
+  /* Stop presence check timer (if started) */
+  nfa_rw_stop_presence_check_timer();
+
+  /* Free scratch buffer if any */
+  nfa_rw_free_ndef_rx_buf();
+
+  /* Free pending command if any */
+  if (nfa_rw_cb.p_pending_msg) {
+    GKI_freebuf(nfa_rw_cb.p_pending_msg);
+    nfa_rw_cb.p_pending_msg = NULL;
+  }
+
+  nfa_sys_deregister(NFA_ID_RW);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_proc_disc_evt
+**
+** Description      Called by nfa_dm to handle ACTIVATED/DEACTIVATED  events
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_rw_proc_disc_evt(tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER* p_data,
+                          bool excl_rf_not_active) {
+  tNFA_RW_MSG msg;
+
+  switch (event) {
+    case NFA_DM_RF_DISC_ACTIVATED_EVT:
+      msg.hdr.event = NFA_RW_ACTIVATE_NTF_EVT;
+      msg.activate_ntf.p_activate_params = &p_data->activate;
+      msg.activate_ntf.excl_rf_not_active = excl_rf_not_active;
+
+      nfa_rw_handle_event((void*)&msg);
+      break;
+
+    case NFA_DM_RF_DISC_DEACTIVATED_EVT:
+      msg.hdr.event = NFA_RW_DEACTIVATE_NTF_EVT;
+
+      nfa_rw_handle_event((void*)&msg);
+      break;
+
+    default:
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_send_raw_frame
+**
+** Description      Called by nfa_dm to send raw frame
+**
+** Returns          tNFA_STATUS
+**
+*******************************************************************************/
+tNFA_STATUS nfa_rw_send_raw_frame(NFC_HDR* p_data) {
+  tNFA_RW_MSG* p_msg;
+
+  p_msg = (tNFA_RW_MSG*)GKI_getbuf((uint16_t)sizeof(tNFA_RW_MSG));
+  if (p_msg != NULL) {
+    p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+    p_msg->op_req.op = NFA_RW_OP_SEND_RAW_FRAME;
+
+    p_msg->op_req.params.send_raw_frame.p_data = p_data;
+
+    if (nfa_rw_handle_event((NFC_HDR*)p_msg)) GKI_freebuf(p_msg);
+
+    return (NFA_STATUS_OK);
+  }
+  return NFA_STATUS_FAILED;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_handle_event
+**
+** Description      nfa rw main event handling function.
+**
+** Returns          true if caller should free p_msg buffer
+**
+*******************************************************************************/
+bool nfa_rw_handle_event(NFC_HDR* p_msg) {
+  uint16_t act_idx;
+
+#if (BT_TRACE_VERBOSE == true)
+  NFA_TRACE_EVENT3("nfa_rw_handle_event event: %s (0x%02x), flags: %08x",
+                   nfa_rw_evt_2_str(p_msg->event), p_msg->event,
+                   nfa_rw_cb.flags);
+#else
+  NFA_TRACE_EVENT2("nfa_rw_handle_event event: 0x%x, flags: %08x", p_msg->event,
+                   nfa_rw_cb.flags);
+#endif
+
+  /* Get NFA_RW sub-event */
+  act_idx = (p_msg->event & 0x00FF);
+  if (act_idx < (NFA_RW_MAX_EVT & 0xFF)) {
+    return (*nfa_rw_action_tbl[act_idx])((tNFA_RW_MSG*)p_msg);
+  } else {
+    NFA_TRACE_ERROR1("nfa_rw_handle_event: unhandled event 0x%02X",
+                     p_msg->event);
+    return true;
+  }
+}
+
+#if (BT_TRACE_VERBOSE == true)
+/*******************************************************************************
+**
+** Function         nfa_rw_evt_2_str
+**
+** Description      convert nfa_rw evt to string
+**
+*******************************************************************************/
+static char* nfa_rw_evt_2_str(uint16_t event) {
+  switch (event) {
+    case NFA_RW_OP_REQUEST_EVT:
+      return "NFA_RW_OP_REQUEST_EVT";
+
+    case NFA_RW_ACTIVATE_NTF_EVT:
+      return "NFA_RW_ACTIVATE_NTF_EVT";
+
+    case NFA_RW_DEACTIVATE_NTF_EVT:
+      return "NFA_RW_DEACTIVATE_NTF_EVT";
+
+    case NFA_RW_PRESENCE_CHECK_TICK_EVT:
+      return "NFA_RW_PRESENCE_CHECK_TICK_EVT";
+
+    case NFA_RW_PRESENCE_CHECK_TIMEOUT_EVT:
+      return "NFA_RW_PRESENCE_CHECK_TIMEOUT_EVT";
+
+    default:
+      return "Unknown";
+  }
+}
+#endif /* BT_TRACE_VERBOSE */
diff --git a/src/nfa/sys/nfa_sys_cback.c b/src/nfa/sys/nfa_sys_cback.c
new file mode 100644
index 0000000..44de648
--- /dev/null
+++ b/src/nfa/sys/nfa_sys_cback.c
@@ -0,0 +1,126 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Registration/deregistration functions for inter-module callbacks
+ *
+ ******************************************************************************/
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+
+/*******************************************************************************
+**
+** Function         nfa_sys_cback_reg_enable_complete
+**
+** Description      Called to register an initialization complete callback
+**                  function
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_cback_reg_enable_complete(tNFA_SYS_ENABLE_CBACK* p_cback) {
+  nfa_sys_cb.p_enable_cback = p_cback;
+  nfa_sys_cb.enable_cplt_flags = 0;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_cback_notify_enable_complete
+**
+** Description      Called by other NFA subsystems to notify initialization is
+**                  complete
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_cback_notify_enable_complete(uint8_t id) {
+  nfa_sys_cb.enable_cplt_flags |= (0x0001 << id);
+
+  NFA_TRACE_DEBUG2(
+      "nfa_sys_cback_notify_enable_complete () enable_cplt_flags=0x%x, "
+      "enable_cplt_mask=0x%x",
+      nfa_sys_cb.enable_cplt_flags, nfa_sys_cb.enable_cplt_mask);
+
+  if ((nfa_sys_cb.enable_cplt_flags == nfa_sys_cb.enable_cplt_mask) &&
+      (nfa_sys_cb.p_enable_cback)) {
+    nfa_sys_cb.p_enable_cback();
+    nfa_sys_cb.p_enable_cback = NULL;
+  }
+}
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         nfa_sys_cback_notify_MinEnable_complete
+**
+** Description      Called by other NFA SYS sub system to notify
+**                  NFC initialisation  is done .
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_cback_notify_MinEnable_complete(uint8_t id) {
+  if (nfa_sys_cb.p_enable_cback && id == NFA_ID_SYS) {
+    nfa_sys_cb.p_enable_cback();
+    nfa_sys_cb.p_enable_cback = NULL;
+  }
+}
+#endif
+/*******************************************************************************
+**
+** Function         nfa_sys_cback_reg_nfcc_power_mode_proc_complete
+**
+** Description      Called to register a callback function for complete of
+**                  processing NFCC power mode change from NFA sub-systems
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_cback_reg_nfcc_power_mode_proc_complete(
+    tNFA_SYS_PROC_NFCC_PWR_MODE_CMPL* p_cback) {
+  nfa_sys_cb.p_proc_nfcc_pwr_mode_cmpl_cback = p_cback;
+  nfa_sys_cb.proc_nfcc_pwr_mode_cplt_flags = 0;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_cback_notify_nfcc_power_mode_proc_complete
+**
+** Description      Called by other NFA subsystems to notify processing NFCC
+**                  power mode is complete
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_cback_notify_nfcc_power_mode_proc_complete(uint8_t id) {
+  nfa_sys_cb.proc_nfcc_pwr_mode_cplt_flags |= (0x0001 << id);
+
+  NFA_TRACE_DEBUG2(
+      "nfa_sys_cback_notify_nfcc_power_mode_proc_complete () flags=0x%x, "
+      "mask=0x%x",
+      nfa_sys_cb.proc_nfcc_pwr_mode_cplt_flags,
+      nfa_sys_cb.proc_nfcc_pwr_mode_cplt_mask);
+
+  /* except SYS */
+  if ((nfa_sys_cb.proc_nfcc_pwr_mode_cplt_flags ==
+       nfa_sys_cb.proc_nfcc_pwr_mode_cplt_mask) &&
+      (nfa_sys_cb.p_proc_nfcc_pwr_mode_cmpl_cback)) {
+    nfa_sys_cb.p_proc_nfcc_pwr_mode_cmpl_cback();
+    nfa_sys_cb.p_proc_nfcc_pwr_mode_cmpl_cback = NULL;
+  }
+}
diff --git a/src/nfa/sys/nfa_sys_cfg.c b/src/nfa/sys/nfa_sys_cfg.c
new file mode 100644
index 0000000..aaaf15e
--- /dev/null
+++ b/src/nfa/sys/nfa_sys_cfg.c
@@ -0,0 +1,37 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains compile-time configurable constants for the NFA
+ *  system manager.
+ *
+ ******************************************************************************/
+
+#include "nfc_target.h"
+#include "gki.h"
+#include "nfa_sys.h"
+
+const tNFA_SYS_CFG nfa_sys_cfg = {
+    NFA_MBOX_EVT_MASK,       /* GKI mailbox event */
+    NFA_MBOX_ID,             /* GKI mailbox id */
+    NFA_TIMER_ID,            /* GKI timer id */
+    APPL_INITIAL_TRACE_LEVEL /* initial trace level */
+};
+
+tNFA_SYS_CFG* p_nfa_sys_cfg = (tNFA_SYS_CFG*)&nfa_sys_cfg;
diff --git a/src/nfa/sys/nfa_sys_main.c b/src/nfa/sys/nfa_sys_main.c
new file mode 100644
index 0000000..28e2c22
--- /dev/null
+++ b/src/nfa/sys/nfa_sys_main.c
@@ -0,0 +1,372 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the main implementation file for the NFA system manager.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_api.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "nfa_sys_ptim.h"
+#include "nfa_dm_int.h"
+
+/* protocol timer update period, in milliseconds */
+#ifndef NFA_SYS_TIMER_PERIOD
+#define NFA_SYS_TIMER_PERIOD 10
+#endif
+
+/* system manager control block definition */
+tNFA_SYS_CB nfa_sys_cb = {.flags = 0}; /* nfa_sys control block. statically
+                                          initialize 'flags' field to 0 */
+
+/*******************************************************************************
+**
+** Function         nfa_sys_init
+**
+** Description      NFA initialization; called from task initialization.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_init(void) {
+  memset(&nfa_sys_cb, 0, sizeof(tNFA_SYS_CB));
+  nfa_sys_cb.flags |= NFA_SYS_FL_INITIALIZED;
+  nfa_sys_ptim_init(&nfa_sys_cb.ptim_cb, NFA_SYS_TIMER_PERIOD,
+                    p_nfa_sys_cfg->timer);
+  nfa_sys_cb.trace_level = p_nfa_sys_cfg->trace_level;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_event
+**
+** Description      BTA event handler; called from task event handler.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_event(NFC_HDR* p_msg) {
+  uint8_t id;
+  bool freebuf = true;
+
+  NFA_TRACE_EVENT1("NFA got event 0x%04X", p_msg->event);
+
+  /* get subsystem id from event */
+  id = (uint8_t)(p_msg->event >> 8);
+
+  /* verify id and call subsystem event handler */
+  if ((id < NFA_ID_MAX) && (nfa_sys_cb.is_reg[id])) {
+    freebuf = (*nfa_sys_cb.reg[id]->evt_hdlr)(p_msg);
+  } else {
+    NFA_TRACE_WARNING1("NFA got unregistered event id %d", id);
+  }
+
+  if (freebuf) {
+    GKI_freebuf(p_msg);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_timer_update
+**
+** Description      Update the BTA timer list and handle expired timers.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_timer_update(void) {
+  if (!nfa_sys_cb.timers_disabled) {
+    nfa_sys_ptim_timer_update(&nfa_sys_cb.ptim_cb);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_register
+**
+** Description      Called by other BTA subsystems to register their event
+**                  handler.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_register(uint8_t id, const tNFA_SYS_REG* p_reg) {
+  nfa_sys_cb.reg[id] = (tNFA_SYS_REG*)p_reg;
+  nfa_sys_cb.is_reg[id] = true;
+
+  if ((id != NFA_ID_DM) && (id != NFA_ID_SYS))
+    nfa_sys_cb.enable_cplt_mask |= (0x0001 << id);
+
+  if (id != NFA_ID_SYS) {
+    if (p_reg->proc_nfcc_pwr_mode)
+      nfa_sys_cb.proc_nfcc_pwr_mode_cplt_mask |= (0x0001 << id);
+  }
+
+  NFA_TRACE_DEBUG2("nfa_sys_register () id=%i, enable_cplt_mask=0x%x", id,
+                   nfa_sys_cb.enable_cplt_mask);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_check_disabled
+**
+** Description      If all subsystems above DM have been disabled, then
+**                  disable DM. Called during NFA shutdown
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_check_disabled(void) {
+  uint8_t id;
+  uint8_t done = true;
+
+  /* Check if all subsystems above DM have been disabled. */
+  for (id = (NFA_ID_DM + 1); id < NFA_ID_MAX; id++) {
+    if (nfa_sys_cb.is_reg[id]) {
+      /* as long as one subsystem is not done */
+      done = false;
+      break;
+    }
+  }
+
+  /* All subsystems disabled. disable DM */
+  if ((done) && (nfa_sys_cb.is_reg[NFA_ID_DM])) {
+    (*nfa_sys_cb.reg[NFA_ID_DM]->disable)();
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_deregister
+**
+** Description      Called by other BTA subsystems to de-register
+**                  handler.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_deregister(uint8_t id) {
+  NFA_TRACE_DEBUG1("nfa_sys: deregistering subsystem %i", id);
+
+  nfa_sys_cb.is_reg[id] = false;
+
+  /* If not deregistering DM, then check if any other subsystems above DM are
+   * still  */
+  /* registered. */
+  if (id != NFA_ID_DM) {
+    /* If all subsystems above NFA_DM have been disabled, then okay to disable
+     * DM */
+    nfa_sys_check_disabled();
+  } else {
+    /* DM (the final sub-system) is deregistering. Clear pending timer events in
+     * nfa_sys. */
+    nfa_sys_ptim_init(&nfa_sys_cb.ptim_cb, NFA_SYS_TIMER_PERIOD,
+                      p_nfa_sys_cfg->timer);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_is_register
+**
+** Description      Called by other BTA subsystems to get registeration
+**                  status.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+bool nfa_sys_is_register(uint8_t id) { return nfa_sys_cb.is_reg[id]; }
+
+/*******************************************************************************
+**
+** Function         nfa_sys_is_graceful_disable
+**
+** Description      Called by other BTA subsystems to get disable
+**                  parameter.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+bool nfa_sys_is_graceful_disable(void) { return nfa_sys_cb.graceful_disable; }
+
+/*******************************************************************************
+**
+** Function         nfa_sys_enable_subsystems
+**
+** Description      Call on NFA Start up
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_enable_subsystems(void) {
+  uint8_t id;
+
+  NFA_TRACE_DEBUG0("nfa_sys: enabling subsystems");
+
+  /* Enable all subsystems except SYS */
+  for (id = NFA_ID_DM; id < NFA_ID_MAX; id++) {
+    if (nfa_sys_cb.is_reg[id]) {
+      if (nfa_sys_cb.reg[id]->enable != NULL) {
+        /* Subsytem has a Disable funciton. Call it now */
+        (*nfa_sys_cb.reg[id]->enable)();
+      } else {
+        /* Subsytem does not have a Enable function. Report Enable on behalf of
+         * subsystem */
+        nfa_sys_cback_notify_enable_complete(id);
+      }
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_disable_subsystems
+**
+** Description      Call on NFA shutdown. Disable all subsystems above NFA_DM
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_disable_subsystems(bool graceful) {
+  uint8_t id;
+  bool done = true;
+
+  NFA_TRACE_DEBUG1("nfa_sys: disabling subsystems:%d", graceful);
+  nfa_sys_cb.graceful_disable = graceful;
+
+  /* Disable all subsystems above NFA_DM. (NFA_DM and NFA_SYS will be disabled
+   * last) */
+  for (id = (NFA_ID_DM + 1); id < NFA_ID_MAX; id++) {
+    if (nfa_sys_cb.is_reg[id]) {
+      done = false;
+      if (nfa_sys_cb.reg[id]->disable != NULL) {
+        /* Subsytem has a Disable funciton. Call it now */
+        (*nfa_sys_cb.reg[id]->disable)();
+      } else {
+        /* Subsytem does not have a Disable function. Deregister on behalf of
+         * subsystem */
+        nfa_sys_deregister(id);
+      }
+    }
+  }
+
+  /* If All subsystems disabled. disable DM */
+  if ((done) && (nfa_sys_cb.is_reg[NFA_ID_DM])) {
+    (*nfa_sys_cb.reg[NFA_ID_DM]->disable)();
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_notify_nfcc_power_mode
+**
+** Description      Call to notify NFCC power mode to NFA sub-modules
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_notify_nfcc_power_mode(uint8_t nfcc_power_mode) {
+  uint8_t id;
+
+  NFA_TRACE_DEBUG1("nfa_sys: notify NFCC power mode(%d) to subsystems",
+                   nfcc_power_mode);
+
+  /* Notify NFCC power state to all subsystems except NFA_SYS */
+  for (id = NFA_ID_DM; id < NFA_ID_MAX; id++) {
+    if ((nfa_sys_cb.is_reg[id]) && (nfa_sys_cb.reg[id]->proc_nfcc_pwr_mode)) {
+      /* Subsytem has a funciton for processing NFCC power mode. Call it now */
+      (*nfa_sys_cb.reg[id]->proc_nfcc_pwr_mode)(nfcc_power_mode);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_sendmsg
+**
+** Description      Send a GKI message to BTA.  This function is designed to
+**                  optimize sending of messages to BTA.  It is called by BTA
+**                  API functions and call-in functions.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_sendmsg(void* p_msg) {
+  GKI_send_msg(NFC_TASK, p_nfa_sys_cfg->mbox, p_msg);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_start_timer
+**
+** Description      Start a protocol timer for the specified amount
+**                  of time in milliseconds.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_start_timer(TIMER_LIST_ENT* p_tle, uint16_t type,
+                         int32_t timeout) {
+  nfa_sys_ptim_start_timer(&nfa_sys_cb.ptim_cb, p_tle, type, timeout);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_stop_timer
+**
+** Description      Stop a BTA timer.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_stop_timer(TIMER_LIST_ENT* p_tle) {
+  nfa_sys_ptim_stop_timer(&nfa_sys_cb.ptim_cb, p_tle);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_disable_timers
+**
+** Description      Disable sys timer event handling
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_disable_timers(void) { nfa_sys_cb.timers_disabled = true; }
+
+/*******************************************************************************
+**
+** Function         nfa_sys_set_trace_level
+**
+** Description      Set trace level for BTA
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_set_trace_level(uint8_t level) { nfa_sys_cb.trace_level = level; }
diff --git a/src/nfa/sys/nfa_sys_ptim.c b/src/nfa/sys/nfa_sys_ptim.c
new file mode 100644
index 0000000..cd9341c
--- /dev/null
+++ b/src/nfa/sys/nfa_sys_ptim.c
@@ -0,0 +1,160 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Protocol timer services (taken from bta ptim)
+ *
+ ******************************************************************************/
+
+#include "nfc_target.h"
+#include "gki.h"
+#include "nfa_sys_ptim.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+
+/*******************************************************************************
+**
+** Function         nfa_sys_ptim_init
+**
+** Description      Initialize a protocol timer control block.  Parameter
+**                  period is the GKI timer period in milliseconds.  Parameter
+**                  timer_id is the GKI timer id.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_ptim_init(tPTIM_CB* p_cb, uint16_t period, uint8_t timer_id) {
+  GKI_init_timer_list(&p_cb->timer_queue);
+  p_cb->period = period;
+  p_cb->timer_id = timer_id;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_ptim_timer_update
+**
+** Description      Update the protocol timer list and handle expired timers.
+**                  This function is called from the task running the protocol
+**                  timers when the periodic GKI timer expires.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_ptim_timer_update(tPTIM_CB* p_cb) {
+  TIMER_LIST_ENT* p_tle;
+  NFC_HDR* p_msg;
+  uint32_t new_ticks_count;
+  int32_t period_in_ticks;
+
+  /* To handle the case when the function is called less frequently than the
+     period
+     we must convert determine the number of ticks since the last update, then
+     convert back to milliseconds before updating timer list */
+  new_ticks_count = GKI_get_tick_count();
+
+  /* Check for wrapped condition */
+  if (new_ticks_count >= p_cb->last_gki_ticks) {
+    period_in_ticks = (int32_t)(new_ticks_count - p_cb->last_gki_ticks);
+  } else {
+    period_in_ticks = (int32_t)(((uint32_t)0xffffffff - p_cb->last_gki_ticks) +
+                                new_ticks_count + 1);
+  }
+
+  /* update timer list */
+  GKI_update_timer_list(&p_cb->timer_queue, GKI_TICKS_TO_MS(period_in_ticks));
+
+  p_cb->last_gki_ticks = new_ticks_count;
+
+  /* while there are expired timers */
+  while ((p_cb->timer_queue.p_first) &&
+         (p_cb->timer_queue.p_first->ticks <= 0)) {
+    /* removed expired timer from list */
+    p_tle = p_cb->timer_queue.p_first;
+    NFA_TRACE_DEBUG1("nfa_sys_ptim_timer_update expired: %08x", p_tle);
+    GKI_remove_from_timer_list(&p_cb->timer_queue, p_tle);
+
+    /* call timer callback */
+    if (p_tle->p_cback) {
+      (*p_tle->p_cback)(p_tle);
+    } else if (p_tle->event) {
+      p_msg = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR));
+      if (p_msg != NULL) {
+        p_msg->event = p_tle->event;
+        p_msg->layer_specific = 0;
+        nfa_sys_sendmsg(p_msg);
+      }
+    }
+  }
+
+  /* if timer list is empty stop periodic GKI timer */
+  if (p_cb->timer_queue.p_first == NULL) {
+    NFA_TRACE_DEBUG0("ptim timer stop");
+    GKI_stop_timer(p_cb->timer_id);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_ptim_start_timer
+**
+** Description      Start a protocol timer for the specified amount
+**                  of time in seconds.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_ptim_start_timer(tPTIM_CB* p_cb, TIMER_LIST_ENT* p_tle,
+                              uint16_t type, int32_t timeout) {
+  NFA_TRACE_DEBUG1("nfa_sys_ptim_start_timer %08x", p_tle);
+
+  /* if timer list is currently empty, start periodic GKI timer */
+  if (p_cb->timer_queue.p_first == NULL) {
+    NFA_TRACE_DEBUG0("ptim timer start");
+    p_cb->last_gki_ticks = GKI_get_tick_count();
+    GKI_start_timer(p_cb->timer_id, GKI_MS_TO_TICKS(p_cb->period), true);
+  }
+
+  GKI_remove_from_timer_list(&p_cb->timer_queue, p_tle);
+
+  p_tle->event = type;
+  p_tle->ticks = timeout;
+
+  GKI_add_to_timer_list(&p_cb->timer_queue, p_tle);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_ptim_stop_timer
+**
+** Description      Stop a protocol timer.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_ptim_stop_timer(tPTIM_CB* p_cb, TIMER_LIST_ENT* p_tle) {
+  NFA_TRACE_DEBUG1("nfa_sys_ptim_stop_timer %08x", p_tle);
+
+  GKI_remove_from_timer_list(&p_cb->timer_queue, p_tle);
+
+  /* if timer list is empty stop periodic GKI timer */
+  if (p_cb->timer_queue.p_first == NULL) {
+    NFA_TRACE_DEBUG0("ptim timer stop");
+    GKI_stop_timer(p_cb->timer_id);
+  }
+}
diff --git a/src/nfc/include/ce_api.h b/src/nfc/include/ce_api.h
new file mode 100644
index 0000000..be3fcbc
--- /dev/null
+++ b/src/nfc/include/ce_api.h
@@ -0,0 +1,259 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the Near Field Communication (NFC) Card Emulation
+ *  mode related API function external definitions.
+ *
+ ******************************************************************************/
+
+#ifndef CE_API_H
+#define CE_API_H
+
+#include "nfc_api.h"
+#include "nfc_types.h"
+#include <stdbool.h>
+#include "tags_defs.h"
+
+#define CE_T3T_FIRST_EVT 0x60
+#define CE_T4T_FIRST_EVT 0x80
+
+enum {
+  CE_T3T_NDEF_UPDATE_START_EVT = CE_T3T_FIRST_EVT,
+  CE_T3T_NDEF_UPDATE_CPLT_EVT,
+  CE_T3T_UPDATE_EVT,
+  CE_T3T_CHECK_EVT,
+  CE_T3T_RAW_FRAME_EVT,
+  CE_T3T_MAX_EVT,
+
+  CE_T4T_NDEF_UPDATE_START_EVT = CE_T4T_FIRST_EVT,
+  CE_T4T_NDEF_UPDATE_CPLT_EVT,
+  CE_T4T_NDEF_UPDATE_ABORT_EVT,
+  CE_T4T_RAW_FRAME_EVT,
+  CE_T4T_MAX_EVT
+};
+
+#define CE_RAW_FRAME_EVT 0xFF
+
+typedef uint8_t tCE_EVENT;
+
+typedef struct {
+  tNFC_STATUS status;
+  NFC_HDR* p_data;
+} tCE_T2T_DATA;
+
+typedef struct {
+  tNFC_STATUS status;
+  uint8_t* p_data;
+  bool b_updated;
+  uint32_t length;
+} tCE_UPDATE_INFO;
+
+typedef struct {
+  tNFC_STATUS status;
+  uint8_t aid_handle;
+  NFC_HDR* p_data;
+} tCE_RAW_FRAME;
+
+typedef union {
+  tNFC_STATUS status;
+  tCE_UPDATE_INFO update_info;
+  tCE_RAW_FRAME raw_frame;
+} tCE_DATA;
+
+typedef void(tCE_CBACK)(tCE_EVENT event, tCE_DATA* p_data);
+
+/* T4T definitions */
+typedef uint8_t tCE_T4T_AID_HANDLE; /* Handle for AID registration  */
+/* Invalid tCE_T4T_AID_HANDLE               */
+#define CE_T4T_AID_HANDLE_INVALID 0xFF
+/* reserved handle for wildcard aid */
+#define CE_T4T_WILDCARD_AID_HANDLE (CE_T4T_MAX_REG_AID)
+
+/*******************************************************************************
+**
+** Function         CE_T3tSetLocalNDEFMsg
+**
+** Description      Initialise CE Type 3 Tag with mandatory NDEF message
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+extern tNFC_STATUS CE_T3tSetLocalNDEFMsg(bool read_only, uint32_t size_max,
+                                         uint32_t size_current, uint8_t* p_buf,
+                                         uint8_t* p_scratch_buf);
+
+/*******************************************************************************
+**
+** Function         CE_T3tSetLocalNDefParams
+**
+** Description      Sets T3T-specific NDEF parameters. (Optional - if not
+**                  called, then CE will use default parameters)
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+extern tNFC_STATUS CE_T3tSetLocalNDefParams(uint8_t nbr, uint8_t nbw);
+
+/*******************************************************************************
+**
+** Function         CE_T3tSendCheckRsp
+**
+** Description      Send CHECK response message
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+extern tNFC_STATUS CE_T3tSendCheckRsp(uint8_t status1, uint8_t status2,
+                                      uint8_t num_blocks,
+                                      uint8_t* p_block_data);
+
+/*******************************************************************************
+**
+** Function         CE_T3tSendUpdateRsp
+**
+** Description      Send UPDATE response message
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+extern tNFC_STATUS CE_T3tSendUpdateRsp(uint8_t status1, uint8_t status2);
+
+/*******************************************************************************
+**
+** Function         CE_T4tSetLocalNDEFMsg
+**
+** Description      Initialise CE Type 4 Tag with mandatory NDEF message
+**
+**                  The following event may be returned
+**                      CE_T4T_UPDATE_START_EVT for starting update
+**                      CE_T4T_UPDATE_CPLT_EVT for complete update
+**                      CE_T4T_UPDATE_ABORT_EVT for failure of update
+**                      CE_T4T_RAW_FRAME_EVT for raw frame
+**
+**                  read_only:      true if read only
+**                  ndef_msg_max:   Max NDEF message size
+**                  ndef_msg_len:   NDEF message size
+**                  p_ndef_msg:     NDEF message (excluding NLEN)
+**                  p_scratch_buf:  temp storage for update
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+extern tNFC_STATUS CE_T4tSetLocalNDEFMsg(bool read_only, uint16_t ndef_msg_max,
+                                         uint16_t ndef_msg_len,
+                                         uint8_t* p_ndef_msg,
+                                         uint8_t* p_scratch_buf);
+
+/*******************************************************************************
+**
+** Function         CE_T4tRegisterAID
+**
+** Description      Register AID in CE T4T
+**
+**                  aid_len: length of AID (up to NFC_MAX_AID_LEN)
+**                  p_aid:   AID
+**                  p_cback: Raw frame will be forwarded with CE_RAW_FRAME_EVT
+**
+** Returns          tCE_T4T_AID_HANDLE if successful,
+**                  CE_T4T_AID_HANDLE_INVALID otherwisse
+**
+*******************************************************************************/
+extern tCE_T4T_AID_HANDLE CE_T4tRegisterAID(uint8_t aid_len, uint8_t* p_aid,
+                                            tCE_CBACK* p_cback);
+
+/*******************************************************************************
+**
+** Function         CE_T4tDeregisterAID
+**
+** Description      Deregister AID in CE T4T
+**
+**                  aid_len: length of AID (up to NFC_MAX_AID_LEN)
+**                  p_aid:   AID
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+extern void CE_T4tDeregisterAID(tCE_T4T_AID_HANDLE aid_handle);
+
+/*******************************************************************************
+**
+** Function         CE_T4TTestSetCC
+**
+** Description      Set fields in Capability Container File for testing
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+extern tNFC_STATUS CE_T4TTestSetCC(uint16_t cc_len, uint8_t version,
+                                   uint16_t max_le, uint16_t max_lc);
+
+/*******************************************************************************
+**
+** Function         CE_T4TTestSetNDEFCtrlTLV
+**
+** Description      Set fields in NDEF File Control TLV for testing
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+extern tNFC_STATUS CE_T4TTestSetNDEFCtrlTLV(uint8_t type, uint8_t length,
+                                            uint16_t file_id,
+                                            uint16_t max_file_size,
+                                            uint8_t read_access,
+                                            uint8_t write_access);
+
+/*******************************************************************************
+**
+** Function         CE_SendRawFrame
+**
+** Description      This function sends a raw frame to the peer device.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS CE_SendRawFrame(uint8_t* p_raw_data, uint16_t data_len);
+
+/*******************************************************************************
+**
+** Function         CE_SetActivatedTagType
+**
+** Description      This function selects the tag type for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS CE_SetActivatedTagType(tNFC_ACTIVATE_DEVT* p_activate_params,
+                                          uint16_t t3t_system_code,
+                                          tCE_CBACK* p_cback);
+
+/*******************************************************************************
+**
+** Function         CE_SetTraceLevel
+**
+** Description      This function sets the trace level for Card Emulation mode.
+**                  If called with a value of 0xFF,
+**                  it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+extern uint8_t CE_SetTraceLevel(uint8_t new_level);
+
+#endif /* CE_API_H */
diff --git a/src/nfc/include/llcp_api.h b/src/nfc/include/llcp_api.h
new file mode 100644
index 0000000..a0bc10a
--- /dev/null
+++ b/src/nfc/include/llcp_api.h
@@ -0,0 +1,725 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the LLCP API definitions
+ *
+ ******************************************************************************/
+#ifndef LLCP_API_H
+#define LLCP_API_H
+
+#include "nfc_target.h"
+#include "llcp_defs.h"
+
+/*****************************************************************************
+**  Constants
+*****************************************************************************/
+/* Successfully done                */
+#define LLCP_STATUS_SUCCESS 0
+/* Failed without specific reason   */
+#define LLCP_STATUS_FAIL 1
+/* Data link is congested           */
+#define LLCP_STATUS_CONGESTED 2
+
+typedef uint8_t tLLCP_STATUS;
+
+#define LLCP_MIN_OFFSET                                             \
+  (NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + LLCP_PDU_HEADER_SIZE + \
+   LLCP_SEQUENCE_SIZE)
+
+/* indication of failure to allocate data link resource */
+#define LLCP_INVALID_SAP 0xFF
+
+/*****************************************************************************
+**  Type Definitions
+*****************************************************************************/
+typedef struct {
+  bool is_initiator;        /* true if we are POLL mode */
+  uint8_t max_payload_size; /* 64, 128, 192 or 254 */
+  uint8_t waiting_time;
+  uint8_t* p_gen_bytes;
+  uint8_t gen_bytes_len;
+} tLLCP_ACTIVATE_CONFIG;
+
+typedef struct {
+  uint16_t miu;                 /* Local receiving MIU      */
+  uint8_t rw;                   /* Local receiving window   */
+  char sn[LLCP_MAX_SN_LEN + 1]; /* Service name to connect  */
+} tLLCP_CONNECTION_PARAMS;
+
+/*********************************
+**  Callback Functions Prototypes
+**********************************/
+
+/* Link Management Callback Events */
+
+/* Fail to activate link    */
+#define LLCP_LINK_ACTIVATION_FAILED_EVT 0x00
+/* LLCP Link is activated   */
+#define LLCP_LINK_ACTIVATION_COMPLETE_EVT 0x01
+/* LLCP Link is deactivated */
+#define LLCP_LINK_DEACTIVATED_EVT 0x02
+/* First LLCP packet received from remote */
+#define LLCP_LINK_FIRST_PACKET_RECEIVED_EVT 0x03
+
+/* Link Management Callback Reasons */
+
+/* Success                                  */
+#define LLCP_LINK_SUCCESS 0x00
+/* Failed to agree version                  */
+#define LLCP_LINK_VERSION_FAILED 0x01
+/* Failed to parse received general bytes   */
+#define LLCP_LINK_BAD_GEN_BYTES 0x02
+/* internal error                           */
+#define LLCP_LINK_INTERNAL_ERROR 0x03
+/* Link has been deactivated by local       */
+#define LLCP_LINK_LOCAL_INITIATED 0x04
+/* Link has been deactivated by remote      */
+#define LLCP_LINK_REMOTE_INITIATED 0x05
+/* Link has been deactivated by timeout     */
+#define LLCP_LINK_TIMEOUT 0x06
+/* Link has been deactivated by frame error */
+#define LLCP_LINK_FRAME_ERROR 0x07
+/* RF link loss without any rx LLC PDU      */
+#define LLCP_LINK_RF_LINK_LOSS_NO_RX_LLC 0x08
+
+#define LLCP_LINK_RF_TRANSMISSION_ERR NFC_STATUS_RF_TRANSMISSION_ERR
+#define LLCP_LINK_RF_PROTOCOL_ERR NFC_STATUS_RF_PROTOCOL_ERR
+#define LLCP_LINK_RF_TIMEOUT NFC_STATUS_TIMEOUT
+#define LLCP_LINK_RF_LINK_LOSS_ERR NFC_STATUS_LINK_LOSS
+
+typedef void(tLLCP_LINK_CBACK)(uint8_t event, uint8_t reason);
+
+/* Minimum length of Gen Bytes for LLCP */
+/* In CE4 low power mode, NFCC can store up to 21 bytes */
+#define LLCP_MIN_GEN_BYTES 20
+
+/* Service Access Point (SAP) Callback Events */
+
+/* Received data on SAP         */
+#define LLCP_SAP_EVT_DATA_IND 0x00
+/* Connection request from peer */
+#define LLCP_SAP_EVT_CONNECT_IND 0x01
+/* Connection accepted by peer  */
+#define LLCP_SAP_EVT_CONNECT_RESP 0x02
+/* Received disconnect request  */
+#define LLCP_SAP_EVT_DISCONNECT_IND 0x03
+/* Received disconnect response */
+#define LLCP_SAP_EVT_DISCONNECT_RESP 0x04
+/* congested status is changed  */
+#define LLCP_SAP_EVT_CONGEST 0x05
+/* Change of LLCP Link status   */
+#define LLCP_SAP_EVT_LINK_STATUS 0x06
+/* tx queue is empty and all PDU is acked   */
+#define LLCP_SAP_EVT_TX_COMPLETE 0x07
+
+#define LLCP_LINK_TYPE_LOGICAL_DATA_LINK 0x01
+#define LLCP_LINK_TYPE_DATA_LINK_CONNECTION 0x02
+
+typedef struct {
+  uint8_t event;      /* LLCP_SAP_EVT_DATA_IND        */
+  uint8_t local_sap;  /* SAP of local device          */
+  uint8_t remote_sap; /* SAP of remote device         */
+  uint8_t link_type;  /* link type                    */
+} tLLCP_SAP_DATA_IND;
+
+typedef struct {
+  uint8_t event;        /* LLCP_SAP_EVT_CONNECT_IND     */
+  uint8_t server_sap;   /* SAP of local server          */
+  uint8_t local_sap;    /* SAP of local device          */
+  uint8_t remote_sap;   /* SAP of remote device         */
+  uint16_t miu;         /* MIU of peer device           */
+  uint8_t rw;           /* RW of peer device            */
+  char* p_service_name; /* Service name (only for SDP)  */
+} tLLCP_SAP_CONNECT_IND;
+
+typedef struct {
+  uint8_t event;      /* LLCP_SAP_EVT_CONNECT_RESP    */
+  uint8_t local_sap;  /* SAP of local device          */
+  uint8_t remote_sap; /* SAP of remote device         */
+  uint16_t miu;       /* MIU of peer device           */
+  uint8_t rw;         /* RW of peer device            */
+} tLLCP_SAP_CONNECT_RESP;
+
+#define LLCP_SAP_DISCONNECT_REASON_TIMEOUT 0x80
+typedef struct {
+  uint8_t event;      /* LLCP_SAP_EVT_DISCONNECT_IND  */
+  uint8_t local_sap;  /* SAP of local device          */
+  uint8_t remote_sap; /* SAP of remote device         */
+} tLLCP_SAP_DISCONNECT_IND;
+
+typedef struct {
+  uint8_t event;      /* LLCP_SAP_EVT_DISCONNECT_RESP */
+  uint8_t local_sap;  /* SAP of local device          */
+  uint8_t remote_sap; /* SAP of remote device         */
+  uint8_t reason;     /* Reason of DM PDU if not timeout */
+} tLLCP_SAP_DISCONNECT_RESP;
+
+typedef struct {
+  uint8_t event;      /* LLCP_SAP_EVT_CONGEST         */
+  uint8_t local_sap;  /* SAP of local device          */
+  uint8_t remote_sap; /* SAP of remote device         */
+  bool is_congested;  /* true if congested            */
+  uint8_t link_type;  /* congested link type          */
+} tLLCP_SAP_CONGEST;
+
+typedef struct {
+  uint8_t event;     /* LLCP_SAP_EVT_LINK_STATUS     */
+  uint8_t local_sap; /* SAP of local device          */
+  bool is_activated; /* true if LLCP link is activated  */
+  bool is_initiator; /* true if local LLCP is initiator */
+} tLLCP_SAP_LINK_STATUS;
+
+typedef struct {
+  uint8_t event;      /* LLCP_SAP_EVT_TX_COMPLETE     */
+  uint8_t local_sap;  /* SAP of local device          */
+  uint8_t remote_sap; /* SAP of remote device         */
+} tLLCP_SAP_TX_COMPLETE;
+
+typedef struct {
+  uint8_t event;     /* event                        */
+  uint8_t local_sap; /* SAP of local device          */
+} tLLCP_SAP_HEADER;
+
+typedef union {
+  tLLCP_SAP_HEADER hdr;                      /* common header                */
+  tLLCP_SAP_DATA_IND data_ind;               /* LLCP_SAP_EVT_DATA_IND        */
+  tLLCP_SAP_CONNECT_IND connect_ind;         /* LLCP_SAP_EVT_CONNECT_IND     */
+  tLLCP_SAP_CONNECT_RESP connect_resp;       /* LLCP_SAP_EVT_CONNECT_RESP    */
+  tLLCP_SAP_DISCONNECT_IND disconnect_ind;   /* LLCP_SAP_EVT_DISCONNECT_IND  */
+  tLLCP_SAP_DISCONNECT_RESP disconnect_resp; /* LLCP_SAP_EVT_DISCONNECT_RESP */
+  tLLCP_SAP_CONGEST congest;                 /* LLCP_SAP_EVT_CONGEST         */
+  tLLCP_SAP_LINK_STATUS link_status;         /* LLCP_SAP_EVT_LINK_STATUS     */
+  tLLCP_SAP_TX_COMPLETE tx_complete;         /* LLCP_SAP_EVT_TX_COMPLETE     */
+} tLLCP_SAP_CBACK_DATA;
+
+typedef void(tLLCP_APP_CBACK)(tLLCP_SAP_CBACK_DATA* p_data);
+
+/* Service Discovery Callback */
+
+typedef void(tLLCP_SDP_CBACK)(uint8_t tid, uint8_t remote_sap);
+
+/* LLCP DTA Callback - notify DTA responded SNL for connectionless echo service
+ */
+
+typedef void(tLLCP_DTA_CBACK)(void);
+
+/*****************************************************************************
+**  External Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+**
+** Function         LLCP_SetConfig
+**
+** Description      Set configuration parameters for LLCP
+**                  - Local Link MIU
+**                  - Option parameter
+**                  - Waiting Time Index
+**                  - Local Link Timeout
+**                  - Inactivity Timeout as initiator role
+**                  - Inactivity Timeout as target role
+**                  - Delay SYMM response
+**                  - Data link connection timeout
+**                  - Delay timeout to send first PDU as initiator
+**                  - Firmware start symmetry
+** Returns          void
+**
+*******************************************************************************/
+extern void LLCP_SetConfig(uint16_t link_miu, uint8_t opt, uint8_t wt,
+                           uint16_t link_timeout, uint16_t inact_timeout_init,
+                           uint16_t inact_timeout_target, uint16_t symm_delay,
+                           uint16_t data_link_timeout,
+                           uint16_t delay_first_pdu_timeout);
+
+/*******************************************************************************
+**
+** Function         LLCP_GetConfig
+**
+** Description      Get configuration parameters for LLCP
+**                  - Local Link MIU
+**                  - Option parameter
+**                  - Response Waiting Time Index
+**                  - Local Link Timeout
+**                  - Inactivity Timeout as initiator role
+**                  - Inactivity Timeout as target role
+**                  - Delay SYMM response
+**                  - Data link connection timeout
+**                  - Delay timeout to send first PDU as initiator
+**                  - Firmware start symmetry
+** Returns          void
+**
+*******************************************************************************/
+extern void LLCP_GetConfig(uint16_t* p_link_miu, uint8_t* p_opt, uint8_t* p_wt,
+                           uint16_t* p_link_timeout,
+                           uint16_t* p_inact_timeout_init,
+                           uint16_t* p_inact_timeout_target,
+                           uint16_t* p_symm_delay,
+                           uint16_t* p_data_link_timeout,
+                           uint16_t* p_delay_first_pdu_timeout);
+
+/*******************************************************************************
+**
+** Function         LLCP_GetDiscoveryConfig
+**
+** Description      Returns discovery config for LLCP MAC link activation
+**                  This function is called to get general bytes for
+**                  NFC_PMID_ATR_REQ_GEN_BYTES or NFC_PMID_ATR_RES_GEN_BYTES
+**                  before starting discovery.
+**
+**                  wt:Waiting time 0 - 8, only for listen
+**                  p_gen_bytes: pointer to store LLCP magic number and
+**                               paramters
+**                  p_gen_bytes_len: length of buffer for gen bytes as input
+**                                   (NOTE:it must be bigger than
+**                                   LLCP_MIN_GEN_BYTES) actual gen bytes
+**                                   size as output
+**
+**                  Restrictions on the use of ISO 18092
+**                  1. The DID features shall not be used.
+**                  2. the NAD features shall not be used.
+**                  3. Frame waiting time extentions (WTX) shall not be used.
+**
+** Returns          None
+**
+*******************************************************************************/
+extern void LLCP_GetDiscoveryConfig(uint8_t* p_wt, uint8_t* p_gen_bytes,
+                                    uint8_t* p_gen_bytes_len);
+
+/*******************************************************************************
+**
+** Function         LLCP_ActivateLink
+**
+** Description      This function will activate LLCP link with LR, WT and Gen
+**                  Bytes in activation NTF from NFCC.
+**
+**                  LLCP_LINK_ACTIVATION_COMPLETE_EVT will be returned through
+**                  callback function if successful.
+**                  Otherwise, LLCP_LINK_ACTIVATION_FAILED_EVT will be returned.
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+extern tLLCP_STATUS LLCP_ActivateLink(tLLCP_ACTIVATE_CONFIG config,
+                                      tLLCP_LINK_CBACK* p_link_cback);
+
+/*******************************************************************************
+**
+** Function         LLCP_DeactivateLink
+**
+** Description      Deactivate LLCP link
+**
+**                  LLCP_LINK_DEACTIVATED_EVT will be returned through callback
+**                  when LLCP link is deactivated. Then NFC link may be
+**                  deactivated.
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+extern tLLCP_STATUS LLCP_DeactivateLink(void);
+
+/*******************************************************************************
+**
+** Function         LLCP_RegisterServer
+**
+** Description      Register server and callback function
+**
+**                  reg_sap : Well-Known SAP except LM and SDP (0x02 - 0x0F)
+**                            Advertized by SDP (0x10 - 0x1F)
+**                            LLCP_INVALID_SAP, LLCP will allocate between 0x10
+**                            and 0x1F
+**                  link_type : LLCP_LINK_TYPE_LOGICAL_DATA_LINK
+**                              and/or LLCP_LINK_TYPE_DATA_LINK_CONNECTION
+**                  p_service_name : Null-terminated string up to
+**                                   LLCP_MAX_SN_LEN
+**
+** Returns          SAP between 0x02 and 0x1F, if success
+**                  LLCP_INVALID_SAP, otherwise
+**
+*******************************************************************************/
+extern uint8_t LLCP_RegisterServer(uint8_t reg_sap, uint8_t link_type,
+                                   char* p_service_name,
+                                   tLLCP_APP_CBACK* p_sap_cback);
+
+/*******************************************************************************
+**
+** Function         LLCP_RegisterClient
+**
+** Description      Register client and callback function
+**
+**                  link_type : LLCP_LINK_TYPE_LOGICAL_DATA_LINK
+**                              and/or LLCP_LINK_TYPE_DATA_LINK_CONNECTION
+**
+** Returns          SAP between 0x20 and 0x3F, if success
+**                  LLCP_INVALID_SAP, otherwise
+**
+*******************************************************************************/
+extern uint8_t LLCP_RegisterClient(uint8_t link_type,
+                                   tLLCP_APP_CBACK* p_sap_cback);
+
+/*******************************************************************************
+**
+** Function         LLCP_Deregister
+**
+** Description      Deregister server or client
+**
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+extern tLLCP_STATUS LLCP_Deregister(uint8_t sap);
+
+/*******************************************************************************
+**
+** Function         LLCP_IsLogicalLinkCongested
+**
+** Description      Check if logical link is congested
+**
+**
+** Returns          true if congested
+**
+*******************************************************************************/
+extern bool LLCP_IsLogicalLinkCongested(uint8_t local_sap,
+                                        uint8_t num_pending_ui_pdu,
+                                        uint8_t total_pending_ui_pdu,
+                                        uint8_t total_pending_i_pdu);
+
+/*******************************************************************************
+**
+** Function         LLCP_SendUI
+**
+** Description      Send connnectionless data to DSAP
+**
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**                  LLCP_STATUS_CONGESTED if logical link is congested
+**                  LLCP_STATUS_FAIL, otherwise
+**
+*******************************************************************************/
+extern tLLCP_STATUS LLCP_SendUI(uint8_t ssap, uint8_t dsap, NFC_HDR* p_buf);
+
+/*******************************************************************************
+**
+** Function         LLCP_ReadLogicalLinkData
+**
+** Description      Read information of UI PDU for local SAP
+**
+**                  - Remote SAP who sent UI PDU is returned.
+**                  - Information of UI PDU up to max_data_len is copied into
+**                    p_data.
+**                  - Information of next UI PDU is not concatenated.
+**                  - Recommended max_data_len is link MIU of local device
+**
+** Returns          true if more information of UI PDU or more UI PDU in queue
+**
+*******************************************************************************/
+extern bool LLCP_ReadLogicalLinkData(uint8_t local_sap, uint32_t max_data_len,
+                                     uint8_t* p_remote_sap,
+                                     uint32_t* p_data_len, uint8_t* p_data);
+
+/*******************************************************************************
+**
+** Function         LLCP_FlushLogicalLinkRxData
+**
+** Description      Discard received data in logical data link of local SAP
+**
+**
+** Returns          length of data flushed
+**
+*******************************************************************************/
+extern uint32_t LLCP_FlushLogicalLinkRxData(uint8_t local_sap);
+
+/*******************************************************************************
+**
+** Function         LLCP_ConnectReq
+**
+** Description      Create data link connection between registered SAP and DSAP
+**                  in peer LLCP,
+**
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**                  LLCP_STATUS_FAIL, otherwise
+**
+*******************************************************************************/
+extern tLLCP_STATUS LLCP_ConnectReq(uint8_t reg_sap, uint8_t dsap,
+                                    tLLCP_CONNECTION_PARAMS* p_params);
+
+/*******************************************************************************
+**
+** Function         LLCP_ConnectCfm
+**
+** Description      Accept connection request from peer LLCP
+**
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**                  LLCP_STATUS_FAIL, otherwise
+**
+*******************************************************************************/
+extern tLLCP_STATUS LLCP_ConnectCfm(uint8_t local_sap, uint8_t remote_sap,
+                                    tLLCP_CONNECTION_PARAMS* p_params);
+
+/*******************************************************************************
+**
+** Function         LLCP_ConnectReject
+**
+** Description      Reject connection request from peer LLCP
+**
+**                  reason : LLCP_SAP_DM_REASON_APP_REJECTED
+**                           LLCP_SAP_DM_REASON_PERM_REJECT_THIS
+**                           LLCP_SAP_DM_REASON_PERM_REJECT_ANY
+**                           LLCP_SAP_DM_REASON_TEMP_REJECT_THIS
+**                           LLCP_SAP_DM_REASON_TEMP_REJECT_ANY
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**                  LLCP_STATUS_FAIL, otherwise
+**
+*******************************************************************************/
+extern tLLCP_STATUS LLCP_ConnectReject(uint8_t local_sap, uint8_t remote_sap,
+                                       uint8_t reason);
+
+/*******************************************************************************
+**
+** Function         LLCP_IsDataLinkCongested
+**
+** Description      Check if data link is congested
+**
+**
+** Returns          true if congested
+**
+*******************************************************************************/
+extern bool LLCP_IsDataLinkCongested(uint8_t local_sap, uint8_t remote_sap,
+                                     uint8_t num_pending_i_pdu,
+                                     uint8_t total_pending_ui_pdu,
+                                     uint8_t total_pending_i_pdu);
+
+/*******************************************************************************
+**
+** Function         LLCP_SendData
+**
+** Description      Send connection-oriented data
+**
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**                  LLCP_STATUS_CONGESTED if data link is congested
+**
+*******************************************************************************/
+extern tLLCP_STATUS LLCP_SendData(uint8_t local_sap, uint8_t remote_sap,
+                                  NFC_HDR* p_buf);
+
+/*******************************************************************************
+**
+** Function         LLCP_ReadDataLinkData
+**
+** Description      Read information of I PDU for data link connection
+**
+**                  - Information of I PDU up to max_data_len is copied into
+**                    p_data.
+**                  - Information of next I PDU is not concatenated.
+**                  - Recommended max_data_len is data link connection MIU of
+**                    local end point
+**
+** Returns          true if more data in queue
+**
+*******************************************************************************/
+extern bool LLCP_ReadDataLinkData(uint8_t local_sap, uint8_t remote_sap,
+                                  uint32_t max_data_len, uint32_t* p_data_len,
+                                  uint8_t* p_data);
+
+/*******************************************************************************
+**
+** Function         LLCP_FlushDataLinkRxData
+**
+** Description      Discard received data in data link connection
+**
+**
+** Returns          length of rx data flushed
+**
+*******************************************************************************/
+extern uint32_t LLCP_FlushDataLinkRxData(uint8_t local_sap, uint8_t remote_sap);
+
+/*******************************************************************************
+**
+** Function         LLCP_DisconnectReq
+**
+** Description      Disconnect data link
+**                  discard any pending data if flush is set to true
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+extern tLLCP_STATUS LLCP_DisconnectReq(uint8_t local_sap, uint8_t remote_sap,
+                                       bool flush);
+
+/*******************************************************************************
+**
+** Function         LLCP_SetTxCompleteNtf
+**
+** Description      This function is called to get LLCP_SAP_EVT_TX_COMPLETE
+**                  when Tx queue is empty and all PDU is acked.
+**                  This is one time event, so upper layer shall call this
+**                  function again to get next LLCP_SAP_EVT_TX_COMPLETE.
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+extern tLLCP_STATUS LLCP_SetTxCompleteNtf(uint8_t local_sap,
+                                          uint8_t remote_sap);
+
+/*******************************************************************************
+**
+** Function         LLCP_SetLocalBusyStatus
+**
+** Description      Set local busy status
+**
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+extern tLLCP_STATUS LLCP_SetLocalBusyStatus(uint8_t local_sap,
+                                            uint8_t remote_sap, bool is_busy);
+
+/*******************************************************************************
+**
+** Function         LLCP_GetRemoteWKS
+**
+** Description      Return well-known service bitmap of connected device
+**
+**
+** Returns          WKS bitmap if success
+**
+*******************************************************************************/
+extern uint16_t LLCP_GetRemoteWKS(void);
+
+/*******************************************************************************
+**
+** Function         LLCP_GetRemoteLSC
+**
+** Description      Return link service class of connected device
+**
+**
+** Returns          link service class
+**
+*******************************************************************************/
+extern uint8_t LLCP_GetRemoteLSC(void);
+
+/*******************************************************************************
+**
+** Function         LLCP_GetRemoteVersion
+**
+** Description      Return LLCP version of connected device
+**
+**
+** Returns          LLCP version
+**
+*******************************************************************************/
+extern uint8_t LLCP_GetRemoteVersion(void);
+
+/*******************************************************************************
+**
+** Function         LLCP_GetLinkMIU
+**
+** Description      Return local and remote link MIU
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+extern void LLCP_GetLinkMIU(uint16_t* p_local_link_miu,
+                            uint16_t* p_remote_link_miu);
+
+/*******************************************************************************
+**
+** Function         LLCP_DiscoverService
+**
+** Description      Return SAP of service name in connected device through
+**                  callback
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+extern tLLCP_STATUS LLCP_DiscoverService(char* p_name, tLLCP_SDP_CBACK* p_cback,
+                                         uint8_t* p_tid);
+
+/*******************************************************************************
+**
+** Function         LLCP_SetTraceLevel
+**
+** Description      This function sets the trace level for LLCP.  If called with
+**                  a value of 0xFF, it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+extern uint8_t LLCP_SetTraceLevel(uint8_t new_level);
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         LLCP_RegisterDtaCback
+**
+** Description      Register callback function for LLCP DTA testing
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+extern void LLCP_RegisterDtaCback(tLLCP_DTA_CBACK* p_dta_cback);
+#endif
+
+#if (LLCP_TEST_INCLUDED == true)
+/*******************************************************************************
+**
+** Function         LLCP_SetTestParams
+**
+** Description      Set test parameters for LLCP
+**
+** Returns          void
+**
+*******************************************************************************/
+extern void LLCP_SetTestParams(uint8_t version, uint16_t wks);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LLCP_API_H */
diff --git a/src/nfc/include/llcp_defs.h b/src/nfc/include/llcp_defs.h
new file mode 100644
index 0000000..ba25710
--- /dev/null
+++ b/src/nfc/include/llcp_defs.h
@@ -0,0 +1,202 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the LLCP definitions
+ *
+ ******************************************************************************/
+#ifndef LLCP_DEFS_H
+#define LLCP_DEFS_H
+
+/*
+** LLCP PDU Descriptions
+*/
+
+#define LLCP_PDU_HEADER_SIZE 2 /* DSAP:PTYPE:SSAP excluding Sequence */
+
+#define LLCP_GET_DSAP(u16) (((u16)&0xFC00) >> 10)
+#define LLCP_GET_PTYPE(u16) (((u16)&0x03C0) >> 6)
+#define LLCP_GET_SSAP(u16) (((u16)&0x003F))
+
+#define LLCP_GET_PDU_HEADER(dsap, ptype, ssap) \
+  (((uint16_t)(dsap) << 10) | ((uint16_t)(ptype) << 6) | (uint16_t)(ssap))
+
+#define LLCP_GET_NS(u8) ((uint8_t)(u8) >> 4)
+#define LLCP_GET_NR(u8) ((uint8_t)(u8)&0x0F)
+#define LLCP_GET_SEQUENCE(NS, NR) (((uint8_t)(NS) << 4) | (uint8_t)(NR))
+#define LLCP_SEQUENCE_SIZE 1
+
+#define LLCP_PDU_SYMM_TYPE 0
+#define LLCP_PDU_PAX_TYPE 1
+#define LLCP_PDU_AGF_TYPE 2
+#define LLCP_PDU_UI_TYPE 3
+#define LLCP_PDU_CONNECT_TYPE 4
+#define LLCP_PDU_DISC_TYPE 5
+#define LLCP_PDU_CC_TYPE 6
+#define LLCP_PDU_DM_TYPE 7
+#define LLCP_PDU_FRMR_TYPE 8
+#define LLCP_PDU_SNL_TYPE 9
+#define LLCP_PDU_RESERVED_1010 10
+#define LLCP_PDU_RESERVED_1011 11
+#define LLCP_PDU_I_TYPE 12
+#define LLCP_PDU_RR_TYPE 13
+#define LLCP_PDU_RNR_TYPE 14
+#define LLCP_PDU_RESERVED_1111 15
+
+#define LLCP_PDU_SYMM_SIZE 2
+#define LLCP_PDU_DISC_SIZE 2
+#define LLCP_PDU_DM_SIZE 3
+#define LLCP_PDU_FRMR_SIZE 6
+#define LLCP_PDU_RR_SIZE 3
+#define LLCP_PDU_RNR_SIZE 3
+#define LLCP_PDU_AGF_LEN_SIZE 2 /* 2 bytes of length in AGF PDU */
+
+#define LLCP_SAP_DM_REASON_RESP_DISC 0x00
+#define LLCP_SAP_DM_REASON_NO_ACTIVE_CONNECTION 0x01
+#define LLCP_SAP_DM_REASON_NO_SERVICE 0x02
+#define LLCP_SAP_DM_REASON_APP_REJECTED 0x03
+#define LLCP_SAP_DM_REASON_PERM_REJECT_THIS 0x10
+#define LLCP_SAP_DM_REASON_PERM_REJECT_ANY 0x11
+#define LLCP_SAP_DM_REASON_TEMP_REJECT_THIS 0x20
+#define LLCP_SAP_DM_REASON_TEMP_REJECT_ANY 0x21
+
+#define LLCP_FRMR_W_ERROR_FLAG 0x08 /* Well-formedness Error */
+#define LLCP_FRMR_I_ERROR_FLAG 0x04 /* Information Field Error */
+#define LLCP_FRMR_R_ERROR_FLAG 0x02 /* Receive Sequence Error */
+#define LLCP_FRMR_S_ERROR_FLAG 0x01 /* Send Sequence Error */
+
+#define LLCP_GET_FRMR_W_ERROR_FLAG(u8) (((uint8_t)(u8) >> 7) & 0x01)
+#define LLCP_GET_FRMR_I_ERROR_FLAG(u8) (((uint8_t)(u8) >> 6) & 0x01)
+#define LLCP_GET_FRMR_R_ERROR_FLAG(u8) (((uint8_t)(u8) >> 5) & 0x01)
+#define LLCP_GET_FRMR_S_ERROR_FLAG(u8) (((uint8_t)(u8) >> 4) & 0x01)
+#define LLCP_GET_FRMR_PTYPE(u8) ((uint8_t)(u8)&0x0F)
+#define LLCP_GET_FRMR_VS(u16) (((uint16_t)(u16) >> 12) & 0x000F)
+#define LLCP_GET_FRMR_VR(u16) (((uint16_t)(u16) >> 8) & 0x000F)
+#define LLCP_GET_FRMR_VSA(u16) (((uint16_t)(u16) >> 4) & 0x000F)
+#define LLCP_GET_FRMR_VRA(u16) (((uint16_t)(u16) >> 0) & 0x000F)
+
+/*
+** LLCP Parameter Descriptions
+*/
+
+/* Version */
+#define LLCP_VERSION_TYPE 0x01
+#define LLCP_VERSION_LEN 0x01
+#define LLCP_GET_MAJOR_VERSION(u8) (((uint8_t)(u8) >> 4) & 0x0F)
+#define LLCP_GET_MINOR_VERSION(u8) ((uint8_t)(u8)&0x0F)
+#define LLCP_MIN_MAJOR_VERSION 0x01
+#define LLCP_MIN_SNL_MAJOR_VERSION 0x01
+#define LLCP_MIN_SNL_MINOR_VERSION 0x01
+
+/* LLCP Version 1.2 */
+#define LLCP_VERSION_MAJOR 0x01
+#define LLCP_VERSION_MINOR 0x02
+#define LLCP_VERSION_VALUE ((LLCP_VERSION_MAJOR << 4) | LLCP_VERSION_MINOR)
+
+/* Maximum Information Unit Extension */
+#define LLCP_MIUX_TYPE 0x02
+#define LLCP_MIUX_LEN 0x02
+#define LLCP_MIUX_MASK 0x07FF /* MIUX bit 10:0 */
+#define LLCP_DEFAULT_MIU 128  /* if local LLC doesn't receive MIUX */
+#define LLCP_MAX_MIU 2175     /* 2047 (11bits) + 128 */
+
+/* Well-Known Service */
+#define LLCP_WKS_TYPE 0x03
+#define LLCP_WKS_LEN 0x02
+
+/* Well-Known Service Bitmap */
+#define LLCP_WKS_MASK_LM 0x0001  /* Link Management */
+#define LLCP_WKS_MASK_SDP 0x0002 /* Service Discovery "urn:nfc:sn:sdp" */
+#define LLCP_WKS_MASK_IP 0x0004  /* IP over LLCP Binding "urn:nfc:sn:ip" */
+/* OBEX over LLCP Binding "urn:nfc:sn:obex" */
+#define LLCP_WKS_MASK_OBEX 0x0008
+/* Simple NDEP Exchange Protocol "urn:nfc:sn:snep" */
+#define LLCP_WKS_MASK_SNEP 0x0010
+
+/* Well-Known Service Access Points */
+#define LLCP_SAP_LM 0x00  /* Link Management */
+#define LLCP_SAP_SDP 0x01 /* Service Discovery "urn:nfc:sn:sdp" */
+#define LLCP_SAP_IP 0x02  /* IP over LLCP Binding "urn:nfc:sn:ip" */
+/* OBEX over LLCP Binding "urn:nfc:sn:obex" */
+#define LLCP_SAP_OBEX 0x03
+/* Simple NDEP Exchange Protocol "urn:nfc:sn:snep" */
+#define LLCP_SAP_SNEP 0x04
+
+/* Link Timeout, LTO */
+#define LLCP_LTO_TYPE 0x04
+#define LLCP_LTO_LEN 0x01
+/* default 100ms. It should be sufficiently larget than RWT */
+#define LLCP_DEFAULT_LTO_IN_MS 100
+#define LLCP_LTO_UNIT 10        /* 10 ms */
+#define LLCP_MAX_LTO_IN_MS 2550 /* 2550 ms; 8bits * 10ms */
+
+/* Receive Window Size, RW */
+#define LLCP_RW_TYPE 0x05
+#define LLCP_RW_LEN 0x01
+#define LLCP_DEFAULT_RW 1 /* if local LLC doesn't receive RW */
+
+/* Service Name, SN */
+#define LLCP_SN_TYPE 0x06
+
+/* Option, OPT */
+#define LLCP_OPT_TYPE 0x07
+#define LLCP_OPT_LEN 0x01
+#define LLCP_GET_OPT_LSC(u8) ((uint8_t)(u8)&0x03)
+
+/* Service Discovery Request, SDREQ */
+#define LLCP_SDREQ_TYPE 0x08
+/* type(1 byte), length(1 byte), TID(1 byte) */
+#define LLCP_SDREQ_MIN_LEN 0x03
+
+/* Service Discovery Response, SDRES */
+#define LLCP_SDRES_TYPE 0x09
+#define LLCP_SDRES_LEN 0x02
+
+/* Link Service Class */
+#define LLCP_LSC_UNKNOWN 0x00
+#define LLCP_LSC_1 0x01
+#define LLCP_LSC_2 0x02
+#define LLCP_LSC_3 0x03
+
+#define LLCP_MAGIC_NUMBER_LEN 3
+#define LLCP_MAGIC_NUMBER_BYTE0 0x46
+#define LLCP_MAGIC_NUMBER_BYTE1 0x66
+#define LLCP_MAGIC_NUMBER_BYTE2 0x6D
+
+#define LLCP_SEQ_MODULO 16
+
+#define LLCP_NUM_SAPS 64
+#define LLCP_LOWER_BOUND_WK_SAP 0x00
+#define LLCP_UPPER_BOUND_WK_SAP 0x0F
+#define LLCP_LOWER_BOUND_SDP_SAP 0x10
+#define LLCP_UPPER_BOUND_SDP_SAP 0x1F
+#define LLCP_LOWER_BOUND_LOCAL_SAP 0x20
+#define LLCP_UPPER_BOUND_LOCAL_SAP 0x3F
+
+/* Max Payload */
+/* Maximum Payload size, Length Reduction LRi/LRt */
+#define LLCP_NCI_MAX_PAYL_SIZE 254
+/* Data exchange protocol header, 3 bytes */
+#define LLCP_NFC_DEP_HEADER_SIZE 3
+#define LLCP_MAX_PAYLOAD_SIZE \
+  (LLCP_NCI_MAX_PAYL_SIZE - LLCP_NFC_DEP_HEADER_SIZE)
+
+#define LLCP_MAX_GEN_BYTES 48
+
+#endif /* LLCP_DEFS_H */
diff --git a/src/nfc/include/nci_hmsgs.h b/src/nfc/include/nci_hmsgs.h
new file mode 100644
index 0000000..4df6cce
--- /dev/null
+++ b/src/nfc/include/nci_hmsgs.h
@@ -0,0 +1,101 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  defines NCI interface messages (for DH)
+ *
+ ******************************************************************************/
+#ifndef NFC_NCI_HMSGS_H
+#define NFC_NCI_HMSGS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "nfc_types.h"
+#include "nci_defs.h"
+
+#include <stdbool.h>
+
+bool nci_proc_core_rsp(NFC_HDR* p_msg);
+void nci_proc_rf_management_rsp(NFC_HDR* p_msg);
+void nci_proc_ee_management_rsp(NFC_HDR* p_msg);
+void nci_proc_core_ntf(NFC_HDR* p_msg);
+void nci_proc_rf_management_ntf(NFC_HDR* p_msg);
+void nci_proc_ee_management_ntf(NFC_HDR* p_msg);
+void nci_proc_prop_rsp(NFC_HDR* p_msg);
+#if (NXP_EXTNS == TRUE)
+void nci_proc_prop_nxp_rsp(NFC_HDR* p_msg);
+uint8_t nci_snd_iso_dep_nak_presence_check_cmd();
+#endif
+void nci_proc_prop_ntf(NFC_HDR* p_msg);
+
+uint8_t nci_snd_core_reset(uint8_t reset_type);
+uint8_t nci_snd_core_init(uint8_t nci_version);
+uint8_t nci_snd_core_get_config(uint8_t* param_ids, uint8_t num_ids);
+uint8_t nci_snd_core_set_config(uint8_t* p_param_tlvs, uint8_t tlv_size);
+
+uint8_t nci_snd_core_conn_create(uint8_t dest_type, uint8_t num_tlv,
+                                 uint8_t tlv_size, uint8_t* p_param_tlvs);
+uint8_t nci_snd_core_conn_close(uint8_t conn_id);
+
+uint8_t nci_snd_discover_cmd(uint8_t num, tNCI_DISCOVER_PARAMS* p_param);
+
+uint8_t nci_snd_discover_select_cmd(uint8_t rf_disc_id, uint8_t protocol,
+                                    uint8_t rf_interface);
+uint8_t nci_snd_deactivate_cmd(uint8_t de_act_type);
+uint8_t nci_snd_discover_map_cmd(uint8_t num, tNCI_DISCOVER_MAPS* p_maps);
+uint8_t nci_snd_t3t_polling(uint16_t system_code, uint8_t rc, uint8_t tsn);
+uint8_t nci_snd_parameter_update_cmd(uint8_t* p_param_tlvs, uint8_t tlv_size);
+#if (NXP_EXTNS == TRUE)
+uint8_t nci_snd_pwr_nd_lnk_ctrl_cmd(uint8_t nfcee_id, uint8_t cfg_value);
+#endif
+#if ((NFC_NFCEE_INCLUDED == true) && (NFC_RW_ONLY == false))
+uint8_t nci_snd_nfcee_discover(uint8_t discover_action);
+uint8_t nci_snd_nfcee_mode_set(uint8_t nfcee_id, uint8_t nfcee_mode);
+uint8_t nci_snd_set_routing_cmd(bool more, uint8_t num_tlv, uint8_t tlv_size,
+                                uint8_t* p_param_tlvs);
+uint8_t nci_snd_get_routing_cmd(void);
+uint8_t nci_snd_nfcee_power_link_control (uint8_t nfcee_id, uint8_t pl_config);
+#endif
+uint8_t nci_snd_core_set_power_sub_state(uint8_t screen_state);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_NCI_MSGS_H */
diff --git a/src/nfc/include/ndef_utils.h b/src/nfc/include/ndef_utils.h
new file mode 100644
index 0000000..6e7caab
--- /dev/null
+++ b/src/nfc/include/ndef_utils.h
@@ -0,0 +1,412 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains definitions for some utility functions to help parse
+ *  and build NFC Data Exchange Format (NDEF) messages
+ *
+ ******************************************************************************/
+
+#ifndef NDEF_UTILS_H
+#define NDEF_UTILS_H
+
+#include "bt_types.h"
+
+#define NDEF_MB_MASK 0x80  /* Message Begin */
+#define NDEF_ME_MASK 0x40  /* Message End */
+#define NDEF_CF_MASK 0x20  /* Chunk Flag */
+#define NDEF_SR_MASK 0x10  /* Short Record */
+#define NDEF_IL_MASK 0x08  /* ID Length */
+#define NDEF_TNF_MASK 0x07 /* Type Name Format */
+/* First valid ASCII as per RTD specification */
+#define NDEF_RTD_VALID_START 0x20
+/* Last valid ASCII as per RTD specification */
+#define NDEF_RTD_VALID_END 0x7E
+
+/* NDEF Type Name Format */
+#define NDEF_TNF_EMPTY 0     /* Empty (type/id/payload len =0) */
+#define NDEF_TNF_WKT 1       /* NFC Forum well-known type/RTD */
+#define NDEF_TNF_MEDIA 2     /* Media-type as defined in RFC 2046 */
+#define NDEF_TNF_URI 3       /* Absolute URI as defined in RFC 3986 */
+#define NDEF_TNF_EXT 4       /* NFC Forum external type/RTD */
+#define NDEF_TNF_UNKNOWN 5   /* Unknown (type len =0) */
+#define NDEF_TNF_UNCHANGED 6 /* Unchanged (type len =0) */
+#define NDEF_TNF_RESERVED 7  /* Reserved */
+
+/* Define the status code returned from the Validate, Parse or Build functions
+*/
+enum {
+  NDEF_OK, /* 0 - OK                                   */
+
+  NDEF_REC_NOT_FOUND,         /* 1 - No record matching the find criteria */
+  NDEF_MSG_TOO_SHORT,         /* 2 - Message was too short (< 3 bytes)    */
+  NDEF_MSG_NO_MSG_BEGIN,      /* 3 - No 'begin' flag at start of message  */
+  NDEF_MSG_NO_MSG_END,        /* 4 - No 'end' flag at end of message      */
+  NDEF_MSG_EXTRA_MSG_BEGIN,   /* 5 - 'begin' flag after start of message  */
+  NDEF_MSG_UNEXPECTED_CHUNK,  /* 6 - Unexpected chunk found               */
+  NDEF_MSG_INVALID_EMPTY_REC, /* 7 - Empty record with non-zero contents  */
+  NDEF_MSG_INVALID_CHUNK,     /* 8 - Invalid chunk found                  */
+  NDEF_MSG_LENGTH_MISMATCH,   /* 9 - Overall message length doesn't match */
+  NDEF_MSG_INSUFFICIENT_MEM,  /* 10 - Insuffiecient memory to add record  */
+  NDEF_MSG_EMPTY_PAYLOAD,     /* 11 - Payload length is zero  */
+  NDEF_MSG_INVALID_TYPE       /* 12 - TYPE field contains invalid characters  */
+};
+typedef uint8_t tNDEF_STATUS;
+
+#define HR_REC_TYPE_LEN 2        /* Handover Request Record Type     */
+#define HS_REC_TYPE_LEN 2        /* Handover Select Record Type      */
+#define HC_REC_TYPE_LEN 2        /* Handover Carrier recrod Type     */
+#define CR_REC_TYPE_LEN 2        /* Collision Resolution Record Type */
+#define AC_REC_TYPE_LEN 2        /* Alternative Carrier Record Type  */
+#define ERR_REC_TYPE_LEN 3       /* Error Record Type                */
+#define BT_OOB_REC_TYPE_LEN 32   /* Bluetooth OOB Data Type          */
+#define WIFI_WSC_REC_TYPE_LEN 23 /* Wifi WSC Data Type               */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Functions to parse a received NDEF Message
+*/
+/*******************************************************************************
+**
+** Function         NDEF_MsgValidate
+**
+** Description      This function validates an NDEF message.
+**
+** Returns          true if all OK, or false if the message is invalid.
+**
+*******************************************************************************/
+extern tNDEF_STATUS NDEF_MsgValidate(uint8_t* p_msg, uint32_t msg_len,
+                                     bool b_allow_chunks);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetNumRecs
+**
+** Description      This function gets the number of records in the given NDEF
+**                  message.
+**
+** Returns          The record count, or 0 if the message is invalid.
+**
+*******************************************************************************/
+extern int32_t NDEF_MsgGetNumRecs(uint8_t* p_msg);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetRecLength
+**
+** Description      This function returns length of the current record in the
+**                  given NDEF message.
+**
+** Returns          Length of record
+**
+*******************************************************************************/
+extern uint32_t NDEF_MsgGetRecLength(uint8_t* p_cur_rec);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetNextRec
+**
+** Description      This function gets a pointer to the next record after the
+**                  current one.
+**
+** Returns          Pointer to the start of the record, or NULL if no more
+**
+*******************************************************************************/
+extern uint8_t* NDEF_MsgGetNextRec(uint8_t* p_cur_rec);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetRecByIndex
+**
+** Description      This function gets a pointer to the record with the given
+**                  index (0-based index) in the given NDEF message.
+**
+** Returns          Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+extern uint8_t* NDEF_MsgGetRecByIndex(uint8_t* p_msg, int32_t index);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetLastRecInMsg
+**
+** Description      This function gets a pointer to the last record in the
+**                  given NDEF message.
+**
+** Returns          Pointer to the start of the last record, or NULL if some
+**                  problem
+**
+*******************************************************************************/
+extern uint8_t* NDEF_MsgGetLastRecInMsg(uint8_t* p_msg);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetFirstRecByType
+**
+** Description      This function gets a pointer to the first record with the
+**                  given record type in the given NDEF message.
+**
+** Returns          Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+extern uint8_t* NDEF_MsgGetFirstRecByType(uint8_t* p_msg, uint8_t tnf,
+                                          uint8_t* p_type, uint8_t tlen);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetNextRecByType
+**
+** Description      This function gets a pointer to the next record with the
+**                  given record type in the given NDEF message.
+**
+** Returns          Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+extern uint8_t* NDEF_MsgGetNextRecByType(uint8_t* p_cur_rec, uint8_t tnf,
+                                         uint8_t* p_type, uint8_t tlen);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetFirstRecById
+**
+** Description      This function gets a pointer to the first record with the
+**                  given record id in the given NDEF message.
+**
+** Returns          Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+extern uint8_t* NDEF_MsgGetFirstRecById(uint8_t* p_msg, uint8_t* p_id,
+                                        uint8_t ilen);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetNextRecById
+**
+** Description      This function gets a pointer to the next record with the
+**                  given record id in the given NDEF message.
+**
+** Returns          Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+extern uint8_t* NDEF_MsgGetNextRecById(uint8_t* p_cur_rec, uint8_t* p_id,
+                                       uint8_t ilen);
+
+/*******************************************************************************
+**
+** Function         NDEF_RecGetType
+**
+** Description      This function gets a pointer to the record type for the
+**                  given NDEF record.
+**
+** Returns          Pointer to Type (NULL if none). TNF and len are filled in.
+**
+*******************************************************************************/
+extern uint8_t* NDEF_RecGetType(uint8_t* p_rec, uint8_t* p_tnf,
+                                uint8_t* p_type_len);
+
+/*******************************************************************************
+**
+** Function         NDEF_RecGetId
+**
+** Description      This function gets a pointer to the record id for the given
+**                  NDEF record.
+**
+** Returns          Pointer to Id (NULL if none). ID Len is filled in.
+**
+*******************************************************************************/
+extern uint8_t* NDEF_RecGetId(uint8_t* p_rec, uint8_t* p_id_len);
+
+/*******************************************************************************
+**
+** Function         NDEF_RecGetPayload
+**
+** Description      This function gets a pointer to the payload for the given
+**                  NDEF record.
+**
+** Returns          a pointer to the payload (NULL if none). Payload len filled
+**                  in.
+**
+*******************************************************************************/
+extern uint8_t* NDEF_RecGetPayload(uint8_t* p_rec, uint32_t* p_payload_len);
+
+/* Functions to build an NDEF Message
+*/
+/*******************************************************************************
+**
+** Function         NDEF_MsgInit
+**
+** Description      This function initializes an NDEF message.
+**
+** Returns          void
+**                  *p_cur_size is initialized to 0
+**
+*******************************************************************************/
+extern void NDEF_MsgInit(uint8_t* p_msg, uint32_t max_size,
+                         uint32_t* p_cur_size);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAddRec
+**
+** Description      This function adds an NDEF record to the end of an NDEF
+**                  message.
+**
+** Returns          OK, or error if the record did not fit
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+extern tNDEF_STATUS NDEF_MsgAddRec(uint8_t* p_msg, uint32_t max_size,
+                                   uint32_t* p_cur_size, uint8_t tnf,
+                                   uint8_t* p_type, uint8_t type_len,
+                                   uint8_t* p_id, uint8_t id_len,
+                                   uint8_t* p_payload, uint32_t payload_len);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgInsertRec
+**
+** Description      This function inserts a record at a specific index into the
+**                  given NDEF message
+**
+** Returns          OK, or error if the record did not fit
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+extern tNDEF_STATUS NDEF_MsgInsertRec(uint8_t* p_msg, uint32_t max_size,
+                                      uint32_t* p_cur_size, int32_t index,
+                                      uint8_t tnf, uint8_t* p_type,
+                                      uint8_t type_len, uint8_t* p_id,
+                                      uint8_t id_len, uint8_t* p_payload,
+                                      uint32_t payload_len);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAppendRec
+**
+** Description      This function adds NDEF records to the end of an NDEF
+**                  message.
+**
+** Returns          OK, or error if the record did not fit
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+extern tNDEF_STATUS NDEF_MsgAppendRec(uint8_t* p_msg, uint32_t max_size,
+                                      uint32_t* p_cur_size, uint8_t* p_new_rec,
+                                      uint32_t new_rec_len);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAppendPayload
+**
+** Description      This function appends extra payload to a specific record in
+**                  the given NDEF message
+**
+** Returns          OK, or error if the extra payload did not fit
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+extern tNDEF_STATUS NDEF_MsgAppendPayload(uint8_t* p_msg, uint32_t max_size,
+                                          uint32_t* p_cur_size, uint8_t* p_rec,
+                                          uint8_t* p_add_pl,
+                                          uint32_t add_pl_len);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgReplacePayload
+**
+** Description      This function replaces the payload of a specific record in
+**                  the given NDEF message
+**
+** Returns          OK, or error if the new payload did not fit
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+extern tNDEF_STATUS NDEF_MsgReplacePayload(uint8_t* p_msg, uint32_t max_size,
+                                           uint32_t* p_cur_size, uint8_t* p_rec,
+                                           uint8_t* p_new_pl,
+                                           uint32_t new_pl_len);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgReplaceType
+**
+** Description      This function replaces the type field of a specific record
+**                  in the given NDEF message
+**
+** Returns          OK, or error if the new type field did not fit
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+extern tNDEF_STATUS NDEF_MsgReplaceType(uint8_t* p_msg, uint32_t max_size,
+                                        uint32_t* p_cur_size, uint8_t* p_rec,
+                                        uint8_t* p_new_type,
+                                        uint8_t new_type_len);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgReplaceId
+**
+** Description      This function replaces the ID field of a specific record in
+**                  the given NDEF message
+**
+** Returns          OK, or error if the new ID field did not fit
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+extern tNDEF_STATUS NDEF_MsgReplaceId(uint8_t* p_msg, uint32_t max_size,
+                                      uint32_t* p_cur_size, uint8_t* p_rec,
+                                      uint8_t* p_new_id, uint8_t new_id_len);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgRemoveRec
+**
+** Description      This function removes the record at the given
+**                  index in the given NDEF message.
+**
+** Returns          OK, or error if the index was invalid
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+extern tNDEF_STATUS NDEF_MsgRemoveRec(uint8_t* p_msg, uint32_t* p_cur_size,
+                                      int32_t index);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgCopyAndDechunk
+**
+** Description      This function copies and de-chunks an NDEF message.
+**                  It is assumed that the destination is at least as large
+**                  as the source, since the source may not actually contain
+**                  any chunks.
+**
+** Returns          The output byte count
+**
+*******************************************************************************/
+extern tNDEF_STATUS NDEF_MsgCopyAndDechunk(uint8_t* p_src, uint32_t src_len,
+                                           uint8_t* p_dest,
+                                           uint32_t* p_out_len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NDEF_UTILS_H */
diff --git a/src/nfc/include/nfc_api.h b/src/nfc/include/nfc_api.h
new file mode 100644
index 0000000..40935a8
--- /dev/null
+++ b/src/nfc/include/nfc_api.h
@@ -0,0 +1,1844 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the Near Field Communication (NFC) API function
+ *  external definitions.
+ *
+ ******************************************************************************/
+
+#ifndef NFC_API_H
+#define NFC_API_H
+
+#include "nfc_target.h"
+#include "nci_defs.h"
+#include "nfc_hal_api.h"
+#include "gki.h"
+#include "vendor_cfg.h"
+
+/* NFC application return status codes */
+/* Command succeeded    */
+#define NFC_STATUS_OK NCI_STATUS_OK
+/* Command is rejected. */
+#define NFC_STATUS_REJECTED NCI_STATUS_REJECTED
+/* Message is corrupted */
+#define NFC_STATUS_MSG_CORRUPTED NCI_STATUS_MESSAGE_CORRUPTED
+/* buffer full          */
+#define NFC_STATUS_BUFFER_FULL NCI_STATUS_BUFFER_FULL
+/* failed               */
+#define NFC_STATUS_FAILED NCI_STATUS_FAILED
+/* not initialized      */
+#define NFC_STATUS_NOT_INITIALIZED NCI_STATUS_NOT_INITIALIZED
+/* Syntax error         */
+#define NFC_STATUS_SYNTAX_ERROR NCI_STATUS_SYNTAX_ERROR
+/* Semantic error       */
+#define NFC_STATUS_SEMANTIC_ERROR NCI_STATUS_SEMANTIC_ERROR
+/* Unknown NCI Group ID */
+#define NFC_STATUS_UNKNOWN_GID NCI_STATUS_UNKNOWN_GID
+/* Unknown NCI Opcode   */
+#define NFC_STATUS_UNKNOWN_OID NCI_STATUS_UNKNOWN_OID
+/* Invalid Parameter    */
+#define NFC_STATUS_INVALID_PARAM NCI_STATUS_INVALID_PARAM
+/* Message size too big */
+#define NFC_STATUS_MSG_SIZE_TOO_BIG NCI_STATUS_MSG_SIZE_TOO_BIG
+/* Already started      */
+#define NFC_STATUS_ALREADY_STARTED NCI_STATUS_ALREADY_STARTED
+/* Activation Failed    */
+#define NFC_STATUS_ACTIVATION_FAILED NCI_STATUS_ACTIVATION_FAILED
+/* Tear Down Error      */
+#define NFC_STATUS_TEAR_DOWN NCI_STATUS_TEAR_DOWN
+/* RF transmission error*/
+#define NFC_STATUS_RF_TRANSMISSION_ERR NCI_STATUS_RF_TRANSMISSION_ERR
+/* RF protocol error    */
+#define NFC_STATUS_RF_PROTOCOL_ERR NCI_STATUS_RF_PROTOCOL_ERR
+/* RF Timeout           */
+#define NFC_STATUS_TIMEOUT NCI_STATUS_TIMEOUT
+/* EE Intf activate err */
+#define NFC_STATUS_EE_INTF_ACTIVE_FAIL NCI_STATUS_EE_INTF_ACTIVE_FAIL
+/* EE transmission error*/
+#define NFC_STATUS_EE_TRANSMISSION_ERR NCI_STATUS_EE_TRANSMISSION_ERR
+/* EE protocol error    */
+#define NFC_STATUS_EE_PROTOCOL_ERR NCI_STATUS_EE_PROTOCOL_ERR
+/* EE Timeout           */
+#define NFC_STATUS_EE_TIMEOUT NCI_STATUS_EE_TIMEOUT
+
+#if (NXP_EXTNS == TRUE)
+#define NFC_STATUS_WIRED_SESSION_ABORTED \
+  NCI_STATUS_WIRED_SESSION_ABORTED /* WIRED_SESSION_ABORT error */
+#define NFC_STATUS_DWP_APDU_DROPPPED \
+  NCI_STATUS_DWP_APDU_DROPPPED /* FW dropped the APDU because UICC switch */
+#define NFC_STATUS_ALREADY_INITIALIZED NCI_STATUS_ALREADY_INITIALIZED
+// DTA API for MW Version need to change according to release
+#define NXP_EN_PN547C2 0
+#define NXP_EN_PN65T 0
+#define NXP_EN_PN548C2 0
+#define NXP_EN_PN66T 0
+#define NXP_EN_PN551 0
+#define NXP_EN_PN67T 0
+#define NXP_EN_PN553 1
+#define NXP_EN_PN80T 1
+#define NXP_EN_PN553_MR1 0
+#define NXP_EN_PN81A     0
+#define NXP_EN_PN553_MR2 0
+#define NXP_EN_PN557     0
+#define NXP_EN_PN81T     0
+#define NXP_ANDROID_VER (8U)        /* NXP android version */
+#define NFC_NXP_MW_VERSION_MAJ (0x01) /* MW Major Version */
+#define NFC_NXP_MW_VERSION_MIN (0x00) /* MW Minor Version */
+#endif
+/* 0xE0 ~0xFF are proprietary status codes */
+/* Command started successfully                     */
+#define NFC_STATUS_CMD_STARTED 0xE3
+#if (NXP_EXTNS == TRUE)
+/* changed from 0xE4 (as 0xE4 is defined for STATUS_EMVCO_PCD_COLLISOIN
+                                             NFCC Timeout in responding to an
+   NCI command     */
+#define NFC_STATUS_HW_TIMEOUT 0xEC
+#else
+/* NFCC Timeout in responding to an NCI command     */
+#define NFC_STATUS_HW_TIMEOUT 0xE4
+#endif
+/* More (same) event to follow                      */
+#define NFC_STATUS_CONTINUE 0xE5
+/* API is called to perform illegal function        */
+#define NFC_STATUS_REFUSED 0xE6
+/* Wrong format of R-APDU, CC file or NDEF file     */
+#define NFC_STATUS_BAD_RESP 0xE7
+/* 7816 Status Word is not command complete(0x9000) */
+#define NFC_STATUS_CMD_NOT_CMPLTD 0xE8
+/* Out of GKI buffers                               */
+#define NFC_STATUS_NO_BUFFERS 0xE9
+/* Protocol mismatch between API and activated one  */
+#define NFC_STATUS_WRONG_PROTOCOL 0xEA
+/* Another Tag command is already in progress       */
+#define NFC_STATUS_BUSY 0xEB
+
+/* Link Loss                  */
+#define NFC_STATUS_LINK_LOSS 0xFC
+/* data len exceeds MIU       */
+#define NFC_STATUS_BAD_LENGTH 0xFD
+/* invalid handle             */
+#define NFC_STATUS_BAD_HANDLE 0xFE
+/* congested                  */
+#define NFC_STATUS_CONGESTED 0xFF
+typedef uint8_t tNFC_STATUS;
+#if (NXP_EXTNS == TRUE)
+#define NFC_NFCC_INIT_MAX_RETRY 2
+#define NFC_NORMAL_BOOT_MODE 0
+#define NFC_FAST_BOOT_MODE 1
+#define NFC_OSU_BOOT_MODE 2
+#define UICC1_HOST ((unsigned char)0x02)
+#define UICC2_HOST ((unsigned char)0x81)
+#define DH_HOST ((unsigned char)0x00)
+#define ESE_HOST ((unsigned char)0xC0)
+#define NXP_FEATURE_ENABLED \
+  ((unsigned char)0x01) /* flag to indicate NXP feature is enabled*/
+#define NXP_FEATURE_DISABLED \
+  ((unsigned char)0x00) /* flag to indicate NXP feature is enabled*/
+#define NXP_NFC_PARAM_SWP_SESSIONID_INT2 ((unsigned char)0xEB)
+#define NXP_NFC_PARAM_SWP_SESSION_ID_LEN 8
+#define NXP_NFC_PROP_MAX_CMD_BUF_SIZE ((unsigned char)0x40)
+#define NXP_NFC_SET_MSB(x) (x |= 0x80)
+#define NXP_NFC_RESET_MSB(x) (x &= 0x7F)
+#define NXP_NFC_ESE_CONN_PIPE_STATUS  ((unsigned char)0x22)
+#define NXP_NFC_ESE_APDU_PIPE_STATUS  ((unsigned char)0x23)
+/**********************************************
+ * NFC Config Parameter IDs defined by NXP NFC
+ **********************************************/
+#define NXP_NFC_SET_CONFIG_PARAM_EXT \
+  ((unsigned char)0xA0) /* NXP NFC set config extension ID*/
+#define NXP_NFC_PARAM_ID_SWP1                \
+  ((unsigned char)0xEC) /* SWP1 parameter ID \
+                           UICC*/
+#define NXP_NFC_PARAM_ID_SWP2                     \
+  ((unsigned char)0xED) /* SWP1 parameter ID  ESE \
+                           */
+#define NXP_NFC_PARAM_ID_SWP1A \
+  ((unsigned char)0xD4) /* SWP1 parameter ID  UICC2 */
+#define NXP_NFC_PARAM_ID_NDEF_NFCEE \
+  ((unsigned char)0x95) /* SWP1 parameter ID  NDEF NFCEE */
+#define NXP_NFC_PARAM_ID_RF_PARAM_UICC \
+  ((unsigned char)0xEF) /* UICC CE RF parameter  */
+#define NXP_NFC_PARAM_ID_RF_PARAM_ESE \
+  ((unsigned char)0xF0) /* ESE RF parameter   */
+#define NXP_NFC_PARAM_ID_NFCC_RF_CONFIG \
+  ((unsigned char)0x9B) /* NFCC RF config parameter*/
+#define NXP_NFC_EMVCO_PCD_COLLISION_DETECTED \
+  ((unsigned char)0xE4) /* Core generic error for EMVCO collision detected */
+#define NXP_NFC_PARAM_ID_RF_PARAM_UICC2 \
+  ((unsigned char)0xE8) /* UICC2 CE RF parameter  */
+#define NXP_NFC_PARAM_SWP_SESSIONID_INT2 \
+  ((unsigned char)0xEB) /* param for retrieveing HCI session ID for ESE */
+#define NXP_NFC_PARAM_SWP_SESSIONID_INT1 \
+  ((unsigned char)0xEA) /* param for retrieveing HCI session ID for UICC */
+#define NXP_NFC_PARAM_SWP_SESSIONID_INT1A \
+  ((unsigned char)0x1E) /* param for retrieveing HCI session ID for UICC2 */
+#endif
+
+/**********************************************
+ * NFC Config Parameter IDs defined by NCI
+ **********************************************/
+#define NFC_PMID_TOTAL_DURATION NCI_PARAM_ID_TOTAL_DURATION
+#define NFC_PMID_CON_DEVICES_LIMIT NCI_PARAM_ID_CON_DEVICES_LIMIT
+#define NFC_PMID_PA_BAILOUT NCI_PARAM_ID_PA_BAILOUT
+#define NFC_PMID_CON_DISCOVERY_PARAM NCI_PARAM_ID_CON_DISCOVERY_PARAM
+#define NFC_PMID_PB_AFI NCI_PARAM_ID_PB_AFI
+#define NFC_PMID_PB_BAILOUT NCI_PARAM_ID_PB_BAILOUT
+#define NFC_PMID_PB_ATTRIB_PARAM1 NCI_PARAM_ID_PB_ATTRIB_PARAM1
+#define NFC_PMID_PF_BIT_RATE NCI_PARAM_ID_PF_BIT_RATE
+#define NFC_PMID_PF_RC NCI_PARAM_ID_PF_RC
+#define NFC_PMID_PB_H_INFO NCI_PARAM_ID_PB_H_INFO
+#define NFC_PMID_BITR_NFC_DEP NCI_PARAM_ID_BITR_NFC_DEP
+#define NFC_PMID_ATR_REQ_GEN_BYTES NCI_PARAM_ID_ATR_REQ_GEN_BYTES
+#define NFC_PMID_ATR_REQ_CONFIG NCI_PARAM_ID_ATR_REQ_CONFIG
+#define NFC_PMID_LA_HIST_BY NCI_PARAM_ID_LA_HIST_BY
+#define NFC_PMID_LA_NFCID1 NCI_PARAM_ID_LA_NFCID1
+#define NFC_PMID_PI_BIT_RATE NCI_PARAM_ID_PI_BIT_RATE
+#define NFC_PMID_LA_BIT_FRAME_SDD NCI_PARAM_ID_LA_BIT_FRAME_SDD
+#define NFC_PMID_LA_PLATFORM_CONFIG NCI_PARAM_ID_LA_PLATFORM_CONFIG
+#define NFC_PMID_LA_SEL_INFO NCI_PARAM_ID_LA_SEL_INFO
+#define NFC_PMID_LI_BIT_RATE NCI_PARAM_ID_LI_BIT_RATE
+#define NFC_PMID_LB_SENSB_INFO NCI_PARAM_ID_LB_SENSB_INFO
+#define NFC_PMID_LB_PROTOCOL NCI_PARAM_ID_LB_PROTOCOL
+#define NFC_PMID_LB_H_INFO NCI_PARAM_ID_LB_H_INFO_RSP
+#define NFC_PMID_LB_NFCID0 NCI_PARAM_ID_LB_NFCID0
+#define NFC_PMID_LB_APPDATA NCI_PARAM_ID_LB_APPDATA
+#define NFC_PMID_LB_SFGI NCI_PARAM_ID_LB_SFGI
+#define NFC_PMID_LB_ADC_FO NCI_PARAM_ID_LB_ADC_FO
+#define NFC_PMID_LF_T3T_ID1 NCI_PARAM_ID_LF_T3T_ID1
+#define NFC_PMID_LF_T3T_ID2 NCI_PARAM_ID_LF_T3T_ID2
+#define NFC_PMID_LF_T3T_ID3 NCI_PARAM_ID_LF_T3T_ID3
+#define NFC_PMID_LF_T3T_ID4 NCI_PARAM_ID_LF_T3T_ID4
+#define NFC_PMID_LF_T3T_ID5 NCI_PARAM_ID_LF_T3T_ID5
+#define NFC_PMID_LF_T3T_ID6 NCI_PARAM_ID_LF_T3T_ID6
+#define NFC_PMID_LF_T3T_ID7 NCI_PARAM_ID_LF_T3T_ID7
+#define NFC_PMID_LF_T3T_ID8 NCI_PARAM_ID_LF_T3T_ID8
+#define NFC_PMID_LF_T3T_ID9 NCI_PARAM_ID_LF_T3T_ID9
+#define NFC_PMID_LF_T3T_ID10 NCI_PARAM_ID_LF_T3T_ID10
+#define NFC_PMID_LF_T3T_ID11 NCI_PARAM_ID_LF_T3T_ID11
+#define NFC_PMID_LF_T3T_ID12 NCI_PARAM_ID_LF_T3T_ID12
+#define NFC_PMID_LF_T3T_ID13 NCI_PARAM_ID_LF_T3T_ID13
+#define NFC_PMID_LF_T3T_ID14 NCI_PARAM_ID_LF_T3T_ID14
+#define NFC_PMID_LF_T3T_ID15 NCI_PARAM_ID_LF_T3T_ID15
+#define NFC_PMID_LF_T3T_ID16 NCI_PARAM_ID_LF_T3T_ID16
+#define NFC_PMID_LF_PROTOCOL NCI_PARAM_ID_LF_PROTOCOL
+#define NFC_PMID_LF_T3T_PMM NCI_PARAM_ID_LF_T3T_PMM
+#define NFC_PMID_LF_T3T_MAX NCI_PARAM_ID_LF_T3T_MAX
+#define NFC_PMID_LF_T3T_FLAGS2 NCI_PARAM_ID_LF_T3T_FLAGS2
+#define NFC_PMID_FWI NCI_PARAM_ID_FWI
+#define NFC_PMID_LF_CON_BITR_F NCI_PARAM_ID_LF_CON_BITR_F
+#define NFC_PMID_WT NCI_PARAM_ID_WT
+#define NFC_PMID_ATR_RES_GEN_BYTES NCI_PARAM_ID_ATR_RES_GEN_BYTES
+#define NFC_PMID_ATR_RSP_CONFIG NCI_PARAM_ID_ATR_RSP_CONFIG
+#define NFC_PMID_RF_FIELD_INFO NCI_PARAM_ID_RF_FIELD_INFO
+#define NFC_PMID_NFC_DEP_OP NCI_PARAM_ID_NFC_DEP_OP
+#define NFC_PARAM_ID_RF_EE_ACTION NCI_PARAM_ID_RF_EE_ACTION
+#define NFC_PARAM_ID_ISO_DEP_OP NCI_PARAM_ID_ISO_DEP_OP
+
+/* Technology based routing  */
+#define NFC_ROUTE_TAG_TECH NCI_ROUTE_TAG_TECH
+/* Protocol based routing  */
+#define NFC_ROUTE_TAG_PROTO NCI_ROUTE_TAG_PROTO
+#define NFC_ROUTE_TAG_AID NCI_ROUTE_TAG_AID /* AID routing */
+#define NFC_ROUTE_TAG_APDU NCI_ROUTE_TAG_APDU /* APDU routing*/
+/* tag, len, 2 byte value for technology/protocol based routing */
+#define NFC_ROUTE_TLV_ENTRY_SIZE 4
+
+/* For routing */
+#define NFC_DH_ID NCI_DH_ID /* for DH */
+/* To identify the loopback test */
+/* use a proprietary range */
+#define NFC_TEST_ID NCI_TEST_ID
+
+typedef uint8_t tNFC_PMID;
+#define NFC_TL_SIZE 2
+#define NFC_SAVED_CMD_SIZE 2
+
+typedef tNCI_DISCOVER_MAPS tNFC_DISCOVER_MAPS;
+typedef tNCI_DISCOVER_PARAMS tNFC_DISCOVER_PARAMS;
+
+/* all NFC Manager Callback functions have prototype like void (cback) (uint8_t
+ * event, void *p_data)
+ * tNFC_DATA_CBACK uses connection id as the first parameter; range 0x00-0x0F.
+ * tNFC_DISCOVER_CBACK uses tNFC_DISCOVER_EVT; range  0x4000 ~
+ * tNFC_RESPONSE_CBACK uses tNFC_RESPONSE_EVT; range  0x5000 ~
+ */
+
+#define NFC_FIRST_DEVT 0x4000
+#define NFC_FIRST_REVT 0x5000
+#define NFC_FIRST_CEVT 0x6000
+#define NFC_FIRST_TEVT 0x8000
+#if (NXP_EXTNS == TRUE)
+void nfc_ncif_onWiredModeHold_timeout();
+void nfc_ncif_allow_dwp_transmission();
+void nfc_ncif_modeSet_Ntf_timeout();
+void nfc_ncif_modeSet_rsp_timeout();
+void nfc_ncif_resume_dwp_wired_mode();
+void nfc_ncif_pwr_link_rsp_timeout();
+/* the events reported on tNFC_RESPONSE_CBACK */
+enum {
+  NFC_ENABLE_REVT = NFC_FIRST_REVT, /* 0  Enable event                  */
+  NFC_DISABLE_REVT,                 /* 1  Disable event                 */
+  NFC_SET_CONFIG_REVT,              /* 2  Set Config Response           */
+  NFC_GET_CONFIG_REVT,              /* 3  Get Config Response           */
+  NFC_NFCEE_DISCOVER_REVT,          /* 4  Discover NFCEE response       */
+  NFC_NFCEE_INFO_REVT,              /* 5  Discover NFCEE Notification   */
+  NFC_NFCEE_MODE_SET_REVT,          /* 6  NFCEE Mode Set response       */
+  NFC_RF_FIELD_REVT,                /* 7  RF Field information          */
+  NFC_EE_ACTION_REVT,               /* 8  EE Action notification        */
+  NFC_EE_DISCOVER_REQ_REVT,         /* 9  EE Discover Req notification  */
+  NFC_SET_ROUTING_REVT,             /* 10 Configure Routing response    */
+  NFC_GET_ROUTING_REVT,             /* 11 Retrieve Routing response     */
+  NFC_RF_COMM_PARAMS_UPDATE_REVT,   /* 12 RF Communication Param Update */
+  NFC_GEN_ERROR_REVT,               /* 13 generic error notification    */
+  NFC_NFCC_RESTART_REVT,            /* 14 NFCC has been re-initialized  */
+  NFC_NFCC_TIMEOUT_REVT,            /* 15 NFCC is not responding        */
+  NFC_NFCC_TRANSPORT_ERR_REVT,      /* 16 NCI Tranport error            */
+  NFC_NFCC_POWER_OFF_REVT,          /* 17 NFCC turned off               */
+  NFC_NFCEE_PL_CONTROL_REVT,              /* NFCEE Power/Link Ctrl response*/
+  NFC_FIRST_VS_REVT,          /* First vendor-specific rsp event  */
+  NFC_NFCEE_PWR_LNK_CTRL_REVT, /* PWR LINK CTRL Event for Wired Mode standby */
+  NFC_NFCEE_STATUS_REVT                  /* NFCEE Status Notification     */
+#if (NXP_EXTNS == TRUE)
+  ,
+  NFC_NFCEE_MODE_SET_INFO /*  NFCEE Mode Set Notification*/
+#endif
+  ,NFC_SET_POWER_SUB_STATE_REVT     /* 18 Set power sub state response  */
+};
+typedef uint16_t tNFC_RESPONSE_EVT;
+
+enum {
+  NFC_CONN_CREATE_CEVT = NFC_FIRST_CEVT, /* 0  Conn Create Response          */
+  NFC_CONN_CLOSE_CEVT,                   /* 1  Conn Close Response           */
+  NFC_DEACTIVATE_CEVT,                   /* 2  Deactivate response/notificatn*/
+  NFC_DATA_CEVT,                         /* 3  Data                          */
+  NFC_ERROR_CEVT,                        /* 4  generic or interface error    */
+  NFC_DATA_START_CEVT, /* 5  received the first fragment on RF link */
+#if (NXP_EXTNS == TRUE)
+  NFC_RF_WTX_CEVT, /* 6  received rf wtx */
+#endif
+  NFC_RF_TRANSMISSION_ERROR, /* 7 CE Error events */
+  NFC_HCI_RESTART_TIMER
+};
+typedef uint16_t tNFC_CONN_EVT;
+
+#define NFC_NFCC_INFO_LEN 4
+#ifndef NFC_NFCC_MAX_NUM_VS_INTERFACE
+#define NFC_NFCC_MAX_NUM_VS_INTERFACE 5
+#endif
+typedef struct {
+  tNFC_STATUS status;                   /* The event status.                */
+  uint8_t nci_version;                  /* the NCI version of NFCC          */
+  uint8_t max_conn;                     /* max number of connections by NFCC*/
+  uint32_t nci_features;                /* the NCI features of NFCC         */
+  uint16_t nci_interfaces;              /* the NCI interfaces of NFCC       */
+  uint16_t max_ce_table;                /* the max routing table size       */
+  uint16_t max_param_size;              /* Max Size for Large Parameters    */
+  uint8_t manufacture_id;               /* the Manufacture ID for NFCC      */
+  uint8_t nfcc_info[NFC_NFCC_INFO_LEN]; /* the Manufacture Info for NFCC      */
+  uint8_t vs_interface
+      [NFC_NFCC_MAX_NUM_VS_INTERFACE]; /* the NCI VS interfaces of NFCC    */
+  uint8_t hci_packet_size;             /*HCI payload size*/
+  uint8_t hci_conn_credits;            /*max number of HCI credits*/
+  uint16_t max_nfc_v_size;        /* maximum frame size for NFC-V*/
+} tNFC_ENABLE_REVT;
+
+
+#define NFC_MAX_NUM_IDS 125
+/* the data type associated with NFC_SET_CONFIG_REVT */
+typedef struct {
+  tNFC_STATUS status;                 /* The event status.                */
+  uint8_t num_param_id;               /* Number of rejected NCI Param ID  */
+  uint8_t param_ids[NFC_MAX_NUM_IDS]; /* NCI Param ID          */
+} tNFC_SET_CONFIG_REVT;
+
+/* the data type associated with NFC_GET_CONFIG_REVT */
+typedef struct {
+  tNFC_STATUS status;    /* The event status.    */
+  uint16_t tlv_size;     /* The length of TLV    */
+  uint8_t* p_param_tlvs; /* TLV                  */
+} tNFC_GET_CONFIG_REVT;
+
+#if (NXP_EXTNS == TRUE)
+/* This data type is for FW Version */
+typedef struct {
+  uint8_t rom_code_version; /* ROM code Version  */
+  uint8_t major_version;    /* Major Version */
+  uint8_t minor_version;    /* Minor Version  */
+} tNFC_FW_VERSION;
+
+typedef struct {
+  tNFC_STATUS status;
+  uint8_t nfcee_id;
+} tNFC_NFCEE_MODE_SET_INFO;
+
+#define ESE_STATE_JCOP_DWNLD                                      \
+  0x8000 /* Depicts the state of Jcop download to be matched with \
+            P61_STATE_JCP_DWNLD                                   \
+            under p61_access_state_t inside pn553.h(NFCC driver header) */
+
+typedef enum jcop_dwnld_state {
+  JCP_DWNLD_IDLE = ESE_STATE_JCOP_DWNLD, /* jcop dwnld is not ongoing*/
+  JCP_DWNLD_INIT = 0x8010,               /* jcop dwonload init state*/
+  JCP_DWNLD_START = 0x8020,              /* download started */
+  JCP_SPI_DWNLD_COMPLETE = 0x8040, /* jcop download complete in spi interface*/
+  JCP_DWP_DWNLD_COMPLETE = 0x8080, /* jcop download complete */
+} jcop_dwnld_state_t;
+#endif
+
+/* the data type associated with NFC_NFCEE_DISCOVER_REVT */
+typedef struct {
+  tNFC_STATUS status; /* The event status.    */
+  uint8_t num_nfcee;  /* The number of NFCEE  */
+} tNFC_NFCEE_DISCOVER_REVT;
+
+#define NFC_NFCEE_INTERFACE_APDU NCI_NFCEE_INTERFACE_APDU
+#define NFC_NFCEE_INTERFACE_HCI_ACCESS NCI_NFCEE_INTERFACE_HCI_ACCESS
+#define NFC_NFCEE_INTERFACE_T3T NCI_NFCEE_INTERFACE_T3T
+#define NFC_NFCEE_INTERFACE_TRANSPARENT NCI_NFCEE_INTERFACE_TRANSPARENT
+#define NFC_NFCEE_INTERFACE_PROPRIETARY NCI_NFCEE_INTERFACE_PROPRIETARY
+typedef uint8_t tNFC_NFCEE_INTERFACE;
+
+#define NFC_NFCEE_TAG_HW_ID NCI_NFCEE_TAG_HW_ID
+#define NFC_NFCEE_TAG_ATR_BYTES NCI_NFCEE_TAG_ATR_BYTES
+#define NFC_NFCEE_TAG_T3T_INFO NCI_NFCEE_TAG_T3T_INFO
+#define NFC_NFCEE_TAG_HCI_HOST_ID NCI_NFCEE_TAG_HCI_HOST_ID
+#if (NXP_EXTNS == TRUE)
+typedef uint16_t tNFC_NFCEE_TAG;
+#else
+typedef uint8_t tNFC_NFCEE_TAG;
+#endif
+/* additional NFCEE Info */
+typedef struct {
+  tNFC_NFCEE_TAG tag;
+  uint8_t len;
+  uint8_t info[NFC_MAX_EE_INFO];
+} tNFC_NFCEE_TLV;
+
+#define NFC_NFCEE_STS_UNRECOVERABLE_ERROR   NCI_NFCEE_STS_UNRECOVERABLE_ERROR
+#define NFC_NFCEE_STS_INIT_STARTED          NCI_NFCEE_STS_INIT_STARTED
+#define NFC_NFCEE_STS_INIT_COMPLETED        NCI_NFCEE_STS_INIT_COMPLETED
+
+/* NFCEE connected and inactive */
+#define NFC_NFCEE_STATUS_INACTIVE NCI_NFCEE_STS_CONN_INACTIVE
+/* NFCEE connected and active   */
+#define NFC_NFCEE_STATUS_ACTIVE NCI_NFCEE_STS_CONN_ACTIVE
+/* NFCEE removed                */
+#define NFC_NFCEE_STATUS_REMOVED NCI_NFCEE_STS_REMOVED
+/* the data type associated with NFC_NFCEE_INFO_REVT */
+#define NFC_NFCEE_STS_INTF_ACTIVATION_FAILED NCI_NFCEE_STS_INTF_ACTIVATION_FAILED
+#define NFC_NFCEE_STS_TRANSMISSION_ERROR     NCI_NFCEE_STS_TRANSMISSION_ERROR
+#define NFC_NFCEE_STS_PROTOCOL_ERROR         NCI_NFCEE_STS_PROTOCOL_ERROR
+#define NFC_NFCEE_STS_TIMEOUT_ERROR          NCI_NFCEE_STS_TIMEOUT_ERROR
+
+typedef struct {
+  tNFC_STATUS status;    /* The event status - place holder  */
+  uint8_t nfcee_id;      /* NFCEE ID                         */
+  uint8_t ee_status;     /* The NFCEE status.                */
+  uint8_t num_interface; /* number of NFCEE interfaces       */
+  uint8_t ee_interface[NFC_MAX_EE_INTERFACE]; /* NFCEE interface       */
+  uint8_t num_tlvs;                       /* number of TLVs                   */
+  tNFC_NFCEE_TLV ee_tlv[NFC_MAX_EE_TLVS]; /* The TLVs associated with NFCEE   */
+  bool  nfcee_power_ctrl;       /* 1, if NFCC has control of NFCEE Power Supply */
+} tNFC_NFCEE_INFO_REVT;
+
+#define NFC_MODE_ACTIVATE NCI_NFCEE_MD_ACTIVATE
+#define NFC_MODE_DEACTIVATE NCI_NFCEE_MD_DEACTIVATE
+typedef uint8_t tNFC_NFCEE_MODE;
+/* the data type associated with NFC_NFCEE_MODE_SET_REVT */
+typedef struct {
+  tNFC_STATUS status;   /* The event status.*/
+  uint8_t nfcee_id;     /* NFCEE ID         */
+  tNFC_NFCEE_MODE mode; /* NFCEE mode       */
+} tNFC_NFCEE_MODE_SET_REVT;
+
+typedef struct {
+  tNFC_STATUS status; /* The event status.*/
+  uint8_t nfcee_id;   /* NFCEE ID         */
+} tNFC_NFCEE_EE_PWR_LNK_REVT;
+
+#define NFC_MAX_AID_LEN NCI_MAX_AID_LEN /* 16 */
+#define NFC_MIN_APDU_DATA_LEN NCI_MIN_APDU_DATA_LEN
+#define NFC_MIN_APDU_MASK_LEN NCI_MIN_APDU_MASK_LEN
+#define NFC_MAX_APDU_DATA_LEN NCI_MAX_APDU_DATA_LEN
+#define NFC_MAX_APDU_MASK_LEN NCI_MAX_APDU_MASK_LEN
+/* the data type associated with NFC_CE_GET_ROUTING_REVT */
+
+/* Max payload size  */
+#define NFC_MAX_GET_ROUTING_PLD_SIZE 255
+
+typedef struct {
+  tNFC_STATUS status; /* The event status                 */
+  uint8_t nfcee_id;   /* NFCEE ID                         */
+  uint8_t num_tlvs;   /* number of TLVs                   */
+  uint8_t tlv_size;   /* the total len of all TLVs        */
+  uint8_t param_tlvs[NFC_MAX_GET_ROUTING_PLD_SIZE]; /* the TLVs*/
+} tNFC_GET_ROUTING_REVT;
+
+/* the data type associated with NFC_CONN_CREATE_CEVT */
+typedef struct {
+  tNFC_STATUS status; /* The event status                 */
+  uint8_t dest_type;  /* the destination type             */
+  uint8_t id;         /* NFCEE ID  or RF Discovery ID     */
+  uint8_t buff_size;  /* The max buffer size              */
+  uint8_t num_buffs;  /* The number of buffers            */
+} tNFC_CONN_CREATE_CEVT;
+
+/* the data type associated with NFC_CONN_CLOSE_CEVT */
+typedef struct {
+  tNFC_STATUS status; /* The event status                 */
+} tNFC_CONN_CLOSE_CEVT;
+
+/* the data type associated with NFC_DATA_CEVT */
+typedef struct {
+  tNFC_STATUS status; /* The event status                 */
+  NFC_HDR* p_data;    /* The received Data                */
+} tNFC_DATA_CEVT;
+
+/* the data type associated with NFC_NFCEE_PL_CONTROL_REVT */
+typedef struct
+{
+    tNFC_STATUS             status;                 /* The event status.*/
+    uint8_t                   nfcee_id;               /* NFCEE ID         */
+    tNCI_NFCEE_PL_CONFIG    pl_control;             /* Power/Link Control Config of the original command */
+} tNFC_NFCEE_PL_CONTROL_REVT;
+
+/* the data type associated with NFC_NFCEE_STATUS_REVT */
+typedef struct
+{
+    tNFC_STATUS             status;                 /* The event status.*/
+    uint8_t                   nfcee_id;               /* NFCEE ID         */
+    tNCI_EE_NTF_STATUS      nfcee_status;           /* NFCEE status     */
+} tNFC_NFCEE_STATUS_REVT;
+
+/* RF Field Status */
+/* No field generated by remote device  */
+#define NFC_RF_STS_NO_REMOTE NCI_RF_STS_NO_REMOTE
+/* field generated by remote device     */
+#define NFC_RF_STS_REMOTE NCI_RF_STS_REMOTE
+typedef uint8_t tNFC_RF_STS;
+
+/* RF Field Technologies */
+#define NFC_RF_TECHNOLOGY_A NCI_RF_TECHNOLOGY_A
+#define NFC_RF_TECHNOLOGY_B NCI_RF_TECHNOLOGY_B
+#define NFC_RF_TECHNOLOGY_F NCI_RF_TECHNOLOGY_F
+#define NFC_RF_TECHNOLOGY_15693 NCI_RF_TECHNOLOGY_15693
+typedef uint8_t tNFC_RF_TECH;
+
+extern uint8_t NFC_GetNCIVersion();
+/* Supported Protocols */
+#define NFC_PROTOCOL_UNKNOWN NCI_PROTOCOL_UNKNOWN /* Unknown */
+/* Type1Tag    - NFC-A            */
+#define NFC_PROTOCOL_T1T NCI_PROTOCOL_T1T
+/* Type2Tag    - NFC-A            */
+#define NFC_PROTOCOL_T2T NCI_PROTOCOL_T2T
+/* Type3Tag    - NFC-F            */
+#define NFC_PROTOCOL_T3T NCI_PROTOCOL_T3T
+/* Type 4A,4B  - NFC-A or NFC-B   */
+#define NFC_PROTOCOL_ISO_DEP NCI_PROTOCOL_ISO_DEP
+/* NFCDEP/LLCP - NFC-A or NFC-F       */
+#define NFC_PROTOCOL_NFC_DEP NCI_PROTOCOL_NFC_DEP
+#define NFC_PROTOCOL_MIFARE NCI_PROTOCOL_MIFARE
+#if (NXP_EXTNS == TRUE)
+#define NFC_PROTOCOL_ISO7816 \
+  NCI_PROTOCOL_ISO7816 /*ISO7816 -AID default Routing */
+#define NFC_PROTOCOL_T3BT NCI_PROTOCOL_T3BT
+#endif
+#define NFC_PROTOCOL_B_PRIME NCI_PROTOCOL_B_PRIME
+#define NFC_PROTOCOL_15693 NCI_PROTOCOL_15693
+#define NFC_PROTOCOL_KOVIO NCI_PROTOCOL_KOVIO
+typedef uint8_t tNFC_PROTOCOL;
+
+/* Discovery Types/Detected Technology and Mode */
+#define NFC_DISCOVERY_TYPE_POLL_A NCI_DISCOVERY_TYPE_POLL_A
+#define NFC_DISCOVERY_TYPE_POLL_B NCI_DISCOVERY_TYPE_POLL_B
+#define NFC_DISCOVERY_TYPE_POLL_F NCI_DISCOVERY_TYPE_POLL_F
+#define NFC_DISCOVERY_TYPE_POLL_A_ACTIVE NCI_DISCOVERY_TYPE_POLL_A_ACTIVE
+#define NFC_DISCOVERY_TYPE_POLL_F_ACTIVE NCI_DISCOVERY_TYPE_POLL_F_ACTIVE
+#define NFC_DISCOVERY_TYPE_POLL_ISO15693 NCI_DISCOVERY_TYPE_POLL_ISO15693
+#define NFC_DISCOVERY_TYPE_POLL_B_PRIME NCI_DISCOVERY_TYPE_POLL_B_PRIME
+#define NFC_DISCOVERY_TYPE_POLL_KOVIO NCI_DISCOVERY_TYPE_POLL_KOVIO
+#define NFC_DISCOVERY_TYPE_LISTEN_A NCI_DISCOVERY_TYPE_LISTEN_A
+#define NFC_DISCOVERY_TYPE_LISTEN_B NCI_DISCOVERY_TYPE_LISTEN_B
+#define NFC_DISCOVERY_TYPE_LISTEN_F NCI_DISCOVERY_TYPE_LISTEN_F
+#define NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE NCI_DISCOVERY_TYPE_LISTEN_A_ACTIVE
+#define NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE
+#define NFC_DISCOVERY_TYPE_LISTEN_ISO15693 NCI_DISCOVERY_TYPE_LISTEN_ISO15693
+#define NFC_DISCOVERY_TYPE_LISTEN_B_PRIME NCI_DISCOVERY_TYPE_LISTEN_B_PRIME
+typedef uint8_t tNFC_DISCOVERY_TYPE;
+typedef uint8_t tNFC_RF_TECH_N_MODE;
+
+/* Select Response codes */
+#define NFC_SEL_RES_NFC_FORUM_T2T 0x00
+#define NFC_SEL_RES_MF_CLASSIC 0x08
+
+#define  NCI_CALCULATE_ACK(a,v) {a &=  ((1 << v) -1);}
+#define  MAX_NUM_VALID_BITS_FOR_ACK      0x07
+/* Bit Rates */
+#define NFC_BIT_RATE_106 NCI_BIT_RATE_106   /* 106 kbit/s */
+#define NFC_BIT_RATE_212 NCI_BIT_RATE_212   /* 212 kbit/s */
+#define NFC_BIT_RATE_424 NCI_BIT_RATE_424   /* 424 kbit/s */
+#define NFC_BIT_RATE_848 NCI_BIT_RATE_848   /* 848 Kbit/s */
+#define NFC_BIT_RATE_1696 NCI_BIT_RATE_1696 /* 1696 Kbit/s*/
+#define NFC_BIT_RATE_3392 NCI_BIT_RATE_3392 /* 3392 Kbit/s*/
+#define NFC_BIT_RATE_6784 NCI_BIT_RATE_6784 /* 6784 Kbit/s*/
+typedef uint8_t tNFC_BIT_RATE;
+
+/**********************************************
+ * Interface Types
+ **********************************************/
+#define NFC_INTERFACE_EE_DIRECT_RF NCI_INTERFACE_EE_DIRECT_RF
+#define NFC_INTERFACE_FRAME NCI_INTERFACE_FRAME
+#define NFC_INTERFACE_ISO_DEP NCI_INTERFACE_ISO_DEP
+#define NFC_INTERFACE_NDEF NCI_INTERFACE_NDEF
+#define NFC_INTERFACE_NFC_DEP NCI_INTERFACE_NFC_DEP
+#define NFC_INTERFACE_LLCP_LOW NCI_INTERFACE_LLCP_LOW
+#define NFC_INTERFACE_LLCP_HIGH NCI_INTERFACE_LLCP_HIGH
+#define NFC_INTERFACE_VS_T2T_CE NCI_INTERFACE_VS_T2T_CE
+#define NFC_INTERFACE_MIFARE NCI_INTERFACE_VS_MIFARE
+typedef tNCI_INTF_TYPE tNFC_INTF_TYPE;
+
+/**********************************************
+ *  Deactivation Type
+ **********************************************/
+#define NFC_DEACTIVATE_TYPE_IDLE NCI_DEACTIVATE_TYPE_IDLE
+#define NFC_DEACTIVATE_TYPE_SLEEP NCI_DEACTIVATE_TYPE_SLEEP
+#define NFC_DEACTIVATE_TYPE_SLEEP_AF NCI_DEACTIVATE_TYPE_SLEEP_AF
+#define NFC_DEACTIVATE_TYPE_DISCOVERY NCI_DEACTIVATE_TYPE_DISCOVERY
+typedef uint8_t tNFC_DEACT_TYPE;
+
+/**********************************************
+ *  Deactivation Reasons
+ **********************************************/
+#define NFC_DEACTIVATE_REASON_DH_REQ NCI_DEACTIVATE_REASON_DH_REQ
+#define NFC_DEACTIVATE_REASON_ENDPOINT_REQ NCI_DEACTIVATE_REASON_ENDPOINT_REQ
+#define NFC_DEACTIVATE_REASON_RF_LINK_LOSS NCI_DEACTIVATE_REASON_RF_LINK_LOSS
+#define NFC_DEACTIVATE_REASON_NFCB_BAD_AFI NCI_DEACTIVATE_REASON_NFCB_BAD_AFI
+typedef uint8_t tNFC_DEACT_REASON;
+
+/* the data type associated with NFC_RF_FIELD_REVT */
+typedef struct {
+  tNFC_STATUS status;   /* The event status - place holder. */
+  tNFC_RF_STS rf_field; /* RF Field Status                  */
+} tNFC_RF_FIELD_REVT;
+
+#define NFC_MAX_APP_DATA_LEN 40
+typedef struct {
+  uint8_t len_aid;              /* length of application id */
+  uint8_t aid[NFC_MAX_AID_LEN]; /* application id           */
+} tNFC_AID;
+typedef struct {
+  uint8_t len_aid;                    /* length of application id */
+  uint8_t aid[NFC_MAX_AID_LEN];       /* application id           */
+  uint8_t len_data;                   /* len of application data  */
+  uint8_t data[NFC_MAX_APP_DATA_LEN]; /* application data    */
+} tNFC_APP_INIT;
+
+/* ISO 7816-4 SELECT command */
+#define NFC_EE_TRIG_SELECT NCI_EE_TRIG_7816_SELECT
+/* RF Protocol changed       */
+#define NFC_EE_TRIG_RF_PROTOCOL NCI_EE_TRIG_RF_PROTOCOL
+/* RF Technology changed     */
+#define NFC_EE_TRIG_RF_TECHNOLOGY NCI_EE_TRIG_RF_TECHNOLOGY
+/* Application initiation    */
+#define NFC_EE_TRIG_APP_INIT NCI_EE_TRIG_APP_INIT
+typedef uint8_t tNFC_EE_TRIGGER;
+typedef struct {
+  tNFC_EE_TRIGGER trigger; /* the trigger of this event        */
+  union {
+    tNFC_PROTOCOL protocol;
+    tNFC_RF_TECH technology;
+    tNFC_AID aid;
+    tNFC_APP_INIT app_init;
+  } param; /* Discovery Type specific parameters */
+} tNFC_ACTION_DATA;
+
+/* the data type associated with NFC_EE_ACTION_REVT */
+typedef struct {
+  tNFC_STATUS status;        /* The event status - place holder  */
+  uint8_t nfcee_id;          /* NFCEE ID                         */
+  tNFC_ACTION_DATA act_data; /* data associated /w the action    */
+} tNFC_EE_ACTION_REVT;
+
+#define NFC_EE_DISC_OP_ADD 0
+#define NFC_EE_DISC_OP_REMOVE 1
+typedef uint8_t tNFC_EE_DISC_OP;
+typedef struct {
+  tNFC_EE_DISC_OP op;              /* add or remove this entry         */
+  uint8_t nfcee_id;                /* NFCEE ID                         */
+  tNFC_RF_TECH_N_MODE tech_n_mode; /* Discovery Technology and Mode    */
+  tNFC_PROTOCOL protocol;          /* NFC protocol                     */
+} tNFC_EE_DISCOVER_INFO;
+
+#ifndef NFC_MAX_EE_DISC_ENTRIES
+#define NFC_MAX_EE_DISC_ENTRIES 6
+#endif
+/* T, L, V(NFCEE ID, TechnMode, Protocol) */
+#define NFC_EE_DISCOVER_ENTRY_LEN 5
+#define NFC_EE_DISCOVER_INFO_LEN 3 /* NFCEE ID, TechnMode, Protocol */
+/* the data type associated with NFC_EE_DISCOVER_REQ_REVT */
+typedef struct {
+  tNFC_STATUS status; /* The event status - place holder  */
+  uint8_t num_info;   /* number of entries in info[]      */
+  tNFC_EE_DISCOVER_INFO
+      info[NFC_MAX_EE_DISC_ENTRIES]; /* discovery request from NFCEE */
+} tNFC_EE_DISCOVER_REQ_REVT;
+
+typedef union {
+  tNFC_STATUS status; /* The event status. */
+  tNFC_ENABLE_REVT enable;
+  tNFC_SET_CONFIG_REVT set_config;
+  tNFC_GET_CONFIG_REVT get_config;
+  tNFC_NFCEE_DISCOVER_REVT nfcee_discover;
+  tNFC_NFCEE_INFO_REVT nfcee_info;
+  tNFC_NFCEE_MODE_SET_REVT mode_set;
+#if (NXP_EXTNS == TRUE)
+  tNFC_NFCEE_MODE_SET_INFO mode_set_info;
+  tNFC_NFCEE_EE_PWR_LNK_REVT pwr_lnk_ctrl;
+#endif
+  tNFC_NFCEE_PL_CONTROL_REVT  pl_control;
+  tNFC_NFCEE_STATUS_REVT  nfcee_status;
+  tNFC_RF_FIELD_REVT rf_field;
+  tNFC_STATUS cfg_routing;
+  tNFC_GET_ROUTING_REVT get_routing;
+  tNFC_EE_ACTION_REVT ee_action;
+  tNFC_EE_DISCOVER_REQ_REVT ee_discover_req;
+  void* p_vs_evt_data;
+} tNFC_RESPONSE;
+
+/*************************************
+**  RESPONSE Callback Functions
+**************************************/
+typedef void(tNFC_RESPONSE_CBACK)(tNFC_RESPONSE_EVT event,
+                                  tNFC_RESPONSE* p_data);
+
+/* The events reported on tNFC_VS_CBACK */
+/* The event is (NCI_RSP_BIT|oid) for response and (NCI_NTF_BIT|oid) for
+ * notification*/
+
+typedef uint8_t tNFC_VS_EVT;
+
+/*************************************
+**  Proprietary (Vendor Specific) Callback Functions
+**************************************/
+typedef void(tNFC_VS_CBACK)(tNFC_VS_EVT event, uint16_t data_len,
+                            uint8_t* p_data);
+
+/* the events reported on tNFC_DISCOVER_CBACK */
+enum {
+  NFC_START_DEVT = NFC_FIRST_DEVT, /* Status of NFC_DiscoveryStart     */
+  NFC_MAP_DEVT,                    /* Status of NFC_DiscoveryMap       */
+  NFC_RESULT_DEVT,                 /* The responses from remote device */
+  NFC_SELECT_DEVT,                 /* Status of NFC_DiscoverySelect    */
+  NFC_ACTIVATE_DEVT,               /* RF interface is activated        */
+  NFC_DEACTIVATE_DEVT              /* Status of RF deactivation        */
+};
+typedef uint16_t tNFC_DISCOVER_EVT;
+
+/* the data type associated with NFC_START_DEVT */
+typedef tNFC_STATUS tNFC_START_DEVT;
+
+typedef tNCI_RF_PA_PARAMS tNFC_RF_PA_PARAMS;
+#define NFC_MAX_SENSB_RES_LEN NCI_MAX_SENSB_RES_LEN
+#define NFC_NFCID0_MAX_LEN 4
+#if (NXP_EXTNS == TRUE)
+#define NFC_PUPIID_MAX_LEN 8
+#endif
+typedef struct {
+  uint8_t sensb_res_len; /* Length of SENSB_RES Response (Byte 2 - Byte 12 or
+                            13) Available after Technology Detection */
+  uint8_t sensb_res[NFC_MAX_SENSB_RES_LEN]; /* SENSB_RES Response (ATQ) */
+  uint8_t nfcid0[NFC_NFCID0_MAX_LEN];
+#if (NXP_EXTNS == TRUE)
+  uint8_t pupiid_len;
+  uint8_t pupiid[NFC_PUPIID_MAX_LEN];
+#endif
+} tNFC_RF_PB_PARAMS;
+
+#define NFC_MAX_SENSF_RES_LEN NCI_MAX_SENSF_RES_LEN
+#define NFC_NFCID2_LEN NCI_NFCID2_LEN
+typedef struct {
+  uint8_t bit_rate;      /* NFC_BIT_RATE_212 or NFC_BIT_RATE_424 */
+  uint8_t sensf_res_len; /* Length of SENSF_RES Response (Byte 2 - Byte 17 or
+                            19) Available after Technology Detection */
+  uint8_t sensf_res[NFC_MAX_SENSF_RES_LEN]; /* SENSB_RES Response */
+  uint8_t nfcid2[NFC_NFCID2_LEN]; /* NFCID2 generated by the Local NFCC for
+                                     NFC-DEP Protocol.Available for Frame
+                                     Interface  */
+  uint8_t mrti_check;
+  uint8_t mrti_update;
+} tNFC_RF_PF_PARAMS;
+
+typedef tNCI_RF_LF_PARAMS tNFC_RF_LF_PARAMS;
+
+#define NFC_ISO15693_UID_LEN 8
+typedef struct {
+  uint8_t flag;
+  uint8_t dsfid;
+  uint8_t uid[NFC_ISO15693_UID_LEN];
+} tNFC_RF_PISO15693_PARAMS;
+
+#ifndef NFC_KOVIO_MAX_LEN
+#define NFC_KOVIO_MAX_LEN 32
+#endif
+typedef struct {
+  uint8_t uid_len;
+  uint8_t uid[NFC_KOVIO_MAX_LEN];
+} tNFC_RF_PKOVIO_PARAMS;
+
+typedef union {
+  tNFC_RF_PA_PARAMS pa;
+  tNFC_RF_PB_PARAMS pb;
+  tNFC_RF_PF_PARAMS pf;
+  tNFC_RF_LF_PARAMS lf;
+  tNFC_RF_PISO15693_PARAMS pi93;
+  tNFC_RF_PKOVIO_PARAMS pk;
+} tNFC_RF_TECH_PARAMU;
+
+typedef struct {
+  tNFC_DISCOVERY_TYPE mode;
+  tNFC_RF_TECH_PARAMU param;
+} tNFC_RF_TECH_PARAMS;
+
+/* the data type associated with NFC_RESULT_DEVT */
+typedef struct {
+  tNFC_STATUS status;                /* The event status - place holder.  */
+  uint8_t rf_disc_id;                /* RF Discovery ID                   */
+  uint8_t protocol;                  /* supported protocol                */
+  tNFC_RF_TECH_PARAMS rf_tech_param; /* RF technology parameters          */
+  uint8_t more;                      /* 0: last, 1: last (limit), 2: more */
+} tNFC_RESULT_DEVT;
+
+/* the data type associated with NFC_SELECT_DEVT */
+typedef tNFC_STATUS tNFC_SELECT_DEVT;
+
+/* the data type associated with NFC_STOP_DEVT */
+typedef tNFC_STATUS tNFC_STOP_DEVT;
+
+#define NFC_MAX_ATS_LEN NCI_MAX_ATS_LEN
+#define NFC_MAX_HIS_BYTES_LEN NCI_MAX_HIS_BYTES_LEN
+#define NFC_MAX_GEN_BYTES_LEN NCI_MAX_GEN_BYTES_LEN
+
+typedef struct {
+  uint8_t ats_res_len;              /* Length of ATS RES                */
+  uint8_t ats_res[NFC_MAX_ATS_LEN]; /* ATS RES                          */
+  bool nad_used;                    /* NAD is used or not               */
+  uint8_t fwi;                      /* Frame Waiting time Integer       */
+  uint8_t sfgi;                     /* Start-up Frame Guard time Integer*/
+  uint8_t his_byte_len;             /* len of historical bytes          */
+  uint8_t his_byte[NFC_MAX_HIS_BYTES_LEN]; /* historical bytes             */
+} tNFC_INTF_PA_ISO_DEP;
+
+typedef struct { uint8_t rats; /* RATS */ } tNFC_INTF_LA_ISO_DEP;
+
+typedef struct {
+  uint8_t atr_res_len;                      /* Length of ATR_RES            */
+  uint8_t atr_res[NFC_MAX_ATS_LEN];         /* ATR_RES (Byte 3 - Byte 17+n) */
+  uint8_t max_payload_size;                 /* 64, 128, 192 or 254          */
+  uint8_t gen_bytes_len;                    /* len of general bytes         */
+  uint8_t gen_bytes[NFC_MAX_GEN_BYTES_LEN]; /* general bytes           */
+  uint8_t
+      waiting_time; /* WT -> Response Waiting Time RWT = (256 x 16/fC) x 2WT */
+} tNFC_INTF_PA_NFC_DEP;
+
+/* Note: keep tNFC_INTF_PA_NFC_DEP data member in the same order as
+ * tNFC_INTF_LA_NFC_DEP */
+typedef struct {
+  uint8_t atr_req_len;                      /* Length of ATR_REQ            */
+  uint8_t atr_req[NFC_MAX_ATS_LEN];         /* ATR_REQ (Byte 3 - Byte 18+n) */
+  uint8_t max_payload_size;                 /* 64, 128, 192 or 254          */
+  uint8_t gen_bytes_len;                    /* len of general bytes         */
+  uint8_t gen_bytes[NFC_MAX_GEN_BYTES_LEN]; /* general bytes           */
+} tNFC_INTF_LA_NFC_DEP;
+typedef tNFC_INTF_LA_NFC_DEP tNFC_INTF_LF_NFC_DEP;
+typedef tNFC_INTF_PA_NFC_DEP tNFC_INTF_PF_NFC_DEP;
+
+#define NFC_MAX_ATTRIB_LEN NCI_MAX_ATTRIB_LEN
+
+typedef struct {
+  uint8_t attrib_res_len;                 /* Length of ATTRIB RES      */
+  uint8_t attrib_res[NFC_MAX_ATTRIB_LEN]; /* ATTRIB RES                */
+  uint8_t hi_info_len;                    /* len of Higher layer Info  */
+  uint8_t hi_info[NFC_MAX_GEN_BYTES_LEN]; /* Higher layer Info         */
+  uint8_t mbli;                           /* Maximum buffer length.    */
+} tNFC_INTF_PB_ISO_DEP;
+
+typedef struct {
+  uint8_t attrib_req_len;                 /* Length of ATTRIB REQ      */
+  uint8_t attrib_req[NFC_MAX_ATTRIB_LEN]; /* ATTRIB REQ (Byte 2 - 10+k)*/
+  uint8_t hi_info_len;                    /* len of Higher layer Info  */
+  uint8_t hi_info[NFC_MAX_GEN_BYTES_LEN]; /* Higher layer Info         */
+  uint8_t nfcid0[NFC_NFCID0_MAX_LEN];     /* NFCID0                    */
+} tNFC_INTF_LB_ISO_DEP;
+
+#ifndef NFC_MAX_RAW_PARAMS
+#define NFC_MAX_RAW_PARAMS 16
+#endif
+#define NFC_MAX_RAW_PARAMS 16
+typedef struct {
+  uint8_t param_len;
+  uint8_t param[NFC_MAX_RAW_PARAMS];
+} tNFC_INTF_FRAME;
+
+typedef struct {
+  tNFC_INTF_TYPE type; /* Interface Type  1 Byte  See Table 67 */
+  union {
+    tNFC_INTF_LA_ISO_DEP la_iso;
+    tNFC_INTF_PA_ISO_DEP pa_iso;
+    tNFC_INTF_LB_ISO_DEP lb_iso;
+    tNFC_INTF_PB_ISO_DEP pb_iso;
+    tNFC_INTF_LA_NFC_DEP la_nfc;
+    tNFC_INTF_PA_NFC_DEP pa_nfc;
+    tNFC_INTF_LF_NFC_DEP lf_nfc;
+    tNFC_INTF_PF_NFC_DEP pf_nfc;
+    tNFC_INTF_FRAME frame;
+  } intf_param; /* Activation Parameters   0 - n Bytes */
+} tNFC_INTF_PARAMS;
+
+/* the data type associated with NFC_ACTIVATE_DEVT */
+typedef struct {
+  uint8_t rf_disc_id;                /* RF Discovery ID          */
+  tNFC_PROTOCOL protocol;            /* supported protocol       */
+  tNFC_RF_TECH_PARAMS rf_tech_param; /* RF technology parameters */
+  tNFC_DISCOVERY_TYPE data_mode;     /* for future Data Exchange */
+  tNFC_BIT_RATE tx_bitrate;          /* Data Exchange Tx Bitrate */
+  tNFC_BIT_RATE rx_bitrate;          /* Data Exchange Rx Bitrate */
+  tNFC_INTF_PARAMS intf_param;       /* interface type and params*/
+} tNFC_ACTIVATE_DEVT;
+
+/* the data type associated with NFC_DEACTIVATE_DEVT and NFC_DEACTIVATE_CEVT */
+typedef struct {
+  tNFC_STATUS status;   /* The event status.        */
+  tNFC_DEACT_TYPE type; /* De-activate type         */
+  bool is_ntf;          /* true, if deactivate notif*/
+} tNFC_DEACTIVATE_DEVT;
+
+typedef union {
+  tNFC_STATUS status; /* The event status.        */
+  tNFC_START_DEVT start;
+  tNFC_RESULT_DEVT result;
+  tNFC_SELECT_DEVT select;
+  tNFC_STOP_DEVT stop;
+  tNFC_ACTIVATE_DEVT activate;
+  tNFC_DEACTIVATE_DEVT deactivate;
+} tNFC_DISCOVER;
+
+/* Min TR0 indicates to tag the min delay before responding after the end of
+ * command */
+#define NFC_RF_PARAM_MIN_TR0_DEFAULT 0x00
+#define NFC_RF_PARAM_MIN_TR0_48X 0x01 /* 48 x 16/fc */
+#define NFC_RF_PARAM_MIN_TR0_16X 0x02 /* 16 x 16/fc */
+
+/* Min TR1 indicates to tag the min delay between subcarrier modulation and data
+ * transmission */
+#define NFC_RF_PARAM_MIN_TR1_DEFAULT 0x00
+#define NFC_RF_PARAM_MIN_TR1_64X 0x01 /* 64 x 16/fc */
+#define NFC_RF_PARAM_MIN_TR1_16X 0x02 /* 16 x 16/fc */
+
+/* Min TR2 indicates to RW the min delay between EoS of tag and SoS of RW */
+#define NFC_RF_PARAM_MIN_TR2_1792 0x00 /* 1792/fc (10etu + 32/fc) */
+#define NFC_RF_PARAM_MIN_TR2_3328 0x01 /* 3328/fc (10etu + 128/fc) */
+#define NFC_RF_PARAM_MIN_TR2_5376 0x02 /* 5376/fc (10etu + 256/fc) */
+#define NFC_RF_PARAM_MIN_TR2_9472 0x03 /* 9472/fc (10etu + 512/fc) */
+
+#define NFC_RF_PARAM_EOS_REQUIRED 0x00     /* EoS required */
+#define NFC_RF_PARAM_EOS_NOT_REQUIRED 0x01 /* EoS not required */
+
+#define NFC_RF_PARAM_SOS_REQUIRED 0x00     /* SoS required */
+#define NFC_RF_PARAM_SOS_NOT_REQUIRED 0x01 /* SoS not required */
+
+#if (NXP_EXTNS == TRUE)
+#define NFA_EE_MAX_EE_SUPPORTED_DEFAULT 0x04
+#endif
+
+typedef struct {
+  bool include_rf_tech_mode; /* true if including RF Tech and Mode update    */
+  tNFC_RF_TECH_N_MODE rf_tech_n_mode; /* RF tech and mode */
+  bool include_tx_bit_rate;  /* true if including Tx bit rate update         */
+  tNFC_BIT_RATE tx_bit_rate; /* Transmit Bit Rate                            */
+  bool include_rx_bit_rate;  /* true if including Rx bit rate update         */
+  tNFC_BIT_RATE rx_bit_rate; /* Receive Bit Rate                             */
+  bool include_nfc_b_config; /* true if including NFC-B data exchange config */
+  uint8_t min_tr0;           /* Minimun TR0                                  */
+  uint8_t min_tr1;           /* Minimun TR1                                  */
+  uint8_t suppression_eos;   /* Suppression of EoS                           */
+  uint8_t suppression_sos;   /* Suppression of SoS                           */
+  uint8_t min_tr2;           /* Minimun TR1                                  */
+} tNFC_RF_COMM_PARAMS;
+
+/*************************************
+**  DISCOVER Callback Functions
+**************************************/
+typedef void(tNFC_DISCOVER_CBACK)(tNFC_DISCOVER_EVT event,
+                                  tNFC_DISCOVER* p_data);
+
+/* the events reported on tNFC_TEST_CBACK */
+enum {
+  NFC_LOOPBACK_TEVT = NFC_FIRST_TEVT, /* 0  Loopback test             */
+  NFC_RF_CONTROL_TEVT,                /* 1  RF control Test response  */
+  NFC_RF_FIELD_DONE_TEVT              /* 1  RF control Test notificatn*/
+};
+typedef uint16_t tNFC_TEST_EVT;
+
+/* the data type associated with NFC_LOOPBACK_TEVT */
+typedef struct {
+  tNFC_STATUS status; /* The event status.            */
+  NFC_HDR* p_data;    /* The loop back data from NFCC */
+} tNFC_LOOPBACK_TEVT;
+
+/* the data type associated with NFC_RF_CONTROL_TEVT */
+typedef tNFC_STATUS tNFC_RF_CONTROL_TEVT;
+
+typedef union {
+  tNFC_STATUS status; /* The event status.            */
+  tNFC_LOOPBACK_TEVT loop_back;
+  tNFC_RF_CONTROL_TEVT rf_control;
+} tNFC_TEST;
+
+/*************************************
+**  TEST Callback Functions
+**************************************/
+typedef void(tNFC_TEST_CBACK)(tNFC_TEST_EVT event, tNFC_TEST* p_data);
+
+typedef tNFC_DEACTIVATE_DEVT tNFC_DEACTIVATE_CEVT;
+typedef union {
+  tNFC_STATUS status; /* The event status. */
+  tNFC_CONN_CREATE_CEVT conn_create;
+  tNFC_CONN_CLOSE_CEVT conn_close;
+  tNFC_DEACTIVATE_CEVT deactivate;
+  tNFC_DATA_CEVT data;
+} tNFC_CONN;
+
+/*************************************
+**  Data Callback Functions
+**************************************/
+typedef void(tNFC_CONN_CBACK)(uint8_t conn_id, tNFC_CONN_EVT event,
+                              tNFC_CONN* p_data);
+#define NFC_MAX_CONN_ID 15
+#define NFC_ILLEGAL_CONN_ID 0xFF
+#define NFC_RF_CONN_ID 0 /* the static connection ID for RF traffic */
+#if (NXP_EXTNS == TRUE)
+#define NFC_NFCEE_CONN_ID 0x03 /* the connection ID for NFCEE */
+#endif
+#define NFC_HCI_CONN_ID 3 /* the static connection ID for HCI transport */
+/*************************************
+**  Status callback function
+**************************************/
+typedef void(tNFC_STATUS_CBACK)(tNFC_STATUS status);
+
+/*****************************************************************************
+**  EXTERNAL FUNCTION DECLARATIONS
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+**
+** Function         NFC_Enable
+**
+** Description      This function enables NFC. Prior to calling NFC_Enable:
+**                  - the NFCC must be powered up, and ready to receive
+**                    commands.
+**                  - GKI must be enabled
+**                  - NFC_TASK must be started
+**                  - NCIT_TASK must be started (if using dedicated NCI
+**                    transport)
+**
+**                  This function opens the NCI transport (if applicable),
+**                  resets the NFC controller, and initializes the NFC
+**                  subsystems.
+**
+**                  When the NFC startup procedure is completed, an
+**                  NFC_ENABLE_REVT is returned to the application using the
+**                  tNFC_RESPONSE_CBACK.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS NFC_Enable(tNFC_RESPONSE_CBACK* p_cback);
+
+/*******************************************************************************
+**
+** Function         NFC_Disable
+**
+** Description      This function performs clean up routines for shutting down
+**                  NFC and closes the NCI transport (if using dedicated NCI
+**                  transport).
+**
+**                  When the NFC shutdown procedure is completed, an
+**                  NFC_DISABLED_REVT is returned to the application using the
+**                  tNFC_RESPONSE_CBACK.
+**
+** Returns          nothing
+**
+*******************************************************************************/
+extern void NFC_Disable(void);
+
+/*******************************************************************************
+**
+** Function         NFC_Init
+**
+** Description      This function initializes control blocks for NFC
+**
+** Returns          nothing
+**
+*******************************************************************************/
+#if (NXP_EXTNS == TRUE)
+extern void NFC_Init(tHAL_NFC_CONTEXT* p_hal_entry_cntxt);
+#else
+extern void NFC_Init(tHAL_NFC_ENTRY* p_hal_entry_tbl);
+#endif
+
+/*******************************************************************************
+**
+** Function         NFC_GetLmrtSize
+**
+** Description      Called by application wto query the Listen Mode Routing
+**                  Table size supported by NFCC
+**
+** Returns          Listen Mode Routing Table size
+**
+*******************************************************************************/
+extern uint16_t NFC_GetLmrtSize(void);
+
+/*******************************************************************************
+**
+** Function         NFC_SetConfig
+**
+** Description      This function is called to send the configuration parameter
+**                  TLV to NFCC. The response from NFCC is reported by
+**                  tNFC_RESPONSE_CBACK as NFC_SET_CONFIG_REVT.
+**
+** Parameters       tlv_size - the length of p_param_tlvs.
+**                  p_param_tlvs - the parameter ID/Len/Value list
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS NFC_SetConfig(uint8_t tlv_size, uint8_t* p_param_tlvs);
+
+/*******************************************************************************
+**
+** Function         NFC_GetConfig
+**
+** Description      This function is called to retrieve the parameter TLV from
+**                  NFCC. The response from NFCC is reported by
+**                  tNFC_RESPONSE_CBACK as NFC_GET_CONFIG_REVT.
+**
+** Parameters       num_ids - the number of parameter IDs
+**                  p_param_ids - the parameter ID list.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS NFC_GetConfig(uint8_t num_ids, uint8_t* p_param_ids);
+
+/*******************************************************************************
+**
+** Function         NFC_NfceeDiscover
+**
+** Description      This function is called to enable or disable NFCEE
+**                  Discovery. The response from NFCC is reported by
+**                  tNFC_RESPONSE_CBACK as NFC_NFCEE_DISCOVER_REVT.
+**                  The notification from NFCC is reported by
+**                  tNFC_RESPONSE_CBACK as NFC_NFCEE_INFO_REVT.
+**
+** Parameters       discover - 1 to enable discover, 0 to disable.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS NFC_NfceeDiscover(bool discover);
+
+/*******************************************************************************
+**
+** Function         NFC_NfceeModeSet
+**
+** Description      This function is called to activate or de-activate an NFCEE
+**                  connected to the NFCC.
+**                  The response from NFCC is reported by tNFC_RESPONSE_CBACK
+**                  as NFC_NFCEE_MODE_SET_REVT.
+**
+** Parameters       nfcee_id - the NFCEE to activate or de-activate.
+**                  mode - 0 to activate NFCEE, 1 to de-activate.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS NFC_NfceeModeSet(uint8_t nfcee_id, tNFC_NFCEE_MODE mode);
+
+/*******************************************************************************
+**
+** Function         NFC_DiscoveryMap
+**
+** Description      This function is called to set the discovery interface
+**                  mapping. The response from NFCC is reported by
+**                  tNFC_DISCOVER_CBACK as. NFC_MAP_DEVT.
+**
+** Parameters       num - the number of items in p_params.
+**                  p_maps - the discovery interface mappings
+**                  p_cback - the discovery callback function
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS NFC_DiscoveryMap(uint8_t num, tNFC_DISCOVER_MAPS* p_maps,
+                                    tNFC_DISCOVER_CBACK* p_cback);
+
+/*******************************************************************************
+**
+** Function         NFC_DiscoveryStart
+**
+** Description      This function is called to start Polling and/or Listening.
+**                  The response from NFCC is reported by tNFC_DISCOVER_CBACK
+**                  as NFC_START_DEVT. The notification from NFCC is reported by
+**                  tNFC_DISCOVER_CBACK as NFC_RESULT_DEVT.
+**
+** Parameters       num_params - the number of items in p_params.
+**                  p_params - the discovery parameters
+**                  p_cback - the discovery callback function
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS NFC_DiscoveryStart(uint8_t num_params,
+                                      tNFC_DISCOVER_PARAMS* p_params,
+                                      tNFC_DISCOVER_CBACK* p_cback);
+
+/*******************************************************************************
+**
+** Function         NFC_DiscoverySelect
+**
+** Description      If tNFC_DISCOVER_CBACK reports status=NFC_MULTIPLE_PROT,
+**                  the application needs to use this function to select the
+**                  the logical endpoint to continue. The response from NFCC is
+**                  reported by tNFC_DISCOVER_CBACK as NFC_SELECT_DEVT.
+**
+** Parameters       rf_disc_id - The ID identifies the remote device.
+**                  protocol - the logical endpoint on the remote devide
+**                  rf_interface - the RF interface to communicate with NFCC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS NFC_DiscoverySelect(uint8_t rf_disc_id, uint8_t protocol,
+                                       uint8_t rf_interface);
+
+/*******************************************************************************
+**
+** Function         NFC_ConnCreate
+**
+** Description      This function is called to create a logical connection with
+**                  NFCC for data exchange.
+**                  The response from NFCC is reported in tNFC_CONN_CBACK
+**                  as NFC_CONN_CREATE_CEVT.
+**
+** Parameters       dest_type - the destination type
+**                  id   - the NFCEE ID or RF Discovery ID .
+**                  protocol - the protocol
+**                  p_cback - the data callback function to receive data from
+**                  NFCC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS NFC_ConnCreate(uint8_t dest_type, uint8_t id,
+                                  uint8_t protocol, tNFC_CONN_CBACK* p_cback);
+
+/*******************************************************************************
+**
+** Function         NFC_ConnClose
+**
+** Description      This function is called to close a logical connection with
+**                  NFCC.
+**                  The response from NFCC is reported in tNFC_CONN_CBACK
+**                  as NFC_CONN_CLOSE_CEVT.
+**
+** Parameters       conn_id - the connection id.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS NFC_ConnClose(uint8_t conn_id);
+
+/*******************************************************************************
+**
+** Function         NFC_SetStaticRfCback
+**
+** Description      This function is called to update the data callback function
+**                  to receive the data for the given connection id.
+**
+** Parameters       p_cback - the connection callback function
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+extern void NFC_SetStaticRfCback(tNFC_CONN_CBACK* p_cback);
+
+/*******************************************************************************
+**
+** Function         NFC_SetReassemblyFlag
+**
+** Description      This function is called to set if nfc will reassemble
+**                  nci packet as much as its buffer can hold or it should not
+**                  reassemble but forward the fragmented nci packet to layer
+**                  above. If nci data pkt is fragmented, nfc may send multiple
+**                  NFC_DATA_CEVT with status NFC_STATUS_CONTINUE before sending
+**                  NFC_DATA_CEVT with status NFC_STATUS_OK based on reassembly
+**                  configuration and reassembly buffer size
+**
+** Parameters       reassembly - flag to indicate if nfc may reassemble or not
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+extern void NFC_SetReassemblyFlag(bool reassembly);
+
+/*******************************************************************************
+**
+** Function         NFC_SendData
+**
+** Description      This function is called to send the given data packet
+**                  to the connection identified by the given connection id.
+**
+** Parameters       conn_id - the connection id.
+**                  p_data - the data packet
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS NFC_SendData(uint8_t conn_id, NFC_HDR* p_data);
+
+/*******************************************************************************
+**
+** Function         NFC_FlushData
+**
+** Description      This function is called to discard the tx data queue of
+**                  the given connection id.
+**
+** Parameters       conn_id - the connection id.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS NFC_FlushData(uint8_t conn_id);
+
+/*******************************************************************************
+**
+** Function         NFC_Deactivate
+**
+** Description      This function is called to stop the discovery process or
+**                  put the listen device in sleep mode or terminate the NFC
+**                  link.
+**
+**                  The response from NFCC is reported by tNFC_DISCOVER_CBACK
+**                  as NFC_DEACTIVATE_DEVT.
+**
+** Parameters       deactivate_type - NFC_DEACTIVATE_TYPE_IDLE, to IDLE mode.
+**                                    NFC_DEACTIVATE_TYPE_SLEEP to SLEEP mode.
+**                                    NFC_DEACTIVATE_TYPE_SLEEP_AF to SLEEP_AF
+**                                    mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS NFC_Deactivate(tNFC_DEACT_TYPE deactivate_type);
+
+/*******************************************************************************
+**
+** Function         NFC_UpdateRFCommParams
+**
+** Description      This function is called to update RF Communication
+**                  parameters once the Frame RF Interface has been activated.
+**
+**                  The response from NFCC is reported by tNFC_RESPONSE_CBACK
+**                  as NFC_RF_COMM_PARAMS_UPDATE_REVT.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS NFC_UpdateRFCommParams(tNFC_RF_COMM_PARAMS* p_params);
+
+/*******************************************************************************
+**
+** Function         NFC_SetPowerOffSleep
+**
+** Description      This function closes/opens transport and turns off/on NFCC.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS NFC_SetPowerOffSleep(bool enable);
+
+/*******************************************************************************
+**
+** Function         NFC_PowerCycleNFCC
+**
+** Description      This function turns off and then on NFCC.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS NFC_PowerCycleNFCC(void);
+
+/*******************************************************************************
+**
+** Function         NFC_SetRouting
+**
+** Description      This function is called to configure the CE routing table.
+**                  The response from NFCC is reported by tNFC_RESPONSE_CBACK
+**                  as NFC_SET_ROUTING_REVT.
+**
+** Parameters
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS NFC_SetRouting(bool more, uint8_t num_tlv, uint8_t tlv_size,
+                                  uint8_t* p_param_tlvs);
+
+/*******************************************************************************
+**
+** Function         NFC_GetRouting
+**
+** Description      This function is called to retrieve the CE routing table
+**                  from NFCC. The response from NFCC is reported by
+**                  tNFC_RESPONSE_CBACK as NFC_GET_ROUTING_REVT.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS NFC_GetRouting(void);
+
+/*******************************************************************************
+**
+** Function         NFC_RegVSCback
+**
+** Description      This function is called to register or de-register a
+**                  callback function to receive Proprietary NCI response and
+**                  notification events.
+**                  The maximum number of callback functions allowed is
+**                  NFC_NUM_VS_CBACKS
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS NFC_RegVSCback(bool is_register, tNFC_VS_CBACK* p_cback);
+
+/*******************************************************************************
+**
+** Function         NFC_SendVsCommand
+**
+** Description      This function is called to send the given vendor specific
+**                  command to NFCC. The response from NFCC is reported to the
+**                  given tNFC_VS_CBACK as (oid).
+**
+** Parameters       oid - The opcode of the VS command.
+**                  p_data - The parameters for the VS command
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS NFC_SendVsCommand(uint8_t oid, NFC_HDR* p_data,
+                                     tNFC_VS_CBACK* p_cback);
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         NFC_SendNxpNciCommand
+**
+** Description      This function is called to send the given nxp specific
+**                  command to NFCC. The response from NFCC is reported to the
+**                  given tNFC_VS_CBACK.
+**
+** Parameters       p_data - The command buffer
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS NFC_SendNxpNciCommand(NFC_HDR* p_data,
+                                         tNFC_VS_CBACK* p_cback);
+
+/*******************************************************************************
+**
+** Function         NFC_SetP61Status
+**
+** Description      This function set the JCOP download
+**                  state to pn544 driver.
+**
+** Returns          0 if api call success, else -1
+**
+*******************************************************************************/
+extern int32_t NFC_SetP61Status(void* pdata, jcop_dwnld_state_t isJcopState);
+#endif
+
+/*******************************************************************************
+**
+** Function         NFC_TestLoopback
+**
+** Description      This function is called to send the given data packet
+**                  to NFCC for loopback test.
+**                  When loopback data is received from NFCC, tNFC_TEST_CBACK .
+**                  reports a NFC_LOOPBACK_TEVT.
+**
+** Parameters       p_data - the data packet
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS NFC_TestLoopback(NFC_HDR* p_data);
+
+/*******************************************************************************
+**
+** Function         NFC_SetTraceLevel
+**
+** Description      This function sets the trace level for NFC.  If called with
+**                  a value of 0xFF, it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+extern uint8_t NFC_SetTraceLevel(uint8_t new_level);
+
+/*******************************************************************************
+**
+** Function         NFC_GetChipType
+**
+** Description      Gets the chipType
+**
+** Returns          ChipType
+**
+*******************************************************************************/
+tNFC_chipType NFC_GetChipType();
+
+#if (BT_TRACE_VERBOSE == true)
+/*******************************************************************************
+**
+** Function         NFC_GetStatusName
+**
+** Description      This function returns the status name.
+**
+** NOTE             conditionally compiled to save memory.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+extern char* NFC_GetStatusName(tNFC_STATUS status);
+#endif
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         nfc_ncif_getFWVersion
+**
+** Description      This function sets the trace level for NFC.  If called with
+**                  a value of 0xFF, it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+extern tNFC_FW_VERSION nfc_ncif_getFWVersion();
+/*******************************************************************************
+**
+** Function         nfc_ncif_storeScreenState
+**
+** Description      This function is called to store the last screen state
+**
+** Returns          void
+**
+*******************************************************************************/
+extern void nfc_ncif_storeScreenState(uint8_t state);
+extern uint8_t nfc_hal_nfcc_reset(void);
+extern uint8_t nfc_hal_nfcc_init(uint8_t** pinit_rsp);
+/*******************************************************************************
+**
+** Function         NFC_EnableDisableHalLog
+**
+** Description      This function is used to enable/disable
+**                  HAL log level.
+**
+*******************************************************************************/
+void NFC_EnableDisableHalLog(uint8_t type);
+/*******************************************************************************
+**
+** Function         nfc_ncif_getMaxRoutingTableSize
+**
+** Description      This function is called to get the Max supported routing
+*Table size.
+**
+** Returns           Max supported routing Table size
+**
+*******************************************************************************/
+extern uint16_t nfc_ncif_getMaxRoutingTableSize();
+
+/*******************************************************************************
+**
+** Function         NFC_Nfcee_PwrLinkCtrl
+**
+** Description      This function is called for NFCC which manages the power
+*supply and
+**                  communication links between the NFCC and its connected
+*NFCEEs.
+**
+** Parameters       nfcee_id   - the NFCEE ID .
+**                  cfg_value  - 0x00 ->Default Value(NFCC decides)
+**                               0x01 ->NFCEE Power Supply always On
+**                               0x03 ->NFCC to NFCEE Communication link always
+**                                      active when the NFCEE is powered on
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS NFC_Nfcee_PwrLinkCtrl(uint8_t nfcee_id, uint8_t cfg_value);
+
+/*******************************************************************************
+**
+** Function         NFC_ReqWiredAccess
+**
+** Description      This function request to pn54x driver to get access
+**                  of P61. Status would be updated to pdata
+**
+** Returns          0 if api call success, else -1
+**
+*******************************************************************************/
+int32_t NFC_ReqWiredAccess(void* pdata);
+/*******************************************************************************
+**
+** Function         NFC_RelWiredAccess
+**
+** Description      This function release access
+**                  of P61. Status would be updated to pdata
+**
+** Returns          0 if api call success, else -1
+**
+*******************************************************************************/
+int32_t NFC_RelWiredAccess(void* pdata);
+/*******************************************************************************
+**
+** Function         NFC_GetWiredAccess
+**
+** Description      This function gets the current access state
+**                  of P61. Current state would be updated to pdata
+**
+** Returns          0 if api call success, else -1
+**
+*******************************************************************************/
+int32_t NFC_GetP61Status(void* pdata);
+/*******************************************************************************
+**
+** Function         NFC_DisableWired
+**
+** Description      This function request to pn54x driver to
+**                  disable ese vdd gpio
+**
+** Returns          0 if api call success, else -1
+**
+*******************************************************************************/
+int32_t NFC_DisableWired(void* pdata);
+/*******************************************************************************
+**
+** Function         NFC_eSEChipReset
+**
+** Description      This function request to reset ESE using ISO_RST feature.
+**
+** Returns          0 if api call success, else -1
+**
+*******************************************************************************/
+int32_t NFC_eSEChipReset(void* pdata);
+/*******************************************************************************
+**
+** Function         NFC_EnableWired
+**
+** Description      This function request to pn54x driver to
+**                  enable ese vdd gpio
+**
+** Returns          0 if api call success, else -1
+**
+*******************************************************************************/
+int32_t NFC_EnableWired(void* pdata);
+/*******************************************************************************
+**
+** Function         NFC_SetNfcServicePid
+**
+** Description      This function request to pn54x driver to
+**                  update NFC service process ID for signalling.
+**
+** Returns          0 if api call success, else -1
+**
+*******************************************************************************/
+int32_t NFC_SetNfcServicePid();
+/*******************************************************************************
+**
+** Function         NFC_ResetNfcServicePid
+**
+** Description      This function request to pn54x driver to
+**                  reset NFC service process ID for signalling.
+**
+** Returns          0 if api call success, else -1
+**
+*******************************************************************************/
+int32_t NFC_ResetNfcServicePid();
+/*******************************************************************************
+**
+** Function         NFC_GetEseAccess
+**
+** Description      This function request to pn54x driver to get access
+**                  of P61. it returns 0 on success. This api waits maximum
+**                  defined timeout
+**
+** Returns          0 if api call success, else -1
+**
+*******************************************************************************/
+int32_t NFC_GetEseAccess(void* pdata);
+
+/*******************************************************************************
+**
+** Function         NFC_RelEseAccess
+**
+** Description      This function release access of P61.
+**                  it returns 0 on success.
+**
+** Returns          0 if api call success, else -1
+**
+*******************************************************************************/
+int32_t NFC_RelEseAccess(void* pdata);
+
+/*******************************************************************************
+**
+** Function         NFC_RelSvddWait
+**
+** Description      This function release wait for svdd change
+**                  of P61. Status would be updated to pdata
+**
+** Returns          0 if api call success, else -1
+**
+*******************************************************************************/
+int32_t NFC_RelSvddWait(void* pdata);
+
+/*******************************************************************************
+**
+** Function         NFC_GetChipType
+**
+** Description      Returns currently selected chip type
+**
+** Returns          chipType
+**
+*******************************************************************************/
+tNFC_chipType NFC_GetChipType();
+
+/*******************************************************************************
+**
+** Function         NFC_Queue_Is_empty
+**
+** Description      This function to get NFCEE connection ID queue information
+**
+** Returns          1 if Queue is empty else 0
+**
+*******************************************************************************/
+extern bool NFC_Queue_Is_empty(uint8_t conn_id);
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         NFC_NfceePLConfig
+**
+** Description      This function is called to set the Power and Link Control to
+**                  an NFCEE connected to the NFCC.
+**                  The response from NFCC is reported by tNFC_RESPONSE_CBACK
+**                  as NFC_NFCEE_PL_CONTROL_REVT.
+**
+* Parameters       nfcee_id - the NFCEE to activate or de-activate.
+**                  pl_config -
+**                     NFCEE_PL_CONFIG_NFCC_DECIDES    NFCC decides (default)
+**                     NFCEE_PL_CONFIG_P_ALWAYS_ON     NFCEE power supply is always on
+**                     NFCEE_PL_CONFIG_L_ON_WHEN_P_ON  communication link is always active
+**                                                          when NFCEE is powered on
+**                     NFCEE_PL_CONFIG_PL_ALWAYS_ON    power supply and communication link are always on
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS NFC_NfceePLConfig (uint8_t                 nfcee_id,
+                                              tNCI_NFCEE_PL_CONFIG  pl_config);
+
+/*******************************************************************************
+**
+** Function         NFC_SetStaticHciCback
+**
+** Description      This function is called to update the data callback function
+**                  to receive the data for the static Hci connection id.
+**
+** Parameters       p_cback - the connection callback function
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+extern void NFC_SetStaticHciCback (tNFC_CONN_CBACK    *p_cback);
+
+/*******************************************************************************
+**
+** Function         NFC_SetPowerSubState
+**
+** Description      This function is called to send the power sub state( screen state)
+**                      to NFCC. The response from NFCC is reported by
+**                  tNFC_RESPONSE_CBACK as NFC_SET_POWER_STATE_REVT.
+**
+** Parameters       scree_state
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS NFC_SetPowerSubState (uint8_t screen_state);
+
+/*******************************************************************************
+**
+** Function         NFC_ISODEPNakPresCheck
+**
+** Description      This function is called to send the ISO DEP nak presenc check cmd
+**                  to check that the remote end point in RF field.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS NFC_ISODEPNakPresCheck ();
+#endif /* NFC_API_H */
diff --git a/src/nfc/include/rw_api.h b/src/nfc/include/rw_api.h
new file mode 100644
index 0000000..c2aebc9
--- /dev/null
+++ b/src/nfc/include/rw_api.h
@@ -0,0 +1,1396 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the Near Field Communication (NFC) Reader/Writer mode
+ *  related API function external definitions.
+ *
+ ******************************************************************************/
+
+#ifndef RW_API_H
+#define RW_API_H
+#include "tags_defs.h"
+
+#define RW_T1T_BLD_ADD(a, k, y) a = ((k & 0xF) << 3) | (y & 0x7);
+#define RW_T1T_BLD_ADDS(a, s) a = ((s & 0xF) << 4);
+
+#define RW_T1T_FIRST_EVT 0x20
+#define RW_T2T_FIRST_EVT 0x40
+#define RW_T3T_FIRST_EVT 0x60
+#define RW_T4T_FIRST_EVT 0x80
+#define RW_I93_FIRST_EVT 0xA0
+#if (NXP_EXTNS == TRUE)
+#define RW_T3BT_FIRST_EVT 0xB0
+#endif
+
+enum {
+  /* Note: the order of these events can not be changed */
+  /* Type 1 tag events for tRW_CBACK */
+  RW_T1T_RID_EVT = RW_T1T_FIRST_EVT, /* Read ID command completd              */
+  RW_T1T_RALL_CPLT_EVT,              /* Read All command completed            */
+  RW_T1T_READ_CPLT_EVT,              /* Read byte completed                   */
+  RW_T1T_WRITE_E_CPLT_EVT,           /* Write byte after erase completed      */
+  RW_T1T_WRITE_NE_CPLT_EVT,          /* Write byte with no erase completed    */
+  RW_T1T_RSEG_CPLT_EVT,              /* Read segment completed                */
+  RW_T1T_READ8_CPLT_EVT,             /* Read block completed                  */
+  RW_T1T_WRITE_E8_CPLT_EVT,          /* Write block after erase completed     */
+  RW_T1T_WRITE_NE8_CPLT_EVT,         /* Write block with no erase completed   */
+  RW_T1T_TLV_DETECT_EVT,             /* Lock/Mem/Prop tlv detection complete  */
+  RW_T1T_NDEF_DETECT_EVT,            /* NDEF detection complete               */
+  RW_T1T_NDEF_READ_EVT,              /* NDEF read completed                   */
+  RW_T1T_NDEF_WRITE_EVT,             /* NDEF write complete                   */
+  RW_T1T_SET_TAG_RO_EVT,             /* Tag is set as read only               */
+  RW_T1T_RAW_FRAME_EVT,              /* Response of raw frame sent            */
+  RW_T1T_PRESENCE_CHECK_EVT,         /* Response to RW_T1tPresenceCheck       */
+  RW_T1T_FORMAT_CPLT_EVT,            /* Tag Formated                          */
+  RW_T1T_INTF_ERROR_EVT,             /* RF Interface error event              */
+  RW_T1T_MAX_EVT,
+
+  /* Type 2 tag events */
+  RW_T2T_READ_CPLT_EVT = RW_T2T_FIRST_EVT, /* Read completed */
+  RW_T2T_WRITE_CPLT_EVT,     /* Write completed                       */
+  RW_T2T_SELECT_CPLT_EVT,    /* Sector select completed               */
+  RW_T2T_NDEF_DETECT_EVT,    /* NDEF detection complete               */
+  RW_T2T_TLV_DETECT_EVT,     /* Lock/Mem/Prop tlv detection complete  */
+  RW_T2T_NDEF_READ_EVT,      /* NDEF read completed                   */
+  RW_T2T_NDEF_WRITE_EVT,     /* NDEF write complete                   */
+  RW_T2T_SET_TAG_RO_EVT,     /* Tag is set as read only               */
+  RW_T2T_RAW_FRAME_EVT,      /* Response of raw frame sent            */
+  RW_T2T_PRESENCE_CHECK_EVT, /* Response to RW_T2tPresenceCheck       */
+  RW_T2T_FORMAT_CPLT_EVT,    /* Tag Formated                          */
+  RW_T2T_INTF_ERROR_EVT,     /* RF Interface error event              */
+  RW_T2T_MAX_EVT,
+
+  /* Type 3 tag events for tRW_CBACK */
+  RW_T3T_CHECK_CPLT_EVT = RW_T3T_FIRST_EVT, /* Read completed */
+  RW_T3T_UPDATE_CPLT_EVT,        /* Write completed                          */
+  RW_T3T_CHECK_EVT,              /* Segment of data received from type 3 tag */
+  RW_T3T_RAW_FRAME_EVT,          /* SendRawFrame response                    */
+  RW_T3T_NDEF_DETECT_EVT,        /* NDEF detection complete                  */
+  RW_T3T_PRESENCE_CHECK_EVT,     /* Response to RW_T3tPresenceCheck          */
+  RW_T3T_POLL_EVT,               /* Response to RW_T3tPoll                   */
+  RW_T3T_GET_SYSTEM_CODES_EVT,   /* Response to RW_T3tGetSystemCodes         */
+  RW_T3T_FORMAT_CPLT_EVT,        /* Tag Formated (Felica-Lite only)          */
+  RW_T3T_SET_READ_ONLY_CPLT_EVT, /* Tag is set as Read only                  */
+  RW_T3T_INTF_ERROR_EVT,         /* RF Interface error event                 */
+  RW_T3T_MAX_EVT,
+
+  /* Type 4 tag events for tRW_CBACK */
+  RW_T4T_NDEF_DETECT_EVT =
+      RW_T4T_FIRST_EVT,        /* Result of NDEF detection procedure       */
+                               /* Mandatory NDEF file is selected          */
+  RW_T4T_NDEF_READ_EVT,        /* Segment of data received from type 4 tag */
+  RW_T4T_NDEF_READ_CPLT_EVT,   /* Read operation completed                 */
+  RW_T4T_NDEF_READ_FAIL_EVT,   /* Read operation failed                    */
+  RW_T4T_NDEF_UPDATE_CPLT_EVT, /* Update operation completed               */
+  RW_T4T_NDEF_UPDATE_FAIL_EVT, /* Update operation failed                  */
+  RW_T4T_SET_TO_RO_EVT,        /* Tag is set as read only                  */
+  RW_T4T_PRESENCE_CHECK_EVT,   /* Response to RW_T4tPresenceCheck          */
+  RW_T4T_RAW_FRAME_EVT,        /* Response of raw frame sent               */
+  RW_T4T_INTF_ERROR_EVT,       /* RF Interface error event                 */
+  RW_T4T_NDEF_FORMAT_CPLT_EVT, /* Format operation completed               */
+#if (NXP_EXTNS == TRUE)
+  RW_T4T_RAW_FRAME_RF_WTX_EVT, /* Received RF WTX for raw frame sent       */
+#endif
+  RW_T4T_MAX_EVT,
+
+  /* ISO 15693 tag events for tRW_CBACK */
+  RW_I93_NDEF_DETECT_EVT =
+      RW_I93_FIRST_EVT,        /* Result of NDEF detection procedure */
+  RW_I93_NDEF_READ_EVT,        /* Segment of data received from tag  */
+  RW_I93_NDEF_READ_CPLT_EVT,   /* Read operation completed           */
+  RW_I93_NDEF_READ_FAIL_EVT,   /* Read operation failed              */
+  RW_I93_NDEF_UPDATE_CPLT_EVT, /* Update operation completed         */
+  RW_I93_NDEF_UPDATE_FAIL_EVT, /* Update operation failed            */
+  RW_I93_FORMAT_CPLT_EVT,      /* Format procedure complete          */
+  RW_I93_SET_TAG_RO_EVT,       /* Set read-only procedure complete   */
+  RW_I93_INVENTORY_EVT,        /* Response of Inventory              */
+  RW_I93_DATA_EVT,             /* Response of Read, Get Multi Security */
+  RW_I93_SYS_INFO_EVT,         /* Response of System Information     */
+  RW_I93_CMD_CMPL_EVT,         /* Command complete                   */
+  RW_I93_PRESENCE_CHECK_EVT,   /* Response to RW_I93PresenceCheck    */
+  RW_I93_RAW_FRAME_EVT,        /* Response of raw frame sent         */
+  RW_I93_INTF_ERROR_EVT,       /* RF Interface error event           */
+#if (NXP_EXTNS == TRUE)
+  RW_I93_MAX_EVT,
+  RW_T3BT_RAW_READ_CPLT_EVT,
+  RW_T3BT_MAX_EVT
+#else
+  RW_I93_MAX_EVT
+#endif
+};
+#if (NXP_EXTNS == TRUE)
+#define RW_I93_MAX_RSP_TIMEOUT 1000
+#endif
+#define RW_RAW_FRAME_EVT 0xFF
+
+typedef uint8_t tRW_EVENT;
+
+/* Tag is read only              */
+#define RW_NDEF_FL_READ_ONLY 0x01
+/* Tag formated for NDEF         */
+#define RW_NDEF_FL_FORMATED 0x02
+/* NDEF supported by the tag     */
+#define RW_NDEF_FL_SUPPORTED 0x04
+/* Unable to find if tag is ndef capable/formated/read only */
+#define RW_NDEF_FL_UNKNOWN 0x08
+/* Tag supports format operation */
+#define RW_NDEF_FL_FORMATABLE 0x10
+/* Tag can be soft locked */
+#define RW_NDEF_FL_SOFT_LOCKABLE 0x20
+/* Tag can be hard locked */
+#define RW_NDEF_FL_HARD_LOCKABLE 0x40
+/* Tag is one time programmable */
+#define RW_NDEF_FL_OTP 0x80
+
+#define RW_T4T_CHK_ISO_DEP_NAK_PRES_CHK 5
+
+typedef uint8_t tRW_NDEF_FLAG;
+
+
+/* options for RW_T4tPresenceCheck  */
+#define RW_T4T_CHK_READ_BINARY_CH0 0
+#define RW_T4T_CHK_READ_BINARY_CH1 1
+#define RW_T4T_CHK_READ_BINARY_CH2 2
+#define RW_T4T_CHK_READ_BINARY_CH3 3
+#define RW_T4T_CHK_EMPTY_I_BLOCK 4
+
+typedef struct {
+  tNFC_STATUS status;
+  uint8_t hr[T1T_HR_LEN];
+  uint8_t uid[T1T_CMD_UID_LEN];
+} tRW_T1T_RID_EVT;
+
+typedef struct {
+  tNFC_STATUS status;
+  uint16_t msg_len; /* Length of the NDEF message */
+} tRW_T2T_DETECT;
+
+typedef struct {
+  tNFC_STATUS status;       /* Status of the POLL request */
+  uint8_t rc;               /* RC (request code) used in the POLL request */
+  uint8_t response_num;     /* Number of SENSF_RES responses */
+  uint8_t response_bufsize; /* Size of SENSF_RES responses */
+  uint8_t* response_buf;    /* Buffer of responses (length + SENSF_RES) see
+                               $8.1.2.2 of NCI specs */
+} tRW_T3T_POLL;
+
+typedef struct {
+  tNFC_STATUS status;       /* Status of the Get System Codes request */
+  uint8_t num_system_codes; /* Number of system codes */
+  uint16_t* p_system_codes; /* Table of system codes */
+} tRW_T3T_SYSTEM_CODES;
+
+typedef struct {
+  tNFC_STATUS status;     /* status of NDEF detection */
+  tNFC_PROTOCOL protocol; /* protocol used to detect NDEF */
+  uint32_t max_size;      /* max number of bytes available for NDEF data */
+  uint32_t cur_size;      /* current size of stored NDEF data (in bytes) */
+  tRW_NDEF_FLAG
+      flags; /* Flags to indicate NDEF capability,formated,formatable and read
+                only */
+} tRW_DETECT_NDEF_DATA;
+
+typedef struct {
+  tNFC_STATUS status;     /* status of NDEF detection */
+  tNFC_PROTOCOL protocol; /* protocol used to detect TLV */
+  uint8_t
+      num_bytes; /* number of reserved/lock bytes based on the type of tlv */
+} tRW_DETECT_TLV_DATA;
+
+typedef struct {
+  tNFC_STATUS status;
+  NFC_HDR* p_data;
+} tRW_READ_DATA;
+
+typedef struct {
+  tNFC_STATUS status;
+  uint8_t sw1;
+  uint8_t sw2;
+} tRW_T4T_SW;
+
+typedef struct /* RW_I93_INVENTORY_EVT        */
+    {
+  tNFC_STATUS status;            /* status of Inventory command */
+  uint8_t dsfid;                 /* DSFID                       */
+  uint8_t uid[I93_UID_BYTE_LEN]; /* UID[0]:MSB, ... UID[7]:LSB  */
+} tRW_I93_INVENTORY;
+
+typedef struct /* RW_I93_DATA_EVT               */
+    {
+  tNFC_STATUS status; /* status of Read/Get security status command */
+  uint8_t command;    /* sent command                  */
+  NFC_HDR* p_data;    /* block data of security status */
+} tRW_I93_DATA;
+
+typedef struct /* RW_I93_SYS_INFO_EVT             */
+    {
+  tNFC_STATUS status;            /* status of Get Sys Info command  */
+  uint8_t info_flags;            /* information flags               */
+  uint8_t uid[I93_UID_BYTE_LEN]; /* UID[0]:MSB, ... UID[7]:LSB      */
+  uint8_t dsfid;                 /* DSFID if I93_INFO_FLAG_DSFID    */
+  uint8_t afi;                   /* AFI if I93_INFO_FLAG_AFI        */
+  uint16_t num_block;   /* number of blocks if I93_INFO_FLAG_MEM_SIZE   */
+  uint8_t block_size;   /* block size in byte if I93_INFO_FLAG_MEM_SIZE */
+  uint8_t IC_reference; /* IC Reference if I93_INFO_FLAG_IC_REF         */
+} tRW_I93_SYS_INFO;
+
+typedef struct /* RW_I93_CMD_CMPL_EVT             */
+    {
+  tNFC_STATUS status; /* status of sent command          */
+  uint8_t command;    /* sent command                    */
+  uint8_t error_code; /* error code; I93_ERROR_CODE_XXX  */
+} tRW_I93_CMD_CMPL;
+
+typedef struct {
+  tNFC_STATUS status;
+  NFC_HDR* p_data;
+} tRW_RAW_FRAME;
+
+typedef union {
+  tNFC_STATUS status;
+  tRW_T3T_POLL t3t_poll;           /* Response to t3t poll command          */
+  tRW_T3T_SYSTEM_CODES t3t_sc;     /* Received system codes from t3 tag     */
+  tRW_DETECT_TLV_DATA tlv;         /* The information of detected TLV data  */
+  tRW_DETECT_NDEF_DATA ndef;       /* The information of detected NDEF data */
+  tRW_READ_DATA data;              /* The received data from a tag          */
+  tRW_RAW_FRAME raw_frame;         /* Response of raw frame sent            */
+  tRW_T4T_SW t4t_sw;               /* Received status words from a tag      */
+  tRW_I93_INVENTORY i93_inventory; /* ISO 15693 Inventory response      */
+  tRW_I93_DATA i93_data;           /* ISO 15693 Data response           */
+  tRW_I93_SYS_INFO i93_sys_info;   /* ISO 15693 System Information      */
+  tRW_I93_CMD_CMPL i93_cmd_cmpl;   /* ISO 15693 Command complete        */
+} tRW_DATA;
+
+typedef void(tRW_CBACK)(tRW_EVENT event, tRW_DATA* p_data);
+
+/*******************************************************************************
+**
+** Function         RW_T1tRid
+**
+** Description      This function send a RID command for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_T1tRid(void);
+
+/*******************************************************************************
+**
+** Function         RW_T1tReadAll
+**
+** Description      This function send a RALL command for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_T1tReadAll(void);
+
+/*******************************************************************************
+**
+** Function         RW_T1tRead
+**
+** Description      This function send a READ command for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_T1tRead(uint8_t block, uint8_t byte);
+
+/*******************************************************************************
+**
+** Function         RW_T1tWriteErase
+**
+** Description      This function send a WRITE-E command for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_T1tWriteErase(uint8_t block, uint8_t byte,
+                                    uint8_t new_byte);
+
+/*******************************************************************************
+**
+** Function         RW_T1tWriteNoErase
+**
+** Description      This function send a WRITE-NE command for Reader/Writer
+**                  mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_T1tWriteNoErase(uint8_t block, uint8_t byte,
+                                      uint8_t new_byte);
+
+/*******************************************************************************
+**
+** Function         RW_T1tReadSeg
+**
+** Description      This function send a RSEG command for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_T1tReadSeg(uint8_t segment);
+
+/*******************************************************************************
+**
+** Function         RW_T1tRead8
+**
+** Description      This function send a READ8 command for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_T1tRead8(uint8_t block);
+
+/*******************************************************************************
+**
+** Function         RW_T1tWriteErase8
+**
+** Description      This function send a WRITE-E8 command for Reader/Writer
+**                  mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_T1tWriteErase8(uint8_t block, uint8_t* p_new_dat);
+
+/*******************************************************************************
+**
+** Function         RW_T1tWriteNoErase8
+**
+** Description      This function send a WRITE-NE8 command for Reader/Writer
+**                  mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_T1tWriteNoErase8(uint8_t block, uint8_t* p_new_dat);
+
+/*******************************************************************************
+**
+** Function         RW_T1tLocateTlv
+**
+** Description      This function is called to find the start of the given TLV
+**
+** Parameters:      void
+**
+** Returns          NCI_STATUS_OK, if detection was started. Otherwise, error
+**                  status.
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_T1tLocateTlv(uint8_t tlv_type);
+
+/*******************************************************************************
+**
+** Function         RW_T1tDetectNDef
+**
+** Description      This function can be called to detect if there is an NDEF
+**                  message on the tag.
+**
+** Parameters:      void
+**
+** Returns          NCI_STATUS_OK, if detection was started. Otherwise, error
+**                  status.
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_T1tDetectNDef(void);
+
+/*******************************************************************************
+**
+** Function         RW_T1tReadNDef
+**
+** Description      This function can be called to read the NDEF message on the
+**                  tag.
+**
+** Parameters:      p_buffer:   The buffer into which to read the NDEF message
+**                  buf_len:    The length of the buffer
+**
+** Returns          NCI_STATUS_OK, if read was started. Otherwise, error status.
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_T1tReadNDef(uint8_t* p_buffer, uint16_t buf_len);
+
+/*******************************************************************************
+**
+** Function         RW_T1tWriteNDef
+**
+** Description      This function can be called to write an NDEF message to the
+**                  tag.
+**
+** Parameters:      msg_len:    The length of the buffer
+**                  p_msg:      The NDEF message to write
+**
+** Returns          NCI_STATUS_OK, if write was started. Otherwise, error
+**                  status.
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_T1tWriteNDef(uint16_t msg_len, uint8_t* p_msg);
+
+/*******************************************************************************
+**
+** Function         RW_T1tSetTagReadOnly
+**
+** Description      This function can be called to set the tag in to read only
+**                  state
+**
+** Parameters:      b_hard_lock: To hard lock or just soft lock the tag
+**
+** Returns          NCI_STATUS_OK, if set readonly operation started.
+**                                 Otherwise, error status.
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_T1tSetTagReadOnly(bool b_hard_lock);
+
+/*****************************************************************************
+**
+** Function         RW_T1tPresenceCheck
+**
+** Description
+**      Check if the tag is still in the field.
+**
+**      The RW_T1T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
+**      or non-presence.
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+extern tNFC_STATUS RW_T1tPresenceCheck(void);
+
+/*****************************************************************************
+**
+** Function         RW_T1tFormatNDef
+**
+** Description
+**      Format Tag content
+**
+** Returns
+**      NFC_STATUS_OK, Command sent to format Tag
+**      NFC_STATUS_REJECTED: Invalid HR0 and cannot format the tag
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T1tFormatNDef(void);
+
+/*******************************************************************************
+**
+** Function         RW_T2tLocateTlv
+**
+** Description      This function is called to find the start of the given TLV
+**
+** Returns          Pointer to the TLV, if successful. Otherwise, NULL.
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_T2tLocateTlv(uint8_t tlv_type);
+
+/*******************************************************************************
+**
+** Function         RW_T2tRead
+**
+** Description      This function issues the Type 2 Tag READ command. When the
+**                  operation is complete the callback function will be called
+**                  with a RW_T2T_READ_EVT.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_T2tRead(uint16_t block);
+
+/*******************************************************************************
+**
+** Function         RW_T2tWrite
+**
+** Description      This function issues the Type 2 Tag WRITE command. When the
+**                  operation is complete the callback function will be called
+**                  with a RW_T2T_WRITE_EVT.
+**
+**                  p_write_data points to the array of 4 bytes to be written
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_T2tWrite(uint16_t block, uint8_t* p_write_data);
+
+/*******************************************************************************
+**
+** Function         RW_T2tSectorSelect
+**
+** Description      This function issues the Type 2 Tag SECTOR-SELECT command
+**                  packet 1. If a NACK is received as the response, the
+**                  callback function will be called with a
+**                  RW_T2T_SECTOR_SELECT_EVT. If an ACK is received as the
+**                  response, the command packet 2 with the given sector number
+**                  is sent to the peer device. When the response for packet 2
+**                  is received, the callback function will be called with a
+**                  RW_T2T_SECTOR_SELECT_EVT.
+**
+**                  A sector is 256 contiguous blocks (1024 bytes).
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_T2tSectorSelect(uint8_t sector);
+
+/*******************************************************************************
+**
+** Function         RW_T2tDetectNDef
+**
+** Description      This function will find NDEF message if any in the Tag
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_T2tDetectNDef(bool skip_dyn_locks);
+
+/*******************************************************************************
+**
+** Function         RW_T2tReadNDef
+**
+** Description      This function can be called to read the NDEF message on the
+**                  tag.
+**
+** Parameters:      p_buffer:   The buffer into which to read the NDEF message
+**                  buf_len:    The length of the buffer
+**
+** Returns          NCI_STATUS_OK, if read was started. Otherwise, error status.
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_T2tReadNDef(uint8_t* p_buffer, uint16_t buf_len);
+
+/*******************************************************************************
+**
+** Function         RW_T2tWriteNDef
+**
+** Description      This function can be called to write an NDEF message to the
+**                  tag.
+**
+** Parameters:      msg_len:    The length of the buffer
+**                  p_msg:      The NDEF message to write
+**
+** Returns          NCI_STATUS_OK, if write was started. Otherwise, error
+**                  status.
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_T2tWriteNDef(uint16_t msg_len, uint8_t* p_msg);
+
+/*******************************************************************************
+**
+** Function         RW_T2tSetTagReadOnly
+**
+** Description      This function can be called to set the tag in to read only
+**                  state
+**
+** Parameters:      b_hard_lock:   To indicate hard lock the tag or not
+**
+** Returns          NCI_STATUS_OK, if set readonly operation started.
+**                                 Otherwise, error status.
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_T2tSetTagReadOnly(bool b_hard_lock);
+
+/*****************************************************************************
+**
+** Function         RW_T2tPresenceCheck
+**
+** Description
+**      Check if the tag is still in the field.
+**
+**      The RW_T2T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
+**      or non-presence.
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+extern tNFC_STATUS RW_T2tPresenceCheck(void);
+
+/*****************************************************************************
+**
+** Function         RW_T2tFormatNDef
+**
+** Description
+**      Format Tag content
+**
+** Returns
+**      NFC_STATUS_OK, Command sent to format Tag
+**      NFC_STATUS_FAILED: otherwise
+**
+*****************************************************************************/
+tNFC_STATUS RW_T2tFormatNDef(void);
+
+/*****************************************************************************
+**
+** Function         RW_T3tDetectNDef
+**
+** Description
+**      This function is used to perform NDEF detection on a Type 3 tag, and
+**      retrieve the tag's NDEF attribute information (block 0).
+**
+**      Before using this API, the application must call RW_SelectTagType to
+**      indicate that a Type 3 tag has been activated, and to provide the
+**      tag's Manufacture ID (IDm) .
+**
+** Returns
+**      NFC_STATUS_OK: ndef detection procedure started
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+extern tNFC_STATUS RW_T3tDetectNDef(void);
+
+/*****************************************************************************
+**
+** Function         RW_T3tFormatNDef
+**
+** Description
+**      Format a type-3 tag for NDEF.
+**
+**      Only Felica-Lite tags are supported by this API. The
+**      RW_T3T_FORMAT_CPLT_EVT is used to notify the status of the operation.
+**
+** Returns
+**      NFC_STATUS_OK: ndef detection procedure started
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+extern tNFC_STATUS RW_T3tFormatNDef(void);
+
+/*****************************************************************************
+**
+** Function         RW_T3tSetReadOnly
+**
+** Description
+**      Set a type-3 tag to Read Only
+**
+**      Only Felica-Lite tags are supported by this API.
+**      RW_T3tDetectNDef() must be called before using this
+**      The RW_T3T_SET_READ_ONLY_CPLT_EVT event will be returned.
+**
+** Returns
+**      NFC_STATUS_OK if success
+**      NFC_STATUS_FAILED if T3T is busy or other error
+**
+*****************************************************************************/
+extern tNFC_STATUS RW_T3tSetReadOnly(bool b_hard_lock);
+
+/*****************************************************************************
+**
+** Function         RW_T3tCheckNDef
+**
+** Description
+**      Retrieve NDEF contents from a Type3 tag.
+**
+**      The RW_T3T_CHECK_EVT event is used to notify the application for each
+**      segment of NDEF data received. The RW_T3T_CHECK_CPLT_EVT event is used
+**      to notify the application all segments have been received.
+**
+**      Before using this API, the RW_T3tDetectNDef function must be called to
+**      verify that the tag contains NDEF data, and to retrieve the NDEF
+**      attributes.
+**
+**      Internally, this command will be separated into multiple Tag 3 Check
+**      commands (if necessary) - depending on the tag's Nbr (max number of
+**      blocks per read) attribute.
+**
+** Returns
+**      NFC_STATUS_OK: check command started
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+extern tNFC_STATUS RW_T3tCheckNDef(void);
+
+/*****************************************************************************
+**
+** Function         RW_T3tUpdateNDef
+**
+** Description
+**      Write NDEF contents to a Type3 tag.
+**
+**      The RW_T3T_UPDATE_CPLT_EVT callback event will be used to notify the
+**      application of the response.
+**
+**      Before using this API, the RW_T3tDetectNDef function must be called to
+**      verify that the tag contains NDEF data, and to retrieve the NDEF
+**      attributes.
+**
+**      Internally, this command will be separated into multiple Tag 3 Update
+**      commands (if necessary) - depending on the tag's Nbw (max number of
+**      blocks per write) attribute.
+**
+** Returns
+**      NFC_STATUS_OK: check command started
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_REFUSED: tag is read-only
+**      NFC_STATUS_BUFFER_FULL: len exceeds tag's maximum size
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+extern tNFC_STATUS RW_T3tUpdateNDef(uint32_t len, uint8_t* p_data);
+
+/*****************************************************************************
+**
+** Function         RW_T3tCheck
+**
+** Description
+**      Read (non-NDEF) contents from a Type3 tag.
+**
+**      The RW_READ_EVT event is used to notify the application for each
+**      segment of NDEF data received. The RW_READ_CPLT_EVT event is used to
+**      notify the application all segments have been received.
+**
+**      Before using this API, the application must call RW_SelectTagType to
+**      indicate that a Type 3 tag has been activated, and to provide the
+**      tag's Manufacture ID (IDm) .
+**
+** Returns
+**      NFC_STATUS_OK: check command started
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+extern tNFC_STATUS RW_T3tCheck(uint8_t num_blocks, tT3T_BLOCK_DESC* t3t_blocks);
+
+/*****************************************************************************
+**
+** Function         RW_T3tUpdate
+**
+** Description
+**      Write (non-NDEF) contents to a Type3 tag.
+**
+**      The RW_WRITE_CPLT_EVT event is used to notify the application all
+**      segments have been received.
+**
+**      Before using this API, the application must call RW_SelectTagType to
+**      indicate that a Type 3 tag has been activated, and to provide the tag's
+**      Manufacture ID (IDm) .
+**
+** Returns
+**      NFC_STATUS_OK: check command started
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+extern tNFC_STATUS RW_T3tUpdate(uint8_t num_blocks, tT3T_BLOCK_DESC* t3t_blocks,
+                                uint8_t* p_data);
+
+/*****************************************************************************
+**
+** Function         RW_T3tSendRawFrame
+**
+** Description
+**      This function is called to send a raw data frame to the peer device.
+**      When type 3 tag receives response from peer, the callback function
+**      will be called with a RW_T3T_RAW_FRAME_EVT [Table 6].
+**
+**      Before using this API, the application must call RW_SelectTagType to
+**      indicate that a Type 3 tag has been activated.
+**
+**      The raw frame should be a properly formatted Type 3 tag message.
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+extern tNFC_STATUS RW_T3tSendRawFrame(uint16_t len, uint8_t* p_data);
+
+/*****************************************************************************
+**
+** Function         RW_T3tPoll
+**
+** Description
+**      Send POLL command
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+extern tNFC_STATUS RW_T3tPoll(uint16_t system_code, tT3T_POLL_RC rc,
+                              uint8_t tsn);
+
+/*****************************************************************************
+**
+** Function         RW_T3tPresenceCheck
+**
+** Description
+**      Check if the tag is still in the field.
+**
+**      The RW_T3T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
+**      or non-presence.
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+extern tNFC_STATUS RW_T3tPresenceCheck(void);
+
+/*****************************************************************************
+**
+** Function         RW_T3tGetSystemCodes
+**
+** Description
+**      Get systems codes supported by the activated tag:
+**              Poll for wildcard (FFFF):
+**                  - If felica-lite code then poll for ndef (12fc)
+**                  - Otherwise send RequestSystmCode command to get
+**                    system codes.
+**
+**      Before using this API, the application must call RW_SelectTagType to
+**      indicate that a Type 3 tag has been activated.
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+extern tNFC_STATUS RW_T3tGetSystemCodes(void);
+
+/*****************************************************************************
+**
+** Function         RW_T4tFormatNDef
+**
+** Description
+**      Format a type-4 tag for NDEF.
+**
+**      Only Desifire tags are supported by this API. The
+**      RW_T4T_FORMAT_CPLT_EVT is used to notify the status of the operation.
+**
+** Returns
+**      NFC_STATUS_OK: if success
+**      NFC_STATUS_FAILED: other error
+*****************************************************************************/
+extern tNFC_STATUS RW_T4tFormatNDef(void);
+
+/*******************************************************************************
+**
+** Function         RW_T4tDetectNDef
+**
+** Description      This function performs NDEF detection procedure
+**
+**                  RW_T4T_NDEF_DETECT_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if T4T is busy or other error
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_T4tDetectNDef(void);
+
+/*******************************************************************************
+**
+** Function         RW_T4tReadNDef
+**
+** Description      This function performs NDEF read procedure
+**                  Note: RW_T4tDetectNDef() must be called before using this
+**
+**                  The following event will be returned
+**                      RW_T4T_NDEF_READ_EVT for each segmented NDEF message
+**                      RW_T4T_NDEF_READ_CPLT_EVT for the last segment or
+**                      complete NDEF
+**                      RW_T4T_NDEF_READ_FAIL_EVT for failure
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if T4T is busy or other error
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_T4tReadNDef(void);
+
+/*******************************************************************************
+**
+** Function         RW_T4tUpdateNDef
+**
+** Description      This function performs NDEF update procedure
+**                  Note: RW_T4tDetectNDef() must be called before using this
+**                        Updating data must not be removed until returning
+**                        event
+**
+**                  The following event will be returned
+**                      RW_T4T_NDEF_UPDATE_CPLT_EVT for complete
+**                      RW_T4T_NDEF_UPDATE_FAIL_EVT for failure
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if T4T is busy or other error
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_T4tUpdateNDef(uint16_t length, uint8_t* p_data);
+
+/*****************************************************************************
+**
+** Function         RW_T4tPresenceCheck
+**
+** Description
+**      Check if the tag is still in the field.
+**
+**      The RW_T4T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
+**      or non-presence.
+**
+**      option is RW_T4T_CHK_EMPTY_I_BLOCK, use empty I block for presence
+**      check.
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+extern tNFC_STATUS RW_T4tPresenceCheck(uint8_t option);
+
+/*****************************************************************************
+**
+** Function         RW_T4tSetNDefReadOnly
+**
+** Description      This function performs NDEF read-only procedure
+**                  Note: RW_T4tDetectNDef() must be called before using this
+**
+**                  The RW_T4T_SET_TO_RO_EVT event will be returned.
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if T4T is busy or other error
+**
+*****************************************************************************/
+extern tNFC_STATUS RW_T4tSetNDefReadOnly(void);
+
+/*******************************************************************************
+**
+** Function         RW_I93Inventory
+**
+** Description      This function send Inventory command with/without AFI
+**                  If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
+**
+**                  RW_I93_RESPONSE_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_FAILED if T4T is busy or other error
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_I93Inventory(bool including_afi, uint8_t afi,
+                                   uint8_t* p_uid);
+
+/*******************************************************************************
+**
+** Function         RW_I93StayQuiet
+**
+** Description      This function send Inventory command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_I93StayQuiet(void);
+
+/*******************************************************************************
+**
+** Function         RW_I93ReadSingleBlock
+**
+** Description      This function send Read Single Block command
+**
+**                  RW_I93_RESPONSE_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_I93ReadSingleBlock(uint16_t block_number);
+
+/*******************************************************************************
+**
+** Function         RW_I93WriteSingleBlock
+**
+** Description      This function send Write Single Block command
+**                  Application must get block size first by calling
+**                  RW_I93GetSysInfo().
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_I93WriteSingleBlock(uint16_t block_number,
+                                          uint8_t* p_data);
+
+/*******************************************************************************
+**
+** Function         RW_I93LockBlock
+**
+** Description      This function send Lock Block command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_I93LockBlock(uint8_t block_number);
+
+/*******************************************************************************
+**
+** Function         RW_I93ReadMultipleBlocks
+**
+** Description      This function send Read Multiple Blocks command
+**
+**                  RW_I93_RESPONSE_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_I93ReadMultipleBlocks(uint16_t first_block_number,
+                                            uint16_t number_blocks);
+
+/*******************************************************************************
+**
+** Function         RW_I93WriteMultipleBlocks
+**
+** Description      This function send Write Multiple Blocks command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_I93WriteMultipleBlocks(uint8_t first_block_number,
+                                             uint16_t number_blocks,
+                                             uint8_t* p_data);
+
+/*******************************************************************************
+**
+** Function         RW_I93Select
+**
+** Description      This function send Select command
+**
+**                  UID[0]: 0xE0, MSB
+**                  UID[1]: IC Mfg Code
+**                  ...
+**                  UID[7]: LSB
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_I93Select(uint8_t* p_uid);
+
+/*******************************************************************************
+**
+** Function         RW_I93ResetToReady
+**
+** Description      This function send Reset To Ready command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_I93ResetToReady(void);
+
+/*******************************************************************************
+**
+** Function         RW_I93WriteAFI
+**
+** Description      This function send Write AFI command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_I93WriteAFI(uint8_t afi);
+
+/*******************************************************************************
+**
+** Function         RW_I93LockAFI
+**
+** Description      This function send Lock AFI command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_I93LockAFI(void);
+
+/*******************************************************************************
+**
+** Function         RW_I93WriteDSFID
+**
+** Description      This function send Write DSFID command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_I93WriteDSFID(uint8_t dsfid);
+
+/*******************************************************************************
+**
+** Function         RW_I93LockDSFID
+**
+** Description      This function send Lock DSFID command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_I93LockDSFID(void);
+
+/*******************************************************************************
+**
+** Function         RW_I93GetSysInfo
+**
+** Description      This function send Get System Information command
+**                  If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
+**
+**                  RW_I93_RESPONSE_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_I93GetSysInfo(uint8_t* p_uid);
+
+/*******************************************************************************
+**
+** Function         RW_I93GetMultiBlockSecurityStatus
+**
+** Description      This function send Get Multiple Block Security Status
+**                  command
+**
+**                  RW_I93_RESPONSE_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_I93GetMultiBlockSecurityStatus(
+    uint16_t first_block_number, uint16_t number_blocks);
+
+/*******************************************************************************
+**
+** Function         RW_I93DetectNDef
+**
+** Description      This function performs NDEF detection procedure
+**
+**                  RW_I93_NDEF_DETECT_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if busy or other error
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_I93DetectNDef(void);
+
+/*******************************************************************************
+**
+** Function         RW_I93ReadNDef
+**
+** Description      This function performs NDEF read procedure
+**                  Note: RW_I93DetectNDef() must be called before using this
+**
+**                  The following event will be returned
+**                      RW_I93_NDEF_READ_EVT for each segmented NDEF message
+**                      RW_I93_NDEF_READ_CPLT_EVT for the last segment or
+**                      complete NDEF
+**                      RW_I93_NDEF_READ_FAIL_EVT for failure
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if I93 is busy or other error
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_I93ReadNDef(void);
+
+/*******************************************************************************
+**
+** Function         RW_I93UpdateNDef
+**
+** Description      This function performs NDEF update procedure
+**                  Note: RW_I93DetectNDef() must be called before using this
+**                        Updating data must not be removed until returning
+**                        event
+**
+**                  The following event will be returned
+**                      RW_I93_NDEF_UPDATE_CPLT_EVT for complete
+**                      RW_I93_NDEF_UPDATE_FAIL_EVT for failure
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if I93 is busy or other error
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_I93UpdateNDef(uint16_t length, uint8_t* p_data);
+
+/*******************************************************************************
+**
+** Function         RW_I93FormatNDef
+**
+** Description      This function performs formatting procedure
+**
+**                  RW_I93_FORMAT_CPLT_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if busy or other error
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_I93FormatNDef(void);
+
+/*******************************************************************************
+**
+** Function         RW_I93SetTagReadOnly
+**
+** Description      This function performs NDEF read-only procedure
+**                  Note: RW_I93DetectNDef() must be called before using this
+**                        Updating data must not be removed until returning
+**                        event
+**
+**                  The RW_I93_SET_TAG_RO_EVT event will be returned.
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if I93 is busy or other error
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_I93SetTagReadOnly(void);
+
+/*****************************************************************************
+**
+** Function         RW_I93PresenceCheck
+**
+** Description      Check if the tag is still in the field.
+**
+**                  The RW_I93_PRESENCE_CHECK_EVT w/ status is used to indicate
+**                  presence or non-presence.
+**
+** Returns          NFC_STATUS_OK, if raw data frame sent
+**                  NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this
+**                  operation
+**                  NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+extern tNFC_STATUS RW_I93PresenceCheck(void);
+
+/*******************************************************************************
+**
+** Function         RW_SendRawFrame
+**
+** Description      This function sends a raw frame to the peer device.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_SendRawFrame(uint8_t* p_raw_data, uint16_t data_len);
+
+/*******************************************************************************
+**
+** Function         RW_SetActivatedTagType
+**
+** Description      This function sets tag type for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+extern tNFC_STATUS RW_SetActivatedTagType(tNFC_ACTIVATE_DEVT* p_activate_params,
+                                          tRW_CBACK* p_cback);
+
+/*******************************************************************************
+**
+** Function         RW_SetTraceLevel
+**
+** Description      This function sets the trace level for Reader/Writer mode.
+**                  If called with a value of 0xFF,
+**                  it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+extern uint8_t RW_SetTraceLevel(uint8_t new_level);
+
+#if (NXP_EXTNS == TRUE)
+extern tNFC_STATUS RW_T3BtGetPupiID();
+#endif
+
+#endif /* RW_API_H */
diff --git a/src/nfc/include/tags_defs.h b/src/nfc/include/tags_defs.h
new file mode 100644
index 0000000..60ae9f1
--- /dev/null
+++ b/src/nfc/include/tags_defs.h
@@ -0,0 +1,806 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the Near Field Communication (NFC) Tags related
+ *  definitions from the specification.
+ *
+ ******************************************************************************/
+
+#ifndef TAGS_DEFS_H
+#define TAGS_DEFS_H
+
+/* Manufacturer ID */
+/* BROADCOM CORPORATION                           */
+#define TAG_BRCM_MID 0x2E
+/* MIFARE                                         */
+#define TAG_MIFARE_MID 0x04
+/* KOVIO                                          */
+#define TAG_KOVIO_MID 0x37
+/* Infineon Technologies                          */
+#define TAG_INFINEON_MID 0x05
+
+/* TLV types present in Type1 and Type 2 Tags */
+/* May be used for padding. SHALL ignore this     */
+#define TAG_NULL_TLV 0
+/* Defines details of the lock bytes              */
+#define TAG_LOCK_CTRL_TLV 1
+/* Identifies reserved memory areas               */
+#define TAG_MEM_CTRL_TLV 2
+/* Contains the NDEF message                      */
+#define TAG_NDEF_TLV 3
+/* Tag proprietary information                    */
+#define TAG_PROPRIETARY_TLV 0xFD
+/* Last TLV block in the data area                */
+#define TAG_TERMINATOR_TLV 0xFE
+/* Number of bits in every tag byte               */
+#define TAG_BITS_PER_BYTE 0x08
+/* Max UID Len of type 1 and type 2 tag           */
+#define TAG_MAX_UID_LEN 0x0A
+
+/* Byte 0 Length field to indicate LNDEF  */
+#define TAG_LONG_NDEF_LEN_FIELD_BYTE0 0xFF
+/* Tlv len for LOCK_CTRL/MEM TLV per spec */
+#define TAG_DEFAULT_TLV_LEN 3
+
+/* Type 1 Tag related definitions */
+
+/* block 0 to Block E                             */
+#define T1T_STATIC_BLOCKS 0x0F
+/* T1T Block size in bytes                        */
+#define T1T_BLOCK_SIZE 0x08
+
+#define T1T_STATIC_SIZE \
+  T1T_STATIC_BLOCKS* T1T_BLOCK_SIZE /* Static Tag size   */
+
+/* Size of Type 1 Tag segment in bytes            */
+#define T1T_SEGMENT_SIZE 0x80
+/* Maximum segment supported by Type 1 Tag        */
+#define T1T_MAX_SEGMENTS 0x10
+/* Number of blocks present in a segment          */
+#define T1T_BLOCKS_PER_SEGMENT 0x10
+/* No.of default OTP,staticlocks,res bytes in tag */
+#define T1T_OTP_LOCK_RES_BYTES 0x10
+
+/* HRO value to indicate static Tag               */
+#define T1T_STATIC_HR0 0x11
+/* 0x1y, as long as (y!=1)                        */
+#define T1T_DYNAMIC_HR0 0x12
+/* HR0 value is 0x1y, indicates NDEF supported    */
+#define T1T_NDEF_SUPPORTED 0x10
+/* should be ignored                              */
+#define T1T_HR1 0x00
+/* UID block                                      */
+#define T1T_UID_BLOCK 0x00
+/* Reserved block                                 */
+#define T1T_RES_BLOCK 0x0D
+/* Static lock block                              */
+#define T1T_LOCK_BLOCK 0x0E
+/* Manufacturer ID offset                         */
+#define T1T_MID_OFFSET 0x06
+/* Reserved bytes offset                          */
+#define T1T_STATIC_RES_OFFSET 0x68
+/* Static lock offset                             */
+#define T1T_LOCK_0_OFFSET 0x70
+/* Static lock offset                             */
+#define T1T_LOCK_1_OFFSET 0x71
+/* Block F - typically used for dynamic locks     */
+#define T1T_DYNAMIC_LOCK_OFFSET 0x78
+#define T1T_DYNAMIC_LOCK_BYTES 0x08
+
+/* the len of reserved byte in T1T block 0        */
+#define T1T_RES_BYTE_LEN 1
+
+/* Capability Container definitions */
+/* Capability container block                     */
+#define T1T_CC_BLOCK 1
+/* the len of CC used in T1T tag                  */
+#define T1T_CC_LEN 4
+/* CC offset */
+/* Offset for NDEF magic number in CC             */
+#define T1T_CC_NMN_OFFSET 0x00
+/* Offset for Version number in CC                */
+#define T1T_CC_VNO_OFFSET 0x01
+/* Offset for Tag memory size in CC               */
+#define T1T_CC_TMS_OFFSET 0x02
+/* Offset for Read/Write access in CC             */
+#define T1T_CC_RWA_OFFSET 0x03
+/* NDEF Magic Number byte number                  */
+#define T1T_CC_NMN_BYTE 0x08
+/* Version Number byte number                     */
+#define T1T_CC_VNO_BYTE 0x09
+/* Tag Memory Size byte number                    */
+#define T1T_CC_TMS_BYTE 0x0A
+/* Read Write Access byte number                  */
+#define T1T_CC_RWA_BYTE 0x0B
+/* NDEF Magic Number                              */
+#define T1T_CC_NMN 0xE1
+/* Supported Legacy Version                       */
+#define T1T_CC_LEGACY_VNO 0x10
+/* Version Number                                 */
+#define T1T_CC_VNO 0x11
+/* TMS static memory - (8 * (n+1)).               */
+#define T1T_CC_TMS_STATIC 0x0E
+/* RWA - Read/write allowed                       */
+#define T1T_CC_RWA_RW 0x00
+/* RWA - Read only                                */
+#define T1T_CC_RWA_RO 0x0F
+
+/* May be used for padding. SHALL ignore this     */
+#define T1T_TAG_NULL 0
+/* Defines details of the lock bytes              */
+#define T1T_TAG_LOCK_CTRL 1
+/* Identifies reserved memory areas               */
+#define T1T_TAG_MEM_CTRL 2
+/* Contains the NDEF message                      */
+#define T1T_TAG_NDEF 3
+/* Tag proprietary information                    */
+#define T1T_TAG_PROPRIETARY 0xFD
+/* Last TLV block in the data area                */
+#define T1T_TAG_TERMINATOR 0xFE
+
+/* Tlv len for LOCK_CTRL/MEM TLV per spec         */
+#define T1T_DEFAULT_TLV_LEN 3
+/* Tlv type identifier len                        */
+#define T1T_TLV_TYPE_LEN 1
+/* Length field size of  lock/mem tlv     */
+#define T1T_DEFAULT_TLV_LEN_FIELD_LEN 1
+
+/* the len of HR used in Type 1 Tag               */
+#define T1T_HR_LEN 2
+/* the len of UID used in Type 1 Tag Commands     */
+#define T1T_CMD_UID_LEN 4
+/* the len of UID used in Type 1 Tag              */
+#define T1T_UID_LEN 7
+#define T1T_ADD_LEN 1
+
+/* Length Field size of short NDEF Message    */
+#define T1T_SHORT_NDEF_LEN_FIELD_LEN 1
+/* Length Field size of Long NDEF Message     */
+#define T1T_LONG_NDEF_LEN_FIELD_LEN 3
+/* Byte 0 in Length field to indicate LNDEF*/
+#define T1T_LONG_NDEF_LEN_FIELD_BYTE0 0xFF
+/* Min. len of NDEF to qualify as LNDEF  */
+#define T1T_LONG_NDEF_MIN_LEN 0x00FF
+
+/* Type 1 Tag Commands (7 bits) */
+/* read id                                      */
+#define T1T_CMD_RID 0x78
+/* read all bytes                               */
+#define T1T_CMD_RALL 0x00
+/* read (1 byte)                                */
+#define T1T_CMD_READ 0x01
+/* write with erase (1 byte)                    */
+#define T1T_CMD_WRITE_E 0x53
+/* write no erase (1 byte)                      */
+#define T1T_CMD_WRITE_NE 0x1A
+/* dynamic memory only */
+/* read segment                                 */
+#define T1T_CMD_RSEG 0x10
+/* read (8 byte)                                */
+#define T1T_CMD_READ8 0x02
+/* write with erase (8 byte)                    */
+#define T1T_CMD_WRITE_E8 0x54
+/* write no erase (8 byte)                      */
+#define T1T_CMD_WRITE_NE8 0x1B
+
+/* Lock */
+/* Number of static lock bytes in tag   */
+#define T1T_NUM_STATIC_LOCK_BYTES 2
+/* Bytes locked by one static lock bit  */
+#define T1T_BYTES_LOCKED_BY_STATIC_LOCK_BIT 4
+
+/* Type 2 Tag related definitions */
+#define T2T_STATIC_MEM_STR 0
+#define T2T_DYNAMIC_MEM_STR 1
+#define T2T_STATIC_SIZE 64
+#define T2T_STATIC_BLOCKS 16 /* block 0 to Block 15 */
+#define T2T_BLOCK_SIZE 4
+#define T2T_HEADER_BLOCKS 4
+#define T2T_HEADER_SIZE 16
+#define T2T_SECTOR_SIZE 1024
+#define T2T_BLOCKS_PER_SECTOR 0x100
+
+#define T2T_UID_LEN 4        /* the len of UID used in T2T tag */
+#define T2T_BLOCK0_UID_LEN 3 /* the len of UID in Block 0 of T2T tag */
+#define T2T_BCC0_LEN 1       /* the len of BCC0 of T2T tag */
+#define T2T_BLOCK1_UID_LEN 4 /* the len of UID in Block 1 of T2T tag */
+#define T2T_BCC1_LEN 1       /* the len of BCC0 of T2T tag */
+/* the len of Serial number used in T2T tag */
+#define T2T_SNO_LEN 4
+#define T2T_INTERNAL_BYTES_LEN 2 /* the len of internal used in T2T tag */
+/* the len of static lock used in T2T tag */
+#define T2T_STATIC_LOCK_LEN 2
+/* Static Lock Bytes */
+#define T2T_STATIC_LOCK0 0x0A /* Static Lock 0 offset */
+#define T2T_STATIC_LOCK1 0x0B /* Static Lock 1 offset */
+
+/* the len of CC used in T2T tag                  */
+#define T2T_CC_LEN 4
+
+/* Capability Container definitions */
+#define T2T_CC_BLOCK 0x03     /* Capability container block */
+#define T2T_CC0_NMN_BYTE 0x0C /* NDEF Magic Number byte number */
+#define T2T_CC1_VNO_BYTE 0x0D /* Version Number byte number*/
+#define T2T_CC2_TMS_BYTE 0x0E /* Tag Memory Size byte number */
+#define T2T_CC3_RWA_BYTE 0x0F /* Read Write Access byte number */
+#define T2T_DATA_MEM 0x10     /* Data Memory */
+
+#define T2T_CC0_NMN 0xE1        /* NDEF Magic Number */
+#define T2T_CC1_VNO 0x11        /* Version Number */
+#define T2T_CC1_LEGACY_VNO 0x10 /* Legacy Version Number */
+#define T2T_CC1_NEW_VNO 0x12    /* Another supported Version Number */
+#define T2T_CC2_TMS_STATIC 0x06 /* TMS static memory - (4 * (n+1)). */
+#define T2T_CC3_RWA_RW 0x00     /* RWA - Read/write allowed */
+#define T2T_CC3_RWA_RO 0x0F     /* RWA - Read only */
+
+/* Factor to multiply to get tag data size from TMS */
+#define T2T_TMS_TAG_FACTOR 0x08
+/* Bytes locked per lock bit of default locks */
+#define T2T_DEFAULT_LOCK_BLPB 0x08
+
+/* Type 2 Tag Commands  */
+#define T2T_CMD_READ 0x30    /* read  4 blocks (16 bytes) */
+#define T2T_CMD_WRITE 0xA2   /* write 1 block  (4 bytes)  */
+#define T2T_CMD_SEC_SEL 0xC2 /* Sector select             */
+#define T2T_RSP_ACK 0xA
+#define T2T_RSP_NACK5 0x5
+#define T2T_RSP_NACK1 0x1 /* Nack can be either 1    */
+
+#define T2T_STATUS_OK_1_BIT 0x11
+#define T2T_STATUS_OK_2_BIT 0x12
+#define T2T_STATUS_OK_3_BIT 0x13
+#define T2T_STATUS_OK_4_BIT 0x14
+#define T2T_STATUS_OK_5_BIT 0x15
+#define T2T_STATUS_OK_6_BIT 0x16
+#define T2T_STATUS_OK_7_BIT 0x17
+
+#define T2T_FIRST_DATA_BLOCK 4
+#define T2T_READ_BLOCKS 4
+#define T2T_BLOCK_LEN 4
+#define T2T_READ_DATA_LEN (T2T_BLOCK_LEN * T2T_READ_BLOCKS)
+#define T2T_WRITE_DATA_LEN 4
+
+/* Type 2 TLV definitions */
+/* May be used for padding. SHALL ignore this */
+#define T2T_TLV_TYPE_NULL 0
+#define T2T_TLV_TYPE_LOCK_CTRL 1      /* Defines details of the lock bytes */
+#define T2T_TLV_TYPE_MEM_CTRL 2       /* Identifies reserved memory areas */
+#define T2T_TLV_TYPE_NDEF 3           /* Contains the NDEF message */
+#define T2T_TLV_TYPE_PROPRIETARY 0xFD /* Tag proprietary information */
+#define T2T_TLV_TYPE_TERMINATOR 0xFE  /* Last TLV block in the data area */
+
+/* Tag len for LOCK_CTRL TLV per spec */
+#define T2T_TLEN_LOCK_CTRL_TLV 3
+/* Tag len for MEM_CTRL TLV per spec */
+#define T2T_TLEN_MEM_CTRL_TLV 3
+
+#if (NXP_EXTNS == TRUE)
+/* Maximum number of sectors supported */
+#define T2T_MAX_SECTOR 3
+#else
+/* Maximum number of sectors supported */
+#define T2T_MAX_SECTOR 2
+#endif
+
+/* Tlv type identifier len                */
+#define T2T_TLV_TYPE_LEN 1
+
+/* Tlv len for LOCK_CTRL/MEM TLV per spec     */
+#define T2T_DEFAULT_TLV_LEN 3
+/* Length Field size of short NDEF Message    */
+#define T2T_SHORT_NDEF_LEN_FIELD_LEN 1
+/* Length Field size of Long NDEF Message     */
+#define T2T_LONG_NDEF_LEN_FIELD_LEN 3
+/* Byte 0 in Length field to indicate LNDEF*/
+#define T2T_LONG_NDEF_LEN_FIELD_BYTE0 0xFF
+/* Min. len of NDEF to qualify as LNDEF  */
+#define T2T_LONG_NDEF_MIN_LEN 0x00FF
+
+/* Lock */
+/* Number of static lock bytes in tag   */
+#define T2T_NUM_STATIC_LOCK_BYTES 2
+/* Bytes locked by one static lock bit  */
+#define T2T_BYTES_LOCKED_BY_STATIC_LOCK_BIT 4
+
+#define T2T_CC2_TMS_MUL 0x06
+#define T2T_CC2_TMS_MULC 0x12
+/*
+ **
+ **  Type 3 Tag Definitions
+ **
+ */
+
+#define T3T_SYSTEM_CODE_NDEF 0x12FC /* System Code for NDEF tags */
+/* System Code for felica-lite tags */
+#define T3T_SYSTEM_CODE_FELICA_LITE 0x88B4
+#define T3T_MAX_SYSTEM_CODES 16
+/* Maximum number of blocks for NDEF message for Felica Lite tags */
+#define T3T_FELICALITE_NMAXB 13
+
+/* Block descriptor, used to describe a block to check/update */
+typedef struct {
+  uint16_t service_code; /* Block service code. Set to T3T_SERVICE_CODE_NDEF
+                            (0x000B) for NDEF data */
+  uint16_t block_number; /* Block number */
+} tT3T_BLOCK_DESC;
+
+/* Poll RC (request code) definitions */
+#define T3T_POLL_RC_NONE 0 /* No RD requested in SENSF_RES */
+#define T3T_POLL_RC_SC 1   /* System code requested in SENSF_RES */
+/* Avanced protocol features requested in SENSF_RES */
+#define T3T_POLL_RC_COMM 2
+typedef uint8_t tT3T_POLL_RC;
+
+/* Definitions for constructing t3t command messages */
+
+/* NFC Forum / Felica commands */
+#define T3T_MSG_OPC_CHECK_CMD 0x06
+#define T3T_MSG_OPC_CHECK_RSP 0x07
+#define T3T_MSG_OPC_UPDATE_CMD 0x08
+#define T3T_MSG_OPC_UPDATE_RSP 0x09
+
+/* Felica commands (not specified in NFC-Forum Type 3 tag specifications) */
+#define T3T_MSG_OPC_POLL_CMD 0x00
+#define T3T_MSG_OPC_POLL_RSP 0x01
+#define T3T_MSG_OPC_REQ_SERVICE_CMD 0x02
+#define T3T_MSG_OPC_REQ_SERVICE_RSP 0x03
+#define T3T_MSG_OPC_REQ_RESPONSE_CMD 0x04
+#define T3T_MSG_OPC_REQ_RESPONSE_RSP 0x05
+#define T3T_MSG_OPC_REQ_SYSTEMCODE_CMD 0x0C
+#define T3T_MSG_OPC_REQ_SYSTEMCODE_RSP 0x0D
+
+/* Service code: read-only NDEF */
+#define T3T_MSG_NDEF_SC_RO 0x000B
+/* Service code: read/write NDEF */
+#define T3T_MSG_NDEF_SC_RW 0x0009
+#define T3T_MSG_NDEF_VERSION 0x10 /* NDEF Mapping Version 1.0 */
+#define T3T_MSG_NDEF_WRITEF_OFF 0x00
+#define T3T_MSG_NDEF_WRITEF_ON 0x0F
+#define T3T_MSG_NDEF_RWFLAG_RO 0x00
+#define T3T_MSG_NDEF_RWFLAG_RW 0x01
+/* Size of NDEF attribute info block (minus checksum) */
+#define T3T_MSG_NDEF_ATTR_INFO_SIZE 14
+
+/* offset of Manufacturer ID in UPDATE/CHECK messages */
+#define T3T_MSG_OFFSET_IDM 1
+/* offset of Number of Services parameter in UPDATE/CHECK messages */
+#define T3T_MSG_OFFSET_NUM_SERVICES 9
+/* offset of Service Code List parameter in UPDATE/CHECK messages */
+#define T3T_MSG_OFFSET_SERVICE_CODE_LIST 10
+/* len flag for Block List Element */
+#define T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT 0x80
+/* service code list mask */
+#define T3T_MSG_SERVICE_LIST_MASK 0x0F
+#define T3T_MSG_SERVICE_LIST_MAX 16
+
+/* Max Number of Services per UPDATE command */
+#define T3T_MSG_NUM_SERVICES_UPDATE_MAX 12
+/* Max Number of Services per CHECK command */
+#define T3T_MSG_NUM_SERVICES_CHECK_MAX 15
+/* Max Number of Blocks per UPDATE command */
+#define T3T_MSG_NUM_BLOCKS_UPDATE_MAX 13
+/* Max Number of Blocks per CHECK command */
+#define T3T_MSG_NUM_BLOCKS_CHECK_MAX 15
+
+/* Data block size for UPDATE and CHECK commands */
+#define T3T_MSG_BLOCKSIZE 16
+
+/* Common header definitions for T3t commands */
+/* Common header: SoD + cmdcode + NFCID2 + num_services */
+#define T3T_MSG_CMD_COMMON_HDR_LEN 11
+
+/* Common header definition for T3t responses */
+/* Common header: rspcode + NFCID2 + StatusFlag1 + StatusFlag2  */
+#define T3T_MSG_RSP_COMMON_HDR_LEN 11
+/* Common header + NumBlocks */
+#define T3T_MSG_RSP_CHECK_HDR_LEN (T3T_MSG_RSP_COMMON_HDR_LEN + 1)
+/* Offset for Response code */
+#define T3T_MSG_RSP_OFFSET_RSPCODE 0
+/* Offset for Manufacturer ID */
+#define T3T_MSG_RSP_OFFSET_IDM 1
+/* Offset for Status Flag1 */
+#define T3T_MSG_RSP_OFFSET_STATUS1 9
+/* Offset for NumberOfBlocks (in CHECK response) */
+#define T3T_MSG_RSP_OFFSET_NUMBLOCKS 11
+/* Offset for Block Data (in CHECK response) */
+#define T3T_MSG_RSP_OFFSET_CHECK_DATA 12
+/* Offset for PMm (in POLL response) */
+#define T3T_MSG_RSP_OFFSET_POLL_PMM 9
+/* Offset for RD (in POLL response) */
+#define T3T_MSG_RSP_OFFSET_POLL_RD 17
+/* Offset for Number of Systems */
+#define T3T_MSG_RSP_OFFSET_NUMSYS 9
+
+#define T3T_MSG_RSP_STATUS_OK 0x00
+#define T3T_MSG_RSP_STATUS_ERROR 0x01
+
+#define T3T_MSG_RSP_STATUS2_ERROR_MEMORY 0x70
+#define T3T_MSG_RSP_STATUS2_ERROR_EXCESSIVE_WRITES 0x71
+#define T3T_MSG_RSP_STATUS2_ERROR_PROCESSING 0xFF
+
+/* Maximum payload lenght for NFC-F messages (including SoD) */
+#define T3T_NFC_F_MAX_PAYLOAD_LEN 0xFE
+
+/* Felica Lite defintions */
+/* Block ID for MC (memory configuration)                       */
+#define T3T_MSG_FELICALITE_BLOCK_ID_MC 0x88
+
+/* Memory Configuration Block offset: MC_SP (Memory Configuration for scratch
+ * pad)   */
+#define T3T_MSG_FELICALITE_MC_OFFSET_MC_SP 0x00
+/* Memory Configuration Block offset: MC_ALL (Memory Configuration for system
+ * block) */
+#define T3T_MSG_FELICALITE_MC_OFFSET_MC_ALL 0x02
+/* Memory Configuration Block offset: SYS_OP (System Option) */
+#define T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP 0x03
+/* Memory Configuration Block offset: RF_PRM (Memory Configuration for RF
+ * Parameter) */
+#define T3T_MSG_FELICALITE_MC_OFFSET_RF_PRM 0x04
+
+/*
+ **
+ **  Type 4 Tag Definitions
+ **
+ */
+#define T4T_CMD_MIN_HDR_SIZE 4 /* CLA, INS, P1, P2 */
+#define T4T_CMD_MAX_HDR_SIZE 5 /* CLA, INS, P1, P2, Lc */
+
+#define T4T_VERSION_2_0 0x20 /* version 2.0 */
+#define T4T_VERSION_1_0 0x10 /* version 1.0 */
+#define T4T_MY_VERSION T4T_VERSION_2_0
+#define T4T_GET_MAJOR_VERSION(x) ((x) >> 4)
+#define T4T_GET_MINOR_VERSION(x) ((x)&0x0F)
+
+#define T4T_CMD_CLASS 0x00
+#define T4T_CMD_INS_SELECT 0xA4
+#define T4T_CMD_INS_READ_BINARY 0xB0
+#define T4T_CMD_INS_UPDATE_BINARY 0xD6
+#define T4T_CMD_DES_CLASS 0x90
+#define T4T_CMD_INS_GET_HW_VERSION 0x60
+#define T4T_CMD_CREATE_AID 0xCA
+#define T4T_CMD_SELECT_APP 0x5A
+#define T4T_CMD_CREATE_DATAFILE 0xCD
+#define T4T_CMD_DES_WRITE 0x3D
+#define T4T_CMD_P1_SELECT_BY_NAME 0x04
+#define T4T_CMD_P1_SELECT_BY_FILE_ID 0x00
+#define T4T_CMD_P2_FIRST_OR_ONLY_00H 0x00
+#define T4T_CMD_P2_FIRST_OR_ONLY_0CH 0x0C
+
+/* Max number of bytes to be read from file in ReadBinary Command */
+#define T4T_MAX_LENGTH_LE 0xFF
+/* Max number of bytes written to NDEF file in UpdateBinary Command */
+#define T4T_MAX_LENGTH_LC 0xFF
+
+#define T4T_RSP_STATUS_WORDS_SIZE 0x02
+
+#define T4T_RSP_CMD_CMPLTED 0x9000
+#define T4T_RSP_NOT_FOUND 0x6A82
+#define T4T_RSP_WRONG_PARAMS 0x6B00
+#define T4T_RSP_CLASS_NOT_SUPPORTED 0x6E00
+#define T4T_RSP_WRONG_LENGTH 0x6700
+#define T4T_RSP_INSTR_NOT_SUPPORTED 0x6D00
+#define T4T_RSP_CMD_NOT_ALLOWED 0x6986
+
+/* V1.0 Type 4 Tag Applicaiton ID length */
+#define T4T_V10_NDEF_TAG_AID_LEN 0x07
+/* V2.0 Type 4 Tag Applicaiton ID length */
+#define T4T_V20_NDEF_TAG_AID_LEN 0x07
+
+/* Min of Max R-APDU data size */
+#define T4T_MIN_MLE 0x000F
+
+#define T4T_FILE_ID_SIZE 0x02
+#define T4T_CC_FILE_ID 0xE103
+#define T4T_CC_FILE_MIN_LEN 0x000F
+
+#define T4T_VERSION_OFFSET_IN_CC 0x02
+#define T4T_FC_TLV_OFFSET_IN_CC 0x07
+/* Offset of Write access byte from type field in CC */
+#define T4T_FC_WRITE_ACCESS_OFFSET_IN_TLV 0x07
+
+#define T4T_NDEF_FILE_CONTROL_TYPE 0x04 /* NDEF File Control Type */
+/* Proprietary File Control Type */
+#define T4T_PROP_FILE_CONTROL_TYPE 0x05
+
+/* size of T(1),L(1),V(6) for file control */
+#define T4T_FILE_CONTROL_TLV_SIZE 0x08
+/* size of V(6) for file control */
+#define T4T_FILE_CONTROL_LENGTH 0x06
+
+/* read access granted without any security */
+#define T4T_FC_READ_ACCESS 0x00
+/* write access granted without any security */
+#define T4T_FC_WRITE_ACCESS 0x00
+/* proprietary write access range start */
+#define T4T_FC_WRITE_ACCESS_PROP_START 0x80
+/* no write access granted at all (read-only) */
+#define T4T_FC_NO_WRITE_ACCESS 0xFF
+
+#define T4T_FILE_LENGTH_SIZE 0x02
+
+#define T4T_ADDI_FRAME_RESP 0xAFU
+#define T4T_SIZE_IDENTIFIER_2K 0x16U
+#define T4T_SIZE_IDENTIFIER_4K 0x18U
+#define T4T_SIZE_IDENTIFIER_8K 0x1AU
+#define T4T_DESEV1_MAJOR_VERSION 0x01U
+#define T4T_TYPE_DESFIRE_EV1 0x01U
+#define T4T_DESEV0_MAJOR_VERSION 0x00U
+#define T4T_DESEV0_MINOR_VERSION 0x06U
+#define T4T_DES_EV1_NFC_APP_ID 0x010000
+#define T4T_DES_EV0_NFC_APP_ID 0x10EEEE
+
+/*
+ **
+ **  ISO 15693 Tag Definitions
+ **
+ */
+
+/* Request flags 1 to 4 definition */
+#define I93_FLAG_SUB_CARRIER_MASK 0x01 /* Sub_carrier_flag */
+/* A single sub-carrier frequency shall be used by VICC */
+#define I93_FLAG_SUB_CARRIER_SINGLE 0x00
+/* Two sub-carriers shall be used by VICC               */
+#define I93_FLAG_SUB_CARRIER_DOUBLE 0x01
+
+#define I93_FLAG_DATA_RATE_MASK 0x02 /* Data_rate_flag */
+/* Low data rate shall be used  */
+#define I93_FLAG_DATA_RATE_LOW 0x00
+/* High data rate shall be used */
+#define I93_FLAG_DATA_RATE_HIGH 0x02
+
+#define I93_FLAG_INVENTORY_MASK 0x04 /* Inventory_flag */
+/* Flags 5 to 8 meaning is according to table 4 */
+#define I93_FLAG_INVENTORY_UNSET 0x00
+/* Flags 5 to 8 meaning is according to table 5 */
+#define I93_FLAG_INVENTORY_SET 0x04
+
+/* Protocol_Extension_flag */
+#define I93_FLAG_PROT_EXT_MASK 0x08
+/* No protocol format extension                         */
+#define I93_FLAG_PROT_EXT_NO 0x00
+/* Protocol format is extended. Reserved for future use */
+#define I93_FLAG_PROT_EXT_YES 0x08
+
+/* Request flags 5 to 6 definition when inventory flag is not set */
+#define I93_FLAG_SELECT_MASK 0x10 /* Select_flag */
+/* Request shall be executed by any VICC according to the setting of
+ * Address_flag */
+#define I93_FLAG_SELECT_UNSET 0x00
+/* Request shall be executed only by VICC in selected state */
+#define I93_FLAG_SELECT_SET 0x10
+/* The Address_flag shall be set to 0 and the UID field shall bot be included in
+ * the request */
+
+#define I93_FLAG_ADDRESS_MASK 0x20 /* Address_flag */
+/* Request is not addressed. UID field is not included. It shall be executed by
+ * any VICC */
+#define I93_FLAG_ADDRESS_UNSET 0x00
+/* Request is addressed. UID field is included. It shall be executed only by
+ * VICC */
+#define I93_FLAG_ADDRESS_SET 0x20
+/* whose UID matches the UID specified in the request */
+
+/* Request flags 5 to 6 definition when inventory flag is set */
+#define I93_FLAG_AFI_MASK 0x10 /* AFI_flag */
+/* AFI field is not present */
+#define I93_FLAG_AFI_NOT_PRESENT 0x00
+/* AFI field is present     */
+#define I93_FLAG_AFI_PRESENT 0x10
+
+#define I93_FLAG_SLOT_MASK 0x20 /* Nb_slots_flag */
+#define I93_FLAG_SLOT_16 0x00   /* 16 slots */
+#define I93_FLAG_SLOT_ONE 0x20  /* 1 slot   */
+
+/* Request flags 6 to 8 definition when inventory flag is set or not set */
+
+#define I93_FLAG_OPTION_MASK 0x40 /* Option_flag */
+/* Meaning is defined by the command description. */
+#define I93_FLAG_OPTION_UNSET 0x00
+/* It shall be set to 0 if not otherwise defined by command */
+/* Meaning is defined by the command description. */
+#define I93_FLAG_OPTION_SET 0x40
+
+/* Response flags */
+#define I93_FLAG_ERROR_MASK 0x01 /* Error_flag */
+/* No error                                           */
+#define I93_FLAG_ERORR_NOT_DETECTED 0x00
+/* Error detected, Error code is in the "Error" field */
+#define I93_FLAG_ERROR_DETECTED 0x01
+
+/* Response error code */
+/* The command is not supported, i.e. the request code is not recognized */
+#define I93_ERROR_CODE_NOT_SUPPORTED 0x01
+/* The command is not recognized, for example: a format error occured    */
+#define I93_ERROR_CODE_NOT_RECOGNIZED 0x02
+/* The command option is not supported                                   */
+#define I93_ERROR_CODE_OPTION_NOT_SUPPORTED 0x03
+/* Error with no information given or a specific error code is not supported */
+#define I93_ERROR_CODE_NO_INFO 0x0F
+/* The specific block is not available (doesn't exist)                   */
+#define I93_ERROR_CODE_BLOCK_NOT_AVAILABLE 0x10
+/* The specific block is already locked and thus cannot be locked again  */
+#define I93_ERROR_CODE_BLOCK_ALREADY_LOCKED 0x11
+/* The specific block is locked and its content cannot be changed        */
+#define I93_ERROR_CODE_BLOCK_LOCKED 0x12
+/* The specific block is was not successfully programmed                 */
+#define I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE 0x13
+/* The specific block is was not successfully locked                     */
+#define I93_ERROR_CODE_BLOCK_FAIL_TO_LOCK 0x14
+
+/* UID length in bytes                  */
+#define I93_UID_BYTE_LEN 8
+/* Data Storage Format is not supported */
+#define I93_DFS_UNSUPPORTED 0x00
+/* Block is not locked                  */
+#define I93_BLOCK_UNLOCKED 0x00
+/* Block is locked                      */
+#define I93_BLOCK_LOCKED 0x01
+
+/* ISO 15693 Mandatory commands */
+#define I93_CMD_INVENTORY 0x01  /* Inventory  */
+#define I93_CMD_STAY_QUIET 0x02 /* Stay Quiet */
+
+/* ISO 15693 Optional commands */
+#define I93_CMD_READ_SINGLE_BLOCK 0x20  /* Read single block     */
+#define I93_CMD_WRITE_SINGLE_BLOCK 0x21 /* Write single block    */
+#define I93_CMD_LOCK_BLOCK 0x22         /* Lock block            */
+#define I93_CMD_READ_MULTI_BLOCK 0x23   /* Read multiple blocks  */
+#define I93_CMD_WRITE_MULTI_BLOCK 0x24  /* Write multiple blocks */
+#define I93_CMD_SELECT 0x25             /* Select                */
+#define I93_CMD_RESET_TO_READY 0x26     /* Reset to ready        */
+#define I93_CMD_WRITE_AFI 0x27          /* Wreite AFI            */
+#define I93_CMD_LOCK_AFI 0x28           /* Lock AFI              */
+#define I93_CMD_WRITE_DSFID 0x29        /* Write DSFID           */
+#define I93_CMD_LOCK_DSFID 0x2A         /* Lock DSFID            */
+/* Get system information             */
+#define I93_CMD_GET_SYS_INFO 0x2B
+/* Get multiple block security status */
+#define I93_CMD_GET_MULTI_BLK_SEC 0x2C
+
+/* Information flags definition */
+/* DSFID is supported and DSFID field is present */
+#define I93_INFO_FLAG_DSFID 0x01
+/* AFI is supported and AFI field is present     */
+#define I93_INFO_FLAG_AFI 0x02
+/* VICC memory size field is present             */
+#define I93_INFO_FLAG_MEM_SIZE 0x04
+/* IC reference field is present                 */
+#define I93_INFO_FLAG_IC_REF 0x08
+
+/* Max block size in bytes */
+#define I93_MAX_BLOCK_LENGH 32
+/* Max number of blocks    */
+#define I93_MAX_NUM_BLOCK 256
+
+/* ICODE Capability Container(CC) definition */
+#define I93_ICODE_CC_MAGIC_NUMER 0xE1    /* magic number in CC[0]  */
+#define I93_ICODE_CC_MAJOR_VER_MASK 0xC0 /* major version in CC[1] */
+#define I93_ICODE_CC_MINOR_VER_MASK 0x30 /* minor version in CC[1] */
+/* read access condition in CC[1]        */
+#define I93_ICODE_CC_READ_ACCESS_MASK 0x0C
+/* read access granted without security  */
+#define I93_ICODE_CC_READ_ACCESS_GRANTED 0x00
+/* write access condition in CC[1]       */
+#define I93_ICODE_CC_WRITE_ACCESS_MASK 0x03
+/* write access granted without security */
+#define I93_ICODE_CC_WRITE_ACCESS_GRANTED 0x00
+/* write access not granted at all       */
+#define I93_ICODE_CC_READ_ONLY 0x03
+/* read multi block supported in CC[3]   */
+#define I93_ICODE_CC_MBREAD_MASK 0x01
+/* inventory page read supported in CC[3] */
+#define I93_ICODE_CC_IPREAD_MASK 0x02
+/* More than 2040 bytes are supported in CC[3] */
+#define I93_STM_CC_OVERFLOW_MASK 0x04
+
+/* ICODE TLV type */
+#define I93_ICODE_TLV_TYPE_NULL 0x00 /* NULL TLV         */
+#define I93_ICODE_TLV_TYPE_NDEF 0x03 /* NDEF message TLV */
+#define I93_ICODE_TLV_TYPE_PROP 0xFD /* Proprietary TLV  */
+#define I93_ICODE_TLV_TYPE_TERM 0xFE /* Terminator TLV   */
+
+/* UID Coding (UID Bit 64-57), First byte of ISO 15693 UID */
+#define I93_UID_FIRST_BYTE 0xE0
+
+/* UID Coding (UID Bit 56-49), IC manufacturer code */
+#define I93_UID_IC_MFG_CODE_STM 0x02
+#define I93_UID_IC_MFG_CODE_NXP 0x04
+#define I93_UID_IC_MFG_CODE_TI 0x07
+
+/* NXP, UID Coding of ICODE type (UID Bit 48-41) */
+/* ICODE SLI, SLIX     */
+#define I93_UID_ICODE_SLI 0x01
+/* ICODE SLI-S, SLIX-S */
+#define I93_UID_ICODE_SLI_S 0x02
+/* ICODE SLI-L, SLIX-L */
+#define I93_UID_ICODE_SLI_L 0x03
+
+/* IC Reference for ICODE SLI-L */
+#define I93_IC_REF_ICODE_SLI_L 0x03
+/* read multi block supported check bit */
+#define I93_ICODE_IC_REF_MBREAD_MASK 0x02
+
+/* TI, UID Coding of product version (UID Bit 48-42) */
+/* upper 7 bits                     */
+#define I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK 0xFE
+/* Tag-it HF-I Plus Inlay           */
+#define I93_UID_TAG_IT_HF_I_PLUS_INLAY 0x00
+/* Tag-it HF-I Plus Chip            */
+#define I93_UID_TAG_IT_HF_I_PLUS_CHIP 0x80
+/* Tag-it HF-I Standard Chip/Inlyas */
+#define I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY 0xC0
+/* Tag-it HF-I Pro Chip/Inlyas      */
+#define I93_UID_TAG_IT_HF_I_PRO_CHIP_INLAY 0xC4
+
+#define I93_TAG_IT_HF_I_STD_CHIP_INLAY_NUM_TOTAL_BLK 11
+#define I93_TAG_IT_HF_I_PRO_CHIP_INLAY_NUM_TOTAL_BLK 12
+
+#define I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_BLK_SIZE 4
+#define I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_NUM_USER_BLK 8
+/* LSB in Block 0x0A */
+#define I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION 40
+
+/* STM, product version (IC manufacturer code) */
+/* IC Reference mask for STM */
+#define I93_IC_REF_STM_MASK 0xFC
+/* IC Reference for LRI1K:      010000xx(b), blockSize: 4, numberBlocks: 0x20 */
+#define I93_IC_REF_STM_LRI1K 0x40
+/* IC Reference for LRI2K:      001000xx(b), blockSize: 4, numberBlocks: 0x40 */
+#define I93_IC_REF_STM_LRI2K 0x20
+/* IC Reference for LRIS2K:     001010xx(b), blockSize: 4, numberBlocks: 0x40 */
+#define I93_IC_REF_STM_LRIS2K 0x28
+/* IC Reference for LRIS64K:    010001xx(b), blockSize: 4, numberBlocks: 0x800
+ */
+#define I93_IC_REF_STM_LRIS64K 0x44
+/* IC Reference for M24LR64-R:  001011xx(b), blockSize: 4, numberBlocks: 0x800
+ */
+#define I93_IC_REF_STM_M24LR64_R 0x2C
+/* IC Reference for M24LR04E-R: 01011010(b), blockSize: 4, numberBlocks: 0x80 */
+#define I93_IC_REF_STM_M24LR04E_R 0x5A
+/* IC Reference for M24LR16E-R: 01001110(b), blockSize: 4, numberBlocks: 0x200
+ */
+#define I93_IC_REF_STM_M24LR16E_R 0x4E
+/* IC Reference for M24LR64E-R: 01011110(b), blockSize: 4, numberBlocks: 0x800
+ */
+#define I93_IC_REF_STM_M24LR64E_R 0x5E
+
+#define I93_STM_BLOCKS_PER_SECTOR 32
+#define I93_STM_MAX_BLOCKS_PER_READ 32
+
+#endif /* TAGS_DEFS_H */
diff --git a/src/nfc/int/ce_int.h b/src/nfc/int/ce_int.h
new file mode 100644
index 0000000..4965dcb
--- /dev/null
+++ b/src/nfc/int/ce_int.h
@@ -0,0 +1,180 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the Near Field Communication (NFC) Card Emulation
+ *  mode related internal function / definitions.
+ *
+ ******************************************************************************/
+
+#ifndef CE_INT_H_
+#define CE_INT_H_
+
+#include "ce_api.h"
+
+#if (CE_TEST_INCLUDED == false)
+#define CE_MIN_SUP_PROTO NCI_PROTOCOL_FELICA
+#define CE_MAX_SUP_PROTO NCI_PROTOCOL_ISO4
+#else
+#define CE_MIN_SUP_PROTO NCI_PROTOCOL_TYPE1
+#define CE_MAX_SUP_PROTO NCI_PROTOCOL_MIFARE
+#endif
+
+/* 2^8=256. CB use uint8_t for BytesPerPage, so max is 7 */
+#define CE_MAX_BYTE_PER_PAGE 7
+
+/* CE Type 3 Tag structures */
+
+/* Type 3 Tag NDEF card-emulation */
+typedef struct {
+  bool initialized;
+  uint8_t version; /* Ver: peer version */
+  uint8_t
+      nbr; /* NBr: number of blocks that can be read using one Check command */
+  uint8_t nbw;    /* Nbw: number of blocks that can be written using one Update
+                     command */
+  uint16_t nmaxb; /* Nmaxb: maximum number of blocks available for NDEF data */
+  uint8_t writef; /* WriteFlag: 00h if writing data finished; 0Fh if writing
+                     data in progress */
+  uint8_t
+      rwflag; /* RWFlag: 00h NDEF is read-only; 01h if read/write available */
+  uint32_t ln;
+  uint8_t* p_buf; /* Current contents for READs */
+
+  /* Scratch NDEF buffer (for update NDEF commands) */
+  uint8_t scratch_writef;
+  uint32_t scratch_ln;
+  uint8_t* p_scratch_buf; /* Scratch buffer for WRITE/readback */
+} tCE_T3T_NDEF_INFO;
+
+/* Type 3 Tag current command processing */
+typedef struct {
+  uint16_t service_code_list[T3T_MSG_SERVICE_LIST_MAX];
+  uint8_t* p_block_list_start;
+  uint8_t* p_block_data_start;
+  uint8_t num_services;
+  uint8_t num_blocks;
+} tCE_T3T_CUR_CMD;
+
+/* Type 3 Tag control blcok */
+typedef struct {
+  uint8_t state;
+  uint16_t system_code;
+  uint8_t local_nfcid2[NCI_RF_F_UID_LEN];
+  uint8_t local_pmm[NCI_T3T_PMM_LEN];
+  tCE_T3T_NDEF_INFO ndef_info;
+  tCE_T3T_CUR_CMD cur_cmd;
+} tCE_T3T_MEM;
+
+/* CE Type 4 Tag control blocks */
+typedef struct {
+  uint8_t aid_len;
+  uint8_t aid[NFC_MAX_AID_LEN];
+  tCE_CBACK* p_cback;
+} tCE_T4T_REG_AID; /* registered AID table */
+
+typedef struct {
+  TIMER_LIST_ENT timer; /* timeout for update file              */
+  uint8_t cc_file[T4T_FC_TLV_OFFSET_IN_CC + T4T_FILE_CONTROL_TLV_SIZE];
+  uint8_t* p_ndef_msg;    /* storage of NDEF message              */
+  uint16_t nlen;          /* current size of NDEF message         */
+  uint16_t max_file_size; /* size of storage + 2 bytes for NLEN   */
+  uint8_t* p_scratch_buf; /* temp storage of NDEF message for update */
+
+/* T4T CE App is selected       */
+#define CE_T4T_STATUS_T4T_APP_SELECTED 0x01
+/* Registered AID is selected   */
+#define CE_T4T_STATUS_REG_AID_SELECTED 0x02
+/* CC file is selected          */
+#define CE_T4T_STATUS_CC_FILE_SELECTED 0x04
+/* NDEF file is selected        */
+#define CE_T4T_STATUS_NDEF_SELECTED 0x08
+/* NDEF is read-only            */
+#define CE_T4T_STATUS_NDEF_FILE_READ_ONLY 0x10
+/* NDEF is updating             */
+#define CE_T4T_STATUS_NDEF_FILE_UPDATING 0x20
+/* Wildcard AID selected        */
+#define CE_T4T_STATUS_WILDCARD_AID_SELECTED 0x40
+
+  uint8_t status;
+
+  tCE_CBACK* p_wildcard_aid_cback; /* registered wildcard AID callback */
+  tCE_T4T_REG_AID reg_aid[CE_T4T_MAX_REG_AID]; /* registered AID table */
+  uint8_t selected_aid_idx;
+} tCE_T4T_MEM;
+
+/* CE memory control blocks */
+typedef struct {
+  tCE_T3T_MEM t3t;
+  tCE_T4T_MEM t4t;
+} tCE_MEM;
+
+/* CE control blocks */
+typedef struct {
+  tCE_MEM mem;
+  tCE_CBACK* p_cback;
+  uint8_t* p_ndef;   /* the memory starting from NDEF */
+  uint16_t ndef_max; /* max size of p_ndef */
+  uint16_t ndef_cur; /* current size of p_ndef */
+  tNFC_RF_TECH tech;
+  uint8_t trace_level;
+
+} tCE_CB;
+
+/*
+** CE Type 4 Tag Definition
+*/
+
+/* Max data size using a single ReadBinary. 2 bytes are for status bytes */
+#define CE_T4T_MAX_LE                                          \
+  (NFC_CE_POOL_BUF_SIZE - NFC_HDR_SIZE - NCI_MSG_OFFSET_SIZE - \
+   NCI_DATA_HDR_SIZE - T4T_RSP_STATUS_WORDS_SIZE)
+
+/* Max data size using a single UpdateBinary. 6 bytes are for CLA, INS, P1, P2,
+ * Lc */
+#define CE_T4T_MAX_LC                                        \
+  (NFC_CE_POOL_BUF_SIZE - NFC_HDR_SIZE - NCI_DATA_HDR_SIZE - \
+   T4T_CMD_MAX_HDR_SIZE)
+
+/*****************************************************************************
+**  EXTERNAL FUNCTION DECLARATIONS
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Global NFC data */
+extern tCE_CB ce_cb;
+
+extern void ce_init(void);
+
+/* ce_t3t internal functions */
+void ce_t3t_init(void);
+tNFC_STATUS ce_select_t3t(uint16_t system_code,
+                          uint8_t nfcid2[NCI_RF_F_UID_LEN]);
+
+/* ce_t4t internal functions */
+extern tNFC_STATUS ce_select_t4t(void);
+extern void ce_t4t_process_timeout(TIMER_LIST_ENT* p_tle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CE_INT_H_ */
diff --git a/src/nfc/int/llcp_int.h b/src/nfc/int/llcp_int.h
new file mode 100644
index 0000000..51473d9
--- /dev/null
+++ b/src/nfc/int/llcp_int.h
@@ -0,0 +1,392 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains LLCP internal definitions
+ *
+ ******************************************************************************/
+#ifndef LLCP_INT_H
+#define LLCP_INT_H
+
+#include "llcp_api.h"
+#include "nfc_api.h"
+
+/*
+** LLCP link states
+*/
+enum {
+  LLCP_LINK_STATE_DEACTIVATED,      /* llcp link is deactivated     */
+  LLCP_LINK_STATE_ACTIVATED,        /* llcp link has been activated */
+  LLCP_LINK_STATE_DEACTIVATING,     /* llcp link is deactivating    */
+  LLCP_LINK_STATE_ACTIVATION_FAILED /* llcp link activation was failed */
+};
+typedef uint8_t tLLCP_LINK_STATE;
+
+/*
+** LLCP Symmetric state
+*/
+
+#define LLCP_LINK_SYMM_LOCAL_XMIT_NEXT 0
+#define LLCP_LINK_SYMM_REMOTE_XMIT_NEXT 1
+
+/*
+** LLCP internal flags
+*/
+/* Received any LLC PDU in activated state */
+#define LLCP_LINK_FLAGS_RX_ANY_LLC_PDU 0x01
+
+/*
+** LLCP link control block
+*/
+typedef struct {
+  tLLCP_LINK_STATE link_state; /* llcp link state */
+  tLLCP_LINK_CBACK*
+      p_link_cback; /* callback function to report llcp link status */
+  uint16_t wks;     /* well-known service bit-map                   */
+
+  bool is_initiator;    /* true if initiator role                       */
+  bool is_sending_data; /* true if llcp_link_check_send_data() is excuting    */
+  uint8_t flags;        /* LLCP internal flags                          */
+  bool received_first_packet; /* true if a packet has been received from remote
+                                 */
+  uint8_t agreed_major_version; /* llcp major version used in activated state */
+  uint8_t agreed_minor_version; /* llcp minor version used in activated state */
+
+  uint8_t peer_version;   /* llcp version of peer device                  */
+  uint16_t peer_miu;      /* link MIU of peer device                      */
+  uint16_t peer_wks;      /* WKS of peer device                           */
+  uint16_t peer_lto;      /* link timeout of peer device in ms            */
+  uint8_t peer_opt;       /* Option field of peer device                  */
+  uint16_t effective_miu; /* MIU to send PDU in activated state           */
+
+  TIMER_LIST_ENT timer; /* link timer for LTO and SYMM response         */
+  uint8_t symm_state;   /* state of symmectric procedure                */
+  bool ll_served;       /* true if last transmisstion was for UI        */
+  uint8_t ll_idx;       /* for scheduler of logical link connection     */
+  uint8_t dl_idx;       /* for scheduler of data link connection        */
+
+  TIMER_LIST_ENT inact_timer; /* inactivity timer                             */
+  uint16_t inact_timeout;     /* inactivity timeout in ms                     */
+
+  uint8_t link_deact_reason; /* reason of LLCP link deactivated              */
+
+  BUFFER_Q sig_xmit_q; /* tx signaling PDU queue                       */
+
+  /* runtime configuration parameters */
+  uint16_t local_link_miu; /* Maximum Information Unit                     */
+  uint8_t local_opt;       /* Option parameter                             */
+  uint8_t local_wt;        /* Response Waiting Time Index                  */
+  uint16_t local_lto;      /* Local Link Timeout                           */
+  uint16_t inact_timeout_init;   /* Inactivity Timeout as initiator role */
+  uint16_t inact_timeout_target; /* Inactivity Timeout as target role */
+  uint16_t symm_delay;        /* Delay SYMM response                          */
+  uint16_t data_link_timeout; /* data link conneciton timeout                 */
+  uint16_t delay_first_pdu_timeout; /* delay timeout to send first PDU as
+                                       initiator */
+} tLLCP_LCB;
+
+/*
+** LLCP Application's registration control block on service access point (SAP)
+*/
+
+typedef struct {
+  uint8_t link_type;       /* logical link and/or data link                */
+  uint8_t* p_service_name; /* GKI buffer containing service name           */
+  tLLCP_APP_CBACK* p_app_cback; /* application's callback pointer */
+
+  BUFFER_Q ui_xmit_q;      /* UI PDU queue for transmitting                */
+  BUFFER_Q ui_rx_q;        /* UI PDU queue for receiving                   */
+  bool is_ui_tx_congested; /* true if transmitting UI PDU is congested     */
+
+} tLLCP_APP_CB;
+
+/*
+** LLCP data link connection states
+*/
+enum {
+  LLCP_DLC_STATE_IDLE, /* initial state                                    */
+  LLCP_DLC_STATE_W4_REMOTE_RESP, /* waiting for connection confirm from peer */
+  LLCP_DLC_STATE_W4_LOCAL_RESP,  /* waiting for connection confirm from upper
+                                    layer  */
+  LLCP_DLC_STATE_CONNECTED,      /* data link connection has been established */
+  LLCP_DLC_STATE_W4_REMOTE_DM, /* waiting for disconnection confirm from peer */
+  LLCP_DLC_STATE_MAX
+};
+typedef uint8_t tLLCP_DLC_STATE;
+
+/*
+** LLCP data link connection events
+*/
+enum {
+  LLCP_DLC_EVENT_API_CONNECT_REQ,    /* connection request from upper layer  */
+  LLCP_DLC_EVENT_API_CONNECT_CFM,    /* connection confirm from upper layer  */
+  LLCP_DLC_EVENT_API_CONNECT_REJECT, /* connection reject from upper layer   */
+  LLCP_DLC_EVENT_PEER_CONNECT_IND,   /* connection request from peer         */
+  LLCP_DLC_EVENT_PEER_CONNECT_CFM,   /* connection confirm from peer         */
+
+  LLCP_DLC_EVENT_API_DATA_REQ,  /* data packet from upper layer         */
+  LLCP_DLC_EVENT_PEER_DATA_IND, /* data packet from peer                */
+
+  LLCP_DLC_EVENT_API_DISCONNECT_REQ,  /* disconnect request from upper layer  */
+  LLCP_DLC_EVENT_PEER_DISCONNECT_IND, /* disconnect request from peer         */
+  LLCP_DLC_EVENT_PEER_DISCONNECT_RESP, /* disconnect response from peer */
+
+  LLCP_DLC_EVENT_FRAME_ERROR, /* received erroneous frame from peer   */
+  LLCP_DLC_EVENT_LINK_ERROR,  /* llcp link has been deactivated       */
+
+  LLCP_DLC_EVENT_TIMEOUT /* timeout event                        */
+};
+typedef uint8_t tLLCP_DLC_EVENT;
+
+/*
+** LLCP data link connection control block
+*/
+
+/* send DISC when tx queue is empty       */
+#define LLCP_DATA_LINK_FLAG_PENDING_DISC 0x01
+/* send RR/RNR with valid sequence        */
+#define LLCP_DATA_LINK_FLAG_PENDING_RR_RNR 0x02
+/* notify upper later when tx complete    */
+#define LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE 0x04
+
+typedef struct {
+  tLLCP_DLC_STATE state;  /* data link connection state               */
+  uint8_t flags;          /* specific action flags                    */
+  tLLCP_APP_CB* p_app_cb; /* pointer of application registration      */
+  TIMER_LIST_ENT timer;   /* timer for connection complete            */
+
+  uint8_t local_sap;  /* SAP of local end point                   */
+  uint16_t local_miu; /* MIU of local SAP                         */
+  uint8_t local_rw;   /* RW of local SAP                          */
+  bool local_busy;    /* true if local SAP is busy                */
+
+  uint8_t remote_sap;  /* SAP of remote end point                  */
+  uint16_t remote_miu; /* MIU of remote SAP                        */
+  uint8_t remote_rw;   /* RW of remote SAP                         */
+  bool remote_busy;    /* true if remote SAP is busy               */
+
+  uint8_t next_tx_seq;  /* V(S), send state variable                */
+  uint8_t rcvd_ack_seq; /* V(SA), send ack state variable           */
+  uint8_t next_rx_seq;  /* V(R), receive state variable             */
+  uint8_t sent_ack_seq; /* V(RA), receive ack state variable        */
+
+  BUFFER_Q i_xmit_q;    /* tx queue of I PDU                        */
+  bool is_tx_congested; /* true if tx I PDU is congested            */
+
+  BUFFER_Q i_rx_q;              /* rx queue of I PDU                        */
+  bool is_rx_congested;         /* true if rx I PDU is congested            */
+  uint8_t num_rx_i_pdu;         /* number of I PDU in rx queue              */
+  uint8_t rx_congest_threshold; /* dynamic congest threshold for rx I PDU */
+
+} tLLCP_DLCB;
+
+/*
+** LLCP service discovery control block
+*/
+
+typedef struct {
+  uint8_t tid;              /* transaction ID                           */
+  tLLCP_SDP_CBACK* p_cback; /* callback function for service discovery  */
+} tLLCP_SDP_TRANSAC;
+
+typedef struct {
+  uint8_t next_tid;                                /* next TID to use         */
+  tLLCP_SDP_TRANSAC transac[LLCP_MAX_SDP_TRANSAC]; /* active SDP transactions */
+  NFC_HDR* p_snl;                                  /* buffer for SNL PDU      */
+} tLLCP_SDP_CB;
+
+/*
+** LLCP control block
+*/
+
+typedef struct {
+  uint8_t trace_level; /* LLCP trace level                             */
+
+  tLLCP_SDP_CB sdp_cb; /* SDP control block                            */
+  tLLCP_LCB lcb;       /* LLCP link control block                      */
+  tLLCP_APP_CB wks_cb[LLCP_MAX_WKS]; /* Application's registration for
+                                        well-known services */
+  tLLCP_APP_CB server_cb
+      [LLCP_MAX_SERVER]; /* Application's registration for SDP services  */
+  tLLCP_APP_CB
+      client_cb[LLCP_MAX_CLIENT]; /* Application's registration for client */
+  tLLCP_DLCB dlcb[LLCP_MAX_DATA_LINK]; /* Data link connection control block */
+
+  uint8_t max_num_ll_tx_buff; /* max number of tx UI PDU in queue             */
+  uint8_t max_num_tx_buff;    /* max number of tx UI/I PDU in queue           */
+
+  uint8_t num_logical_data_link; /* number of logical data link */
+  uint8_t
+      num_data_link_connection; /* number of established data link connection */
+
+  /* these two thresholds (number of tx UI PDU) are dynamically adjusted based
+   * on number of logical links */
+  uint8_t
+      ll_tx_congest_start;   /* congest start threshold for each logical link*/
+  uint8_t ll_tx_congest_end; /* congest end threshold for each logical link  */
+
+  uint8_t total_tx_ui_pdu;   /* total number of tx UI PDU in all of ui_xmit_q*/
+  uint8_t total_tx_i_pdu;    /* total number of tx I PDU in all of i_xmit_q  */
+  bool overall_tx_congested; /* true if tx link is congested                 */
+
+  /* start point of uncongested status notification is in round robin */
+  uint8_t ll_tx_uncongest_ntf_start_sap; /* next start of logical data link */
+  uint8_t
+      dl_tx_uncongest_ntf_start_idx; /* next start of data link connection */
+
+  /*
+  ** when overall rx link congestion starts, RNR is sent to remote end point
+  ** of data link connection while rx link is congested, UI PDU is discarded.
+  */
+  uint8_t num_rx_buff; /* reserved number of rx UI/I PDU in queue      */
+  uint8_t
+      overall_rx_congest_start;   /* threshold of overall rx congestion start */
+  uint8_t overall_rx_congest_end; /* threshold of overall rx congestion end */
+  uint8_t max_num_ll_rx_buff; /* max number of rx UI PDU in queue             */
+
+  /*
+  ** threshold (number of rx UI PDU) is dynamically adjusted based on number
+  ** of logical links when number of rx UI PDU is more than
+  ** ll_rx_congest_start, the oldest UI PDU is discarded
+  */
+  uint8_t ll_rx_congest_start; /* rx congest start threshold for each logical
+                                  link */
+
+  uint8_t total_rx_ui_pdu;   /* total number of rx UI PDU in all of ui_rx_q  */
+  uint8_t total_rx_i_pdu;    /* total number of rx I PDU in all of i_rx_q    */
+  bool overall_rx_congested; /* true if overall rx link is congested         */
+#if (NXP_EXTNS == TRUE)
+  tLLCP_DTA_CBACK* p_dta_cback; /* callback to notify DTA when respoding SNL */
+  bool dta_snl_resp; /* true if need to notify DTA when respoding SNL*/
+#endif
+} tLLCP_CB;
+
+#if (LLCP_TEST_INCLUDED == true) /* this is for LLCP testing */
+
+typedef struct {
+  uint8_t version;
+  uint16_t wks;
+} tLLCP_TEST_PARAMS;
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** LLCP global data
+*/
+
+extern tLLCP_CB llcp_cb;
+
+/*
+** Functions provided by llcp_main.c
+*/
+void llcp_init(void);
+void llcp_cleanup(void);
+void llcp_process_timeout(TIMER_LIST_ENT* p_tle);
+
+/*
+** Functions provided by llcp_link.c
+*/
+tLLCP_STATUS llcp_link_activate(tLLCP_ACTIVATE_CONFIG* p_config);
+void llcp_link_process_link_timeout(void);
+void llcp_link_deactivate(uint8_t reason);
+
+void llcp_link_check_send_data(void);
+void llcp_link_connection_cback(uint8_t conn_id, tNFC_CONN_EVT event,
+                                tNFC_CONN* p_data);
+
+/*
+**  Functions provided by llcp_util.c
+*/
+void llcp_util_adjust_ll_congestion(void);
+void llcp_util_adjust_dl_rx_congestion(void);
+void llcp_util_check_rx_congested_status(void);
+bool llcp_util_parse_link_params(uint16_t length, uint8_t* p_bytes);
+tLLCP_STATUS llcp_util_send_ui(uint8_t ssap, uint8_t dsap,
+                               tLLCP_APP_CB* p_app_cb, NFC_HDR* p_msg);
+void llcp_util_send_disc(uint8_t dsap, uint8_t ssap);
+tLLCP_DLCB* llcp_util_allocate_data_link(uint8_t reg_sap, uint8_t remote_sap);
+void llcp_util_deallocate_data_link(tLLCP_DLCB* p_dlcb);
+tLLCP_STATUS llcp_util_send_connect(tLLCP_DLCB* p_dlcb,
+                                    tLLCP_CONNECTION_PARAMS* p_params);
+tLLCP_STATUS llcp_util_parse_connect(uint8_t* p_bytes, uint16_t length,
+                                     tLLCP_CONNECTION_PARAMS* p_params);
+tLLCP_STATUS llcp_util_send_cc(tLLCP_DLCB* p_dlcb,
+                               tLLCP_CONNECTION_PARAMS* p_params);
+tLLCP_STATUS llcp_util_parse_cc(uint8_t* p_bytes, uint16_t length,
+                                uint16_t* p_miu, uint8_t* p_rw);
+void llcp_util_send_dm(uint8_t dsap, uint8_t ssap, uint8_t reason);
+void llcp_util_build_info_pdu(tLLCP_DLCB* p_dlcb, NFC_HDR* p_msg);
+tLLCP_STATUS llcp_util_send_frmr(tLLCP_DLCB* p_dlcb, uint8_t flags,
+                                 uint8_t ptype, uint8_t sequence);
+void llcp_util_send_rr_rnr(tLLCP_DLCB* p_dlcb);
+tLLCP_APP_CB* llcp_util_get_app_cb(uint8_t sap);
+/*
+** Functions provided by llcp_dlc.c
+*/
+tLLCP_STATUS llcp_dlsm_execute(tLLCP_DLCB* p_dlcb, tLLCP_DLC_EVENT event,
+                               void* p_data);
+tLLCP_DLCB* llcp_dlc_find_dlcb_by_sap(uint8_t local_sap, uint8_t remote_sap);
+void llcp_dlc_flush_q(tLLCP_DLCB* p_dlcb);
+void llcp_dlc_proc_i_pdu(uint8_t dsap, uint8_t ssap, uint16_t i_pdu_length,
+                         uint8_t* p_i_pdu, NFC_HDR* p_msg);
+void llcp_dlc_proc_rx_pdu(uint8_t dsap, uint8_t ptype, uint8_t ssap,
+                          uint16_t length, uint8_t* p_data);
+void llcp_dlc_check_to_send_rr_rnr(void);
+bool llcp_dlc_is_rw_open(tLLCP_DLCB* p_dlcb);
+NFC_HDR* llcp_dlc_get_next_pdu(tLLCP_DLCB* p_dlcb);
+uint16_t llcp_dlc_get_next_pdu_length(tLLCP_DLCB* p_dlcb);
+
+/*
+** Functions provided by llcp_sdp.c
+*/
+void llcp_sdp_proc_data(tLLCP_SAP_CBACK_DATA* p_data);
+tLLCP_STATUS llcp_sdp_send_sdreq(uint8_t tid, char* p_name);
+uint8_t llcp_sdp_get_sap_by_name(char* p_name, uint8_t length);
+tLLCP_STATUS llcp_sdp_proc_snl(uint16_t sdu_length, uint8_t* p);
+void llcp_sdp_check_send_snl(void);
+void llcp_sdp_proc_deactivation(void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/nfc/int/nfc_int.h b/src/nfc/int/nfc_int.h
new file mode 100644
index 0000000..5835632
--- /dev/null
+++ b/src/nfc/int/nfc_int.h
@@ -0,0 +1,459 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  this file contains the main NFC Upper Layer internal definitions and
+ *  functions.
+ *
+ ******************************************************************************/
+
+#ifndef NFC_INT_H_
+#define NFC_INT_H_
+
+#include "nfc_target.h"
+#include "gki.h"
+#include "nci_defs.h"
+#include "nfc_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/****************************************************************************
+ ** Internal NFC constants and definitions
+ ****************************************************************************/
+#if (NXP_EXTNS == TRUE)
+#define NFC_NCI_SETMODE_NTF_TIMEOUT 2 /* time out for modeSet notification */
+#define NFCEE_ID_ESE 0xC0
+#endif
+/****************************************************************************
+ ** NFC_TASK definitions
+ ****************************************************************************/
+
+/* NFC_TASK event masks */
+#define NFC_TASK_EVT_TRANSPORT_READY EVENT_MASK(APPL_EVT_0)
+
+/* NFC Timer events */
+#define NFC_TTYPE_NCI_WAIT_RSP 0
+#define NFC_TTYPE_WAIT_2_DEACTIVATE 1
+#define NFC_TTYPE_WAIT_SETMODE_NTF 6
+#if (NXP_EXTNS == TRUE)
+#define NFC_TTYPE_NCI_WAIT_DATA_NTF 2
+#define NFC_TTYPE_NCI_WAIT_RF_FIELD_NTF 3
+#define NFC_TYPE_NCI_WAIT_SETMODE_NTF 4
+#define NFC_TYPE_NCI_WAIT_SETMODE_RSP 5
+#endif
+#define NFC_TTYPE_LLCP_LINK_MANAGER 100
+#define NFC_TTYPE_LLCP_LINK_INACT 101
+#define NFC_TTYPE_LLCP_DATA_LINK 102
+#define NFC_TTYPE_LLCP_DELAY_FIRST_PDU 103
+#define NFC_TTYPE_RW_T1T_RESPONSE 104
+#define NFC_TTYPE_RW_T2T_RESPONSE 105
+#define NFC_TTYPE_RW_T3T_RESPONSE 106
+#define NFC_TTYPE_RW_T4T_RESPONSE 107
+#define NFC_TTYPE_RW_I93_RESPONSE 108
+#define NFC_TTYPE_CE_T4T_UPDATE 109
+
+/* added for p2p prio logic timer */
+#define NFC_TTYPE_P2P_PRIO_RESPONSE 110
+/* added for p2p prio logic clenaup */
+#define NFC_TTYPE_P2P_PRIO_LOGIC_CLEANUP 112
+#if (NXP_EXTNS == TRUE)
+/* added for listen activation timer */
+#define NFC_TTYPE_LISTEN_ACTIVATION 111
+#define NFC_TTYPE_P2P_PRIO_LOGIC_DEACT_NTF_TIMEOUT 113
+#endif
+#define NFC_TTYPE_VS_BASE 200
+/* time out for modeSet notification */
+#define NFC_SETMODE_NTF_TIMEOUT     2
+#if (NXP_EXTNS == TRUE)
+/* Added for sending fave pwr link response to JNI since pwrlink cmd has been
+                                                  ignored due to RF CE session
+   */
+#define NFC_TTYPE_PWR_LINK_RSP 201
+#define NFC_TTYPE_SET_MODE_RSP 202
+#endif
+
+/* NFC Task event messages */
+
+enum {
+  NFC_STATE_NONE,                /* not start up yet                         */
+  NFC_STATE_W4_HAL_OPEN,         /* waiting for HAL_NFC_OPEN_CPLT_EVT        */
+  NFC_STATE_CORE_INIT,           /* sending CORE_RESET and CORE_INIT         */
+  NFC_STATE_W4_POST_INIT_CPLT,   /* waiting for HAL_NFC_POST_INIT_CPLT_EVT   */
+  NFC_STATE_IDLE,                /* normal operation (discovery state)       */
+  NFC_STATE_OPEN,                /* NFC link is activated                    */
+  NFC_STATE_CLOSING,             /* de-activating                            */
+  NFC_STATE_W4_HAL_CLOSE,        /* waiting for HAL_NFC_POST_INIT_CPLT_EVT   */
+  NFC_STATE_NFCC_POWER_OFF_SLEEP /* NFCC is power-off sleep mode             */
+};
+typedef uint8_t tNFC_STATE;
+
+/* DM P2P Priority event type */
+enum {
+  NFA_DM_P2P_PRIO_RSP = 0x01, /* P2P priority event from RSP   */
+  NFA_DM_P2P_PRIO_NTF         /* P2P priority event from NTF   */
+};
+enum {
+  I2C_FRAGMENATATION_ENABLED, /*i2c fragmentation_enabled           */
+  I2C_FRAGMENTATION_DISABLED  /*i2c_fragmentation_disabled          */
+};
+#if (NXP_EXTNS == TRUE)
+/*Get or Set swp activation state for UICC*/
+typedef enum {
+  GET_UICC_CONFIG = 0x01, /*get swp activation state for UICC  */
+  SET_UICC_CONFIG         /*set swp activation state for UICC  */
+} uicc_config_t;
+#endif
+/* NFC control block flags */
+/* NFC_Deactivate () is called and the NCI cmd is not sent   */
+#define NFC_FL_DEACTIVATING 0x0001
+/* restarting NFCC after PowerOffSleep          */
+#define NFC_FL_RESTARTING 0x0002
+/* enterning power off sleep mode               */
+#define NFC_FL_POWER_OFF_SLEEP 0x0004
+/* Power cycle NFCC                             */
+#define NFC_FL_POWER_CYCLE_NFCC 0x0008
+/* HAL requested control on NCI command window  */
+#define NFC_FL_CONTROL_REQUESTED 0x0010
+/* NCI command window is on the HAL side        */
+#define NFC_FL_CONTROL_GRANTED 0x0020
+/* NCI command window is on the HAL side        */
+#define NFC_FL_DISCOVER_PENDING 0x0040
+/* NFC_FL_CONTROL_REQUESTED on HAL request      */
+#define NFC_FL_HAL_REQUESTED 0x0080
+/* Waiting for NFCEE Mode Set NTF                 */
+#define NFC_FL_WAIT_MODE_SET_NTF        0x0100  /* Waiting for NFCEE Mode Set NTF*/
+
+#define NFC_PEND_CONN_ID 0xFE
+#define NFC_CONN_ID_INT_MASK 0xF0
+#define NFC_CONN_ID_ID_MASK NCI_CID_MASK
+/* set num_buff to this for no flow control */
+#define NFC_CONN_NO_FC 0xFF
+#define NFC_NCI_CONN_NO_FC 0xFF
+
+#if (NFC_RW_ONLY == FALSE)
+/* only allow the entries that the NFCC can support */
+#define NFC_CHECK_MAX_CONN()                          \
+  {                                                   \
+    if (max > nfc_cb.max_conn) max = nfc_cb.max_conn; \
+  }
+#else
+#define NFC_CHECK_MAX_CONN()
+#endif
+
+typedef struct {
+  tNFC_CONN_CBACK* p_cback; /* the callback function to receive the data */
+  BUFFER_Q tx_q;        /* transmit queue                                   */
+  BUFFER_Q rx_q;        /* receive queue                                    */
+  uint8_t id;           /* NFCEE ID or RF Discovery ID or NFC_TEST_ID       */
+  uint8_t act_protocol; /* the active protocol on this logical connection   */
+  uint8_t act_interface;/* the active interface on this logical connection   */
+  uint8_t conn_id;      /* the connection id assigned by NFCC for this conn */
+  uint8_t buff_size;    /* the max buffer size for this connection.     .   */
+  uint8_t num_buff;     /* num of buffers left to send on this connection   */
+  uint8_t init_credits; /* initial num of buffer credits                    */
+#if (NXP_EXTNS == TRUE)
+  uint8_t sel_res; /* the sel_res of the activated rf interface connection */
+#endif
+} tNFC_CONN_CB;
+
+/* This data type is for NFC task to send a NCI VS command to NCIT task */
+typedef struct {
+  NFC_HDR bt_hdr;         /* the NCI command          */
+  tNFC_VS_CBACK* p_cback; /* the callback function to receive RSP   */
+} tNFC_NCI_VS_MSG;
+
+/* This data type is for HAL event */
+typedef struct {
+  NFC_HDR hdr;
+  uint8_t hal_evt; /* HAL event code  */
+  uint8_t status;  /* tHAL_NFC_STATUS */
+} tNFC_HAL_EVT_MSG;
+
+/* callback function pointer(8; use 8 to be safe + NFC_SAVED_CMD_SIZE(2) */
+#define NFC_RECEIVE_MSGS_OFFSET (10)
+
+/* NFCC power state change pending callback */
+typedef void(tNFC_PWR_ST_CBACK)(void);
+#define NFC_SAVED_HDR_SIZE (2)
+/* data Reassembly error (in NFC_HDR.layer_specific) */
+#define NFC_RAS_TOO_BIG 0x08
+#define NFC_RAS_FRAGMENTED 0x01
+
+/* NCI command buffer contains a VSC (in NFC_HDR.layer_specific) */
+#define NFC_WAIT_RSP_VSC 0x01
+#if (NXP_EXTNS == TRUE)
+#define NFC_WAIT_RSP_NXP 0x02
+#endif
+typedef struct {
+  bool bPwrLinkCmdRequested;
+  uint16_t param;
+} tNFC_PWRLINK_CMD;
+
+typedef struct {
+  uint8_t data_ntf_timeout; /* indicates credit ntf timeout occured         */
+  uint8_t
+      nci_cmd_channel_busy; /*  indicates to the data queue that cmd is sent */
+  uint8_t data_stored;      /*  indicates data is stored to be sent later  */
+  uint8_t conn_id;          /*  stores the conn_id of the data stored       */
+} i2c_data;
+
+/* NFC control blocks */
+typedef struct {
+  uint16_t flags; /* NFC control block flags - NFC_FL_* */
+  tNFC_CONN_CB conn_cb[NCI_MAX_CONN_CBS];
+  uint8_t conn_id[NFC_MAX_CONN_ID + 1]; /* index: conn_id; conn_id[]: index(1
+                                           based) to conn_cb[] */
+  tNFC_DISCOVER_CBACK* p_discv_cback;
+  tNFC_RESPONSE_CBACK* p_resp_cback;
+  tNFC_TEST_CBACK* p_test_cback;
+  tNFC_VS_CBACK*
+      p_vs_cb[NFC_NUM_VS_CBACKS]; /* Register for vendor specific events  */
+#if (NXP_EXTNS == TRUE)
+  uint8_t nxpCbflag;
+#endif
+
+#if (NFC_RW_ONLY == FALSE)
+  /* NFCC information at init rsp */
+  uint32_t nci_features; /* the NCI features supported by NFCC */
+  uint16_t max_ce_table; /* the max routing table size       */
+  uint8_t max_conn;      /* the num of connections supported by NFCC */
+#endif
+  uint8_t nci_ctrl_size; /* Max Control Packet Payload Size */
+
+  const tNCI_DISCOVER_MAPS*
+      p_disc_maps; /* NCI RF Discovery interface mapping */
+  uint8_t vs_interface
+      [NFC_NFCC_MAX_NUM_VS_INTERFACE]; /* the NCI VS interfaces of NFCC    */
+  uint16_t nci_interfaces;             /* the NCI interfaces of NFCC       */
+  uint8_t  nci_intf_extensions;
+  uint8_t  nci_intf_extension_map[NCI_INTERFACE_EXTENSION_MAX];
+  uint8_t num_disc_maps; /* number of RF Discovery interface mappings */
+  void* p_disc_pending;  /* the parameters associated with pending
+                            NFC_DiscoveryStart */
+#if (NXP_EXTNS == TRUE)
+  void* p_last_disc; /* the parameters associated with pending
+                        NFC_DiscoveryStart */
+#endif
+
+  /* NFC_TASK timer management */
+  TIMER_LIST_Q timer_queue; /* 1-sec timer event queue */
+  TIMER_LIST_Q quick_timer_queue;
+
+  TIMER_LIST_ENT deactivate_timer; /* Timer to wait for deactivation */
+  TIMER_LIST_ENT mode_set_ntf_timer; /* Timer to wait for deactivation */
+  tNFC_STATE nfc_state;
+  bool reassembly; /* Reassemble fragmented data pkt */
+#if (NXP_EXTNS == TRUE)
+  tNFC_STATE old_nfc_state;
+#endif
+  uint8_t trace_level;
+  uint8_t last_hdr[NFC_SAVED_HDR_SIZE]; /* part of last NCI command header */
+  uint8_t last_cmd[NFC_SAVED_CMD_SIZE]; /* part of last NCI command payload */
+#if (NXP_EXTNS == TRUE)
+  uint8_t* last_cmd_buf;
+  uint8_t cmd_size;
+#endif
+  void* p_vsc_cback;       /* the callback function for last VSC command */
+  BUFFER_Q nci_cmd_xmit_q; /* NCI command queue */
+#if (NXP_EXTNS == TRUE)
+  BUFFER_Q nci_cmd_recov_xmit_q; /* NCI recovery command queue */
+  TIMER_LIST_ENT
+  listen_activation_timer_list; /* Timer for monitoring listen activation */
+  TIMER_LIST_ENT
+  nci_wait_data_ntf_timer; /* Timer for waiting for core credit ntf*/
+#endif
+  TIMER_LIST_ENT
+  nci_wait_rsp_timer;         /* Timer for waiting for nci command response */
+  uint16_t nci_wait_rsp_tout; /* NCI command timeout (in ms) */
+  uint8_t nci_wait_rsp;       /* layer_specific for last NCI message */
+
+  uint8_t nci_cmd_window; /* Number of commands the controller can accecpt
+                             without waiting for response */
+
+  NFC_HDR* p_nci_init_rsp; /* holding INIT_RSP until receiving
+                              HAL_NFC_POST_INIT_CPLT_EVT */
+  tHAL_NFC_ENTRY* p_hal;
+  i2c_data i2c_data_t; /* holding i2c fragmentation data */
+#if (NXP_EXTNS == TRUE)
+  uint8_t boot_mode;
+  bool bBlockWiredMode;
+  bool bRetransmitDwpPacket;
+  bool bIsCreditNtfRcvd;
+  bool bSetmodeOnReq;
+  bool bCeActivatedeSE;
+  tNFC_PWRLINK_CMD pwr_link_cmd;
+  TIMER_LIST_ENT rf_filed_event_timeout_timer;
+  TIMER_LIST_ENT nci_wait_setMode_Ntf_timer;
+  TIMER_LIST_ENT nci_wait_pwrLinkRsp_timer;
+  TIMER_LIST_ENT nci_wait_setModeRsp_timer;
+  bool bIsDwpResPending;
+  bool bIssueModeSetCmd;
+  bool bBlkPwrlinkAndModeSetCmd;
+  NFC_HDR* temp_data;
+#endif
+  uint8_t nci_version;     /* NCI version used for NCI communication*/
+
+  uint8_t hci_packet_size; /* maximum hci payload size*/
+
+  uint8_t hci_conn_credits; /* maximum conn credits for static HCI*/
+
+  uint16_t nci_max_v_size; /*maximum NFC V rf frame size*/
+
+  TIMER_LIST_ENT nci_setmode_ntf_timer;/*Mode notification timer*/
+} tNFC_CB;
+
+#if (NXP_EXTNS == TRUE)
+typedef struct phNxpNci_getCfg_info {
+  bool isGetcfg;
+  uint8_t total_duration[4];
+  uint8_t total_duration_len;
+  uint8_t atr_req_gen_bytes[48];
+  uint8_t atr_req_gen_bytes_len;
+  uint8_t atr_res_gen_bytes[48];
+  uint8_t atr_res_gen_bytes_len;
+  uint8_t pmid_wt[3];
+  uint8_t pmid_wt_len;
+} phNxpNci_getCfg_info_t;
+
+typedef struct {
+  uint8_t fw_update_reqd;
+  uint8_t rf_update_reqd;
+} tNFC_FWUpdate_Info_t;
+#endif
+/*****************************************************************************
+ **  EXTERNAL FUNCTION DECLARATIONS
+ *****************************************************************************/
+
+/* Global NFC data */
+extern tNFC_CB nfc_cb;
+
+/****************************************************************************
+ ** Internal nfc functions
+ ****************************************************************************/
+extern void nfc_init(void);
+
+/* from nfc_utils.c */
+extern tNFC_CONN_CB* nfc_alloc_conn_cb(tNFC_CONN_CBACK* p_cback);
+extern tNFC_CONN_CB* nfc_find_conn_cb_by_conn_id(uint8_t conn_id);
+extern tNFC_CONN_CB* nfc_find_conn_cb_by_handle(uint8_t target_handle);
+extern void nfc_set_conn_id(tNFC_CONN_CB* p_cb, uint8_t conn_id);
+extern void nfc_free_conn_cb(tNFC_CONN_CB* p_cb);
+extern void nfc_reset_all_conn_cbs(void);
+extern void nfc_data_event(tNFC_CONN_CB* p_cb);
+
+void nfc_ncif_send(NFC_HDR* p_buf, bool is_cmd);
+extern uint8_t nfc_ncif_send_data(tNFC_CONN_CB* p_cb, NFC_HDR* p_data);
+extern void nfc_ncif_cmd_timeout(void);
+extern void nfc_wait_2_deactivate_timeout(void);
+extern void nfc_modeset_ntf_timeout(void);
+extern void nfc_ncif_credit_ntf_timeout(void);
+extern bool nfc_ncif_process_event(NFC_HDR* p_msg);
+extern void nfc_ncif_check_cmd_queue(NFC_HDR* p_buf);
+extern void nfc_ncif_send_cmd(NFC_HDR* p_buf);
+extern void nfc_ncif_proc_discover_ntf(uint8_t* p, uint16_t plen);
+extern void nfc_ncif_rf_management_status(tNFC_DISCOVER_EVT event,
+                                          uint8_t status);
+extern void nfc_ncif_set_config_status(uint8_t* p, uint8_t len);
+extern void nfc_ncif_event_status(tNFC_RESPONSE_EVT event, uint8_t status);
+extern void nfc_ncif_error_status(uint8_t conn_id, uint8_t status);
+extern void nfc_ncif_proc_credits(uint8_t* p, uint16_t plen);
+extern void nfc_ncif_proc_activate(uint8_t* p, uint8_t len);
+extern void nfc_ncif_proc_deactivate(uint8_t status, uint8_t deact_type,
+                                     bool is_ntf);
+#if ((NFC_NFCEE_INCLUDED == true) && (NFC_RW_ONLY == false))
+extern void nfc_ncif_proc_ee_action(uint8_t* p, uint16_t plen);
+extern void nfc_ncif_proc_ee_discover_req(uint8_t* p, uint16_t plen);
+extern void nfc_ncif_proc_get_routing(uint8_t* p, uint8_t len);
+#endif
+extern void nfc_ncif_proc_conn_create_rsp(uint8_t* p, uint16_t plen,
+                                          uint8_t dest_type);
+extern void nfc_ncif_report_conn_close_evt(uint8_t conn_id, tNFC_STATUS status);
+extern void nfc_ncif_proc_t3t_polling_ntf(uint8_t* p, uint16_t plen);
+extern void nfc_ncif_proc_reset_rsp(uint8_t* p, bool is_ntf);
+extern void nfc_ncif_proc_init_rsp(NFC_HDR* p_msg);
+extern void nfc_ncif_proc_get_config_rsp(NFC_HDR* p_msg);
+extern void nfc_ncif_proc_data(NFC_HDR* p_msg);
+#if (NXP_EXTNS == TRUE)
+extern uint8_t nfc_ncif_retransmit_data(tNFC_CONN_CB* p_cb, NFC_HDR* p_data);
+extern tNFC_STATUS nfc_ncif_store_FWVersion(uint8_t* p_buf);
+extern tNFC_STATUS nfc_ncif_set_MaxRoutingTableSize(uint8_t* p_buf);
+extern void nfc_ncif_proc_isodep_nak_presence_check_status (uint8_t status, bool is_ntf);
+extern void nfc_ncif_update_window(void);
+extern void nfc_ncif_empty_cmd_queue();
+extern bool nfc_ncif_proc_proprietary_rsp(uint8_t mt, uint8_t gid, uint8_t oid);
+extern void nfc_ncif_proc_rf_wtx_ntf(uint8_t* p, uint16_t plen);
+#endif
+extern bool nfa_dm_p2p_prio_logic(uint8_t event, uint8_t* p, uint8_t ntf_rsp);
+extern void nfa_dm_p2p_timer_event();
+extern void nfa_dm_p2p_prio_logic_cleanup();
+
+#if (NFC_RW_ONLY == FALSE)
+extern void nfc_ncif_proc_rf_field_ntf(uint8_t rf_status);
+#else
+#define nfc_ncif_proc_rf_field_ntf(rf_status)
+#endif
+
+/* From nfc_task.c */
+extern uint32_t nfc_task(uint32_t param);
+void nfc_task_shutdown_nfcc(void);
+
+/* From nfc_main.c */
+void nfc_enabled(tNFC_STATUS nfc_status, NFC_HDR* p_init_rsp_msg);
+void nfc_set_state(tNFC_STATE nfc_state);
+void nfc_main_flush_cmd_queue(void);
+void nfc_gen_cleanup(void);
+void nfc_main_handle_hal_evt(tNFC_HAL_EVT_MSG* p_msg);
+
+/* Timer functions */
+void nfc_start_timer(TIMER_LIST_ENT* p_tle, uint16_t type, uint32_t timeout);
+uint32_t nfc_remaining_time(TIMER_LIST_ENT* p_tle);
+void nfc_stop_timer(TIMER_LIST_ENT* p_tle);
+
+void nfc_start_quick_timer(TIMER_LIST_ENT* p_tle, uint16_t type,
+                           uint32_t timeout);
+void nfc_stop_quick_timer(TIMER_LIST_ENT* p_tle);
+void nfc_process_quick_timer_evt(void);
+void set_i2c_fragmentation_enabled(int value);
+int get_i2c_fragmentation_enabled();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_INT_H_ */
diff --git a/src/nfc/int/rw_int.h b/src/nfc/int/rw_int.h
new file mode 100644
index 0000000..ccb523d
--- /dev/null
+++ b/src/nfc/int/rw_int.h
@@ -0,0 +1,825 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the Near Field Communication (NFC) Reader/Writer mode
+ *  related internal function / definitions.
+ *
+ ******************************************************************************/
+
+#ifndef RW_INT_H_
+#define RW_INT_H_
+
+#include "tags_defs.h"
+#include "tags_int.h"
+#include "rw_api.h"
+
+/* Proprietary definitions for HR0 and HR1 */
+/* HI NIB Tag                                               */
+#define RW_T1T_HR0_HI_NIB 0xF0
+/* Jewel 64 Tag                                             */
+#define RW_T1T_IS_JEWEL64 0x20
+/* Jewel Tag                                                */
+#define RW_T1T_IS_JEWEL 0x00
+/* TOPAZ Tag                                                */
+#define RW_T1T_IS_TOPAZ 0x10
+/* TOPAZ96 Tag                                              */
+#define RW_T1T_IS_TOPAZ96 0x11
+/* TOPAZ512 Tag                                             */
+#define RW_T1T_IS_TOPAZ512 0x12
+/* Supports dynamic commands on static tag if HR1 > 0x49    */
+#define RW_T1T_HR1_MIN 0x49
+
+/* Maximum supported Memory control TLVS in the tag         */
+#define RW_T1T_MAX_MEM_TLVS 0x05
+/* Maximum supported Lock control TLVS in the tag           */
+#define RW_T1T_MAX_LOCK_TLVS 0x05
+/* Maximum supported dynamic lock bytes                     */
+#define RW_T1T_MAX_LOCK_BYTES 0x1E
+
+/* State of the Tag as interpreted by RW */
+/* TAG State is unknown to RW                               */
+#define RW_T1_TAG_ATTRB_UNKNOWN 0x00
+/* TAG is in INITIALIZED state                              */
+#define RW_T1_TAG_ATTRB_INITIALIZED 0x01
+/* TAG is in INITIALIZED state and has NDEF tlv with len=0  */
+#define RW_T1_TAG_ATTRB_INITIALIZED_NDEF 0x02
+/* TAG is in READ ONLY state                                */
+#define RW_T1_TAG_ATTRB_READ_ONLY 0x03
+/* TAG is in READ WRITE state                               */
+#define RW_T1_TAG_ATTRB_READ_WRITE 0x04
+
+/* Lock not yet set as part of SET TAG RO op                */
+#define RW_T1T_LOCK_NOT_UPDATED 0x00
+/* Sent command to set the Lock bytes                       */
+#define RW_T1T_LOCK_UPDATE_INITIATED 0x01
+/* Lock bytes are set                                       */
+#define RW_T1T_LOCK_UPDATED 0x02
+typedef uint8_t tRW_T1T_LOCK_STATUS;
+
+/* States */
+/* Tag not activated and or response not received for RID   */
+#define RW_T1T_STATE_NOT_ACTIVATED 0x00
+/* T1 Tag activated and ready to perform rw operation on Tag*/
+#define RW_T1T_STATE_IDLE 0x01
+/* waiting rsp for read command sent to tag                 */
+#define RW_T1T_STATE_READ 0x02
+/* waiting rsp for write command sent to tag                */
+#define RW_T1T_STATE_WRITE 0x03
+/* performing TLV detection procedure                       */
+#define RW_T1T_STATE_TLV_DETECT 0x04
+/* performing read NDEF procedure                           */
+#define RW_T1T_STATE_READ_NDEF 0x05
+/* performing update NDEF procedure                         */
+#define RW_T1T_STATE_WRITE_NDEF 0x06
+/* Setting Tag as read only tag                             */
+#define RW_T1T_STATE_SET_TAG_RO 0x07
+/* Check if Tag is still present                            */
+#define RW_T1T_STATE_CHECK_PRESENCE 0x08
+/* Format T1 Tag                                            */
+#define RW_T1T_STATE_FORMAT_TAG 0x09
+
+/* Sub states */
+/* Default substate                                         */
+#define RW_T1T_SUBSTATE_NONE 0x00
+
+/* Sub states in RW_T1T_STATE_TLV_DETECT state */
+/* waiting for the detection of a tlv in a tag              */
+#define RW_T1T_SUBSTATE_WAIT_TLV_DETECT 0x01
+/* waiting for finding the len field is 1 or 3 bytes long   */
+#define RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN 0x02
+/* waiting for extracting len field value                   */
+#define RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0 0x03
+/* waiting for extracting len field value                   */
+#define RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN1 0x04
+/* waiting for extracting value field in the TLV            */
+#define RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE 0x05
+/* waiting for reading dynamic locks in the TLV             */
+#define RW_T1T_SUBSTATE_WAIT_READ_LOCKS 0x06
+
+/* Sub states in RW_T1T_STATE_WRITE_NDEF state */
+/* waiting for response of reading a block that will be partially updated */
+#define RW_T1T_SUBSTATE_WAIT_READ_NDEF_BLOCK 0x07
+/* waiting for response of invalidating NDEF Msg                          */
+#define RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF 0x08
+/* waiting for response of writing a part of NDEF Msg                     */
+#define RW_T1T_SUBSTATE_WAIT_NDEF_WRITE 0x09
+/* waiting for response of writing last part of NDEF Msg                  */
+#define RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED 0x0A
+/* waiting for response of validating NDEF Msg                            */
+#define RW_T1T_SUBSTATE_WAIT_VALIDATE_NDEF 0x0B
+
+/* Sub states in RW_T1T_STATE_SET_TAG_RO state */
+/* waiting for response of setting CC-RWA to read only      */
+#define RW_T1T_SUBSTATE_WAIT_SET_CC_RWA_RO 0x0C
+/* waiting for response of setting all static lock bits     */
+#define RW_T1T_SUBSTATE_WAIT_SET_ST_LOCK_BITS 0x0D
+/* waiting for response of setting all dynamic lock bits    */
+#define RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS 0x0E
+
+/* Sub states in RW_T1T_STATE_FORMAT_TAG state */
+/* waiting for response to format/set capability container  */
+#define RW_T1T_SUBSTATE_WAIT_SET_CC 0x0F
+/* waiting for response to format/set NULL NDEF             */
+#define RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF 0x10
+
+typedef struct {
+  uint16_t offset;  /* Offset of the lock byte in the Tag                   */
+  uint8_t num_bits; /* Number of lock bits in the lock byte                 */
+  uint8_t bytes_locked_per_bit; /* No. of tag bytes gets locked by a bit in this
+                                   byte   */
+} tRW_T1T_LOCK_INFO;
+
+typedef struct {
+  uint16_t offset;   /* Reserved bytes offset taken from Memory control TLV  */
+  uint8_t num_bytes; /* Number of reserved bytes as per the TLV              */
+} tRW_T1T_RES_INFO;
+
+typedef struct {
+  uint8_t tlv_index;  /* Index of Lock control tlv that points to this address*/
+  uint8_t byte_index; /* Index of Lock byte pointed by the TLV                */
+  uint8_t lock_byte;  /* Value in the lock byte                               */
+  tRW_T1T_LOCK_STATUS
+      lock_status;  /* Indicates if it is modifed to set tag as Read only   */
+  bool b_lock_read; /* Is the lock byte is already read from tag            */
+} tRW_T1T_LOCK;
+
+typedef struct {
+  uint8_t addr;    /* ADD/ADD8/ADDS field value                            */
+  uint8_t op_code; /* Command sent                                         */
+  uint8_t rsp_len; /* expected length of the response                      */
+  uint8_t
+      pend_retx_rsp; /* Number of pending rsps to retransmission on prev cmd */
+} tRW_T1T_PREV_CMD_RSP_INFO;
+
+#if (RW_NDEF_INCLUDED == true)
+/* Buffer 0-E block, for easier tlv operation           */
+#define T1T_BUFFER_SIZE T1T_STATIC_SIZE
+#else
+/* Buffer UID                                           */
+#define T1T_BUFFER_SIZE T1T_UID_LEN
+#endif
+
+/* RW Type 1 Tag control blocks */
+typedef struct {
+  uint8_t
+      hr[T1T_HR_LEN]; /* Header ROM byte 0 - 0x1y,Header ROM byte 1 - 0x00    */
+  uint8_t mem[T1T_SEGMENT_SIZE]; /* Tag contents of block 0 or from block 0-E */
+  tT1T_CMD_RSP_INFO*
+      p_cmd_rsp_info; /* Pointer to Command rsp info of last sent command     */
+  uint8_t state;      /* Current state of RW module                           */
+  uint8_t tag_attribute; /* Present state of the Tag as interpreted by RW */
+  NFC_HDR*
+      p_cur_cmd_buf; /* Buffer to hold cur sent command for retransmission   */
+  uint8_t addr;      /* ADD/ADD8/ADDS value                                  */
+  tRW_T1T_PREV_CMD_RSP_INFO
+      prev_cmd_rsp_info; /* Information about previous sent command if retx */
+  TIMER_LIST_ENT timer; /* timer to set timelimit for the response to command */
+  bool b_update;    /* Tag header updated                                   */
+  bool b_rseg;      /* Segment 0 read from tag                              */
+  bool b_hard_lock; /* Hard lock the tag as part of config tag to Read only */
+#if (RW_NDEF_INCLUDED == true)
+  uint8_t segment;  /* Current Tag segment                                  */
+  uint8_t substate; /* Current substate of RW module                        */
+  uint16_t work_offset;                     /* Working byte offset */
+  uint8_t ndef_first_block[T1T_BLOCK_SIZE]; /* Buffer for ndef first block */
+  uint8_t ndef_final_block[T1T_BLOCK_SIZE]; /* Buffer for ndef last block */
+  uint8_t* p_ndef_buffer;                   /* Buffer to store ndef message */
+  uint16_t new_ndef_msg_len; /* Lenght of new updating NDEF Message */
+  uint8_t block_read; /* Last read Block                                      */
+  uint8_t write_byte; /* Index of last written byte                           */
+  uint8_t tlv_detect; /* TLV type under detection                             */
+  uint16_t ndef_msg_offset; /* The offset on Tag where first NDEF message is
+                               present*/
+  uint16_t ndef_msg_len;    /* Lenght of NDEF Message */
+  uint16_t
+      max_ndef_msg_len; /* Maximum size of NDEF that can be written on the tag
+                           */
+  uint16_t ndef_header_offset; /* The offset on Tag where first NDEF tlv is
+                                  present    */
+  uint8_t ndef_block_written;  /* Last block where NDEF bytes are written */
+  uint8_t num_ndef_finalblock; /* Block number where NDEF's last byte will be
+                                  present  */
+  uint8_t num_lock_tlvs;       /* Number of lcok tlvs detected in the tag */
+  tRW_T1T_LOCK_INFO lock_tlv[RW_T1T_MAX_LOCK_TLVS]; /* Information retrieved
+                                                       from lock control tlv */
+  uint8_t num_lockbytes; /* Number of dynamic lock bytes present in the tag */
+  tRW_T1T_LOCK
+      lockbyte[RW_T1T_MAX_LOCK_BYTES]; /* Dynamic Lock byte information */
+  uint8_t num_mem_tlvs; /* Number of memory tlvs detected in the tag */
+  tRW_T1T_RES_INFO
+      mem_tlv[RW_T1T_MAX_MEM_TLVS]; /* Information retrieved from mem tlv */
+  uint8_t attr_seg; /* Tag segment for which attributes are prepared        */
+  uint8_t
+      lock_attr_seg; /* Tag segment for which lock attributes are prepared   */
+  uint8_t
+      attr[T1T_BLOCKS_PER_SEGMENT]; /* byte information - Reserved/lock/otp or
+                                       data         */
+  uint8_t lock_attr
+      [T1T_BLOCKS_PER_SEGMENT]; /* byte information - read only or read write */
+#endif
+} tRW_T1T_CB;
+
+/* Mifare Ultalight/ Ultralight Family blank tag version block settings */
+/* Block where version number of the tag is stored */
+#define T2T_MIFARE_VERSION_BLOCK 0x04
+/* Blank Ultralight tag - Block 4 (byte 0, byte 1) */
+#define T2T_MIFARE_ULTRALIGHT_VER_NO 0xFFFF
+/* Blank Ultralight family tag - Block 4 (byte 0, byte 1) */
+#define T2T_MIFARE_ULTRALIGHT_FAMILY_VER_NO 0x0200
+
+/* Infineon my-d move / my-d blank tag uid block settings */
+#define T2T_INFINEON_VERSION_BLOCK 0x00
+#define T2T_INFINEON_MYD_MOVE_LEAN 0x0570
+#define T2T_INFINEON_MYD_MOVE 0x0530
+
+#define T2T_BRCM_VERSION_BLOCK 0x00
+#define T2T_BRCM_STATIC_MEM 0x2E01
+#define T2T_BRCM_DYNAMIC_MEM 0x2E02
+
+#if (NXP_EXTNS == TRUE)
+/* CC2 value on MiFare ULC tag */
+#define T2T_MIFARE_ULC_TMS 0x12
+/* Possible corrupt cc2 value range on MiFare ULC tags */
+#define T2T_INVALID_CC_TMS_VAL0 0x10
+#define T2T_INVALID_CC_TMS_VAL1 0x1F
+#endif
+
+#define T2T_NDEF_NOT_DETECTED 0x00
+#define T2T_NDEF_DETECTED 0x01
+#define T2T_NDEF_READ 0x02
+
+/* Max offset of an NDEF message in a T2 tag */
+#define T2T_MAX_NDEF_OFFSET 128
+#define T2T_MAX_RESERVED_BYTES_IN_TAG 0x64
+#define T2T_MAX_LOCK_BYTES_IN_TAG 0x64
+
+/* Maximum supported Memory control TLVS in the tag         */
+#define RW_T2T_MAX_MEM_TLVS 0x05
+/* Maximum supported Lock control TLVS in the tag           */
+#define RW_T2T_MAX_LOCK_TLVS 0x05
+/* Maximum supported dynamic lock bytes                     */
+#define RW_T2T_MAX_LOCK_BYTES 0x1E
+#define RW_T2T_SEGMENT_BYTES 128
+#define RW_T2T_SEGMENT_SIZE 16
+
+/* Lock not yet set as part of SET TAG RO op                */
+#define RW_T2T_LOCK_NOT_UPDATED 0x00
+/* Sent command to set the Lock bytes                       */
+#define RW_T2T_LOCK_UPDATE_INITIATED 0x01
+/* Lock bytes are set                                       */
+#define RW_T2T_LOCK_UPDATED 0x02
+typedef uint8_t tRW_T2T_LOCK_STATUS;
+
+/* States */
+/* Tag not activated                                        */
+#define RW_T2T_STATE_NOT_ACTIVATED 0x00
+/* T1 Tag activated and ready to perform rw operation on Tag*/
+#define RW_T2T_STATE_IDLE 0x01
+/* waiting response for read command sent to tag            */
+#define RW_T2T_STATE_READ 0x02
+/* waiting response for write command sent to tag           */
+#define RW_T2T_STATE_WRITE 0x03
+/* Waiting response for sector select command               */
+#define RW_T2T_STATE_SELECT_SECTOR 0x04
+/* Detecting Lock/Memory/NDEF/Proprietary TLV in the Tag    */
+#define RW_T2T_STATE_DETECT_TLV 0x05
+/* Performing NDEF Read procedure                           */
+#define RW_T2T_STATE_READ_NDEF 0x06
+/* Performing NDEF Write procedure                          */
+#define RW_T2T_STATE_WRITE_NDEF 0x07
+/* Setting Tag as Read only tag                             */
+#define RW_T2T_STATE_SET_TAG_RO 0x08
+/* Check if Tag is still present                            */
+#define RW_T2T_STATE_CHECK_PRESENCE 0x09
+/* Format the tag                                           */
+#define RW_T2T_STATE_FORMAT_TAG 0x0A
+/* Tag is in HALT State */
+#define RW_T2T_STATE_HALT 0x0B
+
+/* rw_t2t_read/rw_t2t_write takes care of sector change if the block to
+ * read/write is in a different sector
+ * Next Substate should be assigned to control variable 'substate' before
+ * calling these function for State Machine to
+ * move back to the particular substate after Sector change is completed and
+ * read/write command is sent on new sector       */
+
+/* Sub states */
+#define RW_T2T_SUBSTATE_NONE 0x00
+
+/* Sub states in RW_T2T_STATE_SELECT_SECTOR state */
+/* waiting for response of sector select CMD 1              */
+#define RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT 0x01
+/* waiting for response of sector select CMD 2              */
+#define RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR 0x02
+
+/* Sub states in RW_T1T_STATE_DETECT_XXX state */
+/* waiting for the detection of a tlv in a tag              */
+#define RW_T2T_SUBSTATE_WAIT_READ_CC 0x03
+/* waiting for the detection of a tlv in a tag              */
+#define RW_T2T_SUBSTATE_WAIT_TLV_DETECT 0x04
+/* waiting for finding the len field is 1 or 3 bytes long   */
+#define RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN 0x05
+/* waiting for extracting len field value                   */
+#define RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0 0x06
+/* waiting for extracting len field value                   */
+#define RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1 0x07
+/* waiting for extracting value field in the TLV            */
+#define RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE 0x08
+/* waiting for reading dynamic locks in the TLV             */
+#define RW_T2T_SUBSTATE_WAIT_READ_LOCKS 0x09
+
+/* Sub states in RW_T2T_STATE_WRITE_NDEF state */
+/* waiting for rsp to reading the block where NDEF starts   */
+#define RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK 0x0A
+/* waiting for rsp to reading block where new NDEF Msg ends */
+#define RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK 0x0B
+/* waiting for rsp to reading block where Trm tlv gets added*/
+#define RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK 0x0C
+/* waiting for rsp to reading block where nxt NDEF write    */
+#define RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK 0x0D
+/* waiting for rsp to writting NDEF block                   */
+#define RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK 0x0E
+/* waiting for rsp to last NDEF block write cmd             */
+#define RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK 0x0F
+/* waiting for rsp to reading NDEF len field block          */
+#define RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK 0x10
+/* waiting for rsp of updating first NDEF len field block   */
+#define RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK 0x11
+/* waiting for rsp of updating next NDEF len field block    */
+#define RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK 0x12
+/* waiting for rsp to writing to Terminator tlv             */
+#define RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT 0x13
+
+/* Sub states in RW_T2T_STATE_FORMAT_TAG state */
+#define RW_T2T_SUBSTATE_WAIT_READ_VERSION_INFO 0x14
+/* waiting for response to format/set capability container  */
+#define RW_T2T_SUBSTATE_WAIT_SET_CC 0x15
+#define RW_T2T_SUBSTATE_WAIT_SET_LOCK_TLV 0x16
+/* waiting for response to format/set NULL NDEF             */
+#define RW_T2T_SUBSTATE_WAIT_SET_NULL_NDEF 0x17
+
+/* Sub states in RW_T2T_STATE_SET_TAG_RO state */
+/* waiting for response to set CC3 to RO                    */
+#define RW_T2T_SUBSTATE_WAIT_SET_CC_RO 0x19
+/* waiting for response to read dynamic lock bytes block    */
+#define RW_T2T_SUBSTATE_WAIT_READ_DYN_LOCK_BYTE_BLOCK 0x1A
+/* waiting for response to set dynamic lock bits            */
+#define RW_T2T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS 0x1B
+/* waiting for response to set static lock bits             */
+#define RW_T2T_SUBSTATE_WAIT_SET_ST_LOCK_BITS 0x1C
+
+typedef struct {
+  uint16_t offset;              /* Offset of the lock byte in the Tag */
+  uint8_t num_bits;             /* Number of lock bits in the lock byte */
+  uint8_t bytes_locked_per_bit; /* No. of tag bytes gets locked by a bit in this
+                                   byte       */
+} tRW_T2T_LOCK_INFO;
+
+typedef struct {
+  uint16_t offset;   /* Reserved bytes offset taken from Memory control TLV */
+  uint8_t num_bytes; /* Number of reserved bytes as per the TLV */
+} tRW_T2T_RES_INFO;
+
+typedef struct {
+  uint8_t tlv_index; /* Index of Lock control tlv that points to this address */
+  uint8_t byte_index; /* Index of Lock byte pointed by the TLV */
+  uint8_t lock_byte;  /* Value in the lock byte */
+  tRW_T2T_LOCK_STATUS
+      lock_status;  /* Indicates if it is modifed to set tag as Read only */
+  bool b_lock_read; /* Is the lock byte is already read from tag */
+} tRW_T2T_LOCK;
+
+/* RW Type 2 Tag control block */
+typedef struct {
+  uint8_t state;    /* Reader/writer state */
+  uint8_t substate; /* Reader/write substate in NDEF write state */
+  uint8_t
+      prev_substate; /* Substate of the tag before moving to different sector */
+  uint8_t sector;    /* Sector number that is selected */
+  uint8_t select_sector; /* Sector number that is expected to get selected */
+  uint8_t tag_hdr[T2T_READ_DATA_LEN];  /* T2T Header blocks */
+  uint8_t tag_data[T2T_READ_DATA_LEN]; /* T2T Block 4 - 7 data */
+  uint8_t ndef_status;    /* The current status of NDEF Write operation */
+  uint16_t block_read;    /* Read block */
+  uint16_t block_written; /* Written block */
+  tT2T_CMD_RSP_INFO*
+      p_cmd_rsp_info;     /* Pointer to Command rsp info of last sent command */
+  NFC_HDR* p_cur_cmd_buf; /* Copy of current command, for retx/send after sector
+                             change   */
+  NFC_HDR* p_sec_cmd_buf; /* Copy of command, to send after sector change */
+  TIMER_LIST_ENT t2_timer; /* timeout for each API call */
+  bool b_read_hdr;         /* Tag header read from tag */
+  bool b_read_data;        /* Tag data block read from tag */
+  bool b_hard_lock; /* Hard lock the tag as part of config tag to Read only */
+  uint8_t last_cmd_sent;
+  bool check_tag_halt; /* Resent command after NACK rsp to find tag is in HALT
+                          State   */
+#if (RW_NDEF_INCLUDED == true)
+  bool skip_dyn_locks;   /* Skip reading dynamic lock bytes from the tag */
+  uint8_t found_tlv;     /* The Tlv found while searching a particular TLV */
+  uint8_t tlv_detect;    /* TLV type under detection */
+  uint8_t num_lock_tlvs; /* Number of lcok tlvs detected in the tag */
+  uint8_t attr_seg;      /* Tag segment for which attributes are prepared */
+  uint8_t
+      lock_attr_seg; /* Tag segment for which lock attributes are prepared */
+  uint8_t segment;   /* Current operating segment */
+  uint8_t ndef_final_block[T2T_BLOCK_SIZE]; /* Buffer for ndef last block */
+  uint8_t num_mem_tlvs;  /* Number of memory tlvs detected in the tag */
+  uint8_t num_lockbytes; /* Number of dynamic lock bytes present in the tag */
+  uint8_t attr
+      [RW_T2T_SEGMENT_SIZE]; /* byte information - Reserved/lock/otp or data */
+  uint8_t lock_attr[RW_T2T_SEGMENT_SIZE];  /* byte information - read only or
+                                              read write                   */
+  uint8_t tlv_value[3];                    /* Read value field of TLV */
+  uint8_t ndef_first_block[T2T_BLOCK_LEN]; /* NDEF TLV Header block */
+  uint8_t ndef_read_block[T2T_BLOCK_LEN];  /* Buffer to hold read before write
+                                              block                       */
+  uint8_t ndef_last_block[T2T_BLOCK_LEN];  /* Terminator TLV block after NDEF
+                                              Write operation              */
+  uint8_t terminator_tlv_block[T2T_BLOCK_LEN]; /* Terminator TLV Block */
+  uint16_t ndef_last_block_num; /* Block where last byte of updating ndef
+                                   message will exist    */
+  uint16_t ndef_read_block_num; /* Block read during NDEF Write to avoid
+                                   overwritting res bytes */
+  uint16_t
+      bytes_count; /* No. of bytes remaining to collect during tlv detect */
+  uint16_t
+      terminator_byte_index; /* The offset of the tag where terminator tlv may
+                                be added      */
+  uint16_t work_offset;      /* Working byte offset */
+  uint16_t ndef_header_offset;
+  uint16_t
+      ndef_msg_offset;   /* Offset on Tag where first NDEF message is present */
+  uint16_t ndef_msg_len; /* Lenght of NDEF Message */
+  uint16_t
+      max_ndef_msg_len; /* Maximum size of NDEF that can be written on the tag
+                           */
+  uint16_t new_ndef_msg_len; /* Lenght of new updating NDEF Message */
+  uint16_t ndef_write_block;
+  uint16_t prop_msg_len;      /* Proprietary tlv length */
+  uint8_t* p_new_ndef_buffer; /* Pointer to updating NDEF Message */
+  uint8_t* p_ndef_buffer;     /* Pointer to NDEF Message */
+  tRW_T2T_LOCK_INFO lock_tlv[RW_T2T_MAX_LOCK_TLVS]; /* Information retrieved
+                                                       from lock control tlv */
+  tRW_T2T_LOCK
+      lockbyte[RW_T2T_MAX_LOCK_BYTES]; /* Dynamic Lock byte information */
+  tRW_T2T_RES_INFO
+      mem_tlv[RW_T2T_MAX_MEM_TLVS]; /* Information retrieved from mem tlv */
+#endif
+} tRW_T2T_CB;
+
+/* Type 3 Tag control block */
+typedef uint8_t tRW_T3T_RW_STATE;
+
+typedef struct {
+  tNFC_STATUS status;
+  uint8_t version; /* Ver: peer version */
+  uint8_t
+      nbr; /* NBr: number of blocks that can be read using one Check command */
+  uint8_t nbw;    /* Nbw: number of blocks that can be written using one Update
+                     command */
+  uint16_t nmaxb; /* Nmaxb: maximum number of blocks available for NDEF data */
+  uint8_t writef; /* WriteFlag: 00h if writing data finished; 0Fh if writing
+                     data in progress */
+  uint8_t
+      rwflag;  /* RWFlag: 00h NDEF is read-only; 01h if read/write available */
+  uint32_t ln; /* Ln: actual size of stored NDEF data (in bytes) */
+} tRW_T3T_DETECT;
+
+/* RW_T3T control block flags */
+/* The final command for completing the NDEF read/write */
+#define RW_T3T_FL_IS_FINAL_NDEF_SEGMENT 0x01
+/* Waiting for POLL response for presence check */
+#define RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP 0x02
+/* Waiting for POLL response for RW_T3tGetSystemCodes */
+#define RW_T3T_FL_W4_GET_SC_POLL_RSP 0x04
+/* Waiting for POLL response for RW_T3tDetectNDef */
+#define RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP 0x08
+/* Waiting for POLL response for RW_T3tFormat */
+#define RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP 0x10
+/* Waiting for POLL response for RW_T3tSetReadOnly */
+#define RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP 0x20
+
+typedef struct {
+  uint32_t cur_tout; /* Current command timeout */
+  /* check timeout is check_tout_a + n * check_tout_b; X is T/t3t * 4^E */
+  uint32_t check_tout_a; /* Check command timeout (A+1)*X */
+  uint32_t check_tout_b; /* Check command timeout (B+1)*X */
+  /* update timeout is update_tout_a + n * update_tout_b; X is T/t3t * 4^E */
+  uint32_t update_tout_a;    /* Update command timeout (A+1)*X */
+  uint32_t update_tout_b;    /* Update command timeout (B+1)*X */
+  tRW_T3T_RW_STATE rw_state; /* Reader/writer state */
+  uint8_t rw_substate;
+  uint8_t cur_cmd;           /* Current command being executed */
+  NFC_HDR* p_cur_cmd_buf;    /* Copy of current command, for retransmission */
+  TIMER_LIST_ENT timer;      /* timeout for waiting for response */
+  TIMER_LIST_ENT poll_timer; /* timeout for waiting for response */
+
+  tRW_T3T_DETECT ndef_attrib; /* T3T NDEF attribute information */
+
+  uint32_t ndef_msg_len;        /* Length of ndef message to send */
+  uint32_t ndef_msg_bytes_sent; /* Length of ndef message sent so far */
+  uint8_t* ndef_msg;            /* Buffer for outgoing NDEF message */
+  uint32_t ndef_rx_readlen; /* Number of bytes read in current CHECK command */
+  uint32_t ndef_rx_offset;  /* Length of ndef message read so far */
+
+  uint8_t num_system_codes; /* System codes detected */
+  uint16_t system_codes[T3T_MAX_SYSTEM_CODES];
+
+  uint8_t peer_nfcid2[NCI_NFCID2_LEN];
+  uint8_t cur_poll_rc; /* RC used in current POLL command */
+
+  uint8_t flags; /* Flags see RW_T3T_FL_* */
+} tRW_T3T_CB;
+
+/*
+**  Type 4 Tag
+*/
+
+/* Max data size using a single ReadBinary. 2 bytes are for status bytes */
+#define RW_T4T_MAX_DATA_PER_READ                             \
+  (NFC_RW_POOL_BUF_SIZE - NFC_HDR_SIZE - NCI_DATA_HDR_SIZE - \
+   T4T_RSP_STATUS_WORDS_SIZE)
+
+/* Max data size using a single UpdateBinary. 6 bytes are for CLA, INS, P1, P2,
+ * Lc */
+#define RW_T4T_MAX_DATA_PER_WRITE                              \
+  (NFC_RW_POOL_BUF_SIZE - NFC_HDR_SIZE - NCI_MSG_OFFSET_SIZE - \
+   NCI_DATA_HDR_SIZE - T4T_CMD_MAX_HDR_SIZE)
+
+/* Mandatory NDEF file control */
+typedef struct {
+  uint16_t file_id;       /* File Identifier          */
+  uint16_t max_file_size; /* Max NDEF file size       */
+  uint8_t read_access;    /* read access condition    */
+  uint8_t write_access;   /* write access condition   */
+} tRW_T4T_NDEF_FC;
+
+/* Capability Container */
+typedef struct {
+  uint16_t cclen;          /* the size of this capability container        */
+  uint8_t version;         /* the mapping specification version            */
+  uint16_t max_le;         /* the max data size by a single ReadBinary     */
+  uint16_t max_lc;         /* the max data size by a single UpdateBinary   */
+  tRW_T4T_NDEF_FC ndef_fc; /* Mandatory NDEF file control                  */
+} tRW_T4T_CC;
+
+typedef uint8_t tRW_T4T_RW_STATE;
+typedef uint8_t tRW_T4T_RW_SUBSTATE;
+
+/* Type 4 Tag Control Block */
+typedef struct {
+  tRW_T4T_RW_STATE state;        /* main state                       */
+  tRW_T4T_RW_SUBSTATE sub_state; /* sub state                        */
+  uint8_t version;               /* currently effective version      */
+  TIMER_LIST_ENT timer;          /* timeout for each API call        */
+
+  uint16_t ndef_length;    /* length of NDEF data              */
+  uint8_t* p_update_data;  /* pointer of data to update        */
+  uint16_t rw_length;      /* remaining bytes to read/write    */
+  uint16_t rw_offset;      /* remaining offset to read/write   */
+  NFC_HDR* p_data_to_free; /* GKI buffet to delete after done  */
+
+  tRW_T4T_CC cc_file; /* Capability Container File        */
+
+/* NDEF has been detected   */
+#define RW_T4T_NDEF_STATUS_NDEF_DETECTED 0x01
+/* NDEF file is read-only   */
+#define RW_T4T_NDEF_STATUS_NDEF_READ_ONLY 0x02
+
+  uint8_t ndef_status; /* bitmap for NDEF status           */
+  uint8_t channel;     /* channel id: used for read-binary */
+
+  uint16_t max_read_size;   /* max reading size per a command   */
+  uint16_t max_update_size; /* max updating size per a command  */
+  uint16_t card_size;
+  uint8_t card_type;
+} tRW_T4T_CB;
+
+/* RW retransmission statistics */
+#if (RW_STATS_INCLUDED == true)
+typedef struct {
+  uint32_t start_tick;     /* System tick count at activation */
+  uint32_t bytes_sent;     /* Total bytes sent since activation */
+  uint32_t bytes_received; /* Total bytes received since activation */
+  uint32_t num_ops;        /* Number of operations since activation */
+  uint32_t num_retries;    /* Number of retranmissions since activation */
+  uint32_t num_crc;        /* Number of crc failures */
+  uint32_t num_trans_err;  /* Number of transmission error notifications */
+  uint32_t num_fail;       /* Number of aborts (failures after retries) */
+} tRW_STATS;
+#endif /* RW_STATS_INCLUDED */
+
+/* ISO 15693 RW Control Block */
+typedef uint8_t tRW_I93_RW_STATE;
+typedef uint8_t tRW_I93_RW_SUBSTATE;
+
+/* tag is read-only                        */
+#define RW_I93_FLAG_READ_ONLY 0x01
+/* tag supports read multi block           */
+#define RW_I93_FLAG_READ_MULTI_BLOCK 0x02
+/* need to reset DSFID for formatting      */
+#define RW_I93_FLAG_RESET_DSFID 0x04
+/* need to reset AFI for formatting        */
+#define RW_I93_FLAG_RESET_AFI 0x08
+/* use 2 bytes for number of blocks        */
+#define RW_I93_FLAG_16BIT_NUM_BLOCK 0x10
+
+/* searching for type                      */
+#define RW_I93_TLV_DETECT_STATE_TYPE 0x01
+/* searching for the first byte of length  */
+#define RW_I93_TLV_DETECT_STATE_LENGTH_1 0x02
+/* searching for the second byte of length */
+#define RW_I93_TLV_DETECT_STATE_LENGTH_2 0x03
+/* searching for the third byte of length  */
+#define RW_I93_TLV_DETECT_STATE_LENGTH_3 0x04
+/* reading value field                     */
+#define RW_I93_TLV_DETECT_STATE_VALUE 0x05
+
+enum {
+  RW_I93_ICODE_SLI,                  /* ICODE SLI, SLIX                  */
+  RW_I93_ICODE_SLI_S,                /* ICODE SLI-S, SLIX-S              */
+  RW_I93_ICODE_SLI_L,                /* ICODE SLI-L, SLIX-L              */
+  RW_I93_TAG_IT_HF_I_PLUS_INLAY,     /* Tag-it HF-I Plus Inlay           */
+  RW_I93_TAG_IT_HF_I_PLUS_CHIP,      /* Tag-it HF-I Plus Chip            */
+  RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY, /* Tag-it HF-I Standard Chip/Inlyas */
+  RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY, /* Tag-it HF-I Pro Chip/Inlyas      */
+  RW_I93_STM_LRI1K,                  /* STM LRI1K                        */
+  RW_I93_STM_LRI2K,                  /* STM LRI2K                        */
+  RW_I93_STM_LRIS2K,                 /* STM LRIS2K                       */
+  RW_I93_STM_LRIS64K,                /* STM LRIS64K                      */
+  RW_I93_STM_M24LR64_R,              /* STM M24LR64-R                    */
+  RW_I93_STM_M24LR04E_R,             /* STM M24LR04E-R                   */
+  RW_I93_STM_M24LR16E_R,             /* STM M24LR16E-R                   */
+  RW_I93_STM_M24LR64E_R,             /* STM M24LR64E-R                   */
+  RW_I93_UNKNOWN_PRODUCT             /* Unknwon product version          */
+};
+
+typedef struct {
+  tRW_I93_RW_STATE state;        /* main state                       */
+  tRW_I93_RW_SUBSTATE sub_state; /* sub state                        */
+  TIMER_LIST_ENT timer;          /* timeout for each sent command    */
+  uint8_t sent_cmd;              /* last sent command                */
+  uint8_t retry_count;           /* number of retry                  */
+  NFC_HDR* p_retry_cmd;          /* buffer to store cmd sent last    */
+
+  uint8_t info_flags;            /* information flags                */
+  uint8_t uid[I93_UID_BYTE_LEN]; /* UID of currently activated       */
+  uint8_t dsfid;                 /* DSFID if I93_INFO_FLAG_DSFID     */
+  uint8_t afi;                   /* AFI if I93_INFO_FLAG_AFI         */
+  uint8_t block_size;            /* block size of tag, in bytes      */
+  uint16_t num_block;            /* number of blocks in tag          */
+  uint8_t ic_reference;          /* IC Reference of tag              */
+  uint8_t product_version;       /* tag product version              */
+
+  uint8_t intl_flags; /* flags for internal information   */
+
+  uint8_t tlv_detect_state; /* TLV detecting state              */
+  uint8_t tlv_type;         /* currently detected type          */
+  uint16_t tlv_length;      /* currently detected length        */
+
+  uint16_t ndef_tlv_start_offset; /* offset of first byte of NDEF TLV */
+  uint16_t ndef_tlv_last_offset;  /* offset of last byte of NDEF TLV  */
+  uint16_t max_ndef_length;       /* max NDEF length the tag contains */
+  uint16_t ndef_length;           /* length of NDEF data              */
+
+  uint8_t* p_update_data; /* pointer of data to update        */
+  uint16_t rw_length;     /* bytes to read/write              */
+  uint16_t rw_offset;     /* offset to read/write             */
+} tRW_I93_CB;
+
+/* RW memory control blocks */
+typedef union {
+  tRW_T1T_CB t1t;
+  tRW_T2T_CB t2t;
+  tRW_T3T_CB t3t;
+  tRW_T4T_CB t4t;
+  tRW_I93_CB i93;
+} tRW_TCB;
+
+/* RW control blocks */
+typedef struct {
+  tRW_TCB tcb;
+  tRW_CBACK* p_cback;
+  uint32_t cur_retry; /* Retry count for the current operation */
+#if (RW_STATS_INCLUDED == true)
+  tRW_STATS stats;
+#endif /* RW_STATS_INCLUDED */
+  uint8_t trace_level;
+} tRW_CB;
+
+/*****************************************************************************
+**  EXTERNAL FUNCTION DECLARATIONS
+*****************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Global NFC data */
+extern tRW_CB rw_cb;
+
+/* from .c */
+
+#if (RW_NDEF_INCLUDED == true)
+extern tRW_EVENT rw_t1t_handle_rsp(const tT1T_CMD_RSP_INFO* p_info,
+                                   bool* p_notify, uint8_t* p_data,
+                                   tNFC_STATUS* p_status);
+extern tRW_EVENT rw_t1t_info_to_event(const tT1T_CMD_RSP_INFO* p_info);
+#else
+#define rw_t1t_handle_rsp(p, a, b, c) t1t_info_to_evt(p)
+#define rw_t1t_info_to_event(p) t1t_info_to_evt(p)
+#endif
+
+extern void rw_init(void);
+extern tNFC_STATUS rw_t1t_select(uint8_t hr[T1T_HR_LEN],
+                                 uint8_t uid[T1T_CMD_UID_LEN]);
+extern tNFC_STATUS rw_t1t_send_dyn_cmd(uint8_t opcode, uint8_t add,
+                                       uint8_t* p_dat);
+extern tNFC_STATUS rw_t1t_send_static_cmd(uint8_t opcode, uint8_t add,
+                                          uint8_t dat);
+extern void rw_t1t_process_timeout(TIMER_LIST_ENT* p_tle);
+extern void rw_t1t_handle_op_complete(void);
+
+#if (RW_NDEF_INCLUDED == true)
+extern tRW_EVENT rw_t2t_info_to_event(const tT2T_CMD_RSP_INFO* p_info);
+extern void rw_t2t_handle_rsp(uint8_t* p_data);
+#else
+#define rw_t2t_info_to_event(p) t2t_info_to_evt(p)
+#define rw_t2t_handle_rsp(p)
+#endif
+
+extern tNFC_STATUS rw_t2t_sector_change(uint8_t sector);
+extern tNFC_STATUS rw_t2t_read(uint16_t block);
+extern tNFC_STATUS rw_t2t_write(uint16_t block, uint8_t* p_write_data);
+extern void rw_t2t_process_timeout(TIMER_LIST_ENT* p_tle);
+extern tNFC_STATUS rw_t2t_select(void);
+void rw_t2t_handle_op_complete(void);
+
+extern void rw_t3t_process_timeout(TIMER_LIST_ENT* p_tle);
+extern tNFC_STATUS rw_t3t_select(uint8_t peer_nfcid2[NCI_RF_F_UID_LEN],
+                                 uint8_t mrti_check, uint8_t mrti_update);
+void rw_t3t_handle_nci_poll_ntf(uint8_t nci_status, uint8_t num_responses,
+                                uint8_t sensf_res_buf_size,
+                                uint8_t* p_sensf_res_buf);
+
+extern tNFC_STATUS rw_t4t_select(void);
+extern void rw_t4t_process_timeout(TIMER_LIST_ENT* p_tle);
+
+extern tNFC_STATUS rw_i93_select(uint8_t* p_uid);
+extern void rw_i93_process_timeout(TIMER_LIST_ENT* p_tle);
+
+void nfa_rw_update_pupi_id(uint8_t* p, uint8_t len);
+extern void rw_t4t_handle_isodep_nak_rsp(uint8_t status,bool is_ntf);
+#if (RW_STATS_INCLUDED == true)
+/* Internal fcns for statistics (from rw_main.c) */
+void rw_main_reset_stats(void);
+void rw_main_update_tx_stats(uint32_t bytes_tx, bool is_retry);
+void rw_main_update_rx_stats(uint32_t bytes_rx);
+void rw_main_update_crc_error_stats(void);
+void rw_main_update_trans_error_stats(void);
+void rw_main_update_fail_stats(void);
+void rw_main_log_stats(void);
+#endif /* RW_STATS_INCLUDED */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RW_INT_H_ */
diff --git a/src/nfc/int/tags_int.h b/src/nfc/int/tags_int.h
new file mode 100644
index 0000000..550c34c
--- /dev/null
+++ b/src/nfc/int/tags_int.h
@@ -0,0 +1,95 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the common data types shared by Reader/Writer mode
+ *  and Card Emulation.
+ *
+ ******************************************************************************/
+
+#ifndef TAGS_INT_H
+#define TAGS_INT_H
+
+/******************************************************************************
+// T1T command and response definitions
+******************************************************************************/
+
+typedef struct {
+  uint8_t opcode;
+  uint8_t cmd_len;
+  uint8_t uid_offset;
+  uint8_t rsp_len;
+} tT1T_CMD_RSP_INFO;
+
+typedef struct {
+  uint8_t tag_model;
+  uint8_t tms;
+  uint8_t b_dynamic;
+  uint8_t lock_tlv[3];
+  uint8_t mem_tlv[3];
+} tT1T_INIT_TAG;
+
+typedef struct {
+  uint8_t manufacturer_id;
+  bool b_multi_version;
+  uint8_t version_block;
+  uint16_t version_no;
+  uint16_t version_bmask;
+  uint8_t b_calc_cc;
+  uint8_t tms;
+  bool b_otp;
+  uint8_t default_lock_blpb;
+} tT2T_INIT_TAG;
+
+typedef struct {
+  uint8_t opcode;
+  uint8_t cmd_len;
+  uint8_t rsp_len;
+  uint8_t nack_rsp_len;
+} tT2T_CMD_RSP_INFO;
+
+extern const uint8_t
+    t4t_v10_ndef_tag_aid[]; /* V1.0 Type 4 Tag Applicaiton ID */
+extern const uint8_t
+    t4t_v20_ndef_tag_aid[]; /* V2.0 Type 4 Tag Applicaiton ID */
+
+extern const tT1T_CMD_RSP_INFO t1t_cmd_rsp_infos[];
+extern const tT1T_INIT_TAG t1t_init_content[];
+extern const tT1T_CMD_RSP_INFO* t1t_cmd_to_rsp_info(uint8_t opcode);
+extern const tT1T_INIT_TAG* t1t_tag_init_data(uint8_t tag_model);
+extern uint8_t t1t_info_to_evt(const tT1T_CMD_RSP_INFO* p_info);
+
+extern const tT2T_INIT_TAG* t2t_tag_init_data(uint8_t manufacturer_id,
+                                              bool b_valid_ver,
+                                              uint16_t version_no);
+extern const tT2T_CMD_RSP_INFO t2t_cmd_rsp_infos[];
+extern const tT2T_CMD_RSP_INFO* t2t_cmd_to_rsp_info(uint8_t opcode);
+extern uint8_t t2t_info_to_evt(const tT2T_CMD_RSP_INFO* p_info);
+
+#if (BT_TRACE_PROTOCOL == true)
+extern const char* t1t_info_to_str(const tT1T_CMD_RSP_INFO* p_info);
+extern const char* t2t_info_to_str(const tT2T_CMD_RSP_INFO* p_info);
+#else
+#define t1t_info_to_str(x) ""
+#define t2t_info_to_str(x) ""
+#endif
+extern int tags_pow(int x, int y);
+extern unsigned int tags_log2(register unsigned int x);
+
+#endif /* TAGS_INT_H */
diff --git a/src/nfc/llcp/llcp_api.c b/src/nfc/llcp/llcp_api.c
new file mode 100644
index 0000000..7cca07a
--- /dev/null
+++ b/src/nfc/llcp/llcp_api.c
@@ -0,0 +1,1529 @@
+/******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the LLCP API code
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include "gki.h"
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "llcp_api.h"
+#include "llcp_int.h"
+#include "llcp_defs.h"
+
+#if (LLCP_TEST_INCLUDED == true) /* this is for LLCP testing */
+
+tLLCP_TEST_PARAMS llcp_test_params = {
+    LLCP_VERSION_VALUE, 0, /* not override */
+};
+
+/*******************************************************************************
+**
+** Function         LLCP_SetTestParams
+**
+** Description      Set test parameters for LLCP
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void LLCP_SetTestParams(uint8_t version, uint16_t wks) {
+  LLCP_TRACE_API2("LLCP_SetTestParams () version:0x%02X, wks:0x%04X", version,
+                  wks);
+
+  if (version != 0xFF) llcp_test_params.version = version;
+
+  if (wks != 0xFFFF) llcp_test_params.wks = wks;
+}
+#endif
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         LLCP_RegisterDtaCback
+**
+** Description      Register callback function for LLCP DTA testing
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void LLCP_RegisterDtaCback(tLLCP_DTA_CBACK* p_dta_cback) {
+  LLCP_TRACE_API0("LLCP_RegisterDtaCback ()");
+
+  llcp_cb.p_dta_cback = p_dta_cback;
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         LLCP_SetConfig
+**
+** Description      Set configuration parameters for LLCP
+**                  - Local Link MIU
+**                  - Option parameter
+**                  - Response Waiting Time Index
+**                  - Local Link Timeout
+**                  - Inactivity Timeout as initiator role
+**                  - Inactivity Timeout as target role
+**                  - Delay SYMM response
+**                  - Data link connection timeout
+**                  - Delay timeout to send first PDU as initiator
+**                  - firmware start symmetry
+** Returns          void
+**
+*******************************************************************************/
+void LLCP_SetConfig(uint16_t link_miu, uint8_t opt, uint8_t wt,
+                    uint16_t link_timeout, uint16_t inact_timeout_init,
+                    uint16_t inact_timeout_target, uint16_t symm_delay,
+                    uint16_t data_link_timeout,
+                    uint16_t delay_first_pdu_timeout) {
+  LLCP_TRACE_API4(
+      "LLCP_SetConfig () link_miu:%d, opt:0x%02X, wt:%d, link_timeout:%d",
+      link_miu, opt, wt, link_timeout);
+  LLCP_TRACE_API4(
+      "                 inact_timeout (init:%d,target:%d), symm_delay:%d, "
+      "data_link_timeout:%d",
+      inact_timeout_init, inact_timeout_target, symm_delay, data_link_timeout);
+  LLCP_TRACE_API1("                 delay_first_pdu_timeout:%d",
+                  delay_first_pdu_timeout);
+
+  if (link_miu < LLCP_DEFAULT_MIU) {
+    LLCP_TRACE_ERROR1(
+        "LLCP_SetConfig (): link_miu shall not be smaller than "
+        "LLCP_DEFAULT_MIU (%d)",
+        LLCP_DEFAULT_MIU);
+    link_miu = LLCP_DEFAULT_MIU;
+  } else if (link_miu > LLCP_MAX_MIU) {
+    LLCP_TRACE_ERROR1(
+        "LLCP_SetConfig (): link_miu shall not be bigger than LLCP_MAX_MIU "
+        "(%d)",
+        LLCP_MAX_MIU);
+    link_miu = LLCP_MAX_MIU;
+  }
+
+  /* if Link MIU is bigger than GKI buffer */
+  if (link_miu > LLCP_MIU) {
+    LLCP_TRACE_ERROR1(
+        "LLCP_SetConfig (): link_miu shall not be bigger than LLCP_MIU (%d)",
+        LLCP_MIU);
+    llcp_cb.lcb.local_link_miu = LLCP_MIU;
+  } else
+    llcp_cb.lcb.local_link_miu = link_miu;
+
+  llcp_cb.lcb.local_opt = opt;
+  llcp_cb.lcb.local_wt = wt;
+
+  if (link_timeout < LLCP_LTO_UNIT) {
+    LLCP_TRACE_ERROR1(
+        "LLCP_SetConfig (): link_timeout shall not be smaller than "
+        "LLCP_LTO_UNIT (%d ms)",
+        LLCP_LTO_UNIT);
+    llcp_cb.lcb.local_lto = LLCP_DEFAULT_LTO_IN_MS;
+  } else if (link_timeout > LLCP_MAX_LTO_IN_MS) {
+    LLCP_TRACE_ERROR1(
+        "LLCP_SetConfig (): link_timeout shall not be bigger than "
+        "LLCP_MAX_LTO_IN_MS (%d ms)",
+        LLCP_MAX_LTO_IN_MS);
+    llcp_cb.lcb.local_lto = LLCP_MAX_LTO_IN_MS;
+  } else
+    llcp_cb.lcb.local_lto = link_timeout;
+
+  llcp_cb.lcb.inact_timeout_init = inact_timeout_init;
+  llcp_cb.lcb.inact_timeout_target = inact_timeout_target;
+  llcp_cb.lcb.symm_delay = symm_delay;
+  llcp_cb.lcb.data_link_timeout = data_link_timeout;
+  llcp_cb.lcb.delay_first_pdu_timeout = delay_first_pdu_timeout;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_GetConfig
+**
+** Description      Get configuration parameters for LLCP
+**                  - Local Link MIU
+**                  - Option parameter
+**                  - Response Waiting Time Index
+**                  - Local Link Timeout
+**                  - Inactivity Timeout as initiator role
+**                  - Inactivity Timeout as target role
+**                  - Delay SYMM response
+**                  - Data link connection timeout
+**                  - Delay timeout to send first PDU as initiator
+**                  - Firmware start symmetry
+** Returns          void
+**
+*******************************************************************************/
+void LLCP_GetConfig(uint16_t* p_link_miu, uint8_t* p_opt, uint8_t* p_wt,
+                    uint16_t* p_link_timeout, uint16_t* p_inact_timeout_init,
+                    uint16_t* p_inact_timeout_target, uint16_t* p_symm_delay,
+                    uint16_t* p_data_link_timeout,
+                    uint16_t* p_delay_first_pdu_timeout) {
+  *p_link_miu = llcp_cb.lcb.local_link_miu;
+  *p_opt = llcp_cb.lcb.local_opt;
+  *p_wt = llcp_cb.lcb.local_wt;
+  *p_link_timeout = llcp_cb.lcb.local_lto;
+  *p_inact_timeout_init = llcp_cb.lcb.inact_timeout_init;
+  *p_inact_timeout_target = llcp_cb.lcb.inact_timeout_target;
+  *p_symm_delay = llcp_cb.lcb.symm_delay;
+  *p_data_link_timeout = llcp_cb.lcb.data_link_timeout;
+  *p_delay_first_pdu_timeout = llcp_cb.lcb.delay_first_pdu_timeout;
+
+  LLCP_TRACE_API4(
+      "LLCP_GetConfig () link_miu:%d, opt:0x%02X, wt:%d, link_timeout:%d",
+      *p_link_miu, *p_opt, *p_wt, *p_link_timeout);
+  LLCP_TRACE_API4(
+      "                 inact_timeout (init:%d, target:%d), symm_delay:%d, "
+      "data_link_timeout:%d",
+      *p_inact_timeout_init, *p_inact_timeout_target, *p_symm_delay,
+      *p_data_link_timeout);
+  LLCP_TRACE_API1("                 delay_first_pdu_timeout:%d",
+                  *p_delay_first_pdu_timeout);
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_GetDiscoveryConfig
+**
+** Description      Returns discovery config for ISO 18092 MAC link activation
+**                  This function is called to get general bytes for
+**                  NFC_PMID_ATR_REQ_GEN_BYTES or NFC_PMID_ATR_RES_GEN_BYTES
+**                  before starting discovery.
+**
+**                  wt:Waiting time 0 - 8, only for listen
+**                  p_gen_bytes: pointer to store LLCP magic number and
+**                               paramters
+**                  p_gen_bytes_len: length of buffer for gen bytes as input
+**                                   (NOTE:it must be bigger than
+**                                   LLCP_MIN_GEN_BYTES) actual gen bytes size
+**                                   as output
+**
+**                  Restrictions on the use of ISO 18092
+**                  1. The DID features shall not be used.
+**                  2. the NAD features shall not be used.
+**                  3. Frame waiting time extentions (WTX) shall not be used.
+**
+** Returns          None
+**
+*******************************************************************************/
+void LLCP_GetDiscoveryConfig(uint8_t* p_wt, uint8_t* p_gen_bytes,
+                             uint8_t* p_gen_bytes_len) {
+  uint8_t* p = p_gen_bytes;
+
+  LLCP_TRACE_API0("LLCP_GetDiscoveryConfig ()");
+
+  if (*p_gen_bytes_len < LLCP_MIN_GEN_BYTES) {
+    LLCP_TRACE_ERROR1(
+        "LLCP_GetDiscoveryConfig (): GenBytes length shall not be smaller than "
+        "LLCP_MIN_GEN_BYTES (%d)",
+        LLCP_MIN_GEN_BYTES);
+    *p_gen_bytes_len = 0;
+    return;
+  }
+
+  *p_wt = llcp_cb.lcb.local_wt;
+
+  UINT8_TO_BE_STREAM(p, LLCP_MAGIC_NUMBER_BYTE0);
+  UINT8_TO_BE_STREAM(p, LLCP_MAGIC_NUMBER_BYTE1);
+  UINT8_TO_BE_STREAM(p, LLCP_MAGIC_NUMBER_BYTE2);
+
+#if (LLCP_TEST_INCLUDED == true) /* this is for LLCP testing */
+  UINT8_TO_BE_STREAM(p, LLCP_VERSION_TYPE);
+  UINT8_TO_BE_STREAM(p, LLCP_VERSION_LEN);
+  UINT8_TO_BE_STREAM(p, llcp_test_params.version);
+
+  UINT8_TO_BE_STREAM(p, LLCP_MIUX_TYPE);
+  UINT8_TO_BE_STREAM(p, LLCP_MIUX_LEN);
+  UINT16_TO_BE_STREAM(p, (llcp_cb.lcb.local_link_miu - LLCP_DEFAULT_MIU));
+
+  UINT8_TO_BE_STREAM(p, LLCP_WKS_TYPE);
+  UINT8_TO_BE_STREAM(p, LLCP_WKS_LEN);
+  if (llcp_test_params.wks == 0) /* not override */
+  {
+    UINT16_TO_BE_STREAM(p, llcp_cb.lcb.wks);
+  } else {
+    UINT16_TO_BE_STREAM(p, llcp_test_params.wks);
+  }
+#else
+  UINT8_TO_BE_STREAM(p, LLCP_VERSION_TYPE);
+  UINT8_TO_BE_STREAM(p, LLCP_VERSION_LEN);
+  UINT8_TO_BE_STREAM(p, LLCP_VERSION_VALUE);
+
+  UINT8_TO_BE_STREAM(p, LLCP_MIUX_TYPE);
+  UINT8_TO_BE_STREAM(p, LLCP_MIUX_LEN);
+  UINT16_TO_BE_STREAM(p, (llcp_cb.lcb.local_link_miu - LLCP_DEFAULT_MIU));
+
+  UINT8_TO_BE_STREAM(p, LLCP_WKS_TYPE);
+  UINT8_TO_BE_STREAM(p, LLCP_WKS_LEN);
+  UINT16_TO_BE_STREAM(p, llcp_cb.lcb.wks);
+#endif
+
+  UINT8_TO_BE_STREAM(p, LLCP_LTO_TYPE);
+  UINT8_TO_BE_STREAM(p, LLCP_LTO_LEN);
+  UINT8_TO_BE_STREAM(p, (llcp_cb.lcb.local_lto / LLCP_LTO_UNIT));
+
+  UINT8_TO_BE_STREAM(p, LLCP_OPT_TYPE);
+  UINT8_TO_BE_STREAM(p, LLCP_OPT_LEN);
+  UINT8_TO_BE_STREAM(p, llcp_cb.lcb.local_opt);
+
+  *p_gen_bytes_len = (uint8_t)(p - p_gen_bytes);
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_ActivateLink
+**
+** Description      This function will activate LLCP link with LR, WT and Gen
+**                  Bytes in activation NTF from NFCC.
+**
+**                  LLCP_LINK_ACTIVATION_COMPLETE_EVT will be returned through
+**                  callback function if successful.
+**                  Otherwise, LLCP_LINK_ACTIVATION_FAILED_EVT will be returned.
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_ActivateLink(tLLCP_ACTIVATE_CONFIG config,
+                               tLLCP_LINK_CBACK* p_link_cback) {
+  LLCP_TRACE_API1("LLCP_ActivateLink () link_state = %d",
+                  llcp_cb.lcb.link_state);
+
+  if ((llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATED) &&
+      (p_link_cback)) {
+    llcp_cb.lcb.p_link_cback = p_link_cback;
+    return (llcp_link_activate(&config));
+  } else
+    return LLCP_STATUS_FAIL;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_DeactivateLink
+**
+** Description      Deactivate LLCP link
+**
+**                  LLCP_LINK_DEACTIVATED_EVT will be returned through callback
+**                  when LLCP link is deactivated. Then NFC link may be
+**                  deactivated.
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_DeactivateLink(void) {
+  LLCP_TRACE_API1("LLCP_DeactivateLink () link_state = %d",
+                  llcp_cb.lcb.link_state);
+
+  if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_DEACTIVATED) {
+    llcp_link_deactivate(LLCP_LINK_LOCAL_INITIATED);
+    return LLCP_STATUS_SUCCESS;
+  } else
+    return LLCP_STATUS_FAIL;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_RegisterServer
+**
+** Description      Register server and callback function
+**
+**                  reg_sap : Well-Known SAP except LM and SDP (0x02 - 0x0F)
+**                            Advertized by SDP (0x10 - 0x1F)
+**                            LLCP_INVALID_SAP, LLCP will allocate between 0x10
+**                            and 0x1F
+**                  link_type : LLCP_LINK_TYPE_LOGICAL_DATA_LINK
+**                              and/or LLCP_LINK_TYPE_DATA_LINK_CONNECTION
+**                  p_service_name : Null-terminated string up to
+**                                   LLCP_MAX_SN_LEN
+**
+** Returns          SAP between 0x02 and 0x1F, if success
+**                  LLCP_INVALID_SAP, otherwise
+**
+*******************************************************************************/
+uint8_t LLCP_RegisterServer(uint8_t reg_sap, uint8_t link_type,
+                            char* p_service_name,
+                            tLLCP_APP_CBACK* p_app_cback) {
+  uint8_t sap;
+  uint16_t length;
+  tLLCP_APP_CB* p_app_cb = {
+      0,
+  };
+
+  LLCP_TRACE_API3(
+      "LLCP_RegisterServer (): SAP:0x%x, link_type:0x%x, ServiceName:<%s>",
+      reg_sap, link_type, ((p_service_name == NULL) ? "" : p_service_name));
+
+  if (!p_app_cback) {
+    LLCP_TRACE_ERROR0("LLCP_RegisterServer (): Callback must be provided");
+    return LLCP_INVALID_SAP;
+  } else if (((link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0x00) &&
+             ((link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0x00)) {
+    LLCP_TRACE_ERROR1(
+        "LLCP_RegisterServer (): link type (0x%x) must be specified",
+        link_type);
+    return LLCP_INVALID_SAP;
+  }
+
+  if (reg_sap == LLCP_INVALID_SAP) {
+    /* allocate a SAP between 0x10 and 0x1F */
+    for (sap = 0; sap < LLCP_MAX_SERVER; sap++) {
+      if (llcp_cb.server_cb[sap].p_app_cback == NULL) {
+        p_app_cb = &llcp_cb.server_cb[sap];
+        reg_sap = LLCP_LOWER_BOUND_SDP_SAP + sap;
+        break;
+      }
+    }
+
+    if (reg_sap == LLCP_INVALID_SAP) {
+      LLCP_TRACE_ERROR0("LLCP_RegisterServer (): out of resource");
+      return LLCP_INVALID_SAP;
+    }
+  } else if (reg_sap == LLCP_SAP_LM) {
+    LLCP_TRACE_ERROR1("LLCP_RegisterServer (): SAP (0x%x) is for link manager",
+                      reg_sap);
+    return LLCP_INVALID_SAP;
+  } else if (reg_sap <= LLCP_UPPER_BOUND_WK_SAP) {
+    if (reg_sap >= LLCP_MAX_WKS) {
+      LLCP_TRACE_ERROR1(
+          "LLCP_RegisterServer (): out of resource for SAP (0x%x)", reg_sap);
+      return LLCP_INVALID_SAP;
+    } else if (llcp_cb.wks_cb[reg_sap].p_app_cback) {
+      LLCP_TRACE_ERROR1(
+          "LLCP_RegisterServer (): SAP (0x%x) is already registered", reg_sap);
+      return LLCP_INVALID_SAP;
+    } else {
+      p_app_cb = &llcp_cb.wks_cb[reg_sap];
+    }
+  } else if (reg_sap <= LLCP_UPPER_BOUND_SDP_SAP) {
+    if (reg_sap - LLCP_LOWER_BOUND_SDP_SAP >= LLCP_MAX_SERVER) {
+      LLCP_TRACE_ERROR1(
+          "LLCP_RegisterServer (): out of resource for SAP (0x%x)", reg_sap);
+      return LLCP_INVALID_SAP;
+    } else if (llcp_cb.server_cb[reg_sap - LLCP_LOWER_BOUND_SDP_SAP]
+                   .p_app_cback) {
+      LLCP_TRACE_ERROR1(
+          "LLCP_RegisterServer (): SAP (0x%x) is already registered", reg_sap);
+      return LLCP_INVALID_SAP;
+    } else {
+      p_app_cb = &llcp_cb.server_cb[reg_sap - LLCP_LOWER_BOUND_SDP_SAP];
+    }
+  } else if (reg_sap >= LLCP_LOWER_BOUND_LOCAL_SAP) {
+    LLCP_TRACE_ERROR2(
+        "LLCP_RegisterServer (): SAP (0x%x) must be less than 0x%x", reg_sap,
+        LLCP_LOWER_BOUND_LOCAL_SAP);
+    return LLCP_INVALID_SAP;
+  }
+
+  memset(p_app_cb, 0x00, sizeof(tLLCP_APP_CB));
+
+  if (p_service_name) {
+    length = (uint8_t)strlen(p_service_name);
+    if (length > LLCP_MAX_SN_LEN) {
+      LLCP_TRACE_ERROR1(
+          "LLCP_RegisterServer (): Service Name (%d bytes) is too long",
+          length);
+      return LLCP_INVALID_SAP;
+    }
+
+        p_app_cb->p_service_name = (uint8_t*) GKI_getbuf ((uint16_t) (length + 1));
+        if (p_app_cb->p_service_name == NULL)
+        {
+            LLCP_TRACE_ERROR0 ("LLCP_RegisterServer (): Out of resource");
+            return LLCP_INVALID_SAP;
+        }
+
+        NQ_STRLCPY_S ((char *) p_app_cb->p_service_name, length + 1, (char *) p_service_name, length + 1);
+        p_app_cb->p_service_name[length] = 0;
+  } else
+    p_app_cb->p_service_name = NULL;
+
+  p_app_cb->p_app_cback = p_app_cback;
+  p_app_cb->link_type = link_type;
+
+  if (reg_sap <= LLCP_UPPER_BOUND_WK_SAP) {
+    llcp_cb.lcb.wks |= (1 << reg_sap);
+  }
+
+  LLCP_TRACE_DEBUG1("LLCP_RegisterServer (): Registered SAP = 0x%02X", reg_sap);
+
+  if (link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) {
+    llcp_cb.num_logical_data_link++;
+    llcp_util_adjust_ll_congestion();
+  }
+
+  return reg_sap;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_RegisterClient
+**
+** Description      Register client and callback function
+**
+**                  link_type : LLCP_LINK_TYPE_LOGICAL_DATA_LINK
+**                              and/or LLCP_LINK_TYPE_DATA_LINK_CONNECTION
+**
+** Returns          SAP between 0x20 and 0x3F, if success
+**                  LLCP_INVALID_SAP, otherwise
+**
+*******************************************************************************/
+uint8_t LLCP_RegisterClient(uint8_t link_type, tLLCP_APP_CBACK* p_app_cback) {
+  uint8_t reg_sap = LLCP_INVALID_SAP;
+  uint8_t sap;
+  tLLCP_APP_CB* p_app_cb;
+
+  LLCP_TRACE_API1("LLCP_RegisterClient (): link_type = 0x%x", link_type);
+
+  if (!p_app_cback) {
+    LLCP_TRACE_ERROR0("LLCP_RegisterClient (): Callback must be provided");
+    return LLCP_INVALID_SAP;
+  } else if (((link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0x00) &&
+             ((link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0x00)) {
+    LLCP_TRACE_ERROR1(
+        "LLCP_RegisterClient (): link type (0x%x) must be specified",
+        link_type);
+    return LLCP_INVALID_SAP;
+  }
+
+  /* allocate a SAP between 0x20 and 0x3F */
+  for (sap = 0; sap < LLCP_MAX_CLIENT; sap++) {
+    if (llcp_cb.client_cb[sap].p_app_cback == NULL) {
+      p_app_cb = &llcp_cb.client_cb[sap];
+      memset(p_app_cb, 0x00, sizeof(tLLCP_APP_CB));
+      reg_sap = LLCP_LOWER_BOUND_LOCAL_SAP + sap;
+      break;
+    }
+  }
+
+  if (reg_sap == LLCP_INVALID_SAP) {
+    LLCP_TRACE_ERROR0("LLCP_RegisterClient (): out of resource");
+    return LLCP_INVALID_SAP;
+  }
+
+  p_app_cb->p_app_cback = p_app_cback;
+  p_app_cb->p_service_name = NULL;
+  p_app_cb->link_type = link_type;
+
+  LLCP_TRACE_DEBUG1("LLCP_RegisterClient (): Registered SAP = 0x%02X", reg_sap);
+
+  if (link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) {
+    llcp_cb.num_logical_data_link++;
+    llcp_util_adjust_ll_congestion();
+  }
+
+  return reg_sap;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_Deregister
+**
+** Description      Deregister server or client
+**
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_Deregister(uint8_t local_sap) {
+  uint8_t idx;
+  tLLCP_APP_CB* p_app_cb;
+
+  LLCP_TRACE_API1("LLCP_Deregister () SAP:0x%x", local_sap);
+
+  p_app_cb = llcp_util_get_app_cb(local_sap);
+
+  if ((!p_app_cb) || (p_app_cb->p_app_cback == NULL)) {
+    LLCP_TRACE_ERROR1("LLCP_Deregister (): SAP (0x%x) is not registered",
+                      local_sap);
+    return LLCP_STATUS_FAIL;
+  }
+
+  if (p_app_cb->p_service_name) GKI_freebuf(p_app_cb->p_service_name);
+
+  /* update WKS bit map */
+  if (local_sap <= LLCP_UPPER_BOUND_WK_SAP) {
+    llcp_cb.lcb.wks &= ~(1 << local_sap);
+  }
+
+  /* discard any received UI PDU on this SAP */
+  LLCP_FlushLogicalLinkRxData(local_sap);
+  llcp_cb.total_rx_ui_pdu = 0;
+
+  /* deallocate any data link connection on this SAP */
+  for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++) {
+    if ((llcp_cb.dlcb[idx].state != LLCP_DLC_STATE_IDLE) &&
+        (llcp_cb.dlcb[idx].local_sap == local_sap)) {
+      llcp_util_deallocate_data_link(&llcp_cb.dlcb[idx]);
+    }
+  }
+
+  p_app_cb->p_app_cback = NULL;
+
+  /* discard any pending tx UI PDU from this SAP */
+  while (p_app_cb->ui_xmit_q.p_first) {
+    GKI_freebuf(GKI_dequeue(&p_app_cb->ui_xmit_q));
+    llcp_cb.total_tx_ui_pdu--;
+  }
+
+  if (p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) {
+    llcp_cb.num_logical_data_link--;
+    llcp_util_adjust_ll_congestion();
+  }
+
+  /* check rx congestion status */
+  llcp_util_check_rx_congested_status();
+
+  return LLCP_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_IsLogicalLinkCongested
+**
+** Description      Check if logical link is congested
+**
+**
+** Returns          true if congested
+**
+*******************************************************************************/
+bool LLCP_IsLogicalLinkCongested(uint8_t local_sap, uint8_t num_pending_ui_pdu,
+                                 uint8_t total_pending_ui_pdu,
+                                 uint8_t total_pending_i_pdu) {
+  tLLCP_APP_CB* p_app_cb;
+
+  LLCP_TRACE_API4(
+      "LLCP_IsLogicalLinkCongested () Local SAP:0x%x, pending = (%d, %d, %d)",
+      local_sap, num_pending_ui_pdu, total_pending_ui_pdu, total_pending_i_pdu);
+
+  p_app_cb = llcp_util_get_app_cb(local_sap);
+
+  if ((llcp_cb.lcb.link_state != LLCP_LINK_STATE_ACTIVATED) ||
+      (p_app_cb == NULL) || (p_app_cb->p_app_cback == NULL) ||
+      ((p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0) ||
+      (p_app_cb->is_ui_tx_congested)) {
+    return (true);
+  } else if ((num_pending_ui_pdu + p_app_cb->ui_xmit_q.count >=
+              llcp_cb.ll_tx_congest_start) ||
+             (total_pending_ui_pdu + llcp_cb.total_tx_ui_pdu >=
+              llcp_cb.max_num_ll_tx_buff) ||
+             (total_pending_ui_pdu + total_pending_i_pdu +
+                  llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu >=
+              llcp_cb.max_num_tx_buff)) {
+    /* set flag so LLCP can notify uncongested status later */
+    p_app_cb->is_ui_tx_congested = true;
+
+    return (true);
+  }
+  return (false);
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_SendUI
+**
+** Description      Send connnectionless data to DSAP
+**
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**                  LLCP_STATUS_CONGESTED if logical link is congested
+**                  LLCP_STATUS_FAIL, otherwise
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_SendUI(uint8_t ssap, uint8_t dsap, NFC_HDR* p_buf) {
+  tLLCP_STATUS status = LLCP_STATUS_FAIL;
+  tLLCP_APP_CB* p_app_cb;
+
+  LLCP_TRACE_API2("LLCP_SendUI () SSAP=0x%x, DSAP=0x%x", ssap, dsap);
+
+  p_app_cb = llcp_util_get_app_cb(ssap);
+
+  if ((p_app_cb == NULL) || (p_app_cb->p_app_cback == NULL)) {
+    LLCP_TRACE_ERROR1("LLCP_SendUI (): SSAP (0x%x) is not registered", ssap);
+  } else if ((p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0) {
+    LLCP_TRACE_ERROR1(
+        "LLCP_SendUI (): Logical link on SSAP (0x%x) is not enabled", ssap);
+  } else if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_ACTIVATED) {
+    LLCP_TRACE_ERROR0("LLCP_SendUI (): LLCP link is not activated");
+  } else if ((llcp_cb.lcb.peer_opt == LLCP_LSC_UNKNOWN) ||
+             (llcp_cb.lcb.peer_opt & LLCP_LSC_1)) {
+    if (p_buf->len <= llcp_cb.lcb.peer_miu) {
+      if (p_buf->offset >= LLCP_MIN_OFFSET) {
+        status = llcp_util_send_ui(ssap, dsap, p_app_cb, p_buf);
+      } else {
+        LLCP_TRACE_ERROR2("LLCP_SendUI (): offset (%d) must be %d at least",
+                          p_buf->offset, LLCP_MIN_OFFSET);
+      }
+    } else {
+      LLCP_TRACE_ERROR0(
+          "LLCP_SendUI (): Data length shall not be bigger than peer's link "
+          "MIU");
+    }
+  } else {
+    LLCP_TRACE_ERROR0(
+        "LLCP_SendUI (): Peer doesn't support connectionless link");
+  }
+
+  if (status == LLCP_STATUS_FAIL) {
+    GKI_freebuf(p_buf);
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_ReadLogicalLinkData
+**
+** Description      Read information of UI PDU for local SAP
+**
+**                  - Remote SAP who sent UI PDU is returned.
+**                  - Information of UI PDU up to max_data_len is copied into
+**                    p_data.
+**                  - Information of next UI PDU is not concatenated.
+**                  - Recommended max_data_len is link MIU of local device
+**
+** Returns          true if more information of UI PDU or more UI PDU in queue
+**
+*******************************************************************************/
+bool LLCP_ReadLogicalLinkData(uint8_t local_sap, uint32_t max_data_len,
+                              uint8_t* p_remote_sap, uint32_t* p_data_len,
+                              uint8_t* p_data) {
+  tLLCP_APP_CB* p_app_cb;
+  NFC_HDR* p_buf;
+  uint8_t* p_ui_pdu;
+  uint16_t pdu_hdr, ui_pdu_length;
+
+  LLCP_TRACE_API1("LLCP_ReadLogicalLinkData () Local SAP:0x%x", local_sap);
+
+  *p_data_len = 0;
+
+  p_app_cb = llcp_util_get_app_cb(local_sap);
+
+  /* if application is registered */
+  if ((p_app_cb) && (p_app_cb->p_app_cback)) {
+    /* if any UI PDU in rx queue */
+    if (p_app_cb->ui_rx_q.p_first) {
+      p_buf = (NFC_HDR*)p_app_cb->ui_rx_q.p_first;
+      p_ui_pdu = (uint8_t*)(p_buf + 1) + p_buf->offset;
+
+      /* get length of UI PDU */
+      BE_STREAM_TO_UINT16(ui_pdu_length, p_ui_pdu);
+
+      /* get remote SAP from LLCP header */
+      BE_STREAM_TO_UINT16(pdu_hdr, p_ui_pdu);
+      *p_remote_sap = LLCP_GET_SSAP(pdu_hdr);
+
+      /* layer_specific has the offset to read within UI PDU */
+      p_ui_pdu += p_buf->layer_specific;
+
+      /* copy data up to max_data_len */
+      if (max_data_len >= (uint32_t)(ui_pdu_length - LLCP_PDU_HEADER_SIZE -
+                                     p_buf->layer_specific)) {
+        /* copy information without LLCP header */
+        *p_data_len = (uint32_t)(ui_pdu_length - LLCP_PDU_HEADER_SIZE -
+                                 p_buf->layer_specific);
+
+        /* move to next UI PDU if any */
+        p_buf->layer_specific =
+            0; /* reset offset to read from the first byte of next UI PDU */
+        p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
+        p_buf->len -= LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
+      } else {
+        *p_data_len = max_data_len;
+
+        /* update offset to read from remaining UI PDU next time */
+        p_buf->layer_specific += max_data_len;
+      }
+
+      memcpy(p_data, p_ui_pdu, *p_data_len);
+
+      /* if read all of UI PDU */
+      if (p_buf->len == 0) {
+        GKI_dequeue(&p_app_cb->ui_rx_q);
+        GKI_freebuf(p_buf);
+
+        /* decrease number of received UI PDU in in all of ui_rx_q and check rx
+         * congestion status */
+        llcp_cb.total_rx_ui_pdu--;
+        llcp_util_check_rx_congested_status();
+      }
+    }
+
+    /* if there is more UI PDU in rx queue */
+    if (p_app_cb->ui_rx_q.p_first) {
+      return (true);
+    } else {
+      return (false);
+    }
+  } else {
+    LLCP_TRACE_ERROR1("LLCP_ReadLogicalLinkData (): Unregistered SAP:0x%x",
+                      local_sap);
+
+    return (false);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_FlushLogicalLinkRxData
+**
+** Description      Discard received data in logical data link of local SAP
+**
+**
+** Returns          length of data flushed
+**
+*******************************************************************************/
+uint32_t LLCP_FlushLogicalLinkRxData(uint8_t local_sap) {
+  NFC_HDR* p_buf;
+  uint32_t flushed_length = 0;
+  tLLCP_APP_CB* p_app_cb;
+  uint8_t* p_ui_pdu;
+  uint16_t ui_pdu_length;
+
+  LLCP_TRACE_API1("LLCP_FlushLogicalLinkRxData () Local SAP:0x%x", local_sap);
+
+  p_app_cb = llcp_util_get_app_cb(local_sap);
+
+  /* if application is registered */
+  if ((p_app_cb) && (p_app_cb->p_app_cback)) {
+    /* if any UI PDU in rx queue */
+    while (p_app_cb->ui_rx_q.p_first) {
+      p_buf = (NFC_HDR*)p_app_cb->ui_rx_q.p_first;
+      p_ui_pdu = (uint8_t*)(p_buf + 1) + p_buf->offset;
+
+      /* get length of UI PDU */
+      BE_STREAM_TO_UINT16(ui_pdu_length, p_ui_pdu);
+
+      flushed_length += (uint32_t)(ui_pdu_length - LLCP_PDU_HEADER_SIZE -
+                                   p_buf->layer_specific);
+
+      /* move to next UI PDU if any */
+      p_buf->layer_specific = 0; /* offset */
+      p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
+      p_buf->len -= LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
+
+      /* if read all of UI PDU */
+      if (p_buf->len == 0) {
+        GKI_dequeue(&p_app_cb->ui_rx_q);
+        GKI_freebuf(p_buf);
+        llcp_cb.total_rx_ui_pdu--;
+      }
+    }
+
+    /* number of received UI PDU is decreased so check rx congestion status */
+    llcp_util_check_rx_congested_status();
+  } else {
+    LLCP_TRACE_ERROR1("LLCP_FlushLogicalLinkRxData (): Unregistered SAP:0x%x",
+                      local_sap);
+  }
+
+  return (flushed_length);
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_ConnectReq
+**
+** Description      Create data link connection between registered SAP and DSAP
+**                  in peer LLCP,
+**
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**                  LLCP_STATUS_FAIL, otherwise
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_ConnectReq(uint8_t reg_sap, uint8_t dsap,
+                             tLLCP_CONNECTION_PARAMS* p_params) {
+  tLLCP_DLCB* p_dlcb;
+  tLLCP_STATUS status;
+  tLLCP_APP_CB* p_app_cb;
+  tLLCP_CONNECTION_PARAMS params;
+
+  LLCP_TRACE_API2("LLCP_ConnectReq () reg_sap=0x%x, DSAP=0x%x", reg_sap, dsap);
+
+  if ((llcp_cb.lcb.peer_opt != LLCP_LSC_UNKNOWN) &&
+      ((llcp_cb.lcb.peer_opt & LLCP_LSC_2) == 0)) {
+    LLCP_TRACE_ERROR0(
+        "LLCP_ConnectReq (): Peer doesn't support connection-oriented link");
+    return LLCP_STATUS_FAIL;
+  }
+
+  if (!p_params) {
+    params.miu = LLCP_DEFAULT_MIU;
+    params.rw = LLCP_DEFAULT_RW;
+    params.sn[0] = 0;
+    p_params = &params;
+  }
+
+  p_app_cb = llcp_util_get_app_cb(reg_sap);
+
+  /* if application is registered */
+  if ((p_app_cb == NULL) || (p_app_cb->p_app_cback == NULL)) {
+    LLCP_TRACE_ERROR1("LLCP_ConnectReq (): SSAP (0x%x) is not registered",
+                      reg_sap);
+    return LLCP_STATUS_FAIL;
+  }
+
+  if (dsap == LLCP_SAP_LM) {
+    LLCP_TRACE_ERROR1(
+        "LLCP_ConnectReq (): DSAP (0x%x) must not be link manager SAP", dsap);
+    return LLCP_STATUS_FAIL;
+  }
+
+  if (dsap == LLCP_SAP_SDP) {
+    if (strlen(p_params->sn) > LLCP_MAX_SN_LEN) {
+      LLCP_TRACE_ERROR1(
+          "LLCP_ConnectReq (): Service Name (%d bytes) is too long",
+          strlen(p_params->sn));
+      return LLCP_STATUS_FAIL;
+    }
+  }
+
+  if ((p_params) && (p_params->miu > llcp_cb.lcb.local_link_miu)) {
+    LLCP_TRACE_ERROR0(
+        "LLCP_ConnectReq (): Data link MIU shall not be bigger than local link "
+        "MIU");
+    return LLCP_STATUS_FAIL;
+  }
+
+  /* check if any pending connection request on this reg_sap */
+  p_dlcb = llcp_dlc_find_dlcb_by_sap(reg_sap, LLCP_INVALID_SAP);
+  if (p_dlcb) {
+    /*
+    ** Accepting LLCP may change SAP in CC, so we cannot find right data
+    ** link connection if there is multiple pending connection request on
+    ** the same local SAP.
+    */
+    LLCP_TRACE_ERROR0(
+        "LLCP_ConnectReq (): There is pending connect request on this reg_sap");
+    return LLCP_STATUS_FAIL;
+  }
+
+  p_dlcb = llcp_util_allocate_data_link(reg_sap, dsap);
+
+  if (p_dlcb) {
+    status =
+        llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_API_CONNECT_REQ, p_params);
+    if (status != LLCP_STATUS_SUCCESS) {
+      LLCP_TRACE_ERROR0("LLCP_ConnectReq (): Error in state machine");
+      llcp_util_deallocate_data_link(p_dlcb);
+      return LLCP_STATUS_FAIL;
+    }
+  } else {
+    return LLCP_STATUS_FAIL;
+  }
+
+  return LLCP_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_ConnectCfm
+**
+** Description      Accept connection request from peer LLCP
+**
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**                  LLCP_STATUS_FAIL, otherwise
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_ConnectCfm(uint8_t local_sap, uint8_t remote_sap,
+                             tLLCP_CONNECTION_PARAMS* p_params) {
+  tLLCP_STATUS status;
+  tLLCP_DLCB* p_dlcb;
+  tLLCP_CONNECTION_PARAMS params;
+
+  LLCP_TRACE_API2("LLCP_ConnectCfm () Local SAP:0x%x, Remote SAP:0x%x)",
+                  local_sap, remote_sap);
+
+  if (!p_params) {
+    params.miu = LLCP_DEFAULT_MIU;
+    params.rw = LLCP_DEFAULT_RW;
+    params.sn[0] = 0;
+    p_params = &params;
+  }
+  if (p_params->miu > llcp_cb.lcb.local_link_miu) {
+    LLCP_TRACE_ERROR0(
+        "LLCP_ConnectCfm (): Data link MIU shall not be bigger than local link "
+        "MIU");
+    return LLCP_STATUS_FAIL;
+  }
+
+  p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap);
+
+  if (p_dlcb) {
+    status =
+        llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_API_CONNECT_CFM, p_params);
+  } else {
+    LLCP_TRACE_ERROR0("LLCP_ConnectCfm (): No data link");
+    status = LLCP_STATUS_FAIL;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_ConnectReject
+**
+** Description      Reject connection request from peer LLCP
+**
+**                  reason : LLCP_SAP_DM_REASON_APP_REJECTED
+**                           LLCP_SAP_DM_REASON_PERM_REJECT_THIS
+**                           LLCP_SAP_DM_REASON_PERM_REJECT_ANY
+**                           LLCP_SAP_DM_REASON_TEMP_REJECT_THIS
+**                           LLCP_SAP_DM_REASON_TEMP_REJECT_ANY
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**                  LLCP_STATUS_FAIL, otherwise
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_ConnectReject(uint8_t local_sap, uint8_t remote_sap,
+                                uint8_t reason) {
+  tLLCP_STATUS status;
+  tLLCP_DLCB* p_dlcb;
+
+  LLCP_TRACE_API3(
+      "LLCP_ConnectReject () Local SAP:0x%x, Remote SAP:0x%x, reason:0x%x",
+      local_sap, remote_sap, reason);
+
+  p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap);
+
+  if (p_dlcb) {
+    status =
+        llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_API_CONNECT_REJECT, &reason);
+    llcp_util_deallocate_data_link(p_dlcb);
+  } else {
+    LLCP_TRACE_ERROR0("LLCP_ConnectReject (): No data link");
+    status = LLCP_STATUS_FAIL;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_IsDataLinkCongested
+**
+** Description      Check if data link connection is congested
+**
+**
+** Returns          true if congested
+**
+*******************************************************************************/
+bool LLCP_IsDataLinkCongested(uint8_t local_sap, uint8_t remote_sap,
+                              uint8_t num_pending_i_pdu,
+                              uint8_t total_pending_ui_pdu,
+                              uint8_t total_pending_i_pdu) {
+  tLLCP_DLCB* p_dlcb;
+
+  LLCP_TRACE_API5(
+      "LLCP_IsDataLinkCongested () Local SAP:0x%x, Remote SAP:0x%x, pending = "
+      "(%d, %d, %d)",
+      local_sap, remote_sap, num_pending_i_pdu, total_pending_ui_pdu,
+      total_pending_i_pdu);
+
+  p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap);
+
+  if (p_dlcb) {
+    if ((p_dlcb->is_tx_congested) || (p_dlcb->remote_busy)) {
+      return (true);
+    } else if ((num_pending_i_pdu + p_dlcb->i_xmit_q.count >=
+                p_dlcb->remote_rw) ||
+               (total_pending_ui_pdu + total_pending_i_pdu +
+                    llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu >=
+                llcp_cb.max_num_tx_buff)) {
+      /* set flag so LLCP can notify uncongested status later */
+      p_dlcb->is_tx_congested = true;
+      return (true);
+    }
+    return (false);
+  }
+  return (true);
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_SendData
+**
+** Description      Send connection-oriented data
+**
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**                  LLCP_STATUS_CONGESTED if data link is congested
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_SendData(uint8_t local_sap, uint8_t remote_sap,
+                           NFC_HDR* p_buf) {
+  tLLCP_STATUS status = LLCP_STATUS_FAIL;
+  tLLCP_DLCB* p_dlcb;
+
+  LLCP_TRACE_API2("LLCP_SendData () Local SAP:0x%x, Remote SAP:0x%x", local_sap,
+                  remote_sap);
+
+  p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap);
+
+  if (p_dlcb) {
+    if (p_dlcb->remote_miu >= p_buf->len) {
+      if (p_buf->offset >= LLCP_MIN_OFFSET) {
+        status = llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_API_DATA_REQ, p_buf);
+      } else {
+        LLCP_TRACE_ERROR2("LLCP_SendData (): offset (%d) must be %d at least",
+                          p_buf->offset, LLCP_MIN_OFFSET);
+      }
+    } else {
+      LLCP_TRACE_ERROR2(
+          "LLCP_SendData (): Information (%d bytes) cannot be more than peer "
+          "MIU (%d bytes)",
+          p_buf->len, p_dlcb->remote_miu);
+    }
+  } else {
+    LLCP_TRACE_ERROR0("LLCP_SendData (): No data link");
+  }
+
+  if (status == LLCP_STATUS_FAIL) {
+    GKI_freebuf(p_buf);
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_ReadDataLinkData
+**
+** Description      Read information of I PDU for data link connection
+**
+**                  - Information of I PDU up to max_data_len is copied into
+**                    p_data.
+**                  - Information of next I PDU is not concatenated.
+**                  - Recommended max_data_len is data link connection MIU of
+**                    local end point
+**
+** Returns          true if more data in queue
+**
+*******************************************************************************/
+bool LLCP_ReadDataLinkData(uint8_t local_sap, uint8_t remote_sap,
+                           uint32_t max_data_len, uint32_t* p_data_len,
+                           uint8_t* p_data) {
+  tLLCP_DLCB* p_dlcb;
+  NFC_HDR* p_buf;
+  uint8_t* p_i_pdu;
+  uint16_t i_pdu_length;
+
+  LLCP_TRACE_API2("LLCP_ReadDataLinkData () Local SAP:0x%x, Remote SAP:0x%x",
+                  local_sap, remote_sap);
+
+  p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap);
+
+  *p_data_len = 0;
+  if (p_dlcb) {
+    /* if any I PDU in rx queue */
+    if (p_dlcb->i_rx_q.p_first) {
+      p_buf = (NFC_HDR*)p_dlcb->i_rx_q.p_first;
+      p_i_pdu = (uint8_t*)(p_buf + 1) + p_buf->offset;
+
+      /* get length of I PDU */
+      BE_STREAM_TO_UINT16(i_pdu_length, p_i_pdu);
+
+      /* layer_specific has the offset to read within I PDU */
+      p_i_pdu += p_buf->layer_specific;
+
+      /* copy data up to max_data_len */
+      if (max_data_len >= (uint32_t)(i_pdu_length - p_buf->layer_specific)) {
+        /* copy information */
+        *p_data_len = (uint32_t)(i_pdu_length - p_buf->layer_specific);
+
+        /* move to next I PDU if any */
+        p_buf->layer_specific =
+            0; /* reset offset to read from the first byte of next I PDU */
+        p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
+        p_buf->len -= LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
+      } else {
+        *p_data_len = max_data_len;
+
+        /* update offset to read from remaining I PDU next time */
+        p_buf->layer_specific += max_data_len;
+      }
+
+      memcpy(p_data, p_i_pdu, *p_data_len);
+
+      if (p_buf->layer_specific == 0) {
+        p_dlcb->num_rx_i_pdu--;
+      }
+
+      /* if read all of I PDU */
+      if (p_buf->len == 0) {
+        GKI_dequeue(&p_dlcb->i_rx_q);
+        GKI_freebuf(p_buf);
+
+        /* decrease number of received I PDU in in all of ui_rx_q and check rx
+         * congestion status */
+        llcp_cb.total_rx_i_pdu--;
+        llcp_util_check_rx_congested_status();
+      }
+    }
+
+    /* if getting out of rx congestion */
+    if ((!p_dlcb->local_busy) && (p_dlcb->is_rx_congested) &&
+        (p_dlcb->num_rx_i_pdu <= p_dlcb->rx_congest_threshold / 2)) {
+      /* send RR */
+      p_dlcb->is_rx_congested = false;
+      p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
+    }
+
+    /* if there is more I PDU in rx queue */
+    if (p_dlcb->i_rx_q.p_first) {
+      return (true);
+    } else {
+      return (false);
+    }
+  } else {
+    LLCP_TRACE_ERROR0("LLCP_ReadDataLinkData (): No data link connection");
+
+    return (false);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_FlushDataLinkRxData
+**
+** Description      Discard received data in data link connection
+**
+**
+** Returns          length of rx data flushed
+**
+*******************************************************************************/
+uint32_t LLCP_FlushDataLinkRxData(uint8_t local_sap, uint8_t remote_sap) {
+  tLLCP_DLCB* p_dlcb;
+  NFC_HDR* p_buf;
+  uint32_t flushed_length = 0;
+  uint8_t* p_i_pdu;
+  uint16_t i_pdu_length;
+
+  LLCP_TRACE_API2("LLCP_FlushDataLinkRxData () Local SAP:0x%x, Remote SAP:0x%x",
+                  local_sap, remote_sap);
+
+  p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap);
+
+  if (p_dlcb) {
+    /* if any I PDU in rx queue */
+    while (p_dlcb->i_rx_q.p_first) {
+      p_buf = (NFC_HDR*)p_dlcb->i_rx_q.p_first;
+      p_i_pdu = (uint8_t*)(p_buf + 1) + p_buf->offset;
+
+      /* get length of I PDU */
+      BE_STREAM_TO_UINT16(i_pdu_length, p_i_pdu);
+
+      flushed_length += (uint32_t)(i_pdu_length - p_buf->layer_specific);
+
+      /* move to next I PDU if any */
+      p_buf->layer_specific = 0; /* offset */
+      p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
+      p_buf->len -= LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
+
+      /* if read all of I PDU */
+      if (p_buf->len == 0) {
+        GKI_dequeue(&p_dlcb->i_rx_q);
+        GKI_freebuf(p_buf);
+        llcp_cb.total_rx_i_pdu--;
+      }
+    }
+
+    p_dlcb->num_rx_i_pdu = 0;
+
+    /* if getting out of rx congestion */
+    if ((!p_dlcb->local_busy) && (p_dlcb->is_rx_congested)) {
+      /* send RR */
+      p_dlcb->is_rx_congested = false;
+      p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
+    }
+
+    /* number of received I PDU is decreased so check rx congestion status */
+    llcp_util_check_rx_congested_status();
+  } else {
+    LLCP_TRACE_ERROR0("LLCP_FlushDataLinkRxData (): No data link connection");
+  }
+
+  return (flushed_length);
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_DisconnectReq
+**
+** Description      Disconnect data link
+**                  discard any pending data if flush is set to true
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_DisconnectReq(uint8_t local_sap, uint8_t remote_sap,
+                                bool flush) {
+  tLLCP_STATUS status;
+  tLLCP_DLCB* p_dlcb;
+
+  LLCP_TRACE_API3(
+      "LLCP_DisconnectReq () Local SAP:0x%x, Remote SAP:0x%x, flush=%d",
+      local_sap, remote_sap, flush);
+
+  p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap);
+
+  if (p_dlcb) {
+    status =
+        llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
+  } else {
+    LLCP_TRACE_ERROR0("LLCP_DisconnectReq (): No data link");
+    status = LLCP_STATUS_FAIL;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_SetTxCompleteNtf
+**
+** Description      This function is called to get LLCP_SERVICE_TX_COMPLETE
+**                  when Tx queue is empty and all PDU is acked.
+**                  This is one time event, so upper layer shall call this
+**                  function again to get next LLCP_SERVICE_TX_COMPLETE.
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_SetTxCompleteNtf(uint8_t local_sap, uint8_t remote_sap) {
+  tLLCP_STATUS status;
+  tLLCP_DLCB* p_dlcb;
+
+  LLCP_TRACE_API2("LLCP_SetTxCompleteNtf () Local SAP:0x%x, Remote SAP:0x%x",
+                  local_sap, remote_sap);
+
+  p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap);
+
+  if (p_dlcb) {
+    /* set flag to notify upper later when tx complete */
+    p_dlcb->flags |= LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE;
+    status = LLCP_STATUS_SUCCESS;
+  } else {
+    LLCP_TRACE_ERROR0("LLCP_SetTxCompleteNtf (): No data link");
+    status = LLCP_STATUS_FAIL;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_SetLocalBusyStatus
+**
+** Description      Set local busy status
+**
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_SetLocalBusyStatus(uint8_t local_sap, uint8_t remote_sap,
+                                     bool is_busy) {
+  tLLCP_STATUS status;
+  tLLCP_DLCB* p_dlcb;
+
+  LLCP_TRACE_API2("LLCP_SetLocalBusyStatus () Local SAP:0x%x, is_busy=%d",
+                  local_sap, is_busy);
+
+  p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap);
+
+  if (p_dlcb) {
+    if (p_dlcb->local_busy != is_busy) {
+      p_dlcb->local_busy = is_busy;
+
+      /* send RR or RNR with valid sequence */
+      p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
+
+      if (is_busy == false) {
+        if (p_dlcb->i_rx_q.count) {
+          llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_PEER_DATA_IND, NULL);
+        }
+      }
+    }
+    status = LLCP_STATUS_SUCCESS;
+  } else {
+    LLCP_TRACE_ERROR0("LLCP_SetLocalBusyStatus (): No data link");
+    status = LLCP_STATUS_FAIL;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_GetRemoteWKS
+**
+** Description      Return well-known service bitmap of connected device
+**
+**
+** Returns          WKS bitmap if success
+**
+*******************************************************************************/
+uint16_t LLCP_GetRemoteWKS(void) {
+  LLCP_TRACE_API1("LLCP_GetRemoteWKS () WKS:0x%04x",
+                  (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
+                      ? llcp_cb.lcb.peer_wks
+                      : 0);
+
+  if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
+    return (llcp_cb.lcb.peer_wks);
+  else
+    return (0);
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_GetRemoteLSC
+**
+** Description      Return link service class of connected device
+**
+**
+** Returns          link service class
+**
+*******************************************************************************/
+uint8_t LLCP_GetRemoteLSC(void) {
+  LLCP_TRACE_API1("LLCP_GetRemoteLSC () LSC:0x%x",
+                  (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
+                      ? llcp_cb.lcb.peer_opt & (LLCP_LSC_1 | LLCP_LSC_2)
+                      : 0);
+
+  if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
+    return (llcp_cb.lcb.peer_opt & (LLCP_LSC_1 | LLCP_LSC_2));
+  else
+    return (LLCP_LSC_UNKNOWN);
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_GetRemoteVersion
+**
+** Description      Return LLCP version of connected device
+**
+**
+** Returns          LLCP version
+**
+*******************************************************************************/
+uint8_t LLCP_GetRemoteVersion(void) {
+  LLCP_TRACE_API1("LLCP_GetRemoteVersion () Version: 0x%x",
+                  (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
+                      ? llcp_cb.lcb.peer_version
+                      : 0);
+
+  if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
+    return (llcp_cb.lcb.peer_version);
+  else
+    return 0;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_GetLinkMIU
+**
+** Description      Return local and remote link MIU
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void LLCP_GetLinkMIU(uint16_t* p_local_link_miu, uint16_t* p_remote_link_miu) {
+  LLCP_TRACE_API0("LLCP_GetLinkMIU ()");
+
+  if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED) {
+    *p_local_link_miu = llcp_cb.lcb.local_link_miu;
+    *p_remote_link_miu = llcp_cb.lcb.effective_miu;
+  } else {
+    *p_local_link_miu = 0;
+    *p_remote_link_miu = 0;
+  }
+
+  LLCP_TRACE_DEBUG2(
+      "LLCP_GetLinkMIU (): local_link_miu = %d, remote_link_miu = %d",
+      *p_local_link_miu, *p_remote_link_miu);
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_DiscoverService
+**
+** Description      Return SAP of service name in connected device through
+**                  callback
+**
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_DiscoverService(char* p_name, tLLCP_SDP_CBACK* p_cback,
+                                  uint8_t* p_tid) {
+  tLLCP_STATUS status;
+  uint8_t i;
+
+  LLCP_TRACE_API1("LLCP_DiscoverService () Service Name:%s", p_name);
+
+  if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_ACTIVATED) {
+    LLCP_TRACE_ERROR0("LLCP_DiscoverService (): Link is not activated");
+    return LLCP_STATUS_FAIL;
+  }
+
+  if (!p_cback) {
+    LLCP_TRACE_ERROR0("LLCP_DiscoverService (): Callback must be provided.");
+    return LLCP_STATUS_FAIL;
+  }
+
+  /* if peer version is less than V1.1 then SNL is not supported */
+  if ((llcp_cb.lcb.agreed_major_version == 0x01) &&
+      (llcp_cb.lcb.agreed_minor_version < 0x01)) {
+    LLCP_TRACE_ERROR0("LLCP_DiscoverService (): Peer doesn't support SNL");
+    return LLCP_STATUS_FAIL;
+  }
+
+  for (i = 0; i < LLCP_MAX_SDP_TRANSAC; i++) {
+    if (!llcp_cb.sdp_cb.transac[i].p_cback) {
+      llcp_cb.sdp_cb.transac[i].tid = llcp_cb.sdp_cb.next_tid;
+      llcp_cb.sdp_cb.next_tid++;
+      llcp_cb.sdp_cb.transac[i].p_cback = p_cback;
+
+      status = llcp_sdp_send_sdreq(llcp_cb.sdp_cb.transac[i].tid, p_name);
+
+      if (status == LLCP_STATUS_FAIL) {
+        llcp_cb.sdp_cb.transac[i].p_cback = NULL;
+      }
+
+      *p_tid = llcp_cb.sdp_cb.transac[i].tid;
+      return (status);
+    }
+  }
+
+  LLCP_TRACE_ERROR0("LLCP_DiscoverService (): Out of resource");
+
+  return LLCP_STATUS_FAIL;
+}
diff --git a/src/nfc/llcp/llcp_dlc.c b/src/nfc/llcp/llcp_dlc.c
new file mode 100644
index 0000000..73e5003
--- /dev/null
+++ b/src/nfc/llcp/llcp_dlc.c
@@ -0,0 +1,1483 @@
+/******************************************************************************
+ *
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the LLCP Data Link Connection Management
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include "gki.h"
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "llcp_int.h"
+#include "llcp_defs.h"
+#include "nfc_int.h"
+
+static tLLCP_STATUS llcp_dlsm_idle(tLLCP_DLCB* p_dlcb, tLLCP_DLC_EVENT event,
+                                   void* p_data);
+static tLLCP_STATUS llcp_dlsm_w4_remote_resp(tLLCP_DLCB* p_dlcb,
+                                             tLLCP_DLC_EVENT event,
+                                             void* p_data);
+static tLLCP_STATUS llcp_dlsm_w4_local_resp(tLLCP_DLCB* p_dlcb,
+                                            tLLCP_DLC_EVENT event,
+                                            void* p_data);
+static tLLCP_STATUS llcp_dlsm_connected(tLLCP_DLCB* p_dlcb,
+                                        tLLCP_DLC_EVENT event, void* p_data);
+static tLLCP_STATUS llcp_dlsm_w4_remote_dm(tLLCP_DLCB* p_dlcb,
+                                           tLLCP_DLC_EVENT event, void* p_data);
+
+#if (NXP_EXTNS == TRUE)
+extern unsigned char appl_dta_mode_flag;
+#endif
+
+#if (BT_TRACE_VERBOSE == true)
+static char* llcp_dlsm_get_state_name(tLLCP_DLC_STATE state);
+static char* llcp_dlsm_get_event_name(tLLCP_DLC_EVENT event);
+#endif
+
+/*******************************************************************************
+**
+** Function         llcp_dlsm_execute
+**
+** Description      This function executes the state machine for data link
+**                  connection.
+**
+** Returns          tLLCP_STATUS
+**
+*******************************************************************************/
+tLLCP_STATUS llcp_dlsm_execute(tLLCP_DLCB* p_dlcb, tLLCP_DLC_EVENT event,
+                               void* p_data) {
+  tLLCP_STATUS status;
+
+#if (BT_TRACE_VERBOSE == true)
+  LLCP_TRACE_EVENT3("DLC (0x%02X) - state: %s, evt: %s", p_dlcb->local_sap,
+                    llcp_dlsm_get_state_name(p_dlcb->state),
+                    llcp_dlsm_get_event_name(event));
+#else
+  LLCP_TRACE_EVENT3("DLC (0x%02X) - state: %d, evt: %d", p_dlcb->local_sap,
+                    p_dlcb->state, event);
+#endif
+
+  switch (p_dlcb->state) {
+    case LLCP_DLC_STATE_IDLE:
+      status = llcp_dlsm_idle(p_dlcb, event, p_data);
+      break;
+
+    case LLCP_DLC_STATE_W4_REMOTE_RESP:
+      status = llcp_dlsm_w4_remote_resp(p_dlcb, event, p_data);
+      break;
+
+    case LLCP_DLC_STATE_W4_LOCAL_RESP:
+      status = llcp_dlsm_w4_local_resp(p_dlcb, event, p_data);
+      break;
+
+    case LLCP_DLC_STATE_CONNECTED:
+      status = llcp_dlsm_connected(p_dlcb, event, p_data);
+      break;
+
+    case LLCP_DLC_STATE_W4_REMOTE_DM:
+      status = llcp_dlsm_w4_remote_dm(p_dlcb, event, p_data);
+      break;
+
+    default:
+      status = LLCP_STATUS_FAIL;
+      break;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlsm_idle
+**
+** Description      Data link connection is in idle state
+**
+** Returns          tLLCP_STATUS
+**
+*******************************************************************************/
+static tLLCP_STATUS llcp_dlsm_idle(tLLCP_DLCB* p_dlcb, tLLCP_DLC_EVENT event,
+                                   void* p_data) {
+  tLLCP_STATUS status = LLCP_STATUS_SUCCESS;
+  tLLCP_SAP_CBACK_DATA data;
+  tLLCP_CONNECTION_PARAMS* p_params;
+
+  switch (event) {
+    case LLCP_DLC_EVENT_API_CONNECT_REQ:
+
+      /* upper layer requests to create data link connection */
+      p_params = (tLLCP_CONNECTION_PARAMS*)p_data;
+
+      status = llcp_util_send_connect(p_dlcb, p_params);
+
+      if (status == LLCP_STATUS_SUCCESS) {
+        p_dlcb->local_miu = p_params->miu;
+        p_dlcb->local_rw = p_params->rw;
+
+        /* wait for response from peer device */
+        p_dlcb->state = LLCP_DLC_STATE_W4_REMOTE_RESP;
+
+        nfc_start_quick_timer(&p_dlcb->timer, NFC_TTYPE_LLCP_DATA_LINK,
+                              (uint32_t)(llcp_cb.lcb.data_link_timeout *
+                                         QUICK_TIMER_TICKS_PER_SEC) /
+                                  1000);
+      }
+      break;
+
+    case LLCP_DLC_EVENT_PEER_CONNECT_IND:
+
+      /* peer device requests to create data link connection */
+      p_params = (tLLCP_CONNECTION_PARAMS*)p_data;
+
+      if (p_params->miu > llcp_cb.lcb.peer_miu) {
+        LLCP_TRACE_WARNING0(
+            "llcp_dlsm_idle (): Peer sent data link MIU bigger than peer's "
+            "link MIU");
+        p_params->miu = llcp_cb.lcb.peer_miu;
+      }
+
+      data.connect_ind.event = LLCP_SAP_EVT_CONNECT_IND;
+      data.connect_ind.remote_sap = p_dlcb->remote_sap;
+      data.connect_ind.local_sap = p_dlcb->local_sap;
+      data.connect_ind.miu = p_params->miu;
+      data.connect_ind.rw = p_params->rw;
+      data.connect_ind.p_service_name = p_params->sn;
+      data.connect_ind.server_sap = p_dlcb->local_sap;
+
+      p_dlcb->remote_miu = p_params->miu;
+      p_dlcb->remote_rw = p_params->rw;
+
+      LLCP_TRACE_DEBUG2("llcp_dlsm_idle (): Remote MIU:%d, RW:%d",
+                        p_dlcb->remote_miu, p_dlcb->remote_rw);
+
+      /* wait for response from upper layer */
+      p_dlcb->state = LLCP_DLC_STATE_W4_LOCAL_RESP;
+
+      nfc_start_quick_timer(&p_dlcb->timer, NFC_TTYPE_LLCP_DATA_LINK,
+                            (uint32_t)(llcp_cb.lcb.data_link_timeout *
+                                       QUICK_TIMER_TICKS_PER_SEC) /
+                                1000);
+
+      (*p_dlcb->p_app_cb->p_app_cback)(&data);
+
+      break;
+
+    default:
+      LLCP_TRACE_ERROR0("llcp_dlsm_idle (): Unexpected event");
+      status = LLCP_STATUS_FAIL;
+      break;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlsm_w4_remote_resp
+**
+** Description      data link connection is waiting for connection confirm from
+**                  peer
+**
+** Returns          tLLCP_STATUS
+**
+*******************************************************************************/
+static tLLCP_STATUS llcp_dlsm_w4_remote_resp(tLLCP_DLCB* p_dlcb,
+                                             tLLCP_DLC_EVENT event,
+                                             void* p_data) {
+  tLLCP_STATUS status = LLCP_STATUS_SUCCESS;
+  tLLCP_SAP_CBACK_DATA data;
+  tLLCP_CONNECTION_PARAMS* p_params;
+
+  switch (event) {
+    case LLCP_DLC_EVENT_PEER_CONNECT_CFM:
+
+      /* peer device accepted data link connection */
+      nfc_stop_quick_timer(&p_dlcb->timer);
+
+      p_params = (tLLCP_CONNECTION_PARAMS*)p_data;
+
+      /* data link MIU must be up to link MIU */
+      if (p_params->miu > llcp_cb.lcb.peer_miu) {
+        LLCP_TRACE_WARNING0(
+            "llcp_dlsm_w4_remote_resp (): Peer sent data link MIU bigger than "
+            "peer's link MIU");
+        p_params->miu = llcp_cb.lcb.peer_miu;
+      }
+
+      p_dlcb->remote_miu = p_params->miu;
+      p_dlcb->remote_rw = p_params->rw;
+
+      LLCP_TRACE_DEBUG2("llcp_dlsm_w4_remote_resp (): Remote MIU:%d, RW:%d",
+                        p_dlcb->remote_miu, p_dlcb->remote_rw);
+
+      p_dlcb->state = LLCP_DLC_STATE_CONNECTED;
+      llcp_util_adjust_dl_rx_congestion();
+
+      data.connect_resp.event = LLCP_SAP_EVT_CONNECT_RESP;
+      data.connect_resp.remote_sap = p_dlcb->remote_sap;
+      data.connect_resp.local_sap = p_dlcb->local_sap;
+      data.connect_resp.miu = p_params->miu;
+      data.connect_resp.rw = p_params->rw;
+
+      (*p_dlcb->p_app_cb->p_app_cback)(&data);
+
+      if (llcp_cb.overall_rx_congested) {
+        p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
+      }
+      break;
+
+    case LLCP_DLC_EVENT_PEER_DISCONNECT_RESP:
+    case LLCP_DLC_EVENT_TIMEOUT:
+
+      /* peer device rejected connection or didn't respond */
+      data.disconnect_resp.event = LLCP_SAP_EVT_DISCONNECT_RESP;
+      data.disconnect_resp.local_sap = p_dlcb->local_sap;
+      data.disconnect_resp.remote_sap = p_dlcb->remote_sap;
+      data.disconnect_resp.reason = *((uint8_t*)p_data);
+      (*p_dlcb->p_app_cb->p_app_cback)(&data);
+
+      /* stop timer, flush any pending data in queue and deallocate control
+       * block */
+      llcp_util_deallocate_data_link(p_dlcb);
+
+      llcp_util_adjust_dl_rx_congestion();
+      break;
+
+    case LLCP_DLC_EVENT_FRAME_ERROR:
+    case LLCP_DLC_EVENT_LINK_ERROR:
+
+      /* received bad frame or link is deactivated */
+      data.disconnect_ind.event = LLCP_SAP_EVT_DISCONNECT_IND;
+      data.disconnect_ind.local_sap = p_dlcb->local_sap;
+      data.disconnect_ind.remote_sap = p_dlcb->remote_sap;
+      (*p_dlcb->p_app_cb->p_app_cback)(&data);
+
+      llcp_util_deallocate_data_link(p_dlcb);
+      llcp_util_adjust_dl_rx_congestion();
+      break;
+
+    default:
+      LLCP_TRACE_ERROR0("llcp_dlsm_w4_remote_resp (): Unexpected event");
+      status = LLCP_STATUS_FAIL;
+      break;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlsm_w4_local_resp
+**
+** Description      data link connection is waiting for connection confirm from
+**                  application
+**
+** Returns          tLLCP_STATUS
+**
+*******************************************************************************/
+static tLLCP_STATUS llcp_dlsm_w4_local_resp(tLLCP_DLCB* p_dlcb,
+                                            tLLCP_DLC_EVENT event,
+                                            void* p_data) {
+  tLLCP_STATUS status = LLCP_STATUS_SUCCESS;
+  tLLCP_CONNECTION_PARAMS* p_params;
+  tLLCP_SAP_CBACK_DATA data;
+  uint8_t reason;
+
+  switch (event) {
+    case LLCP_DLC_EVENT_API_CONNECT_CFM:
+
+      /* upper layer accepted data link connection */
+      nfc_stop_quick_timer(&p_dlcb->timer);
+
+      p_params = (tLLCP_CONNECTION_PARAMS*)p_data;
+
+      p_dlcb->local_miu = p_params->miu;
+      p_dlcb->local_rw = p_params->rw;
+
+      p_dlcb->state = LLCP_DLC_STATE_CONNECTED;
+
+      if (llcp_cb.overall_rx_congested) {
+        p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
+      }
+
+      status = llcp_util_send_cc(p_dlcb, p_params);
+
+      if (status == LLCP_STATUS_SUCCESS) {
+        llcp_util_adjust_dl_rx_congestion();
+      } else {
+        data.disconnect_ind.event = LLCP_SAP_EVT_DISCONNECT_IND;
+        data.disconnect_ind.local_sap = p_dlcb->local_sap;
+        data.disconnect_ind.remote_sap = p_dlcb->remote_sap;
+        (*p_dlcb->p_app_cb->p_app_cback)(&data);
+
+        llcp_util_deallocate_data_link(p_dlcb);
+      }
+      break;
+
+    case LLCP_DLC_EVENT_API_CONNECT_REJECT:
+    case LLCP_DLC_EVENT_TIMEOUT:
+
+      if (event == LLCP_DLC_EVENT_TIMEOUT)
+        reason = LLCP_SAP_DM_REASON_TEMP_REJECT_THIS;
+      else
+        reason = *((uint8_t*)p_data);
+
+      /* upper layer rejected connection or didn't respond */
+      llcp_util_send_dm(p_dlcb->remote_sap, p_dlcb->local_sap, reason);
+
+      /* stop timer, flush any pending data in queue and deallocate control
+       * block */
+      llcp_util_deallocate_data_link(p_dlcb);
+      llcp_util_adjust_dl_rx_congestion();
+      break;
+
+    case LLCP_DLC_EVENT_FRAME_ERROR:
+    case LLCP_DLC_EVENT_LINK_ERROR:
+
+      /* received bad frame or link is deactivated */
+      data.disconnect_ind.event = LLCP_SAP_EVT_DISCONNECT_IND;
+      data.disconnect_ind.local_sap = p_dlcb->local_sap;
+      data.disconnect_ind.remote_sap = p_dlcb->remote_sap;
+      (*p_dlcb->p_app_cb->p_app_cback)(&data);
+
+      llcp_util_deallocate_data_link(p_dlcb);
+      llcp_util_adjust_dl_rx_congestion();
+      break;
+
+    default:
+      LLCP_TRACE_ERROR0("llcp_dlsm_w4_local_resp (): Unexpected event");
+      status = LLCP_STATUS_FAIL;
+      break;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlsm_connected
+**
+** Description      data link connection is connected
+**
+** Returns          tLLCP_STATUS
+**
+*******************************************************************************/
+static tLLCP_STATUS llcp_dlsm_connected(tLLCP_DLCB* p_dlcb,
+                                        tLLCP_DLC_EVENT event, void* p_data) {
+  bool flush;
+  tLLCP_STATUS status = LLCP_STATUS_SUCCESS;
+  tLLCP_SAP_CBACK_DATA data;
+
+  switch (event) {
+    case LLCP_DLC_EVENT_API_DISCONNECT_REQ:
+
+      /* upper layer requests to disconnect */
+      flush = *(bool*)(p_data);
+
+      /*
+      ** if upper layer asks to discard any pending data
+      ** or there is no pending data/ack to send and it is not waiting for ack
+      */
+      if ((flush) || ((p_dlcb->i_xmit_q.count == 0) &&
+                      (p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq) &&
+                      (p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq))) {
+        /* wait for disconnect response */
+        p_dlcb->state = LLCP_DLC_STATE_W4_REMOTE_DM;
+
+        llcp_util_send_disc(p_dlcb->remote_sap, p_dlcb->local_sap);
+
+        nfc_start_quick_timer(&p_dlcb->timer, NFC_TTYPE_LLCP_DATA_LINK,
+                              (uint32_t)(llcp_cb.lcb.data_link_timeout *
+                                         QUICK_TIMER_TICKS_PER_SEC) /
+                                  1000);
+      } else {
+        /* set flag to send DISC when tx queue is empty */
+        p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_DISC;
+      }
+      break;
+
+    case LLCP_DLC_EVENT_PEER_DISCONNECT_IND:
+
+      /* peer device requests to disconnect */
+
+      /* send disconnect response and notify upper layer */
+      llcp_util_send_dm(p_dlcb->remote_sap, p_dlcb->local_sap,
+                        LLCP_SAP_DM_REASON_RESP_DISC);
+
+      data.disconnect_ind.event = LLCP_SAP_EVT_DISCONNECT_IND;
+      data.disconnect_ind.local_sap = p_dlcb->local_sap;
+      data.disconnect_ind.remote_sap = p_dlcb->remote_sap;
+      (*p_dlcb->p_app_cb->p_app_cback)(&data);
+
+      llcp_util_deallocate_data_link(p_dlcb);
+      llcp_util_adjust_dl_rx_congestion();
+      break;
+
+    case LLCP_DLC_EVENT_API_DATA_REQ:
+
+      /* upper layer requests to send data */
+
+      /* if peer device can receive data */
+      if (p_dlcb->remote_rw) {
+        /* enqueue data and check if data can be sent */
+        GKI_enqueue(&p_dlcb->i_xmit_q, p_data);
+        llcp_cb.total_tx_i_pdu++;
+
+        llcp_link_check_send_data();
+
+        if ((p_dlcb->is_tx_congested) || (llcp_cb.overall_tx_congested) ||
+            (p_dlcb->remote_busy) ||
+            (p_dlcb->i_xmit_q.count >=
+             p_dlcb->remote_rw)) /*if enough data to send next round */
+        {
+          LLCP_TRACE_DEBUG3(
+              "llcp_dlsm_connected (): Data link (SSAP:DSAP=0x%X:0x%X) "
+              "congested: xmit_q.count=%d",
+              p_dlcb->local_sap, p_dlcb->remote_sap, p_dlcb->i_xmit_q.count);
+
+          /* set congested here so overall congestion check routine will not
+           * report event again */
+          p_dlcb->is_tx_congested = true;
+          status = LLCP_STATUS_CONGESTED;
+        }
+      } else {
+        LLCP_TRACE_ERROR0(
+            "llcp_dlsm_connected (): Remote RW is zero: discard data");
+        /* buffer will be freed when returned to API function */
+        status = LLCP_STATUS_FAIL;
+      }
+      break;
+
+    case LLCP_DLC_EVENT_PEER_DATA_IND:
+      /* peer device sends data so notify upper layer to read data from data
+       * link connection */
+
+      data.data_ind.event = LLCP_SAP_EVT_DATA_IND;
+      data.data_ind.local_sap = p_dlcb->local_sap;
+      data.data_ind.link_type = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
+      data.data_ind.remote_sap = p_dlcb->remote_sap;
+
+      (*p_dlcb->p_app_cb->p_app_cback)(&data);
+      break;
+
+    case LLCP_DLC_EVENT_FRAME_ERROR:
+    case LLCP_DLC_EVENT_LINK_ERROR:
+
+      /* received bad frame or link is deactivated */
+      data.disconnect_ind.event = LLCP_SAP_EVT_DISCONNECT_IND;
+      data.disconnect_ind.local_sap = p_dlcb->local_sap;
+      data.disconnect_ind.remote_sap = p_dlcb->remote_sap;
+      (*p_dlcb->p_app_cb->p_app_cback)(&data);
+
+      llcp_util_deallocate_data_link(p_dlcb);
+      llcp_util_adjust_dl_rx_congestion();
+      break;
+
+    default:
+      LLCP_TRACE_ERROR0("llcp_dlsm_connected (): Unexpected event");
+      status = LLCP_STATUS_FAIL;
+      break;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlsm_w4_remote_dm
+**
+** Description      data link connection is waiting for disconnection confirm
+**                  from peer
+**
+** Returns          tLLCP_STATUS
+**
+*******************************************************************************/
+static tLLCP_STATUS llcp_dlsm_w4_remote_dm(tLLCP_DLCB* p_dlcb,
+                                           tLLCP_DLC_EVENT event,
+                                           void* p_data) {
+  tLLCP_STATUS status = LLCP_STATUS_SUCCESS;
+  tLLCP_SAP_CBACK_DATA data;
+  (void)p_data;
+
+  switch (event) {
+    case LLCP_DLC_EVENT_PEER_DISCONNECT_RESP:
+    case LLCP_DLC_EVENT_TIMEOUT:
+
+      /* peer device sends disconnect response or didn't responde */
+      data.disconnect_resp.event = LLCP_SAP_EVT_DISCONNECT_RESP;
+      data.disconnect_resp.local_sap = p_dlcb->local_sap;
+      data.disconnect_resp.remote_sap = p_dlcb->remote_sap;
+      data.disconnect_resp.reason = LLCP_SAP_DM_REASON_RESP_DISC;
+      (*p_dlcb->p_app_cb->p_app_cback)(&data);
+
+      llcp_util_deallocate_data_link(p_dlcb);
+      llcp_util_adjust_dl_rx_congestion();
+      break;
+
+    case LLCP_DLC_EVENT_FRAME_ERROR:
+    case LLCP_DLC_EVENT_LINK_ERROR:
+
+      /* received bad frame or link is deactivated */
+      data.disconnect_ind.event = LLCP_SAP_EVT_DISCONNECT_IND;
+      data.disconnect_ind.local_sap = p_dlcb->local_sap;
+      data.disconnect_ind.remote_sap = p_dlcb->remote_sap;
+      (*p_dlcb->p_app_cb->p_app_cback)(&data);
+
+      llcp_util_deallocate_data_link(p_dlcb);
+      llcp_util_adjust_dl_rx_congestion();
+      break;
+
+    case LLCP_DLC_EVENT_PEER_DATA_IND:
+      break;
+
+    case LLCP_DLC_EVENT_PEER_DISCONNECT_IND:
+      /* it's race condition, send disconnect response and wait for DM */
+      llcp_util_send_dm(p_dlcb->remote_sap, p_dlcb->local_sap,
+                        LLCP_SAP_DM_REASON_RESP_DISC);
+      break;
+
+    default:
+      LLCP_TRACE_ERROR0("llcp_dlsm_w4_remote_dm (): Unexpected event");
+      status = LLCP_STATUS_FAIL;
+      break;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlc_find_dlcb_by_local_sap
+**
+** Description      Find tLLCP_DLCB by local SAP and remote SAP
+**                  if remote_sap is LLCP_INVALID_SAP, it will return a DLCB
+**                  which is waiting for CC from peer.
+**
+** Returns          tLLCP_DLCB *
+**
+*******************************************************************************/
+tLLCP_DLCB* llcp_dlc_find_dlcb_by_sap(uint8_t local_sap, uint8_t remote_sap) {
+  int i;
+
+  for (i = 0; i < LLCP_MAX_DATA_LINK; i++) {
+    if ((llcp_cb.dlcb[i].state != LLCP_DLC_STATE_IDLE) &&
+        (llcp_cb.dlcb[i].local_sap == local_sap)) {
+      if ((remote_sap == LLCP_INVALID_SAP) &&
+          (llcp_cb.dlcb[i].state == LLCP_DLC_STATE_W4_REMOTE_RESP)) {
+        /* Remote SAP has not been finalized because we are watiing for CC */
+        return (&llcp_cb.dlcb[i]);
+      } else if (llcp_cb.dlcb[i].remote_sap == remote_sap) {
+        return (&llcp_cb.dlcb[i]);
+      }
+    }
+  }
+  return NULL;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlc_flush_q
+**
+** Description      Free buffers in tx and rx queue in data link
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_dlc_flush_q(tLLCP_DLCB* p_dlcb) {
+  if (p_dlcb) {
+    LLCP_TRACE_DEBUG1("llcp_dlc_flush_q (): local SAP:0x%02X",
+                      p_dlcb->local_sap);
+
+    /* Release any held buffers */
+    while (p_dlcb->i_xmit_q.p_first) {
+      GKI_freebuf(GKI_dequeue(&p_dlcb->i_xmit_q));
+      llcp_cb.total_tx_i_pdu--;
+    }
+
+    /* discard any received I PDU on data link  including in AGF */
+    LLCP_FlushDataLinkRxData(p_dlcb->local_sap, p_dlcb->remote_sap);
+  } else {
+    LLCP_TRACE_ERROR0("llcp_dlc_flush_q (): p_dlcb is NULL");
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlc_proc_connect_pdu
+**
+** Description      Process CONNECT PDU
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_dlc_proc_connect_pdu(uint8_t dsap, uint8_t ssap,
+                                      uint16_t length, uint8_t* p_data) {
+  tLLCP_DLCB* p_dlcb;
+  tLLCP_STATUS status;
+  tLLCP_APP_CB* p_app_cb;
+
+  tLLCP_CONNECTION_PARAMS params;
+
+  LLCP_TRACE_DEBUG0("llcp_dlc_proc_connect_pdu ()");
+
+  p_app_cb = llcp_util_get_app_cb(dsap);
+
+  if ((p_app_cb == NULL) || (p_app_cb->p_app_cback == NULL) ||
+      ((p_app_cb->link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0)) {
+    LLCP_TRACE_ERROR1("llcp_dlc_proc_connect_pdu (): Unregistered SAP:0x%x",
+                      dsap);
+    llcp_util_send_dm(ssap, dsap, LLCP_SAP_DM_REASON_NO_SERVICE);
+    return;
+  }
+
+  /* parse CONNECT PDU and get connection parameters */
+  if (llcp_util_parse_connect(p_data, length, &params) != LLCP_STATUS_SUCCESS) {
+    LLCP_TRACE_ERROR0("llcp_dlc_proc_connect_pdu (): Bad format CONNECT");
+    /* fix to pass TC_CTO_TAR_BI_02_x (x=5) test case
+     * As per the LLCP test specification v1.2.00 by receiving erroneous SNL PDU
+     * i'e with improper length and service name "urn:nfc:sn:dta-co-echo-in",
+     * the IUT should not
+     * send any PDU except SYMM PDU*/
+    if (appl_dta_mode_flag == 1) {
+      if (p_data[1] == strlen((const char*)&p_data[2])) {
+        LLCP_TRACE_DEBUG0("llcp_dlc_proc_connect_pdu () Strings are not equal");
+        llcp_util_send_dm(ssap, dsap, LLCP_SAP_DM_REASON_NO_SERVICE);
+      }
+    } else {
+      llcp_util_send_dm(ssap, dsap, LLCP_SAP_DM_REASON_NO_SERVICE);
+    }
+    return;
+  }
+
+  /* if this is connection by service name */
+  if (dsap == LLCP_SAP_SDP) {
+    /* find registered SAP with service name */
+    if (strlen(params.sn))
+      dsap = llcp_sdp_get_sap_by_name(params.sn, (uint8_t)strlen(params.sn));
+    else {
+      /* if SN type is included without SN */
+      if (params.sn[1] == LLCP_SN_TYPE) {
+        llcp_util_send_dm(ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_NO_SERVICE);
+      } else {
+        /* SDP doesn't accept connection */
+        llcp_util_send_dm(ssap, LLCP_SAP_SDP,
+                          LLCP_SAP_DM_REASON_PERM_REJECT_THIS);
+      }
+      return;
+    }
+
+    if (dsap == LLCP_SAP_SDP) {
+      LLCP_TRACE_ERROR0(
+          "llcp_dlc_proc_connect_pdu (): SDP doesn't accept connection");
+
+      llcp_util_send_dm(ssap, LLCP_SAP_SDP,
+                        LLCP_SAP_DM_REASON_PERM_REJECT_THIS);
+      return;
+    } else if (dsap == 0) {
+      LLCP_TRACE_ERROR1("llcp_dlc_proc_connect_pdu (): Unregistered Service:%s",
+                        params.sn);
+
+      llcp_util_send_dm(ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_NO_SERVICE);
+      return;
+    } else {
+      /* check if this application can support connection-oriented transport */
+      p_app_cb = llcp_util_get_app_cb(dsap);
+
+      if ((p_app_cb == NULL) || (p_app_cb->p_app_cback == NULL) ||
+          ((p_app_cb->link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0)) {
+        LLCP_TRACE_ERROR1(
+            "llcp_dlc_proc_connect_pdu (): SAP(0x%x) doesn't support "
+            "connection-oriented",
+            dsap);
+        llcp_util_send_dm(ssap, dsap, LLCP_SAP_DM_REASON_NO_SERVICE);
+        return;
+      }
+    }
+  }
+
+  /* check if any data link */
+  p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, ssap);
+  if (p_dlcb) {
+    LLCP_TRACE_ERROR0(
+        "llcp_dlc_proc_connect_pdu (): Data link is aleady established");
+    llcp_util_send_dm(ssap, dsap, LLCP_SAP_DM_REASON_TEMP_REJECT_THIS);
+  } else {
+    /* allocate data link connection control block and notify upper layer
+     * through state machine */
+    p_dlcb = llcp_util_allocate_data_link(dsap, ssap);
+
+    if (p_dlcb) {
+      status =
+          llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_PEER_CONNECT_IND, &params);
+      if (status != LLCP_STATUS_SUCCESS) {
+        LLCP_TRACE_ERROR0(
+            "llcp_dlc_proc_connect_pdu (): Error in state machine");
+        llcp_util_deallocate_data_link(p_dlcb);
+      }
+    } else {
+      LLCP_TRACE_ERROR0("llcp_dlc_proc_connect_pdu (): Out of resource");
+      llcp_util_send_dm(ssap, dsap, LLCP_SAP_DM_REASON_TEMP_REJECT_ANY);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlc_proc_disc_pdu
+**
+** Description      Process DISC PDU
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_dlc_proc_disc_pdu(uint8_t dsap, uint8_t ssap, uint16_t length,
+                                   uint8_t* p_data) {
+  tLLCP_DLCB* p_dlcb;
+  (void)p_data;
+
+  LLCP_TRACE_DEBUG0("llcp_dlc_proc_disc_pdu ()");
+
+  p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, ssap);
+  if (p_dlcb) {
+    if (length > 0) {
+      LLCP_TRACE_ERROR1(
+          "llcp_dlc_proc_disc_pdu (): Received extra data (%d bytes) in DISC "
+          "PDU",
+          length);
+
+      llcp_util_send_frmr(p_dlcb,
+                          LLCP_FRMR_W_ERROR_FLAG | LLCP_FRMR_I_ERROR_FLAG,
+                          LLCP_PDU_DISC_TYPE, 0);
+      llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
+    } else {
+      llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_PEER_DISCONNECT_IND, NULL);
+    }
+  } else {
+    LLCP_TRACE_ERROR2(
+        "llcp_dlc_proc_disc_pdu (): No data link for SAP (0x%x,0x%x)", dsap,
+        ssap);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlc_proc_cc_pdu
+**
+** Description      Process CC PDU
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_dlc_proc_cc_pdu(uint8_t dsap, uint8_t ssap, uint16_t length,
+                                 uint8_t* p_data) {
+  tLLCP_DLCB* p_dlcb;
+  tLLCP_CONNECTION_PARAMS params;
+  tLLCP_STATUS status;
+
+  LLCP_TRACE_DEBUG0("llcp_dlc_proc_cc_pdu ()");
+
+  /* find a DLCB waiting for CC on this local SAP */
+  p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, LLCP_INVALID_SAP);
+  if (p_dlcb) {
+    /* The CC may contain a SSAP that is different from the DSAP in the CONNECT
+     */
+    p_dlcb->remote_sap = ssap;
+
+    if (llcp_util_parse_cc(p_data, length, &(params.miu), &(params.rw)) ==
+        LLCP_STATUS_SUCCESS) {
+      status =
+          llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_PEER_CONNECT_CFM, &params);
+      if (status != LLCP_STATUS_SUCCESS) {
+        LLCP_TRACE_ERROR0("llcp_dlc_proc_cc_pdu (): Error in state machine");
+        llcp_util_deallocate_data_link(p_dlcb);
+      }
+    } else {
+      llcp_util_send_frmr(p_dlcb,
+                          LLCP_FRMR_W_ERROR_FLAG | LLCP_FRMR_I_ERROR_FLAG,
+                          LLCP_PDU_DISC_TYPE, 0);
+      llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
+    }
+  } else {
+    LLCP_TRACE_ERROR2(
+        "llcp_dlc_proc_cc_pdu (): No data link for SAP (0x%x,0x%x)", dsap,
+        ssap);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlc_proc_dm_pdu
+**
+** Description      Process DM PDU
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_dlc_proc_dm_pdu(uint8_t dsap, uint8_t ssap, uint16_t length,
+                                 uint8_t* p_data) {
+  tLLCP_DLCB* p_dlcb;
+
+  LLCP_TRACE_DEBUG0("llcp_dlc_proc_dm_pdu ()");
+
+  if (length != LLCP_PDU_DM_SIZE - LLCP_PDU_HEADER_SIZE) {
+    LLCP_TRACE_ERROR0("llcp_dlc_proc_dm_pdu (): Received invalid DM PDU");
+  } else {
+    if (*p_data == LLCP_SAP_DM_REASON_RESP_DISC) {
+      /* local device initiated disconnecting */
+      p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, ssap);
+    } else {
+      /* peer device rejected connection with any reason */
+      /* find a DLCB waiting for CC on this local SAP    */
+      p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, LLCP_INVALID_SAP);
+    }
+
+    if (p_dlcb) {
+      llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_PEER_DISCONNECT_RESP,
+                        p_data); /* passing reason */
+    } else {
+      LLCP_TRACE_ERROR2(
+          "llcp_dlc_proc_dm_pdu (): No data link for SAP (0x%x,0x%x)", dsap,
+          ssap);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlc_proc_i_pdu
+**
+** Description      Process I PDU
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_dlc_proc_i_pdu(uint8_t dsap, uint8_t ssap, uint16_t i_pdu_length,
+                         uint8_t* p_i_pdu, NFC_HDR* p_msg) {
+  uint8_t* p, *p_dst, send_seq, rcv_seq, error_flags;
+  uint16_t info_len, available_bytes;
+  tLLCP_DLCB* p_dlcb;
+  bool appended;
+  NFC_HDR* p_last_buf;
+
+  LLCP_TRACE_DEBUG0("llcp_dlc_proc_i_pdu ()");
+
+  p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, ssap);
+
+  if ((p_dlcb) && (p_dlcb->state == LLCP_DLC_STATE_CONNECTED)) {
+    error_flags = 0;
+
+    if ((p_msg == NULL) && (p_i_pdu == NULL)) {
+      LLCP_TRACE_ERROR0(
+          "llcp_dlc_proc_i_pdu (): Both p_msg and p_i_pdu are NULL");
+      /* Frame reject cannot be sent in this case, as we don't have sequence
+       * number */
+      llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
+      return;
+    }
+    if (p_msg) {
+      i_pdu_length = p_msg->len;
+      p_i_pdu = (uint8_t*)(p_msg + 1) + p_msg->offset;
+    }
+
+    info_len = i_pdu_length - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE;
+
+    if (info_len > p_dlcb->local_miu) {
+      LLCP_TRACE_ERROR2(
+          "llcp_dlc_proc_i_pdu (): exceeding local MIU (%d bytes): got %d "
+          "bytes SDU",
+          p_dlcb->local_miu, info_len);
+
+      error_flags |= LLCP_FRMR_I_ERROR_FLAG;
+    }
+
+    /* get sequence numbers */
+    p = p_i_pdu + LLCP_PDU_HEADER_SIZE;
+
+    send_seq = LLCP_GET_NS(*p);
+    rcv_seq = LLCP_GET_NR(*p);
+
+#if (BT_TRACE_VERBOSE == true)
+    LLCP_TRACE_DEBUG6(
+        "LLCP RX I PDU - N(S,R):(%d,%d) V(S,SA,R,RA):(%d,%d,%d,%d)", send_seq,
+        rcv_seq, p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq, p_dlcb->next_rx_seq,
+        p_dlcb->sent_ack_seq);
+#endif
+
+    /* if send sequence number, N(S) is not expected one, V(R) */
+    if (p_dlcb->next_rx_seq != send_seq) {
+      LLCP_TRACE_ERROR2("llcp_dlc_proc_i_pdu (): Bad N(S) got:%d, expected:%d",
+                        send_seq, p_dlcb->next_rx_seq);
+
+      error_flags |= LLCP_FRMR_S_ERROR_FLAG;
+    } else {
+      /* if peer device sends more than our receiving window size */
+      if ((uint8_t)(send_seq - p_dlcb->sent_ack_seq) % LLCP_SEQ_MODULO >=
+          p_dlcb->local_rw) {
+        LLCP_TRACE_ERROR3(
+            "llcp_dlc_proc_i_pdu (): Bad N(S):%d >= V(RA):%d + RW(L):%d",
+            send_seq, p_dlcb->sent_ack_seq, p_dlcb->local_rw);
+
+        error_flags |= LLCP_FRMR_S_ERROR_FLAG;
+      }
+    }
+
+    /* check N(R) is in valid range; V(SA) <= N(R) <= V(S) */
+    if ((uint8_t)(rcv_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO +
+            (uint8_t)(p_dlcb->next_tx_seq - rcv_seq) % LLCP_SEQ_MODULO !=
+        (uint8_t)(p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) %
+            LLCP_SEQ_MODULO) {
+      error_flags |= LLCP_FRMR_R_ERROR_FLAG;
+      LLCP_TRACE_ERROR3(
+          "llcp_dlc_proc_i_pdu (): Bad N(R):%d valid range [V(SA):%d, V(S):%d]",
+          rcv_seq, p_dlcb->rcvd_ack_seq, p_dlcb->next_tx_seq);
+    }
+
+    /* if any error is found */
+    if (error_flags) {
+      llcp_util_send_frmr(p_dlcb, error_flags, LLCP_PDU_I_TYPE, *p);
+      llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
+    } else {
+      /* update local sequence variables */
+      p_dlcb->next_rx_seq = (p_dlcb->next_rx_seq + 1) % LLCP_SEQ_MODULO;
+      p_dlcb->rcvd_ack_seq = rcv_seq;
+
+      appended = false;
+
+      /* get last buffer in rx queue */
+      p_last_buf = (NFC_HDR*)GKI_getlast(&p_dlcb->i_rx_q);
+
+      if (p_last_buf) {
+        /* get max length to append at the end of buffer */
+        available_bytes = GKI_get_buf_size(p_last_buf) - NFC_HDR_SIZE -
+                          p_last_buf->offset - p_last_buf->len;
+
+        /* if new UI PDU with length can be attached at the end of buffer */
+        if (available_bytes >= LLCP_PDU_AGF_LEN_SIZE + info_len) {
+          p_dst =
+              (uint8_t*)(p_last_buf + 1) + p_last_buf->offset + p_last_buf->len;
+
+          /* add length of information in I PDU */
+          UINT16_TO_BE_STREAM(p_dst, info_len);
+
+          /* copy information of I PDU */
+          p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
+
+          memcpy(p_dst, p, info_len);
+
+          p_last_buf->len += LLCP_PDU_AGF_LEN_SIZE + info_len;
+
+          if (p_msg) {
+            GKI_freebuf(p_msg);
+            p_msg = NULL;
+          }
+
+          appended = true;
+        }
+      }
+
+      /* if it is not available to append */
+      if (!appended) {
+        /* if it's not from AGF PDU */
+        if (p_msg) {
+          /* add length of information in front of information */
+          p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE -
+              LLCP_PDU_AGF_LEN_SIZE;
+          UINT16_TO_BE_STREAM(p, info_len);
+
+          p_msg->offset +=
+              LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
+          p_msg->len -=
+              LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
+          p_msg->layer_specific = 0;
+        } else {
+          p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
+
+          if (p_msg) {
+            p_dst = (uint8_t*)(p_msg + 1);
+
+            /* add length of information in front of information */
+            UINT16_TO_BE_STREAM(p_dst, info_len);
+
+            p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
+            memcpy(p_dst, p, info_len);
+
+            p_msg->offset = 0;
+            p_msg->len = LLCP_PDU_AGF_LEN_SIZE + info_len;
+            p_msg->layer_specific = 0;
+          } else {
+            LLCP_TRACE_ERROR0("llcp_dlc_proc_i_pdu (): out of buffer");
+          }
+        }
+
+        /* insert I PDU in rx queue */
+        if (p_msg) {
+          GKI_enqueue(&p_dlcb->i_rx_q, p_msg);
+          p_msg = NULL;
+          llcp_cb.total_rx_i_pdu++;
+
+          llcp_util_check_rx_congested_status();
+        }
+      }
+
+      p_dlcb->num_rx_i_pdu++;
+
+      if ((!p_dlcb->local_busy) && (p_dlcb->num_rx_i_pdu == 1)) {
+        /* notify rx data is available so upper layer reads data until queue is
+         * empty */
+        llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_PEER_DATA_IND, NULL);
+      }
+
+      if ((!p_dlcb->is_rx_congested) &&
+          (p_dlcb->num_rx_i_pdu >= p_dlcb->rx_congest_threshold)) {
+        LLCP_TRACE_DEBUG2(
+            "llcp_dlc_proc_i_pdu (): congested num_rx_i_pdu=%d, "
+            "rx_congest_threshold=%d",
+            p_dlcb->num_rx_i_pdu, p_dlcb->rx_congest_threshold);
+
+        /* send RNR */
+        p_dlcb->is_rx_congested = true;
+        p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
+      }
+    }
+  } else {
+    LLCP_TRACE_ERROR2(
+        "llcp_dlc_proc_i_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
+    llcp_util_send_dm(ssap, dsap, LLCP_SAP_DM_REASON_NO_ACTIVE_CONNECTION);
+  }
+
+  if (p_msg) {
+    GKI_freebuf(p_msg);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlc_proc_rr_rnr_pdu
+**
+** Description      Process RR or RNR PDU
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_dlc_proc_rr_rnr_pdu(uint8_t dsap, uint8_t ptype, uint8_t ssap,
+                                     uint16_t length, uint8_t* p_data) {
+  uint8_t rcv_seq, error_flags;
+  tLLCP_DLCB* p_dlcb;
+  bool flush = true;
+  tLLCP_SAP_CBACK_DATA cback_data;
+  bool old_remote_busy;
+
+  LLCP_TRACE_DEBUG0("llcp_dlc_proc_rr_rnr_pdu ()");
+
+  p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, ssap);
+  if (p_dlcb != NULL) {
+    error_flags = 0;
+
+    rcv_seq = LLCP_GET_NR(*p_data);
+
+    if (length != LLCP_PDU_RR_SIZE - LLCP_PDU_HEADER_SIZE) {
+      error_flags |= LLCP_FRMR_W_ERROR_FLAG | LLCP_FRMR_I_ERROR_FLAG;
+    }
+
+    /* check N(R) is in valid range; V(SA) <= N(R) <= V(S) */
+    if ((uint8_t)(rcv_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO +
+            (uint8_t)(p_dlcb->next_tx_seq - rcv_seq) % LLCP_SEQ_MODULO !=
+        (uint8_t)(p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) %
+            LLCP_SEQ_MODULO) {
+      error_flags |= LLCP_FRMR_R_ERROR_FLAG;
+      LLCP_TRACE_ERROR3(
+          "llcp_dlc_proc_rr_rnr_pdu (): Bad N(R):%d valid range [V(SA):%d, "
+          "V(S):%d]",
+          rcv_seq, p_dlcb->rcvd_ack_seq, p_dlcb->next_tx_seq);
+    }
+
+    if (error_flags) {
+      llcp_util_send_frmr(p_dlcb, error_flags, ptype, *p_data);
+      llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
+    } else {
+      p_dlcb->rcvd_ack_seq = rcv_seq;
+
+#if (BT_TRACE_VERBOSE == true)
+      LLCP_TRACE_DEBUG5("LLCP RX - N(S,R):(NA,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
+                        rcv_seq, p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
+                        p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
+#endif
+      old_remote_busy = p_dlcb->remote_busy;
+      if (ptype == LLCP_PDU_RNR_TYPE) {
+        p_dlcb->remote_busy = true;
+        /* if upper layer hasn't get congestion started notification */
+        if ((!old_remote_busy) && (!p_dlcb->is_tx_congested)) {
+          LLCP_TRACE_WARNING3(
+              "llcp_dlc_proc_rr_rnr_pdu (): Data link (SSAP:DSAP=0x%X:0x%X) "
+              "congestion start: i_xmit_q.count=%d",
+              p_dlcb->local_sap, p_dlcb->remote_sap, p_dlcb->i_xmit_q.count);
+
+          cback_data.congest.event = LLCP_SAP_EVT_CONGEST;
+          cback_data.congest.local_sap = p_dlcb->local_sap;
+          cback_data.congest.remote_sap = p_dlcb->remote_sap;
+          cback_data.congest.is_congested = true;
+          cback_data.congest.link_type = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
+
+          (*p_dlcb->p_app_cb->p_app_cback)(&cback_data);
+        }
+      } else {
+        p_dlcb->remote_busy = false;
+        /* if upper layer hasn't get congestion ended notification and data link
+         * is not congested */
+        if ((old_remote_busy) && (!p_dlcb->is_tx_congested)) {
+          LLCP_TRACE_WARNING3(
+              "llcp_dlc_proc_rr_rnr_pdu (): Data link (SSAP:DSAP=0x%X:0x%X) "
+              "congestion end: i_xmit_q.count=%d",
+              p_dlcb->local_sap, p_dlcb->remote_sap, p_dlcb->i_xmit_q.count);
+
+          cback_data.congest.event = LLCP_SAP_EVT_CONGEST;
+          cback_data.congest.local_sap = p_dlcb->local_sap;
+          cback_data.congest.remote_sap = p_dlcb->remote_sap;
+          cback_data.congest.is_congested = false;
+          cback_data.congest.link_type = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
+
+          (*p_dlcb->p_app_cb->p_app_cback)(&cback_data);
+        }
+      }
+
+      /* check flag to send DISC when tx queue is empty */
+      if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_PENDING_DISC) {
+        /* if no pending data and all PDU is acked */
+        if ((p_dlcb->i_xmit_q.count == 0) &&
+            (p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq) &&
+            (p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq)) {
+          p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
+          llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
+        }
+      }
+    }
+  } else {
+    LLCP_TRACE_ERROR2(
+        "llcp_dlc_proc_rr_rnr_pdu (): No data link for SAP (0x%x,0x%x)", dsap,
+        ssap);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlc_proc_rx_pdu
+**
+** Description      Process PDU for data link
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_dlc_proc_rx_pdu(uint8_t dsap, uint8_t ptype, uint8_t ssap,
+                          uint16_t length, uint8_t* p_data) {
+  tLLCP_DLCB* p_dlcb;
+
+  LLCP_TRACE_DEBUG3("llcp_dlc_proc_rx_pdu (): DSAP:0x%x, PTYPE:0x%x, SSAP:0x%x",
+                    dsap, ptype, ssap);
+
+  if (dsap == LLCP_SAP_LM) {
+    LLCP_TRACE_ERROR2(
+        "llcp_dlc_proc_rx_pdu (): Invalid SAP:0x%x for PTYPE:0x%x", dsap,
+        ptype);
+    return;
+  }
+
+  switch (ptype) {
+    case LLCP_PDU_CONNECT_TYPE:
+      llcp_dlc_proc_connect_pdu(dsap, ssap, length, p_data);
+      break;
+
+    case LLCP_PDU_DISC_TYPE:
+      llcp_dlc_proc_disc_pdu(dsap, ssap, length, p_data);
+      break;
+
+    case LLCP_PDU_CC_TYPE:
+      llcp_dlc_proc_cc_pdu(dsap, ssap, length, p_data);
+      break;
+
+    case LLCP_PDU_DM_TYPE:
+      llcp_dlc_proc_dm_pdu(dsap, ssap, length, p_data);
+      break;
+
+    case LLCP_PDU_FRMR_TYPE:
+      p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, ssap);
+      if (p_dlcb) {
+        llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
+      }
+      break;
+
+    case LLCP_PDU_RR_TYPE:
+    case LLCP_PDU_RNR_TYPE:
+      llcp_dlc_proc_rr_rnr_pdu(dsap, ptype, ssap, length, p_data);
+      break;
+
+    default:
+      LLCP_TRACE_ERROR1("llcp_dlc_proc_rx_pdu (): Unexpected PDU type (0x%x)",
+                        ptype);
+
+      p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, ssap);
+      if (p_dlcb) {
+        llcp_util_send_frmr(p_dlcb, LLCP_FRMR_W_ERROR_FLAG, ptype, 0);
+        llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
+      }
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlc_check_to_send_rr_rnr
+**
+** Description      Send RR or RNR if necessary
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_dlc_check_to_send_rr_rnr(void) {
+  uint8_t idx;
+  bool flush = true;
+
+  LLCP_TRACE_DEBUG0("llcp_dlc_check_to_send_rr_rnr ()");
+
+  /*
+  ** DLC doesn't send RR PDU for each received I PDU because multiple I PDUs
+  ** can be aggregated in a received AGF PDU. In this case, this is post
+  ** processing of AGF PDU to send single RR or RNR after processing all I
+  ** PDUs in received AGF if there was no I-PDU to carry N(R).
+  **
+  ** Send RR or RNR if any change of local busy condition or rx congestion
+  ** status, or V(RA) is not V(R).
+  */
+  for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++) {
+    if (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED) {
+      llcp_util_send_rr_rnr(&(llcp_cb.dlcb[idx]));
+
+      /* check flag to send DISC when tx queue is empty */
+      if (llcp_cb.dlcb[idx].flags & LLCP_DATA_LINK_FLAG_PENDING_DISC) {
+        /* if no pending data and all PDU is acked */
+        if ((llcp_cb.dlcb[idx].i_xmit_q.count == 0) &&
+            (llcp_cb.dlcb[idx].next_rx_seq == llcp_cb.dlcb[idx].sent_ack_seq) &&
+            (llcp_cb.dlcb[idx].next_tx_seq == llcp_cb.dlcb[idx].rcvd_ack_seq)) {
+          llcp_cb.dlcb[idx].flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
+          llcp_dlsm_execute(&(llcp_cb.dlcb[idx]),
+                            LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
+        }
+      }
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlc_is_rw_open
+**
+** Description      check if receive window is open in remote
+**
+** Returns          true if remote can receive more data
+**
+*******************************************************************************/
+bool llcp_dlc_is_rw_open(tLLCP_DLCB* p_dlcb) {
+  if ((uint8_t)(p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO <
+      p_dlcb->remote_rw) {
+    return true;
+  } else {
+    LLCP_TRACE_DEBUG3(
+        "llcp_dlc_is_rw_open ():Flow Off, V(S):%d, V(SA):%d, RW(R):%d",
+        p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq, p_dlcb->remote_rw);
+    return false;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlc_get_next_pdu
+**
+** Description      Get a PDU from tx queue of data link
+**
+** Returns          NFC_HDR*
+**
+*******************************************************************************/
+NFC_HDR* llcp_dlc_get_next_pdu(tLLCP_DLCB* p_dlcb) {
+  NFC_HDR* p_msg = NULL;
+  bool flush = true;
+  tLLCP_SAP_CBACK_DATA data;
+
+#if (BT_TRACE_VERBOSE == true)
+  uint8_t send_seq = p_dlcb->next_tx_seq;
+#endif
+
+    /* if there is data to send and remote device can receive it */
+    if (  (p_dlcb->i_xmit_q.count)
+        &&(!p_dlcb->remote_busy)
+        &&(llcp_dlc_is_rw_open (p_dlcb))  )
+    {
+        p_msg = (NFC_HDR *) GKI_dequeue (&p_dlcb->i_xmit_q);
+        llcp_cb.total_tx_i_pdu--;
+        if(p_msg)
+        {
+            if (p_msg->offset >= LLCP_MIN_OFFSET)
+            {
+                /* add LLCP header, DSAP, PTYPE, SSAP, N(S), N(R) and update sent_ack_seq, V(RA) */
+                llcp_util_build_info_pdu (p_dlcb, p_msg);
+
+        p_dlcb->next_tx_seq = (p_dlcb->next_tx_seq + 1) % LLCP_SEQ_MODULO;
+
+#if (BT_TRACE_VERBOSE == true)
+        LLCP_TRACE_DEBUG6("LLCP TX - N(S,R):(%d,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
+                          send_seq, p_dlcb->next_rx_seq, p_dlcb->next_tx_seq,
+                          p_dlcb->rcvd_ack_seq, p_dlcb->next_rx_seq,
+                          p_dlcb->sent_ack_seq);
+#endif
+      } else {
+        LLCP_TRACE_ERROR2(
+            "LLCP - llcp_dlc_get_next_pdu (): offset (%d) must be %d at least",
+            p_msg->offset, LLCP_MIN_OFFSET);
+        GKI_freebuf(p_msg);
+        p_msg = NULL;
+      }
+    }
+  }
+
+  /* if tx queue is empty and all PDU is acknowledged */
+  if ((p_dlcb->i_xmit_q.count == 0) &&
+      (p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq) &&
+      (p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq)) {
+    /* check flag to send DISC */
+    if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_PENDING_DISC) {
+      p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
+      llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
+    }
+
+    /* check flag to notify upper layer */
+    if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE) {
+      p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE;
+
+      data.tx_complete.event = LLCP_SAP_EVT_TX_COMPLETE;
+      data.tx_complete.local_sap = p_dlcb->local_sap;
+      data.tx_complete.remote_sap = p_dlcb->remote_sap;
+
+      (*p_dlcb->p_app_cb->p_app_cback)(&data);
+    }
+  }
+
+  return p_msg;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlc_get_next_pdu_length
+**
+** Description      return length of PDU which is top in tx queue of data link
+**
+** Returns          length of PDU
+**
+*******************************************************************************/
+uint16_t llcp_dlc_get_next_pdu_length(tLLCP_DLCB* p_dlcb) {
+  NFC_HDR* p_msg;
+
+  /* if there is data to send and remote device can receive it */
+  if ((p_dlcb->i_xmit_q.count) && (!p_dlcb->remote_busy) &&
+      (llcp_dlc_is_rw_open(p_dlcb))) {
+    p_msg = (NFC_HDR*)p_dlcb->i_xmit_q.p_first;
+
+    return (p_msg->len + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE);
+  }
+  return 0;
+}
+
+#if (BT_TRACE_VERBOSE == true)
+/*******************************************************************************
+**
+** Function         llcp_dlsm_get_state_name
+**
+** Description      This function returns the state name.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+static char* llcp_dlsm_get_state_name(tLLCP_DLC_STATE state) {
+  switch (state) {
+    case LLCP_DLC_STATE_IDLE:
+      return ("IDLE");
+    case LLCP_DLC_STATE_W4_REMOTE_RESP:
+      return ("W4_REMOTE_RESP");
+    case LLCP_DLC_STATE_W4_LOCAL_RESP:
+      return ("W4_LOCAL_RESP");
+    case LLCP_DLC_STATE_CONNECTED:
+      return ("CONNECTED");
+    case LLCP_DLC_STATE_W4_REMOTE_DM:
+      return ("W4_REMOTE_DM");
+    default:
+      return ("???? UNKNOWN STATE");
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlsm_get_event_name
+**
+** Description      This function returns the event name.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+static char* llcp_dlsm_get_event_name(tLLCP_DLC_EVENT event) {
+  switch (event) {
+    case LLCP_DLC_EVENT_API_CONNECT_REQ:
+      return ("API_CONNECT_REQ");
+    case LLCP_DLC_EVENT_API_CONNECT_CFM:
+      return ("API_CONNECT_CFM");
+    case LLCP_DLC_EVENT_API_CONNECT_REJECT:
+      return ("API_CONNECT_REJECT");
+    case LLCP_DLC_EVENT_PEER_CONNECT_IND:
+      return ("PEER_CONNECT_IND");
+    case LLCP_DLC_EVENT_PEER_CONNECT_CFM:
+      return ("PEER_CONNECT_CFM");
+
+    case LLCP_DLC_EVENT_API_DATA_REQ:
+      return ("API_DATA_REQ");
+    case LLCP_DLC_EVENT_PEER_DATA_IND:
+      return ("PEER_DATA_IND");
+
+    case LLCP_DLC_EVENT_API_DISCONNECT_REQ:
+      return ("API_DISCONNECT_REQ");
+    case LLCP_DLC_EVENT_PEER_DISCONNECT_IND:
+      return ("PEER_DISCONNECT_IND");
+    case LLCP_DLC_EVENT_PEER_DISCONNECT_RESP:
+      return ("PEER_DISCONNECT_RESP");
+
+    case LLCP_DLC_EVENT_FRAME_ERROR:
+      return ("FRAME_ERROR");
+    case LLCP_DLC_EVENT_LINK_ERROR:
+      return ("LINK_ERROR");
+
+    case LLCP_DLC_EVENT_TIMEOUT:
+      return ("TIMEOUT");
+
+    default:
+      return ("???? UNKNOWN EVENT");
+  }
+}
+#endif /* (BT_TRACE_VERBOSE == true) */
diff --git a/src/nfc/llcp/llcp_link.c b/src/nfc/llcp/llcp_link.c
new file mode 100644
index 0000000..e19e630
--- /dev/null
+++ b/src/nfc/llcp/llcp_link.c
@@ -0,0 +1,1713 @@
+/******************************************************************************
+ *
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the LLCP Link Management
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include "gki.h"
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "trace_api.h"
+#include "llcp_int.h"
+#include "llcp_defs.h"
+#include "nfc_int.h"
+#include "nfa_sys.h"
+#include "nfa_dm_int.h"
+
+const uint16_t llcp_link_rwt
+    [15] = /* RWT = (302us)*2**WT; 302us = 256*16/fc; fc = 13.56MHz */
+    {
+     1,    /* WT=0,     302us */
+     1,    /* WT=1,     604us */
+     2,    /* WT=2,    1208us */
+     3,    /* WT=3,     2.4ms */
+     5,    /* WT=4,     4.8ms */
+     10,   /* WT=5,     9.7ms */
+     20,   /* WT=6,    19.3ms */
+     39,   /* WT=7,    38.7ms */
+     78,   /* WT=8,    77.3ms */
+     155,  /* WT=9,   154.6ms */
+     310,  /* WT=10,  309.2ms */
+     619,  /* WT=11,  618.5ms */
+     1237, /* WT=12, 1237.0ms */
+     2474, /* WT=13, 2474.0ms */
+     4948, /* WT=14, 4948.0ms */
+};
+
+static bool llcp_link_parse_gen_bytes(uint8_t gen_bytes_len,
+                                      uint8_t* p_gen_bytes);
+static bool llcp_link_version_agreement(void);
+
+static void llcp_link_send_SYMM(void);
+static void llcp_link_update_status(bool is_activated);
+static void llcp_link_check_congestion(void);
+static void llcp_link_check_uncongested(void);
+static void llcp_link_proc_ui_pdu(uint8_t local_sap, uint8_t remote_sap,
+                                  uint16_t ui_pdu_length, uint8_t* p_ui_pdu,
+                                  NFC_HDR* p_msg);
+static void llcp_link_proc_agf_pdu(NFC_HDR* p_msg);
+static void llcp_link_proc_rx_pdu(uint8_t dsap, uint8_t ptype, uint8_t ssap,
+                                  NFC_HDR* p_msg);
+static void llcp_link_proc_rx_data(NFC_HDR* p_msg);
+
+static NFC_HDR* llcp_link_get_next_pdu(bool length_only,
+                                       uint16_t* p_next_pdu_length);
+static NFC_HDR* llcp_link_build_next_pdu(NFC_HDR* p_agf);
+static void llcp_link_send_to_lower(NFC_HDR* p_msg);
+
+#if (LLCP_TEST_INCLUDED == true) /* this is for LLCP testing */
+extern tLLCP_TEST_PARAMS llcp_test_params;
+#endif
+
+#if (NXP_EXTNS == TRUE)
+extern unsigned char appl_dta_mode_flag;
+#endif
+
+/* debug functions type */
+#if (BT_TRACE_VERBOSE == true)
+static char* llcp_pdu_type(uint8_t ptype);
+#endif
+
+/*******************************************************************************
+**
+** Function         llcp_link_start_inactivity_timer
+**
+** Description      This function start LLCP link inactivity timer.
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_link_start_inactivity_timer(void) {
+  if ((llcp_cb.lcb.inact_timer.in_use == false) &&
+      (llcp_cb.lcb.inact_timeout > 0)) {
+    LLCP_TRACE_DEBUG1("Start inactivity_timer: %d ms",
+                      llcp_cb.lcb.inact_timeout);
+
+    nfc_start_quick_timer(&llcp_cb.lcb.inact_timer, NFC_TTYPE_LLCP_LINK_INACT,
+                          ((uint32_t)llcp_cb.lcb.inact_timeout) *
+                              QUICK_TIMER_TICKS_PER_SEC / 1000);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_stop_inactivity_timer
+**
+** Description      This function stop LLCP link inactivity timer.
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_link_stop_inactivity_timer(void) {
+  if (llcp_cb.lcb.inact_timer.in_use) {
+    LLCP_TRACE_DEBUG0("Stop inactivity_timer");
+
+    nfc_stop_quick_timer(&llcp_cb.lcb.inact_timer);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_start_link_timer
+**
+** Description      This function starts LLCP link timer (LTO or delay response)
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_link_start_link_timer(void) {
+  if (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT) {
+    /* wait for application layer sending data */
+    nfc_start_quick_timer(
+        &llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER,
+        (((uint32_t)llcp_cb.lcb.symm_delay) * QUICK_TIMER_TICKS_PER_SEC) /
+            1000);
+  } else {
+    /* wait for data to receive from remote */
+    nfc_start_quick_timer(
+        &llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER,
+        ((uint32_t)llcp_cb.lcb.peer_lto) * QUICK_TIMER_TICKS_PER_SEC / 1000);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_stop_link_timer
+**
+** Description      This function stop LLCP link timer (LTO or delay response).
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_link_stop_link_timer(void) {
+  nfc_stop_quick_timer(&llcp_cb.lcb.timer);
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_activate
+**
+** Description      Activate LLCP link
+**
+** Returns          tLLCP_STATUS
+**
+*******************************************************************************/
+tLLCP_STATUS llcp_link_activate(tLLCP_ACTIVATE_CONFIG* p_config) {
+  LLCP_TRACE_DEBUG0("llcp_link_activate ()");
+
+  /* At this point, MAC link activation procedure has been successfully
+   * completed */
+
+  /* The Length Reduction values LRi and LRt MUST be 11b. (254bytes) */
+  if (p_config->max_payload_size != LLCP_NCI_MAX_PAYL_SIZE) {
+    LLCP_TRACE_WARNING2(
+        "llcp_link_activate (): max payload size (%d) must be %d bytes",
+        p_config->max_payload_size, LLCP_NCI_MAX_PAYL_SIZE);
+  }
+
+  /* Processing the parametes that have been received with the MAC link
+   * activation */
+  if (llcp_link_parse_gen_bytes(p_config->gen_bytes_len,
+                                p_config->p_gen_bytes) == false) {
+    LLCP_TRACE_ERROR0("llcp_link_activate (): Failed to parse general bytes");
+#if (NXP_EXTNS == TRUE)
+    /*For LLCP DTA test, In case of bad magic bytes normal p2p communication is
+     * expected
+     * In case of wrong magic bytes in ATR_REQ LLC layer will be disconnected
+     * but P2P connection
+     * is expected to be in connected state. So, non LLC PDU is expected.
+     * Below changes is to send PDU after disconnect of LLCP PDU.
+     * fix for TC_MAC_TAR_BI_01 LLCP test case*/
+    if ((appl_dta_mode_flag == 1) && (p_config->is_initiator == false)) {
+      NFC_HDR* p_msg;
+      uint8_t* p;
+      p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
+
+      if (p_msg) {
+        /*LLCP test scenario requires non LLC PDU to be sent in case of wrong
+          magic bytes.
+          So sending NFC-DEP pdu with size 1 (0x00)*/
+        p_msg->len = 1;
+        p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+        p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+        NFC_SendData(NFC_RF_CONN_ID, p_msg);
+      }
+    }
+#endif
+    (*llcp_cb.lcb.p_link_cback)(LLCP_LINK_ACTIVATION_FAILED_EVT,
+                                LLCP_LINK_BAD_GEN_BYTES);
+
+    if (p_config->is_initiator == false) {
+      /* repond to any incoming PDU with invalid LLCP PDU */
+      llcp_cb.lcb.link_state = LLCP_LINK_STATE_ACTIVATION_FAILED;
+      NFC_SetStaticRfCback(llcp_link_connection_cback);
+    }
+    return LLCP_STATUS_FAIL;
+  }
+
+  /*
+  ** For the Target device, the scaled value of RWT MUST be less than or equal
+  ** to the scaled value of the LLC Link Timeout (LTO).
+  */
+  if ((p_config->is_initiator) &&
+      (llcp_link_rwt[p_config->waiting_time] > llcp_cb.lcb.peer_lto)) {
+    LLCP_TRACE_WARNING3(
+        "llcp_link_activate (): WT (%d, %dms) must be less than or equal to "
+        "LTO (%dms)",
+        p_config->waiting_time, llcp_link_rwt[p_config->waiting_time],
+        llcp_cb.lcb.peer_lto);
+  }
+#if (NXP_EXTNS == TRUE)
+  /*For DTA mode Peer LTO Should not include TX RX Delay, Just llcp deactivate
+   * after Peer LTO time */
+  if (!appl_dta_mode_flag) {
+#endif
+    /* extend LTO as much as internally required processing time and propagation
+     * delays */
+    llcp_cb.lcb.peer_lto += LLCP_INTERNAL_TX_DELAY + LLCP_INTERNAL_RX_DELAY;
+#if (NXP_EXTNS == TRUE)
+  }
+#endif
+  /* LLCP version number agreement */
+  if (llcp_link_version_agreement() == false) {
+    LLCP_TRACE_ERROR0("llcp_link_activate (): Failed to agree version");
+    (*llcp_cb.lcb.p_link_cback)(LLCP_LINK_ACTIVATION_FAILED_EVT,
+                                LLCP_LINK_VERSION_FAILED);
+
+    if (p_config->is_initiator == false) {
+      /* repond to any incoming PDU with invalid LLCP PDU */
+      llcp_cb.lcb.link_state = LLCP_LINK_STATE_ACTIVATION_FAILED;
+      NFC_SetStaticRfCback(llcp_link_connection_cback);
+    }
+    return LLCP_STATUS_FAIL;
+  }
+  llcp_cb.lcb.received_first_packet = false;
+  llcp_cb.lcb.is_initiator = p_config->is_initiator;
+
+  /* reset internal flags */
+  llcp_cb.lcb.flags = 0x00;
+
+  /* set tx MIU to MIN (MIU of local LLCP, MIU of peer LLCP) */
+
+  if (llcp_cb.lcb.local_link_miu >= llcp_cb.lcb.peer_miu)
+    llcp_cb.lcb.effective_miu = llcp_cb.lcb.peer_miu;
+  else
+    llcp_cb.lcb.effective_miu = llcp_cb.lcb.local_link_miu;
+
+  /*
+  ** When entering the normal operation phase, LLCP shall initialize the
+  ** symmetry procedure.
+  */
+  if (llcp_cb.lcb.is_initiator) {
+    LLCP_TRACE_DEBUG0("llcp_link_activate (): Connected as Initiator");
+
+    llcp_cb.lcb.inact_timeout = llcp_cb.lcb.inact_timeout_init;
+    llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_LOCAL_XMIT_NEXT;
+
+    if (llcp_cb.lcb.delay_first_pdu_timeout > 0) {
+      /* give a chance to upper layer to send PDU if need */
+      nfc_start_quick_timer(&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_DELAY_FIRST_PDU,
+                            (((uint32_t)llcp_cb.lcb.delay_first_pdu_timeout) *
+                             QUICK_TIMER_TICKS_PER_SEC) /
+                                1000);
+    } else {
+      llcp_link_send_SYMM();
+    }
+  } else {
+    LLCP_TRACE_DEBUG0("llcp_link_activate (): Connected as Target");
+    llcp_cb.lcb.inact_timeout = llcp_cb.lcb.inact_timeout_target;
+    llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_REMOTE_XMIT_NEXT;
+
+    /* wait for data to receive from remote */
+    llcp_link_start_link_timer();
+  }
+
+  /*
+  ** Set state to LLCP_LINK_STATE_ACTIVATED and notify activation before set
+  ** data callback because LLCP PDU could be in NCI queue.
+  */
+  llcp_cb.lcb.link_state = LLCP_LINK_STATE_ACTIVATED;
+
+  /* LLCP Link Activation completed */
+  (*llcp_cb.lcb.p_link_cback)(LLCP_LINK_ACTIVATION_COMPLETE_EVT,
+                              LLCP_LINK_SUCCESS);
+
+  /* Update link status to service layer */
+  llcp_link_update_status(true);
+
+  NFC_SetStaticRfCback(llcp_link_connection_cback);
+
+  return (LLCP_STATUS_SUCCESS);
+}
+
+/*******************************************************************************
+**
+** Function         llcp_deactivate_cleanup
+**
+** Description      Clean up for link deactivation
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_deactivate_cleanup(uint8_t reason) {
+  /* report SDP failure for any pending request */
+  llcp_sdp_proc_deactivation();
+
+  /* Update link status to service layer */
+  llcp_link_update_status(false);
+
+  /* We had sent out DISC */
+  llcp_cb.lcb.link_state = LLCP_LINK_STATE_DEACTIVATED;
+
+  llcp_link_stop_link_timer();
+
+  /* stop inactivity timer */
+  llcp_link_stop_inactivity_timer();
+
+  /* Let upper layer deactivate local link */
+  (*llcp_cb.lcb.p_link_cback)(LLCP_LINK_DEACTIVATED_EVT, reason);
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_process_link_timeout
+**
+** Description      Process timeout events for LTO, SYMM and deactivating
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_link_process_link_timeout(void) {
+  if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED) {
+    if ((llcp_cb.lcb.symm_delay > 0) &&
+        (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT)) {
+      /* upper layer doesn't have anything to send */
+      LLCP_TRACE_DEBUG0(
+          "llcp_link_process_link_timeout (): LEVT_TIMEOUT in state of "
+          "LLCP_LINK_SYMM_LOCAL_XMIT_NEXT");
+      llcp_link_send_SYMM();
+
+      /* wait for data to receive from remote */
+      llcp_link_start_link_timer();
+
+      /* start inactivity timer */
+      if (llcp_cb.num_data_link_connection == 0) {
+        llcp_link_start_inactivity_timer();
+      }
+    } else {
+      LLCP_TRACE_ERROR0(
+          "llcp_link_process_link_timeout (): LEVT_TIMEOUT in state of "
+          "LLCP_LINK_SYMM_REMOTE_XMIT_NEXT");
+      llcp_link_deactivate(LLCP_LINK_TIMEOUT);
+    }
+  } else if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING) {
+    llcp_deactivate_cleanup(llcp_cb.lcb.link_deact_reason);
+
+    NFC_SetStaticRfCback(NULL);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_deactivate
+**
+** Description      Deactivate LLCP link
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_link_deactivate(uint8_t reason) {
+  uint8_t local_sap, idx;
+  tLLCP_DLCB* p_dlcb;
+  tLLCP_APP_CB* p_app_cb;
+
+  LLCP_TRACE_DEBUG1("llcp_link_deactivate () reason = 0x%x", reason);
+
+  /* Release any held buffers in signaling PDU queue */
+  while (llcp_cb.lcb.sig_xmit_q.p_first)
+    GKI_freebuf(GKI_dequeue(&llcp_cb.lcb.sig_xmit_q));
+
+  /* Release any held buffers in UI PDU queue */
+  for (local_sap = LLCP_SAP_SDP + 1; local_sap < LLCP_NUM_SAPS; local_sap++) {
+    p_app_cb = llcp_util_get_app_cb(local_sap);
+
+    if ((p_app_cb) && (p_app_cb->p_app_cback)) {
+      while (p_app_cb->ui_xmit_q.p_first)
+        GKI_freebuf(GKI_dequeue(&p_app_cb->ui_xmit_q));
+
+      p_app_cb->is_ui_tx_congested = false;
+
+      while (p_app_cb->ui_rx_q.p_first)
+        GKI_freebuf(GKI_dequeue(&p_app_cb->ui_rx_q));
+    }
+  }
+
+  llcp_cb.total_tx_ui_pdu = 0;
+  llcp_cb.total_rx_ui_pdu = 0;
+
+  /* Notify all of data link */
+  for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++) {
+    if (llcp_cb.dlcb[idx].state != LLCP_DLC_STATE_IDLE) {
+      p_dlcb = &(llcp_cb.dlcb[idx]);
+
+      llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_LINK_ERROR, NULL);
+    }
+  }
+  llcp_cb.total_tx_i_pdu = 0;
+  llcp_cb.total_rx_i_pdu = 0;
+
+  llcp_cb.overall_tx_congested = false;
+  llcp_cb.overall_rx_congested = false;
+  /* As per the LLCP test specification v1.2.00 for test case TC_LLC_TAR_BV_04
+   * the receiving LLC shall commence sending an LLC PDU to the remote
+   * LLC. So, after IUT receiving DISC PDU from LT(remote device), IUT shall
+   * send DISC PDU to LT.
+     * appl_dta_mode_flag condition is added to fulfill above requirement.
+     * Only in CR8, the IUT shall acknoweledge with SYMM for DISC PDU.
+     * For other CRx, send DISC PDU.
+     */
+
+  if ((reason == LLCP_LINK_FRAME_ERROR) ||
+      (reason == LLCP_LINK_LOCAL_INITIATED) ||
+      ((appl_dta_mode_flag) && (reason == LLCP_LINK_REMOTE_INITIATED) &&
+       (llcp_cb.lcb.is_initiator == false) &&
+       ((nfa_dm_cb.eDtaMode & 0xF0) != NFA_DTA_CR8)))
+  {
+    /* get rid of the data pending in NFC tx queue, so DISC PDU can be sent ASAP
+     */
+    NFC_FlushData(NFC_RF_CONN_ID);
+
+    llcp_util_send_disc(LLCP_SAP_LM, LLCP_SAP_LM);
+
+    /* Wait until DISC is sent to peer */
+    LLCP_TRACE_DEBUG0(
+        "llcp_link_deactivate (): Wait until DISC is sent to peer");
+
+    llcp_cb.lcb.link_state = LLCP_LINK_STATE_DEACTIVATING;
+
+    if (llcp_cb.lcb.sig_xmit_q.count == 0) {
+      /* if DISC is sent to NFCC, wait for short period for NFCC to send it to
+       * peer */
+      nfc_start_quick_timer(&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER,
+                            ((uint32_t)50) * QUICK_TIMER_TICKS_PER_SEC / 1000);
+    }
+
+    llcp_cb.lcb.link_deact_reason = reason;
+    return;
+  } else if ((reason == LLCP_LINK_REMOTE_INITIATED) &&
+             (!llcp_cb.lcb.is_initiator)) {
+    /* if received DISC to deactivate LLCP link as target role, send SYMM PDU */
+    llcp_link_send_SYMM();
+  } else /*  for link timeout and interface error */
+  {
+    /* if got RF link loss receiving no LLC PDU from peer */
+    if ((reason == LLCP_LINK_RF_LINK_LOSS_ERR) &&
+        (!(llcp_cb.lcb.flags & LLCP_LINK_FLAGS_RX_ANY_LLC_PDU))) {
+      reason = LLCP_LINK_RF_LINK_LOSS_NO_RX_LLC;
+    }
+
+    NFC_FlushData(NFC_RF_CONN_ID);
+  }
+  llcp_deactivate_cleanup(reason);
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_parse_gen_bytes
+**
+** Description      Check LLCP magic number and get parameters in general bytes
+**
+** Returns          true if success
+**
+*******************************************************************************/
+static bool llcp_link_parse_gen_bytes(uint8_t gen_bytes_len,
+                                      uint8_t* p_gen_bytes) {
+  uint8_t* p = p_gen_bytes + LLCP_MAGIC_NUMBER_LEN;
+  uint8_t length = gen_bytes_len - LLCP_MAGIC_NUMBER_LEN;
+
+  if ((gen_bytes_len >= LLCP_MAGIC_NUMBER_LEN) &&
+      (*(p_gen_bytes) == LLCP_MAGIC_NUMBER_BYTE0) &&
+      (*(p_gen_bytes + 1) == LLCP_MAGIC_NUMBER_BYTE1) &&
+      (*(p_gen_bytes + 2) == LLCP_MAGIC_NUMBER_BYTE2)) {
+    /* in case peer didn't include these */
+    llcp_cb.lcb.peer_miu = LLCP_DEFAULT_MIU;
+    llcp_cb.lcb.peer_lto = LLCP_DEFAULT_LTO_IN_MS;
+
+    return (llcp_util_parse_link_params(length, p));
+  } else /* if this is not LLCP */
+  {
+    return (false);
+  }
+
+  return (true);
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_version_agreement
+**
+** Description      LLCP version number agreement
+**
+** Returns          true if success
+**
+*******************************************************************************/
+static bool llcp_link_version_agreement(void) {
+  uint8_t peer_major_version, peer_minor_version;
+
+  peer_major_version = LLCP_GET_MAJOR_VERSION(llcp_cb.lcb.peer_version);
+  peer_minor_version = LLCP_GET_MINOR_VERSION(llcp_cb.lcb.peer_version);
+
+  if (peer_major_version < LLCP_MIN_MAJOR_VERSION) {
+    LLCP_TRACE_ERROR1(
+        "llcp_link_version_agreement(): unsupported peer version number. Peer "
+        "Major Version:%d",
+        peer_major_version);
+    return false;
+  } else {
+    if (peer_major_version == LLCP_VERSION_MAJOR) {
+      llcp_cb.lcb.agreed_major_version = LLCP_VERSION_MAJOR;
+      if (peer_minor_version >= LLCP_VERSION_MINOR) {
+        llcp_cb.lcb.agreed_minor_version = LLCP_VERSION_MINOR;
+      } else {
+        llcp_cb.lcb.agreed_minor_version = peer_minor_version;
+      }
+    } else if (peer_major_version < LLCP_VERSION_MAJOR) {
+      /* so far we can support backward compatibility */
+      llcp_cb.lcb.agreed_major_version = peer_major_version;
+      llcp_cb.lcb.agreed_minor_version = peer_minor_version;
+    } else {
+      /* let peer (higher major version) decide it */
+      llcp_cb.lcb.agreed_major_version = LLCP_VERSION_MAJOR;
+      llcp_cb.lcb.agreed_minor_version = LLCP_VERSION_MINOR;
+    }
+
+    LLCP_TRACE_DEBUG6(
+        "local version:%d.%d, remote version:%d.%d, agreed version:%d.%d",
+        LLCP_VERSION_MAJOR, LLCP_VERSION_MINOR, peer_major_version,
+        peer_minor_version, llcp_cb.lcb.agreed_major_version,
+        llcp_cb.lcb.agreed_minor_version);
+
+    return (true);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_update_status
+**
+** Description      Notify all of service layer client link status change
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_link_update_status(bool is_activated) {
+  tLLCP_SAP_CBACK_DATA data;
+  tLLCP_APP_CB* p_app_cb;
+  uint8_t sap;
+
+  data.link_status.event = LLCP_SAP_EVT_LINK_STATUS;
+  data.link_status.is_activated = is_activated;
+  data.link_status.is_initiator = llcp_cb.lcb.is_initiator;
+
+  /* notify all SAP so they can create connection while link is activated */
+  for (sap = LLCP_SAP_SDP + 1; sap < LLCP_NUM_SAPS; sap++) {
+    p_app_cb = llcp_util_get_app_cb(sap);
+
+    if ((p_app_cb) && (p_app_cb->p_app_cback)) {
+      data.link_status.local_sap = sap;
+      p_app_cb->p_app_cback(&data);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_check_congestion
+**
+** Description      Check overall congestion status
+**                  Notify to all of upper layer if congested
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_link_check_congestion(void) {
+  tLLCP_SAP_CBACK_DATA data;
+  tLLCP_APP_CB* p_app_cb;
+  uint8_t sap, idx;
+
+  if (llcp_cb.overall_tx_congested) {
+    /* already congested so no need to check again */
+    return;
+  }
+
+  if (llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu >=
+      llcp_cb.max_num_tx_buff) {
+    /* overall buffer usage is high */
+    llcp_cb.overall_tx_congested = true;
+
+    LLCP_TRACE_WARNING2(
+        "overall tx congestion start: total_tx_ui_pdu=%d, total_tx_i_pdu=%d",
+        llcp_cb.total_tx_ui_pdu, llcp_cb.total_tx_i_pdu);
+
+    data.congest.event = LLCP_SAP_EVT_CONGEST;
+    data.congest.is_congested = true;
+
+    /* notify logical data link congestion status */
+    data.congest.remote_sap = LLCP_INVALID_SAP;
+    data.congest.link_type = LLCP_LINK_TYPE_LOGICAL_DATA_LINK;
+
+    for (sap = LLCP_SAP_SDP + 1; sap < LLCP_NUM_SAPS; sap++) {
+      p_app_cb = llcp_util_get_app_cb(sap);
+
+      if ((p_app_cb) && (p_app_cb->p_app_cback) &&
+          (p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)) {
+        /* if already congested then no need to notify again */
+        if (!p_app_cb->is_ui_tx_congested) {
+          p_app_cb->is_ui_tx_congested = true;
+
+          LLCP_TRACE_WARNING2(
+              "Logical link (SAP=0x%X) congestion start: count=%d", sap,
+              p_app_cb->ui_xmit_q.count);
+
+          data.congest.local_sap = sap;
+          p_app_cb->p_app_cback(&data);
+        }
+      }
+    }
+
+    /* notify data link connection congestion status */
+    data.congest.link_type = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
+
+    for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++) {
+      if ((llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED) &&
+          (llcp_cb.dlcb[idx].remote_busy == false) &&
+          (llcp_cb.dlcb[idx].is_tx_congested == false)) {
+        llcp_cb.dlcb[idx].is_tx_congested = true;
+
+        LLCP_TRACE_WARNING3(
+            "Data link (SSAP:DSAP=0x%X:0x%X) congestion start: count=%d",
+            llcp_cb.dlcb[idx].local_sap, llcp_cb.dlcb[idx].remote_sap,
+            llcp_cb.dlcb[idx].i_xmit_q.count);
+
+        data.congest.local_sap = llcp_cb.dlcb[idx].local_sap;
+        data.congest.remote_sap = llcp_cb.dlcb[idx].remote_sap;
+
+        (*llcp_cb.dlcb[idx].p_app_cb->p_app_cback)(&data);
+      }
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_check_uncongested
+**
+** Description      Check overall congestion status, logical data link and
+**                  data link connection congestion status
+**                  Notify to each upper layer if uncongested
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_link_check_uncongested(void) {
+  tLLCP_SAP_CBACK_DATA data;
+  tLLCP_APP_CB* p_app_cb;
+  uint8_t xx, sap, idx;
+
+  if (llcp_cb.overall_tx_congested) {
+    if (llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu <=
+        llcp_cb.max_num_tx_buff / 2) {
+      /* overall congestion is cleared */
+      llcp_cb.overall_tx_congested = false;
+
+      LLCP_TRACE_WARNING2(
+          "overall tx congestion end: total_tx_ui_pdu=%d, total_tx_i_pdu=%d",
+          llcp_cb.total_tx_ui_pdu, llcp_cb.total_tx_i_pdu);
+    } else {
+      /* wait until more data packets are sent out */
+      return;
+    }
+  }
+
+  data.congest.event = LLCP_SAP_EVT_CONGEST;
+  data.congest.is_congested = false;
+
+  /* if total number of UI PDU is below threshold */
+  if (llcp_cb.total_tx_ui_pdu < llcp_cb.max_num_ll_tx_buff) {
+    /* check and notify logical data link congestion status */
+    data.congest.remote_sap = LLCP_INVALID_SAP;
+    data.congest.link_type = LLCP_LINK_TYPE_LOGICAL_DATA_LINK;
+
+    /*
+    ** start point of uncongested status notification is in round robin
+    ** so each logical data link has equal chance of transmitting.
+    */
+    sap = llcp_cb.ll_tx_uncongest_ntf_start_sap;
+
+    for (xx = LLCP_SAP_SDP + 1; xx < LLCP_NUM_SAPS; xx++) {
+      /* no logical data link on LM and SDP */
+      if (sap > LLCP_SAP_SDP) {
+        p_app_cb = llcp_util_get_app_cb(sap);
+
+        if ((p_app_cb) && (p_app_cb->p_app_cback) &&
+            (p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) &&
+            (p_app_cb->is_ui_tx_congested) &&
+            (p_app_cb->ui_xmit_q.count <= llcp_cb.ll_tx_congest_end)) {
+          /* if it was congested but now tx queue count is below threshold */
+          p_app_cb->is_ui_tx_congested = false;
+
+          LLCP_TRACE_DEBUG2("Logical link (SAP=0x%X) congestion end: count=%d",
+                            sap, p_app_cb->ui_xmit_q.count);
+
+          data.congest.local_sap = sap;
+          p_app_cb->p_app_cback(&data);
+        }
+      }
+
+      sap = (sap + 1) % LLCP_NUM_SAPS;
+    }
+
+    /* move start point for next logical data link */
+    for (xx = 0; xx < LLCP_NUM_SAPS; xx++) {
+      sap = (llcp_cb.ll_tx_uncongest_ntf_start_sap + 1) % LLCP_NUM_SAPS;
+
+      if (sap > LLCP_SAP_SDP) {
+        p_app_cb = llcp_util_get_app_cb(sap);
+
+        if ((p_app_cb) && (p_app_cb->p_app_cback) &&
+            (p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)) {
+          llcp_cb.ll_tx_uncongest_ntf_start_sap = sap;
+          break;
+        }
+      }
+    }
+  }
+
+  /* notify data link connection congestion status */
+  data.congest.link_type = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
+
+  /*
+  ** start point of uncongested status notification is in round robin
+  ** so each data link connection has equal chance of transmitting.
+  */
+  idx = llcp_cb.dl_tx_uncongest_ntf_start_idx;
+
+  for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++) {
+    /* if it was congested but now tx queue is below threshold (receiving
+     * window) */
+    if ((llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED) &&
+        (llcp_cb.dlcb[idx].is_tx_congested) &&
+        (llcp_cb.dlcb[idx].i_xmit_q.count <= llcp_cb.dlcb[idx].remote_rw / 2)) {
+      llcp_cb.dlcb[idx].is_tx_congested = false;
+
+      if (llcp_cb.dlcb[idx].remote_busy == false) {
+        LLCP_TRACE_DEBUG3(
+            "Data link (SSAP:DSAP=0x%X:0x%X) congestion end: count=%d",
+            llcp_cb.dlcb[idx].local_sap, llcp_cb.dlcb[idx].remote_sap,
+            llcp_cb.dlcb[idx].i_xmit_q.count);
+
+        data.congest.local_sap = llcp_cb.dlcb[idx].local_sap;
+        data.congest.remote_sap = llcp_cb.dlcb[idx].remote_sap;
+
+        (*llcp_cb.dlcb[idx].p_app_cb->p_app_cback)(&data);
+      }
+    }
+    idx = (idx + 1) % LLCP_MAX_DATA_LINK;
+  }
+
+  /* move start point for next data link connection */
+  for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++) {
+    idx = (llcp_cb.dl_tx_uncongest_ntf_start_idx + 1) % LLCP_MAX_DATA_LINK;
+    if (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED) {
+      llcp_cb.dl_tx_uncongest_ntf_start_idx = idx;
+      break;
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_send_SYMM
+**
+** Description      Send SYMM PDU
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_link_send_SYMM(void) {
+  NFC_HDR* p_msg;
+  uint8_t* p;
+  p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
+
+  if (p_msg) {
+    p_msg->len = LLCP_PDU_SYMM_SIZE;
+    p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+    p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+    UINT16_TO_BE_STREAM(
+        p, LLCP_GET_PDU_HEADER(LLCP_SAP_LM, LLCP_PDU_SYMM_TYPE, LLCP_SAP_LM));
+
+    llcp_link_send_to_lower(p_msg);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_send_invalid_pdu
+**
+** Description      Send invalid LLC PDU in LLCP_LINK_STATE_ACTIVATION_FAILED
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_link_send_invalid_pdu(void) {
+  NFC_HDR* p_msg;
+  uint8_t* p;
+
+  p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
+
+  if (p_msg) {
+    /* send one byte of 0x00 as invalid LLC PDU */
+    p_msg->len = 1;
+    p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+    p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+    *p = 0x00;
+
+    NFC_SendData(NFC_RF_CONN_ID, p_msg);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_check_send_data
+**
+** Description      Send PDU to peer
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_link_check_send_data(void) {
+  NFC_HDR* p_pdu;
+  /* don't re-enter while processing to prevent out of sequence */
+  if (llcp_cb.lcb.is_sending_data)
+    return;
+  else
+    llcp_cb.lcb.is_sending_data = true;
+
+  /*
+  ** check overall congestion due to high usage of buffer pool
+  ** if congested then notify all of upper layers not to send any more data
+  */
+  llcp_link_check_congestion();
+
+  if (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT ||
+      (appl_dta_mode_flag &&
+       llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING)) {
+    LLCP_TRACE_DEBUG0(
+        "llcp_link_check_send_data () in state of "
+        "LLCP_LINK_SYMM_LOCAL_XMIT_NEXT");
+
+    p_pdu = llcp_link_build_next_pdu(NULL);
+
+    /*
+    ** For data link connection,
+    ** V(RA) was updated and N(R) was set to V(RA), if I PDU was added in
+    ** this transmission. If there was no I PDU to carry V(RA) and V(RA) is
+    ** not V(R) and it's not congested, then RR PDU will be sent.
+    ** If there was no I PDU to carry V(RA) and V(RA) is not V(R) and it's
+    ** congested, then RNR PDU will be sent.
+    ** If local busy state has been changed then RR or RNR PDU may be sent.
+    */
+    llcp_dlc_check_to_send_rr_rnr();
+
+    /* add RR/RNR PDU to be sent if any */
+    p_pdu = llcp_link_build_next_pdu(p_pdu);
+
+    if (p_pdu != NULL) {
+      llcp_link_send_to_lower(p_pdu);
+
+      /* stop inactivity timer */
+      llcp_link_stop_inactivity_timer();
+
+      /* check congestion status after sending out some data */
+      llcp_link_check_uncongested();
+    } else {
+      /* There is no data to send, so send SYMM */
+      if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED) {
+        if (llcp_cb.lcb.symm_delay > 0) {
+          /* wait for application layer sending data */
+          llcp_link_start_link_timer();
+          llcp_cb.lcb.is_sending_data = false;
+          return;
+        } else {
+          llcp_link_send_SYMM();
+
+          /* start inactivity timer */
+          if (llcp_cb.num_data_link_connection == 0) {
+            llcp_link_start_inactivity_timer();
+          }
+        }
+      } else {
+        llcp_cb.lcb.is_sending_data = false;
+        return;
+      }
+    }
+
+    if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING) {
+      /* wait for short period for NFCC to send DISC */
+      nfc_start_quick_timer(&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER,
+                            ((uint32_t)50) * QUICK_TIMER_TICKS_PER_SEC / 1000);
+    } else {
+      /* wait for data to receive from remote */
+      llcp_link_start_link_timer();
+    }
+  }
+
+  llcp_cb.lcb.is_sending_data = false;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_proc_ui_pdu
+**
+** Description      Process UI PDU from peer device
+**
+** Returns          None
+**
+*******************************************************************************/
+static void llcp_link_proc_ui_pdu(uint8_t local_sap, uint8_t remote_sap,
+                                  uint16_t ui_pdu_length, uint8_t* p_ui_pdu,
+                                  NFC_HDR* p_msg) {
+  bool appended;
+  NFC_HDR* p_last_buf;
+  uint16_t available_bytes;
+  uint8_t* p_dst;
+  tLLCP_APP_CB* p_app_cb;
+  tLLCP_SAP_CBACK_DATA data;
+  tLLCP_DLCB* p_dlcb;
+
+  p_app_cb = llcp_util_get_app_cb(local_sap);
+  /*if UI PDU sent to SAP with data link connection*/
+  p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap);
+  if (p_dlcb) {
+    llcp_util_send_frmr(p_dlcb, LLCP_FRMR_W_ERROR_FLAG, LLCP_PDU_UI_TYPE, 0);
+    llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
+    if (p_msg) {
+      GKI_freebuf(p_msg);
+    }
+    return;
+  }
+
+  /* if application is registered and expecting UI PDU on logical data link */
+  if ((p_app_cb) && (p_app_cb->p_app_cback) &&
+      (p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)) {
+    LLCP_TRACE_DEBUG2(
+        "llcp_link_proc_ui_pdu () Local SAP:0x%x, Remote SAP:0x%x", local_sap,
+        remote_sap);
+
+    /* if this is not from AGF PDU */
+    if (p_msg) {
+      ui_pdu_length = p_msg->len; /* including LLCP header */
+      p_ui_pdu = (uint8_t*)(p_msg + 1) + p_msg->offset;
+    }
+
+    appended = false;
+
+    /* get last buffer in rx queue */
+    p_last_buf = (NFC_HDR*)GKI_getlast(&p_app_cb->ui_rx_q);
+
+    if ((p_last_buf) && (p_ui_pdu != NULL)) {
+      /* get max length to append at the end of buffer */
+      available_bytes = GKI_get_buf_size(p_last_buf) - NFC_HDR_SIZE -
+                        p_last_buf->offset - p_last_buf->len;
+
+      /* if new UI PDU with length can be attached at the end of buffer */
+      if (available_bytes >= LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length) {
+        p_dst =
+            (uint8_t*)(p_last_buf + 1) + p_last_buf->offset + p_last_buf->len;
+
+        /* add length of UI PDU */
+        UINT16_TO_BE_STREAM(p_dst, ui_pdu_length);
+
+                /* copy UI PDU with LLCP header */
+                memcpy (p_dst, p_ui_pdu, ui_pdu_length);
+
+        p_last_buf->len += LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
+
+        if (p_msg) GKI_freebuf(p_msg);
+
+        appended = true;
+      }
+    }
+
+        /* if it is not available to append */
+        if (!appended)
+        {
+            /* if it's not from AGF PDU */
+            if (p_msg)
+            {
+                /* add length of PDU in front of UI PDU (reuse room for NCI header) */
+                p_ui_pdu -= LLCP_PDU_AGF_LEN_SIZE;
+                UINT16_TO_BE_STREAM (p_ui_pdu, ui_pdu_length);
+
+        p_msg->offset -= LLCP_PDU_AGF_LEN_SIZE;
+        p_msg->len += LLCP_PDU_AGF_LEN_SIZE;
+        p_msg->layer_specific = 0;
+      } else {
+        p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
+
+        if ((p_msg) && (p_ui_pdu != NULL)) {
+          p_dst = (uint8_t*)(p_msg + 1);
+
+          /* add length of PDU in front of UI PDU */
+          UINT16_TO_BE_STREAM(p_dst, ui_pdu_length);
+
+          memcpy(p_dst, p_ui_pdu, ui_pdu_length);
+
+          p_msg->offset = 0;
+          p_msg->len = LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
+          p_msg->layer_specific = 0;
+        } else {
+          LLCP_TRACE_ERROR0("llcp_link_proc_ui_pdu (): out of buffer");
+        }
+      }
+
+      /* insert UI PDU in rx queue */
+      if (p_msg) {
+        GKI_enqueue(&p_app_cb->ui_rx_q, p_msg);
+        llcp_cb.total_rx_ui_pdu++;
+      }
+    }
+
+    if (p_app_cb->ui_rx_q.count > llcp_cb.ll_rx_congest_start) {
+      LLCP_TRACE_WARNING2(
+          "llcp_link_proc_ui_pdu (): SAP:0x%x, rx link is congested (%d), "
+          "discard oldest UI PDU",
+          local_sap, p_app_cb->ui_rx_q.count);
+
+      GKI_freebuf(GKI_dequeue(&p_app_cb->ui_rx_q));
+      llcp_cb.total_rx_ui_pdu--;
+    }
+
+    if ((p_app_cb->ui_rx_q.count == 1) && (appended == false)) {
+      data.data_ind.event = LLCP_SAP_EVT_DATA_IND;
+      data.data_ind.local_sap = local_sap;
+      data.data_ind.remote_sap = remote_sap;
+      data.data_ind.link_type = LLCP_LINK_TYPE_LOGICAL_DATA_LINK;
+      (*p_app_cb->p_app_cback)(&data);
+    }
+  } else {
+    LLCP_TRACE_ERROR1("llcp_link_proc_ui_pdu (): Unregistered SAP:0x%x",
+                      local_sap);
+
+    if (p_msg) {
+      GKI_freebuf(p_msg);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_proc_agf_pdu
+**
+** Description      Process AGF PDU from peer device
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_link_proc_agf_pdu(NFC_HDR* p_agf) {
+  uint16_t agf_length;
+  uint8_t* p, *p_info, *p_pdu_length;
+  uint16_t pdu_hdr, pdu_length;
+  uint8_t dsap, ptype, ssap;
+
+  p_agf->len -= LLCP_PDU_HEADER_SIZE;
+  p_agf->offset += LLCP_PDU_HEADER_SIZE;
+
+  /*
+  ** check integrity of AGF PDU and get number of PDUs in AGF PDU
+  */
+  agf_length = p_agf->len;
+  p = (uint8_t*)(p_agf + 1) + p_agf->offset;
+
+  while (agf_length > 0) {
+    if (agf_length > LLCP_PDU_AGF_LEN_SIZE) {
+      BE_STREAM_TO_UINT16(pdu_length, p);
+      agf_length -= LLCP_PDU_AGF_LEN_SIZE;
+    } else {
+      break;
+    }
+
+    if (pdu_length <= agf_length) {
+      p += pdu_length;
+      agf_length -= pdu_length;
+    } else {
+      break;
+    }
+  }
+
+  if (agf_length != 0) {
+    LLCP_TRACE_ERROR0("llcp_link_proc_agf_pdu (): Received invalid AGF PDU");
+    GKI_freebuf(p_agf);
+    return;
+  }
+
+  /*
+  ** Process PDUs in AGF
+  */
+  agf_length = p_agf->len;
+  p = (uint8_t*)(p_agf + 1) + p_agf->offset;
+
+  while (agf_length > 0) {
+    /* get length of PDU */
+    p_pdu_length = p;
+    BE_STREAM_TO_UINT16(pdu_length, p);
+    agf_length -= LLCP_PDU_AGF_LEN_SIZE;
+
+    /* get DSAP/PTYPE/SSAP */
+    p_info = p;
+    BE_STREAM_TO_UINT16(pdu_hdr, p_info);
+
+    dsap = LLCP_GET_DSAP(pdu_hdr);
+    ptype = (uint8_t)(LLCP_GET_PTYPE(pdu_hdr));
+    ssap = LLCP_GET_SSAP(pdu_hdr);
+
+#if (BT_TRACE_VERBOSE == true)
+    LLCP_TRACE_DEBUG4(
+        "llcp_link_proc_agf_pdu (): Rx DSAP:0x%x, PTYPE:%s (0x%x), SSAP:0x%x "
+        "in AGF",
+        dsap, llcp_pdu_type(ptype), ptype, ssap);
+#endif
+
+    if ((ptype == LLCP_PDU_DISC_TYPE) && (dsap == LLCP_SAP_LM) &&
+        (ssap == LLCP_SAP_LM)) {
+      GKI_freebuf(p_agf);
+      llcp_link_deactivate(LLCP_LINK_REMOTE_INITIATED);
+      return;
+    } else if (ptype == LLCP_PDU_SYMM_TYPE) {
+      LLCP_TRACE_ERROR0(
+          "llcp_link_proc_agf_pdu (): SYMM PDU exchange shall not be in AGF");
+    } else if (ptype == LLCP_PDU_PAX_TYPE) {
+      LLCP_TRACE_ERROR0(
+          "llcp_link_proc_agf_pdu (): PAX PDU exchange shall not be used");
+    } else if (ptype == LLCP_PDU_SNL_TYPE) {
+      llcp_sdp_proc_snl((uint16_t)(pdu_length - LLCP_PDU_HEADER_SIZE), p_info);
+    } else if ((ptype == LLCP_PDU_UI_TYPE) &&
+               (pdu_length > LLCP_PDU_HEADER_SIZE)) {
+      llcp_link_proc_ui_pdu(dsap, ssap, pdu_length, p, NULL);
+    } else if (ptype == LLCP_PDU_I_TYPE) {
+      llcp_dlc_proc_i_pdu(dsap, ssap, pdu_length, p, NULL);
+    } else /* let data link connection handle PDU */
+    {
+      llcp_dlc_proc_rx_pdu(dsap, ptype, ssap,
+                           (uint16_t)(pdu_length - LLCP_PDU_HEADER_SIZE),
+                           p_info);
+    }
+
+    p += pdu_length;
+    agf_length -= pdu_length;
+  }
+
+  GKI_freebuf(p_agf);
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_proc_rx_pdu
+**
+** Description      Process received PDU from peer device
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_link_proc_rx_pdu(uint8_t dsap, uint8_t ptype, uint8_t ssap,
+                                  NFC_HDR* p_msg) {
+  bool free_buffer = true;
+  uint8_t* p_data;
+
+  switch (ptype) {
+    case LLCP_PDU_PAX_TYPE:
+      LLCP_TRACE_ERROR0(
+          "llcp_link_proc_rx_pdu (); PAX PDU exchange shall not be used");
+      break;
+
+    case LLCP_PDU_DISC_TYPE:
+      if ((dsap == LLCP_SAP_LM) && (ssap == LLCP_SAP_LM)) {
+        llcp_link_deactivate(LLCP_LINK_REMOTE_INITIATED);
+      } else {
+        p_data = (uint8_t*)(p_msg + 1) + p_msg->offset + LLCP_PDU_HEADER_SIZE;
+        llcp_dlc_proc_rx_pdu(dsap, ptype, ssap,
+                             (uint16_t)(p_msg->len - LLCP_PDU_HEADER_SIZE),
+                             p_data);
+      }
+      break;
+
+    case LLCP_PDU_SNL_TYPE:
+      p_data = (uint8_t*)(p_msg + 1) + p_msg->offset + LLCP_PDU_HEADER_SIZE;
+      llcp_sdp_proc_snl((uint16_t)(p_msg->len - LLCP_PDU_HEADER_SIZE), p_data);
+      break;
+
+    case LLCP_PDU_AGF_TYPE:
+      llcp_link_proc_agf_pdu(p_msg);
+      free_buffer = false;
+      break;
+
+    case LLCP_PDU_UI_TYPE:
+      llcp_link_proc_ui_pdu(dsap, ssap, 0, NULL, p_msg);
+      free_buffer = false;
+      break;
+
+    case LLCP_PDU_I_TYPE:
+      llcp_dlc_proc_i_pdu(dsap, ssap, 0, NULL, p_msg);
+      free_buffer = false;
+      break;
+
+    default:
+      p_data = (uint8_t*)(p_msg + 1) + p_msg->offset + LLCP_PDU_HEADER_SIZE;
+      llcp_dlc_proc_rx_pdu(dsap, ptype, ssap,
+                           (uint16_t)(p_msg->len - LLCP_PDU_HEADER_SIZE),
+                           p_data);
+      break;
+  }
+
+  if (free_buffer) GKI_freebuf(p_msg);
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_proc_rx_data
+**
+** Description      Process received data from NFCC and maintain symmetry state
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_link_proc_rx_data(NFC_HDR* p_msg) {
+  uint8_t* p;
+  uint16_t pdu_hdr, info_length = 0;
+  uint8_t dsap, ptype, ssap;
+  bool free_buffer = true;
+  bool frame_error = false;
+
+  if (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_REMOTE_XMIT_NEXT) {
+    llcp_link_stop_link_timer();
+
+    if (llcp_cb.lcb.received_first_packet == false) {
+      llcp_cb.lcb.received_first_packet = true;
+      (*llcp_cb.lcb.p_link_cback)(LLCP_LINK_FIRST_PACKET_RECEIVED_EVT,
+                                  LLCP_LINK_SUCCESS);
+    }
+    if ((llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING) &&
+        (llcp_cb.lcb.sig_xmit_q.count == 0)) {
+      /* this indicates that DISC PDU had been sent out to peer */
+      /* initiator may wait for SYMM PDU */
+      if (appl_dta_mode_flag == 0x01)
+        llcp_util_send_disc(LLCP_SAP_LM, LLCP_SAP_LM);
+      else
+        llcp_link_process_link_timeout();
+    } else {
+      if (p_msg->len < LLCP_PDU_HEADER_SIZE) {
+        LLCP_TRACE_ERROR1("Received too small PDU: got %d bytes", p_msg->len);
+        frame_error = true;
+      } else {
+        p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+        BE_STREAM_TO_UINT16(pdu_hdr, p);
+
+        dsap = LLCP_GET_DSAP(pdu_hdr);
+        ptype = (uint8_t)(LLCP_GET_PTYPE(pdu_hdr));
+        ssap = LLCP_GET_SSAP(pdu_hdr);
+
+        /* get length of information per PDU type */
+        if ((ptype == LLCP_PDU_I_TYPE) || (ptype == LLCP_PDU_RR_TYPE) ||
+            (ptype == LLCP_PDU_RNR_TYPE)) {
+          if (p_msg->len >= LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE) {
+            info_length =
+                p_msg->len - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE;
+          } else {
+            LLCP_TRACE_ERROR0("Received I/RR/RNR PDU without sequence");
+            frame_error = true;
+          }
+        } else {
+          info_length = p_msg->len - LLCP_PDU_HEADER_SIZE;
+        }
+
+        /* check if length of information is bigger than link MIU */
+        if ((!frame_error) && (info_length > llcp_cb.lcb.local_link_miu)) {
+          LLCP_TRACE_ERROR2("Received exceeding MIU (%d): got %d bytes SDU",
+                            llcp_cb.lcb.local_link_miu, info_length);
+
+          frame_error = true;
+        } else {
+#if (BT_TRACE_VERBOSE == true)
+          LLCP_TRACE_DEBUG4(
+              "llcp_link_proc_rx_data (): DSAP:0x%x, PTYPE:%s (0x%x), "
+              "SSAP:0x%x",
+              dsap, llcp_pdu_type(ptype), ptype, ssap);
+#endif
+
+          if (ptype == LLCP_PDU_SYMM_TYPE) {
+            if (info_length > 0) {
+              LLCP_TRACE_ERROR1("Received extra data (%d bytes) in SYMM PDU",
+                                info_length);
+              frame_error = true;
+            }
+          } else {
+            /* received other than SYMM */
+            llcp_link_stop_inactivity_timer();
+
+            llcp_link_proc_rx_pdu(dsap, ptype, ssap, p_msg);
+            free_buffer = false;
+          }
+        }
+      }
+      llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_LOCAL_XMIT_NEXT;
+
+      /* check if any pending packet */
+      llcp_link_check_send_data();
+    }
+  } else {
+    LLCP_TRACE_ERROR0("Received PDU in state of SYMM_MUST_XMIT_NEXT");
+  }
+
+  if (free_buffer) GKI_freebuf(p_msg);
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_get_next_pdu
+**
+** Description      Get next PDU from link manager or data links w/wo dequeue
+**
+** Returns          pointer of a PDU to send if length_only is false
+**                  NULL otherwise
+**
+*******************************************************************************/
+static NFC_HDR* llcp_link_get_next_pdu(bool length_only,
+                                       uint16_t* p_next_pdu_length) {
+  NFC_HDR* p_msg;
+  int count, xx;
+  tLLCP_APP_CB* p_app_cb;
+
+  /* processing signalling PDU first */
+  if (llcp_cb.lcb.sig_xmit_q.p_first) {
+    if (length_only) {
+      p_msg = (NFC_HDR*)llcp_cb.lcb.sig_xmit_q.p_first;
+      *p_next_pdu_length = p_msg->len;
+      return NULL;
+    } else
+      p_msg = (NFC_HDR*)GKI_dequeue(&llcp_cb.lcb.sig_xmit_q);
+
+    return p_msg;
+  } else {
+    /* transmitting logical data link and data link connection equaly */
+    for (xx = 0; xx < 2; xx++) {
+      if (!llcp_cb.lcb.ll_served) {
+        /* Get one from logical link connection */
+        for (count = 0; count < LLCP_NUM_SAPS; count++) {
+          /* round robin schedule without priority  */
+          p_app_cb = llcp_util_get_app_cb(llcp_cb.lcb.ll_idx);
+
+          if ((p_app_cb) && (p_app_cb->p_app_cback) &&
+              (p_app_cb->ui_xmit_q.count)) {
+            if (length_only) {
+              /* don't alternate next data link to return the same length of PDU
+               */
+              p_msg = (NFC_HDR*)p_app_cb->ui_xmit_q.p_first;
+              *p_next_pdu_length = p_msg->len;
+              return NULL;
+            } else {
+              /* check data link connection first in next time */
+              llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
+
+              p_msg = (NFC_HDR*)GKI_dequeue(&p_app_cb->ui_xmit_q);
+              llcp_cb.total_tx_ui_pdu--;
+
+              /* this logical link has been served, so start from next logical
+               * link next time */
+              llcp_cb.lcb.ll_idx = (llcp_cb.lcb.ll_idx + 1) % LLCP_NUM_SAPS;
+
+              return p_msg;
+            }
+          } else {
+            /* check next logical link connection */
+            llcp_cb.lcb.ll_idx = (llcp_cb.lcb.ll_idx + 1) % LLCP_NUM_SAPS;
+          }
+        }
+
+        /* no data, so check data link connection if not checked yet */
+        llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
+      } else {
+        /* Get one from data link connection */
+        for (count = 0; count < LLCP_MAX_DATA_LINK; count++) {
+          /* round robin schedule without priority  */
+          if (llcp_cb.dlcb[llcp_cb.lcb.dl_idx].state != LLCP_DLC_STATE_IDLE) {
+            if (length_only) {
+              *p_next_pdu_length = llcp_dlc_get_next_pdu_length(
+                  &llcp_cb.dlcb[llcp_cb.lcb.dl_idx]);
+
+              if (*p_next_pdu_length > 0) {
+                /* don't change data link connection to return the same length
+                 * of PDU */
+                return NULL;
+              } else {
+                /* no data, so check next data link connection */
+                llcp_cb.lcb.dl_idx =
+                    (llcp_cb.lcb.dl_idx + 1) % LLCP_MAX_DATA_LINK;
+              }
+            } else {
+              p_msg = llcp_dlc_get_next_pdu(&llcp_cb.dlcb[llcp_cb.lcb.dl_idx]);
+
+              /* this data link has been served, so start from next data link
+               * next time */
+              llcp_cb.lcb.dl_idx =
+                  (llcp_cb.lcb.dl_idx + 1) % LLCP_MAX_DATA_LINK;
+
+              if (p_msg) {
+                /* serve logical data link next time */
+                llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
+                return p_msg;
+              }
+            }
+          } else {
+            /* check next data link connection */
+            llcp_cb.lcb.dl_idx = (llcp_cb.lcb.dl_idx + 1) % LLCP_MAX_DATA_LINK;
+          }
+        }
+
+        /* if all of data link connection doesn't have data to send */
+        if (count >= LLCP_MAX_DATA_LINK) {
+          llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
+        }
+      }
+    }
+  }
+
+  /* nothing to send */
+  *p_next_pdu_length = 0;
+  return NULL;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_build_next_pdu
+**
+** Description      Build a PDU from Link Manager and Data Link
+**                  Perform aggregation procedure if necessary
+**
+** Returns          NFC_HDR* if sent any PDU
+**
+*******************************************************************************/
+static NFC_HDR* llcp_link_build_next_pdu(NFC_HDR* p_pdu) {
+  NFC_HDR* p_agf = NULL, * p_msg = NULL, *p_next_pdu;
+  uint8_t* p, ptype;
+  uint16_t next_pdu_length, pdu_hdr;
+
+  LLCP_TRACE_DEBUG0("llcp_link_build_next_pdu ()");
+
+  /* add any pending SNL PDU into sig_xmit_q for transmitting */
+  llcp_sdp_check_send_snl();
+
+  if (p_pdu) {
+    /* get PDU type */
+    p = (uint8_t*)(p_pdu + 1) + p_pdu->offset;
+    BE_STREAM_TO_UINT16(pdu_hdr, p);
+
+    ptype = (uint8_t)(LLCP_GET_PTYPE(pdu_hdr));
+
+    if (ptype == LLCP_PDU_AGF_TYPE) {
+      /* add more PDU into this AGF PDU */
+      p_agf = p_pdu;
+    } else {
+      p_msg = p_pdu;
+    }
+  } else {
+    /* Get a PDU from link manager or data links */
+    p_msg = llcp_link_get_next_pdu(false, &next_pdu_length);
+
+    if (!p_msg) {
+      return NULL;
+    }
+  }
+
+  /* Get length of next PDU from link manager or data links without dequeue */
+  llcp_link_get_next_pdu(true, &next_pdu_length);
+  while (next_pdu_length > 0) {
+    /* if it's first visit */
+    if (!p_agf) {
+      /* if next PDU fits into MIU, allocate AGF PDU and copy the first PDU */
+      if (2 + p_msg->len + 2 + next_pdu_length <= llcp_cb.lcb.effective_miu) {
+        p_agf = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
+        if (p_agf) {
+          p_agf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+          p = (uint8_t*)(p_agf + 1) + p_agf->offset;
+
+          UINT16_TO_BE_STREAM(
+              p,
+              LLCP_GET_PDU_HEADER(LLCP_SAP_LM, LLCP_PDU_AGF_TYPE, LLCP_SAP_LM));
+          UINT16_TO_BE_STREAM(p, p_msg->len);
+          memcpy(p, (uint8_t*)(p_msg + 1) + p_msg->offset, p_msg->len);
+
+          p_agf->len = LLCP_PDU_HEADER_SIZE + 2 + p_msg->len;
+
+          GKI_freebuf(p_msg);
+          p_msg = p_agf;
+        } else {
+          LLCP_TRACE_ERROR0("llcp_link_build_next_pdu (): Out of buffer");
+          return p_msg;
+        }
+      } else {
+        break;
+      }
+    }
+
+    /* if next PDU fits into MIU, copy the next PDU into AGF */
+    if (p_agf->len - LLCP_PDU_HEADER_SIZE + 2 + next_pdu_length <=
+        llcp_cb.lcb.effective_miu) {
+      /* Get a next PDU from link manager or data links */
+      p_next_pdu = llcp_link_get_next_pdu(false, &next_pdu_length);
+      if (p_next_pdu != NULL) {
+        p = (uint8_t*)(p_agf + 1) + p_agf->offset + p_agf->len;
+
+        UINT16_TO_BE_STREAM(p, p_next_pdu->len);
+        memcpy(p, (uint8_t*)(p_next_pdu + 1) + p_next_pdu->offset,
+               p_next_pdu->len);
+
+        p_agf->len += 2 + p_next_pdu->len;
+
+        GKI_freebuf(p_next_pdu);
+
+        /* Get next PDU length from link manager or data links without dequeue
+         */
+        llcp_link_get_next_pdu(true, &next_pdu_length);
+      } else {
+        LLCP_TRACE_ERROR0(
+            "llcp_link_build_next_pdu (): Unable to get next pdu from queue");
+        break;
+      }
+    } else {
+      break;
+    }
+  }
+
+  if (p_agf)
+    return p_agf;
+  else
+    return p_msg;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_send_to_lower
+**
+** Description      Send PDU to lower layer
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_link_send_to_lower(NFC_HDR* p_pdu) {
+#if (BT_TRACE_PROTOCOL == true)
+  DispLLCP(p_pdu, false);
+#endif
+  llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_REMOTE_XMIT_NEXT;
+  NFC_SendData(NFC_RF_CONN_ID, p_pdu);
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_connection_cback
+**
+** Description      processing incoming data
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_link_connection_cback(uint8_t conn_id, tNFC_CONN_EVT event,
+                                tNFC_CONN* p_data) {
+  (void)conn_id;
+
+  if (event == NFC_DATA_CEVT) {
+#if (BT_TRACE_PROTOCOL == true)
+    DispLLCP((NFC_HDR*)p_data->data.p_data, true);
+#endif
+    if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATED) {
+      /* respoding SYMM while LLCP is deactivated but RF link is not deactivated
+       * yet */
+      llcp_link_send_SYMM();
+      GKI_freebuf((NFC_HDR*)p_data->data.p_data);
+    } else if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATION_FAILED) {
+      /* respoding with invalid LLC PDU until initiator deactivates RF link
+      *after LLCP activation was failed,
+      ** so that initiator knows LLCP link activation was failed.
+      */
+      llcp_link_send_invalid_pdu();
+      GKI_freebuf((NFC_HDR*)p_data->data.p_data);
+    } else {
+      llcp_cb.lcb.flags |= LLCP_LINK_FLAGS_RX_ANY_LLC_PDU;
+      llcp_link_proc_rx_data((NFC_HDR*)p_data->data.p_data);
+    }
+  } else if (event == NFC_ERROR_CEVT) {
+    /* RF interface specific status code */
+    llcp_link_deactivate(*(uint8_t*)p_data);
+  } else if (event == NFC_DEACTIVATE_CEVT) {
+    if ((llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING) &&
+        (!llcp_cb.lcb.is_initiator)) {
+      /* peer initiates NFC link deactivation before timeout */
+      llcp_link_stop_link_timer();
+      llcp_link_process_link_timeout();
+    } else if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATION_FAILED) {
+      /* do not notify to upper layer because activation failure was already
+       * notified */
+      NFC_FlushData(NFC_RF_CONN_ID);
+      llcp_cb.lcb.link_state = LLCP_LINK_STATE_DEACTIVATED;
+    } else if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_DEACTIVATED) {
+      llcp_link_deactivate(LLCP_LINK_RF_LINK_LOSS_ERR);
+    }
+
+    NFC_SetStaticRfCback(NULL);
+  } else if (event == NFC_DATA_START_CEVT) {
+    if (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_REMOTE_XMIT_NEXT) {
+      /* LLCP shall stop LTO timer when receiving the first bit of LLC PDU */
+      llcp_link_stop_link_timer();
+    }
+  }
+
+  /* LLCP ignores the following events
+
+      NFC_CONN_CREATE_CEVT
+      NFC_CONN_CLOSE_CEVT
+  */
+}
+
+#if (BT_TRACE_VERBOSE == true)
+/*******************************************************************************
+**
+** Function         llcp_pdu_type
+**
+** Description
+**
+** Returns          string of PDU type
+**
+*******************************************************************************/
+static char* llcp_pdu_type(uint8_t ptype) {
+  switch (ptype) {
+    case LLCP_PDU_SYMM_TYPE:
+      return "SYMM";
+    case LLCP_PDU_PAX_TYPE:
+      return "PAX";
+    case LLCP_PDU_AGF_TYPE:
+      return "AGF";
+    case LLCP_PDU_UI_TYPE:
+      return "UI";
+    case LLCP_PDU_CONNECT_TYPE:
+      return "CONNECT";
+    case LLCP_PDU_DISC_TYPE:
+      return "DISC";
+    case LLCP_PDU_CC_TYPE:
+      return "CC";
+    case LLCP_PDU_DM_TYPE:
+      return "DM";
+    case LLCP_PDU_FRMR_TYPE:
+      return "FRMR";
+    case LLCP_PDU_SNL_TYPE:
+      return "SNL";
+    case LLCP_PDU_I_TYPE:
+      return "I";
+    case LLCP_PDU_RR_TYPE:
+      return "RR";
+    case LLCP_PDU_RNR_TYPE:
+      return "RNR";
+
+    default:
+      return "RESERVED";
+  }
+}
+
+#endif
diff --git a/src/nfc/llcp/llcp_main.c b/src/nfc/llcp/llcp_main.c
new file mode 100644
index 0000000..73dedf6
--- /dev/null
+++ b/src/nfc/llcp/llcp_main.c
@@ -0,0 +1,188 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the main LLCP entry points
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include "gki.h"
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "llcp_api.h"
+#include "llcp_int.h"
+#include "llcp_defs.h"
+#include "nfc_int.h"
+
+tLLCP_CB llcp_cb;
+
+/*******************************************************************************
+**
+** Function         llcp_init
+**
+** Description      This function is called once at startup to initialize
+**                  all the LLCP structures
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_init(void) {
+  uint32_t pool_count;
+
+  memset(&llcp_cb, 0, sizeof(tLLCP_CB));
+
+  llcp_cb.trace_level = LLCP_INITIAL_TRACE_LEVEL;
+
+  LLCP_TRACE_DEBUG0("LLCP - llcp_init ()");
+
+  llcp_cb.lcb.local_link_miu =
+      (LLCP_MIU <= LLCP_MAX_MIU ? LLCP_MIU : LLCP_MAX_MIU);
+  llcp_cb.lcb.local_opt = LLCP_OPT_VALUE;
+  llcp_cb.lcb.local_wt = LLCP_WAITING_TIME;
+  llcp_cb.lcb.local_lto = LLCP_LTO_VALUE;
+
+  llcp_cb.lcb.inact_timeout_init = LLCP_INIT_INACTIVITY_TIMEOUT;
+  llcp_cb.lcb.inact_timeout_target = LLCP_TARGET_INACTIVITY_TIMEOUT;
+  llcp_cb.lcb.symm_delay = LLCP_DELAY_RESP_TIME;
+  llcp_cb.lcb.data_link_timeout = LLCP_DATA_LINK_CONNECTION_TOUT;
+  llcp_cb.lcb.delay_first_pdu_timeout = LLCP_DELAY_TIME_TO_SEND_FIRST_PDU;
+
+  llcp_cb.lcb.wks = LLCP_WKS_MASK_LM;
+
+  /* total number of buffers for LLCP */
+  pool_count = GKI_poolcount(LLCP_POOL_ID);
+
+  /* number of buffers for receiving data */
+  llcp_cb.num_rx_buff = (pool_count * LLCP_RX_BUFF_RATIO) / 100;
+
+  /* rx congestion start/end threshold */
+  llcp_cb.overall_rx_congest_start =
+      (uint8_t)((llcp_cb.num_rx_buff * LLCP_RX_CONGEST_START) / 100);
+  llcp_cb.overall_rx_congest_end =
+      (uint8_t)((llcp_cb.num_rx_buff * LLCP_RX_CONGEST_END) / 100);
+
+  /* max number of buffers for receiving data on logical data link */
+  llcp_cb.max_num_ll_rx_buff =
+      (uint8_t)((llcp_cb.num_rx_buff * LLCP_LL_RX_BUFF_LIMIT) / 100);
+
+  LLCP_TRACE_DEBUG4(
+      "num_rx_buff = %d, rx_congest_start = %d, rx_congest_end = %d, "
+      "max_num_ll_rx_buff = %d",
+      llcp_cb.num_rx_buff, llcp_cb.overall_rx_congest_start,
+      llcp_cb.overall_rx_congest_end, llcp_cb.max_num_ll_rx_buff);
+
+  /* max number of buffers for transmitting data */
+  llcp_cb.max_num_tx_buff = (uint8_t)(pool_count - llcp_cb.num_rx_buff);
+
+  /* max number of buffers for transmitting data on logical data link */
+  llcp_cb.max_num_ll_tx_buff =
+      (uint8_t)((llcp_cb.max_num_tx_buff * LLCP_LL_TX_BUFF_LIMIT) / 100);
+
+  LLCP_TRACE_DEBUG2("max_num_tx_buff = %d, max_num_ll_tx_buff = %d",
+                    llcp_cb.max_num_tx_buff, llcp_cb.max_num_ll_tx_buff);
+
+  llcp_cb.ll_tx_uncongest_ntf_start_sap = LLCP_SAP_SDP + 1;
+
+  LLCP_RegisterServer(LLCP_SAP_SDP, LLCP_LINK_TYPE_DATA_LINK_CONNECTION,
+                      "urn:nfc:sn:sdp", llcp_sdp_proc_data);
+}
+
+/*******************************************************************************
+**
+** Function         llcp_cleanup
+**
+** Description      This function is called once at closing to clean up
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_cleanup(void) {
+  uint8_t sap;
+  tLLCP_APP_CB* p_app_cb;
+
+  LLCP_TRACE_DEBUG0("LLCP - llcp_cleanup ()");
+
+  for (sap = LLCP_SAP_SDP; sap < LLCP_NUM_SAPS; sap++) {
+    p_app_cb = llcp_util_get_app_cb(sap);
+
+    if ((p_app_cb) && (p_app_cb->p_app_cback)) {
+      LLCP_Deregister(sap);
+    }
+  }
+
+  nfc_stop_quick_timer(&llcp_cb.lcb.inact_timer);
+  nfc_stop_quick_timer(&llcp_cb.lcb.timer);
+}
+
+/*******************************************************************************
+**
+** Function         llcp_process_timeout
+**
+** Description      This function is called when an LLCP-related timeout occurs
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_process_timeout(TIMER_LIST_ENT* p_tle) {
+  uint8_t reason;
+
+  LLCP_TRACE_DEBUG1("llcp_process_timeout: event=%d", p_tle->event);
+
+  switch (p_tle->event) {
+    case NFC_TTYPE_LLCP_LINK_MANAGER:
+      /* Link timeout or Symm timeout */
+      llcp_link_process_link_timeout();
+      break;
+
+    case NFC_TTYPE_LLCP_LINK_INACT:
+      /* inactivity timeout */
+      llcp_link_deactivate(LLCP_LINK_LOCAL_INITIATED);
+      break;
+
+    case NFC_TTYPE_LLCP_DATA_LINK:
+      reason = LLCP_SAP_DISCONNECT_REASON_TIMEOUT;
+      llcp_dlsm_execute((tLLCP_DLCB*)(p_tle->param), LLCP_DLC_EVENT_TIMEOUT,
+                        &reason);
+      break;
+
+    case NFC_TTYPE_LLCP_DELAY_FIRST_PDU:
+      llcp_link_check_send_data();
+      break;
+
+    default:
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_SetTraceLevel
+**
+** Description      This function sets the trace level for LLCP.  If called with
+**                  a value of 0xFF, it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+uint8_t LLCP_SetTraceLevel(uint8_t new_level) {
+  if (new_level != 0xFF) llcp_cb.trace_level = new_level;
+
+  return (llcp_cb.trace_level);
+}
diff --git a/src/nfc/llcp/llcp_sdp.c b/src/nfc/llcp/llcp_sdp.c
new file mode 100644
index 0000000..2ad9407
--- /dev/null
+++ b/src/nfc/llcp/llcp_sdp.c
@@ -0,0 +1,509 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the LLCP Service Discovery
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include "gki.h"
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "llcp_api.h"
+#include "llcp_int.h"
+#include "llcp_defs.h"
+
+#if (NXP_EXTNS == TRUE)
+#include "nfa_sys.h"
+#include "nfa_dm_int.h"
+#endif
+
+/*******************************************************************************
+**
+** Function         llcp_sdp_proc_data
+**
+** Description      Do nothing
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_sdp_proc_data(tLLCP_SAP_CBACK_DATA* p_data) {
+  (void)p_data;
+
+  /*
+  ** Do nothing
+  ** llcp_sdp_proc_SNL () is called by link layer
+  */
+}
+
+/*******************************************************************************
+**
+** Function         llcp_sdp_check_send_snl
+**
+** Description      Enqueue Service Name Lookup PDU into sig_xmit_q for
+**                  transmitting
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_sdp_check_send_snl(void) {
+  uint8_t* p;
+
+  if (llcp_cb.sdp_cb.p_snl) {
+    LLCP_TRACE_DEBUG0("SDP: llcp_sdp_check_send_snl ()");
+
+    llcp_cb.sdp_cb.p_snl->len += LLCP_PDU_HEADER_SIZE;
+    llcp_cb.sdp_cb.p_snl->offset -= LLCP_PDU_HEADER_SIZE;
+
+    p = (uint8_t*)(llcp_cb.sdp_cb.p_snl + 1) + llcp_cb.sdp_cb.p_snl->offset;
+    UINT16_TO_BE_STREAM(
+        p, LLCP_GET_PDU_HEADER(LLCP_SAP_SDP, LLCP_PDU_SNL_TYPE, LLCP_SAP_SDP));
+
+    GKI_enqueue(&llcp_cb.lcb.sig_xmit_q, llcp_cb.sdp_cb.p_snl);
+    llcp_cb.sdp_cb.p_snl = NULL;
+  }
+#if (NXP_EXTNS == TRUE)
+  else {
+    /* Notify DTA after sending out SNL with SDRES not to send SNLs in AGF PDU
+     */
+    if ((llcp_cb.p_dta_cback) && (llcp_cb.dta_snl_resp)) {
+      llcp_cb.dta_snl_resp = false;
+      (*llcp_cb.p_dta_cback)();
+    }
+  }
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         llcp_sdp_add_sdreq
+**
+** Description      Add Service Discovery Request into SNL PDU
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_sdp_add_sdreq(uint8_t tid, char* p_name) {
+  uint8_t* p;
+  uint16_t name_len = (uint16_t)strlen(p_name);
+
+  p = (uint8_t*)(llcp_cb.sdp_cb.p_snl + 1) + llcp_cb.sdp_cb.p_snl->offset +
+      llcp_cb.sdp_cb.p_snl->len;
+
+  UINT8_TO_BE_STREAM(p, LLCP_SDREQ_TYPE);
+  UINT8_TO_BE_STREAM(p, (1 + name_len));
+  UINT8_TO_BE_STREAM(p, tid);
+  ARRAY_TO_BE_STREAM(p, p_name, name_len);
+
+  llcp_cb.sdp_cb.p_snl->len += LLCP_SDREQ_MIN_LEN + name_len;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_sdp_send_sdreq
+**
+** Description      Send Service Discovery Request
+**
+**
+** Returns          LLCP_STATUS
+**
+*******************************************************************************/
+tLLCP_STATUS llcp_sdp_send_sdreq(uint8_t tid, char* p_name) {
+  tLLCP_STATUS status;
+  uint16_t name_len;
+  uint16_t available_bytes;
+
+  LLCP_TRACE_DEBUG2("llcp_sdp_send_sdreq (): tid=0x%x, ServiceName=%s", tid,
+                    p_name);
+
+  /* if there is no pending SNL */
+  if (!llcp_cb.sdp_cb.p_snl) {
+    llcp_cb.sdp_cb.p_snl = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
+
+    if (llcp_cb.sdp_cb.p_snl) {
+      llcp_cb.sdp_cb.p_snl->offset =
+          NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + LLCP_PDU_HEADER_SIZE;
+      llcp_cb.sdp_cb.p_snl->len = 0;
+    }
+  }
+
+  if (llcp_cb.sdp_cb.p_snl) {
+    available_bytes = GKI_get_buf_size(llcp_cb.sdp_cb.p_snl) - NFC_HDR_SIZE -
+                      llcp_cb.sdp_cb.p_snl->offset - llcp_cb.sdp_cb.p_snl->len;
+
+    name_len = (uint16_t)strlen(p_name);
+
+    /* if SDREQ parameter can be added in SNL */
+    if ((available_bytes >= LLCP_SDREQ_MIN_LEN + name_len) &&
+        (llcp_cb.sdp_cb.p_snl->len + LLCP_SDREQ_MIN_LEN + name_len <=
+         llcp_cb.lcb.effective_miu)) {
+      llcp_sdp_add_sdreq(tid, p_name);
+      status = LLCP_STATUS_SUCCESS;
+    } else {
+      /* send pending SNL PDU to LM */
+      llcp_sdp_check_send_snl();
+
+      llcp_cb.sdp_cb.p_snl = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
+
+      if (llcp_cb.sdp_cb.p_snl) {
+        llcp_cb.sdp_cb.p_snl->offset =
+            NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + LLCP_PDU_HEADER_SIZE;
+        llcp_cb.sdp_cb.p_snl->len = 0;
+
+        llcp_sdp_add_sdreq(tid, p_name);
+
+        status = LLCP_STATUS_SUCCESS;
+      } else {
+        status = LLCP_STATUS_FAIL;
+      }
+    }
+  } else {
+    status = LLCP_STATUS_FAIL;
+  }
+  /* if LM is waiting for PDUs from upper layer */
+  if ((status == LLCP_STATUS_SUCCESS) &&
+      (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT)) {
+    llcp_link_check_send_data();
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_sdp_add_sdres
+**
+** Description      Add Service Discovery Response into SNL PDU
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_sdp_add_sdres(uint8_t tid, uint8_t sap) {
+  uint8_t* p;
+
+  p = (uint8_t*)(llcp_cb.sdp_cb.p_snl + 1) + llcp_cb.sdp_cb.p_snl->offset +
+      llcp_cb.sdp_cb.p_snl->len;
+
+  UINT8_TO_BE_STREAM(p, LLCP_SDRES_TYPE);
+  UINT8_TO_BE_STREAM(p, LLCP_SDRES_LEN);
+  UINT8_TO_BE_STREAM(p, tid);
+  UINT8_TO_BE_STREAM(p, sap);
+
+  llcp_cb.sdp_cb.p_snl->len += 2 + LLCP_SDRES_LEN; /* type and length */
+}
+
+/*******************************************************************************
+**
+** Function         llcp_sdp_send_sdres
+**
+** Description      Send Service Discovery Response
+**
+**
+** Returns          LLCP_STATUS
+**
+*******************************************************************************/
+static tLLCP_STATUS llcp_sdp_send_sdres(uint8_t tid, uint8_t sap) {
+  tLLCP_STATUS status;
+  uint16_t available_bytes;
+
+  LLCP_TRACE_DEBUG2("llcp_sdp_send_sdres (): tid=0x%x, SAP=0x%x", tid, sap);
+
+  /* if there is no pending SNL */
+  if (!llcp_cb.sdp_cb.p_snl) {
+    llcp_cb.sdp_cb.p_snl = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
+
+    if (llcp_cb.sdp_cb.p_snl) {
+      llcp_cb.sdp_cb.p_snl->offset =
+          NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + LLCP_PDU_HEADER_SIZE;
+      llcp_cb.sdp_cb.p_snl->len = 0;
+    }
+  }
+
+  if (llcp_cb.sdp_cb.p_snl) {
+    available_bytes = GKI_get_buf_size(llcp_cb.sdp_cb.p_snl) - NFC_HDR_SIZE -
+                      llcp_cb.sdp_cb.p_snl->offset - llcp_cb.sdp_cb.p_snl->len;
+
+    /* if SDRES parameter can be added in SNL */
+    if ((available_bytes >= 2 + LLCP_SDRES_LEN) &&
+        (llcp_cb.sdp_cb.p_snl->len + 2 + LLCP_SDRES_LEN <=
+         llcp_cb.lcb.effective_miu)) {
+      llcp_sdp_add_sdres(tid, sap);
+      status = LLCP_STATUS_SUCCESS;
+    } else {
+      /* send pending SNL PDU to LM */
+      llcp_sdp_check_send_snl();
+
+      llcp_cb.sdp_cb.p_snl = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
+
+      if (llcp_cb.sdp_cb.p_snl) {
+        llcp_cb.sdp_cb.p_snl->offset =
+            NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + LLCP_PDU_HEADER_SIZE;
+        llcp_cb.sdp_cb.p_snl->len = 0;
+
+        llcp_sdp_add_sdres(tid, sap);
+
+        status = LLCP_STATUS_SUCCESS;
+      } else {
+        status = LLCP_STATUS_FAIL;
+      }
+    }
+  } else {
+    status = LLCP_STATUS_FAIL;
+  }
+  /* if LM is waiting for PDUs from upper layer */
+  if ((status == LLCP_STATUS_SUCCESS) &&
+      (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT)) {
+    llcp_link_check_send_data();
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_sdp_get_sap_by_name
+**
+** Description      Search SAP by service name
+**
+**
+** Returns          SAP if success
+**
+*******************************************************************************/
+uint8_t llcp_sdp_get_sap_by_name(char* p_name, uint8_t length) {
+  uint8_t sap;
+  tLLCP_APP_CB* p_app_cb;
+
+  for (sap = LLCP_SAP_SDP; sap <= LLCP_UPPER_BOUND_SDP_SAP; sap++) {
+    p_app_cb = llcp_util_get_app_cb(sap);
+
+    if ((p_app_cb) && (p_app_cb->p_app_cback) &&
+        (strlen((char*)p_app_cb->p_service_name) == length) &&
+        (!strncmp((char*)p_app_cb->p_service_name, p_name, length))) {
+#if (NXP_EXTNS == TRUE)
+      /* if device is under LLCP DTA testing */
+      if ((llcp_cb.p_dta_cback) &&
+          (!strncmp((char*)p_app_cb->p_service_name, "urn:nfc:sn:cl-echo-in",
+                    length))) {
+        llcp_cb.dta_snl_resp = true;
+      }
+#endif
+      return (sap);
+    }
+  }
+  return 0;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_sdp_return_sap
+**
+** Description      Report TID and SAP to requester
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_sdp_return_sap(uint8_t tid, uint8_t sap) {
+  uint8_t i;
+
+  LLCP_TRACE_DEBUG2("llcp_sdp_return_sap (): tid=0x%x, SAP=0x%x", tid, sap);
+
+  for (i = 0; i < LLCP_MAX_SDP_TRANSAC; i++) {
+    if ((llcp_cb.sdp_cb.transac[i].p_cback) &&
+        (llcp_cb.sdp_cb.transac[i].tid == tid)) {
+      (*llcp_cb.sdp_cb.transac[i].p_cback)(tid, sap);
+
+      llcp_cb.sdp_cb.transac[i].p_cback = NULL;
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_sdp_proc_deactivation
+**
+** Description      Report SDP failure for any pending request because of
+**                  deactivation
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_sdp_proc_deactivation(void) {
+  uint8_t i;
+
+  LLCP_TRACE_DEBUG0("llcp_sdp_proc_deactivation ()");
+
+  for (i = 0; i < LLCP_MAX_SDP_TRANSAC; i++) {
+    if (llcp_cb.sdp_cb.transac[i].p_cback) {
+      (*llcp_cb.sdp_cb.transac[i].p_cback)(llcp_cb.sdp_cb.transac[i].tid, 0x00);
+
+      llcp_cb.sdp_cb.transac[i].p_cback = NULL;
+    }
+  }
+
+  /* free any pending SNL PDU */
+  if (llcp_cb.sdp_cb.p_snl) {
+    GKI_freebuf(llcp_cb.sdp_cb.p_snl);
+    llcp_cb.sdp_cb.p_snl = NULL;
+  }
+
+  llcp_cb.sdp_cb.next_tid = 0;
+#if (NXP_EXTNS == TRUE)
+  llcp_cb.dta_snl_resp = false;
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         llcp_sdp_proc_snl
+**
+** Description      Process SDREQ and SDRES in SNL
+**
+**
+** Returns          LLCP_STATUS
+**
+*******************************************************************************/
+tLLCP_STATUS llcp_sdp_proc_snl(uint16_t sdu_length, uint8_t* p) {
+  uint8_t type, length, tid, sap, *p_value;
+
+  LLCP_TRACE_DEBUG0("llcp_sdp_proc_snl ()");
+
+  if ((llcp_cb.lcb.agreed_major_version < LLCP_MIN_SNL_MAJOR_VERSION) ||
+      ((llcp_cb.lcb.agreed_major_version == LLCP_MIN_SNL_MAJOR_VERSION) &&
+       (llcp_cb.lcb.agreed_minor_version < LLCP_MIN_SNL_MINOR_VERSION))) {
+    LLCP_TRACE_DEBUG0(
+        "llcp_sdp_proc_snl(): version number less than 1.1, SNL not "
+        "supported.");
+    return LLCP_STATUS_FAIL;
+  }
+  while (sdu_length >= 2) /* at least type and length */
+  {
+    BE_STREAM_TO_UINT8(type, p);
+    BE_STREAM_TO_UINT8(length, p);
+
+    switch (type) {
+      case LLCP_SDREQ_TYPE:
+        if ((length > 1) /* TID and sevice name */
+            &&
+            (sdu_length >= 2 + length)) /* type, length, TID and service name */
+        {
+          p_value = p;
+          BE_STREAM_TO_UINT8(tid, p_value);
+          sap = llcp_sdp_get_sap_by_name((char*)p_value, (uint8_t)(length - 1));
+#if (NXP_EXTNS == TRUE)
+          /* fix to pass TC_CTO_TAR_BI_03_x (x=5) test case
+           * As per the LLCP test specification v1.2.00 by receiving erroneous
+           * SNL PDU
+           * i'e with improper service name "urn:nfc:sn:dta-co-echo-in", the IUT
+           * should not
+           * send any PDU except SYMM PDU*/
+          if ((appl_dta_mode_flag == 1) && (sap == 0x00)) {
+            LLCP_TRACE_DEBUG1(
+                "llcp_sdp_proc_snl () In dta mode sap == 0x00 p_value = %s",
+                p_value);
+            if ((length - 1) == strlen((const char*)p_value)) {
+              LLCP_TRACE_DEBUG0(
+                  "DEBUG> llcp_sdp_proc_snl () Strings are not equal");
+              llcp_sdp_send_sdres(tid, sap);
+            }
+          } else {
+            llcp_sdp_send_sdres(tid, sap);
+          }
+#else
+          llcp_sdp_send_sdres(tid, sap);
+#endif
+        } else {
+#if (NXP_EXTNS == TRUE)
+          /*For P2P in LLCP mode TC_CTO_TAR_BI_03_x(x=3) fix*/
+          if ((appl_dta_mode_flag == 1) &&
+              ((nfa_dm_cb.eDtaMode & 0x0F) == NFA_DTA_LLCP_MODE)) {
+            LLCP_TRACE_ERROR0(
+                " llcp_sdp_proc_snl () Calling llcp_sdp_send_sdres");
+            tid = 0x01;
+            sap = 0x00;
+            llcp_sdp_send_sdres(tid, sap);
+          }
+#endif
+          LLCP_TRACE_ERROR1(
+              "llcp_sdp_proc_snl (): bad length (%d) in LLCP_SDREQ_TYPE",
+              length);
+        }
+        break;
+
+      case LLCP_SDRES_TYPE:
+        if ((length == LLCP_SDRES_LEN)     /* TID and SAP */
+            && (sdu_length >= 2 + length)) /* type, length, TID and SAP */
+        {
+          p_value = p;
+          BE_STREAM_TO_UINT8(tid, p_value);
+          BE_STREAM_TO_UINT8(sap, p_value);
+          llcp_sdp_return_sap(tid, sap);
+        } else {
+          LLCP_TRACE_ERROR1(
+              "llcp_sdp_proc_snl (): bad length (%d) in LLCP_SDRES_TYPE",
+              length);
+        }
+        break;
+
+      default:
+        LLCP_TRACE_WARNING1(
+            "llcp_sdp_proc_snl (): Unknown type (0x%x) is ignored", type);
+        break;
+    }
+
+    if (sdu_length >= 2 + length) /* type, length, value */
+    {
+      sdu_length -= 2 + length;
+      p += length;
+    } else {
+      break;
+    }
+  }
+
+  if (sdu_length) {
+    LLCP_TRACE_ERROR0("llcp_sdp_proc_snl (): Bad format of SNL");
+    return LLCP_STATUS_FAIL;
+  } else {
+    return LLCP_STATUS_SUCCESS;
+  }
+}
diff --git a/src/nfc/llcp/llcp_util.c b/src/nfc/llcp/llcp_util.c
new file mode 100644
index 0000000..3520e78
--- /dev/null
+++ b/src/nfc/llcp/llcp_util.c
@@ -0,0 +1,852 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the LLCP utilities
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include "gki.h"
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "trace_api.h"
+#include "llcp_int.h"
+#include "llcp_defs.h"
+#include "nfc_int.h"
+
+/*******************************************************************************
+**
+** Function         llcp_util_parse_link_params
+**
+** Description      Parse LLCP Link parameters
+**
+** Returns          true if success
+**
+*******************************************************************************/
+bool llcp_util_parse_link_params(uint16_t length, uint8_t* p_bytes) {
+  uint8_t param_type, param_len, * p = p_bytes;
+
+  while (length) {
+    BE_STREAM_TO_UINT8(param_type, p);
+    length--;
+
+    switch (param_type) {
+      case LLCP_VERSION_TYPE:
+        BE_STREAM_TO_UINT8(param_len, p);
+        BE_STREAM_TO_UINT8(llcp_cb.lcb.peer_version, p);
+        LLCP_TRACE_DEBUG1("Peer Version - 0x%02X", llcp_cb.lcb.peer_version);
+        break;
+
+      case LLCP_MIUX_TYPE:
+        BE_STREAM_TO_UINT8(param_len, p);
+        BE_STREAM_TO_UINT16(llcp_cb.lcb.peer_miu, p);
+        llcp_cb.lcb.peer_miu &= LLCP_MIUX_MASK;
+        llcp_cb.lcb.peer_miu += LLCP_DEFAULT_MIU;
+        LLCP_TRACE_DEBUG1("Peer MIU - %d bytes", llcp_cb.lcb.peer_miu);
+        break;
+
+      case LLCP_WKS_TYPE:
+        BE_STREAM_TO_UINT8(param_len, p);
+        BE_STREAM_TO_UINT16(llcp_cb.lcb.peer_wks, p);
+        LLCP_TRACE_DEBUG1("Peer WKS - 0x%04X", llcp_cb.lcb.peer_wks);
+        break;
+
+      case LLCP_LTO_TYPE:
+        BE_STREAM_TO_UINT8(param_len, p);
+        BE_STREAM_TO_UINT8(llcp_cb.lcb.peer_lto, p);
+        llcp_cb.lcb.peer_lto *= LLCP_LTO_UNIT; /* 10ms unit */
+        LLCP_TRACE_DEBUG1("Peer LTO - %d ms", llcp_cb.lcb.peer_lto);
+        break;
+
+      case LLCP_OPT_TYPE:
+        BE_STREAM_TO_UINT8(param_len, p);
+        BE_STREAM_TO_UINT8(llcp_cb.lcb.peer_opt, p);
+        LLCP_TRACE_DEBUG1("Peer OPT - 0x%02X", llcp_cb.lcb.peer_opt);
+        break;
+
+      default:
+        LLCP_TRACE_ERROR1(
+            "llcp_util_parse_link_params (): Unexpected type 0x%x", param_type);
+        BE_STREAM_TO_UINT8(param_len, p);
+        p += param_len;
+        break;
+    }
+
+    if (length >= param_len + 1)
+      length -= param_len + 1;
+    else {
+      LLCP_TRACE_ERROR0("llcp_util_parse_link_params (): Bad LTV's");
+      return (false);
+    }
+  }
+  return (true);
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_adjust_ll_congestion
+**
+** Description      adjust tx/rx congestion thresholds on logical link
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_util_adjust_ll_congestion(void) {
+  /* buffer quota is allocated equally for each logical data link */
+  if (llcp_cb.num_logical_data_link) {
+    llcp_cb.ll_tx_congest_start =
+        llcp_cb.max_num_ll_tx_buff / llcp_cb.num_logical_data_link;
+    llcp_cb.ll_rx_congest_start =
+        llcp_cb.max_num_ll_rx_buff / llcp_cb.num_logical_data_link;
+  } else {
+    llcp_cb.ll_tx_congest_start = llcp_cb.max_num_ll_tx_buff;
+    llcp_cb.ll_rx_congest_start = llcp_cb.max_num_ll_rx_buff;
+  }
+
+  /* at least one for each logical data link */
+  if (llcp_cb.ll_tx_congest_start == 0) {
+    llcp_cb.ll_tx_congest_start = 1;
+  }
+  if (llcp_cb.ll_rx_congest_start == 0) {
+    llcp_cb.ll_rx_congest_start = 1;
+  }
+
+  if (llcp_cb.ll_tx_congest_start > 1) {
+    llcp_cb.ll_tx_congest_end = 1;
+  } else {
+    llcp_cb.ll_tx_congest_end = 0;
+  }
+
+  LLCP_TRACE_DEBUG4(
+      "num_logical_data_link=%d, ll_tx_congest_start=%d, ll_tx_congest_end=%d, "
+      "ll_rx_congest_start=%d",
+      llcp_cb.num_logical_data_link, llcp_cb.ll_tx_congest_start,
+      llcp_cb.ll_tx_congest_end, llcp_cb.ll_rx_congest_start);
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_adjust_dl_rx_congestion
+**
+** Description      adjust rx congestion thresholds on data link
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_util_adjust_dl_rx_congestion(void) {
+  uint8_t idx, rx_congest_start;
+
+  if (llcp_cb.num_data_link_connection) {
+    rx_congest_start = llcp_cb.num_rx_buff / llcp_cb.num_data_link_connection;
+
+    for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++) {
+      if (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED) {
+        if (rx_congest_start > llcp_cb.dlcb[idx].local_rw) {
+          /*
+          ** set rx congestion threshold LLCP_DL_MIN_RX_CONGEST at
+          ** least so, we don't need to flow off too often.
+          */
+          if (llcp_cb.dlcb[idx].local_rw + 1 > LLCP_DL_MIN_RX_CONGEST)
+            llcp_cb.dlcb[idx].rx_congest_threshold =
+                llcp_cb.dlcb[idx].local_rw + 1;
+          else
+            llcp_cb.dlcb[idx].rx_congest_threshold = LLCP_DL_MIN_RX_CONGEST;
+        } else {
+          llcp_cb.dlcb[idx].rx_congest_threshold = LLCP_DL_MIN_RX_CONGEST;
+        }
+
+        LLCP_TRACE_DEBUG3("DLC[%d], local_rw=%d, rx_congest_threshold=%d", idx,
+                          llcp_cb.dlcb[idx].local_rw,
+                          llcp_cb.dlcb[idx].rx_congest_threshold);
+      }
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_check_rx_congested_status
+**
+** Description      Update rx congested status
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_util_check_rx_congested_status(void) {
+  uint8_t idx;
+
+  if (llcp_cb.overall_rx_congested) {
+    /* check if rx congestion clear */
+    if (llcp_cb.total_rx_ui_pdu + llcp_cb.total_rx_i_pdu <=
+        llcp_cb.overall_rx_congest_end) {
+      LLCP_TRACE_DEBUG3(
+          "llcp_util_check_rx_congested_status (): rx link is uncongested, "
+          "%d+%d <= %d",
+          llcp_cb.total_rx_ui_pdu, llcp_cb.total_rx_i_pdu,
+          llcp_cb.overall_rx_congest_end);
+
+      llcp_cb.overall_rx_congested = false;
+
+      for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++) {
+        /* set flag to clear local busy status on data link connections */
+        if ((llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED) &&
+            (llcp_cb.dlcb[idx].is_rx_congested == false)) {
+          llcp_cb.dlcb[idx].flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
+        }
+      }
+    }
+  } else {
+    /* check if rx link is congested */
+    if (llcp_cb.total_rx_ui_pdu + llcp_cb.total_rx_i_pdu >=
+        llcp_cb.overall_rx_congest_start) {
+      LLCP_TRACE_WARNING3(
+          "llcp_util_check_rx_congested_status (): rx link is congested, %d+%d "
+          ">= %d",
+          llcp_cb.total_rx_ui_pdu, llcp_cb.total_rx_i_pdu,
+          llcp_cb.overall_rx_congest_start);
+
+      llcp_cb.overall_rx_congested = true;
+
+      /* rx link congestion is started, send RNR to remote end point */
+      for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++) {
+        if ((llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED) &&
+            (llcp_cb.dlcb[idx].is_rx_congested == false)) {
+          llcp_cb.dlcb[idx].flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
+        }
+      }
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_send_ui
+**
+** Description      Send UI PDU
+**
+** Returns          tLLCP_STATUS
+**
+*******************************************************************************/
+tLLCP_STATUS llcp_util_send_ui(uint8_t ssap, uint8_t dsap,
+                               tLLCP_APP_CB* p_app_cb, NFC_HDR* p_msg) {
+  uint8_t* p;
+  tLLCP_STATUS status = LLCP_STATUS_SUCCESS;
+
+  p_msg->offset -= LLCP_PDU_HEADER_SIZE;
+  p_msg->len += LLCP_PDU_HEADER_SIZE;
+
+  p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+  UINT16_TO_BE_STREAM(p, LLCP_GET_PDU_HEADER(dsap, LLCP_PDU_UI_TYPE, ssap));
+
+  GKI_enqueue(&p_app_cb->ui_xmit_q, p_msg);
+  llcp_cb.total_tx_ui_pdu++;
+
+  llcp_link_check_send_data();
+
+  if ((p_app_cb->is_ui_tx_congested) ||
+      (p_app_cb->ui_xmit_q.count >= llcp_cb.ll_tx_congest_start) ||
+      (llcp_cb.overall_tx_congested) ||
+      (llcp_cb.total_tx_ui_pdu >= llcp_cb.max_num_ll_tx_buff)) {
+    /* set congested here so overall congestion check routine will not report
+     * event again, */
+    /* or notify uncongestion later */
+    p_app_cb->is_ui_tx_congested = true;
+
+    LLCP_TRACE_WARNING2("Logical link (SAP=0x%X) congested: ui_xmit_q.count=%d",
+                        ssap, p_app_cb->ui_xmit_q.count);
+
+    status = LLCP_STATUS_CONGESTED;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_send_disc
+**
+** Description      Send DISC PDU
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_util_send_disc(uint8_t dsap, uint8_t ssap) {
+  NFC_HDR* p_msg;
+  uint8_t* p;
+
+  p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
+
+  if (p_msg) {
+    p_msg->len = LLCP_PDU_DISC_SIZE;
+    p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+    p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+    UINT16_TO_BE_STREAM(p, LLCP_GET_PDU_HEADER(dsap, LLCP_PDU_DISC_TYPE, ssap));
+
+    GKI_enqueue(&llcp_cb.lcb.sig_xmit_q, p_msg);
+    llcp_link_check_send_data();
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_allocate_data_link
+**
+** Description      Allocate tLLCP_DLCB for data link connection
+**
+** Returns          tLLCP_DLCB *
+**
+******************************************************************************/
+tLLCP_DLCB* llcp_util_allocate_data_link(uint8_t reg_sap, uint8_t remote_sap) {
+  tLLCP_DLCB* p_dlcb = NULL;
+  int idx;
+
+  LLCP_TRACE_DEBUG2(
+      "llcp_util_allocate_data_link (): reg_sap = 0x%x, remote_sap = 0x%x",
+      reg_sap, remote_sap);
+
+  for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++) {
+    if (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_IDLE) {
+      p_dlcb = &(llcp_cb.dlcb[idx]);
+
+      memset(p_dlcb, 0, sizeof(tLLCP_DLCB));
+      break;
+    }
+  }
+
+  if (!p_dlcb) {
+    LLCP_TRACE_ERROR0("llcp_util_allocate_data_link (): Out of DLCB");
+  } else {
+    p_dlcb->p_app_cb = llcp_util_get_app_cb(reg_sap);
+    p_dlcb->local_sap = reg_sap;
+    p_dlcb->remote_sap = remote_sap;
+    p_dlcb->timer.param = (uintptr_t)p_dlcb;
+
+    /* this is for inactivity timer and congestion control. */
+    llcp_cb.num_data_link_connection++;
+
+    LLCP_TRACE_DEBUG3(
+        "llcp_util_allocate_data_link (): local_sap = 0x%x, remote_sap = 0x%x, "
+        "num_data_link_connection = %d",
+        p_dlcb->local_sap, p_dlcb->remote_sap,
+        llcp_cb.num_data_link_connection);
+  }
+  return p_dlcb;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_deallocate_data_link
+**
+** Description      Deallocate tLLCP_DLCB
+**
+** Returns          void
+**
+******************************************************************************/
+void llcp_util_deallocate_data_link(tLLCP_DLCB* p_dlcb) {
+  if (p_dlcb) {
+    LLCP_TRACE_DEBUG1("llcp_util_deallocate_data_link (): local_sap = 0x%x",
+                      p_dlcb->local_sap);
+
+    if (p_dlcb->state != LLCP_DLC_STATE_IDLE) {
+      nfc_stop_quick_timer(&p_dlcb->timer);
+      llcp_dlc_flush_q(p_dlcb);
+
+      p_dlcb->state = LLCP_DLC_STATE_IDLE;
+
+      if (llcp_cb.num_data_link_connection > 0) {
+        llcp_cb.num_data_link_connection--;
+      }
+
+      LLCP_TRACE_DEBUG1(
+          "llcp_util_deallocate_data_link (): num_data_link_connection = %d",
+          llcp_cb.num_data_link_connection);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_send_connect
+**
+** Description      Send CONNECT PDU
+**
+** Returns          tLLCP_STATUS
+**
+******************************************************************************/
+tLLCP_STATUS llcp_util_send_connect(tLLCP_DLCB* p_dlcb,
+                                    tLLCP_CONNECTION_PARAMS* p_params) {
+  NFC_HDR* p_msg;
+  uint8_t* p;
+  uint16_t miu_len = 0, rw_len = 0, sn_len = 0;
+
+  if (p_params->miu != LLCP_DEFAULT_MIU) {
+    miu_len = 4; /* TYPE, LEN, 2 bytes MIU */
+  }
+  if (p_params->rw != LLCP_DEFAULT_RW) {
+    rw_len = 3;           /* TYPE, LEN, 1 byte RW */
+    p_params->rw &= 0x0F; /* only 4 bits  */
+  }
+  if ((strlen(p_params->sn)) && (p_dlcb->remote_sap == LLCP_SAP_SDP)) {
+    sn_len = (uint16_t)(2 + strlen(p_params->sn)); /* TYPE, LEN, SN */
+  }
+
+  p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
+
+  if (p_msg) {
+    p_msg->len = LLCP_PDU_HEADER_SIZE + miu_len + rw_len + sn_len;
+    p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+    p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+
+    UINT16_TO_BE_STREAM(
+        p, LLCP_GET_PDU_HEADER(p_dlcb->remote_sap, LLCP_PDU_CONNECT_TYPE,
+                               p_dlcb->local_sap));
+
+    if (miu_len) {
+      UINT8_TO_BE_STREAM(p, LLCP_MIUX_TYPE);
+      UINT8_TO_BE_STREAM(p, LLCP_MIUX_LEN);
+      UINT16_TO_BE_STREAM(p, p_params->miu - LLCP_DEFAULT_MIU);
+    }
+
+    if (rw_len) {
+      UINT8_TO_BE_STREAM(p, LLCP_RW_TYPE);
+      UINT8_TO_BE_STREAM(p, LLCP_RW_LEN);
+      UINT8_TO_BE_STREAM(p, p_params->rw);
+    }
+
+    if (sn_len) {
+      UINT8_TO_BE_STREAM(p, LLCP_SN_TYPE);
+      UINT8_TO_BE_STREAM(p, sn_len - 2);
+      memcpy(p, p_params->sn, sn_len - 2);
+    }
+
+    GKI_enqueue(&llcp_cb.lcb.sig_xmit_q, p_msg);
+    llcp_link_check_send_data();
+
+    return LLCP_STATUS_SUCCESS;
+  }
+
+  return LLCP_STATUS_FAIL;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_parse_connect
+**
+** Description      Parse CONNECT PDU
+**
+** Returns          tLLCP_STATUS
+**
+*******************************************************************************/
+tLLCP_STATUS llcp_util_parse_connect(uint8_t* p_bytes, uint16_t length,
+                                     tLLCP_CONNECTION_PARAMS* p_params) {
+  uint8_t param_type, param_len, * p = p_bytes;
+
+  p_params->miu = LLCP_DEFAULT_MIU;
+  p_params->rw = LLCP_DEFAULT_RW;
+  p_params->sn[0] = 0;
+  p_params->sn[1] = 0;
+
+  while (length) {
+    BE_STREAM_TO_UINT8(param_type, p);
+    length--;
+
+    switch (param_type) {
+      case LLCP_MIUX_TYPE:
+        BE_STREAM_TO_UINT8(param_len, p);
+        BE_STREAM_TO_UINT16(p_params->miu, p);
+        p_params->miu &= LLCP_MIUX_MASK;
+        p_params->miu += LLCP_DEFAULT_MIU;
+
+        LLCP_TRACE_DEBUG1("llcp_util_parse_connect (): LLCP_MIUX_TYPE:%d",
+                          p_params->miu);
+        break;
+
+      case LLCP_RW_TYPE:
+        BE_STREAM_TO_UINT8(param_len, p);
+        BE_STREAM_TO_UINT8(p_params->rw, p);
+        p_params->rw &= 0x0F;
+
+        LLCP_TRACE_DEBUG1("llcp_util_parse_connect (): LLCP_RW_TYPE:%d",
+                          p_params->rw);
+        break;
+
+      case LLCP_SN_TYPE:
+        BE_STREAM_TO_UINT8(param_len, p);
+
+        if (param_len == 0) {
+          /* indicate that SN type is included without SN */
+          p_params->sn[1] = LLCP_SN_TYPE;
+        } else if (param_len <= LLCP_MAX_SN_LEN) {
+          memcpy(p_params->sn, p, param_len);
+          p_params->sn[param_len] = 0;
+        } else {
+          memcpy(p_params->sn, p, LLCP_MAX_SN_LEN);
+          p_params->sn[LLCP_MAX_SN_LEN] = 0;
+        }
+        p += param_len;
+
+        LLCP_TRACE_DEBUG1("llcp_util_parse_connect (): LLCP_SN_TYPE:<%s>",
+                          p_params->sn);
+        break;
+
+      default:
+        LLCP_TRACE_ERROR1("llcp_util_parse_connect (): Unexpected type 0x%x",
+                          param_type);
+        BE_STREAM_TO_UINT8(param_len, p);
+        p += param_len;
+        break;
+    }
+
+    /* check remaining lengh */
+    if (length >= param_len + 1) {
+      length -= param_len + 1;
+    } else {
+      LLCP_TRACE_ERROR0("llcp_util_parse_connect (): Bad LTV's");
+      return LLCP_STATUS_FAIL;
+    }
+  }
+  return LLCP_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_send_cc
+**
+** Description      Send CC PDU
+**
+** Returns          tLLCP_STATUS
+**
+******************************************************************************/
+tLLCP_STATUS llcp_util_send_cc(tLLCP_DLCB* p_dlcb,
+                               tLLCP_CONNECTION_PARAMS* p_params) {
+  NFC_HDR* p_msg;
+  uint8_t* p;
+  uint16_t miu_len = 0, rw_len = 0;
+
+  if (p_params->miu != LLCP_DEFAULT_MIU) {
+    miu_len = 4;
+  }
+  if (p_params->rw != LLCP_DEFAULT_RW) {
+    rw_len = 3;
+    p_params->rw &= 0x0F;
+  }
+
+  p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
+
+  if (p_msg) {
+    p_msg->len = LLCP_PDU_HEADER_SIZE + miu_len + rw_len;
+    p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+    p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+
+    UINT16_TO_BE_STREAM(
+        p, LLCP_GET_PDU_HEADER(p_dlcb->remote_sap, LLCP_PDU_CC_TYPE,
+                               p_dlcb->local_sap));
+
+    if (miu_len) {
+      UINT8_TO_BE_STREAM(p, LLCP_MIUX_TYPE);
+      UINT8_TO_BE_STREAM(p, LLCP_MIUX_LEN);
+      UINT16_TO_BE_STREAM(p, p_params->miu - LLCP_DEFAULT_MIU);
+    }
+
+    if (rw_len) {
+      UINT8_TO_BE_STREAM(p, LLCP_RW_TYPE);
+      UINT8_TO_BE_STREAM(p, LLCP_RW_LEN);
+      UINT8_TO_BE_STREAM(p, p_params->rw);
+    }
+
+    GKI_enqueue(&llcp_cb.lcb.sig_xmit_q, p_msg);
+    llcp_link_check_send_data();
+
+    return LLCP_STATUS_SUCCESS;
+  }
+
+  return LLCP_STATUS_FAIL;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_parse_cc
+**
+** Description      Parse CC PDU
+**
+** Returns          tLLCP_STATUS
+**
+*******************************************************************************/
+tLLCP_STATUS llcp_util_parse_cc(uint8_t* p_bytes, uint16_t length,
+                                uint16_t* p_miu, uint8_t* p_rw) {
+  uint8_t param_type, param_len, * p = p_bytes;
+
+  *p_miu = LLCP_DEFAULT_MIU;
+  *p_rw = LLCP_DEFAULT_RW;
+
+  while (length) {
+    BE_STREAM_TO_UINT8(param_type, p);
+    length--;
+
+    switch (param_type) {
+      case LLCP_MIUX_TYPE:
+        BE_STREAM_TO_UINT8(param_len, p);
+        BE_STREAM_TO_UINT16((*p_miu), p);
+        (*p_miu) &= LLCP_MIUX_MASK;
+        (*p_miu) += LLCP_DEFAULT_MIU;
+
+        LLCP_TRACE_DEBUG1("llcp_util_parse_cc (): LLCP_MIUX_TYPE:%d", *p_miu);
+        break;
+
+      case LLCP_RW_TYPE:
+        BE_STREAM_TO_UINT8(param_len, p);
+        BE_STREAM_TO_UINT8((*p_rw), p);
+        (*p_rw) &= 0x0F;
+
+        LLCP_TRACE_DEBUG1("llcp_util_parse_cc (): LLCP_RW_TYPE:%d", *p_rw);
+        break;
+
+      default:
+        LLCP_TRACE_ERROR1("llcp_util_parse_cc (): Unexpected type 0x%x",
+                          param_type);
+        BE_STREAM_TO_UINT8(param_len, p);
+        p += param_len;
+        break;
+    }
+
+    if (length >= param_len + 1)
+      length -= param_len + 1;
+    else {
+      LLCP_TRACE_ERROR0("llcp_util_parse_cc (): Bad LTV's");
+      return LLCP_STATUS_FAIL;
+    }
+  }
+  return LLCP_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_send_dm
+**
+** Description      Send DM PDU
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_util_send_dm(uint8_t dsap, uint8_t ssap, uint8_t reason) {
+  NFC_HDR* p_msg;
+  uint8_t* p;
+
+  p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
+
+  if (p_msg) {
+    p_msg->len = LLCP_PDU_DM_SIZE;
+    p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+    p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+    UINT16_TO_BE_STREAM(p, LLCP_GET_PDU_HEADER(dsap, LLCP_PDU_DM_TYPE, ssap));
+    UINT8_TO_BE_STREAM(p, reason);
+
+    GKI_enqueue(&llcp_cb.lcb.sig_xmit_q, p_msg);
+    llcp_link_check_send_data();
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_build_info_pdu
+**
+** Description      Add DSAP, PTYPE, SSAP and sequence numbers and update local
+**                  ack sequence
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_util_build_info_pdu(tLLCP_DLCB* p_dlcb, NFC_HDR* p_msg) {
+  uint8_t* p;
+  uint8_t rcv_seq;
+
+  p_msg->offset -= LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
+  p_msg->len += LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
+  p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+
+  UINT16_TO_BE_STREAM(p,
+                      LLCP_GET_PDU_HEADER(p_dlcb->remote_sap, LLCP_PDU_I_TYPE,
+                                          p_dlcb->local_sap));
+
+  /* if local_busy or rx congested then do not update receive sequence number to
+   * flow off */
+  if ((p_dlcb->local_busy) || (p_dlcb->is_rx_congested) ||
+      (llcp_cb.overall_rx_congested)) {
+    rcv_seq = p_dlcb->sent_ack_seq;
+  } else {
+    p_dlcb->sent_ack_seq = p_dlcb->next_rx_seq;
+    rcv_seq = p_dlcb->sent_ack_seq;
+  }
+  UINT8_TO_BE_STREAM(p, LLCP_GET_SEQUENCE(p_dlcb->next_tx_seq, rcv_seq));
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_send_frmr
+**
+** Description      Send FRMR PDU
+**
+** Returns          tLLCP_STATUS
+**
+*******************************************************************************/
+tLLCP_STATUS llcp_util_send_frmr(tLLCP_DLCB* p_dlcb, uint8_t flags,
+                                 uint8_t ptype, uint8_t sequence) {
+  NFC_HDR* p_msg;
+  uint8_t* p;
+
+  p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
+
+  if (p_msg) {
+    p_msg->len = LLCP_PDU_FRMR_SIZE;
+    p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+    p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+
+    UINT16_TO_BE_STREAM(
+        p, LLCP_GET_PDU_HEADER(p_dlcb->remote_sap, LLCP_PDU_FRMR_TYPE,
+                               p_dlcb->local_sap));
+    UINT8_TO_BE_STREAM(p, (flags << 4) | ptype);
+    UINT8_TO_BE_STREAM(p, sequence);
+    UINT8_TO_BE_STREAM(p, (p_dlcb->next_tx_seq << 4) | p_dlcb->next_rx_seq);
+    UINT8_TO_BE_STREAM(p, (p_dlcb->rcvd_ack_seq << 4) | p_dlcb->sent_ack_seq);
+
+    GKI_enqueue(&llcp_cb.lcb.sig_xmit_q, p_msg);
+    llcp_link_check_send_data();
+
+    return LLCP_STATUS_SUCCESS;
+  } else {
+    LLCP_TRACE_ERROR0("llcp_util_send_frmr (): Out of resource");
+    return LLCP_STATUS_FAIL;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_send_rr_rnr
+**
+** Description      Send RR or RNR PDU
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_util_send_rr_rnr(tLLCP_DLCB* p_dlcb) {
+  NFC_HDR* p_msg;
+  uint8_t* p;
+  uint8_t pdu_type;
+  uint8_t pdu_size;
+  uint8_t rcv_seq;
+
+  /* if no indication of change in local busy or rx congestion */
+  if ((p_dlcb->flags & LLCP_DATA_LINK_FLAG_PENDING_RR_RNR) == 0) {
+    /* if all ack is sent */
+    if (p_dlcb->sent_ack_seq == p_dlcb->next_rx_seq) {
+      /* we don't need to send RR/RNR */
+      return;
+    } else {
+      /* if rx flow off because of local busy or congestion */
+      if ((p_dlcb->local_busy) || (p_dlcb->is_rx_congested) ||
+          (llcp_cb.overall_rx_congested)) {
+        /* don't send RR/RNR */
+        return;
+      }
+    }
+  }
+
+  if ((p_dlcb->local_busy) || (p_dlcb->is_rx_congested) ||
+      (llcp_cb.overall_rx_congested)) {
+    LLCP_TRACE_DEBUG3(
+        "llcp_util_send_rr_rnr (): "
+        "local_busy=%d,is_rx_congested=%d,overall_rx_congested=%d",
+        p_dlcb->local_busy, p_dlcb->is_rx_congested,
+        llcp_cb.overall_rx_congested);
+
+    /* if local_busy or rx congested then do not update receive sequence number
+     * to flow off */
+    pdu_type = LLCP_PDU_RNR_TYPE;
+    pdu_size = LLCP_PDU_RNR_SIZE;
+    rcv_seq = p_dlcb->sent_ack_seq;
+  } else {
+    pdu_type = LLCP_PDU_RR_TYPE;
+    pdu_size = LLCP_PDU_RR_SIZE;
+
+    p_dlcb->sent_ack_seq = p_dlcb->next_rx_seq;
+    rcv_seq = p_dlcb->sent_ack_seq;
+  }
+
+  p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
+
+  if (p_msg) {
+    p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
+
+    p_msg->len = pdu_size;
+    p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+    p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+
+    UINT16_TO_BE_STREAM(p, LLCP_GET_PDU_HEADER(p_dlcb->remote_sap, pdu_type,
+                                               p_dlcb->local_sap));
+
+    UINT8_TO_BE_STREAM(p, rcv_seq);
+
+#if (BT_TRACE_VERBOSE == true)
+    LLCP_TRACE_DEBUG5("LLCP TX - N(S,R):(NA,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
+                      p_dlcb->next_rx_seq, p_dlcb->next_tx_seq,
+                      p_dlcb->rcvd_ack_seq, p_dlcb->next_rx_seq,
+                      p_dlcb->sent_ack_seq);
+#endif
+    GKI_enqueue(&llcp_cb.lcb.sig_xmit_q, p_msg);
+    llcp_link_check_send_data();
+  } else {
+    LLCP_TRACE_ERROR0("llcp_util_send_rr_rnr (): Out of resource");
+  }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_get_app_cb
+**
+** Description      get pointer of application registered control block by SAP
+**
+** Returns          tLLCP_APP_CB *
+**
+*******************************************************************************/
+tLLCP_APP_CB* llcp_util_get_app_cb(uint8_t local_sap) {
+  tLLCP_APP_CB* p_app_cb = NULL;
+
+  if (local_sap <= LLCP_UPPER_BOUND_WK_SAP) {
+    if ((local_sap != LLCP_SAP_LM) && (local_sap < LLCP_MAX_WKS)) {
+      p_app_cb = &llcp_cb.wks_cb[local_sap];
+    }
+  } else if (local_sap <= LLCP_UPPER_BOUND_SDP_SAP) {
+    if (local_sap - LLCP_LOWER_BOUND_SDP_SAP < LLCP_MAX_SERVER) {
+      p_app_cb = &llcp_cb.server_cb[local_sap - LLCP_LOWER_BOUND_SDP_SAP];
+    }
+  } else if (local_sap <= LLCP_UPPER_BOUND_LOCAL_SAP) {
+    if (local_sap - LLCP_LOWER_BOUND_LOCAL_SAP < LLCP_MAX_CLIENT) {
+      p_app_cb = &llcp_cb.client_cb[local_sap - LLCP_LOWER_BOUND_LOCAL_SAP];
+    }
+  }
+
+  return (p_app_cb);
+}
diff --git a/src/nfc/nci/nci_hmsgs.c b/src/nfc/nci/nci_hmsgs.c
new file mode 100644
index 0000000..913fe15
--- /dev/null
+++ b/src/nfc/nci/nci_hmsgs.c
@@ -0,0 +1,850 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains function of the NCI unit to format and send NCI
+ *  commands (for DH).
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+
+#include "nci_defs.h"
+#include "nci_hmsgs.h"
+#include "nfc_api.h"
+#include "nfc_int.h"
+/*******************************************************************************
+**
+** Function         nci_snd_core_reset
+**
+** Description      compose and send CORE RESET command to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+uint8_t nci_snd_core_reset(uint8_t reset_type) {
+  NFC_HDR* p;
+  uint8_t* pp;
+
+  p = NCI_GET_CMD_BUF(NCI_CORE_PARAM_SIZE_RESET);
+  if (p == NULL) return (NCI_STATUS_FAILED);
+
+  p->event = BT_EVT_TO_NFC_NCI;
+  p->len = NCI_MSG_HDR_SIZE + NCI_CORE_PARAM_SIZE_RESET;
+  p->offset = NCI_MSG_OFFSET_SIZE;
+  p->layer_specific = 0;
+  pp = (uint8_t*)(p + 1) + p->offset;
+
+  NCI_MSG_BLD_HDR0(pp, NCI_MT_CMD, NCI_GID_CORE);
+  NCI_MSG_BLD_HDR1(pp, NCI_MSG_CORE_RESET);
+  UINT8_TO_STREAM(pp, NCI_CORE_PARAM_SIZE_RESET);
+  UINT8_TO_STREAM(pp, reset_type);
+
+  nfc_ncif_send_cmd(p);
+  return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nci_snd_core_init
+**
+** Description      compose and send CORE INIT command to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+uint8_t nci_snd_core_init(uint8_t nci_version) {
+  NFC_HDR* p;
+  uint8_t* pp;
+  p = NCI_GET_CMD_BUF(NCI_CORE_PARAM_SIZE_INIT(nci_version));
+  if (p == NULL) return (NCI_STATUS_FAILED);
+
+  p->event = BT_EVT_TO_NFC_NCI;
+  p->len = NCI_MSG_HDR_SIZE + NCI_CORE_PARAM_SIZE_INIT(nci_version);
+  p->offset = NCI_MSG_OFFSET_SIZE;
+  p->layer_specific = 0;
+  pp = (uint8_t*)(p + 1) + p->offset;
+
+  NCI_MSG_BLD_HDR0(pp, NCI_MT_CMD, NCI_GID_CORE);
+  NCI_MSG_BLD_HDR1(pp, NCI_MSG_CORE_INIT);
+  UINT8_TO_STREAM(pp, NCI_CORE_PARAM_SIZE_INIT(nci_version));
+  if(nfc_cb.nci_version == NCI_VERSION_2_0) {
+    UINT8_TO_STREAM(pp, NCI2_0_CORE_INIT_CMD_BYTE_0);
+    UINT8_TO_STREAM(pp, NCI2_0_CORE_INIT_CMD_BYTE_1);
+  }
+  nfc_ncif_send_cmd(p);
+  return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nci_snd_set_power_sub_state_cmd
+**
+** Description      compose and send core CORE_SET_POWER_SUB_STATE command
+**                  to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+uint8_t nci_snd_core_set_power_sub_state(uint8_t screen_state)
+{
+  NFC_HDR *p;
+  uint8_t *pp;
+
+  if ((p = NCI_GET_CMD_BUF(NCI_CORE_PARAM_SIZE_SET_POWER_SUB_STATE)) == NULL)
+    return (NCI_STATUS_FAILED);
+
+  p->event            = BT_EVT_TO_NFC_NCI;
+  p->offset           = NCI_MSG_OFFSET_SIZE;
+  p->len              = NCI_MSG_HDR_SIZE + NCI_CORE_PARAM_SIZE_SET_POWER_SUB_STATE;
+  p->layer_specific   = 0;
+  pp                  = (uint8_t *) (p + 1) + p->offset;
+
+  NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_CORE);
+  NCI_MSG_BLD_HDR1 (pp, NCI_MSG_CORE_SET_POWER_SUB_STATE);
+  UINT8_TO_STREAM (pp, NCI_CORE_PARAM_SIZE_SET_POWER_SUB_STATE);
+  UINT8_TO_STREAM (pp, screen_state);
+
+  nfc_ncif_send_cmd (p);
+
+  return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nci_snd_core_get_config
+**
+** Description      compose and send CORE GET_CONFIG command to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+uint8_t nci_snd_core_get_config(uint8_t* param_ids, uint8_t num_ids) {
+  NFC_HDR* p;
+  uint8_t* pp;
+#if (NXP_EXTNS == TRUE)
+  uint8_t bytes;
+  uint8_t propConfigCnt;
+#endif
+
+  p = NCI_GET_CMD_BUF(num_ids);
+  if (p == NULL) return (NCI_STATUS_FAILED);
+#if (NXP_EXTNS == TRUE)
+  uint32_t idx = 0;
+  uint8_t* params = param_ids;
+  propConfigCnt = 0;
+  for (idx = 0; idx < num_ids; idx++) {
+    if (*params == 0xA0) {
+      params++;
+      propConfigCnt++;
+    }
+    params++;
+  }
+  bytes = (num_ids - propConfigCnt) + (propConfigCnt << 1);
+#endif
+
+  p->event = BT_EVT_TO_NFC_NCI;
+#if (NXP_EXTNS == TRUE)
+  p->len = NCI_MSG_HDR_SIZE + bytes + 1;
+#else
+  p->len = NCI_MSG_HDR_SIZE + num_ids + 1;
+#endif
+
+  p->offset = NCI_MSG_OFFSET_SIZE;
+  p->layer_specific = 0;
+  pp = (uint8_t*)(p + 1) + p->offset;
+
+  NCI_MSG_BLD_HDR0(pp, NCI_MT_CMD, NCI_GID_CORE);
+  NCI_MSG_BLD_HDR1(pp, NCI_MSG_CORE_GET_CONFIG);
+#if (NXP_EXTNS == TRUE)
+  UINT8_TO_STREAM(pp, (uint8_t)(bytes + 1));
+#else
+  UINT8_TO_STREAM(pp, (uint8_t)(num_ids + 1));
+#endif
+  UINT8_TO_STREAM(pp, num_ids);
+#if (NXP_EXTNS == TRUE)
+  ARRAY_TO_STREAM(pp, param_ids, bytes);
+#else
+  ARRAY_TO_STREAM(pp, param_ids, num_ids);
+#endif
+
+  nfc_ncif_send_cmd(p);
+  return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nci_snd_core_set_config
+**
+** Description      compose and send CORE SET_CONFIG command to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+uint8_t nci_snd_core_set_config(uint8_t* p_param_tlvs, uint8_t tlv_size) {
+  NFC_HDR* p;
+  uint8_t* pp;
+  uint8_t num = 0, ulen, len, *pt;
+
+  p = NCI_GET_CMD_BUF(tlv_size + 1);
+  if (p == NULL) return (NCI_STATUS_FAILED);
+
+  p->event = BT_EVT_TO_NFC_NCI;
+  p->len = NCI_MSG_HDR_SIZE + tlv_size + 1;
+  p->offset = NCI_MSG_OFFSET_SIZE;
+  pp = (uint8_t*)(p + 1) + p->offset;
+
+  NCI_MSG_BLD_HDR0(pp, NCI_MT_CMD, NCI_GID_CORE);
+  NCI_MSG_BLD_HDR1(pp, NCI_MSG_CORE_SET_CONFIG);
+  UINT8_TO_STREAM(pp, (uint8_t)(tlv_size + 1));
+  len = tlv_size;
+  pt = p_param_tlvs;
+  while (len > 1) {
+    len -= 2;
+    pt++;
+    num++;
+    ulen = *pt++;
+    pt += ulen;
+    if (len >= ulen) {
+      len -= ulen;
+    } else {
+      GKI_freebuf(p);
+      return NCI_STATUS_FAILED;
+    }
+  }
+
+  UINT8_TO_STREAM(pp, num);
+  ARRAY_TO_STREAM(pp, p_param_tlvs, tlv_size);
+  nfc_ncif_send_cmd(p);
+
+  return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nci_snd_core_conn_create
+**
+** Description      compose and send CORE CONN_CREATE command to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+uint8_t nci_snd_core_conn_create(uint8_t dest_type, uint8_t num_tlv,
+                                 uint8_t tlv_size, uint8_t* p_param_tlvs) {
+  NFC_HDR* p;
+  uint8_t* pp;
+  uint8_t size = NCI_CORE_PARAM_SIZE_CON_CREATE + tlv_size;
+
+  p = NCI_GET_CMD_BUF(size);
+  if (p == NULL) return (NCI_STATUS_FAILED);
+
+  p->event = BT_EVT_TO_NFC_NCI;
+  p->len = NCI_MSG_HDR_SIZE + NCI_CORE_PARAM_SIZE_CON_CREATE;
+  p->offset = NCI_MSG_OFFSET_SIZE;
+  p->layer_specific = 0;
+  pp = (uint8_t*)(p + 1) + p->offset;
+
+  NCI_MSG_BLD_HDR0(pp, NCI_MT_CMD, NCI_GID_CORE);
+  NCI_MSG_BLD_HDR1(pp, NCI_MSG_CORE_CONN_CREATE);
+  UINT8_TO_STREAM(pp, size);
+  UINT8_TO_STREAM(pp, dest_type);
+  UINT8_TO_STREAM(pp, num_tlv);
+  if (tlv_size) {
+    ARRAY_TO_STREAM(pp, p_param_tlvs, tlv_size);
+    p->len += tlv_size;
+  }
+
+  nfc_ncif_send_cmd(p);
+  return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nci_snd_core_conn_close
+**
+** Description      compose and send CORE CONN_CLOSE command to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+uint8_t nci_snd_core_conn_close(uint8_t conn_id) {
+  NFC_HDR* p;
+  uint8_t* pp;
+
+  p = NCI_GET_CMD_BUF(NCI_CORE_PARAM_SIZE_CON_CLOSE);
+  if (p == NULL) return (NCI_STATUS_FAILED);
+
+  p->event = BT_EVT_TO_NFC_NCI;
+  p->len = NCI_MSG_HDR_SIZE + NCI_CORE_PARAM_SIZE_CON_CLOSE;
+  p->offset = NCI_MSG_OFFSET_SIZE;
+  p->layer_specific = 0;
+  pp = (uint8_t*)(p + 1) + p->offset;
+
+  NCI_MSG_BLD_HDR0(pp, NCI_MT_CMD, NCI_GID_CORE);
+  NCI_MSG_BLD_HDR1(pp, NCI_MSG_CORE_CONN_CLOSE);
+  UINT8_TO_STREAM(pp, NCI_CORE_PARAM_SIZE_CON_CLOSE);
+  UINT8_TO_STREAM(pp, conn_id);
+
+  nfc_ncif_send_cmd(p);
+  return (NCI_STATUS_OK);
+}
+
+#if (NFC_NFCEE_INCLUDED == true)
+#if (NFC_RW_ONLY == FALSE)
+/*******************************************************************************
+**
+** Function         nci_snd_nfcee_discover
+**
+** Description      compose and send NFCEE Management NFCEE_DISCOVER command
+**                  to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+uint8_t nci_snd_nfcee_discover(uint8_t discover_action) {
+  NFC_HDR* p;
+  uint8_t* pp;
+
+  p = NCI_GET_CMD_BUF(NCI_PARAM_SIZE_DISCOVER_NFCEE(nfc_cb.nci_version));
+  if (p == NULL) return (NCI_STATUS_FAILED);
+
+  p->event = BT_EVT_TO_NFC_NCI;
+  p->len = NCI_MSG_HDR_SIZE +NCI_PARAM_SIZE_DISCOVER_NFCEE(nfc_cb.nci_version);
+  p->offset = NCI_MSG_OFFSET_SIZE;
+  p->layer_specific = 0;
+  pp = (uint8_t*)(p + 1) + p->offset;
+
+  NCI_MSG_BLD_HDR0(pp, NCI_MT_CMD, NCI_GID_EE_MANAGE);
+  NCI_MSG_BLD_HDR1(pp, NCI_MSG_NFCEE_DISCOVER);
+  UINT8_TO_STREAM(pp, NCI_PARAM_SIZE_DISCOVER_NFCEE(nfc_cb.nci_version));
+  if(nfc_cb.nci_version != NCI_VERSION_2_0) {
+    UINT8_TO_STREAM(pp, discover_action);
+  }
+  nfc_ncif_send_cmd(p);
+  return (NCI_STATUS_OK);
+}
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         nci_snd_pwr_nd_lnk_ctrl_cmd
+**
+** Description      CMD for NFCC which manages the power supply and
+**                  communication links between the NFCC and its connected
+*NFCEEs.
+**
+** Returns          status
+**
+*******************************************************************************/
+uint8_t nci_snd_pwr_nd_lnk_ctrl_cmd(uint8_t nfcee_id, uint8_t cfg_value) {
+    NFC_TRACE_DEBUG0("nci_snd_pwr_nd_lnk_ctrl_cmd() Enter ");
+    if(!nfcFL.eseFL._WIRED_MODE_STANDBY) {
+        NFC_TRACE_DEBUG0("WIRED_MODE_STANDBY not available. Returning");
+        return (NCI_STATUS_FAILED);
+    }
+  NFC_HDR* p;
+  uint8_t* pp;
+  if (nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME ==
+          nfcFL.eseFL._ESE_WIRED_MODE_RESUME) {
+      if (nfc_cb.bBlkPwrlinkAndModeSetCmd) {
+          NFC_TRACE_DEBUG0("pwr link cmd ignored due to RF session");
+          nfc_cb.pwr_link_cmd.bPwrLinkCmdRequested = true;
+          nfc_cb.pwr_link_cmd.param = cfg_value;
+          nfc_start_quick_timer(&nfc_cb.nci_wait_pwrLinkRsp_timer,
+                  NFC_TTYPE_PWR_LINK_RSP,
+                  ((uint32_t)100) * QUICK_TIMER_TICKS_PER_SEC / 1000);
+          return (NCI_STATUS_OK);
+      }
+  }
+  if ((p = NCI_GET_CMD_BUF(nfcFL.nfcMwFL._NCI_PWR_LINK_PARAM_CMD_SIZE)) == NULL)
+    return (NCI_STATUS_FAILED);
+
+  p->event = BT_EVT_TO_NFC_NCI;
+  p->len = NCI_MSG_HDR_SIZE + nfcFL.nfcMwFL._NCI_PWR_LINK_PARAM_CMD_SIZE;
+  p->offset = NCI_MSG_OFFSET_SIZE;
+  p->layer_specific = 0;
+  pp = (uint8_t*)(p + 1) + p->offset;
+
+  NCI_MSG_BLD_HDR0(pp, NCI_MT_CMD, NCI_GID_EE_MANAGE);
+  NCI_MSG_BLD_HDR1(pp, NCI_MSG_NFCEE_PWR_LNK_CTRL);
+  UINT8_TO_STREAM(pp, nfcFL.nfcMwFL._NCI_PWR_LINK_PARAM_CMD_SIZE);
+  UINT8_TO_STREAM(pp, nfcee_id);
+  UINT8_TO_STREAM(pp, cfg_value);
+
+  nfc_ncif_send_cmd(p);
+  return (NCI_STATUS_OK);
+}
+#endif
+/*******************************************************************************
+**
+** Function         nci_snd_nfcee_mode_set
+**
+** Description      compose and send NFCEE Management NFCEE MODE SET command
+**                  to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+uint8_t nci_snd_nfcee_mode_set(uint8_t nfcee_id, uint8_t nfcee_mode) {
+  NFC_HDR* p;
+  uint8_t* pp;
+  if (nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME ==
+          nfcFL.eseFL._ESE_WIRED_MODE_RESUME) {
+      if ((nfc_cb.bBlkPwrlinkAndModeSetCmd) && (NFCEE_ID_ESE == nfcee_id)) {
+          NFC_TRACE_DEBUG0("mode set cmd ignored due to RF session");
+          nfc_start_quick_timer(&nfc_cb.nci_wait_pwrLinkRsp_timer,
+                  NFC_TTYPE_SET_MODE_RSP,
+                  ((uint32_t)100) * QUICK_TIMER_TICKS_PER_SEC / 1000);
+          nfc_cb.bSetmodeOnReq = true;
+          return NCI_STATUS_OK;
+      }
+  }
+  p = NCI_GET_CMD_BUF(NCI_CORE_PARAM_SIZE_NFCEE_MODE_SET);
+  if (p == NULL) return (NCI_STATUS_FAILED);
+
+  p->event = BT_EVT_TO_NFC_NCI;
+  p->len = NCI_MSG_HDR_SIZE + NCI_CORE_PARAM_SIZE_NFCEE_MODE_SET;
+  p->offset = NCI_MSG_OFFSET_SIZE;
+  p->layer_specific = 0;
+  pp = (uint8_t*)(p + 1) + p->offset;
+
+  NCI_MSG_BLD_HDR0(pp, NCI_MT_CMD, NCI_GID_EE_MANAGE);
+  NCI_MSG_BLD_HDR1(pp, NCI_MSG_NFCEE_MODE_SET);
+  UINT8_TO_STREAM(pp, NCI_CORE_PARAM_SIZE_NFCEE_MODE_SET);
+  UINT8_TO_STREAM(pp, nfcee_id);
+  UINT8_TO_STREAM(pp, nfcee_mode);
+
+  nfc_ncif_send_cmd(p);
+  return (NCI_STATUS_OK);
+}
+#endif
+#endif
+
+/*******************************************************************************
+**
+** Function         nci_snd_discover_cmd
+**
+** Description      compose and send RF Management DISCOVER command to command
+**                  queue
+**
+** Returns          status
+**
+*******************************************************************************/
+uint8_t nci_snd_discover_cmd(uint8_t num, tNCI_DISCOVER_PARAMS* p_param) {
+  NFC_HDR* p;
+  uint8_t* pp, *p_size, *p_start;
+  int xx;
+  int size;
+
+#if (NXP_EXTNS == TRUE)
+  if (NULL == p_param) {
+    return NCI_STATUS_FAILED;
+  }
+#endif
+
+  size = num * sizeof(tNCI_DISCOVER_PARAMS) + 1;
+  p = NCI_GET_CMD_BUF(size);
+  if (p == NULL) return (NCI_STATUS_FAILED);
+
+  p->event = BT_EVT_TO_NFC_NCI;
+  p->offset = NCI_MSG_OFFSET_SIZE;
+  p->layer_specific = 0;
+  pp = (uint8_t*)(p + 1) + p->offset;
+
+  NCI_MSG_BLD_HDR0(pp, NCI_MT_CMD, NCI_GID_RF_MANAGE);
+  NCI_MSG_BLD_HDR1(pp, NCI_MSG_RF_DISCOVER);
+  p_size = pp;
+  pp++;
+  p_start = pp;
+  UINT8_TO_STREAM(pp, num);
+  for (xx = 0; xx < num; xx++) {
+    UINT8_TO_STREAM(pp, p_param[xx].type);
+    UINT8_TO_STREAM(pp, p_param[xx].frequency);
+  }
+  *p_size = (uint8_t)(pp - p_start);
+  p->len = NCI_MSG_HDR_SIZE + *p_size;
+
+  nfc_ncif_send_cmd(p);
+  return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nci_snd_discover_select_cmd
+**
+** Description      compose and send RF Management DISCOVER SELECT command
+**                  to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+uint8_t nci_snd_discover_select_cmd(uint8_t rf_disc_id, uint8_t protocol,
+                                    uint8_t rf_interface) {
+  NFC_HDR* p;
+  uint8_t* pp;
+
+  p = NCI_GET_CMD_BUF(NCI_DISCOVER_PARAM_SIZE_SELECT);
+  if (p == NULL) return (NCI_STATUS_FAILED);
+
+  p->event = BT_EVT_TO_NFC_NCI;
+  p->len = NCI_MSG_HDR_SIZE + NCI_DISCOVER_PARAM_SIZE_SELECT;
+  p->offset = NCI_MSG_OFFSET_SIZE;
+  p->layer_specific = 0;
+  pp = (uint8_t*)(p + 1) + p->offset;
+
+  NCI_MSG_BLD_HDR0(pp, NCI_MT_CMD, NCI_GID_RF_MANAGE);
+  NCI_MSG_BLD_HDR1(pp, NCI_MSG_RF_DISCOVER_SELECT);
+  UINT8_TO_STREAM(pp, NCI_DISCOVER_PARAM_SIZE_SELECT);
+  UINT8_TO_STREAM(pp, rf_disc_id);
+  UINT8_TO_STREAM(pp, protocol);
+  UINT8_TO_STREAM(pp, rf_interface);
+
+  nfc_ncif_send_cmd(p);
+  return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nci_snd_deactivate_cmd
+**
+** Description      compose and send RF Management DEACTIVATE command
+**                  to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+uint8_t nci_snd_deactivate_cmd(uint8_t de_act_type) {
+  NFC_HDR* p;
+  uint8_t* pp;
+
+  nfc_cb.reassembly = true;
+
+  p = NCI_GET_CMD_BUF(NCI_DISCOVER_PARAM_SIZE_DEACT);
+  if (p == NULL) return (NCI_STATUS_FAILED);
+
+  p->event = BT_EVT_TO_NFC_NCI;
+  p->len = NCI_MSG_HDR_SIZE + NCI_DISCOVER_PARAM_SIZE_DEACT;
+  p->offset = NCI_MSG_OFFSET_SIZE;
+  p->layer_specific = 0;
+  pp = (uint8_t*)(p + 1) + p->offset;
+
+  NCI_MSG_BLD_HDR0(pp, NCI_MT_CMD, NCI_GID_RF_MANAGE);
+  NCI_MSG_BLD_HDR1(pp, NCI_MSG_RF_DEACTIVATE);
+  UINT8_TO_STREAM(pp, NCI_DISCOVER_PARAM_SIZE_DEACT);
+  UINT8_TO_STREAM(pp, de_act_type);
+
+  nfc_ncif_send_cmd(p);
+  return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nci_snd_discover_map_cmd
+**
+** Description      compose and send RF Management DISCOVER MAP command
+**                  to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+uint8_t nci_snd_discover_map_cmd(uint8_t num, tNCI_DISCOVER_MAPS* p_maps) {
+  NFC_HDR* p;
+  uint8_t* pp, *p_size, *p_start;
+  int xx;
+  int size;
+
+  size = num * sizeof(tNCI_DISCOVER_MAPS) + 1;
+
+  p = NCI_GET_CMD_BUF(size);
+  if (p == NULL) return (NCI_STATUS_FAILED);
+
+  p->event = BT_EVT_TO_NFC_NCI;
+  p->offset = NCI_MSG_OFFSET_SIZE;
+  p->layer_specific = 0;
+  pp = (uint8_t*)(p + 1) + p->offset;
+
+  NCI_MSG_BLD_HDR0(pp, NCI_MT_CMD, NCI_GID_RF_MANAGE);
+  NCI_MSG_BLD_HDR1(pp, NCI_MSG_RF_DISCOVER_MAP);
+  p_size = pp;
+  pp++;
+  p_start = pp;
+  UINT8_TO_STREAM(pp, num);
+  for (xx = 0; xx < num; xx++) {
+    UINT8_TO_STREAM(pp, p_maps[xx].protocol);
+    UINT8_TO_STREAM(pp, p_maps[xx].mode);
+    UINT8_TO_STREAM(pp, p_maps[xx].intf_type);
+  }
+  *p_size = (uint8_t)(pp - p_start);
+  p->len = NCI_MSG_HDR_SIZE + *p_size;
+  nfc_ncif_send_cmd(p);
+  return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nci_snd_t3t_polling
+**
+** Description      compose and send RF Management T3T POLLING command
+**                  to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+uint8_t nci_snd_t3t_polling(uint16_t system_code, uint8_t rc, uint8_t tsn) {
+  NFC_HDR* p;
+  uint8_t* pp;
+
+  p = NCI_GET_CMD_BUF(NCI_RF_PARAM_SIZE_T3T_POLLING);
+  if (p == NULL) return (NCI_STATUS_FAILED);
+
+  p->event = BT_EVT_TO_NFC_NCI;
+  p->len = NCI_MSG_HDR_SIZE + NCI_RF_PARAM_SIZE_T3T_POLLING;
+  p->offset = NCI_MSG_OFFSET_SIZE;
+  p->layer_specific = 0;
+  pp = (uint8_t*)(p + 1) + p->offset;
+
+  NCI_MSG_BLD_HDR0(pp, NCI_MT_CMD, NCI_GID_RF_MANAGE);
+  NCI_MSG_BLD_HDR1(pp, NCI_MSG_RF_T3T_POLLING);
+  UINT8_TO_STREAM(pp, NCI_RF_PARAM_SIZE_T3T_POLLING);
+  UINT16_TO_BE_STREAM(pp, system_code);
+  UINT8_TO_STREAM(pp, rc);
+  UINT8_TO_STREAM(pp, tsn);
+
+  nfc_ncif_send_cmd(p);
+  return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nci_snd_parameter_update_cmd
+**
+** Description      compose and send RF Management RF Communication Parameter
+**                  Update commandto command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+uint8_t nci_snd_parameter_update_cmd(uint8_t* p_param_tlvs, uint8_t tlv_size) {
+  NFC_HDR* p;
+  uint8_t* pp;
+  uint8_t num = 0, ulen, len, *pt;
+
+  // p_param_tlvs can take max 12 elements
+  if (tlv_size > 12) return (NCI_STATUS_FAILED);
+
+  p = NCI_GET_CMD_BUF(tlv_size + 1);
+  if (p == NULL) return (NCI_STATUS_FAILED);
+
+  p->event = BT_EVT_TO_NFC_NCI;
+  p->len = NCI_MSG_HDR_SIZE + tlv_size + 1;
+  p->offset = NCI_MSG_OFFSET_SIZE;
+  pp = (uint8_t*)(p + 1) + p->offset;
+
+  NCI_MSG_BLD_HDR0(pp, NCI_MT_CMD, NCI_GID_RF_MANAGE);
+  NCI_MSG_BLD_HDR1(pp, NCI_MSG_RF_PARAMETER_UPDATE);
+  UINT8_TO_STREAM(pp, (uint8_t)(tlv_size + 1));
+  len = tlv_size;
+  pt = p_param_tlvs;
+  while (len > 1) {
+    len -= 2;
+    pt++;
+    num++;
+    ulen = *pt++;
+    pt += ulen;
+    if (len >= ulen) {
+      len -= ulen;
+    } else {
+      GKI_freebuf(p);
+      return NCI_STATUS_FAILED;
+    }
+  }
+
+  UINT8_TO_STREAM(pp, num);
+  ARRAY_TO_STREAM(pp, p_param_tlvs, tlv_size);
+  nfc_ncif_send_cmd(p);
+
+  return (NCI_STATUS_OK);
+}
+
+#if (NFC_NFCEE_INCLUDED == true)
+#if (NFC_RW_ONLY == FALSE)
+/*******************************************************************************
+**
+** Function         nci_snd_set_routing_cmd
+**
+** Description      compose and send RF Management SET_LISTEN_MODE_ROUTING
+**                  command to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+uint8_t nci_snd_set_routing_cmd(bool more, uint8_t num_tlv, uint8_t tlv_size,
+                                uint8_t* p_param_tlvs) {
+  NFC_HDR* p;
+  uint8_t* pp;
+  uint8_t size = tlv_size + 2;
+
+  if (tlv_size == 0) {
+    /* just to terminate routing table
+     * 2 bytes (more=false and num routing entries=0) */
+    size = 2;
+  }
+
+  p = NCI_GET_CMD_BUF(size);
+  if (p == NULL) return (NCI_STATUS_FAILED);
+
+  p->event = BT_EVT_TO_NFC_NCI;
+  p->offset = NCI_MSG_OFFSET_SIZE;
+  p->len = NCI_MSG_HDR_SIZE + size;
+  p->layer_specific = 0;
+  pp = (uint8_t*)(p + 1) + p->offset;
+
+  NCI_MSG_BLD_HDR0(pp, NCI_MT_CMD, NCI_GID_RF_MANAGE);
+  NCI_MSG_BLD_HDR1(pp, NCI_MSG_RF_SET_ROUTING);
+  UINT8_TO_STREAM(pp, size);
+  UINT8_TO_STREAM(pp, more);
+  if (size == 2) {
+    UINT8_TO_STREAM(pp, 0);
+  } else {
+    UINT8_TO_STREAM(pp, num_tlv);
+    ARRAY_TO_STREAM(pp, p_param_tlvs, tlv_size);
+  }
+  nfc_ncif_send_cmd(p);
+
+  return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nci_snd_get_routing_cmd
+**
+** Description      compose and send RF Management GET_LISTEN_MODE_ROUTING
+**                  command to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+uint8_t nci_snd_get_routing_cmd(void) {
+  NFC_HDR* p;
+  uint8_t* pp;
+  uint8_t param_size = 0;
+
+  p = NCI_GET_CMD_BUF(param_size);
+  if (p == NULL) return (NCI_STATUS_FAILED);
+
+  p->event = BT_EVT_TO_NFC_NCI;
+  p->len = NCI_MSG_HDR_SIZE + param_size;
+  p->offset = NCI_MSG_OFFSET_SIZE;
+  p->layer_specific = 0;
+  pp = (uint8_t*)(p + 1) + p->offset;
+
+  NCI_MSG_BLD_HDR0(pp, NCI_MT_CMD, NCI_GID_RF_MANAGE);
+  NCI_MSG_BLD_HDR1(pp, NCI_MSG_RF_GET_ROUTING);
+  UINT8_TO_STREAM(pp, param_size);
+
+  nfc_ncif_send_cmd(p);
+  return (NCI_STATUS_OK);
+}
+#endif
+/*******************************************************************************
+**
+** Function         nci_snd_nfcee_power_link_control
++**
+** Description      compose and send NFCEE Management NFCEE Power and Link
+**                  Control command to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+uint8_t nci_snd_nfcee_power_link_control (uint8_t nfcee_id, uint8_t pl_config)
+{
+    NFC_HDR *p;
+    uint8_t *pp;
+
+    if ((p = NCI_GET_CMD_BUF (NCI_CORE_PARAM_SIZE_NFCEE_PL_CTRL)) == NULL)
+        return (NCI_STATUS_FAILED);
+
+    p->event            = NFC_EVT_TO_NFC_NCI;
+    p->len              = NCI_MSG_HDR_SIZE + NCI_CORE_PARAM_SIZE_NFCEE_PL_CTRL;
+    p->offset           = NCI_MSG_OFFSET_SIZE;
+    p->layer_specific   = 0;
+    pp                  = (uint8_t *) (p + 1) + p->offset;
+
+    NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_EE_MANAGE);
+#if (NXP_EXTNS == TRUE) && (NXP_WIRED_MODE_STANDBY == true)
+    NCI_MSG_BLD_HDR1 (pp, NCI_MSG_NFCEE_POWER_LINK_CTRL);
+#endif
+    UINT8_TO_STREAM (pp, NCI_CORE_PARAM_SIZE_NFCEE_PL_CTRL);
+    UINT8_TO_STREAM (pp, nfcee_id);
+    UINT8_TO_STREAM (pp, pl_config);
+
+    nfc_ncif_send_cmd (p);
+    return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nci_snd_iso_dep_nak_presence_check_cmd
+**
+** Description      compose and send RF Management presence check ISO-DEP NAK
+**                  command.
+**
+**
+** Returns          status
+**
+*******************************************************************************/
+uint8_t nci_snd_iso_dep_nak_presence_check_cmd()
+{
+    NFC_HDR *p;
+    uint8_t *pp;
+
+    if ((p = NCI_GET_CMD_BUF(0)) == NULL) return (NCI_STATUS_FAILED);
+
+    p->event            = BT_EVT_TO_NFC_NCI;
+    p->offset           = NCI_MSG_OFFSET_SIZE;
+    p->len              = NCI_MSG_HDR_SIZE + 0;
+    p->layer_specific   = 0;
+    pp                  = (uint8_t *) (p + 1) + p->offset;
+
+    NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_RF_MANAGE);
+    NCI_MSG_BLD_HDR1 (pp, NCI_MSG_RF_ISO_DEP_NAK_PRESENCE);
+    UINT8_TO_STREAM(pp, 0x00);
+    nfc_ncif_send_cmd (p);
+    return (NCI_STATUS_OK);
+}
+#endif
+
diff --git a/src/nfc/nci/nci_hrcv.c b/src/nfc/nci/nci_hrcv.c
new file mode 100644
index 0000000..c99048e
--- /dev/null
+++ b/src/nfc/nci/nci_hrcv.c
@@ -0,0 +1,646 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains function of the NFC unit to receive/process NCI
+ *  commands.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "gki.h"
+
+#include "nci_defs.h"
+#include "nci_hmsgs.h"
+#include "nfc_api.h"
+#include "nfc_int.h"
+#if (NXP_EXTNS == TRUE)
+#include "nfa_sys.h"
+#endif
+#include "nfa_ee_int.h"
+/*******************************************************************************
+**
+** Function         nci_proc_core_rsp
+**
+** Description      Process NCI responses in the CORE group
+**
+** Returns          true-caller of this function to free the GKI buffer p_msg
+**
+*******************************************************************************/
+bool nci_proc_core_rsp(NFC_HDR* p_msg) {
+  uint8_t* p;
+  uint8_t* pp, len, op_code;
+  bool free = true;
+  uint8_t* p_old = nfc_cb.last_cmd;
+
+  /* find the start of the NCI message and parse the NCI header */
+  p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+  pp = p + 1;
+  NCI_MSG_PRS_HDR1(pp, op_code);
+  NFC_TRACE_DEBUG1("nci_proc_core_rsp opcode:0x%x", op_code);
+  len = *pp++;
+
+  /* process the message based on the opcode and message type */
+  switch (op_code) {
+    case NCI_MSG_CORE_RESET:
+      nfc_ncif_proc_reset_rsp(pp, false);
+      break;
+
+    case NCI_MSG_CORE_INIT:
+      nfc_ncif_proc_init_rsp(p_msg);
+      free = false;
+      break;
+
+    case NCI_MSG_CORE_GET_CONFIG:
+      nfc_ncif_proc_get_config_rsp(p_msg);
+      break;
+
+    case NCI_MSG_CORE_SET_CONFIG:
+      nfc_ncif_set_config_status(pp, len);
+      break;
+
+    case NCI_MSG_CORE_CONN_CREATE:
+      nfc_ncif_proc_conn_create_rsp(p, p_msg->len, *p_old);
+      break;
+
+    case NCI_MSG_CORE_CONN_CLOSE:
+      nfc_ncif_report_conn_close_evt(*p_old, *pp);
+      break;
+
+    case NCI_MSG_CORE_SET_POWER_SUB_STATE:
+      nfc_ncif_event_status(NFC_SET_POWER_SUB_STATE_REVT, *pp);
+      break;
+    default:
+      NFC_TRACE_ERROR1("unknown opcode:0x%x", op_code);
+      break;
+  }
+
+  return free;
+}
+
+/*******************************************************************************
+**
+** Function         nci_proc_core_ntf
+**
+** Description      Process NCI notifications in the CORE group
+**
+** Returns          void
+**
+*******************************************************************************/
+void nci_proc_core_ntf(NFC_HDR* p_msg) {
+  uint8_t* p;
+  uint8_t* pp, len, op_code;
+  uint8_t conn_id;
+
+  /* find the start of the NCI message and parse the NCI header */
+  p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+  pp = p + 1;
+  NCI_MSG_PRS_HDR1(pp, op_code);
+  NFC_TRACE_DEBUG1("nci_proc_core_ntf opcode:0x%x", op_code);
+  len = *pp++;
+
+  /* process the message based on the opcode and message type */
+  switch (op_code) {
+    case NCI_MSG_CORE_RESET:
+      nfc_ncif_proc_reset_rsp(pp, true);
+      break;
+
+    case NCI_MSG_CORE_GEN_ERR_STATUS:
+      /* process the error ntf */
+      /* in case of timeout: notify the static connection callback */
+      nfc_ncif_event_status(NFC_GEN_ERROR_REVT, *pp);
+      nfc_ncif_error_status(NFC_RF_CONN_ID, *pp);
+      break;
+
+    case NCI_MSG_CORE_INTF_ERR_STATUS:
+      conn_id = *(pp + 1);
+      nfc_ncif_error_status(conn_id, *pp);
+      break;
+
+    case NCI_MSG_CORE_CONN_CREDITS:
+      nfc_ncif_proc_credits(pp, len);
+      break;
+
+    default:
+      NFC_TRACE_ERROR1("unknown opcode:0x%x", op_code);
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nci_proc_rf_management_rsp
+**
+** Description      Process NCI responses in the RF Management group
+**
+** Returns          void
+**
+*******************************************************************************/
+void nci_proc_rf_management_rsp(NFC_HDR* p_msg) {
+  uint8_t* p;
+  uint8_t* pp, len, op_code;
+  uint8_t* p_old = nfc_cb.last_cmd;
+
+  /* find the start of the NCI message and parse the NCI header */
+  p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+  pp = p + 1;
+  NCI_MSG_PRS_HDR1(pp, op_code);
+  len = *pp++;
+
+  switch (op_code) {
+    case NCI_MSG_RF_DISCOVER:
+      nfa_dm_p2p_prio_logic(op_code, pp, NFA_DM_P2P_PRIO_RSP);
+      nfc_ncif_rf_management_status(NFC_START_DEVT, *pp);
+      break;
+
+    case NCI_MSG_RF_DISCOVER_SELECT:
+      nfc_ncif_rf_management_status(NFC_SELECT_DEVT, *pp);
+      break;
+
+    case NCI_MSG_RF_T3T_POLLING:
+      break;
+
+    case NCI_MSG_RF_DISCOVER_MAP:
+      nfc_ncif_rf_management_status(NFC_MAP_DEVT, *pp);
+      break;
+
+    case NCI_MSG_RF_DEACTIVATE:
+      if (false == nfa_dm_p2p_prio_logic(op_code, pp, NFA_DM_P2P_PRIO_RSP)) {
+        return;
+      }
+      nfc_ncif_proc_deactivate(*pp, *p_old, false);
+      break;
+
+#if (NFC_NFCEE_INCLUDED == true)
+#if (NFC_RW_ONLY == FALSE)
+
+    case NCI_MSG_RF_SET_ROUTING:
+      nfc_ncif_event_status(NFC_SET_ROUTING_REVT, *pp);
+      break;
+
+    case NCI_MSG_RF_GET_ROUTING:
+      if (*pp != NFC_STATUS_OK)
+        nfc_ncif_event_status(NFC_GET_ROUTING_REVT, *pp);
+      break;
+#endif
+#endif
+
+    case NCI_MSG_RF_PARAMETER_UPDATE:
+      nfc_ncif_event_status(NFC_RF_COMM_PARAMS_UPDATE_REVT, *pp);
+      break;
+
+    case NCI_MSG_RF_ISO_DEP_NAK_PRESENCE:
+      nfc_ncif_proc_isodep_nak_presence_check_status(*pp, false);
+      break;
+    default:
+      NFC_TRACE_ERROR1("unknown opcode:0x%x", op_code);
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nci_proc_rf_management_ntf
+**
+** Description      Process NCI notifications in the RF Management group
+**
+** Returns          void
+**
+*******************************************************************************/
+void nci_proc_rf_management_ntf(NFC_HDR* p_msg) {
+  uint8_t* p;
+  uint8_t* pp, len, op_code;
+
+  /* find the start of the NCI message and parse the NCI header */
+  p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+  pp = p + 1;
+  NCI_MSG_PRS_HDR1(pp, op_code);
+  len = *pp++;
+
+  switch (op_code) {
+    case NCI_MSG_RF_DISCOVER:
+      nfc_ncif_proc_discover_ntf(p, p_msg->len);
+      break;
+
+    case NCI_MSG_RF_DEACTIVATE:
+      if (false == nfa_dm_p2p_prio_logic(op_code, pp, NFA_DM_P2P_PRIO_NTF)) {
+        return;
+      }
+      nfc_ncif_proc_deactivate(NFC_STATUS_OK, *pp, true);
+      break;
+
+    case NCI_MSG_RF_INTF_ACTIVATED:
+      if (false == nfa_dm_p2p_prio_logic(op_code, pp, NFA_DM_P2P_PRIO_NTF)) {
+        return;
+      }
+      nfc_ncif_proc_activate(pp, len);
+      break;
+
+    case NCI_MSG_RF_FIELD:
+      nfc_ncif_proc_rf_field_ntf(*pp);
+      break;
+
+    case NCI_MSG_RF_T3T_POLLING:
+      nfc_ncif_proc_t3t_polling_ntf(pp, len);
+      break;
+
+#if (NFC_NFCEE_INCLUDED == true)
+#if (NFC_RW_ONLY == FALSE)
+
+    case NCI_MSG_RF_GET_ROUTING:
+      nfc_ncif_proc_get_routing(pp, len);
+      break;
+
+    case NCI_MSG_RF_EE_ACTION:
+      nfc_ncif_proc_ee_action(pp, len);
+      break;
+
+    case NCI_MSG_RF_EE_DISCOVERY_REQ:
+      nfc_ncif_proc_ee_discover_req(pp, len);
+      break;
+#endif
+#endif
+    case NCI_MSG_RF_ISO_DEP_NAK_PRESENCE:
+      nfc_ncif_proc_isodep_nak_presence_check_status(*pp, true);
+      break;
+    default:
+      NFC_TRACE_ERROR1("unknown opcode:0x%x", op_code);
+      break;
+  }
+}
+
+#if (NFC_NFCEE_INCLUDED == true)
+#if (NFC_RW_ONLY == FALSE)
+
+/*******************************************************************************
+**
+** Function         nci_proc_ee_management_rsp
+**
+** Description      Process NCI responses in the NFCEE Management group
+**
+** Returns          void
+**
+*******************************************************************************/
+void nci_proc_ee_management_rsp(NFC_HDR* p_msg) {
+  uint8_t* p;
+  uint8_t* pp, len, op_code;
+  tNFC_RESPONSE_CBACK* p_cback = nfc_cb.p_resp_cback;
+  tNFC_NFCEE_DISCOVER_REVT nfcee_discover;
+  tNFC_NFCEE_MODE_SET_REVT mode_set;
+  tNFC_NFCEE_PL_CONTROL_REVT  pl_control;
+#if (NXP_EXTNS == TRUE)
+  tNFC_NFCEE_MODE_SET_INFO mode_set_info;
+  tNFC_NFCEE_EE_PWR_LNK_REVT pwr_lnk_ctrl;
+
+#endif
+  void* p_evt = NULL;
+  tNFC_RESPONSE_EVT event = NFC_NFCEE_INFO_REVT;
+  uint8_t* p_old = nfc_cb.last_cmd;
+
+  /* find the start of the NCI message and parse the NCI header */
+  p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+  pp = p + 1;
+  NCI_MSG_PRS_HDR1(pp, op_code);
+  NFC_TRACE_DEBUG1("nci_proc_ee_management_rsp opcode:0x%x", op_code);
+  len = *pp++;
+
+  switch (op_code) {
+    case NCI_MSG_NFCEE_DISCOVER:
+      p_evt = (void*)&nfcee_discover;
+      nfcee_discover.status = *pp++;
+      nfcee_discover.num_nfcee = *pp++;
+
+      if (nfcee_discover.status != NFC_STATUS_OK) nfcee_discover.num_nfcee = 0;
+
+      event = NFC_NFCEE_DISCOVER_REVT;
+      break;
+
+    case NCI_MSG_NFCEE_MODE_SET:
+      p_evt = (void*)&mode_set;
+      mode_set.status = *pp;
+      mode_set.nfcee_id = 0;
+      event = NFC_NFCEE_MODE_SET_REVT;
+      mode_set.nfcee_id = *p_old++;
+      mode_set.mode = *p_old++;
+      if (nfc_cb.nci_version != NCI_VERSION_2_0 || *pp != NCI_STATUS_OK)
+      {
+          nfc_cb.flags  &= ~NFC_FL_WAIT_MODE_SET_NTF;
+          event               = NFC_NFCEE_MODE_SET_REVT;
+      }
+      else
+      {
+          /* else response reports OK status on notification */
+          return;
+      }
+      break;
+
+#if (NXP_EXTNS == TRUE)
+    case NCI_MSG_NFCEE_PWR_LNK_CTRL:
+        if(nfcFL.eseFL._WIRED_MODE_STANDBY) {
+            p_evt = (tNFC_RESPONSE*)&pwr_lnk_ctrl;
+            pwr_lnk_ctrl.status = *pp;
+            pwr_lnk_ctrl.nfcee_id = 0;
+            event = NFC_NFCEE_PWR_LNK_CTRL_REVT;
+            pwr_lnk_ctrl.nfcee_id = *p_old++;
+            if(nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME ==
+                    nfcFL.eseFL._ESE_WIRED_MODE_RESUME) {
+                if (nfc_cb.bIssueModeSetCmd) {
+                    NFC_TRACE_DEBUG0("mode set cmd send after pwrlink cmd");
+                    nfc_cb.bSetmodeOnReq = true;
+                    nci_snd_nfcee_mode_set(NFCEE_ID_ESE, NFC_MODE_ACTIVATE);
+                    nfc_start_timer(&nfc_cb.nci_wait_setMode_Ntf_timer,
+                            (uint16_t)NFC_TYPE_NCI_WAIT_SETMODE_NTF,
+                            NFC_NCI_SETMODE_NTF_TIMEOUT);
+                    nfc_cb.bIssueModeSetCmd = false;
+                } else {
+                    nfc_cb.bIssueModeSetCmd = false;
+                }
+            }
+            break;
+        }
+#endif
+    case NCI_MSG_NFCEE_POWER_LINK_CTRL:
+        p_evt                   = (tNFC_RESPONSE *) &pl_control;
+        pl_control.status        = *pp;
+        pl_control.nfcee_id      = *p_old++;
+        pl_control.pl_control    = *p_old++;
+        event               = NFC_NFCEE_PL_CONTROL_REVT;
+        break;
+    default:
+      p_cback = NULL;
+      NFC_TRACE_ERROR1("unknown opcode:0x%x", op_code);
+      break;
+  }
+
+  if (p_cback) (*p_cback)(event, p_evt);
+}
+
+/*******************************************************************************
+**
+** Function         nci_proc_ee_management_ntf
+**
+** Description      Process NCI notifications in the NFCEE Management group
+**
+** Returns          void
+**
+*******************************************************************************/
+void nci_proc_ee_management_ntf(NFC_HDR* p_msg) {
+  uint8_t* p;
+  uint8_t* pp, len, op_code;
+  tNFC_RESPONSE_CBACK* p_cback = nfc_cb.p_resp_cback;
+  tNFC_NFCEE_INFO_REVT nfcee_info;
+  void* p_evt = (void*)&nfcee_info;
+  tNFC_RESPONSE_EVT event = NFC_NFCEE_INFO_REVT;
+  uint8_t* p_old = nfc_cb.last_cmd;
+  uint8_t xx;
+  uint8_t yy;
+  uint8_t ee_status;
+  tNFC_NFCEE_TLV* p_tlv;
+#if (NXP_EXTNS == TRUE)
+  tNFC_NFCEE_MODE_SET_INFO mode_set_info;
+#endif
+  tNFC_NFCEE_MODE_SET_REVT    mode_set;
+  tNFC_NFCEE_STATUS_REVT      nfcee_status;
+  /* find the start of the NCI message and parse the NCI header */
+  p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+  pp = p + 1;
+  NCI_MSG_PRS_HDR1(pp, op_code);
+  NFC_TRACE_DEBUG1("nci_proc_ee_management_ntf opcode:0x%x", op_code);
+  len = *pp++;
+
+  if (op_code == NCI_MSG_NFCEE_DISCOVER) {
+    nfcee_info.nfcee_id = *pp++;
+    ee_status = *pp++;
+
+    nfcee_info.ee_status = ee_status;
+    yy = *pp;
+    nfcee_info.num_interface = *pp++;
+    p = pp;
+
+    if (nfcee_info.num_interface > NFC_MAX_EE_INTERFACE)
+      nfcee_info.num_interface = NFC_MAX_EE_INTERFACE;
+
+    for (xx = 0; xx < nfcee_info.num_interface; xx++) {
+      nfcee_info.ee_interface[xx] = *pp++;
+    }
+
+    pp = p + yy;
+    nfcee_info.num_tlvs = *pp++;
+    NFC_TRACE_DEBUG4("nfcee_id: 0x%x num_interface:0x%x/0x%x, num_tlvs:0x%x",
+                     nfcee_info.nfcee_id, nfcee_info.num_interface, yy,
+                     nfcee_info.num_tlvs);
+
+    if (nfcee_info.num_tlvs > NFC_MAX_EE_TLVS)
+      nfcee_info.num_tlvs = NFC_MAX_EE_TLVS;
+
+    p_tlv = &nfcee_info.ee_tlv[0];
+
+    for (xx = 0; xx < nfcee_info.num_tlvs; xx++, p_tlv++) {
+#if (NXP_EXTNS == TRUE)
+      if (*pp < 0xA0) {
+        p_tlv->tag = *pp++;
+      } else {
+        p_tlv->tag = *pp++;
+        p_tlv->tag = (p_tlv->tag << 8) | *pp++;
+      }
+#else
+      p_tlv->tag = *pp++;
+#endif
+      p_tlv->len = yy = *pp++;
+      NFC_TRACE_DEBUG2("tag:0x%x, len:0x%x", p_tlv->tag, p_tlv->len);
+      if (p_tlv->len > NFC_MAX_EE_INFO) p_tlv->len = NFC_MAX_EE_INFO;
+      p = pp;
+      STREAM_TO_ARRAY(p_tlv->info, pp, p_tlv->len);
+      pp = p += yy;
+    }
+  }
+#if (NXP_EXTNS == TRUE)
+  else if (op_code == NCI_MSG_NFCEE_MODE_SET) {
+      NFC_TRACE_DEBUG2("nci_proc_ee_management_ntf status:0x%x, nfceeid:0x%x",
+              *pp, *(pp + 1));
+      nfc_stop_timer(&nfc_cb.nci_wait_setMode_Ntf_timer);
+      if(nfc_cb.nci_version != NCI_VERSION_2_0)
+      {
+          p_evt = (tNFC_RESPONSE*)&mode_set_info;
+          event = NFC_NFCEE_MODE_SET_INFO;
+          ee_status = *pp++;
+          mode_set_info.nfcee_id = *pp++;
+          mode_set_info.status = ee_status;
+      }
+      else
+      {
+          NFC_TRACE_DEBUG2("nci_proc_ee_management_last ntf mode:0x%x, nfceeid:0x%x",
+                  mode_set.mode, mode_set.nfcee_id);
+          p_evt   = (tNFC_RESPONSE *) &mode_set;
+          mode_set.status = *pp;
+          /*mode_set.nfcee_id = *p_old++;
+      mode_set.mode = *p_old++;*/
+          mode_set.nfcee_id = nfa_ee_cb.nfcee_id;
+          mode_set.mode = nfa_ee_cb.mode;
+          event   = NFC_NFCEE_MODE_SET_REVT;
+          nfc_cb.flags  &= ~NFC_FL_WAIT_MODE_SET_NTF;
+          nfc_stop_timer(&nfc_cb.nci_setmode_ntf_timer);
+      }
+      if ((nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME ==
+              nfcFL.eseFL._ESE_WIRED_MODE_RESUME) &&
+              ((nfc_cb.bBlockWiredMode) && (nfc_cb.bSetmodeOnReq))) {
+          nfc_cb.bSetmodeOnReq = false;
+          nfc_cb.bBlockWiredMode = false;
+          nfc_cb.bCeActivatedeSE = false;
+          nfc_ncif_allow_dwp_transmission();
+      }
+  }
+#endif
+  else if (op_code == NCI_MSG_NFCEE_STATUS) {
+      p_evt   = (tNFC_RESPONSE *) &nfcee_status;
+      event   = NFC_NFCEE_STATUS_REVT;
+      nfcee_status.status         = NCI_STATUS_OK;
+      nfcee_status.nfcee_id       = *pp++;
+      nfcee_status.nfcee_status   = *pp;
+     }
+  else {
+    p_cback = NULL;
+    NFC_TRACE_ERROR1("unknown opcode:0x%x", op_code);
+  }
+
+  if (p_cback) (*p_cback)(event, p_evt);
+}
+
+#endif
+#endif
+
+/*******************************************************************************
+**
+** Function         nci_proc_prop_rsp
+**
+** Description      Process NCI responses in the Proprietary group
+**
+** Returns          void
+**
+*******************************************************************************/
+void nci_proc_prop_rsp(NFC_HDR* p_msg) {
+  uint8_t* p;
+  uint8_t* p_evt;
+  uint8_t* pp, len, op_code;
+  tNFC_VS_CBACK* p_cback = (tNFC_VS_CBACK*)nfc_cb.p_vsc_cback;
+
+  /* find the start of the NCI message and parse the NCI header */
+  p = p_evt = (uint8_t*)(p_msg + 1) + p_msg->offset;
+  pp = p + 1;
+  NCI_MSG_PRS_HDR1(pp, op_code);
+  len = *pp++;
+
+  /*If there's a pending/stored command, restore the associated address of the
+   * callback function */
+  if (p_cback)
+    (*p_cback)((tNFC_VS_EVT)(NCI_RSP_BIT | op_code), p_msg->len, p_evt);
+}
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         nci_proc_prop_nxp_rsp
+**
+** Description      Process NXP NCI responses
+**
+** Returns          void
+**
+*******************************************************************************/
+void nci_proc_prop_nxp_rsp(NFC_HDR* p_msg) {
+  uint8_t* p;
+  uint8_t* p_evt;
+  uint8_t* pp, len, op_code;
+  tNFC_VS_CBACK* p_cback = (tNFC_VS_CBACK*)nfc_cb.p_vsc_cback;
+
+  /* find the start of the NCI message and parse the NCI header */
+  p = p_evt = (uint8_t*)(p_msg + 1) + p_msg->offset;
+  pp = p + 1;
+  NCI_MSG_PRS_HDR1(pp, op_code);
+  len = *pp++;
+
+  /*If there's a pending/stored command, restore the associated address of the
+   * callback function */
+  if (p_cback) {
+    (*p_cback)((tNFC_VS_EVT)(NCI_RSP_BIT | op_code), p_msg->len, p_evt);
+    nfc_cb.p_vsc_cback = NULL;
+  }
+  nfc_cb.nxpCbflag = false;
+  nfc_ncif_update_window();
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         nci_proc_prop_ntf
+**
+** Description      Process NCI notifications in the Proprietary group
+**
+** Returns          void
+**
+*******************************************************************************/
+void nci_proc_prop_ntf(NFC_HDR* p_msg) {
+  uint8_t* p;
+  uint8_t* p_evt;
+  uint8_t* pp, len, op_code;
+  int i;
+
+  /* find the start of the NCI message and parse the NCI header */
+  p = p_evt = (uint8_t*)(p_msg + 1) + p_msg->offset;
+  pp = p + 1;
+  NCI_MSG_PRS_HDR1(pp, op_code);
+  len = *pp++;
+
+#if (NXP_EXTNS == TRUE)
+  NFC_TRACE_DEBUG1("nci_proc_prop_ntf:op_code =0x%x", op_code);
+  switch (op_code) {
+    case NCI_MSG_RF_WTX:
+      nfc_ncif_proc_rf_wtx_ntf(p, p_msg->len);
+      return;
+    default:
+      break;
+  }
+#endif
+
+  for (i = 0; i < NFC_NUM_VS_CBACKS; i++) {
+    if (nfc_cb.p_vs_cb[i]) {
+      (*nfc_cb.p_vs_cb[i])((tNFC_VS_EVT)(NCI_NTF_BIT | op_code), p_msg->len,
+                           p_evt);
+    }
+  }
+}
diff --git a/src/nfc/ndef/ndef_utils.c b/src/nfc/ndef/ndef_utils.c
new file mode 100644
index 0000000..0b5cc17
--- /dev/null
+++ b/src/nfc/ndef/ndef_utils.c
@@ -0,0 +1,1495 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains source code for some utility functions to help parse
+ *  and build NFC Data Exchange Format (NDEF) messages
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "ndef_utils.h"
+
+/*******************************************************************************
+**
+**              Static Local Functions
+**
+*******************************************************************************/
+
+/*******************************************************************************
+**
+** Function         shiftdown
+**
+** Description      shift memory down (to make space to insert a record)
+**
+*******************************************************************************/
+static void shiftdown(uint8_t* p_mem, uint32_t len, uint32_t shift_amount) {
+  register uint8_t* ps = p_mem + len - 1;
+  register uint8_t* pd = ps + shift_amount;
+  register uint32_t xx;
+
+  for (xx = 0; xx < len; xx++) *pd-- = *ps--;
+}
+
+/*******************************************************************************
+**
+** Function         shiftup
+**
+** Description      shift memory up (to delete a record)
+**
+*******************************************************************************/
+static void shiftup(uint8_t* p_dest, uint8_t* p_src, uint32_t len) {
+  register uint8_t* ps = p_src;
+  register uint8_t* pd = p_dest;
+  register uint32_t xx;
+
+  for (xx = 0; xx < len; xx++) *pd++ = *ps++;
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgValidate
+**
+** Description      This function validates an NDEF message.
+**
+** Returns          true if all OK, or false if the message is invalid.
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgValidate(uint8_t* p_msg, uint32_t msg_len,
+                              bool b_allow_chunks) {
+  uint8_t* p_rec = p_msg;
+  uint8_t* p_end = p_msg + msg_len;
+  uint8_t rec_hdr = 0, type_len, id_len;
+  int count;
+  uint32_t payload_len;
+  bool bInChunk = false;
+
+  if ((p_msg == NULL) || (msg_len < 3)) return (NDEF_MSG_TOO_SHORT);
+
+  /* The first record must have the MB bit set */
+  if ((*p_msg & NDEF_MB_MASK) == 0) return (NDEF_MSG_NO_MSG_BEGIN);
+
+  /* The first record cannot be a chunk */
+  if ((*p_msg & NDEF_TNF_MASK) == NDEF_TNF_UNCHANGED)
+    return (NDEF_MSG_UNEXPECTED_CHUNK);
+
+  for (count = 0; p_rec < p_end; count++) {
+    /* if less than short record header */
+    if (p_rec + 3 > p_end) return (NDEF_MSG_TOO_SHORT);
+
+    rec_hdr = *p_rec++;
+
+    /* header should have a valid TNF */
+    if ((rec_hdr & NDEF_TNF_MASK) == NDEF_TNF_MASK)
+      return NDEF_MSG_INVALID_CHUNK;
+
+    /* The second and all subsequent records must NOT have the MB bit set */
+    if ((count > 0) && (rec_hdr & NDEF_MB_MASK))
+      return (NDEF_MSG_EXTRA_MSG_BEGIN);
+
+    /* Type field length */
+    type_len = *p_rec++;
+
+    /* If the record is chunked, first record must contain the type unless
+     * it's Type Name Format is Unknown */
+    if ((rec_hdr & NDEF_CF_MASK) && (rec_hdr & NDEF_MB_MASK) && type_len == 0 &&
+        (rec_hdr & NDEF_TNF_MASK) != NDEF_TNF_UNKNOWN)
+      return (NDEF_MSG_INVALID_CHUNK);
+
+    /* Payload length - can be 1 or 4 bytes */
+    if (rec_hdr & NDEF_SR_MASK)
+      payload_len = *p_rec++;
+    else {
+      /* if less than 4 bytes payload length */
+      if (p_rec + 4 > p_end) return (NDEF_MSG_TOO_SHORT);
+
+      BE_STREAM_TO_UINT32(payload_len, p_rec);
+    }
+
+    /* ID field Length */
+    if (rec_hdr & NDEF_IL_MASK) {
+      /* if less than 1 byte ID field length */
+      if (p_rec + 1 > p_end) return (NDEF_MSG_TOO_SHORT);
+
+      id_len = *p_rec++;
+    } else {
+      id_len = 0;
+      /* Empty record must have the id_len */
+      if ((rec_hdr & NDEF_TNF_MASK) == NDEF_TNF_EMPTY)
+        return (NDEF_MSG_INVALID_EMPTY_REC);
+    }
+
+    /* A chunk must have type "unchanged", and no type or ID fields */
+    if (rec_hdr & NDEF_CF_MASK) {
+      if (!b_allow_chunks) return (NDEF_MSG_UNEXPECTED_CHUNK);
+
+      /* Inside a chunk, the type must be unchanged and no type or ID field i
+       * sallowed */
+      if (bInChunk) {
+        if ((type_len != 0) || (id_len != 0) ||
+            ((rec_hdr & NDEF_TNF_MASK) != NDEF_TNF_UNCHANGED))
+          return (NDEF_MSG_INVALID_CHUNK);
+      } else {
+        /* First record of a chunk must NOT have type "unchanged" */
+        if ((rec_hdr & NDEF_TNF_MASK) == NDEF_TNF_UNCHANGED)
+          return (NDEF_MSG_INVALID_CHUNK);
+
+        bInChunk = true;
+      }
+    } else {
+      /* This may be the last guy in a chunk. */
+      if (bInChunk) {
+        if ((type_len != 0) || (id_len != 0) ||
+            ((rec_hdr & NDEF_TNF_MASK) != NDEF_TNF_UNCHANGED))
+          return (NDEF_MSG_INVALID_CHUNK);
+
+        bInChunk = false;
+      } else {
+        /* If not in a chunk, the record must NOT have type "unchanged" */
+        if ((rec_hdr & NDEF_TNF_MASK) == NDEF_TNF_UNCHANGED)
+          return (NDEF_MSG_INVALID_CHUNK);
+      }
+    }
+
+    /* An empty record must NOT have a type, ID or payload */
+    if ((rec_hdr & NDEF_TNF_MASK) == NDEF_TNF_EMPTY) {
+      if ((type_len != 0) || (id_len != 0) || (payload_len != 0))
+        return (NDEF_MSG_INVALID_EMPTY_REC);
+    }
+
+    if ((rec_hdr & NDEF_TNF_MASK) == NDEF_TNF_UNKNOWN) {
+      if (type_len != 0) return (NDEF_MSG_LENGTH_MISMATCH);
+    }
+
+    /* External type should have non-zero type length */
+    if ((rec_hdr & NDEF_TNF_MASK) == NDEF_TNF_EXT) {
+      if (type_len == 0) return (NDEF_MSG_LENGTH_MISMATCH);
+    }
+
+    /* External type and Well Known types should have valid characters
+       in the TYPE field */
+    if ((rec_hdr & NDEF_TNF_MASK) == NDEF_TNF_EXT ||
+        (rec_hdr & NDEF_TNF_MASK) == NDEF_TNF_WKT) {
+      uint8_t* p_rec_type = p_rec;
+      if ((p_rec_type + type_len) > p_end) return (NDEF_MSG_TOO_SHORT);
+
+      for (int type_index = 0; type_index < type_len; type_index++) {
+        if (p_rec_type[type_index] < NDEF_RTD_VALID_START ||
+            p_rec_type[type_index] > NDEF_RTD_VALID_END)
+          return (NDEF_MSG_INVALID_TYPE);
+      }
+    }
+
+    /* Point to next record */
+    p_rec += (payload_len + type_len + id_len);
+
+    if (rec_hdr & NDEF_ME_MASK) break;
+
+    rec_hdr = 0;
+  }
+
+  /* The last record should have the ME bit set */
+  if ((rec_hdr & NDEF_ME_MASK) == 0) return (NDEF_MSG_NO_MSG_END);
+
+  /* p_rec should equal p_end if all the length fields were correct */
+  if (p_rec != p_end) return (NDEF_MSG_LENGTH_MISMATCH);
+
+  return (NDEF_OK);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetNumRecs
+**
+** Description      This function gets the number of records in the given NDEF
+**                  message.
+**
+** Returns          The record count, or 0 if the message is invalid.
+**
+*******************************************************************************/
+int32_t NDEF_MsgGetNumRecs(uint8_t* p_msg) {
+  uint8_t* p_rec = p_msg;
+  uint8_t rec_hdr, type_len, id_len;
+  int count;
+  uint32_t payload_len;
+
+  for (count = 0;;) {
+    count++;
+
+    rec_hdr = *p_rec++;
+
+    if (rec_hdr & NDEF_ME_MASK) break;
+
+    /* Type field length */
+    type_len = *p_rec++;
+
+    /* Payload length - can be 1 or 4 bytes */
+    if (rec_hdr & NDEF_SR_MASK)
+      payload_len = *p_rec++;
+    else
+      BE_STREAM_TO_UINT32(payload_len, p_rec);
+
+    /* ID field Length */
+    if (rec_hdr & NDEF_IL_MASK)
+      id_len = *p_rec++;
+    else
+      id_len = 0;
+
+    /* Point to next record */
+    p_rec += (payload_len + type_len + id_len);
+  }
+
+  /* Return the number of records found */
+  return (count);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetRecLength
+**
+** Description      This function returns length of the current record in the
+**                  given NDEF message.
+**
+** Returns          Length of record
+**
+*******************************************************************************/
+uint32_t NDEF_MsgGetRecLength(uint8_t* p_cur_rec) {
+  uint8_t rec_hdr, type_len, id_len;
+  uint32_t rec_len = 0;
+  uint32_t payload_len;
+
+  /* Get the current record's header */
+  rec_hdr = *p_cur_rec++;
+  rec_len++;
+
+  /* Type field length */
+  type_len = *p_cur_rec++;
+  rec_len++;
+
+  /* Payload length - can be 1 or 4 bytes */
+  if (rec_hdr & NDEF_SR_MASK) {
+    payload_len = *p_cur_rec++;
+    rec_len++;
+  } else {
+    BE_STREAM_TO_UINT32(payload_len, p_cur_rec);
+    rec_len += 4;
+  }
+
+  /* ID field Length */
+  if (rec_hdr & NDEF_IL_MASK) {
+    id_len = *p_cur_rec++;
+    rec_len++;
+  } else
+    id_len = 0;
+
+  /* Total length of record */
+  rec_len += (payload_len + type_len + id_len);
+
+  return (rec_len);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetNextRec
+**
+** Description      This function gets a pointer to the next record in the given
+**                  NDEF message. If the current record pointer is NULL, a
+**                  pointer to the first record is returned.
+**
+** Returns          Pointer to the start of the record, or NULL if no more
+**
+*******************************************************************************/
+uint8_t* NDEF_MsgGetNextRec(uint8_t* p_cur_rec) {
+  uint8_t rec_hdr, type_len, id_len;
+  uint32_t payload_len;
+
+  /* Get the current record's header */
+  rec_hdr = *p_cur_rec++;
+
+  /* If this is the last record, return NULL */
+  if (rec_hdr & NDEF_ME_MASK) return (NULL);
+
+  /* Type field length */
+  type_len = *p_cur_rec++;
+
+  /* Payload length - can be 1 or 4 bytes */
+  if (rec_hdr & NDEF_SR_MASK)
+    payload_len = *p_cur_rec++;
+  else
+    BE_STREAM_TO_UINT32(payload_len, p_cur_rec);
+
+  /* ID field Length */
+  if (rec_hdr & NDEF_IL_MASK)
+    id_len = *p_cur_rec++;
+  else
+    id_len = 0;
+
+  /* Point to next record */
+  p_cur_rec += (payload_len + type_len + id_len);
+
+  return (p_cur_rec);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetRecByIndex
+**
+** Description      This function gets a pointer to the record with the given
+**                  index (0-based index) in the given NDEF message.
+**
+** Returns          Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+uint8_t* NDEF_MsgGetRecByIndex(uint8_t* p_msg, int32_t index) {
+  uint8_t* p_rec = p_msg;
+  uint8_t rec_hdr, type_len, id_len;
+  int32_t count;
+  uint32_t payload_len;
+
+  for (count = 0;; count++) {
+    if (count == index) return (p_rec);
+
+    rec_hdr = *p_rec++;
+
+    if (rec_hdr & NDEF_ME_MASK) return (NULL);
+
+    /* Type field length */
+    type_len = *p_rec++;
+
+    /* Payload length - can be 1 or 4 bytes */
+    if (rec_hdr & NDEF_SR_MASK)
+      payload_len = *p_rec++;
+    else
+      BE_STREAM_TO_UINT32(payload_len, p_rec);
+
+    /* ID field Length */
+    if (rec_hdr & NDEF_IL_MASK)
+      id_len = *p_rec++;
+    else
+      id_len = 0;
+
+    /* Point to next record */
+    p_rec += (payload_len + type_len + id_len);
+  }
+
+  /* If here, there is no record of that index */
+  return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetLastRecInMsg
+**
+** Description      This function gets a pointer to the last record in the
+**                  given NDEF message.
+**
+** Returns          Pointer to the start of the last record, or NULL if some
+**                  problem
+**
+*******************************************************************************/
+uint8_t* NDEF_MsgGetLastRecInMsg(uint8_t* p_msg) {
+  uint8_t* p_rec = p_msg;
+  uint8_t* pRecStart;
+  uint8_t rec_hdr, type_len, id_len;
+  uint32_t payload_len;
+
+  for (;;) {
+    pRecStart = p_rec;
+    rec_hdr = *p_rec++;
+
+    if (rec_hdr & NDEF_ME_MASK) break;
+
+    /* Type field length */
+    type_len = *p_rec++;
+
+    /* Payload length - can be 1 or 4 bytes */
+    if (rec_hdr & NDEF_SR_MASK)
+      payload_len = *p_rec++;
+    else
+      BE_STREAM_TO_UINT32(payload_len, p_rec);
+
+    /* ID field Length */
+    if (rec_hdr & NDEF_IL_MASK)
+      id_len = *p_rec++;
+    else
+      id_len = 0;
+
+    /* Point to next record */
+    p_rec += (payload_len + type_len + id_len);
+  }
+
+  return (pRecStart);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetFirstRecByType
+**
+** Description      This function gets a pointer to the first record with the
+**                  given record type in the given NDEF message.
+**
+** Returns          Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+uint8_t* NDEF_MsgGetFirstRecByType(uint8_t* p_msg, uint8_t tnf, uint8_t* p_type,
+                                   uint8_t tlen) {
+  uint8_t* p_rec = p_msg;
+  uint8_t* pRecStart;
+  uint8_t rec_hdr, type_len, id_len;
+  uint32_t payload_len;
+
+  for (;;) {
+    pRecStart = p_rec;
+
+    rec_hdr = *p_rec++;
+
+    /* Type field length */
+    type_len = *p_rec++;
+
+    /* Payload length - can be 1 or 4 bytes */
+    if (rec_hdr & NDEF_SR_MASK)
+      payload_len = *p_rec++;
+    else
+      BE_STREAM_TO_UINT32(payload_len, p_rec);
+
+    /* ID field Length */
+    if (rec_hdr & NDEF_IL_MASK)
+      id_len = *p_rec++;
+    else
+      id_len = 0;
+
+    /* At this point, p_rec points to the start of the type field. We need to */
+    /* compare the type of the type, the length of the type and the data     */
+    if (((rec_hdr & NDEF_TNF_MASK) == tnf) && (type_len == tlen) &&
+        (!memcmp(p_rec, p_type, tlen)))
+      return (pRecStart);
+
+    /* If this was the last record, return NULL */
+    if (rec_hdr & NDEF_ME_MASK) return (NULL);
+
+    /* Point to next record */
+    p_rec += (payload_len + type_len + id_len);
+  }
+
+  /* If here, there is no record of that type */
+  return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetNextRecByType
+**
+** Description      This function gets a pointer to the next record with the
+**                  given record type in the given NDEF message.
+**
+** Returns          Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+uint8_t* NDEF_MsgGetNextRecByType(uint8_t* p_cur_rec, uint8_t tnf,
+                                  uint8_t* p_type, uint8_t tlen) {
+  uint8_t* p_rec;
+  uint8_t* pRecStart;
+  uint8_t rec_hdr, type_len, id_len;
+  uint32_t payload_len;
+
+  /* If this is the last record in the message, return NULL */
+  p_rec = NDEF_MsgGetNextRec(p_cur_rec);
+  if (p_rec == NULL) return (NULL);
+
+  for (;;) {
+    pRecStart = p_rec;
+
+    rec_hdr = *p_rec++;
+
+    /* Type field length */
+    type_len = *p_rec++;
+
+    /* Payload length - can be 1 or 4 bytes */
+    if (rec_hdr & NDEF_SR_MASK)
+      payload_len = *p_rec++;
+    else
+      BE_STREAM_TO_UINT32(payload_len, p_rec);
+
+    /* ID field Length */
+    if (rec_hdr & NDEF_IL_MASK)
+      id_len = *p_rec++;
+    else
+      id_len = 0;
+
+    /* At this point, p_rec points to the start of the type field. We need to */
+    /* compare the type of the type, the length of the type and the data     */
+    if (((rec_hdr & NDEF_TNF_MASK) == tnf) && (type_len == tlen) &&
+        (!memcmp(p_rec, p_type, tlen)))
+      return (pRecStart);
+
+    /* If this was the last record, return NULL */
+    if (rec_hdr & NDEF_ME_MASK) break;
+
+    /* Point to next record */
+    p_rec += (payload_len + type_len + id_len);
+  }
+
+  /* If here, there is no record of that type */
+  return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetFirstRecById
+**
+** Description      This function gets a pointer to the first record with the
+**                  given record id in the given NDEF message.
+**
+** Returns          Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+uint8_t* NDEF_MsgGetFirstRecById(uint8_t* p_msg, uint8_t* p_id, uint8_t ilen) {
+  uint8_t* p_rec = p_msg;
+  uint8_t* pRecStart;
+  uint8_t rec_hdr, type_len, id_len;
+  uint32_t payload_len;
+
+  for (;;) {
+    pRecStart = p_rec;
+
+    rec_hdr = *p_rec++;
+
+    /* Type field length */
+    type_len = *p_rec++;
+
+    /* Payload length - can be 1 or 4 bytes */
+    if (rec_hdr & NDEF_SR_MASK)
+      payload_len = *p_rec++;
+    else
+      BE_STREAM_TO_UINT32(payload_len, p_rec);
+
+    /* ID field Length */
+    if (rec_hdr & NDEF_IL_MASK)
+      id_len = *p_rec++;
+    else
+      id_len = 0;
+
+    /* At this point, p_rec points to the start of the type field. Skip it */
+    p_rec += type_len;
+
+    /* At this point, p_rec points to the start of the ID field. Compare length
+     * and data */
+    if ((id_len == ilen) && (!memcmp(p_rec, p_id, ilen))) return (pRecStart);
+
+    /* If this was the last record, return NULL */
+    if (rec_hdr & NDEF_ME_MASK) return (NULL);
+
+    /* Point to next record */
+    p_rec += (id_len + payload_len);
+  }
+
+  /* If here, there is no record of that ID */
+  return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetNextRecById
+**
+** Description      This function gets a pointer to the next record with the
+**                  given record id in the given NDEF message.
+**
+** Returns          Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+uint8_t* NDEF_MsgGetNextRecById(uint8_t* p_cur_rec, uint8_t* p_id,
+                                uint8_t ilen) {
+  uint8_t* p_rec;
+  uint8_t* pRecStart;
+  uint8_t rec_hdr, type_len, id_len;
+  uint32_t payload_len;
+
+  /* If this is the last record in the message, return NULL */
+  p_rec = NDEF_MsgGetNextRec(p_cur_rec);
+  if (p_rec == NULL) return (NULL);
+
+  for (;;) {
+    pRecStart = p_rec;
+
+    rec_hdr = *p_rec++;
+
+    /* Type field length */
+    type_len = *p_rec++;
+
+    /* Payload length - can be 1 or 4 bytes */
+    if (rec_hdr & NDEF_SR_MASK)
+      payload_len = *p_rec++;
+    else
+      BE_STREAM_TO_UINT32(payload_len, p_rec);
+
+    /* ID field Length */
+    if (rec_hdr & NDEF_IL_MASK)
+      id_len = *p_rec++;
+    else
+      id_len = 0;
+
+    /* At this point, p_rec points to the start of the type field. Skip it */
+    p_rec += type_len;
+
+    /* At this point, p_rec points to the start of the ID field. Compare length
+     * and data */
+    if ((id_len == ilen) && (!memcmp(p_rec, p_id, ilen))) return (pRecStart);
+
+    /* If this was the last record, return NULL */
+    if (rec_hdr & NDEF_ME_MASK) break;
+
+    /* Point to next record */
+    p_rec += (id_len + payload_len);
+  }
+
+  /* If here, there is no record of that ID */
+  return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_RecGetType
+**
+** Description      This function gets a pointer to the record type for the
+**                  given NDEF record.
+**
+** Returns          Pointer to Type (NULL if none). TNF and len are filled in.
+**
+*******************************************************************************/
+uint8_t* NDEF_RecGetType(uint8_t* p_rec, uint8_t* p_tnf, uint8_t* p_type_len) {
+  uint8_t rec_hdr, type_len;
+
+  /* First byte is the record header */
+  rec_hdr = *p_rec++;
+
+  /* Next byte is the type field length */
+  type_len = *p_rec++;
+
+  /* Skip the payload length */
+  if (rec_hdr & NDEF_SR_MASK)
+    p_rec += 1;
+  else
+    p_rec += 4;
+
+  /* Skip ID field Length, if present */
+  if (rec_hdr & NDEF_IL_MASK) p_rec++;
+
+  /* At this point, p_rec points to the start of the type field.  */
+  *p_type_len = type_len;
+  *p_tnf = rec_hdr& NDEF_TNF_MASK;
+
+  if (type_len == 0)
+    return (NULL);
+  else
+    return (p_rec);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_RecGetId
+**
+** Description      This function gets a pointer to the record id for the given
+**                  NDEF record.
+**
+** Returns          Pointer to Id (NULL if none). ID Len is filled in.
+**
+*******************************************************************************/
+uint8_t* NDEF_RecGetId(uint8_t* p_rec, uint8_t* p_id_len) {
+  uint8_t rec_hdr, type_len;
+
+  /* First byte is the record header */
+  rec_hdr = *p_rec++;
+
+  /* Next byte is the type field length */
+  type_len = *p_rec++;
+
+  /* Skip the payload length */
+  if (rec_hdr & NDEF_SR_MASK)
+    p_rec++;
+  else
+    p_rec += 4;
+
+  /* ID field Length */
+  if (rec_hdr & NDEF_IL_MASK)
+    *p_id_len = *p_rec++;
+  else
+    *p_id_len = 0;
+
+  /* p_rec now points to the start of the type field. The ID field follows it */
+  if (*p_id_len == 0)
+    return (NULL);
+  else
+    return (p_rec + type_len);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_RecGetPayload
+**
+** Description      This function gets a pointer to the payload for the given
+**                  NDEF record.
+**
+** Returns          a pointer to the payload (or NULL none). Payload len filled
+**                  in.
+**
+*******************************************************************************/
+uint8_t* NDEF_RecGetPayload(uint8_t* p_rec, uint32_t* p_payload_len) {
+  uint8_t rec_hdr, type_len, id_len;
+  uint32_t payload_len;
+
+  /* First byte is the record header */
+  rec_hdr = *p_rec++;
+
+  /* Next byte is the type field length */
+  type_len = *p_rec++;
+
+  /* Next is the payload length (1 or 4 bytes) */
+  if (rec_hdr & NDEF_SR_MASK)
+    payload_len = *p_rec++;
+  else
+    BE_STREAM_TO_UINT32(payload_len, p_rec);
+
+  *p_payload_len = payload_len;
+
+  /* ID field Length */
+  if (rec_hdr & NDEF_IL_MASK)
+    id_len = *p_rec++;
+  else
+    id_len = 0;
+
+  /* p_rec now points to the start of the type field. The ID field follows it,
+   * then the payload */
+  if (payload_len == 0)
+    return (NULL);
+  else
+    return (p_rec + type_len + id_len);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgInit
+**
+** Description      This function initializes an NDEF message.
+**
+** Returns          void
+**                  *p_cur_size is initialized to 0
+**
+*******************************************************************************/
+void NDEF_MsgInit(uint8_t* p_msg, uint32_t max_size, uint32_t* p_cur_size) {
+  *p_cur_size = 0;
+  memset(p_msg, 0, max_size);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAddRec
+**
+** Description      This function adds an NDEF record to the end of an NDEF
+**                  message.
+**
+** Returns          OK, or error if the record did not fit
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+extern tNDEF_STATUS NDEF_MsgAddRec(uint8_t* p_msg, uint32_t max_size,
+                                   uint32_t* p_cur_size, uint8_t tnf,
+                                   uint8_t* p_type, uint8_t type_len,
+                                   uint8_t* p_id, uint8_t id_len,
+                                   uint8_t* p_payload, uint32_t payload_len) {
+  uint8_t* p_rec = p_msg + *p_cur_size;
+  uint32_t recSize;
+  int plen = (payload_len < 256) ? 1 : 4;
+  int ilen = (id_len == 0) ? 0 : 1;
+
+  if (tnf > NDEF_TNF_RESERVED) {
+    tnf = NDEF_TNF_UNKNOWN;
+    type_len = 0;
+  }
+
+  /* First, make sure the record will fit. we need at least 2 bytes for header
+   * and type length */
+  recSize = payload_len + 2 + type_len + plen + ilen + id_len;
+
+  if ((*p_cur_size + recSize) > max_size) return (NDEF_MSG_INSUFFICIENT_MEM);
+
+  /* Construct the record header. For the first record, set both begin and end
+   * bits */
+  if (*p_cur_size == 0)
+    *p_rec = tnf | NDEF_MB_MASK | NDEF_ME_MASK;
+  else {
+    /* Find the previous last and clear his 'Message End' bit */
+    uint8_t* pLast = NDEF_MsgGetLastRecInMsg(p_msg);
+
+    if (!pLast) return (NDEF_MSG_NO_MSG_END);
+
+    *pLast &= ~NDEF_ME_MASK;
+    *p_rec = tnf | NDEF_ME_MASK;
+  }
+
+  if (plen == 1) *p_rec |= NDEF_SR_MASK;
+
+  if (ilen != 0) *p_rec |= NDEF_IL_MASK;
+
+  p_rec++;
+
+  /* The next byte is the type field length */
+  *p_rec++ = type_len;
+
+  /* Payload length - can be 1 or 4 bytes */
+  if (plen == 1)
+    *p_rec++ = (uint8_t)payload_len;
+  else
+    UINT32_TO_BE_STREAM(p_rec, payload_len);
+
+  /* ID field Length (optional) */
+  if (ilen > 0) *p_rec++ = id_len;
+
+  /* Next comes the type */
+  if (type_len) {
+    if (p_type) memcpy(p_rec, p_type, type_len);
+
+    p_rec += type_len;
+  }
+
+  /* Next comes the ID */
+  if (id_len) {
+    if (p_id) memcpy(p_rec, p_id, id_len);
+
+    p_rec += id_len;
+  }
+
+  /* And lastly the payload. If NULL, the app just wants to reserve memory */
+  if (p_payload) memcpy(p_rec, p_payload, payload_len);
+
+  *p_cur_size += recSize;
+
+  return (NDEF_OK);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgInsertRec
+**
+** Description      This function inserts a record at a specific index into the
+**                  given NDEF message
+**
+** Returns          OK, or error if the record did not fit
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+extern tNDEF_STATUS NDEF_MsgInsertRec(uint8_t* p_msg, uint32_t max_size,
+                                      uint32_t* p_cur_size, int32_t index,
+                                      uint8_t tnf, uint8_t* p_type,
+                                      uint8_t type_len, uint8_t* p_id,
+                                      uint8_t id_len, uint8_t* p_payload,
+                                      uint32_t payload_len) {
+  uint8_t* p_rec;
+  uint32_t recSize;
+  int32_t plen = (payload_len < 256) ? 1 : 4;
+  int32_t ilen = (id_len == 0) ? 0 : 1;
+
+  /* First, make sure the record will fit. we need at least 2 bytes for header
+   * and type length */
+  recSize = payload_len + 2 + type_len + plen + ilen + id_len;
+
+  if ((*p_cur_size + recSize) > max_size) return (NDEF_MSG_INSUFFICIENT_MEM);
+
+  /* See where the new record goes. If at the end, call the 'AddRec' function */
+  if ((index >= NDEF_MsgGetNumRecs(p_msg)) ||
+      ((p_rec = NDEF_MsgGetRecByIndex(p_msg, index)) == NULL)) {
+    return NDEF_MsgAddRec(p_msg, max_size, p_cur_size, tnf, p_type, type_len,
+                          p_id, id_len, p_payload, payload_len);
+  }
+
+  /* If we are inserting at the beginning, remove the MB bit from the current
+   * first */
+  if (index == 0) *p_msg &= ~NDEF_MB_MASK;
+
+  /* Make space for the new record */
+  shiftdown(p_rec, (uint32_t)(*p_cur_size - (p_rec - p_msg)), recSize);
+
+  /* If adding at the beginning, set begin bit */
+  if (index == 0)
+    *p_rec = tnf | NDEF_MB_MASK;
+  else
+    *p_rec = tnf;
+
+  if (plen == 1) *p_rec |= NDEF_SR_MASK;
+
+  if (ilen != 0) *p_rec |= NDEF_IL_MASK;
+
+  p_rec++;
+
+  /* The next byte is the type field length */
+  *p_rec++ = type_len;
+
+  /* Payload length - can be 1 or 4 bytes */
+  if (plen == 1)
+    *p_rec++ = (uint8_t)payload_len;
+  else
+    UINT32_TO_BE_STREAM(p_rec, payload_len);
+
+  /* ID field Length (optional) */
+  if (ilen != 0) *p_rec++ = id_len;
+
+  /* Next comes the type */
+  if (type_len) {
+    if (p_type) memcpy(p_rec, p_type, type_len);
+
+    p_rec += type_len;
+  }
+
+  /* Next comes the ID */
+  if (ilen != 0) {
+    if (p_id) memcpy(p_rec, p_id, id_len);
+
+    p_rec += id_len;
+  }
+
+  /* And lastly the payload. If NULL, the app just wants to reserve memory */
+  if (p_payload) memcpy(p_rec, p_payload, payload_len);
+
+  *p_cur_size += recSize;
+
+  return (NDEF_OK);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAppendRec
+**
+** Description      This function adds NDEF records to the end of an NDEF
+**                  message.
+**
+** Returns          OK, or error if the record did not fit
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+extern tNDEF_STATUS NDEF_MsgAppendRec(uint8_t* p_msg, uint32_t max_size,
+                                      uint32_t* p_cur_size, uint8_t* p_new_rec,
+                                      uint32_t new_rec_len) {
+  uint8_t* p_rec;
+  tNDEF_STATUS status;
+
+  /* First, validate new records */
+  status = NDEF_MsgValidate(p_new_rec, new_rec_len, false);
+  if (status != NDEF_OK) return (status);
+
+  /* First, make sure the record will fit */
+  if ((*p_cur_size + new_rec_len) > max_size)
+    return (NDEF_MSG_INSUFFICIENT_MEM);
+
+  /* Find where to copy new record */
+  if (*p_cur_size == 0)
+    p_rec = p_msg;
+  else {
+    /* Find the previous last and clear his 'Message End' bit */
+    uint8_t* pLast = NDEF_MsgGetLastRecInMsg(p_msg);
+
+    if (!pLast) return (NDEF_MSG_NO_MSG_END);
+
+    *pLast &= ~NDEF_ME_MASK;
+    p_rec = p_msg + *p_cur_size;
+
+    /* clear 'Message Begin' bit of new record */
+    *p_new_rec &= ~NDEF_MB_MASK;
+  }
+
+  /* append new records */
+  memcpy(p_rec, p_new_rec, new_rec_len);
+
+  *p_cur_size += new_rec_len;
+
+  return (NDEF_OK);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAppendPayload
+**
+** Description      This function appends extra payload to a specific record in
+**                  the given NDEF message
+**
+** Returns          OK, or error if the extra payload did not fit
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgAppendPayload(uint8_t* p_msg, uint32_t max_size,
+                                   uint32_t* p_cur_size, uint8_t* p_rec,
+                                   uint8_t* p_add_pl, uint32_t add_pl_len) {
+  uint32_t prev_paylen, new_paylen;
+  uint8_t* p_prev_pl, *pp;
+  uint8_t incr_lenfld = 0;
+  uint8_t type_len, id_len;
+
+  /* Skip header */
+  pp = p_rec + 1;
+
+  /* Next byte is the type field length */
+  type_len = *pp++;
+
+  /* Next is the payload length (1 or 4 bytes) */
+  if (*p_rec & NDEF_SR_MASK)
+    prev_paylen = *pp++;
+  else
+    BE_STREAM_TO_UINT32(prev_paylen, pp);
+
+  /* ID field Length */
+  if (*p_rec & NDEF_IL_MASK)
+    id_len = *pp++;
+  else
+    id_len = 0;
+
+  p_prev_pl = pp + type_len + id_len;
+
+  new_paylen = prev_paylen + add_pl_len;
+
+  /* Previous payload may be < 256, and this addition may make it larger than
+   * 256 */
+  /* If that were to happen, the payload length field goes from 1 byte to 4
+   * bytes */
+  if ((prev_paylen < 256) && (new_paylen > 255)) incr_lenfld = 3;
+
+  /* Check that it all fits */
+  if ((*p_cur_size + add_pl_len + incr_lenfld) > max_size)
+    return (NDEF_MSG_INSUFFICIENT_MEM);
+
+  /* Point to payload length field */
+  pp = p_rec + 2;
+
+  /* If we need to increase the length field from 1 to 4 bytes, do it first */
+  if (incr_lenfld) {
+    shiftdown(pp + 1, (uint32_t)(*p_cur_size - (pp - p_msg) - 1), 3);
+    p_prev_pl += 3;
+  }
+
+  /* Store in the new length */
+  if (new_paylen > 255) {
+    *p_rec &= ~NDEF_SR_MASK;
+    UINT32_TO_BE_STREAM(pp, new_paylen);
+  } else
+    *pp = (uint8_t)new_paylen;
+
+  /* Point to the end of the previous payload */
+  pp = p_prev_pl + prev_paylen;
+
+  /* If we are not the last record, make space for the extra payload */
+  if ((*p_rec & NDEF_ME_MASK) == 0)
+    shiftdown(pp, (uint32_t)(*p_cur_size - (pp - p_msg)), add_pl_len);
+
+  /* Now copy in the additional payload data */
+  memcpy(pp, p_add_pl, add_pl_len);
+
+  *p_cur_size += add_pl_len + incr_lenfld;
+
+  return (NDEF_OK);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgReplacePayload
+**
+** Description      This function replaces the payload of a specific record in
+**                  the given NDEF message
+**
+** Returns          OK, or error if the new payload did not fit
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgReplacePayload(uint8_t* p_msg, uint32_t max_size,
+                                    uint32_t* p_cur_size, uint8_t* p_rec,
+                                    uint8_t* p_new_pl, uint32_t new_pl_len) {
+  uint32_t prev_paylen;
+  uint8_t* p_prev_pl, *pp;
+  uint32_t paylen_delta;
+  uint8_t type_len, id_len;
+
+  /* Skip header */
+  pp = p_rec + 1;
+
+  /* Next byte is the type field length */
+  type_len = *pp++;
+
+  /* Next is the payload length (1 or 4 bytes) */
+  if (*p_rec & NDEF_SR_MASK)
+    prev_paylen = *pp++;
+  else
+    BE_STREAM_TO_UINT32(prev_paylen, pp);
+
+  /* ID field Length */
+  if (*p_rec & NDEF_IL_MASK)
+    id_len = *pp++;
+  else
+    id_len = 0;
+
+  p_prev_pl = pp + type_len + id_len;
+
+  /* Point to payload length field again */
+  pp = p_rec + 2;
+
+  if (new_pl_len > prev_paylen) {
+    /* New payload is larger than the previous */
+    paylen_delta = new_pl_len - prev_paylen;
+
+    /* If the previous payload length was < 256, and new is > 255 */
+    /* the payload length field goes from 1 byte to 4 bytes       */
+    if ((prev_paylen < 256) && (new_pl_len > 255)) {
+      if ((*p_cur_size + paylen_delta + 3) > max_size)
+        return (NDEF_MSG_INSUFFICIENT_MEM);
+
+      shiftdown(pp + 1, (uint32_t)(*p_cur_size - (pp - p_msg) - 1), 3);
+      p_prev_pl += 3;
+      *p_cur_size += 3;
+      *p_rec &= ~NDEF_SR_MASK;
+    } else if ((*p_cur_size + paylen_delta) > max_size)
+      return (NDEF_MSG_INSUFFICIENT_MEM);
+
+    /* Store in the new length */
+    if (new_pl_len > 255) {
+      UINT32_TO_BE_STREAM(pp, new_pl_len);
+    } else
+      *pp = (uint8_t)new_pl_len;
+
+    /* Point to the end of the previous payload */
+    pp = p_prev_pl + prev_paylen;
+
+    /* If we are not the last record, make space for the extra payload */
+    if ((*p_rec & NDEF_ME_MASK) == 0)
+      shiftdown(pp, (uint32_t)(*p_cur_size - (pp - p_msg)), paylen_delta);
+
+    *p_cur_size += paylen_delta;
+  } else if (new_pl_len < prev_paylen) {
+    /* New payload is smaller than the previous */
+    paylen_delta = prev_paylen - new_pl_len;
+
+    /* If the previous payload was > 256, and new is less than 256 */
+    /* the payload length field goes from 4 bytes to 1 byte        */
+    if ((prev_paylen > 255) && (new_pl_len < 256)) {
+      shiftup(pp + 1, pp + 4, (uint32_t)(*p_cur_size - (pp - p_msg) - 3));
+      p_prev_pl -= 3;
+      *p_cur_size -= 3;
+      *p_rec |= NDEF_SR_MASK;
+    }
+
+    /* Store in the new length */
+    if (new_pl_len > 255) {
+      UINT32_TO_BE_STREAM(pp, new_pl_len);
+    } else
+      *pp = (uint8_t)new_pl_len;
+
+    /* Point to the end of the previous payload */
+    pp = p_prev_pl + prev_paylen;
+
+    /* If we are not the last record, remove the extra space from the previous
+     * payload */
+    if ((*p_rec & NDEF_ME_MASK) == 0)
+      shiftup(pp - paylen_delta, pp, (uint32_t)(*p_cur_size - (pp - p_msg)));
+
+    *p_cur_size -= paylen_delta;
+  }
+
+  /* Now copy in the new payload data */
+  if (p_new_pl) memcpy(p_prev_pl, p_new_pl, new_pl_len);
+
+  return (NDEF_OK);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgReplaceType
+**
+** Description      This function replaces the type field of a specific record
+**                  in the given NDEF message
+**
+** Returns          OK, or error if the new type field did not fit
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgReplaceType(uint8_t* p_msg, uint32_t max_size,
+                                 uint32_t* p_cur_size, uint8_t* p_rec,
+                                 uint8_t* p_new_type, uint8_t new_type_len) {
+  uint8_t typelen_delta;
+  uint8_t* p_prev_type, prev_type_len;
+  uint8_t* pp;
+
+  /* Skip header */
+  pp = p_rec + 1;
+
+  /* Next byte is the type field length */
+  prev_type_len = *pp++;
+
+  /* Skip the payload length */
+  if (*p_rec & NDEF_SR_MASK)
+    pp += 1;
+  else
+    pp += 4;
+
+  if (*p_rec & NDEF_IL_MASK) pp++;
+
+  /* Save pointer to the start of the type field */
+  p_prev_type = pp;
+
+  if (new_type_len > prev_type_len) {
+    /* New type is larger than the previous */
+    typelen_delta = new_type_len - prev_type_len;
+
+    if ((*p_cur_size + typelen_delta) > max_size)
+      return (NDEF_MSG_INSUFFICIENT_MEM);
+
+    /* Point to the end of the previous type, and make space for the extra data
+     */
+    pp = p_prev_type + prev_type_len;
+    shiftdown(pp, (uint32_t)(*p_cur_size - (pp - p_msg)), typelen_delta);
+
+    *p_cur_size += typelen_delta;
+  } else if (new_type_len < prev_type_len) {
+    /* New type field is smaller than the previous */
+    typelen_delta = prev_type_len - new_type_len;
+
+    /* Point to the end of the previous type, and shift up to fill the the
+     * unused space */
+    pp = p_prev_type + prev_type_len;
+    shiftup(pp - typelen_delta, pp, (uint32_t)(*p_cur_size - (pp - p_msg)));
+
+    *p_cur_size -= typelen_delta;
+  }
+
+  /* Save in new type length */
+  p_rec[1] = new_type_len;
+
+  /* Now copy in the new type field data */
+  if (p_new_type) memcpy(p_prev_type, p_new_type, new_type_len);
+
+  return (NDEF_OK);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgReplaceId
+**
+** Description      This function replaces the ID field of a specific record in
+**                  the given NDEF message
+**
+** Returns          OK, or error if the new ID field did not fit
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgReplaceId(uint8_t* p_msg, uint32_t max_size,
+                               uint32_t* p_cur_size, uint8_t* p_rec,
+                               uint8_t* p_new_id, uint8_t new_id_len) {
+  uint8_t idlen_delta;
+  uint8_t* p_prev_id, *p_idlen_field;
+  uint8_t prev_id_len, type_len;
+  uint8_t* pp;
+
+  /* Skip header */
+  pp = p_rec + 1;
+
+  /* Next byte is the type field length */
+  type_len = *pp++;
+
+  /* Skip the payload length */
+  if (*p_rec & NDEF_SR_MASK)
+    pp += 1;
+  else
+    pp += 4;
+
+  p_idlen_field = pp;
+
+  if (*p_rec & NDEF_IL_MASK)
+    prev_id_len = *pp++;
+  else
+    prev_id_len = 0;
+
+  /* Save pointer to the start of the ID field (right after the type field) */
+  p_prev_id = pp + type_len;
+
+  if (new_id_len > prev_id_len) {
+    /* New ID field is larger than the previous */
+    idlen_delta = new_id_len - prev_id_len;
+
+    /* If the previous ID length was 0, we need to add a 1-byte ID length */
+    if (prev_id_len == 0) {
+      if ((*p_cur_size + idlen_delta + 1) > max_size)
+        return (NDEF_MSG_INSUFFICIENT_MEM);
+
+      shiftdown(p_idlen_field,
+                (uint32_t)(*p_cur_size - (p_idlen_field - p_msg)), 1);
+      p_prev_id += 1;
+      *p_cur_size += 1;
+      *p_rec |= NDEF_IL_MASK;
+    } else if ((*p_cur_size + idlen_delta) > max_size)
+      return (NDEF_MSG_INSUFFICIENT_MEM);
+
+    /* Point to the end of the previous ID field, and make space for the extra
+     * data */
+    pp = p_prev_id + prev_id_len;
+    shiftdown(pp, (uint32_t)(*p_cur_size - (pp - p_msg)), idlen_delta);
+
+    *p_cur_size += idlen_delta;
+  } else if (new_id_len < prev_id_len) {
+    /* New ID field is smaller than the previous */
+    idlen_delta = prev_id_len - new_id_len;
+
+    /* Point to the end of the previous ID, and shift up to fill the the unused
+     * space */
+    pp = p_prev_id + prev_id_len;
+    shiftup(pp - idlen_delta, pp, (uint32_t)(*p_cur_size - (pp - p_msg)));
+
+    *p_cur_size -= idlen_delta;
+
+    /* If removing the ID, make sure that length field is also removed */
+    if (new_id_len == 0) {
+      shiftup(p_idlen_field, p_idlen_field + 1,
+              (uint32_t)(*p_cur_size - (p_idlen_field - p_msg - (uint32_t)1)));
+      *p_rec &= ~NDEF_IL_MASK;
+      *p_cur_size -= 1;
+    }
+  }
+
+  /* Save in new ID length and data */
+  if (new_id_len) {
+    *p_idlen_field = new_id_len;
+
+    if (p_new_id) memcpy(p_prev_id, p_new_id, new_id_len);
+  }
+
+  return (NDEF_OK);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgRemoveRec
+**
+** Description      This function removes the record at the given
+**                  index in the given NDEF message.
+**
+** Returns          true if OK, false if the index was invalid
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgRemoveRec(uint8_t* p_msg, uint32_t* p_cur_size,
+                               int32_t index) {
+  uint8_t* p_rec = NDEF_MsgGetRecByIndex(p_msg, index);
+  uint8_t* pNext, *pPrev;
+
+  if (!p_rec) return (NDEF_REC_NOT_FOUND);
+
+  /* If this is the first record in the message... */
+  if (*p_rec & NDEF_MB_MASK) {
+    /* Find the second record (if any) and set his 'Message Begin' bit */
+    pNext = NDEF_MsgGetRecByIndex(p_msg, 1);
+    if (pNext != NULL) {
+      *pNext |= NDEF_MB_MASK;
+
+      *p_cur_size -= (uint32_t)(pNext - p_msg);
+
+      shiftup(p_msg, pNext, *p_cur_size);
+    } else
+      *p_cur_size = 0; /* No more records, lenght must be zero */
+
+    return (NDEF_OK);
+  }
+
+  /* If this is the last record in the message... */
+  if (*p_rec & NDEF_ME_MASK) {
+    if (index > 0) {
+      /* Find the previous record and set his 'Message End' bit */
+      pPrev = NDEF_MsgGetRecByIndex(p_msg, index - 1);
+      if (pPrev == NULL) return false;
+
+      *pPrev |= NDEF_ME_MASK;
+    }
+    *p_cur_size = (uint32_t)(p_rec - p_msg);
+
+    return (NDEF_OK);
+  }
+
+  /* Not the first or the last... get the address of the next record */
+  pNext = NDEF_MsgGetNextRec(p_rec);
+  if (pNext == NULL) return false;
+
+  /* We are removing p_rec, so shift from pNext to the end */
+  shiftup(p_rec, pNext, (uint32_t)(*p_cur_size - (pNext - p_msg)));
+
+  *p_cur_size -= (uint32_t)(pNext - p_rec);
+
+  return (NDEF_OK);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgCopyAndDechunk
+**
+** Description      This function copies and de-chunks an NDEF message.
+**                  It is assumed that the destination is at least as large
+**                  as the source, since the source may not actually contain
+**                  any chunks.
+**
+** Returns          The output byte count
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgCopyAndDechunk(uint8_t* p_src, uint32_t src_len,
+                                    uint8_t* p_dest, uint32_t* p_out_len) {
+  uint32_t out_len, max_out_len;
+  uint8_t* p_rec;
+  uint8_t* p_prev_rec = p_dest;
+  uint8_t* p_type, *p_id, *p_pay;
+  uint8_t type_len, id_len, tnf;
+  uint32_t pay_len;
+  tNDEF_STATUS status;
+
+  /* First, validate the source */
+  status = NDEF_MsgValidate(p_src, src_len, true);
+  if (status != NDEF_OK) return (status);
+
+  /* The output buffer must be at least as large as the input buffer */
+  max_out_len = src_len;
+
+  /* Initialize output */
+  NDEF_MsgInit(p_dest, max_out_len, &out_len);
+
+  p_rec = p_src;
+
+  /* Now, copy record by record */
+  while ((p_rec != NULL) && (status == NDEF_OK)) {
+    p_type = NDEF_RecGetType(p_rec, &tnf, &type_len);
+    p_id = NDEF_RecGetId(p_rec, &id_len);
+    p_pay = NDEF_RecGetPayload(p_rec, &pay_len);
+
+    /* If this is the continuation of a chunk, append the payload to the
+     * previous */
+    if (tnf == NDEF_TNF_UNCHANGED) {
+      if (p_pay) {
+        status = NDEF_MsgAppendPayload(p_dest, max_out_len, &out_len,
+                                       p_prev_rec, p_pay, pay_len);
+      }
+    } else {
+      p_prev_rec = p_dest + out_len;
+
+      status = NDEF_MsgAddRec(p_dest, max_out_len, &out_len, tnf, p_type,
+                              type_len, p_id, id_len, p_pay, pay_len);
+    }
+
+    p_rec = NDEF_MsgGetNextRec(p_rec);
+  }
+
+  *p_out_len = out_len;
+
+  return (status);
+}
diff --git a/src/nfc/nfc/nfc_ee.c b/src/nfc/nfc/nfc_ee.c
new file mode 100644
index 0000000..e26ac8c
--- /dev/null
+++ b/src/nfc/nfc/nfc_ee.c
@@ -0,0 +1,158 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains functions that interface with the NFCEEs.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "gki.h"
+#include "nfc_target.h"
+#include "bt_types.h"
+
+#include "nfc_api.h"
+#include "nfc_int.h"
+#include "nci_hmsgs.h"
+#include "nfa_ee_int.h"
+
+/*******************************************************************************
+**
+** Function         NFC_NfceeDiscover
+**
+** Description      This function is called to enable or disable NFCEE
+**                  Discovery. The response from NFCC is reported by
+**                  tNFC_RESPONSE_CBACK as NFC_NFCEE_DISCOVER_REVT.
+**                  The notification from NFCC is reported by
+**                  tNFC_RESPONSE_CBACK as NFC_NFCEE_INFO_REVT.
+**
+** Parameters       discover - 1 to enable discover, 0 to disable.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_NfceeDiscover(bool discover) {
+  if(nfc_cb.flags & NFC_FL_WAIT_MODE_SET_NTF) {
+    NFC_TRACE_ERROR1("mode set ntf pending ,not allowing nfcee_discover %d", discover);
+    return NFC_STATUS_FAILED;
+  }
+  return nci_snd_nfcee_discover((uint8_t)(
+      discover ? NCI_DISCOVER_ACTION_ENABLE : NCI_DISCOVER_ACTION_DISABLE));
+}
+
+/*******************************************************************************
+**
+** Function         NFC_NfceeModeSet
+**
+** Description      This function is called to activate or de-activate an NFCEE
+**                  connected to the NFCC.
+**                  The response from NFCC is reported by tNFC_RESPONSE_CBACK
+**                  as NFC_NFCEE_MODE_SET_REVT.
+**
+** Parameters       nfcee_id - the NFCEE to activate or de-activate.
+**                  mode - NFC_MODE_ACTIVATE to activate NFCEE,
+**                         NFC_MODE_DEACTIVATE to de-activate.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_NfceeModeSet(uint8_t nfcee_id, tNFC_NFCEE_MODE mode) {
+  tNFC_STATUS status = NCI_STATUS_OK;
+  if (mode >= NCI_NUM_NFCEE_MODE|| nfcee_id == 0x00) {
+    NFC_TRACE_ERROR1("NFC_NfceeModeSet bad mode:%d", mode);
+    return NFC_STATUS_FAILED;
+  }
+  if(nfc_cb.nci_version != NCI_VERSION_2_0)
+    status = nci_snd_nfcee_mode_set (nfcee_id, mode);
+  else {
+    if (nfc_cb.flags & NFC_FL_WAIT_MODE_SET_NTF)
+      status = NFC_STATUS_REFUSED;
+    else {
+      nfa_ee_cb.nfcee_id = nfcee_id;
+      nfa_ee_cb.mode = mode;
+      status = nci_snd_nfcee_mode_set (nfcee_id, mode);
+      if (status == NCI_STATUS_OK)
+      {
+        /* Mode set command is successfully queued or sent.
+         * do not allow another Mode Set command until NTF is received */
+         nfc_cb.flags       |= NFC_FL_WAIT_MODE_SET_NTF;
+         nfc_start_timer(&nfc_cb.nci_setmode_ntf_timer,
+           (uint16_t)(NFC_TTYPE_WAIT_SETMODE_NTF),
+             NFC_SETMODE_NTF_TIMEOUT);
+      }
+    }
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFC_SetRouting
+**
+** Description      This function is called to configure the CE routing table.
+**                  The response from NFCC is reported by tNFC_RESPONSE_CBACK
+**                  as NFC_SET_ROUTING_REVT.
+**
+** Parameters
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_SetRouting(bool more, uint8_t num_tlv, uint8_t tlv_size,
+                           uint8_t* p_param_tlvs) {
+  return nci_snd_set_routing_cmd(more, num_tlv, tlv_size, p_param_tlvs);
+}
+
+/*******************************************************************************
+**
+** Function         NFC_GetRouting
+**
+** Description      This function is called to retrieve the CE routing table
+**                  from NFCC. The response from NFCC is reported by
+**                  tNFC_RESPONSE_CBACK as NFC_GET_ROUTING_REVT.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_GetRouting(void) { return nci_snd_get_routing_cmd(); }
+
+/*******************************************************************************
++**
+** Function         NFC_NfceePLConfig
+**
+** Description      This function is called to set the Power and Link Control to
+*                  an NFCEE connected to the NFCC.
+**                  The response from NFCC is reported by tNFC_RESPONSE_CBACK
+**                  as NFC_NFCEE_PL_CONTROL_REVT.
+**
+** Parameters       nfcee_id - the NFCEE to activate or de-activate.
+**                  pl_config -
+**                     NFCEE_PL_CONFIG_NFCC_DECIDES    NFCC decides (default)
+**                     NFCEE_PL_CONFIG_P_ALWAYS_ON     NFCEE power supply is always on
+**                     NFCEE_PL_CONFIG_L_ON_WHEN_P_ON  communication link is always active
+**                                                          when NFCEE is powered on
+**                     NFCEE_PL_CONFIG_PL_ALWAYS_ON    power supply and communication link are always on
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_NfceePLConfig (uint8_t                 nfcee_id,
+                              tNCI_NFCEE_PL_CONFIG  pl_config)
+{
+    return nci_snd_nfcee_power_link_control (nfcee_id, pl_config);
+}
diff --git a/src/nfc/nfc/nfc_main.c b/src/nfc/nfc/nfc_main.c
new file mode 100644
index 0000000..0d05a13
--- /dev/null
+++ b/src/nfc/nfc/nfc_main.c
@@ -0,0 +1,2048 @@
+/******************************************************************************
+ *
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains functions that interface with the NFC NCI transport.
+ *  On the receive side, it routes events to the appropriate handler
+ *  (callback). On the transmit side, it manages the command transmission.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "gki.h"
+#include "nfc_target.h"
+#include "bt_types.h"
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include "nfc_hal_api.h"
+#include "nfc_api.h"
+#include "nfc_int.h"
+#include "nci_hmsgs.h"
+#include "rw_int.h"
+#include "ce_int.h"
+#include "nfa_sys.h"
+#include <config.h>
+#if (NFC_RW_ONLY == FALSE)
+#include "ce_api.h"
+#include "ce_int.h"
+#include "llcp_int.h"
+
+#if(NXP_EXTNS == TRUE)
+static phNxpNci_getCfg_info_t* mGetCfg_info_main = NULL;
+extern void nfa_dm_init_cfgs (phNxpNci_getCfg_info_t* mGetCfg_info_main);
+#endif
+
+/* NFC mandates support for at least one logical connection;
+ * Update max_conn to the NFCC capability on InitRsp */
+#define NFC_SET_MAX_CONN_DEFAULT() \
+  { nfc_cb.max_conn = 1; }
+
+#else /* NFC_RW_ONLY */
+#define ce_init()
+#define llcp_init()
+
+#define NFC_SET_MAX_CONN_DEFAULT()
+
+#endif /* NFC_RW_ONLY */
+/****************************************************************************
+** Declarations
+****************************************************************************/
+tNFC_CB nfc_cb;
+uint8_t i2c_fragmentation_enabled = 0xff;
+
+tNfc_featureList nfcFL;
+static tNFC_chipType chipType = 0;
+#if (NFC_RW_ONLY == FALSE)
+#if (NXP_EXTNS == TRUE)
+#define NFC_NUM_INTERFACE_MAP 3
+#define NFC_NUM_INTERFACE_MAP_STAT 2
+#else
+#define NFC_NUM_INTERFACE_MAP 2
+#endif
+#else
+#define NFC_NUM_INTERFACE_MAP 1
+#endif
+
+static void NFC_GetFeatureList();
+static const tNCI_DISCOVER_MAPS nfc_interface_mapping[NFC_NUM_INTERFACE_MAP] = {
+    /* Protocols that use Frame Interface do not need to be included in the
+       interface mapping */
+    {NCI_PROTOCOL_ISO_DEP, NCI_INTERFACE_MODE_POLL_N_LISTEN,
+     NCI_INTERFACE_ISO_DEP}
+#if (NFC_RW_ONLY == FALSE)
+    ,
+    /* this can not be set here due to 2079xB0 NFCC issues */
+    {NCI_PROTOCOL_NFC_DEP, NCI_INTERFACE_MODE_POLL_N_LISTEN,
+     NCI_INTERFACE_NFC_DEP}
+#endif
+#if (NXP_EXTNS == TRUE)
+    ,
+    /* This mapping is for Felica on DH  */
+    {NCI_PROTOCOL_T3T, NCI_INTERFACE_MODE_LISTEN, NCI_INTERFACE_FRAME}
+
+#endif
+};
+
+static const tNCI_DISCOVER_MAPS nfc_interface_mapping_stat[NFC_NUM_INTERFACE_MAP_STAT] = {
+    /* Protocols that use Frame Interface do not need to be included in the
+       interface mapping */
+    {NCI_PROTOCOL_ISO_DEP, NCI_INTERFACE_MODE_POLL_N_LISTEN,
+     NCI_INTERFACE_ISO_DEP}
+#if (NFC_RW_ONLY == FALSE)
+    ,
+    /* this can not be set here due to 2079xB0 NFCC issues */
+    {NCI_PROTOCOL_NFC_DEP, NCI_INTERFACE_MODE_POLL_N_LISTEN,
+     NCI_INTERFACE_NFC_DEP}
+#endif
+};
+
+#if (BT_TRACE_VERBOSE == true)
+/*******************************************************************************
+**
+** Function         nfc_state_name
+**
+** Description      This function returns the state name.
+**
+** NOTE             conditionally compiled to save memory.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+static char* nfc_state_name(uint8_t state) {
+  switch (state) {
+    case NFC_STATE_NONE:
+      return ("NONE");
+    case NFC_STATE_W4_HAL_OPEN:
+      return ("W4_HAL_OPEN");
+    case NFC_STATE_CORE_INIT:
+      return ("CORE_INIT");
+    case NFC_STATE_W4_POST_INIT_CPLT:
+      return ("W4_POST_INIT_CPLT");
+    case NFC_STATE_IDLE:
+      return ("IDLE");
+    case NFC_STATE_OPEN:
+      return ("OPEN");
+    case NFC_STATE_CLOSING:
+      return ("CLOSING");
+    case NFC_STATE_W4_HAL_CLOSE:
+      return ("W4_HAL_CLOSE");
+    case NFC_STATE_NFCC_POWER_OFF_SLEEP:
+      return ("NFCC_POWER_OFF_SLEEP");
+    default:
+      return ("???? UNKNOWN STATE");
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_event_name
+**
+** Description      This function returns the HAL event name.
+**
+** NOTE             conditionally compiled to save memory.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+static char* nfc_hal_event_name(uint8_t event) {
+  switch (event) {
+    case HAL_NFC_OPEN_CPLT_EVT:
+      return ("HAL_NFC_OPEN_CPLT_EVT");
+
+    case HAL_NFC_CLOSE_CPLT_EVT:
+      return ("HAL_NFC_CLOSE_CPLT_EVT");
+
+    case HAL_NFC_POST_INIT_CPLT_EVT:
+      return ("HAL_NFC_POST_INIT_CPLT_EVT");
+
+    case HAL_NFC_PRE_DISCOVER_CPLT_EVT:
+      return ("HAL_NFC_PRE_DISCOVER_CPLT_EVT");
+
+    case HAL_NFC_REQUEST_CONTROL_EVT:
+      return ("HAL_NFC_REQUEST_CONTROL_EVT");
+
+    case HAL_NFC_RELEASE_CONTROL_EVT:
+      return ("HAL_NFC_RELEASE_CONTROL_EVT");
+
+    case HAL_NFC_ERROR_EVT:
+      return ("HAL_NFC_ERROR_EVT");
+#if (NXP_EXTNS == TRUE)
+    case HAL_NFC_POST_MIN_INIT_CPLT_EVT:
+      return ("HAL_NFC_POST_MIN_INIT_CPLT_EVT");
+#endif
+    case HAL_NFC_ENABLE_I2C_FRAGMENTATION_EVT:
+      return (" HAL_NFC_ENABLE_I2C_FRAGMENTATION_EVT ");
+
+    default:
+      return ("???? UNKNOWN EVENT");
+  }
+}
+#endif /* BT_TRACE_VERBOSE == true */
+
+/*******************************************************************************
+**
+** Function         nfc_main_notify_enable_status
+**
+** Description      Notify status of Enable/PowerOffSleep/PowerCycle
+**
+*******************************************************************************/
+static void nfc_main_notify_enable_status(tNFC_STATUS nfc_status) {
+  tNFC_RESPONSE evt_data;
+
+  evt_data.status = nfc_status;
+
+  if (nfc_cb.p_resp_cback) {
+    /* if getting out of PowerOffSleep mode or restarting NFCC */
+    if (nfc_cb.flags & (NFC_FL_RESTARTING | NFC_FL_POWER_CYCLE_NFCC)) {
+      nfc_cb.flags &= ~(NFC_FL_RESTARTING | NFC_FL_POWER_CYCLE_NFCC);
+      if (nfc_status != NFC_STATUS_OK) {
+        nfc_cb.flags |= NFC_FL_POWER_OFF_SLEEP;
+      }
+      (*nfc_cb.p_resp_cback)(NFC_NFCC_RESTART_REVT, &evt_data);
+    } else {
+      (*nfc_cb.p_resp_cback)(NFC_ENABLE_REVT, &evt_data);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_enabled
+**
+** Description      NFCC enabled, proceed with stack start up.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_enabled(tNFC_STATUS nfc_status, NFC_HDR* p_init_rsp_msg) {
+  tNFC_RESPONSE evt_data;
+  tNFC_CONN_CB* p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+  uint8_t* p;
+  uint8_t num_interfaces = 0, xx;
+  uint8_t num_interface_extensions = 0, zz;
+  uint8_t interface_type;
+  int yy = 0;
+
+  memset(&evt_data, 0, sizeof(tNFC_RESPONSE));
+
+  if (nfc_status == NCI_STATUS_OK) {
+    nfc_set_state(NFC_STATE_IDLE);
+
+    p = (uint8_t*)(p_init_rsp_msg + 1) + p_init_rsp_msg->offset +
+        NCI_MSG_HDR_SIZE + 1;
+    /* we currently only support NCI of the same version.
+    * We may need to change this, when we support multiple version of NFCC */
+    evt_data.enable.nci_version = nfc_cb.nci_version;
+    STREAM_TO_UINT32(evt_data.enable.nci_features, p);
+    if(nfc_cb.nci_version == NCI_VERSION_1_0) {
+        STREAM_TO_UINT8(num_interfaces, p);
+        evt_data.enable.nci_interfaces = 0;
+        for (xx = 0; xx < num_interfaces; xx++) {
+          if ((*p) <= NCI_INTERFACE_MAX)
+            evt_data.enable.nci_interfaces |= (1 << (*p));
+          else if (((*p) >= NCI_INTERFACE_FIRST_VS) &&
+                   (yy < NFC_NFCC_MAX_NUM_VS_INTERFACE)) {
+            /* save the VS RF interface in control block, if there's still room */
+            nfc_cb.vs_interface[yy++] = *p;
+          }
+          p++;
+        }
+        nfc_cb.nci_interfaces = evt_data.enable.nci_interfaces;
+        memcpy(evt_data.enable.vs_interface, nfc_cb.vs_interface,
+               NFC_NFCC_MAX_NUM_VS_INTERFACE);
+    }
+
+    evt_data.enable.max_conn = *p++;
+    STREAM_TO_UINT16(evt_data.enable.max_ce_table, p);
+#if (NFC_RW_ONLY == FALSE)
+    nfc_cb.max_ce_table = evt_data.enable.max_ce_table;
+    nfc_cb.nci_features = evt_data.enable.nci_features;
+    nfc_cb.max_conn = evt_data.enable.max_conn;
+#endif
+    nfc_cb.nci_ctrl_size = *p++; /* Max Control Packet Payload Length */
+    p_cb->init_credits = p_cb->num_buff = 0;
+
+    nfc_set_conn_id(p_cb, NFC_RF_CONN_ID);
+    if(nfc_cb.nci_version == NCI_VERSION_2_0) {
+      if (evt_data.enable.nci_features & NCI_FEAT_HCI_NETWORK)
+      {
+        //p_cb++;
+        p_cb = &nfc_cb.conn_cb[NFC_HCI_CONN_ID];
+        nfc_set_conn_id (p_cb, NFC_HCI_CONN_ID);
+        p_cb->id    = NFC_HCI_CONN_ID;
+        STREAM_TO_UINT8 (p_cb->buff_size, p);
+        STREAM_TO_UINT8 (p_cb->num_buff, p);
+        p_cb->init_credits = p_cb->num_buff;
+        evt_data.enable.hci_packet_size  = p_cb->buff_size;
+        evt_data.enable.hci_conn_credits = p_cb->init_credits;
+        NFC_TRACE_DEBUG2 ("hci num_buf=%d buf_size=%d", p_cb->num_buff, p_cb->buff_size);
+      }
+      else
+      {
+        p += 2; /* skip the data buffer size and data credit for static HCI connection */
+      }
+        STREAM_TO_UINT16(evt_data.enable.max_nfc_v_size, p);
+        STREAM_TO_UINT8(num_interfaces, p);
+#if (NFC_RW_ONLY == FALSE)
+        nfc_cb.hci_packet_size = evt_data.enable.hci_packet_size;
+        nfc_cb.hci_conn_credits = evt_data.enable.hci_conn_credits;
+        nfc_cb.nci_max_v_size = evt_data.enable.max_nfc_v_size;
+#endif
+        evt_data.enable.nci_interfaces = 0;
+        for (xx = 0; xx < num_interfaces; xx++) {
+          if ((*p) <= NCI_INTERFACE_MAX)
+            evt_data.enable.nci_interfaces |= (1 << (*p));
+          else if (((*p) >= NCI_INTERFACE_FIRST_VS) &&
+                   (yy < NFC_NFCC_MAX_NUM_VS_INTERFACE)) {
+            /* save the VS RF interface in control block, if there's still room */
+            nfc_cb.vs_interface[yy++] = *p;
+          }
+          interface_type = *p++;
+          num_interface_extensions = *p++;
+          for (zz = 0; zz < num_interface_extensions; zz++) {
+            if(((*p) < NCI_INTERFACE_EXTENSION_MAX ) && (interface_type <= NCI_INTERFACE_MAX)) {
+              nfc_cb.nci_intf_extensions |= (1 << (*p));
+              nfc_cb.nci_intf_extension_map[*p] = (1 << interface_type);
+            }
+            p++;
+          }
+        }
+
+        nfc_cb.nci_interfaces = evt_data.enable.nci_interfaces;
+        memcpy(evt_data.enable.vs_interface, nfc_cb.vs_interface,
+               NFC_NFCC_MAX_NUM_VS_INTERFACE);
+    } else {
+      STREAM_TO_UINT16(evt_data.enable.max_param_size, p);
+      evt_data.enable.manufacture_id = *p++;
+      STREAM_TO_ARRAY(evt_data.enable.nfcc_info, p, NFC_NFCC_INFO_LEN);
+    }
+    NFC_TRACE_DEBUG1("nfc_cb.num_disc_maps = %d", nfc_cb.num_disc_maps);
+    NFC_DiscoveryMap(nfc_cb.num_disc_maps,
+                     (tNCI_DISCOVER_MAPS*)nfc_cb.p_disc_maps, NULL);
+  }
+  /* else not successful. the buffers will be freed in nfc_free_conn_cb () */
+  else {
+    if (nfc_cb.flags & NFC_FL_RESTARTING) {
+      nfc_set_state(NFC_STATE_NFCC_POWER_OFF_SLEEP);
+    } else {
+      nfc_free_conn_cb(p_cb);
+
+      /* if NFCC didn't respond to CORE_RESET or CORE_INIT */
+      if (nfc_cb.nfc_state == NFC_STATE_CORE_INIT) {
+        /* report status after closing HAL */
+        nfc_cb.p_hal->close();
+        return;
+      } else
+        nfc_set_state(NFC_STATE_NONE);
+    }
+  }
+
+  nfc_main_notify_enable_status(nfc_status);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_set_state
+**
+** Description      Set the state of NFC stack
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_set_state(tNFC_STATE nfc_state) {
+#if (BT_TRACE_VERBOSE == true)
+  NFC_TRACE_DEBUG4("nfc_set_state %d (%s)->%d (%s)", nfc_cb.nfc_state,
+                   nfc_state_name(nfc_cb.nfc_state), nfc_state,
+                   nfc_state_name(nfc_state));
+#else
+  NFC_TRACE_DEBUG2("nfc_set_state %d->%d", nfc_cb.nfc_state, nfc_state);
+#endif
+  nfc_cb.nfc_state = nfc_state;
+}
+
+/*******************************************************************************
+**
+** Function         nfc_gen_cleanup
+**
+** Description      Clean up for both going into low power mode and disabling
+**                  NFC
+**
+*******************************************************************************/
+void nfc_gen_cleanup(void) {
+  nfc_cb.flags &= ~NFC_FL_DEACTIVATING;
+
+  /* the HAL pre-discover is still active - clear the pending flag/free the
+   * buffer */
+  if (nfc_cb.flags & NFC_FL_DISCOVER_PENDING) {
+    nfc_cb.flags &= ~NFC_FL_DISCOVER_PENDING;
+
+#if (NXP_EXTNS == TRUE)
+    if (nfc_cb.p_last_disc) {
+      GKI_freebuf(nfc_cb.p_last_disc);
+      nfc_cb.p_last_disc = NULL;
+    }
+    nfc_cb.p_last_disc = nfc_cb.p_disc_pending;
+#else
+    GKI_freebuf(nfc_cb.p_disc_pending);
+#endif
+    nfc_cb.p_disc_pending = NULL;
+  }
+
+  nfc_cb.flags &= ~(NFC_FL_CONTROL_REQUESTED | NFC_FL_CONTROL_GRANTED |
+                    NFC_FL_HAL_REQUESTED);
+
+  nfc_stop_timer(&nfc_cb.deactivate_timer);
+
+  /* Reset the connection control blocks */
+  nfc_reset_all_conn_cbs();
+
+  if (nfc_cb.p_nci_init_rsp) {
+    GKI_freebuf(nfc_cb.p_nci_init_rsp);
+    nfc_cb.p_nci_init_rsp = NULL;
+  }
+#if (NXP_EXTNS == TRUE)
+  if (NULL != nfc_cb.p_last_disc) {
+    GKI_freebuf(nfc_cb.p_last_disc);
+    nfc_cb.p_last_disc = NULL;
+  }
+#endif
+  /* clear any pending CMD/RSP */
+  nfc_main_flush_cmd_queue();
+}
+
+/*******************************************************************************
+**
+** Function         nfc_main_handle_hal_evt
+**
+** Description      Handle BT_EVT_TO_NFC_MSGS
+**
+*******************************************************************************/
+void nfc_main_handle_hal_evt(tNFC_HAL_EVT_MSG* p_msg) {
+  uint8_t* ps;
+  NFC_TRACE_DEBUG1("nfc_main_handle_hal_evt(): HAL event=0x%x", p_msg->hal_evt);
+
+  switch (p_msg->hal_evt) {
+    case HAL_NFC_OPEN_CPLT_EVT: /* only for failure case */
+      nfc_enabled(NFC_STATUS_FAILED, NULL);
+      break;
+
+    case HAL_NFC_CLOSE_CPLT_EVT:
+      if (nfc_cb.p_resp_cback) {
+        if (nfc_cb.nfc_state == NFC_STATE_W4_HAL_CLOSE) {
+          if (nfc_cb.flags & NFC_FL_POWER_OFF_SLEEP) {
+            nfc_cb.flags &= ~NFC_FL_POWER_OFF_SLEEP;
+            nfc_set_state(NFC_STATE_NFCC_POWER_OFF_SLEEP);
+            (*nfc_cb.p_resp_cback)(NFC_NFCC_POWER_OFF_REVT, NULL);
+          } else {
+            nfc_set_state(NFC_STATE_NONE);
+            (*nfc_cb.p_resp_cback)(NFC_DISABLE_REVT, NULL);
+            nfc_cb.p_resp_cback = NULL;
+          }
+        } else {
+          /* found error during initialization */
+          nfc_set_state(NFC_STATE_NONE);
+          nfc_main_notify_enable_status(NFC_STATUS_FAILED);
+        }
+      }
+      break;
+
+    case HAL_NFC_POST_INIT_CPLT_EVT:
+      if (nfc_cb.p_nci_init_rsp) {
+        /*
+        ** if NFC_Disable() is called before receiving
+        ** HAL_NFC_POST_INIT_CPLT_EVT, then wait for HAL_NFC_CLOSE_CPLT_EVT.
+        */
+        if (nfc_cb.nfc_state == NFC_STATE_W4_POST_INIT_CPLT) {
+          if (p_msg->status == HAL_NFC_STATUS_OK) {
+            nfc_enabled(NCI_STATUS_OK, nfc_cb.p_nci_init_rsp);
+#if (NXP_EXTNS == TRUE)
+            /*
+             * reading requred EEPROM config vlaues from HAL
+             * and updating libnfc structure.
+             * During Setconfig request these stored values are compared
+             * If found same setconfigs will not be sent
+             * */
+            {
+              nfc_nci_IoctlInOutData_t inpOutData;
+              nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_GET_CONFIG_INFO,
+                                  (void*)&inpOutData);
+              nfa_dm_init_cfgs(
+                  (phNxpNci_getCfg_info_t*)&inpOutData.out.data.nxpNciAtrInfo);
+            }
+#endif
+          } else /* if post initailization failed */
+          {
+            nfc_enabled(NCI_STATUS_FAILED, NULL);
+          }
+        }
+
+        GKI_freebuf(nfc_cb.p_nci_init_rsp);
+        nfc_cb.p_nci_init_rsp = NULL;
+      }
+      break;
+
+    case HAL_NFC_PRE_DISCOVER_CPLT_EVT:
+      /* restore the command window, no matter if the discover command is still
+       * pending */
+      nfc_cb.nci_cmd_window = NCI_MAX_CMD_WINDOW;
+      nfc_cb.flags &= ~NFC_FL_CONTROL_GRANTED;
+      if (nfc_cb.flags & NFC_FL_DISCOVER_PENDING) {
+        /* issue the discovery command now, if it is still pending */
+        nfc_cb.flags &= ~NFC_FL_DISCOVER_PENDING;
+        ps = (uint8_t*)nfc_cb.p_disc_pending;
+        nci_snd_discover_cmd(*ps, (tNFC_DISCOVER_PARAMS*)(ps + 1));
+#if (NXP_EXTNS == TRUE)
+        if (nfc_cb.p_last_disc) {
+          GKI_freebuf(nfc_cb.p_last_disc);
+          nfc_cb.p_last_disc = NULL;
+        }
+        nfc_cb.p_last_disc = nfc_cb.p_disc_pending;
+#else
+        GKI_freebuf(nfc_cb.p_disc_pending);
+#endif
+        nfc_cb.p_disc_pending = NULL;
+      } else {
+        /* check if there's other pending commands */
+        nfc_ncif_check_cmd_queue(NULL);
+      }
+
+      if (p_msg->status == HAL_NFC_STATUS_ERR_CMD_TIMEOUT)
+        nfc_ncif_event_status(NFC_NFCC_TIMEOUT_REVT, NFC_STATUS_HW_TIMEOUT);
+      break;
+
+    case HAL_NFC_REQUEST_CONTROL_EVT:
+      nfc_cb.flags |= NFC_FL_CONTROL_REQUESTED;
+      nfc_cb.flags |= NFC_FL_HAL_REQUESTED;
+      nfc_ncif_check_cmd_queue(NULL);
+      break;
+
+    case HAL_NFC_RELEASE_CONTROL_EVT:
+      if (nfc_cb.flags & NFC_FL_CONTROL_GRANTED) {
+        nfc_cb.flags &= ~NFC_FL_CONTROL_GRANTED;
+        nfc_cb.nci_cmd_window = NCI_MAX_CMD_WINDOW;
+        nfc_ncif_check_cmd_queue(NULL);
+
+        if (p_msg->status == HAL_NFC_STATUS_ERR_CMD_TIMEOUT)
+          nfc_ncif_event_status(NFC_NFCC_TIMEOUT_REVT, NFC_STATUS_HW_TIMEOUT);
+      }
+      break;
+
+    case HAL_NFC_ERROR_EVT:
+      switch (p_msg->status) {
+        case HAL_NFC_STATUS_ERR_TRANSPORT:
+          /* Notify app of transport error */
+          if (nfc_cb.p_resp_cback) {
+            (*nfc_cb.p_resp_cback)(NFC_NFCC_TRANSPORT_ERR_REVT, NULL);
+
+            /* if enabling NFC, notify upper layer of failure after closing HAL
+             */
+            if (nfc_cb.nfc_state < NFC_STATE_IDLE) {
+              nfc_enabled(NFC_STATUS_FAILED, NULL);
+            }
+          }
+          break;
+
+        case HAL_NFC_STATUS_ERR_CMD_TIMEOUT:
+          nfc_ncif_event_status(NFC_NFCC_TIMEOUT_REVT, NFC_STATUS_HW_TIMEOUT);
+
+          /* if enabling NFC, notify upper layer of failure after closing HAL */
+          if (nfc_cb.nfc_state < NFC_STATE_IDLE) {
+            nfc_enabled(NFC_STATUS_FAILED, NULL);
+            return;
+          }
+          break;
+
+        default:
+          break;
+      }
+      break;
+#if (NXP_EXTNS == TRUE)
+    case HAL_NFC_POST_MIN_INIT_CPLT_EVT:
+      nfa_sys_cback_notify_MinEnable_complete(0);
+      break;
+#endif
+    default:
+      NFC_TRACE_ERROR1("nfc_main_handle_hal_evt (): unhandled event (0x%x).",
+                       p_msg->hal_evt);
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_main_flush_cmd_queue
+**
+** Description      This function is called when setting power off sleep state.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_main_flush_cmd_queue(void) {
+  NFC_HDR* p_msg;
+
+  NFC_TRACE_DEBUG0("nfc_main_flush_cmd_queue ()");
+
+  /* initialize command window */
+  nfc_cb.nci_cmd_window = NCI_MAX_CMD_WINDOW;
+
+  /* Stop command-pending timer */
+  nfc_stop_timer(&nfc_cb.nci_wait_rsp_timer);
+
+  /* dequeue and free buffer */
+  while ((p_msg = (NFC_HDR*)GKI_dequeue(&nfc_cb.nci_cmd_xmit_q)) != NULL) {
+    GKI_freebuf(p_msg);
+  }
+#if (NXP_EXTNS == TRUE)
+  if (NULL != nfc_cb.last_cmd_buf) {
+    GKI_freebuf(nfc_cb.last_cmd_buf);
+    nfc_cb.last_cmd_buf = NULL;
+  }
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         nfc_main_post_hal_evt
+**
+** Description      This function posts HAL event to NFC_TASK
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_main_post_hal_evt(uint8_t hal_evt, tHAL_NFC_STATUS status) {
+  tNFC_HAL_EVT_MSG* p_msg;
+
+  p_msg = (tNFC_HAL_EVT_MSG*)GKI_getbuf(sizeof(tNFC_HAL_EVT_MSG));
+  if (p_msg != NULL) {
+    /* Initialize NFC_HDR */
+    p_msg->hdr.len = 0;
+    p_msg->hdr.event = BT_EVT_TO_NFC_MSGS;
+    p_msg->hdr.offset = 0;
+    p_msg->hdr.layer_specific = 0;
+    p_msg->hal_evt = hal_evt;
+    p_msg->status = status;
+    GKI_send_msg(NFC_TASK, NFC_MBOX_ID, p_msg);
+  } else {
+    NFC_TRACE_ERROR0("nfc_main_post_hal_evt (): No buffer");
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_main_hal_cback
+**
+** Description      HAL event handler
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfc_main_hal_cback(uint8_t event, tHAL_NFC_STATUS status) {
+#if (BT_TRACE_VERBOSE == true)
+  NFC_TRACE_DEBUG3("nfc_main_hal_cback event: %s(0x%x), status=%d",
+                   nfc_hal_event_name(event), event, status);
+#else
+  NFC_TRACE_DEBUG2("nfc_main_hal_cback event: 0x%x, status=%d", event, status);
+#endif
+#if (NXP_EXTNS == TRUE)
+  tNFC_RESPONSE eventData;
+#endif
+  switch (event) {
+    case HAL_NFC_OPEN_CPLT_EVT:
+      /*
+      ** if NFC_Disable() is called before receiving HAL_NFC_OPEN_CPLT_EVT,
+      ** then wait for HAL_NFC_CLOSE_CPLT_EVT.
+      */
+      if (nfc_cb.nfc_state == NFC_STATE_W4_HAL_OPEN) {
+        if (status == HAL_NFC_STATUS_OK) {
+            NFC_GetFeatureList();
+          /* Notify NFC_TASK that NCI tranport is initialized */
+          GKI_send_event(NFC_TASK, NFC_TASK_EVT_TRANSPORT_READY);
+        } else {
+          nfc_main_post_hal_evt(event, status);
+        }
+      }
+      break;
+
+    case HAL_NFC_CLOSE_CPLT_EVT:
+    case HAL_NFC_POST_INIT_CPLT_EVT:
+    case HAL_NFC_PRE_DISCOVER_CPLT_EVT:
+    case HAL_NFC_REQUEST_CONTROL_EVT:
+    case HAL_NFC_RELEASE_CONTROL_EVT:
+    case HAL_NFC_ERROR_EVT:
+#if (NXP_EXTNS == TRUE)
+    case HAL_NFC_POST_MIN_INIT_CPLT_EVT:
+        if( nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT) {
+            if (status == HAL_NFC_STATUS_ERR_CMD_TIMEOUT) {
+                eventData.status = (tNFC_STATUS)NFC_STATUS_FAILED;
+                /* Notify app of transport error */
+                if (nfc_cb.p_resp_cback) {
+                    (*nfc_cb.p_resp_cback)(NFC_NFCC_TIMEOUT_REVT, &eventData);
+                    /* if enabling NFC, notify upper layer of failure after closing HAL*/
+                    if (nfc_cb.nfc_state < NFC_STATE_IDLE) {
+                        nfc_enabled(NFC_STATUS_FAILED, NULL);
+                    }
+                }
+                break;
+            }
+        }
+#endif
+      nfc_main_post_hal_evt(event, status);
+      break;
+    case HAL_NFC_ENABLE_I2C_FRAGMENTATION_EVT: {
+      NFC_TRACE_DEBUG1("nfc_main_hal_cback handled  event  %x", event);
+      set_i2c_fragmentation_enabled(I2C_FRAGMENATATION_ENABLED);
+    } break;
+    default:
+      NFC_TRACE_DEBUG1("nfc_main_hal_cback unhandled event %x", event);
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_main_hal_data_cback
+**
+** Description      HAL data event handler
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfc_main_hal_data_cback(uint16_t data_len, uint8_t* p_data) {
+  NFC_HDR* p_msg;
+
+  /* ignore all data while shutting down NFCC */
+  if (nfc_cb.nfc_state == NFC_STATE_W4_HAL_CLOSE) {
+    return;
+  }
+
+  if (p_data) {
+    p_msg = (NFC_HDR*)GKI_getpoolbuf(NFC_NCI_POOL_ID);
+    if (p_msg != NULL) {
+      /* Initialize NFC_HDR */
+      p_msg->len = data_len;
+      p_msg->event = BT_EVT_TO_NFC_NCI;
+      p_msg->offset = NFC_RECEIVE_MSGS_OFFSET;
+
+      /* no need to check length, it always less than pool size */
+      memcpy((uint8_t*)(p_msg + 1) + p_msg->offset, p_data, p_msg->len);
+
+      GKI_send_msg(NFC_TASK, NFC_MBOX_ID, p_msg);
+    } else {
+      NFC_TRACE_ERROR0("nfc_main_hal_data_cback (): No buffer");
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         NFC_Enable
+**
+** Description      This function enables NFC. Prior to calling NFC_Enable:
+**                  - the NFCC must be powered up, and ready to receive
+**                    commands.
+**                  - GKI must be enabled
+**                  - NFC_TASK must be started
+**                  - NCIT_TASK must be started (if using dedicated NCI
+**                    transport)
+**
+**                  This function opens the NCI transport (if applicable),
+**                  resets the NFC controller, and initializes the NFC
+**                  subsystems.
+**
+**                  When the NFC startup procedure is completed, an
+**                  NFC_ENABLE_REVT is returned to the application using the
+**                  tNFC_RESPONSE_CBACK.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_Enable(tNFC_RESPONSE_CBACK* p_cback) {
+  NFC_TRACE_API0("NFC_Enable ()");
+
+  /* Validate callback */
+  if (!p_cback) {
+    return (NFC_STATUS_INVALID_PARAM);
+  }
+  nfc_cb.p_resp_cback = p_cback;
+
+  /* Open HAL transport. */
+  nfc_set_state(NFC_STATE_W4_HAL_OPEN);
+#if (NXP_EXTNS == TRUE)
+  if (nfc_cb.boot_mode != NFC_NORMAL_BOOT_MODE) {
+    nfc_nci_IoctlInOutData_t inpOutData;
+    inpOutData.inp.data.bootMode = nfc_cb.boot_mode;
+    nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_SET_BOOT_MODE, (void*)&inpOutData);
+  }
+#endif
+  nfc_cb.p_hal->open(nfc_main_hal_cback, nfc_main_hal_data_cback);
+  return (NFC_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         NFC_Disable
+**
+** Description      This function performs clean up routines for shutting down
+**                  NFC and closes the NCI transport (if using dedicated NCI
+**                  transport).
+**
+**                  When the NFC shutdown procedure is completed, an
+**                  NFC_DISABLED_REVT is returned to the application using the
+**                  tNFC_RESPONSE_CBACK.
+**
+** Returns          nothing
+**
+*******************************************************************************/
+void NFC_Disable(void) {
+  NFC_TRACE_API1("NFC_Disable (): nfc_state = %d", nfc_cb.nfc_state);
+
+  if ((nfc_cb.nfc_state == NFC_STATE_NONE) ||
+      (nfc_cb.nfc_state == NFC_STATE_NFCC_POWER_OFF_SLEEP)) {
+    nfc_set_state(NFC_STATE_NONE);
+    if (nfc_cb.p_resp_cback) {
+      (*nfc_cb.p_resp_cback)(NFC_DISABLE_REVT, NULL);
+      nfc_cb.p_resp_cback = NULL;
+    }
+    return;
+  }
+
+#if (NXP_EXTNS == TRUE)
+  if (nfc_cb.boot_mode != NFC_NORMAL_BOOT_MODE) {
+    nfc_nci_IoctlInOutData_t inpOutData;
+    inpOutData.inp.data.bootMode = NFC_NORMAL_BOOT_MODE;
+    nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_SET_BOOT_MODE, (void*)&inpOutData);
+  }
+#endif
+
+  if(nfcFL.nfcNxpEse) {
+      tNFC_STATUS setPidStatus = NFC_STATUS_OK;
+      nfc_nci_IoctlInOutData_t inpOutData;
+      inpOutData.inp.data.nfcServicePid = 0;
+      setPidStatus = nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_SET_NFC_SERVICE_PID,(void*)&inpOutData);
+      if (setPidStatus == NFC_STATUS_OK) {
+          NFC_TRACE_API0("nfc service set pid done");
+      } else {
+          NFC_TRACE_API0("nfc service set pid failed");
+      }
+  }
+
+  /* Close transport and clean up */
+  nfc_task_shutdown_nfcc();
+
+}
+
+/*******************************************************************************
+**
+** Function         NFC_Init
+**
+** Description      This function initializes control block for NFC
+**
+** Returns          nothing
+**
+*******************************************************************************/
+#if (NXP_EXTNS == TRUE)
+void NFC_Init(tHAL_NFC_CONTEXT* p_hal_entry_cntxt)
+#else
+void NFC_Init(tHAL_NFC_ENTRY* p_hal_entry_tbl)
+#endif
+{
+  int xx;
+
+  /* Clear nfc control block */
+  memset(&nfc_cb, 0, sizeof(tNFC_CB));
+
+  /* Reset the nfc control block */
+  for (xx = 0; xx < NCI_MAX_CONN_CBS; xx++) {
+    nfc_cb.conn_cb[xx].conn_id = NFC_ILLEGAL_CONN_ID;
+  }
+
+/* NCI init */
+#if (NXP_EXTNS == TRUE)
+  nfc_cb.p_hal = p_hal_entry_cntxt->hal_entry_func;
+#else
+  nfc_cb.p_hal = p_hal_entry_tbl;
+#endif
+  nfc_cb.nfc_state = NFC_STATE_NONE;
+  nfc_cb.nci_cmd_window = NCI_MAX_CMD_WINDOW;
+  nfc_cb.nci_wait_rsp_tout = NFC_CMD_CMPL_TIMEOUT;
+
+  if(nfcFL.chipType != pn547C2) {
+  nfc_cb.p_disc_maps = nfc_interface_mapping;
+  }
+  else {
+      nfc_cb.p_disc_maps = nfc_interface_mapping_stat;
+  }
+
+  nfc_cb.num_disc_maps = NFC_NUM_INTERFACE_MAP;
+  nfc_cb.trace_level = NFC_INITIAL_TRACE_LEVEL;
+  nfc_cb.nci_ctrl_size = NCI_CTRL_INIT_SIZE;
+  nfc_cb.reassembly = true;
+  nfc_cb.nci_version = NCI_VERSION_UNKNOWN;
+#if (NXP_EXTNS == TRUE)
+  nfc_cb.boot_mode = p_hal_entry_cntxt->boot_mode;
+  nfc_cb.bBlockWiredMode = false;
+  nfc_cb.bRetransmitDwpPacket = false;
+  nfc_cb.bIsCreditNtfRcvd = false;
+  nfc_cb.temp_data = NULL;
+  nfc_cb.bSetmodeOnReq = false;
+  nfc_cb.bIsDwpResPending = false;
+  nfc_cb.bIssueModeSetCmd = false;
+  nfc_cb.bCeActivatedeSE = false;
+  nfc_cb.pwr_link_cmd.bPwrLinkCmdRequested = false;
+  nfc_cb.bBlkPwrlinkAndModeSetCmd = false;
+  if (p_hal_entry_cntxt->boot_mode != NFC_FAST_BOOT_MODE)
+#endif
+  {
+    rw_init();
+    ce_init();
+    llcp_init();
+#if (NXP_EXTNS == TRUE)
+  }
+#endif
+
+  NFC_SET_MAX_CONN_DEFAULT();
+}
+
+/*******************************************************************************
+**
+** Function         NFC_GetLmrtSize
+**
+** Description      Called by application wto query the Listen Mode Routing
+**                  Table size supported by NFCC
+**
+** Returns          Listen Mode Routing Table size
+**
+*******************************************************************************/
+uint16_t NFC_GetLmrtSize(void) {
+  uint16_t size = 0;
+#if (NFC_RW_ONLY == FALSE)
+  size = nfc_cb.max_ce_table;
+#endif
+  return size;
+}
+/*******************************************************************************
+**
+** Function         NFC_GetNCIVersion
+**
+** Description      Called by higher layer to get the current nci
+**                  version of nfc.
+**
+** Returns          NCI version NCI2.0 / NCI1.0
+**
+*******************************************************************************/
+uint8_t NFC_GetNCIVersion() {
+  return nfc_cb.nci_version;
+}
+
+/*******************************************************************************
+**
+** Function         NFC_SetConfig
+**
+** Description      This function is called to send the configuration parameter
+**                  TLV to NFCC. The response from NFCC is reported by
+**                  tNFC_RESPONSE_CBACK as NFC_SET_CONFIG_REVT.
+**
+** Parameters       tlv_size - the length of p_param_tlvs.
+**                  p_param_tlvs - the parameter ID/Len/Value list
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_SetConfig(uint8_t tlv_size, uint8_t* p_param_tlvs) {
+  return nci_snd_core_set_config(p_param_tlvs, tlv_size);
+}
+
+/*******************************************************************************
+**
+** Function         NFC_GetConfig
+**
+** Description      This function is called to retrieve the parameter TLV from
+**                  NFCC. The response from NFCC is reported by
+**                  tNFC_RESPONSE_CBACK as NFC_GET_CONFIG_REVT.
+**
+** Parameters       num_ids - the number of parameter IDs
+**                  p_param_ids - the parameter ID list.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_GetConfig(uint8_t num_ids, uint8_t* p_param_ids) {
+  return nci_snd_core_get_config(p_param_ids, num_ids);
+}
+
+/*******************************************************************************
+**
+** Function         NFC_DiscoveryMap
+**
+** Description      This function is called to set the discovery interface
+**                  mapping. The response from NFCC is reported by
+**                  tNFC_DISCOVER_CBACK as NFC_MAP_DEVT.
+**
+** Parameters       num - the number of items in p_params.
+**                  p_maps - the discovery interface mappings
+**                  p_cback - the discovery callback function
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_DiscoveryMap(uint8_t num, tNFC_DISCOVER_MAPS* p_maps,
+                             tNFC_DISCOVER_CBACK* p_cback) {
+  uint8_t num_disc_maps = num;
+  uint8_t xx, yy, num_intf, intf_mask;
+  tNFC_DISCOVER_MAPS
+      max_maps[NFC_NFCC_MAX_NUM_VS_INTERFACE + NCI_INTERFACE_MAX];
+  bool is_supported;
+#if (NXP_EXTNS == TRUE)
+  nfc_cb.num_disc_maps = num;
+#endif
+  nfc_cb.p_discv_cback = p_cback;
+  num_intf = 0;
+  NFC_TRACE_DEBUG2("nci_interfaces supported by NFCC: 0x%x num = 0x%x",
+                   nfc_cb.nci_interfaces, num);
+
+  for (xx = 0; xx < NFC_NFCC_MAX_NUM_VS_INTERFACE + NCI_INTERFACE_MAX; xx++) {
+    memset(&max_maps[xx], 0x00, sizeof(tNFC_DISCOVER_MAPS));
+  }
+
+  for (xx = 0; xx < num_disc_maps; xx++) {
+    is_supported = false;
+    if (p_maps[xx].intf_type > NCI_INTERFACE_MAX) {
+        for (yy = 0; yy < NFC_NFCC_MAX_NUM_VS_INTERFACE; yy++) {
+            if(nfcFL.nfccFL._NFCC_FW_WA) {
+                if ((nfc_cb.vs_interface[yy] == p_maps[xx].intf_type) ||
+                        (nfcFL.nfcMwFL._NCI_INTERFACE_ESE_DIRECT == p_maps[xx].intf_type)) {
+                    is_supported = true;
+                }
+            }
+            else {
+                if (nfc_cb.vs_interface[yy] == p_maps[xx].intf_type) {
+                    is_supported = true;
+                }
+            }
+        }
+        NFC_TRACE_DEBUG3("[%d]: vs intf_type:0x%x is_supported:%d", xx,
+                p_maps[xx].intf_type, is_supported);
+    } else {
+      intf_mask = (1 << (p_maps[xx].intf_type));
+      if ((intf_mask & nfc_cb.nci_interfaces)) {
+        is_supported = true;
+      }
+      NFC_TRACE_DEBUG4("[%d]: intf_type:%d intf_mask: 0x%x is_supported:%d", xx,
+                       p_maps[xx].intf_type, intf_mask, is_supported);
+    }
+    if (is_supported) {
+      if (num_intf < (NFC_NFCC_MAX_NUM_VS_INTERFACE + NCI_INTERFACE_MAX)) {
+        memcpy(&max_maps[num_intf++], &p_maps[xx], sizeof(tNFC_DISCOVER_MAPS));
+      } else {
+        NFC_TRACE_DEBUG1("num_intf exeeds the limit 0x%02x",
+                         NFC_NFCC_MAX_NUM_VS_INTERFACE + NCI_INTERFACE_MAX);
+      }
+    } else {
+      NFC_TRACE_WARNING1(
+          "NFC_DiscoveryMap interface=0x%x is not supported by NFCC",
+          p_maps[xx].intf_type);
+      if(nfcFL.chipType != pn547C2) {
+          return NFC_STATUS_FAILED;
+      }
+    }
+  }
+
+  NFC_TRACE_WARNING1("num_intf = 0x%2x", num_intf);
+
+  for (xx = 0; xx < NFC_NFCC_MAX_NUM_VS_INTERFACE + NCI_INTERFACE_MAX; xx++) {
+    NFC_TRACE_WARNING2("max_maps[%d].intf_type = 0x%2x", xx,
+                       max_maps[xx].intf_type);
+    NFC_TRACE_WARNING2("max_maps[%d].mode = 0x%2x", xx, max_maps[xx].mode);
+    NFC_TRACE_WARNING2("max_maps[%d].protocol = 0x%2x", xx,
+                       max_maps[xx].protocol);
+  }
+  return nci_snd_discover_map_cmd(num_intf, (tNCI_DISCOVER_MAPS*)max_maps);
+}
+
+/*******************************************************************************
+**
+** Function         NFC_DiscoveryStart
+**
+** Description      This function is called to start Polling and/or Listening.
+**                  The response from NFCC is reported by tNFC_DISCOVER_CBACK as
+**                  NFC_START_DEVT. The notification from NFCC is reported by
+**                  tNFC_DISCOVER_CBACK as NFC_RESULT_DEVT.
+**
+** Parameters       num_params - the number of items in p_params.
+**                  p_params - the discovery parameters
+**                  p_cback - the discovery callback function
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_DiscoveryStart(uint8_t num_params,
+                               tNFC_DISCOVER_PARAMS* p_params,
+                               tNFC_DISCOVER_CBACK* p_cback) {
+  uint8_t* p;
+  int params_size;
+  tNFC_STATUS status = NFC_STATUS_NO_BUFFERS;
+
+  NFC_TRACE_API0("NFC_DiscoveryStart");
+  if (nfc_cb.p_disc_pending) {
+    NFC_TRACE_ERROR0("There's pending NFC_DiscoveryStart");
+    status = NFC_STATUS_BUSY;
+  } else {
+    nfc_cb.p_discv_cback = p_cback;
+    nfc_cb.flags |= NFC_FL_DISCOVER_PENDING;
+    nfc_cb.flags |= NFC_FL_CONTROL_REQUESTED;
+    params_size = sizeof(tNFC_DISCOVER_PARAMS) * num_params;
+
+    nfc_cb.p_disc_pending =
+        GKI_getbuf((uint16_t)(NFC_HDR_SIZE + 1 + params_size));
+    if (nfc_cb.p_disc_pending) {
+      p = (uint8_t*)nfc_cb.p_disc_pending;
+      *p++ = num_params;
+      memcpy(p, p_params, params_size);
+      status = NFC_STATUS_CMD_STARTED;
+      nfc_ncif_check_cmd_queue(NULL);
+    }
+  }
+
+  NFC_TRACE_API1("NFC_DiscoveryStart status: 0x%x", status);
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFC_DiscoverySelect
+**
+** Description      If tNFC_DISCOVER_CBACK reports status=NFC_MULTIPLE_PROT,
+**                  the application needs to use this function to select the
+**                  the logical endpoint to continue. The response from NFCC is
+**                  reported by tNFC_DISCOVER_CBACK as NFC_SELECT_DEVT.
+**
+** Parameters       rf_disc_id - The ID identifies the remote device.
+**                  protocol - the logical endpoint on the remote devide
+**                  rf_interface - the RF interface to communicate with NFCC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_DiscoverySelect(uint8_t rf_disc_id, uint8_t protocol,
+                                uint8_t rf_interface) {
+  return nci_snd_discover_select_cmd(rf_disc_id, protocol, rf_interface);
+}
+
+/*******************************************************************************
+**
+** Function         NFC_ConnCreate
+**
+** Description      This function is called to create a logical connection with
+**                  NFCC for data exchange.
+**
+** Parameters       dest_type - the destination type
+**                  id   - the NFCEE ID or RF Discovery ID .
+**                  protocol   - the protocol.
+**                  p_cback - the connection callback function
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_ConnCreate(uint8_t dest_type, uint8_t id, uint8_t protocol,
+                           tNFC_CONN_CBACK* p_cback) {
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  tNFC_CONN_CB* p_cb;
+  uint8_t num_tlv = 0, tlv_size = 0;
+  uint8_t param_tlvs[4], *pp;
+
+  p_cb = nfc_alloc_conn_cb(p_cback);
+  if (p_cb) {
+    p_cb->id = id;
+    pp = param_tlvs;
+    if (dest_type == NCI_DEST_TYPE_NFCEE) {
+      num_tlv = 1;
+      UINT8_TO_STREAM(pp, NCI_CON_CREATE_TAG_NFCEE_VAL);
+      UINT8_TO_STREAM(pp, 2);
+      UINT8_TO_STREAM(pp, id);
+      UINT8_TO_STREAM(pp, protocol);
+      tlv_size = 4;
+    } else if (dest_type == NCI_DEST_TYPE_REMOTE) {
+      num_tlv = 1;
+      UINT8_TO_STREAM(pp, NCI_CON_CREATE_TAG_RF_DISC_ID);
+      UINT8_TO_STREAM(pp, 1);
+      UINT8_TO_STREAM(pp, id);
+      tlv_size = 3;
+    } else if (dest_type == NCI_DEST_TYPE_NFCC) {
+      p_cb->id = NFC_TEST_ID;
+    }
+    /* Add handling of NCI_DEST_TYPE_REMOTE when more RF interface definitions
+     * are added */
+    p_cb->act_protocol = protocol;
+    p_cb->p_cback = p_cback;
+    status = nci_snd_core_conn_create(dest_type, num_tlv, tlv_size, param_tlvs);
+    if (status == NFC_STATUS_FAILED) nfc_free_conn_cb(p_cb);
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFC_ConnClose
+**
+** Description      This function is called to close a logical connection with
+**                  NFCC.
+**
+** Parameters       conn_id - the connection id.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_ConnClose(uint8_t conn_id) {
+  tNFC_CONN_CB* p_cb = nfc_find_conn_cb_by_conn_id(conn_id);
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+
+  if (p_cb) {
+    status = nci_snd_core_conn_close(conn_id);
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFC_SetStaticRfCback
+**
+** Description      This function is called to update the data callback function
+**                  to receive the data for the given connection id.
+**
+** Parameters       p_cback - the connection callback function
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void NFC_SetStaticRfCback(tNFC_CONN_CBACK* p_cback) {
+  tNFC_CONN_CB* p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+
+  p_cb->p_cback = p_cback;
+  /* just in case DH has received NCI data before the data callback is set
+   * check if there's any data event to report on this connection id */
+  nfc_data_event(p_cb);
+}
+
+/*******************************************************************************
+**
+** Function         NFC_SetReassemblyFlag
+**
+** Description      This function is called to set if nfc will reassemble
+**                  nci packet as much as its buffer can hold or it should not
+**                  reassemble but forward the fragmented nci packet to layer
+**                  above. If nci data pkt is fragmented, nfc may send multiple
+**                  NFC_DATA_CEVT with status NFC_STATUS_CONTINUE before sending
+**                  NFC_DATA_CEVT with status NFC_STATUS_OK based on reassembly
+**                  configuration and reassembly buffer size
+**
+** Parameters       reassembly - flag to indicate if nfc may reassemble or not
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void NFC_SetReassemblyFlag(bool reassembly) { nfc_cb.reassembly = reassembly; }
+
+/*******************************************************************************
+**
+** Function         NFC_SendData
+**
+** Description      This function is called to send the given data packet
+**                  to the connection identified by the given connection id.
+**
+** Parameters       conn_id - the connection id.
+**                  p_data - the data packet.
+**                  p_data->offset must be >= NCI_MSG_OFFSET_SIZE +
+**                  NCI_DATA_HDR_SIZE
+**                  The data payload starts at
+**                  ((uint8_t *) (p_data + 1) + p_data->offset)
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_SendData(uint8_t conn_id, NFC_HDR* p_data) {
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  tNFC_CONN_CB* p_cb = nfc_find_conn_cb_by_conn_id(conn_id);
+
+  if (p_cb && p_data &&
+      p_data->offset >= NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE) {
+    status = nfc_ncif_send_data(p_cb, p_data);
+  }
+
+  if (status != NFC_STATUS_OK) GKI_freebuf(p_data);
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFC_FlushData
+**
+** Description      This function is called to discard the tx data queue of
+**                  the given connection id.
+**
+** Parameters       conn_id - the connection id.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_FlushData(uint8_t conn_id) {
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  tNFC_CONN_CB* p_cb = nfc_find_conn_cb_by_conn_id(conn_id);
+  void* p_buf;
+
+  if (p_cb) {
+    status = NFC_STATUS_OK;
+    while ((p_buf = GKI_dequeue(&p_cb->tx_q)) != NULL) GKI_freebuf(p_buf);
+  }
+
+  return status;
+}
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         NFC_Queue_Is_empty
+**
+** Description      This function to get NFCEE connection ID queue information
+**
+** Returns          1 if Queue is empty else 0
+**
+*******************************************************************************/
+bool NFC_Queue_Is_empty(uint8_t conn_id) {
+  tNFC_CONN_CB* p_cb = nfc_find_conn_cb_by_conn_id(conn_id);
+  if (p_cb) {
+    return (GKI_queue_is_empty(&p_cb->tx_q));
+  } else
+    return false;
+}
+#endif
+/*******************************************************************************
+**
+** Function         NFC_Deactivate
+**
+** Description      This function is called to stop the discovery process or
+**                  put the listen device in sleep mode or terminate the NFC
+**                  link.
+**
+**                  The response from NFCC is reported by tNFC_DISCOVER_CBACK
+**                  as NFC_DEACTIVATE_DEVT.
+**
+** Parameters       deactivate_type - NFC_DEACTIVATE_TYPE_IDLE, to IDLE mode.
+**                                    NFC_DEACTIVATE_TYPE_SLEEP to SLEEP mode.
+**                                    NFC_DEACTIVATE_TYPE_SLEEP_AF to SLEEP_AF
+**                                    mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_Deactivate(tNFC_DEACT_TYPE deactivate_type) {
+  tNFC_CONN_CB* p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+  tNFC_STATUS status = NFC_STATUS_OK;
+
+#if (BT_TRACE_VERBOSE == true)
+  NFC_TRACE_API3("NFC_Deactivate %d (%s) deactivate_type:%d", nfc_cb.nfc_state,
+                 nfc_state_name(nfc_cb.nfc_state), deactivate_type);
+#else
+    NFC_TRACE_API2("NFC_Deactivate %d deactivate_type:%d", nfc_cb.nfc_state,
+                   deactivate_type);
+#endif
+
+  if (nfc_cb.flags & NFC_FL_DISCOVER_PENDING) {
+    /* the HAL pre-discover is still active - clear the pending flag */
+    nfc_cb.flags &= ~NFC_FL_DISCOVER_PENDING;
+    if (!(nfc_cb.flags & NFC_FL_HAL_REQUESTED)) {
+      /* if HAL did not request for control, clear this bit now */
+      nfc_cb.flags &= ~NFC_FL_CONTROL_REQUESTED;
+    }
+#if (NXP_EXTNS == TRUE)
+    if (nfc_cb.p_last_disc) {
+      GKI_freebuf(nfc_cb.p_last_disc);
+      nfc_cb.p_last_disc = NULL;
+    }
+    nfc_cb.p_last_disc = nfc_cb.p_disc_pending;
+#else
+      GKI_freebuf(nfc_cb.p_disc_pending);
+#endif
+    nfc_cb.p_disc_pending = NULL;
+    return NFC_STATUS_OK;
+  }
+
+  if (nfc_cb.nfc_state == NFC_STATE_OPEN) {
+    nfc_set_state(NFC_STATE_CLOSING);
+    NFC_TRACE_DEBUG3("act_protocol %d credits:%d/%d", p_cb->act_protocol,
+                     p_cb->init_credits, p_cb->num_buff);
+    if ((p_cb->act_protocol == NCI_PROTOCOL_NFC_DEP) &&
+        (p_cb->init_credits != p_cb->num_buff)) {
+      nfc_cb.flags |= NFC_FL_DEACTIVATING;
+      nfc_cb.deactivate_timer.param = (uintptr_t)deactivate_type;
+      nfc_start_timer(&nfc_cb.deactivate_timer,
+                      (uint16_t)(NFC_TTYPE_WAIT_2_DEACTIVATE),
+                      NFC_DEACTIVATE_TIMEOUT);
+      return status;
+    }
+  }
+
+  status = nci_snd_deactivate_cmd(deactivate_type);
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFC_UpdateRFCommParams
+**
+** Description      This function is called to update RF Communication
+**                  parameters once the Frame RF Interface has been activated.
+**
+**                  The response from NFCC is reported by tNFC_RESPONSE_CBACK
+**                  as NFC_RF_COMM_PARAMS_UPDATE_REVT.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_UpdateRFCommParams(tNFC_RF_COMM_PARAMS* p_params) {
+  uint8_t tlvs[12];
+  uint8_t* p = tlvs;
+  uint8_t data_exch_config;
+
+  /* RF Technology and Mode */
+  if (p_params->include_rf_tech_mode) {
+    UINT8_TO_STREAM(p, NCI_RF_PARAM_ID_TECH_N_MODE);
+    UINT8_TO_STREAM(p, 1);
+    UINT8_TO_STREAM(p, p_params->rf_tech_n_mode);
+  }
+
+  /* Transmit Bit Rate */
+  if (p_params->include_tx_bit_rate) {
+    UINT8_TO_STREAM(p, NCI_RF_PARAM_ID_TX_BIT_RATE);
+    UINT8_TO_STREAM(p, 1);
+    UINT8_TO_STREAM(p, p_params->tx_bit_rate);
+  }
+
+  /* Receive Bit Rate */
+  if (p_params->include_tx_bit_rate) {
+    UINT8_TO_STREAM(p, NCI_RF_PARAM_ID_RX_BIT_RATE);
+    UINT8_TO_STREAM(p, 1);
+    UINT8_TO_STREAM(p, p_params->rx_bit_rate);
+  }
+
+  /* NFC-B Data Exchange Configuration */
+  if (p_params->include_nfc_b_config) {
+    UINT8_TO_STREAM(p, NCI_RF_PARAM_ID_B_DATA_EX_PARAM);
+    UINT8_TO_STREAM(p, 1);
+
+    data_exch_config = (p_params->min_tr0 & 0x03) << 6; /* b7b6 : Mininum TR0 */
+    data_exch_config |= (p_params->min_tr1 & 0x03)
+                        << 4; /* b5b4 : Mininum TR1 */
+    data_exch_config |= (p_params->suppression_eos & 0x01)
+                        << 3; /* b3 :   Suppression of EoS */
+    data_exch_config |= (p_params->suppression_sos & 0x01)
+                        << 2; /* b2 :   Suppression of SoS */
+    data_exch_config |= (p_params->min_tr2 & 0x03); /* b1b0 : Mininum TR2 */
+
+    UINT8_TO_STREAM(p, data_exch_config);
+  }
+
+  return nci_snd_parameter_update_cmd(tlvs, (uint8_t)(p - tlvs));
+}
+
+/*******************************************************************************
+**
+** Function         NFC_SetPowerOffSleep
+**
+** Description      This function closes/opens transport and turns off/on NFCC.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_SetPowerOffSleep(bool enable) {
+  NFC_TRACE_API1("NFC_SetPowerOffSleep () enable = %d", enable);
+
+  if ((enable == false) &&
+      (nfc_cb.nfc_state == NFC_STATE_NFCC_POWER_OFF_SLEEP)) {
+    nfc_cb.flags |= NFC_FL_RESTARTING;
+
+    /* open transport */
+    nfc_set_state(NFC_STATE_W4_HAL_OPEN);
+    nfc_cb.p_hal->open(nfc_main_hal_cback, nfc_main_hal_data_cback);
+
+    return NFC_STATUS_OK;
+  } else if ((enable == true) && (nfc_cb.nfc_state == NFC_STATE_IDLE)) {
+    /* close transport to turn off NFCC and clean up */
+    nfc_cb.flags |= NFC_FL_POWER_OFF_SLEEP;
+    nfc_task_shutdown_nfcc();
+
+    return NFC_STATUS_OK;
+  }
+
+  NFC_TRACE_ERROR1("NFC_SetPowerOffSleep () invalid state = %d",
+                   nfc_cb.nfc_state);
+  return NFC_STATUS_FAILED;
+}
+
+/*******************************************************************************
+**
+** Function         NFC_SetPowerSubState
+**
+** Description      This function is called to send the power sub state( screen state)
+**                      to NFCC. The response from NFCC is reported by
+**                  tNFC_RESPONSE_CBACK as NFC_SET_POWER_STATE_REVT.
+**
+** Parameters       scree_state
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_SetPowerSubState (uint8_t screen_state)
+{
+  return nci_snd_core_set_power_sub_state(screen_state);
+}
+/*******************************************************************************
+**
+** Function         NFC_PowerCycleNFCC
+**
+** Description      This function turns off and then on NFCC.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_PowerCycleNFCC(void) {
+  NFC_TRACE_API0("NFC_PowerCycleNFCC ()");
+
+  if (nfc_cb.nfc_state == NFC_STATE_IDLE) {
+    /* power cycle NFCC */
+    nfc_cb.flags |= NFC_FL_POWER_CYCLE_NFCC;
+    nfc_task_shutdown_nfcc();
+
+    return NFC_STATUS_OK;
+  }
+
+  NFC_TRACE_ERROR1("NFC_PowerCycleNFCC () invalid state = %d",
+                   nfc_cb.nfc_state);
+  return NFC_STATUS_FAILED;
+}
+
+/*******************************************************************************
+**
+** Function         NFC_SetTraceLevel
+**
+** Description      This function sets the trace level for NFC.  If called with
+**                  a value of 0xFF, it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+uint8_t NFC_SetTraceLevel(uint8_t new_level) {
+  NFC_TRACE_API1("NFC_SetTraceLevel () new_level = %d", new_level);
+
+  if (new_level != 0xFF) nfc_cb.trace_level = new_level;
+
+  return (nfc_cb.trace_level);
+}
+void set_i2c_fragmentation_enabled(int value) {
+  i2c_fragmentation_enabled = value;
+}
+
+int get_i2c_fragmentation_enabled() { return i2c_fragmentation_enabled; }
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         NFC_ReqWiredAccess
+**
+** Description      This function request to pn54x driver to get access
+**                  of P61. Status would be updated to pdata
+**
+** Returns          0 if api call success, else -1
+**
+*******************************************************************************/
+int32_t NFC_ReqWiredAccess(void* pdata) {
+    NFC_TRACE_API0("NFC_ReqWiredAccess");
+
+    if(!nfcFL.nfcNxpEse) {
+        NFC_TRACE_API0("nfcNxpEse is not available.. Returning");
+        return -1;
+    }
+  nfc_nci_IoctlInOutData_t inpOutData;
+  int32_t status;
+  status = nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_P61_WIRED_MODE, &inpOutData);
+  *(tNFC_STATUS*)pdata = inpOutData.out.data.status;
+  return status;
+}
+/*******************************************************************************
+**
+** Function         NFC_RelWiredAccess
+**
+** Description      This function release access
+**                  of P61. Status would be updated to pdata
+**
+** Returns          0 if api call success, else -1
+**
+*******************************************************************************/
+int32_t NFC_RelWiredAccess(void* pdata) {
+  nfc_nci_IoctlInOutData_t inpOutData;
+  int32_t status;
+  status = nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_P61_IDLE_MODE, &inpOutData);
+  *(tNFC_STATUS*)pdata = inpOutData.out.data.status;
+  return status;
+}
+/*******************************************************************************
+**
+** Function         NFC_GetP61Status
+**
+** Description      This function gets the current access state
+**                  of P61. Current state would be updated to pdata
+**
+** Returns          0 if api call success, else -1
+**
+*******************************************************************************/
+int32_t NFC_GetP61Status(void* pdata) {
+  nfc_nci_IoctlInOutData_t inpOutData;
+  int32_t status;
+  status = nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_P61_PWR_MODE, &inpOutData);
+  *(uint32_t*)pdata = inpOutData.out.data.p61CurrentState;
+  return status;
+}
+/*******************************************************************************
+*
+** Function         NFC_DisableWired
+**
+** Description      This function request to pn54x driver to
+**                  disable ese vdd gpio
+**
+** Returns          0 if api call success, else -1
+**
+*******************************************************************************/
+int32_t NFC_DisableWired(void* pdata) {
+  nfc_nci_IoctlInOutData_t inpOutData;
+  int32_t status;
+  status = nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_P61_DISABLE_MODE, &inpOutData);
+  *(tNFC_STATUS*)pdata = inpOutData.out.data.status;
+  return status;
+}
+/*******************************************************************************
+**
+** Function         NFC_EnableWired
+**
+** Description      This function request to pn54x driver to
+**                  enable ese vdd gpio
+**
+** Returns          0 if api call success, else -1
+**
+*******************************************************************************/
+int32_t NFC_EnableWired(void* pdata) {
+  nfc_nci_IoctlInOutData_t inpOutData;
+  int32_t status;
+  status = nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_P61_ENABLE_MODE, &inpOutData);
+  *(tNFC_STATUS*)pdata = inpOutData.out.data.status;
+  return status;
+}
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
++**
+** Function         NFC_Nfcee_PwrLinkCtrl
+**
+** Description      This function is called for NFCC which manages the power
+supply and
+**                  communication links between the NFCC and its connected
+NFCEEs.
+**
+** Parameters       nfcee_id   - the NFCEE ID .
+**                  cfg_value  - 0x00 ->Default Value(NFCC decides)
+**                               0x01 ->NFCEE Power Supply always On
+**                               0x03 ->NFCC to NFCEE Communication link always
+**                                      active when the NFCEE is powered on
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_Nfcee_PwrLinkCtrl(uint8_t nfcee_id, uint8_t cfg_value) {
+    if(!nfcFL.eseFL._WIRED_MODE_STANDBY) {
+        NFC_TRACE_API0("NFC_Nfcee_PwrLinkCtrl :"
+                "WIRED_MODE_STANDBY is not available.. Returning");
+        return NFC_STATUS_FAILED;
+    }
+  return nci_snd_pwr_nd_lnk_ctrl_cmd(nfcee_id, cfg_value);
+}
+
+/*******************************************************************************
+**
+** Function         NFC_SetP61Status
+**
+** Description      This function set the JCOP download
+**                  state to pn544 driver.
+**
+** Returns          0 if api call success, else -1
+**
+*******************************************************************************/
+int32_t NFC_SetP61Status(void* pdata, jcop_dwnld_state_t isJcopState) {
+    if(!nfcFL.eseFL._ESE_JCOP_DWNLD_PROTECTION) {
+        NFC_TRACE_API0("NFC_SetP61Status :"
+                "ESE_JCOP_DWNLD_PROTECTION is not available.. Returning");
+        return -1;
+    }
+  nfc_nci_IoctlInOutData_t inpOutData;
+  int32_t status;
+  if (isJcopState == JCP_DWNLD_START)
+    isJcopState =
+        nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_SET_JCP_DWNLD_ENABLE, &inpOutData);
+  else if (isJcopState == JCP_DWP_DWNLD_COMPLETE)
+    isJcopState =
+        (nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_SET_JCP_DWNLD_DISABLE, &inpOutData));
+  *(tNFC_STATUS*)pdata = inpOutData.out.data.status;
+  return isJcopState;
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         NFC_eSEChipReset
+**
+** Description      This function request to pn54x driver to
+**                  chip reset the ESE using ISO_RST pin configuration.
+**
+** Returns          0 if api call success, else -1
+**
+*******************************************************************************/
+int32_t NFC_eSEChipReset(void* pdata) {
+  nfc_nci_IoctlInOutData_t inpOutData;
+  int32_t status;
+  status = nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_ESE_CHIP_RST, &inpOutData);
+  *(tNFC_STATUS*)pdata = inpOutData.out.data.status;
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFC_GetEseAccess
+**
+** Description      This function request to pn54x driver to get access
+**                  of P61. it returns 0 on success. This api waits maximum
+**                  defined timeout
+**
+** Returns          0 if api call success, else -1
+**
+*******************************************************************************/
+int32_t NFC_GetEseAccess(void* pdata) {
+    int32_t status;
+    if((nfcFL.eseFL._NXP_ESE_VER != JCOP_VER_3_1) &&
+            (nfcFL.eseFL._NXP_ESE_VER != JCOP_VER_3_2)) {
+        NFC_TRACE_API0("NFC_GetEseAccess NXP_ESE_VER !="
+                "JCOP_VER_3_1 or JCOP_VER_3_2 . Returning");
+        return status;
+    }
+    nfc_nci_IoctlInOutData_t inpOutData;
+
+    inpOutData.inp.data.timeoutMilliSec = *(uint32_t*)pdata;
+    status = nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_P61_GET_ACCESS, &inpOutData);
+    return status;
+}
+/*******************************************************************************
+**
+** Function         NFC_RelEseAccess
+**
+** Description      This function release access of P61.
+**                  it returns 0 on success.
+**
+** Returns          0 if api call success, else -1
+**
+*******************************************************************************/
+int32_t NFC_RelEseAccess(void* pdata) {
+    int32_t status;
+    if((nfcFL.eseFL._NXP_ESE_VER != JCOP_VER_3_1) &&
+            (nfcFL.eseFL._NXP_ESE_VER != JCOP_VER_3_2)) {
+        NFC_TRACE_API0("NFC_RelEseAccess NXP_ESE_VER !="
+                "JCOP_VER_3_1 or JCOP_VER_3_2 . Returning");
+        return status;
+    }
+    nfc_nci_IoctlInOutData_t inpOutData;
+
+    status = nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_P61_REL_ACCESS, &inpOutData);
+    *(tNFC_STATUS*)pdata = inpOutData.out.data.status;
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFC_RelSvddWait
+**
+** Description      This function release wait for svdd change
+**                  of P61. Status would be updated to pdata
+**
+** Returns          0 if api call success, else -1
+**
+*******************************************************************************/
+int32_t NFC_RelSvddWait(void* pdata) {
+    if(!nfcFL.eseFL._ESE_SVDD_SYNC) {
+        NFC_TRACE_API0("NFC_RelSvddWait :"
+                "ESE_SVDD_SYNC is not available.. Returning");
+        return -1;
+    }
+  nfc_nci_IoctlInOutData_t inpOutData;
+  int32_t status;
+  status = nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_REL_SVDD_WAIT, &inpOutData);
+  *(tNFC_STATUS*)pdata = inpOutData.out.data.status;
+  return status;
+}
+
+#endif
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         NFC_EnableDisableHalLog
+**
+** Description      This function is used to enable/disable
+**                  HAL log level.
+**
+*******************************************************************************/
+void NFC_EnableDisableHalLog(uint8_t type) {
+  if (0x01 == type || 0x00 == type) {
+    nfc_nci_IoctlInOutData_t inpOutData;
+    inpOutData.inp.data.halType = type;
+    nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_DISABLE_HAL_LOG, &inpOutData);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         NFC_SetNfcServicePid
+**
+** Description      This function request to pn54x driver to
+**                  update NFC service process ID for signalling.
+**
+** Returns          0 if api call success, else -1
+**
+*******************************************************************************/
+int32_t NFC_SetNfcServicePid() {
+    tNFC_STATUS setPidStatus = NFC_STATUS_OK;
+    nfc_nci_IoctlInOutData_t inpOutData;
+    inpOutData.inp.data.nfcServicePid = getpid();
+    setPidStatus = nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_SET_NFC_SERVICE_PID,
+                                       (void*)&inpOutData);
+    if (setPidStatus == NFC_STATUS_OK) {
+      NFC_TRACE_API0("nfc service set pid done");
+    } else {
+      NFC_TRACE_API0("nfc service set pid failed");
+    }
+  return setPidStatus;
+}
+/*******************************************************************************
+**
+** Function         NFC_ResetNfcServicePid
+**
+** Description      This function request to pn54x driver to
+**                  update NFC service process ID for signalling.
+**
+** Returns          0 if api call success, else -1
+**
+*******************************************************************************/
+int32_t NFC_ResetNfcServicePid()
+{
+    tNFC_STATUS setPidStatus = NFC_STATUS_OK;
+    nfc_nci_IoctlInOutData_t inpOutData;
+    inpOutData.inp.data.nfcServicePid = 0;
+    setPidStatus = nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_SET_NFC_SERVICE_PID,
+                                       (void*)&inpOutData);
+    if (setPidStatus == NFC_STATUS_OK) {
+      NFC_TRACE_API0("nfc service set pid done");
+    } else {
+      NFC_TRACE_API0("nfc service set pid failed");
+    }
+    return setPidStatus;
+}
+#endif
+/*******************************************************************************
+**
+** Function         NFC_ISODEPNakPresCheck
+**
+** Description      This function is called to send the ISO DEP nak presenc check cmd
+**                  to check that the remote end point in RF field.
+**
+**                  The response from NFCC is reported by call back.The ntf indicates
+**                  success if card is present in field or failed if card is lost.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_ISODEPNakPresCheck () {
+  return nci_snd_iso_dep_nak_presence_check_cmd();
+}
+/*******************************************************************************
+**
+** Function         NFC_SetStaticHciCback
+**
+** Description      This function is called to update the data callback function
+**                  to receive the data for the static Hci connection id.
+**
+** Parameters       p_cback - the connection callback function
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void NFC_SetStaticHciCback (tNFC_CONN_CBACK    *p_cback)
+{
+    NFC_TRACE_API1("NFC_SetStaticHciCback () evt_data.conn_create.dest_type  = %d", NCI_DEST_TYPE_NFCEE);
+    tNFC_CONN_CB * p_cb = &nfc_cb.conn_cb[NFC_HCI_CONN_ID];
+    tNFC_CONN   evt_data;
+
+    p_cb->p_cback = p_cback;
+    if (p_cback && p_cb->buff_size && p_cb->num_buff)
+    {
+        NFC_TRACE_API1("NFC_SetStaticHciCback 2 () evt_data.conn_create.dest_type  = %d", NCI_DEST_TYPE_NFCEE);
+        evt_data.conn_create.status         = NFC_STATUS_OK;
+        evt_data.conn_create.dest_type      = NCI_DEST_TYPE_NFCEE;
+        evt_data.conn_create.id             = p_cb->id;
+        evt_data.conn_create.buff_size      = p_cb->buff_size;
+        evt_data.conn_create.num_buffs      = p_cb->num_buff;
+        (*p_cback) (NFC_HCI_CONN_ID, NFC_CONN_CREATE_CEVT, &evt_data);
+    }
+}
+
+/*******************************************************************************
+ **
+ ** Function         NFC_GetFeatureList
+ **
+ ** Description      Gets the chipType from hal which is already configured
+ **                  during init time.
+ **                  Initializes featureList based onChipType
+ **
+ ** Returns          Nothing
+ *******************************************************************************/
+void NFC_GetFeatureList() {
+    NFC_TRACE_API0("NFC_GetFeatureList() Enter");
+    tNFC_STATUS status = NFC_STATUS_FAILED;
+    nfc_nci_IoctlInOutData_t inpOutData;
+    status = nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_GET_FEATURE_LIST,
+            (void*)&inpOutData);
+    if(status == NFC_STATUS_OK) {
+        chipType = (tNFC_chipType)inpOutData.out.data.chipType;
+        NFC_TRACE_API1("NFC_GetFeatureList ()chipType = %d", chipType);
+
+    }else{
+        chipType = pn553;
+    }
+    CONFIGURE_FEATURELIST(chipType);
+    NFC_TRACE_API1("NFC_GetFeatureList ()chipType = %d", chipType);
+
+}
+
+/*******************************************************************************
+ **
+ ** Function         NFC_GetChipType
+ **
+ ** Description      Gets the chipType initialized during bootup
+ **
+ *******************************************************************************/
+tNFC_chipType NFC_GetChipType() {
+    return chipType;
+}
+
+#if (BT_TRACE_VERBOSE == true)
+/*******************************************************************************
+**
+** Function         NFC_GetStatusName
+**
+** Description      This function returns the status name.
+**
+** NOTE             conditionally compiled to save memory.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+char* NFC_GetStatusName(tNFC_STATUS status) {
+  switch (status) {
+    case NFC_STATUS_OK:
+      return "OK";
+    case NFC_STATUS_REJECTED:
+      return "REJECTED";
+    case NFC_STATUS_MSG_CORRUPTED:
+      return "CORRUPTED";
+    case NFC_STATUS_BUFFER_FULL:
+      return "BUFFER_FULL";
+    case NFC_STATUS_FAILED:
+      return "FAILED";
+    case NFC_STATUS_NOT_INITIALIZED:
+      return "NOT_INITIALIZED";
+    case NFC_STATUS_SYNTAX_ERROR:
+      return "SYNTAX_ERROR";
+    case NFC_STATUS_SEMANTIC_ERROR:
+      return "SEMANTIC_ERROR";
+    case NFC_STATUS_UNKNOWN_GID:
+      return "UNKNOWN_GID";
+    case NFC_STATUS_UNKNOWN_OID:
+      return "UNKNOWN_OID";
+    case NFC_STATUS_INVALID_PARAM:
+      return "INVALID_PARAM";
+    case NFC_STATUS_MSG_SIZE_TOO_BIG:
+      return "MSG_SIZE_TOO_BIG";
+    case NFC_STATUS_ALREADY_STARTED:
+      return "ALREADY_STARTED";
+    case NFC_STATUS_ACTIVATION_FAILED:
+      return "ACTIVATION_FAILED";
+    case NFC_STATUS_TEAR_DOWN:
+      return "TEAR_DOWN";
+    case NFC_STATUS_RF_TRANSMISSION_ERR:
+      return "RF_TRANSMISSION_ERR";
+    case NFC_STATUS_RF_PROTOCOL_ERR:
+      return "RF_PROTOCOL_ERR";
+    case NFC_STATUS_TIMEOUT:
+      return "TIMEOUT";
+    case NFC_STATUS_EE_INTF_ACTIVE_FAIL:
+      return "EE_INTF_ACTIVE_FAIL";
+    case NFC_STATUS_EE_TRANSMISSION_ERR:
+      return "EE_TRANSMISSION_ERR";
+    case NFC_STATUS_EE_PROTOCOL_ERR:
+      return "EE_PROTOCOL_ERR";
+    case NFC_STATUS_EE_TIMEOUT:
+      return "EE_TIMEOUT";
+    case NFC_STATUS_CMD_STARTED:
+      return "CMD_STARTED";
+    case NFC_STATUS_HW_TIMEOUT:
+      return "HW_TIMEOUT";
+    case NFC_STATUS_CONTINUE:
+      return "CONTINUE";
+    case NFC_STATUS_REFUSED:
+      return "REFUSED";
+    case NFC_STATUS_BAD_RESP:
+      return "BAD_RESP";
+    case NFC_STATUS_CMD_NOT_CMPLTD:
+      return "CMD_NOT_CMPLTD";
+    case NFC_STATUS_NO_BUFFERS:
+      return "NO_BUFFERS";
+    case NFC_STATUS_WRONG_PROTOCOL:
+      return "WRONG_PROTOCOL";
+    case NFC_STATUS_BUSY:
+      return "BUSY";
+    case NFC_STATUS_LINK_LOSS:
+      return "LINK_LOSS";
+    case NFC_STATUS_BAD_LENGTH:
+      return "BAD_LENGTH";
+    case NFC_STATUS_BAD_HANDLE:
+      return "BAD_HANDLE";
+    case NFC_STATUS_CONGESTED:
+      return "CONGESTED";
+    default:
+      return "UNKNOWN";
+  }
+}
+#endif
diff --git a/src/nfc/nfc/nfc_ncif.c b/src/nfc/nfc/nfc_ncif.c
new file mode 100644
index 0000000..0ef276b
--- /dev/null
+++ b/src/nfc/nfc/nfc_ncif.c
@@ -0,0 +1,3196 @@
+/******************************************************************************
+ *
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 1999-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains functions that interface with the NFC NCI transport.
+ *  On the receive side, it routes events to the appropriate handler
+ *  (callback). On the transmit side, it manages the command transmission.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include <stdlib.h>
+#include "nfc_target.h"
+
+#include "nfc_hal_api.h"
+#include "nfc_api.h"
+#include "nci_defs.h"
+#include "nci_hmsgs.h"
+#include "nfc_int.h"
+#include "rw_api.h"
+#include "rw_int.h"
+#include "nfc_hal_api.h"
+
+#if (NXP_EXTNS == TRUE)
+#include "nfa_ce_int.h"
+#include "nfa_sys.h"
+#include "nfa_dm_int.h"
+#include "nfa_hci_int.h"
+#include <config.h>
+#endif
+tNFC_CONN_CB* p_cb_stored = NULL;
+#if (NFC_RW_ONLY == FALSE)
+static const uint8_t nfc_mpl_code_to_size[] = {64, 128, 192, 254};
+
+#endif /* NFC_RW_ONLY */
+
+#if (NXP_EXTNS == TRUE)
+#define NFC_NCI_WAIT_DATA_NTF_TOUT 2
+#define NFC_NCI_RFFIELD_EVT_TIMEOUT 2
+uint8_t temp_buff[660];
+#endif
+
+#define NFC_PB_ATTRIB_REQ_FIXED_BYTES 1
+#define NFC_LB_ATTRIB_REQ_FIXED_BYTES 8
+
+#if (NXP_EXTNS == TRUE)
+// Global Structure varibale for FW Version
+static tNFC_FW_VERSION nfc_fw_version;
+static uint8_t gScreenState = 0x0;  // SCREEN ON UNLOCKED
+static uint16_t maxRoutingTableSize;
+uint8_t sListenActivated;
+extern tNFA_CE_CB nfa_ce_cb;
+bool core_reset_init_num_buff = false;
+uint8_t nfcc_dh_conn_id = 0xFF;
+extern void nfa_hci_rsp_timeout(tNFA_HCI_EVENT_DATA* p_evt_data);
+void disc_deact_ntf_timeout_handler(tNFC_RESPONSE_EVT event);
+extern bool etsi_reader_in_progress;
+void uicc_eeprom_get_config(uint8_t* config_resp);
+void uicc_eeprom_set_config(uint8_t* config_resp);
+#endif
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_update_window
+**
+** Description      Update tx cmd window to indicate that NFCC can received
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_update_window(void) {
+  /* Sanity check - see if we were expecting a update_window */
+  if (nfc_cb.nci_cmd_window == NCI_MAX_CMD_WINDOW) {
+    if (nfc_cb.nfc_state != NFC_STATE_W4_HAL_CLOSE) {
+      NFC_TRACE_ERROR0("nfc_ncif_update_window: Unexpected call");
+    }
+    return;
+  }
+
+  /* Stop command-pending timer */
+  nfc_stop_timer(&nfc_cb.nci_wait_rsp_timer);
+
+  nfc_cb.p_vsc_cback = NULL;
+  nfc_cb.nci_cmd_window++;
+
+  /* Check if there were any commands waiting to be sent */
+  nfc_ncif_check_cmd_queue(NULL);
+}
+/*******************************************************************************
+**
+** Function         nfc_ncif_update_data_queue
+**
+** Description      Update tx cmd window  to indicate that NFCC can received and
+*core credit ntf received
+**
+** Returns          void
+**
+*********************************************************************************/
+void nfc_ncif_update_data_queue(void) {
+  nfc_cb.nci_cmd_window++;
+  NFC_TRACE_ERROR0("nfc_ncif_update_data_queue- incrementing window");
+  /* Check if there were any commands waiting to be sent */
+  nfc_ncif_check_cmd_queue(NULL);
+}
+/*******************************************************************************
+**
+** Function         nfc_ncif_cmd_timeout
+**
+** Description      Handle a command timeout
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_cmd_timeout(void) {
+  NFC_TRACE_DEBUG0("nfc_ncif_cmd_timeout(): enter");
+
+#if (NXP_EXTNS == TRUE)
+  NFC_TRACE_DEBUG0("Start Middleware Recovery Procedure");
+  {
+    // TO DO:
+    // Sending command which are core_reset,init,discovery as raw packet (Hard
+    // coding)
+    // and we have to match the RF state between before entering recovery and
+    // after recovery.
+    // finally, executing the last command which is before entering recovery,
+    // and invoking the callback.
+
+    // step 1. Sending core reset/init command
+    // step 2. deciding to send command whether discovery or not.
+    // step 3. invoking the callback function which is registered at last time
+    // before entering recovery.
+
+    /*
+    consist of buffer(p_core_init_rsp_params)
+    buffer[0] = Indicators 0:Normal mode 1:Recovery mode 2:core reset was last
+    command 3:core init was last command
+    buffer[1] = Last NFCC NCI RF State, 0:IDLE 1:DISCOVERY
+    buffer[2] = Length of discovery command to be sent as a part of recovery.
+    buffer[3~34] = Last Discovery command(including phase data).(32 byte)
+    buffer[35] = Indicator 0: No command to be sent after Recovery 1: Command available to be sent after recovery
+    buffer[36~294] = Last Command /or Last Command including Data.
+    buffer[295] = Last screen state
+    */
+    uint8_t* buffer = NULL;
+    tNFC_CONN_CB* p_cb = NULL;
+    uint16_t bufflen = 36 + 258 + 2; //Initial data + max command size + 1 extra buffer + 1 screenState
+    uint16_t fw_dwnld_status = NFC_STATUS_FAILED;
+    tNFC_STATUS status = NFC_STATUS_FAILED;
+    tNFC_FWUpdate_Info_t fw_update_inf;
+    nfc_nci_IoctlInOutData_t inpOutData;
+
+    /*Stop the command timeout timer*/
+    nfc_stop_timer(&nfc_cb.nci_wait_rsp_timer);
+
+    buffer = (uint8_t*)malloc(bufflen * sizeof(uint8_t));
+
+    if (NULL == buffer) {
+      NFC_TRACE_ERROR0("Recovery MEM Allocation is failed!!");
+      return;
+    }
+    memset(buffer, 0x00, (bufflen * sizeof(uint8_t)));
+
+    /*We need to send Core Reset and Core Init as a part of recovery*/
+    buffer[0] = 0x01;
+
+    /*Set the last screen state*/
+    buffer[295] = gScreenState;
+
+    NFC_TRACE_DEBUG1("MW last RF discovery flags 0x%x",
+                     nfa_dm_cb.disc_cb.disc_flags);
+    NFC_TRACE_DEBUG1("MW last RF discovery state 0x%x",
+                     nfa_dm_cb.disc_cb.disc_state);
+
+    if (nfc_cb.nfc_state == NFC_STATE_CORE_INIT) {
+#if (NXP_EXTNS == TRUE)
+        if(nfcFL.nfccFL._NFCC_MW_RCVRY_BLK_FW_DNLD) {
+            NFC_TRACE_DEBUG0(
+                    "MW recovery should abort FW download checking at time of "
+                    "cmd_timeout");
+        }
+        else {
+            NFC_TRACE_DEBUG0("Force FW Download !");
+            nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_CHECK_FLASH_REQ, &inpOutData);
+            fw_update_inf = *(tNFC_FWUpdate_Info_t*)&inpOutData.out.data.fwUpdateInf;
+            nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_FW_DWNLD, &inpOutData);
+            fw_dwnld_status = inpOutData.out.data.fwDwnldStatus;
+            NFC_TRACE_DEBUG1("FW Download 0x%x", fw_dwnld_status);
+            if (fw_dwnld_status != NFC_STATUS_OK)
+                nfc_enabled(NFC_STATUS_FAILED, NULL);
+        }
+#else
+        NFC_TRACE_DEBUG0("Force FW Download !");
+        nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_CHECK_FLASH_REQ, &fw_update_inf);
+        nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_FW_DWNLD, &fw_dwnld_status);
+        NFC_TRACE_DEBUG1("FW Download 0x%x", fw_dwnld_status);
+        if (fw_dwnld_status != NFC_STATUS_OK)
+            nfc_enabled(NFC_STATUS_FAILED, NULL);
+#endif
+    }
+    /*Prepare the DISCOVERY command*/
+    if (!(nfa_dm_cb.disc_cb.disc_state > NFA_DM_RFST_IDLE)) {
+      NFC_TRACE_DEBUG0("NFCC last NCI RF state is IDLE");
+      /*NCI stack RF state set to IDLE*/
+      buffer[1] = 0x00;
+    } else {
+      uint8_t* ps = (uint8_t*)nfc_cb.p_last_disc;
+      NFC_TRACE_DEBUG0("NFCC last NCI RF state is DISCOVERY");
+      /*Last NFCC state set to DISCOVERY*/
+      buffer[1] = 0x01;
+      /*NCI stack RF state set to DISCOVERY*/
+      nfa_dm_cb.disc_cb.disc_state = 0x01;
+      /*Listen Mode flags initialized to 0x00*/
+      nfa_ce_cb.flags = 0x00;
+
+      if (ps[0]) {
+        /*Set the length of last DISCOVERY packet including header*/
+        buffer[2] =
+            2 + 1 + 1 +
+            (ps[0] *
+             2); /*HDR(2) + Length(1) + Configs(1) + Data(TechnMode(2) * 2)*/
+        /*Copy the DISCOVERY command header*/
+        memcpy((uint8_t*)&buffer[3], "\x21\x03", 2);
+        /*Set the length of content of the last DISCOVERY command*/
+        buffer[5] = 1 + (ps[0] * 2); /*Configs(1) + Data(TechnMode(2) * 2)*/
+        /*Copy the content of DISCOVERY command*/
+        memcpy((uint8_t*)&buffer[6], ps, buffer[5]);
+      } else {
+        buffer[2] = 0x1A; /*Length of hard coded recovery discovery command*/
+        memcpy((uint8_t*)&buffer[3],
+               "\x21\x03\x17\x0B\x00\x01\x01\x01\x02\x01\x03\x01\x80\x01\x81"
+               "\x01\x82\x01\x83\x01\x85\x01\x06\x01\x77\x01",
+               24);
+      }
+    }
+    /*Prepare the last command sent just before CORE_RESET_NTF*/
+    if (((nfc_cb.last_hdr[0] == 0x21 && nfc_cb.last_hdr[1] == 0x06) &&
+         (nfc_cb.last_cmd_buf[0] == 0x01 &&
+          nfc_cb.last_cmd_buf[1] == 0x01)) || /*DEACTIVATE TO SLEEP*/
+        (nfc_cb.last_hdr[0] == 0x21 && nfc_cb.last_hdr[1] == 0x04) || /**/
+        (nfc_cb.last_hdr[0] == 0x21 && nfc_cb.last_hdr[1] == 0x08) || /**/
+        ((nfc_cb.last_hdr[0] == 0x21 &&
+          nfc_cb.last_hdr[1] == 0x06) && /*DEACTIVATE TO DISCOVERY*/
+         (nfc_cb.last_cmd_buf[0] == 0x01 && nfc_cb.last_cmd_buf[1] == 0x03))) {
+      buffer[35] = 0x00; /*No need to send last command*/
+    } else if ((nfc_cb.last_hdr[0] == 0x20 &&
+                (nfc_cb.last_hdr[1] == 0x02 ||
+                 nfc_cb.last_hdr[1] == 0x03)) || /*SET CONFIG COMMAND*/
+               (nfc_cb.last_hdr[0] == 0x2F &&
+                nfc_cb.last_hdr[1] == 0x15) || /*PROPRIETARY COMMAND*/
+               (nfc_cb.last_hdr[0] == 0x21 &&
+                nfc_cb.last_hdr[1] == 0x01) || /*LISTEN ROUTING COMMAND*/
+               ((nfc_cb.last_hdr[0] == 0x21 && nfc_cb.last_hdr[1] == 0x06) &&
+                (nfc_cb.last_cmd_buf[0] == 0x01 &&
+                 nfc_cb.last_cmd_buf[1] == 0x00)) /*DEACTIVATE TO IDLE*/
+               ) {
+        /*Set indicating last command is available to be sent after recovery*/
+        buffer[35] = 0x01;
+
+      /*Copy the last HEADER*/
+      memcpy(&buffer[36], nfc_cb.last_hdr, NFC_SAVED_HDR_SIZE);
+      /*Copy the last command*/
+      memcpy(&buffer[38], nfc_cb.last_cmd_buf, nfc_cb.cmd_size + 1);
+    } else /*either CORE_RESET or CORE_INIT was the last command*/
+    {
+        /*Set indicating last command is available to be sent after recovery*/
+      buffer[35] = 0x01;
+      memcpy(&buffer[36], nfc_cb.last_hdr, NFC_SAVED_HDR_SIZE);
+
+      buffer[38] = nfc_cb.cmd_size; /*Length of last command*/
+
+      if (nfc_cb.cmd_size > 0) /*last command was CORE_RESET*/
+        memcpy(&buffer[39], nfc_cb.last_cmd, NFC_SAVED_CMD_SIZE);
+      else
+        buffer[35] = 0x00; /*last command was CORE_INIT*/
+      if (nfc_cb.last_hdr[0] == 0x20 && nfc_cb.last_hdr[1] == 0x00)
+        buffer[0] = 2; /*indicate last command was CORE_RESET*/
+      else if (nfc_cb.last_hdr[0] == 0x20 && nfc_cb.last_hdr[1] == 0x01)
+        buffer[0] = 3; /*indicate last command was CORE_INIT*/
+    }
+    /* if HCI state is in wait for response then stop the timer and send the
+     * response timeout event to the upper layer*/
+    if (nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_RSP) {
+      NFC_HDR* p_msg;
+      nfa_sys_stop_timer(&nfa_hci_cb.timer);
+      if ((p_msg = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR))) != NULL) {
+        NFC_TRACE_DEBUG0(
+            "nfc_ncif_cmd_timeout(): Sending HCI response timeout to upper "
+            "layer");
+        p_msg->event = NFA_HCI_RSP_TIMEOUT_EVT;
+        p_msg->layer_specific = 0;
+        nfa_sys_sendmsg(p_msg);
+      }
+    }
+    if (0xFF != nfcc_dh_conn_id) {
+      /* Flush the data if any before proceeding further with the recovery */
+      p_cb = nfc_find_conn_cb_by_conn_id(nfcc_dh_conn_id);
+      if (NULL != p_cb) {
+        NFC_TRACE_DEBUG1("nfc_ncif_cmd_timeout(): connection id %d",
+                         nfcc_dh_conn_id);
+        status = NFC_FlushData(p_cb->conn_id);
+        if (status != NFC_STATUS_OK) {
+          NFC_TRACE_ERROR0("nfc_ncif_cmd_timeout(): NFC data flush failed");
+        }
+      }
+    }
+    NFC_TRACE_DEBUG3(
+        "nfc_ncif_cmd_timeout(): Indicator:0x%02X disc cmd len:0x%02X last cmd "
+        "len:0x%02X",
+        buffer[0], buffer[2], buffer[38]);
+
+    nfc_cb.p_hal->core_initialized(bufflen, buffer);
+    if (buffer != NULL) free(buffer);
+    NFC_TRACE_DEBUG0("nfc_ncif_cmd_timeout(): exit");
+  }
+#else
+  /* report an error */
+  nfc_ncif_event_status(NFC_GEN_ERROR_REVT, NFC_STATUS_HW_TIMEOUT);
+  nfc_ncif_event_status(NFC_NFCC_TIMEOUT_REVT, NFC_STATUS_HW_TIMEOUT);
+
+  /* if enabling NFC, notify upper layer of failure */
+  if (nfc_cb.nfc_state == NFC_STATE_CORE_INIT) {
+    nfc_enabled(NFC_STATUS_FAILED, NULL);
+  }
+  /* XXX maco since this failure is unrecoverable, abort the process */
+  abort();
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         nfc_wait_2_deactivate_timeout
+**
+** Description      Handle a command timeout
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_wait_2_deactivate_timeout(void) {
+  NFC_TRACE_ERROR0("nfc_wait_2_deactivate_timeout");
+  nfc_cb.flags &= ~NFC_FL_DEACTIVATING;
+  nci_snd_deactivate_cmd((uint8_t)nfc_cb.deactivate_timer.param);
+}
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         nfc_ncif_retransmit_data
+**
+** Description      Retransmission of lost packet
+**
+** Returns          void
+**
+*******************************************************************************/
+uint8_t nfc_ncif_retransmit_data(tNFC_CONN_CB* p_cb, NFC_HDR* p_data) {
+  NFC_TRACE_ERROR0("nfc_ncif_retransmit_data");
+  if (p_data == NULL) {
+    NFC_TRACE_ERROR0("nfc_ncif_retransmit_data: p_data is NULL");
+    return NCI_STATUS_FAILED;
+  }
+  if (p_cb->num_buff != NFC_CONN_NO_FC) p_cb->num_buff--;
+
+  HAL_RE_WRITE(p_data);
+  if (p_cb->conn_id == NFC_NFCEE_CONN_ID) {
+    // Start waiting for credit ntf
+    nfc_cb.bIsCreditNtfRcvd = false;
+    nfc_start_timer(&nfc_cb.nci_wait_data_ntf_timer,
+                    (uint16_t)(NFC_TTYPE_NCI_WAIT_DATA_NTF),
+                    NFC_NCI_WAIT_DATA_NTF_TOUT);
+  }
+  return NCI_STATUS_OK;
+}
+#endif
+/*******************************************************************************
+**
+** Function         nfc_ncif_send_data
+**
+** Description      This function is called to add the NCI data header
+**                  and send it to NCIT task for sending it to transport
+**                  as credits are available.
+**
+** Returns          void
+**
+*******************************************************************************/
+uint8_t nfc_ncif_send_data(tNFC_CONN_CB* p_cb, NFC_HDR* p_data) {
+  uint8_t* pp;
+  uint8_t* ps;
+  uint8_t ulen = NCI_MAX_PAYLOAD_SIZE;
+  NFC_HDR* p;
+  uint8_t pbf = 1;
+  uint8_t buffer_size = p_cb->buff_size;
+  uint8_t hdr0 = p_cb->conn_id;
+  bool fragmented = false;
+#if (NXP_EXTNS == TRUE)
+  uint8_t* pTemp;
+  if (core_reset_init_num_buff == true) {
+    NFC_TRACE_ERROR0("Reinitializing the num_buff");
+
+    if (!p_cb->num_buff) p_cb->num_buff++;
+    core_reset_init_num_buff = false;
+  }
+#endif
+  if (get_i2c_fragmentation_enabled() == I2C_FRAGMENATATION_ENABLED) {
+    if (nfc_cb.i2c_data_t.nci_cmd_channel_busy == 1 && p_data) {
+      NFC_TRACE_DEBUG0("NxpNci : avoiding data packet sending data packet");
+      nfc_cb.i2c_data_t.conn_id = p_cb->conn_id;
+      GKI_enqueue(&p_cb->tx_q, p_data);
+      nfc_cb.i2c_data_t.data_stored = 1;
+      return NCI_STATUS_OK;
+    }
+  }
+  NFC_TRACE_DEBUG3("nfc_ncif_send_data :%d, num_buff:%d qc:%d", p_cb->conn_id,
+                   p_cb->num_buff, p_cb->tx_q.count);
+  if (p_cb->id == NFC_RF_CONN_ID) {
+    if (nfc_cb.nfc_state != NFC_STATE_OPEN) {
+      if (nfc_cb.nfc_state == NFC_STATE_CLOSING) {
+        if ((p_data == NULL) && /* called because credit from NFCC */
+            (nfc_cb.flags & NFC_FL_DEACTIVATING)) {
+          if (p_cb->init_credits == p_cb->num_buff) {
+            /* all the credits are back */
+            nfc_cb.flags &= ~NFC_FL_DEACTIVATING;
+            NFC_TRACE_DEBUG2(
+                "deactivating NFC-DEP init_credits:%d, num_buff:%d",
+                p_cb->init_credits, p_cb->num_buff);
+            nfc_stop_timer(&nfc_cb.deactivate_timer);
+            nci_snd_deactivate_cmd((uint8_t)nfc_cb.deactivate_timer.param);
+          }
+        }
+      }
+      return NCI_STATUS_FAILED;
+    }
+  }
+
+  if (p_data) {
+    /* always enqueue the data to the tx queue */
+    GKI_enqueue(&p_cb->tx_q, p_data);
+  }
+
+#if (NXP_EXTNS == TRUE)
+  if ((nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME ==
+          nfcFL.eseFL._ESE_WIRED_MODE_RESUME) &&
+          ((nfc_cb.bBlockWiredMode) && (p_cb->conn_id == NFC_NFCEE_CONN_ID))) {
+      /* CE is activated on UICC hence return simply without sedning data */
+      return (NCI_STATUS_OK);
+  }
+#endif
+
+  /* try to send the first data packet in the tx queue  */
+  p_data = (NFC_HDR*)GKI_getfirst(&p_cb->tx_q);
+
+  /* post data fragment to NCIT task as credits are available */
+  while (p_data && (p_data->len >= 0) && (p_cb->num_buff > 0)) {
+    if (p_data->len <= buffer_size) {
+      pbf = 0; /* last fragment */
+      ulen = (uint8_t)(p_data->len);
+      fragmented = false;
+    } else {
+      fragmented = true;
+      ulen = buffer_size;
+    }
+
+    if (!fragmented) {
+      /* if data packet is not fragmented, use the original buffer */
+      p = p_data;
+      p_data = (NFC_HDR*)GKI_dequeue(&p_cb->tx_q);
+    } else {
+      /* the data packet is too big and need to be fragmented
+       * prepare a new GKI buffer
+       * (even the last fragment to avoid issues) */
+      p = NCI_GET_CMD_BUF(ulen);
+      if (p == NULL) return (NCI_STATUS_BUFFER_FULL);
+      p->len = ulen;
+      p->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + 1;
+      if (p->len) {
+        pp = (uint8_t*)(p + 1) + p->offset;
+        ps = (uint8_t*)(p_data + 1) + p_data->offset;
+        memcpy(pp, ps, ulen);
+      }
+      /* adjust the NFC_HDR on the old fragment */
+      p_data->len -= ulen;
+      p_data->offset += ulen;
+    }
+
+    p->event = BT_EVT_TO_NFC_NCI;
+    p->layer_specific = pbf;
+    p->len += NCI_DATA_HDR_SIZE;
+    p->offset -= NCI_DATA_HDR_SIZE;
+    pp = (uint8_t*)(p + 1) + p->offset;
+    /* build NCI Data packet header */
+    NCI_DATA_PBLD_HDR(pp, pbf, hdr0, ulen);
+    if (p_cb->num_buff != NFC_CONN_NO_FC) p_cb->num_buff--;
+
+#if (NXP_EXTNS == TRUE)
+    if ((nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME ==
+            nfcFL.eseFL._ESE_WIRED_MODE_RESUME) &&
+            (p_cb->conn_id == NFC_NFCEE_CONN_ID)) {
+        nfc_cb.temp_data = (NFC_HDR*)temp_buff;
+        nfc_cb.temp_data->offset = p->offset;
+        pTemp = (uint8_t*)(nfc_cb.temp_data + 1) + nfc_cb.temp_data->offset;
+        nfc_cb.temp_data->len = p->len;
+        memcpy(pTemp, (uint8_t*)(p + 1) + (p->offset), p->len);
+    }
+#endif
+
+    /* send to HAL */
+    HAL_WRITE(p);
+#if (NXP_EXTNS == TRUE)
+    /* start NFC data ntf timeout timer */
+    if (get_i2c_fragmentation_enabled() == I2C_FRAGMENATATION_ENABLED) {
+      nfc_cb.nci_cmd_window--;
+    }
+    if (p_cb->conn_id != NFC_RF_CONN_ID) {
+      // Start waiting for credit ntf
+      if (p_cb->conn_id == NFC_NFCEE_CONN_ID) {
+        nfc_cb.bIsCreditNtfRcvd = false;
+      }
+      nfc_start_timer(&nfc_cb.nci_wait_data_ntf_timer,
+                      (uint16_t)(NFC_TTYPE_NCI_WAIT_DATA_NTF),
+                      NFC_NCI_WAIT_DATA_NTF_TOUT);
+    }
+    if (!fragmented) {
+      /* check if there are more data to send */
+      p_data = (NFC_HDR*)GKI_getfirst(&p_cb->tx_q);
+    }
+#endif
+  }
+
+  return (NCI_STATUS_OK);
+}
+
+#if (NXP_EXTNS == TRUE)
+/*Function to empty cmd queue.*/
+void nfc_ncif_empty_cmd_queue() {
+  NFC_HDR* p_buf = (NFC_HDR*)GKI_dequeue(&nfc_cb.nci_cmd_xmit_q);
+
+  while (p_buf) {
+    GKI_freebuf(p_buf);
+    p_buf = (NFC_HDR*)GKI_dequeue(&nfc_cb.nci_cmd_xmit_q);
+  }
+}
+
+/*Function to empty data queue.*/
+void nfc_ncif_empty_data_queue() {
+  NFC_HDR* p_data = (NFC_HDR*)GKI_dequeue(&p_cb_stored->tx_q);
+
+  while (p_data) {
+    GKI_freebuf(p_data);
+    p_data = (NFC_HDR*)GKI_dequeue(&p_cb_stored->tx_q);
+  }
+}
+#endif
+/*******************************************************************************
+**
+** Function         nfc_ncif_check_cmd_queue
+**
+** Description      Send NCI command to the transport
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_check_cmd_queue(NFC_HDR* p_buf) {
+  uint8_t* ps;
+  /* If there are commands waiting in the xmit queue, or if the controller
+   * cannot accept any more commands, */
+  /* then enqueue this command */
+  if (p_buf) {
+    if ((nfc_cb.nci_cmd_xmit_q.count) || (nfc_cb.nci_cmd_window == 0)) {
+      GKI_enqueue(&nfc_cb.nci_cmd_xmit_q, p_buf);
+#if (NXP_EXTNS == TRUE)
+      if (p_buf != NULL) {
+        NFC_TRACE_DEBUG0("nfc_ncif_check_cmd_queue : making p_buf NULL.");
+        p_buf = NULL;
+      }
+#else
+      p_buf = NULL;
+#endif
+    }
+  }
+  /* If controller can accept another command, then send the next command */
+  if (nfc_cb.nci_cmd_window > 0) {
+    /* If no command was provided, or if older commands were in the queue, then
+     * get cmd from the queue */
+    if (!p_buf) p_buf = (NFC_HDR*)GKI_dequeue(&nfc_cb.nci_cmd_xmit_q);
+
+    if (p_buf) {
+#if (NXP_EXTNS == TRUE)
+      NFC_TRACE_DEBUG0("nfc_ncif_check_cmd_queue : Writing to HAL...");
+      /*save the message header to double check the response */
+      ps = (uint8_t*)(p_buf + 1) + p_buf->offset;
+      /*save command HEADER(GID+OID) only*/
+      memcpy(nfc_cb.last_hdr, ps, NFC_SAVED_HDR_SIZE);
+      /*save command length only*/
+      nfc_cb.cmd_size = *(ps + NFC_SAVED_HDR_SIZE);
+      NFC_TRACE_DEBUG2("%s : cmd_size:%d", __func__, nfc_cb.cmd_size);
+      if ((nfc_cb.last_hdr[0] == 0x20 &&
+           (nfc_cb.last_hdr[1] == 0x02 || nfc_cb.last_hdr[1] == 0x03)) ||
+          (nfc_cb.last_hdr[0] == 0x2F && nfc_cb.last_hdr[1] == 0x15) ||
+          (nfc_cb.last_hdr[0] == 0x21 && nfc_cb.last_hdr[1] == 0x01) ||
+          (nfc_cb.last_hdr[0] == 0x21 && nfc_cb.last_hdr[1] == 0x06)) {
+        if (nfc_cb.last_cmd_buf != NULL) {
+          GKI_freebuf(nfc_cb.last_cmd_buf);  // ======> Free before allocation
+        }
+        nfc_cb.last_cmd_buf = (uint8_t*)GKI_getbuf(nfc_cb.cmd_size + 1);
+        if (nfc_cb.last_cmd_buf != NULL) {
+          /*save command data including length and excluding header*/
+          memcpy(nfc_cb.last_cmd_buf, ps + NFC_SAVED_HDR_SIZE,
+                 (nfc_cb.cmd_size + 1));
+          memcpy(nfc_cb.last_cmd, ps + NCI_MSG_HDR_SIZE, NFC_SAVED_CMD_SIZE);
+        } else {
+          NFC_TRACE_DEBUG0("NULL buffer nfc_cb.last_cmd_buf");
+        }
+      } else {
+        memcpy(nfc_cb.last_cmd, ps + NCI_MSG_HDR_SIZE, NFC_SAVED_CMD_SIZE);
+      }
+#else
+      /* save the message header to double check the response */
+      ps = (uint8_t*)(p_buf + 1) + p_buf->offset;
+      memcpy(nfc_cb.last_hdr, ps, NFC_SAVED_HDR_SIZE);
+      memcpy(nfc_cb.last_cmd, ps + NCI_MSG_HDR_SIZE, NFC_SAVED_CMD_SIZE);
+#endif
+      if (p_buf->layer_specific == NFC_WAIT_RSP_VSC) {
+        /* save the callback for NCI VSCs)  */
+        nfc_cb.p_vsc_cback = (void*)((tNFC_NCI_VS_MSG*)p_buf)->p_cback;
+      }
+#if (NXP_EXTNS == TRUE)
+      else if (p_buf->layer_specific == NFC_WAIT_RSP_NXP) {
+        /* save the callback for NCI NXPs)  */
+        nfc_cb.p_vsc_cback = (void*)((tNFC_NCI_VS_MSG*)p_buf)->p_cback;
+        nfc_cb.nxpCbflag = true;
+      }
+      /* Indicate command is pending */
+      nfc_cb.nci_cmd_window--;
+#endif
+      /* send to HAL */
+      HAL_WRITE(p_buf);
+#if (NXP_EXTNS != TRUE)
+      /* Indicate command is pending */
+      nfc_cb.nci_cmd_window--;
+#endif
+      if (get_i2c_fragmentation_enabled() == I2C_FRAGMENATATION_ENABLED) {
+        nfc_cb.i2c_data_t.nci_cmd_channel_busy = 1;
+        NFC_TRACE_DEBUG0("setting channel busy flag");
+      }
+
+      /* start NFC command-timeout timer */
+      nfc_start_timer(&nfc_cb.nci_wait_rsp_timer,
+                      (uint16_t)(NFC_TTYPE_NCI_WAIT_RSP),
+                      nfc_cb.nci_wait_rsp_tout);
+    }
+  }
+
+  if (nfc_cb.nci_cmd_window == NCI_MAX_CMD_WINDOW) {
+    /* the command queue must be empty now */
+    if (nfc_cb.flags & NFC_FL_CONTROL_REQUESTED) {
+      /* HAL requested control or stack needs to handle pre-discover */
+      nfc_cb.flags &= ~NFC_FL_CONTROL_REQUESTED;
+      if (nfc_cb.flags & NFC_FL_DISCOVER_PENDING) {
+        if (nfc_cb.p_hal->prediscover()) {
+          /* HAL has the command window now */
+          nfc_cb.flags |= NFC_FL_CONTROL_GRANTED;
+          nfc_cb.nci_cmd_window = 0;
+        } else {
+          /* HAL does not need to send command,
+           * - restore the command window and issue the discovery command now */
+          nfc_cb.flags &= ~NFC_FL_DISCOVER_PENDING;
+          ps = (uint8_t*)nfc_cb.p_disc_pending;
+          nci_snd_discover_cmd(*ps, (tNFC_DISCOVER_PARAMS*)(ps + 1));
+#if (NXP_EXTNS == TRUE)
+          if (nfc_cb.p_last_disc) {
+            GKI_freebuf(nfc_cb.p_last_disc);
+            nfc_cb.p_last_disc = NULL;
+          }
+          nfc_cb.p_last_disc = nfc_cb.p_disc_pending;
+#else
+          GKI_freebuf(nfc_cb.p_disc_pending);
+#endif
+          nfc_cb.p_disc_pending = NULL;
+        }
+      } else if (nfc_cb.flags & NFC_FL_HAL_REQUESTED) {
+        /* grant the control to HAL */
+        nfc_cb.flags &= ~NFC_FL_HAL_REQUESTED;
+        nfc_cb.flags |= NFC_FL_CONTROL_GRANTED;
+        nfc_cb.nci_cmd_window = 0;
+        nfc_cb.p_hal->control_granted();
+      }
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_send_cmd
+**
+** Description      Send NCI command to the NCIT task
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_send_cmd(NFC_HDR* p_buf) {
+#if (NXP_EXTNS == TRUE)
+  NFC_TRACE_DEBUG0("nfc_ncif_send_cmd()");
+  if (p_buf == NULL) {
+    NFC_TRACE_DEBUG0("p_buf is NULL.");
+    return;
+  }
+  uint8_t* cmd = NULL;
+  cmd = (uint8_t*)(p_buf + 1) + p_buf->offset;
+
+  if (sListenActivated == true) {
+    nfc_stop_timer(&nfc_cb.listen_activation_timer_list);
+    sListenActivated = false;
+  }
+#endif
+  /* post the p_buf to NCIT task */
+  p_buf->event = BT_EVT_TO_NFC_NCI;
+  p_buf->layer_specific = 0;
+  nfc_ncif_check_cmd_queue(p_buf);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_process_event
+**
+** Description      This function is called to process the
+**                  data/response/notification from NFCC
+**
+** Returns          true if need to free buffer
+**
+*******************************************************************************/
+bool nfc_ncif_process_event(NFC_HDR* p_msg) {
+  uint8_t mt, pbf, gid, *p, *pp;
+  bool free = true;
+  uint8_t oid;
+  uint8_t* p_old, old_gid, old_oid, old_mt;
+  p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+
+  pp = p;
+  NCI_MSG_PRS_HDR0(pp, mt, pbf, gid);
+#if (NXP_EXTNS == TRUE)
+  oid = ((*pp) & NCI_OID_MASK);
+
+  if (sListenActivated == true) {
+    nfc_stop_timer(&nfc_cb.listen_activation_timer_list);
+    sListenActivated = false;
+  }
+
+  if ((nfc_cb.nxpCbflag == true) &&
+      (nfc_ncif_proc_proprietary_rsp(mt, gid, oid) == true)) {
+    nci_proc_prop_nxp_rsp(p_msg);
+    nfc_cb.nxpCbflag = false;
+    return (free);
+  }
+#endif
+
+  switch (mt) {
+    case NCI_MT_DATA:
+      NFC_TRACE_DEBUG0("NFC received data");
+      nfc_ncif_proc_data(p_msg);
+      free = false;
+      break;
+
+    case NCI_MT_RSP:
+      NFC_TRACE_DEBUG1("NFC received rsp gid:%d", gid);
+      oid = ((*pp) & NCI_OID_MASK);
+      p_old = nfc_cb.last_hdr;
+      NCI_MSG_PRS_HDR0(p_old, old_mt, pbf, old_gid);
+      old_oid = ((*p_old) & NCI_OID_MASK);
+      /* make sure this is the RSP we are waiting for before updating the
+       * command window */
+      if ((old_gid != gid) || (old_oid != oid)) {
+          if ((nfcFL.nfcNxpEse && nfcFL.eseFL._ESE_ETSI_READER_ENABLE) &&
+                  ((gid == NCI_GID_RF_MANAGE) && (oid == NCI_MSG_RF_DISCOVER)) &&
+                  (etsi_reader_in_progress == true)) {
+              NFC_TRACE_DEBUG0("Changing disc_state and disc_flags");
+              nfa_dm_cb.disc_cb.disc_state = NFA_DM_RFST_IDLE;
+              nfa_dm_cb.disc_cb.disc_flags &=
+                      ~(NFA_DM_DISC_FLAGS_W4_NTF | NFA_DM_DISC_FLAGS_STOPPING);
+              nfa_dm_cb.disc_cb.disc_flags |=
+                      (NFA_DM_DISC_FLAGS_W4_RSP | NFA_DM_DISC_FLAGS_NOTIFY |
+                              NFA_DM_DISC_FLAGS_ENABLED);
+              disc_deact_ntf_timeout_handler(NFC_NFCC_TIMEOUT_REVT);
+          } else {
+              /*no response after the deactivate command, handling the error
+               * scenario after the recovery*/
+              if ((gid == NCI_GID_RF_MANAGE) && (oid == NCI_MSG_RF_DISCOVER) &&
+                      (nfc_cb.nci_cmd_window == 0)) {
+                  NFC_TRACE_DEBUG0("resetting the nci_cmd_window");
+                  nfc_cb.nci_cmd_window++;
+              } else {
+                  NFC_TRACE_ERROR2(
+                          "nfc_ncif_process_event unexpected rsp: gid:0x%x, oid:0x%x",
+                          gid, oid);
+                  return true;
+              }
+          }
+      }
+
+      switch (gid) {
+        case NCI_GID_CORE: /* 0000b NCI Core group */
+          free = nci_proc_core_rsp(p_msg);
+          break;
+        case NCI_GID_RF_MANAGE: /* 0001b NCI Discovery group */
+          nci_proc_rf_management_rsp(p_msg);
+          break;
+#if (NFC_NFCEE_INCLUDED == true)
+#if (NFC_RW_ONLY == FALSE)
+        case NCI_GID_EE_MANAGE: /* 0x02 0010b NFCEE Discovery group */
+          nci_proc_ee_management_rsp(p_msg);
+          break;
+#endif
+#endif
+        case NCI_GID_PROP: /* 1111b Proprietary */
+          nci_proc_prop_rsp(p_msg);
+          break;
+        default:
+          NFC_TRACE_ERROR1("NFC: Unknown gid:%d", gid);
+          break;
+      }
+#if (NXP_EXTNS == TRUE)
+      // received command response
+      // set the saved header and command  buffer to zero
+      nfc_cb.cmd_size = 0x00;
+      memset(nfc_cb.last_hdr, 0, NFC_SAVED_HDR_SIZE);
+      memset(nfc_cb.last_cmd, 0, NFC_SAVED_CMD_SIZE);
+#endif
+      if (get_i2c_fragmentation_enabled() == I2C_FRAGMENATATION_ENABLED) {
+        nfc_cb.i2c_data_t.nci_cmd_channel_busy = 0;
+        NFC_TRACE_DEBUG1("%s,updating window", __func__);
+        p_cb_stored = nfc_find_conn_cb_by_conn_id(nfc_cb.i2c_data_t.conn_id);
+        nfc_ncif_update_window();
+        if (p_cb_stored && (nfc_cb.i2c_data_t.data_stored == 1) &&
+            (nfc_cb.i2c_data_t.nci_cmd_channel_busy == 0x00)) {
+          NFC_TRACE_ERROR0("resending the stored data  packet");
+          nfc_ncif_send_data(p_cb_stored, NULL);
+          nfc_cb.i2c_data_t.data_stored = 0;
+        }
+      } else {
+        nfc_ncif_update_window();
+      }
+      break;
+    case NCI_MT_NTF:
+      NFC_TRACE_DEBUG1("NFC received ntf gid:%d", gid);
+      switch (gid) {
+        case NCI_GID_CORE: /* 0000b NCI Core group */
+          nci_proc_core_ntf(p_msg);
+          break;
+        case NCI_GID_RF_MANAGE: /* 0001b NCI Discovery group */
+          nci_proc_rf_management_ntf(p_msg);
+          break;
+#if (NFC_NFCEE_INCLUDED == true)
+#if (NFC_RW_ONLY == FALSE)
+        case NCI_GID_EE_MANAGE: /* 0x02 0010b NFCEE Discovery group */
+          nci_proc_ee_management_ntf(p_msg);
+          break;
+#endif
+#endif
+        case NCI_GID_PROP: /* 1111b Proprietary */
+          nci_proc_prop_ntf(p_msg);
+          break;
+        default:
+          NFC_TRACE_ERROR1("NFC: Unknown gid:%d", gid);
+          break;
+      }
+      break;
+
+    default:
+      NFC_TRACE_DEBUG2("NFC received unknown mt:0x%x, gid:%d", mt, gid);
+  }
+
+  return (free);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_rf_management_status
+**
+** Description      This function is called to report an event
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_rf_management_status(tNFC_DISCOVER_EVT event, uint8_t status) {
+  tNFC_DISCOVER evt_data;
+  if (nfc_cb.p_discv_cback) {
+    evt_data.status = (tNFC_STATUS)status;
+    (*nfc_cb.p_discv_cback)(event, &evt_data);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_set_config_status
+**
+** Description      This function is called to report NFC_SET_CONFIG_REVT
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_set_config_status(uint8_t* p, uint8_t len) {
+  tNFC_RESPONSE evt_data;
+  (void)len;
+
+  if (nfc_cb.p_resp_cback) {
+    evt_data.set_config.status = (tNFC_STATUS)*p++;
+    evt_data.set_config.num_param_id = NFC_STATUS_OK;
+    if (evt_data.set_config.status != NFC_STATUS_OK) {
+      evt_data.set_config.num_param_id = *p++;
+      STREAM_TO_ARRAY(evt_data.set_config.param_ids, p,
+                      evt_data.set_config.num_param_id);
+    }
+
+    (*nfc_cb.p_resp_cback)(NFC_SET_CONFIG_REVT, &evt_data);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_event_status
+**
+** Description      This function is called to report an event
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_event_status(tNFC_RESPONSE_EVT event, uint8_t status) {
+  tNFC_RESPONSE evt_data;
+
+#if (NXP_EXTNS == TRUE)
+  if ((nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME ==
+          nfcFL.eseFL._ESE_WIRED_MODE_RESUME) &&
+          ((status == NFC_STATUS_WIRED_SESSION_ABORTED) ||
+                  (status == NFC_STATUS_DWP_APDU_DROPPPED))) {
+    tNFC_CONN_CB* p_cb;
+    nfc_cb.bBlockWiredMode = true;
+    nfc_cb.bBlkPwrlinkAndModeSetCmd = true;
+    p_cb = nfc_find_conn_cb_by_conn_id(nfa_hci_cb.conn_id);
+    nfc_stop_timer(&nfc_cb.rf_filed_event_timeout_timer);
+    if (!nfc_cb.bIsCreditNtfRcvd) {
+      nfc_stop_timer(&nfc_cb.nci_wait_data_ntf_timer);
+      nfc_cb.bIsCreditNtfRcvd = true;
+
+      if ((p_cb) && !p_cb->num_buff) p_cb->num_buff++;
+    }
+    nfc_cb.bSetmodeOnReq = true; /* Sending mode set ON is required on RF
+                                    deactivation to resume DWP */
+    nfa_hci_cb.bIsHciResponseTimedout = false;
+    if (status == NFC_STATUS_DWP_APDU_DROPPPED) {
+      nfc_cb.bRetransmitDwpPacket = true;
+    }
+    if (status == NFC_STATUS_WIRED_SESSION_ABORTED) {
+      nfc_cb.bIsDwpResPending = true;
+      nfa_hci_cb.IsWiredSessionAborted = true;
+    }
+    nfa_sys_stop_timer(&nfa_hci_cb.timer);
+    if (p_cb && p_cb->p_cback)
+      (*p_cb->p_cback)(nfa_hci_cb.conn_id, NFC_HCI_RESTART_TIMER,
+                       (tNFC_CONN*)&evt_data);
+  }
+#endif
+
+  if (nfc_cb.p_resp_cback) {
+    evt_data.status = (tNFC_STATUS)status;
+    (*nfc_cb.p_resp_cback)(event, &evt_data);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_error_status
+**
+** Description      This function is called to report an error event to data
+**                  cback
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_error_status(uint8_t conn_id, uint8_t status) {
+  tNFC_CONN_CB* p_cb;
+  p_cb = nfc_find_conn_cb_by_conn_id(conn_id);
+  if (p_cb && p_cb->p_cback) {
+    (*p_cb->p_cback)(conn_id, NFC_ERROR_CEVT, (void*)&status);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_rf_field_ntf
+**
+** Description      This function is called to process RF field notification
+**
+** Returns          void
+**
+*******************************************************************************/
+#if (NFC_RW_ONLY == FALSE)
+void nfc_ncif_proc_rf_field_ntf(uint8_t rf_status) {
+  NFC_TRACE_DEBUG0("nfc_ncif_proc_rf_field_ntf");
+  tNFC_RESPONSE evt_data;
+#if (NXP_EXTNS == TRUE)
+  if(nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME ==
+          nfcFL.eseFL._ESE_WIRED_MODE_RESUME) {
+      if (rf_status == 0x01) {
+          NFC_TRACE_DEBUG0("nfc_ncif_proc_rf_field_ntf ON_EVT");
+          nfc_cb.bBlockWiredMode = true;
+          nfc_cb.bBlkPwrlinkAndModeSetCmd = true;
+          nfc_stop_timer(&nfc_cb.nci_wait_setMode_Ntf_timer); /* stop mode set Ntf
+                                                           timer if it is
+                                                           allready started */
+          nfc_start_timer(&nfc_cb.rf_filed_event_timeout_timer,
+                  (uint16_t)(NFC_TTYPE_NCI_WAIT_RF_FIELD_NTF),
+                  NFC_NCI_RFFIELD_EVT_TIMEOUT);
+      } else {
+          nfc_stop_timer(&nfc_cb.rf_filed_event_timeout_timer);
+          if (nfc_cb.bBlockWiredMode) {
+              nfc_start_timer(&nfc_cb.rf_filed_event_timeout_timer,
+                      (uint16_t)(NFC_TTYPE_NCI_WAIT_RF_FIELD_NTF),
+                      NFC_NCI_RFFIELD_EVT_TIMEOUT);
+          }
+      }
+  }
+#endif
+
+  if (nfc_cb.p_resp_cback) {
+    evt_data.status = (tNFC_STATUS)NFC_STATUS_OK;
+    evt_data.rf_field.rf_field = rf_status;
+    (*nfc_cb.p_resp_cback)(NFC_RF_FIELD_REVT, &evt_data);
+  }
+}
+#endif
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         nfc_ncif_allow_dwp_transmission
+**
+** Description      This function is called when CE deactivation/RF event
+*timedout/RF OFF event
+**                  eSE action notification
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_allow_dwp_transmission() {
+    NFC_TRACE_DEBUG0("nfc_ncif_allow_dwp_transmission Enter");
+    if(nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME !=
+            nfcFL.eseFL._ESE_WIRED_MODE_RESUME) {
+        NFC_TRACE_DEBUG0("DUAL_MODE_PRIO_SCHEME != WIRED_MODE_RESUME. Returning");
+        return;
+    }
+  tNFC_RESPONSE evt_data;
+  tNFC_CONN_CB* p_cb;
+  NFC_TRACE_DEBUG2("nfc_ncif_allow_dwp_transmission %d, %d ",
+                   nfc_cb.bIsDwpResPending, nfc_cb.bRetransmitDwpPacket);
+  p_cb = nfc_find_conn_cb_by_conn_id(nfa_hci_cb.conn_id);
+
+  if ((p_cb) && (p_cb->conn_id == NFC_NFCEE_CONN_ID)) {
+    if (nfa_hci_cb.bIsHciResponseTimedout) {
+      nfa_hci_cb.IsHciTimerChanged = false;
+      nfc_cb.bRetransmitDwpPacket = false;
+      nfa_hci_cb.bIsHciResponseTimedout = false;
+      nfc_cb.bIsDwpResPending = false;
+    }
+    if (nfc_cb.bIsDwpResPending) {
+      nfa_sys_stop_timer(&nfa_hci_cb.timer);
+      nfc_cb.bIsDwpResPending = false;
+      nfa_hci_cb.IsHciTimerChanged = true;
+      if (p_cb->p_cback)
+        (*p_cb->p_cback)(nfa_hci_cb.conn_id, NFC_HCI_RESTART_TIMER,
+                         (tNFC_CONN*)&evt_data);
+    } else if (nfc_cb.bRetransmitDwpPacket) {
+      nfa_sys_stop_timer(&nfa_hci_cb.timer);
+      nfc_ncif_retransmit_data(p_cb, nfc_cb.temp_data);
+      nfc_cb.bRetransmitDwpPacket = false;
+      if (p_cb->p_cback)
+        (*p_cb->p_cback)(nfa_hci_cb.conn_id, NFC_HCI_RESTART_TIMER,
+                         (tNFC_CONN*)&evt_data);
+    } else {
+      nfc_ncif_send_data(p_cb, NULL);
+    }
+  }
+}
+/*******************************************************************************
+**
+** Function         nfc_ncif_onWiredModeHold_timeout
+**
+** Description      This function is called when RF field event timedout
+**                  To aviod infinite dwp block on RF_ON event
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_onWiredModeHold_timeout() {
+  NFC_TRACE_DEBUG0("nfc_ncif_onWiredModeHold_timeout");
+  if(nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME !=
+          nfcFL.eseFL._ESE_WIRED_MODE_RESUME) {
+      NFC_TRACE_DEBUG0("DUAL_MODE_PRIO_SCHEME != WIRED_MODE_RESUME. Returning");
+      return;
+  }
+  if (nfc_cb.bBlockWiredMode) {
+    nfc_ncif_resume_dwp_wired_mode();
+  }
+}
+/*******************************************************************************
+**
+** Function         nfc_ncif_resume_dwp_wired_mode
+**
+** Description      This function is called to resume DWP session when RF is
+*session is over
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_resume_dwp_wired_mode() {
+  NFC_TRACE_DEBUG0("nfc_ncif_resume_dwp_wired_mode");
+  if(nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME !=
+          nfcFL.eseFL._ESE_WIRED_MODE_RESUME) {
+      NFC_TRACE_DEBUG0("DUAL_MODE_PRIO_SCHEME != WIRED_MODE_RESUME. Returning");
+      return;
+  }
+  tNFC_CONN_CB* p_cb;
+  p_cb = nfc_find_conn_cb_by_conn_id(nfa_hci_cb.conn_id);
+  nfc_cb.bBlkPwrlinkAndModeSetCmd = false;
+  nfc_cb.bIssueModeSetCmd = false;
+  if (nfc_cb.pwr_link_cmd.bPwrLinkCmdRequested) {
+    NFC_TRACE_DEBUG0("pwr link cmd to send");
+    nci_snd_pwr_nd_lnk_ctrl_cmd(NFCEE_ID_ESE, nfc_cb.pwr_link_cmd.param);
+    nfc_cb.pwr_link_cmd.bPwrLinkCmdRequested = false;
+    if (!nfc_cb.bCeActivatedeSE) nfc_cb.bIssueModeSetCmd = true;
+  } else if (((nfc_cb.bSetmodeOnReq) || (!GKI_queue_is_empty(&p_cb->tx_q))) &&
+             (!nfc_cb.bCeActivatedeSE)) {
+    NFC_TRACE_DEBUG0("mode set cmd to send");
+    nfc_cb.bSetmodeOnReq = true;
+    nci_snd_nfcee_mode_set(NFCEE_ID_ESE, NFC_MODE_ACTIVATE);
+    nfc_start_timer(&nfc_cb.nci_wait_setMode_Ntf_timer,
+                    (uint16_t)NFC_TYPE_NCI_WAIT_SETMODE_NTF,
+                    NFC_NCI_SETMODE_NTF_TIMEOUT);
+  } else {
+    nfc_cb.bBlockWiredMode = false;
+    nfc_cb.bCeActivatedeSE = false;
+    nfc_ncif_allow_dwp_transmission();
+  }
+}
+/*******************************************************************************
+**
+** Function         nfc_ncif_modeSet_Ntf_timeout
+**
+** Description      This function is called when mode set ntf timedout
+**                  To aviod infinite wait for mode set ntf
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_modeSet_Ntf_timeout() {
+  NFC_TRACE_DEBUG0("nfc_ncif_modeSet_Ntf_timeout");
+  if(nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME !=
+          nfcFL.eseFL._ESE_WIRED_MODE_RESUME) {
+      NFC_TRACE_DEBUG0("DUAL_MODE_PRIO_SCHEME != WIRED_MODE_RESUME. Returning");
+      return;
+  }
+  if (nfc_cb.bBlockWiredMode) {
+    nfc_cb.bBlockWiredMode = false;
+    nfc_cb.bCeActivatedeSE = false;
+    nfc_ncif_allow_dwp_transmission();
+  }
+}
+/*******************************************************************************
+**
+** Function         nfc_ncif_modeSet_rsp_timeout
+**
+** Description      This function is called when mode set rsp timedout
+**                  To aviod infinite wait for mode set rsp
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_modeSet_rsp_timeout() {
+  NFC_TRACE_DEBUG0("nfc_ncif_modeSet_rsp_timeout");
+  if(nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME !=
+          nfcFL.eseFL._ESE_WIRED_MODE_RESUME) {
+      NFC_TRACE_DEBUG0("DUAL_MODE_PRIO_SCHEME != WIRED_MODE_RESUME. Returning");
+      return;
+  }
+  tNFC_NFCEE_MODE_SET_REVT mode_set_info;
+  tNFC_RESPONSE_CBACK* p_cback = nfc_cb.p_resp_cback;
+  tNFC_NFCEE_INFO_REVT nfcee_info;
+  tNFC_RESPONSE* p_evt = (tNFC_RESPONSE*)&nfcee_info;
+  tNFC_RESPONSE_EVT event = NFC_NFCEE_INFO_REVT;
+  p_evt = (tNFC_RESPONSE*)&mode_set_info;
+  event = NFC_NFCEE_MODE_SET_REVT;
+  mode_set_info.nfcee_id = NFCEE_ID_ESE;
+  mode_set_info.mode = NFC_MODE_ACTIVATE;
+  mode_set_info.status = NCI_STATUS_OK;
+  if (p_cback) {
+    (*p_cback)(event, p_evt);
+  }
+}
+/*******************************************************************************
+**
+** Function         nfc_ncif_pwr_link_rsp_timeout
+**
+** Description      This function is called when pwr link cmd is ignored due to
+*rf session ongoing and sending fake resp
+**                  to aviod infinite wait for power link Rsp
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_pwr_link_rsp_timeout() {
+  NFC_TRACE_DEBUG0("nfc_ncif_pwr_link_rsp_timeout");
+  if(nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME !=
+          nfcFL.eseFL._ESE_WIRED_MODE_RESUME) {
+      NFC_TRACE_DEBUG0("DUAL_MODE_PRIO_SCHEME != WIRED_MODE_RESUME. Returning");
+      return;
+  }
+  tNFC_RESPONSE_CBACK* p_cback = nfc_cb.p_resp_cback;
+  tNFC_NFCEE_EE_PWR_LNK_REVT pwr_lnk_ctrl;
+  tNFC_NFCEE_INFO_REVT nfcee_info;
+  tNFC_RESPONSE_EVT event = NFC_NFCEE_INFO_REVT;
+  tNFC_RESPONSE* p_evt = (tNFC_RESPONSE*)&nfcee_info;
+  p_evt = (tNFC_RESPONSE*)&pwr_lnk_ctrl;
+  pwr_lnk_ctrl.status = NCI_STATUS_OK;
+  pwr_lnk_ctrl.nfcee_id = NFCEE_ID_ESE;
+  event = NFC_NFCEE_PWR_LNK_CTRL_REVT;
+  if (p_cback) (*p_cback)(event, p_evt);
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_credits
+**
+** Description      This function is called to process data credits
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_proc_credits(uint8_t* p, uint16_t plen) {
+  uint8_t num, xx;
+  tNFC_CONN_CB* p_cb;
+  (void)plen;
+
+  num = *p++;
+  for (xx = 0; xx < num; xx++) {
+    p_cb = nfc_find_conn_cb_by_conn_id(*p++);
+    if (p_cb && p_cb->num_buff != NFC_CONN_NO_FC) {
+      p_cb->num_buff += (*p);
+#if (BT_USE_TRACES == true)
+      if (p_cb->num_buff > p_cb->init_credits) {
+        if (nfc_cb.nfc_state == NFC_STATE_OPEN) {
+          /* if this happens in activated state, it's very likely that our NFCC
+           * has issues */
+          /* However, credit may be returned after deactivation */
+          NFC_TRACE_ERROR2("num_buff:0x%x, init_credits:0x%x", p_cb->num_buff,
+                           p_cb->init_credits);
+        }
+        p_cb->num_buff = p_cb->init_credits;
+      }
+#endif
+#if (NXP_EXTNS == TRUE)
+      if (p_cb->conn_id != NFC_RF_CONN_ID) {
+        nfc_stop_timer(&nfc_cb.nci_wait_data_ntf_timer);
+      }
+      if (p_cb->conn_id == NFC_NFCEE_CONN_ID) {
+        nfc_cb.bIsCreditNtfRcvd = true;
+      }
+#endif
+      if (get_i2c_fragmentation_enabled() == I2C_FRAGMENATATION_ENABLED) {
+        nfc_ncif_update_data_queue();
+      }
+      /* check if there's nay data in tx q to be sent */
+      nfc_ncif_send_data(p_cb, NULL);
+    }
+    p++;
+  }
+}
+/*******************************************************************************
+**
+** Function         nfc_ncif_decode_rf_params
+**
+** Description      This function is called to process the detected technology
+**                  and mode and the associated parameters for DISCOVER_NTF and
+**                  ACTIVATE_NTF
+**
+** Returns          void
+**
+*******************************************************************************/
+uint8_t* nfc_ncif_decode_rf_params(tNFC_RF_TECH_PARAMS* p_param, uint8_t* p) {
+  tNFC_RF_PA_PARAMS* p_pa;
+  uint8_t len, *p_start, u8;
+  tNFC_RF_PB_PARAMS* p_pb;
+  tNFC_RF_LF_PARAMS* p_lf;
+  tNFC_RF_PF_PARAMS* p_pf;
+  tNFC_RF_PISO15693_PARAMS* p_i93;
+
+  len = *p++;
+  p_start = p;
+  memset(&p_param->param, 0, sizeof(tNFC_RF_TECH_PARAMU));
+  if (NCI_DISCOVERY_TYPE_POLL_A == p_param->mode ||
+      NCI_DISCOVERY_TYPE_POLL_A_ACTIVE == p_param->mode) {
+    p_pa = &p_param->param.pa;
+    /*
+SENS_RES Response   2 bytes Defined in [DIGPROT] Available after Technology
+Detection
+NFCID1 length   1 byte  Length of NFCID1 Available after Collision Resolution
+NFCID1  4, 7, or 10 bytes   Defined in [DIGPROT]Available after Collision
+Resolution
+SEL_RES Response    1 byte  Defined in [DIGPROT]Available after Collision
+Resolution
+HRx Length  1 Octets    Length of HRx Parameters collected from the response to
+the T1T RID command.
+HRx 0 or 2 Octets   If present, the first byte SHALL contain HR0 and the second
+byte SHALL contain HR1 as defined in [DIGITAL].
+    */
+    STREAM_TO_ARRAY(p_pa->sens_res, p, 2);
+    p_pa->nfcid1_len = *p++;
+    if (p_pa->nfcid1_len > NCI_NFCID1_MAX_LEN)
+      p_pa->nfcid1_len = NCI_NFCID1_MAX_LEN;
+    STREAM_TO_ARRAY(p_pa->nfcid1, p, p_pa->nfcid1_len);
+    u8 = *p++;
+    if (u8) p_pa->sel_rsp = *p++;
+    if (len ==
+        (7 + p_pa->nfcid1_len + u8)) /* 2(sens_res) + 1(len) +
+                                        p_pa->nfcid1_len + 1(len) + u8 + hr
+                                        (1:len + 2) */
+    {
+      p_pa->hr_len = *p++;
+      if (p_pa->hr_len == NCI_T1T_HR_LEN) {
+        p_pa->hr[0] = *p++;
+        p_pa->hr[1] = *p;
+      }
+    }
+  } else if (NCI_DISCOVERY_TYPE_POLL_B == p_param->mode) {
+    /*
+SENSB_RES Response length (n)   1 byte  Length of SENSB_RES Response (Byte 2 -
+Byte 12 or 13)Available after Technology Detection
+SENSB_RES Response Byte 2 - Byte 12 or 13   11 or 12 bytes  Defined in [DIGPROT]
+Available after Technology Detection
+    */
+    p_pb = &p_param->param.pb;
+    p_pb->sensb_res_len = *p++;
+    if (p_pb->sensb_res_len > NCI_MAX_SENSB_RES_LEN)
+      p_pb->sensb_res_len = NCI_MAX_SENSB_RES_LEN;
+    STREAM_TO_ARRAY(p_pb->sensb_res, p, p_pb->sensb_res_len);
+    memcpy(p_pb->nfcid0, p_pb->sensb_res, NFC_NFCID0_MAX_LEN);
+  } else if (NCI_DISCOVERY_TYPE_POLL_F == p_param->mode ||
+             NCI_DISCOVERY_TYPE_POLL_F_ACTIVE == p_param->mode) {
+    /*
+Bit Rate    1 byte  1   212 kbps/2   424 kbps/0 and 3 to 255  RFU
+SENSF_RES Response length.(n) 1 byte  Length of SENSF_RES (Byte 2 - Byte 17 or
+19).Available after Technology Detection
+SENSF_RES Response Byte 2 - Byte 17 or 19  n bytes Defined in [DIGPROT]
+Available after Technology Detection
+    */
+    p_pf = &p_param->param.pf;
+    p_pf->bit_rate = *p++;
+    p_pf->sensf_res_len = *p++;
+    if (p_pf->sensf_res_len > NCI_MAX_SENSF_RES_LEN)
+      p_pf->sensf_res_len = NCI_MAX_SENSF_RES_LEN;
+    STREAM_TO_ARRAY(p_pf->sensf_res, p, p_pf->sensf_res_len);
+    memcpy(p_pf->nfcid2, p_pf->sensf_res, NCI_NFCID2_LEN);
+    p_pf->mrti_check = p_pf->sensf_res[NCI_MRTI_CHECK_INDEX];
+    p_pf->mrti_update = p_pf->sensf_res[NCI_MRTI_UPDATE_INDEX];
+  } else if (NCI_DISCOVERY_TYPE_LISTEN_F == p_param->mode ||
+             NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE == p_param->mode) {
+    p_lf = &p_param->param.lf;
+    u8 = *p++;
+    if (u8) {
+      STREAM_TO_ARRAY(p_lf->nfcid2, p, NCI_NFCID2_LEN);
+    }
+  } else if (NCI_DISCOVERY_TYPE_POLL_ISO15693 == p_param->mode) {
+    p_i93 = &p_param->param.pi93;
+    p_i93->flag = *p++;
+    p_i93->dsfid = *p++;
+    STREAM_TO_ARRAY(p_i93->uid, p, NFC_ISO15693_UID_LEN);
+  } else if (NCI_DISCOVERY_TYPE_POLL_KOVIO == p_param->mode) {
+    p_param->param.pk.uid_len = len;
+    if (p_param->param.pk.uid_len > NFC_KOVIO_MAX_LEN) {
+      NFC_TRACE_ERROR2("Kovio UID len:0x%x exceeds max(0x%x)",
+                       p_param->param.pk.uid_len, NFC_KOVIO_MAX_LEN);
+      p_param->param.pk.uid_len = NFC_KOVIO_MAX_LEN;
+    }
+    STREAM_TO_ARRAY(p_param->param.pk.uid, p, p_param->param.pk.uid_len);
+  }
+
+  return (p_start + len);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_discover_ntf
+**
+** Description      This function is called to process discover notification
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_proc_discover_ntf(uint8_t* p, uint16_t plen) {
+  tNFC_DISCOVER evt_data;
+  (void)plen;
+
+  if (nfc_cb.p_discv_cback) {
+    p += NCI_MSG_HDR_SIZE;
+    evt_data.status = NCI_STATUS_OK;
+    evt_data.result.rf_disc_id = *p++;
+    evt_data.result.protocol = *p++;
+
+    /* fill in tNFC_RESULT_DEVT */
+    evt_data.result.rf_tech_param.mode = *p++;
+    p = nfc_ncif_decode_rf_params(&evt_data.result.rf_tech_param, p);
+
+    evt_data.result.more = *p++;
+    (*nfc_cb.p_discv_cback)(NFC_RESULT_DEVT, &evt_data);
+  }
+}
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_isodep_nak_presence_check_status
+**
+** Description      This function is called to handle response and notification for
+**                  presence check nak command
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_proc_isodep_nak_presence_check_status (uint8_t status, bool is_ntf) {
+  rw_t4t_handle_isodep_nak_rsp(status , is_ntf);
+}
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_rf_wtx_ntf
+**
+** Description      This function is called to process rf wtx notification
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_proc_rf_wtx_ntf(uint8_t* p, uint16_t plen) {
+  tNFC_CONN_CB* p_cb = NULL;
+  (void)p;
+  (void)plen;
+
+  p_cb = nfc_find_conn_cb_by_conn_id(NFC_RF_CONN_ID);
+
+  if (NULL != p_cb) {
+    if ((p_cb->conn_id == NFC_RF_CONN_ID) && (p_cb->p_cback)) {
+      /* Indicate upper layer that local device started receiving rf wtx */
+      (*p_cb->p_cback)(p_cb->conn_id, NFC_RF_WTX_CEVT, NULL);
+    }
+  }
+}
+
+#endif
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_activate
+**
+** Description      This function is called to process de-activate
+**                  response and notification
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_proc_activate(uint8_t* p, uint8_t len) {
+  tNFC_DISCOVER evt_data;
+  tNFC_INTF_PARAMS* p_intf = &evt_data.activate.intf_param;
+  tNFC_INTF_PA_ISO_DEP* p_pa_iso;
+  tNFC_INTF_LB_ISO_DEP* p_lb_iso;
+  tNFC_INTF_PB_ISO_DEP* p_pb_iso;
+#if (NFC_RW_ONLY == FALSE)
+  tNFC_INTF_PA_NFC_DEP* p_pa_nfc;
+  int mpl_idx = 0;
+  uint8_t gb_idx = 0, mpl;
+#endif
+  uint8_t t0;
+  tNCI_DISCOVERY_TYPE mode;
+  tNFC_CONN_CB* p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+  uint8_t* pp, len_act;
+  uint8_t buff_size, num_buff;
+  tNFC_RF_PA_PARAMS* p_pa;
+
+  nfc_set_state(NFC_STATE_OPEN);
+
+  memset(p_intf, 0, sizeof(tNFC_INTF_PARAMS));
+  evt_data.activate.rf_disc_id = *p++;
+  p_intf->type = *p++;
+  evt_data.activate.protocol = *p++;
+
+  if (evt_data.activate.protocol == NCI_PROTOCOL_18092_ACTIVE)
+    evt_data.activate.protocol = NCI_PROTOCOL_NFC_DEP;
+
+#if (NXP_EXTNS == TRUE)
+  if ((evt_data.activate.protocol == NCI_PROTOCOL_UNKNOWN) &&
+      (p_intf->type == NCI_INTERFACE_FRAME))
+    evt_data.activate.protocol = NCI_PROTOCOL_T3BT;
+#endif
+
+  evt_data.activate.rf_tech_param.mode = *p++;
+  buff_size = *p++;
+  num_buff = *p++;
+  /* fill in tNFC_activate_DEVT */
+  p = nfc_ncif_decode_rf_params(&evt_data.activate.rf_tech_param, p);
+
+  evt_data.activate.data_mode = *p++;
+  evt_data.activate.tx_bitrate = *p++;
+  evt_data.activate.rx_bitrate = *p++;
+  mode = evt_data.activate.rf_tech_param.mode;
+  len_act = *p++;
+  NFC_TRACE_DEBUG3("nfc_ncif_proc_activate:%d %d, mode:0x%02x", len, len_act,
+                   mode);
+
+#if (NXP_EXTNS == TRUE)
+  if ((evt_data.activate.protocol == NCI_PROTOCOL_NFC_DEP) &&
+      (mode == NCI_DISCOVERY_TYPE_LISTEN_F)) {
+    sListenActivated = true;
+    nfc_start_timer(&nfc_cb.listen_activation_timer_list,
+                    (uint16_t)(NFC_TTYPE_LISTEN_ACTIVATION), 2);
+  }
+
+  if ((nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME ==
+          nfcFL.eseFL._ESE_WIRED_MODE_RESUME) && nfc_cb.bBlockWiredMode) {
+      nfc_stop_timer(&nfc_cb.rf_filed_event_timeout_timer);
+  }
+#endif
+
+  /* just in case the interface reports activation parameters not defined in the
+   * NCI spec */
+  p_intf->intf_param.frame.param_len = len_act;
+  if (p_intf->intf_param.frame.param_len > NFC_MAX_RAW_PARAMS)
+    p_intf->intf_param.frame.param_len = NFC_MAX_RAW_PARAMS;
+  pp = p;
+  STREAM_TO_ARRAY(p_intf->intf_param.frame.param, pp,
+                  p_intf->intf_param.frame.param_len);
+  if (evt_data.activate.intf_param.type == NCI_INTERFACE_ISO_DEP) {
+    /* Make max payload of NCI aligned to max payload of ISO-DEP for better
+     * performance */
+    if (buff_size > NCI_ISO_DEP_MAX_INFO) buff_size = NCI_ISO_DEP_MAX_INFO;
+
+    switch (mode) {
+      case NCI_DISCOVERY_TYPE_POLL_A:
+        p_pa_iso = &p_intf->intf_param.pa_iso;
+        p_pa_iso->ats_res_len = *p++;
+
+        if (p_pa_iso->ats_res_len == 0) break;
+
+        if (p_pa_iso->ats_res_len > NFC_MAX_ATS_LEN)
+          p_pa_iso->ats_res_len = NFC_MAX_ATS_LEN;
+        STREAM_TO_ARRAY(p_pa_iso->ats_res, p, p_pa_iso->ats_res_len);
+        pp = &p_pa_iso->ats_res[NCI_ATS_T0_INDEX];
+        t0 = p_pa_iso->ats_res[NCI_ATS_T0_INDEX];
+        pp++;                           /* T0 */
+        if (t0 & NCI_ATS_TA_MASK) pp++; /* TA */
+        if (t0 & NCI_ATS_TB_MASK) {
+          /* FWI (Frame Waiting time Integer) & SPGI (Start-up Frame Guard time
+           * Integer) */
+          p_pa_iso->fwi = (((*pp) >> 4) & 0x0F);
+          p_pa_iso->sfgi = ((*pp) & 0x0F);
+          pp++; /* TB */
+        }
+        if (t0 & NCI_ATS_TC_MASK) {
+          p_pa_iso->nad_used = ((*pp) & 0x01);
+          pp++; /* TC */
+        }
+        p_pa_iso->his_byte_len =
+            (uint8_t)(p_pa_iso->ats_res_len - (pp - p_pa_iso->ats_res));
+        if (p_pa_iso->his_byte_len > NFC_MAX_HIS_BYTES_LEN)
+          p_pa_iso->his_byte_len = NFC_MAX_HIS_BYTES_LEN;
+        memcpy(p_pa_iso->his_byte, pp, p_pa_iso->his_byte_len);
+        break;
+
+      case NCI_DISCOVERY_TYPE_LISTEN_A:
+        p_intf->intf_param.la_iso.rats = *p++;
+        break;
+
+      case NCI_DISCOVERY_TYPE_POLL_B:
+        /* ATTRIB RSP
+        Byte 1   Byte 2 ~ 2+n-1
+        MBLI/DID Higher layer - Response
+        */
+        p_pb_iso = &p_intf->intf_param.pb_iso;
+        p_pb_iso->attrib_res_len = *p++;
+
+        if (p_pb_iso->attrib_res_len == 0) break;
+
+        if (p_pb_iso->attrib_res_len > NFC_MAX_ATTRIB_LEN)
+          p_pb_iso->attrib_res_len = NFC_MAX_ATTRIB_LEN;
+        STREAM_TO_ARRAY(p_pb_iso->attrib_res, p, p_pb_iso->attrib_res_len);
+        p_pb_iso->mbli = (p_pb_iso->attrib_res[0]) >> 4;
+        if (p_pb_iso->attrib_res_len > NFC_PB_ATTRIB_REQ_FIXED_BYTES) {
+          p_pb_iso->hi_info_len =
+              p_pb_iso->attrib_res_len - NFC_PB_ATTRIB_REQ_FIXED_BYTES;
+          if (p_pb_iso->hi_info_len > NFC_MAX_GEN_BYTES_LEN)
+            p_pb_iso->hi_info_len = NFC_MAX_GEN_BYTES_LEN;
+          memcpy(p_pb_iso->hi_info,
+                 &p_pb_iso->attrib_res[NFC_PB_ATTRIB_REQ_FIXED_BYTES],
+                 p_pb_iso->hi_info_len);
+        }
+        break;
+
+      case NCI_DISCOVERY_TYPE_LISTEN_B:
+        /* ATTRIB CMD
+        Byte 2~5 Byte 6  Byte 7  Byte 8  Byte 9  Byte 10 ~ 10+k-1
+        NFCID0   Param 1 Param 2 Param 3 Param 4 Higher layer - INF
+        */
+        p_lb_iso = &p_intf->intf_param.lb_iso;
+        p_lb_iso->attrib_req_len = *p++;
+
+        if (p_lb_iso->attrib_req_len == 0) break;
+
+        if (p_lb_iso->attrib_req_len > NFC_MAX_ATTRIB_LEN)
+          p_lb_iso->attrib_req_len = NFC_MAX_ATTRIB_LEN;
+        STREAM_TO_ARRAY(p_lb_iso->attrib_req, p, p_lb_iso->attrib_req_len);
+        memcpy(p_lb_iso->nfcid0, p_lb_iso->attrib_req, NFC_NFCID0_MAX_LEN);
+        if (p_lb_iso->attrib_req_len > NFC_LB_ATTRIB_REQ_FIXED_BYTES) {
+          p_lb_iso->hi_info_len =
+              p_lb_iso->attrib_req_len - NFC_LB_ATTRIB_REQ_FIXED_BYTES;
+          if (p_lb_iso->hi_info_len > NFC_MAX_GEN_BYTES_LEN)
+            p_lb_iso->hi_info_len = NFC_MAX_GEN_BYTES_LEN;
+          memcpy(p_lb_iso->hi_info,
+                 &p_lb_iso->attrib_req[NFC_LB_ATTRIB_REQ_FIXED_BYTES],
+                 p_lb_iso->hi_info_len);
+        }
+        break;
+    }
+
+  }
+#if (NFC_RW_ONLY == FALSE)
+  else if (evt_data.activate.intf_param.type == NCI_INTERFACE_NFC_DEP) {
+#if (NXP_EXTNS == TRUE)
+      if ((nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME ==
+              nfcFL.eseFL._ESE_WIRED_MODE_RESUME) && nfc_cb.bBlockWiredMode) {
+          nfc_ncif_resume_dwp_wired_mode();
+      }
+#endif
+    /* Make max payload of NCI aligned to max payload of NFC-DEP for better
+     * performance */
+    if (buff_size > NCI_NFC_DEP_MAX_DATA) buff_size = NCI_NFC_DEP_MAX_DATA;
+
+    p_pa_nfc = &p_intf->intf_param.pa_nfc;
+    p_pa_nfc->atr_res_len = *p++;
+
+    if (p_pa_nfc->atr_res_len > 0) {
+      if (p_pa_nfc->atr_res_len > NFC_MAX_ATS_LEN)
+        p_pa_nfc->atr_res_len = NFC_MAX_ATS_LEN;
+      STREAM_TO_ARRAY(p_pa_nfc->atr_res, p, p_pa_nfc->atr_res_len);
+      if ((mode == NCI_DISCOVERY_TYPE_POLL_A) ||
+          (mode == NCI_DISCOVERY_TYPE_POLL_F) ||
+          (mode == NCI_DISCOVERY_TYPE_POLL_A_ACTIVE) ||
+          (mode == NCI_DISCOVERY_TYPE_POLL_F_ACTIVE)) {
+        /* ATR_RES
+        Byte 3~12 Byte 13 Byte 14 Byte 15 Byte 16 Byte 17 Byte 18~18+n
+        NFCID3T   DIDT    BST     BRT     TO      PPT     [GT0 ... GTn] */
+        mpl_idx = 14;
+        gb_idx = NCI_P_GEN_BYTE_INDEX;
+        p_pa_nfc->waiting_time =
+            p_pa_nfc->atr_res[NCI_L_NFC_DEP_TO_INDEX] & 0x0F;
+      } else if ((mode == NCI_DISCOVERY_TYPE_LISTEN_A) ||
+                 (mode == NCI_DISCOVERY_TYPE_LISTEN_F) ||
+                 (mode == NCI_DISCOVERY_TYPE_LISTEN_A_ACTIVE) ||
+                 (mode == NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE)) {
+        /* ATR_REQ
+        Byte 3~12 Byte 13 Byte 14 Byte 15 Byte 16 Byte 17~17+n
+        NFCID3I   DIDI    BSI     BRI     PPI     [GI0 ... GIn] */
+        mpl_idx = 13;
+        gb_idx = NCI_L_GEN_BYTE_INDEX;
+      }
+
+      mpl = ((p_pa_nfc->atr_res[mpl_idx]) >> 4) & 0x03;
+      p_pa_nfc->max_payload_size = nfc_mpl_code_to_size[mpl];
+      if (p_pa_nfc->atr_res_len > gb_idx) {
+        p_pa_nfc->gen_bytes_len = p_pa_nfc->atr_res_len - gb_idx;
+        if (p_pa_nfc->gen_bytes_len > NFC_MAX_GEN_BYTES_LEN)
+          p_pa_nfc->gen_bytes_len = NFC_MAX_GEN_BYTES_LEN;
+        memcpy(p_pa_nfc->gen_bytes, &p_pa_nfc->atr_res[gb_idx],
+               p_pa_nfc->gen_bytes_len);
+      }
+    }
+  }
+#endif
+  else if ((evt_data.activate.intf_param.type == NCI_INTERFACE_FRAME) &&
+           (evt_data.activate.protocol == NCI_PROTOCOL_T1T)) {
+    p_pa = &evt_data.activate.rf_tech_param.param.pa;
+    if ((len_act == NCI_T1T_HR_LEN) && (p_pa->hr_len == 0)) {
+      p_pa->hr_len = NCI_T1T_HR_LEN;
+      p_pa->hr[0] = *p++;
+      p_pa->hr[1] = *p++;
+    }
+  }
+#if (NXP_EXTNS == TRUE)
+  /*
+   * Code to handle the Reader over SWP.
+   * 1. Do not activate tag for this NTF.
+   * 2. Pass this info to JNI as START_READER_EVT.
+   */
+  else if (evt_data.activate.intf_param.type == nfcFL.nfcMwFL._NCI_INTERFACE_UICC_DIRECT ||
+           evt_data.activate.intf_param.type == nfcFL.nfcMwFL._NCI_INTERFACE_ESE_DIRECT) {
+    NFC_TRACE_DEBUG1("nfc_ncif_proc_activate:interface type  %x",
+                     evt_data.activate.intf_param.type);
+  }
+#endif
+
+  p_cb->act_protocol = evt_data.activate.protocol;
+#if (NXP_EXTNS == TRUE)
+  p_cb->act_interface = evt_data.activate.intf_param.type;
+  p_cb->sel_res = evt_data.activate.rf_tech_param.param.pa.sel_rsp;
+#endif
+  p_cb->buff_size = buff_size;
+  p_cb->num_buff = num_buff;
+  p_cb->init_credits = num_buff;
+
+  if (nfc_cb.p_discv_cback) {
+    (*nfc_cb.p_discv_cback)(NFC_ACTIVATE_DEVT, &evt_data);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_deactivate
+**
+** Description      This function is called to process de-activate
+**                  response and notification
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_proc_deactivate(uint8_t status, uint8_t deact_type, bool is_ntf) {
+  tNFC_DISCOVER evt_data;
+  tNFC_DEACTIVATE_DEVT* p_deact;
+  tNFC_CONN_CB* p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+#if (NXP_EXTNS == TRUE)
+    tRW_T3T_CB *p_t3tcb = &rw_cb.tcb.t3t;
+#endif
+  void* p_data;
+
+  nfc_set_state(NFC_STATE_IDLE);
+  p_deact = &evt_data.deactivate;
+  p_deact->status = status;
+  p_deact->type = deact_type;
+  p_deact->is_ntf = is_ntf;
+
+  while ((p_data = GKI_dequeue(&p_cb->rx_q)) != NULL) {
+    GKI_freebuf(p_data);
+  }
+
+  while ((p_data = GKI_dequeue(&p_cb->tx_q)) != NULL) {
+    GKI_freebuf(p_data);
+  }
+
+  if (p_cb->p_cback)
+    (*p_cb->p_cback)(NFC_RF_CONN_ID, NFC_DEACTIVATE_CEVT, (tNFC_CONN*)p_deact);
+
+#if (NXP_EXTNS == TRUE)
+    if (p_t3tcb->poll_timer.in_use)
+    {
+        NFC_TRACE_DEBUG1 ("%s: stopping t3t polling timer", __func__);
+        nfc_stop_quick_timer (&p_t3tcb->poll_timer);
+    }
+
+  if ((nfc_cb.flags & (NFC_FL_DISCOVER_PENDING | NFC_FL_CONTROL_REQUESTED)) &&
+      (deact_type == NFC_DEACTIVATE_TYPE_DISCOVERY) && (is_ntf == true)) {
+    NFC_TRACE_DEBUG0(
+        "Abnormal State, Deactivate NTF is ignored, MW is already going to "
+        "Discovery state");
+    return;
+  }
+#endif
+
+  if (nfc_cb.p_discv_cback) {
+    (*nfc_cb.p_discv_cback)(NFC_DEACTIVATE_DEVT, &evt_data);
+  }
+}
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_ee_action
+**
+** Description      This function is called to process NFCEE ACTION NTF
+**
+** Returns          void
+**
+*******************************************************************************/
+#if ((NFC_NFCEE_INCLUDED == true) && (NFC_RW_ONLY == FALSE))
+void nfc_ncif_proc_ee_action(uint8_t* p, uint16_t plen) {
+  tNFC_EE_ACTION_REVT evt_data;
+  tNFC_RESPONSE_CBACK* p_cback = nfc_cb.p_resp_cback;
+  uint8_t data_len, ulen, tag, *p_data;
+  uint8_t max_len;
+
+  if (p_cback) {
+    memset(&evt_data.act_data, 0, sizeof(tNFC_ACTION_DATA));
+    evt_data.status = NFC_STATUS_OK;
+    evt_data.nfcee_id = *p++;
+    evt_data.act_data.trigger = *p++;
+    data_len = *p++;
+    if (plen >= 3) plen -= 3;
+    if (data_len > plen) data_len = (uint8_t)plen;
+
+    switch (evt_data.act_data.trigger) {
+      case NCI_EE_TRIG_7816_SELECT:
+        if (data_len > NFC_MAX_AID_LEN) data_len = NFC_MAX_AID_LEN;
+        NFC_TRACE_DEBUG1("AID len = %d", data_len);
+        evt_data.act_data.param.aid.len_aid = data_len;
+        STREAM_TO_ARRAY(evt_data.act_data.param.aid.aid, p, data_len);
+        break;
+      case NCI_EE_TRIG_RF_PROTOCOL:
+        evt_data.act_data.param.protocol = *p++;
+        break;
+      case NCI_EE_TRIG_RF_TECHNOLOGY:
+        evt_data.act_data.param.technology = *p++;
+        break;
+      case NCI_EE_TRIG_APP_INIT:
+        while (data_len > NFC_TL_SIZE) {
+          data_len -= NFC_TL_SIZE;
+          tag = *p++;
+          ulen = *p++;
+          if (ulen > data_len) ulen = data_len;
+          p_data = NULL;
+          max_len = ulen;
+          switch (tag) {
+            case NCI_EE_ACT_TAG_AID: /* AID                 */
+              if (max_len > NFC_MAX_AID_LEN) max_len = NFC_MAX_AID_LEN;
+              evt_data.act_data.param.app_init.len_aid = max_len;
+              p_data = evt_data.act_data.param.app_init.aid;
+              break;
+            case NCI_EE_ACT_TAG_DATA: /* hex data for app    */
+              if (max_len > NFC_MAX_APP_DATA_LEN)
+                max_len = NFC_MAX_APP_DATA_LEN;
+              evt_data.act_data.param.app_init.len_data = max_len;
+              p_data = evt_data.act_data.param.app_init.data;
+              break;
+          }
+          if (p_data) {
+            STREAM_TO_ARRAY(p_data, p, max_len);
+          }
+          data_len -= ulen;
+        }
+        break;
+    }
+
+#if (NXP_EXTNS == TRUE)
+    if(nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME ==
+            nfcFL.eseFL._ESE_WIRED_MODE_RESUME) {
+        nfc_stop_timer(&nfc_cb.rf_filed_event_timeout_timer);
+        tNFC_CONN_CB* p_cb;
+        p_cb = nfc_find_conn_cb_by_conn_id(nfa_hci_cb.conn_id);
+        if (evt_data.nfcee_id != 0xC0) {
+            nfc_cb.bBlockWiredMode = true;
+            nfc_cb.bBlkPwrlinkAndModeSetCmd = true;
+            if (!nfc_cb.bIsDwpResPending && nfa_hci_cb.assembling) {
+                    /* To faster transceive time out when CE is activated with UICC during
+                     * chained response being received*/
+                    NFC_TRACE_DEBUG0("restarted hci timer during chained response");
+                    nfa_hci_cb.IsWiredSessionAborted = true;
+                    nfa_sys_stop_timer(&nfa_hci_cb.timer);
+                    if (p_cb && p_cb->p_cback)
+                      (*p_cb->p_cback)(nfa_hci_cb.conn_id, NFC_HCI_RESTART_TIMER,
+                              (tNFC_CONN*)&evt_data);
+            }
+        } else {
+            if (evt_data.act_data.trigger == NCI_EE_TRIG_RF_TECHNOLOGY) {
+                nfc_cb.bBlockWiredMode = true;
+            } else if (nfc_cb.bBlockWiredMode) {
+                nfc_cb.bCeActivatedeSE = true;
+                nfc_ncif_resume_dwp_wired_mode();
+            }
+            nfc_main_flush_cmd_queue();
+        }
+    }
+#endif
+    (*p_cback)(NFC_EE_ACTION_REVT, (tNFC_RESPONSE*)&evt_data);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_ee_discover_req
+**
+** Description      This function is called to process NFCEE DISCOVER REQ NTF
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_proc_ee_discover_req(uint8_t* p, uint16_t plen) {
+  tNFC_RESPONSE_CBACK* p_cback = nfc_cb.p_resp_cback;
+  tNFC_EE_DISCOVER_REQ_REVT ee_disc_req;
+  tNFC_EE_DISCOVER_INFO* p_info;
+  uint8_t u8;
+
+  NFC_TRACE_DEBUG2("nfc_ncif_proc_ee_discover_req %d len:%d", *p, plen);
+  if (p_cback) {
+    u8 = *p;
+    ee_disc_req.status = NFC_STATUS_OK;
+    ee_disc_req.num_info = *p++;
+    p_info = ee_disc_req.info;
+    if (plen) plen--;
+    while ((u8 > 0) && (plen >= NFC_EE_DISCOVER_ENTRY_LEN)) {
+      p_info->op = *p++;                  /* T */
+      if (*p != NFC_EE_DISCOVER_INFO_LEN) /* L */
+      {
+        NFC_TRACE_DEBUG1("bad entry len:%d", *p);
+        return;
+      }
+      p++;
+      /* V */
+      p_info->nfcee_id = *p++;
+      p_info->tech_n_mode = *p++;
+      p_info->protocol = *p++;
+      u8--;
+      plen -= NFC_EE_DISCOVER_ENTRY_LEN;
+      p_info++;
+    }
+    (*p_cback)(NFC_EE_DISCOVER_REQ_REVT, (void*)&ee_disc_req);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_get_routing
+**
+** Description      This function is called to process get routing notification
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_proc_get_routing(uint8_t* p, uint8_t len) {
+  tNFC_GET_ROUTING_REVT evt_data;
+  uint8_t more, num_entries, xx, yy, *pn, tl;
+  tNFC_STATUS status = NFC_STATUS_CONTINUE;
+#if (NXP_EXTNS == TRUE)
+  (void)(p);
+  (void)(len);
+#endif
+
+#if (NXP_EXTNS == FALSE)
+  if (nfc_cb.p_resp_cback) {
+    more = *p++;
+    num_entries = *p++;
+    for (xx = 0; xx < num_entries; xx++) {
+      if ((more == false) && (xx == (num_entries - 1))) status = NFC_STATUS_OK;
+      evt_data.status = (tNFC_STATUS)status;
+      evt_data.nfcee_id = *p++;
+      evt_data.num_tlvs = *p++;
+      evt_data.tlv_size = 0;
+      pn = evt_data.param_tlvs;
+      for (yy = 0; yy < evt_data.num_tlvs; yy++) {
+        tl = *(p + 1);
+        tl += NFC_TL_SIZE;
+        STREAM_TO_ARRAY(pn, p, tl);
+        evt_data.tlv_size += tl;
+        pn += tl;
+      }
+      (*nfc_cb.p_resp_cback)(NFC_GET_ROUTING_REVT, (tNFC_RESPONSE*)&evt_data);
+    }
+  }
+  if (nfc_cb.p_resp_cback) {
+    more = *p;
+    if (more == false) {
+      status = NFC_STATUS_OK;
+    }
+    evt_data.status = (tNFC_STATUS)status;
+    evt_data.num_tlvs = *(p + 1);
+    evt_data.tlv_size = len;
+    memcpy(evt_data.param_tlvs, p, len);
+    (*nfc_cb.p_resp_cback)(NFC_GET_ROUTING_REVT, (tNFC_RESPONSE*)&evt_data);
+  }
+#endif
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_conn_create_rsp
+**
+** Description      This function is called to process connection create
+**                  response
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_proc_conn_create_rsp(uint8_t* p, uint16_t plen,
+                                   uint8_t dest_type) {
+  tNFC_CONN_CB* p_cb;
+  tNFC_STATUS status;
+  tNFC_CONN_CBACK* p_cback;
+  tNFC_CONN evt_data;
+  uint8_t conn_id;
+  (void)plen;
+
+  /* find the pending connection control block */
+  p_cb = nfc_find_conn_cb_by_conn_id(NFC_PEND_CONN_ID);
+  if (p_cb) {
+    p += NCI_MSG_HDR_SIZE;
+    status = *p++;
+    p_cb->buff_size = *p++;
+    p_cb->num_buff = p_cb->init_credits = *p++;
+    conn_id = *p++;
+    evt_data.conn_create.status = status;
+    evt_data.conn_create.dest_type = dest_type;
+    evt_data.conn_create.id = p_cb->id;
+    evt_data.conn_create.buff_size = p_cb->buff_size;
+    evt_data.conn_create.num_buffs = p_cb->num_buff;
+    p_cback = p_cb->p_cback;
+    if (status == NCI_STATUS_OK) {
+      nfc_set_conn_id(p_cb, conn_id);
+#if (NXP_EXTNS == TRUE)
+      if (p_cb->id == 1) {
+        nfcc_dh_conn_id = conn_id;
+      }
+#endif
+    } else {
+      nfc_free_conn_cb(p_cb);
+    }
+
+    if (p_cback) (*p_cback)(conn_id, NFC_CONN_CREATE_CEVT, &evt_data);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_report_conn_close_evt
+**
+** Description      This function is called to report connection close event
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_report_conn_close_evt(uint8_t conn_id, tNFC_STATUS status) {
+  tNFC_CONN evt_data;
+  tNFC_CONN_CBACK* p_cback;
+  tNFC_CONN_CB* p_cb;
+
+  p_cb = nfc_find_conn_cb_by_conn_id(conn_id);
+  if (p_cb) {
+    p_cback = p_cb->p_cback;
+    nfc_free_conn_cb(p_cb);
+    evt_data.status = status;
+    if (p_cback) (*p_cback)(conn_id, NFC_CONN_CLOSE_CEVT, &evt_data);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_reset_rsp
+**
+** Description      This function is called to process reset
+**                  response/notification
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_proc_reset_rsp(uint8_t* p, bool is_ntf) {
+  uint8_t* temp = p, len;
+  uint8_t *p_len = p - 1;
+  uint8_t status = *p++;
+  bool wait_for_ntf = false;
+
+  if (is_ntf) {
+#if (NXP_EXTNS == TRUE)
+      if(nfcFL.nfccFL._NFCC_FORCE_NCI1_0_INIT) {
+          if (status == 0x02) {
+              NFC_TRACE_DEBUG2(
+                      "CORE_RESET_NTF 2 reason Command Received status nfc_state : 0x%x : "
+                      "0x%x",
+                      status, nfc_cb.nfc_state);
+              wait_for_ntf = false;
+              status = NCI_STATUS_OK;
+          } else if (status == 0x00) {
+              NFC_TRACE_DEBUG2(
+                      "CORE_RESET_NTF 2 reason Unrecoverable Error status nfc_state : 0x%x "
+                      ": 0x%x",
+                      status, nfc_cb.nfc_state);
+              core_reset_init_num_buff = true;
+              if(nfa_dm_is_active())
+                  nfc_ncif_cmd_timeout();
+          } else {
+              NFC_TRACE_DEBUG1("CORE_RESET_NTF 1 nfc_state :0x%x ", nfc_cb.nfc_state);
+              NFC_TRACE_DEBUG1("CORE_RESET_NTF 1 status :0x%x ", status);
+              core_reset_init_num_buff = true;
+              if(nfa_dm_is_active())
+                  nfc_ncif_cmd_timeout();
+          }
+      }
+      else {
+          NFC_TRACE_DEBUG1("reset notification nfc_state :0x%x ", nfc_cb.nfc_state);
+          NFC_TRACE_DEBUG1("reset notification!!:0x%x ", status);
+
+          if(status == NCI2_0_RESET_TRIGGER_TYPE_CORE_RESET_CMD_RECEIVED ||
+                  status == NCI2_0_RESET_TRIGGER_TYPE_POWERED_ON) {
+              NFC_TRACE_DEBUG2 ("CORE_RESET_NTF Received status nfc_state : 0x%x : 0x%x",
+                      status ,nfc_cb.nfc_state);
+              nfc_stop_timer(&nfc_cb.nci_wait_rsp_timer);
+              p++;
+              STREAM_TO_UINT8(nfc_cb.nci_version, p);
+              NFC_TRACE_ERROR1(" CORE_RESET_NTF nci_version%x", nfc_cb.nci_version);
+              status = NCI_STATUS_OK;
+          } else {
+              core_reset_init_num_buff = true;
+              /* CORE_RESET_NTF received error case , trigger recovery*/
+              NFC_TRACE_DEBUG2 ("CORE_RESET_NTF Received status nfc_state : 0x%x : 0x%x",
+                      status ,nfc_cb.nfc_state);
+              if(nfa_dm_is_active())
+                  nfc_ncif_cmd_timeout();
+              status = NCI_STATUS_FAILED;
+          }
+      }
+  } else {
+      if(nfcFL.nfccFL._NFCC_FORCE_NCI1_0_INIT) {
+          if ((*p_len) == NCI_CORE_RESET_RSP_LEN(NCI_VERSION_1_0)) {
+              nfc_cb.nci_version = NCI_VERSION_1_0;
+          }
+          NFC_TRACE_DEBUG1("CORE_RESET_RSP 2 nfc_state :0x%x ", nfc_cb.nfc_state);
+          len = *(--temp);  // extract the no of params in reset response
+          if (nfc_cb.flags & (NFC_FL_RESTARTING | NFC_FL_POWER_CYCLE_NFCC)) {
+              nfc_reset_all_conn_cbs();
+          }
+          if (len == 0x01)  // If response length is 01 means NCI2.0
+          {
+              wait_for_ntf = true;
+          }
+      }
+      else {
+
+          NFC_TRACE_DEBUG1 ("CORE_RESET_RSP len :0x%x ", *p_len);
+          if ((*p_len) == NCI_CORE_RESET_RSP_LEN(NCI_VERSION_2_0)) {
+              wait_for_ntf = true;
+          }
+          else if ((*p_len) == NCI_CORE_RESET_RSP_LEN(NCI_VERSION_1_0)) {
+              nfc_cb.nci_version = NCI_VERSION_1_0;
+          }
+
+          NFC_TRACE_DEBUG1("reset response nfc_state :0x%x ", nfc_cb.nfc_state);
+          if (nfc_cb.flags & (NFC_FL_RESTARTING | NFC_FL_POWER_CYCLE_NFCC)) {
+              nfc_reset_all_conn_cbs();
+          }
+#if 0
+          /*Check NCI version only in case of reset rsp*/
+          if (!is_ntf && status == NCI_STATUS_OK) {
+              if ((*p) != NCI_VERSION) {
+                  NFC_TRACE_ERROR2("NCI version mismatch!!:0x%02x != 0x%02x ",
+                          NCI_VERSION, *p);
+                  if ((*p) < NCI_VERSION_0_F) {
+                      NFC_TRACE_ERROR0("NFCC version is too old");
+                      status = NCI_STATUS_FAILED;
+                  }
+              }
+          }
+#endif
+      }
+  }
+#else
+    NFC_TRACE_ERROR1("reset notification!!:0x%x ", status);
+    /* clean up, if the state is OPEN
+     * FW does not report reset ntf right now */
+    if (nfc_cb.nfc_state == NFC_STATE_OPEN) {
+      /*if any conn_cb is connected, close it.
+        if any pending outgoing packets are dropped.*/
+      nfc_reset_all_conn_cbs();
+    }
+    status = NCI_STATUS_OK;
+  }
+
+  if (nfc_cb.flags & (NFC_FL_RESTARTING | NFC_FL_POWER_CYCLE_NFCC)) {
+    nfc_reset_all_conn_cbs();
+  }
+
+  if (status ==
+      NCI_STATUS_OK)  // Status of CORE_RESET_RESPONSE if not notification
+      {
+    if ((*p) != NCI_VERSION) {
+      NFC_TRACE_ERROR2("NCI version mismatch!!:0x%02x != 0x%02x ", NCI_VERSION,
+                       *p);
+      if ((*p) < NCI_VERSION_0_F) {
+        NFC_TRACE_ERROR0("NFCC version is too old");
+        status = NCI_STATUS_FAILED;
+      }
+    }
+  }
+#endif
+
+  if (status == NCI_STATUS_OK) {
+#if (NXP_EXTNS == TRUE)
+      if(nfcFL.nfccFL._NFCC_FORCE_NCI1_0_INIT) {
+          if (!wait_for_ntf) {
+              NFC_TRACE_DEBUG0("Got CORE_RESET_NTF 2 sending CORE_INIT_CMD 1");
+              nci_snd_core_init(NCI_VERSION_1_0);
+          } else {
+              NFC_TRACE_DEBUG0("Waiting for CORE_RESET_NTF 2 reason CMD received");
+              /* start NFC command-timeout timer */
+              nfc_start_timer(&nfc_cb.nci_wait_rsp_timer,
+                      (uint16_t)(NFC_TTYPE_NCI_WAIT_RSP),
+                      nfc_cb.nci_wait_rsp_tout);
+          }
+      }
+      else {
+          if(wait_for_ntf == true) {
+              /* reset version reported by NFCC is NCI2.0 , start a timer for 2000ms to
+               * wait for NTF*/
+              nfc_start_timer (&nfc_cb.nci_wait_rsp_timer, (uint16_t)(NFC_TTYPE_NCI_WAIT_RSP),
+                      nfc_cb.nci_wait_rsp_tout);
+          } else {
+              if(nfc_cb.nci_version == NCI_VERSION_1_0)
+                  nci_snd_core_init(NCI_VERSION_1_0);
+              else
+                  nci_snd_core_init(NCI_VERSION_2_0);
+          }
+      }
+    NFC_TRACE_ERROR0("reset notification sending core init");
+#else
+    nci_snd_core_init();
+#endif
+  } else {
+    if(!core_reset_init_num_buff)
+        {
+            if(!nfa_dm_is_active())
+            {
+                status = NCI_STATUS_NOT_INITIALIZED;
+                NFC_Disable();
+            }
+            NFC_TRACE_ERROR0 ("Failed to reset NFCC");
+            nfc_enabled (status, NULL);
+        }
+  }
+}
+
+#if (NXP_EXTNS == TRUE)
+uint8_t nfc_hal_nfcc_reset(void) {
+  nfc_nci_IoctlInOutData_t inpOutData;
+  /*NCI_RESET_CMD*/
+  uint8_t cmd_reset_nci[] = {0x20, 0x00, 0x01, 0x00};
+  uint8_t core_status = NCI_STATUS_FAILED;
+  uint8_t retry_count = 0;
+  NFC_TRACE_DEBUG0("Inside nfc_hal_nfcc_reset");
+
+  memset(&inpOutData, 0x00, sizeof(nfc_nci_IoctlInOutData_t));
+  inpOutData.inp.data.nciCmd.cmd_len = sizeof(cmd_reset_nci);
+  memcpy(inpOutData.inp.data.nciCmd.p_cmd, cmd_reset_nci,
+         sizeof(cmd_reset_nci));
+  do {
+    core_status =
+        nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_NCI_TRANSCEIVE, &inpOutData);
+    retry_count++;
+  } while (NCI_STATUS_OK != core_status &&
+           retry_count < (NFC_NFCC_INIT_MAX_RETRY + 1));
+  return core_status;
+}
+uint8_t nfc_hal_nfcc_init(uint8_t** pinit_rsp) {
+  nfc_nci_IoctlInOutData_t inpOutData;
+  /*NCI_INIT_CMD*/
+  uint8_t cmd_init_nci[] = {0x20, 0x01, 0x00};
+  uint8_t cmd_init_nci2_0[] = {0x20,0x01,0x02,0x00,0x00};
+  uint8_t init_status = NCI_STATUS_FAILED;
+  uint8_t retry_count = 0;
+  NFC_TRACE_DEBUG0("Inside nfc_hal_nfcc_init");
+  if (pinit_rsp == NULL) return init_status;
+
+  memset(&inpOutData, 0x00, sizeof(nfc_nci_IoctlInOutData_t));
+  if(nfc_cb.nci_version == NCI_VERSION_1_0)
+  {
+     inpOutData.inp.data.nciCmd.cmd_len = sizeof(cmd_init_nci);
+     memcpy(inpOutData.inp.data.nciCmd.p_cmd, cmd_init_nci, sizeof(cmd_init_nci));
+  }
+  else
+  {
+     inpOutData.inp.data.nciCmd.cmd_len = sizeof(cmd_init_nci2_0);
+     memcpy(inpOutData.inp.data.nciCmd.p_cmd, cmd_init_nci2_0, sizeof(cmd_init_nci2_0));
+  }
+  do {
+    init_status =
+        nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_NCI_TRANSCEIVE, &inpOutData);
+    retry_count++;
+  } while (NCI_STATUS_OK != init_status &&
+           retry_count < (NFC_NFCC_INIT_MAX_RETRY + 1));
+  if (init_status == NCI_STATUS_OK && inpOutData.out.data.nciRsp.rsp_len > 0) {
+    *pinit_rsp = GKI_getbuf(inpOutData.out.data.nciRsp.rsp_len);
+    if (NULL != *pinit_rsp)
+      memcpy(*pinit_rsp, inpOutData.out.data.nciRsp.p_rsp,
+             inpOutData.out.data.nciRsp.rsp_len);
+    else {
+      init_status = NCI_STATUS_FAILED;
+      NFC_TRACE_DEBUG0("nfc_hal_nfcc_init: Memory alocation failed");
+    }
+  }
+  return init_status;
+}
+#endif
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_init_rsp
+**
+** Description      This function is called to process init response
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_proc_init_rsp(NFC_HDR* p_msg) {
+  uint8_t* p, status;
+  tNFC_CONN_CB* p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+#if (NXP_EXTNS == TRUE)
+  nfc_nci_IoctlInOutData_t inpOutData;
+  static uint8_t retry_cnt = 0;
+  uint16_t fw_status, fw_dwnld_status = NCI_STATUS_FAILED,
+                      fw_mw_ver_status = NCI_STATUS_FAILED;
+  tNFC_FWUpdate_Info_t fw_update_inf;
+  uint8_t* init_rsp = NULL;
+  uint8_t config_resp[16];
+  int i;
+  memset(&fw_update_inf, 0x00, sizeof(tNFC_FWUpdate_Info_t));
+#endif
+  p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+  /* handle init params in nfc_enabled */
+  status = *(p + NCI_MSG_HDR_SIZE);
+#if (NXP_EXTNS == TRUE)
+  if (NCI_STATUS_OK == status) {
+    // MW_FW recovery disabling at time of sig/crash/die
+    NFC_TRACE_DEBUG1("MW_RCVRY_FW_DNLD_ALLOWED  -> %d",
+                     MW_RCVRY_FW_DNLD_ALLOWED);
+    if (((nfcFL.nfccFL._NFCC_MW_RCVRY_BLK_FW_DNLD) &&
+            ((NFC_STATE_CORE_INIT == nfc_cb.nfc_state) &&
+                    (MW_RCVRY_FW_DNLD_ALLOWED == false))) ||
+            ((!nfcFL.nfccFL._NFCC_MW_RCVRY_BLK_FW_DNLD) &&
+                    (nfcFL.nfccFL._NFCC_MW_RCVRY_BLK_FW_DNLD)))
+    {
+      nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_CHECK_FLASH_REQ, &inpOutData);
+      fw_update_inf = *(tNFC_FWUpdate_Info_t*)&inpOutData.out.data.fwUpdateInf;
+      NFC_TRACE_DEBUG1("fw_update required  -> %d",
+                       fw_update_inf.fw_update_reqd);
+
+      if (fw_update_inf.fw_update_reqd == true) {
+          if(nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH) {
+              uicc_eeprom_get_config(config_resp);
+          }
+        nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_FW_DWNLD, &inpOutData);
+        fw_dwnld_status = inpOutData.out.data.fwDwnldStatus;
+        status = nfc_hal_nfcc_reset();
+        if (NCI_STATUS_OK == status) {
+          status = nfc_hal_nfcc_init(&init_rsp);
+          if (NCI_STATUS_OK == status) {
+            /* Initialize NFC_HDR */
+            p_msg->len = init_rsp[2] + 3;
+            /* copying init rsp to p_msg  */
+            memcpy((uint8_t*)(p_msg + 1) + p_msg->offset, init_rsp, p_msg->len);
+          }
+          if (init_rsp)
+              GKI_freebuf(init_rsp);
+        }
+      }
+    }
+  }
+  if(nfc_cb.nci_version != NCI_VERSION_2_0)
+  {
+      fw_status = nfc_ncif_store_FWVersion(p);
+  }
+  else
+  fw_status = NCI_STATUS_OK;
+
+  if((nfcFL.chipType != pn547C2) && nfcFL.nfcMwFL._NFC_NXP_AID_MAX_SIZE_DYN) {
+      nfc_ncif_set_MaxRoutingTableSize(p);
+  }
+  nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_FW_MW_VER_CHECK, &inpOutData);
+  fw_mw_ver_status = inpOutData.out.data.fwMwVerStatus;
+#endif
+
+  /* TODO To be removed after 553 bringup */
+  fw_mw_ver_status = NCI_STATUS_OK;
+  if (status == NCI_STATUS_OK
+#if (NXP_EXTNS == TRUE)
+      && fw_status == NCI_STATUS_OK && NCI_STATUS_OK == fw_mw_ver_status
+#endif
+      ) {
+#if (NXP_EXTNS == TRUE)
+      if (fw_dwnld_status == NCI_STATUS_OK) {
+          if(nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH) {
+              uicc_eeprom_set_config(config_resp);
+          }
+    }
+#endif
+#if (NXP_EXTNS == TRUE)
+    retry_cnt = 0;
+#endif
+    if(nfc_cb.nci_version == NCI_VERSION_UNKNOWN) {
+      nci_snd_core_reset(NCI_RESET_TYPE_RESET_CFG);
+    } else {
+      p_cb->id = NFC_RF_CONN_ID;
+      p_cb->act_protocol = NCI_PROTOCOL_UNKNOWN;
+      nfc_set_state(NFC_STATE_W4_POST_INIT_CPLT);
+
+      nfc_cb.p_nci_init_rsp = p_msg;
+      nfc_cb.p_hal->core_initialized(p_msg->len - p_msg->offset, p);
+    }
+  }
+#if (NXP_EXTNS == TRUE)
+  /*Recovery is added in case of corrupted init rsp is received
+   * eg: 400119 - only 3 bytes are received. In this case since the
+   * rsp buffer[3] is status and the value is 0x00 because of memset for the rsp
+   * buffer
+   * was done before copying the init response.
+   * Hence FW version check is added to do check the proper status and go for a
+   * recovery*/
+  else if (retry_cnt++ < NFC_NFCC_INIT_MAX_RETRY &&
+           fw_status != NCI_STATUS_OK && NCI_STATUS_OK == fw_mw_ver_status) {
+    GKI_send_event(NFC_TASK, NFC_TASK_EVT_TRANSPORT_READY);
+    GKI_freebuf(p_msg);
+  }
+#endif
+  else {
+#if (NXP_EXTNS == TRUE)
+    status = NCI_STATUS_FAILED;
+    retry_cnt = 0;
+    if(nfc_cb.nci_version == NCI_VERSION_UNKNOWN) {
+      nfc_cb.nci_version = NCI_VERSION_1_0;
+      nci_snd_core_reset(NCI_RESET_TYPE_RESET_CFG);
+    } else {
+      nfc_enabled(status, NULL);
+      GKI_freebuf(p_msg);
+    }
+#else
+    nfc_enabled(status, NULL);
+    GKI_freebuf(p_msg);
+#endif
+  }
+}
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         nfc_ncif_store_FWVersion
+**
+** Description      This function is called to fill the structure with FW
+*Version
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS nfc_ncif_store_FWVersion(uint8_t* p_buf) {
+  uint8_t status = NFC_STATUS_OK;
+  int len = p_buf[2] + 2; /*include 2 byte header*/
+  memset(&nfc_fw_version, 0, sizeof(nfc_fw_version));
+  nfc_fw_version.rom_code_version = p_buf[len - 2];
+  nfc_fw_version.major_version = p_buf[len - 1];
+  nfc_fw_version.minor_version = p_buf[len];
+  if (nfc_fw_version.rom_code_version == 0 ||
+      nfc_fw_version.major_version == 0) {
+    status = NFC_STATUS_FAILED;
+  }
+  NFC_TRACE_DEBUG3("FW Version: %x.%x.%x", nfc_fw_version.rom_code_version,
+                   nfc_fw_version.major_version, nfc_fw_version.minor_version);
+  return status;
+}
+/*******************************************************************************
+**
+** Function         nfc_ncif_set_MaxRoutingTableSize
+**
+** Description      This function is called to get the Max Routing Table Size
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS nfc_ncif_set_MaxRoutingTableSize(uint8_t* p_buf) {
+    NFC_TRACE_DEBUG0("nfc_ncif_set_MaxRoutingTableSize Enter");
+
+    if(!((nfcFL.chipType != pn547C2) && nfcFL.nfcMwFL._NFC_NXP_AID_MAX_SIZE_DYN)) {
+        NFC_TRACE_DEBUG0("chipType : pn547C2 or NFC_NXP_AID_MAX_SIZE_DYN"
+                " not available.. Returning");
+        return NFC_STATUS_FAILED;
+
+    }
+  uint8_t status = NFC_STATUS_OK;
+  int len = p_buf[2] + 2; /*include 2 byte header*/
+  maxRoutingTableSize = p_buf[len - 8];
+  maxRoutingTableSize = maxRoutingTableSize << 8 | p_buf[len - 9];
+  NFC_TRACE_DEBUG1("MAX Routing size : %d", maxRoutingTableSize);
+  if (maxRoutingTableSize == 0) {
+    status = NFC_STATUS_FAILED;
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFC_getMaxRoutingTableSize
+**
+** Description      This function is called to get the Max routing Table size
+**
+** Returns          uint16_t
+**
+*******************************************************************************/
+uint16_t nfc_ncif_getMaxRoutingTableSize() {
+    if(!((nfcFL.chipType != pn547C2) && nfcFL.nfcMwFL._NFC_NXP_AID_MAX_SIZE_DYN)) {
+        NFC_TRACE_DEBUG0("getMaxRoutingTableSize : chipType : pn547C2 or "
+                "NFC_NXP_AID_MAX_SIZE_DYN not available.. Returning");
+        return 0;
+
+    }
+    return maxRoutingTableSize;
+}
+/*******************************************************************************
+**
+** Function         nfc_ncif_getFWVersion
+**
+** Description      This function is called to fet the FW Version
+**
+** Returns          tNFC_FW_VERSION
+**
+*******************************************************************************/
+tNFC_FW_VERSION nfc_ncif_getFWVersion() { return nfc_fw_version; }
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_storeScreenState
+**
+** Description      This function is called to store the last screen state
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_storeScreenState(uint8_t state) {
+  /* store the screen state */
+  gScreenState = state;
+  NFC_TRACE_DEBUG1("nfc_ncif_storeScreenState gScreenState : %d", gScreenState);
+}
+#endif
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_get_config_rsp
+**
+** Description      This function is called to process get config response
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_proc_get_config_rsp(NFC_HDR* p_evt) {
+  uint8_t* p;
+  tNFC_RESPONSE_CBACK* p_cback = nfc_cb.p_resp_cback;
+  tNFC_RESPONSE evt_data;
+
+  p_evt->offset += NCI_MSG_HDR_SIZE;
+  p_evt->len -= NCI_MSG_HDR_SIZE;
+  if (p_cback) {
+    p = (uint8_t*)(p_evt + 1) + p_evt->offset;
+    evt_data.get_config.status = *p++;
+    evt_data.get_config.tlv_size = p_evt->len;
+    evt_data.get_config.p_param_tlvs = p;
+    (*p_cback)(NFC_GET_CONFIG_REVT, &evt_data);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_t3t_polling_ntf
+**
+** Description      Handle NCI_MSG_RF_T3T_POLLING NTF
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_proc_t3t_polling_ntf(uint8_t* p, uint16_t plen) {
+  uint8_t status;
+  uint8_t num_responses;
+
+  /* Pass result to RW_T3T for processing */
+  STREAM_TO_UINT8(status, p);
+  STREAM_TO_UINT8(num_responses, p);
+  plen -= NFC_TL_SIZE;
+  rw_t3t_handle_nci_poll_ntf(status, num_responses, (uint8_t)plen, p);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_data_event
+**
+** Description      Report Data event on the given connection control block
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_data_event(tNFC_CONN_CB* p_cb) {
+  NFC_HDR* p_evt;
+  tNFC_DATA_CEVT data_cevt;
+
+  uint8_t* p;
+
+  if (p_cb->p_cback) {
+    while ((p_evt = (NFC_HDR*)GKI_getfirst(&p_cb->rx_q)) != NULL) {
+      if (p_evt->layer_specific & NFC_RAS_FRAGMENTED) {
+        /* Not the last fragment */
+        if (!(p_evt->layer_specific & NFC_RAS_TOO_BIG)) {
+          /* buffer can hold more */
+          if ((p_cb->conn_id != NFC_RF_CONN_ID) || (nfc_cb.reassembly)) {
+            /* If not rf connection or If rf connection and reassembly
+             * requested,
+             * try to Reassemble next packet */
+            break;
+          }
+        }
+      }
+
+      p_evt = (NFC_HDR*)GKI_dequeue(&p_cb->rx_q);
+
+      if (p_evt == NULL) {
+        break;
+      }
+      /* report data event */
+      p_evt->offset += NCI_MSG_HDR_SIZE;
+      p_evt->len -= NCI_MSG_HDR_SIZE;
+
+      if (p_evt->layer_specific)
+        data_cevt.status = NFC_STATUS_CONTINUE;
+      else {
+        nfc_cb.reassembly = true;
+        data_cevt.status = NFC_STATUS_OK;
+      }
+
+      data_cevt.p_data = p_evt;
+      /* adjust payload, if needed */
+      if (p_cb->conn_id == NFC_RF_CONN_ID) {
+        /* if NCI_PROTOCOL_T1T/NCI_PROTOCOL_T2T/NCI_PROTOCOL_T3T, the status
+         * byte needs to be removed
+         */
+        if ((p_cb->act_protocol >= NCI_PROTOCOL_T1T) &&
+            (p_cb->act_protocol <= NCI_PROTOCOL_T3T)) {
+#if (NXP_EXTNS == TRUE)
+          if ((p_cb->act_protocol == NCI_PROTOCOL_T2T) &&
+              (p_cb->act_interface == NCI_INTERFACE_FIRST_VS) &&
+              (p_cb->sel_res == 0x01)) {
+            NFC_TRACE_ERROR0("Skylander tag detected dont handle this");
+          } else
+#endif
+          {
+              p_evt->len--;
+              p = (uint8_t*)(p_evt + 1);
+              data_cevt.status = *(p + p_evt->offset + p_evt->len);
+              if((NFC_GetNCIVersion() == NCI_VERSION_2_0) &&
+                  (p_cb->act_protocol == NCI_PROTOCOL_T2T) &&
+                  (p_cb->act_interface == NCI_INTERFACE_FRAME)) {
+             if((data_cevt.status != NFC_STATUS_OK) &&
+                     ((data_cevt.status >= T2T_STATUS_OK_1_BIT)&&(data_cevt.status <= T2T_STATUS_OK_7_BIT)))
+             {
+                 NFC_TRACE_DEBUG0("nfc_data_event: T2T tag data xchange");
+                 data_cevt.status = NFC_STATUS_OK;
+             }
+              }
+          }
+        }
+        if((NFC_GetNCIVersion() == NCI_VERSION_2_0)&&(p_cb->act_protocol == NCI_PROTOCOL_15693))
+        {
+          p_evt->len--;
+          p = (uint8_t*)(p_evt + 1);
+          data_cevt.status = *(p + p_evt->offset + p_evt->len);
+        }
+      }
+#if(NXP_EXTNS == TRUE)
+        if(p_cb->act_protocol == NCI_PROTOCOL_15693)
+        {
+            p_evt->len--;
+            p = (uint8_t *) (p_evt + 1);
+            data_cevt.status = *(p + p_evt->offset + p_evt->len);
+        }
+#endif
+      (*p_cb->p_cback)(p_cb->conn_id, NFC_DATA_CEVT, (void*)&data_cevt);
+      p_evt = NULL;
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_data
+**
+** Description      Find the connection control block associated with the data
+**                  packet. Assemble the data packet, if needed.
+**                  Report the Data event.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_proc_data(NFC_HDR* p_msg) {
+  uint8_t* pp, cid;
+  tNFC_CONN_CB* p_cb;
+  uint8_t pbf;
+  NFC_HDR* p_last;
+  uint8_t* ps, *pd;
+  uint16_t size;
+  NFC_HDR* p_max = NULL;
+  uint16_t len;
+
+  pp = (uint8_t*)(p_msg + 1) + p_msg->offset;
+  NFC_TRACE_DEBUG3("nfc_ncif_proc_data 0x%02x%02x%02x", pp[0], pp[1], pp[2]);
+  NCI_DATA_PRS_HDR(pp, pbf, cid, len);
+  p_cb = nfc_find_conn_cb_by_conn_id(cid);
+#if (NXP_EXTNS == TRUE)
+  if ((nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME ==
+          nfcFL.eseFL._ESE_WIRED_MODE_RESUME) &&
+          ((p_cb) && (cid == NFC_RF_CONN_ID) && (nfc_cb.bBlockWiredMode))) {
+    nfc_ncif_resume_dwp_wired_mode();
+  }
+#endif
+  if (p_cb && (p_msg->len >= NCI_DATA_HDR_SIZE)) {
+    NFC_TRACE_DEBUG1("nfc_ncif_proc_data len:%d", len);
+
+    p_msg->layer_specific = 0;
+    if (pbf) {
+#if (NXP_EXTNS == TRUE)
+      NFC_TRACE_DEBUG0(
+          "nfc_ncif_proc_data requesting reassembly for chained data");
+      nfc_cb.reassembly = true;
+#endif
+      p_msg->layer_specific = NFC_RAS_FRAGMENTED;
+    }
+    p_last = (NFC_HDR*)GKI_getlast(&p_cb->rx_q);
+    if (p_last && (p_last->layer_specific & NFC_RAS_FRAGMENTED)) {
+      /* last data buffer is not last fragment, append this new packet to the
+       * last */
+      size = GKI_get_buf_size(p_last);
+      if (size < (NFC_HDR_SIZE + p_last->len + p_last->offset + len)) {
+        /* the current size of p_last is not big enough to hold the new
+         * fragment, p_msg */
+        if (size != GKI_MAX_BUF_SIZE) {
+          /* try the biggest GKI pool */
+          p_max = (NFC_HDR*)GKI_getpoolbuf(GKI_MAX_BUF_SIZE_POOL_ID);
+          if (p_max) {
+            /* copy the content of last buffer to the new buffer */
+            memcpy(p_max, p_last, NFC_HDR_SIZE);
+            pd = (uint8_t*)(p_max + 1) + p_max->offset;
+            ps = (uint8_t*)(p_last + 1) + p_last->offset;
+            memcpy(pd, ps, p_last->len);
+
+            /* place the new buffer in the queue instead */
+            GKI_remove_from_queue(&p_cb->rx_q, p_last);
+            GKI_freebuf(p_last);
+            GKI_enqueue(&p_cb->rx_q, p_max);
+            p_last = p_max;
+          }
+        }
+        if (p_max == NULL) {
+          /* Biggest GKI Pool not available (or)
+           * Biggest available GKI Pool is not big enough to hold the new
+           * fragment, p_msg */
+          p_last->layer_specific |= NFC_RAS_TOO_BIG;
+        }
+      }
+
+      ps = (uint8_t*)(p_msg + 1) + p_msg->offset + NCI_MSG_HDR_SIZE;
+      len = p_msg->len - NCI_MSG_HDR_SIZE;
+
+      if (!(p_last->layer_specific & NFC_RAS_TOO_BIG)) {
+        pd = (uint8_t*)(p_last + 1) + p_last->offset + p_last->len;
+        memcpy(pd, ps, len);
+        p_last->len += len;
+        /* do not need to update pbf and len in NCI header.
+         * They are stripped off at NFC_DATA_CEVT and len may exceed 255 */
+        NFC_TRACE_DEBUG1("nfc_ncif_proc_data len:%d", p_last->len);
+        p_last->layer_specific = p_msg->layer_specific;
+        GKI_freebuf(p_msg);
+#ifdef DISP_NCI
+        if (!(p_last->layer_specific & NFC_RAS_FRAGMENTED)) {
+          /* this packet was reassembled. display the complete packet */
+          DISP_NCI((uint8_t*)(p_last + 1) + p_last->offset, p_last->len, true);
+        }
+#endif
+        nfc_data_event(p_cb);
+      } else {
+        /* Not enough memory to add new buffer
+         * Send data already in queue first with status Continue */
+        nfc_data_event(p_cb);
+        /* now enqueue the new buffer to the rx queue */
+        GKI_enqueue(&p_cb->rx_q, p_msg);
+      }
+    } else {
+      /* if this is the first fragment on RF link */
+      if ((p_msg->layer_specific & NFC_RAS_FRAGMENTED) &&
+          (p_cb->conn_id == NFC_RF_CONN_ID) && (p_cb->p_cback)) {
+        /* Indicate upper layer that local device started receiving data */
+        (*p_cb->p_cback)(p_cb->conn_id, NFC_DATA_START_CEVT, NULL);
+      }
+      /* enqueue the new buffer to the rx queue */
+      GKI_enqueue(&p_cb->rx_q, p_msg);
+      nfc_data_event(p_cb);
+    }
+    return;
+  }
+  GKI_freebuf(p_msg);
+}
+/*******************************************************************************
+**
+** Function         nfc_modeset_ntf_timeout
+**
+** Description      This function is invoked on mode set ntf timeout
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_modeset_ntf_timeout()
+{
+  NFC_TRACE_ERROR0("nfc_ncif_modeSet_Ntf_timeout");
+  tNFC_NFCEE_MODE_SET_REVT    mode_set_info;
+  tNFC_RESPONSE_CBACK  *p_cback = nfc_cb.p_resp_cback;
+  tNFC_NFCEE_INFO_REVT nfcee_info;
+  nfc_cb.flags  &= ~NFC_FL_WAIT_MODE_SET_NTF;
+  tNFC_RESPONSE_EVT event    = NFC_NFCEE_MODE_SET_REVT;
+  mode_set_info.status        = NCI_STATUS_FAILED;
+
+  tNFC_RESPONSE* p_evt = (tNFC_RESPONSE*)&nfcee_info;
+  p_evt = (tNFC_RESPONSE*)&mode_set_info;
+
+    if (p_cback)
+        (*p_cback) (event, p_evt);
+}
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         nfc_ncif_credit_ntf_timeout
+**
+** Description      Handle a credit ntf  timeout
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_credit_ntf_timeout() {
+  NFC_TRACE_DEBUG0("nfc_ncif_credit_ntf_timeout : Enter");
+
+#if (NXP_EXTNS == TRUE)
+  tNFC_CONN_CB* p_cb;
+#endif
+  if (get_i2c_fragmentation_enabled() == I2C_FRAGMENATATION_ENABLED) {
+    nfc_cb.i2c_data_t.data_ntf_timeout = 1;
+  } else {
+    // No need to wait for response since credit ntf timeout calls recovery
+    // Stop the response timer
+    nfa_sys_stop_timer(&nfa_hci_cb.timer);
+
+    // send timeout event to upper layer
+    nfa_hci_rsp_timeout(NULL);
+
+    // will be used to reset credit buffer after recovery
+    core_reset_init_num_buff = true;
+#if (NXP_EXTNS == TRUE)
+    p_cb = nfc_find_conn_cb_by_conn_id(NFC_NFCEE_CONN_ID);
+    if (p_cb && (p_cb->num_buff != NFC_CONN_NO_FC) && (p_cb->num_buff == 0))
+      p_cb->num_buff++;
+
+    p_cb = nfc_find_conn_cb_by_conn_id(NFC_RF_CONN_ID);
+    if (p_cb && (p_cb->num_buff != NFC_CONN_NO_FC) && (p_cb->num_buff == 0))
+      p_cb->num_buff++;
+#endif
+  }
+
+  if (get_i2c_fragmentation_enabled() == I2C_FRAGMENATATION_ENABLED) {
+    // nfc_cb.nfc_state = NFC_STATE_RECOVERY;
+    NFC_TRACE_DEBUG0("nfc_ncif_credit_ntf_timeout :decrementing window");
+    // TODO: Write logic for VEN_RESET.
+    nfc_cb.p_hal->power_cycle();
+    // Remove the pending cmds from the cmd queue. send any pending rsp/cback to
+    // jni
+    nfc_ncif_empty_cmd_queue();
+    // Cancel any ongoing data transfer.
+    /**
+     * send core reset - keep config
+     * send core init
+     * send discovery
+     * */
+
+    // Update the cmd window, since rsp has not came.
+    // nfc_ncif_update_window ();
+    nfc_ncif_empty_data_queue();
+    if (nfc_cb.i2c_data_t.data_ntf_timeout) {
+      nfc_cb.i2c_data_t.data_ntf_timeout = 0;
+    }
+  }
+  NFC_TRACE_ERROR0("cmd timeout sending core reset!!!");
+  nfc_ncif_cmd_timeout();
+  // nci_snd_core_reset(0x00);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_process_proprietary_rsp
+**
+** Description      Process the response to avoid collision
+**                  while nxpCbflag is set
+**
+** Returns          true if proprietary response else false
+**
+*******************************************************************************/
+
+bool nfc_ncif_proc_proprietary_rsp(uint8_t mt, uint8_t gid, uint8_t oid) {
+  bool stat = false;
+  NFC_TRACE_DEBUG3("nfc_ncif_proc_proprietary_rsp: mt=%u, gid=%u, oid=%u", mt,
+                   gid, oid);
+  switch (mt) {
+    case NCI_MT_DATA:
+      switch (gid) {
+        case 0x03:
+          switch (oid) {
+            case 0x00: /*Data Response*/
+              stat = false;
+              break;
+
+            default:
+              stat = true;
+              break;
+          }
+          break;
+
+        default:
+          stat = true;
+          break;
+      }
+      break;
+
+    case NCI_MT_NTF:
+      switch (gid) {
+        case NCI_GID_CORE:
+          switch (oid) {
+            case 0x00: /*CORE_RESET_NTF*/
+            case 0x06: /*CORE_CONN_CREDITS_NTF*/
+              stat = false;
+              break;
+
+            default:
+              stat = true;
+              break;
+          }
+          break;
+        case NCI_GID_RF_MANAGE:
+          switch (oid) {
+            case 0x06: /*CORE_CONN_CREDITS_NTF*/
+              stat = false;
+              break;
+            case 0x09:
+              stat = false; /*NFA_EE_ACTION_NTF*/
+              break;
+            case 0x0A: /*NFA_EE_DISCOVERY_REQ_NTF*/
+              stat = false;
+              break;
+            default:
+              stat = true;
+              break;
+          }
+          break;
+        case NCI_GID_EE_MANAGE:
+          switch (oid) {
+            case 0x00:
+            case 0x01:
+            /*FALL_THRU: NFCEE_MODE_SET_NTF*/
+              stat = false;
+              break;
+            default:
+              stat = true;
+              break;
+          }
+          break;
+        default:
+          stat = true;
+          break;
+      }
+      break;
+
+    default:
+      stat = true;
+      break;
+  }
+  NFC_TRACE_DEBUG1("nfc_ncif_proc_proprietary_rsp: exit status=%u", stat);
+  return stat;
+}
+
+#endif
+
+#if (NXP_EXTNS == TRUE)
+void disc_deact_ntf_timeout_handler(tNFC_RESPONSE_EVT event) {
+    if(!(nfcFL.nfcNxpEse && nfcFL.eseFL._ESE_ETSI_READER_ENABLE)) {
+        NFC_TRACE_DEBUG0("disc_deact_ntf_timeout_handler : nfcNxpEse or "
+                "ETSI_READER_ENABLE not available. Returning..");
+        return;
+    }
+    tNFC_RESPONSE evt_data;
+    etsi_reader_in_progress = false;
+    if (nfc_cb.p_resp_cback) {
+        evt_data.status = (tNFC_STATUS)NFC_STATUS_HW_TIMEOUT;
+        (*nfc_cb.p_resp_cback)(event, &evt_data);
+    }
+}
+#endif
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function:        nfc_ncif_reset_nfcc
+**
+** Description:     Reset the NFCC
+**
+** Returns:         NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFC_STATUS nfc_ncif_reset_nfcc() {
+  NFC_TRACE_DEBUG1("%s : Enter", __func__);
+  if(!nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH) {
+      NFC_TRACE_DEBUG0("NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH"
+              " feature is not available!!");
+      return (NFA_STATUS_FAILED);
+  }
+  nfc_nci_IoctlInOutData_t inpOutData;
+  uint8_t status = NCI_STATUS_FAILED;
+  int isfound, retry_count = 0;
+  long retlen = 0;
+  uint8_t* buffer = NULL;
+  long bufflen = 256;
+
+  /*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
+  /*NXP_ACT_PROP_EXTN*/
+  static uint8_t cmd_act_prop_extn[] = {0x2F, 0x02, 0x00};
+  /*NXP_CORE_STANDBY*/
+  static uint8_t cmd_core_standby[] = {0x2F, 0x00, 0x01, 0x01};
+
+  /*Nfcc power cycle*/
+  nfc_cb.p_hal->power_cycle();
+
+  /*Transceive NCI_INIT_CMD*/
+  memset(&inpOutData, 0x00, sizeof(nfc_nci_IoctlInOutData_t));
+  inpOutData.inp.data.nciCmd.cmd_len = sizeof(cmd_reset_nci);
+  memcpy(inpOutData.inp.data.nciCmd.p_cmd, cmd_reset_nci,
+         sizeof(cmd_reset_nci));
+
+  do {
+    status = nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_NCI_TRANSCEIVE, &inpOutData);
+    retry_count++;
+  } while ((status != NCI_STATUS_OK) && (retry_count <= 3));
+  if (status != NCI_STATUS_OK) goto TheEndReset;
+
+  /*Transceive NCI_RESET_CMD*/
+  retry_count = 0;
+  memset(&inpOutData, 0x00, sizeof(nfc_nci_IoctlInOutData_t));
+  inpOutData.inp.data.nciCmd.cmd_len = sizeof(cmd_init_nci);
+  memcpy(inpOutData.inp.data.nciCmd.p_cmd, cmd_init_nci, sizeof(cmd_init_nci));
+  do {
+    status = nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_NCI_TRANSCEIVE, &inpOutData);
+    retry_count++;
+  } while ((status != NCI_STATUS_OK) && (retry_count <= 3));
+  if (status != NCI_STATUS_OK) goto TheEndReset;
+
+  /*Transceive NXP_ACT_PROP_EXTN*/
+  retry_count = 0;
+  retlen = 0;
+  memset(&inpOutData, 0x00, sizeof(nfc_nci_IoctlInOutData_t));
+  inpOutData.inp.data.nciCmd.cmd_len = sizeof(cmd_act_prop_extn);
+  memcpy(inpOutData.inp.data.nciCmd.p_cmd, cmd_act_prop_extn,
+         sizeof(cmd_act_prop_extn));
+
+  do {
+    status = nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_NCI_TRANSCEIVE, &inpOutData);
+    retry_count++;
+  } while ((status != NCI_STATUS_OK) && (retry_count <= 3));
+  if (status != NCI_STATUS_OK) goto TheEndReset;
+
+  /*Transceive NXP_CORE_STANDBY*/
+  retry_count = 0;
+  memset(&inpOutData, 0x00, sizeof(nfc_nci_IoctlInOutData_t));
+  inpOutData.inp.data.nciCmd.cmd_len = sizeof(cmd_core_standby);
+  memcpy(inpOutData.inp.data.nciCmd.p_cmd, cmd_core_standby,
+         sizeof(cmd_core_standby));
+
+  do {
+    status = nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_NCI_TRANSCEIVE, &inpOutData);
+    retry_count++;
+  } while ((status != NCI_STATUS_OK) && (retry_count <= 3));
+TheEndReset:
+  NFC_TRACE_DEBUG1("%s : Exit", __func__);
+  return status;
+}
+/*******************************************************************************
+**
+** Function         uicc_eeprom_get_config
+**
+** Description      get UICC configuration from EEPROM
+**
+** Returns          None
+**
+*******************************************************************************/
+void uicc_eeprom_get_config(uint8_t* config_resp) {
+  NFC_TRACE_DEBUG1("%s : Enter", __func__);
+  if(!nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH) {
+      NFC_TRACE_DEBUG0("NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH"
+              " feature is not available!!");
+      return;
+  }
+  uint8_t cmd_get_dualUicc_config[] = {0x20, 0x03, 0x03, 0x01, 0xA0, 0xEC};
+  nfc_nci_IoctlInOutData_t inpOutData;
+  int uicc_mode = 0;
+  uint8_t* config_rsp = NULL;
+  uint8_t config_status = NCI_STATUS_FAILED;
+  uint8_t retry_count = 0;
+
+  if (GetNumValue(NAME_NXP_DUAL_UICC_ENABLE, &uicc_mode,
+          sizeof(int))) {
+    NFC_TRACE_DEBUG1("NXP_DUAL_UICC_ENABLE : 0x%02x", uicc_mode);
+
+  } else {
+    uicc_mode = 0x00;
+    NFC_TRACE_DEBUG1(
+        "NXP_DUAL_UICC_ENABLE not found; taking default value : 0x%02x",
+        uicc_mode);
+  }
+  memset(&inpOutData, 0x00, sizeof(nfc_nci_IoctlInOutData_t));
+  inpOutData.inp.data.nciCmd.cmd_len = sizeof(cmd_get_dualUicc_config);
+  memcpy(inpOutData.inp.data.nciCmd.p_cmd, cmd_get_dualUicc_config,
+         sizeof(cmd_get_dualUicc_config));
+  do {
+    config_status =
+        nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_NCI_TRANSCEIVE, &inpOutData);
+    retry_count++;
+  } while ((config_status != NCI_STATUS_OK) && (retry_count <= 3));
+  if (config_status == NCI_STATUS_OK &&
+      inpOutData.out.data.nciRsp.rsp_len > 0) {
+    memcpy(config_resp, inpOutData.out.data.nciRsp.p_rsp, inpOutData.out.data.nciRsp.rsp_len);
+  } else {
+    NFC_TRACE_DEBUG1("%s :HAL_NFC_IOCTL_NCI_TRANSCEIVE Failed", __func__);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         uicc_eeprom_set_config
+**
+** Description      set UICC configuration in EEPROM
+**
+** Returns         No Data
+**
+*******************************************************************************/
+void uicc_eeprom_set_config(uint8_t* config_rsp) {
+  NFC_TRACE_DEBUG1("%s : Enter", __func__);
+  if(!nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH) {
+      NFC_TRACE_DEBUG0("NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH"
+              " feature is not available!!");
+      return;
+  }
+  uint8_t cmd_set_dualUicc_config[] = {0x20, 0x02, 0x05, 0x01,
+                                       0xA0, 0xEC, 0x01, 0x11};
+  nfc_nci_IoctlInOutData_t inpOutData;
+  int uicc_mode = 0;
+  uint8_t config_status = NCI_STATUS_FAILED;
+  uint8_t retry_count = 0;
+
+  if (GetNumValue(NAME_NXP_DUAL_UICC_ENABLE, &uicc_mode,
+          sizeof(int))) {
+    NFC_TRACE_DEBUG1("NXP_DUAL_UICC_ENABLE : 0x%02x", uicc_mode);
+
+  } else {
+    uicc_mode = 0x00;
+    NFC_TRACE_DEBUG1(
+        "NXP_DUAL_UICC_ENABLE not found; taking default value : 0x%02x",
+        uicc_mode);
+  }
+  memset(&inpOutData, 0x00, sizeof(nfc_nci_IoctlInOutData_t));
+
+  if (uicc_mode == 0x00) {
+    cmd_set_dualUicc_config[7] = 0x01;
+  } else if (config_rsp != NULL) {
+    cmd_set_dualUicc_config[7] = config_rsp[8];
+  }
+
+  inpOutData.inp.data.nciCmd.cmd_len = sizeof(cmd_set_dualUicc_config);
+  memcpy(inpOutData.inp.data.nciCmd.p_cmd, cmd_set_dualUicc_config,
+         sizeof(cmd_set_dualUicc_config));
+  do {
+    config_status =
+        nfc_cb.p_hal->ioctl(HAL_NFC_IOCTL_NCI_TRANSCEIVE, &inpOutData);
+    retry_count++;
+  } while ((config_status != NCI_STATUS_OK) && (retry_count <= 3));
+  if ((config_status != NCI_STATUS_OK) && (retry_count = 4)) {
+    NFC_TRACE_DEBUG1("%s :HAL_NFC_IOCTL_NCI_TRANSCEIVE Failed", __func__);
+  }
+}
+#endif
diff --git a/src/nfc/nfc/nfc_task.c b/src/nfc/nfc/nfc_task.c
new file mode 100644
index 0000000..e445bc8
--- /dev/null
+++ b/src/nfc/nfc/nfc_task.c
@@ -0,0 +1,500 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Entry point for NFC_TASK
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "gki.h"
+#include "nfc_target.h"
+#include "bt_types.h"
+
+#include "nfc_api.h"
+#include "nfc_hal_api.h"
+#include "nfc_int.h"
+#include "nci_hmsgs.h"
+#include "rw_int.h"
+#include "ce_int.h"
+#if (NFC_RW_ONLY == FALSE)
+#include "llcp_int.h"
+#else
+#define llcp_cleanup()
+#endif
+
+#include "nfa_sys.h"
+#include "nfa_dm_int.h"
+
+/*******************************************************************************
+**
+** Function         nfc_start_timer
+**
+** Description      Start a timer for the specified amount of time.
+**                  NOTE: The timeout resolution is in SECONDS! (Even
+**                          though the timer structure field is ticks)
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_start_timer(TIMER_LIST_ENT* p_tle, uint16_t type, uint32_t timeout) {
+  NFC_HDR* p_msg;
+
+  /* if timer list is currently empty, start periodic GKI timer */
+  if (nfc_cb.timer_queue.p_first == NULL) {
+    /* if timer starts on other than NFC task (scritp wrapper) */
+    if (GKI_get_taskid() != NFC_TASK) {
+      /* post event to start timer in NFC task */
+      p_msg = (NFC_HDR*)GKI_getbuf(NFC_HDR_SIZE);
+      if (p_msg != NULL) {
+        p_msg->event = BT_EVT_TO_START_TIMER;
+        GKI_send_msg(NFC_TASK, NFC_MBOX_ID, p_msg);
+      }
+    } else {
+      /* Start nfc_task 1-sec resolution timer */
+      GKI_start_timer(NFC_TIMER_ID, GKI_SECS_TO_TICKS(1), true);
+    }
+  }
+
+  GKI_remove_from_timer_list(&nfc_cb.timer_queue, p_tle);
+
+  p_tle->event = type;
+  p_tle->ticks = timeout; /* Save the number of seconds for the timer */
+
+  GKI_add_to_timer_list(&nfc_cb.timer_queue, p_tle);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_remaining_time
+**
+** Description      Return amount of time to expire
+**
+** Returns          time in second
+**
+*******************************************************************************/
+uint32_t nfc_remaining_time(TIMER_LIST_ENT* p_tle) {
+  return (GKI_get_remaining_ticks(&nfc_cb.timer_queue, p_tle));
+}
+
+/*******************************************************************************
+**
+** Function         nfc_process_timer_evt
+**
+** Description      Process nfc GKI timer event
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_process_timer_evt(void) {
+  TIMER_LIST_ENT* p_tle;
+
+  GKI_update_timer_list(&nfc_cb.timer_queue, 1);
+
+  while ((nfc_cb.timer_queue.p_first) && (!nfc_cb.timer_queue.p_first->ticks)) {
+    p_tle = nfc_cb.timer_queue.p_first;
+    GKI_remove_from_timer_list(&nfc_cb.timer_queue, p_tle);
+
+    switch (p_tle->event) {
+      case NFC_TTYPE_NCI_WAIT_RSP:
+        nfc_ncif_cmd_timeout();
+        break;
+
+      case NFC_TTYPE_WAIT_2_DEACTIVATE:
+        nfc_wait_2_deactivate_timeout();
+        break;
+      case NFC_TTYPE_WAIT_SETMODE_NTF:
+        nfc_modeset_ntf_timeout();
+        break;
+#if (NXP_EXTNS == TRUE)
+      case NFC_TTYPE_NCI_WAIT_DATA_NTF: {
+        if (get_i2c_fragmentation_enabled() == I2C_FRAGMENATATION_ENABLED) {
+          nfc_cb.i2c_data_t.nci_cmd_channel_busy = 0;
+          nfc_cb.i2c_data_t.data_stored = 0;
+        }
+        nfc_ncif_credit_ntf_timeout();
+        break;
+      }
+      case NFC_TYPE_NCI_WAIT_SETMODE_NTF:
+          if(nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME ==
+                  nfcFL.eseFL._ESE_WIRED_MODE_RESUME) {
+              nfc_ncif_modeSet_Ntf_timeout();
+          }
+          break;
+      case NFC_TTYPE_NCI_WAIT_RF_FIELD_NTF:
+          if(nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME ==
+                  nfcFL.eseFL._ESE_WIRED_MODE_RESUME) {
+              nfc_ncif_onWiredModeHold_timeout();
+          }
+          break;
+      case NFC_TTYPE_LISTEN_ACTIVATION: {
+        extern uint8_t sListenActivated;
+        sListenActivated = false;
+        nfc_ncif_cmd_timeout();
+      } break;
+#endif
+
+      default:
+        NFC_TRACE_DEBUG2("nfc_process_timer_evt: timer:0x%x event (0x%04x)",
+                         p_tle, p_tle->event);
+        NFC_TRACE_DEBUG1(
+            "nfc_process_timer_evt: unhandled timer event (0x%04x)",
+            p_tle->event);
+    }
+  }
+
+  /* if timer list is empty stop periodic GKI timer */
+  if (nfc_cb.timer_queue.p_first == NULL) {
+    GKI_stop_timer(NFC_TIMER_ID);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_stop_timer
+**
+** Description      Stop a timer.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_stop_timer(TIMER_LIST_ENT* p_tle) {
+  GKI_remove_from_timer_list(&nfc_cb.timer_queue, p_tle);
+
+  /* if timer list is empty stop periodic GKI timer */
+  if (nfc_cb.timer_queue.p_first == NULL) {
+    GKI_stop_timer(NFC_TIMER_ID);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_start_quick_timer
+**
+** Description      Start a timer for the specified amount of time.
+**                  NOTE: The timeout resolution depends on including modules.
+**                  QUICK_TIMER_TICKS_PER_SEC should be used to convert from
+**                  time to ticks.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_start_quick_timer(TIMER_LIST_ENT* p_tle, uint16_t type,
+                           uint32_t timeout) {
+  NFC_HDR* p_msg;
+
+  /* if timer list is currently empty, start periodic GKI timer */
+  if (nfc_cb.quick_timer_queue.p_first == NULL) {
+    /* if timer starts on other than NFC task (scritp wrapper) */
+    if (GKI_get_taskid() != NFC_TASK) {
+      /* post event to start timer in NFC task */
+      p_msg = (NFC_HDR*)GKI_getbuf(NFC_HDR_SIZE);
+      if (p_msg != NULL) {
+        p_msg->event = BT_EVT_TO_START_QUICK_TIMER;
+        GKI_send_msg(NFC_TASK, NFC_MBOX_ID, p_msg);
+      }
+    } else {
+      /* Quick-timer is required for LLCP */
+      GKI_start_timer(NFC_QUICK_TIMER_ID,
+                      ((GKI_SECS_TO_TICKS(1) / QUICK_TIMER_TICKS_PER_SEC)),
+                      true);
+    }
+  }
+
+  GKI_remove_from_timer_list(&nfc_cb.quick_timer_queue, p_tle);
+
+  p_tle->event = type;
+  p_tle->ticks = timeout; /* Save the number of ticks for the timer */
+
+  GKI_add_to_timer_list(&nfc_cb.quick_timer_queue, p_tle);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_stop_quick_timer
+**
+** Description      Stop a timer.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_stop_quick_timer(TIMER_LIST_ENT* p_tle) {
+  GKI_remove_from_timer_list(&nfc_cb.quick_timer_queue, p_tle);
+
+  /* if timer list is empty stop periodic GKI timer */
+  if (nfc_cb.quick_timer_queue.p_first == NULL) {
+    GKI_stop_timer(NFC_QUICK_TIMER_ID);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_process_quick_timer_evt
+**
+** Description      Process quick timer event
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_process_quick_timer_evt(void) {
+  TIMER_LIST_ENT* p_tle;
+
+  GKI_update_timer_list(&nfc_cb.quick_timer_queue, 1);
+
+  while ((nfc_cb.quick_timer_queue.p_first) &&
+         (!nfc_cb.quick_timer_queue.p_first->ticks)) {
+    p_tle = nfc_cb.quick_timer_queue.p_first;
+    GKI_remove_from_timer_list(&nfc_cb.quick_timer_queue, p_tle);
+
+    switch (p_tle->event) {
+#if (NFC_RW_ONLY == FALSE)
+      case NFC_TTYPE_LLCP_LINK_MANAGER:
+      case NFC_TTYPE_LLCP_LINK_INACT:
+      case NFC_TTYPE_LLCP_DATA_LINK:
+      case NFC_TTYPE_LLCP_DELAY_FIRST_PDU:
+        llcp_process_timeout(p_tle);
+        break;
+#endif
+      case NFC_TTYPE_RW_T1T_RESPONSE:
+        rw_t1t_process_timeout(p_tle);
+        break;
+      case NFC_TTYPE_RW_T2T_RESPONSE:
+        rw_t2t_process_timeout(p_tle);
+        break;
+      case NFC_TTYPE_RW_T3T_RESPONSE:
+        rw_t3t_process_timeout(p_tle);
+        break;
+      case NFC_TTYPE_RW_T4T_RESPONSE:
+        rw_t4t_process_timeout(p_tle);
+        break;
+      case NFC_TTYPE_RW_I93_RESPONSE:
+        rw_i93_process_timeout(p_tle);
+        break;
+      case NFC_TTYPE_P2P_PRIO_RESPONSE:
+        nfa_dm_p2p_timer_event();
+        break;
+      case NFC_TTYPE_P2P_PRIO_LOGIC_CLEANUP:
+        nfa_dm_p2p_prio_logic_cleanup();
+        break;
+      case NFC_TTYPE_P2P_PRIO_LOGIC_DEACT_NTF_TIMEOUT:
+        nfa_dm_deact_ntf_timeout();
+        break;
+#if (NFC_RW_ONLY == FALSE)
+      case NFC_TTYPE_CE_T4T_UPDATE:
+        ce_t4t_process_timeout(p_tle);
+        break;
+#endif
+#if (NXP_EXTNS == TRUE)
+      case NFC_TTYPE_PWR_LINK_RSP:
+          if(nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME ==
+                  nfcFL.eseFL._ESE_WIRED_MODE_RESUME) {
+              nfc_ncif_pwr_link_rsp_timeout();
+          }
+          break;
+      case NFC_TTYPE_SET_MODE_RSP:
+          if(nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME ==
+                  nfcFL.eseFL._ESE_WIRED_MODE_RESUME) {
+              nfc_ncif_modeSet_rsp_timeout();
+          }
+          break;
+#endif
+      default:
+        NFC_TRACE_DEBUG1(
+            "nfc_process_quick_timer_evt: unhandled timer event (0x%04x)",
+            p_tle->event);
+        break;
+    }
+  }
+
+  /* if timer list is empty stop periodic GKI timer */
+  if (nfc_cb.quick_timer_queue.p_first == NULL) {
+    GKI_stop_timer(NFC_QUICK_TIMER_ID);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_task_shutdown_nfcc
+**
+** Description      Handle NFC shutdown
+**
+** Returns          nothing
+**
+*******************************************************************************/
+void nfc_task_shutdown_nfcc(void) {
+  NFC_HDR* p_msg;
+
+#if (NXP_EXTNS == TRUE)
+ if(nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME == nfcFL.eseFL._ESE_WIRED_MODE_RESUME) {
+     nfc_stop_timer(&nfc_cb.rf_filed_event_timeout_timer);
+ }
+#endif
+
+  /* Free any messages still in the mbox */
+  while ((p_msg = (NFC_HDR*)GKI_read_mbox(NFC_MBOX_ID)) != NULL) {
+    GKI_freebuf(p_msg);
+  }
+
+  nfc_gen_cleanup();
+
+  if (nfc_cb.flags & NFC_FL_POWER_OFF_SLEEP) {
+    nfc_set_state(NFC_STATE_W4_HAL_CLOSE);
+    nfc_cb.p_hal->close();
+  } else if (nfc_cb.flags & NFC_FL_POWER_CYCLE_NFCC) {
+    nfc_set_state(NFC_STATE_W4_HAL_OPEN);
+    nfc_cb.p_hal->power_cycle();
+  } else {
+    nfc_set_state(NFC_STATE_W4_HAL_CLOSE);
+    nfc_cb.p_hal->close();
+
+    /* Perform final clean up */
+    llcp_cleanup();
+
+    /* Stop the timers */
+    GKI_stop_timer(NFC_TIMER_ID);
+    GKI_stop_timer(NFC_QUICK_TIMER_ID);
+    GKI_stop_timer(NFA_TIMER_ID);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_task
+**
+** Description      NFC event processing task
+**
+** Returns          nothing
+**
+*******************************************************************************/
+uint32_t nfc_task(uint32_t param) {
+  uint16_t event;
+  NFC_HDR* p_msg;
+  bool free_buf;
+  (void)param;
+
+  /* Initialize the nfc control block */
+  memset(&nfc_cb, 0, sizeof(tNFC_CB));
+  nfc_cb.trace_level = NFC_INITIAL_TRACE_LEVEL;
+
+  NFC_TRACE_DEBUG0("NFC_TASK started.");
+
+  /* main loop */
+  while (true) {
+    event = GKI_wait(0xFFFF, 0);
+    if (event == EVENT_MASK(GKI_SHUTDOWN_EVT)) {
+      break;
+    }
+    /* Handle NFC_TASK_EVT_TRANSPORT_READY from NFC HAL */
+    if (event & NFC_TASK_EVT_TRANSPORT_READY) {
+      NFC_TRACE_DEBUG0("NFC_TASK got NFC_TASK_EVT_TRANSPORT_READY.");
+
+      /* Reset the NFC controller. */
+      nfc_set_state(NFC_STATE_CORE_INIT);
+#if (NXP_EXTNS == TRUE)
+      nci_snd_core_reset(NCI_RESET_TYPE_KEEP_CFG);
+#else
+      nci_snd_core_reset(NCI_RESET_TYPE_RESET_CFG);
+#endif
+    }
+
+    if (event & NFC_MBOX_EVT_MASK) {
+      /* Process all incoming NCI messages */
+      while ((p_msg = (NFC_HDR*)GKI_read_mbox(NFC_MBOX_ID)) != NULL) {
+        free_buf = true;
+
+        /* Determine the input message type. */
+        switch (p_msg->event & NFC_EVT_MASK) {
+          case BT_EVT_TO_NFC_NCI:
+            free_buf = nfc_ncif_process_event(p_msg);
+            break;
+
+          case BT_EVT_TO_START_TIMER:
+            /* Start nfc_task 1-sec resolution timer */
+            GKI_start_timer(NFC_TIMER_ID, GKI_SECS_TO_TICKS(1), true);
+            break;
+
+          case BT_EVT_TO_START_QUICK_TIMER:
+            /* Quick-timer is required for LLCP */
+            GKI_start_timer(
+                NFC_QUICK_TIMER_ID,
+                ((GKI_SECS_TO_TICKS(1) / QUICK_TIMER_TICKS_PER_SEC)), true);
+            break;
+
+          case BT_EVT_TO_NFC_MSGS:
+            nfc_main_handle_hal_evt((tNFC_HAL_EVT_MSG*)p_msg);
+            break;
+
+          default:
+            NFC_TRACE_DEBUG1("nfc_task: unhandle mbox message, event=%04x",
+                             p_msg->event);
+            break;
+        }
+
+        if (free_buf) {
+          GKI_freebuf(p_msg);
+        }
+      }
+    }
+
+    /* Process gki timer tick */
+    if (event & NFC_TIMER_EVT_MASK) {
+      nfc_process_timer_evt();
+    }
+
+    /* Process quick timer tick */
+    if (event & NFC_QUICK_TIMER_EVT_MASK) {
+      nfc_process_quick_timer_evt();
+    }
+
+    if (event & NFA_MBOX_EVT_MASK) {
+      while ((p_msg = (NFC_HDR*)GKI_read_mbox(NFA_MBOX_ID)) != NULL) {
+        nfa_sys_event(p_msg);
+      }
+    }
+
+    if (event & NFA_TIMER_EVT_MASK) {
+      nfa_sys_timer_update();
+    }
+  }
+
+  NFC_TRACE_DEBUG0("nfc_task terminated");
+
+  GKI_exit_task(GKI_get_taskid());
+  return 0;
+}
diff --git a/src/nfc/nfc/nfc_test.c b/src/nfc/nfc/nfc_test.c
new file mode 100644
index 0000000..41f26d7
--- /dev/null
+++ b/src/nfc/nfc/nfc_test.c
@@ -0,0 +1,64 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains functions that interface with the NFC NCI transport.
+ *  On the receive side, it routes events to the appropriate handler
+ *  (callback). On the transmit side, it manages the command transmission.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "gki.h"
+#include "nfc_target.h"
+#include "bt_types.h"
+
+#include "nfc_int.h"
+#include "nci_hmsgs.h"
+
+/****************************************************************************
+** Declarations
+****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         NFC_TestLoopback
+**
+** Description      This function is called to send the given data packet
+**                  to NFCC for loopback test.
+**                  When loopback data is received from NFCC, tNFC_TEST_CBACK .
+**                  reports a NFC_LOOPBACK_TEVT.
+**
+** Parameters       p_data - the data packet
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_TestLoopback(NFC_HDR* p_data) {
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  tNFC_CONN_CB* p_cb = nfc_find_conn_cb_by_handle(NCI_TEST_ID);
+
+  if (p_data && p_cb &&
+      (p_data->offset >= (NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE))) {
+    status = nfc_ncif_send_data(p_cb, p_data);
+  }
+
+  if (status != NFC_STATUS_OK) GKI_freebuf(p_data);
+
+  return status;
+}
diff --git a/src/nfc/nfc/nfc_utils.c b/src/nfc/nfc/nfc_utils.c
new file mode 100644
index 0000000..9176807
--- /dev/null
+++ b/src/nfc/nfc/nfc_utils.c
@@ -0,0 +1,192 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains functions that interface with the NFC NCI transport.
+ *  On the receive side, it routes events to the appropriate handler
+ *  (callback). On the transmit side, it manages the command transmission.
+ *
+ ******************************************************************************/
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "nfc_api.h"
+
+#include "nfc_int.h"
+
+/*******************************************************************************
+**
+** Function         nfc_alloc_conn_cb
+**
+** Description      This function is called to allocation a control block for
+**                  NCI logical connection
+**
+** Returns          The allocated control block or NULL
+**
+*******************************************************************************/
+tNFC_CONN_CB* nfc_alloc_conn_cb(tNFC_CONN_CBACK* p_cback) {
+  int xx, max = NCI_MAX_CONN_CBS;
+  tNFC_CONN_CB* p_conn_cb = NULL;
+#if (NXP_EXTNS == TRUE)
+  if(nfcFL.chipType != pn547C2) {
+      NFC_CHECK_MAX_CONN();
+  }
+#else
+  NFC_CHECK_MAX_CONN();
+#endif
+  for (xx = 0; xx < max; xx++) {
+    if (nfc_cb.conn_cb[xx].conn_id == NFC_ILLEGAL_CONN_ID) {
+      nfc_cb.conn_cb[xx].conn_id =
+          NFC_PEND_CONN_ID; /* to indicate this cb is used */
+      p_conn_cb = &nfc_cb.conn_cb[xx];
+      p_conn_cb->p_cback = p_cback;
+      break;
+    }
+  }
+  return p_conn_cb;
+}
+
+/*******************************************************************************
+**
+** Function         nfc_set_conn_id
+**
+** Description      This function is called to set the connection id to the
+**                  connection control block and the id mapping table
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_set_conn_id(tNFC_CONN_CB* p_cb, uint8_t conn_id) {
+  uint8_t handle;
+
+  if (p_cb == NULL) return;
+
+  p_cb->conn_id = conn_id;
+  handle = (uint8_t)(p_cb - nfc_cb.conn_cb + 1);
+  nfc_cb.conn_id[conn_id] = handle;
+  NFC_TRACE_DEBUG2("nfc_set_conn_id conn_id:%d, handle:%d", conn_id, handle);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_find_conn_cb_by_handle
+**
+** Description      This function is called to locate the control block for
+**                  loopback test.
+**
+** Returns          The loopback test control block or NULL
+**
+*******************************************************************************/
+tNFC_CONN_CB* nfc_find_conn_cb_by_handle(uint8_t id) {
+  int xx;
+  tNFC_CONN_CB* p_conn_cb = NULL;
+
+  for (xx = 0; xx < NCI_MAX_CONN_CBS; xx++) {
+    if (nfc_cb.conn_cb[xx].id == id) {
+      p_conn_cb = &nfc_cb.conn_cb[xx];
+      break;
+    }
+  }
+  return p_conn_cb;
+}
+
+/*******************************************************************************
+**
+** Function         nfc_find_conn_cb_by_conn_id
+**
+** Description      This function is called to locate the control block for
+**                  the given connection id
+**
+** Returns          The control block or NULL
+**
+*******************************************************************************/
+tNFC_CONN_CB* nfc_find_conn_cb_by_conn_id(uint8_t conn_id) {
+  tNFC_CONN_CB* p_conn_cb = NULL;
+  uint8_t handle;
+  uint8_t id;
+  int xx;
+
+  if (conn_id == NFC_PEND_CONN_ID) {
+    for (xx = 0; xx < NCI_MAX_CONN_CBS; xx++) {
+      if (nfc_cb.conn_cb[xx].conn_id == NFC_PEND_CONN_ID) {
+        p_conn_cb = &nfc_cb.conn_cb[xx];
+        break;
+      }
+    }
+  } else {
+    id = conn_id & NFC_CONN_ID_ID_MASK;
+    if (id < NFC_MAX_CONN_ID) {
+      handle = nfc_cb.conn_id[id];
+      if (handle > 0) p_conn_cb = &nfc_cb.conn_cb[handle - 1];
+    }
+  }
+
+  return p_conn_cb;
+}
+
+/*******************************************************************************
+**
+** Function         nfc_free_conn_cb
+**
+** Description      This function is called to free the control block and
+**                  resources and id mapping table
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_free_conn_cb(tNFC_CONN_CB* p_cb) {
+  void* p_buf;
+
+  if (p_cb == NULL) return;
+
+  while ((p_buf = GKI_dequeue(&p_cb->rx_q)) != NULL) GKI_freebuf(p_buf);
+
+  while ((p_buf = GKI_dequeue(&p_cb->tx_q)) != NULL) GKI_freebuf(p_buf);
+
+  nfc_cb.conn_id[p_cb->conn_id] = 0;
+  p_cb->p_cback = NULL;
+  p_cb->conn_id = NFC_ILLEGAL_CONN_ID;
+}
+
+/*******************************************************************************
+**
+** Function         nfc_reset_all_conn_cbs
+**
+** Description      This function is called to free all the control blocks and
+**                  resources and id mapping table
+**
+** Returns          void
+**
+*******************************************************************************/
+extern void nfc_reset_all_conn_cbs(void) {
+  int xx;
+  tNFC_CONN_CB* p_conn_cb = &nfc_cb.conn_cb[0];
+  tNFC_DEACTIVATE_DEVT deact;
+
+  deact.status = NFC_STATUS_NOT_INITIALIZED;
+  deact.type = NFC_DEACTIVATE_TYPE_IDLE;
+  deact.is_ntf = true;
+  for (xx = 0; xx < NCI_MAX_CONN_CBS; xx++, p_conn_cb++) {
+    if (p_conn_cb->conn_id != NFC_ILLEGAL_CONN_ID) {
+      if (p_conn_cb->p_cback)
+        (*p_conn_cb->p_cback)(p_conn_cb->conn_id, NFC_DEACTIVATE_CEVT,
+                              (void*)&deact);
+      nfc_free_conn_cb(p_conn_cb);
+    }
+  }
+}
diff --git a/src/nfc/nfc/nfc_vs.c b/src/nfc/nfc/nfc_vs.c
new file mode 100644
index 0000000..286cc64
--- /dev/null
+++ b/src/nfc/nfc/nfc_vs.c
@@ -0,0 +1,177 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains functions that NCI vendor specific interface with the
+ *  NFCC. On the receive side, it routes events to the appropriate handler
+ *  (callback). On the transmit side, it manages the command transmission.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "gki.h"
+#include "nfc_target.h"
+
+#include "nfc_int.h"
+
+/****************************************************************************
+** Declarations
+****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         NFC_RegVSCback
+**
+** Description      This function is called to register or de-register a
+**                  callback function to receive Proprietary NCI response and
+**                  notification events. The maximum number of callback
+**                  functions allowed is NFC_NUM_VS_CBACKS
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_RegVSCback(bool is_register, tNFC_VS_CBACK* p_cback) {
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  int i;
+
+  if (is_register) {
+    for (i = 0; i < NFC_NUM_VS_CBACKS; i++) {
+      /* find an empty spot to hold the callback function */
+      if (nfc_cb.p_vs_cb[i] == NULL) {
+        nfc_cb.p_vs_cb[i] = p_cback;
+        status = NFC_STATUS_OK;
+        break;
+      }
+    }
+  } else {
+    for (i = 0; i < NFC_NUM_VS_CBACKS; i++) {
+      /* find the callback to de-register */
+      if (nfc_cb.p_vs_cb[i] == p_cback) {
+        nfc_cb.p_vs_cb[i] = NULL;
+        status = NFC_STATUS_OK;
+        break;
+      }
+    }
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFC_SendVsCommand
+**
+** Description      This function is called to send the given vendor specific
+**                  command to NFCC. The response from NFCC is reported to the
+**                  given tNFC_VS_CBACK as (oid).
+**
+** Parameters       oid - The opcode of the VS command.
+**                  p_data - The parameters for the VS command
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_SendVsCommand(uint8_t oid, NFC_HDR* p_data,
+                              tNFC_VS_CBACK* p_cback) {
+  tNFC_STATUS status = NFC_STATUS_OK;
+  uint8_t* pp;
+
+  /* Allow VSC with 0-length payload */
+  if (p_data == NULL) {
+    p_data = NCI_GET_CMD_BUF(0);
+    if (p_data) {
+      p_data->offset = NCI_VSC_MSG_HDR_SIZE;
+      p_data->len = 0;
+    }
+  }
+
+  /* Validate parameters */
+  if ((p_data == NULL) || (p_data->offset < NCI_VSC_MSG_HDR_SIZE) ||
+      (p_data->len > NCI_MAX_VSC_SIZE)) {
+    NFC_TRACE_ERROR1("buffer offset must be >= %d", NCI_VSC_MSG_HDR_SIZE);
+    if (p_data) GKI_freebuf(p_data);
+    return NFC_STATUS_INVALID_PARAM;
+  }
+
+  p_data->event = BT_EVT_TO_NFC_NCI;
+  p_data->layer_specific = NFC_WAIT_RSP_VSC;
+  /* save the callback function in the NFC_HDR, to receive the response */
+  ((tNFC_NCI_VS_MSG*)p_data)->p_cback = p_cback;
+
+  p_data->offset -= NCI_MSG_HDR_SIZE;
+  pp = (uint8_t*)(p_data + 1) + p_data->offset;
+  NCI_MSG_BLD_HDR0(pp, NCI_MT_CMD, NCI_GID_PROP);
+  NCI_MSG_BLD_HDR1(pp, oid);
+  *pp = (uint8_t)p_data->len;
+  p_data->len += NCI_MSG_HDR_SIZE;
+  nfc_ncif_check_cmd_queue(p_data);
+  return status;
+}
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         NFC_SendNxpNciCommand
+**
+** Description      This function is called to send the given nxp specific
+**                  command to NFCC. The response from NFCC is reported to the
+**                  given tNFC_VS_CBACK.
+**
+** Parameters       p_data - The command buffer
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_SendNxpNciCommand(NFC_HDR* p_data, tNFC_VS_CBACK* p_cback) {
+  tNFC_STATUS status = NFC_STATUS_OK;
+  uint8_t* pp;
+
+  /* Validate parameters */
+  if ((p_data == NULL) || (p_data->len > NCI_MAX_VSC_SIZE)) {
+    NFC_TRACE_ERROR1("buffer offset must be >= %d", NCI_VSC_MSG_HDR_SIZE);
+    if (p_data) GKI_freebuf(p_data);
+    return NFC_STATUS_INVALID_PARAM;
+  }
+
+  p_data->event = BT_EVT_TO_NFC_NCI;
+  p_data->layer_specific = NFC_WAIT_RSP_NXP;
+  /* save the callback function in the NFC_HDR, to receive the response */
+  ((tNFC_NCI_VS_MSG*)p_data)->p_cback = p_cback;
+  pp = (uint8_t*)(p_data + 1) + p_data->offset;
+
+  nfc_ncif_check_cmd_queue(p_data);
+  return status;
+}
+#endif
diff --git a/src/nfc/tags/ce_main.c b/src/nfc/tags/ce_main.c
new file mode 100644
index 0000000..30d97fa
--- /dev/null
+++ b/src/nfc/tags/ce_main.c
@@ -0,0 +1,139 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains functions that interface with the NFC NCI transport.
+ *  On the receive side, it routes events to the appropriate handler
+ *  (callback). On the transmit side, it manages the command transmission.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+#include "bt_types.h"
+
+#include "nfc_api.h"
+#include "nci_hmsgs.h"
+#include "ce_api.h"
+#include "ce_int.h"
+#include "gki.h"
+
+tCE_CB ce_cb;
+
+/*******************************************************************************
+*******************************************************************************/
+void ce_init(void) {
+  memset(&ce_cb, 0, sizeof(tCE_CB));
+  ce_cb.trace_level = NFC_INITIAL_TRACE_LEVEL;
+
+  /* Initialize tag-specific fields of ce control block */
+  ce_t3t_init();
+}
+
+/*******************************************************************************
+**
+** Function         CE_SendRawFrame
+**
+** Description      This function sends a raw frame to the peer device.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS CE_SendRawFrame(uint8_t* p_raw_data, uint16_t data_len) {
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  NFC_HDR* p_data;
+  uint8_t* p;
+
+  if (ce_cb.p_cback) {
+    /* a valid opcode for RW */
+    p_data = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+    if (p_data) {
+      p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+      p = (uint8_t*)(p_data + 1) + p_data->offset;
+      memcpy(p, p_raw_data, data_len);
+      p_data->len = data_len;
+      CE_TRACE_EVENT1("CE SENT raw frame (0x%x)", data_len);
+      status = NFC_SendData(NFC_RF_CONN_ID, p_data);
+    }
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         CE_SetActivatedTagType
+**
+** Description      This function selects the tag type for CE mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS CE_SetActivatedTagType(tNFC_ACTIVATE_DEVT* p_activate_params,
+                                   uint16_t t3t_system_code,
+                                   tCE_CBACK* p_cback) {
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  tNFC_PROTOCOL protocol = p_activate_params->protocol;
+
+  CE_TRACE_API1("CE_SetActivatedTagType protocol:%d", protocol);
+
+  switch (protocol) {
+    case NFC_PROTOCOL_T1T:
+    case NFC_PROTOCOL_T2T:
+      return NFC_STATUS_FAILED;
+
+    case NFC_PROTOCOL_T3T: /* Type3Tag    - NFC-F */
+      /* store callback function before NFC_SetStaticRfCback () */
+      ce_cb.p_cback = p_cback;
+      status = ce_select_t3t(t3t_system_code,
+                             p_activate_params->rf_tech_param.param.lf.nfcid2);
+      break;
+
+    case NFC_PROTOCOL_ISO_DEP: /* ISODEP/4A,4B- NFC-A or NFC-B */
+      /* store callback function before NFC_SetStaticRfCback () */
+      ce_cb.p_cback = p_cback;
+      status = ce_select_t4t();
+      break;
+
+    default:
+      CE_TRACE_ERROR0("CE_SetActivatedTagType Invalid protocol");
+      return NFC_STATUS_FAILED;
+  }
+
+  if (status != NFC_STATUS_OK) {
+    NFC_SetStaticRfCback(NULL);
+    ce_cb.p_cback = NULL;
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         CE_SetTraceLevel
+**
+** Description      This function sets the trace level for Card Emulation mode.
+**                  If called with a value of 0xFF,
+**                  it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+uint8_t CE_SetTraceLevel(uint8_t new_level) {
+  if (new_level != 0xFF) ce_cb.trace_level = new_level;
+
+  return (ce_cb.trace_level);
+}
diff --git a/src/nfc/tags/ce_t3t.c b/src/nfc/tags/ce_t3t.c
new file mode 100644
index 0000000..7512506
--- /dev/null
+++ b/src/nfc/tags/ce_t3t.c
@@ -0,0 +1,988 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the implementation for Type 3 tag in Card Emulation
+ *  mode.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "trace_api.h"
+
+#include "nfc_api.h"
+#include "nfc_int.h"
+#include "ce_api.h"
+#include "ce_int.h"
+#include "tags_int.h"
+#include "gki.h"
+
+enum {
+  CE_T3T_COMMAND_INVALID,
+  CE_T3T_COMMAND_NFC_FORUM,
+  CE_T3T_COMMAND_FELICA
+};
+
+/* T3T CE states */
+enum { CE_T3T_STATE_NOT_ACTIVATED, CE_T3T_STATE_IDLE, CE_T3T_STATE_UPDATING };
+
+/* Bitmasks to indicate type of UPDATE */
+#define CE_T3T_UPDATE_FL_NDEF_UPDATE_START 0x01
+#define CE_T3T_UPDATE_FL_NDEF_UPDATE_CPLT 0x02
+#define CE_T3T_UPDATE_FL_UPDATE 0x04
+
+/*******************************************************************************
+* Static constant definitions
+*******************************************************************************/
+/* Default PMm param */
+static const uint8_t CE_DEFAULT_LF_PMM[NCI_T3T_PMM_LEN] = {
+    0x01, /* This PAD0 is used to identify HCE-F on Android */
+    0xFE, /* This PAD0 is used to identify HCE-F on Android */
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+
+/*******************************************************************************
+**
+** Function         ce_t3t_init
+**
+** Description      Initialize tag-specific fields of ce control block
+**
+** Returns          none
+**
+*******************************************************************************/
+void ce_t3t_init(void) {
+  memcpy(ce_cb.mem.t3t.local_pmm, CE_DEFAULT_LF_PMM, NCI_T3T_PMM_LEN);
+  ce_cb.mem.t3t.ndef_info.nbr = CE_T3T_DEFAULT_CHECK_MAXBLOCKS;
+  ce_cb.mem.t3t.ndef_info.nbw = CE_T3T_DEFAULT_UPDATE_MAXBLOCKS;
+}
+
+/*******************************************************************************
+**
+** Function         ce_t3t_send_to_lower
+**
+** Description      Send C-APDU to lower layer
+**
+** Returns          none
+**
+*******************************************************************************/
+void ce_t3t_send_to_lower(NFC_HDR* p_msg) {
+  uint8_t* p;
+
+  /* Set NFC-F SoD field (payload len + 1) */
+  p_msg->offset -= 1; /* Point to SoD field */
+  p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+  UINT8_TO_STREAM(p, (p_msg->len + 1));
+  p_msg->len += 1; /* Increment len to include SoD */
+
+#if (BT_TRACE_PROTOCOL == true)
+  DispT3TagMessage(p_msg, false);
+#endif
+
+  if (NFC_SendData(NFC_RF_CONN_ID, p_msg) != NFC_STATUS_OK) {
+    CE_TRACE_ERROR0("ce_t3t_send_to_lower (): NFC_SendData () failed");
+  }
+}
+
+/*******************************************************************************
+**
+** Function         ce_t3t_is_valid_opcode
+**
+** Description      Valid opcode
+**
+** Returns          Type of command
+**
+*******************************************************************************/
+uint8_t ce_t3t_is_valid_opcode(uint8_t cmd_id) {
+  uint8_t retval = CE_T3T_COMMAND_INVALID;
+
+  if ((cmd_id == T3T_MSG_OPC_CHECK_CMD) || (cmd_id == T3T_MSG_OPC_UPDATE_CMD)) {
+    retval = CE_T3T_COMMAND_NFC_FORUM;
+  } else if ((cmd_id == T3T_MSG_OPC_POLL_CMD) ||
+             (cmd_id == T3T_MSG_OPC_REQ_SERVICE_CMD) ||
+             (cmd_id == T3T_MSG_OPC_REQ_RESPONSE_CMD) ||
+             (cmd_id == T3T_MSG_OPC_REQ_SYSTEMCODE_CMD)) {
+    retval = CE_T3T_COMMAND_FELICA;
+  }
+
+  return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         ce_t3t_get_rsp_buf
+**
+** Description      Get a buffer for sending T3T messages
+**
+** Returns          NFC_HDR *
+**
+*****************************************************************************/
+NFC_HDR* ce_t3t_get_rsp_buf(void) {
+  NFC_HDR* p_cmd_buf;
+
+  p_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_CE_POOL_ID);
+  if (p_cmd_buf != NULL) {
+    /* Reserve offset for NCI_DATA_HDR and NFC-F Sod (LEN) field */
+    p_cmd_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + 1;
+    p_cmd_buf->len = 0;
+  }
+
+  return (p_cmd_buf);
+}
+
+/*******************************************************************************
+**
+** Function         ce_t3t_send_rsp
+**
+** Description      Send response to reader/writer
+**
+** Returns          none
+**
+*******************************************************************************/
+void ce_t3t_send_rsp(tCE_CB* p_ce_cb, uint8_t* p_nfcid2, uint8_t opcode,
+                     uint8_t status1, uint8_t status2) {
+  tCE_T3T_MEM* p_cb = &p_ce_cb->mem.t3t;
+  NFC_HDR* p_rsp_msg;
+  uint8_t* p_dst, *p_rsp_start;
+
+  /* If p_nfcid2 is NULL, then used activated NFCID2 */
+  if (p_nfcid2 == NULL) {
+    p_nfcid2 = p_cb->local_nfcid2;
+  }
+
+  p_rsp_msg = ce_t3t_get_rsp_buf();
+  if (p_rsp_msg != NULL) {
+    p_dst = p_rsp_start = (uint8_t*)(p_rsp_msg + 1) + p_rsp_msg->offset;
+
+    /* Response Code */
+    UINT8_TO_STREAM(p_dst, opcode);
+
+    /* Manufacturer ID */
+    ARRAY_TO_STREAM(p_dst, p_nfcid2, NCI_RF_F_UID_LEN);
+
+    /* Status1 and Status2 */
+    UINT8_TO_STREAM(p_dst, status1);
+    UINT8_TO_STREAM(p_dst, status2);
+
+    p_rsp_msg->len = (uint16_t)(p_dst - p_rsp_start);
+    ce_t3t_send_to_lower(p_rsp_msg);
+  } else {
+    CE_TRACE_ERROR0("CE: Unable to allocat buffer for response message");
+  }
+}
+
+/*******************************************************************************
+**
+** Function         ce_t3t_handle_update_cmd
+**
+** Description      Handle UPDATE command from reader/writer
+**
+** Returns          none
+**
+*******************************************************************************/
+void ce_t3t_handle_update_cmd(tCE_CB* p_ce_cb, NFC_HDR* p_cmd_msg) {
+  tCE_T3T_MEM* p_cb = &p_ce_cb->mem.t3t;
+  uint8_t* p_temp;
+  uint8_t* p_block_list = p_cb->cur_cmd.p_block_list_start;
+  uint8_t* p_block_data = p_cb->cur_cmd.p_block_data_start;
+  uint8_t i, j, bl0;
+  uint16_t block_number, service_code, checksum, checksum_rx;
+  uint32_t newlen_hiword;
+  tCE_T3T_NDEF_INFO ndef_info;
+  tNFC_STATUS nfc_status = NFC_STATUS_OK;
+  uint8_t update_flags = 0;
+  tCE_UPDATE_INFO update_info;
+
+  /* If in idle state, notify app that update is starting */
+  if (p_cb->state == CE_T3T_STATE_IDLE) {
+    p_cb->state = CE_T3T_STATE_UPDATING;
+  }
+
+  for (i = 0; i < p_cb->cur_cmd.num_blocks; i++) {
+    /* Read byte0 of block list */
+    STREAM_TO_UINT8(bl0, p_block_list);
+
+    if (bl0 & T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT) {
+      STREAM_TO_UINT8(block_number, p_block_list);
+    } else {
+      STREAM_TO_UINT16(block_number, p_block_list);
+    }
+
+    /* Read the block from memory */
+    service_code =
+        p_cb->cur_cmd.service_code_list[bl0 & T3T_MSG_SERVICE_LIST_MASK];
+
+    /* Reject UPDATE command if service code=T3T_MSG_NDEF_SC_RO */
+    if (service_code == T3T_MSG_NDEF_SC_RO) {
+      /* Error: invalid block number to update */
+      CE_TRACE_ERROR0("CE: UPDATE request using read-only service");
+      nfc_status = NFC_STATUS_FAILED;
+      break;
+    }
+
+    /* Check for NDEF */
+    if (service_code == T3T_MSG_NDEF_SC_RW) {
+      if (p_cb->cur_cmd.num_blocks > p_cb->ndef_info.nbw) {
+        CE_TRACE_ERROR2(
+            "CE: Requested too many blocks to update (requested: %i, max: %i)",
+            p_cb->cur_cmd.num_blocks, p_cb->ndef_info.nbw);
+        nfc_status = NFC_STATUS_FAILED;
+        break;
+      } else if (p_cb->ndef_info.rwflag == T3T_MSG_NDEF_RWFLAG_RO) {
+        CE_TRACE_ERROR0("CE: error: write-request to read-only NDEF message.");
+        nfc_status = NFC_STATUS_FAILED;
+        break;
+      } else if (block_number == 0) {
+        CE_TRACE_DEBUG2("CE: Update sc 0x%04x block %i.", service_code,
+                        block_number);
+
+        /* Special caes: NDEF block0 is the ndef attribute block */
+        p_temp = p_block_data;
+        STREAM_TO_UINT8(ndef_info.version, p_block_data);
+        p_block_data += 8; /* Ignore nbr,nbw,maxb,and reserved (reader/writer
+                              not allowed to update this) */
+        STREAM_TO_UINT8(ndef_info.writef, p_block_data);
+        p_block_data++; /* Ignore rwflag (reader/writer not allowed to update
+                           this) */
+        STREAM_TO_UINT8(newlen_hiword, p_block_data);
+        BE_STREAM_TO_UINT16(ndef_info.ln, p_block_data);
+        ndef_info.ln += (newlen_hiword << 16);
+        BE_STREAM_TO_UINT16(checksum_rx, p_block_data);
+
+        checksum = 0;
+        for (j = 0; j < T3T_MSG_NDEF_ATTR_INFO_SIZE; j++) {
+          checksum += p_temp[j];
+        }
+
+        /* Compare calcuated checksum with received checksum */
+        if (checksum != checksum_rx) {
+          CE_TRACE_ERROR0("CE: Checksum failed for NDEF attribute block.");
+          nfc_status = NFC_STATUS_FAILED;
+        } else {
+          /* Update NDEF attribute block (only allowed to update current length
+           * and writef fields) */
+          p_cb->ndef_info.scratch_ln = ndef_info.ln;
+          p_cb->ndef_info.scratch_writef = ndef_info.writef;
+
+          /* If writef=0 indicates completion of NDEF update */
+          if (ndef_info.writef == 0) {
+            update_flags |= CE_T3T_UPDATE_FL_NDEF_UPDATE_CPLT;
+          }
+          /* writef=1 indicates start of NDEF update */
+          else {
+            update_flags |= CE_T3T_UPDATE_FL_NDEF_UPDATE_START;
+          }
+        }
+      } else {
+        CE_TRACE_DEBUG2("CE: Udpate sc 0x%04x block %i.", service_code,
+                        block_number);
+
+        /* Verify that block_number is within NDEF memory */
+        if (block_number > p_cb->ndef_info.nmaxb) {
+          /* Error: invalid block number to update */
+          CE_TRACE_ERROR2(
+              "CE: Requested invalid NDEF block number to update %i (max is "
+              "%i).",
+              block_number, p_cb->ndef_info.nmaxb);
+          nfc_status = NFC_STATUS_FAILED;
+          break;
+        } else {
+          /* Update NDEF memory block */
+          STREAM_TO_ARRAY(
+              (&p_cb->ndef_info
+                    .p_scratch_buf[(block_number - 1) * T3T_MSG_BLOCKSIZE]),
+              p_block_data, T3T_MSG_BLOCKSIZE);
+        }
+
+        /* Set flag to indicate that this UPDATE contained at least one block */
+        update_flags |= CE_T3T_UPDATE_FL_UPDATE;
+      }
+    } else {
+      /* Error: invalid service code */
+      CE_TRACE_ERROR1("CE: Requested invalid service code: 0x%04x.",
+                      service_code);
+      nfc_status = NFC_STATUS_FAILED;
+      break;
+    }
+  }
+
+  /* Send appropriate response to reader/writer */
+  if (nfc_status == NFC_STATUS_OK) {
+    ce_t3t_send_rsp(p_ce_cb, NULL, T3T_MSG_OPC_UPDATE_RSP,
+                    T3T_MSG_RSP_STATUS_OK, T3T_MSG_RSP_STATUS_OK);
+  } else {
+    ce_t3t_send_rsp(p_ce_cb, NULL, T3T_MSG_OPC_UPDATE_RSP,
+                    T3T_MSG_RSP_STATUS_ERROR, T3T_MSG_RSP_STATUS2_ERROR_MEMORY);
+    p_cb->state = CE_T3T_STATE_IDLE;
+  }
+
+  /* Notify the app of what got updated */
+  if (update_flags & CE_T3T_UPDATE_FL_NDEF_UPDATE_START) {
+    /* NDEF attribute got updated with WriteF=true */
+    p_ce_cb->p_cback(CE_T3T_NDEF_UPDATE_START_EVT, NULL);
+  }
+
+  if (update_flags & CE_T3T_UPDATE_FL_UPDATE) {
+    /* UPDATE message contained at least one non-NDEF block */
+    p_ce_cb->p_cback(CE_T3T_UPDATE_EVT, NULL);
+  }
+
+  if (update_flags & CE_T3T_UPDATE_FL_NDEF_UPDATE_CPLT) {
+    /* NDEF attribute got updated with WriteF=false */
+    update_info.status = nfc_status;
+    update_info.p_data = p_cb->ndef_info.p_scratch_buf;
+    update_info.length = p_cb->ndef_info.scratch_ln;
+    p_cb->state = CE_T3T_STATE_IDLE;
+    p_ce_cb->p_cback(CE_T3T_NDEF_UPDATE_CPLT_EVT, (void*)&update_info);
+  }
+
+  GKI_freebuf(p_cmd_msg);
+}
+
+/*******************************************************************************
+**
+** Function         ce_t3t_handle_check_cmd
+**
+** Description      Handle CHECK command from reader/writer
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void ce_t3t_handle_check_cmd(tCE_CB* p_ce_cb, NFC_HDR* p_cmd_msg) {
+  tCE_T3T_MEM* p_cb = &p_ce_cb->mem.t3t;
+  NFC_HDR* p_rsp_msg;
+  uint8_t* p_rsp_start;
+  uint8_t* p_dst, *p_temp, *p_status;
+  uint8_t* p_src = p_cb->cur_cmd.p_block_list_start;
+  uint8_t i, bl0;
+  uint8_t ndef_writef;
+  uint32_t ndef_len;
+  uint16_t block_number, service_code, checksum;
+
+  p_rsp_msg = ce_t3t_get_rsp_buf();
+  if (p_rsp_msg != NULL) {
+    p_dst = p_rsp_start = (uint8_t*)(p_rsp_msg + 1) + p_rsp_msg->offset;
+
+    /* Response Code */
+    UINT8_TO_STREAM(p_dst, T3T_MSG_OPC_CHECK_RSP);
+
+    /* Manufacturer ID */
+    ARRAY_TO_STREAM(p_dst, p_cb->local_nfcid2, NCI_RF_F_UID_LEN);
+
+    /* Save pointer to start of status field */
+    p_status = p_dst;
+
+    /* Status1 and Status2 (assume success initially */
+    UINT8_TO_STREAM(p_dst, T3T_MSG_RSP_STATUS_OK);
+    UINT8_TO_STREAM(p_dst, T3T_MSG_RSP_STATUS_OK);
+    UINT8_TO_STREAM(p_dst, p_cb->cur_cmd.num_blocks);
+
+    for (i = 0; i < p_cb->cur_cmd.num_blocks; i++) {
+      /* Read byte0 of block list */
+      STREAM_TO_UINT8(bl0, p_src);
+
+      if (bl0 & T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT) {
+        STREAM_TO_UINT8(block_number, p_src);
+      } else {
+        STREAM_TO_UINT16(block_number, p_src);
+      }
+
+      /* Read the block from memory */
+      service_code =
+          p_cb->cur_cmd.service_code_list[bl0 & T3T_MSG_SERVICE_LIST_MASK];
+
+      /* Check for NDEF */
+      if ((service_code == T3T_MSG_NDEF_SC_RO) ||
+          (service_code == T3T_MSG_NDEF_SC_RW)) {
+        /* Verify Nbr (NDEF only) */
+        if (p_cb->cur_cmd.num_blocks > p_cb->ndef_info.nbr) {
+          /* Error: invalid number of blocks to check */
+          CE_TRACE_ERROR2(
+              "CE: Requested too many blocks to check (requested: %i, max: %i)",
+              p_cb->cur_cmd.num_blocks, p_cb->ndef_info.nbr);
+
+          p_dst = p_status;
+          UINT8_TO_STREAM(p_dst, T3T_MSG_RSP_STATUS_ERROR);
+          UINT8_TO_STREAM(p_dst, T3T_MSG_RSP_STATUS2_ERROR_MEMORY);
+          break;
+        } else if (block_number == 0) {
+          /* Special caes: NDEF block0 is the ndef attribute block */
+          p_temp = p_dst;
+
+          /* For rw ndef, use scratch buffer's attributes (in case reader/writer
+           * had previously updated NDEF) */
+          if ((p_cb->ndef_info.rwflag == T3T_MSG_NDEF_RWFLAG_RW) &&
+              (p_cb->ndef_info.p_scratch_buf)) {
+            ndef_writef = p_cb->ndef_info.scratch_writef;
+            ndef_len = p_cb->ndef_info.scratch_ln;
+          } else {
+            ndef_writef = p_cb->ndef_info.writef;
+            ndef_len = p_cb->ndef_info.ln;
+          }
+
+          UINT8_TO_STREAM(p_dst, p_cb->ndef_info.version);
+          UINT8_TO_STREAM(p_dst, p_cb->ndef_info.nbr);
+          UINT8_TO_STREAM(p_dst, p_cb->ndef_info.nbw);
+          UINT16_TO_BE_STREAM(p_dst, p_cb->ndef_info.nmaxb);
+          UINT32_TO_STREAM(p_dst, 0);
+          UINT8_TO_STREAM(p_dst, ndef_writef);
+          UINT8_TO_STREAM(p_dst, p_cb->ndef_info.rwflag);
+          UINT8_TO_STREAM(p_dst, (ndef_len >> 16 & 0xFF));
+          UINT16_TO_BE_STREAM(p_dst, (ndef_len & 0xFFFF));
+
+          checksum = 0;
+          for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++) {
+            checksum += p_temp[i];
+          }
+          UINT16_TO_BE_STREAM(p_dst, checksum);
+        } else {
+          /* Verify that block_number is within NDEF memory */
+          if (block_number > p_cb->ndef_info.nmaxb) {
+            /* Invalid block number */
+            p_dst = p_status;
+
+            CE_TRACE_ERROR1("CE: Requested block number to check %i.",
+                            block_number);
+
+            /* Error: invalid number of blocks to check */
+            UINT8_TO_STREAM(p_dst, T3T_MSG_RSP_STATUS_ERROR);
+            UINT8_TO_STREAM(p_dst, T3T_MSG_RSP_STATUS2_ERROR_MEMORY);
+            break;
+          } else {
+            /* If card is RW, then read from the scratch buffer (so reader/write
+             * can read back what it had just written */
+            if ((p_cb->ndef_info.rwflag == T3T_MSG_NDEF_RWFLAG_RW) &&
+                (p_cb->ndef_info.p_scratch_buf)) {
+              ARRAY_TO_STREAM(
+                  p_dst,
+                  (&p_cb->ndef_info
+                        .p_scratch_buf[(block_number - 1) * T3T_MSG_BLOCKSIZE]),
+                  T3T_MSG_BLOCKSIZE);
+            } else {
+              ARRAY_TO_STREAM(
+                  p_dst, (&p_cb->ndef_info
+                               .p_buf[(block_number - 1) * T3T_MSG_BLOCKSIZE]),
+                  T3T_MSG_BLOCKSIZE);
+            }
+          }
+        }
+      } else {
+        /* Error: invalid service code */
+        CE_TRACE_ERROR1("CE: Requested invalid service code: 0x%04x.",
+                        service_code);
+
+        p_dst = p_status;
+        UINT8_TO_STREAM(p_dst, T3T_MSG_RSP_STATUS_ERROR);
+        UINT8_TO_STREAM(p_dst, T3T_MSG_RSP_STATUS2_ERROR_MEMORY);
+        break;
+      }
+    }
+
+    p_rsp_msg->len = (uint16_t)(p_dst - p_rsp_start);
+    ce_t3t_send_to_lower(p_rsp_msg);
+  } else {
+    CE_TRACE_ERROR0("CE: Unable to allocat buffer for response message");
+  }
+
+  GKI_freebuf(p_cmd_msg);
+}
+
+/*******************************************************************************
+**
+** Function         ce_t3t_handle_non_nfc_forum_cmd
+**
+** Description      Handle POLL command from reader/writer
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void ce_t3t_handle_non_nfc_forum_cmd(tCE_CB* p_mem_cb, uint8_t cmd_id,
+                                     NFC_HDR* p_cmd_msg) {
+  tCE_T3T_MEM* p_cb = &p_mem_cb->mem.t3t;
+  NFC_HDR* p_rsp_msg;
+  uint8_t* p_rsp_start;
+  uint8_t* p_dst;
+  uint8_t* p = (uint8_t*)(p_cmd_msg + 1) + p_cmd_msg->offset;
+  uint16_t sc;
+  uint8_t rc;
+  bool send_response = true;
+
+  p_rsp_msg = ce_t3t_get_rsp_buf();
+  if (p_rsp_msg != NULL) {
+    p_dst = p_rsp_start = (uint8_t*)(p_rsp_msg + 1) + p_rsp_msg->offset;
+
+    switch (cmd_id) {
+      case T3T_MSG_OPC_POLL_CMD:
+        /* Get system code and RC */
+        /* Skip over sod and cmd_id */
+        p += 2;
+        BE_STREAM_TO_UINT16(sc, p);
+        STREAM_TO_UINT8(rc, p);
+
+        /* If requesting wildcard system code, or specifically our system code,
+         * then send POLL response */
+        if ((sc == 0xFFFF) || (sc == p_cb->system_code)) {
+          /* Response Code */
+          UINT8_TO_STREAM(p_dst, T3T_MSG_OPC_POLL_RSP);
+
+          /* Manufacturer ID */
+          ARRAY_TO_STREAM(p_dst, p_cb->local_nfcid2, NCI_RF_F_UID_LEN);
+
+          /* Manufacturer Parameter PMm */
+          ARRAY_TO_STREAM(p_dst, p_cb->local_pmm, NCI_T3T_PMM_LEN);
+
+          /* If requesting system code */
+          if (rc == T3T_POLL_RC_SC) {
+            UINT16_TO_BE_STREAM(p_dst, p_cb->system_code);
+          }
+        } else {
+          send_response = false;
+        }
+        break;
+
+      case T3T_MSG_OPC_REQ_RESPONSE_CMD:
+        /* Response Code */
+        UINT8_TO_STREAM(p_dst, T3T_MSG_OPC_REQ_RESPONSE_RSP);
+
+        /* Manufacturer ID */
+        ARRAY_TO_STREAM(p_dst, p_cb->local_nfcid2, NCI_RF_F_UID_LEN);
+
+        /* Mode */
+        UINT8_TO_STREAM(p_dst, 0);
+        break;
+
+      case T3T_MSG_OPC_REQ_SYSTEMCODE_CMD:
+        /* Response Code */
+        UINT8_TO_STREAM(p_dst, T3T_MSG_OPC_REQ_SYSTEMCODE_RSP);
+
+        /* Manufacturer ID */
+        ARRAY_TO_STREAM(p_dst, p_cb->local_nfcid2, NCI_RF_F_UID_LEN);
+
+        /* Number of system codes */
+        UINT8_TO_STREAM(p_dst, 1);
+
+        /* system codes */
+        UINT16_TO_BE_STREAM(p_dst, T3T_SYSTEM_CODE_NDEF);
+        break;
+
+      case T3T_MSG_OPC_REQ_SERVICE_CMD:
+      default:
+        /* Unhandled command */
+        CE_TRACE_ERROR1("Unhandled CE opcode: %02x", cmd_id);
+        send_response = false;
+        break;
+    }
+
+    if (send_response) {
+      p_rsp_msg->len = (uint16_t)(p_dst - p_rsp_start);
+      ce_t3t_send_to_lower(p_rsp_msg);
+    } else {
+      GKI_freebuf(p_rsp_msg);
+    }
+  } else {
+    CE_TRACE_ERROR0("CE: Unable to allocat buffer for response message");
+  }
+  GKI_freebuf(p_cmd_msg);
+}
+
+/*******************************************************************************
+**
+** Function         ce_t3t_data_cback
+**
+** Description      This callback function receives the data from NFCC.
+**
+** Returns          none
+**
+*******************************************************************************/
+void ce_t3t_data_cback(uint8_t conn_id, tNFC_DATA_CEVT* p_data) {
+  tCE_CB* p_ce_cb = &ce_cb;
+  tCE_T3T_MEM* p_cb = &p_ce_cb->mem.t3t;
+  NFC_HDR* p_msg = p_data->p_data;
+  tCE_DATA ce_data;
+  uint8_t cmd_id, bl0, entry_len, i;
+  uint8_t* p_nfcid2 = NULL;
+  uint8_t* p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+  uint8_t cmd_nfcid2[NCI_RF_F_UID_LEN];
+  uint16_t block_list_start_offset, remaining;
+  bool msg_processed = false;
+  bool block_list_ok;
+  uint8_t sod;
+  uint8_t cmd_type;
+
+#if (BT_TRACE_PROTOCOL == true)
+  DispT3TagMessage(p_msg, true);
+#endif
+  (void)conn_id;
+
+  /* If activate system code is not NDEF, or if no local NDEF contents was set,
+   * then pass data up to the app */
+  if ((p_cb->system_code != T3T_SYSTEM_CODE_NDEF) ||
+      (!p_cb->ndef_info.initialized)) {
+    ce_data.raw_frame.status = p_data->status;
+    ce_data.raw_frame.p_data = p_msg;
+    p_ce_cb->p_cback(CE_T3T_RAW_FRAME_EVT, &ce_data);
+    return;
+  }
+
+  /* Verify that message contains at least Sod and cmd_id */
+  if (p_msg->len < 2) {
+    CE_TRACE_ERROR1("CE: received invalid T3t message (invalid length: %i)",
+                    p_msg->len);
+  } else {
+    /* Get and validate command opcode */
+    STREAM_TO_UINT8(sod, p);
+    STREAM_TO_UINT8(cmd_id, p);
+
+    /* Valid command and message length */
+    cmd_type = ce_t3t_is_valid_opcode(cmd_id);
+    if (cmd_type == CE_T3T_COMMAND_INVALID) {
+      CE_TRACE_ERROR1(
+          "CE: received invalid T3t message (invalid command: 0x%02X)", cmd_id);
+    } else if (cmd_type == CE_T3T_COMMAND_FELICA) {
+      ce_t3t_handle_non_nfc_forum_cmd(p_ce_cb, cmd_id, p_msg);
+      msg_processed = true;
+    } else {
+      /* Verify that message contains at least NFCID2 and NUM services */
+      if (p_msg->len < T3T_MSG_CMD_COMMON_HDR_LEN) {
+        CE_TRACE_ERROR1("CE: received invalid T3t message (invalid length: %i)",
+                        p_msg->len);
+      } else {
+        /* Handle NFC_FORUM command (UPDATE or CHECK) */
+        STREAM_TO_ARRAY(cmd_nfcid2, p, NCI_RF_F_UID_LEN);
+        STREAM_TO_UINT8(p_cb->cur_cmd.num_services, p);
+
+        /* Calculate offset of block-list-start */
+        block_list_start_offset =
+            T3T_MSG_CMD_COMMON_HDR_LEN + 2 * p_cb->cur_cmd.num_services + 1;
+
+        if (p_cb->state == CE_T3T_STATE_NOT_ACTIVATED) {
+          CE_TRACE_ERROR2(
+              "CE: received command 0x%02X while in bad state (%i))", cmd_id,
+              p_cb->state);
+        } else if (memcmp(cmd_nfcid2, p_cb->local_nfcid2, NCI_RF_F_UID_LEN) !=
+                   0) {
+          CE_TRACE_ERROR0("CE: received invalid T3t message (invalid NFCID2)");
+          p_nfcid2 = cmd_nfcid2; /* respond with ERROR using the NFCID2 from the
+                                    command message */
+        } else if (p_msg->len < block_list_start_offset) {
+          /* Does not have minimum (including number_of_blocks field) */
+          CE_TRACE_ERROR0("CE: incomplete message");
+        } else {
+          /* Parse service code list */
+          for (i = 0; i < p_cb->cur_cmd.num_services; i++) {
+            STREAM_TO_UINT16(p_cb->cur_cmd.service_code_list[i], p);
+          }
+
+          /* Verify that block list */
+          block_list_ok = true;
+          STREAM_TO_UINT8(p_cb->cur_cmd.num_blocks, p);
+          remaining = p_msg->len - block_list_start_offset;
+          p_cb->cur_cmd.p_block_list_start = p;
+          for (i = 0; i < p_cb->cur_cmd.num_blocks; i++) {
+            /* Each entry is at lease 2 bytes long */
+            if (remaining < 2) {
+              /* Unexpected end of message (while reading block-list) */
+              CE_TRACE_ERROR0(
+                  "CE: received invalid T3t message (unexpected end of "
+                  "block-list)");
+              block_list_ok = false;
+              break;
+            }
+
+            /* Get byte0 of block-list entry */
+            bl0 = *p;
+
+            /* Validate service code index and size of block-list */
+            if ((bl0 & T3T_MSG_SERVICE_LIST_MASK) >=
+                p_cb->cur_cmd.num_services) {
+              /* Invalid service code */
+              CE_TRACE_ERROR1(
+                  "CE: received invalid T3t message (invalid service index: "
+                  "%i)",
+                  (bl0 & T3T_MSG_SERVICE_LIST_MASK));
+              block_list_ok = false;
+              break;
+            } else if ((!(bl0 & T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT)) &&
+                       (remaining < 3)) {
+              /* Unexpected end of message (while reading 3-byte entry) */
+              CE_TRACE_ERROR0(
+                  "CE: received invalid T3t message (unexpected end of "
+                  "block-list)");
+              block_list_ok = false;
+              break;
+            }
+
+            /* Advance pointers to next block-list entry */
+            entry_len = (bl0 & T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT) ? 2 : 3;
+            p += entry_len;
+            remaining -= entry_len;
+          }
+
+          /* Block list is verified. Call CHECK or UPDATE handler */
+          if (block_list_ok) {
+            p_cb->cur_cmd.p_block_data_start = p;
+            if (cmd_id == T3T_MSG_OPC_CHECK_CMD) {
+              /* This is a CHECK command. Sanity check: there shouldn't be any
+               * more data remaining after reading block list */
+              if (remaining) {
+                CE_TRACE_ERROR1(
+                    "CE: unexpected data after after CHECK command (#i bytes)",
+                    remaining);
+              }
+              ce_t3t_handle_check_cmd(p_ce_cb, p_msg);
+              msg_processed = true;
+            } else {
+              /* This is an UPDATE command. See if message contains all the
+               * expected block data */
+              if (remaining < p_cb->cur_cmd.num_blocks * T3T_MSG_BLOCKSIZE) {
+                CE_TRACE_ERROR0("CE: unexpected end of block-data");
+              } else {
+                ce_t3t_handle_update_cmd(p_ce_cb, p_msg);
+                msg_processed = true;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  if (!msg_processed) {
+    ce_t3t_send_rsp(p_ce_cb, p_nfcid2, T3T_MSG_OPC_CHECK_RSP,
+                    T3T_MSG_RSP_STATUS_ERROR,
+                    T3T_MSG_RSP_STATUS2_ERROR_PROCESSING);
+    GKI_freebuf(p_msg);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         ce_t3t_conn_cback
+**
+** Description      This callback function receives the events/data from NFCC.
+**
+** Returns          none
+**
+*******************************************************************************/
+void ce_t3t_conn_cback(uint8_t conn_id, tNFC_CONN_EVT event,
+                       tNFC_CONN* p_data) {
+  tCE_T3T_MEM* p_cb = &ce_cb.mem.t3t;
+
+  CE_TRACE_DEBUG2("ce_t3t_conn_cback: conn_id=%i, evt=%i", conn_id, event);
+
+  switch (event) {
+    case NFC_CONN_CREATE_CEVT:
+      break;
+
+    case NFC_CONN_CLOSE_CEVT:
+      p_cb->state = CE_T3T_STATE_NOT_ACTIVATED;
+      break;
+
+    case NFC_DATA_CEVT:
+      if (p_data->data.status == NFC_STATUS_OK) {
+        ce_t3t_data_cback(conn_id, &p_data->data);
+      }
+      break;
+
+    case NFC_DEACTIVATE_CEVT:
+      p_cb->state = CE_T3T_STATE_NOT_ACTIVATED;
+      NFC_SetStaticRfCback(NULL);
+      break;
+
+    default:
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         ce_select_t3t
+**
+** Description      Select Type 3 Tag
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS ce_select_t3t(uint16_t system_code,
+                          uint8_t nfcid2[NCI_RF_F_UID_LEN]) {
+  tCE_T3T_MEM* p_cb = &ce_cb.mem.t3t;
+
+  CE_TRACE_DEBUG0("ce_select_t3t ()");
+
+  p_cb->state = CE_T3T_STATE_IDLE;
+  p_cb->system_code = system_code;
+  memcpy(p_cb->local_nfcid2, nfcid2, NCI_RF_F_UID_LEN);
+
+  NFC_SetStaticRfCback(ce_t3t_conn_cback);
+  return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         CE_T3tSetLocalNDEFMsg
+**
+** Description      Initialise CE Type 3 Tag with mandatory NDEF message
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS CE_T3tSetLocalNDEFMsg(bool read_only, uint32_t size_max,
+                                  uint32_t size_current, uint8_t* p_buf,
+                                  uint8_t* p_scratch_buf) {
+  tCE_T3T_MEM* p_cb = &ce_cb.mem.t3t;
+
+  CE_TRACE_API3("CE_T3tSetContent: ro=%i, size_max=%i, size_current=%i",
+                read_only, size_max, size_current);
+
+  /* Verify scratch buffer was provided if NDEF message is read/write */
+  if ((!read_only) && (!p_scratch_buf)) {
+    CE_TRACE_ERROR0(
+        "CE_T3tSetLocalNDEFMsg (): p_scratch_buf cannot be NULL if not "
+        "read-only");
+    return NFC_STATUS_FAILED;
+  }
+
+  /* Check if disabling the local NDEF */
+  if (!p_buf) {
+    p_cb->ndef_info.initialized = false;
+  }
+  /* Save ndef attributes */
+  else {
+    p_cb->ndef_info.initialized = true;
+    p_cb->ndef_info.ln = size_current; /* Current length */
+    p_cb->ndef_info.nmaxb = (uint16_t)(
+        (size_max + 15) / T3T_MSG_BLOCKSIZE); /* Max length (in blocks) */
+    p_cb->ndef_info.rwflag =
+        (read_only) ? T3T_MSG_NDEF_RWFLAG_RO : T3T_MSG_NDEF_RWFLAG_RW;
+    p_cb->ndef_info.writef = T3T_MSG_NDEF_WRITEF_OFF;
+    p_cb->ndef_info.version = 0x10;
+    p_cb->ndef_info.p_buf = p_buf;
+    p_cb->ndef_info.p_scratch_buf = p_scratch_buf;
+
+    /* Initiate scratch buffer with same contents as read-buffer */
+    if (p_scratch_buf) {
+      p_cb->ndef_info.scratch_ln = p_cb->ndef_info.ln;
+      p_cb->ndef_info.scratch_writef = T3T_MSG_NDEF_WRITEF_OFF;
+      memcpy(p_scratch_buf, p_buf, p_cb->ndef_info.ln);
+    }
+  }
+
+  return (NFC_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         CE_T3tSetLocalNDefParams
+**
+** Description      Sets T3T-specific NDEF parameters. (Optional - if not
+**                  called, then CE will use default parameters)
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS CE_T3tSetLocalNDefParams(uint8_t nbr, uint8_t nbw) {
+  tCE_T3T_MEM* p_cb = &ce_cb.mem.t3t;
+
+  CE_TRACE_API2("CE_T3tSetLocalNDefParams: nbr=%i, nbw=%i", nbr, nbw);
+
+  /* Validate */
+  if ((nbr > T3T_MSG_NUM_BLOCKS_CHECK_MAX) ||
+      (nbw > T3T_MSG_NUM_BLOCKS_UPDATE_MAX) || (nbr < 1) || (nbw < 1)) {
+    CE_TRACE_ERROR0("CE_T3tSetLocalNDefParams: invalid params");
+    return NFC_STATUS_FAILED;
+  }
+
+  p_cb->ndef_info.nbr = nbr;
+  p_cb->ndef_info.nbw = nbw;
+
+  return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         CE_T3tSendCheckRsp
+**
+** Description      Send CHECK response message
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS CE_T3tSendCheckRsp(uint8_t status1, uint8_t status2,
+                               uint8_t num_blocks, uint8_t* p_block_data) {
+  tCE_T3T_MEM* p_cb = &ce_cb.mem.t3t;
+  tNFC_STATUS retval = NFC_STATUS_OK;
+  NFC_HDR* p_rsp_msg;
+  uint8_t* p_dst, *p_rsp_start;
+
+  CE_TRACE_API3("CE_T3tCheckRsp: status1=0x%02X, status2=0x%02X, num_blocks=%i",
+                status1, status2, num_blocks);
+
+  /* Validate num_blocks */
+  if (num_blocks > T3T_MSG_NUM_BLOCKS_CHECK_MAX) {
+    CE_TRACE_ERROR2("CE_T3tCheckRsp num_blocks (%i) exceeds maximum (%i)",
+                    num_blocks, T3T_MSG_NUM_BLOCKS_CHECK_MAX);
+    return (NFC_STATUS_FAILED);
+  }
+
+  p_rsp_msg = ce_t3t_get_rsp_buf();
+  if (p_rsp_msg != NULL) {
+    p_dst = p_rsp_start = (uint8_t*)(p_rsp_msg + 1) + p_rsp_msg->offset;
+
+    /* Response Code */
+    UINT8_TO_STREAM(p_dst, T3T_MSG_OPC_CHECK_RSP);
+
+    /* Manufacturer ID */
+    ARRAY_TO_STREAM(p_dst, p_cb->local_nfcid2, NCI_RF_F_UID_LEN);
+
+    /* Status1 and Status2 */
+    UINT8_TO_STREAM(p_dst, status1);
+    UINT8_TO_STREAM(p_dst, status2);
+
+    if (status1 == T3T_MSG_RSP_STATUS_OK) {
+      UINT8_TO_STREAM(p_dst, num_blocks);
+      ARRAY_TO_STREAM(p_dst, p_block_data, (num_blocks * T3T_MSG_BLOCKSIZE));
+    }
+
+    p_rsp_msg->len = (uint16_t)(p_dst - p_rsp_start);
+    ce_t3t_send_to_lower(p_rsp_msg);
+  } else {
+    CE_TRACE_ERROR0("CE: Unable to allocate buffer for response message");
+  }
+
+  return (retval);
+}
+
+/*******************************************************************************
+**
+** Function         CE_T3tSendUpdateRsp
+**
+** Description      Send UPDATE response message
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS CE_T3tSendUpdateRsp(uint8_t status1, uint8_t status2) {
+  tNFC_STATUS retval = NFC_STATUS_OK;
+  tCE_CB* p_ce_cb = &ce_cb;
+
+  CE_TRACE_API2("CE_T3tUpdateRsp: status1=0x%02X, status2=0x%02X", status1,
+                status2);
+  ce_t3t_send_rsp(p_ce_cb, NULL, T3T_MSG_OPC_UPDATE_RSP, status1, status2);
+
+  return (retval);
+}
diff --git a/src/nfc/tags/ce_t4t.c b/src/nfc/tags/ce_t4t.c
new file mode 100644
index 0000000..ae3af2a
--- /dev/null
+++ b/src/nfc/tags/ce_t4t.c
@@ -0,0 +1,1075 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the implementation for Type 4 tag in Card Emulation
+ *  mode.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "trace_api.h"
+
+#include "nfc_api.h"
+#include "nfc_int.h"
+#include "ce_api.h"
+#include "ce_int.h"
+#include "tags_int.h"
+#include "gki.h"
+
+#if (CE_TEST_INCLUDED == true) /* test only */
+bool mapping_aid_test_enabled = false;
+uint8_t ce_test_tag_app_id[T4T_V20_NDEF_TAG_AID_LEN] = {0xD2, 0x76, 0x00, 0x00,
+                                                        0x85, 0x01, 0x01};
+#endif
+
+/*******************************************************************************
+**
+** Function         ce_t4t_send_to_lower
+**
+** Description      Send packet to lower layer
+**
+** Returns          true if success
+**
+*******************************************************************************/
+static bool ce_t4t_send_to_lower(NFC_HDR* p_r_apdu) {
+#if (BT_TRACE_PROTOCOL == true)
+  DispCET4Tags(p_r_apdu, false);
+#endif
+
+  if (NFC_SendData(NFC_RF_CONN_ID, p_r_apdu) != NFC_STATUS_OK) {
+    CE_TRACE_ERROR0("ce_t4t_send_to_lower (): NFC_SendData () failed");
+    return false;
+  }
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         ce_t4t_send_status
+**
+** Description      Send status on R-APDU to peer
+**
+** Returns          true if success
+**
+*******************************************************************************/
+static bool ce_t4t_send_status(uint16_t status) {
+  NFC_HDR* p_r_apdu;
+  uint8_t* p;
+
+  CE_TRACE_DEBUG1("ce_t4t_send_status (): Status:0x%04X", status);
+
+  p_r_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_CE_POOL_ID);
+
+  if (!p_r_apdu) {
+    CE_TRACE_ERROR0("ce_t4t_send_status (): Cannot allocate buffer");
+    return false;
+  }
+
+  p_r_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
+
+  UINT16_TO_BE_STREAM(p, status);
+
+  p_r_apdu->len = T4T_RSP_STATUS_WORDS_SIZE;
+
+  if (!ce_t4t_send_to_lower(p_r_apdu)) {
+    return false;
+  }
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         ce_t4t_select_file
+**
+** Description      Select a file
+**
+** Returns          true if success
+**
+*******************************************************************************/
+static bool ce_t4t_select_file(uint16_t file_id) {
+  tCE_T4T_MEM* p_t4t = &ce_cb.mem.t4t;
+
+  CE_TRACE_DEBUG1("ce_t4t_select_file (): FileID:0x%04X", file_id);
+
+  if (file_id == T4T_CC_FILE_ID) {
+    CE_TRACE_DEBUG0("ce_t4t_select_file (): Select CC file");
+
+    p_t4t->status |= CE_T4T_STATUS_CC_FILE_SELECTED;
+    p_t4t->status &= ~(CE_T4T_STATUS_NDEF_SELECTED);
+
+    return true;
+  }
+
+  if (file_id == CE_T4T_MANDATORY_NDEF_FILE_ID) {
+    CE_TRACE_DEBUG3(
+        "ce_t4t_select_file (): NLEN:0x%04X, MaxFileSize:0x%04X, "
+        "WriteAccess:%s",
+        p_t4t->nlen, p_t4t->max_file_size,
+        (p_t4t->status & CE_T4T_STATUS_NDEF_FILE_READ_ONLY ? "RW" : "RO"));
+
+    p_t4t->status |= CE_T4T_STATUS_NDEF_SELECTED;
+    p_t4t->status &= ~(CE_T4T_STATUS_CC_FILE_SELECTED);
+
+    return true;
+  } else {
+    CE_TRACE_ERROR1("ce_t4t_select_file (): Cannot find file ID (0x%04X)",
+                    file_id);
+
+    p_t4t->status &= ~(CE_T4T_STATUS_CC_FILE_SELECTED);
+    p_t4t->status &= ~(CE_T4T_STATUS_NDEF_SELECTED);
+
+    return false;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         ce_t4t_read_binary
+**
+** Description      Read data from selected file and send R-APDU to peer
+**
+** Returns          true if success
+**
+*******************************************************************************/
+static bool ce_t4t_read_binary(uint16_t offset, uint8_t length) {
+  tCE_T4T_MEM* p_t4t = &ce_cb.mem.t4t;
+  uint8_t* p_src = NULL, *p_dst;
+  NFC_HDR* p_r_apdu;
+
+  CE_TRACE_DEBUG3(
+      "ce_t4t_read_binary (): Offset:0x%04X, Length:0x%04X, selected status = "
+      "0x%02X",
+      offset, length, p_t4t->status);
+
+  if (p_t4t->status & CE_T4T_STATUS_CC_FILE_SELECTED) {
+    p_src = p_t4t->cc_file;
+  } else if (p_t4t->status & CE_T4T_STATUS_NDEF_SELECTED) {
+    if (p_t4t->p_scratch_buf)
+      p_src = p_t4t->p_scratch_buf;
+    else
+      p_src = p_t4t->p_ndef_msg;
+  }
+
+  if (p_src) {
+    p_r_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_CE_POOL_ID);
+
+    if (!p_r_apdu) {
+      CE_TRACE_ERROR0("ce_t4t_read_binary (): Cannot allocate buffer");
+      return false;
+    }
+
+    p_r_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+    p_dst = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
+
+    p_r_apdu->len = length;
+
+    /* add NLEN before NDEF message and adjust offset             */
+    /* if NDEF file is selected and offset < T4T_FILE_LENGTH_SIZE */
+    if ((p_t4t->status & CE_T4T_STATUS_NDEF_SELECTED) && (length > 0)) {
+      if (offset == 0) {
+        UINT16_TO_BE_STREAM(p_dst, p_t4t->nlen);
+
+        if (length == 1) {
+          length = 0;
+          p_dst--;
+        } else /* length >= 2 */
+          length -= T4T_FILE_LENGTH_SIZE;
+      } else if (offset == 1) {
+        UINT8_TO_BE_STREAM(p_dst, (uint8_t)(p_t4t->nlen));
+
+        offset = 0;
+        length--;
+      } else {
+        offset -= T4T_FILE_LENGTH_SIZE;
+      }
+    }
+
+    if (length > 0) {
+      memcpy(p_dst, p_src + offset, length);
+      p_dst += length;
+    }
+
+    UINT16_TO_BE_STREAM(p_dst, T4T_RSP_CMD_CMPLTED);
+    p_r_apdu->len += T4T_RSP_STATUS_WORDS_SIZE;
+
+    if (!ce_t4t_send_to_lower(p_r_apdu)) {
+      return false;
+    }
+    return true;
+  } else {
+    CE_TRACE_ERROR0("ce_t4t_read_binary (): No selected file");
+
+    if (!ce_t4t_send_status(T4T_RSP_CMD_NOT_ALLOWED)) {
+      return false;
+    }
+    return true;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         ce_t4t_update_binary
+**
+** Description      Update file and send R-APDU to peer
+**
+** Returns          true if success
+**
+*******************************************************************************/
+static bool ce_t4t_update_binary(uint16_t offset, uint8_t length,
+                                 uint8_t* p_data) {
+  tCE_T4T_MEM* p_t4t = &ce_cb.mem.t4t;
+  uint8_t* p;
+  uint8_t file_length[2];
+  uint16_t starting_offset;
+  tCE_DATA ce_data;
+
+  CE_TRACE_DEBUG3(
+      "ce_t4t_update_binary (): Offset:0x%04X, Length:0x%04X, selected status "
+      "= 0x%02X",
+      offset, length, p_t4t->status);
+
+  starting_offset = offset;
+
+  /* update file size (NLEN) */
+  if ((offset < T4T_FILE_LENGTH_SIZE) && (length > 0)) {
+    p = file_length;
+    UINT16_TO_BE_STREAM(p, p_t4t->nlen);
+
+    while ((offset < T4T_FILE_LENGTH_SIZE) && (length > 0)) {
+      *(file_length + offset++) = *(p_data++);
+      length--;
+    }
+
+    p = file_length;
+    BE_STREAM_TO_UINT16(p_t4t->nlen, p);
+  }
+
+  if (length > 0)
+    memcpy(p_t4t->p_scratch_buf + offset - T4T_FILE_LENGTH_SIZE, p_data,
+           length);
+
+  /* if this is the last step: writing non-zero length in NLEN */
+  if ((starting_offset == 0) && (p_t4t->nlen > 0)) {
+    nfc_stop_quick_timer(&p_t4t->timer);
+
+    if (ce_cb.p_cback) {
+      ce_data.update_info.status = NFC_STATUS_OK;
+      ce_data.update_info.length = p_t4t->nlen;
+      ce_data.update_info.p_data = p_t4t->p_scratch_buf;
+
+      (*ce_cb.p_cback)(CE_T4T_NDEF_UPDATE_CPLT_EVT, &ce_data);
+      CE_TRACE_DEBUG0(
+          "ce_t4t_update_binary (): Sent CE_T4T_NDEF_UPDATE_CPLT_EVT");
+    }
+
+    p_t4t->status &= ~(CE_T4T_STATUS_NDEF_FILE_UPDATING);
+  } else if (!(p_t4t->status & CE_T4T_STATUS_NDEF_FILE_UPDATING)) {
+    /* starting of updating */
+    p_t4t->status |= CE_T4T_STATUS_NDEF_FILE_UPDATING;
+
+    nfc_start_quick_timer(
+        &p_t4t->timer, NFC_TTYPE_CE_T4T_UPDATE,
+        (CE_T4T_TOUT_UPDATE * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+
+    if (ce_cb.p_cback) (*ce_cb.p_cback)(CE_T4T_NDEF_UPDATE_START_EVT, NULL);
+  }
+
+  if (!ce_t4t_send_status(T4T_RSP_CMD_CMPLTED)) {
+    return false;
+  } else {
+    return true;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         ce_t4t_set_version_in_cc
+**
+** Description      update version in CC file
+**                  If reader selects NDEF Tag Application with V1.0 AID then
+**                  set V1.0 into CC file.
+**                  If reader selects NDEF Tag Application with V2.0 AID then
+**                  set V2.0 into CC file.
+**
+** Returns          None
+**
+*******************************************************************************/
+static void ce_t4t_set_version_in_cc(uint8_t version) {
+  tCE_T4T_MEM* p_t4t = &ce_cb.mem.t4t;
+  uint8_t* p;
+
+  CE_TRACE_DEBUG1("ce_t4t_set_version_in_cc (): version = 0x%02X", version);
+
+  p = p_t4t->cc_file + T4T_VERSION_OFFSET_IN_CC;
+
+  UINT8_TO_BE_STREAM(p, version);
+}
+
+/*******************************************************************************
+**
+** Function         ce_t4t_process_select_file_cmd
+**
+** Description      This function processes Select Command by file ID.
+**
+** Returns          true if success
+**
+*******************************************************************************/
+static bool ce_t4t_process_select_file_cmd(uint8_t* p_cmd) {
+  uint8_t data_len;
+  uint16_t file_id, status_words;
+
+  CE_TRACE_DEBUG0("ce_t4t_process_select_file_cmd ()");
+
+  p_cmd++; /* skip P2 */
+
+  /* Lc Byte */
+  BE_STREAM_TO_UINT8(data_len, p_cmd);
+
+  if (data_len == T4T_FILE_ID_SIZE) {
+    /* File ID */
+    BE_STREAM_TO_UINT16(file_id, p_cmd);
+
+    if (ce_t4t_select_file(file_id)) {
+      status_words = T4T_RSP_CMD_CMPLTED;
+    } else {
+      status_words = T4T_RSP_NOT_FOUND;
+    }
+  } else {
+    status_words = T4T_RSP_WRONG_LENGTH;
+  }
+
+  if (!ce_t4t_send_status(status_words)) {
+    return false;
+  }
+
+  if (status_words == T4T_RSP_CMD_CMPLTED) {
+    return true;
+  }
+  return false;
+}
+
+/*******************************************************************************
+**
+** Function         ce_t4t_process_select_app_cmd
+**
+** Description      This function processes Select Command by AID.
+**
+** Returns          none
+**
+*******************************************************************************/
+static void ce_t4t_process_select_app_cmd(uint8_t* p_cmd, NFC_HDR* p_c_apdu) {
+  uint8_t data_len;
+  uint16_t status_words = 0x0000; /* invalid status words */
+  tCE_DATA ce_data;
+  uint8_t xx;
+
+  CE_TRACE_DEBUG0("ce_t4t_process_select_app_cmd ()");
+
+  p_cmd++; /* skip P2 */
+
+  /* Lc Byte */
+  BE_STREAM_TO_UINT8(data_len, p_cmd);
+
+#if (CE_TEST_INCLUDED == true)
+  if (mapping_aid_test_enabled) {
+    if ((data_len == T4T_V20_NDEF_TAG_AID_LEN) &&
+        (!memcmp(p_cmd, ce_test_tag_app_id, data_len)) &&
+        (ce_cb.mem.t4t.p_ndef_msg)) {
+      GKI_freebuf(p_c_apdu);
+      ce_t4t_send_status((uint16_t)T4T_RSP_CMD_CMPLTED);
+      return;
+    }
+  }
+#endif
+
+  /*
+  ** Compare AIDs registered by applications
+  ** if found, use callback of the application
+  ** otherwise, return error and maintain the same status
+  */
+  ce_cb.mem.t4t.selected_aid_idx = CE_T4T_MAX_REG_AID;
+  for (xx = 0; xx < CE_T4T_MAX_REG_AID; xx++) {
+    if ((ce_cb.mem.t4t.reg_aid[xx].aid_len > 0) &&
+        (ce_cb.mem.t4t.reg_aid[xx].aid_len == data_len) &&
+        (!(memcmp(ce_cb.mem.t4t.reg_aid[xx].aid, p_cmd, data_len)))) {
+      ce_cb.mem.t4t.selected_aid_idx = xx;
+      break;
+    }
+  }
+
+  /* if found matched AID */
+  if (ce_cb.mem.t4t.selected_aid_idx < CE_T4T_MAX_REG_AID) {
+    ce_cb.mem.t4t.status &= ~(CE_T4T_STATUS_CC_FILE_SELECTED);
+    ce_cb.mem.t4t.status &= ~(CE_T4T_STATUS_NDEF_SELECTED);
+    ce_cb.mem.t4t.status &= ~(CE_T4T_STATUS_T4T_APP_SELECTED);
+    ce_cb.mem.t4t.status &= ~(CE_T4T_STATUS_WILDCARD_AID_SELECTED);
+    ce_cb.mem.t4t.status |= CE_T4T_STATUS_REG_AID_SELECTED;
+
+    CE_TRACE_DEBUG4(
+        "ce_t4t_process_select_app_cmd (): Registered AID[%02X%02X%02X%02X...] "
+        "is selected",
+        ce_cb.mem.t4t.reg_aid[ce_cb.mem.t4t.selected_aid_idx].aid[0],
+        ce_cb.mem.t4t.reg_aid[ce_cb.mem.t4t.selected_aid_idx].aid[1],
+        ce_cb.mem.t4t.reg_aid[ce_cb.mem.t4t.selected_aid_idx].aid[2],
+        ce_cb.mem.t4t.reg_aid[ce_cb.mem.t4t.selected_aid_idx].aid[3]);
+
+    ce_data.raw_frame.status = NFC_STATUS_OK;
+    ce_data.raw_frame.p_data = p_c_apdu;
+    ce_data.raw_frame.aid_handle = ce_cb.mem.t4t.selected_aid_idx;
+
+    p_c_apdu = NULL;
+
+    (*(ce_cb.mem.t4t.reg_aid[ce_cb.mem.t4t.selected_aid_idx].p_cback))(
+        CE_T4T_RAW_FRAME_EVT, &ce_data);
+  } else if ((data_len == T4T_V20_NDEF_TAG_AID_LEN) &&
+             (!memcmp(p_cmd, t4t_v20_ndef_tag_aid, data_len - 1)) &&
+             (ce_cb.mem.t4t.p_ndef_msg)) {
+    p_cmd += data_len - 1;
+
+    /* adjust version if possible */
+    if ((*p_cmd) == 0x00) {
+      ce_t4t_set_version_in_cc(T4T_VERSION_1_0);
+      status_words = T4T_RSP_CMD_CMPLTED;
+    } else if ((*p_cmd) == 0x01) {
+      ce_t4t_set_version_in_cc(T4T_VERSION_2_0);
+      status_words = T4T_RSP_CMD_CMPLTED;
+    } else {
+      CE_TRACE_DEBUG0(
+          "ce_t4t_process_select_app_cmd (): Not found matched AID");
+      status_words = T4T_RSP_NOT_FOUND;
+    }
+  } else if (ce_cb.mem.t4t.p_wildcard_aid_cback) {
+    ce_cb.mem.t4t.status &= ~(CE_T4T_STATUS_CC_FILE_SELECTED);
+    ce_cb.mem.t4t.status &= ~(CE_T4T_STATUS_NDEF_SELECTED);
+    ce_cb.mem.t4t.status &= ~(CE_T4T_STATUS_T4T_APP_SELECTED);
+    ce_cb.mem.t4t.status &= ~(CE_T4T_STATUS_REG_AID_SELECTED);
+    ce_cb.mem.t4t.status |= CE_T4T_STATUS_WILDCARD_AID_SELECTED;
+
+    ce_data.raw_frame.status = NFC_STATUS_OK;
+    ce_data.raw_frame.p_data = p_c_apdu;
+    ce_data.raw_frame.aid_handle = CE_T4T_WILDCARD_AID_HANDLE;
+    p_c_apdu = NULL;
+
+    CE_TRACE_DEBUG0(
+        "CET4T: Forward raw frame (SELECT APP) to wildcard AID handler");
+    (*(ce_cb.mem.t4t.p_wildcard_aid_cback))(CE_T4T_RAW_FRAME_EVT, &ce_data);
+  } else {
+    CE_TRACE_DEBUG0(
+        "ce_t4t_process_select_app_cmd (): Not found matched AID or not "
+        "listening T4T NDEF");
+    status_words = T4T_RSP_NOT_FOUND;
+  }
+
+  if (status_words) {
+    /* if T4T CE can support */
+    if (status_words == T4T_RSP_CMD_CMPLTED) {
+      ce_cb.mem.t4t.status &= ~(CE_T4T_STATUS_CC_FILE_SELECTED);
+      ce_cb.mem.t4t.status &= ~(CE_T4T_STATUS_NDEF_SELECTED);
+      ce_cb.mem.t4t.status &= ~(CE_T4T_STATUS_REG_AID_SELECTED);
+      ce_cb.mem.t4t.status &= ~(CE_T4T_STATUS_WILDCARD_AID_SELECTED);
+      ce_cb.mem.t4t.status |= CE_T4T_STATUS_T4T_APP_SELECTED;
+
+      CE_TRACE_DEBUG0("ce_t4t_process_select_app_cmd (): T4T CE App selected");
+    }
+
+    ce_t4t_send_status(status_words);
+    GKI_freebuf(p_c_apdu);
+  }
+  /* if status_words is not set then upper layer will send R-APDU */
+
+  return;
+}
+
+/*******************************************************************************
+**
+** Function         ce_t4t_process_timeout
+**
+** Description      process timeout event
+**
+** Returns          none
+**
+*******************************************************************************/
+void ce_t4t_process_timeout(TIMER_LIST_ENT* p_tle) {
+  tCE_T4T_MEM* p_t4t = &ce_cb.mem.t4t;
+  tCE_DATA ce_data;
+
+  CE_TRACE_DEBUG1("ce_t4t_process_timeout () event=%d", p_tle->event);
+
+  if (p_tle->event == NFC_TTYPE_CE_T4T_UPDATE) {
+    if (p_t4t->status & CE_T4T_STATUS_NDEF_FILE_UPDATING) {
+      ce_data.status = NFC_STATUS_TIMEOUT;
+
+      if (ce_cb.p_cback)
+        (*ce_cb.p_cback)(CE_T4T_NDEF_UPDATE_ABORT_EVT, &ce_data);
+
+      p_t4t->status &= ~(CE_T4T_STATUS_NDEF_FILE_UPDATING);
+    }
+  } else {
+    CE_TRACE_ERROR1("ce_t4t_process_timeout () unknown event=%d", p_tle->event);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         ce_t4t_data_cback
+**
+** Description      This callback function receives the data from NFCC.
+**
+** Returns          none
+**
+*******************************************************************************/
+static void ce_t4t_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
+                              tNFC_CONN* p_data) {
+  NFC_HDR* p_c_apdu;
+  uint8_t* p_cmd;
+  uint8_t cla, instruct, select_type = 0;
+  uint16_t offset, max_file_size, length;
+  tCE_DATA ce_data;
+
+  if (event == NFC_DEACTIVATE_CEVT) {
+    NFC_SetStaticRfCback(NULL);
+    return;
+  }
+  if (event != NFC_DATA_CEVT) {
+    return;
+  }
+
+  p_c_apdu = (NFC_HDR*)p_data->data.p_data;
+
+#if (BT_TRACE_PROTOCOL == true)
+  DispCET4Tags(p_c_apdu, true);
+#endif
+
+  CE_TRACE_DEBUG1("ce_t4t_data_cback (): conn_id = 0x%02X", conn_id);
+
+  p_cmd = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
+
+  /* Class Byte */
+  BE_STREAM_TO_UINT8(cla, p_cmd);
+
+  /* Don't check class if registered AID has been selected */
+  if ((cla != T4T_CMD_CLASS) &&
+      ((ce_cb.mem.t4t.status & CE_T4T_STATUS_REG_AID_SELECTED) == 0) &&
+      ((ce_cb.mem.t4t.status & CE_T4T_STATUS_WILDCARD_AID_SELECTED) == 0)) {
+    GKI_freebuf(p_c_apdu);
+    ce_t4t_send_status(T4T_RSP_CLASS_NOT_SUPPORTED);
+    return;
+  }
+
+  /* Instruction Byte */
+  BE_STREAM_TO_UINT8(instruct, p_cmd);
+
+  if ((cla == T4T_CMD_CLASS) && (instruct == T4T_CMD_INS_SELECT)) {
+    /* P1 Byte */
+    BE_STREAM_TO_UINT8(select_type, p_cmd);
+
+    if (select_type == T4T_CMD_P1_SELECT_BY_NAME) {
+      ce_t4t_process_select_app_cmd(p_cmd, p_c_apdu);
+      return;
+    }
+  }
+
+  /* if registered AID is selected */
+  if (ce_cb.mem.t4t.status & CE_T4T_STATUS_REG_AID_SELECTED) {
+    CE_TRACE_DEBUG0("CET4T: Forward raw frame to registered AID");
+
+    /* forward raw frame to upper layer */
+    if (ce_cb.mem.t4t.selected_aid_idx < CE_T4T_MAX_REG_AID) {
+      ce_data.raw_frame.status = p_data->data.status;
+      ce_data.raw_frame.p_data = p_c_apdu;
+      ce_data.raw_frame.aid_handle = ce_cb.mem.t4t.selected_aid_idx;
+      p_c_apdu = NULL;
+
+      (*(ce_cb.mem.t4t.reg_aid[ce_cb.mem.t4t.selected_aid_idx].p_cback))(
+          CE_T4T_RAW_FRAME_EVT, &ce_data);
+    } else {
+      GKI_freebuf(p_c_apdu);
+      ce_t4t_send_status(T4T_RSP_NOT_FOUND);
+    }
+  } else if (ce_cb.mem.t4t.status & CE_T4T_STATUS_WILDCARD_AID_SELECTED) {
+    CE_TRACE_DEBUG0("CET4T: Forward raw frame to wildcard AID handler");
+
+    /* forward raw frame to upper layer */
+    ce_data.raw_frame.status = p_data->data.status;
+    ce_data.raw_frame.p_data = p_c_apdu;
+    ce_data.raw_frame.aid_handle = CE_T4T_WILDCARD_AID_HANDLE;
+    p_c_apdu = NULL;
+
+    (*(ce_cb.mem.t4t.p_wildcard_aid_cback))(CE_T4T_RAW_FRAME_EVT, &ce_data);
+  } else if (ce_cb.mem.t4t.status & CE_T4T_STATUS_T4T_APP_SELECTED) {
+    if (instruct == T4T_CMD_INS_SELECT) {
+      /* P1 Byte is already parsed */
+      if (select_type == T4T_CMD_P1_SELECT_BY_FILE_ID) {
+        ce_t4t_process_select_file_cmd(p_cmd);
+      } else {
+        CE_TRACE_ERROR1("CET4T: Bad P1 byte (0x%02X)", select_type);
+        ce_t4t_send_status(T4T_RSP_WRONG_PARAMS);
+      }
+    } else if (instruct == T4T_CMD_INS_READ_BINARY) {
+      if ((ce_cb.mem.t4t.status & CE_T4T_STATUS_CC_FILE_SELECTED) ||
+          (ce_cb.mem.t4t.status & CE_T4T_STATUS_NDEF_SELECTED)) {
+        if (ce_cb.mem.t4t.status & CE_T4T_STATUS_CC_FILE_SELECTED) {
+          max_file_size = T4T_FC_TLV_OFFSET_IN_CC + T4T_FILE_CONTROL_TLV_SIZE;
+        } else {
+          max_file_size = ce_cb.mem.t4t.max_file_size;
+        }
+
+        BE_STREAM_TO_UINT16(offset, p_cmd); /* Offset */
+        BE_STREAM_TO_UINT8(length, p_cmd);  /* Le     */
+
+        /* check if valid parameters */
+        if ((uint32_t)length <= CE_T4T_MAX_LE) {
+          /* CE allows to read more than current file size but not max file size
+           */
+          if (length + offset > max_file_size) {
+            if (offset < max_file_size) {
+              length = (uint8_t)(max_file_size - offset);
+
+              CE_TRACE_DEBUG2(
+                  "CET4T: length is reduced to %d by max_file_size (%d)",
+                  length, max_file_size);
+            } else {
+              CE_TRACE_ERROR2(
+                  "CET4T: offset (%d) must be less than max_file_size (%d)",
+                  offset, max_file_size);
+              length = 0;
+            }
+          }
+        } else {
+          CE_TRACE_ERROR2("CET4T: length (%d) must be less than MLe (%d)",
+                          length, CE_T4T_MAX_LE);
+          length = 0;
+        }
+
+        if (length > 0)
+          ce_t4t_read_binary(offset, length);
+        else
+          ce_t4t_send_status(T4T_RSP_WRONG_PARAMS);
+      } else {
+        CE_TRACE_ERROR0("CET4T: File has not been selected");
+        ce_t4t_send_status(T4T_RSP_CMD_NOT_ALLOWED);
+      }
+    } else if (instruct == T4T_CMD_INS_UPDATE_BINARY) {
+      if (ce_cb.mem.t4t.status & CE_T4T_STATUS_NDEF_FILE_READ_ONLY) {
+        CE_TRACE_ERROR0("CET4T: No access right");
+        ce_t4t_send_status(T4T_RSP_CMD_NOT_ALLOWED);
+      } else if (ce_cb.mem.t4t.status & CE_T4T_STATUS_NDEF_SELECTED) {
+        BE_STREAM_TO_UINT16(offset, p_cmd); /* Offset */
+        BE_STREAM_TO_UINT8(length, p_cmd);  /* Lc     */
+
+        /* check if valid parameters */
+        if ((uint32_t)length <= CE_T4T_MAX_LC) {
+          if (length + offset > ce_cb.mem.t4t.max_file_size) {
+            CE_TRACE_ERROR3(
+                "CET4T: length (%d) + offset (%d) must be less than "
+                "max_file_size (%d)",
+                length, offset, ce_cb.mem.t4t.max_file_size);
+            length = 0;
+          }
+        } else {
+          CE_TRACE_ERROR2("CET4T: length (%d) must be less than MLc (%d)",
+                          length, CE_T4T_MAX_LC);
+          length = 0;
+        }
+
+        if (length > 0)
+          ce_t4t_update_binary(offset, length, p_cmd);
+        else
+          ce_t4t_send_status(T4T_RSP_WRONG_PARAMS);
+      } else {
+        CE_TRACE_ERROR0("CET4T: NDEF File has not been selected");
+        ce_t4t_send_status(T4T_RSP_CMD_NOT_ALLOWED);
+      }
+    } else {
+      CE_TRACE_ERROR1("CET4T: Unsupported Instruction byte (0x%02X)", instruct);
+      ce_t4t_send_status(T4T_RSP_INSTR_NOT_SUPPORTED);
+    }
+  } else {
+    CE_TRACE_ERROR0("CET4T: Application has not been selected");
+    ce_t4t_send_status(T4T_RSP_CMD_NOT_ALLOWED);
+  }
+
+  if (p_c_apdu) GKI_freebuf(p_c_apdu);
+}
+
+/*******************************************************************************
+**
+** Function         ce_select_t4t
+**
+** Description      Select Type 4 Tag
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS ce_select_t4t(void) {
+  tCE_T4T_MEM* p_t4t = &ce_cb.mem.t4t;
+
+  CE_TRACE_DEBUG0("ce_select_t4t ()");
+
+  nfc_stop_quick_timer(&p_t4t->timer);
+
+  /* clear other than read-only flag */
+  p_t4t->status &= CE_T4T_STATUS_NDEF_FILE_READ_ONLY;
+
+  NFC_SetStaticRfCback(ce_t4t_data_cback);
+
+  return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         CE_T4tSetLocalNDEFMsg
+**
+** Description      Initialise CE Type 4 Tag with mandatory NDEF message
+**
+**                  The following event may be returned
+**                      CE_T4T_UPDATE_START_EVT for starting update
+**                      CE_T4T_UPDATE_CPLT_EVT for complete update
+**                      CE_T4T_UPDATE_ABORT_EVT for failure of update
+**                      CE_T4T_RAW_FRAME_EVT for raw frame
+**
+**                  read_only:      true if read only
+**                  ndef_msg_max:   Max NDEF message size
+**                  ndef_msg_len:   NDEF message size
+**                  p_ndef_msg:     NDEF message (excluding NLEN)
+**                  p_scratch_buf:  temp storage for update
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS CE_T4tSetLocalNDEFMsg(bool read_only, uint16_t ndef_msg_max,
+                                  uint16_t ndef_msg_len, uint8_t* p_ndef_msg,
+                                  uint8_t* p_scratch_buf) {
+  tCE_T4T_MEM* p_t4t = &ce_cb.mem.t4t;
+  uint8_t* p;
+
+  CE_TRACE_API3(
+      "CE_T4tSetLocalNDEFMsg () read_only=%d, ndef_msg_max=%d, ndef_msg_len=%d",
+      read_only, ndef_msg_max, ndef_msg_len);
+
+  if (!p_ndef_msg) {
+    p_t4t->p_ndef_msg = NULL;
+
+    CE_TRACE_DEBUG0("CE_T4tSetLocalNDEFMsg (): T4T is disabled");
+    return NFC_STATUS_OK;
+  }
+
+  if ((!read_only) && (!p_scratch_buf)) {
+    CE_TRACE_ERROR0(
+        "CE_T4tSetLocalNDEFMsg (): p_scratch_buf cannot be NULL if not "
+        "read-only");
+    return NFC_STATUS_FAILED;
+  }
+
+#if (CE_TEST_INCLUDED == true)
+  mapping_aid_test_enabled = false;
+#endif
+
+  /* Initialise CC file */
+  p = p_t4t->cc_file;
+
+  UINT16_TO_BE_STREAM(p, T4T_CC_FILE_MIN_LEN);
+  UINT8_TO_BE_STREAM(p, T4T_MY_VERSION);
+  UINT16_TO_BE_STREAM(p, CE_T4T_MAX_LE);
+  UINT16_TO_BE_STREAM(p, CE_T4T_MAX_LC);
+
+  /* Mandatory NDEF File Control TLV */
+  UINT8_TO_BE_STREAM(p, T4T_NDEF_FILE_CONTROL_TYPE);     /* type */
+  UINT8_TO_BE_STREAM(p, T4T_FILE_CONTROL_LENGTH);        /* length */
+  UINT16_TO_BE_STREAM(p, CE_T4T_MANDATORY_NDEF_FILE_ID); /* file ID */
+  UINT16_TO_BE_STREAM(
+      p, ndef_msg_max + T4T_FILE_LENGTH_SIZE); /* max NDEF file size */
+  UINT8_TO_BE_STREAM(p, T4T_FC_READ_ACCESS);   /* read access */
+
+  if (read_only) {
+    UINT8_TO_BE_STREAM(p, T4T_FC_NO_WRITE_ACCESS); /* read only */
+    p_t4t->status |= CE_T4T_STATUS_NDEF_FILE_READ_ONLY;
+  } else {
+    UINT8_TO_BE_STREAM(p, T4T_FC_WRITE_ACCESS); /* write access */
+    p_t4t->status &= ~(CE_T4T_STATUS_NDEF_FILE_READ_ONLY);
+  }
+
+  /* set mandatory NDEF file */
+  p_t4t->p_ndef_msg = p_ndef_msg;
+  p_t4t->nlen = ndef_msg_len;
+  p_t4t->max_file_size = ndef_msg_max + T4T_FILE_LENGTH_SIZE;
+
+  /* Initialize scratch buffer */
+  p_t4t->p_scratch_buf = p_scratch_buf;
+
+  if (p_scratch_buf) {
+    memcpy(p_scratch_buf, p_ndef_msg, ndef_msg_len);
+  }
+
+  return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         CE_T4tRegisterAID
+**
+** Description      Register AID in CE T4T
+**
+**                  aid_len: length of AID (up to NFC_MAX_AID_LEN)
+**                  p_aid:   AID
+**                  p_cback: Raw frame will be forwarded with CE_RAW_FRAME_EVT
+**
+** Returns          tCE_T4T_AID_HANDLE if successful,
+**                  CE_T4T_AID_HANDLE_INVALID otherwisse
+**
+*******************************************************************************/
+tCE_T4T_AID_HANDLE CE_T4tRegisterAID(uint8_t aid_len, uint8_t* p_aid,
+                                     tCE_CBACK* p_cback) {
+  tCE_T4T_MEM* p_t4t = &ce_cb.mem.t4t;
+  uint8_t xx;
+
+  /* Handle registering callback for wildcard AID (all AIDs) */
+  if (aid_len == 0) {
+    CE_TRACE_API0(
+        "CE_T4tRegisterAID (): registering callback for wildcard AID ");
+
+    /* Check if a wildcard callback is already registered (only one is allowed)
+     */
+    if (p_t4t->p_wildcard_aid_cback != NULL) {
+      CE_TRACE_ERROR0(
+          "CE_T4tRegisterAID (): only one wildcard AID can be registered at "
+          "time.");
+      return CE_T4T_AID_HANDLE_INVALID;
+    }
+
+    CE_TRACE_DEBUG1(
+        "CE_T4tRegisterAID (): handle 0x%02x registered (for wildcard AID)",
+        CE_T4T_WILDCARD_AID_HANDLE);
+    p_t4t->p_wildcard_aid_cback = p_cback;
+    return CE_T4T_WILDCARD_AID_HANDLE;
+  }
+
+  CE_TRACE_API5("CE_T4tRegisterAID () AID [%02X%02X%02X%02X...], %d bytes",
+                *p_aid, *(p_aid + 1), *(p_aid + 2), *(p_aid + 3), aid_len);
+
+  if (aid_len > NFC_MAX_AID_LEN) {
+    CE_TRACE_ERROR1("CE_T4tRegisterAID (): AID is up to %d bytes",
+                    NFC_MAX_AID_LEN);
+    return CE_T4T_AID_HANDLE_INVALID;
+  }
+
+  if (p_cback == NULL) {
+    CE_TRACE_ERROR0("CE_T4tRegisterAID (): callback must be provided");
+    return CE_T4T_AID_HANDLE_INVALID;
+  }
+
+  for (xx = 0; xx < CE_T4T_MAX_REG_AID; xx++) {
+    if ((p_t4t->reg_aid[xx].aid_len == aid_len) &&
+        (!(memcmp(p_t4t->reg_aid[xx].aid, p_aid, aid_len)))) {
+      CE_TRACE_ERROR0("CE_T4tRegisterAID (): already registered");
+      return CE_T4T_AID_HANDLE_INVALID;
+    }
+  }
+
+  for (xx = 0; xx < CE_T4T_MAX_REG_AID; xx++) {
+    if (p_t4t->reg_aid[xx].aid_len == 0) {
+      p_t4t->reg_aid[xx].aid_len = aid_len;
+      p_t4t->reg_aid[xx].p_cback = p_cback;
+      memcpy(p_t4t->reg_aid[xx].aid, p_aid, aid_len);
+      break;
+    }
+  }
+
+  if (xx >= CE_T4T_MAX_REG_AID) {
+    CE_TRACE_ERROR0("CE_T4tRegisterAID (): No resource");
+    return CE_T4T_AID_HANDLE_INVALID;
+  } else {
+    CE_TRACE_DEBUG1("CE_T4tRegisterAID (): handle 0x%02x registered", xx);
+  }
+
+  return (xx);
+}
+
+/*******************************************************************************
+**
+** Function         CE_T4tDeregisterAID
+**
+** Description      Deregister AID in CE T4T
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+extern void CE_T4tDeregisterAID(tCE_T4T_AID_HANDLE aid_handle) {
+  tCE_T4T_MEM* p_t4t = &ce_cb.mem.t4t;
+
+  CE_TRACE_API1("CE_T4tDeregisterAID () handle 0x%02x", aid_handle);
+
+  /* Check if deregistering wildcard AID */
+  if (aid_handle == CE_T4T_WILDCARD_AID_HANDLE) {
+    if (p_t4t->p_wildcard_aid_cback != NULL) {
+      p_t4t->p_wildcard_aid_cback = NULL;
+    } else {
+      CE_TRACE_ERROR0("CE_T4tDeregisterAID (): Invalid handle");
+    }
+    return;
+  }
+
+  /* Deregister AID */
+  if ((aid_handle >= CE_T4T_MAX_REG_AID) ||
+      (p_t4t->reg_aid[aid_handle].aid_len == 0)) {
+    CE_TRACE_ERROR0("CE_T4tDeregisterAID (): Invalid handle");
+  } else {
+    p_t4t->reg_aid[aid_handle].aid_len = 0;
+    p_t4t->reg_aid[aid_handle].p_cback = NULL;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         CE_T4TTestSetCC
+**
+** Description      Set fields in Capability Container File for testing
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS CE_T4TTestSetCC(uint16_t cc_len, uint8_t version, uint16_t max_le,
+                            uint16_t max_lc) {
+#if (CE_TEST_INCLUDED == false)
+  (void)(cc_len);
+  (void)(version);
+  (void)(max_le);
+  (void)(max_lc);
+#endif
+
+#if (CE_TEST_INCLUDED == true)
+  tCE_T4T_MEM* p_t4t = &ce_cb.mem.t4t;
+  uint8_t* p;
+
+  CE_TRACE_DEBUG4(
+      "CE_T4TTestSetCC (): CCLen:0x%04X, Ver:0x%02X, MaxLe:0x%04X, "
+      "MaxLc:0x%04X",
+      cc_len, version, max_le, max_lc);
+
+  /* CC file */
+  p = p_t4t->cc_file;
+
+  if (cc_len != 0xFFFF) {
+    UINT16_TO_BE_STREAM(p, cc_len);
+  } else
+    p += 2;
+
+  if (version != 0xFF) {
+    mapping_aid_test_enabled = true;
+    if (version == T4T_VERSION_1_0)
+      ce_test_tag_app_id[T4T_V20_NDEF_TAG_AID_LEN - 1] = 0x00;
+    else if (version == T4T_VERSION_2_0)
+      ce_test_tag_app_id[T4T_V20_NDEF_TAG_AID_LEN - 1] = 0x01;
+    else /* Undefined version */
+      ce_test_tag_app_id[T4T_V20_NDEF_TAG_AID_LEN - 1] = 0xFF;
+
+    UINT8_TO_BE_STREAM(p, version);
+  } else {
+    mapping_aid_test_enabled = false;
+    p += 1;
+  }
+
+  if (max_le != 0xFFFF) {
+    UINT16_TO_BE_STREAM(p, max_le);
+  } else
+    p += 2;
+
+  if (max_lc != 0xFFFF) {
+    UINT16_TO_BE_STREAM(p, max_lc);
+  } else
+    p += 2;
+
+  return NFC_STATUS_OK;
+#else
+  return NFC_STATUS_FAILED;
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         CE_T4TTestSetNDEFCtrlTLV
+**
+** Description      Set fields in NDEF File Control TLV for testing
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS CE_T4TTestSetNDEFCtrlTLV(uint8_t type, uint8_t length,
+                                     uint16_t file_id, uint16_t max_file_size,
+                                     uint8_t read_access,
+                                     uint8_t write_access) {
+#if (CE_TEST_INCLUDED == false)
+  (void)(type);
+  (void)(length);
+  (void)(file_id);
+  (void)(max_file_size);
+  (void)(read_access);
+  (void)(write_access);
+#endif
+
+#if (CE_TEST_INCLUDED == true)
+  tCE_T4T_MEM* p_t4t = &ce_cb.mem.t4t;
+  uint8_t* p;
+
+  CE_TRACE_DEBUG6(
+      "CE_T4TTestSetNDEFCtrlTLV (): type:0x%02X, len:0x%02X, FileID:0x%04X, "
+      "MaxFile:0x%04X, RdAcc:0x%02X, WrAcc:0x%02X",
+      type, length, file_id, max_file_size, read_access, write_access);
+
+  /* NDEF File control TLV */
+  p = p_t4t->cc_file + T4T_FC_TLV_OFFSET_IN_CC;
+
+  if (type != 0xFF) {
+    UINT8_TO_BE_STREAM(p, type);
+  } else
+    p += 1;
+
+  if (length != 0xFF) {
+    UINT8_TO_BE_STREAM(p, length);
+  } else
+    p += 1;
+
+  if (file_id != 0xFFFF) {
+    UINT16_TO_BE_STREAM(p, file_id);
+  } else
+    p += 2;
+
+  if (max_file_size != 0xFFFF) {
+    UINT16_TO_BE_STREAM(p, max_file_size);
+  } else
+    p += 2;
+
+  if (read_access != 0xFF) {
+    UINT8_TO_BE_STREAM(p, read_access);
+  } else
+    p += 1;
+
+  if (write_access != 0xFF) {
+    UINT8_TO_BE_STREAM(p, write_access);
+  } else
+    p += 1;
+
+  return NFC_STATUS_OK;
+#else
+  return NFC_STATUS_FAILED;
+#endif
+}
diff --git a/src/nfc/tags/rw_i93.c b/src/nfc/tags/rw_i93.c
new file mode 100644
index 0000000..fbe09fc
--- /dev/null
+++ b/src/nfc/tags/rw_i93.c
@@ -0,0 +1,3893 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2011-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the implementation for ISO 15693 in Reader/Writer
+ *  mode.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "trace_api.h"
+
+#include "nfc_api.h"
+#include "nfc_int.h"
+#include "rw_api.h"
+#include "rw_int.h"
+
+#if (NXP_EXTNS == TRUE)
+/* Response timeout     */
+#define RW_I93_TOUT_RESP RW_I93_MAX_RSP_TIMEOUT
+#else
+/* Response timeout */
+#define RW_I93_TOUT_RESP 1000
+#endif
+/* stay quiet timeout   */
+#define RW_I93_TOUT_STAY_QUIET 200
+/* max reading data if read multi block is supported */
+#define RW_I93_READ_MULTI_BLOCK_SIZE 128
+/* CC, zero length NDEF, Terminator TLV              */
+#define RW_I93_FORMAT_DATA_LEN 8
+/* max getting lock status if get multi block sec is supported */
+#define RW_I93_GET_MULTI_BLOCK_SEC_SIZE 253
+
+/* main state */
+enum {
+  RW_I93_STATE_NOT_ACTIVATED, /* ISO15693 is not activated            */
+  RW_I93_STATE_IDLE,          /* waiting for upper layer API          */
+  RW_I93_STATE_BUSY,          /* waiting for response from tag        */
+
+  RW_I93_STATE_DETECT_NDEF,   /* performing NDEF detection precedure  */
+  RW_I93_STATE_READ_NDEF,     /* performing read NDEF procedure       */
+  RW_I93_STATE_UPDATE_NDEF,   /* performing update NDEF procedure     */
+  RW_I93_STATE_FORMAT,        /* performing format procedure          */
+  RW_I93_STATE_SET_READ_ONLY, /* performing set read-only procedure   */
+
+  RW_I93_STATE_PRESENCE_CHECK /* checking presence of tag             */
+};
+
+/* sub state */
+enum {
+  RW_I93_SUBSTATE_WAIT_UID,          /* waiting for response of inventory    */
+  RW_I93_SUBSTATE_WAIT_SYS_INFO,     /* waiting for response of get sys info */
+  RW_I93_SUBSTATE_WAIT_CC,           /* waiting for reading CC               */
+  RW_I93_SUBSTATE_SEARCH_NDEF_TLV,   /* searching NDEF TLV                   */
+  RW_I93_SUBSTATE_CHECK_LOCK_STATUS, /* check if any NDEF TLV is locked      */
+
+  RW_I93_SUBSTATE_RESET_LEN,  /* set length to 0 to update NDEF TLV   */
+  RW_I93_SUBSTATE_WRITE_NDEF, /* writing NDEF and Terminator TLV      */
+  RW_I93_SUBSTATE_UPDATE_LEN, /* set length into NDEF TLV             */
+
+  RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI, /* reset DSFID and AFI */
+  RW_I93_SUBSTATE_CHECK_READ_ONLY,   /* check if any block is locked         */
+  RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV, /* write CC and empty NDEF/Terminator TLV
+                                        */
+
+  RW_I93_SUBSTATE_WAIT_UPDATE_CC, /* updating CC as read-only             */
+  RW_I93_SUBSTATE_LOCK_NDEF_TLV,  /* lock blocks of NDEF TLV              */
+  RW_I93_SUBSTATE_WAIT_LOCK_CC    /* lock block of CC                     */
+};
+
+#if (BT_TRACE_VERBOSE == true)
+static char* rw_i93_get_state_name(uint8_t state);
+static char* rw_i93_get_sub_state_name(uint8_t sub_state);
+static char* rw_i93_get_tag_name(uint8_t product_version);
+#endif
+
+static void rw_i93_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
+                              tNFC_CONN* p_data);
+void rw_i93_handle_error(tNFC_STATUS status);
+tNFC_STATUS rw_i93_send_cmd_get_sys_info(uint8_t* p_uid, uint8_t extra_flag);
+
+/*******************************************************************************
+**
+** Function         rw_i93_get_product_version
+**
+** Description      Get product version from UID
+**
+** Returns          void
+**
+*******************************************************************************/
+void rw_i93_get_product_version(uint8_t* p_uid) {
+  tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
+
+  if (!memcmp(p_i93->uid, p_uid, I93_UID_BYTE_LEN)) {
+    return;
+  }
+
+  RW_TRACE_DEBUG0("rw_i93_get_product_version ()");
+
+  memcpy(p_i93->uid, p_uid, I93_UID_BYTE_LEN);
+
+  if (p_uid[1] == I93_UID_IC_MFG_CODE_NXP) {
+    if (p_uid[2] == I93_UID_ICODE_SLI)
+      p_i93->product_version = RW_I93_ICODE_SLI;
+    else if (p_uid[2] == I93_UID_ICODE_SLI_S)
+      p_i93->product_version = RW_I93_ICODE_SLI_S;
+    else if (p_uid[2] == I93_UID_ICODE_SLI_L)
+      p_i93->product_version = RW_I93_ICODE_SLI_L;
+    else
+      p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
+  } else if (p_uid[1] == I93_UID_IC_MFG_CODE_TI) {
+    if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
+        I93_UID_TAG_IT_HF_I_PLUS_INLAY)
+      p_i93->product_version = RW_I93_TAG_IT_HF_I_PLUS_INLAY;
+    else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
+             I93_UID_TAG_IT_HF_I_PLUS_CHIP)
+      p_i93->product_version = RW_I93_TAG_IT_HF_I_PLUS_CHIP;
+    else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
+             I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY)
+      p_i93->product_version = RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY;
+    else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
+             I93_UID_TAG_IT_HF_I_PRO_CHIP_INLAY)
+      p_i93->product_version = RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY;
+    else
+      p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
+  } else if ((p_uid[1] == I93_UID_IC_MFG_CODE_STM) &&
+             (p_i93->info_flags & I93_INFO_FLAG_IC_REF)) {
+    if (p_i93->ic_reference == I93_IC_REF_STM_M24LR04E_R)
+      p_i93->product_version = RW_I93_STM_M24LR04E_R;
+    else if (p_i93->ic_reference == I93_IC_REF_STM_M24LR16E_R)
+      p_i93->product_version = RW_I93_STM_M24LR16E_R;
+    else if (p_i93->ic_reference == I93_IC_REF_STM_M24LR64E_R)
+      p_i93->product_version = RW_I93_STM_M24LR64E_R;
+    else {
+      switch (p_i93->ic_reference & I93_IC_REF_STM_MASK) {
+        case I93_IC_REF_STM_LRI1K:
+          p_i93->product_version = RW_I93_STM_LRI1K;
+          break;
+        case I93_IC_REF_STM_LRI2K:
+          p_i93->product_version = RW_I93_STM_LRI2K;
+          break;
+        case I93_IC_REF_STM_LRIS2K:
+          p_i93->product_version = RW_I93_STM_LRIS2K;
+          break;
+        case I93_IC_REF_STM_LRIS64K:
+          p_i93->product_version = RW_I93_STM_LRIS64K;
+          break;
+        case I93_IC_REF_STM_M24LR64_R:
+          p_i93->product_version = RW_I93_STM_M24LR64_R;
+          break;
+        default:
+          p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
+          break;
+      }
+    }
+  } else {
+    p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
+  }
+
+#if (BT_TRACE_VERBOSE == true)
+  RW_TRACE_DEBUG1("product_version = <%s>",
+                  rw_i93_get_tag_name(p_i93->product_version));
+#else
+  RW_TRACE_DEBUG1("product_version = %d", p_i93->product_version);
+#endif
+
+  switch (p_i93->product_version) {
+    case RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY:
+    case RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY:
+      /* these don't support Get System Information Command */
+      /* these support only Inventory, Stay Quiet, Read Single Block, Write
+       * Single Block, Lock Block */
+      p_i93->block_size = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_BLK_SIZE;
+      p_i93->num_block = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_NUM_USER_BLK;
+      break;
+    default:
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_process_sys_info
+**
+** Description      Store system information of tag
+**
+** Returns          false if retrying with protocol extension flag
+**
+*******************************************************************************/
+bool rw_i93_process_sys_info(uint8_t* p_data) {
+  uint8_t* p = p_data;
+  tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
+  uint8_t uid[I93_UID_BYTE_LEN], *p_uid;
+
+  RW_TRACE_DEBUG0("rw_i93_process_sys_info ()");
+
+  STREAM_TO_UINT8(p_i93->info_flags, p);
+
+  p_uid = uid;
+  STREAM_TO_ARRAY8(p_uid, p);
+
+  if (p_i93->info_flags & I93_INFO_FLAG_DSFID) {
+    STREAM_TO_UINT8(p_i93->dsfid, p);
+  }
+  if (p_i93->info_flags & I93_INFO_FLAG_AFI) {
+    STREAM_TO_UINT8(p_i93->afi, p);
+  }
+  if (p_i93->info_flags & I93_INFO_FLAG_MEM_SIZE) {
+    if (p_i93->intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK) {
+      STREAM_TO_UINT16(p_i93->num_block, p);
+    } else {
+      STREAM_TO_UINT8(p_i93->num_block, p);
+    }
+    /* it is one less than actual number of bytes */
+    p_i93->num_block += 1;
+
+    STREAM_TO_UINT8(p_i93->block_size, p);
+    /* it is one less than actual number of blocks */
+    p_i93->block_size = (p_i93->block_size & 0x1F) + 1;
+  }
+  if (p_i93->info_flags & I93_INFO_FLAG_IC_REF) {
+    STREAM_TO_UINT8(p_i93->ic_reference, p);
+
+    /* clear existing UID to set product version */
+    p_i93->uid[0] = 0x00;
+
+    /* store UID and get product version */
+    rw_i93_get_product_version(p_uid);
+
+    if (p_i93->uid[0] == I93_UID_FIRST_BYTE) {
+      if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
+          (p_i93->ic_reference == I93_IC_REF_ICODE_SLI_L)) {
+        p_i93->num_block = 8;
+        p_i93->block_size = 4;
+      } else if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) {
+        /*
+        **  LRI1K:      010000xx(b), blockSize: 4, numberBlocks: 0x20
+        **  LRI2K:      001000xx(b), blockSize: 4, numberBlocks: 0x40
+        **  LRIS2K:     001010xx(b), blockSize: 4, numberBlocks: 0x40
+        **  LRIS64K:    010001xx(b), blockSize: 4, numberBlocks: 0x800
+        **  M24LR64-R:  001011xx(b), blockSize: 4, numberBlocks: 0x800
+        **  M24LR04E-R: 01011010(b), blockSize: 4, numberBlocks: 0x80
+        **  M24LR16E-R: 01001110(b), blockSize: 4, numberBlocks: 0x200
+        **  M24LR64E-R: 01011110(b), blockSize: 4, numberBlocks: 0x800
+        */
+        if ((p_i93->product_version == RW_I93_STM_M24LR16E_R) ||
+            (p_i93->product_version == RW_I93_STM_M24LR64E_R)) {
+          /*
+          ** M24LR16E-R or M24LR64E-R returns system information
+          ** without memory size, if option flag is not set.
+          ** LRIS64K and M24LR64-R return error if option flag is not
+          ** set.
+          */
+          if (!(p_i93->intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)) {
+            /* get memory size with protocol extension flag */
+            if (rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_YES) ==
+                NFC_STATUS_OK) {
+              /* STM supports more than 2040 bytes */
+              p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
+
+              return false;
+            }
+          }
+          return true;
+        } else if ((p_i93->product_version == RW_I93_STM_LRI2K) &&
+                   (p_i93->ic_reference == 0x21)) {
+          /* workaround of byte order in memory size information */
+          p_i93->num_block = 64;
+          p_i93->block_size = 4;
+        }
+      }
+    }
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_check_sys_info_prot_ext
+**
+** Description      Check if need to set protocol extension flag to get system
+**                  info
+**
+** Returns          true if sent Get System Info with protocol extension flag
+**
+*******************************************************************************/
+bool rw_i93_check_sys_info_prot_ext(uint8_t error_code) {
+  tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
+
+  RW_TRACE_DEBUG0("rw_i93_check_sys_info_prot_ext ()");
+
+  if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) &&
+      (p_i93->sent_cmd == I93_CMD_GET_SYS_INFO) &&
+      (error_code == I93_ERROR_CODE_OPTION_NOT_SUPPORTED) &&
+      (rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_YES) ==
+       NFC_STATUS_OK)) {
+    return true;
+  } else {
+    return false;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_to_upper
+**
+** Description      Send response to upper layer
+**
+** Returns          void
+**
+*******************************************************************************/
+void rw_i93_send_to_upper(NFC_HDR* p_resp) {
+  uint8_t* p = (uint8_t*)(p_resp + 1) + p_resp->offset, *p_uid;
+  uint16_t length = p_resp->len;
+  tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
+  tRW_DATA rw_data;
+  uint8_t event = RW_I93_MAX_EVT;
+  uint8_t flags;
+  NFC_HDR* p_buff;
+
+  RW_TRACE_DEBUG0("rw_i93_send_to_upper ()");
+
+  STREAM_TO_UINT8(flags, p);
+  length--;
+
+  if (flags & I93_FLAG_ERROR_DETECTED) {
+    if ((length) && (rw_i93_check_sys_info_prot_ext(*p))) {
+      /* getting system info with protocol extension flag */
+      /* This STM tag supports more than 2040 bytes */
+      p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
+      p_i93->state = RW_I93_STATE_BUSY;
+    } else {
+      /* notify error to upper layer */
+      rw_data.i93_cmd_cmpl.status = NFC_STATUS_FAILED;
+      rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
+      STREAM_TO_UINT8(rw_data.i93_cmd_cmpl.error_code, p);
+
+      rw_cb.tcb.i93.sent_cmd = 0;
+      (*(rw_cb.p_cback))(RW_I93_CMD_CMPL_EVT, &rw_data);
+    }
+    return;
+  }
+
+  switch (p_i93->sent_cmd) {
+    case I93_CMD_INVENTORY:
+
+      /* forward inventory response */
+      rw_data.i93_inventory.status = NFC_STATUS_OK;
+      STREAM_TO_UINT8(rw_data.i93_inventory.dsfid, p);
+
+      p_uid = rw_data.i93_inventory.uid;
+      STREAM_TO_ARRAY8(p_uid, p);
+
+      /* store UID and get product version */
+      rw_i93_get_product_version(p_uid);
+
+      event = RW_I93_INVENTORY_EVT;
+      break;
+
+    case I93_CMD_READ_SINGLE_BLOCK:
+    case I93_CMD_READ_MULTI_BLOCK:
+    case I93_CMD_GET_MULTI_BLK_SEC:
+
+      /* forward tag data or security status */
+      p_buff = (NFC_HDR*)GKI_getbuf((uint16_t)(length + NFC_HDR_SIZE));
+
+      if (p_buff) {
+        p_buff->offset = 0;
+        p_buff->len = length;
+
+        memcpy((p_buff + 1), p, length);
+
+        rw_data.i93_data.status = NFC_STATUS_OK;
+        rw_data.i93_data.command = p_i93->sent_cmd;
+        rw_data.i93_data.p_data = p_buff;
+
+        event = RW_I93_DATA_EVT;
+      } else {
+        rw_data.i93_cmd_cmpl.status = NFC_STATUS_NO_BUFFERS;
+        rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
+        rw_data.i93_cmd_cmpl.error_code = 0;
+
+        event = RW_I93_CMD_CMPL_EVT;
+      }
+      break;
+
+    case I93_CMD_WRITE_SINGLE_BLOCK:
+    case I93_CMD_LOCK_BLOCK:
+    case I93_CMD_WRITE_MULTI_BLOCK:
+    case I93_CMD_SELECT:
+    case I93_CMD_RESET_TO_READY:
+    case I93_CMD_WRITE_AFI:
+    case I93_CMD_LOCK_AFI:
+    case I93_CMD_WRITE_DSFID:
+    case I93_CMD_LOCK_DSFID:
+
+      /* notify the complete of command */
+      rw_data.i93_cmd_cmpl.status = NFC_STATUS_OK;
+      rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
+      rw_data.i93_cmd_cmpl.error_code = 0;
+
+      event = RW_I93_CMD_CMPL_EVT;
+      break;
+
+    case I93_CMD_GET_SYS_INFO:
+
+      if (rw_i93_process_sys_info(p)) {
+        rw_data.i93_sys_info.status = NFC_STATUS_OK;
+        rw_data.i93_sys_info.info_flags = p_i93->info_flags;
+        rw_data.i93_sys_info.dsfid = p_i93->dsfid;
+        rw_data.i93_sys_info.afi = p_i93->afi;
+        rw_data.i93_sys_info.num_block = p_i93->num_block;
+        rw_data.i93_sys_info.block_size = p_i93->block_size;
+        rw_data.i93_sys_info.IC_reference = p_i93->ic_reference;
+
+        memcpy(rw_data.i93_sys_info.uid, p_i93->uid, I93_UID_BYTE_LEN);
+
+        event = RW_I93_SYS_INFO_EVT;
+      } else {
+        /* retrying with protocol extension flag */
+        p_i93->state = RW_I93_STATE_BUSY;
+        return;
+      }
+      break;
+
+    default:
+      break;
+  }
+
+  rw_cb.tcb.i93.sent_cmd = 0;
+  if (event != RW_I93_MAX_EVT) {
+    (*(rw_cb.p_cback))(event, &rw_data);
+  } else {
+    RW_TRACE_ERROR0("rw_i93_send_to_upper (): Invalid response");
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_to_lower
+**
+** Description      Send Request frame to lower layer
+**
+** Returns          true if success
+**
+*******************************************************************************/
+bool rw_i93_send_to_lower(NFC_HDR* p_msg) {
+#if (BT_TRACE_PROTOCOL == true)
+  DispRWI93Tag(p_msg, false, 0x00);
+#endif
+
+  /* store command for retransmitting */
+  if (rw_cb.tcb.i93.p_retry_cmd) {
+    GKI_freebuf(rw_cb.tcb.i93.p_retry_cmd);
+    rw_cb.tcb.i93.p_retry_cmd = NULL;
+  }
+
+  rw_cb.tcb.i93.p_retry_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (rw_cb.tcb.i93.p_retry_cmd) {
+    memcpy(rw_cb.tcb.i93.p_retry_cmd, p_msg,
+           sizeof(NFC_HDR) + p_msg->offset + p_msg->len);
+  }
+
+  if (NFC_SendData(NFC_RF_CONN_ID, p_msg) != NFC_STATUS_OK) {
+    RW_TRACE_ERROR0("rw_i93_send_to_lower (): NFC_SendData () failed");
+    return false;
+  }
+
+  nfc_start_quick_timer(&rw_cb.tcb.i93.timer, NFC_TTYPE_RW_I93_RESPONSE,
+                        (RW_I93_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_inventory
+**
+** Description      Send Inventory Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_inventory(uint8_t* p_uid, bool including_afi,
+                                      uint8_t afi) {
+  NFC_HDR* p_cmd;
+  uint8_t* p, flags;
+
+  RW_TRACE_DEBUG2("rw_i93_send_cmd_inventory () including_afi:%d, AFI:0x%02X",
+                  including_afi, afi);
+
+  p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_cmd) {
+    RW_TRACE_ERROR0("rw_i93_send_cmd_inventory (): Cannot allocate buffer");
+    return NFC_STATUS_NO_BUFFERS;
+  }
+
+  p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p_cmd->len = 3;
+  p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
+
+  /* Flags */
+  flags = (I93_FLAG_SLOT_ONE | I93_FLAG_INVENTORY_SET |
+           RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
+  if (including_afi) {
+    flags |= I93_FLAG_AFI_PRESENT;
+  }
+
+  UINT8_TO_STREAM(p, flags);
+
+  /* Command Code */
+  UINT8_TO_STREAM(p, I93_CMD_INVENTORY);
+
+  if (including_afi) {
+    /* Parameters */
+    UINT8_TO_STREAM(p, afi); /* Optional AFI */
+    p_cmd->len++;
+  }
+
+  if (p_uid) {
+    UINT8_TO_STREAM(p, I93_UID_BYTE_LEN * 8); /* Mask Length */
+    ARRAY8_TO_STREAM(p, p_uid);               /* UID */
+    p_cmd->len += I93_UID_BYTE_LEN;
+  } else {
+    UINT8_TO_STREAM(p, 0x00); /* Mask Length */
+  }
+
+  if (rw_i93_send_to_lower(p_cmd)) {
+    rw_cb.tcb.i93.sent_cmd = I93_CMD_INVENTORY;
+    return NFC_STATUS_OK;
+  } else {
+    return NFC_STATUS_FAILED;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_stay_quiet
+**
+** Description      Send Stay Quiet Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_stay_quiet(void) {
+  NFC_HDR* p_cmd;
+  uint8_t* p;
+
+  RW_TRACE_DEBUG0("rw_i93_send_cmd_stay_quiet ()");
+
+  p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_cmd) {
+    RW_TRACE_ERROR0("rw_i93_send_cmd_stay_quiet (): Cannot allocate buffer");
+    return NFC_STATUS_NO_BUFFERS;
+  }
+
+  p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p_cmd->len = 10;
+  p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
+
+  /* Flags */
+  UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
+                      RW_I93_FLAG_DATA_RATE));
+
+  /* Command Code */
+  UINT8_TO_STREAM(p, I93_CMD_STAY_QUIET);
+
+  /* Parameters */
+  ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
+
+  if (rw_i93_send_to_lower(p_cmd)) {
+    rw_cb.tcb.i93.sent_cmd = I93_CMD_STAY_QUIET;
+
+    /* restart timer for stay quiet */
+    nfc_start_quick_timer(
+        &rw_cb.tcb.i93.timer, NFC_TTYPE_RW_I93_RESPONSE,
+        (RW_I93_TOUT_STAY_QUIET * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+    return NFC_STATUS_OK;
+  } else {
+    return NFC_STATUS_FAILED;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_read_single_block
+**
+** Description      Send Read Single Block Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_read_single_block(uint16_t block_number,
+                                              bool read_security) {
+  NFC_HDR* p_cmd;
+  uint8_t* p, flags;
+
+  RW_TRACE_DEBUG0("rw_i93_send_cmd_read_single_block ()");
+
+  p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_cmd) {
+    RW_TRACE_ERROR0(
+        "rw_i93_send_cmd_read_single_block (): Cannot allocate buffer");
+    return NFC_STATUS_NO_BUFFERS;
+  }
+
+  p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p_cmd->len = 11;
+  p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
+
+  /* Flags */
+  flags =
+      (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
+
+  if (read_security) flags |= I93_FLAG_OPTION_SET;
+
+  if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
+    flags |= I93_FLAG_PROT_EXT_YES;
+
+  UINT8_TO_STREAM(p, flags);
+
+  /* Command Code */
+  UINT8_TO_STREAM(p, I93_CMD_READ_SINGLE_BLOCK);
+
+  /* Parameters */
+  ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
+
+  if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK) {
+    UINT16_TO_STREAM(p, block_number); /* Block number */
+    p_cmd->len++;
+  } else {
+    UINT8_TO_STREAM(p, block_number); /* Block number */
+  }
+
+  if (rw_i93_send_to_lower(p_cmd)) {
+    rw_cb.tcb.i93.sent_cmd = I93_CMD_READ_SINGLE_BLOCK;
+    return NFC_STATUS_OK;
+  } else {
+    return NFC_STATUS_FAILED;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_write_single_block
+**
+** Description      Send Write Single Block Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_write_single_block(uint16_t block_number,
+                                               uint8_t* p_data) {
+  NFC_HDR* p_cmd;
+  uint8_t* p, flags;
+
+  RW_TRACE_DEBUG0("rw_i93_send_cmd_write_single_block ()");
+
+  p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_cmd) {
+    RW_TRACE_ERROR0(
+        "rw_i93_send_cmd_write_single_block (): Cannot allocate buffer");
+    return NFC_STATUS_NO_BUFFERS;
+  }
+
+  p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p_cmd->len = 11 + rw_cb.tcb.i93.block_size;
+  p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
+
+  /* Flags */
+  if ((rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
+      (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
+      (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
+      (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
+    /* Option must be set for TI tag */
+    flags = (I93_FLAG_ADDRESS_SET | I93_FLAG_OPTION_SET |
+             RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
+  } else {
+    flags = (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
+             RW_I93_FLAG_DATA_RATE);
+  }
+
+  if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
+    flags |= I93_FLAG_PROT_EXT_YES;
+
+  UINT8_TO_STREAM(p, flags);
+
+  /* Command Code */
+  UINT8_TO_STREAM(p, I93_CMD_WRITE_SINGLE_BLOCK);
+
+  /* Parameters */
+  ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
+
+  if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK) {
+    UINT16_TO_STREAM(p, block_number); /* Block number */
+    p_cmd->len++;
+  } else {
+    UINT8_TO_STREAM(p, block_number); /* Block number */
+  }
+
+  /* Data */
+  ARRAY_TO_STREAM(p, p_data, rw_cb.tcb.i93.block_size);
+
+  if (rw_i93_send_to_lower(p_cmd)) {
+    rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_SINGLE_BLOCK;
+    return NFC_STATUS_OK;
+  } else {
+    return NFC_STATUS_FAILED;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_lock_block
+**
+** Description      Send Lock Block Request to VICC
+**
+**                  STM LRIS64K, M24LR64-R, M24LR04E-R, M24LR16E-R, M24LR64E-R
+**                  do not support.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_lock_block(uint8_t block_number) {
+  NFC_HDR* p_cmd;
+  uint8_t* p;
+
+  RW_TRACE_DEBUG0("rw_i93_send_cmd_lock_block ()");
+
+  p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_cmd) {
+    RW_TRACE_ERROR0("rw_i93_send_cmd_lock_block (): Cannot allocate buffer");
+    return NFC_STATUS_NO_BUFFERS;
+  }
+
+  p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p_cmd->len = 11;
+  p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
+
+  /* Flags */
+  if ((rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
+      (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
+      (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
+      (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
+    /* Option must be set for TI tag */
+    UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | I93_FLAG_OPTION_SET |
+                        RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+  } else {
+    UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
+                        RW_I93_FLAG_DATA_RATE));
+  }
+
+  /* Command Code */
+  UINT8_TO_STREAM(p, I93_CMD_LOCK_BLOCK);
+
+  /* Parameters */
+  ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
+  UINT8_TO_STREAM(p, block_number);       /* Block number */
+
+  if (rw_i93_send_to_lower(p_cmd)) {
+    rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_BLOCK;
+    return NFC_STATUS_OK;
+  } else {
+    return NFC_STATUS_FAILED;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_read_multi_blocks
+**
+** Description      Send Read Multiple Blocks Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_read_multi_blocks(uint16_t first_block_number,
+                                              uint16_t number_blocks) {
+  NFC_HDR* p_cmd;
+  uint8_t* p, flags;
+
+  RW_TRACE_DEBUG0("rw_i93_send_cmd_read_multi_blocks ()");
+
+  p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_cmd) {
+    RW_TRACE_ERROR0(
+        "rw_i93_send_cmd_read_multi_blocks (): Cannot allocate buffer");
+    return NFC_STATUS_NO_BUFFERS;
+  }
+
+  p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p_cmd->len = 12;
+  p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
+
+  /* Flags */
+  flags =
+      (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
+
+  if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
+    flags |= I93_FLAG_PROT_EXT_YES;
+
+  UINT8_TO_STREAM(p, flags);
+
+  /* Command Code */
+  UINT8_TO_STREAM(p, I93_CMD_READ_MULTI_BLOCK);
+
+  /* Parameters */
+  ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
+
+  if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK) {
+    UINT16_TO_STREAM(p, first_block_number); /* First block number */
+    p_cmd->len++;
+  } else {
+    UINT8_TO_STREAM(p, first_block_number); /* First block number */
+  }
+
+  UINT8_TO_STREAM(
+      p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
+
+  if (rw_i93_send_to_lower(p_cmd)) {
+    rw_cb.tcb.i93.sent_cmd = I93_CMD_READ_MULTI_BLOCK;
+    return NFC_STATUS_OK;
+  } else {
+    return NFC_STATUS_FAILED;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_write_multi_blocks
+**
+** Description      Send Write Multiple Blocks Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_write_multi_blocks(uint8_t first_block_number,
+                                               uint16_t number_blocks,
+                                               uint8_t* p_data) {
+  NFC_HDR* p_cmd;
+  uint8_t* p;
+
+  RW_TRACE_DEBUG0("rw_i93_send_cmd_write_multi_blocks ()");
+
+  p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_cmd) {
+    RW_TRACE_ERROR0(
+        "rw_i93_send_cmd_write_multi_blocks (): Cannot allocate buffer");
+    return NFC_STATUS_NO_BUFFERS;
+  }
+
+  p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p_cmd->len = 12 + number_blocks * rw_cb.tcb.i93.block_size;
+  p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
+
+  /* Flags */
+  UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
+                      RW_I93_FLAG_DATA_RATE));
+
+  /* Command Code */
+  UINT8_TO_STREAM(p, I93_CMD_WRITE_MULTI_BLOCK);
+
+  /* Parameters */
+  ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
+  UINT8_TO_STREAM(p, first_block_number); /* First block number */
+  UINT8_TO_STREAM(
+      p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
+
+  /* Data */
+  ARRAY_TO_STREAM(p, p_data, number_blocks * rw_cb.tcb.i93.block_size);
+
+  if (rw_i93_send_to_lower(p_cmd)) {
+    rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_MULTI_BLOCK;
+    return NFC_STATUS_OK;
+  } else {
+    return NFC_STATUS_FAILED;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_select
+**
+** Description      Send Select Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_select(uint8_t* p_uid) {
+  NFC_HDR* p_cmd;
+  uint8_t* p;
+
+  RW_TRACE_DEBUG0("rw_i93_send_cmd_select ()");
+
+  p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_cmd) {
+    RW_TRACE_ERROR0("rw_i93_send_cmd_select (): Cannot allocate buffer");
+    return NFC_STATUS_NO_BUFFERS;
+  }
+
+  p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p_cmd->len = 10;
+  p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
+
+  /* Flags */
+  UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
+                      RW_I93_FLAG_DATA_RATE));
+
+  /* Command Code */
+  UINT8_TO_STREAM(p, I93_CMD_SELECT);
+
+  /* Parameters */
+  ARRAY8_TO_STREAM(p, p_uid); /* UID */
+
+  if (rw_i93_send_to_lower(p_cmd)) {
+    rw_cb.tcb.i93.sent_cmd = I93_CMD_SELECT;
+    return NFC_STATUS_OK;
+  } else {
+    return NFC_STATUS_FAILED;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_reset_to_ready
+**
+** Description      Send Reset to Ready Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_reset_to_ready(void) {
+  NFC_HDR* p_cmd;
+  uint8_t* p;
+
+  RW_TRACE_DEBUG0("rw_i93_send_cmd_reset_to_ready ()");
+
+  p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_cmd) {
+    RW_TRACE_ERROR0(
+        "rw_i93_send_cmd_reset_to_ready (): Cannot allocate buffer");
+    return NFC_STATUS_NO_BUFFERS;
+  }
+
+  p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p_cmd->len = 10;
+  p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
+
+  /* Flags */
+  UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
+                      RW_I93_FLAG_DATA_RATE));
+
+  /* Command Code */
+  UINT8_TO_STREAM(p, I93_CMD_RESET_TO_READY);
+
+  /* Parameters */
+  ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
+
+  if (rw_i93_send_to_lower(p_cmd)) {
+    rw_cb.tcb.i93.sent_cmd = I93_CMD_RESET_TO_READY;
+    return NFC_STATUS_OK;
+  } else {
+    return NFC_STATUS_FAILED;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_write_afi
+**
+** Description      Send Write AFI Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_write_afi(uint8_t afi) {
+  NFC_HDR* p_cmd;
+  uint8_t* p;
+
+  RW_TRACE_DEBUG0("rw_i93_send_cmd_write_afi ()");
+
+  p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_cmd) {
+    RW_TRACE_ERROR0("rw_i93_send_cmd_write_afi (): Cannot allocate buffer");
+    return NFC_STATUS_NO_BUFFERS;
+  }
+
+  p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p_cmd->len = 11;
+  p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
+
+  /* Flags */
+  UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
+                      RW_I93_FLAG_DATA_RATE));
+
+  /* Command Code */
+  UINT8_TO_STREAM(p, I93_CMD_WRITE_AFI);
+
+  /* Parameters */
+  ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
+  UINT8_TO_STREAM(p, afi);                /* AFI */
+
+  if (rw_i93_send_to_lower(p_cmd)) {
+    rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_AFI;
+    return NFC_STATUS_OK;
+  } else {
+    return NFC_STATUS_FAILED;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_lock_afi
+**
+** Description      Send Lock AFI Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_lock_afi(void) {
+  NFC_HDR* p_cmd;
+  uint8_t* p;
+
+  RW_TRACE_DEBUG0("rw_i93_send_cmd_lock_afi ()");
+
+  p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_cmd) {
+    RW_TRACE_ERROR0("rw_i93_send_cmd_lock_afi (): Cannot allocate buffer");
+    return NFC_STATUS_NO_BUFFERS;
+  }
+
+  p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p_cmd->len = 10;
+  p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
+
+  /* Flags */
+  UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
+                      RW_I93_FLAG_DATA_RATE));
+
+  /* Command Code */
+  UINT8_TO_STREAM(p, I93_CMD_LOCK_AFI);
+
+  /* Parameters */
+  ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
+
+  if (rw_i93_send_to_lower(p_cmd)) {
+    rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_AFI;
+    return NFC_STATUS_OK;
+  } else {
+    return NFC_STATUS_FAILED;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_write_dsfid
+**
+** Description      Send Write DSFID Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_write_dsfid(uint8_t dsfid) {
+  NFC_HDR* p_cmd;
+  uint8_t* p;
+
+  RW_TRACE_DEBUG0("rw_i93_send_cmd_write_dsfid ()");
+
+  p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_cmd) {
+    RW_TRACE_ERROR0("rw_i93_send_cmd_write_dsfid (): Cannot allocate buffer");
+    return NFC_STATUS_NO_BUFFERS;
+  }
+
+  p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p_cmd->len = 11;
+  p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
+
+  /* Flags */
+  UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
+                      RW_I93_FLAG_DATA_RATE));
+
+  /* Command Code */
+  UINT8_TO_STREAM(p, I93_CMD_WRITE_DSFID);
+
+  /* Parameters */
+  ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
+  UINT8_TO_STREAM(p, dsfid);              /* DSFID */
+
+  if (rw_i93_send_to_lower(p_cmd)) {
+    rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_DSFID;
+    return NFC_STATUS_OK;
+  } else {
+    return NFC_STATUS_FAILED;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_lock_dsfid
+**
+** Description      Send Lock DSFID Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_lock_dsfid(void) {
+  NFC_HDR* p_cmd;
+  uint8_t* p;
+
+  RW_TRACE_DEBUG0("rw_i93_send_cmd_lock_dsfid ()");
+
+  p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_cmd) {
+    RW_TRACE_ERROR0("rw_i93_send_cmd_lock_dsfid (): Cannot allocate buffer");
+    return NFC_STATUS_NO_BUFFERS;
+  }
+
+  p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p_cmd->len = 10;
+  p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
+
+  /* Flags */
+  UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
+                      RW_I93_FLAG_DATA_RATE));
+
+  /* Command Code */
+  UINT8_TO_STREAM(p, I93_CMD_LOCK_DSFID);
+
+  /* Parameters */
+  ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
+
+  if (rw_i93_send_to_lower(p_cmd)) {
+    rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_DSFID;
+    return NFC_STATUS_OK;
+  } else {
+    return NFC_STATUS_FAILED;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_get_sys_info
+**
+** Description      Send Get System Information Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_get_sys_info(uint8_t* p_uid, uint8_t extra_flags) {
+  NFC_HDR* p_cmd;
+  uint8_t* p;
+
+  RW_TRACE_DEBUG0("rw_i93_send_cmd_get_sys_info ()");
+
+  p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_cmd) {
+    RW_TRACE_ERROR0("rw_i93_send_cmd_get_sys_info (): Cannot allocate buffer");
+    return NFC_STATUS_NO_BUFFERS;
+  }
+
+  p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p_cmd->len = 10;
+  p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
+
+  /* Flags */
+  UINT8_TO_STREAM(p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER |
+                      RW_I93_FLAG_DATA_RATE | extra_flags));
+
+  /* Command Code */
+  UINT8_TO_STREAM(p, I93_CMD_GET_SYS_INFO);
+
+  /* Parameters */
+  if (p_uid) {
+    ARRAY8_TO_STREAM(p, p_uid); /* UID */
+  } else {
+    ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
+  }
+
+  if (rw_i93_send_to_lower(p_cmd)) {
+    rw_cb.tcb.i93.sent_cmd = I93_CMD_GET_SYS_INFO;
+    return NFC_STATUS_OK;
+  } else {
+    return NFC_STATUS_FAILED;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_get_multi_block_sec
+**
+** Description      Send Get Multiple Block Security Status Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_get_multi_block_sec(uint16_t first_block_number,
+                                                uint16_t number_blocks) {
+  NFC_HDR* p_cmd;
+  uint8_t* p, flags;
+
+  RW_TRACE_DEBUG0("rw_i93_send_cmd_get_multi_block_sec ()");
+
+  p_cmd = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_cmd) {
+    RW_TRACE_ERROR0(
+        "rw_i93_send_cmd_get_multi_block_sec (): Cannot allocate buffer");
+    return NFC_STATUS_NO_BUFFERS;
+  }
+
+  p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p_cmd->len = 12;
+  p = (uint8_t*)(p_cmd + 1) + p_cmd->offset;
+
+  /* Flags */
+  flags =
+      (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE);
+
+  if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK)
+    flags |= I93_FLAG_PROT_EXT_YES;
+
+  UINT8_TO_STREAM(p, flags);
+
+  /* Command Code */
+  UINT8_TO_STREAM(p, I93_CMD_GET_MULTI_BLK_SEC);
+
+  /* Parameters */
+  ARRAY8_TO_STREAM(p, rw_cb.tcb.i93.uid); /* UID */
+
+  if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_16BIT_NUM_BLOCK) {
+    UINT16_TO_STREAM(p, first_block_number); /* First block number */
+    UINT16_TO_STREAM(
+        p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
+    p_cmd->len += 2;
+  } else {
+    UINT8_TO_STREAM(p, first_block_number); /* First block number */
+    UINT8_TO_STREAM(
+        p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
+  }
+
+  if (rw_i93_send_to_lower(p_cmd)) {
+    rw_cb.tcb.i93.sent_cmd = I93_CMD_GET_MULTI_BLK_SEC;
+    return NFC_STATUS_OK;
+  } else {
+    return NFC_STATUS_FAILED;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_get_next_blocks
+**
+** Description      Read as many blocks as possible (up to
+**                  RW_I93_READ_MULTI_BLOCK_SIZE)
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_get_next_blocks(uint16_t offset) {
+  tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
+  uint16_t first_block;
+  uint16_t num_block;
+
+  RW_TRACE_DEBUG0("rw_i93_get_next_blocks ()");
+
+  first_block = offset / p_i93->block_size;
+
+  /* more blocks, more efficent but more error rate */
+
+  if (p_i93->intl_flags & RW_I93_FLAG_READ_MULTI_BLOCK) {
+    num_block = RW_I93_READ_MULTI_BLOCK_SIZE / p_i93->block_size;
+
+    if (num_block + first_block > p_i93->num_block)
+      num_block = p_i93->num_block - first_block;
+
+    if (p_i93->uid[1] == I93_UID_IC_MFG_CODE_STM) {
+      /* LRIS64K, M24LR64-R, M24LR04E-R, M24LR16E-R, M24LR64E-R requires
+      ** - The max number of blocks is 32 and they are all located in the
+      **   same sector.
+      ** - The sector is 32 blocks of 4 bytes.
+      */
+      if ((p_i93->product_version == RW_I93_STM_LRIS64K) ||
+          (p_i93->product_version == RW_I93_STM_M24LR64_R) ||
+          (p_i93->product_version == RW_I93_STM_M24LR04E_R) ||
+          (p_i93->product_version == RW_I93_STM_M24LR16E_R) ||
+          (p_i93->product_version == RW_I93_STM_M24LR64E_R)) {
+        if (num_block > I93_STM_MAX_BLOCKS_PER_READ)
+          num_block = I93_STM_MAX_BLOCKS_PER_READ;
+
+        if ((first_block / I93_STM_BLOCKS_PER_SECTOR) !=
+            ((first_block + num_block - 1) / I93_STM_BLOCKS_PER_SECTOR)) {
+          num_block = I93_STM_BLOCKS_PER_SECTOR -
+                      (first_block % I93_STM_BLOCKS_PER_SECTOR);
+        }
+      }
+    }
+
+    return rw_i93_send_cmd_read_multi_blocks(first_block, num_block);
+  } else {
+    return rw_i93_send_cmd_read_single_block(first_block, false);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_get_next_block_sec
+**
+** Description      Get as many security of blocks as possible from
+**                  p_i93->rw_offset (up to RW_I93_GET_MULTI_BLOCK_SEC_SIZE)
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_get_next_block_sec(void) {
+  tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
+  uint16_t num_blocks;
+
+  RW_TRACE_DEBUG0("rw_i93_get_next_block_sec ()");
+
+  if (p_i93->num_block <= p_i93->rw_offset) {
+    RW_TRACE_ERROR2("rw_offset(0x%x) must be less than num_block(0x%x)",
+                    p_i93->rw_offset, p_i93->num_block);
+    return NFC_STATUS_FAILED;
+  }
+
+  num_blocks = p_i93->num_block - p_i93->rw_offset;
+
+  if (num_blocks > RW_I93_GET_MULTI_BLOCK_SEC_SIZE)
+    num_blocks = RW_I93_GET_MULTI_BLOCK_SEC_SIZE;
+
+  return rw_i93_send_cmd_get_multi_block_sec(p_i93->rw_offset, num_blocks);
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_sm_detect_ndef
+**
+** Description      Process NDEF detection procedure
+**
+**                  1. Get UID if not having yet
+**                  2. Get System Info if not having yet
+**                  3. Read first block for CC
+**                  4. Search NDEF Type and length
+**                  5. Get block status to get max NDEF size and read-only
+**                     status
+**
+** Returns          void
+**
+*******************************************************************************/
+void rw_i93_sm_detect_ndef(NFC_HDR* p_resp) {
+  uint8_t* p = (uint8_t*)(p_resp + 1) + p_resp->offset, *p_uid;
+  uint8_t flags, u8 = 0, cc[4];
+  uint16_t length = p_resp->len, xx, block, first_block, last_block, num_blocks;
+  tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
+  tRW_DATA rw_data;
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+
+#if (BT_TRACE_VERBOSE == true)
+  RW_TRACE_DEBUG2("rw_i93_sm_detect_ndef () sub_state:%s (0x%x)",
+                  rw_i93_get_sub_state_name(p_i93->sub_state),
+                  p_i93->sub_state);
+#else
+  RW_TRACE_DEBUG1("rw_i93_sm_detect_ndef () sub_state:0x%x", p_i93->sub_state);
+#endif
+
+  STREAM_TO_UINT8(flags, p);
+  length--;
+
+  if (flags & I93_FLAG_ERROR_DETECTED) {
+    if ((length) && (rw_i93_check_sys_info_prot_ext(*p))) {
+      /* getting system info with protocol extension flag */
+      /* This STM tag supports more than 2040 bytes */
+      p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
+    } else {
+      RW_TRACE_DEBUG1("Got error flags (0x%02x)", flags);
+      rw_i93_handle_error(NFC_STATUS_FAILED);
+    }
+    return;
+  }
+
+  switch (p_i93->sub_state) {
+    case RW_I93_SUBSTATE_WAIT_UID:
+
+      STREAM_TO_UINT8(u8, p); /* DSFID */
+      p_uid = p_i93->uid;
+      STREAM_TO_ARRAY8(p_uid, p);
+
+      if (u8 != I93_DFS_UNSUPPORTED) {
+        /* if Data Storage Format is unknown */
+        RW_TRACE_DEBUG1("Got unknown DSFID (0x%02x)", u8);
+        rw_i93_handle_error(NFC_STATUS_FAILED);
+      } else {
+        /* get system information to get memory size */
+        if (rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_NO) ==
+            NFC_STATUS_OK) {
+          p_i93->sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
+        } else {
+          rw_i93_handle_error(NFC_STATUS_FAILED);
+        }
+      }
+      break;
+
+    case RW_I93_SUBSTATE_WAIT_SYS_INFO:
+
+      p_i93->block_size = 0;
+      p_i93->num_block = 0;
+
+      if (!rw_i93_process_sys_info(p)) {
+        /* retrying with protocol extension flag */
+        break;
+      }
+
+      if ((p_i93->block_size == 0) || (p_i93->num_block == 0)) {
+        RW_TRACE_DEBUG0("Unable to get tag memory size");
+        rw_i93_handle_error(status);
+      } else {
+        /* read CC in the first block */
+        if (rw_i93_send_cmd_read_single_block(0x0000, false) == NFC_STATUS_OK) {
+          p_i93->sub_state = RW_I93_SUBSTATE_WAIT_CC;
+        } else {
+          rw_i93_handle_error(NFC_STATUS_FAILED);
+        }
+      }
+      break;
+
+    case RW_I93_SUBSTATE_WAIT_CC:
+
+      /* assume block size is more than 4 */
+      STREAM_TO_ARRAY(cc, p, 4);
+
+      status = NFC_STATUS_FAILED;
+
+      /*
+      ** Capability Container (CC)
+      **
+      ** CC[0] : magic number (0xE1)
+      ** CC[1] : Bit 7-6:Major version number
+      **       : Bit 5-4:Minor version number
+      **       : Bit 3-2:Read access condition (00b: read access granted
+      **         without any security)
+      **       : Bit 1-0:Write access condition (00b: write access granted
+      **         without any security)
+      ** CC[2] : Memory size in 8 bytes (Ex. 0x04 is 32 bytes) [STM, set to
+      **         0xFF if more than 2040bytes]
+      ** CC[3] : Bit 0:Read multiple blocks is supported [NXP, STM]
+      **       : Bit 1:Inventory page read is supported [NXP]
+      **       : Bit 2:More than 2040 bytes are supported [STM]
+      */
+
+      RW_TRACE_DEBUG4(
+          "rw_i93_sm_detect_ndef (): cc: 0x%02X 0x%02X 0x%02X 0x%02X", cc[0],
+          cc[1], cc[2], cc[3]);
+      RW_TRACE_DEBUG2(
+          "rw_i93_sm_detect_ndef (): Total blocks:0x%04X, Block size:0x%02X",
+          p_i93->num_block, p_i93->block_size);
+
+      if ((cc[0] == I93_ICODE_CC_MAGIC_NUMER) &&
+          ((cc[3] & I93_STM_CC_OVERFLOW_MASK) ||
+           (cc[2] * 8) == (p_i93->num_block * p_i93->block_size))) {
+        if ((cc[1] & I93_ICODE_CC_READ_ACCESS_MASK) ==
+            I93_ICODE_CC_READ_ACCESS_GRANTED) {
+          if ((cc[1] & I93_ICODE_CC_WRITE_ACCESS_MASK) !=
+              I93_ICODE_CC_WRITE_ACCESS_GRANTED) {
+            /* read-only or password required to write */
+            p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
+          }
+          if (cc[3] & I93_ICODE_CC_MBREAD_MASK) {
+            /* tag supports read multi blocks command */
+            p_i93->intl_flags |= RW_I93_FLAG_READ_MULTI_BLOCK;
+          }
+          status = NFC_STATUS_OK;
+        }
+      }
+
+      if (status == NFC_STATUS_OK) {
+        /* seach NDEF TLV from offset 4 when CC file coded on 4 bytes NFC Forum
+         */
+        if (cc[2] != 0)
+          p_i93->rw_offset = 4;
+        else
+          p_i93->rw_offset = 8;
+
+        if (rw_i93_get_next_blocks(p_i93->rw_offset) == NFC_STATUS_OK) {
+          p_i93->sub_state = RW_I93_SUBSTATE_SEARCH_NDEF_TLV;
+          p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_TYPE;
+        } else {
+          rw_i93_handle_error(NFC_STATUS_FAILED);
+        }
+      } else {
+        rw_i93_handle_error(NFC_STATUS_FAILED);
+      }
+      break;
+
+    case RW_I93_SUBSTATE_SEARCH_NDEF_TLV:
+
+      /* search TLV within read blocks */
+      for (xx = 0; xx < length; xx++) {
+        /* if looking for type */
+        if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_TYPE) {
+          if (*(p + xx) == I93_ICODE_TLV_TYPE_NULL) {
+            continue;
+          } else if ((*(p + xx) == I93_ICODE_TLV_TYPE_NDEF) ||
+                     (*(p + xx) == I93_ICODE_TLV_TYPE_PROP)) {
+            /* store found type and get length field */
+            p_i93->tlv_type = *(p + xx);
+            p_i93->ndef_tlv_start_offset = p_i93->rw_offset + xx;
+
+            p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_1;
+          } else if (*(p + xx) == I93_ICODE_TLV_TYPE_TERM) {
+            /* no NDEF TLV found */
+            p_i93->tlv_type = I93_ICODE_TLV_TYPE_TERM;
+            break;
+          } else {
+            RW_TRACE_DEBUG1("Invalid type: 0x%02x", *(p + xx));
+            rw_i93_handle_error(NFC_STATUS_FAILED);
+            return;
+          }
+        } else if (p_i93->tlv_detect_state ==
+                   RW_I93_TLV_DETECT_STATE_LENGTH_1) {
+          /* if 3 bytes length field */
+          if (*(p + xx) == 0xFF) {
+            /* need 2 more bytes for length field */
+            p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_2;
+          } else {
+            p_i93->tlv_length = *(p + xx);
+            p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_VALUE;
+
+            if (p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF) {
+              p_i93->ndef_tlv_last_offset =
+                  p_i93->ndef_tlv_start_offset + 1 + p_i93->tlv_length;
+              break;
+            }
+          }
+        } else if (p_i93->tlv_detect_state ==
+                   RW_I93_TLV_DETECT_STATE_LENGTH_2) {
+          /* the second byte of 3 bytes length field */
+          p_i93->tlv_length = *(p + xx);
+          p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_3;
+        } else if (p_i93->tlv_detect_state ==
+                   RW_I93_TLV_DETECT_STATE_LENGTH_3) {
+          /* the last byte of 3 bytes length field */
+          p_i93->tlv_length = (p_i93->tlv_length << 8) + *(p + xx);
+          p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_VALUE;
+
+          if (p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF) {
+            p_i93->ndef_tlv_last_offset =
+                p_i93->ndef_tlv_start_offset + 3 + p_i93->tlv_length;
+            break;
+          }
+        } else if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_VALUE) {
+          /* this is other than NDEF TLV */
+          if (p_i93->tlv_length <= length - xx) {
+            /* skip value field */
+            xx += (uint8_t)p_i93->tlv_length;
+            p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_TYPE;
+          } else {
+            /* read more data */
+            p_i93->tlv_length -= (length - xx);
+            break;
+          }
+        }
+      }
+
+      /* found NDEF TLV and read length field */
+      if ((p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF) &&
+          (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_VALUE)) {
+        p_i93->ndef_length = p_i93->tlv_length;
+
+        /* get lock status to see if read-only */
+        if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
+            (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) ||
+            ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
+             (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))) {
+          /* these doesn't support GetMultiBlockSecurityStatus */
+
+          p_i93->rw_offset = p_i93->ndef_tlv_start_offset;
+          first_block = p_i93->ndef_tlv_start_offset / p_i93->block_size;
+
+          /* read block to get lock status */
+          rw_i93_send_cmd_read_single_block(first_block, true);
+          p_i93->sub_state = RW_I93_SUBSTATE_CHECK_LOCK_STATUS;
+        } else {
+          /* block offset for read-only check */
+          p_i93->rw_offset = 0;
+
+          if (rw_i93_get_next_block_sec() == NFC_STATUS_OK) {
+            p_i93->sub_state = RW_I93_SUBSTATE_CHECK_LOCK_STATUS;
+          } else {
+            rw_i93_handle_error(NFC_STATUS_FAILED);
+          }
+        }
+      } else {
+        /* read more data */
+        p_i93->rw_offset += length;
+
+        if (p_i93->rw_offset >= p_i93->block_size * p_i93->num_block) {
+          rw_i93_handle_error(NFC_STATUS_FAILED);
+        } else if (rw_i93_get_next_blocks(p_i93->rw_offset) == NFC_STATUS_OK) {
+          p_i93->sub_state = RW_I93_SUBSTATE_SEARCH_NDEF_TLV;
+        } else {
+          rw_i93_handle_error(NFC_STATUS_FAILED);
+        }
+      }
+      break;
+
+    case RW_I93_SUBSTATE_CHECK_LOCK_STATUS:
+
+      if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
+          (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) ||
+          ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
+           (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))) {
+        /* these doesn't support GetMultiBlockSecurityStatus */
+
+        block = (p_i93->rw_offset / p_i93->block_size);
+        last_block = (p_i93->ndef_tlv_last_offset / p_i93->block_size);
+
+        if ((*p) & I93_BLOCK_LOCKED) {
+          if (block <= last_block) {
+            p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
+          }
+        } else {
+          /* if we need to check more user blocks */
+          if (block + 1 < p_i93->num_block) {
+            p_i93->rw_offset += p_i93->block_size;
+
+            /* read block to get lock status */
+            rw_i93_send_cmd_read_single_block(
+                (uint16_t)(p_i93->rw_offset / p_i93->block_size), true);
+            break;
+          }
+        }
+
+        p_i93->max_ndef_length =
+            p_i93->ndef_length
+            /* add available bytes including the last block of NDEF TLV */
+            +
+            (p_i93->block_size * (block - last_block) + 1) -
+            (p_i93->ndef_tlv_last_offset % p_i93->block_size) - 1;
+      } else {
+        if (p_i93->rw_offset == 0) {
+          p_i93->max_ndef_length =
+              p_i93->ndef_length
+              /* add available bytes in the last block of NDEF TLV */
+              +
+              p_i93->block_size -
+              (p_i93->ndef_tlv_last_offset % p_i93->block_size) - 1;
+
+          first_block = (p_i93->ndef_tlv_start_offset / p_i93->block_size);
+        } else {
+          first_block = 0;
+        }
+
+        last_block = (p_i93->ndef_tlv_last_offset / p_i93->block_size);
+        num_blocks = length;
+
+        for (block = first_block; block < num_blocks; block++) {
+          /* if any block of NDEF TLV is locked */
+          if ((block + p_i93->rw_offset) <= last_block) {
+            if (*(p + block) & I93_BLOCK_LOCKED) {
+              p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
+              break;
+            }
+          } else {
+            if (*(p + block) & I93_BLOCK_LOCKED) {
+              /* no more consecutive unlocked block */
+              break;
+            } else {
+              /* add block size if not locked */
+              p_i93->max_ndef_length += p_i93->block_size;
+            }
+          }
+        }
+
+        /* update next security of block to check */
+        p_i93->rw_offset += num_blocks;
+
+        /* if need to check more */
+        if (p_i93->num_block > p_i93->rw_offset) {
+          if (rw_i93_get_next_block_sec() != NFC_STATUS_OK) {
+            rw_i93_handle_error(NFC_STATUS_FAILED);
+          }
+          break;
+        }
+      }
+
+      /* check if need to adjust max NDEF length */
+      if ((p_i93->ndef_length < 0xFF) && (p_i93->max_ndef_length >= 0xFF)) {
+        /* 3 bytes length field must be used */
+        p_i93->max_ndef_length -= 2;
+      }
+
+      rw_data.ndef.status = NFC_STATUS_OK;
+      rw_data.ndef.protocol = NFC_PROTOCOL_15693;
+      rw_data.ndef.flags = 0;
+      rw_data.ndef.flags |= RW_NDEF_FL_SUPPORTED;
+      rw_data.ndef.flags |= RW_NDEF_FL_FORMATED;
+      rw_data.ndef.flags |= RW_NDEF_FL_FORMATABLE;
+      rw_data.ndef.cur_size = p_i93->ndef_length;
+
+      if (p_i93->intl_flags & RW_I93_FLAG_READ_ONLY) {
+        rw_data.ndef.flags |= RW_NDEF_FL_READ_ONLY;
+        rw_data.ndef.max_size = p_i93->ndef_length;
+      } else {
+        rw_data.ndef.flags |= RW_NDEF_FL_HARD_LOCKABLE;
+        rw_data.ndef.max_size = p_i93->max_ndef_length;
+      }
+
+      p_i93->state = RW_I93_STATE_IDLE;
+      p_i93->sent_cmd = 0;
+
+      RW_TRACE_DEBUG3("NDEF cur_size(%d),max_size (%d), flags (0x%x)",
+                      rw_data.ndef.cur_size, rw_data.ndef.max_size,
+                      rw_data.ndef.flags);
+
+      (*(rw_cb.p_cback))(RW_I93_NDEF_DETECT_EVT, &rw_data);
+      break;
+
+    default:
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_sm_read_ndef
+**
+** Description      Process NDEF read procedure
+**
+** Returns          void
+**
+*******************************************************************************/
+void rw_i93_sm_read_ndef(NFC_HDR* p_resp) {
+#if (NXP_EXTNS == TRUE)
+  uint8_t* p;
+  uint16_t offset = 0, length = 0;
+#else
+  uint8_t* p = (uint8_t*)(p_resp + 1) + p_resp->offset;
+  uint16_t offset, length = p_resp->len;
+#endif
+
+  uint8_t flags;
+
+  tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
+  tRW_DATA rw_data;
+
+  RW_TRACE_DEBUG0("rw_i93_sm_read_ndef ()");
+
+  if (NULL == p_resp) {
+    RW_TRACE_DEBUG0("rw_i93_sm_read_ndef: p_resp is NULL");
+    return;
+  }
+#if (NXP_EXTNS == TRUE)
+  p = (uint8_t*)(p_resp + 1) + p_resp->offset;
+  length = p_resp->len;
+#endif
+  STREAM_TO_UINT8(flags, p);
+  length--;
+
+  if (flags & I93_FLAG_ERROR_DETECTED) {
+    RW_TRACE_DEBUG1("Got error flags (0x%02x)", flags);
+    rw_i93_handle_error(NFC_STATUS_FAILED);
+    return;
+  }
+
+  /* if this is the first block */
+  if (p_i93->rw_length == 0) {
+    /* get start of NDEF in the first block */
+    offset = p_i93->ndef_tlv_start_offset % p_i93->block_size;
+
+    if (p_i93->ndef_length < 0xFF) {
+      offset += 2;
+    } else {
+      offset += 4;
+    }
+
+    /* adjust offset if read more blocks because the first block doesn't have
+     * NDEF */
+    offset -= (p_i93->rw_offset - p_i93->ndef_tlv_start_offset);
+  } else {
+    offset = 0;
+  }
+
+  /* if read enough data to skip type and length field for the beginning */
+  if (offset < length) {
+    offset++; /* flags */
+    p_resp->offset += offset;
+    p_resp->len -= offset;
+
+    rw_data.data.status = NFC_STATUS_OK;
+    rw_data.data.p_data = p_resp;
+
+    p_i93->rw_length += p_resp->len;
+  } else {
+    /* in case of no Ndef data included */
+    p_resp->len = 0;
+  }
+
+  /* if read all of NDEF data */
+  if (p_i93->rw_length >= p_i93->ndef_length) {
+    /* remove extra btyes in the last block */
+    p_resp->len -= (p_i93->rw_length - p_i93->ndef_length);
+
+    p_i93->state = RW_I93_STATE_IDLE;
+    p_i93->sent_cmd = 0;
+
+    RW_TRACE_DEBUG2("NDEF read complete read (%d)/total (%d)", p_resp->len,
+                    p_i93->ndef_length);
+
+    (*(rw_cb.p_cback))(RW_I93_NDEF_READ_CPLT_EVT, &rw_data);
+  } else {
+    RW_TRACE_DEBUG2("NDEF read segment read (%d)/total (%d)", p_resp->len,
+                    p_i93->ndef_length);
+
+    if (p_resp->len > 0) {
+      (*(rw_cb.p_cback))(RW_I93_NDEF_READ_EVT, &rw_data);
+    }
+
+    /* this will make read data from next block */
+    p_i93->rw_offset += length;
+
+    if (rw_i93_get_next_blocks(p_i93->rw_offset) != NFC_STATUS_OK) {
+      rw_i93_handle_error(NFC_STATUS_FAILED);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_sm_update_ndef
+**
+** Description      Process NDEF update procedure
+**
+**                  1. Set length field to zero
+**                  2. Write NDEF and Terminator TLV
+**                  3. Set length field to NDEF length
+**
+** Returns          void
+**
+*******************************************************************************/
+void rw_i93_sm_update_ndef(NFC_HDR* p_resp) {
+  uint8_t* p = (uint8_t*)(p_resp + 1) + p_resp->offset;
+  uint8_t flags, xx, length_offset, buff[I93_MAX_BLOCK_LENGH];
+  uint16_t length = p_resp->len, block_number;
+  tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
+  tRW_DATA rw_data;
+
+#if (BT_TRACE_VERBOSE == true)
+  RW_TRACE_DEBUG2("rw_i93_sm_update_ndef () sub_state:%s (0x%x)",
+                  rw_i93_get_sub_state_name(p_i93->sub_state),
+                  p_i93->sub_state);
+#else
+  RW_TRACE_DEBUG1("rw_i93_sm_update_ndef () sub_state:0x%x", p_i93->sub_state);
+#endif
+
+  STREAM_TO_UINT8(flags, p);
+  length--;
+
+  if (flags & I93_FLAG_ERROR_DETECTED) {
+    if (((p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
+         (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
+         (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
+         (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) &&
+        (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE)) {
+      /* ignore error */
+    } else {
+      RW_TRACE_DEBUG1("Got error flags (0x%02x)", flags);
+      rw_i93_handle_error(NFC_STATUS_FAILED);
+      return;
+    }
+  }
+
+  switch (p_i93->sub_state) {
+    case RW_I93_SUBSTATE_RESET_LEN:
+
+      /* get offset of length field */
+      length_offset = (p_i93->ndef_tlv_start_offset + 1) % p_i93->block_size;
+
+      /* set length to zero */
+      *(p + length_offset) = 0x00;
+
+      if (p_i93->ndef_length > 0) {
+        /* if 3 bytes length field is needed */
+        if (p_i93->ndef_length >= 0xFF) {
+          xx = length_offset + 3;
+        } else {
+          xx = length_offset + 1;
+        }
+
+        /* write the first part of NDEF in the same block */
+        for (; xx < p_i93->block_size; xx++) {
+          if (p_i93->rw_length < p_i93->ndef_length) {
+            *(p + xx) = *(p_i93->p_update_data + p_i93->rw_length++);
+          } else {
+            *(p + xx) = I93_ICODE_TLV_TYPE_NULL;
+          }
+        }
+      }
+
+      block_number = (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
+
+      if (rw_i93_send_cmd_write_single_block(block_number, p) ==
+          NFC_STATUS_OK) {
+        /* update next writing offset */
+        p_i93->rw_offset = (block_number + 1) * p_i93->block_size;
+        p_i93->sub_state = RW_I93_SUBSTATE_WRITE_NDEF;
+      } else {
+        rw_i93_handle_error(NFC_STATUS_FAILED);
+      }
+      break;
+
+    case RW_I93_SUBSTATE_WRITE_NDEF:
+
+      /* if it's not the end of tag memory */
+      if (p_i93->rw_offset < p_i93->block_size * p_i93->num_block) {
+        block_number = p_i93->rw_offset / p_i93->block_size;
+
+        /* if we have more data to write */
+        if (p_i93->rw_length < p_i93->ndef_length) {
+          p = p_i93->p_update_data + p_i93->rw_length;
+
+          p_i93->rw_offset += p_i93->block_size;
+          p_i93->rw_length += p_i93->block_size;
+
+          /* if this is the last block of NDEF TLV */
+          if (p_i93->rw_length > p_i93->ndef_length) {
+            /* length of NDEF TLV in the block */
+            xx = (uint8_t)(p_i93->block_size -
+                           (p_i93->rw_length - p_i93->ndef_length));
+
+            /* set NULL TLV in the unused part of block */
+            memset(buff, I93_ICODE_TLV_TYPE_NULL, p_i93->block_size);
+            memcpy(buff, p, xx);
+            p = buff;
+
+            /* if it's the end of tag memory */
+            if ((p_i93->rw_offset >= p_i93->block_size * p_i93->num_block) &&
+                (xx < p_i93->block_size)) {
+              buff[xx] = I93_ICODE_TLV_TYPE_TERM;
+            }
+
+            p_i93->ndef_tlv_last_offset =
+                p_i93->rw_offset - p_i93->block_size + xx - 1;
+          }
+
+          if (rw_i93_send_cmd_write_single_block(block_number, p) !=
+              NFC_STATUS_OK) {
+            rw_i93_handle_error(NFC_STATUS_FAILED);
+          }
+        } else {
+          /* if this is the very next block of NDEF TLV */
+          if (block_number ==
+              (p_i93->ndef_tlv_last_offset / p_i93->block_size) + 1) {
+            p_i93->rw_offset += p_i93->block_size;
+
+            /* write Terminator TLV and NULL TLV */
+            memset(buff, I93_ICODE_TLV_TYPE_NULL, p_i93->block_size);
+            buff[0] = I93_ICODE_TLV_TYPE_TERM;
+            p = buff;
+
+            if (rw_i93_send_cmd_write_single_block(block_number, p) !=
+                NFC_STATUS_OK) {
+              rw_i93_handle_error(NFC_STATUS_FAILED);
+            }
+          } else {
+            /* finished writing NDEF and Terminator TLV */
+            /* read length field to update length       */
+            block_number =
+                (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
+
+            if (rw_i93_send_cmd_read_single_block(block_number, false) ==
+                NFC_STATUS_OK) {
+              /* set offset to length field */
+              p_i93->rw_offset = p_i93->ndef_tlv_start_offset + 1;
+
+              /* get size of length field */
+              if (p_i93->ndef_length >= 0xFF) {
+                p_i93->rw_length = 3;
+              } else if (p_i93->ndef_length > 0) {
+                p_i93->rw_length = 1;
+              } else {
+                p_i93->rw_length = 0;
+              }
+
+              p_i93->sub_state = RW_I93_SUBSTATE_UPDATE_LEN;
+            } else {
+              rw_i93_handle_error(NFC_STATUS_FAILED);
+            }
+          }
+        }
+      } else {
+        /* if we have no more data to write */
+        if (p_i93->rw_length >= p_i93->ndef_length) {
+          /* finished writing NDEF and Terminator TLV */
+          /* read length field to update length       */
+          block_number = (p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size;
+
+          if (rw_i93_send_cmd_read_single_block(block_number, false) ==
+              NFC_STATUS_OK) {
+            /* set offset to length field */
+            p_i93->rw_offset = p_i93->ndef_tlv_start_offset + 1;
+
+            /* get size of length field */
+            if (p_i93->ndef_length >= 0xFF) {
+              p_i93->rw_length = 3;
+            } else if (p_i93->ndef_length > 0) {
+              p_i93->rw_length = 1;
+            } else {
+              p_i93->rw_length = 0;
+            }
+
+            p_i93->sub_state = RW_I93_SUBSTATE_UPDATE_LEN;
+            break;
+          }
+        }
+        rw_i93_handle_error(NFC_STATUS_FAILED);
+      }
+      break;
+
+    case RW_I93_SUBSTATE_UPDATE_LEN:
+
+      /* if we have more length field to write */
+      if (p_i93->rw_length > 0) {
+        /* if we got ack for writing, read next block to update rest of length
+         * field */
+        if (length == 0) {
+          block_number = p_i93->rw_offset / p_i93->block_size;
+
+          if (rw_i93_send_cmd_read_single_block(block_number, false) !=
+              NFC_STATUS_OK) {
+            rw_i93_handle_error(NFC_STATUS_FAILED);
+          }
+        } else {
+          length_offset = p_i93->rw_offset % p_i93->block_size;
+
+          /* update length field within the read block */
+          for (xx = length_offset; xx < p_i93->block_size; xx++) {
+            if (p_i93->rw_length == 3)
+              *(p + xx) = 0xFF;
+            else if (p_i93->rw_length == 2)
+              *(p + xx) = (uint8_t)((p_i93->ndef_length >> 8) & 0xFF);
+            else if (p_i93->rw_length == 1)
+              *(p + xx) = (uint8_t)(p_i93->ndef_length & 0xFF);
+
+            p_i93->rw_length--;
+            if (p_i93->rw_length == 0) break;
+          }
+
+          block_number = (p_i93->rw_offset / p_i93->block_size);
+
+          if (rw_i93_send_cmd_write_single_block(block_number, p) ==
+              NFC_STATUS_OK) {
+            /* set offset to the beginning of next block */
+            p_i93->rw_offset +=
+                p_i93->block_size - (p_i93->rw_offset % p_i93->block_size);
+          } else {
+            rw_i93_handle_error(NFC_STATUS_FAILED);
+          }
+        }
+      } else {
+        RW_TRACE_DEBUG3("NDEF update complete, %d bytes, (%d-%d)",
+                        p_i93->ndef_length, p_i93->ndef_tlv_start_offset,
+                        p_i93->ndef_tlv_last_offset);
+
+        p_i93->state = RW_I93_STATE_IDLE;
+        p_i93->sent_cmd = 0;
+        p_i93->p_update_data = NULL;
+
+        rw_data.status = NFC_STATUS_OK;
+        (*(rw_cb.p_cback))(RW_I93_NDEF_UPDATE_CPLT_EVT, &rw_data);
+      }
+      break;
+
+    default:
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_sm_format
+**
+** Description      Process format procedure
+**
+**                  1. Get UID
+**                  2. Get sys info for memory size (reset AFI/DSFID)
+**                  3. Get block status to get read-only status
+**                  4. Write CC and empty NDEF
+**
+** Returns          void
+**
+*******************************************************************************/
+void rw_i93_sm_format(NFC_HDR* p_resp) {
+  uint8_t* p = (uint8_t*)(p_resp + 1) + p_resp->offset, *p_uid;
+  uint8_t flags;
+  uint16_t length = p_resp->len, xx, block_number;
+  tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
+  tRW_DATA rw_data;
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+
+#if (BT_TRACE_VERBOSE == true)
+  RW_TRACE_DEBUG2("rw_i93_sm_format () sub_state:%s (0x%x)",
+                  rw_i93_get_sub_state_name(p_i93->sub_state),
+                  p_i93->sub_state);
+#else
+  RW_TRACE_DEBUG1("rw_i93_sm_format () sub_state:0x%x", p_i93->sub_state);
+#endif
+
+  STREAM_TO_UINT8(flags, p);
+  length--;
+
+  if (flags & I93_FLAG_ERROR_DETECTED) {
+    if (((p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
+         (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
+         (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
+         (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) &&
+        (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE)) {
+      /* ignore error */
+    } else if ((length) && (rw_i93_check_sys_info_prot_ext(*p))) {
+      /* getting system info with protocol extension flag */
+      /* This STM tag supports more than 2040 bytes */
+      p_i93->intl_flags |= RW_I93_FLAG_16BIT_NUM_BLOCK;
+      return;
+    } else {
+      RW_TRACE_DEBUG1("Got error flags (0x%02x)", flags);
+      rw_i93_handle_error(NFC_STATUS_FAILED);
+      return;
+    }
+  }
+
+  switch (p_i93->sub_state) {
+    case RW_I93_SUBSTATE_WAIT_UID:
+
+      p++; /* skip DSFID */
+      p_uid = p_i93->uid;
+      STREAM_TO_ARRAY8(p_uid, p); /* store UID */
+
+      /* get system information to get memory size */
+      if (rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_NO) ==
+          NFC_STATUS_OK) {
+        p_i93->sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
+      } else {
+        rw_i93_handle_error(NFC_STATUS_FAILED);
+      }
+      break;
+
+    case RW_I93_SUBSTATE_WAIT_SYS_INFO:
+
+      p_i93->block_size = 0;
+      p_i93->num_block = 0;
+
+      if (!rw_i93_process_sys_info(p)) {
+        /* retrying with protocol extension flag */
+        break;
+      }
+
+      if (p_i93->info_flags & I93_INFO_FLAG_DSFID) {
+        /* DSFID, if any DSFID then reset */
+        if (p_i93->dsfid != I93_DFS_UNSUPPORTED) {
+          p_i93->intl_flags |= RW_I93_FLAG_RESET_DSFID;
+        }
+      }
+      if (p_i93->info_flags & I93_INFO_FLAG_AFI) {
+        /* AFI, reset to 0 */
+        if (p_i93->afi != 0x00) {
+          p_i93->intl_flags |= RW_I93_FLAG_RESET_AFI;
+        }
+      }
+
+      if ((p_i93->block_size == 0) || (p_i93->num_block == 0)) {
+        RW_TRACE_DEBUG0("Unable to get tag memory size");
+        rw_i93_handle_error(status);
+      } else if (p_i93->intl_flags & RW_I93_FLAG_RESET_DSFID) {
+        if (rw_i93_send_cmd_write_dsfid(I93_DFS_UNSUPPORTED) == NFC_STATUS_OK) {
+          p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
+        } else {
+          rw_i93_handle_error(NFC_STATUS_FAILED);
+        }
+      } else if (p_i93->intl_flags & RW_I93_FLAG_RESET_AFI) {
+        if (rw_i93_send_cmd_write_afi(0x00) == NFC_STATUS_OK) {
+          p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
+        } else {
+          rw_i93_handle_error(NFC_STATUS_FAILED);
+        }
+      } else {
+        /* get lock status to see if read-only */
+        if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
+            (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)) {
+          /* these doesn't support GetMultiBlockSecurityStatus */
+
+          rw_cb.tcb.i93.rw_offset = 0;
+
+          /* read blocks with option flag to get block security status */
+          if (rw_i93_send_cmd_read_single_block(0x0000, true) ==
+              NFC_STATUS_OK) {
+            p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
+          } else {
+            rw_i93_handle_error(NFC_STATUS_FAILED);
+          }
+        } else {
+          /* block offset for read-only check */
+          p_i93->rw_offset = 0;
+
+          if (rw_i93_get_next_block_sec() == NFC_STATUS_OK) {
+            p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
+          } else {
+            rw_i93_handle_error(NFC_STATUS_FAILED);
+          }
+        }
+      }
+
+      break;
+
+    case RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI:
+
+      if (p_i93->sent_cmd == I93_CMD_WRITE_DSFID) {
+        p_i93->intl_flags &= ~RW_I93_FLAG_RESET_DSFID;
+      } else if (p_i93->sent_cmd == I93_CMD_WRITE_AFI) {
+        p_i93->intl_flags &= ~RW_I93_FLAG_RESET_AFI;
+      }
+
+      if (p_i93->intl_flags & RW_I93_FLAG_RESET_DSFID) {
+        if (rw_i93_send_cmd_write_dsfid(I93_DFS_UNSUPPORTED) == NFC_STATUS_OK) {
+          p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
+        } else {
+          rw_i93_handle_error(NFC_STATUS_FAILED);
+        }
+      } else if (p_i93->intl_flags & RW_I93_FLAG_RESET_AFI) {
+        if (rw_i93_send_cmd_write_afi(0x00) == NFC_STATUS_OK) {
+          p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
+        } else {
+          rw_i93_handle_error(NFC_STATUS_FAILED);
+        }
+      } else {
+        /* get lock status to see if read-only */
+        if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
+            (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)) {
+          /* these doesn't support GetMultiBlockSecurityStatus */
+
+          rw_cb.tcb.i93.rw_offset = 0;
+
+          /* read blocks with option flag to get block security status */
+          if (rw_i93_send_cmd_read_single_block(0x0000, true) ==
+              NFC_STATUS_OK) {
+            p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
+          } else {
+            rw_i93_handle_error(NFC_STATUS_FAILED);
+          }
+        } else {
+          /* block offset for read-only check */
+          p_i93->rw_offset = 0;
+
+          if (rw_i93_get_next_block_sec() == NFC_STATUS_OK) {
+            p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
+          } else {
+            rw_i93_handle_error(NFC_STATUS_FAILED);
+          }
+        }
+      }
+      break;
+
+    case RW_I93_SUBSTATE_CHECK_READ_ONLY:
+
+      if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
+          (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) ||
+          ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) &&
+           (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))) {
+        if ((*p) & I93_BLOCK_LOCKED) {
+          rw_i93_handle_error(NFC_STATUS_FAILED);
+          break;
+        }
+
+        /* if we checked all of user blocks */
+        if ((p_i93->rw_offset / p_i93->block_size) + 1 == p_i93->num_block) {
+          if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
+              (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
+            /* read the block which has AFI */
+            p_i93->rw_offset = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION;
+            rw_i93_send_cmd_read_single_block(
+                (uint16_t)(p_i93->rw_offset / p_i93->block_size), true);
+            break;
+          }
+        } else if (p_i93->rw_offset ==
+                   I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION) {
+          /* no block is locked */
+        } else {
+          p_i93->rw_offset += p_i93->block_size;
+          rw_i93_send_cmd_read_single_block(
+              (uint16_t)(p_i93->rw_offset / p_i93->block_size), true);
+          break;
+        }
+      } else {
+        /* if any block is locked, we cannot format it */
+        for (xx = 0; xx < length; xx++) {
+          if (*(p + xx) & I93_BLOCK_LOCKED) {
+            rw_i93_handle_error(NFC_STATUS_FAILED);
+            break;
+          }
+        }
+
+        /* update block offset for read-only check */
+        p_i93->rw_offset += length;
+
+        /* if need to get more lock status of blocks */
+        if (p_i93->num_block > p_i93->rw_offset) {
+          if (rw_i93_get_next_block_sec() != NFC_STATUS_OK) {
+            rw_i93_handle_error(NFC_STATUS_FAILED);
+          }
+          break;
+        }
+      }
+
+      /* get buffer to store CC, zero length NDEF TLV and Terminator TLV */
+      p_i93->p_update_data = (uint8_t*)GKI_getbuf(RW_I93_FORMAT_DATA_LEN);
+
+      if (!p_i93->p_update_data) {
+        RW_TRACE_ERROR0("rw_i93_sm_format (): Cannot allocate buffer");
+        rw_i93_handle_error(NFC_STATUS_FAILED);
+        break;
+      }
+
+      p = p_i93->p_update_data;
+
+      /* Capability Container */
+      *(p++) = I93_ICODE_CC_MAGIC_NUMER; /* magic number */
+      *(p++) = 0x40;                     /* version 1.0, read/write */
+
+      /* if memory size is less than 2048 bytes */
+      if (((p_i93->num_block * p_i93->block_size) / 8) < 0x100)
+        *(p++) = (uint8_t)((p_i93->num_block * p_i93->block_size) /
+                           8); /* memory size */
+      else
+        *(p++) = 0xFF;
+
+      if ((p_i93->product_version == RW_I93_ICODE_SLI) ||
+          (p_i93->product_version == RW_I93_ICODE_SLI_S) ||
+          (p_i93->product_version == RW_I93_ICODE_SLI_L)) {
+        if (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)
+          *(p++) = I93_ICODE_CC_IPREAD_MASK; /* IPREAD */
+        else
+          *(p++) = I93_ICODE_CC_MBREAD_MASK; /* MBREAD, read multi block command
+                                                supported */
+      } else if ((p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
+                 (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)) {
+        *(p++) = I93_ICODE_CC_MBREAD_MASK; /* MBREAD, read multi block command
+                                              supported */
+      } else if ((p_i93->product_version ==
+                  RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
+                 (p_i93->product_version ==
+                  RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
+        *(p++) = 0;
+      } else {
+        /* STM except LRIS2K, Broadcom supports read multi block command */
+
+        /* if memory size is more than 2040 bytes (which is not LRIS2K) */
+        if (((p_i93->num_block * p_i93->block_size) / 8) > 0xFF)
+          *(p++) = (I93_ICODE_CC_MBREAD_MASK | I93_STM_CC_OVERFLOW_MASK);
+        else if (p_i93->product_version == RW_I93_STM_LRIS2K)
+          *(p++) = 0x00;
+        else
+          *(p++) = I93_ICODE_CC_MBREAD_MASK;
+      }
+
+      /* zero length NDEF and Terminator TLV */
+      *(p++) = I93_ICODE_TLV_TYPE_NDEF;
+      *(p++) = 0x00;
+      *(p++) = I93_ICODE_TLV_TYPE_TERM;
+      *(p++) = I93_ICODE_TLV_TYPE_NULL;
+
+      /* start from block 0 */
+      p_i93->rw_offset = 0;
+
+      if (rw_i93_send_cmd_write_single_block(0, p_i93->p_update_data) ==
+          NFC_STATUS_OK) {
+        p_i93->sub_state = RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV;
+        p_i93->rw_offset += p_i93->block_size;
+      } else {
+        rw_i93_handle_error(NFC_STATUS_FAILED);
+      }
+      break;
+
+    case RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV:
+
+      /* if we have more data to write */
+      if (p_i93->rw_offset < RW_I93_FORMAT_DATA_LEN) {
+        block_number = (p_i93->rw_offset / p_i93->block_size);
+        p = p_i93->p_update_data + p_i93->rw_offset;
+
+        if (rw_i93_send_cmd_write_single_block(block_number, p) ==
+            NFC_STATUS_OK) {
+          p_i93->sub_state = RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV;
+          p_i93->rw_offset += p_i93->block_size;
+        } else {
+          rw_i93_handle_error(NFC_STATUS_FAILED);
+        }
+      } else {
+        GKI_freebuf(p_i93->p_update_data);
+        p_i93->p_update_data = NULL;
+
+        p_i93->state = RW_I93_STATE_IDLE;
+        p_i93->sent_cmd = 0;
+
+        rw_data.status = NFC_STATUS_OK;
+        (*(rw_cb.p_cback))(RW_I93_FORMAT_CPLT_EVT, &rw_data);
+      }
+      break;
+
+    default:
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_sm_set_read_only
+**
+** Description      Process read-only procedure
+**
+**                  1. Update CC as read-only
+**                  2. Lock all block of NDEF TLV
+**                  3. Lock block of CC
+**
+** Returns          void
+**
+*******************************************************************************/
+void rw_i93_sm_set_read_only(NFC_HDR* p_resp) {
+  uint8_t* p = (uint8_t*)(p_resp + 1) + p_resp->offset;
+  uint8_t flags, block_number;
+  uint16_t length = p_resp->len;
+  tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
+  tRW_DATA rw_data;
+
+#if (BT_TRACE_VERBOSE == true)
+  RW_TRACE_DEBUG2("rw_i93_sm_set_read_only () sub_state:%s (0x%x)",
+                  rw_i93_get_sub_state_name(p_i93->sub_state),
+                  p_i93->sub_state);
+#else
+  RW_TRACE_DEBUG1("rw_i93_sm_set_read_only () sub_state:0x%x",
+                  p_i93->sub_state);
+#endif
+
+  STREAM_TO_UINT8(flags, p);
+  length--;
+
+  if (flags & I93_FLAG_ERROR_DETECTED) {
+    if (((p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY) ||
+         (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP) ||
+         (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
+         (p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) &&
+        (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE)) {
+      /* ignore error */
+    } else {
+      RW_TRACE_DEBUG1("Got error flags (0x%02x)", flags);
+      rw_i93_handle_error(NFC_STATUS_FAILED);
+      return;
+    }
+  }
+
+  switch (p_i93->sub_state) {
+    case RW_I93_SUBSTATE_WAIT_CC:
+
+      /* mark CC as read-only */
+      *(p + 1) |= I93_ICODE_CC_READ_ONLY;
+
+      if (rw_i93_send_cmd_write_single_block(0, p) == NFC_STATUS_OK) {
+        p_i93->sub_state = RW_I93_SUBSTATE_WAIT_UPDATE_CC;
+      } else {
+        rw_i93_handle_error(NFC_STATUS_FAILED);
+      }
+      break;
+
+    case RW_I93_SUBSTATE_WAIT_UPDATE_CC:
+
+      /* successfully write CC then lock all blocks of NDEF TLV */
+      p_i93->rw_offset = p_i93->ndef_tlv_start_offset;
+      block_number = (uint8_t)(p_i93->rw_offset / p_i93->block_size);
+
+      if (rw_i93_send_cmd_lock_block(block_number) == NFC_STATUS_OK) {
+        p_i93->rw_offset += p_i93->block_size;
+        p_i93->sub_state = RW_I93_SUBSTATE_LOCK_NDEF_TLV;
+      } else {
+        rw_i93_handle_error(NFC_STATUS_FAILED);
+      }
+      break;
+
+    case RW_I93_SUBSTATE_LOCK_NDEF_TLV:
+
+      /* if we need to lock more blocks */
+      if (p_i93->rw_offset < p_i93->ndef_tlv_last_offset) {
+        /* get the next block of NDEF TLV */
+        block_number = (uint8_t)(p_i93->rw_offset / p_i93->block_size);
+
+        if (rw_i93_send_cmd_lock_block(block_number) == NFC_STATUS_OK) {
+          p_i93->rw_offset += p_i93->block_size;
+        } else {
+          rw_i93_handle_error(NFC_STATUS_FAILED);
+        }
+      }
+      /* if the first block of NDEF TLV is different from block of CC */
+      else if (p_i93->ndef_tlv_start_offset / p_i93->block_size != 0) {
+        /* lock block of CC */
+        if (rw_i93_send_cmd_lock_block(0) == NFC_STATUS_OK) {
+          p_i93->sub_state = RW_I93_SUBSTATE_WAIT_LOCK_CC;
+        } else {
+          rw_i93_handle_error(NFC_STATUS_FAILED);
+        }
+      } else {
+        p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
+        p_i93->state = RW_I93_STATE_IDLE;
+        p_i93->sent_cmd = 0;
+
+        rw_data.status = NFC_STATUS_OK;
+        (*(rw_cb.p_cback))(RW_I93_SET_TAG_RO_EVT, &rw_data);
+      }
+      break;
+
+    case RW_I93_SUBSTATE_WAIT_LOCK_CC:
+
+      p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
+      p_i93->state = RW_I93_STATE_IDLE;
+      p_i93->sent_cmd = 0;
+
+      rw_data.status = NFC_STATUS_OK;
+      (*(rw_cb.p_cback))(RW_I93_SET_TAG_RO_EVT, &rw_data);
+      break;
+
+    default:
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_handle_error
+**
+** Description      notify error to application and clean up
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_i93_handle_error(tNFC_STATUS status) {
+  tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
+  tRW_DATA rw_data;
+  tRW_EVENT event;
+
+  RW_TRACE_DEBUG2("rw_i93_handle_error (): status:0x%02X, state:0x%X", status,
+                  p_i93->state);
+
+  nfc_stop_quick_timer(&p_i93->timer);
+
+  if (rw_cb.p_cback) {
+    rw_data.status = status;
+
+    switch (p_i93->state) {
+      case RW_I93_STATE_IDLE: /* in case of RawFrame */
+        event = RW_I93_INTF_ERROR_EVT;
+        break;
+
+      case RW_I93_STATE_BUSY:
+        if (p_i93->sent_cmd == I93_CMD_STAY_QUIET) {
+          /* There is no response to Stay Quiet command */
+          rw_data.i93_cmd_cmpl.status = NFC_STATUS_OK;
+          rw_data.i93_cmd_cmpl.command = I93_CMD_STAY_QUIET;
+          rw_data.i93_cmd_cmpl.error_code = 0;
+          event = RW_I93_CMD_CMPL_EVT;
+        } else {
+          event = RW_I93_INTF_ERROR_EVT;
+        }
+        break;
+
+      case RW_I93_STATE_DETECT_NDEF:
+        rw_data.ndef.protocol = NFC_PROTOCOL_15693;
+        rw_data.ndef.cur_size = 0;
+        rw_data.ndef.max_size = 0;
+        rw_data.ndef.flags = 0;
+        rw_data.ndef.flags |= RW_NDEF_FL_FORMATABLE;
+        rw_data.ndef.flags |= RW_NDEF_FL_UNKNOWN;
+        event = RW_I93_NDEF_DETECT_EVT;
+        break;
+
+      case RW_I93_STATE_READ_NDEF:
+        event = RW_I93_NDEF_READ_FAIL_EVT;
+        break;
+
+      case RW_I93_STATE_UPDATE_NDEF:
+        p_i93->p_update_data = NULL;
+        event = RW_I93_NDEF_UPDATE_FAIL_EVT;
+        break;
+
+      case RW_I93_STATE_FORMAT:
+        if (p_i93->p_update_data) {
+          GKI_freebuf(p_i93->p_update_data);
+          p_i93->p_update_data = NULL;
+        }
+        event = RW_I93_FORMAT_CPLT_EVT;
+        break;
+
+      case RW_I93_STATE_SET_READ_ONLY:
+        event = RW_I93_SET_TAG_RO_EVT;
+        break;
+
+      case RW_I93_STATE_PRESENCE_CHECK:
+        event = RW_I93_PRESENCE_CHECK_EVT;
+        break;
+
+      default:
+        event = RW_I93_MAX_EVT;
+        break;
+    }
+
+    p_i93->state = RW_I93_STATE_IDLE;
+    p_i93->sent_cmd = 0;
+
+    if (event != RW_I93_MAX_EVT) {
+      (*(rw_cb.p_cback))(event, &rw_data);
+    }
+  } else {
+    p_i93->state = RW_I93_STATE_IDLE;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_process_timeout
+**
+** Description      process timeout event
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_i93_process_timeout(TIMER_LIST_ENT* p_tle) {
+  NFC_HDR* p_buf;
+
+  RW_TRACE_DEBUG1("rw_i93_process_timeout () event=%d", p_tle->event);
+
+  if (p_tle->event == NFC_TTYPE_RW_I93_RESPONSE) {
+    if ((rw_cb.tcb.i93.retry_count < RW_MAX_RETRIES) &&
+        (rw_cb.tcb.i93.p_retry_cmd) &&
+        (rw_cb.tcb.i93.sent_cmd != I93_CMD_STAY_QUIET)) {
+      rw_cb.tcb.i93.retry_count++;
+      RW_TRACE_ERROR1("rw_i93_process_timeout (): retry_count = %d",
+                      rw_cb.tcb.i93.retry_count);
+
+      p_buf = rw_cb.tcb.i93.p_retry_cmd;
+      rw_cb.tcb.i93.p_retry_cmd = NULL;
+
+      if (rw_i93_send_to_lower(p_buf)) {
+        return;
+      }
+    }
+
+    /* all retrial is done or failed to send command to lower layer */
+    if (rw_cb.tcb.i93.p_retry_cmd) {
+      GKI_freebuf(rw_cb.tcb.i93.p_retry_cmd);
+      rw_cb.tcb.i93.p_retry_cmd = NULL;
+      rw_cb.tcb.i93.retry_count = 0;
+    }
+    rw_i93_handle_error(NFC_STATUS_TIMEOUT);
+  } else {
+    RW_TRACE_ERROR1("rw_i93_process_timeout () unknown event=%d", p_tle->event);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_data_cback
+**
+** Description      This callback function receives the data from NFCC.
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_i93_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
+                              tNFC_CONN* p_data) {
+  tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
+  NFC_HDR* p_resp;
+  tRW_DATA rw_data;
+
+#if (BT_TRACE_VERBOSE == true)
+  uint8_t begin_state = p_i93->state;
+#endif
+  (void)conn_id;
+
+  if(p_data == NULL) {
+       RW_TRACE_ERROR0 ("rw_i93_data_cback (): p_data is NULL");
+       return;
+    }
+
+  RW_TRACE_DEBUG2 ("rw_i93_data_cback () event = 0x%X 0x%X", event, p_data->status);
+
+  if ((event == NFC_DEACTIVATE_CEVT) || (event == NFC_ERROR_CEVT)
+#if (NXP_EXTNS == TRUE)
+          || ((event == NFC_DATA_CEVT)&&(p_data->status != NFC_STATUS_OK))
+#endif
+    )
+  {
+    nfc_stop_quick_timer(&p_i93->timer);
+#if(NXP_EXTNS == TRUE)
+        if ((event == NFC_ERROR_CEVT) || (p_data->status != NFC_STATUS_OK))
+#else
+    if (event == NFC_ERROR_CEVT)
+#endif
+    {
+      if ((p_i93->retry_count < RW_MAX_RETRIES) && (p_i93->p_retry_cmd)) {
+        p_i93->retry_count++;
+
+        RW_TRACE_ERROR1("rw_i93_data_cback (): retry_count = %d",
+                        p_i93->retry_count);
+
+        p_resp = p_i93->p_retry_cmd;
+        p_i93->p_retry_cmd = NULL;
+        if (rw_i93_send_to_lower(p_resp)) {
+          return;
+        }
+      }
+
+      /* all retrial is done or failed to send command to lower layer */
+      if (p_i93->p_retry_cmd) {
+        GKI_freebuf(p_i93->p_retry_cmd);
+        p_i93->p_retry_cmd = NULL;
+        p_i93->retry_count = 0;
+      }
+
+      rw_i93_handle_error((tNFC_STATUS)(*(uint8_t*)p_data));
+    } else {
+      /* free retry buffer */
+      if (p_i93->p_retry_cmd) {
+        GKI_freebuf(p_i93->p_retry_cmd);
+        p_i93->p_retry_cmd = NULL;
+        p_i93->retry_count = 0;
+      }
+      NFC_SetStaticRfCback(NULL);
+      p_i93->state = RW_I93_STATE_NOT_ACTIVATED;
+    }
+    return;
+  }
+
+  if (event != NFC_DATA_CEVT) {
+    return;
+  }
+
+  p_resp = (NFC_HDR*)p_data->data.p_data;
+
+  nfc_stop_quick_timer(&p_i93->timer);
+
+  /* free retry buffer */
+  if (p_i93->p_retry_cmd) {
+    GKI_freebuf(p_i93->p_retry_cmd);
+    p_i93->p_retry_cmd = NULL;
+    p_i93->retry_count = 0;
+  }
+
+#if (BT_TRACE_PROTOCOL == true)
+  DispRWI93Tag(p_resp, true, p_i93->sent_cmd);
+#endif
+
+#if (BT_TRACE_VERBOSE == true)
+  RW_TRACE_DEBUG2("RW I93 state: <%s (%d)>",
+                  rw_i93_get_state_name(p_i93->state), p_i93->state);
+#else
+  RW_TRACE_DEBUG1("RW I93 state: %d", p_i93->state);
+#endif
+
+  switch (p_i93->state) {
+    case RW_I93_STATE_IDLE:
+      /* Unexpected Response from VICC, it should be raw frame response */
+      /* forward to upper layer without parsing */
+      p_i93->sent_cmd = 0;
+      if (rw_cb.p_cback) {
+        rw_data.raw_frame.status = p_data->data.status;
+        rw_data.raw_frame.p_data = p_resp;
+        (*(rw_cb.p_cback))(RW_I93_RAW_FRAME_EVT, &rw_data);
+        p_resp = NULL;
+      } else {
+        GKI_freebuf(p_resp);
+      }
+      break;
+    case RW_I93_STATE_BUSY:
+      p_i93->state = RW_I93_STATE_IDLE;
+      rw_i93_send_to_upper(p_resp);
+      GKI_freebuf(p_resp);
+      break;
+
+    case RW_I93_STATE_DETECT_NDEF:
+      rw_i93_sm_detect_ndef(p_resp);
+      GKI_freebuf(p_resp);
+      break;
+
+    case RW_I93_STATE_READ_NDEF:
+      rw_i93_sm_read_ndef(p_resp);
+      /* p_resp may send upper lyaer */
+      break;
+
+    case RW_I93_STATE_UPDATE_NDEF:
+      rw_i93_sm_update_ndef(p_resp);
+      GKI_freebuf(p_resp);
+      break;
+
+    case RW_I93_STATE_FORMAT:
+      rw_i93_sm_format(p_resp);
+      GKI_freebuf(p_resp);
+      break;
+
+    case RW_I93_STATE_SET_READ_ONLY:
+      rw_i93_sm_set_read_only(p_resp);
+      GKI_freebuf(p_resp);
+      break;
+
+    case RW_I93_STATE_PRESENCE_CHECK:
+      p_i93->state = RW_I93_STATE_IDLE;
+      p_i93->sent_cmd = 0;
+
+      /* if any response, send presence check with ok */
+      rw_data.status = NFC_STATUS_OK;
+      (*(rw_cb.p_cback))(RW_I93_PRESENCE_CHECK_EVT, &rw_data);
+      GKI_freebuf(p_resp);
+      break;
+
+    default:
+      RW_TRACE_ERROR1("rw_i93_data_cback (): invalid state=%d", p_i93->state);
+      GKI_freebuf(p_resp);
+      break;
+  }
+
+#if (BT_TRACE_VERBOSE == true)
+  if (begin_state != p_i93->state) {
+    RW_TRACE_DEBUG2("RW I93 state changed:<%s> -> <%s>",
+                    rw_i93_get_state_name(begin_state),
+                    rw_i93_get_state_name(p_i93->state));
+  }
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_select
+**
+** Description      Initialise ISO 15693 RW
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_select(uint8_t* p_uid) {
+  tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
+  uint8_t uid[I93_UID_BYTE_LEN], *p;
+
+  RW_TRACE_DEBUG0("rw_i93_select ()");
+
+  NFC_SetStaticRfCback(rw_i93_data_cback);
+
+  p_i93->state = RW_I93_STATE_IDLE;
+
+  /* convert UID to big endian format - MSB(0xE0) in first byte */
+  p = uid;
+  STREAM_TO_ARRAY8(p, p_uid);
+
+  rw_i93_get_product_version(uid);
+
+  return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93Inventory
+**
+** Description      This function send Inventory command with/without AFI
+**                  If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
+**
+**                  RW_I93_RESPONSE_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93Inventory(bool including_afi, uint8_t afi, uint8_t* p_uid) {
+  tNFC_STATUS status;
+
+  RW_TRACE_API2("RW_I93Inventory (), including_afi:%d, AFI:0x%02X",
+                including_afi, afi);
+
+  if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
+    RW_TRACE_ERROR1(
+        "RW_I93Inventory ():Unable to start command at state (0x%X)",
+        rw_cb.tcb.i93.state);
+    return NFC_STATUS_BUSY;
+  }
+
+  status = rw_i93_send_cmd_inventory(p_uid, including_afi, afi);
+
+  if (status == NFC_STATUS_OK) {
+    rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+  }
+
+  return (status);
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93StayQuiet
+**
+** Description      This function send Inventory command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93StayQuiet(void) {
+  tNFC_STATUS status;
+
+  RW_TRACE_API0("RW_I93StayQuiet ()");
+
+  if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
+    RW_TRACE_ERROR1(
+        "RW_I93StayQuiet ():Unable to start command at state (0x%X)",
+        rw_cb.tcb.i93.state);
+    return NFC_STATUS_BUSY;
+  }
+
+  status = rw_i93_send_cmd_stay_quiet();
+  if (status == NFC_STATUS_OK) {
+    rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93ReadSingleBlock
+**
+** Description      This function send Read Single Block command
+**
+**                  RW_I93_RESPONSE_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93ReadSingleBlock(uint16_t block_number) {
+  tNFC_STATUS status;
+
+  RW_TRACE_API1("RW_I93ReadSingleBlock () block_number:0x%02X", block_number);
+
+  if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
+    RW_TRACE_ERROR1(
+        "RW_I93ReadSingleBlock ():Unable to start command at state (0x%X)",
+        rw_cb.tcb.i93.state);
+    return NFC_STATUS_BUSY;
+  }
+
+  status = rw_i93_send_cmd_read_single_block(block_number, false);
+  if (status == NFC_STATUS_OK) {
+    rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93WriteSingleBlock
+**
+** Description      This function send Write Single Block command
+**                  Application must get block size first by calling
+**                  RW_I93GetSysInfo().
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93WriteSingleBlock(uint16_t block_number, uint8_t* p_data) {
+  tNFC_STATUS status;
+
+  RW_TRACE_API0("RW_I93WriteSingleBlock ()");
+
+  if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
+    RW_TRACE_ERROR1(
+        "RW_I93WriteSingleBlock ():Unable to start command at state (0x%X)",
+        rw_cb.tcb.i93.state);
+    return NFC_STATUS_BUSY;
+  }
+
+  if (rw_cb.tcb.i93.block_size == 0) {
+    RW_TRACE_ERROR0("RW_I93WriteSingleBlock ():Block size is unknown");
+    return NFC_STATUS_FAILED;
+  }
+
+  status = rw_i93_send_cmd_write_single_block(block_number, p_data);
+  if (status == NFC_STATUS_OK) {
+    rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93LockBlock
+**
+** Description      This function send Lock Block command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93LockBlock(uint8_t block_number) {
+  tNFC_STATUS status;
+
+  RW_TRACE_API0("RW_I93LockBlock ()");
+
+  if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
+    RW_TRACE_ERROR1(
+        "RW_I93LockBlock ():Unable to start command at state (0x%X)",
+        rw_cb.tcb.i93.state);
+    return NFC_STATUS_BUSY;
+  }
+
+  status = rw_i93_send_cmd_lock_block(block_number);
+  if (status == NFC_STATUS_OK) {
+    rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93ReadMultipleBlocks
+**
+** Description      This function send Read Multiple Blocks command
+**
+**                  RW_I93_RESPONSE_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93ReadMultipleBlocks(uint16_t first_block_number,
+                                     uint16_t number_blocks) {
+  tNFC_STATUS status;
+
+  RW_TRACE_API0("RW_I93ReadMultipleBlocks ()");
+
+  if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
+    RW_TRACE_ERROR1(
+        "RW_I93ReadMultipleBlocks ():Unable to start command at state (0x%X)",
+        rw_cb.tcb.i93.state);
+    return NFC_STATUS_BUSY;
+  }
+
+  status = rw_i93_send_cmd_read_multi_blocks(first_block_number, number_blocks);
+  if (status == NFC_STATUS_OK) {
+    rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93WriteMultipleBlocks
+**
+** Description      This function send Write Multiple Blocks command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93WriteMultipleBlocks(uint8_t first_block_number,
+                                      uint16_t number_blocks, uint8_t* p_data) {
+  tNFC_STATUS status;
+
+  RW_TRACE_API0("RW_I93WriteMultipleBlocks ()");
+
+  if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
+    RW_TRACE_ERROR1(
+        "RW_I93WriteMultipleBlocks ():Unable to start command at state (0x%X)",
+        rw_cb.tcb.i93.state);
+    return NFC_STATUS_BUSY;
+  }
+
+  if (rw_cb.tcb.i93.block_size == 0) {
+    RW_TRACE_ERROR0("RW_I93WriteSingleBlock ():Block size is unknown");
+    return NFC_STATUS_FAILED;
+  }
+
+  status = rw_i93_send_cmd_write_multi_blocks(first_block_number, number_blocks,
+                                              p_data);
+  if (status == NFC_STATUS_OK) {
+    rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93Select
+**
+** Description      This function send Select command
+**
+**                  UID[0]: 0xE0, MSB
+**                  UID[1]: IC Mfg Code
+**                  ...
+**                  UID[7]: LSB
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93Select(uint8_t* p_uid) {
+  tNFC_STATUS status;
+
+  RW_TRACE_API0("RW_I93Select ()");
+
+  if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
+    RW_TRACE_ERROR1("RW_I93Select ():Unable to start command at state (0x%X)",
+                    rw_cb.tcb.i93.state);
+    return NFC_STATUS_BUSY;
+  }
+
+  if (p_uid) {
+    status = rw_i93_send_cmd_select(p_uid);
+    if (status == NFC_STATUS_OK) {
+      rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+    }
+  } else {
+    RW_TRACE_ERROR0("RW_I93Select ():UID shall be provided");
+    status = NFC_STATUS_FAILED;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93ResetToReady
+**
+** Description      This function send Reset To Ready command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93ResetToReady(void) {
+  tNFC_STATUS status;
+
+  RW_TRACE_API0("RW_I93ResetToReady ()");
+
+  if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
+    RW_TRACE_ERROR1(
+        "RW_I93ResetToReady ():Unable to start command at state (0x%X)",
+        rw_cb.tcb.i93.state);
+    return NFC_STATUS_BUSY;
+  }
+
+  status = rw_i93_send_cmd_reset_to_ready();
+  if (status == NFC_STATUS_OK) {
+    rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93WriteAFI
+**
+** Description      This function send Write AFI command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93WriteAFI(uint8_t afi) {
+  tNFC_STATUS status;
+
+  RW_TRACE_API0("RW_I93WriteAFI ()");
+
+  if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
+    RW_TRACE_ERROR1("RW_I93WriteAFI ():Unable to start command at state (0x%X)",
+                    rw_cb.tcb.i93.state);
+    return NFC_STATUS_BUSY;
+  }
+
+  status = rw_i93_send_cmd_write_afi(afi);
+  if (status == NFC_STATUS_OK) {
+    rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93LockAFI
+**
+** Description      This function send Lock AFI command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93LockAFI(void) {
+  tNFC_STATUS status;
+
+  RW_TRACE_API0("RW_I93LockAFI ()");
+
+  if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
+    RW_TRACE_ERROR1("RW_I93LockAFI ():Unable to start command at state (0x%X)",
+                    rw_cb.tcb.i93.state);
+    return NFC_STATUS_BUSY;
+  }
+
+  status = rw_i93_send_cmd_lock_afi();
+  if (status == NFC_STATUS_OK) {
+    rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93WriteDSFID
+**
+** Description      This function send Write DSFID command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93WriteDSFID(uint8_t dsfid) {
+  tNFC_STATUS status;
+
+  RW_TRACE_API0("RW_I93WriteDSFID ()");
+
+  if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
+    RW_TRACE_ERROR1(
+        "RW_I93WriteDSFID ():Unable to start command at state (0x%X)",
+        rw_cb.tcb.i93.state);
+    return NFC_STATUS_BUSY;
+  }
+
+  status = rw_i93_send_cmd_write_dsfid(dsfid);
+  if (status == NFC_STATUS_OK) {
+    rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93LockDSFID
+**
+** Description      This function send Lock DSFID command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93LockDSFID(void) {
+  tNFC_STATUS status;
+
+  RW_TRACE_API0("RW_I93LockDSFID ()");
+
+  if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
+    RW_TRACE_ERROR1(
+        "RW_I93LockDSFID ():Unable to start command at state (0x%X)",
+        rw_cb.tcb.i93.state);
+    return NFC_STATUS_BUSY;
+  }
+
+  status = rw_i93_send_cmd_lock_dsfid();
+  if (status == NFC_STATUS_OK) {
+    rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93GetSysInfo
+**
+** Description      This function send Get System Information command
+**
+**                  RW_I93_RESPONSE_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93GetSysInfo(uint8_t* p_uid) {
+  tNFC_STATUS status;
+
+  RW_TRACE_API0("RW_I93GetSysInfo ()");
+
+  if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
+    RW_TRACE_ERROR1(
+        "RW_I93GetSysInfo ():Unable to start command at state (0x%X)",
+        rw_cb.tcb.i93.state);
+    return NFC_STATUS_BUSY;
+  }
+
+  if (p_uid) {
+    status = rw_i93_send_cmd_get_sys_info(p_uid, I93_FLAG_PROT_EXT_NO);
+  } else {
+    status = rw_i93_send_cmd_get_sys_info(NULL, I93_FLAG_PROT_EXT_NO);
+  }
+
+  if (status == NFC_STATUS_OK) {
+    rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93GetMultiBlockSecurityStatus
+**
+** Description      This function send Get Multiple Block Security Status
+**                  command
+**
+**                  RW_I93_RESPONSE_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93GetMultiBlockSecurityStatus(uint16_t first_block_number,
+                                              uint16_t number_blocks) {
+  tNFC_STATUS status;
+
+  RW_TRACE_API0("RW_I93GetMultiBlockSecurityStatus ()");
+
+  if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
+    RW_TRACE_ERROR1(
+        "RW_I93GetMultiBlockSecurityStatus ():Unable to start command at state "
+        "(0x%X)",
+        rw_cb.tcb.i93.state);
+    return NFC_STATUS_BUSY;
+  }
+
+  status =
+      rw_i93_send_cmd_get_multi_block_sec(first_block_number, number_blocks);
+  if (status == NFC_STATUS_OK) {
+    rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93DetectNDef
+**
+** Description      This function performs NDEF detection procedure
+**
+**                  RW_I93_NDEF_DETECT_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if busy or other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93DetectNDef(void) {
+  tNFC_STATUS status;
+  tRW_I93_RW_SUBSTATE sub_state;
+
+  RW_TRACE_API0("RW_I93DetectNDef ()");
+
+  if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
+    RW_TRACE_ERROR1(
+        "RW_I93DetectNDef ():Unable to start command at state (0x%X)",
+        rw_cb.tcb.i93.state);
+    return NFC_STATUS_FAILED;
+  }
+
+  if (rw_cb.tcb.i93.uid[0] != I93_UID_FIRST_BYTE) {
+    status = rw_i93_send_cmd_inventory(NULL, false, 0x00);
+    sub_state = RW_I93_SUBSTATE_WAIT_UID;
+  } else if ((rw_cb.tcb.i93.num_block == 0) ||
+             (rw_cb.tcb.i93.block_size == 0)) {
+    status =
+        rw_i93_send_cmd_get_sys_info(rw_cb.tcb.i93.uid, I93_FLAG_PROT_EXT_NO);
+    sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
+
+    /* clear all flags */
+    rw_cb.tcb.i93.intl_flags = 0;
+  } else {
+    /* read CC in the first block */
+    status = rw_i93_send_cmd_read_single_block(0x0000, false);
+    sub_state = RW_I93_SUBSTATE_WAIT_CC;
+  }
+
+  if (status == NFC_STATUS_OK) {
+    rw_cb.tcb.i93.state = RW_I93_STATE_DETECT_NDEF;
+    rw_cb.tcb.i93.sub_state = sub_state;
+
+    /* clear flags except flag for 2 bytes of number of blocks */
+    rw_cb.tcb.i93.intl_flags &= RW_I93_FLAG_16BIT_NUM_BLOCK;
+  }
+
+  return (status);
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93ReadNDef
+**
+** Description      This function performs NDEF read procedure
+**                  Note: RW_I93DetectNDef () must be called before using this
+**
+**                  The following event will be returned
+**                      RW_I93_NDEF_READ_EVT for each segmented NDEF message
+**                      RW_I93_NDEF_READ_CPLT_EVT for the last segment or
+**                      complete NDEF
+**                      RW_I93_NDEF_READ_FAIL_EVT for failure
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if I93 is busy or other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93ReadNDef(void) {
+  RW_TRACE_API0("RW_I93ReadNDef ()");
+
+  if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
+    RW_TRACE_ERROR1("RW_I93ReadNDef ():Unable to start command at state (0x%X)",
+                    rw_cb.tcb.i93.state);
+    return NFC_STATUS_FAILED;
+  }
+
+  if ((rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF) &&
+      (rw_cb.tcb.i93.ndef_length > 0)) {
+    rw_cb.tcb.i93.rw_offset = rw_cb.tcb.i93.ndef_tlv_start_offset;
+    rw_cb.tcb.i93.rw_length = 0;
+
+    if (rw_i93_get_next_blocks(rw_cb.tcb.i93.rw_offset) == NFC_STATUS_OK) {
+      rw_cb.tcb.i93.state = RW_I93_STATE_READ_NDEF;
+    } else {
+      return NFC_STATUS_FAILED;
+    }
+  } else {
+    RW_TRACE_ERROR0("RW_I93ReadNDef ():No NDEF detected");
+    return NFC_STATUS_FAILED;
+  }
+
+  return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93UpdateNDef
+**
+** Description      This function performs NDEF update procedure
+**                  Note: RW_I93DetectNDef () must be called before using this
+**                        Updating data must not be removed until returning
+**                        event
+**
+**                  The following event will be returned
+**                      RW_I93_NDEF_UPDATE_CPLT_EVT for complete
+**                      RW_I93_NDEF_UPDATE_FAIL_EVT for failure
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if I93 is busy or other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93UpdateNDef(uint16_t length, uint8_t* p_data) {
+  uint16_t block_number;
+
+  RW_TRACE_API1("RW_I93UpdateNDef () length:%d", length);
+
+  if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
+    RW_TRACE_ERROR1(
+        "RW_I93UpdateNDef ():Unable to start command at state (0x%X)",
+        rw_cb.tcb.i93.state);
+    return NFC_STATUS_FAILED;
+  }
+
+  if (rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF) {
+    if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_READ_ONLY) {
+      RW_TRACE_ERROR0("RW_I93UpdateNDef ():NDEF is read-only");
+      return NFC_STATUS_FAILED;
+    }
+    if (rw_cb.tcb.i93.max_ndef_length < length) {
+      RW_TRACE_ERROR2(
+          "RW_I93UpdateNDef ():data (%d bytes) is more than max NDEF length "
+          "(%d)",
+          length, rw_cb.tcb.i93.max_ndef_length);
+      return NFC_STATUS_FAILED;
+    }
+
+    rw_cb.tcb.i93.ndef_length = length;
+    rw_cb.tcb.i93.p_update_data = p_data;
+
+    /* read length field */
+    rw_cb.tcb.i93.rw_offset = rw_cb.tcb.i93.ndef_tlv_start_offset + 1;
+    rw_cb.tcb.i93.rw_length = 0;
+
+    block_number = rw_cb.tcb.i93.rw_offset / rw_cb.tcb.i93.block_size;
+
+    if (rw_i93_send_cmd_read_single_block(block_number, false) ==
+        NFC_STATUS_OK) {
+      rw_cb.tcb.i93.state = RW_I93_STATE_UPDATE_NDEF;
+      rw_cb.tcb.i93.sub_state = RW_I93_SUBSTATE_RESET_LEN;
+    } else {
+      return NFC_STATUS_FAILED;
+    }
+  } else {
+    RW_TRACE_ERROR0("RW_I93ReadNDef ():No NDEF detected");
+    return NFC_STATUS_FAILED;
+  }
+
+  return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93FormatNDef
+**
+** Description      This function performs formatting procedure
+**
+**                  RW_I93_FORMAT_CPLT_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if busy or other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93FormatNDef(void) {
+  tNFC_STATUS status;
+  tRW_I93_RW_SUBSTATE sub_state;
+
+  RW_TRACE_API0("RW_I93FormatNDef ()");
+
+  if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
+    RW_TRACE_ERROR1(
+        "RW_I93FormatNDef ():Unable to start command at state (0x%X)",
+        rw_cb.tcb.i93.state);
+    return NFC_STATUS_FAILED;
+  }
+
+  if ((rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY) ||
+      (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)) {
+    /* These don't support GetSystemInformation and GetMultiBlockSecurityStatus
+     */
+    rw_cb.tcb.i93.rw_offset = 0;
+
+    /* read blocks with option flag to get block security status */
+    status = rw_i93_send_cmd_read_single_block(0x0000, true);
+    sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
+  } else {
+    status = rw_i93_send_cmd_inventory(rw_cb.tcb.i93.uid, false, 0x00);
+    sub_state = RW_I93_SUBSTATE_WAIT_UID;
+  }
+
+  if (status == NFC_STATUS_OK) {
+    rw_cb.tcb.i93.state = RW_I93_STATE_FORMAT;
+    rw_cb.tcb.i93.sub_state = sub_state;
+    rw_cb.tcb.i93.intl_flags = 0;
+  }
+
+  return (status);
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93SetTagReadOnly
+**
+** Description      This function performs NDEF read-only procedure
+**                  Note: RW_I93DetectNDef () must be called before using this
+**                        Updating data must not be removed until returning
+**                        event
+**
+**                  The RW_I93_SET_TAG_RO_EVT event will be returned.
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if I93 is busy or other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93SetTagReadOnly(void) {
+  RW_TRACE_API0("RW_I93SetTagReadOnly ()");
+
+  if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
+    RW_TRACE_ERROR1(
+        "RW_I93SetTagReadOnly ():Unable to start command at state (0x%X)",
+        rw_cb.tcb.i93.state);
+    return NFC_STATUS_FAILED;
+  }
+
+  if (rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF) {
+    if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_READ_ONLY) {
+      RW_TRACE_ERROR0("RW_I93SetTagReadOnly ():NDEF is already read-only");
+      return NFC_STATUS_FAILED;
+    }
+
+    /* get CC in the first block */
+    if (rw_i93_send_cmd_read_single_block(0, false) == NFC_STATUS_OK) {
+      rw_cb.tcb.i93.state = RW_I93_STATE_SET_READ_ONLY;
+      rw_cb.tcb.i93.sub_state = RW_I93_SUBSTATE_WAIT_CC;
+    } else {
+      return NFC_STATUS_FAILED;
+    }
+  } else {
+    RW_TRACE_ERROR0("RW_I93SetTagReadOnly ():No NDEF detected");
+    return NFC_STATUS_FAILED;
+  }
+
+  return NFC_STATUS_OK;
+}
+
+/*****************************************************************************
+**
+** Function         RW_I93PresenceCheck
+**
+** Description      Check if the tag is still in the field.
+**
+**                  The RW_I93_PRESENCE_CHECK_EVT w/ status is used to indicate
+**                  presence or non-presence.
+**
+** Returns          NFC_STATUS_OK, if raw data frame sent
+**                  NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this
+**                  operation
+**                  NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_I93PresenceCheck(void) {
+  tNFC_STATUS status;
+  tRW_DATA evt_data;
+
+  RW_TRACE_API0("RW_I93PresenceCheck ()");
+
+  if (!rw_cb.p_cback) {
+    return NFC_STATUS_FAILED;
+  } else if (rw_cb.tcb.i93.state == RW_I93_STATE_NOT_ACTIVATED) {
+    evt_data.status = NFC_STATUS_FAILED;
+    (*rw_cb.p_cback)(RW_T4T_PRESENCE_CHECK_EVT, &evt_data);
+
+    return NFC_STATUS_OK;
+  } else if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE) {
+    return NFC_STATUS_BUSY;
+  } else {
+    /* The support of AFI by the VICC is optional, so do not include AFI */
+    status = rw_i93_send_cmd_inventory(rw_cb.tcb.i93.uid, false, 0x00);
+
+    if (status == NFC_STATUS_OK) {
+      /* do not retry during presence check */
+      rw_cb.tcb.i93.retry_count = RW_MAX_RETRIES;
+      rw_cb.tcb.i93.state = RW_I93_STATE_PRESENCE_CHECK;
+    }
+  }
+
+  return (status);
+}
+
+#if (BT_TRACE_VERBOSE == true)
+/*******************************************************************************
+**
+** Function         rw_i93_get_state_name
+**
+** Description      This function returns the state name.
+**
+** NOTE             conditionally compiled to save memory.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+static char* rw_i93_get_state_name(uint8_t state) {
+  switch (state) {
+    case RW_I93_STATE_NOT_ACTIVATED:
+      return ("NOT_ACTIVATED");
+    case RW_I93_STATE_IDLE:
+      return ("IDLE");
+    case RW_I93_STATE_BUSY:
+      return ("BUSY");
+
+    case RW_I93_STATE_DETECT_NDEF:
+      return ("NDEF_DETECTION");
+    case RW_I93_STATE_READ_NDEF:
+      return ("READ_NDEF");
+    case RW_I93_STATE_UPDATE_NDEF:
+      return ("UPDATE_NDEF");
+    case RW_I93_STATE_FORMAT:
+      return ("FORMAT");
+    case RW_I93_STATE_SET_READ_ONLY:
+      return ("SET_READ_ONLY");
+
+    case RW_I93_STATE_PRESENCE_CHECK:
+      return ("PRESENCE_CHECK");
+    default:
+      return ("???? UNKNOWN STATE");
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_get_sub_state_name
+**
+** Description      This function returns the sub_state name.
+**
+** NOTE             conditionally compiled to save memory.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+static char* rw_i93_get_sub_state_name(uint8_t sub_state) {
+  switch (sub_state) {
+    case RW_I93_SUBSTATE_WAIT_UID:
+      return ("WAIT_UID");
+    case RW_I93_SUBSTATE_WAIT_SYS_INFO:
+      return ("WAIT_SYS_INFO");
+    case RW_I93_SUBSTATE_WAIT_CC:
+      return ("WAIT_CC");
+    case RW_I93_SUBSTATE_SEARCH_NDEF_TLV:
+      return ("SEARCH_NDEF_TLV");
+    case RW_I93_SUBSTATE_CHECK_LOCK_STATUS:
+      return ("CHECK_LOCK_STATUS");
+    case RW_I93_SUBSTATE_RESET_LEN:
+      return ("RESET_LEN");
+    case RW_I93_SUBSTATE_WRITE_NDEF:
+      return ("WRITE_NDEF");
+    case RW_I93_SUBSTATE_UPDATE_LEN:
+      return ("UPDATE_LEN");
+    case RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI:
+      return ("WAIT_RESET_DSFID_AFI");
+    case RW_I93_SUBSTATE_CHECK_READ_ONLY:
+      return ("CHECK_READ_ONLY");
+    case RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV:
+      return ("WRITE_CC_NDEF_TLV");
+    case RW_I93_SUBSTATE_WAIT_UPDATE_CC:
+      return ("WAIT_UPDATE_CC");
+    case RW_I93_SUBSTATE_LOCK_NDEF_TLV:
+      return ("LOCK_NDEF_TLV");
+    case RW_I93_SUBSTATE_WAIT_LOCK_CC:
+      return ("WAIT_LOCK_CC");
+    default:
+      return ("???? UNKNOWN SUBSTATE");
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_get_tag_name
+**
+** Description      This function returns the tag name.
+**
+** NOTE             conditionally compiled to save memory.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+static char* rw_i93_get_tag_name(uint8_t product_version) {
+  switch (product_version) {
+    case RW_I93_ICODE_SLI:
+      return ("SLI/SLIX");
+    case RW_I93_ICODE_SLI_S:
+      return ("SLI-S/SLIX-S");
+    case RW_I93_ICODE_SLI_L:
+      return ("SLI-L/SLIX-L");
+    case RW_I93_TAG_IT_HF_I_PLUS_INLAY:
+      return ("Tag-it HF-I Plus Inlay");
+    case RW_I93_TAG_IT_HF_I_PLUS_CHIP:
+      return ("Tag-it HF-I Plus Chip");
+    case RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY:
+      return ("Tag-it HF-I Standard Chip/Inlyas");
+    case RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY:
+      return ("Tag-it HF-I Pro Chip/Inlays");
+    case RW_I93_STM_LRI1K:
+      return ("LRi1K");
+    case RW_I93_STM_LRI2K:
+      return ("LRi2K");
+    case RW_I93_STM_LRIS2K:
+      return ("LRiS2K");
+    case RW_I93_STM_LRIS64K:
+      return ("LRiS64K");
+    case RW_I93_STM_M24LR64_R:
+      return ("M24LR64");
+    case RW_I93_STM_M24LR04E_R:
+      return ("M24LR04E");
+    case RW_I93_STM_M24LR16E_R:
+      return ("M24LR16E");
+    case RW_I93_STM_M24LR64E_R:
+      return ("M24LR64E");
+    case RW_I93_UNKNOWN_PRODUCT:
+    default:
+      return ("UNKNOWN");
+  }
+}
+
+#endif
diff --git a/src/nfc/tags/rw_main.c b/src/nfc/tags/rw_main.c
new file mode 100644
index 0000000..0ffefce
--- /dev/null
+++ b/src/nfc/tags/rw_main.c
@@ -0,0 +1,294 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains functions that interface with the NFC NCI transport.
+ *  On the receive side, it routes events to the appropriate handler
+ *  (callback). On the transmit side, it manages the command transmission.
+ *
+******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+#include "bt_types.h"
+
+#include "nfc_api.h"
+#include "nci_hmsgs.h"
+#include "rw_api.h"
+#include "rw_int.h"
+
+tRW_CB rw_cb;
+/*******************************************************************************
+*******************************************************************************/
+void rw_init(void) {
+  memset(&rw_cb, 0, sizeof(tRW_CB));
+  rw_cb.trace_level = NFC_INITIAL_TRACE_LEVEL;
+}
+
+#if (RW_STATS_INCLUDED == true)
+/*******************************************************************************
+* Internal functions for statistics
+*******************************************************************************/
+/*******************************************************************************
+**
+** Function         rw_main_reset_stats
+**
+** Description      Reset counters for statistics
+**
+** Returns          void
+**
+*******************************************************************************/
+void rw_main_reset_stats(void) {
+  memset(&rw_cb.stats, 0, sizeof(tRW_STATS));
+
+  /* Get current tick count */
+  rw_cb.stats.start_tick = GKI_get_tick_count();
+}
+
+/*******************************************************************************
+**
+** Function         rw_main_update_tx_stats
+**
+** Description      Update stats for tx
+**
+** Returns          void
+**
+*******************************************************************************/
+void rw_main_update_tx_stats(uint32_t num_bytes, bool is_retry) {
+  rw_cb.stats.bytes_sent += num_bytes;
+  rw_cb.stats.num_ops++;
+
+  if (is_retry) rw_cb.stats.num_retries++;
+}
+
+/*******************************************************************************
+**
+** Function         rw_main_update_fail_stats
+**
+** Description      Increment failure count
+**
+** Returns          void
+**
+*******************************************************************************/
+void rw_main_update_fail_stats(void) { rw_cb.stats.num_fail++; }
+
+/*******************************************************************************
+**
+** Function         rw_main_update_crc_error_stats
+**
+** Description      Increment crc error count
+**
+** Returns          void
+**
+*******************************************************************************/
+void rw_main_update_crc_error_stats(void) { rw_cb.stats.num_crc++; }
+
+/*******************************************************************************
+**
+** Function         rw_main_update_trans_error_stats
+**
+** Description      Increment trans error count
+**
+** Returns          void
+**
+*******************************************************************************/
+void rw_main_update_trans_error_stats(void) { rw_cb.stats.num_trans_err++; }
+
+/*******************************************************************************
+**
+** Function         rw_main_update_rx_stats
+**
+** Description      Update stats for rx
+**
+** Returns          void
+**
+*******************************************************************************/
+void rw_main_update_rx_stats(uint32_t num_bytes) {
+  rw_cb.stats.bytes_received += num_bytes;
+}
+
+/*******************************************************************************
+**
+** Function         rw_main_log_stats
+**
+** Description      Dump stats
+**
+** Returns          void
+**
+*******************************************************************************/
+void rw_main_log_stats(void) {
+  uint32_t ticks, elapsed_ms;
+
+  ticks = GKI_get_tick_count() - rw_cb.stats.start_tick;
+  elapsed_ms = GKI_TICKS_TO_MS(ticks);
+
+  RW_TRACE_DEBUG5(
+      "NFC tx stats: cmds:%i, retries:%i, aborted: %i, tx_errs: %i, bytes "
+      "sent:%i",
+      rw_cb.stats.num_ops, rw_cb.stats.num_retries, rw_cb.stats.num_fail,
+      rw_cb.stats.num_trans_err, rw_cb.stats.bytes_sent);
+  RW_TRACE_DEBUG2("    rx stats: rx-crc errors %i, bytes received: %i",
+                  rw_cb.stats.num_crc, rw_cb.stats.bytes_received);
+  RW_TRACE_DEBUG1("    time activated %i ms", elapsed_ms);
+}
+#endif /* RW_STATS_INCLUDED */
+
+/*******************************************************************************
+**
+** Function         RW_SendRawFrame
+**
+** Description      This function sends a raw frame to the peer device.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_SendRawFrame(uint8_t* p_raw_data, uint16_t data_len) {
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  NFC_HDR* p_data;
+  uint8_t* p;
+
+  if (rw_cb.p_cback) {
+    /* a valid opcode for RW - remove */
+    p_data = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+    if (p_data) {
+      p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+      p = (uint8_t*)(p_data + 1) + p_data->offset;
+      memcpy(p, p_raw_data, data_len);
+      p_data->len = data_len;
+
+      RW_TRACE_EVENT1("RW SENT raw frame (0x%x)", data_len);
+      status = NFC_SendData(NFC_RF_CONN_ID, p_data);
+    }
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_SetActivatedTagType
+**
+** Description      This function selects the tag type for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_SetActivatedTagType(tNFC_ACTIVATE_DEVT* p_activate_params,
+                                   tRW_CBACK* p_cback) {
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+
+  /* check for null cback here / remove checks from rw_t?t */
+  RW_TRACE_DEBUG3("RW_SetActivatedTagType protocol:%d, technology:%d, SAK:%d",
+                  p_activate_params->protocol,
+                  p_activate_params->rf_tech_param.mode,
+                  p_activate_params->rf_tech_param.param.pa.sel_rsp);
+
+  if (p_cback == NULL) {
+    RW_TRACE_ERROR0("RW_SetActivatedTagType called with NULL callback");
+    return (NFC_STATUS_FAILED);
+  }
+
+  /* Reset tag-specific area of control block */
+  memset(&rw_cb.tcb, 0, sizeof(tRW_TCB));
+
+#if (RW_STATS_INCLUDED == true)
+  /* Reset RW stats */
+  rw_main_reset_stats();
+#endif /* RW_STATS_INCLUDED */
+
+  rw_cb.p_cback = p_cback;
+  /* not a tag NFC_PROTOCOL_NFCIP1:   NFCDEP/LLCP - NFC-A or NFC-F */
+  if (NFC_PROTOCOL_T1T == p_activate_params->protocol) {
+    /* Type1Tag    - NFC-A */
+    if (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A) {
+      status = rw_t1t_select(p_activate_params->rf_tech_param.param.pa.hr,
+                             p_activate_params->rf_tech_param.param.pa.nfcid1);
+    }
+  } else if (NFC_PROTOCOL_T2T == p_activate_params->protocol) {
+    /* Type2Tag    - NFC-A */
+    if (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A) {
+      if (p_activate_params->rf_tech_param.param.pa.sel_rsp ==
+          NFC_SEL_RES_NFC_FORUM_T2T)
+        status = rw_t2t_select();
+    }
+  } else if (NFC_PROTOCOL_T3T == p_activate_params->protocol) {
+    /* Type3Tag    - NFC-F */
+    if (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_F) {
+      status =
+          rw_t3t_select(p_activate_params->rf_tech_param.param.pf.nfcid2,
+                        p_activate_params->rf_tech_param.param.pf.mrti_check,
+                        p_activate_params->rf_tech_param.param.pf.mrti_update);
+    }
+  } else if (NFC_PROTOCOL_ISO_DEP == p_activate_params->protocol
+#if (NXP_EXTNS == TRUE)
+             || NFC_PROTOCOL_T3BT == p_activate_params->protocol
+#endif
+             ) {
+    /* ISODEP/4A,4B- NFC-A or NFC-B */
+    if ((p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_B) ||
+        (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A)) {
+      status = rw_t4t_select();
+    }
+  } else if (NFC_PROTOCOL_15693 ==
+             p_activate_params->protocol) { /* ISO 15693 */
+    if (p_activate_params->rf_tech_param.mode ==
+        NFC_DISCOVERY_TYPE_POLL_ISO15693) {
+      status = rw_i93_select(p_activate_params->rf_tech_param.param.pi93.uid);
+    }
+  } else {
+    RW_TRACE_ERROR0("RW_SetActivatedTagType Invalid protocol");
+  }
+
+  if (status != NFC_STATUS_OK) rw_cb.p_cback = NULL;
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_SetTraceLevel
+**
+** Description      This function sets the trace level for Reader/Writer mode.
+**                  If called with a value of 0xFF,
+**                  it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+uint8_t RW_SetTraceLevel(uint8_t new_level) {
+  if (new_level != 0xFF) rw_cb.trace_level = new_level;
+
+  return (rw_cb.trace_level);
+}
diff --git a/src/nfc/tags/rw_t1t.c b/src/nfc/tags/rw_t1t.c
new file mode 100644
index 0000000..ec3de9f
--- /dev/null
+++ b/src/nfc/tags/rw_t1t.c
@@ -0,0 +1,1149 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the implementation for Type 1 tag in Reader/Writer
+ *  mode.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+
+#include "nfc_api.h"
+#include "nci_hmsgs.h"
+#include "rw_api.h"
+#include "rw_int.h"
+#include "nfc_int.h"
+#include "gki.h"
+
+#if (NXP_EXTNS == TRUE)
+extern unsigned char appl_dta_mode_flag;
+#endif
+/* Local Functions */
+static tRW_EVENT rw_t1t_handle_rid_rsp(NFC_HDR* p_pkt);
+static void rw_t1t_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
+                              tNFC_CONN* p_data);
+static void rw_t1t_process_frame_error(void);
+static void rw_t1t_process_error(void);
+static void rw_t1t_handle_presence_check_rsp(tNFC_STATUS status);
+#if (BT_TRACE_VERBOSE == true)
+static char* rw_t1t_get_state_name(uint8_t state);
+static char* rw_t1t_get_sub_state_name(uint8_t sub_state);
+static char* rw_t1t_get_event_name(uint8_t event);
+#endif
+
+/*******************************************************************************
+**
+** Function         rw_t1t_data_cback
+**
+** Description      This callback function handles data from NFCC.
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t1t_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
+                              tNFC_CONN* p_data) {
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  tRW_EVENT rw_event = RW_RAW_FRAME_EVT;
+  bool b_notify = true;
+  tRW_DATA evt_data;
+  NFC_HDR* p_pkt;
+  uint8_t* p;
+  tT1T_CMD_RSP_INFO* p_cmd_rsp_info =
+      (tT1T_CMD_RSP_INFO*)rw_cb.tcb.t1t.p_cmd_rsp_info;
+#if (BT_TRACE_VERBOSE == true)
+  uint8_t begin_state = p_t1t->state;
+#endif
+  (void)conn_id;
+  (void)event;
+
+  p_pkt = (NFC_HDR*)(p_data->data.p_data);
+  if (p_pkt == NULL) return;
+  /* Assume the data is just the response byte sequence */
+  p = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
+
+#if (BT_TRACE_VERBOSE == true)
+  RW_TRACE_DEBUG2("rw_t1t_data_cback (): state:%s (%d)",
+                  rw_t1t_get_state_name(p_t1t->state), p_t1t->state);
+#else
+  RW_TRACE_DEBUG1("rw_t1t_data_cback (): state=%d", p_t1t->state);
+#endif
+
+  evt_data.status = NFC_STATUS_OK;
+
+  if ((p_t1t->state == RW_T1T_STATE_IDLE) || (!p_cmd_rsp_info)) {
+    /* If previous command was retransmitted and if response is pending to
+     * previous command retransmission,
+     * check if lenght and ADD/ADD8/ADDS field matches the expected value of
+     * previous
+     * retransmited command response. However, ignore ADD field if the command
+     * was RALL/RID
+     */
+    if ((p_t1t->prev_cmd_rsp_info.pend_retx_rsp) &&
+        (p_t1t->prev_cmd_rsp_info.rsp_len == p_pkt->len) &&
+        ((p_t1t->prev_cmd_rsp_info.op_code == T1T_CMD_RID) ||
+         (p_t1t->prev_cmd_rsp_info.op_code == T1T_CMD_RALL) ||
+         (p_t1t->prev_cmd_rsp_info.addr == *p))) {
+      /* Response to previous command retransmission */
+      RW_TRACE_ERROR2(
+          "T1T Response to previous command in Idle state. command=0x%02x, "
+          "Remaining max retx rsp:0x%02x ",
+          p_t1t->prev_cmd_rsp_info.op_code,
+          p_t1t->prev_cmd_rsp_info.pend_retx_rsp - 1);
+      p_t1t->prev_cmd_rsp_info.pend_retx_rsp--;
+      GKI_freebuf(p_pkt);
+    } else {
+      /* Raw frame event */
+      evt_data.data.p_data = p_pkt;
+      (*rw_cb.p_cback)(RW_T1T_RAW_FRAME_EVT, (tRW_DATA*)&evt_data);
+    }
+    return;
+  }
+
+#if (RW_STATS_INCLUDED == true)
+  /* Update rx stats */
+  rw_main_update_rx_stats(p_pkt->len);
+#endif /* RW_STATS_INCLUDED */
+
+  if ((p_pkt->len != p_cmd_rsp_info->rsp_len) ||
+      ((p_cmd_rsp_info->opcode != T1T_CMD_RALL) &&
+       (p_cmd_rsp_info->opcode != T1T_CMD_RID) && (*p != p_t1t->addr)))
+
+  {
+    /* If previous command was retransmitted and if response is pending to
+     * previous command retransmission,
+     * then check if lenght and ADD/ADD8/ADDS field matches the expected value
+     * of previous
+     * retransmited command response. However, ignore ADD field if the command
+     * was RALL/RID
+     */
+    if ((p_t1t->prev_cmd_rsp_info.pend_retx_rsp) &&
+        (p_t1t->prev_cmd_rsp_info.rsp_len == p_pkt->len) &&
+        ((p_t1t->prev_cmd_rsp_info.op_code == T1T_CMD_RID) ||
+         (p_t1t->prev_cmd_rsp_info.op_code == T1T_CMD_RALL) ||
+         (p_t1t->prev_cmd_rsp_info.addr == *p))) {
+      RW_TRACE_ERROR2(
+          "T1T Response to previous command. command=0x%02x, Remaining max "
+          "retx rsp:0x%02x",
+          p_t1t->prev_cmd_rsp_info.op_code,
+          p_t1t->prev_cmd_rsp_info.pend_retx_rsp - 1);
+      p_t1t->prev_cmd_rsp_info.pend_retx_rsp--;
+    } else {
+      /* Stop timer as some response to current command is received */
+      nfc_stop_quick_timer(&p_t1t->timer);
+/* Retrasmit the last sent command if retry-count < max retry */
+#if (BT_TRACE_VERBOSE == true)
+      RW_TRACE_ERROR2("T1T Frame error. state=%s command (opcode) = 0x%02x",
+                      rw_t1t_get_state_name(p_t1t->state),
+                      p_cmd_rsp_info->opcode);
+#else
+      RW_TRACE_ERROR2("T1T Frame error. state=0x%02x command = 0x%02x ",
+                      p_t1t->state, p_cmd_rsp_info->opcode);
+#endif
+      rw_t1t_process_frame_error();
+    }
+    GKI_freebuf(p_pkt);
+    return;
+  }
+
+  /* Stop timer as response to current command is received */
+  nfc_stop_quick_timer(&p_t1t->timer);
+
+  RW_TRACE_EVENT2("RW RECV [%s]:0x%x RSP", t1t_info_to_str(p_cmd_rsp_info),
+                  p_cmd_rsp_info->opcode);
+
+  /* If we did not receive response to all retransmitted previous command,
+   * dont expect that as response have come for the current command itself.
+   */
+  if (p_t1t->prev_cmd_rsp_info.pend_retx_rsp)
+    memset(&(p_t1t->prev_cmd_rsp_info), 0, sizeof(tRW_T1T_PREV_CMD_RSP_INFO));
+
+  if (rw_cb.cur_retry) {
+    /* If the current command was retransmitted to get this response, we might
+       get
+       response later to all or some of the retrasnmission of the current
+       command
+     */
+    p_t1t->prev_cmd_rsp_info.addr = ((p_cmd_rsp_info->opcode != T1T_CMD_RALL) &&
+                                     (p_cmd_rsp_info->opcode != T1T_CMD_RID))
+                                        ? p_t1t->addr
+                                        : 0;
+    p_t1t->prev_cmd_rsp_info.rsp_len = p_cmd_rsp_info->rsp_len;
+    p_t1t->prev_cmd_rsp_info.op_code = p_cmd_rsp_info->opcode;
+    p_t1t->prev_cmd_rsp_info.pend_retx_rsp = (uint8_t)rw_cb.cur_retry;
+  }
+
+  rw_cb.cur_retry = 0;
+
+  if (p_cmd_rsp_info->opcode == T1T_CMD_RID) {
+    rw_event = rw_t1t_handle_rid_rsp(p_pkt);
+  } else {
+    rw_event =
+        rw_t1t_handle_rsp(p_cmd_rsp_info, &b_notify, p, &evt_data.status);
+  }
+
+  if (b_notify) {
+    if ((p_t1t->state != RW_T1T_STATE_READ) &&
+        (p_t1t->state != RW_T1T_STATE_WRITE)) {
+      GKI_freebuf(p_pkt);
+      evt_data.data.p_data = NULL;
+    } else {
+      evt_data.data.p_data = p_pkt;
+    }
+    rw_t1t_handle_op_complete();
+    (*rw_cb.p_cback)(rw_event, (tRW_DATA*)&evt_data);
+  } else
+    GKI_freebuf(p_pkt);
+
+#if (BT_TRACE_VERBOSE == true)
+  if (begin_state != p_t1t->state) {
+    RW_TRACE_DEBUG2("RW T1T state changed:<%s> -> <%s>",
+                    rw_t1t_get_state_name(begin_state),
+                    rw_t1t_get_state_name(p_t1t->state));
+  }
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_conn_cback
+**
+** Description      This callback function receives the events/data from NFCC.
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t1t_conn_cback(uint8_t conn_id, tNFC_CONN_EVT event,
+                       tNFC_CONN* p_data) {
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  tRW_READ_DATA evt_data;
+
+  RW_TRACE_DEBUG2("rw_t1t_conn_cback: conn_id=%i, evt=0x%x", conn_id, event);
+  /* Only handle static conn_id */
+  if (conn_id != NFC_RF_CONN_ID) {
+    RW_TRACE_WARNING1("rw_t1t_conn_cback - Not static connection id: =%i",
+                      conn_id);
+    return;
+  }
+
+  switch (event) {
+    case NFC_CONN_CREATE_CEVT:
+    case NFC_CONN_CLOSE_CEVT:
+      break;
+
+    case NFC_DEACTIVATE_CEVT:
+#if (RW_STATS_INCLUDED == true)
+      /* Display stats */
+      rw_main_log_stats();
+#endif /* RW_STATS_INCLUDED */
+
+      /* Stop t1t timer (if started) */
+      nfc_stop_quick_timer(&p_t1t->timer);
+
+      /* Free cmd buf for retransmissions */
+      if (p_t1t->p_cur_cmd_buf) {
+        GKI_freebuf(p_t1t->p_cur_cmd_buf);
+        p_t1t->p_cur_cmd_buf = NULL;
+      }
+
+      p_t1t->state = RW_T1T_STATE_NOT_ACTIVATED;
+      NFC_SetStaticRfCback(NULL);
+      break;
+
+    case NFC_DATA_CEVT:
+      if (p_data != NULL) {
+        if (p_data->data.status == NFC_STATUS_OK) {
+          rw_t1t_data_cback(conn_id, event, p_data);
+          break;
+        } else if (p_data->data.p_data != NULL) {
+          /* Free the response buffer in case of error response */
+          GKI_freebuf((NFC_HDR*)(p_data->data.p_data));
+          p_data->data.p_data = NULL;
+        }
+      }
+    /* Data event with error status...fall through to NFC_ERROR_CEVT case */
+
+    case NFC_ERROR_CEVT:
+      if ((p_t1t->state == RW_T1T_STATE_NOT_ACTIVATED) ||
+          (p_t1t->state == RW_T1T_STATE_IDLE)) {
+#if (RW_STATS_INCLUDED == true)
+        rw_main_update_trans_error_stats();
+#endif /* RW_STATS_INCLUDED */
+
+        if (event == NFC_ERROR_CEVT)
+          evt_data.status = (tNFC_STATUS)(*(uint8_t*)p_data);
+        else if (p_data)
+          evt_data.status = p_data->status;
+        else
+          evt_data.status = NFC_STATUS_FAILED;
+
+        evt_data.p_data = NULL;
+        (*rw_cb.p_cback)(RW_T1T_INTF_ERROR_EVT, (void*)&evt_data);
+        break;
+      }
+      nfc_stop_quick_timer(&p_t1t->timer);
+
+#if (RW_STATS_INCLUDED == true)
+      rw_main_update_trans_error_stats();
+#endif /* RW_STATS_INCLUDED */
+
+      if (p_t1t->state == RW_T1T_STATE_CHECK_PRESENCE) {
+        rw_t1t_handle_presence_check_rsp(NFC_STATUS_FAILED);
+      } else {
+        rw_t1t_process_error();
+      }
+      break;
+
+    default:
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_send_static_cmd
+**
+** Description      This function composes a Type 1 Tag command for static
+**                  memory and send through NCI to NFCC.
+**
+** Returns          NFC_STATUS_OK if the command is successfuly sent to NCI
+**                  otherwise, error status
+**
+*******************************************************************************/
+tNFC_STATUS rw_t1t_send_static_cmd(uint8_t opcode, uint8_t add, uint8_t dat) {
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  const tT1T_CMD_RSP_INFO* p_cmd_rsp_info = t1t_cmd_to_rsp_info(opcode);
+  NFC_HDR* p_data;
+  uint8_t* p;
+
+  if (p_cmd_rsp_info) {
+    /* a valid opcode for RW */
+    p_data = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+    if (p_data) {
+      p_t1t->p_cmd_rsp_info = (tT1T_CMD_RSP_INFO*)p_cmd_rsp_info;
+      p_t1t->addr = add;
+      p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+      p = (uint8_t*)(p_data + 1) + p_data->offset;
+      UINT8_TO_BE_STREAM(p, opcode);
+      UINT8_TO_BE_STREAM(p, add);
+      UINT8_TO_BE_STREAM(p, dat);
+
+      ARRAY_TO_STREAM(p, p_t1t->mem, T1T_CMD_UID_LEN);
+      p_data->len = p_cmd_rsp_info->cmd_len;
+
+      /* Indicate first attempt to send command, back up cmd buffer in case
+       * needed for retransmission */
+      rw_cb.cur_retry = 0;
+      memcpy(p_t1t->p_cur_cmd_buf, p_data,
+             sizeof(NFC_HDR) + p_data->offset + p_data->len);
+
+#if (RW_STATS_INCLUDED == true)
+      /* Update stats */
+      rw_main_update_tx_stats(p_data->len, false);
+#endif /* RW_STATS_INCLUDED */
+
+      RW_TRACE_EVENT2("RW SENT [%s]:0x%x CMD", t1t_info_to_str(p_cmd_rsp_info),
+                      p_cmd_rsp_info->opcode);
+      status = NFC_SendData(NFC_RF_CONN_ID, p_data);
+      if (status == NFC_STATUS_OK) {
+        nfc_start_quick_timer(
+            &p_t1t->timer, NFC_TTYPE_RW_T1T_RESPONSE,
+            (RW_T1T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+      }
+    } else {
+      status = NFC_STATUS_NO_BUFFERS;
+    }
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_send_dyn_cmd
+**
+** Description      This function composes a Type 1 Tag command for dynamic
+**                  memory and send through NCI to NFCC.
+**
+** Returns          NFC_STATUS_OK if the command is successfuly sent to NCI
+**                  otherwise, error status
+**
+*******************************************************************************/
+tNFC_STATUS rw_t1t_send_dyn_cmd(uint8_t opcode, uint8_t add, uint8_t* p_dat) {
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  const tT1T_CMD_RSP_INFO* p_cmd_rsp_info = t1t_cmd_to_rsp_info(opcode);
+  NFC_HDR* p_data;
+  uint8_t* p;
+
+  if (p_cmd_rsp_info) {
+    /* a valid opcode for RW */
+    p_data = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+    if (p_data) {
+      p_t1t->p_cmd_rsp_info = (tT1T_CMD_RSP_INFO*)p_cmd_rsp_info;
+      p_t1t->addr = add;
+      p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+      p = (uint8_t*)(p_data + 1) + p_data->offset;
+      UINT8_TO_BE_STREAM(p, opcode);
+      UINT8_TO_BE_STREAM(p, add);
+
+      if (p_dat) {
+        ARRAY_TO_STREAM(p, p_dat, 8);
+      } else {
+        memset(p, 0, 8);
+        p += 8;
+      }
+      ARRAY_TO_STREAM(p, p_t1t->mem, T1T_CMD_UID_LEN);
+      p_data->len = p_cmd_rsp_info->cmd_len;
+
+      /* Indicate first attempt to send command, back up cmd buffer in case
+       * needed for retransmission */
+      rw_cb.cur_retry = 0;
+      memcpy(p_t1t->p_cur_cmd_buf, p_data,
+             sizeof(NFC_HDR) + p_data->offset + p_data->len);
+
+#if (RW_STATS_INCLUDED == true)
+      /* Update stats */
+      rw_main_update_tx_stats(p_data->len, false);
+#endif /* RW_STATS_INCLUDED */
+
+      RW_TRACE_EVENT2("RW SENT [%s]:0x%x CMD", t1t_info_to_str(p_cmd_rsp_info),
+                      p_cmd_rsp_info->opcode);
+
+      status = NFC_SendData(NFC_RF_CONN_ID, p_data);
+      if (status == NFC_STATUS_OK) {
+        nfc_start_quick_timer(
+            &p_t1t->timer, NFC_TTYPE_RW_T1T_RESPONSE,
+            (RW_T1T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+      }
+    } else {
+      status = NFC_STATUS_NO_BUFFERS;
+    }
+  }
+  return status;
+}
+
+/*****************************************************************************
+**
+** Function         rw_t1t_handle_rid_rsp
+**
+** Description      Handles response to RID: Collects HR, UID, notify up the
+**                  stack
+**
+** Returns          event to notify application
+**
+*****************************************************************************/
+static tRW_EVENT rw_t1t_handle_rid_rsp(NFC_HDR* p_pkt) {
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  tRW_DATA evt_data;
+  uint8_t* p_rid_rsp;
+
+  evt_data.status = NFC_STATUS_OK;
+  evt_data.data.p_data = p_pkt;
+
+  /* Assume the data is just the response byte sequence */
+  p_rid_rsp = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
+
+  /* Response indicates tag is present */
+  if (p_t1t->state == RW_T1T_STATE_CHECK_PRESENCE) {
+    /* If checking for the presence of the tag then just notify */
+    return RW_T1T_PRESENCE_CHECK_EVT;
+  }
+
+  /* Extract HR and UID from response */
+  STREAM_TO_ARRAY(p_t1t->hr, p_rid_rsp, T1T_HR_LEN);
+
+#if (BT_TRACE_VERBOSE == true)
+  RW_TRACE_DEBUG2("hr0:0x%x, hr1:0x%x", p_t1t->hr[0], p_t1t->hr[1]);
+  RW_TRACE_DEBUG4("rw_t1t_handle_rid_rsp (): UID0-3=%02x%02x%02x%02x",
+                  p_rid_rsp[0], p_rid_rsp[1], p_rid_rsp[2], p_rid_rsp[3]);
+#else
+  RW_TRACE_DEBUG0("rw_t1t_handle_rid_rsp ()");
+#endif
+
+  /* Fetch UID0-3 from RID response message */
+  STREAM_TO_ARRAY(p_t1t->mem, p_rid_rsp, T1T_CMD_UID_LEN);
+
+  /* Notify RID response Event */
+  return RW_T1T_RID_EVT;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_select
+**
+** Description      This function will set the callback function to
+**                  receive data from lower layers and also send rid command
+**
+** Returns          none
+**
+*******************************************************************************/
+tNFC_STATUS rw_t1t_select(uint8_t hr[T1T_HR_LEN],
+                          uint8_t uid[T1T_CMD_UID_LEN]) {
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+
+  p_t1t->state = RW_T1T_STATE_NOT_ACTIVATED;
+
+  /* Alloc cmd buf for retransmissions */
+  if (p_t1t->p_cur_cmd_buf == NULL) {
+    p_t1t->p_cur_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+    if (p_t1t->p_cur_cmd_buf == NULL) {
+      RW_TRACE_ERROR0(
+          "rw_t1t_select: unable to allocate buffer for retransmission");
+      return status;
+    }
+  }
+
+  memcpy(p_t1t->hr, hr, T1T_HR_LEN);
+  memcpy(p_t1t->mem, uid, T1T_CMD_UID_LEN);
+
+  NFC_SetStaticRfCback(rw_t1t_conn_cback);
+
+  p_t1t->state = RW_T1T_STATE_IDLE;
+
+  return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_process_timeout
+**
+** Description      process timeout event
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t1t_process_timeout(TIMER_LIST_ENT* p_tle) {
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  (void)p_tle;
+
+#if (BT_TRACE_VERBOSE == true)
+  RW_TRACE_ERROR2("T1T timeout. state=%s command (opcode)=0x%02x ",
+                  rw_t1t_get_state_name(p_t1t->state),
+                  (rw_cb.tcb.t1t.p_cmd_rsp_info)->opcode);
+#else
+  RW_TRACE_ERROR2("T1T timeout. state=0x%02x command=0x%02x ", p_t1t->state,
+                  (rw_cb.tcb.t1t.p_cmd_rsp_info)->opcode);
+#endif
+
+  if (p_t1t->state == RW_T1T_STATE_CHECK_PRESENCE) {
+    /* Tag has moved from range */
+    rw_t1t_handle_presence_check_rsp(NFC_STATUS_FAILED);
+  } else if (p_t1t->state != RW_T1T_STATE_IDLE) {
+    rw_t1t_process_error();
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_process_frame_error
+**
+** Description      Process frame crc error
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t1t_process_frame_error(void) {
+#if (RW_STATS_INCLUDED == true)
+  /* Update stats */
+  rw_main_update_crc_error_stats();
+#endif /* RW_STATS_INCLUDED */
+
+  /* Process the error */
+  rw_t1t_process_error();
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_process_error
+**
+** Description      process timeout event
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t1t_process_error(void) {
+  tRW_READ_DATA evt_data;
+  tRW_EVENT rw_event;
+  NFC_HDR* p_cmd_buf;
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  tT1T_CMD_RSP_INFO* p_cmd_rsp_info =
+      (tT1T_CMD_RSP_INFO*)rw_cb.tcb.t1t.p_cmd_rsp_info;
+  tRW_DETECT_NDEF_DATA ndef_data;
+
+  RW_TRACE_DEBUG1("rw_t1t_process_error () State: %u", p_t1t->state);
+
+  /* Retry sending command if retry-count < max */
+  if (rw_cb.cur_retry < RW_MAX_RETRIES) {
+    /* retry sending the command */
+    rw_cb.cur_retry++;
+
+    RW_TRACE_DEBUG2("T1T retransmission attempt %i of %i", rw_cb.cur_retry,
+                    RW_MAX_RETRIES);
+
+    /* allocate a new buffer for message */
+    p_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+    if (p_cmd_buf != NULL) {
+      memcpy(p_cmd_buf, p_t1t->p_cur_cmd_buf, sizeof(NFC_HDR) +
+                                                  p_t1t->p_cur_cmd_buf->offset +
+                                                  p_t1t->p_cur_cmd_buf->len);
+
+#if (RW_STATS_INCLUDED == true)
+      /* Update stats */
+      rw_main_update_tx_stats(p_cmd_buf->len, true);
+#endif /* RW_STATS_INCLUDED */
+
+      if (NFC_SendData(NFC_RF_CONN_ID, p_cmd_buf) == NFC_STATUS_OK) {
+        /* Start timer for waiting for response */
+        nfc_start_quick_timer(
+            &p_t1t->timer, NFC_TTYPE_RW_T1T_RESPONSE,
+            (RW_T1T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+
+        return;
+      }
+    }
+  } else {
+    /* we might get response later to all or some of the retrasnmission
+     * of the current command, update previous command response information */
+    RW_TRACE_DEBUG1("T1T maximum retransmission attempts reached (%i)",
+                    RW_MAX_RETRIES);
+    p_t1t->prev_cmd_rsp_info.addr = ((p_cmd_rsp_info->opcode != T1T_CMD_RALL) &&
+                                     (p_cmd_rsp_info->opcode != T1T_CMD_RID))
+                                        ? p_t1t->addr
+                                        : 0;
+    p_t1t->prev_cmd_rsp_info.rsp_len = p_cmd_rsp_info->rsp_len;
+    p_t1t->prev_cmd_rsp_info.op_code = p_cmd_rsp_info->opcode;
+    p_t1t->prev_cmd_rsp_info.pend_retx_rsp = RW_MAX_RETRIES;
+  }
+
+#if (RW_STATS_INCLUDED == true)
+  /* update failure count */
+  rw_main_update_fail_stats();
+#endif /* RW_STATS_INCLUDED */
+
+  rw_event = rw_t1t_info_to_event(p_cmd_rsp_info);
+  if (p_t1t->state != RW_T1T_STATE_NOT_ACTIVATED) rw_t1t_handle_op_complete();
+
+  evt_data.status = NFC_STATUS_TIMEOUT;
+  if (rw_event == RW_T2T_NDEF_DETECT_EVT) {
+    ndef_data.status = evt_data.status;
+    ndef_data.protocol = NFC_PROTOCOL_T1T;
+    ndef_data.flags = RW_NDEF_FL_UNKNOWN;
+    ndef_data.max_size = 0;
+    ndef_data.cur_size = 0;
+    (*rw_cb.p_cback)(rw_event, (void*)&ndef_data);
+  } else {
+    evt_data.p_data = NULL;
+    (*rw_cb.p_cback)(rw_event, (void*)&evt_data);
+  }
+}
+
+/*****************************************************************************
+**
+** Function         rw_t1t_handle_presence_check_rsp
+**
+** Description      Handle response to presence check
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+void rw_t1t_handle_presence_check_rsp(tNFC_STATUS status) {
+  tRW_READ_DATA evt_data;
+
+  /* Notify, Tag is present or not */
+  evt_data.status = status;
+  rw_t1t_handle_op_complete();
+
+  (*(rw_cb.p_cback))(RW_T1T_PRESENCE_CHECK_EVT, (void*)&evt_data);
+}
+
+/*****************************************************************************
+**
+** Function         rw_t1t_handle_op_complete
+**
+** Description      Reset to IDLE state
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+void rw_t1t_handle_op_complete(void) {
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+
+  p_t1t->state = RW_T1T_STATE_IDLE;
+#if (RW_NDEF_INCLUDED == true)
+#if (NXP_EXTNS == TRUE)
+  if ((appl_dta_mode_flag == 0) && (p_t1t->state != RW_T1T_STATE_READ_NDEF))
+#else
+  if (p_t1t->state != RW_T1T_STATE_READ_NDEF)
+#endif
+  {
+    p_t1t->b_update = false;
+    p_t1t->b_rseg = false;
+  }
+  p_t1t->substate = RW_T1T_SUBSTATE_NONE;
+#endif
+  return;
+}
+
+/*****************************************************************************
+**
+** Function         RW_T1tPresenceCheck
+**
+** Description
+**      Check if the tag is still in the field.
+**
+**      The RW_T1T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
+**      or non-presence.
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T1tPresenceCheck(void) {
+  tNFC_STATUS retval = NFC_STATUS_OK;
+  tRW_DATA evt_data;
+  tRW_CB* p_rw_cb = &rw_cb;
+
+  RW_TRACE_API0("RW_T1tPresenceCheck");
+
+  /* If RW_SelectTagType was not called (no conn_callback) return failure */
+  if (!p_rw_cb->p_cback) {
+    retval = NFC_STATUS_FAILED;
+  }
+  /* If we are not activated, then RW_T1T_PRESENCE_CHECK_EVT status=FAIL */
+  else if (p_rw_cb->tcb.t1t.state == RW_T1T_STATE_NOT_ACTIVATED) {
+    evt_data.status = NFC_STATUS_FAILED;
+    (*p_rw_cb->p_cback)(RW_T1T_PRESENCE_CHECK_EVT, &evt_data);
+  }
+  /* If command is pending, assume tag is still present */
+  else if (p_rw_cb->tcb.t1t.state != RW_T1T_STATE_IDLE) {
+    evt_data.status = NFC_STATUS_OK;
+    (*p_rw_cb->p_cback)(RW_T1T_PRESENCE_CHECK_EVT, &evt_data);
+  } else {
+    /* IDLE state: send a RID command to the tag to see if it responds */
+    retval = rw_t1t_send_static_cmd(T1T_CMD_RID, 0, 0);
+    if (retval == NFC_STATUS_OK) {
+      p_rw_cb->tcb.t1t.state = RW_T1T_STATE_CHECK_PRESENCE;
+    }
+  }
+
+  return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         RW_T1tRid
+**
+** Description
+**      This function sends a RID command for Reader/Writer mode.
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T1tRid(void) {
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+
+  RW_TRACE_API0("RW_T1tRid");
+
+  if (p_t1t->state != RW_T1T_STATE_IDLE) {
+    RW_TRACE_WARNING1("RW_T1tRid - Busy - State: %u", p_t1t->state);
+    return (NFC_STATUS_BUSY);
+  }
+
+  /* send a RID command */
+  status = rw_t1t_send_static_cmd(T1T_CMD_RID, 0, 0);
+  if (status == NFC_STATUS_OK) {
+    p_t1t->state = RW_T1T_STATE_READ;
+  }
+
+  return (status);
+}
+
+/*******************************************************************************
+**
+** Function         RW_T1tReadAll
+**
+** Description      This function sends a RALL command for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tReadAll(void) {
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+
+  RW_TRACE_API0("RW_T1tReadAll");
+
+  if (p_t1t->state != RW_T1T_STATE_IDLE) {
+    RW_TRACE_WARNING1("RW_T1tReadAll - Busy - State: %u", p_t1t->state);
+    return (NFC_STATUS_BUSY);
+  }
+
+  /* send RALL command */
+  status = rw_t1t_send_static_cmd(T1T_CMD_RALL, 0, 0);
+  if (status == NFC_STATUS_OK) {
+    p_t1t->state = RW_T1T_STATE_READ;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T1tRead
+**
+** Description      This function sends a READ command for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tRead(uint8_t block, uint8_t byte) {
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  uint8_t addr;
+
+  if (p_t1t->state != RW_T1T_STATE_IDLE) {
+    RW_TRACE_WARNING1("RW_T1tRead - Busy - State: %u", p_t1t->state);
+    return (NFC_STATUS_BUSY);
+  }
+
+  /* send READ command */
+  RW_T1T_BLD_ADD((addr), (block), (byte));
+  status = rw_t1t_send_static_cmd(T1T_CMD_READ, addr, 0);
+  if (status == NFC_STATUS_OK) {
+    p_t1t->state = RW_T1T_STATE_READ;
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T1tWriteErase
+**
+** Description      This function sends a WRITE-E command for Reader/Writer
+**                  mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tWriteErase(uint8_t block, uint8_t byte, uint8_t new_byte) {
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  uint8_t addr;
+
+  if (p_t1t->state != RW_T1T_STATE_IDLE) {
+    RW_TRACE_WARNING1("RW_T1tWriteErase - Busy - State: %u", p_t1t->state);
+    return (NFC_STATUS_BUSY);
+  }
+  if ((p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_ONLY) &&
+      (block != T1T_CC_BLOCK) && (byte != T1T_CC_RWA_OFFSET)) {
+    RW_TRACE_ERROR0("RW_T1tWriteErase - Tag is in Read only state");
+    return (NFC_STATUS_REFUSED);
+  }
+  if ((block >= T1T_STATIC_BLOCKS) || (byte >= T1T_BLOCK_SIZE)) {
+    RW_TRACE_ERROR2("RW_T1tWriteErase - Invalid Block/byte: %u / %u", block,
+                    byte);
+    return (NFC_STATUS_REFUSED);
+  }
+  if ((block == T1T_UID_BLOCK) || (block == T1T_RES_BLOCK)) {
+    RW_TRACE_WARNING1("RW_T1tWriteErase - Cannot write to Locked block: %u",
+                      block);
+    return (NFC_STATUS_REFUSED);
+  }
+  /* send WRITE-E command */
+  RW_T1T_BLD_ADD((addr), (block), (byte));
+  status = rw_t1t_send_static_cmd(T1T_CMD_WRITE_E, addr, new_byte);
+  if (status == NFC_STATUS_OK) {
+    p_t1t->state = RW_T1T_STATE_WRITE;
+    if (block < T1T_BLOCKS_PER_SEGMENT) {
+      p_t1t->b_update = false;
+      p_t1t->b_rseg = false;
+    }
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T1tWriteNoErase
+**
+** Description      This function sends a WRITE-NE command for Reader/Writer
+**                  mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tWriteNoErase(uint8_t block, uint8_t byte, uint8_t new_byte) {
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  uint8_t addr;
+
+  if (p_t1t->state != RW_T1T_STATE_IDLE) {
+    RW_TRACE_WARNING1("RW_T1tWriteNoErase - Busy - State: %u", p_t1t->state);
+    return (NFC_STATUS_BUSY);
+  }
+  if ((p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_ONLY) &&
+      (block != T1T_CC_BLOCK) && (byte != T1T_CC_RWA_OFFSET)) {
+    RW_TRACE_ERROR0("RW_T1tWriteErase - Tag is in Read only state");
+    return (NFC_STATUS_REFUSED);
+  }
+  if ((block >= T1T_STATIC_BLOCKS) || (byte >= T1T_BLOCK_SIZE)) {
+    RW_TRACE_ERROR2("RW_T1tWriteErase - Invalid Block/byte: %u / %u", block,
+                    byte);
+    return (NFC_STATUS_REFUSED);
+  }
+  if ((block == T1T_UID_BLOCK) || (block == T1T_RES_BLOCK)) {
+    RW_TRACE_WARNING1("RW_T1tWriteNoErase - Cannot write to Locked block: %u",
+                      block);
+    return (NFC_STATUS_REFUSED);
+  }
+  /* send WRITE-NE command */
+  RW_T1T_BLD_ADD((addr), (block), (byte));
+  status = rw_t1t_send_static_cmd(T1T_CMD_WRITE_NE, addr, new_byte);
+  if (status == NFC_STATUS_OK) {
+    p_t1t->state = RW_T1T_STATE_WRITE;
+    if (block < T1T_BLOCKS_PER_SEGMENT) {
+      p_t1t->b_update = false;
+      p_t1t->b_rseg = false;
+    }
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T1tReadSeg
+**
+** Description      This function sends a RSEG command for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tReadSeg(uint8_t segment) {
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  uint8_t adds;
+
+  if (p_t1t->state != RW_T1T_STATE_IDLE) {
+    RW_TRACE_WARNING1("RW_T1tReadSeg - Busy - State: %u", p_t1t->state);
+    return (NFC_STATUS_BUSY);
+  }
+  if (segment >= T1T_MAX_SEGMENTS) {
+    RW_TRACE_ERROR1("RW_T1tReadSeg - Invalid Segment: %u", segment);
+    return (NFC_STATUS_REFUSED);
+  }
+  if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0) {
+    /* send RSEG command */
+    RW_T1T_BLD_ADDS((adds), (segment));
+    status = rw_t1t_send_dyn_cmd(T1T_CMD_RSEG, adds, NULL);
+    if (status == NFC_STATUS_OK) {
+      p_t1t->state = RW_T1T_STATE_READ;
+    }
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T1tRead8
+**
+** Description      This function sends a READ8 command for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tRead8(uint8_t block) {
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+
+  if (p_t1t->state != RW_T1T_STATE_IDLE) {
+    RW_TRACE_WARNING1("RW_T1tRead8 - Busy - State: %u", p_t1t->state);
+    return (NFC_STATUS_BUSY);
+  }
+
+  if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 ||
+      rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN) {
+    /* send READ8 command */
+    status = rw_t1t_send_dyn_cmd(T1T_CMD_READ8, block, NULL);
+    if (status == NFC_STATUS_OK) {
+      p_t1t->state = RW_T1T_STATE_READ;
+    }
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T1tWriteErase8
+**
+** Description      This function sends a WRITE-E8 command for Reader/Writer
+**                  mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tWriteErase8(uint8_t block, uint8_t* p_new_dat) {
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+
+  if (p_t1t->state != RW_T1T_STATE_IDLE) {
+    RW_TRACE_WARNING1("RW_T1tWriteErase8 - Busy - State: %u", p_t1t->state);
+    return (NFC_STATUS_BUSY);
+  }
+
+  if ((p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_ONLY) &&
+      (block != T1T_CC_BLOCK)) {
+    RW_TRACE_ERROR0("RW_T1tWriteErase8 - Tag is in Read only state");
+    return (NFC_STATUS_REFUSED);
+  }
+
+  if ((block == T1T_UID_BLOCK) || (block == T1T_RES_BLOCK)) {
+    RW_TRACE_WARNING1("RW_T1tWriteErase8 - Cannot write to Locked block: %u",
+                      block);
+    return (NFC_STATUS_REFUSED);
+  }
+
+  if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 ||
+      rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN) {
+    /* send WRITE-E8 command */
+    status = rw_t1t_send_dyn_cmd(T1T_CMD_WRITE_E8, block, p_new_dat);
+    if (status == NFC_STATUS_OK) {
+      p_t1t->state = RW_T1T_STATE_WRITE;
+      if (block < T1T_BLOCKS_PER_SEGMENT) {
+        p_t1t->b_update = false;
+        p_t1t->b_rseg = false;
+      }
+    }
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T1tWriteNoErase8
+**
+** Description      This function sends a WRITE-NE8 command for Reader/Writer
+**                  mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tWriteNoErase8(uint8_t block, uint8_t* p_new_dat) {
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+
+  if (p_t1t->state != RW_T1T_STATE_IDLE) {
+    RW_TRACE_WARNING1("RW_T1tWriteNoErase8 - Busy - State: %u", p_t1t->state);
+    return (NFC_STATUS_BUSY);
+  }
+
+  if ((p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_ONLY) &&
+      (block != T1T_CC_BLOCK)) {
+    RW_TRACE_ERROR0("RW_T1tWriteNoErase8 - Tag is in Read only state");
+    return (NFC_STATUS_REFUSED);
+  }
+
+  if ((block == T1T_UID_BLOCK) || (block == T1T_RES_BLOCK)) {
+    RW_TRACE_WARNING1("RW_T1tWriteNoErase8 - Cannot write to Locked block: %u",
+                      block);
+    return (NFC_STATUS_REFUSED);
+  }
+
+  if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 ||
+      rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN) {
+    /* send WRITE-NE command */
+    status = rw_t1t_send_dyn_cmd(T1T_CMD_WRITE_NE8, block, p_new_dat);
+    if (status == NFC_STATUS_OK) {
+      p_t1t->state = RW_T1T_STATE_WRITE;
+      if (block < T1T_BLOCKS_PER_SEGMENT) {
+        p_t1t->b_update = false;
+        p_t1t->b_rseg = false;
+      }
+    }
+  }
+  return status;
+}
+
+#if (BT_TRACE_VERBOSE == true)
+/*******************************************************************************
+**
+** Function         rw_t1t_get_state_name
+**
+** Description      This function returns the state name.
+**
+** NOTE             conditionally compiled to save memory.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+static char* rw_t1t_get_state_name(uint8_t state) {
+  switch (state) {
+    case RW_T1T_STATE_IDLE:
+      return ("IDLE");
+    case RW_T1T_STATE_NOT_ACTIVATED:
+      return ("NOT_ACTIVATED");
+    case RW_T1T_STATE_READ:
+      return ("APP_READ");
+    case RW_T1T_STATE_WRITE:
+      return ("APP_WRITE");
+    case RW_T1T_STATE_TLV_DETECT:
+      return ("TLV_DETECTION");
+    case RW_T1T_STATE_READ_NDEF:
+      return ("READING_NDEF");
+    case RW_T1T_STATE_WRITE_NDEF:
+      return ("WRITING_NDEF");
+    case RW_T1T_STATE_SET_TAG_RO:
+      return ("SET_TAG_RO");
+    case RW_T1T_STATE_CHECK_PRESENCE:
+      return ("CHECK_PRESENCE");
+    case RW_T1T_STATE_FORMAT_TAG:
+      return ("FORMAT_TAG");
+    default:
+      return ("???? UNKNOWN STATE");
+  }
+}
+
+#endif /* (BT_TRACE_VERBOSE == true) */
diff --git a/src/nfc/tags/rw_t1t_ndef.c b/src/nfc/tags/rw_t1t_ndef.c
new file mode 100644
index 0000000..6d9ae16
--- /dev/null
+++ b/src/nfc/tags/rw_t1t_ndef.c
@@ -0,0 +1,2593 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the implementation for Type 1 tag NDEF operation in
+ *  Reader/Writer mode.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+
+#include "nfc_api.h"
+#include "nci_hmsgs.h"
+#include "rw_api.h"
+#include "rw_int.h"
+#include "nfc_int.h"
+#include "gki.h"
+
+#if (RW_NDEF_INCLUDED == true)
+
+/* Local Functions */
+static tNFC_STATUS rw_t1t_handle_rall_rsp(bool* p_notify, uint8_t* p_data);
+static tNFC_STATUS rw_t1t_handle_dyn_read_rsp(bool* p_notify, uint8_t* p_data);
+static tNFC_STATUS rw_t1t_handle_write_rsp(bool* p_notify, uint8_t* p_data);
+static tNFC_STATUS rw_t1t_handle_read_rsp(bool* p_callback, uint8_t* p_data);
+static tNFC_STATUS rw_t1t_handle_tlv_detect_rsp(uint8_t* p_data);
+static tNFC_STATUS rw_t1t_handle_ndef_read_rsp(uint8_t* p_data);
+static tNFC_STATUS rw_t1t_handle_ndef_write_rsp(uint8_t* p_data);
+static tNFC_STATUS rw_t1t_handle_ndef_rall_rsp(void);
+static tNFC_STATUS rw_t1t_ndef_write_first_block(void);
+static tNFC_STATUS rw_t1t_next_ndef_write_block(void);
+static tNFC_STATUS rw_t1t_send_ndef_byte(uint8_t data, uint8_t block,
+                                         uint8_t index, uint8_t msg_len);
+static tNFC_STATUS rw_t1t_send_ndef_block(uint8_t* p_data, uint8_t block);
+static uint8_t rw_t1t_prepare_ndef_bytes(uint8_t* p_data,
+                                         uint8_t* p_length_field,
+                                         uint8_t* p_index, bool b_one_byte,
+                                         uint8_t block,
+                                         uint8_t lengthfield_len);
+static uint8_t rw_t1t_get_ndef_flags(void);
+static uint16_t rw_t1t_get_ndef_max_size(void);
+static bool rw_t1t_is_lock_reserved_otp_byte(uint16_t index);
+static bool rw_t1t_is_read_only_byte(uint16_t index);
+static uint8_t rw_t1t_get_lock_bits_for_segment(uint8_t segment,
+                                                uint8_t* p_start_byte,
+                                                uint8_t* p_start_bit,
+                                                uint8_t* p_end_byte);
+static void rw_t1t_update_attributes(void);
+static void rw_t1t_update_lock_attributes(void);
+static void rw_t1t_extract_lock_bytes(uint8_t* p_data);
+static void rw_t1t_update_tag_state(void);
+
+const uint8_t rw_t1t_mask_bits[8] = {0x01, 0x02, 0x04, 0x08,
+                                     0x10, 0x20, 0x40, 0x80};
+
+/*******************************************************************************
+**
+** Function         rw_t1t_handle_rsp
+**
+** Description      This function handles the response received for all commands
+**                  sent to tag
+**
+** Returns          event to be sent to application
+**
+*******************************************************************************/
+tRW_EVENT rw_t1t_handle_rsp(const tT1T_CMD_RSP_INFO* p_info, bool* p_notify,
+                            uint8_t* p_data, tNFC_STATUS* p_status) {
+  tRW_EVENT rw_event;
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  uint8_t adds;
+
+  if ((p_t1t->state == RW_T1T_STATE_READ) ||
+      (p_t1t->state == RW_T1T_STATE_WRITE)) {
+    return t1t_info_to_evt(p_info);
+  }
+
+  rw_event = rw_t1t_info_to_event(p_info);
+
+  if (p_info->opcode == T1T_CMD_RALL) {
+    *p_status = rw_t1t_handle_rall_rsp(p_notify, p_data);
+  } else if (p_info->opcode == T1T_CMD_RSEG) {
+    adds = *p_data;
+    if (adds == 0) {
+      p_t1t->b_rseg = true;
+      rw_t1t_update_tag_state();
+      rw_t1t_update_attributes();
+      rw_t1t_update_lock_attributes();
+      memcpy(p_t1t->mem, (uint8_t*)(p_data + T1T_ADD_LEN), T1T_SEGMENT_SIZE);
+    }
+    *p_status = rw_t1t_handle_dyn_read_rsp(p_notify, p_data);
+  } else if (p_info->opcode == T1T_CMD_READ8) {
+    *p_status = rw_t1t_handle_dyn_read_rsp(p_notify, p_data);
+  } else {
+    *p_status = rw_t1t_handle_write_rsp(p_notify, p_data);
+  }
+  return rw_event;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_info_to_event
+**
+** Description      This function returns RW event code based on the current
+**                  state
+**
+** Returns          RW event code
+**
+*******************************************************************************/
+tRW_EVENT rw_t1t_info_to_event(const tT1T_CMD_RSP_INFO* p_info) {
+  tRW_EVENT rw_event;
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+
+  switch (p_t1t->state) {
+    case RW_T1T_STATE_TLV_DETECT:
+      if (p_t1t->tlv_detect == TAG_NDEF_TLV)
+        rw_event = RW_T1T_NDEF_DETECT_EVT;
+      else
+        rw_event = RW_T1T_TLV_DETECT_EVT;
+      break;
+
+    case RW_T1T_STATE_READ_NDEF:
+      rw_event = RW_T1T_NDEF_READ_EVT;
+      break;
+
+    case RW_T1T_STATE_WRITE_NDEF:
+      rw_event = RW_T1T_NDEF_WRITE_EVT;
+      break;
+
+    case RW_T1T_STATE_SET_TAG_RO:
+      rw_event = RW_T1T_SET_TAG_RO_EVT;
+      break;
+
+    case RW_T1T_STATE_CHECK_PRESENCE:
+      rw_event = RW_T1T_PRESENCE_CHECK_EVT;
+      break;
+
+    case RW_T1T_STATE_FORMAT_TAG:
+      rw_event = RW_T1T_FORMAT_CPLT_EVT;
+      break;
+
+    default:
+      rw_event = t1t_info_to_evt(p_info);
+      break;
+  }
+  return rw_event;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_extract_lock_bytes
+**
+** Description      This function will extract lock bytes if any present in the
+**                  response data
+**
+** Parameters       p_data: Data bytes in the response of RSEG/READ8/RALL
+**                          command
+**
+** Returns          None
+**
+*******************************************************************************/
+void rw_t1t_extract_lock_bytes(uint8_t* p_data) {
+  uint16_t end;
+  uint16_t start;
+  uint8_t num_locks;
+  uint16_t lock_offset = 0;
+  uint16_t offset;
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  tT1T_CMD_RSP_INFO* p_cmd_rsp_info =
+      (tT1T_CMD_RSP_INFO*)rw_cb.tcb.t1t.p_cmd_rsp_info;
+
+  num_locks = 0;
+  /* Based on the Command used to read Tag, calculate the offset of the tag read
+   */
+  if (p_cmd_rsp_info->opcode == T1T_CMD_RSEG) {
+    start = p_t1t->segment * T1T_SEGMENT_SIZE;
+    end = start + T1T_SEGMENT_SIZE;
+  } else if (p_cmd_rsp_info->opcode == T1T_CMD_READ8) {
+    start = p_t1t->block_read * T1T_BLOCK_SIZE;
+    end = start + T1T_BLOCK_SIZE;
+  } else if (p_cmd_rsp_info->opcode == T1T_CMD_RALL) {
+    start = 0;
+    end = T1T_STATIC_SIZE;
+  } else
+    return;
+
+  /* Collect lock bytes that are present in the part of the data read from Tag
+   */
+  while (num_locks < p_t1t->num_lockbytes) {
+    if (p_t1t->lockbyte[num_locks].b_lock_read == false) {
+      /* Get the exact offset of the dynamic lock byte in the tag */
+      offset = p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].offset +
+               p_t1t->lockbyte[num_locks].byte_index;
+      if ((offset < end) && (offset >= start))
+
+      {
+        /* This dynamic lock byte is in the response */
+        if (p_cmd_rsp_info->opcode == T1T_CMD_RSEG) {
+          lock_offset = (offset % T1T_SEGMENT_SIZE);
+        } else if (p_cmd_rsp_info->opcode == T1T_CMD_READ8) {
+          lock_offset = (offset % T1T_BLOCK_SIZE);
+        } else if (p_cmd_rsp_info->opcode == T1T_CMD_RALL) {
+          lock_offset = offset;
+        }
+
+        p_t1t->lockbyte[num_locks].lock_byte = p_data[lock_offset];
+        p_t1t->lockbyte[num_locks].b_lock_read = true;
+      } else
+        break;
+    }
+    num_locks++;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_update_tag_attributes
+**
+** Description      This function will update tag attributes based on cc, ndef
+**                  message length
+**
+** Returns          None
+**
+*******************************************************************************/
+void rw_t1t_update_tag_state(void) {
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+
+  /* Set Tag state based on CC value and NDEF Message length */
+  if (((p_t1t->mem[T1T_CC_NMN_BYTE] == T1T_CC_NMN) ||
+       (p_t1t->mem[T1T_CC_NMN_BYTE] == 0)) &&
+      ((p_t1t->mem[T1T_CC_VNO_BYTE] == T1T_CC_VNO) ||
+       (p_t1t->mem[T1T_CC_VNO_BYTE] == T1T_CC_LEGACY_VNO)) &&
+      ((p_t1t->mem[T1T_CC_RWA_BYTE] == T1T_CC_RWA_RW) ||
+       (p_t1t->mem[T1T_CC_RWA_BYTE] == T1T_CC_RWA_RO))) {
+    /* Valid CC value, so Tag is initialized */
+    if (p_t1t->ndef_msg_len > 0) {
+      if (p_t1t->mem[T1T_CC_RWA_BYTE] == T1T_CC_RWA_RO) {
+        /* NDEF Message presence, CC indication sets Tag as READ ONLY  */
+        p_t1t->tag_attribute = RW_T1_TAG_ATTRB_READ_ONLY;
+      } else if (p_t1t->mem[T1T_CC_RWA_BYTE] == T1T_CC_RWA_RW) {
+        /* NDEF Message presence, CC indication sets Tag as READ WRITE */
+        p_t1t->tag_attribute = RW_T1_TAG_ATTRB_READ_WRITE;
+      }
+    } else {
+      /* If NDEF is not yet detected then Tag remains in Initialized state
+      *  after NDEF Detection the Tag state may be updated */
+      p_t1t->tag_attribute = RW_T1_TAG_ATTRB_INITIALIZED;
+    }
+  } else {
+    p_t1t->tag_attribute = RW_T1_TAG_ATTRB_UNKNOWN;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_read_locks
+**
+** Description      This function will send command to read next unread locks
+**
+** Returns          NFC_STATUS_OK, if all locks are read successfully
+**                  NFC_STATUS_FAILED, if reading locks failed
+**                  NFC_STATUS_CONTINUE, if reading locks is in progress
+**
+*******************************************************************************/
+tNFC_STATUS rw_t1t_read_locks(void) {
+  uint8_t num_locks = 0;
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  tNFC_STATUS status = NFC_STATUS_CONTINUE;
+  uint16_t offset;
+
+  while (num_locks < p_t1t->num_lockbytes) {
+    if (p_t1t->lockbyte[num_locks].b_lock_read == false) {
+      offset = p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].offset +
+               p_t1t->lockbyte[num_locks].byte_index;
+      if (offset < T1T_STATIC_SIZE) {
+        p_t1t->lockbyte[num_locks].lock_byte = p_t1t->mem[offset];
+        p_t1t->lockbyte[num_locks].b_lock_read = true;
+      } else if (offset < (p_t1t->mem[T1T_CC_TMS_BYTE] + 1) * T1T_BLOCK_SIZE) {
+        /* send READ8 command */
+        p_t1t->block_read = (uint8_t)(offset / T1T_BLOCK_SIZE);
+        status = rw_t1t_send_dyn_cmd(T1T_CMD_READ8, p_t1t->block_read, NULL);
+        if (status == NFC_STATUS_OK) {
+          /* Reading Locks */
+          status = NFC_STATUS_CONTINUE;
+          p_t1t->substate = RW_T1T_SUBSTATE_WAIT_READ_LOCKS;
+        }
+        break;
+      } else {
+        /* Read locks failed */
+        status = NFC_STATUS_FAILED;
+        break;
+      }
+    }
+    num_locks++;
+  }
+  if (num_locks == p_t1t->num_lockbytes) {
+    /* All locks are read */
+    status = NFC_STATUS_OK;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_handle_write_rsp
+**
+** Description      This function handles response received for WRITE_E8,
+**                  WRITE_NE8, WRITE_E, WRITE_NE commands
+**
+** Returns          status of the current NDEF/TLV Operation
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_handle_write_rsp(bool* p_notify, uint8_t* p_data) {
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  tNFC_STATUS status = NFC_STATUS_OK;
+  uint8_t num_locks;
+  uint8_t lock_count;
+  uint8_t value;
+  uint8_t addr;
+  uint8_t write_block[T1T_BLOCK_SIZE];
+  uint16_t offset;
+  uint16_t next_offset;
+  uint8_t num_bits;
+  uint8_t next_num_bits;
+
+  *p_notify = false;
+
+  switch (p_t1t->state) {
+    case RW_T1T_STATE_WRITE:
+      *p_notify = true;
+      break;
+
+    case RW_T1T_STATE_FORMAT_TAG:
+      if (p_t1t->substate == RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF) {
+        if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 ||
+            rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN)
+          *p_notify = true;
+        else {
+          if (p_t1t->work_offset < (T1T_BLOCK_SIZE - 1)) {
+            p_t1t->work_offset++;
+            /* send WRITE-E command */
+            RW_T1T_BLD_ADD((addr), 1, (uint8_t)p_t1t->work_offset);
+
+            status = rw_t1t_send_static_cmd(
+                T1T_CMD_WRITE_E, addr,
+                p_t1t->ndef_first_block[(uint8_t)p_t1t->work_offset]);
+            if (status != NFC_STATUS_OK) *p_notify = true;
+          } else
+            *p_notify = true;
+        }
+
+      } else {
+        /* send WRITE-E8 command */
+        status =
+            rw_t1t_send_dyn_cmd(T1T_CMD_WRITE_E8, 2, p_t1t->ndef_final_block);
+        if (status != NFC_STATUS_OK)
+          *p_notify = true;
+        else
+          p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF;
+      }
+      break;
+
+    case RW_T1T_STATE_SET_TAG_RO:
+      switch (p_t1t->substate) {
+        case RW_T1T_SUBSTATE_WAIT_SET_CC_RWA_RO:
+
+          if (!p_t1t->b_hard_lock) {
+            status = NFC_STATUS_OK;
+            *p_notify = true;
+            break;
+          }
+
+          if ((p_t1t->hr[0] & 0x0F) != 1) {
+            memset(write_block, 0, T1T_BLOCK_SIZE);
+            write_block[0] = 0xFF;
+            write_block[1] = 0xFF;
+
+            /* send WRITE-NE8 command */
+            status = rw_t1t_send_dyn_cmd(T1T_CMD_WRITE_NE8, T1T_LOCK_BLOCK,
+                                         write_block);
+            if (status != NFC_STATUS_OK)
+              *p_notify = true;
+            else
+              p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
+          } else {
+            /* send WRITE-NE command */
+            RW_T1T_BLD_ADD((addr), (T1T_LOCK_BLOCK), (0));
+            status = rw_t1t_send_static_cmd(T1T_CMD_WRITE_NE, addr, 0xFF);
+            if (status != NFC_STATUS_OK)
+              *p_notify = true;
+            else
+              p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_ST_LOCK_BITS;
+          }
+          break;
+
+        case RW_T1T_SUBSTATE_WAIT_SET_ST_LOCK_BITS:
+
+          /* send WRITE-NE command */
+          RW_T1T_BLD_ADD((addr), (T1T_LOCK_BLOCK), (1));
+          status = rw_t1t_send_static_cmd(T1T_CMD_WRITE_NE, addr, 0xFF);
+          if (status != NFC_STATUS_OK)
+            *p_notify = true;
+          else
+            p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
+
+          break;
+
+        case RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS:
+          num_locks = 0;
+          while (num_locks < p_t1t->num_lockbytes) {
+            if (p_t1t->lockbyte[num_locks].lock_status ==
+                RW_T1T_LOCK_UPDATE_INITIATED) {
+              p_t1t->lockbyte[num_locks].lock_status = RW_T1T_LOCK_UPDATED;
+            }
+            num_locks++;
+          }
+
+          num_locks = 0;
+          while (num_locks < p_t1t->num_lockbytes) {
+            if (p_t1t->lockbyte[num_locks].lock_status ==
+                RW_T1T_LOCK_NOT_UPDATED) {
+              offset =
+                  p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].offset +
+                  p_t1t->lockbyte[num_locks].byte_index;
+              num_bits =
+                  ((p_t1t->lockbyte[num_locks].byte_index + 1) * 8 <=
+                   p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index]
+                       .num_bits)
+                      ? 8
+                      : p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index]
+                                .num_bits %
+                            8;
+
+              if ((p_t1t->hr[0] & 0x0F) != 1) {
+                memset(write_block, 0, T1T_BLOCK_SIZE);
+
+                write_block[(uint8_t)(offset % T1T_BLOCK_SIZE)] |=
+                    tags_pow(2, num_bits) - 1;
+                lock_count = num_locks + 1;
+                while (lock_count < p_t1t->num_lockbytes) {
+                  next_offset =
+                      p_t1t->lock_tlv[p_t1t->lockbyte[lock_count].tlv_index]
+                          .offset +
+                      p_t1t->lockbyte[lock_count].byte_index;
+                  next_num_bits =
+                      ((p_t1t->lockbyte[lock_count].byte_index + 1) * 8 <=
+                       p_t1t->lock_tlv[p_t1t->lockbyte[lock_count].tlv_index]
+                           .num_bits)
+                          ? 8
+                          : p_t1t->lock_tlv[p_t1t->lockbyte[lock_count]
+                                                .tlv_index].num_bits %
+                                8;
+
+                  if (next_offset / T1T_BLOCK_SIZE == offset / T1T_BLOCK_SIZE) {
+                    write_block[(uint8_t)(next_offset % T1T_BLOCK_SIZE)] |=
+                        tags_pow(2, next_num_bits) - 1;
+                  } else
+                    break;
+                  lock_count++;
+                }
+
+                /* send WRITE-NE8 command */
+                status = rw_t1t_send_dyn_cmd(T1T_CMD_WRITE_NE8,
+                                             (uint8_t)(offset / T1T_BLOCK_SIZE),
+                                             write_block);
+                if (status == NFC_STATUS_OK) {
+                  p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
+                  while (lock_count > num_locks) {
+                    p_t1t->lockbyte[lock_count - 1].lock_status =
+                        RW_T1T_LOCK_UPDATE_INITIATED;
+                    lock_count--;
+                  }
+                } else
+                  *p_notify = true;
+              } else {
+                /* send WRITE-NE command */
+                RW_T1T_BLD_ADD((addr), ((uint8_t)(offset / T1T_BLOCK_SIZE)),
+                               ((uint8_t)(offset % T1T_BLOCK_SIZE)));
+                value = (uint8_t)(tags_pow(2, num_bits) - 1);
+                status = rw_t1t_send_static_cmd(T1T_CMD_WRITE_NE, addr, value);
+                if (status == NFC_STATUS_OK) {
+                  p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
+                  p_t1t->lockbyte[num_locks].lock_status =
+                      RW_T1T_LOCK_UPDATE_INITIATED;
+                } else
+                  *p_notify = true;
+              }
+              break;
+            }
+            num_locks++;
+          }
+          if (num_locks == p_t1t->num_lockbytes) {
+            rw_t1t_update_lock_attributes();
+            status = NFC_STATUS_OK;
+            *p_notify = true;
+          }
+          break;
+      }
+      break;
+
+    case RW_T1T_STATE_WRITE_NDEF:
+      switch (p_t1t->substate) {
+        case RW_T1T_SUBSTATE_WAIT_VALIDATE_NDEF:
+          p_t1t->ndef_msg_len = p_t1t->new_ndef_msg_len;
+          p_t1t->tag_attribute = RW_T1_TAG_ATTRB_READ_WRITE;
+          *p_notify = true;
+          break;
+
+        case RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED:
+          status = rw_t1t_handle_ndef_write_rsp(p_data);
+          if (status == NFC_STATUS_OK) {
+            p_t1t->substate = RW_T1T_SUBSTATE_WAIT_VALIDATE_NDEF;
+          } else if (status == NFC_STATUS_FAILED) {
+            /* Send Negative response to upper layer */
+            *p_notify = true;
+          }
+          break;
+
+        case RW_T1T_SUBSTATE_WAIT_NDEF_WRITE:
+          status = rw_t1t_handle_ndef_write_rsp(p_data);
+
+          if (status == NFC_STATUS_FAILED) {
+            /* Send Negative response to upper layer */
+            *p_notify = true;
+          } else if (status == NFC_STATUS_OK) {
+            p_t1t->substate = RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED;
+          }
+          break;
+
+        case RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF:
+          status = rw_t1t_handle_ndef_write_rsp(p_data);
+          if (status == NFC_STATUS_FAILED) {
+            /* Send Negative response to upper layer */
+            *p_notify = true;
+          } else if (status == NFC_STATUS_CONTINUE) {
+            p_t1t->substate = RW_T1T_SUBSTATE_WAIT_NDEF_WRITE;
+          } else {
+            p_t1t->substate = RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED;
+          }
+          break;
+      }
+      break;
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_handle_read_rsp
+**
+** Description      This function handle the data bytes excluding ADD(S)/ADD8
+**                  field received as part of RSEG, RALL, READ8 command response
+**
+** Returns          status of the current NDEF/TLV Operation
+**
+*******************************************************************************/
+tNFC_STATUS rw_t1t_handle_read_rsp(bool* p_notify, uint8_t* p_data) {
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  tNFC_STATUS status = NFC_STATUS_OK;
+  tRW_DETECT_NDEF_DATA ndef_data;
+  tRW_DETECT_TLV_DATA tlv_data;
+  uint8_t count;
+  tRW_READ_DATA evt_data;
+
+  *p_notify = false;
+  /* Handle the response based on the current state */
+  switch (p_t1t->state) {
+    case RW_T1T_STATE_READ:
+      *p_notify = true;
+      break;
+
+    case RW_T1T_STATE_READ_NDEF:
+      status = rw_t1t_handle_ndef_rall_rsp();
+      if (status != NFC_STATUS_CONTINUE) {
+        evt_data.status = status;
+        evt_data.p_data = NULL;
+        rw_t1t_handle_op_complete();
+        (*rw_cb.p_cback)(RW_T1T_NDEF_READ_EVT, (void*)&evt_data);
+      }
+      break;
+
+    case RW_T1T_STATE_TLV_DETECT:
+      switch (p_t1t->substate) {
+        case RW_T1T_SUBSTATE_WAIT_READ_LOCKS:
+          status = rw_t1t_read_locks();
+          if (status != NFC_STATUS_CONTINUE) {
+            rw_t1t_update_lock_attributes();
+            /* Send positive response to upper layer */
+            if (p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) {
+              tlv_data.protocol = NFC_PROTOCOL_T1T;
+              tlv_data.num_bytes = p_t1t->num_lockbytes;
+              tlv_data.status = status;
+              rw_t1t_handle_op_complete();
+              (*rw_cb.p_cback)(RW_T1T_TLV_DETECT_EVT, (void*)&tlv_data);
+            } else if (p_t1t->tlv_detect == TAG_NDEF_TLV) {
+              ndef_data.protocol = NFC_PROTOCOL_T1T;
+              ndef_data.flags = rw_t1t_get_ndef_flags();
+              ndef_data.flags |= RW_NDEF_FL_FORMATED;
+              ndef_data.max_size = (uint32_t)rw_t1t_get_ndef_max_size();
+              ndef_data.cur_size = p_t1t->ndef_msg_len;
+
+              if (ndef_data.max_size < ndef_data.cur_size) {
+                ndef_data.flags |= RW_NDEF_FL_READ_ONLY;
+                ndef_data.max_size = ndef_data.cur_size;
+              }
+
+              if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY)) {
+                ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE;
+                if (status == NFC_STATUS_OK)
+                  ndef_data.flags |= RW_NDEF_FL_HARD_LOCKABLE;
+              }
+              ndef_data.status = status;
+              rw_t1t_handle_op_complete();
+              (*rw_cb.p_cback)(RW_T1T_NDEF_DETECT_EVT, (void*)&ndef_data);
+            }
+          }
+          break;
+
+        case RW_T1T_SUBSTATE_NONE:
+          if (p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) {
+            tlv_data.status = rw_t1t_handle_tlv_detect_rsp(p_t1t->mem);
+            tlv_data.protocol = NFC_PROTOCOL_T1T;
+            tlv_data.num_bytes = 0;
+            count = 0;
+            while (count < p_t1t->num_mem_tlvs) {
+              tlv_data.num_bytes +=
+                  p_t1t->mem_tlv[p_t1t->num_mem_tlvs].num_bytes;
+              count++;
+            }
+            rw_t1t_handle_op_complete();
+            /* Send response to upper layer */
+            (*rw_cb.p_cback)(RW_T1T_TLV_DETECT_EVT, (void*)&tlv_data);
+          } else if (p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) {
+            tlv_data.status = rw_t1t_handle_tlv_detect_rsp(p_t1t->mem);
+            tlv_data.protocol = NFC_PROTOCOL_T1T;
+            tlv_data.num_bytes = p_t1t->num_lockbytes;
+
+            if (tlv_data.status == NFC_STATUS_FAILED) {
+              rw_t1t_handle_op_complete();
+
+              /* Send Negative response to upper layer */
+              (*rw_cb.p_cback)(RW_T1T_TLV_DETECT_EVT, (void*)&tlv_data);
+            } else {
+              rw_t1t_extract_lock_bytes(p_data);
+              status = rw_t1t_read_locks();
+              if (status != NFC_STATUS_CONTINUE) {
+                /* Send positive response to upper layer */
+                tlv_data.status = status;
+                rw_t1t_handle_op_complete();
+
+                (*rw_cb.p_cback)(RW_T1T_TLV_DETECT_EVT, (void*)&tlv_data);
+              }
+            }
+          } else if (p_t1t->tlv_detect == TAG_NDEF_TLV) {
+            ndef_data.protocol = NFC_PROTOCOL_T1T;
+            ndef_data.flags = rw_t1t_get_ndef_flags();
+
+            if (p_t1t->mem[T1T_CC_NMN_BYTE] == T1T_CC_NMN) {
+              ndef_data.status = rw_t1t_handle_tlv_detect_rsp(p_t1t->mem);
+
+              ndef_data.cur_size = p_t1t->ndef_msg_len;
+              if (ndef_data.status == NFC_STATUS_FAILED) {
+                ndef_data.max_size = (uint32_t)rw_t1t_get_ndef_max_size();
+                if (ndef_data.max_size < ndef_data.cur_size) {
+                  ndef_data.flags |= RW_NDEF_FL_READ_ONLY;
+                  ndef_data.max_size = ndef_data.cur_size;
+                }
+                if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY)) {
+                  ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE;
+                }
+                /* Send Negative response to upper layer */
+                rw_t1t_handle_op_complete();
+
+                (*rw_cb.p_cback)(RW_T1T_NDEF_DETECT_EVT, (void*)&ndef_data);
+              } else {
+                ndef_data.flags |= RW_NDEF_FL_FORMATED;
+                rw_t1t_extract_lock_bytes(p_data);
+                status = rw_t1t_read_locks();
+                if (status != NFC_STATUS_CONTINUE) {
+                  ndef_data.max_size = (uint32_t)rw_t1t_get_ndef_max_size();
+                  if (ndef_data.max_size < ndef_data.cur_size) {
+                    ndef_data.flags |= RW_NDEF_FL_READ_ONLY;
+                    ndef_data.max_size = ndef_data.cur_size;
+                  }
+
+                  if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY)) {
+                    ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE;
+                    if (status == NFC_STATUS_OK)
+                      ndef_data.flags |= RW_NDEF_FL_HARD_LOCKABLE;
+                  }
+                  /* Send positive response to upper layer */
+                  ndef_data.status = status;
+                  rw_t1t_handle_op_complete();
+
+                  (*rw_cb.p_cback)(RW_T1T_NDEF_DETECT_EVT, (void*)&ndef_data);
+                }
+              }
+            } else {
+              /* Send Negative response to upper layer */
+              ndef_data.status = NFC_STATUS_FAILED;
+              ndef_data.max_size = (uint32_t)rw_t1t_get_ndef_max_size();
+              ndef_data.cur_size = p_t1t->ndef_msg_len;
+              if (ndef_data.max_size < ndef_data.cur_size) {
+                ndef_data.flags |= RW_NDEF_FL_READ_ONLY;
+                ndef_data.max_size = ndef_data.cur_size;
+              }
+              if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY)) {
+                ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE;
+                ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE;
+              }
+              rw_t1t_handle_op_complete();
+
+              (*rw_cb.p_cback)(RW_T1T_NDEF_DETECT_EVT, (void*)&ndef_data);
+            }
+          }
+          break;
+      }
+      break;
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_handle_dyn_read_rsp
+**
+** Description      This function handles response received for READ8, RSEG
+**                  commands based on the current state
+**
+** Returns          status of the current NDEF/TLV Operation
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_handle_dyn_read_rsp(bool* p_notify, uint8_t* p_data) {
+  tNFC_STATUS status = NFC_STATUS_OK;
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+
+  *p_notify = false;
+
+  p_data += T1T_ADD_LEN;
+
+  rw_t1t_extract_lock_bytes(p_data);
+
+  if (p_t1t->state == RW_T1T_STATE_READ_NDEF) {
+    status = rw_t1t_handle_ndef_read_rsp(p_data);
+    if ((status == NFC_STATUS_FAILED) || (status == NFC_STATUS_OK)) {
+      /* Send response to upper layer */
+      *p_notify = true;
+    }
+  } else if (p_t1t->state == RW_T1T_STATE_WRITE_NDEF) {
+    status = rw_t1t_handle_ndef_write_rsp(p_data);
+    if (status == NFC_STATUS_FAILED) {
+      /* Send response to upper layer */
+      *p_notify = true;
+    } else if (status == NFC_STATUS_CONTINUE) {
+      p_t1t->substate = RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF;
+    }
+  } else {
+    status = rw_t1t_handle_read_rsp(p_notify, p_data);
+  }
+  return status;
+}
+
+/*****************************************************************************
+**
+** Function         rw_t1t_handle_rall_rsp
+**
+** Description      Handle response to RALL - Collect CC, set Tag state
+**
+** Returns          None
+**
+*****************************************************************************/
+static tNFC_STATUS rw_t1t_handle_rall_rsp(bool* p_notify, uint8_t* p_data) {
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+
+  p_data += T1T_HR_LEN; /* skip HR */
+  memcpy(p_t1t->mem, (uint8_t*)p_data, T1T_STATIC_SIZE);
+  p_t1t->segment = 0;
+  rw_t1t_extract_lock_bytes(p_data);
+
+  p_data +=
+      T1T_UID_LEN + T1T_RES_BYTE_LEN; /* skip Block 0, UID and Reserved byte */
+
+  RW_TRACE_DEBUG0("rw_t1t_handle_rall_rsp ()");
+
+  rw_t1t_update_tag_state();
+  rw_t1t_update_attributes();
+  rw_t1t_update_lock_attributes();
+  p_t1t->b_update = true;
+  return (rw_t1t_handle_read_rsp(p_notify, p_t1t->mem));
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_handle_tlv_detect_rsp
+**
+** Description      Handle response to the last command sent while
+**                  detecting tlv
+**
+** Returns          NFC_STATUS_OK, if tlv detect is complete & success
+**                  NFC_STATUS_FAILED,if tlv detect failed
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_handle_tlv_detect_rsp(uint8_t* p_data) {
+  uint16_t offset;
+  uint16_t len;
+  uint8_t xx;
+  uint8_t* p_readbytes;
+  uint8_t index;
+  uint8_t tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
+  uint8_t found_tlv = TAG_NULL_TLV;
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  bool failed = false;
+  bool found = false;
+  uint8_t count = 0;
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  uint8_t start_offset = T1T_UID_LEN + T1T_CC_LEN + T1T_RES_BYTE_LEN;
+  uint8_t end_offset = T1T_STATIC_SIZE - (2 * T1T_BLOCK_SIZE);
+  uint8_t bytes_read = T1T_STATIC_SIZE;
+  uint8_t tlv_value[T1T_DEFAULT_TLV_LEN];
+  uint16_t bytes_count = 0;
+
+  p_readbytes = p_data;
+
+  for (offset = start_offset; offset < end_offset && !failed && !found;) {
+    if (rw_t1t_is_lock_reserved_otp_byte((uint16_t)(offset)) == true) {
+      offset++;
+      continue;
+    }
+    switch (tlv_detect_state) {
+      case RW_T1T_SUBSTATE_WAIT_TLV_DETECT:
+        /* Search for the tag */
+        found_tlv = p_readbytes[offset++];
+        switch (found_tlv) {
+          case TAG_NULL_TLV: /* May be used for padding. SHALL ignore this */
+            break;
+
+          case TAG_NDEF_TLV:
+            if (p_t1t->tlv_detect == TAG_NDEF_TLV) {
+              index = (offset % T1T_BLOCK_SIZE);
+              /* Backup ndef first block */
+              memcpy(&p_t1t->ndef_first_block[0], &p_readbytes[offset - index],
+                     index);
+              memcpy(&p_t1t->ndef_first_block[index], &p_readbytes[offset],
+                     T1T_BLOCK_SIZE - index);
+              tlv_detect_state = RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
+            } else if (p_t1t->tlv_detect == TAG_PROPRIETARY_TLV) {
+              tlv_detect_state = RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
+            } else if (((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) &&
+                        (p_t1t->num_lockbytes > 0)) ||
+                       ((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) &&
+                        (p_t1t->num_mem_tlvs > 0))) {
+              found = true;
+            } else {
+              failed = true;
+            }
+            break;
+
+          case TAG_LOCK_CTRL_TLV:
+          case TAG_MEM_CTRL_TLV:
+            tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0;
+            break;
+
+          case TAG_PROPRIETARY_TLV:
+            if (p_t1t->tlv_detect == TAG_PROPRIETARY_TLV) {
+              index = (offset % T1T_BLOCK_SIZE);
+              /* Backup ndef first block */
+              tlv_detect_state = RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
+            } else {
+              /* NDEF/LOCK/MEM TLV can exist after Proprietary Tlv so we
+               * continue searching, skiping proprietary tlv */
+              tlv_detect_state = RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
+            }
+            break;
+
+          case TAG_TERMINATOR_TLV: /* Last TLV block in the data area. Must be
+                                      no NDEF nessage */
+            if (((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) &&
+                 (p_t1t->num_lockbytes > 0)) ||
+                ((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) &&
+                 (p_t1t->num_mem_tlvs > 0))) {
+              found = true;
+            } else {
+              failed = true;
+            }
+            break;
+          default:
+            failed = true;
+        }
+        break;
+
+      case RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN:
+        len = p_readbytes[offset];
+        switch (found_tlv) {
+          case TAG_NDEF_TLV:
+            p_t1t->ndef_header_offset = offset + p_t1t->work_offset;
+            if (len == T1T_LONG_NDEF_LEN_FIELD_BYTE0) {
+              /* The next two bytes constitute length bytes */
+              tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0;
+            } else {
+              /* one byte length field */
+              p_t1t->ndef_msg_len = len;
+              bytes_count = p_t1t->ndef_msg_len;
+              tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE;
+            }
+            break;
+
+          case TAG_PROPRIETARY_TLV:
+            if (len == 0xFF) {
+              /* The next two bytes constitute length bytes */
+              tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0;
+            } else {
+              /* one byte length field */
+              bytes_count = len;
+              tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE;
+            }
+            break;
+        }
+        offset++;
+        break;
+
+      case RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0:
+        switch (found_tlv) {
+          case TAG_LOCK_CTRL_TLV:
+          case TAG_MEM_CTRL_TLV:
+
+            len = p_readbytes[offset];
+            if (len == T1T_DEFAULT_TLV_LEN) {
+              /* Valid Lock control TLV */
+              tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE;
+              bytes_count = T1T_DEFAULT_TLV_LEN;
+            } else if (((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) &&
+                        (p_t1t->num_lockbytes > 0)) ||
+                       ((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) &&
+                        (p_t1t->num_mem_tlvs > 0))) {
+              found = true;
+            } else {
+              failed = true;
+            }
+            break;
+
+          case TAG_NDEF_TLV:
+          case TAG_PROPRIETARY_TLV:
+            /* The first length byte */
+            bytes_count = (uint8_t)p_readbytes[offset];
+            tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN1;
+            break;
+        }
+        offset++;
+        break;
+
+      case RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN1:
+        bytes_count = (bytes_count << 8) + p_readbytes[offset];
+        if (found_tlv == TAG_NDEF_TLV) {
+          p_t1t->ndef_msg_len = bytes_count;
+        }
+        tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE;
+        offset++;
+        break;
+
+      case RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE:
+        switch (found_tlv) {
+          case TAG_NDEF_TLV:
+            if ((bytes_count == p_t1t->ndef_msg_len) &&
+                (p_t1t->tlv_detect == TAG_NDEF_TLV)) {
+              /* The first byte offset after length field */
+              p_t1t->ndef_msg_offset = offset + p_t1t->work_offset;
+            }
+            if (bytes_count > 0) bytes_count--;
+
+            if (p_t1t->tlv_detect == TAG_NDEF_TLV) {
+              if (p_t1t->ndef_msg_len > 0) {
+                rw_t1t_update_tag_state();
+              } else {
+                p_t1t->tag_attribute = RW_T1_TAG_ATTRB_INITIALIZED_NDEF;
+              }
+              found = true;
+            } else if (bytes_count == 0) {
+              tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
+            }
+            break;
+
+          case TAG_LOCK_CTRL_TLV:
+            bytes_count--;
+            if ((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) ||
+                (p_t1t->tlv_detect == TAG_NDEF_TLV)) {
+              tlv_value[2 - bytes_count] = p_readbytes[offset];
+              if (bytes_count == 0) {
+                if (p_t1t->num_lock_tlvs < RW_T1T_MAX_LOCK_TLVS) {
+                  p_t1t->lock_tlv[p_t1t->num_lock_tlvs].offset =
+                      (tlv_value[0] >> 4) & 0x0F;
+                  p_t1t->lock_tlv[p_t1t->num_lock_tlvs].offset *=
+                      (uint8_t)tags_pow(2, tlv_value[2] & 0x0F);
+                  p_t1t->lock_tlv[p_t1t->num_lock_tlvs].offset +=
+                      tlv_value[0] & 0x0F;
+                  p_t1t->lock_tlv[p_t1t->num_lock_tlvs].bytes_locked_per_bit =
+                      (uint8_t)tags_pow(2, ((tlv_value[2] & 0xF0) >> 4));
+                  p_t1t->lock_tlv[p_t1t->num_lock_tlvs].num_bits = tlv_value[1];
+                  count = tlv_value[1] / 8 + ((tlv_value[1] % 8 != 0) ? 1 : 0);
+                  xx = 0;
+                  while (xx < count) {
+                    if (p_t1t->num_lockbytes < RW_T1T_MAX_LOCK_BYTES) {
+                      p_t1t->lockbyte[p_t1t->num_lockbytes].tlv_index =
+                          p_t1t->num_lock_tlvs;
+                      p_t1t->lockbyte[p_t1t->num_lockbytes].byte_index = xx;
+                      p_t1t->lockbyte[p_t1t->num_lockbytes].b_lock_read = false;
+                      p_t1t->num_lockbytes++;
+                    } else
+                      RW_TRACE_ERROR1(
+                          "T1T Buffer overflow error. Max supported lock "
+                          "bytes=0x%02X",
+                          RW_T1T_MAX_LOCK_BYTES);
+                    xx++;
+                  }
+                  p_t1t->num_lock_tlvs++;
+                  rw_t1t_update_attributes();
+                } else
+                  RW_TRACE_ERROR1(
+                      "T1T Buffer overflow error. Max supported lock "
+                      "tlvs=0x%02X",
+                      RW_T1T_MAX_LOCK_TLVS);
+
+                tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
+              }
+            } else {
+              if (bytes_count == 0) {
+                tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
+              }
+            }
+            break;
+
+          case TAG_MEM_CTRL_TLV:
+            bytes_count--;
+            if ((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) ||
+                (p_t1t->tlv_detect == TAG_NDEF_TLV)) {
+              tlv_value[2 - bytes_count] = p_readbytes[offset];
+              if (bytes_count == 0) {
+                if (p_t1t->num_mem_tlvs >= RW_T1T_MAX_MEM_TLVS) {
+                  RW_TRACE_ERROR0(
+                      "rw_t1t_handle_tlv_detect_rsp - Maximum buffer allocated "
+                      "for Memory tlv has reached");
+                  failed = true;
+                } else {
+                  /* Extract dynamic reserved bytes */
+                  p_t1t->mem_tlv[p_t1t->num_mem_tlvs].offset =
+                      (tlv_value[0] >> 4) & 0x0F;
+                  p_t1t->mem_tlv[p_t1t->num_mem_tlvs].offset *=
+                      (uint8_t)tags_pow(2, tlv_value[2] & 0x0F);
+                  p_t1t->mem_tlv[p_t1t->num_mem_tlvs].offset +=
+                      tlv_value[0] & 0x0F;
+                  p_t1t->mem_tlv[p_t1t->num_mem_tlvs].num_bytes = tlv_value[1];
+                  p_t1t->num_mem_tlvs++;
+                  rw_t1t_update_attributes();
+                  tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
+                }
+              }
+            } else {
+              if (bytes_count == 0) {
+                tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
+              }
+            }
+            break;
+
+          case TAG_PROPRIETARY_TLV:
+            bytes_count--;
+            if (p_t1t->tlv_detect == TAG_PROPRIETARY_TLV)
+              found = true;
+            else {
+              if (bytes_count == 0) {
+                tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
+              }
+            }
+            break;
+        }
+        offset++;
+        break;
+    }
+  }
+
+  p_t1t->work_offset += bytes_read;
+
+  /* NDEF/Lock/Mem TLV to be found in segment 0, if not assume detection failed
+   */
+  if (!found && !failed) {
+    if (((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) &&
+         (p_t1t->num_lockbytes > 0)) ||
+        ((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) &&
+         (p_t1t->num_mem_tlvs > 0))) {
+      found = true;
+    } else {
+      if (p_t1t->tlv_detect == TAG_NDEF_TLV) {
+        p_t1t->tag_attribute = RW_T1_TAG_ATTRB_INITIALIZED;
+      }
+      failed = true;
+    }
+  }
+
+  status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK;
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_handle_ndef_rall_rsp
+**
+** Description      Handle response to RALL command sent while reading an
+**                  NDEF message
+**
+** Returns          NFC_STATUS_CONTINUE, if NDEF read operation is not complete
+**                  NFC_STATUS_OK, if NDEF read is successfull
+**                  NFC_STATUS_FAILED,if NDEF read failed
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_handle_ndef_rall_rsp(void) {
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  tNFC_STATUS status = NFC_STATUS_CONTINUE;
+  uint8_t count;
+  uint8_t adds;
+
+  count = (uint8_t)p_t1t->ndef_msg_offset;
+  p_t1t->work_offset = 0;
+  p_t1t->segment = 0;
+
+  while (count < T1T_STATIC_SIZE && p_t1t->work_offset < p_t1t->ndef_msg_len) {
+    if (rw_t1t_is_lock_reserved_otp_byte(count) == false) {
+      p_t1t->p_ndef_buffer[p_t1t->work_offset] = p_t1t->mem[count];
+      p_t1t->work_offset++;
+    }
+    count++;
+  }
+  if (p_t1t->work_offset != p_t1t->ndef_msg_len) {
+    if ((p_t1t->hr[0] & 0x0F) != 1) {
+      if (p_t1t->work_offset == 0)
+        return NFC_STATUS_FAILED;
+
+      else {
+        p_t1t->block_read = T1T_STATIC_BLOCKS + 1;
+        p_t1t->segment++;
+      }
+      if (p_t1t->ndef_msg_len - p_t1t->work_offset <= 8) {
+        status = rw_t1t_send_dyn_cmd(T1T_CMD_READ8, p_t1t->block_read, NULL);
+        if (status == NFC_STATUS_OK) {
+          p_t1t->tlv_detect = TAG_NDEF_TLV;
+          p_t1t->state = RW_T1T_STATE_READ_NDEF;
+          status = NFC_STATUS_CONTINUE;
+        }
+      } else {
+        /* send RSEG command */
+        RW_T1T_BLD_ADDS((adds), (p_t1t->segment));
+        status = rw_t1t_send_dyn_cmd(T1T_CMD_RSEG, adds, NULL);
+        if (status == NFC_STATUS_OK) {
+          p_t1t->state = RW_T1T_STATE_READ_NDEF;
+          status = NFC_STATUS_CONTINUE;
+        }
+      }
+    } else {
+      RW_TRACE_ERROR1("RW_T1tReadNDef - Invalid NDEF len: %u or NDEF corrupted",
+                      p_t1t->ndef_msg_len);
+      status = NFC_STATUS_FAILED;
+    }
+  } else {
+    status = NFC_STATUS_OK;
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_handle_ndef_read_rsp
+**
+** Description      Handle response to commands sent while reading an
+**                  NDEF message
+**
+** Returns          NFC_STATUS_CONTINUE, if tlv read is not yet complete
+**                  NFC_STATUS_OK, if tlv read is complete & success
+**                  NFC_STATUS_FAILED,if tlv read failed
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_handle_ndef_read_rsp(uint8_t* p_data) {
+  tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  uint8_t index;
+  uint8_t adds;
+  tT1T_CMD_RSP_INFO* p_cmd_rsp_info =
+      (tT1T_CMD_RSP_INFO*)rw_cb.tcb.t1t.p_cmd_rsp_info;
+
+  /* The Response received could be for Read8 or Read Segment command */
+  switch (p_cmd_rsp_info->opcode) {
+    case T1T_CMD_READ8:
+      if (p_t1t->work_offset == 0) {
+        index = p_t1t->ndef_msg_offset % T1T_BLOCK_SIZE;
+      } else {
+        index = 0;
+      }
+      p_t1t->segment = (p_t1t->block_read * T1T_BLOCK_SIZE) / T1T_SEGMENT_SIZE;
+      while (index < T1T_BLOCK_SIZE &&
+             p_t1t->work_offset < p_t1t->ndef_msg_len) {
+        if (rw_t1t_is_lock_reserved_otp_byte((uint16_t)(
+                (p_t1t->block_read * T1T_BLOCK_SIZE) + index)) == false) {
+          p_t1t->p_ndef_buffer[p_t1t->work_offset] = p_data[index];
+          p_t1t->work_offset++;
+        }
+        index++;
+      }
+      break;
+
+    case T1T_CMD_RSEG:
+      if (p_t1t->work_offset == 0) {
+        index = p_t1t->ndef_msg_offset % T1T_SEGMENT_SIZE;
+      } else {
+        index = 0;
+      }
+      p_t1t->block_read = ((p_t1t->segment + 1) * T1T_BLOCKS_PER_SEGMENT) - 1;
+
+      while (index < T1T_SEGMENT_SIZE &&
+             p_t1t->work_offset < p_t1t->ndef_msg_len) {
+        if (rw_t1t_is_lock_reserved_otp_byte((uint16_t)(index)) == false) {
+          p_t1t->p_ndef_buffer[p_t1t->work_offset] = p_data[index];
+          p_t1t->work_offset++;
+        }
+        index++;
+      }
+      break;
+
+    default:
+      break;
+  }
+  if (p_t1t->work_offset < p_t1t->ndef_msg_len) {
+    if ((p_t1t->hr[0] & 0x0F) != 1) {
+      if ((p_t1t->ndef_msg_len - p_t1t->work_offset) <= T1T_BLOCK_SIZE) {
+        p_t1t->block_read++;
+        ndef_status = rw_t1t_send_dyn_cmd(T1T_CMD_READ8,
+                                          (uint8_t)(p_t1t->block_read), NULL);
+        if (ndef_status == NFC_STATUS_OK) {
+          ndef_status = NFC_STATUS_CONTINUE;
+        }
+      } else {
+        p_t1t->segment++;
+        /* send RSEG command */
+        RW_T1T_BLD_ADDS((adds), (p_t1t->segment));
+        ndef_status = rw_t1t_send_dyn_cmd(T1T_CMD_RSEG, adds, NULL);
+        if (ndef_status == NFC_STATUS_OK) {
+          ndef_status = NFC_STATUS_CONTINUE;
+        }
+      }
+    }
+  } else {
+    ndef_status = NFC_STATUS_OK;
+  }
+  return ndef_status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_next_ndef_write_block
+**
+** Description      This function prepare and writes ndef blocks
+**
+** Returns          NFC_STATUS_CONTINUE, if tlv write is not yet complete
+**                  NFC_STATUS_OK, if tlv write is complete & success
+**                  NFC_STATUS_FAILED,if tlv write failed
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_next_ndef_write_block(void) {
+  bool b_block_write_cmd = false;
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
+  uint8_t write_block[8];
+  uint8_t block;
+  uint8_t index;
+  uint8_t new_lengthfield_len;
+  uint8_t length_field[3];
+  uint16_t initial_offset;
+  uint8_t count;
+  /* Write NDEF Message */
+  new_lengthfield_len = p_t1t->new_ndef_msg_len > 254 ? 3 : 1;
+
+  /* Identify the command to use for NDEF write operation */
+  if ((p_t1t->hr[0] & 0x0F) != 1) {
+    /* Dynamic memory structure */
+    b_block_write_cmd = false;
+    block = p_t1t->ndef_block_written + 1;
+    p_t1t->segment = (block * T1T_BLOCK_SIZE) / T1T_SEGMENT_SIZE;
+
+    count = 0;
+    while (block <= p_t1t->mem[T1T_CC_TMS_BYTE]) {
+      index = 0;
+      if (block == p_t1t->num_ndef_finalblock) {
+        /* T1T_CMD_WRITE_E8 Command */
+        b_block_write_cmd = true;
+        break;
+      }
+      while (index < T1T_BLOCK_SIZE &&
+             p_t1t->work_offset <
+                 (p_t1t->new_ndef_msg_len + new_lengthfield_len)) {
+        if (rw_t1t_is_lock_reserved_otp_byte(
+                (uint16_t)((block * T1T_BLOCK_SIZE) + index)) == false) {
+          count++;
+        }
+        index++;
+      }
+      if (count == T1T_BLOCK_SIZE) {
+        /* T1T_CMD_WRITE_E8 Command */
+        b_block_write_cmd = true;
+        break;
+      } else if (count == 0) {
+        index = 0;
+        block++;
+        if (p_t1t->segment != (block * T1T_BLOCK_SIZE) / T1T_SEGMENT_SIZE) {
+          p_t1t->segment = (block * T1T_BLOCK_SIZE) / T1T_SEGMENT_SIZE;
+        }
+      } else {
+        /* T1T_CMD_WRITE_E Command */
+        b_block_write_cmd = false;
+        break;
+      }
+    }
+  } else {
+    /* Static memory structure */
+    block = p_t1t->ndef_block_written;
+    b_block_write_cmd = false;
+  }
+
+  new_lengthfield_len = p_t1t->new_ndef_msg_len > 254 ? 3 : 1;
+  if (new_lengthfield_len == 3) {
+    length_field[0] = T1T_LONG_NDEF_LEN_FIELD_BYTE0;
+    length_field[1] = (uint8_t)(p_t1t->new_ndef_msg_len >> 8);
+    length_field[2] = (uint8_t)(p_t1t->new_ndef_msg_len);
+  } else {
+    length_field[0] = (uint8_t)(p_t1t->new_ndef_msg_len);
+  }
+
+  if (b_block_write_cmd) {
+    /* Dynamic memory structure */
+    index = 0;
+    p_t1t->segment = (block * T1T_BLOCK_SIZE) / T1T_SEGMENT_SIZE;
+
+    initial_offset = p_t1t->work_offset;
+    block = rw_t1t_prepare_ndef_bytes(write_block, length_field, &index, false,
+                                      block, new_lengthfield_len);
+    if (p_t1t->work_offset == initial_offset) {
+      ndef_status = NFC_STATUS_FAILED;
+    } else {
+      /* Send WRITE_E8 command */
+      ndef_status = rw_t1t_send_ndef_block(write_block, block);
+    }
+  } else {
+    /* Static memory structure */
+    if (p_t1t->write_byte + 1 >= T1T_BLOCK_SIZE) {
+      index = 0;
+      block++;
+    } else {
+      index = p_t1t->write_byte + 1;
+    }
+    initial_offset = p_t1t->work_offset;
+    block = rw_t1t_prepare_ndef_bytes(write_block, length_field, &index, true,
+                                      block, new_lengthfield_len);
+    if (p_t1t->work_offset == initial_offset) {
+      ndef_status = NFC_STATUS_FAILED;
+    } else {
+      /* send WRITE-E command */
+      ndef_status = rw_t1t_send_ndef_byte(write_block[index], block, index,
+                                          new_lengthfield_len);
+    }
+  }
+  return ndef_status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_ndef_write_first_block
+**
+** Description      This function writes ndef first block
+**
+** Returns          NFC_STATUS_CONTINUE, if tlv write is not yet complete
+**                  NFC_STATUS_OK, if tlv write is complete & success
+**                  NFC_STATUS_FAILED,if tlv write failed
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_ndef_write_first_block(void) {
+  tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  uint8_t block;
+  uint8_t index;
+  uint8_t new_lengthfield_len;
+  uint8_t length_field[3];
+  uint8_t write_block[8];
+
+  /* handle positive response to invalidating existing NDEF Message */
+  p_t1t->work_offset = 0;
+  new_lengthfield_len = p_t1t->new_ndef_msg_len > 254 ? 3 : 1;
+  if (new_lengthfield_len == 3) {
+    length_field[0] = T1T_LONG_NDEF_LEN_FIELD_BYTE0;
+    length_field[1] = (uint8_t)(p_t1t->new_ndef_msg_len >> 8);
+    length_field[2] = (uint8_t)(p_t1t->new_ndef_msg_len);
+  } else {
+    length_field[0] = (uint8_t)(p_t1t->new_ndef_msg_len);
+  }
+  /* updating ndef_first_block with new ndef message */
+  memcpy(write_block, p_t1t->ndef_first_block, T1T_BLOCK_SIZE);
+  index = p_t1t->ndef_header_offset % T1T_BLOCK_SIZE;
+  block = (uint8_t)(p_t1t->ndef_header_offset / T1T_BLOCK_SIZE);
+  p_t1t->segment = (uint8_t)(p_t1t->ndef_header_offset / T1T_SEGMENT_SIZE);
+
+  if ((p_t1t->hr[0] & 0x0F) != 1) {
+    /* Dynamic Memory structure */
+    block = rw_t1t_prepare_ndef_bytes(write_block, length_field, &index, false,
+                                      block, new_lengthfield_len);
+
+    if (p_t1t->work_offset == 0) {
+      ndef_status = NFC_STATUS_FAILED;
+    } else {
+      /* Send WRITE-E8 command based on the prepared write_block */
+      ndef_status = rw_t1t_send_ndef_block(write_block, block);
+    }
+  } else {
+    /* Static Memory structure */
+    block = rw_t1t_prepare_ndef_bytes(write_block, length_field, &index, true,
+                                      block, new_lengthfield_len);
+    if (p_t1t->work_offset == 0) {
+      ndef_status = NFC_STATUS_FAILED;
+    } else {
+      /* send WRITE-E command */
+      ndef_status = rw_t1t_send_ndef_byte(write_block[index], block, index,
+                                          new_lengthfield_len);
+    }
+  }
+
+  return ndef_status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_send_ndef_byte
+**
+** Description      Sends ndef message or length field byte and update
+**                  status
+**
+** Returns          NFC_STATUS_CONTINUE, if tlv write is not yet complete
+**                  NFC_STATUS_OK, if tlv write is complete & success
+**                  NFC_STATUS_FAILED,if tlv write failed
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_send_ndef_byte(uint8_t data, uint8_t block,
+                                         uint8_t index, uint8_t msg_len) {
+  tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  uint8_t addr;
+
+  /* send WRITE-E command */
+  RW_T1T_BLD_ADD((addr), (block), (index));
+  if (NFC_STATUS_OK == rw_t1t_send_static_cmd(T1T_CMD_WRITE_E, addr, data)) {
+    p_t1t->write_byte = index;
+    p_t1t->ndef_block_written = block;
+    if (p_t1t->work_offset == p_t1t->new_ndef_msg_len + msg_len) {
+      ndef_status = NFC_STATUS_OK;
+    } else {
+      ndef_status = NFC_STATUS_CONTINUE;
+    }
+  } else {
+    ndef_status = NFC_STATUS_FAILED;
+  }
+  return ndef_status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_prepare_ndef_bytes
+**
+** Description      prepares ndef block to write
+**
+** Returns          block number where to write
+**
+*******************************************************************************/
+static uint8_t rw_t1t_prepare_ndef_bytes(uint8_t* p_data,
+                                         uint8_t* p_length_field,
+                                         uint8_t* p_index, bool b_one_byte,
+                                         uint8_t block,
+                                         uint8_t lengthfield_len) {
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  uint8_t first_block = (uint8_t)(p_t1t->ndef_header_offset / T1T_BLOCK_SIZE);
+  uint16_t initial_offset = p_t1t->work_offset;
+
+  while (p_t1t->work_offset == initial_offset &&
+         block <= p_t1t->mem[T1T_CC_TMS_BYTE]) {
+    if ((block == p_t1t->num_ndef_finalblock) && (block != first_block)) {
+      memcpy(p_data, p_t1t->ndef_final_block, T1T_BLOCK_SIZE);
+    }
+    /* Update length field */
+    while ((*p_index < T1T_BLOCK_SIZE) &&
+           (p_t1t->work_offset < lengthfield_len)) {
+      if (rw_t1t_is_lock_reserved_otp_byte(
+              (uint16_t)((block * T1T_BLOCK_SIZE) + *p_index)) == false) {
+        p_data[*p_index] = p_length_field[p_t1t->work_offset];
+        p_t1t->work_offset++;
+        if (b_one_byte) return block;
+      }
+      (*p_index)++;
+      if (p_t1t->work_offset == lengthfield_len) {
+        break;
+      }
+    }
+    /* Update ndef message field */
+    while (*p_index < T1T_BLOCK_SIZE &&
+           p_t1t->work_offset < (p_t1t->new_ndef_msg_len + lengthfield_len)) {
+      if (rw_t1t_is_lock_reserved_otp_byte(
+              (uint16_t)((block * T1T_BLOCK_SIZE) + *p_index)) == false) {
+        p_data[*p_index] =
+            p_t1t->p_ndef_buffer[p_t1t->work_offset - lengthfield_len];
+        p_t1t->work_offset++;
+        if (b_one_byte) return block;
+      }
+      (*p_index)++;
+    }
+    if (p_t1t->work_offset == initial_offset) {
+      *p_index = 0;
+      block++;
+      if (p_t1t->segment != (block * T1T_BLOCK_SIZE) / T1T_SEGMENT_SIZE) {
+        p_t1t->segment = (block * T1T_BLOCK_SIZE) / T1T_SEGMENT_SIZE;
+      }
+    }
+  }
+  return block;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_send_ndef_block
+**
+** Description      Sends ndef block and update status
+**
+** Returns          NFC_STATUS_CONTINUE, if tlv write is not yet complete
+**                  NFC_STATUS_OK, if tlv write is complete & success
+**                  NFC_STATUS_FAILED,if tlv write failed
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_send_ndef_block(uint8_t* p_data, uint8_t block) {
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
+
+  if (NFC_STATUS_OK == rw_t1t_send_dyn_cmd(T1T_CMD_WRITE_E8, block, p_data)) {
+    p_t1t->ndef_block_written = block;
+    if (p_t1t->ndef_block_written == p_t1t->num_ndef_finalblock) {
+      ndef_status = NFC_STATUS_OK;
+    } else {
+      ndef_status = NFC_STATUS_CONTINUE;
+    }
+  } else {
+    ndef_status = NFC_STATUS_FAILED;
+  }
+  return ndef_status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_get_ndef_flags
+**
+** Description      Prepare NDEF Flags
+**
+** Returns          NDEF Flag value
+**
+*******************************************************************************/
+static uint8_t rw_t1t_get_ndef_flags(void) {
+  uint8_t flags = 0;
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+
+  if ((p_t1t->hr[0] & 0xF0) == T1T_NDEF_SUPPORTED)
+    flags |= RW_NDEF_FL_SUPPORTED;
+
+  if (t1t_tag_init_data(p_t1t->hr[0]) != NULL) flags |= RW_NDEF_FL_FORMATABLE;
+
+  if ((p_t1t->mem[T1T_CC_RWA_BYTE] & 0x0F) == T1T_CC_RWA_RO)
+    flags |= RW_NDEF_FL_READ_ONLY;
+
+  return flags;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_get_ndef_max_size
+**
+** Description      Calculate maximum size of NDEF message that can be written
+**                  on to the tag
+**
+** Returns          Maximum size of NDEF Message
+**
+*******************************************************************************/
+static uint16_t rw_t1t_get_ndef_max_size(void) {
+  uint16_t offset;
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  uint16_t tag_size = (p_t1t->mem[T1T_CC_TMS_BYTE] + 1) * T1T_BLOCK_SIZE;
+  const tT1T_INIT_TAG* p_ret;
+  uint8_t init_segment = p_t1t->segment;
+
+  p_t1t->max_ndef_msg_len = 0;
+  offset = p_t1t->ndef_msg_offset;
+  p_t1t->segment = (uint8_t)(p_t1t->ndef_msg_offset / T1T_SEGMENT_SIZE);
+
+  if ((tag_size < T1T_STATIC_SIZE) ||
+      (tag_size > (T1T_SEGMENT_SIZE * T1T_MAX_SEGMENTS)) ||
+      ((p_t1t->mem[T1T_CC_NMN_BYTE] != T1T_CC_NMN) &&
+       (p_t1t->mem[T1T_CC_NMN_BYTE] != 0))) {
+    /* Tag not formated, determine maximum NDEF size from HR */
+    if (((p_t1t->hr[0] & 0xF0) == T1T_NDEF_SUPPORTED) &&
+        ((p_ret = t1t_tag_init_data(p_t1t->hr[0])) != NULL)) {
+      p_t1t->max_ndef_msg_len = ((p_ret->tms + 1) * T1T_BLOCK_SIZE) -
+                                T1T_OTP_LOCK_RES_BYTES - T1T_UID_LEN -
+                                T1T_ADD_LEN - T1T_CC_LEN - T1T_TLV_TYPE_LEN -
+                                T1T_SHORT_NDEF_LEN_FIELD_LEN;
+      if (p_ret->b_dynamic) {
+        p_t1t->max_ndef_msg_len -=
+            (T1T_TLV_TYPE_LEN + T1T_DEFAULT_TLV_LEN_FIELD_LEN +
+             T1T_DEFAULT_TLV_LEN + T1T_TLV_TYPE_LEN +
+             T1T_DEFAULT_TLV_LEN_FIELD_LEN + T1T_DEFAULT_TLV_LEN);
+        p_t1t->max_ndef_msg_len -= T1T_DYNAMIC_LOCK_BYTES;
+      }
+      offset = tag_size;
+    } else {
+      p_t1t->segment = init_segment;
+      return p_t1t->max_ndef_msg_len;
+    }
+  }
+
+  /* Starting from NDEF Message offset find the first locked data byte */
+  while (offset < tag_size) {
+    if (rw_t1t_is_lock_reserved_otp_byte((uint16_t)(offset)) == false) {
+      if (rw_t1t_is_read_only_byte((uint16_t)offset) == true) break;
+      p_t1t->max_ndef_msg_len++;
+    }
+    offset++;
+    if (offset % T1T_SEGMENT_SIZE == 0) {
+      p_t1t->segment = (uint8_t)(offset / T1T_SEGMENT_SIZE);
+    }
+  }
+  /* NDEF Length field length changes based on NDEF size */
+  if ((p_t1t->max_ndef_msg_len >= T1T_LONG_NDEF_LEN_FIELD_BYTE0) &&
+      ((p_t1t->ndef_msg_offset - p_t1t->ndef_header_offset) ==
+       T1T_SHORT_NDEF_LEN_FIELD_LEN)) {
+    p_t1t->max_ndef_msg_len -=
+        (p_t1t->max_ndef_msg_len == T1T_LONG_NDEF_LEN_FIELD_BYTE0)
+            ? 1
+            : (T1T_LONG_NDEF_LEN_FIELD_LEN - T1T_SHORT_NDEF_LEN_FIELD_LEN);
+  }
+
+  p_t1t->segment = init_segment;
+  return p_t1t->max_ndef_msg_len;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_handle_ndef_write_rsp
+**
+** Description      Handle response to commands sent while writing an
+**                  NDEF message
+**
+** Returns          NFC_STATUS_CONTINUE, if tlv write is not yet complete
+**                  NFC_STATUS_OK, if tlv write is complete & success
+**                  NFC_STATUS_FAILED,if tlv write failed
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_handle_ndef_write_rsp(uint8_t* p_data) {
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
+  uint8_t addr;
+
+  switch (p_t1t->substate) {
+    case RW_T1T_SUBSTATE_WAIT_READ_NDEF_BLOCK:
+      /* Backup ndef_final_block */
+      memcpy(p_t1t->ndef_final_block, p_data, T1T_BLOCK_SIZE);
+      /* Invalidate existing NDEF Message */
+      RW_T1T_BLD_ADD((addr), (T1T_CC_BLOCK), (T1T_CC_NMN_OFFSET));
+      if (NFC_STATUS_OK == rw_t1t_send_static_cmd(T1T_CMD_WRITE_E, addr, 0)) {
+        ndef_status = NFC_STATUS_CONTINUE;
+        p_t1t->state = RW_T1T_STATE_WRITE_NDEF;
+        p_t1t->substate = RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF;
+      } else {
+        ndef_status = NFC_STATUS_FAILED;
+      }
+      break;
+
+    case RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF:
+      ndef_status = rw_t1t_ndef_write_first_block();
+      break;
+
+    case RW_T1T_SUBSTATE_WAIT_NDEF_WRITE:
+      ndef_status = rw_t1t_next_ndef_write_block();
+      break;
+
+    case RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED:
+      /* Validate new NDEF Message */
+      RW_T1T_BLD_ADD((addr), (T1T_CC_BLOCK), (T1T_CC_NMN_OFFSET));
+      if (NFC_STATUS_OK ==
+          rw_t1t_send_static_cmd(T1T_CMD_WRITE_E, addr, T1T_CC_NMN)) {
+        ndef_status = NFC_STATUS_OK;
+      } else {
+        ndef_status = NFC_STATUS_FAILED;
+      }
+      break;
+    default:
+      break;
+  }
+
+  return ndef_status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_update_attributes
+**
+** Description      This function will prepare attributes for the current
+**                  segment. Every bit in the attribute refers to one byte of
+**                  tag content.The bit corresponding to a tag byte will be set
+**                  to '1' when the Tag byte is read only,otherwise will be set
+**                  to '0'
+**
+** Returns          None
+**
+*******************************************************************************/
+static void rw_t1t_update_attributes(void) {
+  uint8_t count = 0;
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  uint16_t lower_offset;
+  uint16_t upper_offset;
+  uint8_t num_bytes;
+  uint16_t offset;
+  uint8_t bits_per_byte = 8;
+
+  count = 0;
+  while (count < T1T_BLOCKS_PER_SEGMENT) {
+    p_t1t->attr[count] = 0x00;
+    count++;
+  }
+
+  lower_offset = p_t1t->segment * T1T_SEGMENT_SIZE;
+  upper_offset = (p_t1t->segment + 1) * T1T_SEGMENT_SIZE;
+
+  if (p_t1t->segment == 0) {
+    /* UID/Lock/Reserved/OTP bytes */
+    p_t1t->attr[0x00] = 0xFF; /* Uid bytes */
+    p_t1t->attr[0x0D] = 0xFF; /* Reserved bytes */
+    p_t1t->attr[0x0E] = 0xFF; /* lock/otp bytes */
+    p_t1t->attr[0x0F] = 0xFF; /* lock/otp bytes */
+  }
+
+  /* update attr based on lock control and mem control tlvs */
+  count = 0;
+  while (count < p_t1t->num_lockbytes) {
+    offset = p_t1t->lock_tlv[p_t1t->lockbyte[count].tlv_index].offset +
+             p_t1t->lockbyte[count].byte_index;
+    if (offset >= lower_offset && offset < upper_offset) {
+      /* Set the corresponding bit in attr to indicate - lock byte */
+      p_t1t->attr[(offset % T1T_SEGMENT_SIZE) / bits_per_byte] |=
+          rw_t1t_mask_bits[(offset % T1T_SEGMENT_SIZE) % bits_per_byte];
+    }
+    count++;
+  }
+  count = 0;
+  while (count < p_t1t->num_mem_tlvs) {
+    num_bytes = 0;
+    while (num_bytes < p_t1t->mem_tlv[count].num_bytes) {
+      offset = p_t1t->mem_tlv[count].offset + num_bytes;
+      if (offset >= lower_offset && offset < upper_offset) {
+        /* Set the corresponding bit in attr to indicate - reserved byte */
+        p_t1t->attr[(offset % T1T_SEGMENT_SIZE) / bits_per_byte] |=
+            rw_t1t_mask_bits[(offset % T1T_SEGMENT_SIZE) % bits_per_byte];
+      }
+      num_bytes++;
+    }
+    count++;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_get_lock_bits_for_segment
+**
+** Description      This function will identify the index of the dynamic lock
+**                  byte that covers the current segment
+**
+** Parameters:      segment, segment number
+**                  p_start_byte, pointer to hold the first lock byte index
+**                  p_start_bit, pointer to hold the first lock bit index
+**                  p_end_byte, pointer to hold the last lock byte index
+**
+** Returns          Total lock bits that covers the specified segment
+**
+*******************************************************************************/
+static uint8_t rw_t1t_get_lock_bits_for_segment(uint8_t segment,
+                                                uint8_t* p_start_byte,
+                                                uint8_t* p_start_bit,
+                                                uint8_t* p_end_byte) {
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  uint16_t byte_count = T1T_SEGMENT_SIZE;
+  uint8_t total_bits = 0;
+  uint8_t num_dynamic_locks = 0;
+  uint8_t bit_count = 0;
+  uint16_t tag_size = (p_t1t->mem[T1T_CC_TMS_BYTE] + 1) * T1T_BLOCK_SIZE;
+  uint16_t lower_offset;
+  uint16_t upper_offset;
+  bool b_all_bits_are_locks = true;
+  uint8_t bytes_locked_per_bit;
+  uint8_t num_bits;
+
+  upper_offset = (segment + 1) * T1T_SEGMENT_SIZE;
+
+  if (upper_offset > tag_size) upper_offset = tag_size;
+
+  lower_offset = segment * T1T_SEGMENT_SIZE;
+  *p_start_byte = num_dynamic_locks;
+  *p_start_bit = 0;
+
+  while ((byte_count <= lower_offset) &&
+         (num_dynamic_locks < p_t1t->num_lockbytes)) {
+    bytes_locked_per_bit =
+        p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index]
+            .bytes_locked_per_bit;
+    /* Number of bits in the current lock byte */
+    b_all_bits_are_locks =
+        ((p_t1t->lockbyte[num_dynamic_locks].byte_index + 1) *
+             TAG_BITS_PER_BYTE <=
+         p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index]
+             .num_bits);
+    num_bits =
+        b_all_bits_are_locks
+            ? TAG_BITS_PER_BYTE
+            : p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index]
+                      .num_bits %
+                  TAG_BITS_PER_BYTE;
+
+    /* Skip lock bits that covers all previous segments */
+    if (bytes_locked_per_bit * num_bits + byte_count <= lower_offset) {
+      byte_count += bytes_locked_per_bit * num_bits;
+      num_dynamic_locks++;
+    } else {
+      /* The first lock bit that covers this segment is present in this segment
+       */
+      bit_count = 0;
+      while (bit_count < num_bits) {
+        byte_count += bytes_locked_per_bit;
+        if (byte_count > lower_offset) {
+          *p_start_byte = num_dynamic_locks;
+          *p_end_byte = num_dynamic_locks;
+          *p_start_bit = bit_count;
+          bit_count++;
+          total_bits = 1;
+          break;
+        }
+        bit_count++;
+      }
+    }
+  }
+  if (num_dynamic_locks == p_t1t->num_lockbytes) {
+    return 0;
+  }
+  while ((byte_count < upper_offset) &&
+         (num_dynamic_locks < p_t1t->num_lockbytes)) {
+    bytes_locked_per_bit =
+        p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index]
+            .bytes_locked_per_bit;
+
+    /* Number of bits in the current lock byte */
+    b_all_bits_are_locks =
+        ((p_t1t->lockbyte[num_dynamic_locks].byte_index + 1) *
+             TAG_BITS_PER_BYTE <=
+         p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index]
+             .num_bits);
+    num_bits =
+        b_all_bits_are_locks
+            ? TAG_BITS_PER_BYTE
+            : p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index]
+                      .num_bits %
+                  TAG_BITS_PER_BYTE;
+
+    /* Collect all lock bits that covers the current segment */
+    if ((bytes_locked_per_bit * (num_bits - bit_count)) + byte_count <
+        upper_offset) {
+      byte_count += bytes_locked_per_bit * (num_bits - bit_count);
+      total_bits += num_bits - bit_count;
+      bit_count = 0;
+      *p_end_byte = num_dynamic_locks;
+      num_dynamic_locks++;
+    } else {
+      /* The last lock byte that covers the current segment */
+      bit_count = 0;
+      while (bit_count < num_bits) {
+        byte_count += bytes_locked_per_bit;
+        if (byte_count >= upper_offset) {
+          *p_end_byte = num_dynamic_locks;
+          total_bits += (bit_count + 1);
+          break;
+        }
+        bit_count++;
+      }
+    }
+  }
+  return total_bits;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_update_lock_attributes
+**
+** Description      This function will check if the tag index passed as
+**                  argument is a locked byte and return
+**                  true or false
+**
+** Parameters:      index, the index of the byte in the tag
+**
+**
+** Returns          true, if the specified index in the tag is a locked or
+**                        reserved or otp byte
+**                  false, otherwise
+**
+*******************************************************************************/
+static void rw_t1t_update_lock_attributes(void) {
+  uint8_t xx = 0;
+  uint8_t bytes_locked_per_lock_bit;
+  uint8_t num_static_lock_bytes = 0;
+  uint8_t num_dynamic_lock_bytes = 0;
+  uint8_t bits_covered = 0;
+  uint8_t bytes_covered = 0;
+  uint8_t block_count = 0;
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  uint8_t start_lock_byte;
+  uint8_t start_lock_bit;
+  uint8_t end_lock_byte;
+  uint8_t num_lock_bits;
+  uint8_t total_bits;
+
+  block_count = 0;
+  while (block_count < T1T_BLOCKS_PER_SEGMENT) {
+    p_t1t->lock_attr[block_count] = 0x00;
+    block_count++;
+  }
+
+  /* update lock_attr based on static lock bytes */
+  if (p_t1t->segment == 0) {
+    xx = 0;
+    num_static_lock_bytes = 0;
+    block_count = 0;
+    num_lock_bits = 8;
+
+    while (num_static_lock_bytes < T1T_NUM_STATIC_LOCK_BYTES) {
+      /* Update lock attribute based on 2 static locks */
+      while (xx < num_lock_bits) {
+        p_t1t->lock_attr[block_count] = 0x00;
+
+        if (p_t1t->mem[T1T_LOCK_0_OFFSET + num_static_lock_bytes] &
+            rw_t1t_mask_bits[xx++]) {
+          /* If the bit is set then 1 block is locked */
+          p_t1t->lock_attr[block_count] = 0xFF;
+        }
+
+        block_count++;
+      }
+      num_static_lock_bytes++;
+      xx = 0;
+    }
+    /* Locked bytes */
+    p_t1t->lock_attr[0x00] = 0xFF;
+    p_t1t->lock_attr[0x0D] = 0xFF;
+  } else {
+    /* update lock_attr based on segment and using dynamic lock bytes */
+    total_bits = rw_t1t_get_lock_bits_for_segment(
+        p_t1t->segment, &start_lock_byte, &start_lock_bit, &end_lock_byte);
+    if (total_bits != 0) {
+      xx = start_lock_bit;
+      num_dynamic_lock_bytes = start_lock_byte;
+      bits_covered = 0;
+      bytes_covered = 0;
+      block_count = 0;
+      num_lock_bits = 8;
+
+      p_t1t->lock_attr[block_count] = 0;
+
+      while (num_dynamic_lock_bytes <= end_lock_byte) {
+        bytes_locked_per_lock_bit =
+            p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_lock_bytes].tlv_index]
+                .bytes_locked_per_bit;
+        if (num_dynamic_lock_bytes == end_lock_byte) {
+          num_lock_bits = (total_bits % 8 == 0) ? 8 : total_bits % 8;
+        }
+        while (xx < num_lock_bits) {
+          bytes_covered = 0;
+          while (bytes_covered < bytes_locked_per_lock_bit) {
+            /* Set/clear lock_attr byte bits based on whether a particular lock
+             * bit is set or not
+             * each bit in lock_attr represents one byte in Tag read only
+             * attribute */
+            if ((p_t1t->lockbyte[num_dynamic_lock_bytes].lock_byte &
+                 rw_t1t_mask_bits[xx]) &&
+                (block_count < T1T_BLOCKS_PER_SEGMENT)) {
+              p_t1t->lock_attr[block_count] |= 0x01 << bits_covered;
+            }
+            bytes_covered++;
+            bits_covered++;
+            if (bits_covered == 8) {
+              bits_covered = 0;
+              block_count++;
+              if (block_count < T1T_BLOCKS_PER_SEGMENT)
+                p_t1t->lock_attr[block_count] = 0;
+            }
+          }
+          xx++;
+        }
+        num_dynamic_lock_bytes++;
+        xx = 0;
+      }
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_is_lock_reserved_otp_byte
+**
+** Description      This function will check if the tag index passed as
+**                  argument is a lock or reserved or otp byte
+**
+** Parameters:      index, the index of the byte in the tag's current segment
+**
+**
+** Returns          true, if the specified index in the tag is a locked or
+**                        reserved or otp byte
+**                  false, otherwise
+**
+*******************************************************************************/
+static bool rw_t1t_is_lock_reserved_otp_byte(uint16_t index) {
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+
+  if (p_t1t->attr_seg != p_t1t->segment) {
+    /* Update p_t1t->attr to reflect the current segment */
+    rw_t1t_update_attributes();
+    p_t1t->attr_seg = p_t1t->segment;
+  }
+  index = index % T1T_SEGMENT_SIZE;
+
+  /* Every bit in p_t1t->attr indicates one specific byte of the tag is either a
+   * lock/reserved/otp byte or not
+   * So, each array element in p_t1t->attr covers one block in the tag as T1
+   * block size and array element size is 8
+   * Find the block and offset for the index (passed as argument) and Check if
+   * the offset bit in the
+   * p_t1t->attr[block] is set or not. If the bit is set then it is a
+   * lock/reserved/otp byte, otherwise not */
+
+  return ((p_t1t->attr[index / 8] & rw_t1t_mask_bits[index % 8]) == 0) ? false
+                                                                       : true;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_is_read_only_byte
+**
+** Description      This function will check if the tag index passed as
+**                  argument is a read only byte
+**
+** Parameters:      index, the index of the byte in the tag's current segment
+**
+**
+** Returns          true, if the specified index in the tag is a locked or
+**                        reserved or otp byte
+**                  false, otherwise
+**
+*******************************************************************************/
+static bool rw_t1t_is_read_only_byte(uint16_t index) {
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+
+  if (p_t1t->lock_attr_seg != p_t1t->segment) {
+    /* Update p_t1t->lock_attr to reflect the current segment */
+    rw_t1t_update_lock_attributes();
+    p_t1t->lock_attr_seg = p_t1t->segment;
+  }
+
+  index = index % T1T_SEGMENT_SIZE;
+  /* Every bit in p_t1t->lock_attr indicates one specific byte of the tag is a
+   * read only byte or read write byte
+   * So, each array element in p_t1t->lock_attr covers one block in the tag as
+   * T1 block size and array element size is 8
+   * Find the block and offset for the index (passed as argument) and Check if
+   * the offset bit in the
+   * p_t1t->lock_attr[block] is set or not. If the bit is set then it is a read
+   * only byte, otherwise read write byte */
+
+  return ((p_t1t->lock_attr[index / 8] & rw_t1t_mask_bits[index % 8]) == 0)
+             ? false
+             : true;
+}
+
+/*****************************************************************************
+**
+** Function         RW_T1tFormatNDef
+**
+** Description
+**      Format Tag content
+**
+** Returns
+**      NFC_STATUS_OK, Command sent to format Tag
+**      NFC_STATUS_REJECTED: Invalid HR0 and cannot format the tag
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T1tFormatNDef(void) {
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  const tT1T_INIT_TAG* p_ret;
+  uint8_t addr;
+  uint8_t* p;
+
+  if (p_t1t->state != RW_T1T_STATE_IDLE) {
+    RW_TRACE_WARNING1("RW_T1tFormatNDef - Tag not initialized/ Busy! State: %u",
+                      p_t1t->state);
+    return (NFC_STATUS_FAILED);
+  }
+
+  if ((p_t1t->hr[0] & 0xF0) != T1T_NDEF_SUPPORTED) {
+    RW_TRACE_WARNING1(
+        "RW_T1tFormatNDef - Cannot format tag as NDEF not supported. HR0: %u",
+        p_t1t->hr[0]);
+    return (NFC_STATUS_REJECTED);
+  }
+
+  p_ret = t1t_tag_init_data(p_t1t->hr[0]);
+  if (p_ret == NULL) {
+    RW_TRACE_WARNING2("RW_T1tFormatNDef - Invalid HR - HR0: %u, HR1: %u",
+                      p_t1t->hr[0], p_t1t->hr[1]);
+    return (NFC_STATUS_REJECTED);
+  }
+
+  memset(p_t1t->ndef_first_block, 0, T1T_BLOCK_SIZE);
+  memset(p_t1t->ndef_final_block, 0, T1T_BLOCK_SIZE);
+  p = p_t1t->ndef_first_block;
+
+  /* Prepare Capability Container */
+  UINT8_TO_BE_STREAM(p, T1T_CC_NMN);
+  UINT8_TO_BE_STREAM(p, T1T_CC_VNO);
+  UINT8_TO_BE_STREAM(p, p_ret->tms);
+  UINT8_TO_BE_STREAM(p, T1T_CC_RWA_RW);
+  if (p_ret->b_dynamic) {
+    /* Prepare Lock and Memory TLV */
+    UINT8_TO_BE_STREAM(p, TAG_LOCK_CTRL_TLV);
+    UINT8_TO_BE_STREAM(p, T1T_DEFAULT_TLV_LEN);
+    UINT8_TO_BE_STREAM(p, p_ret->lock_tlv[0]);
+    UINT8_TO_BE_STREAM(p, p_ret->lock_tlv[1]);
+    p = p_t1t->ndef_final_block;
+    UINT8_TO_BE_STREAM(p, p_ret->lock_tlv[2]);
+    UINT8_TO_BE_STREAM(p, TAG_MEM_CTRL_TLV);
+    UINT8_TO_BE_STREAM(p, T1T_DEFAULT_TLV_LEN);
+    UINT8_TO_BE_STREAM(p, p_ret->mem_tlv[0]);
+    UINT8_TO_BE_STREAM(p, p_ret->mem_tlv[1]);
+    UINT8_TO_BE_STREAM(p, p_ret->mem_tlv[2]);
+  }
+  /* Prepare NULL NDEF TLV */
+  UINT8_TO_BE_STREAM(p, TAG_NDEF_TLV);
+  UINT8_TO_BE_STREAM(p, 0);
+
+  if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 ||
+      rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN) {
+    /* send WRITE-E8 command */
+    status = rw_t1t_send_dyn_cmd(T1T_CMD_WRITE_E8, 1, p_t1t->ndef_first_block);
+    if (status == NFC_STATUS_OK) {
+      p_t1t->state = RW_T1T_STATE_FORMAT_TAG;
+      p_t1t->b_update = false;
+      p_t1t->b_rseg = false;
+      if (p_ret->b_dynamic)
+        p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_CC;
+      else
+        p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF;
+    }
+  } else {
+    /* send WRITE-E command */
+    RW_T1T_BLD_ADD((addr), 1, 0);
+
+    status = rw_t1t_send_static_cmd(T1T_CMD_WRITE_E, addr,
+                                    p_t1t->ndef_first_block[0]);
+    if (status == NFC_STATUS_OK) {
+      p_t1t->work_offset = 0;
+      p_t1t->state = RW_T1T_STATE_FORMAT_TAG;
+      p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF;
+      p_t1t->b_update = false;
+      p_t1t->b_rseg = false;
+    }
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T1tLocateTlv
+**
+** Description      This function is called to find the start of the given TLV
+**
+** Parameters:      tlv_type, Type of TLV to find
+**
+** Returns          NCI_STATUS_OK, if detection was started. Otherwise, error
+**                  status.
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tLocateTlv(uint8_t tlv_type) {
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  uint8_t adds;
+
+  if (p_t1t->state != RW_T1T_STATE_IDLE) {
+    RW_TRACE_WARNING1("RW_T1tLocateTlv - Busy - State: %u", p_t1t->state);
+    return (NFC_STATUS_FAILED);
+  }
+  p_t1t->tlv_detect = tlv_type;
+
+  if ((p_t1t->tlv_detect == TAG_NDEF_TLV) &&
+      (((p_t1t->hr[0]) & 0xF0) != T1T_NDEF_SUPPORTED)) {
+    RW_TRACE_ERROR0("RW_T1tLocateTlv - Error: NDEF not supported by the tag");
+    return (NFC_STATUS_REFUSED);
+  }
+
+  if ((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) ||
+      (p_t1t->tlv_detect == TAG_NDEF_TLV)) {
+    p_t1t->num_mem_tlvs = 0;
+  }
+
+  if ((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) ||
+      (p_t1t->tlv_detect == TAG_NDEF_TLV)) {
+    p_t1t->num_lockbytes = 0;
+    p_t1t->num_lock_tlvs = 0;
+  }
+
+  /* Start reading memory, looking for the TLV */
+  p_t1t->segment = 0;
+  if ((p_t1t->hr[0] & 0x0F) != 1) {
+    /* send RSEG command */
+    RW_T1T_BLD_ADDS((adds), (p_t1t->segment));
+    status = rw_t1t_send_dyn_cmd(T1T_CMD_RSEG, adds, NULL);
+  } else {
+    status = rw_t1t_send_static_cmd(T1T_CMD_RALL, 0, 0);
+  }
+  if (status == NFC_STATUS_OK) {
+    p_t1t->tlv_detect = tlv_type;
+    p_t1t->work_offset = 0;
+    p_t1t->state = RW_T1T_STATE_TLV_DETECT;
+    p_t1t->substate = RW_T1T_SUBSTATE_NONE;
+  }
+
+  return status;
+}
+
+/*****************************************************************************
+**
+** Function         RW_T1tDetectNDef
+**
+** Description
+**      This function is used to perform NDEF detection on a Type 1 tag, and
+**      retrieve the tag's NDEF attribute information (block 0).
+**
+**      Before using this API, the application must call RW_SelectTagType to
+**      indicate that a Type 1 tag has been activated.
+**
+** Returns
+**      NFC_STATUS_OK: ndef detection procedure started
+**      NFC_STATUS_WRONG_PROTOCOL: type 1 tag not activated
+**      NFC_STATUS_BUSY: another command is already in progress
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T1tDetectNDef(void) { return RW_T1tLocateTlv(TAG_NDEF_TLV); }
+
+/*******************************************************************************
+**
+** Function         RW_T1tReadNDef
+**
+** Description      This function can be called to read the NDEF message on the
+**                  tag.
+**
+** Parameters:      p_buffer:   The buffer into which to read the NDEF message
+**                  buf_len:    The length of the buffer
+**
+** Returns          NCI_STATUS_OK, if read was started. Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tReadNDef(uint8_t* p_buffer, uint16_t buf_len) {
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  bool b_notify;
+  uint8_t adds;
+  const tT1T_CMD_RSP_INFO* p_cmd_rsp_info_rall =
+      t1t_cmd_to_rsp_info(T1T_CMD_RALL);
+  const tT1T_CMD_RSP_INFO* p_cmd_rsp_info_rseg =
+      t1t_cmd_to_rsp_info(T1T_CMD_RSEG);
+
+  if (p_t1t->state != RW_T1T_STATE_IDLE) {
+    RW_TRACE_WARNING1("RW_T1tReadNDef - Busy - State: %u", p_t1t->state);
+    return (NFC_STATUS_FAILED);
+  }
+
+  /* Check HR0 if NDEF supported by the tag */
+  if (((p_t1t->hr[0]) & 0xF0) != T1T_NDEF_SUPPORTED) {
+    RW_TRACE_ERROR0("RW_T1tReadNDef - Error: NDEF not supported by the tag");
+    return (NFC_STATUS_REFUSED);
+  }
+
+  if (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_INITIALIZED_NDEF) {
+    RW_TRACE_WARNING1(
+        "RW_T1tReadNDef - NDEF Message length is zero, NDEF Length : %u ",
+        p_t1t->ndef_msg_len);
+    return (NFC_STATUS_NOT_INITIALIZED);
+  }
+
+  if ((p_t1t->tag_attribute != RW_T1_TAG_ATTRB_READ_WRITE) &&
+      (p_t1t->tag_attribute != RW_T1_TAG_ATTRB_READ_ONLY)) {
+    RW_TRACE_ERROR0(
+        "RW_T1tReadNDef - Error: NDEF detection not performed yet/ Tag is in "
+        "Initialized state");
+    return (NFC_STATUS_FAILED);
+  }
+
+  if (buf_len < p_t1t->ndef_msg_len) {
+    RW_TRACE_WARNING2(
+        "RW_T1tReadNDef - buffer size: %u  less than NDEF msg sise: %u",
+        buf_len, p_t1t->ndef_msg_len);
+    return (NFC_STATUS_FAILED);
+  }
+  p_t1t->p_ndef_buffer = p_buffer;
+
+  if (p_t1t->b_rseg == true) {
+    /* If already got response to RSEG 0 */
+    p_t1t->state = RW_T1T_STATE_READ_NDEF;
+    p_t1t->p_cmd_rsp_info = (tT1T_CMD_RSP_INFO*)p_cmd_rsp_info_rseg;
+
+    rw_t1t_handle_read_rsp(&b_notify, p_t1t->mem);
+    status = NFC_STATUS_OK;
+  } else if (p_t1t->b_update == true) {
+    /* If already got response to RALL */
+    p_t1t->state = RW_T1T_STATE_READ_NDEF;
+    p_t1t->p_cmd_rsp_info = (tT1T_CMD_RSP_INFO*)p_cmd_rsp_info_rall;
+
+    rw_t1t_handle_read_rsp(&b_notify, p_t1t->mem);
+    status = NFC_STATUS_OK;
+
+  } else {
+    p_t1t->segment = 0;
+    p_t1t->work_offset = 0;
+    if ((p_t1t->hr[0] & 0x0F) != 1) {
+      /* send RSEG command */
+      RW_T1T_BLD_ADDS((adds), (p_t1t->segment));
+      status = rw_t1t_send_dyn_cmd(T1T_CMD_RSEG, adds, NULL);
+    } else {
+      status = rw_t1t_send_static_cmd(T1T_CMD_RALL, 0, 0);
+    }
+    if (status == NFC_STATUS_OK) p_t1t->state = RW_T1T_STATE_READ_NDEF;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T1tWriteNDef
+**
+** Description      This function can be called to write an NDEF message to the
+**                  tag.
+**
+** Parameters:      msg_len:    The length of the buffer
+**                  p_msg:      The NDEF message to write
+**
+** Returns          NCI_STATUS_OK, if write was started. Otherwise, error
+**                  status.
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tWriteNDef(uint16_t msg_len, uint8_t* p_msg) {
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  uint16_t num_ndef_bytes;
+  uint16_t offset;
+  uint8_t addr;
+  uint8_t init_lengthfield_len;
+  uint8_t new_lengthfield_len;
+  uint16_t init_ndef_msg_offset;
+
+  if (p_t1t->state != RW_T1T_STATE_IDLE) {
+    RW_TRACE_WARNING1("RW_T1tWriteNDef - Busy - State: %u", p_t1t->state);
+    return (NFC_STATUS_FAILED);
+  }
+
+  /* Check HR0 if NDEF supported by the tag */
+  if (((p_t1t->hr[0]) & 0xF0) != T1T_NDEF_SUPPORTED) {
+    RW_TRACE_ERROR0("RW_T1tWriteNDef - Error: NDEF not supported by the tag");
+    return (NFC_STATUS_REFUSED);
+  }
+
+  if ((p_t1t->tag_attribute != RW_T1_TAG_ATTRB_READ_WRITE) &&
+      (p_t1t->tag_attribute != RW_T1_TAG_ATTRB_INITIALIZED_NDEF)) {
+    RW_TRACE_ERROR0("RW_T1tWriteNDef - Tag cannot update NDEF");
+    return (NFC_STATUS_REFUSED);
+  }
+
+  if (msg_len > p_t1t->max_ndef_msg_len) {
+    RW_TRACE_ERROR1(
+        "RW_T1tWriteNDef - Cannot write NDEF of size greater than %u bytes",
+        p_t1t->max_ndef_msg_len);
+    return (NFC_STATUS_REFUSED);
+  }
+
+  p_t1t->p_ndef_buffer = p_msg;
+  p_t1t->new_ndef_msg_len = msg_len;
+  new_lengthfield_len = p_t1t->new_ndef_msg_len > 254 ? 3 : 1;
+  init_lengthfield_len =
+      (uint8_t)(p_t1t->ndef_msg_offset - p_t1t->ndef_header_offset);
+  init_ndef_msg_offset = p_t1t->ndef_msg_offset;
+
+  /* ndef_msg_offset should reflect the new ndef message offset */
+  if (init_lengthfield_len > new_lengthfield_len) {
+    p_t1t->ndef_msg_offset =
+        init_ndef_msg_offset -
+        (T1T_LONG_NDEF_LEN_FIELD_LEN - T1T_SHORT_NDEF_LEN_FIELD_LEN);
+  } else if (init_lengthfield_len < new_lengthfield_len) {
+    p_t1t->ndef_msg_offset =
+        init_ndef_msg_offset +
+        (T1T_LONG_NDEF_LEN_FIELD_LEN - T1T_SHORT_NDEF_LEN_FIELD_LEN);
+  }
+
+  num_ndef_bytes = 0;
+  offset = p_t1t->ndef_msg_offset;
+  p_t1t->segment = (uint8_t)(p_t1t->ndef_msg_offset / T1T_SEGMENT_SIZE);
+
+  /* Locate NDEF final block based on the size of new NDEF Message */
+  while (num_ndef_bytes < p_t1t->new_ndef_msg_len) {
+    if (rw_t1t_is_lock_reserved_otp_byte((uint16_t)offset) == false)
+      num_ndef_bytes++;
+
+    offset++;
+    if (offset % T1T_SEGMENT_SIZE == 0) {
+      p_t1t->segment = (uint8_t)(offset / T1T_SEGMENT_SIZE);
+    }
+  }
+
+  p_t1t->b_update = false;
+  p_t1t->b_rseg = false;
+
+  if ((p_t1t->hr[0] & 0x0F) != 1) {
+    /* Dynamic data structure */
+    p_t1t->block_read = (uint8_t)((offset - 1) / T1T_BLOCK_SIZE);
+    /* Read NDEF final block before updating */
+    status = rw_t1t_send_dyn_cmd(T1T_CMD_READ8, p_t1t->block_read, NULL);
+    if (status == NFC_STATUS_OK) {
+      p_t1t->num_ndef_finalblock = p_t1t->block_read;
+      p_t1t->state = RW_T1T_STATE_WRITE_NDEF;
+      p_t1t->substate = RW_T1T_SUBSTATE_WAIT_READ_NDEF_BLOCK;
+    }
+  } else {
+    /* NDEF detected and Static memory structure so send WRITE-E command */
+    RW_T1T_BLD_ADD((addr), (T1T_CC_BLOCK), (T1T_CC_NMN_OFFSET));
+    status = rw_t1t_send_static_cmd(T1T_CMD_WRITE_E, addr, 0);
+    if (status == NFC_STATUS_OK) {
+      p_t1t->state = RW_T1T_STATE_WRITE_NDEF;
+      p_t1t->substate = RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF;
+    }
+  }
+
+  if (status != NFC_STATUS_OK) {
+    /* if status failed, reset ndef_msg_offset to initial message */
+    p_t1t->ndef_msg_offset = init_ndef_msg_offset;
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T1tSetTagReadOnly
+**
+** Description      This function can be called to set t1 tag as read only.
+**
+** Parameters:      None
+**
+** Returns          NCI_STATUS_OK, if setting tag as read only was started.
+**                  Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tSetTagReadOnly(bool b_hard_lock) {
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
+  uint8_t addr;
+  uint8_t num_locks;
+
+  if (p_t1t->state != RW_T1T_STATE_IDLE) {
+    RW_TRACE_WARNING1("RW_T1tSetTagReadOnly - Busy - State: %u", p_t1t->state);
+    return (NFC_STATUS_BUSY);
+  }
+
+  p_t1t->b_hard_lock = b_hard_lock;
+
+  if ((p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_WRITE) ||
+      (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_INITIALIZED) ||
+      (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_INITIALIZED_NDEF)) {
+    /* send WRITE-NE command */
+    RW_T1T_BLD_ADD((addr), (T1T_CC_BLOCK), (T1T_CC_RWA_OFFSET));
+    status = rw_t1t_send_static_cmd(T1T_CMD_WRITE_NE, addr, 0x0F);
+    if (status == NFC_STATUS_OK) {
+      p_t1t->b_update = false;
+      p_t1t->b_rseg = false;
+
+      if (p_t1t->b_hard_lock) {
+        num_locks = 0;
+        while (num_locks < p_t1t->num_lockbytes) {
+          p_t1t->lockbyte[num_locks].lock_status = RW_T1T_LOCK_NOT_UPDATED;
+          num_locks++;
+        }
+      }
+      p_t1t->state = RW_T1T_STATE_SET_TAG_RO;
+      p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_CC_RWA_RO;
+    }
+  }
+
+  return status;
+}
+
+#if (BT_TRACE_VERBOSE == true)
+/*******************************************************************************
+**
+** Function         rw_t1t_get_sub_state_name
+**
+** Description      This function returns the sub_state name.
+**
+** NOTE             conditionally compiled to save memory.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+static char* rw_t1t_get_sub_state_name(uint8_t sub_state) {
+  switch (sub_state) {
+    case RW_T1T_SUBSTATE_NONE:
+      return ("NONE");
+    case RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE:
+      return ("EXTRACT_TLV_VALUE");
+    case RW_T1T_SUBSTATE_WAIT_READ_LOCKS:
+      return ("READING_LOCKS");
+    case RW_T1T_SUBSTATE_WAIT_READ_NDEF_BLOCK:
+      return ("READ_NDEF_FINAL_BLOCK");
+    case RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF:
+      return ("INVALIDATING_NDEF");
+    case RW_T1T_SUBSTATE_WAIT_NDEF_WRITE:
+      return ("WRITE_NDEF_TLV_MESSAGE");
+    case RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED:
+      return ("WAITING_RSP_FOR_LAST_NDEF_WRITE");
+    case RW_T1T_SUBSTATE_WAIT_VALIDATE_NDEF:
+      return ("VALIDATING_NDEF");
+    case RW_T1T_SUBSTATE_WAIT_SET_CC_RWA_RO:
+      return ("SET_RWA_RO");
+    case RW_T1T_SUBSTATE_WAIT_SET_ST_LOCK_BITS:
+      return ("SET_STATIC_LOCK_BITS");
+    case RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS:
+      return ("SET_DYNAMIC_LOCK_BITS");
+
+    default:
+      return ("???? UNKNOWN SUBSTATE");
+  }
+}
+#endif /* (BT_TRACE_VERBOSE == true) */
+
+#endif /* (RW_NDEF_INCLUDED == true) */
diff --git a/src/nfc/tags/rw_t2t.c b/src/nfc/tags/rw_t2t.c
new file mode 100644
index 0000000..2a952e2
--- /dev/null
+++ b/src/nfc/tags/rw_t2t.c
@@ -0,0 +1,1154 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the implementation for Type 2 tag in Reader/Writer
+ *  mode.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+#include "bt_types.h"
+
+#include "nfc_api.h"
+#include "nci_hmsgs.h"
+#include "rw_api.h"
+#include "rw_int.h"
+#include "nfc_int.h"
+#include "gki.h"
+
+/* Static local functions */
+static void rw_t2t_proc_data(uint8_t conn_id, tNFC_DATA_CEVT* p_data);
+static tNFC_STATUS rw_t2t_send_cmd(uint8_t opcode, uint8_t* p_dat);
+static void rw_t2t_process_error(void);
+static void rw_t2t_process_frame_error(void);
+static void rw_t2t_handle_presence_check_rsp(tNFC_STATUS status);
+static void rw_t2t_resume_op(void);
+
+#if (BT_TRACE_VERBOSE == true)
+static char* rw_t2t_get_state_name(uint8_t state);
+static char* rw_t2t_get_substate_name(uint8_t substate);
+#endif
+
+/*******************************************************************************
+**
+** Function         rw_t2t_proc_data
+**
+** Description      This function handles data evt received from NFC Controller.
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t2t_proc_data(uint8_t conn_id, tNFC_DATA_CEVT* p_data) {
+  tRW_EVENT rw_event = RW_RAW_FRAME_EVT;
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  NFC_HDR* p_pkt = p_data->p_data;
+  bool b_notify = true;
+  bool b_release = true;
+  uint8_t* p;
+  tRW_READ_DATA evt_data = {0, NULL};
+  tT2T_CMD_RSP_INFO* p_cmd_rsp_info =
+      (tT2T_CMD_RSP_INFO*)rw_cb.tcb.t2t.p_cmd_rsp_info;
+  tRW_DETECT_NDEF_DATA ndef_data;
+#if (BT_TRACE_VERBOSE == true)
+  uint8_t begin_state = p_t2t->state;
+#endif
+
+  if ((p_t2t->state == RW_T2T_STATE_IDLE) || (p_cmd_rsp_info == NULL)) {
+#if (BT_TRACE_VERBOSE == true)
+    RW_TRACE_DEBUG2("RW T2T Raw Frame: Len [0x%X] Status [%s]", p_pkt->len,
+                    NFC_GetStatusName(p_data->status));
+#else
+    RW_TRACE_DEBUG2("RW T2T Raw Frame: Len [0x%X] Status [0x%X]", p_pkt->len,
+                    p_data->status);
+#endif
+    evt_data.status = p_data->status;
+    evt_data.p_data = p_pkt;
+    (*rw_cb.p_cback)(RW_T2T_RAW_FRAME_EVT, (void*)&evt_data);
+    return;
+  }
+#if (RW_STATS_INCLUDED == true)
+  /* Update rx stats */
+  rw_main_update_rx_stats(p_pkt->len);
+#endif
+  /* Stop timer as response is received */
+  nfc_stop_quick_timer(&p_t2t->t2_timer);
+
+  RW_TRACE_EVENT2("RW RECV [%s]:0x%x RSP", t2t_info_to_str(p_cmd_rsp_info),
+                  p_cmd_rsp_info->opcode);
+
+  if (((p_pkt->len != p_cmd_rsp_info->rsp_len) &&
+       (p_pkt->len != p_cmd_rsp_info->nack_rsp_len) &&
+       (p_t2t->substate != RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR)) ||
+      (p_t2t->state == RW_T2T_STATE_HALT)) {
+#if (BT_TRACE_VERBOSE == true)
+    RW_TRACE_ERROR1("T2T Frame error. state=%s ",
+                    rw_t2t_get_state_name(p_t2t->state));
+#else
+    RW_TRACE_ERROR1("T2T Frame error. state=0x%02X command=0x%02X ",
+                    p_t2t->state);
+#endif
+    if (p_t2t->state != RW_T2T_STATE_HALT) {
+      /* Retrasmit the last sent command if retry-count < max retry */
+      rw_t2t_process_frame_error();
+      p_t2t->check_tag_halt = false;
+    }
+    GKI_freebuf(p_pkt);
+    return;
+  }
+  rw_cb.cur_retry = 0;
+
+  /* Assume the data is just the response byte sequence */
+  p = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
+
+  RW_TRACE_EVENT4(
+      "rw_t2t_proc_data State: %u  conn_id: %u  len: %u  data[0]: 0x%02x",
+      p_t2t->state, conn_id, p_pkt->len, *p);
+
+  evt_data.p_data = NULL;
+
+  if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT) {
+    /* The select process happens in two steps */
+    if ((*p & 0x0f) == T2T_RSP_ACK) {
+      if (rw_t2t_sector_change(p_t2t->select_sector) == NFC_STATUS_OK)
+        b_notify = false;
+      else
+        evt_data.status = NFC_STATUS_FAILED;
+    } else {
+      RW_TRACE_EVENT1(
+          "rw_t2t_proc_data - Received NACK response(0x%x) to SEC-SELCT CMD",
+          (*p & 0x0f));
+      evt_data.status = NFC_STATUS_REJECTED;
+    }
+  } else if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR) {
+    evt_data.status = NFC_STATUS_FAILED;
+  } else if ((p_pkt->len != p_cmd_rsp_info->rsp_len) ||
+             ((p_cmd_rsp_info->opcode == T2T_CMD_WRITE) &&
+              ((*p & 0x0f) != T2T_RSP_ACK))) {
+    /* Received NACK response */
+    evt_data.p_data = p_pkt;
+    if (p_t2t->state == RW_T2T_STATE_READ) b_release = false;
+
+    RW_TRACE_EVENT1("rw_t2t_proc_data - Received NACK response(0x%x)",
+                    (*p & 0x0f));
+
+    if (!p_t2t->check_tag_halt) {
+      /* Just received first NACK. Retry just one time to find if tag went in to
+       * HALT State */
+      b_notify = false;
+      rw_t2t_process_error();
+      /* Assume Tag is in HALT State, untill we get response to retry command */
+      p_t2t->check_tag_halt = true;
+    } else {
+      p_t2t->check_tag_halt = false;
+      /* Got consecutive NACK so tag not really halt after first NACK, but
+       * current operation failed */
+      evt_data.status = NFC_STATUS_FAILED;
+    }
+  } else {
+    /* If the response length indicates positive response or cannot be known
+     * from length then assume success */
+    evt_data.status = NFC_STATUS_OK;
+    p_t2t->check_tag_halt = false;
+
+    /* The response data depends on what the current operation was */
+    switch (p_t2t->state) {
+      case RW_T2T_STATE_CHECK_PRESENCE:
+        b_notify = false;
+        rw_t2t_handle_presence_check_rsp(NFC_STATUS_OK);
+        break;
+
+      case RW_T2T_STATE_READ:
+        evt_data.p_data = p_pkt;
+        b_release = false;
+        if (p_t2t->block_read == 0) {
+          p_t2t->b_read_hdr = true;
+          memcpy(p_t2t->tag_hdr, p, T2T_READ_DATA_LEN);
+#if (NXP_EXTNS == TRUE)
+          /* On Ultralight - C tag, if CC is corrupt, correct it */
+          if ((p_t2t->tag_hdr[0] == TAG_MIFARE_MID) &&
+              (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] >= T2T_INVALID_CC_TMS_VAL0) &&
+              (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] <= T2T_INVALID_CC_TMS_VAL1)) {
+            p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] = T2T_CC2_TMS_MULC;
+          }
+#endif
+        }
+        break;
+
+      case RW_T2T_STATE_WRITE:
+        /* Write operation completed successfully */
+        break;
+
+      default:
+        /* NDEF/other Tlv Operation/Format-Tag/Config Tag as Read only */
+        b_notify = false;
+        rw_t2t_handle_rsp(p);
+        break;
+    }
+  }
+
+  if (b_notify) {
+    rw_event = rw_t2t_info_to_event(p_cmd_rsp_info);
+
+    if (rw_event == RW_T2T_NDEF_DETECT_EVT) {
+      ndef_data.status = evt_data.status;
+      ndef_data.protocol = NFC_PROTOCOL_T2T;
+      ndef_data.flags = RW_NDEF_FL_UNKNOWN;
+      if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_LOCKS)
+        ndef_data.flags = RW_NDEF_FL_FORMATED;
+      ndef_data.max_size = 0;
+      ndef_data.cur_size = 0;
+      /* Move back to idle state */
+      rw_t2t_handle_op_complete();
+      (*rw_cb.p_cback)(rw_event, (void*)&ndef_data);
+    } else {
+      /* Move back to idle state */
+      rw_t2t_handle_op_complete();
+      (*rw_cb.p_cback)(rw_event, (void*)&evt_data);
+    }
+  }
+
+  if (b_release) GKI_freebuf(p_pkt);
+
+#if (BT_TRACE_VERBOSE == true)
+  if (begin_state != p_t2t->state) {
+    RW_TRACE_DEBUG2("RW T2T state changed:<%s> -> <%s>",
+                    rw_t2t_get_state_name(begin_state),
+                    rw_t2t_get_state_name(p_t2t->state));
+  }
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_conn_cback
+**
+** Description      This callback function receives events/data from NFCC.
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t2t_conn_cback(uint8_t conn_id, tNFC_CONN_EVT event,
+                       tNFC_CONN* p_data) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  tRW_READ_DATA evt_data;
+
+  RW_TRACE_DEBUG2("rw_t2t_conn_cback: conn_id=%i, evt=%i", conn_id, event);
+  /* Only handle static conn_id */
+  if (conn_id != NFC_RF_CONN_ID) {
+    return;
+  }
+
+  switch (event) {
+    case NFC_CONN_CREATE_CEVT:
+    case NFC_CONN_CLOSE_CEVT:
+      break;
+
+    case NFC_DEACTIVATE_CEVT:
+#if (RW_STATS_INCLUDED == true)
+      /* Display stats */
+      rw_main_log_stats();
+#endif
+      /* Stop t2t timer (if started) */
+      nfc_stop_quick_timer(&p_t2t->t2_timer);
+
+      /* Free cmd buf for retransmissions */
+      if (p_t2t->p_cur_cmd_buf) {
+        GKI_freebuf(p_t2t->p_cur_cmd_buf);
+        p_t2t->p_cur_cmd_buf = NULL;
+      }
+      /* Free cmd buf used to hold command before sector change */
+      if (p_t2t->p_sec_cmd_buf) {
+        GKI_freebuf(p_t2t->p_sec_cmd_buf);
+        p_t2t->p_sec_cmd_buf = NULL;
+      }
+
+      p_t2t->state = RW_T2T_STATE_NOT_ACTIVATED;
+      NFC_SetStaticRfCback(NULL);
+      break;
+
+    case NFC_DATA_CEVT:
+      if (p_data != NULL) {
+        if ((p_data->data.status == NFC_STATUS_OK) ||
+            (p_data->data.status == NFC_STATUS_CONTINUE)) {
+          rw_t2t_proc_data(conn_id, &(p_data->data));
+          break;
+        } else if (p_data->data.p_data != NULL) {
+          /* Free the response buffer in case of error response */
+          GKI_freebuf((NFC_HDR*)(p_data->data.p_data));
+          p_data->data.p_data = NULL;
+        }
+      }
+    /* Data event with error status...fall through to NFC_ERROR_CEVT case */
+
+    case NFC_ERROR_CEVT:
+      if ((p_t2t->state == RW_T2T_STATE_NOT_ACTIVATED) ||
+          (p_t2t->state == RW_T2T_STATE_IDLE) ||
+          (p_t2t->state == RW_T2T_STATE_HALT)) {
+#if (RW_STATS_INCLUDED == true)
+        rw_main_update_trans_error_stats();
+#endif /* RW_STATS_INCLUDED */
+        if (event == NFC_ERROR_CEVT)
+          evt_data.status = (tNFC_STATUS)(*(uint8_t*)p_data);
+        else if (p_data)
+          evt_data.status = p_data->status;
+        else
+          evt_data.status = NFC_STATUS_FAILED;
+
+        evt_data.p_data = NULL;
+        (*rw_cb.p_cback)(RW_T2T_INTF_ERROR_EVT, (void*)&evt_data);
+        break;
+      }
+      nfc_stop_quick_timer(&p_t2t->t2_timer);
+#if (RW_STATS_INCLUDED == true)
+      rw_main_update_trans_error_stats();
+#endif
+      if (p_t2t->state == RW_T2T_STATE_CHECK_PRESENCE) {
+        if (p_t2t->check_tag_halt) {
+          p_t2t->state = RW_T2T_STATE_HALT;
+          rw_t2t_handle_presence_check_rsp(NFC_STATUS_REJECTED);
+        } else {
+          /* Move back to idle state */
+          rw_t2t_handle_presence_check_rsp(NFC_STATUS_FAILED);
+        }
+      } else {
+        rw_t2t_process_error();
+      }
+      break;
+
+    default:
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_send_cmd
+**
+** Description      This function composes a Type 2 Tag command and send it via
+**                  NCI to NFCC.
+**
+** Returns          NFC_STATUS_OK if the command is successfuly sent to NCI
+**                  otherwise, error status
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_send_cmd(uint8_t opcode, uint8_t* p_dat) {
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  const tT2T_CMD_RSP_INFO* p_cmd_rsp_info = t2t_cmd_to_rsp_info(opcode);
+  NFC_HDR* p_data;
+  uint8_t* p;
+
+  if (p_cmd_rsp_info) {
+    /* a valid opcode for RW */
+    p_data = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+    if (p_data) {
+      p_t2t->p_cmd_rsp_info = (tT2T_CMD_RSP_INFO*)p_cmd_rsp_info;
+      p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+      p = (uint8_t*)(p_data + 1) + p_data->offset;
+
+      UINT8_TO_STREAM(p, opcode);
+
+      if (p_dat) {
+        ARRAY_TO_STREAM(p, p_dat, (p_cmd_rsp_info->cmd_len - 1));
+      }
+
+      p_data->len = p_cmd_rsp_info->cmd_len;
+
+      /* Indicate first attempt to send command, back up cmd buffer in case
+       * needed for retransmission */
+      rw_cb.cur_retry = 0;
+      memcpy(p_t2t->p_cur_cmd_buf, p_data,
+             sizeof(NFC_HDR) + p_data->offset + p_data->len);
+
+#if (RW_STATS_INCLUDED == true)
+      /* Update stats */
+      rw_main_update_tx_stats(p_data->len, false);
+#endif
+      RW_TRACE_EVENT2("RW SENT [%s]:0x%x CMD", t2t_info_to_str(p_cmd_rsp_info),
+                      p_cmd_rsp_info->opcode);
+
+      status = NFC_SendData(NFC_RF_CONN_ID, p_data);
+      if (status == NFC_STATUS_OK) {
+        p_t2t->last_cmd_sent = opcode;
+        nfc_start_quick_timer(
+            &p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE,
+            (RW_T2T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+      } else {
+#if (BT_TRACE_VERBOSE == true)
+        RW_TRACE_ERROR2("T2T NFC Send data failed. state=%s substate=%s ",
+                        rw_t2t_get_state_name(p_t2t->state),
+                        rw_t2t_get_substate_name(p_t2t->substate));
+#else
+        RW_TRACE_ERROR2(
+            "T2T NFC Send data failed. state=0x%02X substate=0x%02X ",
+            p_t2t->state, p_t2t->substate);
+#endif
+      }
+    } else {
+      status = NFC_STATUS_NO_BUFFERS;
+    }
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_process_timeout
+**
+** Description      handles timeout event
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t2t_process_timeout(TIMER_LIST_ENT* p_tle) {
+  tRW_READ_DATA evt_data;
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  (void)p_tle;
+
+  if (p_t2t->state == RW_T2T_STATE_CHECK_PRESENCE) {
+    if (p_t2t->check_tag_halt) {
+      p_t2t->state = RW_T2T_STATE_HALT;
+      rw_t2t_handle_presence_check_rsp(NFC_STATUS_REJECTED);
+    } else {
+      /* Move back to idle state */
+      rw_t2t_handle_presence_check_rsp(NFC_STATUS_FAILED);
+    }
+    return;
+  }
+
+  if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR) {
+    p_t2t->sector = p_t2t->select_sector;
+    /* Here timeout is an acknowledgment for successfull sector change */
+    if (p_t2t->state == RW_T2T_STATE_SELECT_SECTOR) {
+      /* Notify that select sector op is successfull */
+      rw_t2t_handle_op_complete();
+      evt_data.status = NFC_STATUS_OK;
+      evt_data.p_data = NULL;
+      (*rw_cb.p_cback)(RW_T2T_SELECT_CPLT_EVT, (void*)&evt_data);
+    } else {
+      /* Resume operation from where we stopped before sector change */
+      rw_t2t_resume_op();
+    }
+  } else if (p_t2t->state != RW_T2T_STATE_IDLE) {
+#if (BT_TRACE_VERBOSE == true)
+    RW_TRACE_ERROR1("T2T timeout. state=%s ",
+                    rw_t2t_get_state_name(p_t2t->state));
+#else
+    RW_TRACE_ERROR1("T2T timeout. state=0x%02X ", p_t2t->state);
+#endif
+    /* Handle timeout error as no response to the command sent */
+    rw_t2t_process_error();
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_process_frame_error
+**
+** Description      handles frame crc error
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t2t_process_frame_error(void) {
+#if (RW_STATS_INCLUDED == true)
+  /* Update stats */
+  rw_main_update_crc_error_stats();
+#endif
+  /* Process the error */
+  rw_t2t_process_error();
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_process_error
+**
+** Description      Process error including Timeout, Frame error. This function
+**                  will retry atleast till RW_MAX_RETRIES before give up and
+**                  sending negative notification to upper layer
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t2t_process_error(void) {
+  tRW_READ_DATA evt_data;
+  tRW_EVENT rw_event;
+  NFC_HDR* p_cmd_buf;
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  tT2T_CMD_RSP_INFO* p_cmd_rsp_info =
+      (tT2T_CMD_RSP_INFO*)rw_cb.tcb.t2t.p_cmd_rsp_info;
+  tRW_DETECT_NDEF_DATA ndef_data;
+
+  RW_TRACE_DEBUG1("rw_t2t_process_error () State: %u", p_t2t->state);
+
+  /* Retry sending command if retry-count < max */
+  if ((!p_t2t->check_tag_halt) && (rw_cb.cur_retry < RW_MAX_RETRIES)) {
+    /* retry sending the command */
+    rw_cb.cur_retry++;
+
+    RW_TRACE_DEBUG2("T2T retransmission attempt %i of %i", rw_cb.cur_retry,
+                    RW_MAX_RETRIES);
+
+    /* allocate a new buffer for message */
+    p_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+    if (p_cmd_buf != NULL) {
+      memcpy(p_cmd_buf, p_t2t->p_cur_cmd_buf, sizeof(NFC_HDR) +
+                                                  p_t2t->p_cur_cmd_buf->offset +
+                                                  p_t2t->p_cur_cmd_buf->len);
+#if (RW_STATS_INCLUDED == true)
+      /* Update stats */
+      rw_main_update_tx_stats(p_cmd_buf->len, true);
+#endif
+      if (NFC_SendData(NFC_RF_CONN_ID, p_cmd_buf) == NFC_STATUS_OK) {
+        /* Start timer for waiting for response */
+        nfc_start_quick_timer(
+            &p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE,
+            (RW_T2T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+
+        return;
+      }
+    }
+  } else {
+    if (p_t2t->check_tag_halt) {
+      RW_TRACE_DEBUG0("T2T Went to HALT State!");
+    } else {
+      RW_TRACE_DEBUG1("T2T maximum retransmission attempts reached (%i)",
+                      RW_MAX_RETRIES);
+    }
+  }
+  rw_event = rw_t2t_info_to_event(p_cmd_rsp_info);
+#if (RW_STATS_INCLUDED == true)
+  /* update failure count */
+  rw_main_update_fail_stats();
+#endif
+  if (p_t2t->check_tag_halt) {
+    evt_data.status = NFC_STATUS_REJECTED;
+    p_t2t->state = RW_T2T_STATE_HALT;
+  } else {
+    evt_data.status = NFC_STATUS_TIMEOUT;
+  }
+
+  if (rw_event == RW_T2T_NDEF_DETECT_EVT) {
+    ndef_data.status = evt_data.status;
+    ndef_data.protocol = NFC_PROTOCOL_T2T;
+    ndef_data.flags = RW_NDEF_FL_UNKNOWN;
+    if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_LOCKS)
+      ndef_data.flags = RW_NDEF_FL_FORMATED;
+    ndef_data.max_size = 0;
+    ndef_data.cur_size = 0;
+    /* If not Halt move to idle state */
+    rw_t2t_handle_op_complete();
+
+    (*rw_cb.p_cback)(rw_event, (void*)&ndef_data);
+  } else {
+    evt_data.p_data = NULL;
+    /* If activated and not Halt move to idle state */
+    if (p_t2t->state != RW_T2T_STATE_NOT_ACTIVATED) rw_t2t_handle_op_complete();
+
+    p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+    (*rw_cb.p_cback)(rw_event, (void*)&evt_data);
+  }
+}
+
+/*****************************************************************************
+**
+** Function         rw_t2t_handle_presence_check_rsp
+**
+** Description      Handle response to presence check
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+void rw_t2t_handle_presence_check_rsp(tNFC_STATUS status) {
+  tRW_READ_DATA evt_data;
+
+  /* Notify, Tag is present or not */
+  evt_data.status = status;
+  rw_t2t_handle_op_complete();
+
+  (*rw_cb.p_cback)(RW_T2T_PRESENCE_CHECK_EVT, (void*)&evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_resume_op
+**
+** Description      This function will continue operation after moving to new
+**                  sector
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+static void rw_t2t_resume_op(void) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  tRW_READ_DATA evt_data;
+  NFC_HDR* p_cmd_buf;
+  tRW_EVENT event;
+  const tT2T_CMD_RSP_INFO* p_cmd_rsp_info =
+      (tT2T_CMD_RSP_INFO*)rw_cb.tcb.t2t.p_cmd_rsp_info;
+  uint8_t* p;
+
+  /* Move back to the substate where we were before changing sector */
+  p_t2t->substate = p_t2t->prev_substate;
+
+  p = (uint8_t*)(p_t2t->p_sec_cmd_buf + 1) + p_t2t->p_sec_cmd_buf->offset;
+  p_cmd_rsp_info = t2t_cmd_to_rsp_info((uint8_t)*p);
+  p_t2t->p_cmd_rsp_info = (tT2T_CMD_RSP_INFO*)p_cmd_rsp_info;
+
+  /* allocate a new buffer for message */
+  p_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+  if (p_cmd_buf != NULL) {
+    memcpy(p_cmd_buf, p_t2t->p_sec_cmd_buf, sizeof(NFC_HDR) +
+                                                p_t2t->p_sec_cmd_buf->offset +
+                                                p_t2t->p_sec_cmd_buf->len);
+    memcpy(p_t2t->p_cur_cmd_buf, p_t2t->p_sec_cmd_buf,
+           sizeof(NFC_HDR) + p_t2t->p_sec_cmd_buf->offset +
+               p_t2t->p_sec_cmd_buf->len);
+
+#if (RW_STATS_INCLUDED == true)
+    /* Update stats */
+    rw_main_update_tx_stats(p_cmd_buf->len, true);
+#endif
+    if (NFC_SendData(NFC_RF_CONN_ID, p_cmd_buf) == NFC_STATUS_OK) {
+      /* Start timer for waiting for response */
+      nfc_start_quick_timer(
+          &p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE,
+          (RW_T2T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+    } else {
+      /* failure - could not send buffer */
+      evt_data.p_data = NULL;
+      evt_data.status = NFC_STATUS_FAILED;
+      event = rw_t2t_info_to_event(p_cmd_rsp_info);
+      rw_t2t_handle_op_complete();
+      (*rw_cb.p_cback)(event, (void*)&evt_data);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_sector_change
+**
+** Description      This function issues Type 2 Tag SECTOR-SELECT command
+**                  packet 1.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_sector_change(uint8_t sector) {
+  tNFC_STATUS status;
+  NFC_HDR* p_data;
+  uint8_t* p;
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+
+  p_data = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+  if (p_data == NULL) {
+    RW_TRACE_ERROR0("rw_t2t_sector_change - No buffer");
+    return (NFC_STATUS_NO_BUFFERS);
+  }
+
+  p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p = (uint8_t*)(p_data + 1) + p_data->offset;
+
+  UINT8_TO_BE_STREAM(p, sector);
+  UINT8_TO_BE_STREAM(p, 0x00);
+  UINT8_TO_BE_STREAM(p, 0x00);
+  UINT8_TO_BE_STREAM(p, 0x00);
+
+  p_data->len = 4;
+
+  status = NFC_SendData(NFC_RF_CONN_ID, p_data);
+  if (status == NFC_STATUS_OK) {
+    /* Passive rsp command and suppose not to get response to this command */
+    p_t2t->p_cmd_rsp_info = NULL;
+    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR;
+
+    RW_TRACE_EVENT0("rw_t2t_sector_change Sent Second Command");
+    nfc_start_quick_timer(
+        &p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE,
+        (RW_T2T_SEC_SEL_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+  } else {
+    RW_TRACE_ERROR1(
+        "rw_t2t_sector_change Send failed at rw_t2t_send_cmd, error: %u",
+        status);
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_read
+**
+** Description      This function issues Type 2 Tag READ command for the
+**                  specified block. If the specified block is in different
+**                  sector then it first sends command to move to new sector
+**                  and after the tag moves to new sector it issues the read
+**                  command for the block.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_read(uint16_t block) {
+  tNFC_STATUS status;
+  uint8_t* p;
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  uint8_t sector_byte2[1];
+  uint8_t read_cmd[1];
+
+  read_cmd[0] = block % T2T_BLOCKS_PER_SECTOR;
+  if (p_t2t->sector != block / T2T_BLOCKS_PER_SECTOR) {
+    sector_byte2[0] = 0xFF;
+    /* First Move to new sector before sending Read command */
+    status = rw_t2t_send_cmd(T2T_CMD_SEC_SEL, sector_byte2);
+    if (status == NFC_STATUS_OK) {
+      /* Prepare command that needs to be sent after sector change op is
+       * completed */
+      p_t2t->select_sector = (uint8_t)(block / T2T_BLOCKS_PER_SECTOR);
+      p_t2t->p_sec_cmd_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+      p = (uint8_t*)(p_t2t->p_sec_cmd_buf + 1) + p_t2t->p_sec_cmd_buf->offset;
+      UINT8_TO_BE_STREAM(p, T2T_CMD_READ);
+      UINT8_TO_BE_STREAM(p, read_cmd[0]);
+      p_t2t->p_sec_cmd_buf->len = 2;
+      p_t2t->block_read = block;
+
+      /* Backup the current substate to move back to this substate after
+       * changing sector */
+      p_t2t->prev_substate = p_t2t->substate;
+      p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT;
+      return NFC_STATUS_OK;
+    }
+    return NFC_STATUS_FAILED;
+  }
+
+  /* Send Read command as sector change is not needed */
+  status = rw_t2t_send_cmd(T2T_CMD_READ, (uint8_t*)read_cmd);
+  if (status == NFC_STATUS_OK) {
+    p_t2t->block_read = block;
+    RW_TRACE_EVENT1("rw_t2t_read Sent Command for Block: %u", block);
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_write
+**
+** Description      This function issues Type 2 Tag WRITE command for the
+**                  specified block.  If the specified block is in different
+**                  sector then it first sends command to move to new sector
+**                  and after the tag moves to new sector it issues the write
+**                  command for the block.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_write(uint16_t block, uint8_t* p_write_data) {
+  tNFC_STATUS status;
+  uint8_t* p;
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  uint8_t write_cmd[T2T_WRITE_DATA_LEN + 1];
+  uint8_t sector_byte2[1];
+
+  p_t2t->block_written = block;
+  write_cmd[0] = (uint8_t)(block % T2T_BLOCKS_PER_SECTOR);
+  memcpy(&write_cmd[1], p_write_data, T2T_WRITE_DATA_LEN);
+
+  if (p_t2t->sector != block / T2T_BLOCKS_PER_SECTOR) {
+    sector_byte2[0] = 0xFF;
+    /* First Move to new sector before sending Write command */
+    status = rw_t2t_send_cmd(T2T_CMD_SEC_SEL, sector_byte2);
+    if (status == NFC_STATUS_OK) {
+      /* Prepare command that needs to be sent after sector change op is
+       * completed */
+      p_t2t->select_sector = (uint8_t)(block / T2T_BLOCKS_PER_SECTOR);
+      p_t2t->p_sec_cmd_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+      p = (uint8_t*)(p_t2t->p_sec_cmd_buf + 1) + p_t2t->p_sec_cmd_buf->offset;
+      UINT8_TO_BE_STREAM(p, T2T_CMD_WRITE);
+      memcpy(p, write_cmd, T2T_WRITE_DATA_LEN + 1);
+      p_t2t->p_sec_cmd_buf->len = 2 + T2T_WRITE_DATA_LEN;
+      p_t2t->block_written = block;
+
+      /* Backup the current substate to move back to this substate after
+       * changing sector */
+      p_t2t->prev_substate = p_t2t->substate;
+      p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT;
+      return NFC_STATUS_OK;
+    }
+    return NFC_STATUS_FAILED;
+  }
+
+  /* Send Write command as sector change is not needed */
+  status = rw_t2t_send_cmd(T2T_CMD_WRITE, write_cmd);
+  if (status == NFC_STATUS_OK) {
+    RW_TRACE_EVENT1("rw_t2t_write Sent Command for Block: %u", block);
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_select
+**
+** Description      This function selects type 2 tag.
+**
+** Returns          Tag selection status
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_select(void) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+
+  p_t2t->state = RW_T2T_STATE_IDLE;
+  p_t2t->ndef_status = T2T_NDEF_NOT_DETECTED;
+
+  /* Alloc cmd buf for retransmissions */
+  if (p_t2t->p_cur_cmd_buf == NULL) {
+    p_t2t->p_cur_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+    if (p_t2t->p_cur_cmd_buf == NULL) {
+      RW_TRACE_ERROR0(
+          "rw_t2t_select: unable to allocate buffer for retransmission");
+      return (NFC_STATUS_FAILED);
+    }
+  }
+  /* Alloc cmd buf for holding a command untill sector changes */
+  if (p_t2t->p_sec_cmd_buf == NULL) {
+    p_t2t->p_sec_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+    if (p_t2t->p_sec_cmd_buf == NULL) {
+      RW_TRACE_ERROR0(
+          "rw_t2t_select: unable to allocate buffer used during sector change");
+      return (NFC_STATUS_FAILED);
+    }
+  }
+
+  NFC_SetStaticRfCback(rw_t2t_conn_cback);
+  rw_t2t_handle_op_complete();
+  p_t2t->check_tag_halt = false;
+
+  return NFC_STATUS_OK;
+}
+
+/*****************************************************************************
+**
+** Function         rw_t2t_handle_op_complete
+**
+** Description      Reset to IDLE state
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+void rw_t2t_handle_op_complete(void) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+
+  if ((p_t2t->state == RW_T2T_STATE_READ_NDEF) ||
+      (p_t2t->state == RW_T2T_STATE_WRITE_NDEF)) {
+    p_t2t->b_read_data = false;
+  }
+
+  if (p_t2t->state != RW_T2T_STATE_HALT) p_t2t->state = RW_T2T_STATE_IDLE;
+  p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+  return;
+}
+
+/*****************************************************************************
+**
+** Function         RW_T2tPresenceCheck
+**
+** Description
+**      Check if the tag is still in the field.
+**
+**      The RW_T2T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
+**      or non-presence.
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T2tPresenceCheck(void) {
+  tNFC_STATUS retval = NFC_STATUS_OK;
+  tRW_DATA evt_data;
+  tRW_CB* p_rw_cb = &rw_cb;
+  uint8_t sector_blk = 0; /* block 0 of current sector */
+
+  RW_TRACE_API0("RW_T2tPresenceCheck");
+
+  /* If RW_SelectTagType was not called (no conn_callback) return failure */
+  if (!p_rw_cb->p_cback) {
+    retval = NFC_STATUS_FAILED;
+  }
+  /* If we are not activated, then RW_T2T_PRESENCE_CHECK_EVT status=FAIL */
+  else if (p_rw_cb->tcb.t2t.state == RW_T2T_STATE_NOT_ACTIVATED) {
+    evt_data.status = NFC_STATUS_FAILED;
+    (*p_rw_cb->p_cback)(RW_T2T_PRESENCE_CHECK_EVT, &evt_data);
+  }
+  /* If command is pending, assume tag is still present */
+  else if (p_rw_cb->tcb.t2t.state != RW_T2T_STATE_IDLE) {
+    evt_data.status = NFC_STATUS_OK;
+    (*p_rw_cb->p_cback)(RW_T2T_PRESENCE_CHECK_EVT, &evt_data);
+  } else {
+    /* IDLE state: send a READ command to block 0 of the current sector */
+    retval = rw_t2t_send_cmd(T2T_CMD_READ, &sector_blk);
+    if (retval == NFC_STATUS_OK) {
+      p_rw_cb->tcb.t2t.state = RW_T2T_STATE_CHECK_PRESENCE;
+    }
+  }
+
+  return (retval);
+}
+
+/*******************************************************************************
+**
+** Function         RW_T2tRead
+**
+** Description      This function issues the Type 2 Tag READ command. When the
+**                  operation is complete the callback function will be called
+**                  with a RW_T2T_READ_EVT.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T2tRead(uint16_t block) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  tNFC_STATUS status;
+
+  if (p_t2t->state != RW_T2T_STATE_IDLE) {
+    RW_TRACE_ERROR1("Error: Type 2 tag not activated or Busy - State: %u",
+                    p_t2t->state);
+    return (NFC_STATUS_FAILED);
+  }
+
+  status = rw_t2t_read(block);
+  if (status == NFC_STATUS_OK) {
+    p_t2t->state = RW_T2T_STATE_READ;
+    RW_TRACE_EVENT0("RW_T2tRead Sent Read command");
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T2tWrite
+**
+** Description      This function issues the Type 2 Tag WRITE command. When the
+**                  operation is complete the callback function will be called
+**                  with a RW_T2T_WRITE_EVT.
+**
+**                  p_new_bytes points to the array of 4 bytes to be written
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T2tWrite(uint16_t block, uint8_t* p_write_data) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  tNFC_STATUS status;
+
+  if (p_t2t->state != RW_T2T_STATE_IDLE) {
+    RW_TRACE_ERROR1("Error: Type 2 tag not activated or Busy - State: %u",
+                    p_t2t->state);
+    return (NFC_STATUS_FAILED);
+  }
+
+  status = rw_t2t_write(block, p_write_data);
+  if (status == NFC_STATUS_OK) {
+    p_t2t->state = RW_T2T_STATE_WRITE;
+    if (block < T2T_FIRST_DATA_BLOCK)
+      p_t2t->b_read_hdr = false;
+    else if (block < (T2T_FIRST_DATA_BLOCK + T2T_READ_BLOCKS))
+      p_t2t->b_read_data = false;
+    RW_TRACE_EVENT0("RW_T2tWrite Sent Write command");
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T2tSectorSelect
+**
+** Description      This function issues the Type 2 Tag SECTOR-SELECT command
+**                  packet 1. If a NACK is received as the response, the
+**                  callback function will be called with a
+**                  RW_T2T_SECTOR_SELECT_EVT. If an ACK is received as the
+**                  response, the command packet 2 with the given sector number
+**                  is sent to the peer device. When the response for packet 2
+**                  is received, the callback function will be called with a
+**                  RW_T2T_SECTOR_SELECT_EVT.
+**
+**                  A sector is 256 contiguous blocks (1024 bytes).
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T2tSectorSelect(uint8_t sector) {
+  tNFC_STATUS status;
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  uint8_t sector_byte2[1];
+
+  if (p_t2t->state != RW_T2T_STATE_IDLE) {
+    RW_TRACE_ERROR1("Error: Type 2 tag not activated or Busy - State: %u",
+                    p_t2t->state);
+    return (NFC_STATUS_FAILED);
+  }
+
+  if (sector >= T2T_MAX_SECTOR) {
+    RW_TRACE_ERROR2(
+        "RW_T2tSectorSelect - Invalid sector: %u, T2 Max supported sector "
+        "value: %u",
+        sector, T2T_MAX_SECTOR - 1);
+    return (NFC_STATUS_FAILED);
+  }
+
+  sector_byte2[0] = 0xFF;
+
+  status = rw_t2t_send_cmd(T2T_CMD_SEC_SEL, sector_byte2);
+  if (status == NFC_STATUS_OK) {
+    p_t2t->state = RW_T2T_STATE_SELECT_SECTOR;
+    p_t2t->select_sector = sector;
+    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT;
+
+    RW_TRACE_EVENT0("RW_T2tSectorSelect Sent Sector select first command");
+  }
+
+  return status;
+}
+
+#if (BT_TRACE_VERBOSE == true)
+/*******************************************************************************
+**
+** Function         rw_t2t_get_state_name
+**
+** Description      This function returns the state name.
+**
+** NOTE             conditionally compiled to save memory.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+static char* rw_t2t_get_state_name(uint8_t state) {
+  switch (state) {
+    case RW_T2T_STATE_NOT_ACTIVATED:
+      return ("NOT_ACTIVATED");
+    case RW_T2T_STATE_IDLE:
+      return ("IDLE");
+    case RW_T2T_STATE_READ:
+      return ("APP_READ");
+    case RW_T2T_STATE_WRITE:
+      return ("APP_WRITE");
+    case RW_T2T_STATE_SELECT_SECTOR:
+      return ("SECTOR_SELECT");
+    case RW_T2T_STATE_DETECT_TLV:
+      return ("TLV_DETECT");
+    case RW_T2T_STATE_READ_NDEF:
+      return ("READ_NDEF");
+    case RW_T2T_STATE_WRITE_NDEF:
+      return ("WRITE_NDEF");
+    case RW_T2T_STATE_SET_TAG_RO:
+      return ("SET_TAG_RO");
+    case RW_T2T_STATE_CHECK_PRESENCE:
+      return ("CHECK_PRESENCE");
+    default:
+      return ("???? UNKNOWN STATE");
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_get_substate_name
+**
+** Description      This function returns the substate name.
+**
+** NOTE             conditionally compiled to save memory.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+static char* rw_t2t_get_substate_name(uint8_t substate) {
+  switch (substate) {
+    case RW_T2T_SUBSTATE_NONE:
+      return ("RW_T2T_SUBSTATE_NONE");
+    case RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT:
+      return ("RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT");
+    case RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR:
+      return ("RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR");
+    case RW_T2T_SUBSTATE_WAIT_READ_CC:
+      return ("RW_T2T_SUBSTATE_WAIT_READ_CC");
+    case RW_T2T_SUBSTATE_WAIT_TLV_DETECT:
+      return ("RW_T2T_SUBSTATE_WAIT_TLV_DETECT");
+    case RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN:
+      return ("RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN");
+    case RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0:
+      return ("RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0");
+    case RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1:
+      return ("RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1");
+    case RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE:
+      return ("RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE");
+    case RW_T2T_SUBSTATE_WAIT_READ_LOCKS:
+      return ("RW_T2T_SUBSTATE_WAIT_READ_LOCKS");
+    case RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK:
+      return ("RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK");
+    case RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK:
+      return ("RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK");
+    case RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK:
+      return ("RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK");
+    case RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK:
+      return ("RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK");
+    case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK:
+      return ("RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK");
+    case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK:
+      return ("RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK");
+    case RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK:
+      return ("RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK");
+    case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK:
+      return ("RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK");
+    case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK:
+      return ("RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK");
+    case RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT:
+      return ("RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT");
+    default:
+      return ("???? UNKNOWN SUBSTATE");
+  }
+}
+
+#endif /* (BT_TRACE_VERBOSE == true) */
diff --git a/src/nfc/tags/rw_t2t_ndef.c b/src/nfc/tags/rw_t2t_ndef.c
new file mode 100644
index 0000000..3741755
--- /dev/null
+++ b/src/nfc/tags/rw_t2t_ndef.c
@@ -0,0 +1,3071 @@
+/******************************************************************************
+ *
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the implementation for Type 2 tag NDEF operation in
+ *  Reader/Writer mode.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+
+#include "nfc_api.h"
+#include "nci_hmsgs.h"
+#include "rw_api.h"
+#include "rw_int.h"
+#include "nfc_int.h"
+#include "gki.h"
+
+#if (RW_NDEF_INCLUDED == true)
+
+/* Local static functions */
+static void rw_t2t_handle_cc_read_rsp(void);
+static void rw_t2t_handle_lock_read_rsp(uint8_t* p_data);
+static void rw_t2t_handle_tlv_detect_rsp(uint8_t* p_data);
+static void rw_t2t_handle_ndef_read_rsp(uint8_t* p_data);
+static void rw_t2t_handle_ndef_write_rsp(uint8_t* p_data);
+static void rw_t2t_handle_format_tag_rsp(uint8_t* p_data);
+static void rw_t2t_handle_config_tag_readonly(uint8_t* p_data);
+static uint8_t rw_t2t_get_tag_size(uint8_t* p_data);
+static void rw_t2t_extract_default_locks_info(void);
+static void rw_t2t_update_cb(uint16_t block, uint8_t* p_write_block,
+                             bool b_update_len);
+static uint8_t rw_t2t_get_ndef_flags(void);
+static uint16_t rw_t2t_get_ndef_max_size(void);
+static tNFC_STATUS rw_t2t_read_locks(void);
+static tNFC_STATUS rw_t2t_read_ndef_last_block(void);
+static void rw_t2t_update_attributes(void);
+static void rw_t2t_update_lock_attributes(void);
+static bool rw_t2t_is_lock_res_byte(uint16_t index);
+static bool rw_t2t_is_read_only_byte(uint16_t index);
+static tNFC_STATUS rw_t2t_write_ndef_first_block(uint16_t msg_len,
+                                                 bool b_update_len);
+static tNFC_STATUS rw_t2t_write_ndef_next_block(uint16_t block,
+                                                uint16_t msg_len,
+                                                bool b_update_len);
+static tNFC_STATUS rw_t2t_read_ndef_next_block(uint16_t block);
+static tNFC_STATUS rw_t2t_add_terminator_tlv(void);
+static bool rw_t2t_is_read_before_write_block(uint16_t block,
+                                              uint16_t* p_block_to_read);
+static tNFC_STATUS rw_t2t_set_cc(uint8_t tms);
+static tNFC_STATUS rw_t2t_set_lock_tlv(uint16_t addr, uint8_t num_dyn_lock_bits,
+                                       uint16_t locked_area_size);
+static tNFC_STATUS rw_t2t_format_tag(void);
+static tNFC_STATUS rw_t2t_soft_lock_tag(void);
+static tNFC_STATUS rw_t2t_set_dynamic_lock_bits(uint8_t* p_data);
+static void rw_t2t_ntf_tlv_detect_complete(tNFC_STATUS status);
+
+const uint8_t rw_t2t_mask_bits[8] = {0x01, 0x02, 0x04, 0x08,
+                                     0x10, 0x20, 0x40, 0x80};
+
+/*******************************************************************************
+**
+** Function         rw_t2t_handle_rsp
+**
+** Description      This function handles response to command sent during
+**                  NDEF and other tlv operation
+**
+** Returns          None
+**
+*******************************************************************************/
+void rw_t2t_handle_rsp(uint8_t* p_data) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+
+  if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_CC) {
+    p_t2t->b_read_hdr = true;
+    memcpy(p_t2t->tag_hdr, p_data, T2T_READ_DATA_LEN);
+#if (NXP_EXTNS == TRUE)
+    /* On Ultralight - C tag, if CC is corrupt, correct it */
+    if ((p_t2t->tag_hdr[0] == TAG_MIFARE_MID) &&
+        (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] >= T2T_INVALID_CC_TMS_VAL0) &&
+        (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] <= T2T_INVALID_CC_TMS_VAL1)) {
+      p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] = T2T_CC2_TMS_MULC;
+    }
+#endif
+  }
+
+  switch (p_t2t->state) {
+    case RW_T2T_STATE_DETECT_TLV:
+      if (p_t2t->tlv_detect == TAG_LOCK_CTRL_TLV) {
+        if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_CC) {
+          rw_t2t_handle_cc_read_rsp();
+        } else if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_LOCKS) {
+          rw_t2t_handle_lock_read_rsp(p_data);
+        } else {
+          rw_t2t_handle_tlv_detect_rsp(p_data);
+        }
+      } else if (p_t2t->tlv_detect == TAG_NDEF_TLV) {
+        if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_CC) {
+          if (p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] == T2T_CC0_NMN) {
+            rw_t2t_handle_cc_read_rsp();
+          } else {
+            RW_TRACE_WARNING3(
+                "NDEF Detection failed!, CC[0]: 0x%02x, CC[1]: 0x%02x, CC[3]: "
+                "0x%02x",
+                p_t2t->tag_hdr[T2T_CC0_NMN_BYTE],
+                p_t2t->tag_hdr[T2T_CC1_VNO_BYTE],
+                p_t2t->tag_hdr[T2T_CC3_RWA_BYTE]);
+            rw_t2t_ntf_tlv_detect_complete(NFC_STATUS_FAILED);
+          }
+        } else if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_LOCKS) {
+          rw_t2t_handle_lock_read_rsp(p_data);
+        } else {
+          rw_t2t_handle_tlv_detect_rsp(p_data);
+        }
+      } else {
+        if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_CC) {
+          rw_t2t_handle_cc_read_rsp();
+        } else {
+          rw_t2t_handle_tlv_detect_rsp(p_data);
+        }
+      }
+      break;
+
+    case RW_T2T_STATE_SET_TAG_RO:
+      rw_t2t_handle_config_tag_readonly(p_data);
+      break;
+
+    case RW_T2T_STATE_FORMAT_TAG:
+      rw_t2t_handle_format_tag_rsp(p_data);
+      break;
+
+    case RW_T2T_STATE_READ_NDEF:
+      rw_t2t_handle_ndef_read_rsp(p_data);
+      break;
+
+    case RW_T2T_STATE_WRITE_NDEF:
+      rw_t2t_handle_ndef_write_rsp(p_data);
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_info_to_event
+**
+** Description      This function returns RW event code based on the current
+**                  state
+**
+** Returns          RW event code
+**
+*******************************************************************************/
+tRW_EVENT rw_t2t_info_to_event(const tT2T_CMD_RSP_INFO* p_info) {
+  tRW_EVENT rw_event;
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+
+  switch (p_t2t->state) {
+    case RW_T2T_STATE_DETECT_TLV:
+      if (p_t2t->tlv_detect == TAG_NDEF_TLV)
+        rw_event = RW_T2T_NDEF_DETECT_EVT;
+      else
+        rw_event = RW_T2T_TLV_DETECT_EVT;
+
+      break;
+
+    case RW_T2T_STATE_READ_NDEF:
+      rw_event = RW_T2T_NDEF_READ_EVT;
+      break;
+
+    case RW_T2T_STATE_WRITE_NDEF:
+      rw_event = RW_T2T_NDEF_WRITE_EVT;
+      break;
+
+    case RW_T2T_STATE_SET_TAG_RO:
+      rw_event = RW_T2T_SET_TAG_RO_EVT;
+      break;
+
+    case RW_T2T_STATE_CHECK_PRESENCE:
+      rw_event = RW_T2T_PRESENCE_CHECK_EVT;
+      break;
+
+    case RW_T2T_STATE_FORMAT_TAG:
+      rw_event = RW_T2T_FORMAT_CPLT_EVT;
+      break;
+
+    default:
+      rw_event = t2t_info_to_evt(p_info);
+      break;
+  }
+  return rw_event;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_handle_cc_read_rsp
+**
+** Description      Handle read cc bytes
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t2t_handle_cc_read_rsp(void) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+
+  if (((p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] != T2T_CC3_RWA_RW) &&
+       (p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] != T2T_CC3_RWA_RO)) ||
+      ((p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_LEGACY_VNO) &&
+       (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_VNO) &&
+       (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_NEW_VNO))) {
+    /* Invalid Version number or RWA byte */
+    rw_t2t_ntf_tlv_detect_complete(NFC_STATUS_FAILED);
+    return;
+  }
+
+  p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
+
+  if (rw_t2t_read((uint16_t)T2T_FIRST_DATA_BLOCK) != NFC_STATUS_OK) {
+    rw_t2t_ntf_tlv_detect_complete(NFC_STATUS_FAILED);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_ntf_tlv_detect_complete
+**
+** Description      Notify TLV detection complete to upper layer
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t2t_ntf_tlv_detect_complete(tNFC_STATUS status) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  tRW_DETECT_NDEF_DATA ndef_data = {.status = 0};
+  tRW_DETECT_TLV_DATA tlv_data;
+  tRW_T2T_DETECT evt_data;
+  uint8_t xx;
+
+  if (p_t2t->tlv_detect == TAG_NDEF_TLV) {
+    /* Notify upper layer the result of NDEF detect op */
+    ndef_data.status = status;
+    ndef_data.protocol = NFC_PROTOCOL_T2T;
+    ndef_data.flags = rw_t2t_get_ndef_flags();
+    ndef_data.cur_size = p_t2t->ndef_msg_len;
+
+    if (status == NFC_STATUS_OK) ndef_data.flags |= RW_NDEF_FL_FORMATED;
+
+    if (p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] == T2T_CC3_RWA_RW)
+      ndef_data.max_size = (uint32_t)rw_t2t_get_ndef_max_size();
+    else
+      ndef_data.max_size = ndef_data.cur_size;
+
+    if (ndef_data.max_size < ndef_data.cur_size) {
+      ndef_data.flags |= RW_NDEF_FL_READ_ONLY;
+      ndef_data.max_size = ndef_data.cur_size;
+    }
+
+    if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY)) {
+      ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE;
+      if (status == NFC_STATUS_OK) ndef_data.flags |= RW_NDEF_FL_HARD_LOCKABLE;
+    }
+
+    rw_t2t_handle_op_complete();
+    (*rw_cb.p_cback)(RW_T2T_NDEF_DETECT_EVT, (void*)&ndef_data);
+  } else if (p_t2t->tlv_detect == TAG_PROPRIETARY_TLV) {
+    evt_data.msg_len = p_t2t->prop_msg_len;
+    evt_data.status = status;
+    rw_t2t_handle_op_complete();
+    (*rw_cb.p_cback)(RW_T2T_TLV_DETECT_EVT, (void*)&evt_data);
+  } else {
+    /* Notify upper layer the result of Lock/Mem TLV detect op */
+    tlv_data.protocol = NFC_PROTOCOL_T2T;
+    if (p_t2t->tlv_detect == TAG_LOCK_CTRL_TLV) {
+      tlv_data.num_bytes = p_t2t->num_lockbytes;
+    } else {
+      tlv_data.num_bytes = 0;
+      for (xx = 0; xx < p_t2t->num_mem_tlvs; xx++) {
+        tlv_data.num_bytes += p_t2t->mem_tlv[p_t2t->num_mem_tlvs].num_bytes;
+      }
+    }
+    tlv_data.status = status;
+    rw_t2t_handle_op_complete();
+    (*rw_cb.p_cback)(RW_T2T_TLV_DETECT_EVT, (void*)&tlv_data);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_handle_lock_read_rsp
+**
+** Description      Handle response to reading lock bytes
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t2t_handle_lock_read_rsp(uint8_t* p_data) {
+  uint8_t updated_lock_byte;
+  uint8_t num_locks;
+  uint8_t offset = 0;
+  uint16_t lock_offset;
+  uint16_t base_lock_offset = 0;
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  uint16_t block;
+
+  /* Prepare NDEF/TLV attributes (based on current op) for sending response to
+   * upper layer */
+
+  num_locks = 0;
+  updated_lock_byte = 0;
+
+  /*  Extract all lock bytes present in the read 16 bytes
+   *  but atleast one lock byte (base lock) should be present in the read 16
+   * bytes */
+
+  while (num_locks < p_t2t->num_lockbytes) {
+    if (p_t2t->lockbyte[num_locks].b_lock_read == false) {
+      lock_offset =
+          p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].offset +
+          p_t2t->lockbyte[num_locks].byte_index;
+      if (updated_lock_byte == 0) {
+        /* The offset of the first lock byte present in the 16 bytes read using
+         * READ command */
+        base_lock_offset = lock_offset;
+        /* Block number used to read may not be the block where lock offset is
+         * present */
+        offset = (uint8_t)(lock_offset - (p_t2t->block_read * T2T_BLOCK_SIZE));
+        /* Update the lock byte value in the control block */
+        p_t2t->lockbyte[num_locks].lock_byte = p_data[offset];
+        p_t2t->lockbyte[num_locks].b_lock_read = true;
+        updated_lock_byte++;
+      } else if (lock_offset > base_lock_offset) {
+        /* Atleast one lock byte will get updated in the control block */
+        if ((lock_offset - base_lock_offset + offset) < T2T_READ_DATA_LEN) {
+          /* And this lock byte is also present in the read data */
+          p_t2t->lockbyte[num_locks].lock_byte =
+              p_data[lock_offset - base_lock_offset + offset];
+          p_t2t->lockbyte[num_locks].b_lock_read = true;
+          updated_lock_byte++;
+        } else {
+          /* This lock byte is not present in the read data */
+          block = (uint16_t)(lock_offset / T2T_BLOCK_LEN);
+          block -= block % T2T_READ_BLOCKS;
+          /* send READ command to read this lock byte */
+          if (NFC_STATUS_OK != rw_t2t_read((uint16_t)block)) {
+            /* Unable to send Read command, notify failure status to upper layer
+             */
+            rw_t2t_ntf_tlv_detect_complete(NFC_STATUS_FAILED);
+          }
+          break;
+        }
+      } else {
+        /* This Lock byte is not present in the read 16 bytes
+         * send READ command to read the lock byte       */
+        if (NFC_STATUS_OK !=
+            rw_t2t_read((uint16_t)(lock_offset / T2T_BLOCK_LEN))) {
+          /* Unable to send Read command, notify failure status to upper layer
+           */
+          rw_t2t_ntf_tlv_detect_complete(NFC_STATUS_FAILED);
+        }
+        break;
+      }
+    }
+    num_locks++;
+  }
+  if (num_locks == p_t2t->num_lockbytes) {
+    /* All locks are read, notify upper layer */
+    rw_t2t_update_lock_attributes();
+    rw_t2t_ntf_tlv_detect_complete(NFC_STATUS_OK);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_handle_tlv_detect_rsp
+**
+** Description      Handle TLV detection.
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t2t_handle_tlv_detect_rsp(uint8_t* p_data) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  uint16_t offset;
+  uint16_t len = 0;
+  bool failed = false;
+  bool found = false;
+  tRW_EVENT event;
+  uint8_t index;
+  uint8_t count = 0;
+  uint8_t xx;
+  tNFC_STATUS status;
+  tT2T_CMD_RSP_INFO* p_cmd_rsp_info =
+      (tT2T_CMD_RSP_INFO*)rw_cb.tcb.t2t.p_cmd_rsp_info;
+  uint8_t tlvtype = p_t2t->tlv_detect;
+
+  if (p_t2t->work_offset == 0) {
+    /* Skip UID,Static Lock block,CC*/
+    p_t2t->work_offset = T2T_FIRST_DATA_BLOCK * T2T_BLOCK_LEN;
+    p_t2t->b_read_data = true;
+    memcpy(p_t2t->tag_data, p_data, T2T_READ_DATA_LEN);
+  }
+
+  p_t2t->segment = 0;
+
+  for (offset = 0; offset < T2T_READ_DATA_LEN && !failed && !found;) {
+    if (rw_t2t_is_lock_res_byte((uint16_t)(p_t2t->work_offset + offset)) ==
+        true) {
+      /* Skip locks, reserved bytes while searching for TLV */
+      offset++;
+      continue;
+    }
+    switch (p_t2t->substate) {
+      case RW_T2T_SUBSTATE_WAIT_TLV_DETECT:
+        /* Search for the tlv */
+        p_t2t->found_tlv = p_data[offset++];
+        switch (p_t2t->found_tlv) {
+          case TAG_NULL_TLV: /* May be used for padding. SHALL ignore this */
+            break;
+
+          case TAG_NDEF_TLV:
+            if (tlvtype == TAG_NDEF_TLV) {
+              /* NDEF Detected, now collect NDEF Attributes including NDEF
+               * Length */
+              index = (offset % T2T_BLOCK_SIZE);
+              /* Backup ndef first block */
+              memcpy(p_t2t->ndef_first_block, &p_data[offset - index], index);
+              p_t2t->substate = RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
+            } else if (tlvtype == TAG_PROPRIETARY_TLV) {
+              /* Proprietary TLV can exist after NDEF Tlv so we continue
+               * searching */
+              p_t2t->substate = RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
+            } else if (((tlvtype == TAG_LOCK_CTRL_TLV) &&
+                        (p_t2t->num_lockbytes > 0)) ||
+                       ((tlvtype == TAG_MEM_CTRL_TLV) &&
+                        (p_t2t->num_mem_tlvs > 0))) {
+              /* Lock / Memory control tlv cannot exist after NDEF TLV
+               * So when NDEF is found, we stop searching for Lock and Memory
+               * control tlv */
+              found = true;
+            } else {
+              /* While searching for Lock / Memory control tlv, if NDEF TLV is
+               * found
+               * first then our search for Lock /Memory control tlv failed and
+               * we stop here */
+              failed = true;
+            }
+            break;
+
+          case TAG_LOCK_CTRL_TLV:
+          case TAG_MEM_CTRL_TLV:
+            p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0;
+            break;
+
+          case TAG_PROPRIETARY_TLV:
+            if (tlvtype == TAG_PROPRIETARY_TLV) {
+              index = (offset % T2T_BLOCK_SIZE);
+              p_t2t->substate = RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
+            } else {
+              /* NDEF/LOCK/MEM TLV can exist after Proprietary Tlv so we
+               * continue searching, skiping proprietary tlv */
+              p_t2t->substate = RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
+            }
+            break;
+
+          case TAG_TERMINATOR_TLV: /* Last TLV block in the data area. Must be
+                                      no NDEF nessage */
+            if (((tlvtype == TAG_LOCK_CTRL_TLV) &&
+                 (p_t2t->num_lockbytes > 0)) ||
+                ((tlvtype == TAG_MEM_CTRL_TLV) && (p_t2t->num_mem_tlvs > 0))) {
+              /* No more Lock/Memory TLV control tlv in the tag, so stop
+               * searching */
+              found = true;
+            } else {
+              /* NDEF/Lock/Memory/Proprietary TLV cannot exist after Terminator
+               * Tlv */
+              failed = true;
+            }
+            break;
+          default:
+            failed = true;
+        }
+        break;
+
+      case RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN:
+        len = p_data[offset];
+        switch (p_t2t->found_tlv) {
+          case TAG_NDEF_TLV:
+            p_t2t->ndef_header_offset = offset + p_t2t->work_offset;
+            if (len == TAG_LONG_NDEF_LEN_FIELD_BYTE0) {
+              /* The next two bytes constitute length bytes */
+              p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0;
+            } else {
+              /* one byte length field */
+              p_t2t->ndef_msg_len = len;
+              p_t2t->bytes_count = p_t2t->ndef_msg_len;
+              p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
+            }
+            break;
+
+          case TAG_PROPRIETARY_TLV:
+            if (len == T2T_LONG_NDEF_LEN_FIELD_BYTE0) {
+              /* The next two bytes constitute length bytes */
+              p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0;
+            } else {
+              /* one byte length field */
+              p_t2t->prop_msg_len = len;
+              p_t2t->bytes_count = p_t2t->prop_msg_len;
+              p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
+            }
+            break;
+        }
+        offset++;
+        break;
+
+      case RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0:
+        switch (p_t2t->found_tlv) {
+          case TAG_LOCK_CTRL_TLV:
+          case TAG_MEM_CTRL_TLV:
+
+            len = p_data[offset];
+            if (len == TAG_DEFAULT_TLV_LEN) {
+              /* Valid Lock control TLV */
+              p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
+              p_t2t->bytes_count = TAG_DEFAULT_TLV_LEN;
+            } else if (((tlvtype == TAG_LOCK_CTRL_TLV) &&
+                        (p_t2t->num_lockbytes > 0)) ||
+                       ((tlvtype == TAG_MEM_CTRL_TLV) &&
+                        (p_t2t->num_mem_tlvs > 0))) {
+              /* Stop searching for Lock/ Memory control tlv */
+              found = true;
+            } else {
+              failed = true;
+            }
+            break;
+
+          case TAG_NDEF_TLV:
+          case TAG_PROPRIETARY_TLV:
+            /* The first length byte */
+            p_t2t->bytes_count = (uint8_t)p_data[offset];
+            p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1;
+            break;
+        }
+        offset++;
+        break;
+
+      case RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1:
+        /* Prepare NDEF Message length */
+        p_t2t->bytes_count = (p_t2t->bytes_count << 8) + p_data[offset];
+        if (p_t2t->found_tlv == TAG_NDEF_TLV) {
+          p_t2t->ndef_msg_len = p_t2t->bytes_count;
+        } else if (p_t2t->found_tlv == TAG_PROPRIETARY_TLV) {
+          p_t2t->prop_msg_len = p_t2t->bytes_count;
+        }
+        p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
+        offset++;
+        break;
+
+      case RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE:
+        switch (p_t2t->found_tlv) {
+          case TAG_NDEF_TLV:
+            if ((p_t2t->bytes_count == p_t2t->ndef_msg_len) &&
+                (tlvtype == TAG_NDEF_TLV)) {
+              /* The first byte offset after length field */
+              p_t2t->ndef_msg_offset = offset + p_t2t->work_offset;
+            }
+            /* Reduce number of NDEF bytes remaining to pass over NDEF TLV */
+            if (p_t2t->bytes_count > 0) p_t2t->bytes_count--;
+
+            if (tlvtype == TAG_NDEF_TLV) {
+              found = true;
+              p_t2t->ndef_status = T2T_NDEF_DETECTED;
+            } else if (p_t2t->bytes_count == 0) {
+              /* Next byte could be a different TLV */
+              p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
+            }
+            break;
+
+          case TAG_LOCK_CTRL_TLV:
+            p_t2t->bytes_count--;
+            if ((tlvtype == TAG_LOCK_CTRL_TLV) || (tlvtype == TAG_NDEF_TLV)) {
+              if (p_t2t->bytes_count > 2)
+                // avoid causing negative index
+                break;
+              /* Collect Lock TLV */
+              p_t2t->tlv_value[2 - p_t2t->bytes_count] = p_data[offset];
+              if (p_t2t->bytes_count == 0) {
+                /* Lock TLV is collected and buffered in tlv_value, now decode
+                 * it */
+                p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset =
+                    (p_t2t->tlv_value[0] >> 4) & 0x0F;
+                p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset *=
+                    (uint8_t)tags_pow(2, p_t2t->tlv_value[2] & 0x0F);
+                p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset +=
+                    p_t2t->tlv_value[0] & 0x0F;
+                p_t2t->lock_tlv[p_t2t->num_lock_tlvs].bytes_locked_per_bit =
+                    (uint8_t)tags_pow(2, ((p_t2t->tlv_value[2] & 0xF0) >> 4));
+                p_t2t->lock_tlv[p_t2t->num_lock_tlvs].num_bits =
+                    p_t2t->tlv_value[1];
+                count = p_t2t->tlv_value[1] / 8 +
+                        ((p_t2t->tlv_value[1] % 8 != 0) ? 1 : 0);
+
+                /* Extract lockbytes info addressed by this Lock TLV */
+                xx = 0;
+                while (xx < count) {
+                  p_t2t->lockbyte[p_t2t->num_lockbytes].tlv_index =
+                      p_t2t->num_lock_tlvs;
+                  p_t2t->lockbyte[p_t2t->num_lockbytes].byte_index = xx;
+                  p_t2t->lockbyte[p_t2t->num_lockbytes].b_lock_read = false;
+                  xx++;
+                  p_t2t->num_lockbytes++;
+                }
+                p_t2t->num_lock_tlvs++;
+                rw_t2t_update_attributes();
+                /* Next byte could be a different TLV */
+                p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
+              }
+            } else {
+              /* If not looking for lock/ndef tlv, just skip this Lock TLV */
+              if (p_t2t->bytes_count == 0) {
+                p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
+              }
+            }
+            break;
+
+          case TAG_MEM_CTRL_TLV:
+            p_t2t->bytes_count--;
+            if ((tlvtype == TAG_MEM_CTRL_TLV) || (tlvtype == TAG_NDEF_TLV)) {
+              if (p_t2t->bytes_count > 2)
+                // avoid causing negative index
+                break;
+              p_t2t->tlv_value[2 - p_t2t->bytes_count] = p_data[offset];
+              if (p_t2t->bytes_count == 0) {
+                if (p_t2t->num_mem_tlvs >= RW_T2T_MAX_MEM_TLVS) {
+                  RW_TRACE_ERROR0(
+                      "rw_t2t_handle_tlv_detect_rsp - Maximum buffer allocated "
+                      "for Memory tlv has reached");
+                  failed = true;
+                } else {
+                  /* Extract memory control tlv */
+                  p_t2t->mem_tlv[p_t2t->num_mem_tlvs].offset =
+                      (p_t2t->tlv_value[0] >> 4) & 0x0F;
+                  p_t2t->mem_tlv[p_t2t->num_mem_tlvs].offset *=
+                      (uint8_t)tags_pow(2, p_t2t->tlv_value[2] & 0x0F);
+                  p_t2t->mem_tlv[p_t2t->num_mem_tlvs].offset +=
+                      p_t2t->tlv_value[0] & 0x0F;
+                  p_t2t->mem_tlv[p_t2t->num_mem_tlvs].num_bytes =
+                      p_t2t->tlv_value[1];
+                  p_t2t->num_mem_tlvs++;
+                  rw_t2t_update_attributes();
+                  p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
+                }
+              }
+            } else {
+              if (p_t2t->bytes_count == 0) {
+                p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
+              }
+            }
+            break;
+
+          case TAG_PROPRIETARY_TLV:
+            p_t2t->bytes_count--;
+            if (tlvtype == TAG_PROPRIETARY_TLV) {
+              found = true;
+              p_t2t->prop_msg_len = len;
+            } else {
+              if (p_t2t->bytes_count == 0) {
+                p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
+              }
+            }
+            break;
+        }
+        offset++;
+        break;
+    }
+  }
+
+  p_t2t->work_offset += T2T_READ_DATA_LEN;
+
+  event = rw_t2t_info_to_event(p_cmd_rsp_info);
+
+  /* If not found and not failed, read next block and search tlv */
+  if (!found && !failed) {
+    if (p_t2t->work_offset >=
+        (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR)) {
+      if (((tlvtype == TAG_LOCK_CTRL_TLV) && (p_t2t->num_lockbytes > 0)) ||
+          ((tlvtype == TAG_MEM_CTRL_TLV) && (p_t2t->num_mem_tlvs > 0))) {
+        found = true;
+      } else {
+        failed = true;
+      }
+    } else {
+      if (rw_t2t_read((uint16_t)((p_t2t->work_offset / T2T_BLOCK_LEN) +
+                                 T2T_FIRST_DATA_BLOCK)) != NFC_STATUS_OK)
+        failed = true;
+    }
+  }
+
+  if (failed || found) {
+    if (tlvtype == TAG_LOCK_CTRL_TLV) {
+      /* Incase no Lock control tlv is present then look for default dynamic
+       * lock bytes */
+      rw_t2t_extract_default_locks_info();
+
+      /* Send command to read the dynamic lock bytes */
+      status = rw_t2t_read_locks();
+
+      if (status != NFC_STATUS_CONTINUE) {
+        /* If unable to read a lock/all locks read, notify upper layer */
+        rw_t2t_update_lock_attributes();
+        rw_t2t_ntf_tlv_detect_complete(status);
+      }
+    } else if (tlvtype == TAG_NDEF_TLV) {
+      rw_t2t_extract_default_locks_info();
+
+      if (failed) {
+        rw_t2t_ntf_tlv_detect_complete(NFC_STATUS_FAILED);
+      } else {
+        /* NDEF present,Send command to read the dynamic lock bytes */
+        status = rw_t2t_read_locks();
+        if (status != NFC_STATUS_CONTINUE) {
+          /* If unable to read a lock/all locks read, notify upper layer */
+          rw_t2t_update_lock_attributes();
+          rw_t2t_ntf_tlv_detect_complete(status);
+        }
+      }
+    } else {
+      /* Notify Memory/ Proprietary tlv detect result */
+      status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK;
+      rw_t2t_ntf_tlv_detect_complete(status);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_read_locks
+**
+** Description      This function will send command to read next unread locks
+**
+** Returns          NFC_STATUS_OK, if all locks are read successfully
+**                  NFC_STATUS_FAILED, if reading locks failed
+**                  NFC_STATUS_CONTINUE, if reading locks is in progress
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_read_locks(void) {
+  uint8_t num_locks = 0;
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  tNFC_STATUS status = NFC_STATUS_CONTINUE;
+  uint16_t offset;
+  uint16_t block;
+
+  if ((p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] != T2T_CC3_RWA_RW)
+#if (NXP_EXTNS == TRUE)
+      || ((p_t2t->tag_hdr[0] == TAG_MIFARE_MID) &&
+          (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] == T2T_CC2_TMS_MULC)) ||
+      ((p_t2t->tag_hdr[0] == TAG_MIFARE_MID) &&
+       (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] == T2T_CC2_TMS_MUL))
+#endif
+      ||
+      (p_t2t->skip_dyn_locks)) {
+    /* Skip reading dynamic lock bytes if CC is set as Read only or layer above
+     * instructs to skip */
+    while (num_locks < p_t2t->num_lockbytes) {
+      p_t2t->lockbyte[num_locks].lock_byte = 0x00;
+      p_t2t->lockbyte[num_locks].b_lock_read = true;
+      num_locks++;
+    }
+  }
+
+  while ((num_locks < p_t2t->num_lockbytes)
+#if (NXP_EXTNS == TRUE)
+         && (num_locks < RW_T2T_MAX_LOCK_BYTES)
+#endif
+             ) {
+    if (p_t2t->lockbyte[num_locks].b_lock_read == false) {
+      /* Send Read command to read the first un read locks */
+      offset = p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].offset +
+               p_t2t->lockbyte[num_locks].byte_index;
+
+      /* Read 16 bytes where this lock byte is present */
+      block = (uint16_t)(offset / T2T_BLOCK_LEN);
+      block -= block % T2T_READ_BLOCKS;
+
+      p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_LOCKS;
+      /* send READ8 command */
+      status = rw_t2t_read((uint16_t)block);
+      if (status == NFC_STATUS_OK) {
+        /* Reading Locks */
+        status = NFC_STATUS_CONTINUE;
+      } else {
+        status = NFC_STATUS_FAILED;
+      }
+      break;
+    }
+    num_locks++;
+  }
+  if (num_locks == p_t2t->num_lockbytes) {
+    /* All locks are read */
+    status = NFC_STATUS_OK;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_extract_default_locks_info
+**
+** Description      This function will prepare lockbytes information for default
+**                  locks present in the tag in the absence of lock control tlv.
+**                  Adding a virtual lock control tlv for these lock bytes for
+**                  easier manipulation.
+**
+** Returns          None
+**
+*******************************************************************************/
+void rw_t2t_extract_default_locks_info(void) {
+  uint8_t num_dynamic_lock_bits;
+  uint8_t num_dynamic_lock_bytes;
+  uint8_t xx;
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  const tT2T_INIT_TAG* p_ret;
+  uint8_t bytes_locked_per_lock_bit = T2T_DEFAULT_LOCK_BLPB;
+
+  if ((p_t2t->num_lock_tlvs == 0) &&
+      (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] > T2T_CC2_TMS_STATIC)) {
+    /* No Lock control tlv is detected. Indicates lock bytes are present in
+     * default location */
+    /* Add a virtual Lock tlv to map this default lock location */
+    p_ret = t2t_tag_init_data(p_t2t->tag_hdr[0], false, 0);
+    if (p_ret != NULL) bytes_locked_per_lock_bit = p_ret->default_lock_blpb;
+
+    num_dynamic_lock_bits =
+        ((p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) -
+         (T2T_STATIC_SIZE - T2T_HEADER_SIZE)) /
+        bytes_locked_per_lock_bit;
+    num_dynamic_lock_bytes = num_dynamic_lock_bits / 8;
+    num_dynamic_lock_bytes += (num_dynamic_lock_bits % 8 == 0) ? 0 : 1;
+
+    p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset =
+        (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) +
+        (T2T_FIRST_DATA_BLOCK * T2T_BLOCK_LEN);
+    p_t2t->lock_tlv[p_t2t->num_lock_tlvs].bytes_locked_per_bit =
+        bytes_locked_per_lock_bit;
+    p_t2t->lock_tlv[p_t2t->num_lock_tlvs].num_bits = num_dynamic_lock_bits;
+
+    /* Based on tag data size the number of locks present in the default
+     * location changes */
+    for (xx = 0; xx < num_dynamic_lock_bytes; xx++) {
+      p_t2t->lockbyte[xx].tlv_index = p_t2t->num_lock_tlvs;
+      p_t2t->lockbyte[xx].byte_index = xx;
+      p_t2t->lockbyte[xx].b_lock_read = false;
+    }
+    p_t2t->num_lockbytes = num_dynamic_lock_bytes;
+    p_t2t->num_lock_tlvs = 1;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_read_ndef_last_block
+**
+** Description      This function will locate and read the last ndef block.
+**                  The last ndef block refers to the tag block where last byte
+**                  of new ndef message will reside. Also this function will
+**                  locate the offset of Terminator TLV based on the size of
+**                  new NDEF Message
+**
+** Returns          NCI_STATUS_OK, if able to locate last ndef block & read
+**                  started. Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_read_ndef_last_block(void) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  uint16_t header_len = (p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN)
+                            ? T2T_LONG_NDEF_LEN_FIELD_LEN
+                            : T2T_SHORT_NDEF_LEN_FIELD_LEN;
+  uint16_t num_ndef_bytes;
+  uint16_t total_ndef_bytes;
+  uint16_t last_ndef_byte_offset;
+  uint16_t terminator_tlv_byte_index;
+  tNFC_STATUS status;
+  uint16_t block;
+
+  total_ndef_bytes = header_len + p_t2t->new_ndef_msg_len;
+  num_ndef_bytes = 0;
+  last_ndef_byte_offset = p_t2t->ndef_header_offset;
+
+  /* Locate NDEF final block based on the size of new NDEF Message */
+  while (num_ndef_bytes < total_ndef_bytes) {
+    if (rw_t2t_is_lock_res_byte((uint16_t)(last_ndef_byte_offset)) == false)
+      num_ndef_bytes++;
+
+    last_ndef_byte_offset++;
+  }
+  p_t2t->ndef_last_block_num =
+      (uint16_t)((last_ndef_byte_offset - 1) / T2T_BLOCK_SIZE);
+  block = p_t2t->ndef_last_block_num;
+
+  p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK;
+  /* Read NDEF last block before updating */
+  status = rw_t2t_read(block);
+  if (status == NFC_STATUS_OK) {
+    if ((p_t2t->new_ndef_msg_len + 1) <= p_t2t->max_ndef_msg_len) {
+      /* Locate Terminator TLV Block */
+      total_ndef_bytes++;
+      terminator_tlv_byte_index = last_ndef_byte_offset;
+
+      while (num_ndef_bytes < total_ndef_bytes) {
+        if (rw_t2t_is_lock_res_byte((uint16_t)terminator_tlv_byte_index) ==
+            false)
+          num_ndef_bytes++;
+
+        terminator_tlv_byte_index++;
+      }
+
+      p_t2t->terminator_byte_index = terminator_tlv_byte_index - 1;
+    } else {
+      /* No space for Terminator TLV */
+      p_t2t->terminator_byte_index = 0x00;
+    }
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_read_terminator_tlv_block
+**
+** Description      This function will read the block where terminator tlv will
+**                  be added later
+**
+** Returns          NCI_STATUS_OK, if read was started. Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_read_terminator_tlv_block(void) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  tNFC_STATUS status;
+  uint16_t block;
+
+  /* Send read command to read base block (Block % 4==0) where this block is
+   * also read as part of 16 bytes */
+  block = p_t2t->terminator_byte_index / T2T_BLOCK_SIZE;
+  block -= block % T2T_READ_BLOCKS;
+
+  p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK;
+  /* Read the block where Terminator TLV may be added later during NDEF Write
+   * operation */
+  status = rw_t2t_read(block);
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_read_ndef_next_block
+**
+** Description      This function will read the tag block passed as argument
+**
+** Returns          NCI_STATUS_OK, if read was started. Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_read_ndef_next_block(uint16_t block) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  tNFC_STATUS status;
+
+  /* Send read command to read base block (Block % 4==0) where this block is
+   * also read as part of 16 bytes */
+  block -= block % T2T_READ_BLOCKS;
+
+  p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK;
+  /* Read the block */
+  status = rw_t2t_read(block);
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_is_read_before_write_block
+**
+** Description      This function will check if the block has to be read before
+**                  writting to avoid over writting in to lock/reserved bytes
+**                  present in the block.
+**                  If no bytes in the block can be overwritten it moves in to
+**                  next block and check. Finally it finds a block where part of
+**                  ndef bytes can exist and check if the whole block can be
+**                  updated or only part of block can be modified.
+**
+** Returns          true, if the block returned should be read before writting
+**                  false, if the block need not be read as it was already
+**                         read or during NDEF write we may completely overwrite
+**                         the block and there is no reserved or locked bytes in
+**                         that block
+**
+*******************************************************************************/
+static bool rw_t2t_is_read_before_write_block(uint16_t block,
+                                              uint16_t* p_block_to_read) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  uint8_t* p_cc = &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE];
+  uint8_t count;
+  uint8_t index;
+  uint16_t tag_size = p_cc[2] * 2 + T2T_FIRST_DATA_BLOCK;
+  bool read_before_write = true;
+
+  if (block == p_t2t->ndef_header_offset / T2T_BLOCK_SIZE) {
+    /* First NDEF block is already read */
+    read_before_write = false;
+    memcpy(p_t2t->ndef_read_block, p_t2t->ndef_first_block, T2T_BLOCK_SIZE);
+  } else if (block == p_t2t->ndef_last_block_num) {
+    /* Last NDEF block is already read */
+    read_before_write = false;
+    memcpy(p_t2t->ndef_read_block, p_t2t->ndef_last_block, T2T_BLOCK_SIZE);
+  } else if (block == p_t2t->terminator_byte_index / T2T_BLOCK_SIZE) {
+    /* Terminator tlv block is already read */
+    read_before_write = false;
+    memcpy(p_t2t->ndef_read_block, p_t2t->terminator_tlv_block, T2T_BLOCK_SIZE);
+  } else {
+    count = 0;
+    while (block < tag_size) {
+      index = 0;
+
+      while (index < T2T_BLOCK_SIZE) {
+        /* check if it is a reserved or locked byte */
+        if (rw_t2t_is_lock_res_byte(
+                (uint16_t)((block * T2T_BLOCK_SIZE) + index)) == false) {
+          count++;
+        }
+        index++;
+      }
+      if (count == T2T_BLOCK_SIZE) {
+        /* All the bytes in the block are free to NDEF write  */
+        read_before_write = false;
+        break;
+      } else if (count == 0) {
+        /* The complete block is not free for NDEF write  */
+        index = 0;
+        block++;
+      } else {
+        /* The block has reseved byte (s) or locked byte (s) or both */
+        read_before_write = true;
+        break;
+      }
+    }
+  }
+  /* Return the block to read next before NDEF write */
+  *p_block_to_read = block;
+  return read_before_write;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_write_ndef_first_block
+**
+** Description      This function will write the first NDEF block with Length
+**                  field reset to zero.
+**                  Also after writting NDEF this function may be called to
+**                  update new NDEF length
+**
+** Returns          NCI_STATUS_OK, if write was started.
+**                  Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_write_ndef_first_block(uint16_t msg_len, bool b_update_len) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  uint8_t new_lengthfield_len;
+  uint8_t write_block[4];
+  uint8_t block;
+  uint8_t* p_cc = &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE];
+  uint16_t total_blocks = p_cc[2] * 2 + T2T_FIRST_DATA_BLOCK;
+  tNFC_STATUS status;
+  uint8_t length_field[3];
+  uint8_t index;
+
+  p_t2t->work_offset = 0;
+  new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN
+                            ? T2T_LONG_NDEF_LEN_FIELD_LEN
+                            : T2T_SHORT_NDEF_LEN_FIELD_LEN;
+  if (new_lengthfield_len == 3) {
+    /* New NDEF is Long NDEF */
+    if (msg_len == 0) {
+      /* Clear NDEF length field */
+      length_field[0] = 0x00;
+      length_field[1] = 0x00;
+      length_field[2] = 0x00;
+    } else {
+      /* Update NDEF length field with new NDEF Msg len */
+      length_field[0] = T2T_LONG_NDEF_LEN_FIELD_BYTE0;
+      length_field[1] = (uint8_t)(msg_len >> 8);
+      length_field[2] = (uint8_t)(msg_len);
+    }
+  } else {
+    /* New NDEF is Short NDEF */
+    length_field[0] = (uint8_t)(msg_len);
+  }
+
+  /* updating ndef_first_block with new ndef message */
+  memcpy(write_block, p_t2t->ndef_first_block, T2T_BLOCK_SIZE);
+
+  index = p_t2t->ndef_header_offset % T2T_BLOCK_SIZE;
+  block = (uint8_t)(p_t2t->ndef_header_offset / T2T_BLOCK_SIZE);
+
+  while (p_t2t->work_offset == 0 && block < total_blocks) {
+    /* update length field */
+    while (index < T2T_BLOCK_SIZE &&
+           p_t2t->work_offset < p_t2t->new_ndef_msg_len) {
+      if (rw_t2t_is_lock_res_byte(
+              (uint16_t)((block * T2T_BLOCK_SIZE) + index)) == false) {
+        write_block[index] = length_field[p_t2t->work_offset];
+        p_t2t->work_offset++;
+      }
+      index++;
+      if (p_t2t->work_offset == new_lengthfield_len) {
+        break;
+      }
+    }
+    /* If more space in this block then add ndef message */
+    while (index < T2T_BLOCK_SIZE &&
+           p_t2t->work_offset <
+               (p_t2t->new_ndef_msg_len + new_lengthfield_len)) {
+      if (rw_t2t_is_lock_res_byte(
+              (uint16_t)((block * T2T_BLOCK_SIZE) + index)) == false) {
+        write_block[index] =
+            p_t2t->p_new_ndef_buffer[p_t2t->work_offset - new_lengthfield_len];
+        p_t2t->work_offset++;
+      }
+      index++;
+    }
+    if (p_t2t->work_offset == 0) {
+      /* If no bytes are written move to next block */
+      index = 0;
+      block++;
+      if (block == p_t2t->ndef_last_block_num) {
+        memcpy(write_block, p_t2t->ndef_last_block, T2T_BLOCK_SIZE);
+      }
+    }
+  }
+  if (p_t2t->work_offset == 0) {
+    status = NFC_STATUS_FAILED;
+  } else {
+    rw_t2t_update_cb(block, write_block, b_update_len);
+    /* Update the identified block with newly prepared data */
+    status = rw_t2t_write(block, write_block);
+    if (status == NFC_STATUS_OK) {
+      p_t2t->b_read_data = false;
+    }
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_write_ndef_next_block
+**
+** Description      This function can be called to write an NDEF message block
+**
+** Returns          NCI_STATUS_OK, if write was started.
+**                  Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_write_ndef_next_block(uint16_t block, uint16_t msg_len,
+                                         bool b_update_len) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  uint8_t new_lengthfield_len;
+  uint8_t write_block[4];
+  uint8_t* p_cc = &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE];
+  uint16_t total_blocks = p_cc[2] * 2 + T2T_FIRST_DATA_BLOCK;
+  uint16_t initial_offset;
+  uint8_t length_field[3];
+  uint8_t index;
+  tNFC_STATUS status;
+
+  /* Write NDEF Message */
+  new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN
+                            ? T2T_LONG_NDEF_LEN_FIELD_LEN
+                            : T2T_SHORT_NDEF_LEN_FIELD_LEN;
+
+  index = 0;
+
+  memcpy(write_block, p_t2t->ndef_read_block, T2T_BLOCK_SIZE);
+
+  if (p_t2t->work_offset >= new_lengthfield_len) {
+    /* Length field is updated, write ndef message field */
+    initial_offset = p_t2t->work_offset;
+    while (p_t2t->work_offset == initial_offset && block < total_blocks) {
+      while (index < T2T_BLOCK_SIZE &&
+             p_t2t->work_offset <
+                 (p_t2t->new_ndef_msg_len + new_lengthfield_len)) {
+        if (rw_t2t_is_lock_res_byte(
+                (uint16_t)((block * T2T_BLOCK_SIZE) + index)) == false) {
+          write_block[index] =
+              p_t2t
+                  ->p_new_ndef_buffer[p_t2t->work_offset - new_lengthfield_len];
+          p_t2t->work_offset++;
+        }
+        index++;
+      }
+      if (p_t2t->work_offset == initial_offset) {
+        index = 0;
+        block++;
+      }
+    }
+  } else {
+    /* Complete writting Length field and then write ndef message */
+    new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN
+                              ? T2T_LONG_NDEF_LEN_FIELD_LEN
+                              : T2T_SHORT_NDEF_LEN_FIELD_LEN;
+    if (new_lengthfield_len == 3) {
+      /* New NDEF is Long NDEF */
+      if (msg_len == 0) {
+        length_field[0] = 0x00;
+        length_field[1] = 0x00;
+        length_field[2] = 0x00;
+      } else {
+        length_field[0] = T2T_LONG_NDEF_LEN_FIELD_BYTE0;
+        length_field[1] = (uint8_t)(msg_len >> 8);
+        length_field[2] = (uint8_t)(msg_len);
+      }
+    } else {
+      /* New NDEF is short NDEF */
+      length_field[0] = (uint8_t)(msg_len);
+    }
+    initial_offset = p_t2t->work_offset;
+    while (p_t2t->work_offset == initial_offset && block < total_blocks) {
+      /* Update length field */
+      while (index < T2T_BLOCK_SIZE &&
+             p_t2t->work_offset < p_t2t->new_ndef_msg_len) {
+        if (rw_t2t_is_lock_res_byte(
+                (uint16_t)((block * T2T_BLOCK_SIZE) + index)) == false) {
+          write_block[index] = length_field[p_t2t->work_offset];
+          p_t2t->work_offset++;
+        }
+        index++;
+        if (p_t2t->work_offset == new_lengthfield_len) {
+          break;
+        }
+      }
+      /* Update ndef message field */
+      while (index < T2T_BLOCK_SIZE &&
+             p_t2t->work_offset <
+                 (p_t2t->new_ndef_msg_len + new_lengthfield_len)) {
+        if (rw_t2t_is_lock_res_byte(
+                (uint16_t)((block * T2T_BLOCK_SIZE) + index)) == false) {
+          write_block[index] =
+              p_t2t
+                  ->p_new_ndef_buffer[p_t2t->work_offset - new_lengthfield_len];
+          p_t2t->work_offset++;
+        }
+        index++;
+      }
+      if (p_t2t->work_offset == initial_offset) {
+        index = 0;
+        block++;
+      }
+    }
+  }
+  if (p_t2t->work_offset == initial_offset) {
+    status = NFC_STATUS_FAILED;
+  } else {
+    rw_t2t_update_cb(block, write_block, b_update_len);
+    /* Write the NDEF Block */
+    status = rw_t2t_write(block, write_block);
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_update_cb
+**
+** Description      This function can be called to write an NDEF message block
+**
+** Returns          NCI_STATUS_OK, if write was started.
+**                  Otherwise, error status.
+**
+*******************************************************************************/
+static void rw_t2t_update_cb(uint16_t block, uint8_t* p_write_block,
+                             bool b_update_len) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  uint8_t new_lengthfield_len;
+
+  /* Write NDEF Message */
+  new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN
+                            ? T2T_LONG_NDEF_LEN_FIELD_LEN
+                            : T2T_SHORT_NDEF_LEN_FIELD_LEN;
+
+  if (block == p_t2t->ndef_header_offset / T2T_BLOCK_SIZE) {
+    /* Update ndef first block if the 'block' points to ndef first block */
+    memcpy(p_t2t->ndef_first_block, p_write_block, T2T_BLOCK_SIZE);
+  }
+  if (p_t2t->terminator_byte_index / T2T_BLOCK_SIZE == block) {
+    /* Update terminator block if the 'block' points to terminator tlv block */
+    memcpy(p_t2t->terminator_tlv_block, p_write_block, T2T_BLOCK_LEN);
+  }
+  if (b_update_len == false) {
+    if (block == p_t2t->ndef_last_block_num) {
+      p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK;
+      p_t2t->work_offset = 0;
+      /* Update ndef final block if the 'block' points to ndef final block */
+      memcpy(p_t2t->ndef_last_block, p_write_block, T2T_BLOCK_SIZE);
+    } else {
+      p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK;
+    }
+  } else {
+    if (block == p_t2t->ndef_last_block_num) {
+      /* Update the backup of Ndef final block TLV block */
+      memcpy(p_t2t->ndef_last_block, p_write_block, T2T_BLOCK_SIZE);
+    }
+
+    if (p_t2t->work_offset >= new_lengthfield_len) {
+      if (p_t2t->terminator_byte_index != 0) {
+        /* Add Terminator TLV as part of NDEF Write operation */
+        p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK;
+      } else {
+        /* Skip adding Terminator TLV */
+        p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT;
+      }
+    } else {
+      /* Part of NDEF Message Len should be added in the next block */
+      p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK;
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_get_ndef_flags
+**
+** Description      Prepare NDEF Flags
+**
+** Returns          NDEF Flag value
+**
+*******************************************************************************/
+static uint8_t rw_t2t_get_ndef_flags(void) {
+  uint8_t flags = 0;
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  const tT2T_INIT_TAG* p_ret;
+
+  flags |= RW_NDEF_FL_SUPPORTED;
+
+  if ((p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] == T2T_CC2_TMS_STATIC) ||
+      (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] == 0))
+    flags |= RW_NDEF_FL_FORMATABLE;
+
+  if ((p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] & T2T_CC3_RWA_RO) == T2T_CC3_RWA_RO)
+    flags |= RW_NDEF_FL_READ_ONLY;
+
+  if (((p_ret = t2t_tag_init_data(p_t2t->tag_hdr[0], false, 0)) != NULL) &&
+      (p_ret->b_otp)) {
+    /* Set otp flag */
+    flags |= RW_NDEF_FL_OTP;
+
+    /* Set Read only flag if otp tag already has NDEF Message */
+    if (p_t2t->ndef_msg_len) flags |= RW_NDEF_FL_READ_ONLY;
+  }
+  return flags;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_get_ndef_max_size
+**
+** Description      Calculate maximum size of NDEF message that can be written
+**                  on to the tag
+**
+** Returns          Maximum size of NDEF Message
+**
+*******************************************************************************/
+static uint16_t rw_t2t_get_ndef_max_size(void) {
+  uint16_t offset;
+  uint8_t xx;
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  uint16_t tag_size = (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) +
+                      (T2T_FIRST_DATA_BLOCK * T2T_BLOCK_LEN) +
+                      p_t2t->num_lockbytes;
+
+  for (xx = 0; xx < p_t2t->num_mem_tlvs; xx++)
+    tag_size += p_t2t->mem_tlv[xx].num_bytes;
+
+  offset = p_t2t->ndef_msg_offset;
+  p_t2t->max_ndef_msg_len = 0;
+
+  if ((tag_size < T2T_STATIC_SIZE) ||
+      (tag_size > (T2T_SECTOR_SIZE * T2T_MAX_SECTOR)) ||
+      ((p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != T2T_CC0_NMN) &&
+       (p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != 0))) {
+    /* Tag not formated, assume static tag */
+    p_t2t->max_ndef_msg_len = T2T_STATIC_SIZE - T2T_HEADER_SIZE -
+                              T2T_TLV_TYPE_LEN - T2T_SHORT_NDEF_LEN_FIELD_LEN;
+    return p_t2t->max_ndef_msg_len;
+  }
+
+  /* Starting from NDEF Message offset find the first locked data byte */
+  while (offset < tag_size) {
+    if (rw_t2t_is_lock_res_byte((uint16_t)offset) == false) {
+      if (rw_t2t_is_read_only_byte((uint16_t)offset) == true) break;
+      p_t2t->max_ndef_msg_len++;
+    }
+    offset++;
+  }
+  /* NDEF Length field length changes based on NDEF size */
+  if ((p_t2t->max_ndef_msg_len >= T2T_LONG_NDEF_LEN_FIELD_BYTE0) &&
+      ((p_t2t->ndef_msg_offset - p_t2t->ndef_header_offset) ==
+       T2T_SHORT_NDEF_LEN_FIELD_LEN)) {
+    p_t2t->max_ndef_msg_len -=
+        (p_t2t->max_ndef_msg_len == T2T_LONG_NDEF_LEN_FIELD_BYTE0)
+            ? 1
+            : (T2T_LONG_NDEF_LEN_FIELD_LEN - T2T_SHORT_NDEF_LEN_FIELD_LEN);
+  }
+  return p_t2t->max_ndef_msg_len;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_add_terminator_tlv
+**
+** Description      This function will add terminator TLV after NDEF Message
+**
+** Returns          NCI_STATUS_OK, if write was started.
+**                  Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_add_terminator_tlv(void) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  tNFC_STATUS status;
+  uint16_t block;
+
+  /* Add Terminator TLV after NDEF Message */
+  p_t2t->terminator_tlv_block[p_t2t->terminator_byte_index % T2T_BLOCK_LEN] =
+      TAG_TERMINATOR_TLV;
+  p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT;
+
+  block = p_t2t->terminator_byte_index / T2T_BLOCK_LEN;
+  status = rw_t2t_write(block, p_t2t->terminator_tlv_block);
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_handle_ndef_read_rsp
+**
+** Description      This function handles reading an NDEF message.
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t2t_handle_ndef_read_rsp(uint8_t* p_data) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  tRW_READ_DATA evt_data;
+  uint16_t len;
+  uint16_t offset;
+  bool failed = false;
+  bool done = false;
+
+  /* On the first read, adjust for any partial block offset */
+  offset = 0;
+  len = T2T_READ_DATA_LEN;
+
+  if (p_t2t->work_offset == 0) {
+    /* The Ndef Message offset may be present in the read 16 bytes */
+    offset = (p_t2t->ndef_msg_offset - (p_t2t->block_read * T2T_BLOCK_SIZE));
+  }
+
+  /* Skip all reserved and lock bytes */
+  while ((offset < len) && (p_t2t->work_offset < p_t2t->ndef_msg_len))
+
+  {
+    if (rw_t2t_is_lock_res_byte(
+            (uint16_t)(offset + p_t2t->block_read * T2T_BLOCK_LEN)) == false) {
+      /* Collect the NDEF Message */
+      p_t2t->p_ndef_buffer[p_t2t->work_offset] = p_data[offset];
+      p_t2t->work_offset++;
+    }
+    offset++;
+  }
+
+  if (p_t2t->work_offset >= p_t2t->ndef_msg_len) {
+    done = true;
+    p_t2t->ndef_status = T2T_NDEF_READ;
+  } else {
+    /* Read next 4 blocks */
+    if (rw_t2t_read((uint16_t)(p_t2t->block_read + T2T_READ_BLOCKS)) !=
+        NFC_STATUS_OK)
+      failed = true;
+  }
+
+  if (failed || done) {
+    evt_data.status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK;
+    evt_data.p_data = NULL;
+    rw_t2t_handle_op_complete();
+    (*rw_cb.p_cback)(RW_T2T_NDEF_READ_EVT, (void*)&evt_data);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_handle_ndef_write_rsp
+**
+** Description      Handle response received to reading (or part of) NDEF
+**                  message.
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t2t_handle_ndef_write_rsp(uint8_t* p_data) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  tRW_READ_DATA evt_data;
+  bool failed = false;
+  bool done = false;
+  uint16_t block;
+  uint8_t offset;
+
+  switch (p_t2t->substate) {
+    case RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK:
+
+      /* Backup the read NDEF first block */
+      memcpy(p_t2t->ndef_first_block, p_data, T2T_BLOCK_LEN);
+      /* Read ndef final block */
+      if (rw_t2t_read_ndef_last_block() != NFC_STATUS_OK) failed = true;
+      break;
+
+    case RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK:
+
+      offset = (uint8_t)(p_t2t->ndef_last_block_num - p_t2t->block_read) *
+               T2T_BLOCK_SIZE;
+      /* Backup the read NDEF final block */
+      memcpy(p_t2t->ndef_last_block, &p_data[offset], T2T_BLOCK_LEN);
+      if ((p_t2t->terminator_byte_index / T2T_BLOCK_SIZE) ==
+          p_t2t->ndef_last_block_num) {
+        /* If Terminator TLV will reside on the NDEF Final block */
+        memcpy(p_t2t->terminator_tlv_block, p_t2t->ndef_last_block,
+               T2T_BLOCK_LEN);
+        if (rw_t2t_write_ndef_first_block(0x0000, false) != NFC_STATUS_OK)
+          failed = true;
+      } else if (p_t2t->terminator_byte_index != 0) {
+        /* If there is space for Terminator TLV and if it will reside outside
+         * NDEF Final block */
+        if (rw_t2t_read_terminator_tlv_block() != NFC_STATUS_OK) failed = true;
+      } else {
+        if (rw_t2t_write_ndef_first_block(0x0000, false) != NFC_STATUS_OK)
+          failed = true;
+      }
+      break;
+
+    case RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK:
+
+      offset = (uint8_t)(((p_t2t->terminator_byte_index / T2T_BLOCK_SIZE) -
+                          p_t2t->block_read) *
+                         T2T_BLOCK_SIZE);
+      /* Backup the read Terminator TLV block */
+      memcpy(p_t2t->terminator_tlv_block, &p_data[offset], T2T_BLOCK_LEN);
+
+      /* Write the first block for new NDEF Message */
+      if (rw_t2t_write_ndef_first_block(0x0000, false) != NFC_STATUS_OK)
+        failed = true;
+      break;
+
+    case RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK:
+
+      offset = (uint8_t)(p_t2t->ndef_read_block_num - p_t2t->block_read) *
+               T2T_BLOCK_SIZE;
+      /* Backup read block */
+      memcpy(p_t2t->ndef_read_block, &p_data[offset], T2T_BLOCK_LEN);
+
+      /* Update the block with new NDEF Message */
+      if (rw_t2t_write_ndef_next_block(p_t2t->ndef_read_block_num, 0x0000,
+                                       false) != NFC_STATUS_OK)
+        failed = true;
+      break;
+
+    case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK:
+    case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK:
+      if (rw_t2t_is_read_before_write_block(
+              (uint16_t)(p_t2t->block_written + 1), &block) == true) {
+        p_t2t->ndef_read_block_num = block;
+        /* If only part of the block is going to be updated read the block to
+           retain previous data for
+           unchanged part of the block */
+        if (rw_t2t_read_ndef_next_block(block) != NFC_STATUS_OK) failed = true;
+      } else {
+        if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK) {
+          /* Directly write the block with new NDEF contents as whole block is
+           * going to be updated */
+          if (rw_t2t_write_ndef_next_block(block, p_t2t->new_ndef_msg_len,
+                                           true) != NFC_STATUS_OK)
+            failed = true;
+        } else {
+          /* Directly write the block with new NDEF contents as whole block is
+           * going to be updated */
+          if (rw_t2t_write_ndef_next_block(block, 0x0000, false) !=
+              NFC_STATUS_OK)
+            failed = true;
+        }
+      }
+      break;
+
+    case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK:
+      /* Write the next block for new NDEF Message */
+      p_t2t->ndef_write_block = p_t2t->ndef_header_offset / T2T_BLOCK_SIZE;
+      if (rw_t2t_is_read_before_write_block((uint16_t)(p_t2t->ndef_write_block),
+                                            &block) == true) {
+        /* If only part of the block is going to be updated read the block to
+           retain previous data for
+           part of the block thats not going to be changed */
+        p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK;
+        if (rw_t2t_read(block) != NFC_STATUS_OK) failed = true;
+
+      } else {
+        /* Update NDEF Message Length in the Tag */
+        if (rw_t2t_write_ndef_first_block(p_t2t->new_ndef_msg_len, true) !=
+            NFC_STATUS_OK)
+          failed = true;
+      }
+      break;
+
+    case RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK:
+      /* Backup read block */
+      memcpy(p_t2t->ndef_read_block, p_data, T2T_BLOCK_LEN);
+
+      /* Update the block with new NDEF Message */
+      if (rw_t2t_write_ndef_next_block(p_t2t->block_read,
+                                       p_t2t->new_ndef_msg_len,
+                                       true) == NFC_STATUS_OK)
+        p_t2t->ndef_write_block = p_t2t->block_read + 1;
+      else
+        failed = true;
+
+      break;
+
+    case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK:
+      if (rw_t2t_add_terminator_tlv() != NFC_STATUS_OK) failed = true;
+      break;
+
+    case RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT:
+      done = true;
+      break;
+
+    default:
+      break;
+  }
+
+  if (failed || done) {
+    evt_data.p_data = NULL;
+    /* NDEF WRITE Operation is done, inform up the stack */
+    evt_data.status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK;
+    if (done) {
+      if ((p_t2t->ndef_msg_len >= 0x00FF) &&
+          (p_t2t->new_ndef_msg_len < 0x00FF)) {
+        p_t2t->ndef_msg_offset -= 2;
+      } else if ((p_t2t->new_ndef_msg_len >= 0x00FF) &&
+                 (p_t2t->ndef_msg_len < 0x00FF)) {
+        p_t2t->ndef_msg_offset += 2;
+      }
+      p_t2t->ndef_msg_len = p_t2t->new_ndef_msg_len;
+    }
+    rw_t2t_handle_op_complete();
+    (*rw_cb.p_cback)(RW_T2T_NDEF_WRITE_EVT, (void*)&evt_data);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_get_tag_size
+**
+** Description      This function calculates tag data area size from data read
+**                  from block with version number
+**
+** Returns          TMS of the tag
+**
+*******************************************************************************/
+static uint8_t rw_t2t_get_tag_size(uint8_t* p_data) {
+  uint16_t LchunkSize = 0;
+  uint16_t Num_LChuncks = 0;
+  uint16_t tms = 0;
+
+  LchunkSize = (uint16_t)p_data[2] << 8 | p_data[3];
+  Num_LChuncks = (uint16_t)p_data[4] << 8 | p_data[5];
+
+  tms = (uint16_t)(LchunkSize * Num_LChuncks);
+
+  tms += (T2T_STATIC_SIZE - T2T_HEADER_SIZE);
+
+  tms /= 0x08;
+
+  return (uint8_t)tms;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_handle_config_tag_readonly
+**
+** Description      This function handles configure type 2 tag as read only
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t2t_handle_config_tag_readonly(uint8_t* p_data) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  bool b_notify = false;
+  uint8_t write_block[T2T_BLOCK_SIZE];
+  tRW_DATA evt;
+  bool b_pending = false;
+  uint8_t read_lock = 0;
+  uint8_t num_locks = 0;
+  uint16_t offset;
+
+  switch (p_t2t->substate) {
+    case RW_T2T_SUBSTATE_WAIT_READ_CC:
+
+      /* First soft lock the tag */
+      rw_t2t_soft_lock_tag();
+
+      break;
+
+    case RW_T2T_SUBSTATE_WAIT_SET_CC_RO:
+
+      /* Successfully soft locked! Update Tag header for future reference */
+      p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] = T2T_CC3_RWA_RO;
+      if (!p_t2t->b_hard_lock) {
+        /* Tag configuration complete */
+        status = NFC_STATUS_OK;
+        b_notify = true;
+        break;
+      }
+
+    /* Coverity: [false-POSITIVE error] intended fall through */
+    /* Missing break statement between cases in switch statement */
+    /* fall through */
+    case RW_T2T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS:
+
+      num_locks = 0;
+
+      while (num_locks < p_t2t->num_lockbytes) {
+        if (p_t2t->lockbyte[num_locks].lock_status ==
+            RW_T2T_LOCK_UPDATE_INITIATED) {
+          /* Update control block as one or more dynamic lock byte (s) are set
+           */
+          p_t2t->lockbyte[num_locks].lock_status = RW_T2T_LOCK_UPDATED;
+        }
+        if (!b_pending &&
+            p_t2t->lockbyte[num_locks].lock_status == RW_T2T_LOCK_NOT_UPDATED) {
+          /* One or more dynamic lock bits are not set */
+          b_pending = true;
+          read_lock = num_locks;
+        }
+        num_locks++;
+      }
+
+      if (b_pending) {
+        /* Read the block where dynamic lock bits are present to avoid writing
+         * to NDEF bytes in the same block */
+        offset = p_t2t->lock_tlv[p_t2t->lockbyte[read_lock].tlv_index].offset +
+                 p_t2t->lockbyte[read_lock].byte_index;
+        p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_DYN_LOCK_BYTE_BLOCK;
+        status = rw_t2t_read((uint16_t)(offset / T2T_BLOCK_LEN));
+      } else {
+        /* Now set Static lock bits as no more dynamic lock bits to set */
+
+        /* Copy the internal bytes */
+        memcpy(write_block,
+               &p_t2t->tag_hdr[T2T_STATIC_LOCK0 - T2T_INTERNAL_BYTES_LEN],
+               T2T_INTERNAL_BYTES_LEN);
+        /* Set all Static lock bits */
+        write_block[T2T_STATIC_LOCK0 % T2T_BLOCK_SIZE] = 0xFF;
+        write_block[T2T_STATIC_LOCK1 % T2T_BLOCK_SIZE] = 0xFF;
+        p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_ST_LOCK_BITS;
+        status = rw_t2t_write((T2T_STATIC_LOCK0 / T2T_BLOCK_SIZE), write_block);
+      }
+      break;
+
+    case RW_T2T_SUBSTATE_WAIT_READ_DYN_LOCK_BYTE_BLOCK:
+      /* Now set the dynamic lock bits present in the block read now */
+      status = rw_t2t_set_dynamic_lock_bits(p_data);
+      break;
+
+    case RW_T2T_SUBSTATE_WAIT_SET_ST_LOCK_BITS:
+      /* Tag configuration complete */
+      status = NFC_STATUS_OK;
+      b_notify = true;
+      break;
+  }
+
+  if (status != NFC_STATUS_OK || b_notify) {
+    /* Notify upper layer the result of Configuring Tag as Read only */
+    evt.status = status;
+    rw_t2t_handle_op_complete();
+    (*rw_cb.p_cback)(RW_T2T_SET_TAG_RO_EVT, (tRW_DATA*)&evt);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_handle_format_tag_rsp
+**
+** Description      This function handles formating a type 2 tag
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t2t_handle_format_tag_rsp(uint8_t* p_data) {
+  tRW_DATA evt;
+  uint8_t* p;
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  uint16_t version_no;
+  const tT2T_INIT_TAG* p_ret;
+  uint8_t tms;
+  uint8_t next_block = T2T_FIRST_DATA_BLOCK + 1;
+  uint16_t addr, locked_area;
+  bool b_notify = false;
+
+  p = p_t2t->ndef_final_block;
+  UINT8_TO_BE_STREAM(p, p_t2t->tlv_value[2]);
+
+  switch (p_t2t->substate) {
+    case RW_T2T_SUBSTATE_WAIT_READ_CC:
+      /* Start format operation */
+      status = rw_t2t_format_tag();
+      break;
+
+    case RW_T2T_SUBSTATE_WAIT_READ_VERSION_INFO:
+
+      memcpy(p_t2t->tag_data, p_data, T2T_READ_DATA_LEN);
+      p_t2t->b_read_data = true;
+      version_no = (uint16_t)p_data[0] << 8 | p_data[1];
+      p_ret = t2t_tag_init_data(p_t2t->tag_hdr[0], true, version_no);
+      if (p_ret != NULL) {
+        /* Valid Version Number */
+        if (p_ret->b_calc_cc) /* Calculate tag size from Version Information */
+          tms = rw_t2t_get_tag_size(p_data);
+
+        else
+          /* Tag size from Look up table */
+          tms = p_ret->tms;
+
+        /* Set CC with the Tag size from look up table or from calculated value
+         */
+        status = rw_t2t_set_cc(tms);
+      }
+      break;
+
+    case RW_T2T_SUBSTATE_WAIT_SET_CC:
+
+      version_no = (uint16_t)p_t2t->tag_data[0] << 8 | p_t2t->tag_data[1];
+      if ((version_no == 0) ||
+          ((p_ret = t2t_tag_init_data(p_t2t->tag_hdr[0], true, version_no)) ==
+           NULL) ||
+          (!p_ret->b_multi_version) || (!p_ret->b_calc_cc)) {
+        /* Currently Formating a non blank tag or a blank tag with manufacturer
+         * has only one variant of tag. Set Null NDEF TLV and complete Format
+         * Operation */
+        next_block = T2T_FIRST_DATA_BLOCK;
+        p = p_t2t->ndef_final_block;
+      } else {
+        addr = (uint16_t)(
+            ((uint16_t)p_t2t->tag_data[2] << 8 | p_t2t->tag_data[3]) *
+                ((uint16_t)p_t2t->tag_data[4] << 8 | p_t2t->tag_data[5]) +
+            T2T_STATIC_SIZE);
+        locked_area = ((uint16_t)p_t2t->tag_data[2] << 8 | p_t2t->tag_data[3]) *
+                      ((uint16_t)p_t2t->tag_data[6]);
+
+        status = rw_t2t_set_lock_tlv(addr, p_t2t->tag_data[7], locked_area);
+        if (status == NFC_STATUS_REJECTED) {
+          /* Cannot calculate Lock TLV. Set Null NDEF TLV and complete Format
+           * Operation */
+          next_block = T2T_FIRST_DATA_BLOCK;
+          p = p_t2t->ndef_final_block;
+        } else
+          break;
+      }
+
+    /* falls through */
+    case RW_T2T_SUBSTATE_WAIT_SET_LOCK_TLV:
+
+      /* Prepare NULL NDEF TLV, TERMINATOR_TLV */
+      UINT8_TO_BE_STREAM(p, TAG_NDEF_TLV);
+      UINT8_TO_BE_STREAM(p, 0);
+
+      if (((p_ret = t2t_tag_init_data(p_t2t->tag_hdr[0], false, 0)) != NULL) &&
+          (!p_ret->b_otp)) {
+        UINT8_TO_BE_STREAM(p, TAG_TERMINATOR_TLV);
+      } else
+        UINT8_TO_BE_STREAM(p, 0);
+
+      p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_NULL_NDEF;
+      /* send WRITE-E8 command */
+      status = rw_t2t_write(next_block, p_t2t->ndef_final_block);
+      if (status == NFC_STATUS_OK) p_t2t->b_read_data = false;
+      break;
+
+    case RW_T2T_SUBSTATE_WAIT_SET_NULL_NDEF:
+      /* Tag Formated successfully */
+      status = NFC_STATUS_OK;
+      b_notify = true;
+      break;
+
+    default:
+      break;
+  }
+
+  if (status != NFC_STATUS_OK || b_notify) {
+    /* Notify upper layer the result of Format op */
+    evt.status = status;
+    rw_t2t_handle_op_complete();
+    (*rw_cb.p_cback)(RW_T2T_FORMAT_CPLT_EVT, (tRW_DATA*)&evt);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_update_attributes
+**
+** Description      This function will update attribute for the current segment
+**                  based on lock and reserved bytes
+**
+** Returns          None
+**
+*******************************************************************************/
+static void rw_t2t_update_attributes(void) {
+  uint8_t count = 0;
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  uint16_t lower_offset;
+  uint16_t upper_offset;
+  uint16_t offset;
+  uint8_t num_bytes;
+
+  /* Prepare attr for the current segment */
+  memset(p_t2t->attr, 0, RW_T2T_SEGMENT_SIZE * sizeof(uint8_t));
+
+  /* calculate offset where the current segment starts in the tag */
+  lower_offset = p_t2t->segment * RW_T2T_SEGMENT_BYTES;
+  /* calculate offset where the current segment ends in the tag */
+  upper_offset = (p_t2t->segment + 1) * RW_T2T_SEGMENT_BYTES;
+
+  /* check offset of lock bytes in the tag and update p_t2t->attr
+   * for every lock byte that is present in the current segment */
+  count = 0;
+  while (count < p_t2t->num_lockbytes) {
+    offset = p_t2t->lock_tlv[p_t2t->lockbyte[count].tlv_index].offset +
+             p_t2t->lockbyte[count].byte_index;
+    if (offset >= lower_offset && offset < upper_offset) {
+      /* Calculate offset in the current segment as p_t2t->attr is prepared for
+       * one segment only */
+      offset %= RW_T2T_SEGMENT_BYTES;
+      /* Every bit in p_t2t->attr indicates one byte of the tag is either a
+       * lock/reserved byte or not
+       * So, each array element in p_t2t->attr covers two blocks in the tag as
+       * T2 block size is 4 and array element size is 8
+       * Set the corresponding bit in attr to indicate - reserved byte */
+      p_t2t->attr[offset / TAG_BITS_PER_BYTE] |=
+          rw_t2t_mask_bits[offset % TAG_BITS_PER_BYTE];
+    }
+    count++;
+  }
+
+  /* Search reserved bytes identified by all memory tlvs present in the tag */
+  count = 0;
+  while (count < p_t2t->num_mem_tlvs) {
+    /* check the offset of reserved bytes in the tag and update  p_t2t->attr
+     * for every  reserved byte that is present in the current segment */
+    num_bytes = 0;
+    while (num_bytes < p_t2t->mem_tlv[count].num_bytes) {
+      offset = p_t2t->mem_tlv[count].offset + num_bytes;
+      if (offset >= lower_offset && offset < upper_offset) {
+        /* Let offset represents offset in the current segment as p_t2t->attr is
+         * prepared for one segment only */
+        offset %= RW_T2T_SEGMENT_BYTES;
+        /* Every bit in p_t2t->attr indicates one byte of the tag is either a
+         * lock/reserved byte or not
+         * So, each array element in p_t2t->attr covers two blocks in the tag as
+         * T2 block size is 4 and array element size is 8
+         * Set the corresponding bit in attr to indicate - reserved byte */
+        p_t2t->attr[offset / TAG_BITS_PER_BYTE] |=
+            rw_t2t_mask_bits[offset % TAG_BITS_PER_BYTE];
+      }
+      num_bytes++;
+    }
+    count++;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_get_lock_bits_for_segment
+**
+** Description      This function returns the offset of lock bits associated for
+**                  the specified segment
+**
+** Parameters:      segment: The segment number to which lock bits are
+**                           associated
+**                  p_start_byte: The offset of lock byte that contains the
+**                                first lock bit for the segment
+**                  p_start_bit:  The offset of the lock bit in the lock byte
+**
+**                  p_end_byte:   The offset of the last bit associcated to the
+**                                segment
+**
+** Returns          Total number of lock bits assigned to the specified segment
+**
+*******************************************************************************/
+static uint8_t rw_t2t_get_lock_bits_for_segment(uint8_t segment,
+                                                uint8_t* p_start_byte,
+                                                uint8_t* p_start_bit,
+                                                uint8_t* p_end_byte) {
+  uint8_t total_bits = 0;
+  uint16_t byte_count = 0;
+  uint16_t lower_offset, upper_offset;
+  uint8_t num_dynamic_locks = 0;
+  uint8_t bit_count = 0;
+  uint8_t bytes_locked_per_bit;
+  uint8_t num_bits;
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  bool b_all_bits_are_locks = true;
+  uint16_t tag_size;
+  uint8_t xx;
+
+  tag_size = (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) +
+             (T2T_FIRST_DATA_BLOCK * T2T_BLOCK_SIZE) + p_t2t->num_lockbytes;
+
+  for (xx = 0; xx < p_t2t->num_mem_tlvs; xx++)
+    tag_size += p_t2t->mem_tlv[xx].num_bytes;
+
+  lower_offset = segment * RW_T2T_SEGMENT_BYTES;
+  if (segment == 0) {
+    lower_offset += T2T_STATIC_SIZE;
+  }
+  upper_offset = (segment + 1) * RW_T2T_SEGMENT_BYTES;
+
+  byte_count = T2T_STATIC_SIZE;
+  if (tag_size < upper_offset) {
+    upper_offset = tag_size;
+  }
+
+  *p_start_byte = num_dynamic_locks;
+  *p_start_bit = 0;
+
+  while ((byte_count <= lower_offset) &&
+         (num_dynamic_locks < p_t2t->num_lockbytes)) {
+    bytes_locked_per_bit =
+        p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index]
+            .bytes_locked_per_bit;
+    /* Number of bits in the current lock byte */
+    b_all_bits_are_locks =
+        ((p_t2t->lockbyte[num_dynamic_locks].byte_index + 1) *
+             TAG_BITS_PER_BYTE <=
+         p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index]
+             .num_bits);
+    num_bits =
+        b_all_bits_are_locks
+            ? TAG_BITS_PER_BYTE
+            : p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index]
+                      .num_bits %
+                  TAG_BITS_PER_BYTE;
+
+    if (((bytes_locked_per_bit * num_bits) + byte_count) <= lower_offset) {
+      /* Skip this lock byte as it covers different segment */
+      byte_count += bytes_locked_per_bit * num_bits;
+      num_dynamic_locks++;
+    } else {
+      bit_count = 0;
+      while (bit_count < num_bits) {
+        byte_count += bytes_locked_per_bit;
+        if (byte_count > lower_offset) {
+          /* First lock bit that is used to lock this segment */
+          *p_start_byte = num_dynamic_locks;
+          *p_end_byte = num_dynamic_locks;
+          *p_start_bit = bit_count;
+          bit_count++;
+          total_bits = 1;
+          break;
+        }
+        bit_count++;
+      }
+    }
+  }
+  if (num_dynamic_locks == p_t2t->num_lockbytes) {
+    return 0;
+  }
+  while ((byte_count < upper_offset) &&
+         (num_dynamic_locks < p_t2t->num_lockbytes)) {
+    bytes_locked_per_bit =
+        p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index]
+            .bytes_locked_per_bit;
+    /* Number of bits in the current lock byte */
+    b_all_bits_are_locks =
+        ((p_t2t->lockbyte[num_dynamic_locks].byte_index + 1) *
+             TAG_BITS_PER_BYTE <=
+         p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index]
+             .num_bits);
+    num_bits =
+        b_all_bits_are_locks
+            ? TAG_BITS_PER_BYTE
+            : p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index]
+                      .num_bits %
+                  TAG_BITS_PER_BYTE;
+
+    if ((bytes_locked_per_bit * (num_bits - bit_count)) + byte_count <
+        upper_offset) {
+      /* Collect all lock bits that covers the current segment */
+      byte_count += bytes_locked_per_bit * (num_bits - bit_count);
+      total_bits += num_bits - bit_count;
+      bit_count = 0;
+      *p_end_byte = num_dynamic_locks;
+      num_dynamic_locks++;
+    } else {
+      /* The last lock byte that covers the current segment */
+      bit_count = 0;
+      while (bit_count < num_bits) {
+        /* The last lock bit that is used to lock this segment */
+        byte_count += bytes_locked_per_bit;
+        if (byte_count >= upper_offset) {
+          *p_end_byte = num_dynamic_locks;
+          total_bits += (bit_count + 1);
+          break;
+        }
+        bit_count++;
+      }
+    }
+  }
+  return total_bits;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_update_lock_attributes
+**
+** Description      This function will check if the tag index passed as
+**                  argument is a locked byte and return true or false
+**
+** Parameters:      index, the index of the byte in the tag
+**
+**
+** Returns          true, if the specified index in the tag is a locked or
+**                        reserved or otp byte
+**                  false, otherwise
+**
+*******************************************************************************/
+static void rw_t2t_update_lock_attributes(void) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  uint8_t xx = 0;
+  uint8_t num_static_lock_bytes = 0;
+  uint8_t num_dyn_lock_bytes = 0;
+  uint8_t bits_covered = 0;
+  uint8_t bytes_covered = 0;
+  uint8_t block_count = 0;
+  bool b_all_bits_are_locks = true;
+  uint8_t bytes_locked_per_lock_bit;
+  uint8_t start_lock_byte;
+  uint8_t start_lock_bit;
+  uint8_t end_lock_byte;
+  uint8_t num_lock_bits;
+  uint8_t total_bits;
+
+  /* Prepare lock_attr for the current segment */
+  memset(p_t2t->lock_attr, 0, RW_T2T_SEGMENT_SIZE * sizeof(uint8_t));
+
+  block_count = 0;
+  if (p_t2t->segment == 0) {
+    /* Update lock_attributes based on static lock bytes */
+    xx = 0;
+    num_static_lock_bytes = 0;
+    block_count = 0;
+    num_lock_bits =
+        TAG_BITS_PER_BYTE - 1; /* the inner while loop increases xx by 2. need
+                                  (-1) to avoid coverity overrun error */
+
+    while (num_static_lock_bytes < T2T_NUM_STATIC_LOCK_BYTES) {
+      /* Update lock attribute based on 2 static locks */
+      while (xx < num_lock_bits) {
+        p_t2t->lock_attr[block_count] = 0x00;
+
+        if (p_t2t->tag_hdr[T2T_STATIC_LOCK0 + num_static_lock_bytes] &
+            rw_t2t_mask_bits[xx++]) {
+          /* If the bit is set then 1 block is locked */
+          p_t2t->lock_attr[block_count] = 0x0F;
+        }
+
+        if (p_t2t->tag_hdr[T2T_STATIC_LOCK0 + num_static_lock_bytes] &
+            rw_t2t_mask_bits[xx++]) {
+          /* If the bit is set then 1 block is locked */
+          p_t2t->lock_attr[block_count] |= 0xF0;
+        }
+        block_count++;
+      }
+      num_static_lock_bytes++;
+      xx = 0;
+    }
+    /* UID is always locked, irrespective of the lock value */
+    p_t2t->lock_attr[0x00] = 0xFF;
+  }
+
+  /* Get lock bits applicable for the current segment */
+  total_bits = rw_t2t_get_lock_bits_for_segment(
+      p_t2t->segment, &start_lock_byte, &start_lock_bit, &end_lock_byte);
+  if (total_bits != 0) {
+    /* update lock_attributes based on current segment using dynamic lock bytes
+     */
+    xx = start_lock_bit;
+    num_dyn_lock_bytes = start_lock_byte;
+    bits_covered = 0;
+    bytes_covered = 0;
+    num_lock_bits = TAG_BITS_PER_BYTE;
+    p_t2t->lock_attr[block_count] = 0;
+
+    while (num_dyn_lock_bytes <= end_lock_byte) {
+      bytes_locked_per_lock_bit =
+          p_t2t->lock_tlv[p_t2t->lockbyte[num_dyn_lock_bytes].tlv_index]
+              .bytes_locked_per_bit;
+      /* Find number of bits in the byte are lock bits */
+      b_all_bits_are_locks =
+          ((p_t2t->lockbyte[num_dyn_lock_bytes].byte_index + 1) *
+               TAG_BITS_PER_BYTE <=
+           p_t2t->lock_tlv[p_t2t->lockbyte[num_dyn_lock_bytes].tlv_index]
+               .num_bits);
+      num_lock_bits =
+          b_all_bits_are_locks
+              ? TAG_BITS_PER_BYTE
+              : p_t2t->lock_tlv[p_t2t->lockbyte[num_dyn_lock_bytes].tlv_index]
+                        .num_bits %
+                    TAG_BITS_PER_BYTE;
+
+      while (xx < num_lock_bits) {
+        bytes_covered = 0;
+        while (bytes_covered < bytes_locked_per_lock_bit) {
+#if (NXP_EXTNS == TRUE)
+          if ((p_t2t->lockbyte[num_dyn_lock_bytes].lock_byte &
+               rw_t2t_mask_bits[xx]) &&
+              (block_count < RW_T2T_SEGMENT_SIZE))
+#else
+          if (p_t2t->lockbyte[num_dyn_lock_bytes].lock_byte &
+              rw_t2t_mask_bits[xx])
+#endif
+          {
+            /* If the bit is set then it is locked */
+            p_t2t->lock_attr[block_count] |= 0x01 << bits_covered;
+          }
+          bytes_covered++;
+          bits_covered++;
+          if (bits_covered == TAG_BITS_PER_BYTE) {
+            /* Move to next 8 bytes */
+            bits_covered = 0;
+            block_count++;
+            /* Assume unlocked before updating using locks */
+            if (block_count < RW_T2T_SEGMENT_SIZE)
+              p_t2t->lock_attr[block_count] = 0;
+          }
+        }
+        xx++;
+      }
+      num_dyn_lock_bytes++;
+      xx = 0;
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_is_lock_res_byte
+**
+** Description      This function will check if the tag index passed as
+**                  argument is a lock or reserved or otp byte and return
+**                  true or false
+**
+** Parameters:      index, the index of the byte in the tag
+**
+**
+** Returns          true, if the specified index in the tag is a locked or
+**                        reserved or otp byte
+**                  false, otherwise
+**
+*******************************************************************************/
+static bool rw_t2t_is_lock_res_byte(uint16_t index) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+
+  p_t2t->segment = (uint8_t)(index / RW_T2T_SEGMENT_BYTES);
+
+  if (p_t2t->attr_seg != p_t2t->segment) {
+    /* Update attributes for the current segment */
+    rw_t2t_update_attributes();
+    p_t2t->attr_seg = p_t2t->segment;
+  }
+
+  index = index % RW_T2T_SEGMENT_BYTES;
+  /* Every bit in p_t2t->attr indicates one specific byte of the tag is either a
+   * lock/reserved byte or not
+   * So, each array element in p_t2t->attr covers two blocks in the tag as T2
+   * block size is 4 and array element size is 8
+   * Find the block and offset for the index (passed as argument) and Check if
+   * the offset bit in the
+   * p_t2t->attr[block/2] is set or not. If the bit is set then it is a
+   * lock/reserved byte, otherwise not */
+
+  return ((p_t2t->attr[index / 8] & rw_t2t_mask_bits[index % 8]) == 0) ? false
+                                                                       : true;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_is_read_only_byte
+**
+** Description      This function will check if the tag index passed as
+**                  argument is a locked and return
+**                  true or false
+**
+** Parameters:      index, the index of the byte in the tag
+**
+**
+** Returns          true, if the specified index in the tag is a locked or
+**                        reserved or otp byte
+**                  false, otherwise
+**
+*******************************************************************************/
+static bool rw_t2t_is_read_only_byte(uint16_t index) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+
+  p_t2t->segment = (uint8_t)(index / RW_T2T_SEGMENT_BYTES);
+
+  if (p_t2t->lock_attr_seg != p_t2t->segment) {
+    /* Update lock attributes for the current segment */
+    rw_t2t_update_lock_attributes();
+    p_t2t->lock_attr_seg = p_t2t->segment;
+  }
+
+  index = index % RW_T2T_SEGMENT_BYTES;
+  /* Every bit in p_t2t->lock_attr indicates one specific byte of the tag is a
+   * read only byte or read write byte
+   * So, each array element in p_t2t->lock_attr covers two blocks of the tag as
+   * T2 block size is 4 and array element size is 8
+   * Find the block and offset for the index (passed as argument) and Check if
+   * the offset bit in
+   * p_t2t->lock_attr[block/2] is set or not. If the bit is set then it is a
+   * read only byte, otherwise read write byte */
+
+  return ((p_t2t->lock_attr[index / 8] & rw_t2t_mask_bits[index % 8]) == 0)
+             ? false
+             : true;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_set_dynamic_lock_bits
+**
+** Description      This function will set dynamic lock bits as part of
+**                  configuring tag as read only
+**
+** Returns
+**                  NFC_STATUS_OK, Command sent to set dynamic lock bits
+**                  NFC_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_set_dynamic_lock_bits(uint8_t* p_data) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  uint8_t write_block[T2T_BLOCK_SIZE];
+  uint16_t offset;
+  uint16_t next_offset;
+  uint8_t num_bits;
+  uint8_t next_num_bits;
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  uint8_t num_locks;
+  uint8_t lock_count;
+  bool b_all_bits_are_locks = true;
+
+  num_locks = 0;
+
+  memcpy(write_block, p_data, T2T_BLOCK_SIZE);
+  while (num_locks < p_t2t->num_lockbytes) {
+    if (p_t2t->lockbyte[num_locks].lock_status == RW_T2T_LOCK_NOT_UPDATED) {
+      offset = p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].offset +
+               p_t2t->lockbyte[num_locks].byte_index;
+
+      /* Check if all bits are lock bits in the byte */
+      b_all_bits_are_locks =
+          ((p_t2t->lockbyte[num_locks].byte_index + 1) * TAG_BITS_PER_BYTE <=
+           p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].num_bits);
+      num_bits =
+          b_all_bits_are_locks
+              ? TAG_BITS_PER_BYTE
+              : p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].num_bits %
+                    TAG_BITS_PER_BYTE;
+
+      write_block[(uint8_t)(offset % T2T_BLOCK_SIZE)] |=
+          tags_pow(2, num_bits) - 1;
+      lock_count = num_locks + 1;
+
+      /* Set all the lock bits in the block using a sing block write command */
+      while (lock_count < p_t2t->num_lockbytes) {
+        next_offset =
+            p_t2t->lock_tlv[p_t2t->lockbyte[lock_count].tlv_index].offset +
+            p_t2t->lockbyte[lock_count].byte_index;
+
+        /* Check if all bits are lock bits in the byte */
+        b_all_bits_are_locks =
+            ((p_t2t->lockbyte[lock_count].byte_index + 1) * TAG_BITS_PER_BYTE <=
+             p_t2t->lock_tlv[p_t2t->lockbyte[lock_count].tlv_index].num_bits);
+        next_num_bits =
+            b_all_bits_are_locks
+                ? TAG_BITS_PER_BYTE
+                : p_t2t->lock_tlv[p_t2t->lockbyte[lock_count].tlv_index]
+                          .num_bits %
+                      TAG_BITS_PER_BYTE;
+
+        if (next_offset / T2T_BLOCK_SIZE == offset / T2T_BLOCK_SIZE) {
+          write_block[(uint8_t)(next_offset % T2T_BLOCK_SIZE)] |=
+              tags_pow(2, next_num_bits) - 1;
+        } else
+          break;
+        lock_count++;
+      }
+
+      p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
+      /* send WRITE command to set dynamic lock bits */
+      status = rw_t2t_write((uint16_t)(offset / T2T_BLOCK_SIZE), write_block);
+      if (status == NFC_STATUS_OK) {
+        while (lock_count > num_locks) {
+          /* Set update initiated flag to indicate a write command is sent to
+           * set dynamic lock bits of the block */
+          p_t2t->lockbyte[lock_count - 1].lock_status =
+              RW_T2T_LOCK_UPDATE_INITIATED;
+          lock_count--;
+        }
+      } else
+        status = NFC_STATUS_FAILED;
+
+      break;
+    }
+    num_locks++;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_set_lock_tlv
+**
+** Description      This function will set lock control tlv on the blank
+**                  activated type 2 tag based on values read from version block
+**
+** Parameters:      TAG data memory size
+**
+** Returns
+**                  NFC_STATUS_OK, Command sent to set Lock TLV
+**                  NFC_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_set_lock_tlv(uint16_t addr, uint8_t num_dyn_lock_bits,
+                                uint16_t locked_area_size) {
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  int8_t PageAddr = 0;
+  int8_t BytePerPage = 0;
+  int8_t ByteOffset = 0;
+  uint8_t a;
+  uint8_t data_block[T2T_BLOCK_SIZE];
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  uint8_t* p;
+  uint8_t xx;
+
+  for (xx = 15; xx > 0; xx--) {
+    a = (uint8_t)(addr / xx);
+    a += (addr % xx) ? 1 : 0;
+
+    BytePerPage = (int8_t)tags_log2(a);
+    ByteOffset = (int8_t)(addr - xx * tags_pow(2, BytePerPage));
+
+    if (ByteOffset < 16) {
+      PageAddr = xx;
+      break;
+    }
+  }
+
+  if ((ByteOffset < 16) && (BytePerPage < 16) && (PageAddr < 16)) {
+    memset(data_block, 0, T2T_BLOCK_SIZE);
+    p = data_block;
+    UINT8_TO_BE_STREAM(p, T2T_TLV_TYPE_LOCK_CTRL);
+    UINT8_TO_BE_STREAM(p, T2T_TLEN_LOCK_CTRL_TLV);
+    UINT8_TO_BE_STREAM(p, (PageAddr << 4 | ByteOffset));
+    UINT8_TO_BE_STREAM(p, num_dyn_lock_bits);
+
+    p_t2t->tlv_value[0] = PageAddr << 4 | ByteOffset;
+    p_t2t->tlv_value[1] = num_dyn_lock_bits;
+    p_t2t->tlv_value[2] =
+        (uint8_t)(BytePerPage << 4 | tags_log2(locked_area_size));
+
+    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_LOCK_TLV;
+
+    /* send WRITE-E8 command */
+    status = rw_t2t_write(T2T_FIRST_DATA_BLOCK, data_block);
+    if (status == NFC_STATUS_OK) {
+      p_t2t->b_read_data = false;
+    } else
+      p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+  } else
+    status = NFC_STATUS_REJECTED;
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_set_cc
+**
+** Description      This function will set Capability Container on the activated
+**                  type 2 tag with default values of CC0, CC1, CC4 and
+**                  specified CC3 value
+**
+** Parameters:      CC3 value of the tag
+**
+** Returns
+**                  NFC_STATUS_OK, Command sent to set CC
+**                  NFC_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_set_cc(uint8_t tms) {
+  uint8_t cc_block[T2T_BLOCK_SIZE];
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  uint8_t* p;
+
+  memset(cc_block, 0, T2T_BLOCK_SIZE);
+  memset(p_t2t->ndef_final_block, 0, T2T_BLOCK_SIZE);
+  p = cc_block;
+
+  /* Prepare Capability Container */
+  UINT8_TO_BE_STREAM(p, T2T_CC0_NMN);
+  UINT8_TO_BE_STREAM(p, T2T_CC1_VNO);
+  UINT8_TO_BE_STREAM(p, tms);
+  UINT8_TO_BE_STREAM(p, T2T_CC3_RWA_RW);
+
+  p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_CC;
+
+  /* send WRITE-E8 command */
+  status = rw_t2t_write(T2T_CC_BLOCK, cc_block);
+  if (status == NFC_STATUS_OK) {
+    p_t2t->state = RW_T2T_STATE_FORMAT_TAG;
+    p_t2t->b_read_hdr = false;
+  } else
+    p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_format_tag
+**
+** Description      This function will format tag based on Manufacturer ID
+**
+** Returns
+**                  NFC_STATUS_OK, Command sent to format Tag
+**                  NFC_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_format_tag(void) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  const tT2T_INIT_TAG* p_ret;
+  uint8_t tms;
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  bool b_blank_tag = true;
+
+  p_ret = t2t_tag_init_data(p_t2t->tag_hdr[0], false, 0);
+  if (p_ret == NULL) {
+    RW_TRACE_WARNING1(
+        "rw_t2t_format_tag - Unknown Manufacturer ID: %u, Cannot Format the "
+        "tag!",
+        p_t2t->tag_hdr[0]);
+    return (NFC_STATUS_FAILED);
+  }
+
+  if (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] != 0) {
+    /* If OTP tag has valid NDEF Message, cannot format the tag */
+    if ((p_t2t->ndef_msg_len > 0) && (p_ret->b_otp)) {
+      RW_TRACE_WARNING0(
+          "rw_t2t_format_tag - Cannot Format a OTP tag with NDEF Message!");
+      return (NFC_STATUS_FAILED);
+    }
+
+    if (((p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != 0) &&
+         (p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != T2T_CC0_NMN)) ||
+        ((p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != 0) &&
+         (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_LEGACY_VNO) &&
+         (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_VNO) &&
+         (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_NEW_VNO))) {
+      RW_TRACE_WARNING0("rw_t2t_format_tag - Tag not blank to Format!");
+      return (NFC_STATUS_FAILED);
+    } else {
+      tms = p_t2t->tag_hdr[T2T_CC2_TMS_BYTE];
+      b_blank_tag = false;
+    }
+  } else
+    tms = p_ret->tms;
+
+  memset(p_t2t->tag_data, 0, sizeof(p_t2t->tag_data));
+
+  if (!b_blank_tag || !p_ret->b_multi_version) {
+    status = rw_t2t_set_cc(tms);
+  } else if (p_ret->version_block != 0) {
+    /* If Version number is not read, READ it now */
+    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_VERSION_INFO;
+
+    status = rw_t2t_read(p_ret->version_block);
+    if (status == NFC_STATUS_OK)
+      p_t2t->state = RW_T2T_STATE_FORMAT_TAG;
+    else
+      p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+  } else {
+    /* UID block is the version block */
+    p_t2t->state = RW_T2T_STATE_FORMAT_TAG;
+    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_VERSION_INFO;
+    rw_t2t_handle_format_tag_rsp(p_t2t->tag_hdr);
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_soft_lock_tag
+**
+** Description      This function will soft lock the tag after validating CC.
+**
+** Returns
+**                  NFC_STATUS_OK, Command sent to soft lock the tag
+**                  NFC_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_soft_lock_tag(void) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  uint8_t write_block[T2T_BLOCK_SIZE];
+  uint8_t num_locks;
+
+  /* If CC block is read and cc3 is soft locked, reject the command */
+  if ((p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] & T2T_CC3_RWA_RO) == T2T_CC3_RWA_RO) {
+    RW_TRACE_ERROR1(
+        "rw_t2t_soft_lock_tag: Error: Type 2 tag is in Read only state, CC3: "
+        "%u",
+        p_t2t->tag_hdr[T2T_CC3_RWA_BYTE]);
+    return (NFC_STATUS_FAILED);
+  }
+
+  if (p_t2t->b_hard_lock) {
+    /* Should have performed NDEF Detection on dynamic memory structure tag,
+     * before permanently converting to Read only
+     * Even when no lock control tlv is present, default lock bytes should be
+     * present */
+
+    if ((p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] != T2T_CC2_TMS_STATIC) &&
+        (p_t2t->num_lockbytes == 0)) {
+      RW_TRACE_ERROR0(
+          "rw_t2t_soft_lock_tag: Error: Lock TLV not detected! Cannot hard "
+          "lock the tag");
+      return (NFC_STATUS_FAILED);
+    }
+
+    /* On dynamic memory structure tag, reset all lock bytes status to 'Not
+     * Updated' if not in Updated status */
+    num_locks = 0;
+    while (num_locks < p_t2t->num_lockbytes) {
+      if (p_t2t->lockbyte[num_locks].lock_status != RW_T2T_LOCK_UPDATED)
+        p_t2t->lockbyte[num_locks].lock_status = RW_T2T_LOCK_NOT_UPDATED;
+      num_locks++;
+    }
+  }
+
+  memcpy(write_block, &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE], T2T_BLOCK_SIZE);
+  write_block[(T2T_CC3_RWA_BYTE % T2T_BLOCK_SIZE)] = T2T_CC3_RWA_RO;
+
+  p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_CC_RO;
+  /* First Soft lock the tag */
+  status = rw_t2t_write(T2T_CC_BLOCK, write_block);
+  if (status == NFC_STATUS_OK) {
+    p_t2t->state = RW_T2T_STATE_SET_TAG_RO;
+    p_t2t->b_read_hdr = false;
+  } else {
+    p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+  }
+  return status;
+}
+
+/*****************************************************************************
+**
+** Function         RW_T2tFormatNDef
+**
+** Description
+**      Format Tag content
+**
+** Returns
+**      NFC_STATUS_OK, Command sent to format Tag
+**      NFC_STATUS_FAILED: otherwise
+**
+*****************************************************************************/
+tNFC_STATUS RW_T2tFormatNDef(void) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+
+  if (p_t2t->state != RW_T2T_STATE_IDLE) {
+    RW_TRACE_WARNING1("RW_T2tFormatNDef - Tag not initialized/ Busy! State: %u",
+                      p_t2t->state);
+    return (NFC_STATUS_FAILED);
+  }
+
+  if (!p_t2t->b_read_hdr) {
+    /* If UID is not read, READ it now */
+    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_CC;
+
+    status = rw_t2t_read(0);
+    if (status == NFC_STATUS_OK)
+      p_t2t->state = RW_T2T_STATE_FORMAT_TAG;
+    else
+      p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+  } else {
+    status = rw_t2t_format_tag();
+    if (status != NFC_STATUS_OK) p_t2t->b_read_hdr = false;
+  }
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T2tLocateTlv
+**
+** Description      This function is used to perform TLV detection on a Type 2
+**                  tag, and retrieve the tag's TLV attribute information.
+**
+**                  Before using this API, the application must call
+**                  RW_SelectTagType to indicate that a Type 2 tag has been
+**                  activated.
+**
+** Parameters:      tlv_type : TLV to detect
+**
+** Returns          NCI_STATUS_OK, if detection was started. Otherwise, error
+**                  status.
+**
+*******************************************************************************/
+tNFC_STATUS RW_T2tLocateTlv(uint8_t tlv_type) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  tNFC_STATUS status;
+  uint16_t block;
+
+  if (p_t2t->state != RW_T2T_STATE_IDLE) {
+    RW_TRACE_ERROR1("Error: Type 2 tag not activated or Busy - State: %u",
+                    p_t2t->state);
+    return (NFC_STATUS_BUSY);
+  }
+
+  if ((tlv_type != TAG_LOCK_CTRL_TLV) && (tlv_type != TAG_MEM_CTRL_TLV) &&
+      (tlv_type != TAG_NDEF_TLV) && (tlv_type != TAG_PROPRIETARY_TLV)) {
+    RW_TRACE_API1("RW_T2tLocateTlv - Cannot search TLV: 0x%02x", tlv_type);
+    return (NFC_STATUS_FAILED);
+  }
+
+  if ((tlv_type == TAG_LOCK_CTRL_TLV) && (p_t2t->b_read_hdr) &&
+      (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] == T2T_CC2_TMS_STATIC)) {
+    p_t2t->b_read_hdr = false;
+    RW_TRACE_API1(
+        "RW_T2tLocateTlv - No Lock tlv in static structure tag, CC[0]: 0x%02x",
+        p_t2t->tag_hdr[T2T_CC2_TMS_BYTE]);
+    return (NFC_STATUS_FAILED);
+  }
+
+  if ((tlv_type == TAG_NDEF_TLV) && (p_t2t->b_read_hdr) &&
+      (p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != T2T_CC0_NMN)) {
+    p_t2t->b_read_hdr = false;
+    RW_TRACE_WARNING3(
+        "RW_T2tLocateTlv - Invalid NDEF Magic Number!, CC[0]: 0x%02x, CC[1]: "
+        "0x%02x, CC[3]: 0x%02x",
+        p_t2t->tag_hdr[T2T_CC0_NMN_BYTE], p_t2t->tag_hdr[T2T_CC1_VNO_BYTE],
+        p_t2t->tag_hdr[T2T_CC3_RWA_BYTE]);
+    return (NFC_STATUS_FAILED);
+  }
+
+  p_t2t->work_offset = 0;
+  p_t2t->tlv_detect = tlv_type;
+
+  /* Reset control block variables based on type of tlv to detect */
+  if (tlv_type == TAG_LOCK_CTRL_TLV) {
+    p_t2t->num_lockbytes = 0;
+    p_t2t->num_lock_tlvs = 0;
+  } else if (tlv_type == TAG_MEM_CTRL_TLV) {
+    p_t2t->num_mem_tlvs = 0;
+  } else if (tlv_type == TAG_NDEF_TLV) {
+    p_t2t->ndef_msg_offset = 0;
+    p_t2t->num_lockbytes = 0;
+    p_t2t->num_lock_tlvs = 0;
+    p_t2t->num_mem_tlvs = 0;
+    p_t2t->ndef_msg_len = 0;
+    p_t2t->ndef_status = T2T_NDEF_NOT_DETECTED;
+  } else {
+    p_t2t->prop_msg_len = 0;
+  }
+
+  if (!p_t2t->b_read_hdr) {
+    /* First read CC block */
+    block = 0;
+    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_CC;
+  } else {
+    /* Read first data block */
+    block = T2T_FIRST_DATA_BLOCK;
+    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
+  }
+
+  /* Start reading tag, looking for the specified TLV */
+  status = rw_t2t_read((uint16_t)block);
+  if (status == NFC_STATUS_OK) {
+    p_t2t->state = RW_T2T_STATE_DETECT_TLV;
+  } else {
+    p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+  }
+  return (status);
+}
+
+/*******************************************************************************
+**
+** Function         RW_T2tDetectNDef
+**
+** Description      This function is used to perform NDEF detection on a Type 2
+**                  tag, and retrieve the tag's NDEF attribute information.
+**
+**                  Before using this API, the application must call
+**                  RW_SelectTagType to indicate that a Type 2 tag has been
+**                  activated.
+**
+** Parameters:      none
+**
+** Returns          NCI_STATUS_OK,if detect op started.Otherwise,error status.
+**
+*******************************************************************************/
+tNFC_STATUS RW_T2tDetectNDef(bool skip_dyn_locks) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+
+  p_t2t->skip_dyn_locks = skip_dyn_locks;
+
+  return RW_T2tLocateTlv(TAG_NDEF_TLV);
+}
+
+/*******************************************************************************
+**
+** Function         RW_T2tReadNDef
+**
+** Description      Retrieve NDEF contents from a Type2 tag.
+**
+**                  The RW_T2T_NDEF_READ_EVT event is used to notify the
+**                  application after reading the NDEF message.
+**
+**                  Before using this API, the RW_T2tDetectNDef function must
+**                  be called to verify that the tag contains NDEF data, and to
+**                  retrieve the NDEF attributes.
+**
+**                  Internally, this command will be separated into multiple
+**                  Tag2 Read commands (if necessary) - depending on the NDEF
+**                  Msg size
+**
+** Parameters:      p_buffer:   The buffer into which to read the NDEF message
+**                  buf_len:    The length of the buffer
+**
+** Returns          NCI_STATUS_OK, if read was started. Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS RW_T2tReadNDef(uint8_t* p_buffer, uint16_t buf_len) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  tNFC_STATUS status = NFC_STATUS_OK;
+  uint16_t block;
+
+  if (p_t2t->state != RW_T2T_STATE_IDLE) {
+    RW_TRACE_ERROR1("Error: Type 2 tag not activated or Busy - State: %u",
+                    p_t2t->state);
+    return (NFC_STATUS_FAILED);
+  }
+
+  if (p_t2t->ndef_status == T2T_NDEF_NOT_DETECTED) {
+    RW_TRACE_ERROR0("RW_T2tReadNDef - Error: NDEF detection not performed yet");
+    return (NFC_STATUS_FAILED);
+  }
+
+  if (buf_len < p_t2t->ndef_msg_len) {
+    RW_TRACE_WARNING2(
+        "RW_T2tReadNDef - buffer size: %u  less than NDEF msg sise: %u",
+        buf_len, p_t2t->ndef_msg_len);
+    return (NFC_STATUS_FAILED);
+  }
+
+  if (!p_t2t->ndef_msg_len) {
+    RW_TRACE_WARNING1("RW_T2tReadNDef - NDEF Message length is zero ",
+                      p_t2t->ndef_msg_len);
+    return (NFC_STATUS_NOT_INITIALIZED);
+  }
+
+  p_t2t->p_ndef_buffer = p_buffer;
+  p_t2t->work_offset = 0;
+
+  block = (uint16_t)(p_t2t->ndef_msg_offset / T2T_BLOCK_LEN);
+  block -= block % T2T_READ_BLOCKS;
+
+  p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+
+  if ((block == T2T_FIRST_DATA_BLOCK) && (p_t2t->b_read_data)) {
+    p_t2t->state = RW_T2T_STATE_READ_NDEF;
+    p_t2t->block_read = T2T_FIRST_DATA_BLOCK;
+    rw_t2t_handle_ndef_read_rsp(p_t2t->tag_data);
+  } else {
+    /* Start reading NDEF Message */
+    status = rw_t2t_read(block);
+    if (status == NFC_STATUS_OK) {
+      p_t2t->state = RW_T2T_STATE_READ_NDEF;
+    }
+  }
+
+  return (status);
+}
+
+/*******************************************************************************
+**
+** Function         RW_T2tWriteNDef
+**
+** Description      Write NDEF contents to a Type2 tag.
+**
+**                  Before using this API, the RW_T2tDetectNDef
+**                  function must be called to verify that the tag contains
+**                  NDEF data, and to retrieve the NDEF attributes.
+**
+**                  The RW_T2T_NDEF_WRITE_EVT callback event will be used to
+**                  notify the application of the response.
+**
+**                  Internally, this command will be separated into multiple
+**                  Tag2 Write commands (if necessary) - depending on the NDEF
+**                  Msg size
+**
+** Parameters:      msg_len:    The length of the buffer
+**                  p_msg:      The NDEF message to write
+**
+** Returns          NCI_STATUS_OK,if write was started. Otherwise, error status
+**
+*******************************************************************************/
+tNFC_STATUS RW_T2tWriteNDef(uint16_t msg_len, uint8_t* p_msg) {
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+  uint16_t block;
+  uint8_t offset = 0;
+  const tT2T_INIT_TAG* p_ret;
+
+  tNFC_STATUS status = NFC_STATUS_OK;
+
+  if (p_t2t->state != RW_T2T_STATE_IDLE) {
+    RW_TRACE_ERROR1("Error: Type 2 tag not activated or Busy - State: %u",
+                    p_t2t->state);
+    return (NFC_STATUS_FAILED);
+  }
+
+  if (p_t2t->ndef_status == T2T_NDEF_NOT_DETECTED) {
+    RW_TRACE_ERROR0("RW_T2tWriteNDef - Error: NDEF detection not performed!");
+    return (NFC_STATUS_FAILED);
+  }
+
+  if (p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] != T2T_CC3_RWA_RW) {
+    RW_TRACE_ERROR1("RW_T2tWriteNDef - Write access not granted - CC3: %u",
+                    p_t2t->tag_hdr[T2T_CC3_RWA_BYTE]);
+    return (NFC_STATUS_REFUSED);
+  }
+
+  /* Check if there is enough memory on the tag */
+  if (msg_len > p_t2t->max_ndef_msg_len) {
+    RW_TRACE_ERROR1(
+        "RW_T2tWriteNDef - Cannot write NDEF of size greater than %u bytes",
+        p_t2t->max_ndef_msg_len);
+    return (NFC_STATUS_FAILED);
+  }
+
+  /* If OTP tag and tag has valid NDEF Message, stop writting new NDEF Message
+   * as it may corrupt the tag */
+  if ((p_t2t->ndef_msg_len > 0) &&
+      ((p_ret = t2t_tag_init_data(p_t2t->tag_hdr[0], false, 0)) != NULL) &&
+      (p_ret->b_otp)) {
+    RW_TRACE_WARNING0(
+        "RW_T2tWriteNDef - Cannot Overwrite NDEF Message on a OTP tag!");
+    return (NFC_STATUS_FAILED);
+  }
+  p_t2t->p_new_ndef_buffer = p_msg;
+  p_t2t->new_ndef_msg_len = msg_len;
+  p_t2t->work_offset = 0;
+
+  p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK;
+  /* Read first NDEF Block before updating NDEF */
+
+  block = (uint16_t)(p_t2t->ndef_header_offset / T2T_BLOCK_LEN);
+
+  if ((block < (T2T_FIRST_DATA_BLOCK + T2T_READ_BLOCKS)) &&
+      (p_t2t->b_read_data)) {
+    p_t2t->state = RW_T2T_STATE_WRITE_NDEF;
+    p_t2t->block_read = block;
+    offset = (block - T2T_FIRST_DATA_BLOCK) * T2T_BLOCK_LEN;
+    if (offset <= T2T_READ_DATA_LEN)
+      rw_t2t_handle_ndef_write_rsp(&p_t2t->tag_data[offset]);
+    else {
+      RW_TRACE_WARNING0("tag_data offset exceeds the limit");
+      return (NFC_STATUS_FAILED);
+    }
+  } else {
+    status = rw_t2t_read(block);
+    if (status == NFC_STATUS_OK)
+      p_t2t->state = RW_T2T_STATE_WRITE_NDEF;
+    else
+      p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+  }
+
+  return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T2tSetTagReadOnly
+**
+** Description      This function can be called to set T2 tag as read only.
+**
+** Parameters:      b_hard_lock:   To indicate hard lock the tag or not
+**
+** Returns          NCI_STATUS_OK, if setting tag as read only was started.
+**                  Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS RW_T2tSetTagReadOnly(bool b_hard_lock) {
+  tNFC_STATUS status = NFC_STATUS_FAILED;
+  tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+
+  if (p_t2t->state != RW_T2T_STATE_IDLE) {
+    RW_TRACE_ERROR1(
+        "RW_T2tSetTagReadOnly: Error: Type 2 tag not activated or Busy - "
+        "State: %u",
+        p_t2t->state);
+    return (NFC_STATUS_FAILED);
+  }
+
+  p_t2t->b_hard_lock = b_hard_lock;
+
+  if (!p_t2t->b_read_hdr) {
+    /* Read CC block before configuring tag as Read only */
+    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_CC;
+    status = rw_t2t_read((uint16_t)0);
+    if (status == NFC_STATUS_OK) {
+      p_t2t->state = RW_T2T_STATE_SET_TAG_RO;
+    } else
+      p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+  } else {
+    status = rw_t2t_soft_lock_tag();
+    if (status != NFC_STATUS_OK) p_t2t->b_read_hdr = false;
+  }
+
+  return status;
+}
+
+#endif /* (RW_NDEF_INCLUDED == true) */
diff --git a/src/nfc/tags/rw_t3t.c b/src/nfc/tags/rw_t3t.c
new file mode 100644
index 0000000..2f18030
--- /dev/null
+++ b/src/nfc/tags/rw_t3t.c
@@ -0,0 +1,3073 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the implementation for Type 3 tag in Reader/Writer
+ *  mode.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "trace_api.h"
+
+#include "nfc_api.h"
+#include "nfc_int.h"
+#include "nci_hmsgs.h"
+#include "rw_api.h"
+#include "rw_int.h"
+#include "tags_int.h"
+#include "gki.h"
+
+/* Definitions for constructing t3t command messages */
+#define RW_T3T_FL_PADDING 0x01 /* Padding needed for last NDEF block */
+/* Maximum number of NDEF blocks updates that can fit into one command (when all
+ * block-numbers are < 256) */
+#define RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT (13)
+/* Maximum number of NDEF blocks updates that can fit into one command (when all
+ * block-numbers are >= 256) */
+#define RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_2_BYTE_FORMAT (12)
+
+/* Definitions for SENSF_RES */
+/* Offset of RD in SENSF_RES from NCI_POLL NTF (includes 1 byte SENSF_RES
+ * length) */
+#define RW_T3T_SENSF_RES_RD_OFFSET 17
+#define RW_T3T_SENSF_RES_RD_LEN 2 /* Size of RD in SENSF_RES   */
+
+/* Timeout definitions for commands */
+#define RW_T3T_POLL_CMD_TIMEOUT_TICKS \
+  ((RW_T3T_TOUT_RESP * 2 * QUICK_TIMER_TICKS_PER_SEC) / 1000)
+#define RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS \
+  ((RW_T3T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000)
+#define RW_T3T_RAW_FRAME_CMD_TIMEOUT_TICKS \
+  (RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS * 4)
+#define RW_T3T_MIN_TIMEOUT_TICKS 10
+
+/* Macro to extract major version from NDEF version byte */
+#define T3T_GET_MAJOR_VERSION(ver) (ver >> 4)
+
+/* Enumeration of API commands */
+enum {
+  RW_T3T_CMD_DETECT_NDEF,
+  RW_T3T_CMD_CHECK_NDEF,
+  RW_T3T_CMD_UPDATE_NDEF,
+  RW_T3T_CMD_CHECK,
+  RW_T3T_CMD_UPDATE,
+  RW_T3T_CMD_SEND_RAW_FRAME,
+  RW_T3T_CMD_GET_SYSTEM_CODES,
+  RW_T3T_CMD_FORMAT,
+  RW_T3T_CMD_SET_READ_ONLY_SOFT,
+  RW_T3T_CMD_SET_READ_ONLY_HARD,
+
+  RW_T3T_CMD_MAX
+};
+
+/* RW_CBACK events corresponding to API comands */
+const uint8_t rw_t3t_api_res_evt[RW_T3T_CMD_MAX] = {
+    RW_T3T_NDEF_DETECT_EVT,       /* RW_T3T_CMD_DETECT_NDEF */
+    RW_T3T_CHECK_CPLT_EVT,        /* RW_T3T_CMD_CHECK_NDEF  */
+    RW_T3T_UPDATE_CPLT_EVT,       /* RW_T3T_CMD_UPDATE_NDEF */
+    RW_T3T_CHECK_CPLT_EVT,        /* RW_T3T_CMD_CHECK */
+    RW_T3T_UPDATE_CPLT_EVT,       /* RW_T3T_CMD_UPDATE */
+    RW_T3T_RAW_FRAME_EVT,         /* RW_T3T_CMD_SEND_RAW_FRAME */
+    RW_T3T_GET_SYSTEM_CODES_EVT,  /* RW_T3T_CMD_GET_SYSTEM_CODES */
+    RW_T3T_FORMAT_CPLT_EVT,       /* RW_T3T_CMD_FORMAT */
+    RW_T3T_SET_READ_ONLY_CPLT_EVT /* RW_T3T_CMD_SET_READ_ONLY */
+};
+
+/* States */
+enum {
+  RW_T3T_STATE_NOT_ACTIVATED,
+  RW_T3T_STATE_IDLE,
+  RW_T3T_STATE_COMMAND_PENDING
+};
+
+/* Sub-states */
+enum {
+  /* Sub states for formatting Felica-Lite */
+  RW_T3T_FMT_SST_POLL_FELICA_LITE, /* Waiting for POLL Felica-Lite response (for
+                                      formatting) */
+  RW_T3T_FMT_SST_CHECK_MC_BLK,     /* Waiting for Felica-Lite MC (MemoryControl)
+                                      block-read to complete */
+  RW_T3T_FMT_SST_UPDATE_MC_BLK,    /* Waiting for Felica-Lite MC (MemoryControl)
+                                      block-write to complete */
+  RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB, /* Waiting for NDEF attribute block-write
+                                        to complete */
+
+  /* Sub states for setting Felica-Lite read only */
+  RW_T3T_SRO_SST_POLL_FELICA_LITE, /* Waiting for POLL Felica-Lite response (for
+                                      setting read only) */
+  RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB, /* Waiting for NDEF attribute block-write
+                                        to complete */
+  RW_T3T_SRO_SST_CHECK_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl)
+                                  block-read to complete */
+  RW_T3T_SRO_SST_UPDATE_MC_BLK /* Waiting for Felica-Lite MC (MemoryControl)
+                                  block-write to complete */
+};
+
+#if (BT_TRACE_VERBOSE == true)
+static char* rw_t3t_cmd_str(uint8_t cmd_id);
+static char* rw_t3t_state_str(uint8_t state_id);
+#endif
+
+/* Local static functions */
+static void rw_t3t_update_ndef_flag(uint8_t* p_flag);
+static tNFC_STATUS rw_t3t_unselect(uint8_t peer_nfcid2[]);
+static NFC_HDR* rw_t3t_get_cmd_buf(void);
+static tNFC_STATUS rw_t3t_send_to_lower(NFC_HDR* p_msg);
+static void rw_t3t_handle_get_system_codes_cplt(void);
+static void rw_t3t_handle_get_sc_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
+                                          uint8_t num_responses,
+                                          uint8_t sensf_res_buf_size,
+                                          uint8_t* p_sensf_res_buf);
+static void rw_t3t_handle_ndef_detect_poll_rsp(tRW_T3T_CB* p_cb,
+                                               uint8_t nci_status,
+                                               uint8_t num_responses,
+                                               uint8_t sensf_res_buf_size,
+                                               uint8_t* p_sensf_res_buf);
+static void rw_t3t_handle_fmt_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
+                                       uint8_t num_responses,
+                                       uint8_t sensf_res_buf_size,
+                                       uint8_t* p_sensf_res_buf);
+static void rw_t3t_handle_sro_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
+                                       uint8_t num_responses,
+                                       uint8_t sensf_res_buf_size,
+                                       uint8_t* p_sensf_res_buf);
+
+/* Default NDEF attribute information block (used when formatting Felica-Lite
+ * tags) */
+/* NBr (max block reads per cmd)*/
+#define RW_T3T_DEFAULT_FELICALITE_NBR 4
+/* NBw (max block write per cmd)*/
+#define RW_T3T_DEFAULT_FELICALITE_NBW 1
+#define RW_T3T_DEFAULT_FELICALITE_NMAXB (T3T_FELICALITE_NMAXB)
+#define RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM                       \
+  ((T3T_MSG_NDEF_VERSION + RW_T3T_DEFAULT_FELICALITE_NBR +                   \
+    RW_T3T_DEFAULT_FELICALITE_NBW + (RW_T3T_DEFAULT_FELICALITE_NMAXB >> 8) + \
+    (RW_T3T_DEFAULT_FELICALITE_NMAXB & 0xFF) + T3T_MSG_NDEF_WRITEF_OFF +     \
+    T3T_MSG_NDEF_RWFLAG_RW) &                                                \
+   0xFFFF)
+
+const uint8_t rw_t3t_default_attrib_info[T3T_MSG_BLOCKSIZE] = {
+    T3T_MSG_NDEF_VERSION,                     /* Ver                          */
+    RW_T3T_DEFAULT_FELICALITE_NBR,            /* NBr (max block reads per cmd)*/
+    RW_T3T_DEFAULT_FELICALITE_NBW,            /* NBw (max block write per cmd)*/
+    (RW_T3T_DEFAULT_FELICALITE_NMAXB >> 8),   /* Nmaxb (max size in blocks)   */
+    (RW_T3T_DEFAULT_FELICALITE_NMAXB & 0xFF), /* Nmaxb (max size in blocks)   */
+    0, 0, 0, 0,                               /* Unused                       */
+    T3T_MSG_NDEF_WRITEF_OFF,                  /* WriteF                       */
+    T3T_MSG_NDEF_RWFLAG_RW,                   /* RW Flag                      */
+    0, 0, 0,                                  /* Ln (current size in bytes)   */
+
+    (RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM >>
+     8), /* checksum (high-byte) */
+    (RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM &
+     0xFF) /* checksum (low-byte)  */
+
+};
+
+/* This is (T/t3t * 4^E) , E is the index of the array. The unit is .0001 ms */
+static const uint32_t rw_t3t_mrti_base[] = {302, 1208, 4832, 19328};
+
+/*******************************************************************************
+**
+** Function         rw_t3t_check_timeout
+**
+** Description      The timeout value is a + b * number_blocks)
+**
+** Returns          timeout value in ticks
+**
+*******************************************************************************/
+static uint32_t rw_t3t_check_timeout(uint16_t num_blocks) {
+  tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
+  uint32_t timeout;
+  uint32_t extra;
+
+  timeout = (p_cb->check_tout_a + num_blocks * p_cb->check_tout_b) *
+            QUICK_TIMER_TICKS_PER_SEC / 1000000;
+  /* allow some extra time for driver */
+  extra = (timeout / 10) + RW_T3T_MIN_TIMEOUT_TICKS;
+  timeout += extra;
+
+  return timeout;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t3t_update_timeout
+**
+** Description      The timeout value is a + b * number_blocks)
+**
+** Returns          timeout value in ticks
+**
+*******************************************************************************/
+static uint32_t rw_t3t_update_timeout(uint16_t num_blocks) {
+  tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
+  uint32_t timeout;
+  uint32_t extra;
+
+  timeout = (p_cb->update_tout_a + num_blocks * p_cb->update_tout_b) *
+            QUICK_TIMER_TICKS_PER_SEC / 1000000;
+  /* allow some extra time for driver */
+  extra = (timeout / 10) + RW_T3T_MIN_TIMEOUT_TICKS;
+  timeout += extra;
+
+  return timeout;
+}
+/*******************************************************************************
+**
+** Function         rw_t3t_process_error
+**
+** Description      Process error (timeout or CRC error)
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t3t_process_error(tNFC_STATUS status) {
+  tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
+  uint8_t evt;
+  tRW_DATA evt_data;
+  NFC_HDR* p_cmd_buf;
+
+  if (p_cb->rw_state == RW_T3T_STATE_COMMAND_PENDING) {
+    if (p_cb->cur_cmd == RW_T3T_CMD_GET_SYSTEM_CODES) {
+      /* For GetSystemCode: tag did not respond to requested POLL */
+      rw_t3t_handle_get_system_codes_cplt();
+      return;
+    }
+    /* Retry sending command if retry-count < max */
+    else if (rw_cb.cur_retry < RW_MAX_RETRIES) {
+      /* retry sending the command */
+      rw_cb.cur_retry++;
+
+      RW_TRACE_DEBUG2("T3T retransmission attempt %i of %i", rw_cb.cur_retry,
+                      RW_MAX_RETRIES);
+
+      /* allocate a new buffer for message */
+      p_cmd_buf = rw_t3t_get_cmd_buf();
+      if (p_cmd_buf != NULL) {
+        memcpy(p_cmd_buf, p_cb->p_cur_cmd_buf, sizeof(NFC_HDR) +
+                                                   p_cb->p_cur_cmd_buf->offset +
+                                                   p_cb->p_cur_cmd_buf->len);
+
+        if (rw_t3t_send_to_lower(p_cmd_buf) == NFC_STATUS_OK) {
+          /* Start timer for waiting for response */
+          nfc_start_quick_timer(&p_cb->timer, NFC_TTYPE_RW_T3T_RESPONSE,
+                                p_cb->cur_tout);
+          return;
+        } else {
+          /* failure - could not send buffer */
+          GKI_freebuf(p_cmd_buf);
+        }
+      }
+    } else {
+      RW_TRACE_DEBUG1("T3T maximum retransmission attempts reached (%i)",
+                      RW_MAX_RETRIES);
+    }
+
+#if (RW_STATS_INCLUDED == true)
+    /* update failure count */
+    rw_main_update_fail_stats();
+#endif /* RW_STATS_INCLUDED */
+
+    p_cb->rw_state = RW_T3T_STATE_IDLE;
+
+    /* Notify app of result (if there was a pending command) */
+    if (p_cb->cur_cmd < RW_T3T_CMD_MAX) {
+      /* If doing presence check, use status=NFC_STATUS_FAILED, otherwise
+       * NFC_STATUS_TIMEOUT */
+      evt_data.status = status;
+      evt = rw_t3t_api_res_evt[p_cb->cur_cmd];
+
+      /* Set additional flags for RW_T3T_NDEF_DETECT_EVT */
+      if (evt == RW_T3T_NDEF_DETECT_EVT) {
+        evt_data.ndef.flags = RW_NDEF_FL_UNKNOWN;
+        rw_t3t_update_ndef_flag(&evt_data.ndef.flags);
+      }
+
+      (*(rw_cb.p_cback))(evt, &evt_data);
+    }
+  } else {
+    evt_data.status = status;
+    (*(rw_cb.p_cback))(RW_T3T_INTF_ERROR_EVT, &evt_data);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t3t_start_poll_timer
+**
+** Description      Start the timer for T3T POLL Command
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t3t_start_poll_timer(tRW_T3T_CB* p_cb) {
+  RW_TRACE_DEBUG1 ("%s: starting t3t poll timer", __func__);
+  nfc_start_quick_timer(&p_cb->poll_timer, NFC_TTYPE_RW_T3T_RESPONSE,
+                        RW_T3T_POLL_CMD_TIMEOUT_TICKS);
+}
+
+#if (NXP_EXTNS == TRUE)
+/*******************************************************************************
+**
+** Function         rw_t3t_stop_poll_timer
+**
+** Description      Stop the timer for T3T POLL Command
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t3t_stop_poll_timer (tRW_T3T_CB *p_cb)
+{
+    RW_TRACE_DEBUG1 ("%s: stopping t3t poll timer", __func__);
+    if(p_cb->poll_timer.in_use)
+        nfc_stop_quick_timer (&p_cb->poll_timer);
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         rw_t3t_handle_nci_poll_ntf
+**
+** Description      Handle NCI_T3T_POLLING_NTF
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t3t_handle_nci_poll_ntf(uint8_t nci_status, uint8_t num_responses,
+                                uint8_t sensf_res_buf_size,
+                                uint8_t* p_sensf_res_buf) {
+  tRW_DATA evt_data;
+  tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
+
+  /* stop timer for poll response */
+  #if (NXP_EXTNS == TRUE)
+    rw_t3t_stop_poll_timer (p_cb);
+  #else
+    nfc_stop_quick_timer(&p_cb->poll_timer);
+  #endif
+
+  /* Stop t3t timer (if started) */
+  if (p_cb->flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP) {
+    p_cb->flags &= ~RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
+    evt_data.status = nci_status;
+    p_cb->rw_state = RW_T3T_STATE_IDLE;
+    (*(rw_cb.p_cback))(RW_T3T_PRESENCE_CHECK_EVT, (tRW_DATA*)&evt_data);
+  } else if (p_cb->flags & RW_T3T_FL_W4_GET_SC_POLL_RSP) {
+    /* Handle POLL ntf in response to get system codes */
+    p_cb->flags &= ~RW_T3T_FL_W4_GET_SC_POLL_RSP;
+    rw_t3t_handle_get_sc_poll_rsp(p_cb, nci_status, num_responses,
+                                  sensf_res_buf_size, p_sensf_res_buf);
+  } else if (p_cb->flags & RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP) {
+    /* Handle POLL ntf in response to get system codes */
+    p_cb->flags &= ~RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
+    rw_t3t_handle_fmt_poll_rsp(p_cb, nci_status, num_responses,
+                               sensf_res_buf_size, p_sensf_res_buf);
+  } else if (p_cb->flags & RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP) {
+    /* Handle POLL ntf in response to get system codes */
+    p_cb->flags &= ~RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP;
+    rw_t3t_handle_sro_poll_rsp(p_cb, nci_status, num_responses,
+                               sensf_res_buf_size, p_sensf_res_buf);
+  } else if (p_cb->flags & RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP) {
+    /* Handle POLL ntf in response to ndef detection */
+    p_cb->flags &= ~RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
+    rw_t3t_handle_ndef_detect_poll_rsp(p_cb, nci_status, num_responses,
+                                       sensf_res_buf_size, p_sensf_res_buf);
+  } else {
+    /* Handle POLL ntf in response to RW_T3tPoll */
+    evt_data.t3t_poll.status = nci_status;
+    if (evt_data.t3t_poll.status == NCI_STATUS_OK) {
+      evt_data.t3t_poll.rc = p_cb->cur_poll_rc;
+      evt_data.t3t_poll.response_num = num_responses;
+      evt_data.t3t_poll.response_bufsize = sensf_res_buf_size;
+      evt_data.t3t_poll.response_buf = p_sensf_res_buf;
+    }
+
+    p_cb->rw_state = RW_T3T_STATE_IDLE;
+    (*(rw_cb.p_cback))(RW_T3T_POLL_EVT, &evt_data);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t3t_handle_get_system_codes_cplt
+**
+** Description      Notify upper layer of system codes
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t3t_handle_get_system_codes_cplt(void) {
+  tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
+  tRW_DATA evt_data;
+  uint8_t i;
+
+  evt_data.t3t_sc.status = NFC_STATUS_OK;
+  evt_data.t3t_sc.num_system_codes = p_cb->num_system_codes;
+  evt_data.t3t_sc.p_system_codes = p_cb->system_codes;
+
+  RW_TRACE_DEBUG1("rw_t3t_handle_get_system_codes_cplt, number of systems: %i",
+                  evt_data.t3t_sc.num_system_codes);
+  for (i = 0; i < evt_data.t3t_sc.num_system_codes; i++) {
+    RW_TRACE_DEBUG2("   system %i: %04X", i, evt_data.t3t_sc.p_system_codes[i]);
+  }
+
+  p_cb->rw_state = RW_T3T_STATE_IDLE;
+  (*(rw_cb.p_cback))(RW_T3T_GET_SYSTEM_CODES_EVT, &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         rw_t3t_format_cplt
+**
+** Description      Notify upper layer of format complete
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t3t_format_cplt(tNFC_STATUS status) {
+  tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
+  tRW_DATA evt_data;
+
+  p_cb->rw_state = RW_T3T_STATE_IDLE;
+
+  /* Update ndef info */
+  p_cb->ndef_attrib.status = status;
+  if (status == NFC_STATUS_OK) {
+    p_cb->ndef_attrib.version = T3T_MSG_NDEF_VERSION;
+    p_cb->ndef_attrib.nbr = RW_T3T_DEFAULT_FELICALITE_NBR;
+    p_cb->ndef_attrib.nbw = RW_T3T_DEFAULT_FELICALITE_NBW;
+    p_cb->ndef_attrib.nmaxb = RW_T3T_DEFAULT_FELICALITE_NMAXB;
+    p_cb->ndef_attrib.writef = T3T_MSG_NDEF_WRITEF_OFF;
+    p_cb->ndef_attrib.rwflag = T3T_MSG_NDEF_RWFLAG_RW;
+    p_cb->ndef_attrib.ln = 0;
+  }
+
+  /* Notify upper layer of format complete */
+  evt_data.status = status;
+  (*(rw_cb.p_cback))(RW_T3T_FORMAT_CPLT_EVT, &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         rw_t3t_set_readonly_cplt
+**
+** Description      Notify upper layer of set read only complete
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t3t_set_readonly_cplt(tNFC_STATUS status) {
+  tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
+  tRW_DATA evt_data;
+
+  p_cb->rw_state = RW_T3T_STATE_IDLE;
+
+  /* Notify upper layer of format complete */
+  evt_data.status = status;
+  (*(rw_cb.p_cback))(RW_T3T_SET_READ_ONLY_CPLT_EVT, &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         rw_t3t_process_timeout
+**
+** Description      Process timeout
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t3t_process_timeout(TIMER_LIST_ENT* p_tle) {
+  tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
+  tRW_DATA evt_data;
+
+  /* Check which timer timed out */
+  if (p_tle == &p_cb->timer) {
+/* UPDATE/CHECK response timeout */
+#if (BT_TRACE_VERBOSE == true)
+    RW_TRACE_ERROR3("T3T timeout. state=%s cur_cmd=0x%02X (%s)",
+                    rw_t3t_state_str(rw_cb.tcb.t3t.rw_state),
+                    rw_cb.tcb.t3t.cur_cmd,
+                    rw_t3t_cmd_str(rw_cb.tcb.t3t.cur_cmd));
+#else
+    RW_TRACE_ERROR2("T3T timeout. state=0x%02X cur_cmd=0x%02X",
+                    rw_cb.tcb.t3t.rw_state, rw_cb.tcb.t3t.cur_cmd);
+#endif
+
+    rw_t3t_process_error(NFC_STATUS_TIMEOUT);
+  } else {
+    RW_TRACE_ERROR0("T3T POLL timeout.");
+
+    /* POLL response timeout */
+    if (p_cb->flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP) {
+      /* POLL timeout for presence check */
+      p_cb->flags &= ~RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
+      evt_data.status = NFC_STATUS_FAILED;
+      p_cb->rw_state = RW_T3T_STATE_IDLE;
+      (*(rw_cb.p_cback))(RW_T3T_PRESENCE_CHECK_EVT, (tRW_DATA*)&evt_data);
+    } else if (p_cb->flags & RW_T3T_FL_W4_GET_SC_POLL_RSP) {
+      /* POLL timeout for getting system codes */
+      p_cb->flags &= ~RW_T3T_FL_W4_GET_SC_POLL_RSP;
+      rw_t3t_handle_get_system_codes_cplt();
+    } else if (p_cb->flags & RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP) {
+      /* POLL timeout for formatting Felica Lite */
+      p_cb->flags &= ~RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
+      RW_TRACE_ERROR0("Felica-Lite tag not detected");
+      rw_t3t_format_cplt(NFC_STATUS_FAILED);
+    } else if (p_cb->flags & RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP) {
+      /* POLL timeout for configuring Felica Lite read only */
+      p_cb->flags &= ~RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP;
+      RW_TRACE_ERROR0("Felica-Lite tag not detected");
+      rw_t3t_set_readonly_cplt(NFC_STATUS_FAILED);
+    } else if (p_cb->flags & RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP) {
+      /* POLL timeout for ndef detection */
+      p_cb->flags &= ~RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
+      rw_t3t_handle_ndef_detect_poll_rsp(p_cb, NFC_STATUS_TIMEOUT, 0, 0, NULL);
+    } else {
+      /* Timeout waiting for response for RW_T3tPoll */
+      evt_data.t3t_poll.status = NFC_STATUS_FAILED;
+      p_cb->rw_state = RW_T3T_STATE_IDLE;
+      (*(rw_cb.p_cback))(RW_T3T_POLL_EVT, (tRW_DATA*)&evt_data);
+    }
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t3t_process_frame_error
+**
+** Description      Process frame crc error
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t3t_process_frame_error(void) {
+#if (BT_TRACE_VERBOSE == true)
+  RW_TRACE_ERROR3("T3T frame error. state=%s cur_cmd=0x%02X (%s)",
+                  rw_t3t_state_str(rw_cb.tcb.t3t.rw_state),
+                  rw_cb.tcb.t3t.cur_cmd, rw_t3t_cmd_str(rw_cb.tcb.t3t.cur_cmd));
+#else
+  RW_TRACE_ERROR2("T3T frame error. state=0x%02X cur_cmd=0x%02X",
+                  rw_cb.tcb.t3t.rw_state, rw_cb.tcb.t3t.cur_cmd);
+#endif
+
+#if (RW_STATS_INCLUDED == true)
+  /* Update stats */
+  rw_main_update_crc_error_stats();
+#endif /* RW_STATS_INCLUDED */
+
+  /* Process the error */
+  rw_t3t_process_error(NFC_STATUS_MSG_CORRUPTED);
+}
+
+/*******************************************************************************
+**
+** Function         rw_t3t_send_to_lower
+**
+** Description      Send command to lower layer
+**
+** Returns          status of the send
+**
+*******************************************************************************/
+tNFC_STATUS rw_t3t_send_to_lower(NFC_HDR* p_msg) {
+  uint8_t* p;
+
+#if (RW_STATS_INCLUDED == true)
+  bool is_retry;
+  /* Update stats */
+  rw_main_update_tx_stats(p_msg->len, ((rw_cb.cur_retry == 0) ? false : true));
+#endif /* RW_STATS_INCLUDED */
+
+  /* Set NFC-F SoD field (payload len + 1) */
+  p_msg->offset -= 1; /* Point to SoD field */
+  p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+  UINT8_TO_STREAM(p, (p_msg->len + 1));
+  p_msg->len += 1; /* Increment len to include SoD */
+
+#if (BT_TRACE_PROTOCOL == true)
+  DispT3TagMessage(p_msg, false);
+#endif
+
+  return (NFC_SendData(NFC_RF_CONN_ID, p_msg));
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_get_cmd_buf
+**
+** Description      Get a buffer for sending T3T messages
+**
+** Returns          NFC_HDR *
+**
+*****************************************************************************/
+NFC_HDR* rw_t3t_get_cmd_buf(void) {
+  NFC_HDR* p_cmd_buf;
+
+  p_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+  if (p_cmd_buf != NULL) {
+    /* Reserve offset for NCI_DATA_HDR and NFC-F Sod (LEN) field */
+    p_cmd_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + 1;
+    p_cmd_buf->len = 0;
+  }
+
+  return (p_cmd_buf);
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_send_cmd
+**
+** Description      Send command to tag, and start timer for response
+**
+** Returns          tNFC_STATUS
+**
+*****************************************************************************/
+tNFC_STATUS rw_t3t_send_cmd(tRW_T3T_CB* p_cb, uint8_t rw_t3t_cmd,
+                            NFC_HDR* p_cmd_buf, uint32_t timeout_ticks) {
+  tNFC_STATUS retval;
+
+  /* Indicate first attempt to send command, back up cmd buffer in case needed
+   * for retransmission */
+  rw_cb.cur_retry = 0;
+  memcpy(p_cb->p_cur_cmd_buf, p_cmd_buf,
+         sizeof(NFC_HDR) + p_cmd_buf->offset + p_cmd_buf->len);
+
+  p_cb->cur_cmd = rw_t3t_cmd;
+  p_cb->cur_tout = timeout_ticks;
+  p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
+
+  retval = rw_t3t_send_to_lower(p_cmd_buf);
+  if (retval == NFC_STATUS_OK) {
+    /* Start timer for waiting for response */
+    nfc_start_quick_timer(&p_cb->timer, NFC_TTYPE_RW_T3T_RESPONSE,
+                          timeout_ticks);
+  } else {
+    /* Error sending */
+    p_cb->rw_state = RW_T3T_STATE_IDLE;
+  }
+
+  RW_TRACE_DEBUG3("rw_t3t_send_cmd: cur_tout: %d, timeout_ticks: %d ret:%d",
+                  p_cb->cur_tout, timeout_ticks, retval);
+  return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_send_update_ndef_attribute_cmd
+**
+** Description      Send UPDATE command for Attribute Information
+**
+** Returns          tNFC_STATUS
+**
+*****************************************************************************/
+tNFC_STATUS rw_t3t_send_update_ndef_attribute_cmd(tRW_T3T_CB* p_cb,
+                                                  bool write_in_progress) {
+  tNFC_STATUS retval = NFC_STATUS_OK;
+  NFC_HDR* p_cmd_buf;
+  uint8_t* p_cmd_start, *p;
+  uint16_t checksum, i;
+  uint8_t write_f;
+  uint32_t ln;
+  uint8_t* p_ndef_attr_info_start;
+
+  p_cmd_buf = rw_t3t_get_cmd_buf();
+  if (p_cmd_buf != NULL) {
+    /* Construct T3T message */
+    p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
+
+    /* Add UPDATE opcode to message  */
+    UINT8_TO_STREAM(p, T3T_MSG_OPC_UPDATE_CMD);
+
+    /* Add IDm to message */
+    ARRAY_TO_STREAM(p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
+
+    /* Add Service code list */
+    UINT8_TO_STREAM(p, 1); /* Number of services (only 1 service: NDEF) */
+    UINT16_TO_STREAM(
+        p, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */
+
+    /* Add number of blocks in this UPDATE command */
+    UINT8_TO_STREAM(p, 1); /* Number of blocks to write in this command */
+
+    /* Block List element: the NDEF attribute information block (block 0) */
+    UINT8_TO_STREAM(p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
+    UINT8_TO_STREAM(p, 0);
+
+    /* Add payload (Attribute information block) */
+    p_ndef_attr_info_start =
+        p; /* Save start of a NDEF attribute info block for checksum */
+    UINT8_TO_STREAM(p, T3T_MSG_NDEF_VERSION);
+    UINT8_TO_STREAM(p, p_cb->ndef_attrib.nbr);
+    UINT8_TO_STREAM(p, p_cb->ndef_attrib.nbw);
+    UINT16_TO_BE_STREAM(p, p_cb->ndef_attrib.nmaxb);
+    UINT32_TO_STREAM(p, 0);
+
+    /* If starting NDEF write: set WriteF=ON, and ln=current ndef length */
+    if (write_in_progress) {
+      write_f = T3T_MSG_NDEF_WRITEF_ON;
+      ln = p_cb->ndef_attrib.ln;
+    }
+    /* If finishing NDEF write: set WriteF=OFF, and ln=new ndef len */
+    else {
+      write_f = T3T_MSG_NDEF_WRITEF_OFF;
+      ln = p_cb->ndef_msg_len;
+    }
+    UINT8_TO_STREAM(p, write_f);
+    UINT8_TO_STREAM(p, p_cb->ndef_attrib.rwflag);
+    UINT8_TO_STREAM(p, (ln >> 16) & 0xFF); /* High byte (of 3) of Ln */
+    UINT8_TO_STREAM(p, (ln >> 8) & 0xFF);  /* Middle byte (of 3) of Ln */
+    UINT8_TO_STREAM(p, (ln)&0xFF);         /* Low byte (of 3) of Ln */
+
+    /* Calculate and append Checksum */
+    checksum = 0;
+    for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++) {
+      checksum += p_ndef_attr_info_start[i];
+    }
+    UINT16_TO_BE_STREAM(p, checksum);
+
+    /* Calculate length of message */
+    p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
+
+    /* Send the T3T message */
+    retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_UPDATE_NDEF, p_cmd_buf,
+                             rw_t3t_update_timeout(1));
+  } else {
+    retval = NFC_STATUS_NO_BUFFERS;
+  }
+
+  return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_send_next_ndef_update_cmd
+**
+** Description      Send next segment of NDEF message to update
+**
+** Returns          tNFC_STATUS
+**
+*****************************************************************************/
+tNFC_STATUS rw_t3t_send_next_ndef_update_cmd(tRW_T3T_CB* p_cb) {
+  tNFC_STATUS retval = NFC_STATUS_OK;
+  uint16_t block_id;
+  uint16_t first_block_to_write;
+  uint16_t ndef_blocks_to_write, ndef_blocks_remaining;
+  uint32_t ndef_bytes_remaining, ndef_padding = 0;
+  uint8_t flags = 0;
+  uint8_t* p_cur_ndef_src_offset;
+  NFC_HDR* p_cmd_buf;
+  uint8_t* p_cmd_start, *p;
+  uint8_t blocks_per_update;
+  uint32_t timeout;
+
+  p_cmd_buf = rw_t3t_get_cmd_buf();
+  if (p_cmd_buf != NULL) {
+    /* Construct T3T message */
+    p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
+
+    /* Calculate number of ndef bytes remaining to write */
+    ndef_bytes_remaining = p_cb->ndef_msg_len - p_cb->ndef_msg_bytes_sent;
+
+    /* Calculate number of blocks remaining to write */
+    ndef_blocks_remaining =
+        (uint16_t)((ndef_bytes_remaining + 15) >>
+                   4); /* ndef blocks remaining (rounded upward) */
+
+    /* Calculate first NDEF block ID for this UPDATE command */
+    first_block_to_write = (uint16_t)((p_cb->ndef_msg_bytes_sent >> 4) + 1);
+
+    /* Calculate max number of blocks per write. */
+    if ((first_block_to_write +
+         RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT) < 0x100) {
+      /* All block-numbers are < 0x100 (i.e. can be specified using one-byte
+       * format) */
+      blocks_per_update = RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT;
+    } else {
+      /* Block-numbers are >= 0x100 (i.e. need to be specified using two-byte
+       * format) */
+      blocks_per_update = RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_2_BYTE_FORMAT;
+    }
+
+    /* Check if blocks_per_update is bigger than what peer allows */
+    if (blocks_per_update > p_cb->ndef_attrib.nbw)
+      blocks_per_update = p_cb->ndef_attrib.nbw;
+
+    /* Check if remaining blocks can fit into one UPDATE command */
+    if (ndef_blocks_remaining <= blocks_per_update) {
+      /* remaining blocks can fit into one UPDATE command */
+      ndef_blocks_to_write = ndef_blocks_remaining;
+    } else {
+      /* Remaining blocks cannot fit into one UPDATE command */
+      ndef_blocks_to_write = blocks_per_update;
+    }
+
+    /* Write to command header for UPDATE */
+
+    /* Add UPDATE opcode to message  */
+    UINT8_TO_STREAM(p, T3T_MSG_OPC_UPDATE_CMD);
+
+    /* Add IDm to message */
+    ARRAY_TO_STREAM(p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
+
+    /* Add Service code list */
+    UINT8_TO_STREAM(p, 1); /* Number of services (only 1 service: NDEF) */
+    UINT16_TO_STREAM(
+        p, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */
+
+    /* Add number of blocks in this UPDATE command */
+    UINT8_TO_STREAM(
+        p,
+        ndef_blocks_to_write); /* Number of blocks to write in this command */
+    timeout = rw_t3t_update_timeout(ndef_blocks_to_write);
+
+    for (block_id = first_block_to_write;
+         block_id < (first_block_to_write + ndef_blocks_to_write); block_id++) {
+      if (block_id < 256) {
+        /* Block IDs 0-255 can be specified in '2-byte' format: byte0=0,
+         * byte1=blocknumber */
+        UINT8_TO_STREAM(
+            p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT); /* byte0: len=1;
+                                                            access-mode=0;
+                                                            service code list
+                                                            order=0 */
+        UINT8_TO_STREAM(p, block_id); /* byte1: block number */
+      } else {
+        /* Block IDs 256+ must be specified in '3-byte' format: byte0=80h,
+         * followed by blocknumber */
+        UINT8_TO_STREAM(
+            p,
+            0x00); /* byte0: len=0; access-mode=0; service code list order=0 */
+        UINT16_TO_STREAM(
+            p, block_id); /* byte1-2: block number in little-endian format */
+      }
+    }
+
+    /* Add NDEF payload */
+
+    /* If this sending last block of NDEF,  check if padding is needed to make
+     * payload a multiple of 16 bytes */
+    if (ndef_blocks_to_write == ndef_blocks_remaining) {
+      ndef_padding = (16 - (ndef_bytes_remaining & 0x0F)) & 0x0F;
+      if (ndef_padding) {
+        flags |= RW_T3T_FL_PADDING;
+        ndef_blocks_to_write--; /* handle the last block separately if it needs
+                                   padding */
+      }
+    }
+
+    /* Add NDEF payload to the message */
+    p_cur_ndef_src_offset = &p_cb->ndef_msg[p_cb->ndef_msg_bytes_sent];
+
+    ARRAY_TO_STREAM(p, p_cur_ndef_src_offset, (ndef_blocks_to_write * 16));
+    p_cb->ndef_msg_bytes_sent += ((uint32_t)ndef_blocks_to_write * 16);
+
+    if (flags & RW_T3T_FL_PADDING) {
+      /* Add last of the NDEF message */
+      p_cur_ndef_src_offset = &p_cb->ndef_msg[p_cb->ndef_msg_bytes_sent];
+      ARRAY_TO_STREAM(p, p_cur_ndef_src_offset, (int)(16 - ndef_padding));
+      p_cb->ndef_msg_bytes_sent += (16 - ndef_padding);
+
+      /* Add padding */
+      memset(p, 0, ndef_padding);
+      p += ndef_padding;
+    }
+
+    /* Calculate length of message */
+    p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
+
+    /* Send the T3T message */
+    retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_UPDATE_NDEF, p_cmd_buf, timeout);
+  } else {
+    retval = NFC_STATUS_NO_BUFFERS;
+  }
+
+  return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_send_next_ndef_check_cmd
+**
+** Description      Send command for reading next segment of NDEF message
+**
+** Returns          tNFC_STATUS
+**
+*****************************************************************************/
+tNFC_STATUS rw_t3t_send_next_ndef_check_cmd(tRW_T3T_CB* p_cb) {
+  tNFC_STATUS retval = NFC_STATUS_OK;
+  uint16_t block_id;
+  uint16_t ndef_blocks_remaining, first_block_to_read, cur_blocks_to_read;
+  uint32_t ndef_bytes_remaining;
+  NFC_HDR* p_cmd_buf;
+  uint8_t* p_cmd_start, *p;
+
+  p_cmd_buf = rw_t3t_get_cmd_buf();
+  if (p_cmd_buf != NULL) {
+    /* Construct T3T message */
+    p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
+
+    /* Calculate number of ndef bytes remaining to read */
+    ndef_bytes_remaining = p_cb->ndef_attrib.ln - p_cb->ndef_rx_offset;
+
+    /* Calculate number of blocks remaining to read */
+    ndef_blocks_remaining =
+        (uint16_t)((ndef_bytes_remaining + 15) >>
+                   4); /* ndef blocks remaining (rounded upward) */
+
+    /* Calculate first NDEF block ID */
+    first_block_to_read = (uint16_t)((p_cb->ndef_rx_offset >> 4) + 1);
+
+    /* Check if remaining blocks can fit into one CHECK command */
+    if (ndef_blocks_remaining <= p_cb->ndef_attrib.nbr) {
+      /* remaining blocks can fit into one CHECK command */
+      cur_blocks_to_read = ndef_blocks_remaining;
+      p_cb->ndef_rx_readlen = ndef_bytes_remaining;
+      p_cb->flags |= RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
+    } else {
+      /* Remaining blocks cannot fit into one CHECK command */
+      cur_blocks_to_read =
+          p_cb->ndef_attrib
+              .nbr; /* Read maximum number of blocks allowed by the peer */
+      p_cb->ndef_rx_readlen = ((uint32_t)p_cb->ndef_attrib.nbr * 16);
+    }
+
+    RW_TRACE_DEBUG3(
+        "rw_t3t_send_next_ndef_check_cmd: bytes_remaining: %i, "
+        "cur_blocks_to_read: %i, is_final: %i",
+        ndef_bytes_remaining, cur_blocks_to_read,
+        (p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT));
+
+    /* Add CHECK opcode to message  */
+    UINT8_TO_STREAM(p, T3T_MSG_OPC_CHECK_CMD);
+
+    /* Add IDm to message */
+    ARRAY_TO_STREAM(p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
+
+    /* Add Service code list */
+    UINT8_TO_STREAM(p, 1); /* Number of services (only 1 service: NDEF) */
+
+    /* Service code (little-endian format) . If NDEF is read-only, then use
+     * T3T_MSG_NDEF_SC_RO, otherwise use T3T_MSG_NDEF_SC_RW */
+    if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO) {
+      UINT16_TO_STREAM(p, T3T_MSG_NDEF_SC_RO);
+    } else {
+      UINT16_TO_STREAM(p, T3T_MSG_NDEF_SC_RW);
+    }
+
+    /* Add number of blocks in this CHECK command */
+    UINT8_TO_STREAM(
+        p, cur_blocks_to_read); /* Number of blocks to check in this command */
+
+    for (block_id = first_block_to_read;
+         block_id < (first_block_to_read + cur_blocks_to_read); block_id++) {
+      if (block_id < 256) {
+        /* Block IDs 0-255 can be specified in '2-byte' format: byte0=0,
+         * byte1=blocknumber */
+        UINT8_TO_STREAM(
+            p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT); /* byte1: len=0;
+                                                            access-mode=0;
+                                                            service code list
+                                                            order=0 */
+        UINT8_TO_STREAM(p, block_id); /* byte1: block number */
+      } else {
+        /* Block IDs 256+ must be specified in '3-byte' format: byte0=80h,
+         * followed by blocknumber */
+        UINT8_TO_STREAM(
+            p,
+            0x00); /* byte0: len=1; access-mode=0; service code list order=0 */
+        UINT16_TO_STREAM(
+            p, block_id); /* byte1-2: block number in little-endian format */
+      }
+    }
+
+    /* Calculate length of message */
+    p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
+
+    /* Send the T3T message */
+    retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_CHECK_NDEF, p_cmd_buf,
+                             rw_t3t_check_timeout(cur_blocks_to_read));
+  } else {
+    retval = NFC_STATUS_NO_BUFFERS;
+  }
+
+  return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_message_set_block_list
+**
+** Description      Add block list to T3T message
+**
+** Returns          Number of bytes added to message
+**
+*****************************************************************************/
+void rw_t3t_message_set_block_list(tRW_T3T_CB* p_cb, uint8_t** p,
+                                   uint8_t num_blocks,
+                                   tT3T_BLOCK_DESC* p_t3t_blocks) {
+  uint16_t i, cur_service_code;
+  uint8_t service_code_idx, num_services = 0;
+  uint8_t* p_msg_num_services;
+  uint16_t service_list[T3T_MSG_SERVICE_LIST_MAX];
+
+  /* Add CHECK or UPDATE opcode to message  */
+  UINT8_TO_STREAM(
+      (*p), ((p_cb->cur_cmd == RW_T3T_CMD_CHECK) ? T3T_MSG_OPC_CHECK_CMD
+                                                 : T3T_MSG_OPC_UPDATE_CMD));
+
+  /* Add IDm to message */
+  ARRAY_TO_STREAM((*p), p_cb->peer_nfcid2, NCI_NFCID2_LEN);
+
+  /* Skip over Number of Services field */
+  p_msg_num_services = (*p); /* pointer to Number of Services offset */
+  (*p)++;
+
+  /* Count number of different services are specified in the list, and add
+   * services to Service Code list */
+  for (i = 0; i < num_blocks; i++) {
+    cur_service_code = p_t3t_blocks[i].service_code;
+
+    /* Check if current service_code is already in the service_list */
+    for (service_code_idx = 0; service_code_idx < num_services;
+         service_code_idx++) {
+      if (service_list[service_code_idx] == cur_service_code) break;
+    }
+
+    if (service_code_idx == num_services) {
+      /* Service not in the list yet. Add it. */
+      service_list[service_code_idx] = cur_service_code;
+      num_services++;
+
+      /* Add service code to T3T message */
+      UINT16_TO_STREAM((*p), cur_service_code);
+    }
+  }
+
+  /* Add 'Number of Sservices' to the message */
+  *p_msg_num_services = num_services;
+
+  /* Add 'number of blocks' to the message */
+  UINT8_TO_STREAM((*p), num_blocks);
+
+  /* Add block descriptors */
+  for (i = 0; i < num_blocks; i++) {
+    cur_service_code = p_t3t_blocks[i].service_code;
+
+    /* Check if current service_code is already in the service_list */
+    for (service_code_idx = 0; service_code_idx < num_services;
+         service_code_idx++) {
+      if (service_list[service_code_idx] == cur_service_code) break;
+    }
+
+    /* Add decriptor to T3T message */
+    if (p_t3t_blocks[i].block_number > 0xFF) {
+      UINT8_TO_STREAM((*p), service_code_idx);
+      UINT16_TO_STREAM((*p), p_t3t_blocks[i].block_number);
+    } else {
+      service_code_idx |= T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT;
+      UINT8_TO_STREAM((*p), service_code_idx);
+      UINT8_TO_STREAM((*p), p_t3t_blocks[i].block_number);
+    }
+  }
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_send_check_cmd
+**
+** Description      Send CHECK command
+**
+** Returns          tNFC_STATUS
+**
+*****************************************************************************/
+tNFC_STATUS rw_t3t_send_check_cmd(tRW_T3T_CB* p_cb, uint8_t num_blocks,
+                                  tT3T_BLOCK_DESC* p_t3t_blocks) {
+  NFC_HDR* p_cmd_buf;
+  uint8_t* p, *p_cmd_start;
+  tNFC_STATUS retval = NFC_STATUS_OK;
+
+  p_cb->cur_cmd = RW_T3T_CMD_CHECK;
+  p_cmd_buf = rw_t3t_get_cmd_buf();
+  if (p_cmd_buf != NULL) {
+    /* Construct T3T message */
+    p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
+    rw_t3t_message_set_block_list(p_cb, &p, num_blocks, p_t3t_blocks);
+
+    /* Calculate length of message */
+    p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
+
+    /* Send the T3T message */
+    retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_CHECK, p_cmd_buf,
+                             rw_t3t_check_timeout(num_blocks));
+  } else {
+    retval = NFC_STATUS_NO_BUFFERS;
+  }
+
+  return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_send_update_cmd
+**
+** Description      Send UPDATE command
+**
+** Returns          tNFC_STATUS
+**
+*****************************************************************************/
+tNFC_STATUS rw_t3t_send_update_cmd(tRW_T3T_CB* p_cb, uint8_t num_blocks,
+                                   tT3T_BLOCK_DESC* p_t3t_blocks,
+                                   uint8_t* p_data) {
+  NFC_HDR* p_cmd_buf;
+  uint8_t* p, *p_cmd_start;
+  tNFC_STATUS retval = NFC_STATUS_OK;
+
+  p_cb->cur_cmd = RW_T3T_CMD_UPDATE;
+  p_cmd_buf = rw_t3t_get_cmd_buf();
+  if (p_cmd_buf != NULL) {
+    /* Construct T3T message */
+    p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
+    rw_t3t_message_set_block_list(p_cb, &p, num_blocks, p_t3t_blocks);
+
+    /* Add data blocks to the message */
+    ARRAY_TO_STREAM(p, p_data, num_blocks * 16);
+
+    /* Calculate length of message */
+    p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
+
+    /* Send the T3T message */
+    retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_UPDATE, p_cmd_buf,
+                             rw_t3t_update_timeout(num_blocks));
+  } else {
+    retval = NFC_STATUS_NO_BUFFERS;
+  }
+
+  return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_check_mc_block
+**
+** Description      Send command to check Memory Configuration Block
+**
+** Returns          tNFC_STATUS
+**
+*****************************************************************************/
+tNFC_STATUS rw_t3t_check_mc_block(tRW_T3T_CB* p_cb) {
+  NFC_HDR* p_cmd_buf;
+  uint8_t* p, *p_cmd_start;
+
+  /* Read Memory Configuration block */
+  p_cmd_buf = rw_t3t_get_cmd_buf();
+  if (p_cmd_buf != NULL) {
+    /* Construct T3T message */
+    p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
+
+    /* Add CHECK opcode to message  */
+    UINT8_TO_STREAM(p, T3T_MSG_OPC_CHECK_CMD);
+
+    /* Add IDm to message */
+    ARRAY_TO_STREAM(p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
+
+    /* Add Service code list */
+    UINT8_TO_STREAM(p, 1); /* Number of services (only 1 service: NDEF) */
+    UINT16_TO_STREAM(
+        p, T3T_MSG_NDEF_SC_RO); /* Service code (little-endian format) */
+
+    /* Number of blocks */
+    UINT8_TO_STREAM(p, 1); /* Number of blocks (only 1 block: Memory
+                              Configuration Information ) */
+
+    /* Block List element: the Memory Configuration block (block 0x88) */
+    UINT8_TO_STREAM(p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
+    UINT8_TO_STREAM(p, T3T_MSG_FELICALITE_BLOCK_ID_MC);
+
+    /* Calculate length of message */
+    p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
+
+    /* Send the T3T message */
+    return rw_t3t_send_cmd(p_cb, p_cb->cur_cmd, p_cmd_buf,
+                           rw_t3t_check_timeout(1));
+  } else {
+    RW_TRACE_ERROR0("Unable to allocate buffer to read MC block");
+    return (NFC_STATUS_NO_BUFFERS);
+  }
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_send_raw_frame
+**
+** Description      Send raw frame
+**
+** Returns          tNFC_STATUS
+**
+*****************************************************************************/
+tNFC_STATUS rw_t3t_send_raw_frame(tRW_T3T_CB* p_cb, uint16_t len,
+                                  uint8_t* p_data) {
+  NFC_HDR* p_cmd_buf;
+  uint8_t* p;
+  tNFC_STATUS retval = NFC_STATUS_OK;
+
+  p_cmd_buf = rw_t3t_get_cmd_buf();
+  if (p_cmd_buf != NULL) {
+    /* Construct T3T message */
+    p = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
+
+    /* Add data blocks to the message */
+    ARRAY_TO_STREAM(p, p_data, len);
+
+    /* Calculate length of message */
+    p_cmd_buf->len = len;
+
+    /* Send the T3T message */
+    retval = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_SEND_RAW_FRAME, p_cmd_buf,
+                             RW_T3T_RAW_FRAME_CMD_TIMEOUT_TICKS);
+  } else {
+    retval = NFC_STATUS_NO_BUFFERS;
+  }
+
+  return (retval);
+}
+
+/*****************************************************************************
+**  TAG RESPONSE HANDLERS
+*****************************************************************************/
+
+/*****************************************************************************
+**
+** Function         rw_t3t_act_handle_ndef_detect_rsp
+**
+** Description      Handle response to NDEF detection
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+void rw_t3t_act_handle_ndef_detect_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
+  uint8_t* p;
+  uint32_t temp;
+  uint8_t i;
+  uint16_t checksum_calc, checksum_rx;
+  tRW_DETECT_NDEF_DATA evt_data;
+  uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
+
+  evt_data.status = NFC_STATUS_FAILED;
+  evt_data.flags = RW_NDEF_FL_UNKNOWN;
+
+  /* Check if response code is CHECK resp (for reading NDEF attribute block) */
+  if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
+    RW_TRACE_ERROR2("Response error: expecting rsp_code %02X, but got %02X",
+                    T3T_MSG_OPC_CHECK_RSP,
+                    p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
+    evt_data.status = NFC_STATUS_FAILED;
+  }
+  /* Validate status code and NFCID2 response from tag */
+  else if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
+            T3T_MSG_RSP_STATUS_OK) /* verify response status code */
+           ||
+           (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
+                   NCI_NFCID2_LEN) != 0)) /* verify response IDm */
+  {
+    evt_data.status = NFC_STATUS_FAILED;
+  } else {
+    /* Get checksum from received ndef attribute msg */
+    p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA + T3T_MSG_NDEF_ATTR_INFO_SIZE];
+    BE_STREAM_TO_UINT16(checksum_rx, p);
+
+    /* Calculate checksum - move check for checsum to beginning */
+    checksum_calc = 0;
+    p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA];
+    for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++) {
+      checksum_calc += p[i];
+    }
+
+    /* Validate checksum */
+    if (checksum_calc != checksum_rx) {
+      p_cb->ndef_attrib.status =
+          NFC_STATUS_FAILED; /* only ok or failed passed to the app. can be
+                                boolean*/
+
+      RW_TRACE_ERROR0("RW_T3tDetectNDEF checksum failed");
+    } else {
+      p_cb->ndef_attrib.status = NFC_STATUS_OK;
+
+      /* Validate version number */
+      STREAM_TO_UINT8(p_cb->ndef_attrib.version, p);
+
+      if (T3T_GET_MAJOR_VERSION(T3T_MSG_NDEF_VERSION) <
+          T3T_GET_MAJOR_VERSION(p_cb->ndef_attrib.version)) {
+        /* Remote tag's MajorVer is newer than our's. Reject NDEF as per T3TOP
+         * RQ_T3T_NDA_024 */
+        RW_TRACE_ERROR2(
+            "RW_T3tDetectNDEF: incompatible NDEF version. Local=0x%02x, "
+            "Remote=0x%02x",
+            T3T_MSG_NDEF_VERSION, p_cb->ndef_attrib.version);
+        p_cb->ndef_attrib.status = NFC_STATUS_FAILED;
+        evt_data.status = NFC_STATUS_BAD_RESP;
+      } else {
+        /* Remote tag's MajorVer is equal or older than our's. NDEF is
+         * compatible with our version. */
+
+        /* Update NDEF info */
+        STREAM_TO_UINT8(
+            p_cb->ndef_attrib.nbr,
+            p); /* NBr: number of blocks that can be read using one Check
+                   command */
+        STREAM_TO_UINT8(p_cb->ndef_attrib.nbw,
+                        p); /* Nbw: number of blocks that can be written using
+                               one Update command */
+        BE_STREAM_TO_UINT16(
+            p_cb->ndef_attrib.nmaxb,
+            p); /* Nmaxb: maximum number of blocks available for NDEF data */
+        BE_STREAM_TO_UINT32(temp, p);
+        STREAM_TO_UINT8(p_cb->ndef_attrib.writef,
+                        p); /* WriteFlag: 00h if writing data finished; 0Fh if
+                               writing data in progress */
+        STREAM_TO_UINT8(
+            p_cb->ndef_attrib.rwflag,
+            p); /* RWFlag: 00h NDEF is read-only; 01h if read/write available */
+
+        /* Get length (3-byte, big-endian) */
+        STREAM_TO_UINT8(temp, p);                     /* Ln: high-byte */
+        BE_STREAM_TO_UINT16(p_cb->ndef_attrib.ln, p); /* Ln: lo-word */
+        p_cb->ndef_attrib.ln += (temp << 16);
+
+        RW_TRACE_DEBUG1("Detected NDEF Ver: 0x%02x", p_cb->ndef_attrib.version);
+        RW_TRACE_DEBUG6(
+            "Detected NDEF Attributes: Nbr=%i, Nbw=%i, Nmaxb=%i, WriteF=%i, "
+            "RWFlag=%i, Ln=%i",
+            p_cb->ndef_attrib.nbr, p_cb->ndef_attrib.nbw,
+            p_cb->ndef_attrib.nmaxb, p_cb->ndef_attrib.writef,
+            p_cb->ndef_attrib.rwflag, p_cb->ndef_attrib.ln);
+
+        /* Set data for RW_T3T_NDEF_DETECT_EVT */
+        evt_data.status = p_cb->ndef_attrib.status;
+        evt_data.cur_size = p_cb->ndef_attrib.ln;
+        evt_data.max_size = (uint32_t)p_cb->ndef_attrib.nmaxb * 16;
+        evt_data.protocol = NFC_PROTOCOL_T3T;
+        evt_data.flags = (RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATED);
+        if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO)
+          evt_data.flags |= RW_NDEF_FL_READ_ONLY;
+      }
+    }
+  }
+
+  RW_TRACE_DEBUG1("RW_T3tDetectNDEF response: %i", evt_data.status);
+
+  p_cb->rw_state = RW_T3T_STATE_IDLE;
+  rw_t3t_update_ndef_flag(&evt_data.flags);
+  /* Notify app of NDEF detection result */
+  (*(rw_cb.p_cback))(RW_T3T_NDEF_DETECT_EVT, (void*)&evt_data);
+
+  GKI_freebuf(p_msg_rsp);
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_act_handle_check_rsp
+**
+** Description      Handle response to CHECK command
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+void rw_t3t_act_handle_check_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
+  uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
+  tRW_READ_DATA evt_data;
+  tNFC_STATUS nfc_status = NFC_STATUS_OK;
+
+  /* Validate response from tag */
+  if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
+       T3T_MSG_RSP_STATUS_OK) /* verify response status code */
+      ||
+      (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
+              NCI_NFCID2_LEN) != 0)) /* verify response IDm */
+  {
+    nfc_status = NFC_STATUS_FAILED;
+    GKI_freebuf(p_msg_rsp);
+  } else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
+    RW_TRACE_ERROR2("Response error: expecting rsp_code %02X, but got %02X",
+                    T3T_MSG_OPC_CHECK_RSP,
+                    p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
+    nfc_status = NFC_STATUS_FAILED;
+    GKI_freebuf(p_msg_rsp);
+  } else {
+    /* Copy incoming data into buffer */
+    p_msg_rsp->offset +=
+        T3T_MSG_RSP_OFFSET_CHECK_DATA; /* Skip over t3t header */
+    p_msg_rsp->len -= T3T_MSG_RSP_OFFSET_CHECK_DATA;
+    evt_data.status = NFC_STATUS_OK;
+    evt_data.p_data = p_msg_rsp;
+    (*(rw_cb.p_cback))(RW_T3T_CHECK_EVT, (void*)&evt_data);
+  }
+
+  p_cb->rw_state = RW_T3T_STATE_IDLE;
+
+  (*(rw_cb.p_cback))(RW_T3T_CHECK_CPLT_EVT, (void*)&nfc_status);
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_act_handle_update_rsp
+**
+** Description      Handle response to UPDATE command
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+void rw_t3t_act_handle_update_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
+  uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
+  tRW_READ_DATA evt_data;
+
+  /* Validate response from tag */
+  if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
+       T3T_MSG_RSP_STATUS_OK) /* verify response status code */
+      ||
+      (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
+              NCI_NFCID2_LEN) != 0)) /* verify response IDm */
+  {
+    evt_data.status = NFC_STATUS_FAILED;
+  } else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) {
+    RW_TRACE_ERROR2("Response error: expecting rsp_code %02X, but got %02X",
+                    T3T_MSG_OPC_UPDATE_RSP,
+                    p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
+    evt_data.status = NFC_STATUS_FAILED;
+  } else {
+    /* Copy incoming data into buffer */
+    evt_data.status = NFC_STATUS_OK;
+  }
+
+  p_cb->rw_state = RW_T3T_STATE_IDLE;
+
+  (*(rw_cb.p_cback))(RW_T3T_UPDATE_CPLT_EVT, (void*)&evt_data);
+
+  GKI_freebuf(p_msg_rsp);
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_act_handle_raw_senddata_rsp
+**
+** Description      Handle response to NDEF detection
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+void rw_t3t_act_handle_raw_senddata_rsp(tRW_T3T_CB* p_cb,
+                                        tNFC_DATA_CEVT* p_data) {
+  tRW_READ_DATA evt_data;
+  NFC_HDR* p_pkt = p_data->p_data;
+
+#if (BT_TRACE_VERBOSE == true)
+  RW_TRACE_DEBUG2("RW T3T Raw Frame: Len [0x%X] Status [%s]", p_pkt->len,
+                  NFC_GetStatusName(p_data->status));
+#else
+  RW_TRACE_DEBUG2("RW T3T Raw Frame: Len [0x%X] Status [0x%X]", p_pkt->len,
+                  p_data->status);
+#endif
+
+  /* Copy incoming data into buffer */
+  evt_data.status = p_data->status;
+  evt_data.p_data = p_pkt;
+
+  p_cb->rw_state = RW_T3T_STATE_IDLE;
+
+  (*(rw_cb.p_cback))(RW_T3T_RAW_FRAME_EVT, (void*)&evt_data);
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_act_handle_check_ndef_rsp
+**
+** Description      Handle response to NDEF read segment
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+void rw_t3t_act_handle_check_ndef_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
+  bool check_complete = true;
+  tNFC_STATUS nfc_status = NFC_STATUS_OK;
+  tRW_READ_DATA read_data;
+  tRW_DATA evt_data;
+  uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
+  uint8_t rsp_num_bytes_rx;
+
+  /* Validate response from tag */
+  if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
+       T3T_MSG_RSP_STATUS_OK) /* verify response status code */
+      ||
+      (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
+              NCI_NFCID2_LEN) != 0) /* verify response IDm */
+      ||
+      (p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] !=
+       ((p_cb->ndef_rx_readlen + 15) >> 4))) /* verify length of response */
+  {
+    RW_TRACE_ERROR2("Response error: bad status, nfcid2, or invalid len: %i %i",
+                    p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS],
+                    ((p_cb->ndef_rx_readlen + 15) >> 4));
+    nfc_status = NFC_STATUS_FAILED;
+    GKI_freebuf(p_msg_rsp);
+  } else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
+    RW_TRACE_ERROR2("Response error: expecting rsp_code %02X, but got %02X",
+                    T3T_MSG_OPC_CHECK_RSP,
+                    p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
+    nfc_status = NFC_STATUS_FAILED;
+    GKI_freebuf(p_msg_rsp);
+  } else {
+    /* Notify app of NDEF segment received */
+    rsp_num_bytes_rx = p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] *
+                       16; /* Number of bytes received, according to header */
+    p_cb->ndef_rx_offset += p_cb->ndef_rx_readlen;
+    read_data.status = NFC_STATUS_OK;
+    p_msg_rsp->offset +=
+        T3T_MSG_RSP_OFFSET_CHECK_DATA; /* Skip over t3t header (point to block
+                                          data) */
+    p_msg_rsp->len -= T3T_MSG_RSP_OFFSET_CHECK_DATA;
+
+    /* Verify that the bytes received is really the amount indicated in the
+     * check-response header */
+    if (rsp_num_bytes_rx > p_msg_rsp->len) {
+      RW_TRACE_ERROR2(
+          "Response error: CHECK rsp header indicates %i bytes, but only "
+          "received %i bytes",
+          rsp_num_bytes_rx, p_msg_rsp->len);
+      nfc_status = NFC_STATUS_FAILED;
+      GKI_freebuf(p_msg_rsp);
+    } else {
+      /* If this is the the final block, then set len to reflect only valid
+       * bytes (do not include padding to 16-byte boundary) */
+      if ((p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT) &&
+          (p_cb->ndef_attrib.ln & 0x000F)) {
+        rsp_num_bytes_rx -= (16 - (p_cb->ndef_attrib.ln & 0x000F));
+      }
+
+      p_msg_rsp->len = rsp_num_bytes_rx;
+      read_data.p_data = p_msg_rsp;
+      (*(rw_cb.p_cback))(RW_T3T_CHECK_EVT, (void*)&read_data);
+
+      /* Send CHECK cmd for next NDEF segment, if needed */
+      if (!(p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT)) {
+        nfc_status = rw_t3t_send_next_ndef_check_cmd(p_cb);
+        if (nfc_status == NFC_STATUS_OK) {
+          /* Still getting more segments. Don't send RW_T3T_CHECK_CPLT_EVT yet
+           */
+          check_complete = false;
+        }
+      }
+    }
+  }
+
+  /* Notify app of RW_T3T_CHECK_CPLT_EVT if entire NDEF has been read, or if
+   * failure */
+  if (check_complete) {
+    p_cb->rw_state = RW_T3T_STATE_IDLE;
+    evt_data.status = nfc_status;
+    (*(rw_cb.p_cback))(RW_T3T_CHECK_CPLT_EVT, (tRW_DATA*)&evt_data);
+  }
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_act_handle_update_ndef_rsp
+**
+** Description      Handle response to NDEF write segment
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+void rw_t3t_act_handle_update_ndef_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
+  bool update_complete = true;
+  tNFC_STATUS nfc_status = NFC_STATUS_OK;
+  tRW_DATA evt_data;
+  uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
+
+  /* Check nfcid2 and status of response */
+  if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
+       T3T_MSG_RSP_STATUS_OK) /* verify response status code */
+      ||
+      (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
+              NCI_NFCID2_LEN) != 0)) /* verify response IDm */
+  {
+    nfc_status = NFC_STATUS_FAILED;
+  }
+  /* Validate response opcode */
+  else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) {
+    RW_TRACE_ERROR2("Response error: expecting rsp_code %02X, but got %02X",
+                    T3T_MSG_OPC_UPDATE_RSP,
+                    p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
+    nfc_status = NFC_STATUS_FAILED;
+  }
+  /* If this is response to final UPDATE, then update NDEF local size */
+  else if (p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT) {
+    /* If successful, update current NDEF size */
+    p_cb->ndef_attrib.ln = p_cb->ndef_msg_len;
+  }
+  /*  If any more NDEF bytes to update, then send next UPDATE command */
+  else if (p_cb->ndef_msg_bytes_sent < p_cb->ndef_msg_len) {
+    /* Send UPDATE command for next segment of NDEF */
+    nfc_status = rw_t3t_send_next_ndef_update_cmd(p_cb);
+    if (nfc_status == NFC_STATUS_OK) {
+      /* Wait for update response */
+      update_complete = false;
+    }
+  }
+  /*  Otherwise, no more NDEF bytes. Send final UPDATE for Attribute Information
+     block */
+  else {
+    p_cb->flags |= RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
+    nfc_status = rw_t3t_send_update_ndef_attribute_cmd(p_cb, false);
+    if (nfc_status == NFC_STATUS_OK) {
+      /* Wait for update response */
+      update_complete = false;
+    }
+  }
+
+  /* If update is completed, then notify app */
+  if (update_complete) {
+    p_cb->rw_state = RW_T3T_STATE_IDLE;
+    evt_data.status = nfc_status;
+    (*(rw_cb.p_cback))(RW_T3T_UPDATE_CPLT_EVT, (tRW_DATA*)&evt_data);
+  }
+
+  GKI_freebuf(p_msg_rsp);
+
+  return;
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_handle_get_sc_poll_rsp
+**
+** Description      Handle POLL response for getting system codes
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+static void rw_t3t_handle_get_sc_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
+                                          uint8_t num_responses,
+                                          uint8_t sensf_res_buf_size,
+                                          uint8_t* p_sensf_res_buf) {
+  uint8_t* p;
+  uint16_t sc;
+
+  /* Get the system code from the response */
+  if ((nci_status == NCI_STATUS_OK) && (num_responses > 0) &&
+      (sensf_res_buf_size >=
+       (RW_T3T_SENSF_RES_RD_OFFSET + RW_T3T_SENSF_RES_RD_LEN))) {
+    p = &p_sensf_res_buf[RW_T3T_SENSF_RES_RD_OFFSET];
+    BE_STREAM_TO_UINT16(sc, p);
+
+    RW_TRACE_DEBUG1("FeliCa detected (RD, system code %04X)", sc);
+    p_cb->system_codes[p_cb->num_system_codes++] = sc;
+  }
+
+  rw_t3t_handle_get_system_codes_cplt();
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_handle_ndef_detect_poll_rsp
+**
+** Description      Handle POLL response for getting system codes
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+static void rw_t3t_handle_ndef_detect_poll_rsp(tRW_T3T_CB* p_cb,
+                                               uint8_t nci_status,
+                                               uint8_t num_responses,
+                                               uint8_t sensf_res_buf_size,
+                                               uint8_t* p_sensf_res_buf) {
+  NFC_HDR* p_cmd_buf;
+  uint8_t* p, *p_cmd_start;
+  tRW_DATA evt_data;
+  (void)sensf_res_buf_size;
+
+  /* Validate response for NDEF poll */
+  if ((nci_status == NCI_STATUS_OK) && (num_responses > 0)) {
+    /* Tag responded for NDEF poll */
+
+    /* Read NDEF attribute block */
+    p_cmd_buf = rw_t3t_get_cmd_buf();
+    if (p_cmd_buf != NULL) {
+      /* Construct T3T message */
+      p = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
+
+      /* Add CHECK opcode to message  */
+      UINT8_TO_STREAM(p, T3T_MSG_OPC_CHECK_CMD);
+
+#if (NXP_EXTNS == TRUE)
+      /* Update NFCID2 using SENSF_RES */
+      memcpy(p_cb->peer_nfcid2, (p_sensf_res_buf + NCI_SENSF_RES_OFFSET_NFCID2),
+             NCI_NFCID2_LEN);
+#endif
+      /* Add IDm to message */
+      ARRAY_TO_STREAM(p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
+
+      /* Add Service code list */
+      UINT8_TO_STREAM(p, 1); /* Number of services (only 1 service: NDEF) */
+      UINT16_TO_STREAM(
+          p, T3T_MSG_NDEF_SC_RO); /* Service code (little-endian format) */
+
+      /* Number of blocks */
+      UINT8_TO_STREAM(
+          p,
+          1); /* Number of blocks (only 1 block: NDEF Attribute Information ) */
+
+      /* Block List element: the NDEF attribute information block (block 0) */
+      UINT8_TO_STREAM(p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
+      UINT8_TO_STREAM(p, 0);
+
+      /* Calculate length of message */
+      p_cmd_buf->len = (uint16_t)(p - p_cmd_start);
+
+      /* Send the T3T message */
+      evt_data.status = rw_t3t_send_cmd(p_cb, RW_T3T_CMD_DETECT_NDEF, p_cmd_buf,
+                                        rw_t3t_check_timeout(1));
+      if (evt_data.status == NFC_STATUS_OK) {
+        /* CHECK command sent. Wait for response */
+        return;
+      }
+    }
+    nci_status = NFC_STATUS_FAILED;
+  }
+
+  /* NDEF detection failed */
+  p_cb->rw_state = RW_T3T_STATE_IDLE;
+  evt_data.ndef.status = nci_status;
+  evt_data.ndef.flags = RW_NDEF_FL_UNKNOWN;
+  rw_t3t_update_ndef_flag(&evt_data.ndef.flags);
+  (*(rw_cb.p_cback))(RW_T3T_NDEF_DETECT_EVT, &evt_data);
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_update_block
+**
+** Description      Send UPDATE command for single block
+**                  (for formatting/configuring read only)
+**
+** Returns          tNFC_STATUS
+**
+*****************************************************************************/
+tNFC_STATUS rw_t3t_update_block(tRW_T3T_CB* p_cb, uint8_t block_id,
+                                uint8_t* p_block_data) {
+  uint8_t* p_dst, *p_cmd_start;
+  NFC_HDR* p_cmd_buf;
+  tNFC_STATUS status;
+
+  p_cmd_buf = rw_t3t_get_cmd_buf();
+  if (p_cmd_buf != NULL) {
+    p_dst = p_cmd_start = (uint8_t*)(p_cmd_buf + 1) + p_cmd_buf->offset;
+
+    /* Add UPDATE opcode to message  */
+    UINT8_TO_STREAM(p_dst, T3T_MSG_OPC_UPDATE_CMD);
+
+    /* Add IDm to message */
+    ARRAY_TO_STREAM(p_dst, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
+
+    /* Add Service code list */
+    UINT8_TO_STREAM(p_dst, 1); /* Number of services (only 1 service: NDEF) */
+    UINT16_TO_STREAM(
+        p_dst, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */
+
+    /* Number of blocks */
+    UINT8_TO_STREAM(p_dst, 1);
+
+    /* Add Block list element for MC */
+    UINT8_TO_STREAM(p_dst, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
+    UINT8_TO_STREAM(p_dst, block_id);
+
+    /* Copy MC data to UPDATE message */
+    ARRAY_TO_STREAM(p_dst, p_block_data, T3T_MSG_BLOCKSIZE);
+
+    /* Calculate length of message */
+    p_cmd_buf->len = (uint16_t)(p_dst - p_cmd_start);
+
+    /* Send the T3T message */
+    status = rw_t3t_send_cmd(p_cb, p_cb->cur_cmd, p_cmd_buf,
+                             rw_t3t_update_timeout(1));
+  } else {
+    /* Unable to send UPDATE command */
+    status = NFC_STATUS_NO_BUFFERS;
+  }
+
+  return (status);
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_handle_fmt_poll_rsp
+**
+** Description      Handle POLL response for formatting felica-lite
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+static void rw_t3t_handle_fmt_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
+                                       uint8_t num_responses,
+                                       uint8_t sensf_res_buf_size,
+                                       uint8_t* p_sensf_res_buf) {
+  tRW_DATA evt_data;
+  (void)sensf_res_buf_size;
+  (void)p_sensf_res_buf;
+
+  evt_data.status = NFC_STATUS_OK;
+
+  /* Validate response for poll response */
+  if ((nci_status == NCI_STATUS_OK) && (num_responses > 0)) {
+    /* Tag responded for Felica-Lite poll */
+    /* Get MemoryControl block */
+    RW_TRACE_DEBUG0("Felica-Lite tag detected...getting Memory Control block.");
+
+    p_cb->rw_substate = RW_T3T_FMT_SST_CHECK_MC_BLK;
+
+    /* Send command to check Memory Configuration block */
+    evt_data.status = rw_t3t_check_mc_block(p_cb);
+  } else {
+    RW_TRACE_ERROR0("Felica-Lite tag not detected");
+    evt_data.status = NFC_STATUS_FAILED;
+  }
+
+  /* If error, notify upper layer */
+  if (evt_data.status != NFC_STATUS_OK) {
+    rw_t3t_format_cplt(evt_data.status);
+  }
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_act_handle_fmt_rsp
+**
+** Description      Handle response for formatting codes
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+void rw_t3t_act_handle_fmt_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
+  uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
+  uint8_t* p_mc;
+  tRW_DATA evt_data;
+
+  evt_data.status = NFC_STATUS_OK;
+
+  /* Check tags's response for reading MemoryControl block */
+  if (p_cb->rw_substate == RW_T3T_FMT_SST_CHECK_MC_BLK) {
+    /* Validate response opcode */
+    if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
+      RW_TRACE_ERROR2("Response error: expecting rsp_code %02X, but got %02X",
+                      T3T_MSG_OPC_CHECK_RSP,
+                      p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
+      evt_data.status = NFC_STATUS_FAILED;
+    }
+    /* Validate status code and NFCID2 response from tag */
+    else if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
+              T3T_MSG_RSP_STATUS_OK) /* verify response status code */
+             ||
+             (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
+                     NCI_NFCID2_LEN) != 0)) /* verify response IDm */
+    {
+      evt_data.status = NFC_STATUS_FAILED;
+    } else {
+      /* Check if memory configuration (MC) block to see if SYS_OP=1 (NDEF
+       * enabled) */
+      p_mc = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA]; /* Point to MC data of
+                                                           CHECK response */
+
+      if (p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] != 0x01) {
+        /* Tag is not currently enabled for NDEF. Indicate that we need to
+         * update the MC block */
+
+        /* Set SYS_OP field to 0x01 (enable NDEF) */
+        p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] = 0x01;
+
+        /* Set RF_PRM field to 0x07 (procedure of issuance) */
+        p_mc[T3T_MSG_FELICALITE_MC_OFFSET_RF_PRM] = 0x07;
+
+        /* Construct and send UPDATE message to write MC block */
+        p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_MC_BLK;
+        evt_data.status =
+            rw_t3t_update_block(p_cb, T3T_MSG_FELICALITE_BLOCK_ID_MC, p_mc);
+      } else {
+        /* SYS_OP=1: ndef already enabled. Just need to update attribute
+         * information block */
+        p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB;
+        evt_data.status =
+            rw_t3t_update_block(p_cb, 0, (uint8_t*)rw_t3t_default_attrib_info);
+      }
+    }
+
+    /* If error, notify upper layer */
+    if (evt_data.status != NFC_STATUS_OK) {
+      rw_t3t_format_cplt(evt_data.status);
+    }
+  } else if (p_cb->rw_substate == RW_T3T_FMT_SST_UPDATE_MC_BLK) {
+    /* Validate response opcode */
+    if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) ||
+        (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK))
+
+    {
+      RW_TRACE_ERROR2("Response error: rsp_code=%02X, status=%02X",
+                      p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE],
+                      p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
+      evt_data.status = NFC_STATUS_FAILED;
+    } else {
+      /* SYS_OP=1: ndef already enabled. Just need to update attribute
+       * information block */
+      p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB;
+      evt_data.status =
+          rw_t3t_update_block(p_cb, 0, (uint8_t*)rw_t3t_default_attrib_info);
+    }
+
+    /* If error, notify upper layer */
+    if (evt_data.status != NFC_STATUS_OK) {
+      rw_t3t_format_cplt(evt_data.status);
+    }
+  } else if (p_cb->rw_substate == RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB) {
+    /* Validate response opcode */
+    if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) ||
+        (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK))
+
+    {
+      RW_TRACE_ERROR2("Response error: rsp_code=%02X, status=%02X",
+                      p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE],
+                      p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
+      evt_data.status = NFC_STATUS_FAILED;
+    }
+
+    rw_t3t_format_cplt(evt_data.status);
+  }
+
+  GKI_freebuf(p_msg_rsp);
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_handle_sro_poll_rsp
+**
+** Description      Handle POLL response for configuring felica-lite read only
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+static void rw_t3t_handle_sro_poll_rsp(tRW_T3T_CB* p_cb, uint8_t nci_status,
+                                       uint8_t num_responses,
+                                       uint8_t sensf_res_buf_size,
+                                       uint8_t* p_sensf_res_buf) {
+  tRW_DATA evt_data;
+  uint8_t rw_t3t_ndef_attrib_info[T3T_MSG_BLOCKSIZE];
+  uint8_t* p;
+  uint8_t tempU8;
+  uint16_t checksum, i;
+  uint32_t tempU32 = 0;
+  (void)sensf_res_buf_size;
+  (void)p_sensf_res_buf;
+
+  evt_data.status = NFC_STATUS_OK;
+
+  /* Validate response for poll response */
+  if ((nci_status == NCI_STATUS_OK) && (num_responses > 0)) {
+    /* Tag responded for Felica-Lite poll */
+    if (p_cb->ndef_attrib.rwflag != T3T_MSG_NDEF_RWFLAG_RO) {
+      /* First update attribute information block */
+      RW_TRACE_DEBUG0(
+          "Felica-Lite tag detected...update NDef attribution block.");
+
+      p_cb->rw_substate = RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB;
+
+      p = rw_t3t_ndef_attrib_info;
+
+      UINT8_TO_STREAM(p, p_cb->ndef_attrib.version);
+
+      /* Update NDEF info */
+      UINT8_TO_STREAM(
+          p, p_cb->ndef_attrib.nbr); /* NBr: number of blocks that can be read
+                                        using one Check command */
+      UINT8_TO_STREAM(p, p_cb->ndef_attrib.nbw); /* Nbw: number of blocks that
+                                                    can be written using one
+                                                    Update command */
+      UINT16_TO_BE_STREAM(
+          p, p_cb->ndef_attrib.nmaxb); /* Nmaxb: maximum number of blocks
+                                          available for NDEF data */
+      UINT32_TO_BE_STREAM(p, tempU32);
+      UINT8_TO_STREAM(p,
+                      p_cb->ndef_attrib.writef); /* WriteFlag: 00h if writing
+                                                    data finished; 0Fh if
+                                                    writing data in progress */
+      UINT8_TO_STREAM(p, 0x00); /* RWFlag: 00h NDEF is read-only */
+
+      tempU8 = (uint8_t)(p_cb->ndef_attrib.ln >> 16);
+      /* Get length (3-byte, big-endian) */
+      UINT8_TO_STREAM(p, tempU8);                   /* Ln: high-byte */
+      UINT16_TO_BE_STREAM(p, p_cb->ndef_attrib.ln); /* Ln: lo-word */
+
+      /* Calculate and append Checksum */
+      checksum = 0;
+      for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++) {
+        checksum += rw_t3t_ndef_attrib_info[i];
+      }
+      UINT16_TO_BE_STREAM(p, checksum);
+
+      evt_data.status =
+          rw_t3t_update_block(p_cb, 0, (uint8_t*)rw_t3t_ndef_attrib_info);
+    } else if (p_cb->cur_cmd == RW_T3T_CMD_SET_READ_ONLY_HARD) {
+      /* NDEF is already read only, Read and update MemoryControl block */
+      RW_TRACE_DEBUG0(
+          "Felica-Lite tag detected...getting Memory Control block.");
+      p_cb->rw_substate = RW_T3T_SRO_SST_CHECK_MC_BLK;
+
+      /* Send command to check Memory Configuration block */
+      evt_data.status = rw_t3t_check_mc_block(p_cb);
+    }
+  } else {
+    RW_TRACE_ERROR0("Felica-Lite tag not detected");
+    evt_data.status = NFC_STATUS_FAILED;
+  }
+
+  /* If error, notify upper layer */
+  if (evt_data.status != NFC_STATUS_OK) {
+    rw_t3t_set_readonly_cplt(evt_data.status);
+  }
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_act_handle_sro_rsp
+**
+** Description      Handle response for setting read only codes
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+void rw_t3t_act_handle_sro_rsp(tRW_T3T_CB* p_cb, NFC_HDR* p_msg_rsp) {
+  uint8_t* p_t3t_rsp = (uint8_t*)(p_msg_rsp + 1) + p_msg_rsp->offset;
+  uint8_t* p_mc;
+  tRW_DATA evt_data;
+
+  evt_data.status = NFC_STATUS_OK;
+
+  if (p_cb->rw_substate == RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB) {
+    /* Validate response opcode */
+    if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) ||
+        (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK))
+
+    {
+      RW_TRACE_ERROR2("Response error: rsp_code=%02X, status=%02X",
+                      p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE],
+                      p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
+      evt_data.status = NFC_STATUS_FAILED;
+    } else {
+      p_cb->ndef_attrib.rwflag = T3T_MSG_NDEF_RWFLAG_RO;
+      if (p_cb->cur_cmd == RW_T3T_CMD_SET_READ_ONLY_HARD) {
+        p_cb->rw_substate = RW_T3T_SRO_SST_CHECK_MC_BLK;
+
+        /* Send command to check Memory Configuration block */
+        evt_data.status = rw_t3t_check_mc_block(p_cb);
+      } else {
+        rw_t3t_set_readonly_cplt(evt_data.status);
+      }
+    }
+  } else if (p_cb->rw_substate == RW_T3T_SRO_SST_CHECK_MC_BLK) {
+    /* Check tags's response for reading MemoryControl block, Validate response
+     * opcode */
+    if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP) {
+      RW_TRACE_ERROR2("Response error: expecting rsp_code %02X, but got %02X",
+                      T3T_MSG_OPC_CHECK_RSP,
+                      p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
+      evt_data.status = NFC_STATUS_FAILED;
+    }
+    /* Validate status code and NFCID2 response from tag */
+    else if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] !=
+              T3T_MSG_RSP_STATUS_OK) /* verify response status code */
+             ||
+             (memcmp(p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM],
+                     NCI_NFCID2_LEN) != 0)) /* verify response IDm */
+    {
+      evt_data.status = NFC_STATUS_FAILED;
+    } else {
+      /* Check if memory configuration (MC) block to see if SYS_OP=1 (NDEF
+       * enabled) */
+      p_mc = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA]; /* Point to MC data of
+                                                           CHECK response */
+
+      if (p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] != 0x01) {
+        /* Tag is not currently enabled for NDEF */
+        evt_data.status = NFC_STATUS_FAILED;
+      } else {
+        /* Set MC_SP field with MC[0] = 0x00 & MC[1] = 0xC0 (Hardlock) to change
+         * access permission from RW to RO */
+        p_mc[T3T_MSG_FELICALITE_MC_OFFSET_MC_SP] = 0x00;
+        /* Not changing the access permission of Subtraction Register and
+         * MC[0:1] */
+        p_mc[T3T_MSG_FELICALITE_MC_OFFSET_MC_SP + 1] = 0xC0;
+
+        /* Set RF_PRM field to 0x07 (procedure of issuance) */
+        p_mc[T3T_MSG_FELICALITE_MC_OFFSET_RF_PRM] = 0x07;
+
+        /* Construct and send UPDATE message to write MC block */
+        p_cb->rw_substate = RW_T3T_SRO_SST_UPDATE_MC_BLK;
+        evt_data.status =
+            rw_t3t_update_block(p_cb, T3T_MSG_FELICALITE_BLOCK_ID_MC, p_mc);
+      }
+    }
+  } else if (p_cb->rw_substate == RW_T3T_SRO_SST_UPDATE_MC_BLK) {
+    /* Validate response opcode */
+    if ((p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP) ||
+        (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK))
+
+    {
+      RW_TRACE_ERROR2("Response error: rsp_code=%02X, status=%02X",
+                      p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE],
+                      p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
+      evt_data.status = NFC_STATUS_FAILED;
+    } else {
+      rw_t3t_set_readonly_cplt(evt_data.status);
+    }
+  }
+
+  /* If error, notify upper layer */
+  if (evt_data.status != NFC_STATUS_OK) {
+    rw_t3t_set_readonly_cplt(evt_data.status);
+  }
+
+  GKI_freebuf(p_msg_rsp);
+}
+
+/*******************************************************************************
+**
+** Function         rw_t3t_data_cback
+**
+** Description      This callback function receives the data from NFCC.
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t3t_data_cback(uint8_t conn_id, tNFC_DATA_CEVT* p_data) {
+  tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
+  NFC_HDR* p_msg = p_data->p_data;
+  bool free_msg = false; /* if true, free msg buffer before returning */
+  uint8_t* p, sod;
+  (void)conn_id;
+
+  /* Stop rsponse timer */
+  nfc_stop_quick_timer(&p_cb->timer);
+
+#if (RW_STATS_INCLUDED == true)
+  /* Update rx stats */
+  rw_main_update_rx_stats(p_msg->len);
+#endif /* RW_STATS_INCLUDED */
+
+  /* Check if we are expecting a response */
+  if (p_cb->rw_state != RW_T3T_STATE_COMMAND_PENDING) {
+    /*
+    **  This must be raw frame response
+    **  send raw frame to app with SoD
+    */
+    rw_t3t_act_handle_raw_senddata_rsp(p_cb, p_data);
+  }
+  /* Sanity check: verify msg len is big enough to contain t3t header */
+  else if (p_msg->len < T3T_MSG_RSP_COMMON_HDR_LEN) {
+    RW_TRACE_ERROR1("T3T: invalid Type3 Tag Message (invalid len: %i)",
+                    p_msg->len);
+    free_msg = true;
+
+    rw_t3t_process_frame_error();
+  } else {
+    /* Check for RF frame error */
+    p = (uint8_t*)(p_msg + 1) + p_msg->offset;
+    sod = p[0];
+    if (p[sod] != NCI_STATUS_OK) {
+      RW_TRACE_ERROR1("T3T: rf frame error (crc status=%i)", p[sod]);
+      GKI_freebuf(p_msg);
+
+      rw_t3t_process_frame_error();
+      return;
+    }
+
+#if (BT_TRACE_PROTOCOL == true)
+    DispT3TagMessage(p_msg, true);
+#endif
+
+    /* Skip over SoD */
+    p_msg->offset++;
+    p_msg->len--;
+
+    /* Get response code */
+    switch (p_cb->cur_cmd) {
+      case RW_T3T_CMD_DETECT_NDEF:
+        rw_t3t_act_handle_ndef_detect_rsp(p_cb, p_msg);
+        break;
+
+      case RW_T3T_CMD_CHECK_NDEF:
+        rw_t3t_act_handle_check_ndef_rsp(p_cb, p_msg);
+        break;
+
+      case RW_T3T_CMD_UPDATE_NDEF:
+        rw_t3t_act_handle_update_ndef_rsp(p_cb, p_msg);
+        break;
+
+      case RW_T3T_CMD_CHECK:
+        rw_t3t_act_handle_check_rsp(p_cb, p_msg);
+        break;
+
+      case RW_T3T_CMD_UPDATE:
+        rw_t3t_act_handle_update_rsp(p_cb, p_msg);
+        break;
+
+      case RW_T3T_CMD_SEND_RAW_FRAME:
+        rw_t3t_act_handle_raw_senddata_rsp(p_cb, p_data);
+        break;
+
+      case RW_T3T_CMD_FORMAT:
+        rw_t3t_act_handle_fmt_rsp(p_cb, p_msg);
+        break;
+
+      case RW_T3T_CMD_SET_READ_ONLY_SOFT:
+      case RW_T3T_CMD_SET_READ_ONLY_HARD:
+        rw_t3t_act_handle_sro_rsp(p_cb, p_msg);
+        break;
+
+      default:
+        GKI_freebuf(p_msg);
+        break;
+    }
+  }
+
+  if (free_msg) {
+    GKI_freebuf(p_msg);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t3t_conn_cback
+**
+** Description      This callback function receives the events/data from NFCC.
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t3t_conn_cback(uint8_t conn_id, tNFC_CONN_EVT event,
+                       tNFC_CONN* p_data) {
+  tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
+  RW_TRACE_DEBUG2("rw_t3t_conn_cback: conn_id=%i, evt=0x%02x", conn_id, event);
+
+  /* Only handle NFC_RF_CONN_ID conn_id */
+  if (conn_id != NFC_RF_CONN_ID) {
+    return;
+  }
+
+  switch (event) {
+    case NFC_DEACTIVATE_CEVT:
+      rw_t3t_unselect(NULL);
+      break;
+
+    case NFC_DATA_CEVT: /* check for status in tNFC_CONN */
+      if ((p_data != NULL) && ((p_data->data.status == NFC_STATUS_OK) ||
+                               (p_data->data.status == NFC_STATUS_CONTINUE))) {
+        rw_t3t_data_cback(conn_id, &(p_data->data));
+        break;
+      } else if ((p_data != NULL) && (p_data->data.p_data != NULL)) {
+        RW_TRACE_DEBUG2(
+            "rw_t3t_conn_cback: p_data->data.p_data=0x%X "
+            "p_data->data.status=0x%02x",
+            p_data->data.p_data, p_data->data.status);
+        /* Free the response buffer in case of error response */
+        GKI_freebuf((NFC_HDR*)(p_data->data.p_data));
+        p_data->data.p_data = NULL;
+      } else if (p_data->data.p_data != NULL) {
+        /* Free the response buffer in case of error response */
+        GKI_freebuf((NFC_HDR*)(p_data->data.p_data));
+        p_data->data.p_data = NULL;
+      }
+    /* Data event with error status...fall through to NFC_ERROR_CEVT case */
+
+    case NFC_ERROR_CEVT:
+      nfc_stop_quick_timer(&p_cb->timer);
+
+#if (RW_STATS_INCLUDED == true)
+      rw_main_update_trans_error_stats();
+#endif /* RW_STATS_INCLUDED */
+
+      if (event == NFC_ERROR_CEVT)
+        rw_t3t_process_error(NFC_STATUS_TIMEOUT);
+      else if (p_data)
+        rw_t3t_process_error(p_data->status);
+#if (NXP_EXTNS == TRUE)
+      if ((p_data != NULL) && (p_data->data.p_data != NULL)) {
+        RW_TRACE_DEBUG0("rw_t3t_conn_cback: free GKI buffer");
+        GKI_freebuf((NFC_HDR*)(p_data->data.p_data));
+      }
+#endif
+      break;
+
+    default:
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t3t_mrti_to_a_b
+**
+** Description      Converts the given MRTI (Maximum Response Time Information)
+**                  to the base to calculate timeout value.
+**                  (The timeout value is a + b * number_blocks)
+**
+** Returns          NFC_STATUS_OK
+**
+*******************************************************************************/
+static void rw_t3t_mrti_to_a_b(uint8_t mrti, uint32_t* p_a, uint32_t* p_b) {
+  uint8_t a, b, e;
+
+  a = (mrti & 0x7) + 1; /* A is bit 0 ~ bit 2 */
+  mrti >>= 3;
+  b = (mrti & 0x7) + 1; /* B is bit 3 ~ bit 5 */
+  mrti >>= 3;
+  e = mrti & 0x3;                 /* E is bit 6 ~ bit 7 */
+  *p_a = rw_t3t_mrti_base[e] * a; /* (A+1) * base (i.e T/t3t * 4^E) */
+  *p_b = rw_t3t_mrti_base[e] * b; /* (B+1) * base (i.e T/t3t * 4^E) */
+}
+
+/*******************************************************************************
+**
+** Function         rw_t3t_select
+**
+** Description      Called by NFC manager when a Type3 tag has been activated
+**
+** Returns          NFC_STATUS_OK
+**
+*******************************************************************************/
+tNFC_STATUS rw_t3t_select(uint8_t peer_nfcid2[NCI_RF_F_UID_LEN],
+                          uint8_t mrti_check, uint8_t mrti_update) {
+  tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
+
+  RW_TRACE_API0("rw_t3t_select");
+
+  memcpy(p_cb->peer_nfcid2, peer_nfcid2,
+         NCI_NFCID2_LEN); /* Store tag's NFCID2 */
+  p_cb->ndef_attrib.status =
+      NFC_STATUS_NOT_INITIALIZED; /* Indicate that NDEF detection has not been
+                                     performed yet */
+  p_cb->rw_state = RW_T3T_STATE_IDLE;
+  p_cb->flags = 0;
+  rw_t3t_mrti_to_a_b(mrti_check, &p_cb->check_tout_a, &p_cb->check_tout_b);
+  rw_t3t_mrti_to_a_b(mrti_update, &p_cb->update_tout_a, &p_cb->update_tout_b);
+
+  /* Alloc cmd buf for retransmissions */
+  if (p_cb->p_cur_cmd_buf == NULL) {
+    p_cb->p_cur_cmd_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+    if (p_cb->p_cur_cmd_buf == NULL) {
+      RW_TRACE_ERROR0(
+          "rw_t3t_select: unable to allocate buffer for retransmission");
+      p_cb->rw_state = RW_T3T_STATE_NOT_ACTIVATED;
+      return (NFC_STATUS_FAILED);
+    }
+  }
+
+  NFC_SetStaticRfCback(rw_t3t_conn_cback);
+
+  return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t3t_unselect
+**
+** Description      Called by NFC manager when a Type3 tag has been de-activated
+**
+** Returns          NFC_STATUS_OK
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t3t_unselect(uint8_t peer_nfcid2[]) {
+  tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
+  (void)peer_nfcid2;
+
+#if (RW_STATS_INCLUDED == true)
+  /* Display stats */
+  rw_main_log_stats();
+#endif /* RW_STATS_INCLUDED */
+
+  /* Stop t3t timer (if started) */
+  nfc_stop_quick_timer(&p_cb->timer);
+
+  /* Free cmd buf for retransmissions */
+  if (p_cb->p_cur_cmd_buf) {
+    GKI_freebuf(p_cb->p_cur_cmd_buf);
+    p_cb->p_cur_cmd_buf = NULL;
+  }
+
+  p_cb->rw_state = RW_T3T_STATE_NOT_ACTIVATED;
+  NFC_SetStaticRfCback(NULL);
+
+  return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t3t_update_ndef_flag
+**
+** Description      set additional NDEF Flags for felica lite tag
+**
+** Returns          updated NDEF Flag value
+**
+*******************************************************************************/
+static void rw_t3t_update_ndef_flag(uint8_t* p_flag) {
+  tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
+  uint8_t xx;
+
+  for (xx = 0; xx < p_cb->num_system_codes; xx++) {
+    if (p_cb->system_codes[xx] == T3T_SYSTEM_CODE_FELICA_LITE) {
+      *p_flag &= ~RW_NDEF_FL_UNKNOWN;
+      *p_flag |= (RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATABLE);
+      break;
+    }
+  }
+}
+
+#if (BT_TRACE_VERBOSE == true)
+/*******************************************************************************
+**
+** Function         rw_t3t_cmd_str
+**
+** Description      Converts cmd_id to command string for logging
+**
+** Returns          command string
+**
+*******************************************************************************/
+static char* rw_t3t_cmd_str(uint8_t cmd_id) {
+  switch (cmd_id) {
+    case RW_T3T_CMD_DETECT_NDEF:
+      return "RW_T3T_CMD_DETECT_NDEF";
+
+    case RW_T3T_CMD_CHECK_NDEF:
+      return "RW_T3T_CMD_CHECK_NDEF";
+
+    case RW_T3T_CMD_UPDATE_NDEF:
+      return "RW_T3T_CMD_UPDATE_NDEF";
+
+    case RW_T3T_CMD_CHECK:
+      return "RW_T3T_CMD_CHECK";
+
+    case RW_T3T_CMD_UPDATE:
+      return "RW_T3T_CMD_UPDATE";
+
+    case RW_T3T_CMD_SEND_RAW_FRAME:
+      return "RW_T3T_CMD_SEND_RAW_FRAME";
+
+    case RW_T3T_CMD_GET_SYSTEM_CODES:
+      return "RW_T3T_CMD_GET_SYSTEM_CODES";
+
+    default:
+      return "Unknown";
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t3t_state_str
+**
+** Description      Converts state_id to command string for logging
+**
+** Returns          command string
+**
+*******************************************************************************/
+static char* rw_t3t_state_str(uint8_t state_id) {
+  switch (state_id) {
+    case RW_T3T_STATE_NOT_ACTIVATED:
+      return "RW_T3T_STATE_NOT_ACTIVATED";
+
+    case RW_T3T_STATE_IDLE:
+      return "RW_T3T_STATE_IDLE";
+
+    case RW_T3T_STATE_COMMAND_PENDING:
+      return "RW_T3T_STATE_COMMAND_PENDING";
+
+    default:
+      return "Unknown";
+  }
+}
+#endif
+
+/*****************************************************************************
+**  Type3 Tag API Functions
+*****************************************************************************/
+
+/*****************************************************************************
+**
+** Function         RW_T3tDetectNDef
+**
+** Description
+**      This function is used to perform NDEF detection on a Type 3 tag, and
+**      retrieve the tag's NDEF attribute information (block 0).
+**
+**      Before using this API, the application must call RW_SelectTagType to
+**      indicate that a Type 3 tag has been activated, and to provide the
+**      tag's Manufacture ID (IDm) .
+**
+** Returns
+**      NFC_STATUS_OK: ndef detection procedure started
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tDetectNDef(void) {
+  tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
+  tNFC_STATUS retval = NFC_STATUS_OK;
+
+  RW_TRACE_API0("RW_T3tDetectNDef");
+
+  /* Check if we are in valid state to handle this API */
+  if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
+    RW_TRACE_ERROR1("Error: invalid state to handle API (0x%x)",
+                    p_cb->rw_state);
+    return (NFC_STATUS_FAILED);
+  }
+
+  retval = (tNFC_STATUS)nci_snd_t3t_polling(T3T_SYSTEM_CODE_NDEF, 0, 0);
+  if (retval == NCI_STATUS_OK) {
+    p_cb->cur_cmd = RW_T3T_CMD_DETECT_NDEF;
+    p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
+    p_cb->cur_poll_rc = 0;
+    p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
+    p_cb->flags |= RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
+
+    /* start timer for waiting for responses */
+    rw_t3t_start_poll_timer(p_cb);
+  }
+
+  return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         RW_T3tCheckNDef
+**
+** Description
+**      Retrieve NDEF contents from a Type3 tag.
+**
+**      The RW_T3T_CHECK_EVT event is used to notify the application for each
+**      segment of NDEF data received. The RW_T3T_CHECK_CPLT_EVT event is used
+**      to notify the application all segments have been received.
+**
+**      Before using this API, the RW_T3tDetectNDef function must be called to
+**      verify that the tag contains NDEF data, and to retrieve the NDEF
+**      attributes.
+**
+**      Internally, this command will be separated into multiple Tag 3 Check
+**      commands (if necessary) - depending on the tag's Nbr (max number of
+**      blocks per read) attribute.
+**
+** Returns
+**      NFC_STATUS_OK: check command started
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tCheckNDef(void) {
+  tNFC_STATUS retval = NFC_STATUS_OK;
+  tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
+
+  RW_TRACE_API0("RW_T3tCheckNDef");
+
+  /* Check if we are in valid state to handle this API */
+  if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
+    RW_TRACE_ERROR1("Error: invalid state to handle API (0x%x)",
+                    p_cb->rw_state);
+    return (NFC_STATUS_FAILED);
+  } else if (p_cb->ndef_attrib.status !=
+             NFC_STATUS_OK) /* NDEF detection not performed yet? */
+  {
+    RW_TRACE_ERROR0("Error: NDEF detection not performed yet");
+    return (NFC_STATUS_NOT_INITIALIZED);
+  } else if (p_cb->ndef_attrib.ln == 0) {
+    RW_TRACE_ERROR0("Type 3 tag contains empty NDEF message");
+    return (NFC_STATUS_FAILED);
+  }
+
+  /* Check number of blocks needed for this update */
+  p_cb->flags &= ~RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
+  p_cb->ndef_rx_offset = 0;
+  retval = rw_t3t_send_next_ndef_check_cmd(p_cb);
+
+  return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         RW_T3tUpdateNDef
+**
+** Description
+**      Write NDEF contents to a Type3 tag.
+**
+**      The RW_T3T_UPDATE_CPLT_EVT callback event will be used to notify the
+**      application of the response.
+**
+**      Before using this API, the RW_T3tDetectNDef function must be called to
+**      verify that the tag contains NDEF data, and to retrieve the NDEF
+**      attributes.
+**
+**      Internally, this command will be separated into multiple Tag 3 Update
+**      commands (if necessary) - depending on the tag's Nbw (max number of
+**      blocks per write) attribute.
+**
+** Returns
+**      NFC_STATUS_OK: check command started
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_REFUSED: tag is read-only
+**      NFC_STATUS_BUFFER_FULL: len exceeds tag's maximum size
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tUpdateNDef(uint32_t len, uint8_t* p_data) {
+  tNFC_STATUS retval = NFC_STATUS_OK;
+  tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
+
+  RW_TRACE_API1("RW_T3tUpdateNDef (len=%i)", len);
+
+  /* Check if we are in valid state to handle this API */
+  if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
+    RW_TRACE_ERROR1("Error: invalid state to handle API (0x%x)",
+                    p_cb->rw_state);
+    return (NFC_STATUS_FAILED);
+  } else if (p_cb->ndef_attrib.status !=
+             NFC_STATUS_OK) /* NDEF detection not performed yet? */
+  {
+    RW_TRACE_ERROR0("Error: NDEF detection not performed yet");
+    return (NFC_STATUS_NOT_INITIALIZED);
+  } else if (len > (((uint32_t)p_cb->ndef_attrib.nmaxb) *
+                    16)) /* Len exceed's tag's NDEF memory? */
+  {
+    return (NFC_STATUS_BUFFER_FULL);
+  } else if (p_cb->ndef_attrib.rwflag ==
+             T3T_MSG_NDEF_RWFLAG_RO) /* Tag's NDEF memory is read-only? */
+  {
+    return (NFC_STATUS_REFUSED);
+  }
+
+  /* Check number of blocks needed for this update */
+  p_cb->flags &= ~RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
+  p_cb->ndef_msg_bytes_sent = 0;
+  p_cb->ndef_msg_len = len;
+  p_cb->ndef_msg = p_data;
+
+  /* Send initial UPDATE command for NDEF Attribute Info */
+  retval = rw_t3t_send_update_ndef_attribute_cmd(p_cb, true);
+
+  return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         RW_T3tCheck
+**
+** Description
+**      Read (non-NDEF) contents from a Type3 tag.
+**
+**      The RW_READ_EVT event is used to notify the application for each
+**      segment of NDEF data received. The RW_READ_CPLT_EVT event is used to
+**      notify the application all segments have been received.
+**
+**      Before using this API, the application must call RW_SelectTagType to
+**      indicate that a Type 3 tag has been activated, and to provide the
+**      tag's Manufacture ID (IDm) .
+**
+** Returns
+**      NFC_STATUS_OK: check command started
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tCheck(uint8_t num_blocks, tT3T_BLOCK_DESC* t3t_blocks) {
+  tNFC_STATUS retval = NFC_STATUS_OK;
+  tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
+
+  RW_TRACE_API1("RW_T3tCheck (num_blocks = %i)", num_blocks);
+
+  /* Check if we are in valid state to handle this API */
+  if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
+    RW_TRACE_ERROR1("Error: invalid state to handle API (0x%x)",
+                    p_cb->rw_state);
+    return (NFC_STATUS_FAILED);
+  }
+
+  /* Send the CHECK command */
+  retval = rw_t3t_send_check_cmd(p_cb, num_blocks, t3t_blocks);
+
+  return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         RW_T3tUpdate
+**
+** Description
+**      Write (non-NDEF) contents to a Type3 tag.
+**
+**      The RW_WRITE_CPLT_EVT event is used to notify the application all
+**      segments have been received.
+**
+**      Before using this API, the application must call RW_SelectTagType to
+**      indicate that a Type 3 tag has been activated, and to provide the tag's
+**      Manufacture ID (IDm) .
+**
+** Returns
+**      NFC_STATUS_OK: check command started
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tUpdate(uint8_t num_blocks, tT3T_BLOCK_DESC* t3t_blocks,
+                         uint8_t* p_data) {
+  tNFC_STATUS retval = NFC_STATUS_OK;
+  tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
+
+  RW_TRACE_API1("RW_T3tUpdate (num_blocks = %i)", num_blocks);
+
+  /* Check if we are in valid state to handle this API */
+  if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
+    RW_TRACE_ERROR1("Error: invalid state to handle API (0x%x)",
+                    p_cb->rw_state);
+    return (NFC_STATUS_FAILED);
+  }
+
+  /* Send the UPDATE command */
+  retval = rw_t3t_send_update_cmd(p_cb, num_blocks, t3t_blocks, p_data);
+
+  return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         RW_T3tPresenceCheck
+**
+** Description
+**      Check if the tag is still in the field.
+**
+**      The RW_T3T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
+**      or non-presence.
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tPresenceCheck(void) {
+  tNFC_STATUS retval = NFC_STATUS_OK;
+  tRW_DATA evt_data;
+  tRW_CB* p_rw_cb = &rw_cb;
+
+  RW_TRACE_API0("RW_T3tPresenceCheck");
+
+  /* If RW_SelectTagType was not called (no conn_callback) return failure */
+  if (!(p_rw_cb->p_cback)) {
+    retval = NFC_STATUS_FAILED;
+  }
+  /* If we are not activated, then RW_T3T_PRESENCE_CHECK_EVT status=FAIL */
+  else if (p_rw_cb->tcb.t3t.rw_state == RW_T3T_STATE_NOT_ACTIVATED) {
+    evt_data.status = NFC_STATUS_FAILED;
+    (*p_rw_cb->p_cback)(RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
+  }
+  /* If command is pending */
+  else if (p_rw_cb->tcb.t3t.rw_state == RW_T3T_STATE_COMMAND_PENDING) {
+    /* If already performing presence check, return error */
+    if (p_rw_cb->tcb.t3t.flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP) {
+      RW_TRACE_DEBUG0("RW_T3tPresenceCheck already in progress");
+      retval = NFC_STATUS_FAILED;
+    }
+    /* If busy with any other command, assume that the tag is present */
+    else {
+      evt_data.status = NFC_STATUS_OK;
+      (*p_rw_cb->p_cback)(RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
+    }
+  } else {
+    /* IDLE state: send POLL command */
+    retval = (tNFC_STATUS)nci_snd_t3t_polling(0xFFFF, T3T_POLL_RC_SC, 0);
+    if (retval == NCI_STATUS_OK) {
+      p_rw_cb->tcb.t3t.flags |= RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
+      p_rw_cb->tcb.t3t.rw_state = RW_T3T_STATE_COMMAND_PENDING;
+      p_rw_cb->tcb.t3t.cur_poll_rc = 0;
+
+      /* start timer for waiting for responses */
+      rw_t3t_start_poll_timer(&p_rw_cb->tcb.t3t);
+    } else {
+      RW_TRACE_DEBUG1(
+          "RW_T3tPresenceCheck error sending NCI_RF_T3T_POLLING cmd (status = "
+          "0x%0x)",
+          retval);
+    }
+  }
+
+  return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         RW_T3tPoll
+**
+** Description
+**      Send POLL command
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tPoll(uint16_t system_code, tT3T_POLL_RC rc, uint8_t tsn) {
+  tNFC_STATUS retval = NFC_STATUS_OK;
+  tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
+
+  RW_TRACE_API0("RW_T3tPoll");
+
+  /* Check if we are in valid state to handle this API */
+  if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
+    RW_TRACE_ERROR1("Error: invalid state to handle API (0x%x)",
+                    p_cb->rw_state);
+    return (NFC_STATUS_FAILED);
+  }
+
+  retval = (tNFC_STATUS)nci_snd_t3t_polling(system_code, (uint8_t)rc, tsn);
+  if (retval == NCI_STATUS_OK) {
+    /* start timer for waiting for responses */
+    p_cb->cur_poll_rc = rc;
+    p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
+    rw_t3t_start_poll_timer(p_cb);
+  }
+
+  return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         RW_T3tSendRawFrame
+**
+** Description
+**      This function is called to send a raw data frame to the peer device.
+**      When type 3 tag receives response from peer, the callback function
+**      will be called with a RW_T3T_RAW_FRAME_EVT [Table 6].
+**
+**      Before using this API, the application must call RW_SelectTagType to
+**      indicate that a Type 3 tag has been activated.
+**
+**      The raw frame should be a properly formatted Type 3 tag message.
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tSendRawFrame(uint16_t len, uint8_t* p_data) {
+  tNFC_STATUS retval = NFC_STATUS_OK;
+  tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
+
+  RW_TRACE_API1("RW_T3tSendRawFrame (len = %i)", len);
+
+  /* Check if we are in valid state to handle this API */
+  if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
+    RW_TRACE_ERROR1("Error: invalid state to handle API (0x%x)",
+                    p_cb->rw_state);
+    return (NFC_STATUS_FAILED);
+  }
+
+  /* Send the UPDATE command */
+  retval = rw_t3t_send_raw_frame(p_cb, len, p_data);
+
+  return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         RW_T3tGetSystemCodes
+**
+** Description
+**      Get systems codes supported by the activated tag:
+**              Poll for wildcard (FFFF, RC=1):
+**
+**      Before using this API, the application must call RW_SelectTagType to
+**      indicate that a Type 3 tag has been activated.
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tGetSystemCodes(void) {
+  tNFC_STATUS retval = NFC_STATUS_OK;
+  tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
+
+  RW_TRACE_API0("RW_T3tGetSystemCodes");
+
+  /* Check if we are in valid state to handle this API */
+  if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
+    RW_TRACE_ERROR1("Error: invalid state to handle API (0x%x)",
+                    p_cb->rw_state);
+    return (NFC_STATUS_FAILED);
+  } else {
+    retval = (tNFC_STATUS)nci_snd_t3t_polling(0xFFFF, T3T_POLL_RC_SC, 0);
+    if (retval == NCI_STATUS_OK) {
+      p_cb->cur_cmd = RW_T3T_CMD_GET_SYSTEM_CODES;
+      p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
+      p_cb->cur_poll_rc = T3T_POLL_RC_SC;
+      p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
+      p_cb->flags |= RW_T3T_FL_W4_GET_SC_POLL_RSP;
+      p_cb->num_system_codes = 0;
+
+      /* start timer for waiting for responses */
+      rw_t3t_start_poll_timer(p_cb);
+    }
+  }
+
+  return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         RW_T3tFormatNDef
+**
+** Description
+**      Format a type-3 tag for NDEF.
+**
+**      Only Felica-Lite tags are supported by this API. The
+**      RW_T3T_FORMAT_CPLT_EVT is used to notify the status of the operation.
+**
+** Returns
+**      NFC_STATUS_OK: ndef detection procedure started
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tFormatNDef(void) {
+  tNFC_STATUS retval = NFC_STATUS_OK;
+  tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
+
+  RW_TRACE_API0("RW_T3tFormatNDef");
+
+  /* Check if we are in valid state to handle this API */
+  if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
+    RW_TRACE_ERROR1("Error: invalid state to handle API (0x%x)",
+                    p_cb->rw_state);
+    return (NFC_STATUS_FAILED);
+  } else {
+    /* Poll tag, to see if Felica-Lite system is supported */
+    retval = (tNFC_STATUS)nci_snd_t3t_polling(T3T_SYSTEM_CODE_FELICA_LITE,
+                                              T3T_POLL_RC_SC, 0);
+    if (retval == NCI_STATUS_OK) {
+      p_cb->cur_cmd = RW_T3T_CMD_FORMAT;
+      p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
+      p_cb->cur_poll_rc = T3T_POLL_RC_SC;
+      p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
+      p_cb->rw_substate = RW_T3T_FMT_SST_POLL_FELICA_LITE;
+      p_cb->flags |= RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
+
+      /* start timer for waiting for responses */
+      rw_t3t_start_poll_timer(p_cb);
+    }
+  }
+
+  return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         RW_T3tSetReadOnly
+**
+** Description      This function performs NDEF read-only procedure
+**                  Note: Only Felica-Lite tags are supported by this API.
+**                        RW_T3tDetectNDef() must be called before using this
+**
+**                  The RW_T3T_SET_READ_ONLY_CPLT_EVT event will be returned.
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if T3T is busy or other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tSetReadOnly(bool b_hard_lock) {
+  tNFC_STATUS retval = NFC_STATUS_OK;
+  tRW_T3T_CB* p_cb = &rw_cb.tcb.t3t;
+  tRW_DATA evt_data;
+
+  RW_TRACE_API1("RW_T3tSetReadOnly (): b_hard_lock=%d", b_hard_lock);
+
+  /* Check if we are in valid state to handle this API */
+  if (p_cb->rw_state != RW_T3T_STATE_IDLE) {
+    RW_TRACE_ERROR1("Error: invalid state to handle API (0x%x)",
+                    p_cb->rw_state);
+    return (NFC_STATUS_FAILED);
+  }
+
+  if (p_cb->ndef_attrib.status !=
+      NFC_STATUS_OK) /* NDEF detection not performed yet? */
+  {
+    RW_TRACE_ERROR0("Error: NDEF detection not performed yet");
+    return (NFC_STATUS_NOT_INITIALIZED);
+  }
+
+  if ((!b_hard_lock) &&
+      (p_cb->ndef_attrib.rwflag ==
+       T3T_MSG_NDEF_RWFLAG_RO)) /* Tag's NDEF memory is read-only already */
+  {
+    evt_data.status = NFC_STATUS_OK;
+    (*(rw_cb.p_cback))(RW_T3T_SET_READ_ONLY_CPLT_EVT, &evt_data);
+    return (retval);
+  } else {
+    /* Poll tag, to see if Felica-Lite system is supported */
+    retval = (tNFC_STATUS)nci_snd_t3t_polling(T3T_SYSTEM_CODE_FELICA_LITE,
+                                              T3T_POLL_RC_SC, 0);
+    if (retval == NCI_STATUS_OK) {
+      if (b_hard_lock)
+        p_cb->cur_cmd = RW_T3T_CMD_SET_READ_ONLY_HARD;
+      else
+        p_cb->cur_cmd = RW_T3T_CMD_SET_READ_ONLY_SOFT;
+      p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
+      p_cb->cur_poll_rc = T3T_POLL_RC_SC;
+      p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
+      p_cb->rw_substate = RW_T3T_SRO_SST_POLL_FELICA_LITE;
+      p_cb->flags |= RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP;
+
+      /* start timer for waiting for responses */
+      rw_t3t_start_poll_timer(p_cb);
+    }
+  }
+  return (retval);
+}
diff --git a/src/nfc/tags/rw_t4t.c b/src/nfc/tags/rw_t4t.c
new file mode 100644
index 0000000..b9392f3
--- /dev/null
+++ b/src/nfc/tags/rw_t4t.c
@@ -0,0 +1,2476 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the implementation for Type 4 tag in Reader/Writer
+ *  mode.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "trace_api.h"
+
+#include "nfc_api.h"
+#include "nfc_int.h"
+#include "rw_api.h"
+#include "rw_int.h"
+#include "tags_int.h"
+#include "gki.h"
+
+/* main state */
+/* T4T is not activated                 */
+#define RW_T4T_STATE_NOT_ACTIVATED 0x00
+/* waiting for upper layer API          */
+#define RW_T4T_STATE_IDLE 0x01
+/* performing NDEF detection precedure  */
+#define RW_T4T_STATE_DETECT_NDEF 0x02
+/* performing read NDEF procedure       */
+#define RW_T4T_STATE_READ_NDEF 0x03
+/* performing update NDEF procedure     */
+#define RW_T4T_STATE_UPDATE_NDEF 0x04
+/* checking presence of tag             */
+#define RW_T4T_STATE_PRESENCE_CHECK 0x05
+/* convert tag to read only             */
+#define RW_T4T_STATE_SET_READ_ONLY 0x06
+
+/* performing NDEF format               */
+#define RW_T4T_STATE_NDEF_FORMAT 0x07
+#if (NXP_EXTNS == TRUE)
+#define RW_T3BT_STATE_GET_PROP_DATA 0x08
+#endif
+/* sub state */
+/* waiting for response of selecting AID    */
+#define RW_T4T_SUBSTATE_WAIT_SELECT_APP 0x00
+/* waiting for response of selecting CC     */
+#define RW_T4T_SUBSTATE_WAIT_SELECT_CC 0x01
+/* waiting for response of reading CC       */
+#define RW_T4T_SUBSTATE_WAIT_CC_FILE 0x02
+/* waiting for response of selecting NDEF   */
+#define RW_T4T_SUBSTATE_WAIT_SELECT_NDEF_FILE 0x03
+/* waiting for response of reading NLEN     */
+#define RW_T4T_SUBSTATE_WAIT_READ_NLEN 0x04
+/* waiting for response of reading file     */
+#define RW_T4T_SUBSTATE_WAIT_READ_RESP 0x05
+/* waiting for response of updating file    */
+#define RW_T4T_SUBSTATE_WAIT_UPDATE_RESP 0x06
+/* waiting for response of updating NLEN    */
+#define RW_T4T_SUBSTATE_WAIT_UPDATE_NLEN 0x07
+/* waiting for response of updating CC      */
+#define RW_T4T_SUBSTATE_WAIT_UPDATE_CC 0x08
+
+#define RW_T4T_SUBSTATE_WAIT_GET_HW_VERSION 0x09
+#define RW_T4T_SUBSTATE_WAIT_GET_SW_VERSION 0x0A
+#define RW_T4T_SUBSTATE_WAIT_GET_UID 0x0B
+#define RW_T4T_SUBSTATE_WAIT_CREATE_APP 0x0C
+#define RW_T4T_SUBSTATE_WAIT_CREATE_CC 0x0D
+#define RW_T4T_SUBSTATE_WAIT_CREATE_NDEF 0x0E
+#define RW_T4T_SUBSTATE_WAIT_WRITE_CC 0x0F
+#define RW_T4T_SUBSTATE_WAIT_WRITE_NDEF 0x10
+#if (NXP_EXTNS == TRUE)
+#define RW_T3BT_SUBSTATE_WAIT_GET_ATTRIB 0x11
+#define RW_T3BT_SUBSTATE_WAIT_GET_PUPI 0x12
+#endif
+
+#if (BT_TRACE_VERBOSE == true)
+static char* rw_t4t_get_state_name(uint8_t state);
+static char* rw_t4t_get_sub_state_name(uint8_t sub_state);
+#endif
+
+static bool rw_t4t_send_to_lower(NFC_HDR* p_c_apdu);
+static bool rw_t4t_select_file(uint16_t file_id);
+static bool rw_t4t_read_file(uint16_t offset, uint16_t length,
+                             bool is_continue);
+static bool rw_t4t_update_nlen(uint16_t ndef_len);
+static bool rw_t4t_update_file(void);
+static bool rw_t4t_update_cc_to_readonly(void);
+static bool rw_t4t_select_application(uint8_t version);
+static bool rw_t4t_validate_cc_file(void);
+
+static bool rw_t4t_get_hw_version(void);
+static bool rw_t4t_get_sw_version(void);
+static bool rw_t4t_create_app(void);
+static bool rw_t4t_select_app(void);
+static bool rw_t4t_create_ccfile(void);
+static bool rw_t4t_create_ndef(void);
+static bool rw_t4t_write_cc(void);
+static bool rw_t4t_write_ndef(void);
+#if (NXP_EXTNS == TRUE)
+static bool rw_t3bt_get_pupi(void);
+static void rw_t3Bt_sm_get_card_id(NFC_HDR* p_r_apdu);
+#endif
+static void rw_t4t_sm_ndef_format(NFC_HDR* p_r_apdu);
+static void rw_t4t_handle_error(tNFC_STATUS status, uint8_t sw1, uint8_t sw2);
+static void rw_t4t_sm_detect_ndef(NFC_HDR* p_r_apdu);
+static void rw_t4t_sm_read_ndef(NFC_HDR* p_r_apdu);
+static void rw_t4t_sm_update_ndef(NFC_HDR* p_r_apdu);
+static void rw_t4t_sm_set_readonly(NFC_HDR* p_r_apdu);
+static void rw_t4t_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
+                              tNFC_CONN* p_data);
+
+/*******************************************************************************
+**
+** Function         rw_t4t_send_to_lower
+**
+** Description      Send C-APDU to lower layer
+**
+** Returns          true if success
+**
+*******************************************************************************/
+static bool rw_t4t_send_to_lower(NFC_HDR* p_c_apdu) {
+#if (BT_TRACE_PROTOCOL == true)
+  DispRWT4Tags(p_c_apdu, false);
+#endif
+
+  if (NFC_SendData(NFC_RF_CONN_ID, p_c_apdu) != NFC_STATUS_OK) {
+    RW_TRACE_ERROR0("rw_t4t_send_to_lower (): NFC_SendData () failed");
+    return false;
+  }
+
+  nfc_start_quick_timer(&rw_cb.tcb.t4t.timer, NFC_TTYPE_RW_T4T_RESPONSE,
+                        (RW_T4T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_get_hw_version
+**
+** Description      Send get hw version cmd to peer
+**
+** Returns          true if success
+**
+*******************************************************************************/
+static bool rw_t4t_get_hw_version(void) {
+  NFC_HDR* p_c_apdu;
+  uint8_t* p;
+
+  p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_c_apdu) {
+    RW_TRACE_ERROR0("rw_t4t_get_hw_version (): Cannot allocate buffer");
+    return false;
+  }
+
+  p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
+
+  UINT8_TO_BE_STREAM(p, T4T_CMD_DES_CLASS);
+  UINT8_TO_BE_STREAM(p, T4T_CMD_INS_GET_HW_VERSION);
+  UINT16_TO_BE_STREAM(p, 0x0000);
+  UINT8_TO_BE_FIELD(p, 0x00);
+
+  p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE;
+
+  if (!rw_t4t_send_to_lower(p_c_apdu)) {
+    return false;
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_get_sw_version
+**
+** Description      Send get sw version cmd to peer
+**
+** Returns          true if success
+**
+*******************************************************************************/
+static bool rw_t4t_get_sw_version(void) {
+  NFC_HDR* p_c_apdu;
+  uint8_t* p;
+
+  p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_c_apdu) {
+    RW_TRACE_ERROR0("rw_t4t_get_sw_version (): Cannot allocate buffer");
+    return false;
+  }
+
+  p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
+
+  UINT8_TO_BE_STREAM(p, T4T_CMD_DES_CLASS);
+  UINT8_TO_BE_STREAM(p, T4T_ADDI_FRAME_RESP);
+  UINT16_TO_BE_STREAM(p, 0x0000);
+  UINT8_TO_BE_FIELD(p, 0x00);
+
+  p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE;
+
+  if (!rw_t4t_send_to_lower(p_c_apdu)) {
+    return false;
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_update_version_details
+**
+** Description      Updates the size of the card
+**
+** Returns          true if success
+**
+*******************************************************************************/
+static bool rw_t4t_update_version_details(NFC_HDR* p_r_apdu) {
+  tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
+  uint8_t* p;
+  uint16_t major_version, minor_version;
+
+  p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
+  major_version = *(p + 3);
+  minor_version = *(p + 4);
+
+  if ((T4T_DESEV0_MAJOR_VERSION == major_version) &&
+      (T4T_DESEV0_MINOR_VERSION == minor_version)) {
+    p_t4t->card_size = 0xEDE;
+  } else if (major_version >= T4T_DESEV1_MAJOR_VERSION) {
+    p_t4t->card_type = T4T_TYPE_DESFIRE_EV1;
+    switch (*(p + 5)) {
+      case T4T_SIZE_IDENTIFIER_2K:
+        p_t4t->card_size = 2048;
+        break;
+      case T4T_SIZE_IDENTIFIER_4K:
+        p_t4t->card_size = 4096;
+        break;
+      case T4T_SIZE_IDENTIFIER_8K:
+        p_t4t->card_size = 7680;
+        break;
+      default:
+        return false;
+    }
+  } else {
+    return false;
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_get_uid_details
+**
+** Description      Send get uid cmd to peer
+**
+** Returns          true if success
+**
+*******************************************************************************/
+static bool rw_t4t_get_uid_details(void) {
+  NFC_HDR* p_c_apdu;
+  uint8_t* p;
+
+  p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_c_apdu) {
+    RW_TRACE_ERROR0("rw_t4t_get_uid_details (): Cannot allocate buffer");
+    return false;
+  }
+
+  p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
+
+  UINT8_TO_BE_STREAM(p, T4T_CMD_DES_CLASS);
+  UINT8_TO_BE_STREAM(p, T4T_ADDI_FRAME_RESP);
+  UINT16_TO_BE_STREAM(p, 0x0000);
+  UINT8_TO_BE_FIELD(p, 0x00);
+
+  p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE;
+
+  if (!rw_t4t_send_to_lower(p_c_apdu)) {
+    return false;
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_create_app
+**
+** Description      Send create application cmd to peer
+**
+** Returns          true if success
+**
+*******************************************************************************/
+static bool rw_t4t_create_app(void) {
+  tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
+  NFC_HDR* p_c_apdu;
+  uint8_t* p;
+  uint8_t df_name[] = {0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01};
+
+  p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_c_apdu) {
+    RW_TRACE_ERROR0("rw_t4t_create_app (): Cannot allocate buffer");
+    return false;
+  }
+
+  p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
+
+  UINT8_TO_BE_STREAM(p, T4T_CMD_DES_CLASS);
+  UINT8_TO_BE_STREAM(p, T4T_CMD_CREATE_AID);
+  UINT16_TO_BE_STREAM(p, 0x0000);
+  if (p_t4t->card_type == T4T_TYPE_DESFIRE_EV1) {
+    UINT8_TO_BE_STREAM(p, (T4T_CMD_MAX_HDR_SIZE + sizeof(df_name) + 2));
+    UINT24_TO_BE_STREAM(p, T4T_DES_EV1_NFC_APP_ID);
+    UINT16_TO_BE_STREAM(p, 0x0F21); /*Key settings and no.of keys */
+    UINT16_TO_BE_STREAM(p, 0x05E1); /* ISO file ID */
+    ARRAY_TO_BE_STREAM(p, df_name, (int)sizeof(df_name)); /*DF file name */
+    UINT8_TO_BE_STREAM(p, 0x00);                          /* Le */
+    p_c_apdu->len = 20;
+  } else {
+    UINT8_TO_BE_STREAM(p, T4T_CMD_MAX_HDR_SIZE);
+    UINT24_TO_BE_STREAM(p, T4T_DES_EV0_NFC_APP_ID);
+    UINT16_TO_BE_STREAM(p, 0x0F01); /*Key settings and no.of keys */
+    UINT8_TO_BE_STREAM(p, 0x00);    /* Le */
+    p_c_apdu->len = 11;
+  }
+
+  if (!rw_t4t_send_to_lower(p_c_apdu)) {
+    return false;
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_select_app
+**
+** Description      Select application cmd to peer
+**
+** Returns          true if success
+**
+*******************************************************************************/
+static bool rw_t4t_select_app(void) {
+  tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
+  NFC_HDR* p_c_apdu;
+  uint8_t* p;
+
+  p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_c_apdu) {
+    RW_TRACE_ERROR0("rw_t4t_select_app (): Cannot allocate buffer");
+    return false;
+  }
+
+  p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
+
+  UINT8_TO_BE_STREAM(p, T4T_CMD_DES_CLASS);
+  UINT8_TO_BE_STREAM(p, T4T_CMD_SELECT_APP);
+  UINT16_TO_BE_STREAM(p, 0x0000);
+  UINT8_TO_BE_STREAM(p, 0x03); /* Lc: length of wrapped data */
+  if (p_t4t->card_type == T4T_TYPE_DESFIRE_EV1) {
+    UINT24_TO_BE_STREAM(p, T4T_DES_EV1_NFC_APP_ID);
+  } else {
+    UINT24_TO_BE_STREAM(p, T4T_DES_EV0_NFC_APP_ID);
+  }
+  UINT8_TO_BE_STREAM(p, 0x00); /* Le */
+
+  p_c_apdu->len = 9;
+
+  if (!rw_t4t_send_to_lower(p_c_apdu)) {
+    return false;
+  }
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_create_ccfile
+**
+** Description      create capability container file cmd to peer
+**
+** Returns          true if success
+**
+*******************************************************************************/
+static bool rw_t4t_create_ccfile(void) {
+  tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
+  NFC_HDR* p_c_apdu;
+  uint8_t* p;
+
+  p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_c_apdu) {
+    RW_TRACE_ERROR0("rw_t4t_create_ccfile (): Cannot allocate buffer");
+    return false;
+  }
+
+  p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
+
+  UINT8_TO_BE_STREAM(p, T4T_CMD_DES_CLASS);
+  UINT8_TO_BE_STREAM(p, T4T_CMD_CREATE_DATAFILE);
+  UINT16_TO_BE_STREAM(p, 0x0000);
+  if (p_t4t->card_type == T4T_TYPE_DESFIRE_EV1) {
+    UINT8_TO_BE_STREAM(p, 0x09);    /* Lc: length of wrapped data */
+    UINT8_TO_BE_STREAM(p, 0x01);    /* EV1 CC file id             */
+    UINT16_TO_BE_STREAM(p, 0x03E1); /* ISO file id                */
+  } else {
+    UINT8_TO_BE_STREAM(p, 0x07); /* Lc: length of wrapped data */
+    UINT8_TO_BE_STREAM(p, 0x03); /* DESFire CC file id         */
+  }
+  UINT8_TO_BE_STREAM(p, 0x00);      /* COMM settings              */
+  UINT16_TO_BE_STREAM(p, 0xEEEE);   /* Access rights              */
+  UINT24_TO_BE_STREAM(p, 0x0F0000); /* Set file size              */
+  UINT8_TO_BE_STREAM(p, 0x00);      /* Le                         */
+
+  p_c_apdu->len = (p_t4t->card_type == T4T_TYPE_DESFIRE_EV1) ? 15 : 13;
+
+  if (!rw_t4t_send_to_lower(p_c_apdu)) {
+    return false;
+  }
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_create_ndef
+**
+** Description      creates an ndef file cmd to peer
+**
+** Returns          true if success
+**
+*******************************************************************************/
+static bool rw_t4t_create_ndef(void) {
+  tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
+  NFC_HDR* p_c_apdu;
+  uint8_t* p;
+
+  p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_c_apdu) {
+    RW_TRACE_ERROR0("rw_t4t_create_ndef (): Cannot allocate buffer");
+    return false;
+  }
+
+  p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
+
+  UINT8_TO_BE_STREAM(p, T4T_CMD_DES_CLASS);
+  UINT8_TO_BE_STREAM(p, T4T_CMD_CREATE_DATAFILE);
+  UINT16_TO_BE_STREAM(p, 0x0000);
+  if (p_t4t->card_type == T4T_TYPE_DESFIRE_EV1) {
+    UINT8_TO_BE_STREAM(p, 0x09);    /* Lc: length of wrapped data */
+    UINT8_TO_BE_STREAM(p, 0x02);    /* DESFEv1 NDEF file id       */
+    UINT16_TO_BE_STREAM(p, 0x04E1); /* ISO file id                */
+  } else {
+    UINT8_TO_BE_STREAM(p, 0x07);
+    UINT8_TO_BE_STREAM(p, 0x04); /* DESF4 NDEF file id        */
+  }
+
+  UINT8_TO_BE_STREAM(p, 0x00);    /* COMM settings              */
+  UINT16_TO_BE_STREAM(p, 0xEEEE); /* Access rights              */
+  UINT16_TO_STREAM(p, p_t4t->card_size);
+  UINT8_TO_BE_STREAM(p, 0x00); /* Set card size              */
+  UINT8_TO_BE_STREAM(p, 0x00); /* Le                         */
+
+  p_c_apdu->len = (p_t4t->card_type == T4T_TYPE_DESFIRE_EV1) ? 15 : 13;
+
+  if (!rw_t4t_send_to_lower(p_c_apdu)) {
+    return false;
+  }
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_write_cc
+**
+** Description      sends write cc file cmd to peer
+**
+** Returns          true if success
+**
+*******************************************************************************/
+static bool rw_t4t_write_cc(void) {
+  tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
+  NFC_HDR* p_c_apdu;
+  uint8_t* p;
+  uint8_t CCFileBytes[] = {0x00, 0x0F, 0x10, 0x00, 0x3B, 0x00, 0x34, 0x04,
+                           0x06, 0xE1, 0x04, 0x04, 0x00, 0x00, 0x00};
+
+  p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_c_apdu) {
+    RW_TRACE_ERROR0("rw_t4t_write_cc (): Cannot allocate buffer");
+    return false;
+  }
+
+  p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
+
+  UINT8_TO_BE_STREAM(p, T4T_CMD_DES_CLASS);
+  UINT8_TO_BE_STREAM(p, T4T_CMD_DES_WRITE);
+  UINT16_TO_BE_STREAM(p, 0x0000);
+  UINT8_TO_BE_STREAM(p, 0x16); /* Lc: length of wrapped data  */
+  if (p_t4t->card_type == T4T_TYPE_DESFIRE_EV1) {
+    CCFileBytes[2] = 0x20;
+    CCFileBytes[11] = p_t4t->card_size >> 8;
+    CCFileBytes[12] = (uint8_t)p_t4t->card_size;
+    UINT8_TO_BE_STREAM(p, 0x01); /* CC file id                  */
+  } else {
+    UINT8_TO_BE_STREAM(p, 0x03);
+  }
+  UINT24_TO_BE_STREAM(p, 0x000000); /* Set the offset              */
+  UINT24_TO_BE_STREAM(p, 0x0F0000); /* Set available length        */
+  ARRAY_TO_BE_STREAM(p, CCFileBytes, (int)sizeof(CCFileBytes));
+  UINT8_TO_BE_STREAM(p, 0x00); /* Le                         */
+
+  p_c_apdu->len = 28;
+
+  if (!rw_t4t_send_to_lower(p_c_apdu)) {
+    return false;
+  }
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_write_ndef
+**
+** Description      sends write ndef file cmd to peer
+**
+** Returns          true if success
+**
+*******************************************************************************/
+static bool rw_t4t_write_ndef(void) {
+  tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
+  NFC_HDR* p_c_apdu;
+  uint8_t* p;
+
+  p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_c_apdu) {
+    RW_TRACE_ERROR0("rw_t4t_write_ndef (): Cannot allocate buffer");
+    return false;
+  }
+
+  p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
+
+  UINT8_TO_BE_STREAM(p, T4T_CMD_DES_CLASS);
+  UINT8_TO_BE_STREAM(p, T4T_CMD_DES_WRITE);
+  UINT16_TO_BE_STREAM(p, 0x0000);
+  UINT8_TO_BE_STREAM(p, 0x09); /* Lc: length of wrapped data  */
+  if (p_t4t->card_type == T4T_TYPE_DESFIRE_EV1) {
+    UINT8_TO_BE_STREAM(p, 0x02); /* DESFEv1 Ndef file id        */
+  } else {
+    UINT8_TO_BE_STREAM(p, 0x04);
+  }
+  UINT24_TO_BE_STREAM(p, 0x000000); /* Set the offset              */
+  UINT24_TO_BE_STREAM(p, 0x020000); /* Set available length        */
+  UINT16_TO_BE_STREAM(p, 0x0000);   /* Ndef file bytes             */
+  UINT8_TO_BE_STREAM(p, 0x00);      /* Le                          */
+
+  p_c_apdu->len = 15;
+
+  if (!rw_t4t_send_to_lower(p_c_apdu)) {
+    return false;
+  }
+  return true;
+}
+
+#if (NXP_EXTNS == TRUE)
+static bool rw_t3bt_get_pupi(void) {
+  tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
+  NFC_HDR* p_c_apdu;
+  uint8_t* p;
+
+  p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_c_apdu) {
+    RW_TRACE_ERROR0("rw_t3bt_get_pupi (): Cannot allocate buffer");
+    return false;
+  }
+
+  p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
+
+  UINT8_TO_BE_STREAM(p, 0x00);
+  UINT8_TO_BE_STREAM(p, 0x36);
+  UINT16_TO_BE_STREAM(p, 0x0000);
+  UINT8_TO_BE_STREAM(p, 0x08); /* Lc: length of wrapped data  */
+
+  p_c_apdu->len = 0x05;
+
+  if (!rw_t4t_send_to_lower(p_c_apdu)) {
+    return false;
+  }
+  return true;
+}
+#endif
+/*******************************************************************************
+**
+** Function         rw_t4t_select_file
+**
+** Description      Send Select Command (by File ID) to peer
+**
+** Returns          true if success
+**
+*******************************************************************************/
+static bool rw_t4t_select_file(uint16_t file_id) {
+  NFC_HDR* p_c_apdu;
+  uint8_t* p;
+
+  RW_TRACE_DEBUG1("rw_t4t_select_file (): File ID:0x%04X", file_id);
+
+  p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_c_apdu) {
+    RW_TRACE_ERROR0("rw_t4t_select_file (): Cannot allocate buffer");
+    return false;
+  }
+
+  p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
+
+  UINT8_TO_BE_STREAM(p, T4T_CMD_CLASS);
+  UINT8_TO_BE_STREAM(p, T4T_CMD_INS_SELECT);
+  UINT8_TO_BE_STREAM(p, T4T_CMD_P1_SELECT_BY_FILE_ID);
+
+  /* if current version mapping is V2.0 */
+  if (rw_cb.tcb.t4t.version == T4T_VERSION_2_0) {
+    UINT8_TO_BE_STREAM(p, T4T_CMD_P2_FIRST_OR_ONLY_0CH);
+  } else /* version 1.0 */
+  {
+    UINT8_TO_BE_STREAM(p, T4T_CMD_P2_FIRST_OR_ONLY_00H);
+  }
+
+  UINT8_TO_BE_STREAM(p, T4T_FILE_ID_SIZE);
+  UINT16_TO_BE_STREAM(p, file_id);
+
+  p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + T4T_FILE_ID_SIZE;
+
+  if (!rw_t4t_send_to_lower(p_c_apdu)) {
+    return false;
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_read_file
+**
+** Description      Send ReadBinary Command to peer
+**
+** Returns          true if success
+**
+*******************************************************************************/
+static bool rw_t4t_read_file(uint16_t offset, uint16_t length,
+                             bool is_continue) {
+  tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
+  NFC_HDR* p_c_apdu;
+  uint8_t* p;
+
+  RW_TRACE_DEBUG3("rw_t4t_read_file () offset:%d, length:%d, is_continue:%d, ",
+                  offset, length, is_continue);
+
+  p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_c_apdu) {
+    RW_TRACE_ERROR0("rw_t4t_read_file (): Cannot allocate buffer");
+    return false;
+  }
+
+  /* if this is the first reading */
+  if (is_continue == false) {
+    /* initialise starting offset and total length */
+    /* these will be updated when receiving response */
+    p_t4t->rw_offset = offset;
+    p_t4t->rw_length = length;
+  }
+
+  /* adjust reading length if payload is bigger than max size per single command
+   */
+  if (length > p_t4t->max_read_size) {
+    length = (uint8_t)(p_t4t->max_read_size);
+  }
+
+  p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
+
+  UINT8_TO_BE_STREAM(p, (T4T_CMD_CLASS | rw_cb.tcb.t4t.channel));
+  UINT8_TO_BE_STREAM(p, T4T_CMD_INS_READ_BINARY);
+  UINT16_TO_BE_STREAM(p, offset);
+  UINT8_TO_BE_STREAM(p, length); /* Le */
+
+  p_c_apdu->len = T4T_CMD_MIN_HDR_SIZE + 1; /* adding Le */
+
+  if (!rw_t4t_send_to_lower(p_c_apdu)) {
+    return false;
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_update_nlen
+**
+** Description      Send UpdateBinary Command to update NLEN to peer
+**
+** Returns          true if success
+**
+*******************************************************************************/
+static bool rw_t4t_update_nlen(uint16_t ndef_len) {
+  NFC_HDR* p_c_apdu;
+  uint8_t* p;
+
+  RW_TRACE_DEBUG1("rw_t4t_update_nlen () NLEN:%d", ndef_len);
+
+  p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_c_apdu) {
+    RW_TRACE_ERROR0("rw_t4t_update_nlen (): Cannot allocate buffer");
+    return false;
+  }
+
+  p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
+
+  UINT8_TO_BE_STREAM(p, T4T_CMD_CLASS);
+  UINT8_TO_BE_STREAM(p, T4T_CMD_INS_UPDATE_BINARY);
+  UINT16_TO_BE_STREAM(p, 0x0000); /* offset for NLEN */
+  UINT8_TO_BE_STREAM(p, T4T_FILE_LENGTH_SIZE);
+  UINT16_TO_BE_STREAM(p, ndef_len);
+
+  p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + T4T_FILE_LENGTH_SIZE;
+
+  if (!rw_t4t_send_to_lower(p_c_apdu)) {
+    return false;
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_update_file
+**
+** Description      Send UpdateBinary Command to peer
+**
+** Returns          true if success
+**
+*******************************************************************************/
+static bool rw_t4t_update_file(void) {
+  tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
+  NFC_HDR* p_c_apdu;
+  uint8_t* p;
+  uint16_t length;
+
+  RW_TRACE_DEBUG2("rw_t4t_update_file () rw_offset:%d, rw_length:%d",
+                  p_t4t->rw_offset, p_t4t->rw_length);
+
+  p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_c_apdu) {
+    RW_TRACE_ERROR0("rw_t4t_write_file (): Cannot allocate buffer");
+    return false;
+  }
+
+  /* try to send all of remaining data */
+  length = p_t4t->rw_length;
+
+  /* adjust updating length if payload is bigger than max size per single
+   * command */
+  if (length > p_t4t->max_update_size) {
+    length = (uint8_t)(p_t4t->max_update_size);
+  }
+
+  p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
+
+  UINT8_TO_BE_STREAM(p, T4T_CMD_CLASS);
+  UINT8_TO_BE_STREAM(p, T4T_CMD_INS_UPDATE_BINARY);
+  UINT16_TO_BE_STREAM(p, p_t4t->rw_offset);
+  UINT8_TO_BE_STREAM(p, length);
+
+  memcpy(p, p_t4t->p_update_data, length);
+
+  p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + length;
+
+  if (!rw_t4t_send_to_lower(p_c_apdu)) {
+    return false;
+  }
+
+  /* adjust offset, length and pointer for remaining data */
+  p_t4t->rw_offset += length;
+  p_t4t->rw_length -= length;
+  p_t4t->p_update_data += length;
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_update_cc_to_readonly
+**
+** Description      Send UpdateBinary Command for changing Write access
+**
+** Returns          true if success
+**
+*******************************************************************************/
+static bool rw_t4t_update_cc_to_readonly(void) {
+  NFC_HDR* p_c_apdu;
+  uint8_t* p;
+
+  RW_TRACE_DEBUG0(
+      "rw_t4t_update_cc_to_readonly (): Remove Write access from CC");
+
+  p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_c_apdu) {
+    RW_TRACE_ERROR0("rw_t4t_update_cc_to_readonly (): Cannot allocate buffer");
+    return false;
+  }
+
+  p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
+
+  /* Add Command Header */
+  UINT8_TO_BE_STREAM(p, T4T_CMD_CLASS);
+  UINT8_TO_BE_STREAM(p, T4T_CMD_INS_UPDATE_BINARY);
+  UINT16_TO_BE_STREAM(
+      p, (T4T_FC_TLV_OFFSET_IN_CC +
+          T4T_FC_WRITE_ACCESS_OFFSET_IN_TLV)); /* Offset for Read Write access
+                                                  byte of CC */
+  UINT8_TO_BE_STREAM(
+      p, 1); /* Length of write access field in cc interms of bytes */
+
+  /* Remove Write access */
+  UINT8_TO_BE_STREAM(p, T4T_FC_NO_WRITE_ACCESS);
+
+  p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + 1;
+
+  if (!rw_t4t_send_to_lower(p_c_apdu)) {
+    return false;
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_select_application
+**
+** Description      Select Application
+**
+**                  NDEF Tag Application Select - C-APDU
+**
+**                        CLA INS P1 P2 Lc Data(AID)      Le
+**                  V1.0: 00  A4  04 00 07 D2760000850100 -
+**                  V2.0: 00  A4  04 00 07 D2760000850101 00
+**
+** Returns          true if success
+**
+*******************************************************************************/
+static bool rw_t4t_select_application(uint8_t version) {
+  NFC_HDR* p_c_apdu;
+  uint8_t* p;
+
+  RW_TRACE_DEBUG1("rw_t4t_select_application () version:0x%X", version);
+
+  p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_c_apdu) {
+    RW_TRACE_ERROR0("rw_t4t_select_application (): Cannot allocate buffer");
+    return false;
+  }
+
+  p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
+
+  UINT8_TO_BE_STREAM(p, T4T_CMD_CLASS);
+  UINT8_TO_BE_STREAM(p, T4T_CMD_INS_SELECT);
+  UINT8_TO_BE_STREAM(p, T4T_CMD_P1_SELECT_BY_NAME);
+  UINT8_TO_BE_STREAM(p, T4T_CMD_P2_FIRST_OR_ONLY_00H);
+
+  if (version == T4T_VERSION_1_0) /* this is for V1.0 */
+  {
+    UINT8_TO_BE_STREAM(p, T4T_V10_NDEF_TAG_AID_LEN);
+
+    memcpy(p, t4t_v10_ndef_tag_aid, T4T_V10_NDEF_TAG_AID_LEN);
+
+    p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + T4T_V10_NDEF_TAG_AID_LEN;
+  } else if (version == T4T_VERSION_2_0) /* this is for V2.0 */
+  {
+    UINT8_TO_BE_STREAM(p, T4T_V20_NDEF_TAG_AID_LEN);
+
+    memcpy(p, t4t_v20_ndef_tag_aid, T4T_V20_NDEF_TAG_AID_LEN);
+    p += T4T_V20_NDEF_TAG_AID_LEN;
+
+    UINT8_TO_BE_STREAM(p, 0x00); /* Le set to 0x00 */
+
+    p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + T4T_V20_NDEF_TAG_AID_LEN + 1;
+  } else {
+    return false;
+  }
+
+  if (!rw_t4t_send_to_lower(p_c_apdu)) {
+    return false;
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_validate_cc_file
+**
+** Description      Validate CC file and mandatory NDEF TLV
+**
+** Returns          true if success
+**
+*******************************************************************************/
+static bool rw_t4t_validate_cc_file(void) {
+  tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
+
+  RW_TRACE_DEBUG0("rw_t4t_validate_cc_file ()");
+
+  if (p_t4t->cc_file.cclen < T4T_CC_FILE_MIN_LEN) {
+    RW_TRACE_ERROR1("rw_t4t_validate_cc_file (): CCLEN (%d) is too short",
+                    p_t4t->cc_file.cclen);
+    return false;
+  }
+
+  if (T4T_GET_MAJOR_VERSION(p_t4t->cc_file.version) !=
+      T4T_GET_MAJOR_VERSION(p_t4t->version)) {
+    RW_TRACE_ERROR2(
+        "rw_t4t_validate_cc_file (): Peer version (0x%02X) is matched to ours "
+        "(0x%02X)",
+        p_t4t->cc_file.version, p_t4t->version);
+    return false;
+  }
+
+  if (p_t4t->cc_file.max_le < 0x000F) {
+    RW_TRACE_ERROR1("rw_t4t_validate_cc_file (): MaxLe (%d) is too small",
+                    p_t4t->cc_file.max_le);
+    return false;
+  }
+
+  if (p_t4t->cc_file.max_lc < 0x0001) {
+    RW_TRACE_ERROR1("rw_t4t_validate_cc_file (): MaxLc (%d) is too small",
+                    p_t4t->cc_file.max_lc);
+    return false;
+  }
+
+  if ((p_t4t->cc_file.ndef_fc.file_id == T4T_CC_FILE_ID) ||
+      (p_t4t->cc_file.ndef_fc.file_id == 0xE102) ||
+      (p_t4t->cc_file.ndef_fc.file_id == 0xE103) ||
+      ((p_t4t->cc_file.ndef_fc.file_id == 0x0000) &&
+       (p_t4t->cc_file.version == 0x20)) ||
+      (p_t4t->cc_file.ndef_fc.file_id == 0x3F00) ||
+      (p_t4t->cc_file.ndef_fc.file_id == 0x3FFF) ||
+      (p_t4t->cc_file.ndef_fc.file_id == 0xFFFF)) {
+    RW_TRACE_ERROR1("rw_t4t_validate_cc_file (): File ID (0x%04X) is invalid",
+                    p_t4t->cc_file.ndef_fc.file_id);
+    return false;
+  }
+
+  if ((p_t4t->cc_file.ndef_fc.max_file_size < 0x0005) ||
+      (p_t4t->cc_file.ndef_fc.max_file_size == 0xFFFF)) {
+    RW_TRACE_ERROR1(
+        "rw_t4t_validate_cc_file (): max_file_size (%d) is reserved",
+        p_t4t->cc_file.ndef_fc.max_file_size);
+    return false;
+  }
+
+  if (p_t4t->cc_file.ndef_fc.read_access != T4T_FC_READ_ACCESS) {
+    RW_TRACE_ERROR1(
+        "rw_t4t_validate_cc_file (): Read Access (0x%02X) is invalid",
+        p_t4t->cc_file.ndef_fc.read_access);
+    return false;
+  }
+
+  if ((p_t4t->cc_file.ndef_fc.write_access != T4T_FC_WRITE_ACCESS) &&
+      (p_t4t->cc_file.ndef_fc.write_access < T4T_FC_WRITE_ACCESS_PROP_START)) {
+    RW_TRACE_ERROR1(
+        "rw_t4t_validate_cc_file (): Write Access (0x%02X) is invalid",
+        p_t4t->cc_file.ndef_fc.write_access);
+    return false;
+  }
+
+  return true;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_handle_error
+**
+** Description      notify error to application and clean up
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t4t_handle_error(tNFC_STATUS status, uint8_t sw1, uint8_t sw2) {
+  tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
+  tRW_DATA rw_data;
+  tRW_EVENT event;
+
+  RW_TRACE_DEBUG4(
+      "rw_t4t_handle_error (): status:0x%02X, sw1:0x%02X, sw2:0x%02X, "
+      "state:0x%X",
+      status, sw1, sw2, p_t4t->state);
+
+  nfc_stop_quick_timer(&p_t4t->timer);
+
+  if (rw_cb.p_cback) {
+    rw_data.status = status;
+
+    rw_data.t4t_sw.sw1 = sw1;
+    rw_data.t4t_sw.sw2 = sw2;
+
+    switch (p_t4t->state) {
+      case RW_T4T_STATE_DETECT_NDEF:
+        rw_data.ndef.flags = RW_NDEF_FL_UNKNOWN;
+        event = RW_T4T_NDEF_DETECT_EVT;
+        break;
+
+      case RW_T4T_STATE_READ_NDEF:
+        event = RW_T4T_NDEF_READ_FAIL_EVT;
+        break;
+
+      case RW_T4T_STATE_UPDATE_NDEF:
+        event = RW_T4T_NDEF_UPDATE_FAIL_EVT;
+        break;
+
+      case RW_T4T_STATE_PRESENCE_CHECK:
+        event = RW_T4T_PRESENCE_CHECK_EVT;
+        rw_data.status = NFC_STATUS_FAILED;
+        break;
+
+      case RW_T4T_STATE_SET_READ_ONLY:
+        event = RW_T4T_SET_TO_RO_EVT;
+        break;
+
+      case RW_T4T_STATE_NDEF_FORMAT:
+        event = RW_T4T_NDEF_FORMAT_CPLT_EVT;
+        rw_data.status = NFC_STATUS_FAILED;
+        break;
+#if (NXP_EXTNS == TRUE)
+      case RW_T3BT_STATE_GET_PROP_DATA:
+        event = RW_T3BT_RAW_READ_CPLT_EVT;
+        rw_data.status = NFC_STATUS_FAILED;
+        break;
+#endif
+      default:
+        event = RW_T4T_MAX_EVT;
+        break;
+    }
+
+    p_t4t->state = RW_T4T_STATE_IDLE;
+
+    if (event != RW_T4T_MAX_EVT) {
+      (*(rw_cb.p_cback))(event, &rw_data);
+    }
+  } else {
+    p_t4t->state = RW_T4T_STATE_IDLE;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_sm_ndef_format
+**
+** Description      State machine for NDEF format procedure
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t4t_sm_ndef_format(NFC_HDR* p_r_apdu) {
+  tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
+  uint8_t* p, type, length;
+  uint16_t status_words, nlen;
+  tRW_DATA rw_data;
+
+#if (BT_TRACE_VERBOSE == true)
+  RW_TRACE_DEBUG2("rw_t4t_sm_ndef_format (): sub_state:%s (%d)",
+                  rw_t4t_get_sub_state_name(p_t4t->sub_state),
+                  p_t4t->sub_state);
+#else
+  RW_TRACE_DEBUG1("rw_t4t_sm_ndef_format (): sub_state=%d", p_t4t->sub_state);
+#endif
+
+  /* get status words */
+  p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
+
+  switch (p_t4t->sub_state) {
+    case RW_T4T_SUBSTATE_WAIT_GET_HW_VERSION:
+      p += (p_r_apdu->len - 1);
+      if (*(p) == T4T_ADDI_FRAME_RESP) {
+        if (!rw_t4t_get_sw_version()) {
+          rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+        } else {
+          p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_GET_SW_VERSION;
+        }
+      } else {
+        rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+      }
+      break;
+
+    case RW_T4T_SUBSTATE_WAIT_GET_SW_VERSION:
+      p += (p_r_apdu->len - 1);
+      if (*(p) == T4T_ADDI_FRAME_RESP) {
+        if (!rw_t4t_update_version_details(p_r_apdu)) {
+          rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+        }
+        if (!rw_t4t_get_uid_details()) {
+          rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+        }
+        p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_GET_UID;
+      } else {
+        rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+      }
+      break;
+
+    case RW_T4T_SUBSTATE_WAIT_GET_UID:
+      p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
+      BE_STREAM_TO_UINT16(status_words, p);
+      if (status_words != 0x9100) {
+        rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
+      } else {
+        if (!rw_t4t_create_app()) {
+          rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+        } else {
+          p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_CREATE_APP;
+        }
+      }
+      break;
+
+    case RW_T4T_SUBSTATE_WAIT_CREATE_APP:
+      p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
+      BE_STREAM_TO_UINT16(status_words, p);
+      if (status_words == 0x91DE) /* DUPLICATE_ERROR, file already exist*/
+      {
+        status_words = 0x9100;
+      }
+      if (status_words != 0x9100) {
+        rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
+      } else {
+        if (!rw_t4t_select_app()) {
+          rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+        } else {
+          p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_APP;
+        }
+      }
+      break;
+
+    case RW_T4T_SUBSTATE_WAIT_SELECT_APP:
+      p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
+      BE_STREAM_TO_UINT16(status_words, p);
+      if (status_words != 0x9100) {
+        rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
+      } else {
+        if (!rw_t4t_create_ccfile()) {
+          rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+        } else {
+          p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_CREATE_CC;
+        }
+      }
+      break;
+
+    case RW_T4T_SUBSTATE_WAIT_CREATE_CC:
+      p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
+      BE_STREAM_TO_UINT16(status_words, p);
+      if (status_words == 0x91DE) /* DUPLICATE_ERROR, file already exist*/
+      {
+        status_words = 0x9100;
+      }
+      if (status_words != 0x9100) {
+        rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
+      } else {
+        if (!rw_t4t_create_ndef()) {
+          rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+        } else {
+          p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_CREATE_NDEF;
+        }
+      }
+      break;
+
+    case RW_T4T_SUBSTATE_WAIT_CREATE_NDEF:
+      p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
+      BE_STREAM_TO_UINT16(status_words, p);
+      if (status_words == 0x91DE) /* DUPLICATE_ERROR, file already exist*/
+      {
+        status_words = 0x9100;
+      }
+      if (status_words != 0x9100) {
+        rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
+      } else {
+        if (!rw_t4t_write_cc()) {
+          rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+        } else {
+          p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_WRITE_CC;
+        }
+      }
+      break;
+
+    case RW_T4T_SUBSTATE_WAIT_WRITE_CC:
+      p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
+      BE_STREAM_TO_UINT16(status_words, p);
+      if (status_words != 0x9100) {
+        rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
+      } else {
+        if (!rw_t4t_write_ndef()) {
+          rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+        } else {
+          p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_WRITE_NDEF;
+        }
+      }
+      break;
+
+    case RW_T4T_SUBSTATE_WAIT_WRITE_NDEF:
+      p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
+      BE_STREAM_TO_UINT16(status_words, p);
+      if (status_words != 0x9100) {
+        rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
+      } else {
+        p_t4t->state = RW_T4T_STATE_IDLE;
+        if (rw_cb.p_cback) {
+          rw_data.ndef.status = NFC_STATUS_OK;
+          rw_data.ndef.protocol = NFC_PROTOCOL_ISO_DEP;
+          rw_data.ndef.max_size = p_t4t->card_size;
+          rw_data.ndef.cur_size = 0x00;
+
+          (*(rw_cb.p_cback))(RW_T4T_NDEF_FORMAT_CPLT_EVT, &rw_data);
+
+          RW_TRACE_DEBUG0(
+              "rw_t4t_ndef_format (): Sent RW_T4T_NDEF_FORMAT_CPLT_EVT");
+        }
+      }
+      break;
+
+    default:
+      RW_TRACE_ERROR1("rw_t4t_sm_ndef_format (): unknown sub_state=%d",
+                      p_t4t->sub_state);
+      rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+      break;
+  }
+}
+
+#if (NXP_EXTNS == TRUE)
+static void rw_t3Bt_sm_get_card_id(NFC_HDR* p_r_apdu) {
+  tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
+  uint8_t* p, type, length;
+  uint16_t status_words, nlen;
+  tRW_DATA rw_data;
+
+#if (BT_TRACE_VERBOSE == true)
+  RW_TRACE_DEBUG2("rw_t3Bt_sm_get_id (): sub_state:%s (%d)",
+                  rw_t4t_get_sub_state_name(p_t4t->sub_state),
+                  p_t4t->sub_state);
+#else
+  RW_TRACE_DEBUG1("rw_t3Bt_sm_get_id (): sub_state=%d", p_t4t->sub_state);
+#endif
+
+  /* get status words */
+  p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
+
+  switch (p_t4t->sub_state) {
+    case RW_T3BT_SUBSTATE_WAIT_GET_ATTRIB:
+      if ((p_r_apdu->len == 0x00) && ((*p != 0x00) && (*p++ != 0x00))) {
+        rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
+      } else {
+        if (!rw_t3bt_get_pupi()) {
+          rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+        } else {
+          p_t4t->sub_state = RW_T3BT_SUBSTATE_WAIT_GET_PUPI;
+        }
+      }
+      break;
+
+    case RW_T3BT_SUBSTATE_WAIT_GET_PUPI:
+      p += (p_r_apdu->len - 3);
+      BE_STREAM_TO_UINT16(status_words, p);
+      if (status_words != 0x9000) {
+        rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
+      } else {
+        uint8_t rsp_len = p_r_apdu->len - 3;
+        p = (uint8_t*)(p_r_apdu + 1) +
+            p_r_apdu->offset;  //"p" points to start of response
+        p_t4t->state = RW_T4T_STATE_IDLE;
+        nfa_rw_update_pupi_id(p, rsp_len);
+        if (rw_cb.p_cback) {
+          (*(rw_cb.p_cback))(RW_T3BT_RAW_READ_CPLT_EVT, &rw_data);
+        } else {
+          RW_TRACE_ERROR0("rw_t3Bt_sm_get_id (): NULL callback");
+        }
+      }
+      break;
+
+    default:
+      RW_TRACE_ERROR1("rw_t3Bt_sm_get_id (): unknown sub_state=%d",
+                      p_t4t->sub_state);
+      rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+      break;
+  }
+}
+#endif
+/*******************************************************************************
+**
+** Function         rw_t4t_sm_detect_ndef
+**
+** Description      State machine for NDEF detection procedure
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t4t_sm_detect_ndef(NFC_HDR* p_r_apdu) {
+  tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
+  uint8_t* p, type, length;
+  uint16_t status_words, nlen;
+  tRW_DATA rw_data;
+
+#if (BT_TRACE_VERBOSE == true)
+  RW_TRACE_DEBUG2("rw_t4t_sm_detect_ndef (): sub_state:%s (%d)",
+                  rw_t4t_get_sub_state_name(p_t4t->sub_state),
+                  p_t4t->sub_state);
+#else
+  RW_TRACE_DEBUG1("rw_t4t_sm_detect_ndef (): sub_state=%d", p_t4t->sub_state);
+#endif
+
+  /* get status words */
+  p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
+  p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
+  BE_STREAM_TO_UINT16(status_words, p);
+
+  if (status_words != T4T_RSP_CMD_CMPLTED) {
+    /* try V1.0 after failing of V2.0 */
+    if ((p_t4t->sub_state == RW_T4T_SUBSTATE_WAIT_SELECT_APP) &&
+        (p_t4t->version == T4T_VERSION_2_0)) {
+      p_t4t->version = T4T_VERSION_1_0;
+
+      RW_TRACE_DEBUG1("rw_t4t_sm_detect_ndef (): retry with version=0x%02X",
+                      p_t4t->version);
+
+      if (!rw_t4t_select_application(T4T_VERSION_1_0)) {
+        rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+      }
+      return;
+    }
+
+    p_t4t->ndef_status &= ~(RW_T4T_NDEF_STATUS_NDEF_DETECTED);
+    rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
+    return;
+  }
+
+  switch (p_t4t->sub_state) {
+    case RW_T4T_SUBSTATE_WAIT_SELECT_APP:
+
+      /* NDEF Tag application has been selected then select CC file */
+      if (!rw_t4t_select_file(T4T_CC_FILE_ID)) {
+        rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+      } else {
+        p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_CC;
+      }
+      break;
+
+    case RW_T4T_SUBSTATE_WAIT_SELECT_CC:
+
+      /* CC file has been selected then read mandatory part of CC file */
+      if (!rw_t4t_read_file(0x00, T4T_CC_FILE_MIN_LEN, false)) {
+        rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+      } else {
+        p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_CC_FILE;
+      }
+      break;
+
+    case RW_T4T_SUBSTATE_WAIT_CC_FILE:
+
+      /* CC file has been read then validate and select mandatory NDEF file */
+      if (p_r_apdu->len >= T4T_CC_FILE_MIN_LEN + T4T_RSP_STATUS_WORDS_SIZE) {
+        p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
+
+        BE_STREAM_TO_UINT16(p_t4t->cc_file.cclen, p);
+        BE_STREAM_TO_UINT8(p_t4t->cc_file.version, p);
+        BE_STREAM_TO_UINT16(p_t4t->cc_file.max_le, p);
+        BE_STREAM_TO_UINT16(p_t4t->cc_file.max_lc, p);
+
+        BE_STREAM_TO_UINT8(type, p);
+        BE_STREAM_TO_UINT8(length, p);
+
+        if ((type == T4T_NDEF_FILE_CONTROL_TYPE) &&
+            (length == T4T_FILE_CONTROL_LENGTH)) {
+          BE_STREAM_TO_UINT16(p_t4t->cc_file.ndef_fc.file_id, p);
+          BE_STREAM_TO_UINT16(p_t4t->cc_file.ndef_fc.max_file_size, p);
+          BE_STREAM_TO_UINT8(p_t4t->cc_file.ndef_fc.read_access, p);
+          BE_STREAM_TO_UINT8(p_t4t->cc_file.ndef_fc.write_access, p);
+
+#if (BT_TRACE_VERBOSE == true)
+          RW_TRACE_DEBUG0("Capability Container (CC) file");
+          RW_TRACE_DEBUG1("  CCLEN:  0x%04X", p_t4t->cc_file.cclen);
+          RW_TRACE_DEBUG1("  Version:0x%02X", p_t4t->cc_file.version);
+          RW_TRACE_DEBUG1("  MaxLe:  0x%04X", p_t4t->cc_file.max_le);
+          RW_TRACE_DEBUG1("  MaxLc:  0x%04X", p_t4t->cc_file.max_lc);
+          RW_TRACE_DEBUG0("  NDEF File Control TLV");
+          RW_TRACE_DEBUG1("    FileID:      0x%04X",
+                          p_t4t->cc_file.ndef_fc.file_id);
+          RW_TRACE_DEBUG1("    MaxFileSize: 0x%04X",
+                          p_t4t->cc_file.ndef_fc.max_file_size);
+          RW_TRACE_DEBUG1("    ReadAccess:  0x%02X",
+                          p_t4t->cc_file.ndef_fc.read_access);
+          RW_TRACE_DEBUG1("    WriteAccess: 0x%02X",
+                          p_t4t->cc_file.ndef_fc.write_access);
+#endif
+
+          if (rw_t4t_validate_cc_file()) {
+            if (!rw_t4t_select_file(p_t4t->cc_file.ndef_fc.file_id)) {
+              rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+            } else {
+              p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_NDEF_FILE;
+            }
+            break;
+          }
+        }
+      }
+
+      /* invalid response or CC file */
+      p_t4t->ndef_status &= ~(RW_T4T_NDEF_STATUS_NDEF_DETECTED);
+      rw_t4t_handle_error(NFC_STATUS_BAD_RESP, 0, 0);
+      break;
+
+    case RW_T4T_SUBSTATE_WAIT_SELECT_NDEF_FILE:
+
+      /* NDEF file has been selected then read the first 2 bytes (NLEN) */
+      if (!rw_t4t_read_file(0, T4T_FILE_LENGTH_SIZE, false)) {
+        rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+      } else {
+        p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_READ_NLEN;
+      }
+      break;
+
+    case RW_T4T_SUBSTATE_WAIT_READ_NLEN:
+
+      /* NLEN has been read then report upper layer */
+      if (p_r_apdu->len == T4T_FILE_LENGTH_SIZE + T4T_RSP_STATUS_WORDS_SIZE) {
+        /* get length of NDEF */
+        p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
+        BE_STREAM_TO_UINT16(nlen, p);
+
+        if (nlen <=
+            p_t4t->cc_file.ndef_fc.max_file_size - T4T_FILE_LENGTH_SIZE) {
+          p_t4t->ndef_status = RW_T4T_NDEF_STATUS_NDEF_DETECTED;
+
+          if (p_t4t->cc_file.ndef_fc.write_access != T4T_FC_WRITE_ACCESS) {
+            p_t4t->ndef_status |= RW_T4T_NDEF_STATUS_NDEF_READ_ONLY;
+          }
+
+          /* Get max bytes to read per command */
+          if (p_t4t->cc_file.max_le >= RW_T4T_MAX_DATA_PER_READ) {
+            p_t4t->max_read_size = RW_T4T_MAX_DATA_PER_READ;
+          } else {
+            p_t4t->max_read_size = p_t4t->cc_file.max_le;
+          }
+
+          /* Le: valid range is 0x01 to 0xFF */
+          if (p_t4t->max_read_size >= T4T_MAX_LENGTH_LE) {
+            p_t4t->max_read_size = T4T_MAX_LENGTH_LE;
+          }
+
+          /* Get max bytes to update per command */
+          if (p_t4t->cc_file.max_lc >= RW_T4T_MAX_DATA_PER_WRITE) {
+            p_t4t->max_update_size = RW_T4T_MAX_DATA_PER_WRITE;
+          } else {
+            p_t4t->max_update_size = p_t4t->cc_file.max_lc;
+          }
+
+          /* Lc: valid range is 0x01 to 0xFF */
+          if (p_t4t->max_update_size >= T4T_MAX_LENGTH_LC) {
+            p_t4t->max_update_size = T4T_MAX_LENGTH_LC;
+          }
+
+          p_t4t->ndef_length = nlen;
+          p_t4t->state = RW_T4T_STATE_IDLE;
+
+          if (rw_cb.p_cback) {
+            rw_data.ndef.status = NFC_STATUS_OK;
+            rw_data.ndef.protocol = NFC_PROTOCOL_ISO_DEP;
+            rw_data.ndef.max_size =
+                (uint32_t)(p_t4t->cc_file.ndef_fc.max_file_size -
+                           (uint16_t)T4T_FILE_LENGTH_SIZE);
+            rw_data.ndef.cur_size = nlen;
+            rw_data.ndef.flags = RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATED;
+            if (p_t4t->cc_file.ndef_fc.write_access != T4T_FC_WRITE_ACCESS) {
+              rw_data.ndef.flags |= RW_NDEF_FL_READ_ONLY;
+            }
+
+            (*(rw_cb.p_cback))(RW_T4T_NDEF_DETECT_EVT, &rw_data);
+
+            RW_TRACE_DEBUG0(
+                "rw_t4t_sm_detect_ndef (): Sent RW_T4T_NDEF_DETECT_EVT");
+          }
+        } else {
+          /* NLEN should be less than max file size */
+          RW_TRACE_ERROR2(
+              "rw_t4t_sm_detect_ndef (): NLEN (%d) + 2 must be <= max file "
+              "size (%d)",
+              nlen, p_t4t->cc_file.ndef_fc.max_file_size);
+
+          p_t4t->ndef_status &= ~(RW_T4T_NDEF_STATUS_NDEF_DETECTED);
+          rw_t4t_handle_error(NFC_STATUS_BAD_RESP, 0, 0);
+        }
+      } else {
+        /* response payload size should be T4T_FILE_LENGTH_SIZE */
+        RW_TRACE_ERROR2(
+            "rw_t4t_sm_detect_ndef (): Length (%d) of R-APDU must be %d",
+            p_r_apdu->len, T4T_FILE_LENGTH_SIZE + T4T_RSP_STATUS_WORDS_SIZE);
+
+        p_t4t->ndef_status &= ~(RW_T4T_NDEF_STATUS_NDEF_DETECTED);
+        rw_t4t_handle_error(NFC_STATUS_BAD_RESP, 0, 0);
+      }
+      break;
+
+    default:
+      RW_TRACE_ERROR1("rw_t4t_sm_detect_ndef (): unknown sub_state=%d",
+                      p_t4t->sub_state);
+      rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_sm_read_ndef
+**
+** Description      State machine for NDEF read procedure
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t4t_sm_read_ndef(NFC_HDR* p_r_apdu) {
+  tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
+  uint8_t* p;
+  uint16_t status_words;
+  tRW_DATA rw_data;
+
+#if (BT_TRACE_VERBOSE == true)
+  RW_TRACE_DEBUG2("rw_t4t_sm_read_ndef (): sub_state:%s (%d)",
+                  rw_t4t_get_sub_state_name(p_t4t->sub_state),
+                  p_t4t->sub_state);
+#else
+  RW_TRACE_DEBUG1("rw_t4t_sm_read_ndef (): sub_state=%d", p_t4t->sub_state);
+#endif
+
+  /* get status words */
+  p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
+  p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
+  BE_STREAM_TO_UINT16(status_words, p);
+
+  if (status_words != T4T_RSP_CMD_CMPLTED) {
+    rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
+    GKI_freebuf(p_r_apdu);
+    return;
+  }
+
+  switch (p_t4t->sub_state) {
+    case RW_T4T_SUBSTATE_WAIT_READ_RESP:
+
+      /* Read partial or complete data */
+      p_r_apdu->len -= T4T_RSP_STATUS_WORDS_SIZE;
+
+      if ((p_r_apdu->len > 0) && (p_r_apdu->len <= p_t4t->rw_length)) {
+        p_t4t->rw_length -= p_r_apdu->len;
+        p_t4t->rw_offset += p_r_apdu->len;
+
+        if (rw_cb.p_cback) {
+          rw_data.data.status = NFC_STATUS_OK;
+          rw_data.data.p_data = p_r_apdu;
+
+          /* if need to read more data */
+          if (p_t4t->rw_length > 0) {
+            (*(rw_cb.p_cback))(RW_T4T_NDEF_READ_EVT, &rw_data);
+
+            if (!rw_t4t_read_file(p_t4t->rw_offset, p_t4t->rw_length, true)) {
+              rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+            }
+          } else {
+            p_t4t->state = RW_T4T_STATE_IDLE;
+
+            (*(rw_cb.p_cback))(RW_T4T_NDEF_READ_CPLT_EVT, &rw_data);
+
+            RW_TRACE_DEBUG0(
+                "rw_t4t_sm_read_ndef (): Sent RW_T4T_NDEF_READ_CPLT_EVT");
+          }
+
+          p_r_apdu = NULL;
+        } else {
+          p_t4t->rw_length = 0;
+          p_t4t->state = RW_T4T_STATE_IDLE;
+        }
+      } else {
+        RW_TRACE_ERROR2(
+            "rw_t4t_sm_read_ndef (): invalid payload length (%d), rw_length "
+            "(%d)",
+            p_r_apdu->len, p_t4t->rw_length);
+        rw_t4t_handle_error(NFC_STATUS_BAD_RESP, 0, 0);
+      }
+      break;
+
+    default:
+      RW_TRACE_ERROR1("rw_t4t_sm_read_ndef (): unknown sub_state = %d",
+                      p_t4t->sub_state);
+      rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+      break;
+  }
+
+  if (p_r_apdu) GKI_freebuf(p_r_apdu);
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_sm_update_ndef
+**
+** Description      State machine for NDEF update procedure
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t4t_sm_update_ndef(NFC_HDR* p_r_apdu) {
+  tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
+  uint8_t* p;
+  uint16_t status_words;
+  tRW_DATA rw_data;
+
+#if (BT_TRACE_VERBOSE == true)
+  RW_TRACE_DEBUG2("rw_t4t_sm_update_ndef (): sub_state:%s (%d)",
+                  rw_t4t_get_sub_state_name(p_t4t->sub_state),
+                  p_t4t->sub_state);
+#else
+  RW_TRACE_DEBUG1("rw_t4t_sm_update_ndef (): sub_state=%d", p_t4t->sub_state);
+#endif
+
+  /* Get status words */
+  p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
+  p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
+  BE_STREAM_TO_UINT16(status_words, p);
+
+  if (status_words != T4T_RSP_CMD_CMPLTED) {
+    rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
+    return;
+  }
+
+  switch (p_t4t->sub_state) {
+    case RW_T4T_SUBSTATE_WAIT_UPDATE_NLEN:
+
+      /* NLEN has been updated */
+      /* if need to update data */
+      if (p_t4t->p_update_data) {
+        p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_UPDATE_RESP;
+
+        if (!rw_t4t_update_file()) {
+          rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+          p_t4t->p_update_data = NULL;
+        }
+      } else {
+        p_t4t->state = RW_T4T_STATE_IDLE;
+
+        /* just finished last step of updating (updating NLEN) */
+        if (rw_cb.p_cback) {
+          rw_data.status = NFC_STATUS_OK;
+
+          (*(rw_cb.p_cback))(RW_T4T_NDEF_UPDATE_CPLT_EVT, &rw_data);
+          RW_TRACE_DEBUG0(
+              "rw_t4t_sm_update_ndef (): Sent RW_T4T_NDEF_UPDATE_CPLT_EVT");
+        }
+      }
+      break;
+
+    case RW_T4T_SUBSTATE_WAIT_UPDATE_RESP:
+
+      /* if updating is not completed */
+      if (p_t4t->rw_length > 0) {
+        if (!rw_t4t_update_file()) {
+          rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+          p_t4t->p_update_data = NULL;
+        }
+      } else {
+        p_t4t->p_update_data = NULL;
+
+        /* update NLEN as last step of updating file */
+        if (!rw_t4t_update_nlen(p_t4t->ndef_length)) {
+          rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+        } else {
+          p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_UPDATE_NLEN;
+        }
+      }
+      break;
+
+    default:
+      RW_TRACE_ERROR1("rw_t4t_sm_update_ndef (): unknown sub_state = %d",
+                      p_t4t->sub_state);
+      rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_sm_set_readonly
+**
+** Description      State machine for CC update procedure
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t4t_sm_set_readonly(NFC_HDR* p_r_apdu) {
+  tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
+  uint8_t* p;
+  uint16_t status_words;
+  tRW_DATA rw_data;
+
+#if (BT_TRACE_VERBOSE == true)
+  RW_TRACE_DEBUG2("rw_t4t_sm_set_readonly (): sub_state:%s (%d)",
+                  rw_t4t_get_sub_state_name(p_t4t->sub_state),
+                  p_t4t->sub_state);
+#else
+  RW_TRACE_DEBUG1("rw_t4t_sm_set_readonly (): sub_state=%d", p_t4t->sub_state);
+#endif
+
+  /* Get status words */
+  p = (uint8_t*)(p_r_apdu + 1) + p_r_apdu->offset;
+  p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
+  BE_STREAM_TO_UINT16(status_words, p);
+
+  if (status_words != T4T_RSP_CMD_CMPLTED) {
+    rw_t4t_handle_error(NFC_STATUS_CMD_NOT_CMPLTD, *(p - 2), *(p - 1));
+    return;
+  }
+
+  switch (p_t4t->sub_state) {
+    case RW_T4T_SUBSTATE_WAIT_SELECT_CC:
+
+      /* CC file has been selected then update write access to read-only in CC
+       * file */
+      if (!rw_t4t_update_cc_to_readonly()) {
+        rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+      } else {
+        p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_UPDATE_CC;
+      }
+      break;
+
+    case RW_T4T_SUBSTATE_WAIT_UPDATE_CC:
+      /* CC Updated, Select NDEF File to allow NDEF operation */
+      p_t4t->cc_file.ndef_fc.write_access = T4T_FC_NO_WRITE_ACCESS;
+      p_t4t->ndef_status |= RW_T4T_NDEF_STATUS_NDEF_READ_ONLY;
+
+      if (!rw_t4t_select_file(p_t4t->cc_file.ndef_fc.file_id)) {
+        rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+      } else {
+        p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_NDEF_FILE;
+      }
+      break;
+
+    case RW_T4T_SUBSTATE_WAIT_SELECT_NDEF_FILE:
+      p_t4t->state = RW_T4T_STATE_IDLE;
+      /* just finished last step of configuring tag read only (Selecting NDEF
+       * file CC) */
+      if (rw_cb.p_cback) {
+        rw_data.status = NFC_STATUS_OK;
+
+        RW_TRACE_DEBUG0("rw_t4t_sm_set_readonly (): Sent RW_T4T_SET_TO_RO_EVT");
+        (*(rw_cb.p_cback))(RW_T4T_SET_TO_RO_EVT, &rw_data);
+      }
+      break;
+
+    default:
+      RW_TRACE_ERROR1("rw_t4t_sm_set_readonly (): unknown sub_state = %d",
+                      p_t4t->sub_state);
+      rw_t4t_handle_error(NFC_STATUS_FAILED, 0, 0);
+      break;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_process_timeout
+**
+** Description      process timeout event
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t4t_process_timeout(TIMER_LIST_ENT* p_tle) {
+  RW_TRACE_DEBUG1("rw_t4t_process_timeout () event=%d", p_tle->event);
+
+  if (p_tle->event == NFC_TTYPE_RW_T4T_RESPONSE) {
+    rw_t4t_handle_error(NFC_STATUS_TIMEOUT, 0, 0);
+  } else {
+    RW_TRACE_ERROR1("rw_t4t_process_timeout () unknown event=%d", p_tle->event);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_handle_isodep_nak_rsp
+**
+** Description      This function handles the response and ntf .
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t4t_handle_isodep_nak_rsp(uint8_t status,bool is_ntf) {
+  tRW_DATA rw_data;
+  tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
+  RW_TRACE_DEBUG1("rw_t4t_handle_isodep_nak_rsp %d", status);
+  if (is_ntf || (status != NFC_STATUS_OK)) {
+    rw_data.status = status;
+    nfc_stop_quick_timer(&p_t4t->timer);
+    p_t4t->state = RW_T4T_STATE_IDLE;
+    (*(rw_cb.p_cback))(RW_T4T_PRESENCE_CHECK_EVT, &rw_data);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_data_cback
+**
+** Description      This callback function receives the data from NFCC.
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t4t_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
+                              tNFC_CONN* p_data) {
+  tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
+  NFC_HDR* p_r_apdu;
+  tRW_DATA rw_data;
+  (void)conn_id;
+
+#if (BT_TRACE_VERBOSE == true)
+  uint8_t begin_state = p_t4t->state;
+#endif
+
+  RW_TRACE_DEBUG1("rw_t4t_data_cback () event = 0x%X", event);
+  nfc_stop_quick_timer(&p_t4t->timer);
+
+  switch (event) {
+    case NFC_DEACTIVATE_CEVT:
+      NFC_SetStaticRfCback(NULL);
+      p_t4t->state = RW_T4T_STATE_NOT_ACTIVATED;
+      return;
+
+    case NFC_ERROR_CEVT:
+      if (p_t4t->state == RW_T4T_STATE_PRESENCE_CHECK) {
+        p_t4t->state = RW_T4T_STATE_IDLE;
+        rw_data.status = NFC_STATUS_FAILED;
+        (*(rw_cb.p_cback))(RW_T4T_PRESENCE_CHECK_EVT, &rw_data);
+      } else if (p_t4t->state == RW_T4T_STATE_NDEF_FORMAT) {
+        p_t4t->state = RW_T4T_STATE_IDLE;
+        rw_data.status = NFC_STATUS_FAILED;
+        (*(rw_cb.p_cback))(RW_T4T_NDEF_FORMAT_CPLT_EVT, &rw_data);
+      } else if (p_t4t->state != RW_T4T_STATE_IDLE) {
+#if (NXP_EXTNS == TRUE)
+        rw_data.status = (tNFC_STATUS)(*(uint8_t*)p_data);
+#endif
+        rw_t4t_handle_error(rw_data.status, 0, 0);
+      } else {
+        p_t4t->state = RW_T4T_STATE_IDLE;
+        rw_data.status = (tNFC_STATUS)(*(uint8_t*)p_data);
+        (*(rw_cb.p_cback))(RW_T4T_INTF_ERROR_EVT, &rw_data);
+      }
+      return;
+
+    case NFC_DATA_CEVT:
+      p_r_apdu = (NFC_HDR*)p_data->data.p_data;
+      break;
+
+#if (NXP_EXTNS == TRUE)
+    case NFC_RF_WTX_CEVT:
+      if (p_t4t->state == RW_T4T_STATE_IDLE) {
+        /* WTX received for raw frame sent
+         * forward to upper layer without parsing */
+        if (rw_cb.p_cback) {
+          (*(rw_cb.p_cback))(RW_T4T_RAW_FRAME_RF_WTX_EVT, &rw_data);
+        }
+      } else {
+        nfc_start_quick_timer(
+            &p_t4t->timer, NFC_TTYPE_RW_T4T_RESPONSE,
+            (RW_T4T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+      }
+      return;
+#endif
+
+    default:
+      return;
+  }
+
+#if (BT_TRACE_PROTOCOL == true)
+  if (p_t4t->state != RW_T4T_STATE_IDLE) DispRWT4Tags(p_r_apdu, true);
+#endif
+
+#if (BT_TRACE_VERBOSE == true)
+  RW_TRACE_DEBUG2("RW T4T state: <%s (%d)>",
+                  rw_t4t_get_state_name(p_t4t->state), p_t4t->state);
+#else
+  RW_TRACE_DEBUG1("RW T4T state: %d", p_t4t->state);
+#endif
+
+  switch (p_t4t->state) {
+    case RW_T4T_STATE_IDLE:
+/* Unexpected R-APDU, it should be raw frame response */
+/* forward to upper layer without parsing */
+#if (BT_TRACE_VERBOSE == true)
+      RW_TRACE_DEBUG2("RW T4T Raw Frame: Len [0x%X] Status [%s]", p_r_apdu->len,
+                      NFC_GetStatusName(p_data->data.status));
+#else
+      RW_TRACE_DEBUG2("RW T4T Raw Frame: Len [0x%X] Status [0x%X]",
+                      p_r_apdu->len, p_data->data.status);
+#endif
+      if (rw_cb.p_cback) {
+        rw_data.raw_frame.status = p_data->data.status;
+        rw_data.raw_frame.p_data = p_r_apdu;
+        (*(rw_cb.p_cback))(RW_T4T_RAW_FRAME_EVT, &rw_data);
+        p_r_apdu = NULL;
+      } else {
+        GKI_freebuf(p_r_apdu);
+      }
+      break;
+    case RW_T4T_STATE_DETECT_NDEF:
+      rw_t4t_sm_detect_ndef(p_r_apdu);
+      GKI_freebuf(p_r_apdu);
+      break;
+    case RW_T4T_STATE_READ_NDEF:
+      rw_t4t_sm_read_ndef(p_r_apdu);
+      /* p_r_apdu may send upper lyaer */
+      break;
+    case RW_T4T_STATE_UPDATE_NDEF:
+      rw_t4t_sm_update_ndef(p_r_apdu);
+      GKI_freebuf(p_r_apdu);
+      break;
+    case RW_T4T_STATE_PRESENCE_CHECK:
+      /* if any response, send presence check with ok */
+      rw_data.status = NFC_STATUS_OK;
+      p_t4t->state = RW_T4T_STATE_IDLE;
+      (*(rw_cb.p_cback))(RW_T4T_PRESENCE_CHECK_EVT, &rw_data);
+      GKI_freebuf(p_r_apdu);
+      break;
+    case RW_T4T_STATE_SET_READ_ONLY:
+      rw_t4t_sm_set_readonly(p_r_apdu);
+      GKI_freebuf(p_r_apdu);
+      break;
+    case RW_T4T_STATE_NDEF_FORMAT:
+      rw_t4t_sm_ndef_format(p_r_apdu);
+      GKI_freebuf(p_r_apdu);
+      break;
+#if (NXP_EXTNS == TRUE)
+    case RW_T3BT_STATE_GET_PROP_DATA:
+      rw_t3Bt_sm_get_card_id(p_r_apdu);
+      GKI_freebuf(p_r_apdu);
+      break;
+#endif
+    default:
+      RW_TRACE_ERROR1("rw_t4t_data_cback (): invalid state=%d", p_t4t->state);
+      GKI_freebuf(p_r_apdu);
+      break;
+  }
+
+#if (BT_TRACE_VERBOSE == true)
+  if (begin_state != p_t4t->state) {
+    RW_TRACE_DEBUG2("RW T4T state changed:<%s> -> <%s>",
+                    rw_t4t_get_state_name(begin_state),
+                    rw_t4t_get_state_name(p_t4t->state));
+  }
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         RW_T4tFormatNDef
+**
+** Description      format T4T tag
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS RW_T4tFormatNDef(void) {
+  RW_TRACE_API0("RW_T4tFormatNDef ()");
+
+  if (rw_cb.tcb.t4t.state != RW_T4T_STATE_IDLE) {
+    RW_TRACE_ERROR1(
+        "RW_T4tFormatNDef ():Unable to start command at state (0x%X)",
+        rw_cb.tcb.t4t.state);
+    return NFC_STATUS_FAILED;
+  }
+
+  rw_cb.tcb.t4t.card_type = 0x00;
+  if (!rw_t4t_get_hw_version()) {
+    return NFC_STATUS_FAILED;
+  }
+  rw_cb.tcb.t4t.state = RW_T4T_STATE_NDEF_FORMAT;
+  rw_cb.tcb.t4t.sub_state = RW_T4T_SUBSTATE_WAIT_GET_HW_VERSION;
+
+  return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_select
+**
+** Description      Initialise T4T
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS rw_t4t_select(void) {
+  tRW_T4T_CB* p_t4t = &rw_cb.tcb.t4t;
+
+  RW_TRACE_DEBUG0("rw_t4t_select ()");
+
+  NFC_SetStaticRfCback(rw_t4t_data_cback);
+
+  p_t4t->state = RW_T4T_STATE_IDLE;
+  p_t4t->version = T4T_MY_VERSION;
+
+  /* set it min of max R-APDU data size before reading CC file */
+  p_t4t->cc_file.max_le = T4T_MIN_MLE;
+
+  /* These will be udated during NDEF detection */
+  p_t4t->max_read_size = T4T_MAX_LENGTH_LE;
+  p_t4t->max_update_size = T4T_MAX_LENGTH_LC;
+
+  return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T4tDetectNDef
+**
+** Description      This function performs NDEF detection procedure
+**
+**                  RW_T4T_NDEF_DETECT_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if T4T is busy or other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_T4tDetectNDef(void) {
+  RW_TRACE_API0("RW_T4tDetectNDef ()");
+
+  if (rw_cb.tcb.t4t.state != RW_T4T_STATE_IDLE) {
+    RW_TRACE_ERROR1(
+        "RW_T4tDetectNDef ():Unable to start command at state (0x%X)",
+        rw_cb.tcb.t4t.state);
+    return NFC_STATUS_FAILED;
+  }
+
+  if (rw_cb.tcb.t4t.ndef_status & RW_T4T_NDEF_STATUS_NDEF_DETECTED) {
+    /* NDEF Tag application has been selected then select CC file */
+    if (!rw_t4t_select_file(T4T_CC_FILE_ID)) {
+      return NFC_STATUS_FAILED;
+    }
+    rw_cb.tcb.t4t.sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_CC;
+  } else {
+    /* Select NDEF Tag Application */
+    if (!rw_t4t_select_application(rw_cb.tcb.t4t.version)) {
+      return NFC_STATUS_FAILED;
+    }
+    rw_cb.tcb.t4t.sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_APP;
+  }
+
+  rw_cb.tcb.t4t.state = RW_T4T_STATE_DETECT_NDEF;
+
+  return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T4tReadNDef
+**
+** Description      This function performs NDEF read procedure
+**                  Note: RW_T4tDetectNDef () must be called before using this
+**
+**                  The following event will be returned
+**                      RW_T4T_NDEF_READ_EVT for each segmented NDEF message
+**                      RW_T4T_NDEF_READ_CPLT_EVT for the last segment or
+**                      complete NDEF
+**                      RW_T4T_NDEF_READ_FAIL_EVT for failure
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if T4T is busy or other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_T4tReadNDef(void) {
+  RW_TRACE_API0("RW_T4tReadNDef ()");
+
+  if (rw_cb.tcb.t4t.state != RW_T4T_STATE_IDLE) {
+    RW_TRACE_ERROR1("RW_T4tReadNDef ():Unable to start command at state (0x%X)",
+                    rw_cb.tcb.t4t.state);
+    return NFC_STATUS_FAILED;
+  }
+
+  /* if NDEF has been detected */
+  if (rw_cb.tcb.t4t.ndef_status & RW_T4T_NDEF_STATUS_NDEF_DETECTED) {
+    /* start reading NDEF */
+    if (!rw_t4t_read_file(T4T_FILE_LENGTH_SIZE, rw_cb.tcb.t4t.ndef_length,
+                          false)) {
+      return NFC_STATUS_FAILED;
+    }
+
+    rw_cb.tcb.t4t.state = RW_T4T_STATE_READ_NDEF;
+    rw_cb.tcb.t4t.sub_state = RW_T4T_SUBSTATE_WAIT_READ_RESP;
+
+    return NFC_STATUS_OK;
+  } else {
+    RW_TRACE_ERROR0("RW_T4tReadNDef ():No NDEF detected");
+    return NFC_STATUS_FAILED;
+  }
+}
+
+/*******************************************************************************
+**
+** Function         RW_T4tUpdateNDef
+**
+** Description      This function performs NDEF update procedure
+**                  Note: RW_T4tDetectNDef () must be called before using this
+**                        Updating data must not be removed until returning
+**                        event
+**
+**                  The following event will be returned
+**                      RW_T4T_NDEF_UPDATE_CPLT_EVT for complete
+**                      RW_T4T_NDEF_UPDATE_FAIL_EVT for failure
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if T4T is busy or other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_T4tUpdateNDef(uint16_t length, uint8_t* p_data) {
+  RW_TRACE_API1("RW_T4tUpdateNDef () length:%d", length);
+
+  if (rw_cb.tcb.t4t.state != RW_T4T_STATE_IDLE) {
+    RW_TRACE_ERROR1(
+        "RW_T4tUpdateNDef ():Unable to start command at state (0x%X)",
+        rw_cb.tcb.t4t.state);
+    return NFC_STATUS_FAILED;
+  }
+
+  /* if NDEF has been detected */
+  if (rw_cb.tcb.t4t.ndef_status & RW_T4T_NDEF_STATUS_NDEF_DETECTED) {
+    /* if read-only */
+    if (rw_cb.tcb.t4t.ndef_status & RW_T4T_NDEF_STATUS_NDEF_READ_ONLY) {
+      RW_TRACE_ERROR0("RW_T4tUpdateNDef ():NDEF is read-only");
+      return NFC_STATUS_FAILED;
+    }
+
+    if (rw_cb.tcb.t4t.cc_file.ndef_fc.max_file_size <
+        length + T4T_FILE_LENGTH_SIZE) {
+      RW_TRACE_ERROR2(
+          "RW_T4tUpdateNDef ():data (%d bytes) plus NLEN is more than max file "
+          "size (%d)",
+          length, rw_cb.tcb.t4t.cc_file.ndef_fc.max_file_size);
+      return NFC_STATUS_FAILED;
+    }
+
+    /* store NDEF length and data */
+    rw_cb.tcb.t4t.ndef_length = length;
+    rw_cb.tcb.t4t.p_update_data = p_data;
+
+    rw_cb.tcb.t4t.rw_offset = T4T_FILE_LENGTH_SIZE;
+    rw_cb.tcb.t4t.rw_length = length;
+
+    /* set NLEN to 0x0000 for the first step */
+    if (!rw_t4t_update_nlen(0x0000)) {
+      return NFC_STATUS_FAILED;
+    }
+
+    rw_cb.tcb.t4t.state = RW_T4T_STATE_UPDATE_NDEF;
+    rw_cb.tcb.t4t.sub_state = RW_T4T_SUBSTATE_WAIT_UPDATE_NLEN;
+
+    return NFC_STATUS_OK;
+  } else {
+    RW_TRACE_ERROR0("RW_T4tUpdateNDef ():No NDEF detected");
+    return NFC_STATUS_FAILED;
+  }
+}
+
+/*****************************************************************************
+**
+** Function         RW_T4tPresenceCheck
+**
+** Description
+**      Check if the tag is still in the field.
+**
+**      The RW_T4T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
+**      or non-presence.
+**
+**      option is RW_T4T_CHK_EMPTY_I_BLOCK, use empty I block for presence check
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T4tPresenceCheck(uint8_t option) {
+  tNFC_STATUS retval = NFC_STATUS_OK;
+  tRW_DATA evt_data;
+  bool status;
+  NFC_HDR* p_data;
+
+  RW_TRACE_API1("RW_T4tPresenceCheck () %d", option);
+
+  /* If RW_SelectTagType was not called (no conn_callback) return failure */
+  if (!rw_cb.p_cback) {
+    retval = NFC_STATUS_FAILED;
+  }
+  /* If we are not activated, then RW_T4T_PRESENCE_CHECK_EVT with
+     NFC_STATUS_FAILED */
+  else if (rw_cb.tcb.t4t.state == RW_T4T_STATE_NOT_ACTIVATED) {
+    evt_data.status = NFC_STATUS_FAILED;
+    (*rw_cb.p_cback)(RW_T4T_PRESENCE_CHECK_EVT, &evt_data);
+  }
+  /* If command is pending, assume tag is still present */
+  else if (rw_cb.tcb.t4t.state != RW_T4T_STATE_IDLE) {
+    evt_data.status = NFC_STATUS_OK;
+    (*rw_cb.p_cback)(RW_T4T_PRESENCE_CHECK_EVT, &evt_data);
+  } else {
+    status = false;
+    if (option == RW_T4T_CHK_EMPTY_I_BLOCK) {
+      /* use empty I block for presence check */
+      p_data = (NFC_HDR*)GKI_getbuf(NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE);
+      if (p_data != NULL) {
+        p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+        p_data->len = 0;
+        if (NFC_SendData(NFC_RF_CONN_ID, (NFC_HDR*)p_data) == NFC_STATUS_OK)
+          status = true;
+      }
+    } else if (option == RW_T4T_CHK_ISO_DEP_NAK_PRES_CHK) {
+      if (NFC_ISODEPNakPresCheck() == NFC_STATUS_OK)
+        status = true;
+    } else {
+      /* use read binary on the given channel */
+      rw_cb.tcb.t4t.channel = 0;
+      if (option <= RW_T4T_CHK_READ_BINARY_CH3) rw_cb.tcb.t4t.channel = option;
+      status = rw_t4t_read_file(0, 1, false);
+      rw_cb.tcb.t4t.channel = 0;
+    }
+
+    if (status == true) {
+      rw_cb.tcb.t4t.state = RW_T4T_STATE_PRESENCE_CHECK;
+    } else {
+      retval = NFC_STATUS_NO_BUFFERS;
+    }
+  }
+
+  return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         RW_T4tSetNDefReadOnly
+**
+** Description      This function performs NDEF read-only procedure
+**                  Note: RW_T4tDetectNDef() must be called before using this
+**
+**                  The RW_T4T_SET_TO_RO_EVT event will be returned.
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if T4T is busy or other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T4tSetNDefReadOnly(void) {
+  tNFC_STATUS retval = NFC_STATUS_OK;
+  tRW_DATA evt_data;
+
+  RW_TRACE_API0("RW_T4tSetNDefReadOnly ()");
+
+  if (rw_cb.tcb.t4t.state != RW_T4T_STATE_IDLE) {
+    RW_TRACE_ERROR1(
+        "RW_T4tSetNDefReadOnly ():Unable to start command at state (0x%X)",
+        rw_cb.tcb.t4t.state);
+    return NFC_STATUS_FAILED;
+  }
+
+  /* if NDEF has been detected */
+  if (rw_cb.tcb.t4t.ndef_status & RW_T4T_NDEF_STATUS_NDEF_DETECTED) {
+    /* if read-only */
+    if (rw_cb.tcb.t4t.ndef_status & RW_T4T_NDEF_STATUS_NDEF_READ_ONLY) {
+      RW_TRACE_API0("RW_T4tSetNDefReadOnly (): NDEF is already read-only");
+
+      evt_data.status = NFC_STATUS_OK;
+      (*rw_cb.p_cback)(RW_T4T_SET_TO_RO_EVT, &evt_data);
+      return (retval);
+    }
+
+    /* NDEF Tag application has been selected then select CC file */
+    if (!rw_t4t_select_file(T4T_CC_FILE_ID)) {
+      return NFC_STATUS_FAILED;
+    }
+
+    rw_cb.tcb.t4t.state = RW_T4T_STATE_SET_READ_ONLY;
+    rw_cb.tcb.t4t.sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_CC;
+
+    return NFC_STATUS_OK;
+  } else {
+    RW_TRACE_ERROR0("RW_T4tSetNDefReadOnly ():No NDEF detected");
+    return NFC_STATUS_FAILED;
+  }
+  return (retval);
+}
+
+#if (NXP_EXTNS == TRUE)
+tNFC_STATUS RW_T3BtGetPupiID(void) {
+  NFC_HDR* p_c_apdu;
+  uint8_t* p;
+
+  p_c_apdu = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
+
+  if (!p_c_apdu) {
+    RW_TRACE_ERROR0("RW_T3BtGetPupiID (): Cannot allocate buffer");
+    return false;
+  }
+
+  p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+  p = (uint8_t*)(p_c_apdu + 1) + p_c_apdu->offset;
+
+  UINT8_TO_BE_STREAM(p, 0x1D);
+  UINT16_TO_BE_STREAM(p, 0x0000);
+  UINT16_TO_BE_STREAM(p, 0x0000);
+  UINT16_TO_BE_STREAM(p, 0x0008);
+  UINT16_TO_BE_STREAM(p, 0x0100);
+
+  p_c_apdu->len = 0x09;
+
+  if (!rw_t4t_send_to_lower(p_c_apdu)) {
+    return false;
+  }
+
+  rw_cb.tcb.t4t.state = RW_T3BT_STATE_GET_PROP_DATA;
+  rw_cb.tcb.t4t.sub_state = RW_T3BT_SUBSTATE_WAIT_GET_ATTRIB;
+  return true;
+}
+#endif
+
+#if (BT_TRACE_VERBOSE == true)
+/*******************************************************************************
+**
+** Function         rw_t4t_get_state_name
+**
+** Description      This function returns the state name.
+**
+** NOTE             conditionally compiled to save memory.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+static char* rw_t4t_get_state_name(uint8_t state) {
+  switch (state) {
+    case RW_T4T_STATE_NOT_ACTIVATED:
+      return ("NOT_ACTIVATED");
+    case RW_T4T_STATE_IDLE:
+      return ("IDLE");
+    case RW_T4T_STATE_DETECT_NDEF:
+      return ("NDEF_DETECTION");
+    case RW_T4T_STATE_READ_NDEF:
+      return ("READ_NDEF");
+    case RW_T4T_STATE_UPDATE_NDEF:
+      return ("UPDATE_NDEF");
+    case RW_T4T_STATE_PRESENCE_CHECK:
+      return ("PRESENCE_CHECK");
+    case RW_T4T_STATE_SET_READ_ONLY:
+      return ("SET_READ_ONLY");
+
+    default:
+      return ("???? UNKNOWN STATE");
+  }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_get_sub_state_name
+**
+** Description      This function returns the sub_state name.
+**
+** NOTE             conditionally compiled to save memory.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+static char* rw_t4t_get_sub_state_name(uint8_t sub_state) {
+  switch (sub_state) {
+    case RW_T4T_SUBSTATE_WAIT_SELECT_APP:
+      return ("WAIT_SELECT_APP");
+    case RW_T4T_SUBSTATE_WAIT_SELECT_CC:
+      return ("WAIT_SELECT_CC");
+    case RW_T4T_SUBSTATE_WAIT_CC_FILE:
+      return ("WAIT_CC_FILE");
+    case RW_T4T_SUBSTATE_WAIT_SELECT_NDEF_FILE:
+      return ("WAIT_SELECT_NDEF_FILE");
+    case RW_T4T_SUBSTATE_WAIT_READ_NLEN:
+      return ("WAIT_READ_NLEN");
+
+    case RW_T4T_SUBSTATE_WAIT_READ_RESP:
+      return ("WAIT_READ_RESP");
+    case RW_T4T_SUBSTATE_WAIT_UPDATE_RESP:
+      return ("WAIT_UPDATE_RESP");
+    case RW_T4T_SUBSTATE_WAIT_UPDATE_NLEN:
+      return ("WAIT_UPDATE_NLEN");
+    case RW_T4T_SUBSTATE_WAIT_GET_HW_VERSION:
+      return ("WAIT_GET_HW_VERSION");
+    case RW_T4T_SUBSTATE_WAIT_GET_SW_VERSION:
+      return ("WAIT_GET_SW_VERSION");
+    case RW_T4T_SUBSTATE_WAIT_GET_UID:
+      return ("WAIT_GET_UID");
+    case RW_T4T_SUBSTATE_WAIT_CREATE_APP:
+      return ("WAIT_CREATE_APP");
+    case RW_T4T_SUBSTATE_WAIT_CREATE_CC:
+      return ("WAIT_CREATE_CC");
+    case RW_T4T_SUBSTATE_WAIT_CREATE_NDEF:
+      return ("WAIT_CREATE_NDEF");
+    case RW_T4T_SUBSTATE_WAIT_WRITE_CC:
+      return ("WAIT_WRITE_CC");
+    case RW_T4T_SUBSTATE_WAIT_WRITE_NDEF:
+      return ("WAIT_WRITE_NDEF");
+#if (NXP_EXTNS == TRUE)
+    case RW_T3BT_SUBSTATE_WAIT_GET_ATTRIB:
+      return ("WAIT_GET_ATTRIB");
+    case RW_T3BT_SUBSTATE_WAIT_GET_PUPI:
+      return ("WAIT_GET_PUPI");
+#endif
+    default:
+      return ("???? UNKNOWN SUBSTATE");
+  }
+}
+#endif
diff --git a/src/nfc/tags/tags_int.c b/src/nfc/tags/tags_int.c
new file mode 100644
index 0000000..fe554b0
--- /dev/null
+++ b/src/nfc/tags/tags_int.c
@@ -0,0 +1,327 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the common data types shared by Reader/Writer mode
+ *  and Card Emulation.
+ *
+ ******************************************************************************/
+#include "nfc_target.h"
+#include "bt_types.h"
+
+#include "nfc_api.h"
+#include "rw_api.h"
+#include "rw_int.h"
+#include "tags_int.h"
+
+#define T1T_MAX_NUM_OPCODES 9
+#define T1T_STATIC_OPCODES 5
+#define T1T_MAX_TAG_MODELS 2
+
+const tT1T_CMD_RSP_INFO t1t_cmd_rsp_infos[] = {
+    /* Note: the order of these commands can not be changed.
+     * If new events are added, add them after T1T_CMD_WRITE_NE8 */
+    /*   opcode         cmd_len,  uid_offset,  rsp_len */
+    {T1T_CMD_RID, 7, 3, 6},
+    {T1T_CMD_RALL, 7, 3, 122},
+    {T1T_CMD_READ, 7, 3, 2},
+    {T1T_CMD_WRITE_E, 7, 3, 2},
+    {T1T_CMD_WRITE_NE, 7, 3, 2},
+    {T1T_CMD_RSEG, 14, 10, 129},
+    {T1T_CMD_READ8, 14, 10, 9},
+    {T1T_CMD_WRITE_E8, 14, 10, 9},
+    {T1T_CMD_WRITE_NE8, 14, 10, 9}};
+
+const tT1T_INIT_TAG t1t_init_content[] = {
+    /*  Tag Name            CC3,        is dynamic, ltv[0]  ltv[1]  ltv[2]
+       mtv[0]  mtv[1]  mtv[2]*/
+    {RW_T1T_IS_TOPAZ96, 0x0E, false, {0, 0, 0}, {0, 0, 0}},
+    {RW_T1T_IS_TOPAZ512, 0x3F, true, {0xF2, 0x30, 0x33}, {0xF0, 0x02, 0x03}}};
+
+#define T2T_MAX_NUM_OPCODES 3
+#define T2T_MAX_TAG_MODELS 7
+
+const tT2T_CMD_RSP_INFO t2t_cmd_rsp_infos[] = {
+    /* Note: the order of these commands can not be changed.
+     * If new events are added, add them after T2T_CMD_SEC_SEL */
+    /*  opcode            cmd_len,   rsp_len, nack_rsp_len */
+    {T2T_CMD_READ, 2, 16, 1},
+    {T2T_CMD_WRITE, 6, 1, 1},
+    {T2T_CMD_SEC_SEL, 2, 1, 1}};
+
+const tT2T_INIT_TAG t2t_init_content[] = {
+    /*  Tag Name        is_multi_v  Ver Block                   Ver No
+       Vbitmask   to_calc_cc CC3      OTP     BLPB */
+    {TAG_MIFARE_MID, true, T2T_MIFARE_VERSION_BLOCK,
+     T2T_MIFARE_ULTRALIGHT_VER_NO, 0xFFFF, false, 0x06, false,
+     T2T_DEFAULT_LOCK_BLPB},
+    {TAG_MIFARE_MID, true, T2T_MIFARE_VERSION_BLOCK,
+     T2T_MIFARE_ULTRALIGHT_FAMILY_VER_NO, 0xFFFF, true, 0x00, false,
+     T2T_DEFAULT_LOCK_BLPB},
+    {TAG_KOVIO_MID, false, 0x00, 0x00, 0x0000, false, 0x1D, true, 0x04},
+    {TAG_INFINEON_MID, true, T2T_INFINEON_VERSION_BLOCK,
+     T2T_INFINEON_MYD_MOVE_LEAN, 0xFFF0, false, 0x06, false,
+     T2T_DEFAULT_LOCK_BLPB},
+    {TAG_INFINEON_MID, true, T2T_INFINEON_VERSION_BLOCK, T2T_INFINEON_MYD_MOVE,
+     0xFFF0, false, 0x10, false, T2T_DEFAULT_LOCK_BLPB},
+    {TAG_BRCM_MID, true, T2T_BRCM_VERSION_BLOCK, T2T_BRCM_STATIC_MEM, 0xFFFF,
+     false, 0x06, false, T2T_DEFAULT_LOCK_BLPB},
+    {TAG_BRCM_MID, true, T2T_BRCM_VERSION_BLOCK, T2T_BRCM_DYNAMIC_MEM, 0xFFFF,
+     false, 0x3C, false, T2T_DEFAULT_LOCK_BLPB}
+
+};
+
+const uint8_t t4t_v10_ndef_tag_aid[T4T_V10_NDEF_TAG_AID_LEN] = {
+    0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x00};
+const uint8_t t4t_v20_ndef_tag_aid[T4T_V20_NDEF_TAG_AID_LEN] = {
+    0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01};
+
+#if (BT_TRACE_PROTOCOL == true)
+const char* const t1t_cmd_str[] = {
+    "T1T_RID",  "T1T_RALL",  "T1T_READ",     "T1T_WRITE_E",  "T1T_WRITE_NE",
+    "T1T_RSEG", "T1T_READ8", "T1T_WRITE_E8", "T1T_WRITE_NE8"};
+
+const char* const t2t_cmd_str[] = {"T2T_CMD_READ", "T2T_CMD_WRITE",
+                                   "T2T_CMD_SEC_SEL"};
+#endif
+
+static unsigned int tags_ones32(register unsigned int x);
+
+/*******************************************************************************
+**
+** Function         t1t_cmd_to_rsp_info
+**
+** Description      This function maps the given opcode to tT1T_CMD_RSP_INFO.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+const tT1T_CMD_RSP_INFO* t1t_cmd_to_rsp_info(uint8_t opcode) {
+  const tT1T_CMD_RSP_INFO* p_ret = NULL, *p;
+  int xx;
+
+  for (xx = 0, p = &t1t_cmd_rsp_infos[0]; xx < T1T_MAX_NUM_OPCODES; xx++, p++) {
+    if (opcode == p->opcode) {
+      if ((xx < T1T_STATIC_OPCODES) || (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0))
+        p_ret = p;
+      break;
+    }
+  }
+
+  return p_ret;
+}
+
+/*******************************************************************************
+**
+** Function         t1t_tag_init_data
+**
+** Description      This function maps the given opcode to tT1T_INIT_TAG.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+const tT1T_INIT_TAG* t1t_tag_init_data(uint8_t tag_model) {
+  const tT1T_INIT_TAG* p_ret = NULL, *p;
+  int xx;
+
+  for (xx = 0, p = &t1t_init_content[0]; xx < T1T_MAX_TAG_MODELS; xx++, p++) {
+    if (tag_model == p->tag_model) {
+      p_ret = p;
+      break;
+    }
+  }
+
+  return p_ret;
+}
+
+/*******************************************************************************
+**
+** Function         t2t_tag_init_data
+**
+** Description      This function maps the given manufacturer id and version to
+**                  tT2T_INIT_TAG.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+const tT2T_INIT_TAG* t2t_tag_init_data(uint8_t manufacturer_id,
+                                       bool b_valid_ver, uint16_t version_no) {
+  const tT2T_INIT_TAG* p_ret = NULL, *p;
+  int xx;
+
+  for (xx = 0, p = &t2t_init_content[0]; xx < T2T_MAX_TAG_MODELS; xx++, p++) {
+    if (manufacturer_id == p->manufacturer_id) {
+      if ((!p->b_multi_version) || (!b_valid_ver) ||
+          (p->version_no == (version_no & p->version_bmask))) {
+        p_ret = p;
+        break;
+      }
+    }
+  }
+
+  return p_ret;
+}
+
+/*******************************************************************************
+**
+** Function         t2t_cmd_to_rsp_info
+**
+** Description      This function maps the given opcode to tT2T_CMD_RSP_INFO.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+const tT2T_CMD_RSP_INFO* t2t_cmd_to_rsp_info(uint8_t opcode) {
+  const tT2T_CMD_RSP_INFO* p_ret = NULL, *p;
+  int xx;
+
+  for (xx = 0, p = &t2t_cmd_rsp_infos[0]; xx < T2T_MAX_NUM_OPCODES; xx++, p++) {
+    if (opcode == p->opcode) {
+      p_ret = p;
+      break;
+    }
+  }
+
+  return p_ret;
+}
+
+/*******************************************************************************
+**
+** Function         t1t_info_to_evt
+**
+** Description      This function maps the given tT1T_CMD_RSP_INFO to RW/CE
+**                  event code
+**
+** Returns          RW/CE event code
+**
+*******************************************************************************/
+uint8_t t1t_info_to_evt(const tT1T_CMD_RSP_INFO* p_info) {
+  return ((uint8_t)(p_info - t1t_cmd_rsp_infos) + RW_T1T_FIRST_EVT);
+}
+
+/*******************************************************************************
+**
+** Function         t2t_info_to_evt
+**
+** Description      This function maps the given tT2T_CMD_RSP_INFO to RW/CE
+**                  event code
+**
+** Returns          RW/CE event code
+**
+*******************************************************************************/
+uint8_t t2t_info_to_evt(const tT2T_CMD_RSP_INFO* p_info) {
+  return ((uint8_t)(p_info - t2t_cmd_rsp_infos) + RW_T2T_FIRST_EVT);
+}
+
+#if (BT_TRACE_PROTOCOL == true)
+/*******************************************************************************
+**
+** Function         t1t_info_to_str
+**
+** Description      This function maps the given tT1T_CMD_RSP_INFO to T1T cmd
+**                  str
+**
+** Returns          T1T cmd str
+**
+*******************************************************************************/
+const char* t1t_info_to_str(const tT1T_CMD_RSP_INFO* p_info) {
+  int ind = (int)(p_info - t1t_cmd_rsp_infos);
+  if (ind < T1T_MAX_NUM_OPCODES)
+    return (const char*)t1t_cmd_str[ind];
+  else
+    return "";
+}
+
+/*******************************************************************************
+**
+** Function         t2t_info_to_str
+**
+** Description      This function maps the given tT2T_CMD_RSP_INFO to T2T cmd
+**                  str
+**
+** Returns          T2T cmd str
+**
+*******************************************************************************/
+const char* t2t_info_to_str(const tT2T_CMD_RSP_INFO* p_info) {
+  int ind = (int)(p_info - t2t_cmd_rsp_infos);
+  if (ind < T2T_MAX_NUM_OPCODES)
+    return (const char*)t2t_cmd_str[ind];
+  else
+    return "";
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         tags_pow
+**
+** Description      This function calculates x(base) power of y.
+**
+** Returns          int
+**
+*******************************************************************************/
+int tags_pow(int x, int y) {
+  int i, ret = 1;
+  for (i = 0; i < y; i++) {
+    ret *= x;
+  }
+  return ret;
+}
+
+/*******************************************************************************
+**
+** Function         ones32
+**
+** Description      This function returns number of bits set in an unsigned
+**                  integer variable
+**
+** Returns          int
+**
+*******************************************************************************/
+static unsigned int tags_ones32(register unsigned int x) {
+  /* 32-bit recursive reduction using SWAR...
+ but first step is mapping 2-bit values
+ into sum of 2 1-bit values in sneaky way
+*/
+  x -= ((x >> 1) & 0x55555555);
+  x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
+  x = (((x >> 4) + x) & 0x0f0f0f0f);
+  x += (x >> 8);
+  x += (x >> 16);
+  return (x & 0x0000003f);
+}
+
+/*******************************************************************************
+**
+** Function         tags_log2
+**
+** Description      This function calculates log to the base  2.
+**
+** Returns          int
+**
+*******************************************************************************/
+unsigned int tags_log2(register unsigned int x) {
+  x |= (x >> 1);
+  x |= (x >> 2);
+  x |= (x >> 4);
+  x |= (x >> 8);
+  x |= (x >> 16);
+
+  return (tags_ones32(x) - 1);
+}
diff --git a/src/nfca_version.c b/src/nfca_version.c
new file mode 100644
index 0000000..6c83d7d
--- /dev/null
+++ b/src/nfca_version.c
@@ -0,0 +1,28 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "bt_types.h"
+
+const uint8_t nfca_version_string[] = "NFCDROID-AOSP_M_00.01";
+
+/*
+// The following string should be manually updated to contain the
+// label of the NFA version being used (see stack-info.txt).
+//
+// NOTE: IF additional branches are used add a "+" at the end of the string
+*/
+const uint8_t nfa_version_string[] = "NFA_PI_1.03.66+";
diff --git a/src/static-lib-adapt/ProtoDispBluetoothHci.c b/src/static-lib-adapt/ProtoDispBluetoothHci.c
new file mode 100644
index 0000000..449a5ae
--- /dev/null
+++ b/src/static-lib-adapt/ProtoDispBluetoothHci.c
@@ -0,0 +1,162 @@
+/******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 2011-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "_OverrideLog.h"
+#include "ProtoDispBluetoothHci.h"
+#include "nfc_target.h"
+#include <cutils/log.h>
+
+extern uint8_t* HCIDisp1(char* p_descr, uint8_t* p_data);
+extern uint32_t ScrProtocolTraceFlag;
+#define HCI_GEN_TRACE \
+  (TRACE_CTRL_GENERAL | TRACE_LAYER_HCI | TRACE_ORG_PROTO_DISP | hci_trace_type)
+static uint8_t hci_trace_type = 0;
+static char* modes_str[] = {"No sleep mode", "UART", "UART with messaging",
+                            "USB", "H4IBSS", "USB with host wake", "SDIO",
+                            "UART CS-N", "SPI", "H5", "H4DS", "",
+                            "UART with BREAK"};
+static uint8_t* p_end_hci = NULL;
+static uint8_t* HCIDisp1Ext(char* p_descr, uint8_t* p_data, char* p_ext);
+static void disp_sleepmode(uint8_t* p);
+static void disp_sleepmode_evt(uint8_t* p);
+
+///////////////////////////////////////////
+///////////////////////////////////////////
+
+uint8_t* HCIDisp1Ext(char* p_descr, uint8_t* p_data, char* p_ext) {
+    if (p_data == p_end_hci) return p_data;
+
+    char buff[200];
+
+    snprintf (buff, 200, "%40s : %u (0x%02x): %s", p_descr, *p_data, *p_data, p_ext);
+
+    ScrLog (HCI_GEN_TRACE, "%s", buff);
+    return (p_data + 1);
+}
+
+/*******************************************************************************
+**
+** Function         disp_sleepmode
+**
+** Description      Displays VSC sleep mode
+**
+** Returns          none.
+**
+*******************************************************************************/
+void disp_sleepmode(uint8_t* p) {
+  hci_trace_type = TRACE_TYPE_CMD_TX;
+  ScrLog(HCI_GEN_TRACE, "--");
+  int len = p[2];
+  ScrLog(HCI_GEN_TRACE,
+         "SEND Command to HCI.  Name: Set_Sleepmode_Param   (Hex Code: 0xfc27  "
+         "Param Len: %d)",
+         len);
+  p += 3;
+  p_end_hci = p + len;
+  p = HCIDisp1Ext("Sleep_Mode", p, (*p <= 12) ? modes_str[*p] : "");
+  p = HCIDisp1("Idle_Threshold_Host", p);
+  p = HCIDisp1("Idle_Threshold_HC", p);
+  p = HCIDisp1Ext("BT_WAKE_Active_Mode", p,
+                  (*p == 0) ? "Active Low" : ((*p == 1) ? "Active High" : ""));
+  p = HCIDisp1Ext("HOST_WAKE_Active_Mode", p,
+                  (*p == 0) ? "Active Low" : ((*p == 1) ? "Active High" : ""));
+  p = HCIDisp1("Allow_Host_Sleep_During_SCO", p);
+  p = HCIDisp1("Combine_Sleep_Mode_And_LPM", p);
+  p = HCIDisp1("Enable_Tristate_Control_Of_UART_Tx_Line", p);
+  p = HCIDisp1Ext("Active_Connection_Handling_On_Suspend", p,
+                  (*p == 0)
+                      ? "Maintain connections; sleep when timed activity allows"
+                      : ((*p == 1) ? "Sleep until resume is detected" : ""));
+  p = HCIDisp1("Resume_Timeout", p);
+  p = HCIDisp1("Enable_BREAK_To_Host", p);
+  p = HCIDisp1("Pulsed_HOST_WAKE", p);
+
+  ScrLog(HCI_GEN_TRACE, "--");
+}
+
+/*******************************************************************************
+**
+** Function         disp_sleepmode_evt
+**
+** Description      Displays HCI comand complete event for VSC sleep mode.
+**
+** Returns          none.
+**
+*******************************************************************************/
+void disp_sleepmode_evt(uint8_t* p) {
+  uint8_t len = p[1], status = p[5];
+
+  hci_trace_type = TRACE_TYPE_EVT_RX;
+  ScrLog(HCI_GEN_TRACE, "--");
+  ScrLog(HCI_GEN_TRACE,
+         "RCVD Event from HCI. Name: HCI_Command_Complete  (Hex Code: 0x0e  "
+         "Param Len: %d)",
+         len);
+
+  p = HCIDisp1("Num HCI Cmd Packets", p + 2);
+  ScrLog(HCI_GEN_TRACE, "%40s : 0xfc27  (Set_Sleepmode_Param)", "Cmd Code");
+  ScrLog(HCI_GEN_TRACE, "%40s : %d (0x%02x) %s", "Status", status, status,
+         (status == 0) ? "Success" : "");
+  ScrLog(HCI_GEN_TRACE, "--");
+}
+
+/*******************************************************************************
+**
+** Function         ProtoDispBluetoothHciCmd
+**
+** Description      Display a HCI command string
+**
+** Returns:
+**                  Nothing
+**
+*******************************************************************************/
+void ProtoDispBluetoothHciCmd(NFC_HDR* p_buf) {
+  if (!(ScrProtocolTraceFlag & SCR_PROTO_TRACE_HCI_SUMMARY)) return;
+  uint8_t* p = (uint8_t*)(p_buf + 1) + p_buf->offset;
+  if (*(p) == 0x27 && *(p + 1) == 0xfc)  // opcode sleep mode
+  {
+    disp_sleepmode(p);
+  }
+}
+
+/*******************************************************************************
+**
+** Function         ProtoDispBluetoothHciEvt
+**
+** Description      display a NCI event
+**
+** Returns:
+**                  Nothing
+**
+*******************************************************************************/
+void ProtoDispBluetoothHciEvt(NFC_HDR* pBuffer) {
+  if (!(ScrProtocolTraceFlag & SCR_PROTO_TRACE_HCI_SUMMARY)) return;
+
+  uint8_t* p = (uint8_t*)(pBuffer + 1) + pBuffer->offset;
+  if (*p == 0x0e)  // command complete
+  {
+    if (*(p + 1) == 4)  // length
+    {
+      if (*(p + 3) == 0x27 && *(p + 4) == 0xfc)  // opcode 0x27fc (sleep mode)
+      {
+        disp_sleepmode_evt(p);
+      }
+    }
+  }
+}
diff --git a/src/udrv/include/upio.h b/src/udrv/include/upio.h
new file mode 100644
index 0000000..06555c7
--- /dev/null
+++ b/src/udrv/include/upio.h
@@ -0,0 +1,348 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2001-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Definitions for UPIO driver
+ *
+ ******************************************************************************/
+#ifndef UPIO_H
+#define UPIO_H
+
+/* Enumeration of UPIO features                                         */
+/* Not all features enumerated here are supported by the hardware.      */
+/* Use UPIO_Feature() to determine support of a particular feature.     */
+enum {
+  /* LEDs */
+  UPIO_FEAT_LED1,
+  UPIO_FEAT_LED2,
+  UPIO_FEAT_LED3,
+  UPIO_FEAT_LED4,
+  UPIO_FEAT_LED5,
+  UPIO_FEAT_LED6,
+  UPIO_FEAT_LED7,
+  UPIO_FEAT_LED8,
+
+  /* Switches */
+  UPIO_FEAT_SWITCH1,
+  UPIO_FEAT_SWITCH2,
+  UPIO_FEAT_SWITCH3,
+  UPIO_FEAT_SWITCH4,
+  UPIO_FEAT_SWITCH5,
+  UPIO_FEAT_SWITCH6,
+  UPIO_FEAT_SWITCH7,
+  UPIO_FEAT_SWITCH8,
+  UPIO_FEAT_SWITCH9,
+  UPIO_FEAT_SWITCH10,
+  UPIO_FEAT_SWITCH11,
+  UPIO_FEAT_SWITCH12,
+  UPIO_FEAT_SWITCH13,
+  UPIO_FEAT_SWITCH14,
+  UPIO_FEAT_SWITCH15,
+  UPIO_FEAT_SWITCH16,
+
+  /* Jumpers */
+  UPIO_FEAT_JUMPER1,
+  UPIO_FEAT_JUMPER2,
+  UPIO_FEAT_JUMPER3,
+  UPIO_FEAT_JUMPER4,
+  UPIO_FEAT_JUMPER5,
+  UPIO_FEAT_JUMPER6,
+  UPIO_FEAT_JUMPER7,
+  UPIO_FEAT_JUMPER8,
+
+  /* Push buttons */
+  UPIO_FEAT_BUTTON1,
+  UPIO_FEAT_BUTTON2,
+  UPIO_FEAT_BUTTON3,
+  UPIO_FEAT_BUTTON4,
+  UPIO_FEAT_BUTTON5,
+  UPIO_FEAT_BUTTON6,
+  UPIO_FEAT_BUTTON7,
+  UPIO_FEAT_BUTTON8,
+
+  /* General purpose */
+  UPIO_FEAT_GENERAL1,
+  UPIO_FEAT_GENERAL2,
+  UPIO_FEAT_GENERAL3,
+  UPIO_FEAT_GENERAL4,
+  UPIO_FEAT_GENERAL5,
+  UPIO_FEAT_GENERAL6,
+  UPIO_FEAT_GENERAL7,
+  UPIO_FEAT_GENERAL8,
+  UPIO_FEAT_GENERAL9,
+  UPIO_FEAT_GENERAL10,
+  UPIO_FEAT_GENERAL11,
+  UPIO_FEAT_GENERAL12,
+  UPIO_FEAT_GENERAL13,
+  UPIO_FEAT_GENERAL14,
+  UPIO_FEAT_GENERAL15,
+  UPIO_FEAT_GENERAL16,
+  UPIO_FEAT_GENERAL17,
+  UPIO_FEAT_GENERAL18,
+  UPIO_FEAT_GENERAL19,
+  UPIO_FEAT_GENERAL20,
+  UPIO_FEAT_GENERAL21,
+  UPIO_FEAT_GENERAL22,
+  UPIO_FEAT_GENERAL23,
+  UPIO_FEAT_GENERAL24,
+  UPIO_FEAT_GENERAL25,
+  UPIO_FEAT_GENERAL26,
+  UPIO_FEAT_GENERAL27,
+  UPIO_FEAT_GENERAL28,
+  UPIO_FEAT_GENERAL29,
+  UPIO_FEAT_GENERAL30,
+  UPIO_FEAT_GENERAL31,
+  UPIO_FEAT_GENERAL32,
+
+  UPIO_FEAT_IN_HIGH, /* Support for input with interrupt on high signal level.
+                        */
+  UPIO_FEAT_IN_LOW,  /* Support for input with interrupt on low signal level. */
+  UPIO_FEAT_IN_RISE, /* Support for input with interrupt on rising edge. */
+  UPIO_FEAT_IN_FALL  /* Support for input with interrupt on falling. */
+
+};
+typedef uint8_t tUPIO_FEATURE;
+
+/* Enumeration of UPIO configurations */
+enum { UPIO_OUT, UPIO_IN, UPIO_IN_EDGE, UPIO_IN_LEVEL, UPIO_NONE };
+typedef uint8_t tUPIO_CONFIG;
+
+/* Enumeration of UPIO types */
+enum {
+  UPIO_LED,     /* LED */
+  UPIO_SWITCH,  /* Switch */
+  UPIO_JUMPER,  /* Jumper */
+  UPIO_BUTTON,  /* Push-button switch */
+  UPIO_GENERAL, /* General purpose I/O */
+
+  UPIO_NUMBER_OF_TYPES
+};
+typedef uint8_t tUPIO_TYPE;
+
+/* Enumeration of UPIO states */
+enum { UPIO_OFF, UPIO_ON, UPIO_TOGGLE };
+typedef uint8_t tUPIO_STATE;
+
+enum { UPIO_SW_BANK2, UPIO_SW_BANK3 };
+typedef uint8_t tUPIO_SW_BANK;
+
+/* Jumper masks */
+#define UPIO_JUMPER1 0x00000001
+#define UPIO_JUMPER2 0x00000002
+#define UPIO_JUMPER3 0x00000004
+#define UPIO_JUMPER4 0x00000008
+#define UPIO_JUMPER5 0x00000010
+#define UPIO_JUMPER6 0x00000020
+#define UPIO_JUMPER7 0x00000040
+#define UPIO_JUMPER8 0x00000080
+
+/* General purpose i/o masks */
+#define UPIO_GENERAL1 0x00000001
+#define UPIO_GENERAL2 0x00000002
+#define UPIO_GENERAL3 0x00000004
+#define UPIO_GENERAL4 0x00000008
+#define UPIO_GENERAL5 0x00000010
+#define UPIO_GENERAL6 0x00000020
+#define UPIO_GENERAL7 0x00000040
+#define UPIO_GENERAL8 0x00000080
+#define UPIO_GENERAL9 0x00000100
+#define UPIO_GENERAL10 0x00000200
+#define UPIO_GENERAL11 0x00000400
+#define UPIO_GENERAL12 0x00000800
+#define UPIO_GENERAL13 0x00001000
+#define UPIO_GENERAL14 0x00002000
+#define UPIO_GENERAL15 0x00004000
+#define UPIO_GENERAL16 0x00008000
+#define UPIO_GENERAL17 0x00010000
+#define UPIO_GENERAL18 0x00020000
+#define UPIO_GENERAL19 0x00040000
+#define UPIO_GENERAL20 0x00080000
+#define UPIO_GENERAL21 0x00100000
+#define UPIO_GENERAL22 0x00200000
+#define UPIO_GENERAL23 0x00400000
+#define UPIO_GENERAL24 0x00800000
+#define UPIO_GENERAL25 0x01000000
+#define UPIO_GENERAL26 0x02000000
+#define UPIO_GENERAL27 0x04000000
+#define UPIO_GENERAL28 0x08000000
+#define UPIO_GENERAL29 0x10000000
+#define UPIO_GENERAL30 0x20000000
+#define UPIO_GENERAL31 0x40000000
+#define UPIO_GENERAL32 0x80000000
+
+typedef uint32_t tUPIO;
+
+/* LED masks */
+#define UPIO_LED1 0x00000001
+#define UPIO_LED2 0x00000002
+#define UPIO_LED3 0x00000004
+#define UPIO_LED4 0x00000008
+#define UPIO_LED5 0x00000010
+#define UPIO_LED6 0x00000020
+#define UPIO_LED7 0x00000040
+#define UPIO_LED8 0x00000080
+
+#define UPIO_LED_ALL                                                       \
+  (UPIO_LED1 | UPIO_LED2 | UPIO_LED3 | UPIO_LED4 | UPIO_LED5 | UPIO_LED6 | \
+   UPIO_LED7 | UPIO_LED8)
+
+/* Switch masks */
+#define UPIO_SWITCH1 0x00000001
+#define UPIO_SWITCH2 0x00000002
+#define UPIO_SWITCH3 0x00000004
+#define UPIO_SWITCH4 0x00000008
+#define UPIO_SWITCH5 0x00000010
+#define UPIO_SWITCH6 0x00000020
+#define UPIO_SWITCH7 0x00000040
+#define UPIO_SWITCH8 0x00000080
+#define UPIO_SWITCH9 0x00000100
+#define UPIO_SWITCH10 0x00000200
+#define UPIO_SWITCH11 0x00000400
+#define UPIO_SWITCH12 0x00000800
+#define UPIO_SWITCH13 0x00001000
+#define UPIO_SWITCH14 0x00002000
+#define UPIO_SWITCH15 0x00004000
+#define UPIO_SWITCH16 0x00008000
+
+/* Push button masks */
+#define UPIO_BUTTON1 0x00000001
+#define UPIO_BUTTON2 0x00000002
+#define UPIO_BUTTON3 0x00000004
+#define UPIO_BUTTON4 0x00000008
+#define UPIO_BUTTON5 0x00000010
+#define UPIO_BUTTON6 0x00000020
+#define UPIO_BUTTON7 0x00000040
+#define UPIO_BUTTON8 0x00000080
+
+typedef void(tUPIO_CBACK)(tUPIO_TYPE type, tUPIO pio, tUPIO_STATE state);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* API functions for UPIO driver */
+
+/*****************************************************************************
+**
+** Function         UPIO_Init
+**
+** Description
+**      Initialize the GPIO service.
+**      This function is typically called once upon system startup.
+**
+** Returns          nothing
+**
+*****************************************************************************/
+void UPIO_Init(void* p_cfg);
+
+/*****************************************************************************
+**
+** Function         UPIO_Set
+**
+** Description
+**      This function sets one or more GPIO devices to the given state.
+**      Multiple GPIOs of the same type can be masked together to set more
+**      than one GPIO. This function can only be used on types UPIO_LED and
+**      UPIO_GENERAL.
+**
+** Input Parameters:
+**      type    The type of device.
+**      pio     Indicates the particular GPIOs.
+**      state   The desired state.
+**
+** Output Parameter:
+**      None.
+**
+** Returns:
+**      None.
+**
+*****************************************************************************/
+void UPIO_Set(tUPIO_TYPE type, tUPIO pio, tUPIO_STATE state);
+
+/*****************************************************************************
+**
+** Function         UPIO_Read
+**
+** Description
+**      Read the state of a GPIO. This function can be used for any type of
+**      device. Parameter pio can only indicate a single GPIO; multiple GPIOs
+**      cannot be masked together.
+**
+** Input Parameters:
+**      Type:   The type of device.
+**      pio:    Indicates the particular GUPIO.
+**
+** Output Parameter:
+**      None.
+**
+** Returns:
+**      State of GPIO (UPIO_ON or UPIO_OFF).
+**
+*****************************************************************************/
+tUPIO_STATE UPIO_Read(tUPIO_TYPE type, tUPIO pio);
+
+/*****************************************************************************
+**
+** Function         UPIO_Config
+**
+** Description      - Configure GPIOs of type UPIO_GENERAL as inputs or outputs
+**                  - Configure GPIOs to be polled or interrupt driven
+**
+**                  Currently only support polled GPIOs.
+**
+** Input Parameters:
+**      type    The type of device.
+**      pio     Indicates the particular GPIOs.
+**      config
+**      cback
+**
+** Output Parameter:
+**      None.
+**
+** Returns:
+**      None.
+**
+*****************************************************************************/
+void UPIO_Config(tUPIO_TYPE type, tUPIO pio, tUPIO_CONFIG config,
+                 tUPIO_CBACK* cback);
+
+/*****************************************************************************
+**
+** Function         UPIO_Feature
+**
+** Description
+**      Checks whether a feature of the pio API is supported
+**
+** Input Parameter:
+**      feature     The feature to check
+**
+** Output Parameter:
+**      None.
+**
+** Returns:
+**      true if feature is supported, false if it is not.
+**
+*****************************************************************************/
+bool UPIO_Feature(tUPIO_FEATURE feature);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ifdef UPIO_H */