NFC_NCIHALx_AR0F.3.5.0_L_OpnSrc
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..49146f4
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,98 @@
+# 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)
+include $(CLEAR_VARS)
+NFA := src/nfa
+NFC := src/nfc
+HAL := src/hal
+UDRV := src/udrv
+
+D_CFLAGS := -DANDROID -DBUILDCFG=1
+
+#NXP PN547 Enable
+D_CFLAGS += -DNFC_NXP_NOT_OPEN_INCLUDED=TRUE
+#variables for NFC_NXP_CHIP_TYPE
+PN547C2 := 1
+PN548C2 := 2
+PN551C2 := 3
+NQ110 := $PN547C2
+NQ120 := $PN547C2
+NQ210 := $PN548C2
+NQ220 := $PN548C2
+
+ifeq ($(PN547C2),1)
+D_CFLAGS += -DPN547C2=1
+endif
+ifeq ($(PN548C2),2)
+D_CFLAGS += -DPN548C2=2
+endif
+ifeq ($(PN551C2),3)
+D_CFLAGS += -DPN551C2=3
+endif
+
+#### Select the JCOP OS Version ####
+JCOP_VER_3_0 := 1
+JCOP_VER_3_1_1 := 2
+JCOP_VER_3_1_2 := 3
+JCOP_VER_3_2 := 4
+
+LOCAL_CFLAGS += -DJCOP_VER_3_0=$(JCOP_VER_3_0)
+LOCAL_CFLAGS += -DJCOP_VER_3_1_1=$(JCOP_VER_3_1_1)
+LOCAL_CFLAGS += -DJCOP_VER_3_1_2=$(JCOP_VER_3_1_2)
+LOCAL_CFLAGS += -DJCOP_VER_3_2=$(JCOP_VER_3_2)
+
+NFC_NXP_ESE:= FALSE
+ifeq ($(NFC_NXP_ESE),TRUE)
+LOCAL_CFLAGS += -DNFC_NXP_ESE=TRUE
+LOCAL_CFLAGS += -DNFC_NXP_ESE_VER=$(JCOP_VER_3_1_2)
+else
+LOCAL_CFLAGS += -DNFC_NXP_ESE=FALSE
+endif
+
+#### Select the CHIP ####
+D_CFLAGS += -DNFC_NXP_CHIP_TYPE=PN548C2
+
+#Gemalto SE support
+D_CFLAGS += -DGEMALTO_SE_SUPPORT
+D_CFLAGS += -DNXP_UICC_ENABLE
+D_CFLAGS += -DESE_NFC_POWER_MANAGEMENT=FALSE
+######################################
+# Build shared library system/lib/libnfc-nci.so for stack code.
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_ARM_MODE := arm
+LOCAL_MODULE := libnfc-nci
+LOCAL_MODULE_TAGS := optional
+LOCAL_SHARED_LIBRARIES := libhardware_legacy libcutils liblog libdl libstlport libhardware
+LOCAL_CFLAGS += $(D_CFLAGS)
+LOCAL_C_INCLUDES := external/stlport/stlport bionic/ bionic/libstdc++/include \
+ $(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
+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))
diff --git a/CleanSpec.mk b/CleanSpec.mk
new file mode 100644
index 0000000..e051104
--- /dev/null
+++ b/CleanSpec.mk
@@ -0,0 +1,50 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# If you don't need to do a full clean build but would like to touch
+# a file or delete some intermediate files, add a clean step to the end
+# of the list. These steps will only be run once, if they haven't been
+# run before.
+#
+# E.g.:
+# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
+# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
+#
+# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
+# files that are missing or have been moved.
+#
+# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
+# Use $(OUT_DIR) to refer to the "out" directory.
+#
+# If you need to re-do something that's already mentioned, just copy
+# the command and add it to the bottom of the list. E.g., if a change
+# that you made last week required touching a file and a change you
+# made today requires touching the same file, just copy the old
+# touch step and add it to the end of the list.
+#
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
+
+# For example:
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
+#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
+#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libnfc-nci_intermediates)
+
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
diff --git a/halimpl/Android.mk b/halimpl/Android.mk
new file mode 100644
index 0000000..cfd03be
--- /dev/null
+++ b/halimpl/Android.mk
@@ -0,0 +1,2 @@
+LOCAL_PATH:= $(call my-dir)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/halimpl/pn54x/Android.mk b/halimpl/pn54x/Android.mk
new file mode 100644
index 0000000..5b200a7
--- /dev/null
+++ b/halimpl/pn54x/Android.mk
@@ -0,0 +1,77 @@
+# Copyright (C) 2011 The Android Open Source Project
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# function to find all *.cpp files under a directory
+define all-cpp-files-under
+$(patsubst ./%,%, \
+ $(shell cd $(LOCAL_PATH) ; \
+ find $(1) -name "*.cpp" -and -not -name ".*") \
+ )
+endef
+
+
+HAL_SUFFIX := $(TARGET_DEVICE)
+ifeq ($(TARGET_DEVICE),crespo)
+ HAL_SUFFIX := herring
+endif
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_ARM_MODE := arm
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+LOCAL_MODULE := nfc_nci.pn54x.default
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_SRC_FILES := $(call all-c-files-under, .) $(call all-cpp-files-under, .)
+LOCAL_SHARED_LIBRARIES := liblog libcutils libhardware_legacy libdl libstlport
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_C_INCLUDES += external/stlport/stlport bionic/ bionic/libstdc++/include \
+ $(LOCAL_PATH)/utils \
+ $(LOCAL_PATH)/inc \
+ $(LOCAL_PATH)/common \
+ $(LOCAL_PATH)/dnld \
+ $(LOCAL_PATH)/hal \
+ $(LOCAL_PATH)/log \
+ $(LOCAL_PATH)/tml \
+ $(LOCAL_PATH)/self-test
+
+
+#variables for NFC_NXP_CHIP_TYPE
+PN547C2 := 1
+PN548C2 := 2
+NQ110 := $PN547C2
+NQ120 := $PN547C2
+NQ210 := $PN548C2
+NQ220 := $PN548C2
+#NXP PN547 Enable
+ifeq ($(PN547C2),1)
+LOCAL_CFLAGS += -DPN547C2=1
+endif
+ifeq ($(PN548C2),2)
+LOCAL_CFLAGS += -DPN548C2=2
+endif
+
+#### Select the CHIP ####
+LOCAL_CFLAGS += -DNFC_NXP_CHIP_TYPE=PN548C2
+
+LOCAL_CFLAGS += -DANDROID \
+ -DNXP_UICC_ENABLE -DNXP_HW_SELF_TEST
+LOCAL_CFLAGS += -DNFC_NXP_HFO_SETTINGS=FALSE
+D_CFLAGS += -DESE_NFC_POWER_MANAGEMENT=FALSE
+LOCAL_CFLAGS += $(D_CFLAGS)
+#LOCAL_CFLAGS += -DFELICA_CLT_ENABLE
+#-DNXP_PN547C1_DOWNLOAD
+include $(BUILD_SHARED_LIBRARY)
diff --git a/halimpl/pn54x/common/phNfcCommon.h b/halimpl/pn54x/common/phNfcCommon.h
new file mode 100644
index 0000000..9759ae3
--- /dev/null
+++ b/halimpl/pn54x/common/phNfcCommon.h
@@ -0,0 +1,145 @@
+/*
+ * 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>
+
+
+# define FW_DLL_ROOT_DIR "/system/vendor/firmware/"
+# define FW_DLL_EXTENSION ".so"
+
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+
+/* Actual FW library name*/
+#define FW_LIB_PATH FW_DLL_ROOT_DIR "libpn548ad_fw" FW_DLL_EXTENSION
+/* Restore Currupted PLL Setttings/etc */
+#define PLATFORM_LIB_PATH FW_DLL_ROOT_DIR "libpn548ad_fw_platform" FW_DLL_EXTENSION
+/* Upgrade the public Key */
+#define PKU_LIB_PATH FW_DLL_ROOT_DIR "libpn548ad_fw_pku" FW_DLL_EXTENSION
+#else
+/* Actual FW library name*/
+#define FW_LIB_PATH FW_DLL_ROOT_DIR "libpn547_fw" FW_DLL_EXTENSION
+/* Restore Currupted PLL Setttings/etc */
+#define PLATFORM_LIB_PATH FW_DLL_ROOT_DIR "libpn547_fw_platform" FW_DLL_EXTENSION
+/* Upgrade the public Key */
+#define PKU_LIB_PATH FW_DLL_ROOT_DIR "libpn547_fw_pku" FW_DLL_EXTENSION
+#endif
+
+/* HAL Version number (Updated as per release) */
+#define NXP_MW_VERSION_MAJ (5U)
+#define NXP_MW_VERSION_MIN (0U)
+
+/*
+ *****************************************************************
+ *********** System clock source selection configuration ********
+ *****************************************************************
+ */
+
+#define CLK_SRC_UNDEF 0
+#define CLK_SRC_XTAL 1
+#define CLK_SRC_PLL 2
+#define CLK_SRC_PADDIRECT 3
+
+/*Extern crystal clock source*/
+#define NXP_SYS_CLK_SRC_SEL CLK_SRC_PLL /* Use one of CLK_SRC_<value> */
+/*Direct clock*/
+
+/*
+ *****************************************************************
+ *********** System clock frequency selection configuration ****************
+ * If Clk_Src is set to PLL, make sure to set the Clk_Freq also*
+ *****************************************************************
+ */
+#define CLK_FREQ_UNDEF 0
+#define CLK_FREQ_13MHZ 1
+#define CLK_FREQ_19_2MHZ 2
+#define CLK_FREQ_24MHZ 3
+#define CLK_FREQ_26MHZ 4
+#define CLK_FREQ_38_4MHZ 5
+#define CLK_FREQ_52MHZ 6
+
+#define NXP_SYS_CLK_FREQ_SEL CLK_FREQ_19_2MHZ /* Set to one of CLK_FREQ_<value> */
+
+#define CLK_TO_CFG_DEF 1
+#define CLK_TO_CFG_MAX 26
+/*
+ * information to configure OSAL
+ */
+typedef struct phOsalNfc_Config
+{
+ uint8_t *pLogFile; /* Log File Name*/
+ uintptr_t dwCallbackThreadId; /* Client ID to which message is posted */
+}phOsalNfc_Config_t, *pphOsalNfc_Config_t /* Pointer to #phOsalNfc_Config_t */;
+
+
+/*
+ * Deferred call declaration.
+ * This type of API is called from ClientApplication (main thread) to notify
+ * specific callback.
+ */
+typedef void (*pphOsalNfc_DeferFuncPointer_t) (void*);
+
+
+/*
+ * Deferred message specific info declaration.
+ */
+typedef struct phOsalNfc_DeferedCallInfo
+{
+ pphOsalNfc_DeferFuncPointer_t pDeferedCall;/* pointer to Deferred callback */
+ void *pParam; /* contains timer message specific details*/
+}phOsalNfc_DeferedCallInfo_t;
+
+
+/*
+ * States in which a OSAL timer exist.
+ */
+typedef enum
+{
+ eTimerIdle = 0, /* Indicates Initial state of timer */
+ eTimerRunning = 1, /* Indicate timer state when started */
+ eTimerStopped = 2 /* Indicates timer state when stopped */
+}phOsalNfc_TimerStates_t; /* Variable representing State of timer */
+
+/*
+ **Timer Handle structure containing details of a timer.
+ */
+typedef struct phOsalNfc_TimerHandle
+{
+ uint32_t TimerId; /* ID of the timer */
+ timer_t hTimerHandle; /* Handle of the timer */
+ pphOsalNfc_TimerCallbck_t Application_callback; /* Timer callback function to be invoked */
+ void *pContext; /* Parameter to be passed to the callback function */
+ phOsalNfc_TimerStates_t eState; /* Timer states */
+ phLibNfc_Message_t tOsalMessage; /* Osal Timer message posted on User Thread */
+ phOsalNfc_DeferedCallInfo_t tDeferedCallInfo; /* Deferred Call structure to Invoke Callback function */
+}phOsalNfc_TimerHandle_t,*pphOsalNfc_TimerHandle_t; /* Variables for Structure Instance and Structure Ptr */
+
+#endif /* PHOSALNFC_H */
diff --git a/halimpl/pn54x/common/phNfcCompId.h b/halimpl/pn54x/common/phNfcCompId.h
new file mode 100644
index 0000000..2d94e67
--- /dev/null
+++ b/halimpl/pn54x/common/phNfcCompId.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2015 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * NFC Component ID Values - Used for Function Return Codes
+ */
+
+#ifndef PHNFCCOMPID_H
+#define PHNFCCOMPID_H
+
+/*
+ * Component IDs
+ *
+ * IDs for all NFC components. Combined with the Status Code they build the value (status)
+ * returned by each function.
+ *
+ * ID Number Spaces:
+ * - 01..1F: HAL
+ * - 20..3F: NFC-MW (Local Device)
+ * - 40..5F: NFC-MW (Remote Device)
+ * .
+ *
+ * The value CID_NFC_NONE does not exist for Component IDs. Do not use this value except
+ * for NFCSTATUS_SUCCESS. The enumeration function uses CID_NFC_NONE
+ * to mark unassigned "References".
+ */
+#define CID_NFC_NONE 0x00 /* Unassigned or doesn't apply (see #NFCSTATUS_SUCCESS) */
+#define CID_NFC_TML 0x01 /* Transport Mapping Layer */
+#define CID_NFC_LLC 0x07 /* Logical Link Control Layer */
+#define CID_NFC_NCI 0x08 /* NFC Controller(NFCC) Interface Layer */
+#define CID_NFC_DNLD 0x09 /* Firmware Download Management Layer */
+#define CID_NFC_HAL 0x10 /* Hardware Abstraction Layer */
+#define CID_NFC_OSAL CID_NFC_NONE /* Operating System Abstraction Layer*/
+#define CID_FRI_NFC_OVR_HAL 0x20 /* NFC-Device, HAL-based */
+#define CID_FRI_NFC_NDEF_RECORD 0x22 /* NDEF Record Tools Library. */
+#define CID_FRI_NFC_NDEF_MAP 0x23 /* NDEF Mapping. */
+#define CID_FRI_NFC_NDEF_REGISTRY 0x24 /* NDEF_REGISTRY. */
+#define CID_FRI_NFC_AUTO_DEV_DIS 0x25 /* Automatic Device Discovery. */
+#define CID_FRI_NFC_NDEF_SMTCRDFMT 0x26 /* Smart Card Formatting */
+#define CID_NFC_LIB 0x30 /* NFC Library Layer*/
+#define CID_MAX_VALUE 0xF0 /* The maximum CID value that is defined. */
+#define CID_FRI_NFC_LLCP 0x40 /* Logical Link Control Protocol */
+#define CID_FRI_NFC_LLCP_TRANSPORT 0x50
+#define CID_FRI_NFC_LLCP_MAC 0x60
+
+#endif /* PHNFCCOMPID_H */
diff --git a/halimpl/pn54x/common/phNfcStatus.h b/halimpl/pn54x/common/phNfcStatus.h
new file mode 100644
index 0000000..69dcef4
--- /dev/null
+++ b/halimpl/pn54x/common/phNfcStatus.h
@@ -0,0 +1,391 @@
+/*
+ * 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)
+
+/*
+ * 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)
+
+#if(ESE_NFC_POWER_MANAGEMENT == TRUE)
+
+#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)
+
+#else
+/* The current module is busy ; one might retry later */
+#define NFCSTATUS_SMX_BAD_STATE (0x00F0)
+
+#endif
+
+/* 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..cb431c0
--- /dev/null
+++ b/halimpl/pn54x/common/phNfcTypes.h
@@ -0,0 +1,312 @@
+/*
+ * 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>
+
+#ifndef TRUE
+#define TRUE (0x01) /* Logical True Value */
+#endif
+#ifndef FALSE
+#define FALSE (0x00) /* Logical False Value */
+#endif
+typedef uint8_t utf8_t; /* UTF8 Character String */
+typedef uint8_t bool_t; /* boolean data type */
+typedef uint16_t NFCSTATUS; /* Return values */
+#define STATIC static
+
+#define PHNFC_MAX_UID_LENGTH 0x0AU /* Maximum UID length expected */
+#define PHNFC_MAX_ATR_LENGTH 0x30U /* Maximum ATR_RES (General Bytes) length expected */
+#define PHNFC_NFCID_LENGTH 0x0AU /* Maximum length of NFCID 1.3*/
+#define PHNFC_ATQA_LENGTH 0x02U /* ATQA length */
+
+/*
+ * NFC Data structure
+ */
+typedef struct phNfc_sData
+{
+ uint8_t *buffer; /* Buffer to store data */
+ uint32_t length; /* Buffer length */
+} phNfc_sData_t;
+
+/*
+ * Possible Hardware Configuration exposed to upper layer.
+ * Typically this should be port name (Ex:"COM1","COM2") to which PN54X is connected.
+ */
+typedef enum
+{
+ ENUM_LINK_TYPE_COM1,
+ ENUM_LINK_TYPE_COM2,
+ ENUM_LINK_TYPE_COM3,
+ ENUM_LINK_TYPE_COM4,
+ ENUM_LINK_TYPE_COM5,
+ ENUM_LINK_TYPE_COM6,
+ ENUM_LINK_TYPE_COM7,
+ ENUM_LINK_TYPE_COM8,
+ ENUM_LINK_TYPE_I2C,
+ ENUM_LINK_TYPE_SPI,
+ ENUM_LINK_TYPE_USB,
+ ENUM_LINK_TYPE_TCP,
+ ENUM_LINK_TYPE_NB
+} phLibNfc_eConfigLinkType;
+
+/*
+ * Deferred message. This message type will be posted to the client application thread
+ * to notify that a deferred call must be invoked.
+ */
+#define PH_LIBNFC_DEFERREDCALL_MSG (0x311)
+
+/*
+ * Deferred call declaration.
+ * This type of API is called from ClientApplication ( main thread) to notify
+ * specific callback.
+ */
+typedef void (*pphLibNfc_DeferredCallback_t) (void*);
+
+/*
+ * Deferred parameter declaration.
+ * This type of data is passed as parameter from ClientApplication (main thread) to the
+ * callback.
+ */
+typedef void *pphLibNfc_DeferredParameter_t;
+
+/*
+ * Possible Hardware Configuration exposed to upper layer.
+ * Typically this should be at least the communication link (Ex:"COM1","COM2")
+ * the controller is connected to.
+ */
+typedef struct phLibNfc_sConfig
+{
+ uint8_t *pLogFile; /* Log File Name*/
+ /* Hardware communication link to the controller */
+ phLibNfc_eConfigLinkType nLinkType;
+ /* The client ID (thread ID or message queue ID) */
+ uintptr_t nClientId;
+} phLibNfc_sConfig_t, *pphLibNfc_sConfig_t;
+
+/*
+ * NFC Message structure contains message specific details like
+ * message type, message specific data block details, etc.
+ */
+typedef struct phLibNfc_Message
+{
+ uint32_t eMsgType; /* Type of the message to be posted*/
+ void * pMsgData; /* Pointer to message specific data block in case any*/
+ uint32_t Size; /* Size of the datablock*/
+} phLibNfc_Message_t,*pphLibNfc_Message_t;
+
+/*
+ * Deferred message specific info declaration.
+ * This type of information is packed as message data when PH_LIBNFC_DEFERREDCALL_MSG
+ * type message is posted to message handler thread.
+ */
+typedef struct phLibNfc_DeferredCall
+{
+ pphLibNfc_DeferredCallback_t pCallback;/* pointer to Deferred callback */
+ pphLibNfc_DeferredParameter_t pParameter;/* pointer to Deferred parameter */
+} phLibNfc_DeferredCall_t;
+
+/*
+ * Definitions for supported protocol
+ */
+typedef struct phNfc_sSupProtocol
+{
+ unsigned int MifareUL : 1; /* Protocol Mifare Ultra Light or any NFC Forum Type-2 tags */
+ unsigned int MifareStd : 1; /* Protocol Mifare Standard. */
+ unsigned int ISO14443_4A : 1; /* Protocol ISO14443-4 Type A. */
+ unsigned int ISO14443_4B : 1; /* Protocol ISO14443-4 Type B. */
+ unsigned int ISO15693 : 1; /* Protocol ISO15693 HiTag. */
+ unsigned int Felica : 1; /* Protocol Felica. */
+ unsigned int NFC : 1; /* Protocol NFC. */
+ unsigned int Jewel : 1; /* Protocol Innovision Jewel Tag. or Any T1T*/
+ unsigned int Desfire : 1; /*TRUE indicates specified feature (mapping
+ or formatting)for DESFire tag supported else not supported.*/
+ unsigned int Kovio : 1; /* Protocol Kovio Tag*/
+ unsigned int HID : 1; /* Protocol HID(Picopass) Tag*/
+ unsigned int Bprime : 1; /* Protocol BPrime Tag*/
+ unsigned int EPCGEN2 : 1; /* Protocol EPCGEN2 Tag*/
+}phNfc_sSupProtocol_t;
+
+/*
+ * Enumerated MIFARE Commands
+ */
+
+typedef enum phNfc_eMifareCmdList
+{
+ phNfc_eMifareRaw = 0x00U, /* This command performs raw transcations */
+ phNfc_eMifareAuthentA = 0x60U, /* This command performs an authentication with KEY A for a sector. */
+ phNfc_eMifareAuthentB = 0x61U, /* This command performs an authentication with KEY B for a sector. */
+ phNfc_eMifareRead16 = 0x30U, /* Read 16 Bytes from a Mifare Standard block */
+ phNfc_eMifareRead = 0x30U, /* Read Mifare Standard */
+ phNfc_eMifareWrite16 = 0xA0U, /* Write 16 Bytes to a Mifare Standard block */
+ phNfc_eMifareWrite4 = 0xA2U, /* Write 4 bytes. */
+ phNfc_eMifareInc = 0xC1U, /* Increment */
+ phNfc_eMifareDec = 0xC0U, /* Decrement */
+ phNfc_eMifareTransfer = 0xB0U, /* Transfer */
+ phNfc_eMifareRestore = 0xC2U, /* Restore. */
+ phNfc_eMifareReadSector = 0x38U, /* Read Sector. */
+ phNfc_eMifareWriteSector= 0xA8U, /* Write Sector. */
+ /* Above commands could be used for preparing raw command but below one can not be */
+ phNfc_eMifareReadN = 0x01, /* Proprietary Command */
+ phNfc_eMifareWriteN = 0x02, /* Proprietary Command */
+ phNfc_eMifareSectorSel = 0x03, /* Proprietary Command */
+ phNfc_eMifareAuth = 0x04, /* Proprietary Command */
+ phNfc_eMifareProxCheck = 0x05, /* Proprietary Command */
+ phNfc_eMifareInvalidCmd = 0xFFU /* Invalid Command */
+} phNfc_eMifareCmdList_t;
+
+/*
+ * Information about ISO14443A
+ */
+typedef struct phNfc_sIso14443AInfo
+{
+ uint8_t Uid[PHNFC_MAX_UID_LENGTH]; /* UID information of the TYPE A
+ * Tag Discovered */
+ uint8_t UidLength; /* UID information length */
+ uint8_t AppData[PHNFC_MAX_ATR_LENGTH]; /* Application data information of the
+ 1 * tag discovered (= Historical bytes for
+ * type A) */
+ uint8_t AppDataLength; /* Application data length */
+ uint8_t Sak; /* SAK information of the TYPE A
+ * Tag Discovered */
+ uint8_t AtqA[PHNFC_ATQA_LENGTH]; /* ATQA informationof the TYPE A
+ * Tag Discovered */
+ uint8_t MaxDataRate; /* Maximum data rate supported
+ * by the tag Discovered */
+ uint8_t Fwi_Sfgt; /* Frame waiting time and start up
+ * frame guard */
+}phNfc_sIso14443AInfo_t;
+
+/* Remote device information structure */
+typedef union phNfc_uRemoteDevInfo
+{
+ phNfc_sIso14443AInfo_t Iso14443A_Info;/* ISO1443A Remote device info */
+}phNfc_uRemoteDevInfo_t;
+
+/*
+*
+* The RF Device Type List is used to identify the type of
+* remote device that is discovered and connected.
+*
+*/
+
+typedef enum phNfc_eRFDevType
+{
+ phNfc_eUnknown_DevType = 0x00U,
+
+ phNfc_eISO14443_A_PCD,
+ phNfc_eISO14443_B_PCD,
+ phNfc_eISO14443_BPrime_PCD,
+ phNfc_eFelica_PCD,
+ phNfc_eJewel_PCD,
+ phNfc_eISO15693_PCD,
+ phNfc_eEpcGen2_PCD,
+ phNfc_ePCD_DevType,
+
+ phNfc_ePICC_DevType,
+ phNfc_eISO14443_A_PICC,
+ phNfc_eISO14443_4A_PICC,
+ phNfc_eISO14443_3A_PICC,
+ phNfc_eMifare_PICC,
+ phNfc_eISO14443_B_PICC,
+ phNfc_eISO14443_4B_PICC,
+ phNfc_eISO14443_BPrime_PICC,
+ phNfc_eFelica_PICC,
+ phNfc_eJewel_PICC,
+ phNfc_eISO15693_PICC,
+ phNfc_eEpcGen2_PICC,
+
+ phNfc_eNfcIP1_Target,
+ phNfc_eNfcIP1_Initiator,
+
+ phNfc_eInvalid_DevType
+
+}phNfc_eRFDevType_t;
+
+/*
+ * The Remote Device Type List is used to identify the type of
+ * remote device that is discovered/connected
+ */
+typedef phNfc_eRFDevType_t phNfc_eRemDevType_t;
+typedef phNfc_eRemDevType_t phHal_eRemDevType_t;
+
+/*
+ * Union for each available type of Commands.
+ */
+
+typedef union phNfc_uCommand
+{
+ phNfc_eMifareCmdList_t MfCmd; /* Mifare command structure. */
+}phNfc_uCmdList_t;
+
+/*
+ * The Remote Device Information Structure holds information about one single Remote
+ * Device detected.
+ */
+typedef struct phNfc_sRemoteDevInformation
+{
+ uint8_t SessionOpened; /* Flag indicating the validity of
+ * the handle of the remote device.
+ * 1 = Device is not activer (Only discovered), 2 = Device is active and ready for use*/
+ phNfc_eRemDevType_t RemDevType; /* Remote device type */
+ phNfc_uRemoteDevInfo_t RemoteDevInfo; /* Union of available Remote Device */
+}phNfc_sRemoteDevInformation_t;
+
+
+/*
+ * Transceive Information Data Structure for sending commands/response to the remote device
+ */
+
+typedef struct phNfc_sTransceiveInfo
+{
+ phNfc_uCmdList_t cmd; /* Command for transceive */
+ uint8_t addr; /* Start Block Number */
+ uint8_t NumBlock; /* Number of Blocks to perform operation */
+ /* For Felica only*/
+ uint16_t *ServiceCodeList; /* 2 Byte service Code List */
+ uint16_t *Blocklist; /* 2 Byte Block list */
+ phNfc_sData_t sSendData; /* Send data */
+ phNfc_sData_t sRecvData; /* Recv data */
+ /* For EPC-GEN */
+ uint32_t dwWordPtr; /* Word address for the memory write */
+ uint8_t bWordPtrLen; /* Specifies the length of word pointer
+ 00: 8 bits
+ 01: 16 bits
+ 10: 24 bits
+ 11: 32 bits
+ */
+ uint8_t bWordCount; /* Number of words to be read or written */
+}phNfc_sTransceiveInfo_t;
+#if((ESE_NFC_POWER_MANAGEMENT == TRUE)&&(NFC_NXP_NOT_OPEN_INCLUDED == 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_access_state_t;
+#endif
+#define UNUSED(X) (void)X;
+
+#endif /* PHNFCTYPES_H */
diff --git a/halimpl/pn54x/dnld/phDnldNfc.c b/halimpl/pn54x/dnld/phDnldNfc.c
new file mode 100644
index 0000000..13aaab5
--- /dev/null
+++ b/halimpl/pn54x/dnld/phDnldNfc.c
@@ -0,0 +1,1459 @@
+/*
+ * 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 */
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+uint8_t gRecFWDwnld; // flag set to true to indicate dummy FW download
+#endif
+static pphDnldNfc_DlContext_t gpphDnldContext = NULL; /* Download contex */
+static pphDnldNfc_RspCb_t UserCb; /* Upper layer call back function */
+static void* UserCtxt; /* Pointer to upper layer context */
+#undef EEPROM_Read_Mem_IMP
+
+/* Function prototype declaration */
+static void phDnldNfc_ReadComplete(void* pContext, NFCSTATUS status, void* pInfo);
+
+/*******************************************************************************
+**
+** Function phDnldNfc_Reset
+**
+** Description Performs a soft reset of the download module
+**
+** Parameters pNotify - notify caller after getting response
+** pContext - caller context
+**
+** Returns NFC status:
+** NFCSTATUS_SUCCESS - reset request to NFCC is successful
+** NFCSTATUS_FAILED - reset request failed due to internal error
+** NFCSTATUS_NOT_ALLOWED - command not allowed
+** Other command specific errors -
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_Reset(pphDnldNfc_RspCb_t pNotify, void *pContext)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+
+ if((NULL == pNotify) ||
+ (NULL == pContext)
+ )
+ {
+ NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+ }
+ else
+ {
+ if(phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress)
+ {
+ NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
+ }
+ else
+ {
+ (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTNone;
+ (gpphDnldContext->tCmdId) = PH_DL_CMD_RESET;
+ (gpphDnldContext->tRspBuffInfo.pBuff) = NULL;
+ (gpphDnldContext->tRspBuffInfo.wLen) = 0;
+ (gpphDnldContext->tUserData.pBuff) = NULL;
+ (gpphDnldContext->tUserData.wLen) = 0;
+ (gpphDnldContext->UserCb) = pNotify;
+ (gpphDnldContext->UserCtxt) = pContext;
+
+ wStatus = phDnldNfc_CmdHandler(gpphDnldContext,phDnldNfc_EventReset);
+
+ if(NFCSTATUS_PENDING == wStatus)
+ {
+ NXPLOG_FWDNLD_D("Reset Request submitted successfully");
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Reset Request Failed!!");
+ }
+ }
+ }
+
+ return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function phDnldNfc_GetVersion
+**
+** Description Retrieves Hardware version, ROM Code version, Protected Data version,
+** Trim data version, User data version, and Firmware version information
+**
+** Parameters pVersionInfo - response buffer which gets updated with complete version info from NFCC
+** pNotify - notify caller after getting response
+** pContext - caller context
+**
+** Returns NFC status:
+** NFCSTATUS_SUCCESS - GetVersion request to NFCC is successful
+** NFCSTATUS_FAILED - GetVersion request failed due to internal error
+** NFCSTATUS_NOT_ALLOWED - command not allowed
+** Other command specific errors -
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_GetVersion(pphDnldNfc_Buff_t pVersionInfo, pphDnldNfc_RspCb_t pNotify, void *pContext)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+
+ if((NULL == pVersionInfo) || (NULL == pNotify) ||
+ (NULL == pContext)
+ )
+ {
+ NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+ }
+ else
+ {
+ if(phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress)
+ {
+ NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
+ }
+ else
+ {
+ if((NULL != pVersionInfo->pBuff) && (0 != pVersionInfo->wLen))
+ {
+ (gpphDnldContext->tRspBuffInfo.pBuff) = pVersionInfo->pBuff;
+ (gpphDnldContext->tRspBuffInfo.wLen) = pVersionInfo->wLen;
+ (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTNone;
+ (gpphDnldContext->tCmdId) = PH_DL_CMD_GETVERSION;
+ (gpphDnldContext->tUserData.pBuff) = NULL;
+ (gpphDnldContext->tUserData.wLen) = 0;
+ (gpphDnldContext->UserCb) = pNotify;
+ (gpphDnldContext->UserCtxt) = pContext;
+
+ wStatus = phDnldNfc_CmdHandler(gpphDnldContext,phDnldNfc_EventGetVer);
+
+ if(NFCSTATUS_PENDING == wStatus)
+ {
+ NXPLOG_FWDNLD_D("GetVersion Request submitted successfully");
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("GetVersion Request Failed!!");
+ }
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+ }
+ }
+ }
+
+ return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function phDnldNfc_GetSessionState
+**
+** Description Retrieves the current session state of NFCC
+**
+** Parameters pSession - response buffer which gets updated with complete version info from NFCC
+** pNotify - notify caller after getting response
+** pContext - caller context
+**
+** Returns NFC status:
+** NFCSTATUS_SUCCESS - GetSessionState request to NFCC is successful
+** NFCSTATUS_FAILED - GetSessionState request failed due to internal error
+** NFCSTATUS_NOT_ALLOWED - command not allowed
+** Other command specific errors -
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_GetSessionState(pphDnldNfc_Buff_t pSession, pphDnldNfc_RspCb_t pNotify, void *pContext)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+
+ if((NULL == pSession) || (NULL == pNotify) ||
+ (NULL == pContext)
+ )
+ {
+ NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+ }
+ else
+ {
+ if(phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress)
+ {
+ NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
+ }
+ else
+ {
+ if((NULL != pSession->pBuff) && (0 != pSession->wLen))
+ {
+ (gpphDnldContext->tRspBuffInfo.pBuff) = pSession->pBuff;
+ (gpphDnldContext->tRspBuffInfo.wLen) = pSession->wLen;
+ (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTNone;
+ (gpphDnldContext->tCmdId) = PH_DL_CMD_GETSESSIONSTATE;
+ (gpphDnldContext->tUserData.pBuff) = NULL;
+ (gpphDnldContext->tUserData.wLen) = 0;
+ (gpphDnldContext->UserCb) = pNotify;
+ (gpphDnldContext->UserCtxt) = pContext;
+
+ wStatus = phDnldNfc_CmdHandler(gpphDnldContext,phDnldNfc_EventGetSesnSt);
+
+ if(NFCSTATUS_PENDING == wStatus)
+ {
+ NXPLOG_FWDNLD_D("GetSessionState Request submitted successfully");
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("GetSessionState Request Failed!!");
+ }
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+ }
+ }
+ }
+
+ return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function phDnldNfc_CheckIntegrity
+**
+** Description Inspects the integrity of EEPROM and FLASH contents of the NFCC,
+** provides CRC for each section
+** NOTE: The user data section CRC is valid only after fresh download
+**
+** Parameters bChipVer - current ChipVersion for including additional parameters in request payload
+** pCRCData - response buffer which gets updated with respective section CRC status
+** and CRC bytes from NFCC
+** pNotify - notify caller after getting response
+** pContext - caller context
+**
+** Returns NFC status:
+** NFCSTATUS_SUCCESS - CheckIntegrity request is successful
+** NFCSTATUS_FAILED - CheckIntegrity request failed due to internal error
+** NFCSTATUS_NOT_ALLOWED - command not allowed
+** Other command specific errors -
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_CheckIntegrity(uint8_t bChipVer, pphDnldNfc_Buff_t pCRCData, pphDnldNfc_RspCb_t pNotify, void *pContext)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+
+ if((NULL == pNotify) ||
+ (NULL == pContext)
+ )
+ {
+ NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+ }
+ else
+ {
+ if(phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress)
+ {
+ NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
+ }
+ else
+ {
+ if((PHDNLDNFC_HWVER_MRA2_1 == bChipVer) || (PHDNLDNFC_HWVER_MRA2_2 == bChipVer) ||
+ (PHDNLDNFC_HWVER_PN548AD_MRA1_0 == bChipVer))
+ {
+ (gpphDnldContext->FrameInp.Type) = phDnldNfc_ChkIntg;
+ }
+ else
+ {
+ (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTNone;
+ }
+
+ if((NULL != pCRCData->pBuff) && (0 != pCRCData->wLen))
+ {
+ (gpphDnldContext->tRspBuffInfo.pBuff) = pCRCData->pBuff;
+ (gpphDnldContext->tRspBuffInfo.wLen) = pCRCData->wLen;
+ (gpphDnldContext->tCmdId) = PH_DL_CMD_CHECKINTEGRITY;
+ (gpphDnldContext->tUserData.pBuff) = NULL;
+ (gpphDnldContext->tUserData.wLen) = 0;
+ (gpphDnldContext->UserCb) = pNotify;
+ (gpphDnldContext->UserCtxt) = pContext;
+
+ wStatus = phDnldNfc_CmdHandler(gpphDnldContext,phDnldNfc_EventIntegChk);
+
+ if(NFCSTATUS_PENDING == wStatus)
+ {
+ NXPLOG_FWDNLD_D("CheckIntegrity Request submitted successfully");
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("CheckIntegrity Request Failed!!");
+ }
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+ }
+ }
+ }
+
+ return wStatus;
+}
+/*******************************************************************************
+**
+** Function phDnldNfc_ReadLog
+**
+** Description Retrieves log data from EEPROM
+**
+** Parameters pData - response buffer which gets updated with data from EEPROM
+** pNotify - notify caller after getting response
+** pContext - caller context
+**
+** Returns NFC status:
+** NFCSTATUS_SUCCESS - Read request to NFCC is successful
+** NFCSTATUS_FAILED - Read request failed due to internal error
+** NFCSTATUS_NOT_ALLOWED - command not allowed
+** Other command specific errors -
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_ReadLog(pphDnldNfc_Buff_t pData, pphDnldNfc_RspCb_t pNotify, void *pContext)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+
+ if((NULL == pNotify) || (NULL == pData) ||
+ (NULL == pContext)
+ )
+ {
+ NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+ }
+ else
+ {
+ if(phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress)
+ {
+ NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
+ }
+ else
+ {
+ if((NULL != pData->pBuff) && (0 != pData->wLen))
+ {
+ (gpphDnldContext->tCmdId) = PH_DL_CMD_READ;
+ (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTRead;
+ (gpphDnldContext->FrameInp.dwAddr) = PHDNLDNFC_EEPROM_LOG_START_ADDR;
+ (gpphDnldContext->tRspBuffInfo.pBuff) = pData->pBuff;
+ (gpphDnldContext->tRspBuffInfo.wLen) = pData->wLen;
+ (gpphDnldContext->tUserData.pBuff) = NULL;
+ (gpphDnldContext->tUserData.wLen) = 0;
+ (gpphDnldContext->UserCb) = pNotify;
+ (gpphDnldContext->UserCtxt) = pContext;
+
+ memset(&(gpphDnldContext->tRWInfo),0,sizeof(gpphDnldContext->tRWInfo));
+
+ wStatus = phDnldNfc_CmdHandler(gpphDnldContext,phDnldNfc_EventRead);
+
+ if(NFCSTATUS_PENDING == wStatus)
+ {
+ NXPLOG_FWDNLD_D("Read Request submitted successfully");
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Read Request Failed!!");
+ }
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+ }
+ }
+ }
+
+ return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function phDnldNfc_Write
+**
+** Description Writes requested data of length len to desired EEPROM/FLASH address
+**
+** Parameters bRecoverSeq - flag to indicate whether recover sequence data needs to be written or not
+** pData - data buffer to write into EEPROM/FLASH by user
+** pNotify - notify caller after getting response
+** pContext - caller context
+**
+** Returns NFC status:
+** NFCSTATUS_SUCCESS - Write request to NFCC is successful
+** NFCSTATUS_FAILED - Write request failed due to internal error
+** NFCSTATUS_NOT_ALLOWED - command not allowed
+** Other command specific errors -
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_Write(bool_t bRecoverSeq, pphDnldNfc_Buff_t pData, pphDnldNfc_RspCb_t pNotify, void *pContext)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+ uint8_t *pImgPtr = NULL;
+ uint16_t wLen = 0;
+ phDnldNfc_Buff_t tImgBuff;
+
+ if((NULL == pNotify) || (NULL == pContext))
+ {
+ NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+ }
+ else
+ {
+ if(phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress)
+ {
+ NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
+ }
+ else
+ {
+ if(NULL != pData)
+ {
+ pImgPtr = pData->pBuff;
+ wLen = pData->wLen;
+ }
+ else
+ {
+ if(FALSE == bRecoverSeq)
+ {
+
+ pImgPtr = (uint8_t *)gpphDnldContext->nxp_nfc_fw;
+ wLen = gpphDnldContext->nxp_nfc_fw_len;
+
+ }
+ else
+ {
+ if(PH_DL_STATUS_PLL_ERROR == (gpphDnldContext->tLastStatus))
+ {
+ wStatus = phDnldNfc_LoadRecInfo();
+ }
+ else if(PH_DL_STATUS_SIGNATURE_ERROR == (gpphDnldContext->tLastStatus))
+ {
+ wStatus = phDnldNfc_LoadPKInfo();
+ }
+ else
+ {
+ }
+
+ if(NFCSTATUS_SUCCESS == wStatus)
+ {
+ pImgPtr = (uint8_t *)gpphDnldContext->nxp_nfc_fwp;
+ wLen = gpphDnldContext->nxp_nfc_fwp_len;
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Platform Recovery Image extraction Failed!!");
+ pImgPtr = NULL;
+ wLen = 0;
+ }
+ }
+ }
+
+ if((NULL != pImgPtr) && (0 != wLen))
+ {
+ tImgBuff.pBuff = pImgPtr;
+ tImgBuff.wLen = wLen;
+
+ (gpphDnldContext->tCmdId) = PH_DL_CMD_WRITE;
+ (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTWrite;
+ (gpphDnldContext->tRspBuffInfo.pBuff) = NULL;
+ (gpphDnldContext->tRspBuffInfo.wLen) = 0;
+ (gpphDnldContext->tUserData.pBuff) = pImgPtr;
+ (gpphDnldContext->tUserData.wLen) = wLen;
+ (gpphDnldContext->bResendLastFrame) = FALSE;
+
+ memset(&(gpphDnldContext->tRWInfo),0,sizeof(gpphDnldContext->tRWInfo));
+ (gpphDnldContext->tRWInfo.bFirstWrReq) = TRUE;
+ (gpphDnldContext->UserCb) = pNotify;
+ (gpphDnldContext->UserCtxt) = pContext;
+
+ wStatus = phDnldNfc_CmdHandler(gpphDnldContext,phDnldNfc_EventWrite);
+
+ if(NFCSTATUS_PENDING == wStatus)
+ {
+ NXPLOG_FWDNLD_D("Write Request submitted successfully");
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Write Request Failed!!");
+ }
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Download Image Primitives extraction failed!!");
+ wStatus = NFCSTATUS_FAILED;
+ }
+ }
+ }
+
+ return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function phDnldNfc_Log
+**
+** Description Provides a full page free write to EEPROM
+**
+** Parameters pData - data buffer to write into EEPROM/FLASH by user
+** pNotify - notify caller after getting response
+** pContext - caller context
+**
+** Returns NFC status:
+** NFCSTATUS_SUCCESS - Write request to NFCC is successful
+** NFCSTATUS_FAILED - Write request failed due to internal error
+** NFCSTATUS_NOT_ALLOWED - command not allowed
+** Other command specific errors -
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_Log(pphDnldNfc_Buff_t pData, pphDnldNfc_RspCb_t pNotify, void *pContext)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+
+ if((NULL == pNotify) || (NULL == pData) ||
+ (NULL == pContext)
+ )
+ {
+ NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+ }
+ else
+ {
+ if(phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress)
+ {
+ NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
+ }
+ else
+ {
+ if((NULL != (pData->pBuff)) && ((0 != (pData->wLen) && (PHDNLDNFC_MAX_LOG_SIZE >= (pData->wLen)))))
+ {
+ (gpphDnldContext->tCmdId) = PH_DL_CMD_LOG;
+ (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTLog;
+ (gpphDnldContext->tRspBuffInfo.pBuff) = NULL;
+ (gpphDnldContext->tRspBuffInfo.wLen) = 0;
+ (gpphDnldContext->tUserData.pBuff) = (pData->pBuff);
+ (gpphDnldContext->tUserData.wLen) = (pData->wLen);
+
+ memset(&(gpphDnldContext->tRWInfo),0,sizeof(gpphDnldContext->tRWInfo));
+ (gpphDnldContext->UserCb) = pNotify;
+ (gpphDnldContext->UserCtxt) = pContext;
+
+ wStatus = phDnldNfc_CmdHandler(gpphDnldContext,phDnldNfc_EventLog);
+
+ if(NFCSTATUS_PENDING == wStatus)
+ {
+ NXPLOG_FWDNLD_D("Log Request submitted successfully");
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Log Request Failed!!");
+ }
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Invalid Input Parameters for Log!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+ }
+ }
+ }
+
+ return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function phDnldNfc_Force
+**
+** Description Used as an emergency recovery procedure for NFCC due to corrupt
+** settings of system platform specific parameters by the host
+**
+** Parameters pInputs - input buffer which contains clk src & clk freq settings for desired platform
+** pNotify - notify caller after getting response
+** pContext - caller context
+**
+** Returns NFC status:
+** NFCSTATUS_SUCCESS - Emergency Recovery request is successful
+** NFCSTATUS_FAILED - Emergency Recovery failed due to internal error
+** NFCSTATUS_NOT_ALLOWED - command not allowed
+** Other command specific errors -
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_Force(pphDnldNfc_Buff_t pInputs, pphDnldNfc_RspCb_t pNotify, void *pContext)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+ uint8_t bClkSrc = 0x00,bClkFreq = 0x00;
+ uint8_t bPldVal[3] = {0x11,0x00,0x00}; /* default values to be used if input not provided */
+
+ if((NULL == pNotify) || (NULL == pContext))
+ {
+ NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+ }
+ else
+ {
+ if(phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress)
+ {
+ NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
+ }
+ else
+ {
+ (gpphDnldContext->tCmdId) = PH_DL_CMD_FORCE;
+ (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTForce;
+ (gpphDnldContext->tRspBuffInfo.pBuff) = NULL;
+ (gpphDnldContext->tRspBuffInfo.wLen) = 0;
+
+ if((0 != (pInputs->wLen)) || (NULL != (pInputs->pBuff)))
+ {
+ if(CLK_SRC_XTAL == (pInputs->pBuff[0]))
+ {
+ bClkSrc = phDnldNfc_ClkSrcXtal;
+ }
+ else if(CLK_SRC_PLL == (pInputs->pBuff[0]))
+ {
+ bClkSrc = phDnldNfc_ClkSrcPLL;
+ if(CLK_FREQ_13MHZ == (pInputs->pBuff[1]))
+ {
+ bClkFreq = phDnldNfc_ClkFreq_13Mhz;
+ }
+ else if(CLK_FREQ_19_2MHZ == (pInputs->pBuff[1]))
+ {
+ bClkFreq = phDnldNfc_ClkFreq_19_2Mhz;
+ }
+ else if(CLK_FREQ_24MHZ == (pInputs->pBuff[1]))
+ {
+ bClkFreq = phDnldNfc_ClkFreq_24Mhz;
+ }
+ else if(CLK_FREQ_26MHZ == (pInputs->pBuff[1]))
+ {
+ bClkFreq = phDnldNfc_ClkFreq_26Mhz;
+ }
+ else if(CLK_FREQ_38_4MHZ == (pInputs->pBuff[1]))
+ {
+ bClkFreq = phDnldNfc_ClkFreq_38_4Mhz;
+ }
+ else if(CLK_FREQ_52MHZ == (pInputs->pBuff[1]))
+ {
+ bClkFreq = phDnldNfc_ClkFreq_52Mhz;
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Invalid Clk Frequency !! Using default value of 19.2Mhz..");
+ bClkFreq = phDnldNfc_ClkFreq_19_2Mhz;
+ }
+
+ }
+ else if(CLK_SRC_PADDIRECT == (pInputs->pBuff[0]))
+ {
+ bClkSrc = phDnldNfc_ClkSrcPad;
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Invalid Clk src !! Using default value of PLL..");
+ bClkSrc = phDnldNfc_ClkSrcPLL;
+ }
+
+ bPldVal[0] = 0U;
+ bPldVal[0] = ((bClkSrc << 3U) | bClkFreq);
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Clk src inputs not provided!! Using default values..");
+ }
+
+ (gpphDnldContext->tUserData.pBuff) = bPldVal;
+ (gpphDnldContext->tUserData.wLen) = sizeof(bPldVal);
+
+ memset(&(gpphDnldContext->tRWInfo),0,sizeof(gpphDnldContext->tRWInfo));
+ (gpphDnldContext->UserCb) = pNotify;
+ (gpphDnldContext->UserCtxt) = pContext;
+
+ wStatus = phDnldNfc_CmdHandler(gpphDnldContext,phDnldNfc_EventForce);
+
+ if(NFCSTATUS_PENDING == wStatus)
+ {
+ NXPLOG_FWDNLD_D("Force Command Request submitted successfully");
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Force Command Request Failed!!");
+ }
+ }
+ }
+
+ return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function phDnldNfc_SetHwDevHandle
+**
+** Description Stores the HwDev handle to download context. The handle is required for subsequent operations
+**
+** Parameters None
+**
+** Returns None -
+**
+*******************************************************************************/
+void phDnldNfc_SetHwDevHandle(void)
+{
+ pphDnldNfc_DlContext_t psDnldContext = NULL;
+
+ if(NULL == gpphDnldContext)
+ {
+ NXPLOG_FWDNLD_D("Allocating Mem for Dnld Context..");
+ /* Create the memory for Download Mgmt Context */
+ psDnldContext = (pphDnldNfc_DlContext_t)
+ malloc(sizeof(phDnldNfc_DlContext_t));
+
+ if(psDnldContext != NULL)
+ {
+ (void ) memset((void *)psDnldContext,0,
+ sizeof(phDnldNfc_DlContext_t));
+ gpphDnldContext = psDnldContext;
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Error Allocating Mem for Dnld Context..")
+ }
+ }
+ else
+ {
+ (void ) memset((void *)gpphDnldContext,0,
+ sizeof(phDnldNfc_DlContext_t));
+ }
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phDnldNfc_ReSetHwDevHandle
+**
+** Description Frees the HwDev handle to download context.
+**
+** Parameters None
+**
+** Returns None -
+**
+*******************************************************************************/
+void phDnldNfc_ReSetHwDevHandle(void)
+{
+ if (gpphDnldContext != NULL)
+ {
+ NXPLOG_FWDNLD_E("Freeing Mem for Dnld Context..")
+ free(gpphDnldContext);
+ gpphDnldContext = NULL;
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function phDnldNfc_RawReq
+**
+** Description Sends raw frame request to NFCC.
+** It is currently used for sending an NCI RESET cmd after doing a production key update
+**
+** Parameters pFrameData - input buffer, contains raw frame packet to be sent to NFCC
+** pRspData - response buffer received from NFCC
+** pNotify - notify caller after getting response
+** pContext - caller context
+**
+** Returns NFC status:
+** NFCSTATUS_SUCCESS - GetSessionState request to NFCC is successful
+** NFCSTATUS_FAILED - GetSessionState request failed due to internal error
+** NFCSTATUS_NOT_ALLOWED - command not allowed
+** Other command specific errors -
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_RawReq(pphDnldNfc_Buff_t pFrameData, pphDnldNfc_Buff_t pRspData, pphDnldNfc_RspCb_t pNotify, void *pContext)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+
+ if((NULL == pFrameData) || (NULL == pNotify) || (NULL == pRspData) ||
+ (NULL == pContext)
+ )
+ {
+ NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+ }
+ else
+ {
+ if(phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress)
+ {
+ NXPLOG_FWDNLD_E("Raw Cmd Request in Progress..Cannot Continue!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
+ }
+ else
+ {
+ if(((NULL != pFrameData->pBuff) && (0 != pFrameData->wLen)) &&
+ ((NULL != pRspData->pBuff) && (0 != pRspData->wLen))
+ )
+ {
+ (gpphDnldContext->tRspBuffInfo.pBuff) = pRspData->pBuff;
+ (gpphDnldContext->tRspBuffInfo.wLen) = pRspData->wLen;
+ (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTRaw;
+ (gpphDnldContext->tCmdId) = PH_DL_CMD_NONE;
+ (gpphDnldContext->tUserData.pBuff) = pFrameData->pBuff;
+ (gpphDnldContext->tUserData.wLen) = pFrameData->wLen;
+ (gpphDnldContext->UserCb) = pNotify;
+ (gpphDnldContext->UserCtxt) = pContext;
+
+ wStatus = phDnldNfc_CmdHandler(gpphDnldContext,phDnldNfc_EventRaw);
+
+ if(NFCSTATUS_PENDING == wStatus)
+ {
+ NXPLOG_FWDNLD_D("RawFrame Request submitted successfully");
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("RawFrame Request Failed!!");
+ }
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+ }
+ }
+ }
+
+ return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function phDnldNfc_InitImgInfo
+**
+** Description Extracts image information and stores it in respective variables,
+** to be used internally for write operation
+**
+** Parameters None
+**
+** Returns NFC status
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_InitImgInfo(void)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+ uint8_t *pImageInfo = NULL;
+ uint16_t ImageInfoLen = 0;
+ 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, fwFileName, sizeof(fwFileName)) == TRUE)
+ {
+ strcpy(fwpathName, FW_DLL_ROOT_DIR);
+ strncat(fwpathName, fwFileName, strlen(fwFileName));
+ pathName = fwpathName;
+ }
+
+ /* load the library and get the image info pointer */
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+ if(gRecFWDwnld == TRUE)
+ wStatus = phDnldNfc_LoadRecoveryFW(pathName, &pImageInfo, &ImageInfoLen);
+ else
+#endif
+ wStatus = phDnldNfc_LoadFW(pathName, &pImageInfo, &ImageInfoLen);
+
+ NXPLOG_FWDNLD_D("FW Image Length - ImageInfoLen %d",ImageInfoLen);
+ NXPLOG_FWDNLD_D("FW Image Info Pointer - pImageInfo %x",(uintptr_t)pImageInfo);
+
+ if((pImageInfo == NULL) || (ImageInfoLen == 0))
+ {
+ NXPLOG_FWDNLD_E("Image extraction Failed - invalid imginfo or imginfolen!!");
+ wStatus = NFCSTATUS_FAILED;
+ }
+
+ if (wStatus != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_FWDNLD_E("Error loading libpn54x_fw !!\n");
+ }
+
+ /* get the MW version */
+ if(NFCSTATUS_SUCCESS == wStatus)
+ {
+ //NXPLOG_FWDNLD_D("MW Major Version Num - %x",NXP_MW_VERSION_MAJ);
+ //NXPLOG_FWDNLD_D("MW Minor Version Num - %x",NXP_MW_VERSION_MIN);
+ wMwVer = (((uint16_t)(NXP_MW_VERSION_MAJ) << 8U) | (NXP_MW_VERSION_MIN));
+ }
+
+ if(NFCSTATUS_SUCCESS == wStatus)
+ {
+ gpphDnldContext->nxp_nfc_fw = (uint8_t*)pImageInfo;
+ gpphDnldContext->nxp_nfc_fw_len = ImageInfoLen;
+ if((NULL != gpphDnldContext->nxp_nfc_fw) && (0 != gpphDnldContext->nxp_nfc_fw_len))
+ {
+ NXPLOG_FWDNLD_D("FW Major Version Num - %x",gpphDnldContext->nxp_nfc_fw[5]);
+ NXPLOG_FWDNLD_D("FW Minor Version Num - %x",gpphDnldContext->nxp_nfc_fw[4]);
+ NXPLOG_FWDNLD_D("FW Image Length - %d",ImageInfoLen);
+ NXPLOG_FWDNLD_D("FW Image Info Pointer - %x",(uintptr_t)pImageInfo);
+
+ /* get the FW version */
+ wFwVer = (((uint16_t)(gpphDnldContext->nxp_nfc_fw[5]) << 8U) | (gpphDnldContext->nxp_nfc_fw[4]));
+ wStatus = NFCSTATUS_SUCCESS;
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Image details extraction Failed!!");
+ wStatus = NFCSTATUS_FAILED;
+ }
+ }
+
+ return wStatus;
+}
+
+
+/*******************************************************************************
+**
+** Function phDnldNfc_LoadRecInfo
+**
+** Description Extracts recovery sequence image information and stores it
+** in respective variables, to be used internally for write operation
+**
+** Parameters None
+**
+** Returns NFC status
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_LoadRecInfo(void)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+ uint8_t *pImageInfo = NULL;
+ uint16_t ImageInfoLen = 0;
+
+ /* if memory is not allocated then allocate memory for donwload context structure */
+ phDnldNfc_SetHwDevHandle();
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+ if(gRecFWDwnld == TRUE)
+ wStatus = phDnldNfc_LoadRecoveryFW(PLATFORM_LIB_PATH, &pImageInfo, &ImageInfoLen);
+ else
+#endif
+ wStatus = phDnldNfc_LoadFW(PLATFORM_LIB_PATH, &pImageInfo, &ImageInfoLen);
+ if((pImageInfo == NULL) || (ImageInfoLen == 0))
+ {
+ NXPLOG_FWDNLD_E("Image extraction Failed - invalid imginfo or imginfolen!!");
+ wStatus = NFCSTATUS_FAILED;
+ }
+
+ /* load the PLL recovery image library */
+ if (wStatus != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_FWDNLD_E("Error loading libpn54x_fw_platform !!\n");
+ }
+
+ if(NFCSTATUS_SUCCESS == wStatus)
+ {
+ /* fetch the PLL recovery image pointer and the image length */
+ gpphDnldContext->nxp_nfc_fwp = (uint8_t*)pImageInfo;
+ gpphDnldContext->nxp_nfc_fwp_len = ImageInfoLen;
+ if((NULL != gpphDnldContext->nxp_nfc_fwp) && (0 != gpphDnldContext->nxp_nfc_fwp_len))
+ {
+ NXPLOG_FWDNLD_D("Recovery Image Length - %d",ImageInfoLen);
+ NXPLOG_FWDNLD_D("Recovery Image Info Pointer - %x",(uintptr_t)pImageInfo);
+ wStatus = NFCSTATUS_SUCCESS;
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Recovery Image details extraction Failed!!");
+ wStatus = NFCSTATUS_FAILED;
+ }
+ }
+
+ return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function phDnldNfc_LoadPKInfo
+**
+** Description Extracts production sequence image information and stores it
+** in respective variables, to be used internally for write operation
+**
+** Parameters None
+**
+** Returns NFC status
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_LoadPKInfo(void)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+ uint8_t *pImageInfo = NULL;
+ uint16_t ImageInfoLen = 0;
+
+ /* if memory is not allocated then allocate memory for donwload context structure */
+ phDnldNfc_SetHwDevHandle();
+
+ /* load the PKU image library */
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+ if(gRecFWDwnld == TRUE)
+ wStatus = phDnldNfc_LoadRecoveryFW(PKU_LIB_PATH, &pImageInfo, &ImageInfoLen);
+ else
+#endif
+ wStatus = phDnldNfc_LoadFW(PKU_LIB_PATH, &pImageInfo, &ImageInfoLen);
+ if((pImageInfo == NULL) || (ImageInfoLen == 0))
+ {
+ NXPLOG_FWDNLD_E("Image extraction Failed - invalid imginfo or imginfolen!!");
+ wStatus = NFCSTATUS_FAILED;
+ }
+
+ if (wStatus != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_FWDNLD_E("Error loading libpn54x_fw_pku !!\n");
+ }
+
+ if(NFCSTATUS_SUCCESS == wStatus)
+ {
+ /* fetch the PKU image pointer and the image length */
+ gpphDnldContext->nxp_nfc_fwp = (uint8_t*)pImageInfo;
+ gpphDnldContext->nxp_nfc_fwp_len = ImageInfoLen;
+
+ if((NULL != gpphDnldContext->nxp_nfc_fwp) && (0 != gpphDnldContext->nxp_nfc_fwp_len))
+ {
+ NXPLOG_FWDNLD_D("PKU Image Length - %d",ImageInfoLen);
+ NXPLOG_FWDNLD_D("PKU Image Info Pointer - %x",(uintptr_t)pImageInfo);
+ wStatus = NFCSTATUS_SUCCESS;
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("PKU Image details extraction Failed!!");
+ wStatus = NFCSTATUS_FAILED;
+ }
+ }
+
+ return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function phDnldNfc_CloseFwLibHandle
+**
+** Description Closes previously opened fw library handle as part of
+** dynamic loader processing
+**
+** Parameters None
+**
+** Returns None
+**
+*******************************************************************************/
+void phDnldNfc_CloseFwLibHandle(void)
+{
+ NFCSTATUS wStatus;
+
+ wStatus = phDnldNfc_UnloadFW();
+ if(wStatus != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_FWDNLD_E("free library FAILED !!\n");
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("free library SUCCESS !!\n");
+ }
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phDnldNfc_LoadFW
+**
+** Description Load the firmware version form firmware lib
+**
+** Parameters pathName - Firmware image path
+** pImgInfo - Firmware image handle
+** pImgInfoLen - Firmware image length
+**
+** Returns NFC status
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_LoadFW(const char* pathName, uint8_t **pImgInfo, uint16_t* pImgInfoLen)
+{
+ void* pImageInfo = NULL;
+ void* pImageInfoLen = NULL;
+
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ /* check for path name */
+ if(pathName == NULL)
+ {
+ pathName = "/system/vendor/firmware/libpn548ad_fw.so";
+ }
+#else
+ if(pathName == NULL)
+ {
+ pathName = "/system/vendor/firmware/libpn547_fw.so";
+ }
+#endif
+
+ /* check if the handle is not NULL then free the library */
+ if(pFwLibHandle != NULL)
+ {
+ phDnldNfc_UnloadFW();
+ pFwLibHandle = NULL;
+ }
+
+ /* load the DLL file */
+ pFwLibHandle = dlopen(pathName, RTLD_LAZY);
+ NXPLOG_FWDNLD_D ("@@@%s", pathName);
+
+ /* if library load failed then handle will be NULL */
+ if(pFwLibHandle == NULL)
+ {
+ NXPLOG_FWDNLD_E("NULL handler : unable to load the library file, specify correct path");
+ return NFCSTATUS_FAILED;
+ }
+
+ dlerror(); /* Clear any existing error */
+
+ /* load the address of download image pointer and image size */
+ pImageInfo = (void*)dlsym(pFwLibHandle,"gphDnldNfc_DlSeq");
+
+ if(dlerror()|| (NULL == pImageInfo))
+ {
+ NXPLOG_FWDNLD_E("Problem loading symbol : gphDnldNfc_DlSeq");
+ return NFCSTATUS_FAILED;
+ }
+ (*pImgInfo) = (*(uint8_t**)pImageInfo);
+
+ pImageInfoLen = (void*)dlsym(pFwLibHandle,"gphDnldNfc_DlSeqSz");
+ if(dlerror() || (NULL == pImageInfoLen))
+ {
+ NXPLOG_FWDNLD_E("Problem loading symbol : gphDnldNfc_DlSeqSz");
+ return NFCSTATUS_FAILED;
+ }
+
+ (*pImgInfoLen) = (uint16_t)(*((uint16_t*)pImageInfoLen));
+
+ return NFCSTATUS_SUCCESS;
+}
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+/*******************************************************************************
+**
+** 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 NFC
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_LoadRecoveryFW(const char* pathName, uint8_t **pImgInfo, uint16_t* pImgInfoLen)
+{
+ void* pImageInfo = NULL;
+ void* pImageInfoLen = NULL;
+
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+ /* check for path name */
+ if(pathName == NULL)
+ {
+ pathName = "/system/vendor/firmware/libpn548ad_fw.so";
+ }
+#else
+ if(pathName == NULL)
+ {
+ pathName = "/system/vendor/firmware/libpn547_fw.so";
+ }
+#endif
+ /* check if the handle is not NULL then free the library */
+ if(pFwLibHandle != NULL)
+ {
+ phDnldNfc_UnloadFW();
+ pFwLibHandle = NULL;
+ }
+ /* load the DLL file */
+ pFwLibHandle = dlopen(pathName, RTLD_LAZY);
+ NXPLOG_FWDNLD_D ("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;
+}
+#endif
+/*******************************************************************************
+**
+** 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..10aeed1
--- /dev/null
+++ b/halimpl/pn54x/dnld/phDnldNfc.h
@@ -0,0 +1,111 @@
+/*
+ * 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 */
+
+#define PHDNLDNFC_HWVER_PN548AD_MRA1_0 (0x08U) /* PN548AD ChipVersion MRA1.0 */
+/*
+ * Enum definition contains Download Life Cycle States
+ */
+typedef enum phDnldNfc_LC{
+ phDnldNfc_LCCreat = 11, /* Life Cycle Creation*/
+ phDnldNfc_LCInit = 13, /* Life Cycle Initializing */
+ phDnldNfc_LCOper = 17, /* Life Cycle Operational */
+ phDnldNfc_LCTerm = 19 /* Life Cycle Termination */
+}phDnldNfc_LC_t;
+
+/*
+ * Enum definition contains Clk Source Options for Force command request
+ */
+typedef enum phDnldNfc_ClkSrc{
+ phDnldNfc_ClkSrcXtal = 1U, /* Crystal */
+ phDnldNfc_ClkSrcPLL = 2U, /* PLL output */
+ phDnldNfc_ClkSrcPad = 3U /* Directly use clk on CLK_IN Pad */
+}phDnldNfc_ClkSrc_t;
+
+/*
+ * Enum definition contains Clk Frequency value for Force command request
+ */
+typedef enum phDnldNfc_ClkFreq{
+ phDnldNfc_ClkFreq_13Mhz = 0U, /* 13Mhz Clk Frequency */
+ phDnldNfc_ClkFreq_19_2Mhz = 1U, /* 19.2Mhz Clk Frequency */
+ phDnldNfc_ClkFreq_24Mhz = 2U, /* 24Mhz Clk Frequency */
+ phDnldNfc_ClkFreq_26Mhz = 3U, /* 26Mhz Clk Frequency */
+ phDnldNfc_ClkFreq_38_4Mhz = 4U, /* 38.4Mhz Clk Frequency */
+ phDnldNfc_ClkFreq_52Mhz = 5U /* 52Mhz Clk Frequency */
+}phDnldNfc_ClkFreq_t;
+
+/*
+ * Struct contains buffer where user payload shall be stored
+ */
+typedef struct phDnldNfc_Buff
+{
+ uint8_t *pBuff; /*pointer to the buffer where user payload shall be stored*/
+ uint16_t wLen; /*Buffer length*/
+}phDnldNfc_Buff_t, *pphDnldNfc_Buff_t; /* pointer to #phDnldNfc_Buff_t */
+
+/*
+*********************** Function Prototype Declaration *************************
+*/
+
+extern NFCSTATUS phDnldNfc_Reset(pphDnldNfc_RspCb_t pNotify, void *pContext);
+extern NFCSTATUS phDnldNfc_GetVersion(pphDnldNfc_Buff_t pVersionInfo, pphDnldNfc_RspCb_t pNotify, void *pContext);
+extern NFCSTATUS phDnldNfc_CheckIntegrity(uint8_t bChipVer, pphDnldNfc_Buff_t pCRCData, pphDnldNfc_RspCb_t pNotify, void *pContext);
+extern NFCSTATUS phDnldNfc_GetSessionState(pphDnldNfc_Buff_t pSession, pphDnldNfc_RspCb_t pNotify, void *pContext);
+extern NFCSTATUS phDnldNfc_Force(pphDnldNfc_Buff_t pInputs, pphDnldNfc_RspCb_t pNotify,void *pContext);
+extern NFCSTATUS phDnldNfc_Read(pphDnldNfc_Buff_t pData, uint32_t dwRdAddr, pphDnldNfc_RspCb_t pNotify, void *pContext);
+extern NFCSTATUS phDnldNfc_ReadLog(pphDnldNfc_Buff_t pData, pphDnldNfc_RspCb_t pNotify, void *pContext);
+extern NFCSTATUS phDnldNfc_Write(bool_t bRecoverSeq, pphDnldNfc_Buff_t pData, pphDnldNfc_RspCb_t pNotify, void *pContext);
+extern NFCSTATUS phDnldNfc_Log(pphDnldNfc_Buff_t pData, pphDnldNfc_RspCb_t pNotify, void *pContext);
+extern void phDnldNfc_SetHwDevHandle(void);
+void phDnldNfc_ReSetHwDevHandle(void);
+extern NFCSTATUS phDnldNfc_ReadMem(void *pHwRef, pphDnldNfc_RspCb_t pNotify, void *pContext);
+extern NFCSTATUS phDnldNfc_RawReq(pphDnldNfc_Buff_t pFrameData, pphDnldNfc_Buff_t pRspData, pphDnldNfc_RspCb_t pNotify, void *pContext);
+extern NFCSTATUS phDnldNfc_InitImgInfo(void);
+extern NFCSTATUS phDnldNfc_LoadRecInfo(void);
+extern NFCSTATUS phDnldNfc_LoadPKInfo(void);
+extern void phDnldNfc_CloseFwLibHandle(void);
+extern NFCSTATUS phDnldNfc_LoadFW(const char* pathName, uint8_t **pImgInfo, uint16_t* pImgInfoLen);
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+extern NFCSTATUS phDnldNfc_LoadRecoveryFW(const char* pathName, uint8_t **pImgInfo, uint16_t* pImgInfoLen);
+#endif
+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..b489f06
--- /dev/null
+++ b/halimpl/pn54x/dnld/phDnldNfc_Cmd.h
@@ -0,0 +1,42 @@
+/*
+ * 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..3b18ad3
--- /dev/null
+++ b/halimpl/pn54x/dnld/phDnldNfc_Internal.c
@@ -0,0 +1,1326 @@
+/*
+ * 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>
+
+#define PHDNLDNFC_MIN_PLD_LEN (0x04U) /* Minimum length of payload including 1 byte CmdId */
+
+#define PHDNLDNFC_FRAME_HDR_OFFSET (0x00) /* Offset of Length byte within the frame */
+#define PHDNLDNFC_FRAMEID_OFFSET (PHDNLDNFC_FRAME_HDR_LEN) /* Offset of FrameId within the frame */
+#define PHDNLDNFC_FRAMESTATUS_OFFSET PHDNLDNFC_FRAMEID_OFFSET /* Offset of status byte within the frame */
+#define PHDNLDNFC_PLD_OFFSET (PHDNLDNFC_MIN_PLD_LEN - 1) /* Offset within frame where payload starts*/
+
+#define PHDNLDNFC_FRAME_RDDATA_OFFSET ((PHDNLDNFC_FRAME_HDR_LEN) + \
+ (PHDNLDNFC_MIN_PLD_LEN)) /* recvd frame offset where data starts */
+
+#define PHDNLDNFC_FRAME_SIGNATURE_SIZE (0xC0U) /* Size of first secure write frame Signature */
+#define PHDNLDNFC_FIRST_FRAME_PLD_SIZE (0xE4U) /* Size of first secure write frame payload */
+
+#define PHDNLDNFC_FIRST_FRAGFRAME_RESP (0x2DU) /* Status response for first fragmented write frame */
+#define PHDNLDNFC_NEXT_FRAGFRAME_RESP (0x2EU) /* Status response for subsequent fragmented write frame */
+
+#define PHDNLDNFC_SET_HDR_FRAGBIT(n) ((n) | (1<<10)) /* Header chunk bit set macro */
+#define PHDNLDNFC_CLR_HDR_FRAGBIT(n) ((n) & ~(1U<<10)) /* Header chunk bit clear macro */
+#define PHDNLDNFC_CHK_HDR_FRAGBIT(n) ((n) & 0x04) /* macro to check if frag bit is set in Hdr */
+
+#define PHDNLDNFC_RSP_TIMEOUT (2500) /* Timeout value to wait for response from NFCC */
+#define PHDNLDNFC_RETRY_FRAME_WRITE (50) /* Timeout value to wait before resending the last frame */
+
+#define PHDNLDNFC_USERDATA_EEPROM_LENSIZE (0x02U) /* size of EEPROM user data length */
+#define PHDNLDNFC_USERDATA_EEPROM_OFFSIZE (0x02U) /* size of EEPROM offset */
+
+#ifdef NXP_PN547C1_DOWNLOAD
+/* EEPROM offset and length value for C1 */
+#define PHDNLDNFC_USERDATA_EEPROM_OFFSET (0x003CU) /* 16 bits offset indicating user data area start location */
+#define PHDNLDNFC_USERDATA_EEPROM_LEN (0x0DC0U) /* 16 bits length of user data area */
+#else
+
+#if(NFC_NXP_CHIP_TYPE == PN547C2)
+/* EEPROM offset and length value for C2 */
+#define PHDNLDNFC_USERDATA_EEPROM_OFFSET (0x023CU) /* 16 bits offset indicating user data area start location */
+#define PHDNLDNFC_USERDATA_EEPROM_LEN (0x0C80U) /* 16 bits length of user data area */
+#else
+/* EEPROM offset and length value for PN548AD */
+#define PHDNLDNFC_USERDATA_EEPROM_OFFSET (0x02BCU) /* 16 bits offset indicating user data area start location */
+#define PHDNLDNFC_USERDATA_EEPROM_LEN (0x0C00U) /* 16 bits length of user data area */
+#endif
+
+#endif
+#define PH_LIBNFC_VEN_RESET_ON_DOWNLOAD_TIMEOUT (1)
+
+/* Function prototype declarations */
+static void phDnldNfc_ProcessSeqState(void *pContext, phTmlNfc_TransactInfo_t *pInfo);
+static void phDnldNfc_ProcessRWSeqState(void *pContext, phTmlNfc_TransactInfo_t *pInfo);
+static NFCSTATUS phDnldNfc_ProcessFrame(void *pContext, phTmlNfc_TransactInfo_t *pInfo);
+static NFCSTATUS phDnldNfc_ProcessRecvInfo(void *pContext, phTmlNfc_TransactInfo_t *pInfo);
+static NFCSTATUS phDnldNfc_BuildFramePkt(pphDnldNfc_DlContext_t pDlContext);
+static NFCSTATUS phDnldNfc_CreateFramePld(pphDnldNfc_DlContext_t pDlContext);
+static NFCSTATUS phDnldNfc_SetupResendTimer(pphDnldNfc_DlContext_t pDlContext);
+static NFCSTATUS phDnldNfc_UpdateRsp(pphDnldNfc_DlContext_t pDlContext, phTmlNfc_TransactInfo_t *pInfo, uint16_t wPldLen);
+static void phDnldNfc_RspTimeOutCb(uint32_t TimerId, void *pContext);
+static void phDnldNfc_ResendTimeOutCb(uint32_t TimerId, void *pContext);
+
+/*
+*************************** Function Definitions ***************************
+*/
+
+/*******************************************************************************
+**
+** Function phDnldNfc_CmdHandler
+**
+** Description Download Command Handler Mechanism
+** - holds the sub states for each command processing
+** - coordinates with TML download thread to complete a download command request
+** - calls the user callback on completion of a cmd
+**
+** Parameters pContext - pointer to the download context structure
+** TrigEvent - event requested by user
+**
+** Returns NFC status:
+** NFCSTATUS_PENDING - download request sent to NFCC successfully,response pending
+** NFCSTATUS_BUSY - handler is busy processing a download request
+** NFCSTATUS_INVALID_PARAMETER - one or more of the supplied parameters could not be interpreted properly
+** Other errors -
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_CmdHandler(void *pContext, phDnldNfc_Event_t TrigEvent)
+{
+ NFCSTATUS status = NFCSTATUS_SUCCESS;
+ pphDnldNfc_DlContext_t pDlCtxt = (pphDnldNfc_DlContext_t)pContext;
+
+ if(NULL == pDlCtxt)
+ {
+ NXPLOG_FWDNLD_E("Invalid Input Parameter!!");
+ status = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
+ }
+ else
+ {
+ switch(TrigEvent)
+ {
+ case phDnldNfc_EventReset:
+ case phDnldNfc_EventGetVer:
+ case phDnldNfc_EventIntegChk:
+ case phDnldNfc_EventGetSesnSt:
+ case phDnldNfc_EventRaw:
+ {
+ if(phDnldNfc_EventInvalid == (pDlCtxt->tCurrEvent))
+ {
+ NXPLOG_FWDNLD_D("Processing Normal Sequence..");
+ pDlCtxt->tCurrEvent = TrigEvent;
+ pDlCtxt->tDnldInProgress = phDnldNfc_TransitionBusy;
+
+ phDnldNfc_ProcessSeqState(pDlCtxt,NULL);
+
+ status = pDlCtxt->wCmdSendStatus;
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Prev Norml Sequence not completed/restored!!");
+ status = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_FAILED);
+ }
+ break;
+ }
+ case phDnldNfc_EventWrite:
+ case phDnldNfc_EventRead:
+ case phDnldNfc_EventLog:
+ case phDnldNfc_EventForce:
+ {
+ if(phDnldNfc_EventInvalid == (pDlCtxt->tCurrEvent))
+ {
+ NXPLOG_FWDNLD_D("Processing R/W Sequence..");
+ pDlCtxt->tCurrEvent = TrigEvent;
+ pDlCtxt->tDnldInProgress = phDnldNfc_TransitionBusy;
+
+ phDnldNfc_ProcessRWSeqState(pDlCtxt,NULL);
+
+ status = pDlCtxt->wCmdSendStatus;
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Prev R/W Sequence not completed/restored!!");
+ status = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_FAILED);
+ }
+ break;
+ }
+ default:
+ {
+ /* Unknown Event */
+ NXPLOG_FWDNLD_E("Unknown Event Parameter!!");
+ status = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
+ break;
+ }
+ }
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function phDnldNfc_ProcessSeqState
+**
+** Description Processes all cmd/resp sequences except read & write
+**
+** Parameters pContext - pointer to the download context structure
+** pInfo - pointer to the Transaction buffer updated by TML Thread
+**
+** Returns None
+**
+*******************************************************************************/
+static void phDnldNfc_ProcessSeqState(void *pContext, phTmlNfc_TransactInfo_t *pInfo)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+ NFCSTATUS wIntStatus;
+ uint32_t TimerId;
+ pphDnldNfc_DlContext_t pDlCtxt = (pphDnldNfc_DlContext_t)pContext;
+
+ if(NULL == pDlCtxt)
+ {
+ NXPLOG_FWDNLD_E("Invalid Input Parameter!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
+ }
+ else
+ {
+ switch(pDlCtxt->tCurrState)
+ {
+ case phDnldNfc_StateInit:
+ {
+ NXPLOG_FWDNLD_D("Initializing Sequence..");
+
+ if(0 == (pDlCtxt->TimerInfo.dwRspTimerId))
+ {
+ TimerId = phOsalNfc_Timer_Create();
+
+ if (0 == TimerId)
+ {
+ NXPLOG_FWDNLD_W("Response Timer Create failed!!");
+ wStatus = NFCSTATUS_INSUFFICIENT_RESOURCES;
+ pDlCtxt->wCmdSendStatus = wStatus;
+ break;
+ }
+ else
+ {
+ NXPLOG_FWDNLD_D("Response Timer Created Successfully");
+ (pDlCtxt->TimerInfo.dwRspTimerId) = TimerId;
+ (pDlCtxt->TimerInfo.TimerStatus) = 0;
+ (pDlCtxt->TimerInfo.wTimerExpStatus) = 0;
+ }
+ }
+ pDlCtxt->tCurrState = phDnldNfc_StateSend;
+ }
+ case phDnldNfc_StateSend:
+ {
+ wStatus = phDnldNfc_BuildFramePkt(pDlCtxt);
+
+ if(NFCSTATUS_SUCCESS == wStatus)
+ {
+ pDlCtxt->tCurrState = phDnldNfc_StateRecv;
+
+ wStatus = phTmlNfc_Write( (pDlCtxt->tCmdRspFrameInfo.aFrameBuff),
+ (uint16_t)(pDlCtxt->tCmdRspFrameInfo.dwSendlength),
+ (pphTmlNfc_TransactCompletionCb_t)&phDnldNfc_ProcessSeqState,
+ pDlCtxt);
+ }
+ pDlCtxt->wCmdSendStatus = wStatus;
+ break;
+ }
+ case phDnldNfc_StateRecv:
+ {
+ wStatus = phDnldNfc_ProcessRecvInfo(pContext,pInfo);
+
+ if(NFCSTATUS_SUCCESS == wStatus)
+ {
+ wStatus = phOsalNfc_Timer_Start((pDlCtxt->TimerInfo.dwRspTimerId),
+ PHDNLDNFC_RSP_TIMEOUT,
+ &phDnldNfc_RspTimeOutCb,
+ pDlCtxt);
+
+ if (NFCSTATUS_SUCCESS == wStatus)
+ {
+ NXPLOG_FWDNLD_D("Response timer started");
+ pDlCtxt->TimerInfo.TimerStatus = 1;
+ pDlCtxt->tCurrState = phDnldNfc_StateTimer;
+ }
+ else
+ {
+ NXPLOG_FWDNLD_W("Response timer not started");
+ pDlCtxt->tCurrState = phDnldNfc_StateResponse;
+ }
+ /* Call TML_Read function and register the call back function */
+ wStatus = phTmlNfc_Read(
+ pDlCtxt->tCmdRspFrameInfo.aFrameBuff,
+ (uint16_t )PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE,
+ (pphTmlNfc_TransactCompletionCb_t)&phDnldNfc_ProcessSeqState,
+ (void *)pDlCtxt);
+
+ /* 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(phDnldNfc_FTRaw != (pDlContext->FrameInp.Type))
+ {
+ if(phDnldNfc_FTWrite != (pDlContext->FrameInp.Type))
+ {
+ pFrameByte = (uint8_t *)&wFrameLen;
+
+ pDlContext->tCmdRspFrameInfo.aFrameBuff[PHDNLDNFC_FRAME_HDR_OFFSET] = pFrameByte[1];
+ pDlContext->tCmdRspFrameInfo.aFrameBuff[PHDNLDNFC_FRAME_HDR_OFFSET + 1] = pFrameByte[0];
+
+ NXPLOG_FWDNLD_D("Inserting FrameId ..");
+ pDlContext->tCmdRspFrameInfo.aFrameBuff[PHDNLDNFC_FRAMEID_OFFSET] =
+ (pDlContext->tCmdId);
+
+ wFrameLen += PHDNLDNFC_FRAME_HDR_LEN;
+ }
+ else
+ {
+ if(0 != (pDlContext->tRWInfo.wRWPldSize))
+ {
+ if(TRUE == (pDlContext->tRWInfo.bFramesSegmented))
+ {
+ /* Turning ON the Fragmentation bit in FrameLen */
+ wFrameLen = PHDNLDNFC_SET_HDR_FRAGBIT(wFrameLen);
+ }
+
+ pFrameByte = (uint8_t *)&wFrameLen;
+
+ pDlContext->tCmdRspFrameInfo.aFrameBuff[PHDNLDNFC_FRAME_HDR_OFFSET] = pFrameByte[1];
+ pDlContext->tCmdRspFrameInfo.aFrameBuff[PHDNLDNFC_FRAME_HDR_OFFSET + 1] = pFrameByte[0];
+
+ /* To ensure we have no frag bit set for crc calculation */
+ wFrameLen = PHDNLDNFC_CLR_HDR_FRAGBIT(wFrameLen);
+
+ wFrameLen += PHDNLDNFC_FRAME_HDR_LEN;
+ }
+ }
+
+ /* calculate CRC16 */
+ wCrcVal = phDnldNfc_CalcCrc16((pDlContext->tCmdRspFrameInfo.aFrameBuff),wFrameLen);
+
+ pFrameByte = (uint8_t *)&wCrcVal;
+
+ /* Insert the computed Crc value */
+ pDlContext->tCmdRspFrameInfo.aFrameBuff[wFrameLen] = pFrameByte[1];
+ pDlContext->tCmdRspFrameInfo.aFrameBuff[wFrameLen+ 1] = pFrameByte[0];
+
+ wFrameLen += PHDNLDNFC_FRAME_CRC_LEN;
+ }
+
+ (pDlContext->tCmdRspFrameInfo.dwSendlength) = wFrameLen;
+ NXPLOG_FWDNLD_D("Frame created successfully");
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Frame creation failed!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_FAILED);
+ }
+ }
+
+ return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function phDnldNfc_CreateFramePld
+**
+** Description Forms the frame payload
+**
+** Parameters pDlContext - pointer to the download context structure
+**
+** Returns NFC status
+**
+*******************************************************************************/
+static NFCSTATUS phDnldNfc_CreateFramePld(pphDnldNfc_DlContext_t pDlContext)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+ uint16_t wBuffIdx = 0;
+ uint16_t wChkIntgVal = 0;
+ uint16_t wFrameLen = 0;
+
+ if(NULL == pDlContext)
+ {
+ NXPLOG_FWDNLD_E("Invalid Input Parameter!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
+ }
+ else
+ {
+ memset((pDlContext->tCmdRspFrameInfo.aFrameBuff),0,PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE);
+ (pDlContext->tCmdRspFrameInfo.dwSendlength) = 0;
+
+ if(phDnldNfc_FTNone == (pDlContext->FrameInp.Type))
+ {
+ (pDlContext->tCmdRspFrameInfo.dwSendlength) += PHDNLDNFC_MIN_PLD_LEN;
+ }
+ else if(phDnldNfc_ChkIntg == (pDlContext->FrameInp.Type))
+ {
+ (pDlContext->tCmdRspFrameInfo.dwSendlength) += PHDNLDNFC_MIN_PLD_LEN;
+
+ wChkIntgVal = PHDNLDNFC_USERDATA_EEPROM_OFFSET;
+ memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[PHDNLDNFC_FRAME_RDDATA_OFFSET]),
+ &wChkIntgVal,sizeof(wChkIntgVal));
+
+ wChkIntgVal = PHDNLDNFC_USERDATA_EEPROM_LEN;
+ memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[PHDNLDNFC_FRAME_RDDATA_OFFSET +
+ PHDNLDNFC_USERDATA_EEPROM_OFFSIZE]),&wChkIntgVal,sizeof(wChkIntgVal));
+
+ (pDlContext->tCmdRspFrameInfo.dwSendlength) += PHDNLDNFC_USERDATA_EEPROM_LENSIZE;
+ (pDlContext->tCmdRspFrameInfo.dwSendlength) += PHDNLDNFC_USERDATA_EEPROM_OFFSIZE;
+ }
+ else if(phDnldNfc_FTWrite == (pDlContext->FrameInp.Type))
+ {
+ wBuffIdx = (pDlContext->tRWInfo.wOffset);
+
+ if(FALSE == (pDlContext->tRWInfo.bFramesSegmented))
+ {
+ wFrameLen = (pDlContext->tUserData.pBuff[wBuffIdx]);
+ wFrameLen <<= 8;
+ wFrameLen |= (pDlContext->tUserData.pBuff[wBuffIdx + 1]);
+
+ (pDlContext->tRWInfo.wRWPldSize) = wFrameLen;
+ }
+
+ if((pDlContext->tRWInfo.wRWPldSize) > PHDNLDNFC_CMDRESP_MAX_PLD_SIZE)
+ {
+ if(FALSE == (pDlContext->tRWInfo.bFirstChunkResp))
+ {
+ (pDlContext->tRWInfo.wRemChunkBytes) = wFrameLen;
+ (pDlContext->tRWInfo.wOffset) += PHDNLDNFC_FRAME_HDR_LEN;
+ wBuffIdx = (pDlContext->tRWInfo.wOffset);
+ }
+
+ if(PHDNLDNFC_CMDRESP_MAX_PLD_SIZE < (pDlContext->tRWInfo.wRemChunkBytes))
+ {
+ (pDlContext->tRWInfo.wBytesToSendRecv) = PHDNLDNFC_CMDRESP_MAX_PLD_SIZE;
+ (pDlContext->tRWInfo.bFramesSegmented) = TRUE;
+ }
+ else
+ {
+ (pDlContext->tRWInfo.wBytesToSendRecv) = (pDlContext->tRWInfo.wRemChunkBytes);
+ (pDlContext->tRWInfo.bFramesSegmented) = FALSE;
+ }
+
+ memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[PHDNLDNFC_FRAMEID_OFFSET]),
+ &(pDlContext->tUserData.pBuff[wBuffIdx]),(pDlContext->tRWInfo.wBytesToSendRecv));
+ }
+ else
+ {
+ (pDlContext->tRWInfo.wRWPldSize) = 0;
+ (pDlContext->tRWInfo.wBytesToSendRecv) = (wFrameLen + PHDNLDNFC_FRAME_HDR_LEN);
+
+ memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[0]),
+ &(pDlContext->tUserData.pBuff[wBuffIdx]),(pDlContext->tRWInfo.wBytesToSendRecv));
+ }
+ (pDlContext->tCmdRspFrameInfo.dwSendlength) += (pDlContext->tRWInfo.wBytesToSendRecv);
+ }
+ else if(phDnldNfc_FTRead == (pDlContext->FrameInp.Type))
+ {
+ (pDlContext->tRWInfo.wBytesToSendRecv) = ((pDlContext->tRWInfo.wRemBytes) >
+ (pDlContext->tRWInfo.wRWPldSize)) ? (pDlContext->tRWInfo.wRWPldSize) :
+ (pDlContext->tRWInfo.wRemBytes);
+
+ wBuffIdx = (PHDNLDNFC_PLD_OFFSET + ((sizeof(pDlContext->tRWInfo.wBytesToSendRecv))
+ % PHDNLDNFC_MIN_PLD_LEN) - 1);
+
+ memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[wBuffIdx]),
+ &(pDlContext->tRWInfo.wBytesToSendRecv),(sizeof(pDlContext->tRWInfo.wBytesToSendRecv)));
+
+ wBuffIdx += sizeof(pDlContext->tRWInfo.wBytesToSendRecv);
+
+ memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[wBuffIdx]),
+ &(pDlContext->tRWInfo.dwAddr),sizeof(pDlContext->tRWInfo.dwAddr));
+
+ (pDlContext->tCmdRspFrameInfo.dwSendlength) += (PHDNLDNFC_MIN_PLD_LEN +
+ (sizeof(pDlContext->tRWInfo.dwAddr)));
+ }
+ else if(phDnldNfc_FTLog == (pDlContext->FrameInp.Type))
+ {
+ (pDlContext->tCmdRspFrameInfo.dwSendlength) += PHDNLDNFC_MIN_PLD_LEN;
+
+ wBuffIdx = (PHDNLDNFC_MIN_PLD_LEN + PHDNLDNFC_FRAME_HDR_LEN);
+
+ memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[wBuffIdx]),
+ (pDlContext->tUserData.pBuff),(pDlContext->tUserData.wLen));
+
+ (pDlContext->tCmdRspFrameInfo.dwSendlength) += (pDlContext->tUserData.wLen);
+ }
+ else if(phDnldNfc_FTForce == (pDlContext->FrameInp.Type))
+ {
+ (pDlContext->tCmdRspFrameInfo.dwSendlength) += PHDNLDNFC_MIN_PLD_LEN;
+
+ wBuffIdx = PHDNLDNFC_PLD_OFFSET;
+
+ memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[wBuffIdx]),
+ (pDlContext->tUserData.pBuff),(pDlContext->tUserData.wLen));
+ }
+ else if(phDnldNfc_FTRaw == (pDlContext->FrameInp.Type))
+ {
+ if((0 == (pDlContext->tUserData.wLen)) || (NULL == (pDlContext->tUserData.pBuff)))
+ {
+ NXPLOG_FWDNLD_E("Invalid Input Parameter(s) for Raw Request!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
+ }
+ else
+ {
+ memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[wBuffIdx]),
+ (pDlContext->tUserData.pBuff),(pDlContext->tUserData.wLen));
+
+ (pDlContext->tCmdRspFrameInfo.dwSendlength) += (pDlContext->tUserData.wLen);
+ }
+ }
+ else
+ {
+ }
+ }
+
+ return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function phDnldNfc_ProcessFrame
+**
+** Description Processes response frame received
+**
+** Parameters pContext - pointer to the download context structure
+** pInfo - pointer to the Transaction buffer updated by TML Thread
+**
+** Returns NFCSTATUS_SUCCESS - parameters successfully validated
+** NFCSTATUS_INVALID_PARAMETER - invalid parameters
+**
+*******************************************************************************/
+static NFCSTATUS phDnldNfc_ProcessFrame(void *pContext, phTmlNfc_TransactInfo_t *pInfo)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+ uint16_t wCrcVal,wRecvdCrc,wRecvdLen,wPldLen;
+ pphDnldNfc_DlContext_t pDlCtxt = (pphDnldNfc_DlContext_t)pContext;
+
+ if((NULL == pDlCtxt) ||
+ (NULL == pInfo)
+ )
+ {
+ NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
+ }
+ else
+ {
+ if((PH_DL_STATUS_OK != pInfo->wStatus) ||
+ (0 == pInfo->wLength) ||
+ (NULL == pInfo->pBuff))
+ {
+ NXPLOG_FWDNLD_E("Dnld Cmd Request Failed!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_FAILED);
+ }
+ else
+ {
+ if(phDnldNfc_FTRaw == (pDlCtxt->FrameInp.Type))
+ {
+ if((0 != (pDlCtxt->tRspBuffInfo.wLen)) &&
+ (NULL != (pDlCtxt->tRspBuffInfo.pBuff)))
+ {
+ memcpy((pDlCtxt->tRspBuffInfo.pBuff),(pInfo->pBuff),(pInfo->wLength));
+
+ (pDlCtxt->tRspBuffInfo.wLen) = (pInfo->wLength);
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Cannot update Response buff with received data!!");
+ }
+ }
+ else
+ {
+ /* calculate CRC16 */
+ wCrcVal = phDnldNfc_CalcCrc16((pInfo->pBuff),((pInfo->wLength) - PHDNLDNFC_FRAME_CRC_LEN));
+
+ wRecvdCrc = 0;
+ wRecvdCrc = (((uint16_t)(pInfo->pBuff[(pInfo->wLength) - 2]) << 8U) |
+ (pInfo->pBuff[(pInfo->wLength) - 1]));
+
+ if(wRecvdCrc == wCrcVal)
+ {
+ wRecvdLen = (((uint16_t)(pInfo->pBuff[PHDNLDNFC_FRAME_HDR_OFFSET]) << 8U) |
+ (pInfo->pBuff[PHDNLDNFC_FRAME_HDR_OFFSET + 1]));
+
+ wPldLen = ((pInfo->wLength) - (PHDNLDNFC_FRAME_HDR_LEN + PHDNLDNFC_FRAME_CRC_LEN));
+
+ if(wRecvdLen != wPldLen)
+ {
+ NXPLOG_FWDNLD_E("Invalid frame payload length received");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_FAILED);
+ }
+ else
+ {
+ wStatus = phDnldNfc_UpdateRsp(pDlCtxt,pInfo,(wPldLen - 1));
+ }
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Invalid frame received");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_FAILED);
+ }
+ }
+ }
+ }
+
+ return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function phDnldNfc_ProcessRecvInfo
+**
+** Description Processes the response during the state phDnldNfc_StateRecv
+**
+** Parameters pContext - pointer to the download context structure
+** pInfo - pointer to the Transaction buffer updated by TML Thread
+**
+** Returns NFCSTATUS_SUCCESS - parameters successfully validated
+** NFCSTATUS_INVALID_PARAMETER - invalid parameters
+**
+*******************************************************************************/
+static NFCSTATUS phDnldNfc_ProcessRecvInfo(void *pContext, phTmlNfc_TransactInfo_t *pInfo)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+
+ if(NULL != pContext)
+ {
+ if (NULL == pInfo)
+ {
+ NXPLOG_FWDNLD_E("Invalid pInfo received from TML!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_FAILED);
+ }
+ else
+ {
+ wStatus = PHNFCSTATUS(pInfo->wStatus);
+
+ if(NFCSTATUS_SUCCESS == wStatus)
+ {
+ NXPLOG_FWDNLD_D("Send Success");
+ }else
+ {
+ NXPLOG_FWDNLD_E("Tml Write error!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_FAILED);
+ }
+ }
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Invalid context received from TML!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_FAILED);
+ }
+
+ return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function phDnldNfc_SetupResendTimer
+**
+** Description Sets up the timer for resending the previous write frame
+**
+** Parameters pDlContext - pointer to the download context structure
+**
+** Returns NFC status
+**
+*******************************************************************************/
+static NFCSTATUS phDnldNfc_SetupResendTimer(pphDnldNfc_DlContext_t pDlContext)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+
+ wStatus = phOsalNfc_Timer_Start((pDlContext->TimerInfo.dwRspTimerId),
+ PHDNLDNFC_RETRY_FRAME_WRITE,
+ &phDnldNfc_ResendTimeOutCb,
+ pDlContext);
+
+ if(NFCSTATUS_SUCCESS == wStatus)
+ {
+ NXPLOG_FWDNLD_D("Frame Resend wait timer started");
+ (pDlContext->TimerInfo.TimerStatus) = 1;
+ pDlContext->tCurrState = phDnldNfc_StateTimer;
+ }
+ else
+ {
+ NXPLOG_FWDNLD_W("Frame Resend wait timer not started");
+ (pDlContext->TimerInfo.TimerStatus) = 0;/*timer stopped*/
+ pDlContext->tCurrState = phDnldNfc_StateResponse;
+ /* Todo:- diagnostic in this case */
+ }
+
+ return wStatus;
+}
+
+#if !defined(PH_LIBNFC_VEN_RESET_ON_DOWNLOAD_TIMEOUT)
+# error PH_LIBNFC_VEN_RESET_ON_DOWNLOAD_TIMEOUT has to be defined
+#endif
+
+/*******************************************************************************
+**
+** Function phDnldNfc_RspTimeOutCb
+**
+** Description Callback function in case of timer expiration
+**
+** Parameters TimerId - expired timer id
+** pContext - pointer to the download context structure
+**
+** Returns None
+**
+*******************************************************************************/
+static void phDnldNfc_RspTimeOutCb(uint32_t TimerId, void *pContext)
+{
+ pphDnldNfc_DlContext_t pDlCtxt = (pphDnldNfc_DlContext_t)pContext;
+
+ if (NULL != pDlCtxt)
+ {
+ UNUSED(TimerId);
+
+ if(1 == pDlCtxt->TimerInfo.TimerStatus)
+ {
+ /* No response received and the timer expired */
+ pDlCtxt->TimerInfo.TimerStatus = 0; /* Reset timer status flag */
+
+ NXPLOG_FWDNLD_D("%x",pDlCtxt->tLastStatus);
+
+#if PH_LIBNFC_VEN_RESET_ON_DOWNLOAD_TIMEOUT
+ if ( PH_DL_STATUS_SIGNATURE_ERROR == pDlCtxt->tLastStatus ) {
+ /* Do a VEN Reset of the chip. */
+ NXPLOG_FWDNLD_E("Performing a VEN Reset");
+ phTmlNfc_IoCtl(phTmlNfc_e_EnableNormalMode);
+ phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode);
+ NXPLOG_FWDNLD_E("VEN Reset Done");
+ }
+#endif
+
+
+ (pDlCtxt->TimerInfo.wTimerExpStatus) = NFCSTATUS_RF_TIMEOUT;
+
+ if((phDnldNfc_EventRead == pDlCtxt->tCurrEvent) || (phDnldNfc_EventWrite == pDlCtxt->tCurrEvent))
+ {
+ phDnldNfc_ProcessRWSeqState(pDlCtxt,NULL);
+ }
+ else
+ {
+ phDnldNfc_ProcessSeqState(pDlCtxt,NULL);
+ }
+ }
+ }
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phDnldNfc_ResendTimeOutCb
+**
+** Description Callback function in case of Frame Resend Wait timer expiration
+**
+** Parameters TimerId - expired timer id
+** pContext - pointer to the download context structure
+**
+** Returns None
+**
+*******************************************************************************/
+static void phDnldNfc_ResendTimeOutCb(uint32_t TimerId, void *pContext)
+{
+ pphDnldNfc_DlContext_t pDlCtxt = (pphDnldNfc_DlContext_t)pContext;
+
+ if (NULL != pDlCtxt)
+ {
+ UNUSED(TimerId);
+
+ if(1 == pDlCtxt->TimerInfo.TimerStatus)
+ {
+ /* No response received and the timer expired */
+ pDlCtxt->TimerInfo.TimerStatus = 0; /* Reset timer status flag */
+
+ (pDlCtxt->TimerInfo.wTimerExpStatus) = 0;
+
+ pDlCtxt->tCurrState = phDnldNfc_StateSend;
+
+ /* set the flag to trigger last frame re-transmission */
+ pDlCtxt->bResendLastFrame = TRUE;
+
+ phDnldNfc_ProcessRWSeqState(pDlCtxt,NULL);
+ }
+ }
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phDnldNfc_UpdateRsp
+**
+** Description verifies the payload status byte and copies data
+** to response buffer if successful
+**
+** Parameters pDlContext - pointer to the download context structure
+** pInfo - pointer to the Transaction buffer updated by TML Thread
+** wPldLen - Length of the payload bytes to copy to response buffer
+**
+** Returns NFC status
+**
+*******************************************************************************/
+static NFCSTATUS phDnldNfc_UpdateRsp(pphDnldNfc_DlContext_t pDlContext, phTmlNfc_TransactInfo_t *pInfo, uint16_t wPldLen)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+ uint16_t wReadLen = 0;
+
+ if((NULL == pDlContext) || (NULL == pInfo))
+ {
+ NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
+ }
+ else
+ {
+ if(PH_DL_CMD_WRITE == (pDlContext->tCmdId))
+ {
+ if(PH_DL_STATUS_OK == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET]))
+ {
+ /* first write frame response received case */
+ if(TRUE == (pDlContext->tRWInfo.bFirstWrReq))
+ {
+ NXPLOG_FWDNLD_D("First Write Frame Success Status received!!");
+ (pDlContext->tRWInfo.bFirstWrReq) = FALSE;
+ }
+
+ if(TRUE == (pDlContext->tRWInfo.bFirstChunkResp))
+ {
+ if(FALSE == (pDlContext->tRWInfo.bFramesSegmented))
+ {
+ NXPLOG_FWDNLD_D("Chunked Write Frame Success Status received!!");
+ (pDlContext->tRWInfo.wRemChunkBytes) -= (pDlContext->tRWInfo.wBytesToSendRecv);
+ (pDlContext->tRWInfo.bFirstChunkResp) = FALSE;
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("UnExpected Status received!!");
+ wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FAILED);
+ }
+ }
+
+ if(NFCSTATUS_SUCCESS == wStatus)
+ {
+ (pDlContext->tRWInfo.wRemBytes) -= (pDlContext->tRWInfo.wBytesToSendRecv);
+ (pDlContext->tRWInfo.wOffset) += (pDlContext->tRWInfo.wBytesToSendRecv);
+ }
+ }
+ else if((FALSE == (pDlContext->tRWInfo.bFirstChunkResp)) &&
+ (TRUE == (pDlContext->tRWInfo.bFramesSegmented)) &&
+ (PHDNLDNFC_FIRST_FRAGFRAME_RESP == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET])))
+ {
+ (pDlContext->tRWInfo.bFirstChunkResp) = TRUE;
+ (pDlContext->tRWInfo.wRemChunkBytes) -= (pDlContext->tRWInfo.wBytesToSendRecv);
+ (pDlContext->tRWInfo.wRemBytes) -= ((pDlContext->tRWInfo.wBytesToSendRecv) + PHDNLDNFC_FRAME_HDR_LEN);
+ (pDlContext->tRWInfo.wOffset) += (pDlContext->tRWInfo.wBytesToSendRecv);
+
+ /* first write frame response received case */
+ if(TRUE == (pDlContext->tRWInfo.bFirstWrReq))
+ {
+ NXPLOG_FWDNLD_D("First Write Frame Success Status received!!");
+ (pDlContext->tRWInfo.bFirstWrReq) = FALSE;
+ }
+ }
+ else if((TRUE == (pDlContext->tRWInfo.bFirstChunkResp)) &&
+ (TRUE == (pDlContext->tRWInfo.bFramesSegmented)) &&
+ (PHDNLDNFC_NEXT_FRAGFRAME_RESP == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET])))
+ {
+ (pDlContext->tRWInfo.wRemChunkBytes) -= (pDlContext->tRWInfo.wBytesToSendRecv);
+ (pDlContext->tRWInfo.wRemBytes) -= (pDlContext->tRWInfo.wBytesToSendRecv);
+ (pDlContext->tRWInfo.wOffset) += (pDlContext->tRWInfo.wBytesToSendRecv);
+ }
+ else if(PH_DL_STATUS_FIRMWARE_VERSION_ERROR == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET]))
+ {
+ NXPLOG_FWDNLD_E("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..4a3facd
--- /dev/null
+++ b/halimpl/pn54x/dnld/phDnldNfc_Internal.h
@@ -0,0 +1,181 @@
+/*
+ * 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
+
+#define PHDNLDNFC_WRITERSP_BUFF_SIZE (0x08U) /* DL Host Short Frame Buffer Size for pipelined WRITE RSP */
+
+#define PHDNLDNFC_FRAME_HDR_LEN (0x02U) /* DL Host Frame Buffer Header Length */
+#define PHDNLDNFC_FRAME_CRC_LEN (PHDNLDNFC_FRAME_HDR_LEN) /* DL Host Frame Buffer CRC Length */
+#define PHDNLDNFC_FRAME_ID_LEN (0x01U) /* Length of Cmd Id */
+
+#define PHDNLDNFC_EEFL_ADDR_SIZE (0x03U) /* size of EEPROM/Flash address */
+#define PHDNLDNFC_DATA_SIZE (PHDNLDNFC_FRAME_HDR_LEN) /* 2 Byte size of data */
+
+#define PHDNLDNFC_EEPROM_LOG_START_ADDR (0x201F80U) /* Start of EEPROM address for log */
+#define PHDNLDNFC_EEPROM_LOG_END_ADDR (0x201FBFU) /* End of EEPROM address for log */
+
+#define PHDNLDNFC_MAX_LOG_SIZE ((PHDNLDNFC_EEPROM_LOG_END_ADDR - PHDNLDNFC_EEPROM_LOG_START_ADDR) + 1)
+
+/* DL Max Payload Size */
+#define PHDNLDNFC_CMDRESP_MAX_PLD_SIZE ((PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE) - \
+ (PHDNLDNFC_FRAME_HDR_LEN + PHDNLDNFC_FRAME_CRC_LEN))
+
+/*
+ * Enum definition contains Download Event Types
+ */
+typedef enum phDnldNfc_Event{
+ phDnldNfc_EventInvalid = 0x00, /*Invalid Event Value*/
+ phDnldNfc_EventReset, /* Reset event */
+ phDnldNfc_EventGetVer, /* Get Version event*/
+ phDnldNfc_EventWrite, /* Write event*/
+ phDnldNfc_EventRead, /* Read event*/
+ phDnldNfc_EventIntegChk, /* Integrity Check event*/
+ phDnldNfc_EventGetSesnSt, /* Get Session State event*/
+ phDnldNfc_EventLog, /* Log event*/
+ phDnldNfc_EventForce, /* Force event*/
+ phDnldNfc_EventRaw, /* Raw Req/Rsp event,used currently for sending NCI RESET cmd */
+ phDnldNfc_EVENT_INT_MAX /* Max Event Count*/
+}phDnldNfc_Event_t;
+
+/*
+ * Enum definition contains Download Handler states for each event requested
+ */
+typedef enum phDnldNfc_State{
+ phDnldNfc_StateInit=0x00, /* Handler init state */
+ phDnldNfc_StateSend, /* Send frame to NFCC state */
+ phDnldNfc_StateRecv, /* Recv Send complete State */
+ phDnldNfc_StateTimer, /* State to stop prev set timer on Recv or handle timed out scenario */
+ phDnldNfc_StateResponse, /* Process response from NFCC state */
+ phDnldNfc_StatePipelined, /* Write requests to be pipelined state */
+ phDnldNfc_StateInvalid /* Invalid Handler state */
+}phDnldNfc_State_t;
+
+/*
+ * Enum definition contains Download Handler Transition
+ */
+typedef enum phDnldNfc_Transition{
+ phDnldNfc_TransitionIdle = 0x00, /* Handler in Idle state - No Download in progress */
+ phDnldNfc_TransitionBusy, /* Handler is busy processing download request */
+ phDnldNfc_TransitionInvalid /* Invalid Handler Transition */
+}phDnldNfc_Transition_t;
+
+/*
+ * Enum definition contains the Frame input type for CmdId in process
+ */
+ typedef enum
+ {
+ phDnldNfc_FTNone = 0, /* input type None */
+ phDnldNfc_ChkIntg, /* user eeprom offset & len to be added for Check Integrity Request */
+ phDnldNfc_FTWrite, /* Frame inputs for Write request */
+ phDnldNfc_FTLog, /* Frame inputs for Log request */
+ phDnldNfc_FTForce, /* Frame input for Force cmd request */
+ phDnldNfc_FTRead, /* Addr input required for read request */
+ phDnldNfc_FTRaw /* Raw Req/Rsp type */
+}phDnldNfc_FrameInputType_t;
+
+/*
+ * Contains Host Frame Buffer information.
+ */
+typedef struct phDnldNfc_FrameInfo
+{
+ uint16_t dwSendlength; /* length of the payload */
+ uint8_t aFrameBuff[PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE]; /* Buffer to store command that needs to be sent*/
+}phDnldNfc_FrameInfo_t,*pphDnldNfc_FrameInfo_t; /* pointer to #phDnldNfc_FrameInfo_t */
+
+/*
+ * Frame Input Type & Value for CmdId in Process
+ */
+typedef struct phDnldNfc_FrameInput
+{
+ phDnldNfc_FrameInputType_t Type; /* Type of frame input required for current cmd in process */
+ uint32_t dwAddr; /* Address value required for Read/Write Cmd*/
+}phDnldNfc_FrameInput_t, *pphDnldNfc_FrameInput_t;/* pointer to #phDnldNfc_FrameInput_t */
+
+/*
+ * Context for the response timeout
+ */
+typedef struct phDnldNfc_RspTimerInfo
+{
+ uint32_t dwRspTimerId; /* Timer for Core to handle response */
+ uint8_t TimerStatus; /* 0 = Timer not running 1 = timer running*/
+ NFCSTATUS wTimerExpStatus; /* Holds the status code on timer expiry */
+}phDnldNfc_RspTimerInfo_t;
+
+/*
+ * Read/Write Processing Info
+ */
+typedef struct phDnldNfc_RWInfo
+{
+ uint32_t dwAddr; /* current Addr updated for read/write */
+ uint16_t wOffset; /* current offset within the user buffer to read/write */
+ uint16_t wRemBytes; /* Remaining bytes to read/write */
+ uint16_t wRemChunkBytes; /* Remaining bytes within the chunked frame */
+ uint16_t wRWPldSize; /* Size of the read/write payload per transaction */
+ uint16_t wBytesToSendRecv; /* Num of Bytes being written/read currently */
+ uint16_t wBytesRead; /* Bytes read from read cmd currently */
+ bool_t bFramesSegmented; /* Flag to indicate if Read/Write frames are segmented */
+ bool_t bFirstWrReq; /* Flag to indicate if this is the first write frame being sent */
+ bool_t bFirstChunkResp; /* Flag to indicate if we got the first chunk response */
+}phDnldNfc_RWInfo_t, *pphDnldNfc_RWInfo_t;/* pointer to #phDnldNfc_RWInfo_t */
+
+/*
+ * Download context structure
+ */
+typedef struct phDnldNfc_DlContext
+{
+ const uint8_t *nxp_nfc_fw; /* Pointer to firmware version from image */
+ const uint8_t *nxp_nfc_fwp; /* Pointer to firmware version from get_version cmd */
+ uint16_t nxp_nfc_fwp_len; /* Length of firmware image length */
+ uint16_t nxp_nfc_fw_len; /* Firmware image length */
+ bool_t bResendLastFrame; /* Flag to resend the last write frame after MEM_BSY status */
+ phDnldNfc_Transition_t tDnldInProgress; /* Flag to indicate if download request is ongoing */
+ phDnldNfc_Event_t tCurrEvent; /* Current event being processed */
+ phDnldNfc_State_t tCurrState; /* Current state being processed */
+ pphDnldNfc_RspCb_t UserCb ; /* Upper layer call back function */
+ void* UserCtxt ; /* Pointer to upper layer context */
+ phDnldNfc_Buff_t tUserData; /* Data buffer provided by caller */
+ phDnldNfc_Buff_t tRspBuffInfo; /* Buffer to store payload field of the received response*/
+ phDnldNfc_FrameInfo_t tCmdRspFrameInfo; /* Buffer to hold the cmd/resp frame except pipeline write */
+ phDnldNfc_FrameInfo_t tPipeLineWrFrameInfo; /* Buffer to hold the pipelined write frame */
+ NFCSTATUS wCmdSendStatus; /* Holds the status of cmd request made to cmd handler */
+ phDnldNfc_CmdId_t tCmdId; /* Cmd Id of the currently processed cmd */
+ phDnldNfc_FrameInput_t FrameInp; /* input value required for current cmd in process */
+ phDnldNfc_RspTimerInfo_t TimerInfo; /* Timer context handled into download context*/
+ phDnldNfc_Buff_t tTKey; /* Defualt Transport Key provided by caller */
+ phDnldNfc_RWInfo_t tRWInfo; /* Read/Write segmented frame info */
+ phDnldNfc_Status_t tLastStatus; /* saved status to distinguish signature or pltform recovery */
+}phDnldNfc_DlContext_t,*pphDnldNfc_DlContext_t; /* pointer to #phDnldNfc_DlContext_t structure */
+
+/* The phDnldNfc_CmdHandler function declaration */
+extern NFCSTATUS phDnldNfc_CmdHandler(void *pContext, phDnldNfc_Event_t TrigEvent);
+
+#endif /* PHDNLDNFC_INTERNAL_H */
diff --git a/halimpl/pn54x/dnld/phDnldNfc_Status.h b/halimpl/pn54x/dnld/phDnldNfc_Status.h
new file mode 100644
index 0000000..035f7a9
--- /dev/null
+++ b/halimpl/pn54x/dnld/phDnldNfc_Status.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.
+ */
+
+/*
+ * 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..f264865
--- /dev/null
+++ b/halimpl/pn54x/dnld/phDnldNfc_Utils.c
@@ -0,0 +1,83 @@
+/*
+ * 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..95ff877
--- /dev/null
+++ b/halimpl/pn54x/dnld/phNxpNciHal_Dnld.c
@@ -0,0 +1,1973 @@
+/*
+ * 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;
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+extern uint8_t gRecFWDwnld; // flag set to true to indicate dummy FW download
+#endif
+/* RF Configuration structure */
+typedef struct phLibNfc_IoctlSetRfConfig
+{
+ uint8_t bNumOfParams; /* Number of Rf configurable parameters to be set */
+ uint8_t *pInputBuffer; /* Buffer containing Rf configurable parameters */
+ uint8_t bSetSysPmuFlag; /* Flag to decide wether to set SystemPmu or no from the first byte */
+}phLibNfc_IoctlSetRfConfig;
+
+/* Structure to hold information from EEPROM */
+typedef struct phLibNfc_EELogParams
+{
+ uint16_t wCurrMwVer; /* Holds current MW version on the chip */
+ uint16_t wCurrFwVer; /* Holds current FW version on the chip */
+ uint16_t wNumDnldTrig; /* Total number of times dnld has been attempted */
+ uint16_t wNumDnldSuccess; /* Total number of times dnld has been successful */
+ uint16_t wNumDnldFail; /* Total number of times dnld has Failed */
+ uint16_t wDnldFailCnt; /* holds the number of times dnld has failed,will be reset on success */
+ bool_t bConfig; /* Flag to be set in dnld mode after successful dnld,to be reset in NCI Mode
+ after setting the NCI configuration */
+} phLibNfc_EELogParams_t;
+
+/* FW download module context structure */
+typedef struct
+{
+ bool_t bDnldEepromWrite; /* Flag to indicate eeprom write request*/
+ bool_t bSkipSeq; /* Flag to indicate FW download sequence to be skipped or not */
+ bool_t bSkipReset; /* Flag to indicate Reset cmd to be skipped or not in FW download sequence */
+ bool_t bSkipForce; /* Flag to indicate Force cmd to be skipped or not in FW recovery sequence */
+ bool_t bPrevSessnOpen; /* Flag to indicate previous download session is open or not */
+ bool_t bLibNfcCtxtMem; /* flag to indicate if mem was allocated for gpphLibNfc_Context */
+ bool_t bDnldInitiated; /* Flag to indicate if fw upgrade was initiated */
+ bool_t bSendNciCmd; /* Flag to indicate if NCI cmd to be sent or not,after PKU */
+ uint8_t bChipVer; /* holds the hw chip version */
+ bool_t bDnldRecovery; /* Flag to indicate if dnld recovery sequence needs to be triggered */
+ bool_t bForceDnld; /* Flag to indicate if forced download option is enabled */
+ bool_t bRetryDnld; /* Flag to indicate retry download after successful recovery complete */
+ uint8_t bDnldAttempts; /* Holds the count of no. of dnld attempts made.max 3 */
+ uint16_t IoctlCode; /* Ioctl code*/
+ bool_t bDnldAttemptFailed; /* Flag to indicate last download attempt failed */
+ NFCSTATUS bLastStatus; /* Holds the actual download write attempt status */
+ phLibNfc_EELogParams_t tLogParams; /* holds the params that could be logged to reserved EE address */
+ uint8_t bClkSrcVal; /* Holds the System clock source read from config file */
+ uint8_t bClkFreqVal; /* Holds the System clock frequency read from config file */
+} phNxpNciHal_fw_Ioctl_Cntx_t;
+
+
+/* Global variables used in this file only*/
+static phNxpNciHal_fw_Ioctl_Cntx_t gphNxpNciHal_fw_IoctlCtx;
+
+/* Local function prototype */
+static NFCSTATUS
+phNxpNciHal_fw_dnld_reset(void* pContext, NFCSTATUS status, void* pInfo);
+
+static void
+phNxpNciHal_fw_dnld_reset_cb(void* pContext, NFCSTATUS status, void* pInfo);
+
+static NFCSTATUS
+phNxpNciHal_fw_dnld_force(void* pContext, NFCSTATUS status, void* pInfo);
+
+static void
+phNxpNciHal_fw_dnld_force_cb(void* pContext, NFCSTATUS status, void* pInfo);
+
+static void
+phNxpNciHal_fw_dnld_normal_cb(void* pContext, NFCSTATUS status, void* pInfo);
+
+static NFCSTATUS
+phNxpNciHal_fw_dnld_normal(void* pContext, NFCSTATUS status, void* pInfo);
+
+static void
+phNxpNciHal_fw_dnld_get_version_cb(void* pContext, NFCSTATUS status, void* pInfo);
+
+static NFCSTATUS
+phNxpNciHal_fw_dnld_get_version(void* pContext, NFCSTATUS status, void* pInfo);
+
+static void
+phNxpNciHal_fw_dnld_get_sessn_state_cb(void* pContext, NFCSTATUS status, void* pInfo);
+
+static NFCSTATUS
+phNxpNciHal_fw_dnld_get_sessn_state(void* pContext, NFCSTATUS status, void* pInfo);
+
+static void
+phNxpNciHal_fw_dnld_log_read_cb(void* pContext, NFCSTATUS status, void* pInfo);
+
+static NFCSTATUS
+phNxpNciHal_fw_dnld_log_read(void* pContext, NFCSTATUS status, void* pInfo);
+
+static void
+phNxpNciHal_fw_dnld_write_cb(void* pContext, NFCSTATUS status, void* pInfo);
+
+static NFCSTATUS
+phNxpNciHal_fw_dnld_write(void* pContext, NFCSTATUS status, void* pInfo);
+
+static void
+phNxpNciHal_fw_dnld_chk_integrity_cb(void* pContext, NFCSTATUS status, void* pInfo);
+
+static NFCSTATUS
+phNxpNciHal_fw_dnld_chk_integrity(void* pContext, NFCSTATUS status, void* pInfo);
+
+static void
+phNxpNciHal_fw_dnld_log_cb(void* pContext, NFCSTATUS status, void* pInfo);
+
+static NFCSTATUS
+phNxpNciHal_fw_dnld_log(void* pContext, NFCSTATUS status, void* pInfo);
+
+static void
+phNxpNciHal_fw_dnld_send_ncicmd_Cb(void* pContext, NFCSTATUS status, void* pInfo);
+
+static NFCSTATUS
+phNxpNciHal_fw_dnld_send_ncicmd(void* pContext, NFCSTATUS status, void* pInfo);
+
+static NFCSTATUS
+phNxpNciHal_fw_dnld_recover(void* pContext, NFCSTATUS status, void* pInfo);
+
+static NFCSTATUS
+phNxpNciHal_fw_dnld_complete(void* pContext, NFCSTATUS status, void* pInfo);
+
+/** Internal function to verify Crc Status byte received during CheckIntegrity */
+static NFCSTATUS
+phLibNfc_VerifyCrcStatus(uint8_t bCrcStatus);
+
+static void phNxpNciHal_fw_dnld_recover_cb(void* pContext, NFCSTATUS status,
+ void* pInfo);
+
+static NFCSTATUS phNxpNciHal_fw_seq_handler(NFCSTATUS (*seq_handler[])(void* pContext, NFCSTATUS status, void* pInfo));
+
+/* Array of pointers to start fw download seq */
+static NFCSTATUS (*phNxpNciHal_dwnld_seqhandler[])(
+ void* pContext, NFCSTATUS status, void* pInfo) = {
+#if(NFC_NXP_CHIP_TYPE == PN547C2)
+ phNxpNciHal_fw_dnld_normal,
+ phNxpNciHal_fw_dnld_normal,
+#endif
+ phNxpNciHal_fw_dnld_get_sessn_state,
+ phNxpNciHal_fw_dnld_get_version,
+ phNxpNciHal_fw_dnld_log_read,
+ phNxpNciHal_fw_dnld_write,
+ phNxpNciHal_fw_dnld_get_sessn_state,
+ phNxpNciHal_fw_dnld_get_version,
+ phNxpNciHal_fw_dnld_log,
+ phNxpNciHal_fw_dnld_chk_integrity,
+ NULL
+};
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+/* 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
+};
+#endif
+/* Download Recovery Sequence */
+static NFCSTATUS (*phNxpNciHal_dwnld_rec_seqhandler[])(
+ void* pContext, NFCSTATUS status, void* pInfo) = {
+ phNxpNciHal_fw_dnld_reset,
+ phNxpNciHal_fw_dnld_force,
+ phNxpNciHal_fw_dnld_recover,
+ phNxpNciHal_fw_dnld_send_ncicmd,
+ NULL
+};
+
+/* Download Log Sequence */
+static NFCSTATUS (*phNxpNciHal_dwnld_log_seqhandler[])(
+ void* pContext, NFCSTATUS status, void* pInfo) = {
+ phNxpNciHal_fw_dnld_log,
+ NULL
+};
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_fw_dnld_reset_cb
+**
+** Description Download Reset callback
+**
+** Returns None
+**
+*******************************************************************************/
+static void phNxpNciHal_fw_dnld_reset_cb(void* pContext, NFCSTATUS status,
+ void* pInfo)
+{
+ phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+ UNUSED(pInfo);
+ if (NFCSTATUS_SUCCESS == status)
+ {
+ NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_reset_cb - Request Successful");
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset_cb - Request Failed!!");
+ }
+ p_cb_data->status = status;
+
+ SEM_POST(p_cb_data);
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_fw_dnld_reset
+**
+** Description Download Reset
+**
+** Returns NFCSTATUS_SUCCESS if success
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_fw_dnld_reset(void* pContext, NFCSTATUS status,
+ void* pInfo)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+ phNxpNciHal_Sem_t cb_data;
+ UNUSED(pContext);
+ UNUSED(status);
+ UNUSED(pInfo);
+ if((TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipSeq)) || (TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipReset)))
+ {
+ if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipReset))
+ {
+ (gphNxpNciHal_fw_IoctlCtx.bSkipReset) = FALSE;
+ }
+ return NFCSTATUS_SUCCESS;
+ }
+
+ if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset Create dnld_cb_data failed");
+ return NFCSTATUS_FAILED;
+ }
+ wStatus = phDnldNfc_Reset((pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_reset_cb, (void*) &cb_data);
+
+ if (wStatus != NFCSTATUS_PENDING)
+ {
+ NXPLOG_FWDNLD_E("phDnldNfc_Reset failed");
+ wStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ /* Wait for callback response */
+ if (SEM_WAIT(cb_data))
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset semaphore error");
+ wStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ if (cb_data.status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset cb failed");
+ wStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ wStatus = NFCSTATUS_SUCCESS;
+
+clean_and_return:
+ phNxpNciHal_cleanup_cb_data(&cb_data);
+
+
+ return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_fw_dnld_normal_cb
+**
+** Description Download Normal callback
+**
+** Returns None
+**
+*******************************************************************************/
+static void phNxpNciHal_fw_dnld_normal_cb(void* pContext, NFCSTATUS status,
+ void* pInfo)
+{
+ phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+ UNUSED(pInfo);
+ if (NFCSTATUS_SUCCESS == status)
+ {
+ NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_normal_cb - Request Successful");
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_normal_cb - Request Failed!!");
+ /* In this fail scenario trick the sequence handler to call next recover sequence */
+ status = NFCSTATUS_SUCCESS;
+ }
+ p_cb_data->status = status;
+
+ SEM_POST(p_cb_data);
+ usleep(1000 * 10);
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_fw_dnld_force_cb
+**
+** Description Download Force callback
+**
+** Returns None
+**
+*******************************************************************************/
+static void phNxpNciHal_fw_dnld_force_cb(void* pContext, NFCSTATUS status,
+ void* pInfo)
+{
+ phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+ UNUSED(pInfo);
+ if (NFCSTATUS_SUCCESS == status)
+ {
+ NXPLOG_FWDNLD_D("phLibNfc_DnldForceCb - Request Successful");
+ (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = FALSE;
+ (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = TRUE;
+ (gphNxpNciHal_fw_IoctlCtx.bSkipReset) = TRUE;
+ }
+ else
+ {
+ /* In this fail scenario trick the sequence handler to call next recover sequence */
+ status = NFCSTATUS_SUCCESS;
+ NXPLOG_FWDNLD_E("phLibNfc_DnldForceCb - Request Failed!!");
+
+ }
+ p_cb_data->status = status;
+
+ SEM_POST(p_cb_data);
+ usleep(1000 * 10);
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_fw_dnld_normal
+**
+** Description Download Normal
+**
+** Returns NFCSTATUS_SUCCESS if success
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_fw_dnld_normal(void* pContext, NFCSTATUS status,
+ void* pInfo)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+ uint8_t bClkVal[2];
+ phDnldNfc_Buff_t tData;
+ phNxpNciHal_Sem_t cb_data;
+ UNUSED(pContext);
+ UNUSED(status);
+ UNUSED(pInfo);
+ if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipForce))
+ {
+ return NFCSTATUS_SUCCESS;
+ }
+ else
+ {
+ /*
+ bClkVal[0] = NXP_SYS_CLK_SRC_SEL;
+ bClkVal[1] = NXP_SYS_CLK_FREQ_SEL;
+ */
+ bClkVal[0] = gphNxpNciHal_fw_IoctlCtx.bClkSrcVal;
+ bClkVal[1] = gphNxpNciHal_fw_IoctlCtx.bClkFreqVal;
+
+ (tData.pBuff) = bClkVal;
+ (tData.wLen) = sizeof(bClkVal);
+
+ if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery))
+ {
+ (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts)++;
+ }
+
+ if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset Create dnld_cb_data failed");
+ return NFCSTATUS_FAILED;
+ }
+ wStatus = phDnldNfc_Force(&tData,(pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_normal_cb, (void*) &cb_data);
+
+ if(NFCSTATUS_PENDING != wStatus)
+ {
+ NXPLOG_FWDNLD_E("phDnldNfc_Normal failed");
+ (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = FALSE;
+ (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE;
+ goto clean_and_return;
+ }
+ }
+
+ /* Wait for callback response */
+ if (SEM_WAIT(cb_data))
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_normal semaphore error");
+ wStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ if (cb_data.status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_normal cb failed");
+ wStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ wStatus = NFCSTATUS_SUCCESS;
+
+clean_and_return:
+ phNxpNciHal_cleanup_cb_data(&cb_data);
+
+ return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_fw_dnld_force
+**
+** Description Download Force
+**
+** Returns NFCSTATUS_SUCCESS if success
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_fw_dnld_force(void* pContext, NFCSTATUS status,
+ void* pInfo)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+ uint8_t bClkVal[2];
+ phDnldNfc_Buff_t tData;
+ phNxpNciHal_Sem_t cb_data;
+ UNUSED(pContext);
+ UNUSED(status);
+ UNUSED(pInfo);
+ if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipForce))
+ {
+ return NFCSTATUS_SUCCESS;
+ }
+ else
+ {
+ /*
+ bClkVal[0] = NXP_SYS_CLK_SRC_SEL;
+ bClkVal[1] = NXP_SYS_CLK_FREQ_SEL;
+ */
+ bClkVal[0] = gphNxpNciHal_fw_IoctlCtx.bClkSrcVal;
+ bClkVal[1] = gphNxpNciHal_fw_IoctlCtx.bClkFreqVal;
+
+ (tData.pBuff) = bClkVal;
+ (tData.wLen) = sizeof(bClkVal);
+
+ if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery))
+ {
+ (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts)++;
+ }
+
+ if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset Create dnld_cb_data failed");
+ return NFCSTATUS_FAILED;
+ }
+ wStatus = phDnldNfc_Force(&tData,(pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_force_cb, (void*) &cb_data);
+
+ if(NFCSTATUS_PENDING != wStatus)
+ {
+ NXPLOG_FWDNLD_E("phDnldNfc_Force failed");
+ (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = FALSE;
+ (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE;
+ goto clean_and_return;
+ }
+ }
+
+ /* Wait for callback response */
+ if (SEM_WAIT(cb_data))
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_force semaphore error");
+ wStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ if (cb_data.status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_force cb failed");
+ wStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ wStatus = NFCSTATUS_SUCCESS;
+
+clean_and_return:
+ phNxpNciHal_cleanup_cb_data(&cb_data);
+
+ return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_fw_dnld_get_version_cb
+**
+** Description Download Get version callback
+**
+** Returns None
+**
+*******************************************************************************/
+static void phNxpNciHal_fw_dnld_get_version_cb(void* pContext,
+ NFCSTATUS status, void* pInfo)
+{
+ phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+ NFCSTATUS wStatus = status;
+ pphDnldNfc_Buff_t pRespBuff;
+ uint16_t wFwVern = 0;
+ uint16_t wMwVern = 0;
+ uint8_t bHwVer = 0;
+ uint8_t bExpectedLen = 0;
+ uint8_t bNewVer[2];
+ uint8_t bCurrVer[2];
+
+ if ((NFCSTATUS_SUCCESS == wStatus) && (NULL != pInfo))
+ {
+ NXPLOG_FWDNLD_D ("phNxpNciHal_fw_dnld_get_version_cb - Request Successful");
+
+ pRespBuff = (pphDnldNfc_Buff_t) pInfo;
+
+ if ((0 != pRespBuff->wLen) && (NULL != pRespBuff->pBuff))
+ {
+ bHwVer = (pRespBuff->pBuff[0]);
+ bHwVer &= 0x0F; /* 0x0F is the mask to extract chip version */
+
+ if ((PHDNLDNFC_HWVER_MRA2_1 == bHwVer) || (PHDNLDNFC_HWVER_MRA2_2 == bHwVer) ||
+ (PHDNLDNFC_HWVER_PN548AD_MRA1_0 == bHwVer))
+ {
+ bExpectedLen = PHLIBNFC_IOCTL_DNLD_GETVERLEN_MRA2_1;
+ (gphNxpNciHal_fw_IoctlCtx.bChipVer) = bHwVer;
+ }
+ else if ((bHwVer >= PHDNLDNFC_HWVER_MRA1_0) && (bHwVer
+ <= PHDNLDNFC_HWVER_MRA2_0))
+ {
+ bExpectedLen = PHLIBNFC_IOCTL_DNLD_GETVERLEN;
+ (gphNxpNciHal_fw_IoctlCtx.bChipVer) = bHwVer;
+ }
+ else
+ {
+ wStatus = NFCSTATUS_FAILED;
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version_cb - Invalid ChipVersion!!");
+ }
+ }
+ else
+ {
+ wStatus = NFCSTATUS_FAILED;
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version_cb - Version Resp Buff Invalid...\n");
+ }
+
+ if ((NFCSTATUS_SUCCESS == wStatus) && (bExpectedLen == pRespBuff->wLen)
+ && (NULL != pRespBuff->pBuff))
+ {
+ NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_get_version_cb - Valid Version Resp Buff!!...\n");
+
+ /* Validate version details to confirm if continue with the next sequence of Operations. */
+ memcpy(bCurrVer, &(pRespBuff->pBuff[bExpectedLen - 2]),
+ sizeof(bCurrVer));
+ wFwVern = wFwVer;
+ wMwVern = wMwVer;
+
+ memcpy(bNewVer,&wFwVern,sizeof(bNewVer));
+
+ /* check if the ROM code version and FW Major version is valid for the chip*/
+ /* ES2.2 Rom Version - 0x7 and Valid FW Major Version - 0x1 */
+ if ((pRespBuff->pBuff[1] == 0x07) &&(bNewVer[1] !=0x01))
+ {
+ NXPLOG_FWDNLD_E("C1 FW on C2 chip is not allowed - FW Major Version!= 1 on ES2.2");
+ wStatus = NFCSTATUS_NOT_ALLOWED;
+ }
+ /* Major Version number check */
+ else if((FALSE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated)) && (bNewVer[1] < bCurrVer[1]))
+ {
+ NXPLOG_FWDNLD_E("Version Check Failed - MajorVerNum Mismatch\n");
+ wStatus = NFCSTATUS_NOT_ALLOWED;
+ }
+ /* Minor Version number check - before download.*/
+ else if((FALSE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated)) && ((bNewVer[0] == bCurrVer[0]) &&
+ (bNewVer[1] == bCurrVer[1])))
+ {
+ wStatus = NFCSTATUS_SUCCESS;
+#if (PH_LIBNFC_ENABLE_FORCE_DOWNLOAD == 0)
+ NXPLOG_FWDNLD_D("Version Already UpToDate!!\n");
+ (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = TRUE;
+#else
+ (gphNxpNciHal_fw_IoctlCtx.bForceDnld) = TRUE;
+#endif
+
+ }
+ /* Minor Version number check - after download
+ * after download, we should get the same version information.*/
+ else if ((TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated)) && ((bNewVer[0] != bCurrVer[0]) ||
+ (bNewVer[1] != bCurrVer[1])))
+ {
+ NXPLOG_FWDNLD_E("Version Not Updated After Download!!\n");
+ wStatus = NFCSTATUS_FAILED;
+ }
+ else
+ {
+ NXPLOG_FWDNLD_D("Version Check Successful\n");
+ /* Store the Mw & Fw Version for updating in EEPROM Log Area after successful download */
+ if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated))
+ {
+ NXPLOG_FWDNLD_W("Updating Fw & Mw Versions..");
+ (gphNxpNciHal_fw_IoctlCtx.tLogParams.wCurrMwVer) = wMwVern;
+ (gphNxpNciHal_fw_IoctlCtx.tLogParams.wCurrFwVer) = wFwVern;
+ }
+
+ }
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version_cb - Version Resp Buff Invalid...\n");
+ }
+ }
+ else
+ {
+ wStatus = NFCSTATUS_FAILED;
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version_cb - Request Failed!!");
+ }
+
+ p_cb_data->status = wStatus;
+ SEM_POST(p_cb_data);
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_fw_dnld_get_version
+**
+** Description Download Get version
+**
+** Returns NFCSTATUS_SUCCESS if success
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_fw_dnld_get_version(void* pContext,
+ NFCSTATUS status, void* pInfo)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+ phNxpNciHal_Sem_t cb_data;
+ static uint8_t bGetVerRes[11];
+ phDnldNfc_Buff_t tDnldBuff;
+ UNUSED(pContext);
+ UNUSED(status);
+ UNUSED(pInfo);
+ if((TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipSeq)) ||
+ (TRUE == (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen)))
+ {
+ return NFCSTATUS_SUCCESS;
+ }
+
+ if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version cb_data creation failed");
+ return NFCSTATUS_FAILED;
+ }
+
+ tDnldBuff.pBuff = bGetVerRes;
+ tDnldBuff.wLen = sizeof(bGetVerRes);
+
+ wStatus = phDnldNfc_GetVersion(&tDnldBuff,
+ (pphDnldNfc_RspCb_t) &phNxpNciHal_fw_dnld_get_version_cb,
+ (void*) &cb_data);
+ if (wStatus != NFCSTATUS_PENDING)
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version failed");
+ wStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+ /* Wait for callback response */
+ if (SEM_WAIT(cb_data))
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version semaphore error");
+ wStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ if (cb_data.status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version cb failed");
+ wStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ wStatus = NFCSTATUS_SUCCESS;
+
+clean_and_return:
+ phNxpNciHal_cleanup_cb_data(&cb_data);
+
+ return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_fw_dnld_get_sessn_state_cb
+**
+** Description Download Get session state callback
+**
+** Returns None
+**
+*******************************************************************************/
+static void phNxpNciHal_fw_dnld_get_sessn_state_cb(void* pContext,
+ NFCSTATUS status, void* pInfo)
+{
+ phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+ NFCSTATUS wStatus = status;
+ pphDnldNfc_Buff_t pRespBuff;
+ if ((NFCSTATUS_SUCCESS == wStatus) && (NULL != pInfo))
+ {
+ NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_get_sessn_state_cb - Request Successful");
+
+ pRespBuff = (pphDnldNfc_Buff_t) pInfo;
+
+ if ((3 == (pRespBuff->wLen)) && (NULL != (pRespBuff->pBuff)))
+ {
+ NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_get_sessn_state_cb - Valid Session State Resp Buff!!...");
+
+ if (phDnldNfc_LCOper == pRespBuff->pBuff[2])
+ {
+ if (PHLIBNFC_FWDNLD_SESSNOPEN == pRespBuff->pBuff[0])
+ {
+ NXPLOG_FWDNLD_E("Prev Fw Upgrade Session still Open..");
+ (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) = TRUE;
+ if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated))
+ {
+ NXPLOG_FWDNLD_D("Session still Open after Prev Fw Upgrade attempt!!");
+
+ if((gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) < PHLIBNFC_IOCTL_DNLD_MAX_ATTEMPTS)
+ {
+ NXPLOG_FWDNLD_W("Setting Dnld Retry ..");
+ (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = TRUE;
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Max Dnld Retry Counts Exceeded!!");
+ (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE;
+ }
+ wStatus = NFCSTATUS_FAILED;
+ }
+ }
+ else
+ {
+ gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen = FALSE;
+ }
+ }
+ else
+ {
+ wStatus = NFCSTATUS_FAILED;
+ NXPLOG_FWDNLD_E("NFCC not in Operational State..Fw Upgrade not allowed!!");
+ }
+ }
+ else
+ {
+ wStatus = NFCSTATUS_FAILED;
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_sessn_state_cb - Session State Resp Buff Invalid...");
+ }
+ }
+ else
+ {
+ wStatus = NFCSTATUS_FAILED;
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_sessn_state_cb - Request Failed!!");
+ }
+
+ p_cb_data->status = wStatus;
+
+ SEM_POST(p_cb_data);
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_fw_dnld_get_sessn_state
+**
+** Description Download Get session state
+**
+** Returns NFCSTATUS_SUCCESS if success
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_fw_dnld_get_sessn_state(void* pContext,
+ NFCSTATUS status, void* pInfo)
+{
+ phDnldNfc_Buff_t tDnldBuff;
+ static uint8_t bGSnStateRes[3];
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+ phNxpNciHal_Sem_t cb_data;
+ UNUSED(pContext);
+ UNUSED(status);
+ UNUSED(pInfo);
+ if (TRUE == gphNxpNciHal_fw_IoctlCtx.bSkipSeq)
+ {
+ return NFCSTATUS_SUCCESS;
+ }
+
+ if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version cb_data creation failed");
+ return NFCSTATUS_FAILED;
+ }
+
+ tDnldBuff.pBuff = bGSnStateRes;
+ tDnldBuff.wLen = sizeof(bGSnStateRes);
+
+ wStatus = phDnldNfc_GetSessionState(&tDnldBuff,
+ &phNxpNciHal_fw_dnld_get_sessn_state_cb, (void *) &cb_data);
+ if (wStatus != NFCSTATUS_PENDING)
+ {
+ NXPLOG_FWDNLD_E("phDnldNfc_GetSessionState failed");
+ wStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ /* Wait for callback response */
+ if (SEM_WAIT(cb_data))
+ {
+ NXPLOG_FWDNLD_E("phDnldNfc_GetSessionState semaphore error");
+ wStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ if (cb_data.status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_FWDNLD_E("phDnldNfc_GetSessionState cb failed");
+ wStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ wStatus = NFCSTATUS_SUCCESS;
+
+clean_and_return:
+ phNxpNciHal_cleanup_cb_data(&cb_data);
+
+ return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_fw_dnld_log_read_cb
+**
+** Description Download Logread callback
+**
+** Returns None
+**
+*******************************************************************************/
+static void phNxpNciHal_fw_dnld_log_read_cb(void* pContext, NFCSTATUS status,
+ void* pInfo)
+{
+ phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+
+ if((NFCSTATUS_SUCCESS == status) && (NULL != pInfo))
+ {
+ NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_log_read_cb - Request Successful");
+ }
+ else
+ {
+ status = NFCSTATUS_FAILED;
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read_cb - Request Failed!!");
+ }
+
+ p_cb_data->status = status;
+ SEM_POST(p_cb_data);
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_fw_dnld_log_read
+**
+** Description Download Log Read
+**
+** Returns NFCSTATUS_SUCCESS if success
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_fw_dnld_log_read(void* pContext, NFCSTATUS status,
+ void* pInfo)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+ phNxpNciHal_Sem_t cb_data;
+ phDnldNfc_Buff_t Data;
+ UNUSED(pContext);
+ UNUSED(status);
+ UNUSED(pInfo);
+ if((((TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipSeq)) || (TRUE == (gphNxpNciHal_fw_IoctlCtx.bForceDnld))) &&
+ (FALSE == (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen))) || (((TRUE == (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen))) &&
+ (TRUE == (gphNxpNciHal_fw_IoctlCtx.bRetryDnld))))
+
+ {
+ return NFCSTATUS_SUCCESS;
+ }
+
+ if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read cb_data creation failed");
+ return NFCSTATUS_FAILED;
+ }
+
+ (Data.pBuff) = (void *)&(gphNxpNciHal_fw_IoctlCtx.tLogParams);
+ (Data.wLen) = sizeof(phLibNfc_EELogParams_t);
+
+ wStatus = phDnldNfc_ReadLog(&Data,
+ (pphDnldNfc_RspCb_t) &phNxpNciHal_fw_dnld_log_read_cb,
+ (void *) &cb_data);
+ if (wStatus != NFCSTATUS_PENDING)
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read failed");
+ wStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ /* Wait for callback response */
+ if (SEM_WAIT(cb_data))
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read semaphore error");
+ wStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ if (cb_data.status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read cb failed");
+ wStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ wStatus = NFCSTATUS_SUCCESS;
+
+clean_and_return:
+ phNxpNciHal_cleanup_cb_data(&cb_data);
+
+ return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_fw_dnld_write_cb
+**
+** Description Download Write callback
+**
+** Returns None
+**
+*******************************************************************************/
+static void phNxpNciHal_fw_dnld_write_cb(void* pContext, NFCSTATUS status,
+ void* pInfo)
+{
+ phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+ UNUSED(pInfo);
+ if (NFCSTATUS_SUCCESS == status)
+ {
+ NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_write_cb - Request Successful");
+ (gphNxpNciHal_fw_IoctlCtx.bDnldEepromWrite) = FALSE;
+ if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated))
+ {
+ (gphNxpNciHal_fw_IoctlCtx.tLogParams.wNumDnldSuccess) += 1;
+
+ if((gphNxpNciHal_fw_IoctlCtx.tLogParams.wDnldFailCnt) > 0)
+ {
+ NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_write_cb - Resetting DnldFailCnt");
+ (gphNxpNciHal_fw_IoctlCtx.tLogParams.wDnldFailCnt) = 0;
+ }
+
+ if(FALSE == (gphNxpNciHal_fw_IoctlCtx.tLogParams.bConfig))
+ {
+ NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_write_cb - Setting bConfig for use by NCI mode");
+ (gphNxpNciHal_fw_IoctlCtx.tLogParams.bConfig) = TRUE;
+ }
+ }
+
+ /* Reset the previously set DnldAttemptFailed flag */
+ if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed))
+ {
+ (gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed) = FALSE;
+ }
+ }
+ else
+ {
+ if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated))
+ {
+ (gphNxpNciHal_fw_IoctlCtx.tLogParams.wNumDnldFail) += 1;
+ (gphNxpNciHal_fw_IoctlCtx.tLogParams.wDnldFailCnt) += 1;
+ (gphNxpNciHal_fw_IoctlCtx.tLogParams.bConfig) = FALSE;
+ }
+ if(NFCSTATUS_WRITE_FAILED == status)
+ {
+ (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = TRUE;
+ (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = TRUE;
+ }
+ //status = NFCSTATUS_FAILED;
+
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write_cb - Request Failed!!");
+ }
+
+ p_cb_data->status = status;
+ SEM_POST(p_cb_data);
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_fw_dnld_write
+**
+** Description Download Write
+**
+** Returns NFCSTATUS_SUCCESS if success
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_fw_dnld_write(void* pContext, NFCSTATUS status,
+ void* pInfo)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+ phNxpNciHal_Sem_t cb_data;
+ UNUSED(pContext);
+ UNUSED(status);
+ UNUSED(pInfo);
+ if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bRetryDnld))
+ {
+ (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE;
+ }
+
+ if((TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipSeq))
+ && (FALSE == (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen)))
+ {
+ return NFCSTATUS_SUCCESS;
+ }
+
+ if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write cb_data creation failed");
+ return NFCSTATUS_FAILED;
+ }
+ if(FALSE == (gphNxpNciHal_fw_IoctlCtx.bForceDnld))
+ {
+ NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_write - Incrementing NumDnldTrig..");
+ (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = TRUE;
+ (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts)++;
+ (gphNxpNciHal_fw_IoctlCtx.tLogParams.wNumDnldTrig) += 1;
+ }
+ wStatus = phDnldNfc_Write(FALSE, NULL,
+ (pphDnldNfc_RspCb_t) &phNxpNciHal_fw_dnld_write_cb,
+ (void *) &cb_data);
+ if(FALSE == (gphNxpNciHal_fw_IoctlCtx.bForceDnld))
+ {
+ if (wStatus != NFCSTATUS_PENDING)
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write failed");
+ wStatus = NFCSTATUS_FAILED;
+ (gphNxpNciHal_fw_IoctlCtx.tLogParams.wNumDnldFail) += 1;
+ (gphNxpNciHal_fw_IoctlCtx.tLogParams.wDnldFailCnt) += 1;
+ (gphNxpNciHal_fw_IoctlCtx.tLogParams.bConfig) = FALSE;
+ goto clean_and_return;
+ }
+ }
+ /* Wait for callback response */
+ if (SEM_WAIT(cb_data))
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write semaphore error");
+ wStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ if (cb_data.status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write cb failed");
+ wStatus = cb_data.status;
+ goto clean_and_return;
+ }
+
+ wStatus = NFCSTATUS_SUCCESS;
+
+clean_and_return:
+ phNxpNciHal_cleanup_cb_data(&cb_data);
+
+ return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_fw_dnld_chk_integrity_cb
+**
+** Description Download Check Integrity callback
+**
+** Returns None
+**
+*******************************************************************************/
+static void phNxpNciHal_fw_dnld_chk_integrity_cb(void* pContext,
+ NFCSTATUS status, void* pInfo)
+{
+ phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+ NFCSTATUS wStatus = status;
+ pphDnldNfc_Buff_t pRespBuff;
+ //uint8_t bUserDataCrc[4];
+
+ if ((NFCSTATUS_SUCCESS == wStatus) && (NULL != pInfo))
+ {
+ NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_chk_integrity_cb - Request Successful");
+ pRespBuff = (pphDnldNfc_Buff_t) pInfo;
+
+ if ((31 == (pRespBuff->wLen)) && (NULL != (pRespBuff->pBuff)))
+ {
+ NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_chk_integrity_cb - Valid Resp Buff!!...\n");
+ wStatus = phLibNfc_VerifyCrcStatus(pRespBuff->pBuff[0]);
+ /*
+ memcpy(bUserDataCrc, &(pRespBuff->pBuff[27]),
+ sizeof(bUserDataCrc));*/
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity_cb - Resp Buff Invalid...\n");
+ }
+ }
+ else
+ {
+ wStatus = NFCSTATUS_FAILED;
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity_cb - Request Failed!!");
+ }
+
+ p_cb_data->status = wStatus;
+
+ SEM_POST(p_cb_data);
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_fw_dnld_chk_integrity
+**
+** Description Download Check Integrity
+**
+** Returns NFCSTATUS_SUCCESS if success
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_fw_dnld_chk_integrity(void* pContext,
+ NFCSTATUS status, void* pInfo)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+ phNxpNciHal_Sem_t cb_data;
+ phDnldNfc_Buff_t tDnldBuff;
+ static uint8_t bChkIntgRes[31];
+ UNUSED(pInfo);
+ UNUSED(pContext);
+ UNUSED(status);
+ if(TRUE == gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen)
+ {
+ NXPLOG_FWDNLD_D("Previous Upload session is open..Cannot issue ChkIntegrity Cmd!!");
+ return NFCSTATUS_SUCCESS;
+ }
+
+ if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipSeq))
+ {
+ return NFCSTATUS_SUCCESS;
+ }
+ else if(TRUE == gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen)
+ {
+ NXPLOG_FWDNLD_E("Previous Upload session is open..Cannot issue ChkIntegrity Cmd!!");
+ return NFCSTATUS_SUCCESS;
+ }
+
+ tDnldBuff.pBuff = bChkIntgRes;
+ tDnldBuff.wLen = sizeof(bChkIntgRes);
+
+ if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity cb_data creation failed");
+ return NFCSTATUS_FAILED;
+ }
+
+ wStatus = phDnldNfc_CheckIntegrity((gphNxpNciHal_fw_IoctlCtx.bChipVer),
+ &tDnldBuff, &phNxpNciHal_fw_dnld_chk_integrity_cb,
+ (void *) &cb_data);
+ if (wStatus != NFCSTATUS_PENDING)
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity failed");
+ wStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ /* Wait for callback response */
+ if (SEM_WAIT(cb_data))
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity semaphore error");
+ wStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ if (cb_data.status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity cb failed");
+ wStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ wStatus = NFCSTATUS_SUCCESS;
+
+clean_and_return:
+ phNxpNciHal_cleanup_cb_data(&cb_data);
+
+ return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_fw_dnld_recover
+**
+** Description Download Recover
+**
+** Returns NFCSTATUS_SUCCESS if success
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_fw_dnld_recover(void* pContext, NFCSTATUS status,
+ void* pInfo)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+ phNxpNciHal_Sem_t cb_data;
+
+ UNUSED(pInfo);
+ UNUSED(status);
+ UNUSED(pContext);
+ if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery))
+ {
+ if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_recover cb_data creation failed");
+ return NFCSTATUS_FAILED;
+ }
+ (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts)++;
+
+ /* resetting this flag to avoid cyclic issuance of recovery sequence in case of failure */
+ (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = FALSE;
+
+ wStatus = phDnldNfc_Write(TRUE,NULL,(pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_recover_cb, (void*) &cb_data);
+
+ if(NFCSTATUS_PENDING != wStatus)
+ {
+ (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = FALSE;
+ (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE;
+ goto clean_and_return;
+ }
+ /* Wait for callback response */
+ if (SEM_WAIT(cb_data))
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_recover semaphore error");
+ wStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ if (cb_data.status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_recover cb failed");
+ wStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+ wStatus = NFCSTATUS_SUCCESS;
+
+clean_and_return:
+ phNxpNciHal_cleanup_cb_data(&cb_data);
+ }
+
+ return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_fw_dnld_recover_cb
+**
+** Description Download Recover callback
+**
+** Returns None
+**
+*******************************************************************************/
+static void phNxpNciHal_fw_dnld_recover_cb(void* pContext, NFCSTATUS status,
+ void* pInfo)
+{
+ phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+ NFCSTATUS wStatus = status;
+ UNUSED(pContext);
+ UNUSED(pInfo);
+
+ if(NFCSTATUS_SUCCESS == wStatus)
+ {
+ if(FALSE == (gphNxpNciHal_fw_IoctlCtx.bSkipForce))
+ {
+ NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_recoverCb - Request Successful");
+ (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = TRUE;
+ }
+ else
+ {
+ NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_recoverCb - Production key update Request Successful");
+ (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = TRUE;
+ }
+ }
+ else
+ {
+ wStatus = NFCSTATUS_FAILED;
+ NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_recoverCb - Request Failed!!");
+ }
+
+ /* resetting this flag to avoid cyclic issuance of recovery sequence in case of failure */
+ (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = FALSE;
+
+ /* reset previously set SkipForce */
+ (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = FALSE;
+ p_cb_data->status = wStatus;
+
+ SEM_POST(p_cb_data);
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_fw_dnld_send_ncicmd_cb
+**
+** Description Download Send NCI Command callback
+**
+** Returns None
+**
+*******************************************************************************/
+static void phNxpNciHal_fw_dnld_send_ncicmd_cb(void* pContext, NFCSTATUS status,
+ void* pInfo)
+{
+ phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+ NFCSTATUS wStatus = status;
+ pphDnldNfc_Buff_t pRespBuff;
+ UNUSED(pContext);
+
+ if(NFCSTATUS_SUCCESS == wStatus)
+ {
+ NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_send_ncicmdCb - Request Successful");
+ pRespBuff = (pphDnldNfc_Buff_t)pInfo;
+
+ if((0 != (pRespBuff->wLen)) && (NULL != (pRespBuff->pBuff)))
+ {
+ if(0 == (pRespBuff->pBuff[3]))
+ {
+ NXPLOG_FWDNLD_D("Successful Response received for Nci Reset Cmd");
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Nci Reset Request Failed!!");
+ }
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Invalid Response received for Nci Reset Request!!");
+ }
+ /* Call Tml Ioctl to enable download mode */
+ wStatus = phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode);
+
+ if(NFCSTATUS_SUCCESS == wStatus)
+ {
+ NXPLOG_FWDNLD_D("Switched Successfully to dnld mode..");
+ (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = TRUE;
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Switching back to dnld mode Failed!!");
+ (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE;
+ wStatus = NFCSTATUS_FAILED;
+ }
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_send_ncicmdCb - Request Failed!!");
+ }
+
+ (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = FALSE;
+ p_cb_data->status = wStatus;
+
+ SEM_POST(p_cb_data);
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_fw_dnld_send_ncicmd
+**
+** Description Download Send NCI Command
+**
+** Returns NFCSTATUS_SUCCESS if success
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_fw_dnld_send_ncicmd(void* pContext, NFCSTATUS status,
+ void* pInfo)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+ static uint8_t bNciCmd[4] = {0x20,0x00,0x01,0x00}; /* Nci Reset Cmd with KeepConfig option */
+ static uint8_t bNciResp[6];
+ phDnldNfc_Buff_t tsData;
+ phDnldNfc_Buff_t trData;
+ phNxpNciHal_Sem_t cb_data;
+
+ UNUSED(pInfo);
+ UNUSED(status);
+ UNUSED(pContext);
+ if(FALSE == (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd))
+ {
+ return NFCSTATUS_SUCCESS;
+ }
+ else
+ {
+ /* Call Tml Ioctl to enable/restore normal mode */
+ wStatus = phTmlNfc_IoCtl(phTmlNfc_e_EnableNormalMode);
+
+ if(NFCSTATUS_SUCCESS != wStatus)
+ {
+ NXPLOG_FWDNLD_E("Switching to NormalMode Failed!!");
+ (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE;
+ (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = FALSE;
+ }
+ else
+ {
+ if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_send_ncicmd cb_data creation failed");
+ return NFCSTATUS_FAILED;
+ }
+ (tsData.pBuff) = bNciCmd;
+ (tsData.wLen) = sizeof(bNciCmd);
+ (trData.pBuff) = bNciResp;
+ (trData.wLen) = sizeof(bNciResp);
+
+ wStatus = phDnldNfc_RawReq(&tsData,&trData,
+ (pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_send_ncicmd_cb, (void*) &cb_data);
+ if(NFCSTATUS_PENDING != wStatus)
+ {
+ goto clean_and_return;
+ }
+ /* Wait for callback response */
+ if (SEM_WAIT(cb_data))
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_send_ncicmd semaphore error");
+ wStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ if (cb_data.status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_send_ncicmd cb failed");
+ wStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+ wStatus = NFCSTATUS_SUCCESS;
+
+clean_and_return:
+ phNxpNciHal_cleanup_cb_data(&cb_data);
+ }
+ }
+
+ return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_fw_dnld_log_cb
+**
+** Description Download Log callback
+**
+** Returns None
+**
+*******************************************************************************/
+static void phNxpNciHal_fw_dnld_log_cb(void* pContext, NFCSTATUS status,
+ void* pInfo)
+{
+ phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+ NFCSTATUS wStatus = status;
+ UNUSED(pContext);
+ UNUSED(pInfo);
+
+ if(NFCSTATUS_SUCCESS == wStatus)
+ {
+ NXPLOG_FWDNLD_D("phLibNfc_DnldLogCb - Request Successful");
+ (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = FALSE;
+ }
+ else
+ {
+ wStatus = NFCSTATUS_FAILED;
+ NXPLOG_FWDNLD_E("phLibNfc_DnldLogCb - Request Failed!!");
+ }
+ p_cb_data->status = wStatus;
+
+ SEM_POST(p_cb_data);
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_fw_dnld_log
+**
+** Description Download Log
+**
+** Returns NFCSTATUS_SUCCESS if success
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_fw_dnld_log(void* pContext, NFCSTATUS status,
+ void* pInfo)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+ phNxpNciHal_Sem_t cb_data;
+ phDnldNfc_Buff_t tData;
+
+ UNUSED(pInfo);
+ UNUSED(status);
+ UNUSED(pContext);
+ if(((TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipSeq)) ||
+ (TRUE == (gphNxpNciHal_fw_IoctlCtx.bForceDnld))) &&
+ (FALSE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated)))
+ {
+ return NFCSTATUS_SUCCESS;
+ }
+ else
+ {
+ if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log cb_data creation failed");
+ return NFCSTATUS_FAILED;
+ }
+ (tData.pBuff) = (void *)&(gphNxpNciHal_fw_IoctlCtx.tLogParams);
+ (tData.wLen) = sizeof(gphNxpNciHal_fw_IoctlCtx.tLogParams);
+
+ wStatus = phDnldNfc_Log(&tData,(pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_log_cb, (void*) &cb_data);
+
+ if (wStatus != NFCSTATUS_PENDING)
+ {
+ NXPLOG_FWDNLD_E("phDnldNfc_Log failed");
+ (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = FALSE;
+ wStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+ /* Wait for callback response */
+ if (SEM_WAIT(cb_data))
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log semaphore error");
+ wStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ if (cb_data.status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_cb failed");
+ wStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ wStatus = NFCSTATUS_SUCCESS;
+
+clean_and_return:
+ phNxpNciHal_cleanup_cb_data(&cb_data);
+
+ return wStatus;
+ }
+
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_fw_seq_handler
+**
+** Description Sequence Handler
+**
+** Returns NFCSTATUS_SUCCESS if sequence completed uninterrupted
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_fw_seq_handler(NFCSTATUS (*seq_handler[])(void* pContext, NFCSTATUS status, void* pInfo))
+{
+ char *pContext = "FW-Download";
+ int16_t seq_counter = 0;
+ phDnldNfc_Buff_t pInfo;
+ NFCSTATUS status = NFCSTATUS_FAILED;
+
+ status = phTmlNfc_ReadAbort();
+ if(NFCSTATUS_SUCCESS != status)
+ {
+ NXPLOG_FWDNLD_E("Tml Read Abort failed!!");
+ return status;
+ }
+
+ while(seq_handler[seq_counter] != NULL )
+ {
+ status = NFCSTATUS_FAILED;
+ status = (seq_handler[seq_counter])(pContext, status, &pInfo );
+ if(NFCSTATUS_SUCCESS != status)
+ {
+ NXPLOG_FWDNLD_E(" phNxpNciHal_fw_seq_handler : FAILED");
+ break;
+ }
+ seq_counter++;
+ }
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_fw_dnld_complete
+**
+** Description Download Sequence Complete
+**
+** Returns NFCSTATUS_SUCCESS if success
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_fw_dnld_complete(void* pContext,NFCSTATUS status,
+ void* pInfo)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+ NFCSTATUS fStatus = status;
+ UNUSED(pInfo);
+ UNUSED(pContext);
+
+ if(NFCSTATUS_WRITE_FAILED == status)
+ {
+ if((gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) < PHLIBNFC_IOCTL_DNLD_MAX_ATTEMPTS)
+ {
+ (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = TRUE;
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Max Dnld Retry Counts Exceeded!!");
+ (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = FALSE;
+ (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE;
+ }
+ }
+ else if(NFCSTATUS_REJECTED == status)
+ {
+ if((gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) < PHLIBNFC_IOCTL_DNLD_MAX_ATTEMPTS)
+ {
+ (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = TRUE;
+
+ /* in case of signature error we need to try recover sequence directly bypassing the force cmd */
+ (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = TRUE;
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("Max Dnld Retry Counts Exceeded!!");
+ (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = FALSE;
+ (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE;
+ }
+ }
+
+ if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated))
+ {
+ (gphNxpNciHal_fw_IoctlCtx.bLastStatus) = status;
+ (gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed) = TRUE;
+
+ NXPLOG_FWDNLD_E("Invoking Pending Download Log Sequence..");
+ (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = FALSE;
+ /* Perform the Logging sequence */
+ wStatus = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_log_seqhandler);
+ 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 */
+ wStatus = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_seqhandler);
+
+ status = phNxpNciHal_fw_dnld_complete(pContext, wStatus, &pInfo);
+ if (NFCSTATUS_SUCCESS == status)
+ {
+ NXPLOG_FWDNLD_D(" phNxpNciHal_fw_dnld_complete : SUCCESS");
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E(" phNxpNciHal_fw_dnld_complete : FAILED");
+ }
+ }
+ else
+ {
+ 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)
+{
+ NFCSTATUS status = NFCSTATUS_FAILED;
+ phDnldNfc_Buff_t pInfo;
+ char *pContext = "FW-Download";
+
+ /* reset the global flags */
+ gphNxpNciHal_fw_IoctlCtx.IoctlCode = NFC_FW_DOWNLOAD;
+ (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) = FALSE;
+ (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = FALSE;
+ (gphNxpNciHal_fw_IoctlCtx.bChipVer) = 0;
+ (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = FALSE;
+ (gphNxpNciHal_fw_IoctlCtx.bForceDnld) = FALSE;
+ (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = FALSE;
+ (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE;
+ (gphNxpNciHal_fw_IoctlCtx.bSkipReset) = FALSE;
+ (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = FALSE;
+ (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = FALSE;
+ (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) = 0;
+ (gphNxpNciHal_fw_IoctlCtx.bClkSrcVal) = bClkSrcVal;
+ (gphNxpNciHal_fw_IoctlCtx.bClkFreqVal) = bClkFreqVal;
+ /* Get firmware version */
+ if (NFCSTATUS_SUCCESS == phDnldNfc_InitImgInfo())
+ {
+ NXPLOG_FWDNLD_D("phDnldNfc_InitImgInfo:SUCCESS");
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+ if(gRecFWDwnld == TRUE)
+ {
+ status = phNxpNciHal_fw_seq_handler(phNxpNciHal_dummy_rec_dwnld_seqhandler);
+ }else
+#endif
+ {
+ status = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_seqhandler);
+ }
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E("phDnldNfc_InitImgInfo: FAILED");
+ }
+
+ /* Chage to normal mode */
+ status = phNxpNciHal_fw_dnld_complete(pContext, status, &pInfo);
+ /*if (NFCSTATUS_SUCCESS == status)
+ {
+ NXPLOG_FWDNLD_D(" phNxpNciHal_fw_dnld_complete : SUCCESS");
+ }
+ else
+ {
+ NXPLOG_FWDNLD_E(" phNxpNciHal_fw_dnld_complete : FAILED");
+ }*/
+
+ return status;
+}
+
+static
+NFCSTATUS
+phLibNfc_VerifyCrcStatus(uint8_t bCrcStatus)
+{
+ uint8_t bBitPos = 0;
+ uint8_t bShiftVal = 1;
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+ while(bBitPos < 7)
+ {
+ if(!(bCrcStatus & bShiftVal))
+ {
+ switch(bBitPos)
+ {
+ case 0:
+ {
+ NXPLOG_FWDNLD_E("User Data Crc is NOT OK!!");
+ wStatus = NFCSTATUS_FAILED;
+ break;
+ }
+ case 1:
+ {
+ NXPLOG_FWDNLD_E("Trim Data Crc is NOT OK!!");
+ wStatus = NFCSTATUS_FAILED;
+ break;
+ }
+ case 2:
+ {
+ NXPLOG_FWDNLD_E("Protected Data Crc is NOT OK!!");
+ wStatus = NFCSTATUS_FAILED;
+ break;
+ }
+ case 3:
+ {
+ NXPLOG_FWDNLD_E("Patch Code Crc is NOT OK!!");
+ wStatus = NFCSTATUS_FAILED;
+ break;
+ }
+ case 4:
+ {
+ NXPLOG_FWDNLD_E("Function Code Crc is NOT OK!!");
+ wStatus = NFCSTATUS_FAILED;
+ break;
+ }
+ case 5:
+ {
+ NXPLOG_FWDNLD_E("Patch Table Crc is NOT OK!!");
+ wStatus = NFCSTATUS_FAILED;
+ break;
+ }
+ case 6:
+ {
+ NXPLOG_FWDNLD_E("Function Table Crc is NOT OK!!");
+ wStatus = NFCSTATUS_FAILED;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ bShiftVal <<= 1;
+ ++bBitPos;
+ }
+
+ return wStatus;
+}
diff --git a/halimpl/pn54x/dnld/phNxpNciHal_Dnld.h b/halimpl/pn54x/dnld/phNxpNciHal_Dnld.h
new file mode 100644
index 0000000..59e8ad9
--- /dev/null
+++ b/halimpl/pn54x/dnld/phNxpNciHal_Dnld.h
@@ -0,0 +1,24 @@
+/*
+ * 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);
+
+#endif /* _PHNXPNCIHAL_DNLD_H_ */
diff --git a/halimpl/pn54x/hal/phNxpNciHal.c b/halimpl/pn54x/hal/phNxpNciHal.c
new file mode 100644
index 0000000..4cf7f64
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal.c
@@ -0,0 +1,2735 @@
+/*
+ * 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>
+/*********************** Global Variables *************************************/
+#define PN547C2_CLOCK_SETTING
+#undef PN547C2_FACTORY_RESET_DEBUG
+#define CORE_RES_STATUS_BYTE 3
+/* Processing of ISO 15693 EOF */
+extern uint8_t icode_send_eof;
+static uint8_t cmd_icode_eof[] = { 0x00, 0x00, 0x00 };
+
+/* FW download success flag */
+static uint8_t fw_download_success = 0;
+
+static uint8_t config_access = FALSE;
+/* NCI HAL Control structure */
+phNxpNciHal_Control_t nxpncihal_ctrl;
+
+/* NXP Poll Profile structure */
+phNxpNciProfile_Control_t nxpprofile_ctrl;
+
+/* TML Context */
+extern phTmlNfc_Context_t *gpphTmlNfc_Context;
+extern void phTmlNfc_set_fragmentation_enabled(phTmlNfc_i2cfragmentation_t result);
+/* global variable to get FW version from NCI response*/
+uint32_t wFwVerRsp;
+/* External global variable to get FW version */
+extern uint16_t wFwVer;
+extern int send_to_upper_kovio;
+extern int kovio_detected;
+extern int disable_kovio;
+extern bool_t rf_deactive_cmd;
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+extern uint8_t gRecFWDwnld;// flag set to true to indicate dummy FW download
+static uint8_t gRecFwRetryCount; //variable to hold dummy FW recovery count
+#endif
+static uint8_t Rx_data[NCI_MAX_DATA_LEN];
+
+uint32_t timeoutTimerId = 0;
+phNxpNciHal_Sem_t config_data;
+
+phNxpNciClock_t phNxpNciClock={0,};
+
+phNxpNciRfSetting_t phNxpNciRfSet={0,};
+
+/**************** local methods used in this file only ************************/
+static NFCSTATUS phNxpNciHal_fw_download(void);
+static void phNxpNciHal_open_complete(NFCSTATUS status);
+static void phNxpNciHal_write_complete(void *pContext, phTmlNfc_TransactInfo_t *pInfo);
+static void phNxpNciHal_read_complete(void *pContext, phTmlNfc_TransactInfo_t *pInfo);
+static void phNxpNciHal_close_complete(NFCSTATUS status);
+static void phNxpNciHal_core_initialized_complete(NFCSTATUS status);
+static void phNxpNciHal_pre_discover_complete(NFCSTATUS status);
+static void phNxpNciHal_power_cycle_complete(NFCSTATUS status);
+static void phNxpNciHal_kill_client_thread(phNxpNciHal_Control_t *p_nxpncihal_ctrl);
+static void *phNxpNciHal_client_thread(void *arg);
+static void phNxpNciHal_get_clk_freq(void);
+static void phNxpNciHal_set_clock(void);
+static void phNxpNciHal_check_factory_reset(void);
+static void phNxpNciHal_print_res_status( uint8_t *p_rx_data, uint16_t *p_len);
+static NFCSTATUS phNxpNciHal_CheckValidFwVersion(void);
+static void phNxpNciHal_enable_i2c_fragmentation();
+NFCSTATUS phNxpNciHal_check_clock_config(void);
+NFCSTATUS phNxpNciHal_china_tianjin_rf_setting(void);
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+static NFCSTATUS phNxpNciHalRFConfigCmdRecSequence();
+static NFCSTATUS phNxpNciHal_CheckRFCmdRespStatus();
+#endif
+int check_config_parameter();
+static NFCSTATUS phNxpNciHal_uicc_baud_rate();
+/******************************************************************************
+ * Function phNxpNciHal_client_thread
+ *
+ * Description This function is a thread handler which handles all TML and
+ * NCI messages.
+ *
+ * Returns void
+ *
+ ******************************************************************************/
+static void *phNxpNciHal_client_thread(void *arg)
+{
+ phNxpNciHal_Control_t *p_nxpncihal_ctrl = (phNxpNciHal_Control_t *) arg;
+ phLibNfc_Message_t msg;
+
+ NXPLOG_NCIHAL_D("thread started");
+
+ p_nxpncihal_ctrl->thread_running = 1;
+
+ while (p_nxpncihal_ctrl->thread_running == 1)
+ {
+ /* Fetch next message from the NFC stack message queue */
+ if (phDal4Nfc_msgrcv(p_nxpncihal_ctrl->gDrvCfg.nClientId,
+ &msg, 0, 0) == -1)
+ {
+ NXPLOG_NCIHAL_E("NFC client received bad message");
+ continue;
+ }
+
+ if(p_nxpncihal_ctrl->thread_running == 0){
+ break;
+ }
+
+ switch (msg.eMsgType)
+ {
+ case PH_LIBNFC_DEFERREDCALL_MSG:
+ {
+ phLibNfc_DeferredCall_t *deferCall =
+ (phLibNfc_DeferredCall_t *) (msg.pMsgData);
+
+ REENTRANCE_LOCK();
+ deferCall->pCallback(deferCall->pParameter);
+ REENTRANCE_UNLOCK();
+
+ break;
+ }
+
+ case NCI_HAL_OPEN_CPLT_MSG:
+ {
+ REENTRANCE_LOCK();
+ if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
+ {
+ /* Send the event */
+ (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_OPEN_CPLT_EVT,
+ HAL_NFC_STATUS_OK);
+ }
+ REENTRANCE_UNLOCK();
+ break;
+ }
+
+ case NCI_HAL_CLOSE_CPLT_MSG:
+ {
+ REENTRANCE_LOCK();
+ if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
+ {
+ /* Send the event */
+ (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_CLOSE_CPLT_EVT,
+ HAL_NFC_STATUS_OK);
+ phNxpNciHal_kill_client_thread(&nxpncihal_ctrl);
+ }
+ REENTRANCE_UNLOCK();
+ break;
+ }
+
+ case NCI_HAL_POST_INIT_CPLT_MSG:
+ {
+ REENTRANCE_LOCK();
+ if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
+ {
+ /* Send the event */
+ (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_POST_INIT_CPLT_EVT,
+ HAL_NFC_STATUS_OK);
+ }
+ REENTRANCE_UNLOCK();
+ break;
+ }
+
+ case NCI_HAL_PRE_DISCOVER_CPLT_MSG:
+ {
+ REENTRANCE_LOCK();
+ if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
+ {
+ /* Send the event */
+ (*nxpncihal_ctrl.p_nfc_stack_cback)(
+ HAL_NFC_PRE_DISCOVER_CPLT_EVT, HAL_NFC_STATUS_OK);
+ }
+ REENTRANCE_UNLOCK();
+ break;
+ }
+
+ case NCI_HAL_ERROR_MSG:
+ {
+ REENTRANCE_LOCK();
+ if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
+ {
+ /* Send the event */
+ (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_ERROR_EVT,
+ HAL_NFC_STATUS_FAILED);
+ }
+ REENTRANCE_UNLOCK();
+ break;
+ }
+
+ case NCI_HAL_RX_MSG:
+ {
+ REENTRANCE_LOCK();
+ if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL)
+ {
+ (*nxpncihal_ctrl.p_nfc_stack_data_cback)(
+ nxpncihal_ctrl.rsp_len, nxpncihal_ctrl.p_rsp_data);
+ }
+ REENTRANCE_UNLOCK();
+ break;
+ }
+ }
+ }
+
+ NXPLOG_NCIHAL_D("NxpNciHal thread stopped");
+
+ return NULL;
+}
+
+/******************************************************************************
+ * Function phNxpNciHal_kill_client_thread
+ *
+ * Description This function safely kill the client thread and clean all
+ * resources.
+ *
+ * Returns void.
+ *
+ ******************************************************************************/
+static void phNxpNciHal_kill_client_thread(phNxpNciHal_Control_t *p_nxpncihal_ctrl)
+{
+ NXPLOG_NCIHAL_D("Terminating phNxpNciHal client thread...");
+
+ p_nxpncihal_ctrl->p_nfc_stack_cback = NULL;
+ p_nxpncihal_ctrl->p_nfc_stack_data_cback = NULL;
+ p_nxpncihal_ctrl->thread_running = 0;
+
+ return;
+}
+
+/******************************************************************************
+ * Function phNxpNciHal_fw_download
+ *
+ * Description This function download the PN54X secure firmware to IC. If
+ * firmware version in Android filesystem and firmware in the
+ * IC is same then firmware download will return with success
+ * without downloading the firmware.
+ *
+ * Returns NFCSTATUS_SUCCESS if firmware download successful
+ * NFCSTATUS_FAILED in case of failure
+ *
+ ******************************************************************************/
+static NFCSTATUS phNxpNciHal_fw_download(void)
+{
+ NFCSTATUS status = NFCSTATUS_FAILED;
+
+ phNxpNciHal_get_clk_freq();
+ status = phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode);
+ if (NFCSTATUS_SUCCESS == status)
+ {
+ /* Set the obtained device handle to download module */
+ phDnldNfc_SetHwDevHandle();
+ NXPLOG_NCIHAL_D("Calling Seq handler for FW Download \n");
+ status = phNxpNciHal_fw_download_seq(nxpprofile_ctrl.bClkSrcVal, nxpprofile_ctrl.bClkFreqVal);
+ phDnldNfc_ReSetHwDevHandle();
+ }
+ else
+ {
+ status = NFCSTATUS_FAILED;
+ }
+
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpNciHal_CheckValidFwVersion
+ *
+ * Description This function checks the valid FW for Mobile device.
+ * If the FW doesn't belong the Mobile device it further
+ * checks nxp config file to override.
+ *
+ * Returns NFCSTATUS_SUCCESS if valid fw version found
+ * NFCSTATUS_NOT_ALLOWED in case of FW not valid for mobile
+ * device
+ *
+ ******************************************************************************/
+static NFCSTATUS phNxpNciHal_CheckValidFwVersion(void)
+{
+ NFCSTATUS status = NFCSTATUS_NOT_ALLOWED;
+ const unsigned char sfw_mobile_major_no = 0x01;
+ const unsigned char sfw_infra_major_no = 0x02;
+ unsigned char ufw_current_major_no = 0x00;
+ unsigned long num = 0;
+ int isfound = 0;
+
+ /* extract the firmware's major no */
+ ufw_current_major_no = ((0x00FF) & (wFwVer >> 8U));
+
+ NXPLOG_NCIHAL_D("%s current_major_no = 0x%x", __FUNCTION__,ufw_current_major_no );
+ if ( ufw_current_major_no == sfw_mobile_major_no)
+ {
+ status = NFCSTATUS_SUCCESS;
+ }
+ else if (ufw_current_major_no == sfw_infra_major_no)
+ {
+ /* Check the nxp config file if still want to go for download */
+ /* By default NAME_NXP_FW_PROTECION_OVERRIDE will not be defined in config file.
+ If user really want to override the Infra firmware over mobile firmware, please
+ put "NXP_FW_PROTECION_OVERRIDE=0x01" in libnfc-nxp.conf file.
+ Please note once Infra firmware downloaded to Mobile device, The device
+ can never be updated to Mobile firmware*/
+ isfound = GetNxpNumValue(NAME_NXP_FW_PROTECION_OVERRIDE, &num, sizeof(num));
+ if (isfound > 0)
+ {
+ if (num == 0x01)
+ {
+ NXPLOG_NCIHAL_D("Override Infra FW over Mobile");
+ status = NFCSTATUS_SUCCESS;
+ }
+ else
+ {
+ NXPLOG_NCIHAL_D("Firmware download not allowed (NXP_FW_PROTECION_OVERRIDE invalid value)");
+ }
+ }
+ else
+ {
+ NXPLOG_NCIHAL_D("Firmware download not allowed (NXP_FW_PROTECION_OVERRIDE not defiend)");
+ }
+ }
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+ else if(gRecFWDwnld == TRUE)
+ {
+ status = NFCSTATUS_SUCCESS;
+ }
+#endif
+ else if (wFwVerRsp == 0)
+ {
+ NXPLOG_NCIHAL_E("FW Version not received by NCI command >>> Force Firmware download");
+ status = NFCSTATUS_SUCCESS;
+ }
+ else
+ {
+ NXPLOG_NCIHAL_E("Wrong FW Version >>> Firmware download not allowed");
+ }
+
+ return status;
+}
+
+static void phNxpNciHal_get_clk_freq(void)
+{
+ unsigned long num = 0;
+ int isfound = 0;
+
+ nxpprofile_ctrl.bClkSrcVal = 0;
+ nxpprofile_ctrl.bClkFreqVal = 0;
+ nxpprofile_ctrl.bTimeout = 0;
+
+ isfound = GetNxpNumValue(NAME_NXP_SYS_CLK_SRC_SEL, &num, sizeof(num));
+ if (isfound > 0)
+ {
+ nxpprofile_ctrl.bClkSrcVal = num;
+ }
+
+ num = 0;
+ isfound = 0;
+ isfound = GetNxpNumValue(NAME_NXP_SYS_CLK_FREQ_SEL, &num, sizeof(num));
+ if (isfound > 0)
+ {
+ nxpprofile_ctrl.bClkFreqVal = num;
+ }
+
+ num = 0;
+ isfound = 0;
+ isfound = GetNxpNumValue(NAME_NXP_SYS_CLOCK_TO_CFG, &num, sizeof(num));
+ if (isfound > 0)
+ {
+ nxpprofile_ctrl.bTimeout = num;
+ }
+
+ NXPLOG_FWDNLD_D("gphNxpNciHal_fw_IoctlCtx.bClkSrcVal = 0x%x", nxpprofile_ctrl.bClkSrcVal);
+ NXPLOG_FWDNLD_D("gphNxpNciHal_fw_IoctlCtx.bClkFreqVal = 0x%x", nxpprofile_ctrl.bClkFreqVal);
+ NXPLOG_FWDNLD_D("gphNxpNciHal_fw_IoctlCtx.bClkFreqVal = 0x%x", nxpprofile_ctrl.bTimeout);
+
+ if ((nxpprofile_ctrl.bClkSrcVal < CLK_SRC_XTAL) ||
+ (nxpprofile_ctrl.bClkSrcVal > CLK_SRC_PLL))
+ {
+ NXPLOG_FWDNLD_E("Clock source value is wrong in config file, setting it as default");
+ nxpprofile_ctrl.bClkSrcVal = NXP_SYS_CLK_SRC_SEL;
+ }
+ if ((nxpprofile_ctrl.bClkFreqVal < CLK_FREQ_13MHZ) ||
+ (nxpprofile_ctrl.bClkFreqVal > CLK_FREQ_52MHZ))
+ {
+ NXPLOG_FWDNLD_E("Clock frequency value is wrong in config file, setting it as default");
+ nxpprofile_ctrl.bClkFreqVal = NXP_SYS_CLK_FREQ_SEL;
+ }
+ if ((nxpprofile_ctrl.bTimeout < CLK_TO_CFG_DEF) || (nxpprofile_ctrl.bTimeout > CLK_TO_CFG_MAX))
+ {
+ NXPLOG_FWDNLD_E("Clock timeout value is wrong in config file, setting it as default");
+ nxpprofile_ctrl.bTimeout = CLK_TO_CFG_DEF;
+ }
+
+}
+
+/******************************************************************************
+ * Function phNxpNciHal_open
+ *
+ * Description This function is called by libnfc-nci during the
+ * initialization of the NFCC. It opens the physical connection
+ * with NFCC (PN54X) and creates required client thread for
+ * operation.
+ * After open is complete, status is informed to libnfc-nci
+ * through callback function.
+ *
+ * Returns This function return NFCSTATUS_SUCCES (0) in case of success
+ * In case of failure returns other failure value.
+ *
+ ******************************************************************************/
+int phNxpNciHal_open(nfc_stack_callback_t *p_cback, nfc_stack_data_callback_t *p_data_cback)
+{
+ phOsalNfc_Config_t tOsalConfig;
+ phTmlNfc_Config_t tTmlConfig;
+ NFCSTATUS wConfigStatus = NFCSTATUS_SUCCESS;
+ NFCSTATUS status = NFCSTATUS_SUCCESS;
+ /*NCI_INIT_CMD*/
+ static uint8_t cmd_init_nci[] = {0x20,0x01,0x00};
+ /*NCI_RESET_CMD*/
+ static uint8_t cmd_reset_nci[] = {0x20,0x00,0x01,0x01};
+ /* reset config cache */
+ resetNxpConfig();
+
+ int init_retry_cnt=0;
+ int8_t ret_val = 0x00;
+ /* initialize trace level */
+ phNxpLog_InitializeLogLevel();
+
+ /*Create the timer for extns write response*/
+ timeoutTimerId = phOsalNfc_Timer_Create();
+
+ if (phNxpNciHal_init_monitor() == NULL)
+ {
+ NXPLOG_NCIHAL_E("Init monitor failed");
+ return NFCSTATUS_FAILED;
+ }
+
+ CONCURRENCY_LOCK();
+
+ memset(&nxpncihal_ctrl, 0x00, sizeof(nxpncihal_ctrl));
+ memset(&tOsalConfig, 0x00, sizeof(tOsalConfig));
+ memset(&tTmlConfig, 0x00, sizeof(tTmlConfig));
+ memset (&nxpprofile_ctrl, 0, sizeof(phNxpNciProfile_Control_t));
+
+ /* By default HAL status is HAL_STATUS_OPEN */
+ nxpncihal_ctrl.halStatus = HAL_STATUS_OPEN;
+
+ nxpncihal_ctrl.p_nfc_stack_cback = p_cback;
+ nxpncihal_ctrl.p_nfc_stack_data_cback = p_data_cback;
+
+ /* Configure hardware link */
+ nxpncihal_ctrl.gDrvCfg.nClientId = phDal4Nfc_msgget(0, 0600);
+ nxpncihal_ctrl.gDrvCfg.nLinkType = ENUM_LINK_TYPE_I2C;/* For PN54X */
+ tTmlConfig.pDevName = (int8_t *) "/dev/pn544";
+ tOsalConfig.dwCallbackThreadId
+ = (uintptr_t) nxpncihal_ctrl.gDrvCfg.nClientId;
+ tOsalConfig.pLogFile = NULL;
+ tTmlConfig.dwGetMsgThreadId = (uintptr_t) nxpncihal_ctrl.gDrvCfg.nClientId;
+
+ /* Initialize TML layer */
+ wConfigStatus = phTmlNfc_Init(&tTmlConfig);
+ if (wConfigStatus != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E("phTmlNfc_Init Failed");
+ goto clean_and_return;
+ }
+
+ /* Create the client thread */
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ 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("Force FW Download, NFCC not coming out from Standby");
+ wConfigStatus = NFCSTATUS_FAILED;
+ goto force_download;
+ }
+ else if(status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E ("NCI_CORE_RESET: Failed");
+ if(init_retry_cnt < 3) {
+ init_retry_cnt++;
+ (void)phNxpNciHal_power_cycle();
+ goto init_retry;
+ } else
+ init_retry_cnt = 0;
+ wConfigStatus = phTmlNfc_Shutdown();
+ wConfigStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci),cmd_init_nci);
+ if(status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E ("NCI_CORE_INIT : Failed");
+ if(init_retry_cnt < 3) {
+ init_retry_cnt++;
+ (void)phNxpNciHal_power_cycle();
+ goto init_retry;
+ } else
+ init_retry_cnt = 0;
+ wConfigStatus = phTmlNfc_Shutdown();
+ wConfigStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+ phNxpNciHal_enable_i2c_fragmentation();
+ /*Get FW version from device*/
+ status = phDnldNfc_InitImgInfo();
+ NXPLOG_NCIHAL_D ("FW version for FW file = 0x%x", wFwVer);
+ NXPLOG_NCIHAL_D ("FW version from device = 0x%x", wFwVerRsp);
+ if ((wFwVerRsp & 0x0000FFFF) == wFwVer)
+ {
+ NXPLOG_NCIHAL_D ("FW uptodate not required");
+ phDnldNfc_ReSetHwDevHandle();
+ }
+ else
+ {
+force_download:
+ if (wFwVerRsp == 0)
+ {
+ phDnldNfc_InitImgInfo();
+ }
+ if (NFCSTATUS_SUCCESS == phNxpNciHal_CheckValidFwVersion())
+ {
+ NXPLOG_NCIHAL_D ("FW update required");
+ fw_download_success = 0;
+ status = phNxpNciHal_fw_download();
+ if (status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E ("FW Download failed - NFCC init will continue");
+ }
+ else
+ {
+ wConfigStatus = NFCSTATUS_SUCCESS;
+ fw_download_success = 1;
+ /* call read pending */
+ status = phTmlNfc_Read(
+ nxpncihal_ctrl.p_cmd_data,
+ NCI_MAX_DATA_LEN,
+ (pphTmlNfc_TransactCompletionCb_t) &phNxpNciHal_read_complete,
+ NULL);
+ if (status != NFCSTATUS_PENDING)
+ {
+ NXPLOG_NCIHAL_E("TML Read status error status = %x", status);
+ wConfigStatus = phTmlNfc_Shutdown();
+ wConfigStatus = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+ }
+ }
+ else
+ {
+ if (wFwVerRsp == 0)
+ phDnldNfc_ReSetHwDevHandle();
+ }
+ }
+ /* Call open complete */
+ phNxpNciHal_open_complete(wConfigStatus);
+
+ return wConfigStatus;
+
+ clean_and_return:
+ CONCURRENCY_UNLOCK();
+ /* Report error status */
+ (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_OPEN_CPLT_EVT,
+ HAL_NFC_STATUS_FAILED);
+
+ nxpncihal_ctrl.p_nfc_stack_cback = NULL;
+ nxpncihal_ctrl.p_nfc_stack_data_cback = NULL;
+ phNxpNciHal_cleanup_monitor();
+ nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;
+ return NFCSTATUS_FAILED;
+}
+
+/******************************************************************************
+ * Function phNxpNciHal_open_complete
+ *
+ * Description This function inform the status of phNxpNciHal_open
+ * function to libnfc-nci.
+ *
+ * Returns void.
+ *
+ ******************************************************************************/
+static void phNxpNciHal_open_complete(NFCSTATUS status)
+{
+ static phLibNfc_Message_t msg;
+
+ if (status == NFCSTATUS_SUCCESS)
+ {
+ msg.eMsgType = NCI_HAL_OPEN_CPLT_MSG;
+ nxpncihal_ctrl.hal_open_status = TRUE;
+ }
+ else
+ {
+ msg.eMsgType = NCI_HAL_ERROR_MSG;
+ }
+
+ msg.pMsgData = NULL;
+ msg.Size = 0;
+
+ phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
+ (phLibNfc_Message_t *) &msg);
+
+ return;
+}
+
+/******************************************************************************
+ * Function phNxpNciHal_write
+ *
+ * Description This function write the data to NFCC through physical
+ * interface (e.g. I2C) using the PN54X driver interface.
+ * Before sending the data to NFCC, phNxpNciHal_write_ext
+ * is called to check if there is any extension processing
+ * is required for the NCI packet being sent out.
+ *
+ * Returns It returns number of bytes successfully written to NFCC.
+ *
+ ******************************************************************************/
+int phNxpNciHal_write(uint16_t data_len, const uint8_t *p_data)
+{
+ NFCSTATUS status = NFCSTATUS_FAILED;
+ static phLibNfc_Message_t msg;
+
+ /* Create local copy of cmd_data */
+ memcpy(nxpncihal_ctrl.p_cmd_data, p_data, data_len);
+ nxpncihal_ctrl.cmd_len = data_len;
+
+#ifdef P2P_PRIO_LOGIC_HAL_IMP
+ /* Specific logic to block RF disable when P2P priority logic is busy */
+ if (p_data[0] == 0x21&&
+ p_data[1] == 0x06 &&
+ p_data[2] == 0x01 &&
+ EnableP2P_PrioLogic == TRUE)
+ {
+ NXPLOG_NCIHAL_D ("P2P priority logic busy: Disable it.");
+ phNxpNciHal_clean_P2P_Prio();
+ }
+#endif
+ /* Specific logic to block RF disable when Kovio detection logic is active */
+ if (p_data[0] == 0x21&&
+ p_data[1] == 0x06 &&
+ p_data[2] == 0x01)
+ {
+ rf_deactive_cmd = TRUE;
+ if(kovio_detected == TRUE)
+ {
+ NXPLOG_NCIHAL_D ("Kovio detection logic is active: Set Flag to disable it.");
+ disable_kovio=0x01;
+ }
+ }
+
+ /* Check for NXP ext before sending write */
+ status = phNxpNciHal_write_ext(&nxpncihal_ctrl.cmd_len,
+ nxpncihal_ctrl.p_cmd_data, &nxpncihal_ctrl.rsp_len,
+ nxpncihal_ctrl.p_rsp_data);
+ if (status != NFCSTATUS_SUCCESS)
+ {
+ /* Do not send packet to PN54X, send response directly */
+ msg.eMsgType = NCI_HAL_RX_MSG;
+ msg.pMsgData = NULL;
+ msg.Size = 0;
+
+ phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
+ (phLibNfc_Message_t *) &msg);
+ goto clean_and_return;
+ }
+
+ CONCURRENCY_LOCK();
+ data_len = phNxpNciHal_write_unlocked(nxpncihal_ctrl.cmd_len,
+ nxpncihal_ctrl.p_cmd_data);
+ CONCURRENCY_UNLOCK();
+
+ if (icode_send_eof == 1)
+ {
+ usleep (10000);
+ icode_send_eof = 2;
+ phNxpNciHal_send_ext_cmd (3, cmd_icode_eof);
+ }
+
+ clean_and_return:
+ /* No data written */
+ return data_len;
+}
+
+/******************************************************************************
+ * Function phNxpNciHal_write_unlocked
+ *
+ * Description This is the actual function which is being called by
+ * phNxpNciHal_write. This function writes the data to NFCC.
+ * It waits till write callback provide the result of write
+ * process.
+ *
+ * Returns It returns number of bytes successfully written to NFCC.
+ *
+ ******************************************************************************/
+int phNxpNciHal_write_unlocked(uint16_t data_len, const uint8_t *p_data)
+{
+ NFCSTATUS status = NFCSTATUS_INVALID_PARAMETER;
+ phNxpNciHal_Sem_t cb_data;
+ nxpncihal_ctrl.retry_cnt = 0;
+ static uint8_t reset_ntf[] = {0x60, 0x00, 0x06, 0xA0, 0x00, 0xC7, 0xD4, 0x00, 0x00};
+
+ /* Create the local semaphore */
+ if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_D("phNxpNciHal_write_unlocked Create cb data failed");
+ data_len = 0;
+ goto clean_and_return;
+ }
+
+ /* Create local copy of cmd_data */
+ memcpy(nxpncihal_ctrl.p_cmd_data, p_data, data_len);
+ nxpncihal_ctrl.cmd_len = data_len;
+
+ retry:
+
+ data_len = nxpncihal_ctrl.cmd_len;
+
+ status = phTmlNfc_Write( (uint8_t *) nxpncihal_ctrl.p_cmd_data,
+ (uint16_t) nxpncihal_ctrl.cmd_len,
+ (pphTmlNfc_TransactCompletionCb_t) &phNxpNciHal_write_complete,
+ (void *) &cb_data);
+ if (status != NFCSTATUS_PENDING)
+ {
+ NXPLOG_NCIHAL_E("write_unlocked status error");
+ data_len = 0;
+ goto clean_and_return;
+ }
+
+ /* Wait for callback response */
+ if (SEM_WAIT(cb_data))
+ {
+ NXPLOG_NCIHAL_E("write_unlocked semaphore error");
+ data_len = 0;
+ goto clean_and_return;
+ }
+
+ if (cb_data.status != NFCSTATUS_SUCCESS)
+ {
+ data_len = 0;
+ if(nxpncihal_ctrl.retry_cnt++ < MAX_RETRY_COUNT)
+ {
+ NXPLOG_NCIHAL_E("write_unlocked failed - PN54X Maybe in Standby Mode - Retry");
+ /* 1ms delay to give NFCC wake up delay */
+ usleep(1000);
+ goto retry;
+ }
+ else
+ {
+
+ NXPLOG_NCIHAL_E("write_unlocked failed - PN54X Maybe in Standby Mode (max count = 0x%x)", nxpncihal_ctrl.retry_cnt);
+
+ status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
+
+ if(NFCSTATUS_SUCCESS == status)
+ {
+ NXPLOG_NCIHAL_D("PN54X Reset - SUCCESS\n");
+ }
+ else
+ {
+ NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n");
+ }
+ if (nxpncihal_ctrl.p_nfc_stack_data_cback!= NULL &&
+ nxpncihal_ctrl.p_rx_data!= NULL &&
+ nxpncihal_ctrl.hal_open_status == TRUE)
+ {
+ NXPLOG_NCIHAL_D("Send the Core Reset NTF to upper layer, which will trigger the recovery\n");
+ //Send the Core Reset NTF to upper layer, which will trigger the recovery.
+ nxpncihal_ctrl.rx_data_len = sizeof(reset_ntf);
+ memcpy(nxpncihal_ctrl.p_rx_data, reset_ntf, sizeof(reset_ntf));
+ (*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rx_data_len, nxpncihal_ctrl.p_rx_data);
+ }
+ }
+ }
+
+ clean_and_return:
+ phNxpNciHal_cleanup_cb_data(&cb_data);
+ return data_len;
+}
+
+/******************************************************************************
+ * Function phNxpNciHal_write_complete
+ *
+ * Description This function handles write callback.
+ *
+ * Returns void.
+ *
+ ******************************************************************************/
+static void phNxpNciHal_write_complete(void *pContext, phTmlNfc_TransactInfo_t *pInfo)
+{
+ phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+
+ if (pInfo->wStatus == NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_D("write successful status = 0x%x", pInfo->wStatus);
+ }
+ else
+ {
+ NXPLOG_NCIHAL_E("write error status = 0x%x", pInfo->wStatus);
+ }
+
+ p_cb_data->status = pInfo->wStatus;
+
+ SEM_POST(p_cb_data);
+
+ return;
+}
+
+/******************************************************************************
+ * Function phNxpNciHal_read_complete
+ *
+ * Description This function is called whenever there is an NCI packet
+ * received from NFCC. It could be RSP or NTF packet. This
+ * function provide the received NCI packet to libnfc-nci
+ * using data callback of libnfc-nci.
+ * There is a pending read called from each
+ * phNxpNciHal_read_complete so each a packet received from
+ * NFCC can be provide to libnfc-nci.
+ *
+ * Returns void.
+ *
+ ******************************************************************************/
+static void phNxpNciHal_read_complete(void *pContext, phTmlNfc_TransactInfo_t *pInfo)
+{
+ NFCSTATUS status = NFCSTATUS_FAILED;
+ UNUSED(pContext);
+ if(nxpncihal_ctrl.read_retry_cnt == 1)
+ {
+ nxpncihal_ctrl.read_retry_cnt = 0;
+ }
+
+ if (pInfo->wStatus == NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_D("read successful status = 0x%x", pInfo->wStatus);
+
+ nxpncihal_ctrl.p_rx_data = pInfo->pBuff;
+ nxpncihal_ctrl.rx_data_len = pInfo->wLength;
+
+ status = phNxpNciHal_process_ext_rsp (nxpncihal_ctrl.p_rx_data, &nxpncihal_ctrl.rx_data_len);
+
+ phNxpNciHal_print_res_status(nxpncihal_ctrl.p_rx_data, &nxpncihal_ctrl.rx_data_len);
+ /* Check if response should go to hal module only */
+ if (nxpncihal_ctrl.hal_ext_enabled == 1
+ && (nxpncihal_ctrl.p_rx_data[0x00] & 0x40) == 0x40)
+ {
+ if(status == NFCSTATUS_FAILED)
+ {
+ NXPLOG_NCIHAL_D("enter into NFCC init recovery");
+ nxpncihal_ctrl.ext_cb_data.status = status;
+ }
+ /* Unlock semaphore */
+ SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
+ }
+ /* Read successful send the event to higher layer */
+ else if ((nxpncihal_ctrl.p_nfc_stack_data_cback != NULL) &&
+ (status == NFCSTATUS_SUCCESS)&&(send_to_upper_kovio==1))
+ {
+ (*nxpncihal_ctrl.p_nfc_stack_data_cback)(
+ nxpncihal_ctrl.rx_data_len, nxpncihal_ctrl.p_rx_data);
+ }
+ }
+ else
+ {
+ NXPLOG_NCIHAL_E("read error status = 0x%x", pInfo->wStatus);
+ }
+
+ if(nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE)
+ {
+ return;
+ }
+ /* Read again because read must be pending always.*/
+ status = phTmlNfc_Read(
+ Rx_data,
+ NCI_MAX_DATA_LEN,
+ (pphTmlNfc_TransactCompletionCb_t) &phNxpNciHal_read_complete,
+ NULL);
+ if (status != NFCSTATUS_PENDING)
+ {
+ NXPLOG_NCIHAL_E("read status error status = %x", status);
+ /* TODO: Not sure how to handle this ? */
+ }
+
+ return;
+}
+
+void read_retry()
+{
+ /* Read again because read must be pending always.*/
+ NFCSTATUS status = phTmlNfc_Read(
+ Rx_data,
+ NCI_MAX_DATA_LEN,
+ (pphTmlNfc_TransactCompletionCb_t) &phNxpNciHal_read_complete,
+ NULL);
+ if (status != NFCSTATUS_PENDING)
+ {
+ NXPLOG_NCIHAL_E("read status error status = %x", status);
+ /* TODO: Not sure how to handle this ? */
+ }
+}
+/******************************************************************************
+ * Function phNxpNciHal_core_initialized
+ *
+ * Description This function is called by libnfc-nci after successful open
+ * of NFCC. All proprietary setting for PN54X are done here.
+ * After completion of proprietary settings notification is
+ * provided to libnfc-nci through callback function.
+ *
+ * Returns Always returns NFCSTATUS_SUCCESS (0).
+ *
+ ******************************************************************************/
+int phNxpNciHal_core_initialized(uint8_t* p_core_init_rsp_params)
+{
+ NFCSTATUS status = NFCSTATUS_SUCCESS;
+ static uint8_t p2p_listen_mode_routing_cmd[] = { 0x21, 0x01, 0x07, 0x00, 0x01,
+ 0x01, 0x03, 0x00, 0x01, 0x05 };
+
+ uint8_t swp_full_pwr_mode_on_cmd[] = { 0x20, 0x02, 0x05, 0x01, 0xA0,
+ 0xF1,0x01,0x01 };
+
+ static uint8_t android_l_aid_matching_mode_on_cmd[] = {0x20, 0x02, 0x05, 0x01, 0xA0, 0x91, 0x01, 0x01};
+ static uint8_t swp_switch_timeout_cmd[] = {0x20, 0x02, 0x06, 0x01, 0xA0, 0xF3, 0x02, 0x00, 0x00};
+
+ uint8_t *buffer = NULL;
+ long bufflen = 260;
+ long retlen = 0;
+ int isfound;
+ /* Temp fix to re-apply the proper clock setting */
+ int temp_fix = 1;
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+ unsigned long num = 0;
+ //initialize dummy FW recovery variables
+ gRecFwRetryCount = 0;
+ gRecFWDwnld = 0;
+#endif
+ // recovery --start
+ /*NCI_INIT_CMD*/
+ static uint8_t cmd_init_nci[] = {0x20,0x01,0x00};
+ /*NCI_RESET_CMD*/
+ static uint8_t cmd_reset_nci[] = {0x20,0x00,0x01,0x00}; //keep configuration
+ /* reset config cache */
+ static uint8_t retry_core_init_cnt;
+
+ if((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4)) //initializing for recovery.
+ {
+retry_core_init:
+ config_access = FALSE;
+ if(buffer != NULL)
+ {
+ free(buffer);
+ buffer = NULL;
+ }
+ if(retry_core_init_cnt > 3)
+ {
+ return NFCSTATUS_FAILED;
+ }
+
+ status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
+ if(NFCSTATUS_SUCCESS == status) { NXPLOG_NCIHAL_D("PN54X Reset - SUCCESS\n"); }
+ else { NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n"); }
+
+ status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci),cmd_reset_nci);
+ if((status != NFCSTATUS_SUCCESS) && (nxpncihal_ctrl.retry_cnt >= MAX_RETRY_COUNT))
+ {
+ NXPLOG_NCIHAL_E("Force FW Download, NFCC not coming out from Standby");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ else if(status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E ("NCI_CORE_RESET: Failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+
+ }
+
+ if(*p_core_init_rsp_params == 2) {
+ NXPLOG_NCIHAL_E(" Last command is CORE_RESET!!");
+ goto invoke_callback;
+ }
+
+ status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci),cmd_init_nci);
+ if(status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E ("NCI_CORE_INIT : Failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+
+ if(*p_core_init_rsp_params == 3) {
+ NXPLOG_NCIHAL_E(" Last command is CORE_INIT!!");
+ goto invoke_callback;
+ }
+ }
+// recovery --end
+
+
+ buffer = (uint8_t*) malloc(bufflen*sizeof(uint8_t));
+ if(NULL == buffer)
+ {
+ return NFCSTATUS_FAILED;
+ }
+ config_access = TRUE;
+ retlen = 0;
+ isfound = GetNxpByteArrayValue(NAME_NXP_ACT_PROP_EXTN, (char *) buffer,
+ bufflen, &retlen);
+ if (retlen > 0) {
+ /* NXP ACT Proprietary Ext */
+ status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+ if (status != NFCSTATUS_SUCCESS) {
+ NXPLOG_NCIHAL_E("NXP ACT Proprietary Ext failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }
+
+ //
+ status = phNxpNciHal_check_clock_config();
+ if (status != NFCSTATUS_SUCCESS) {
+ NXPLOG_NCIHAL_E("phNxpNciHal_check_clock_config failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+
+#ifdef PN547C2_CLOCK_SETTING
+ if (isNxpConfigModified() || (fw_download_success == 1) || (phNxpNciClock.issetConfig)
+#if(NFC_NXP_HFO_SETTINGS == TRUE)
+ || temp_fix == 1
+#endif
+ )
+ {
+ //phNxpNciHal_get_clk_freq();
+ phNxpNciHal_set_clock();
+ phNxpNciClock.issetConfig = FALSE;
+#if(NFC_NXP_HFO_SETTINGS == TRUE)
+ if (temp_fix == 1 )
+ {
+ NXPLOG_NCIHAL_D("Applying Default Clock setting and DPLL register at power on");
+ /*
+ # A0, 0D, 06, 06, 83, 55, 2A, 04, 00 RF_CLIF_CFG_TARGET CLIF_DPLL_GEAR_REG
+ # A0, 0D, 06, 06, 82, 33, 14, 17, 00 RF_CLIF_CFG_TARGET CLIF_DPLL_INIT_REG
+ # A0, 0D, 06, 06, 84, AA, 85, 00, 80 RF_CLIF_CFG_TARGET CLIF_DPLL_INIT_FREQ_REG
+ # A0, 0D, 06, 06, 81, 63, 00, 00, 00 RF_CLIF_CFG_TARGET CLIF_DPLL_CONTROL_REG
+ */
+ static uint8_t cmd_dpll_set_reg_nci[] = {0x20, 0x02, 0x25, 0x04,
+ 0xA0, 0x0D, 0x06, 0x06, 0x83, 0x55, 0x2A, 0x04, 0x00,
+ 0xA0, 0x0D, 0x06, 0x06, 0x82, 0x33, 0x14, 0x17, 0x00,
+ 0xA0, 0x0D, 0x06, 0x06, 0x84, 0xAA, 0x85, 0x00, 0x80,
+ 0xA0, 0x0D, 0x06, 0x06, 0x81, 0x63, 0x00, 0x00, 0x00};
+
+ status = phNxpNciHal_send_ext_cmd(sizeof(cmd_dpll_set_reg_nci), cmd_dpll_set_reg_nci);
+ if (status != NFCSTATUS_SUCCESS) {
+ NXPLOG_NCIHAL_E("NXP DPLL REG ACT Proprietary Ext failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ /* reset the NFCC after applying the clock setting and DPLL setting */
+ //phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
+ temp_fix = 0;
+ goto retry_core_init;
+ }
+#endif
+ }
+#endif
+
+ phNxpNciHal_check_factory_reset();
+ retlen = 0;
+ config_access = TRUE;
+ isfound = GetNxpByteArrayValue(NAME_NXP_NFC_PROFILE_EXTN, (char *) buffer,
+ bufflen, &retlen);
+ if (retlen > 0) {
+ /* NXP ACT Proprietary Ext */
+ status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+ if (status != NFCSTATUS_SUCCESS) {
+ NXPLOG_NCIHAL_E("NXP ACT Proprietary Ext failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }
+
+ if(isNxpConfigModified() || (fw_download_success == 1))
+ {
+
+ retlen = 0;
+ fw_download_success = 0;
+
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+ NXPLOG_NCIHAL_D ("Performing TVDD Settings");
+ isfound = GetNxpNumValue(NAME_NXP_EXT_TVDD_CFG, &num, sizeof(num));
+ if (isfound > 0) {
+ if(num == 1) {
+ isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_1, (char *) buffer,
+ bufflen, &retlen);
+ if (retlen > 0) {
+ status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+ if (status != NFCSTATUS_SUCCESS) {
+ NXPLOG_NCIHAL_E("EXT TVDD CFG 1 Settings failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }
+ }
+ else if(num == 2) {
+ isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_2, (char *) buffer,
+ bufflen, &retlen);
+ if (retlen > 0) {
+ status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+ if (status != NFCSTATUS_SUCCESS) {
+ NXPLOG_NCIHAL_E("EXT TVDD CFG 2 Settings failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }
+ }
+ else if(num == 3) {
+ isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_3, (char *) buffer,
+ bufflen, &retlen);
+ if (retlen > 0) {
+ status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+ if (status != NFCSTATUS_SUCCESS) {
+ NXPLOG_NCIHAL_E("EXT TVDD CFG 3 Settings failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }
+ }
+ else {
+ NXPLOG_NCIHAL_E("Wrong Configuration Value %ld", num);
+ }
+
+ }
+#endif
+ retlen = 0;
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+ config_access = FALSE;
+#endif
+ 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(NFC_NXP_CHIP_TYPE == PN548C2)
+ if(status == NFCSTATUS_SUCCESS)
+ {
+ status = phNxpNciHal_CheckRFCmdRespStatus();
+ /*STATUS INVALID PARAM 0x09*/
+ if(status == 0x09)
+ {
+ phNxpNciHalRFConfigCmdRecSequence();
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }else
+#endif
+ if (status != NFCSTATUS_SUCCESS) {
+ NXPLOG_NCIHAL_E("RF Settings BLK 1 failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }
+ retlen = 0;
+
+ NXPLOG_NCIHAL_D ("Performing RF Settings BLK 2");
+ isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_2, (char *) buffer,
+ bufflen, &retlen);
+ if (retlen > 0) {
+ status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+ if(status == NFCSTATUS_SUCCESS)
+ {
+ status = phNxpNciHal_CheckRFCmdRespStatus();
+ /*STATUS INVALID PARAM 0x09*/
+ if(status == 0x09)
+ {
+ phNxpNciHalRFConfigCmdRecSequence();
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }else
+#endif
+ if (status != NFCSTATUS_SUCCESS) {
+ NXPLOG_NCIHAL_E("RF Settings BLK 2 failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }
+ retlen = 0;
+
+ NXPLOG_NCIHAL_D ("Performing RF Settings BLK 3");
+ isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_3, (char *) buffer,
+ bufflen, &retlen);
+ if (retlen > 0) {
+ status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+ if(status == NFCSTATUS_SUCCESS)
+ {
+ status = phNxpNciHal_CheckRFCmdRespStatus();
+ /*STATUS INVALID PARAM 0x09*/
+ if(status == 0x09)
+ {
+ phNxpNciHalRFConfigCmdRecSequence();
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }else
+#endif
+ if (status != NFCSTATUS_SUCCESS) {
+ NXPLOG_NCIHAL_E("RF Settings BLK 3 failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }
+ retlen = 0;
+
+ NXPLOG_NCIHAL_D ("Performing RF Settings BLK 4");
+ isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_4, (char *) buffer,
+ bufflen, &retlen);
+ if (retlen > 0) {
+ status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+ if(status == NFCSTATUS_SUCCESS)
+ {
+ status = phNxpNciHal_CheckRFCmdRespStatus();
+ /*STATUS INVALID PARAM 0x09*/
+ if(status == 0x09)
+ {
+ phNxpNciHalRFConfigCmdRecSequence();
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }else
+#endif
+ if (status != NFCSTATUS_SUCCESS) {
+ NXPLOG_NCIHAL_E("RF Settings BLK 4 failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }
+ retlen = 0;
+
+ NXPLOG_NCIHAL_D ("Performing RF Settings BLK 5");
+ isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_5, (char *) buffer,
+ bufflen, &retlen);
+ if (retlen > 0) {
+ status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+ if(status == NFCSTATUS_SUCCESS)
+ {
+ status = phNxpNciHal_CheckRFCmdRespStatus();
+ /*STATUS INVALID PARAM 0x09*/
+ if(status == 0x09)
+ {
+ phNxpNciHalRFConfigCmdRecSequence();
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }else
+#endif
+ if (status != NFCSTATUS_SUCCESS) {
+ NXPLOG_NCIHAL_E("RF Settings BLK 5 failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }
+ retlen = 0;
+
+ NXPLOG_NCIHAL_D ("Performing RF Settings BLK 6");
+ isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_6, (char *) buffer,
+ bufflen, &retlen);
+ if (retlen > 0) {
+ status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+ if(status == NFCSTATUS_SUCCESS)
+ {
+ status = phNxpNciHal_CheckRFCmdRespStatus();
+ /*STATUS INVALID PARAM 0x09*/
+ if(status == 0x09)
+ {
+ phNxpNciHalRFConfigCmdRecSequence();
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }else
+#endif
+ if (status != NFCSTATUS_SUCCESS) {
+ NXPLOG_NCIHAL_E("RF Settings BLK 6 failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }
+ retlen = 0;
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+ config_access = TRUE;
+#endif
+ NXPLOG_NCIHAL_D ("Performing NAME_NXP_CORE_CONF_EXTN Settings");
+ isfound = GetNxpByteArrayValue(NAME_NXP_CORE_CONF_EXTN,
+ (char *) buffer, bufflen, &retlen);
+ if (retlen > 0) {
+ /* NXP ACT Proprietary Ext */
+ status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+ if (status != NFCSTATUS_SUCCESS) {
+ NXPLOG_NCIHAL_E("NXP Core configuration failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }
+
+ retlen = 0;
+
+ isfound = GetNxpByteArrayValue(NAME_NXP_CORE_MFCKEY_SETTING,
+ (char *) buffer, bufflen, &retlen);
+ if (retlen > 0) {
+ /* NXP ACT Proprietary Ext */
+ status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+ if (status != NFCSTATUS_SUCCESS) {
+ NXPLOG_NCIHAL_E("Setting mifare keys failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }
+
+ retlen = 0;
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+ config_access = FALSE;
+#endif
+ 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(NFC_NXP_CHIP_TYPE == PN548C2)
+ if(status == NFCSTATUS_SUCCESS)
+ {
+ status = phNxpNciHal_CheckRFCmdRespStatus();
+ /*STATUS INVALID PARAM 0x09*/
+ if(status == 0x09)
+ {
+ phNxpNciHalRFConfigCmdRecSequence();
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }else
+#endif
+ if (status != NFCSTATUS_SUCCESS) {
+ NXPLOG_NCIHAL_E("Setting NXP_CORE_RF_FIELD status failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+ config_access = TRUE;
+#endif
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ retlen = 0;
+
+ /* NXP SWP switch timeout Setting*/
+ if(GetNxpNumValue(NAME_NXP_SWP_SWITCH_TIMEOUT, (void *)&retlen, sizeof(retlen)))
+ {
+ //Check the permissible range [0 - 60]
+ if(0 <= retlen && retlen <= 60)
+ {
+ if( 0 < retlen)
+ {
+ uint16_t timeout = retlen * 1000;
+ uint16_t timeoutHx = 0x0000;
+
+ uint8_t tmpbuffer[10];
+ snprintf ( tmpbuffer, 10, "%04x", timeout );
+ sscanf (tmpbuffer,"%x",&timeoutHx);
+
+ swp_switch_timeout_cmd[7]= (timeoutHx & 0xFF);
+ swp_switch_timeout_cmd[8]= ((timeoutHx & 0xFF00) >> 8);
+ }
+
+ status = phNxpNciHal_send_ext_cmd (sizeof(swp_switch_timeout_cmd),
+ swp_switch_timeout_cmd);
+ if (status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E("SWP switch timeout Setting Failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }
+ else
+ {
+ NXPLOG_NCIHAL_E("SWP switch timeout Setting Failed - out of range!");
+ }
+
+ }
+
+ status = phNxpNciHal_china_tianjin_rf_setting();
+ if (status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E("phNxpNciHal_china_tianjin_rf_setting failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+#endif
+#if(NFC_NXP_CHIP_TYPE == PN547C2)
+ status = phNxpNciHal_uicc_baud_rate();
+ if (status != NFCSTATUS_SUCCESS) {
+ NXPLOG_NCIHAL_E("Setting NXP_CORE_RF_FIELD status failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+#endif
+ }
+
+ retlen = 0;
+
+ isfound = GetNxpByteArrayValue(NAME_NXP_CORE_STANDBY, (char *) buffer,bufflen, &retlen);
+ if (retlen > 0) {
+ /* NXP ACT Proprietary Ext */
+ status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+ if (status != NFCSTATUS_SUCCESS) {
+ NXPLOG_NCIHAL_E("Stand by mode enable failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }
+ retlen = 0;
+
+ isfound = GetNxpByteArrayValue(NAME_NXP_CORE_CONF,(char *)buffer,bufflen,&retlen);
+ if(retlen > 0)
+ {
+ /* NXP ACT Proprietary Ext */
+ status = phNxpNciHal_send_ext_cmd(retlen,buffer);
+ if (status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E("Core Set Config failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }
+
+ config_access = FALSE;
+ //if length of last command is 0 then only reset the P2P listen mode routing.
+ if(p_core_init_rsp_params[35] == 0)
+ {
+ /* P2P listen mode routing */
+ status = phNxpNciHal_send_ext_cmd (sizeof (p2p_listen_mode_routing_cmd), p2p_listen_mode_routing_cmd);
+ if (status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E("P2P listen mode routing failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }
+
+ retlen = 0;
+
+ /* SWP FULL PWR MODE SETTING ON */
+ if(GetNxpNumValue(NAME_NXP_SWP_FULL_PWR_ON, (void *)&retlen, sizeof(retlen)))
+ {
+ if(1 == retlen)
+ {
+ status = phNxpNciHal_send_ext_cmd (sizeof(swp_full_pwr_mode_on_cmd),
+ swp_full_pwr_mode_on_cmd);
+ if (status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E("SWP FULL PWR MODE SETTING ON CMD FAILED");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }
+ else
+ {
+ swp_full_pwr_mode_on_cmd[7]=0x00;
+ status = phNxpNciHal_send_ext_cmd (sizeof(swp_full_pwr_mode_on_cmd),
+ swp_full_pwr_mode_on_cmd);
+ if (status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E("SWP FULL PWR MODE SETTING OFF CMD FAILED");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }
+ }
+
+ /* Android L AID Matching Platform Setting*/
+ if(GetNxpNumValue(NAME_AID_MATCHING_PLATFORM, (void *)&retlen, sizeof(retlen)))
+ {
+ if(1 == retlen)
+ {
+ status = phNxpNciHal_send_ext_cmd (sizeof(android_l_aid_matching_mode_on_cmd),
+ android_l_aid_matching_mode_on_cmd);
+ if (status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E("Android L AID Matching Platform Setting Failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }
+ else if (2 == retlen)
+ {
+ android_l_aid_matching_mode_on_cmd[7]=0x00;
+ status = phNxpNciHal_send_ext_cmd (sizeof(android_l_aid_matching_mode_on_cmd),
+ android_l_aid_matching_mode_on_cmd);
+ if (status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E("Android L AID Matching Platform Setting Failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }
+ }
+
+ if((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4))
+ {
+ static phLibNfc_Message_t msg;
+ uint16_t tmp_len = 0;
+ uint8_t uicc_set_mode[] = {0x22, 0x01, 0x02, 0x02, 0x01};
+ uint8_t set_screen_state[] = {0x2F, 0x15, 01, 00}; //SCREEN ON
+ uint8_t nfcc_core_conn_create[] = {0x20, 0x04, 0x06, 0x03, 0x01, 0x01, 0x02, 0x01, 0x01};
+ uint8_t nfcc_mode_set_on[] = {0x22, 0x01, 0x02, 0x01, 0x01};
+
+ NXPLOG_NCIHAL_E("Sending DH and NFCC core connection command as raw packet!!");
+ status = phNxpNciHal_send_ext_cmd (sizeof(nfcc_core_conn_create), nfcc_core_conn_create);
+
+ if (status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E("Sending DH and NFCC core connection command as raw packet!! Failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+
+ NXPLOG_NCIHAL_E("Sending DH and NFCC mode set as raw packet!!");
+ status = phNxpNciHal_send_ext_cmd (sizeof(nfcc_mode_set_on), nfcc_mode_set_on);
+
+ if (status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E("Sending DH and NFCC mode set as raw packet!! Failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+
+ NXPLOG_NCIHAL_E("Sending UICC Select Command as raw packet!!");
+ status = phNxpNciHal_send_ext_cmd (sizeof(uicc_set_mode),
+ uicc_set_mode);
+ if (status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E("Sending UICC Select Command as raw packet!! Failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+
+ if(*(p_core_init_rsp_params + 1) == 1) // RF state is Discovery!!
+ {
+ NXPLOG_NCIHAL_E("Sending Set Screen ON State Command as raw packet!!");
+ status = phNxpNciHal_send_ext_cmd (sizeof(set_screen_state),
+ set_screen_state);
+ if (status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E("Sending Set Screen ON State Command as raw packet!! Failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+
+ NXPLOG_NCIHAL_E("Sending discovery as raw packet!!");
+ status = phNxpNciHal_send_ext_cmd (p_core_init_rsp_params[2],
+ (uint8_t *)&p_core_init_rsp_params[3]);
+ if (status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E("Sending discovery as raw packet Failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+
+ }
+ else
+ {
+ NXPLOG_NCIHAL_E("Sending Set Screen OFF State Command as raw packet!!");
+ set_screen_state[3] = 0x01; //Screen OFF
+ status = phNxpNciHal_send_ext_cmd (sizeof(set_screen_state),
+ set_screen_state);
+ if (status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E("Sending Set Screen OFF State Command as raw packet!! Failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+
+ }
+
+ 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] > 0)
+ { //if length of last command is 0 then it doesn't need to send last command.
+ if( !(((p_core_init_rsp_params[36] == 0x21) && (p_core_init_rsp_params[37] == 0x03))
+ && (*(p_core_init_rsp_params + 1) == 1))&&
+ !((p_core_init_rsp_params[36] == 0x21) && (p_core_init_rsp_params[37] == 0x06)))
+ //if last command is discovery and RF staus is also discovery state, then it doesn't need to execute.
+ {
+ tmp_len = p_core_init_rsp_params[35];
+
+ /* Check for NXP ext before sending write */
+ status = phNxpNciHal_write_ext(&tmp_len,
+ (uint8_t *)&p_core_init_rsp_params[36], &nxpncihal_ctrl.rsp_len,
+ nxpncihal_ctrl.p_rsp_data);
+ if (status != NFCSTATUS_SUCCESS)
+ {
+ 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;
+ }
+
+ p_core_init_rsp_params[35] = (uint8_t)tmp_len;
+
+ status = phNxpNciHal_send_ext_cmd (p_core_init_rsp_params[35],
+ (uint8_t *)&p_core_init_rsp_params[36]);
+ if (status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E("Sending last command for Recovery Failed");
+ retry_core_init_cnt++;
+ goto retry_core_init;
+ }
+ }
+ }
+ }
+
+ retry_core_init_cnt = 0;
+
+ if(buffer)
+ {
+ free(buffer);
+ buffer = NULL;
+ }
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+ //initialize dummy FW recovery variables
+ gRecFWDwnld = 0;
+ gRecFwRetryCount = 0;
+#endif
+ 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;
+}
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+/******************************************************************************
+ * 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()
+{
+ 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()
+{
+ NFCSTATUS status = NFCSTATUS_SUCCESS;
+ uint16_t recFWState = 1;
+ gRecFWDwnld = TRUE;
+ gRecFwRetryCount++;
+ if(gRecFwRetryCount > 0x03)
+ {
+ NXPLOG_NCIHAL_D ("Max retry count for RF config FW recovery exceeded ");
+ gRecFWDwnld = FALSE;
+ return NFCSTATUS_FAILED;
+ }
+ do{
+ status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
+ phDnldNfc_InitImgInfo();
+ if (NFCSTATUS_SUCCESS == phNxpNciHal_CheckValidFwVersion())
+ {
+ fw_download_success = 0;
+ status = phNxpNciHal_fw_download();
+ if(status == NFCSTATUS_SUCCESS)
+ {
+ fw_download_success = 1;
+ 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);
+ status = phTmlNfc_Shutdown();
+ status = NFCSTATUS_FAILED;
+ break;
+ }
+ }
+ else
+ {
+ status = NFCSTATUS_FAILED;
+ break;
+ }
+ }
+ gRecFWDwnld = FALSE;
+ }while(recFWState--);
+ gRecFWDwnld = FALSE;
+ return status;
+}
+#endif
+#if(NFC_NXP_CHIP_TYPE == PN547C2)
+/******************************************************************************
+ * 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()
+{
+ uint32_t 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;
+}
+#endif
+/******************************************************************************
+ * Function phNxpNciHal_core_initialized_complete
+ *
+ * Description This function is called when phNxpNciHal_core_initialized
+ * complete all proprietary command exchanges. This function
+ * informs libnfc-nci about completion of core initialize
+ * and result of that through callback.
+ *
+ * Returns void.
+ *
+ ******************************************************************************/
+static void phNxpNciHal_core_initialized_complete(NFCSTATUS status)
+{
+ static phLibNfc_Message_t msg;
+
+ if (status == NFCSTATUS_SUCCESS)
+ {
+ msg.eMsgType = NCI_HAL_POST_INIT_CPLT_MSG;
+ }
+ else
+ {
+ msg.eMsgType = NCI_HAL_ERROR_MSG;
+ }
+ msg.pMsgData = NULL;
+ msg.Size = 0;
+
+ phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
+ (phLibNfc_Message_t *) &msg);
+
+ return;
+}
+
+/******************************************************************************
+ * Function phNxpNciHal_pre_discover
+ *
+ * Description This function is called by libnfc-nci to perform any
+ * proprietary exchange before RF discovery. When proprietary
+ * exchange is over completion is informed to libnfc-nci
+ * through phNxpNciHal_pre_discover_complete function.
+ *
+ * Returns It always returns NFCSTATUS_SUCCESS (0).
+ *
+ ******************************************************************************/
+int phNxpNciHal_pre_discover(void)
+{
+ /* Nothing to do here for initial version */
+ return NFCSTATUS_SUCCESS;
+}
+
+/******************************************************************************
+ * Function phNxpNciHal_pre_discover_complete
+ *
+ * Description This function informs libnfc-nci about completion and
+ * status of phNxpNciHal_pre_discover through callback.
+ *
+ * Returns void.
+ *
+ ******************************************************************************/
+static void phNxpNciHal_pre_discover_complete(NFCSTATUS status)
+{
+ static phLibNfc_Message_t msg;
+
+ if (status == NFCSTATUS_SUCCESS)
+ {
+ msg.eMsgType = NCI_HAL_PRE_DISCOVER_CPLT_MSG;
+ }
+ else
+ {
+ msg.eMsgType = NCI_HAL_ERROR_MSG;
+ }
+ msg.pMsgData = NULL;
+ msg.Size = 0;
+
+ phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
+ &msg);
+
+ return;
+}
+
+/******************************************************************************
+ * Function phNxpNciHal_close
+ *
+ * Description This function close the NFCC interface and free all
+ * resources.This is called by libnfc-nci on NFC service stop.
+ *
+ * Returns Always return NFCSTATUS_SUCCESS (0).
+ *
+ ******************************************************************************/
+int phNxpNciHal_close(void)
+{
+ NFCSTATUS status;
+ /*NCI_RESET_CMD*/
+ static uint8_t cmd_reset_nci[] = {0x20,0x00,0x01,0x00};
+
+ static uint8_t cmd_ce_disc_nci[] = {0x21,0x03,0x07,0x03,0x80,0x01,0x81,0x01,0x82,0x01};
+
+ CONCURRENCY_LOCK();
+
+ status = phNxpNciHal_send_ext_cmd(sizeof(cmd_ce_disc_nci),cmd_ce_disc_nci);
+ if(status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E ("CMD_CE_DISC_NCI: Failed");
+ }
+
+ nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;
+
+ status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci),cmd_reset_nci);
+ if(status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E ("NCI_CORE_RESET: Failed");
+ }
+
+ if (NULL != gpphTmlNfc_Context->pDevHandle)
+ {
+ phNxpNciHal_close_complete(NFCSTATUS_SUCCESS);
+ /* Abort any pending read and write */
+ status = phTmlNfc_ReadAbort();
+ status = phTmlNfc_WriteAbort();
+
+ phOsalNfc_Timer_Cleanup();
+
+ status = phTmlNfc_Shutdown();
+
+ phDal4Nfc_msgrelease(nxpncihal_ctrl.gDrvCfg.nClientId);
+
+
+ memset (&nxpncihal_ctrl, 0x00, sizeof (nxpncihal_ctrl));
+
+ NXPLOG_NCIHAL_D("phNxpNciHal_close - phOsalNfc_DeInit completed");
+ }
+
+ CONCURRENCY_UNLOCK();
+
+ phNxpNciHal_cleanup_monitor();
+
+ /* Return success always */
+ return NFCSTATUS_SUCCESS;
+}
+
+/******************************************************************************
+ * Function phNxpNciHal_close_complete
+ *
+ * Description This function inform libnfc-nci about result of
+ * phNxpNciHal_close.
+ *
+ * Returns void.
+ *
+ ******************************************************************************/
+void phNxpNciHal_close_complete(NFCSTATUS status)
+{
+ static phLibNfc_Message_t msg;
+
+ if (status == NFCSTATUS_SUCCESS)
+ {
+ msg.eMsgType = NCI_HAL_CLOSE_CPLT_MSG;
+ }
+ else
+ {
+ msg.eMsgType = NCI_HAL_ERROR_MSG;
+ }
+ msg.pMsgData = NULL;
+ msg.Size = 0;
+
+ phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
+ &msg);
+
+ return;
+}
+/******************************************************************************
+ * Function phNxpNciHal_notify_i2c_fragmentation
+ *
+ * Description This function can be used by HAL to inform
+ * libnfc-nci that i2c fragmentation is enabled/disabled
+ *
+ * Returns void.
+ *
+ ******************************************************************************/
+void phNxpNciHal_notify_i2c_fragmentation(void)
+{
+ if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
+ {
+ /*inform libnfc-nci that i2c fragmentation is enabled/disabled */
+ (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_ENABLE_I2C_FRAGMENTATION_EVT,
+ HAL_NFC_STATUS_OK);
+ }
+}
+/******************************************************************************
+ * Function phNxpNciHal_control_granted
+ *
+ * Description Called by libnfc-nci when NFCC control is granted to HAL.
+ *
+ * Returns Always returns NFCSTATUS_SUCCESS (0).
+ *
+ ******************************************************************************/
+int phNxpNciHal_control_granted(void)
+{
+ /* Take the concurrency lock so no other calls from upper layer
+ * will be allowed
+ */
+ CONCURRENCY_LOCK();
+
+ if(NULL != nxpncihal_ctrl.p_control_granted_cback)
+ {
+ (*nxpncihal_ctrl.p_control_granted_cback)();
+ }
+ /* At the end concurrency unlock so calls from upper layer will
+ * be allowed
+ */
+ CONCURRENCY_UNLOCK();
+ return NFCSTATUS_SUCCESS;
+}
+
+/******************************************************************************
+ * Function phNxpNciHal_request_control
+ *
+ * Description This function can be used by HAL to request control of
+ * NFCC to libnfc-nci. When control is provided to HAL it is
+ * notified through phNxpNciHal_control_granted.
+ *
+ * Returns void.
+ *
+ ******************************************************************************/
+void phNxpNciHal_request_control(void)
+{
+ if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
+ {
+ /* Request Control of NCI Controller from NCI NFC Stack */
+ (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_REQUEST_CONTROL_EVT,
+ HAL_NFC_STATUS_OK);
+ }
+
+ return;
+}
+
+/******************************************************************************
+ * Function phNxpNciHal_release_control
+ *
+ * Description This function can be used by HAL to release the control of
+ * NFCC back to libnfc-nci.
+ *
+ * Returns void.
+ *
+ ******************************************************************************/
+void phNxpNciHal_release_control(void)
+{
+ if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
+ {
+ /* Release Control of NCI Controller to NCI NFC Stack */
+ (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_RELEASE_CONTROL_EVT,
+ HAL_NFC_STATUS_OK);
+ }
+
+ return;
+}
+
+/******************************************************************************
+ * Function phNxpNciHal_power_cycle
+ *
+ * Description This function is called by libnfc-nci when power cycling is
+ * performed. When processing is complete it is notified to
+ * libnfc-nci through phNxpNciHal_power_cycle_complete.
+ *
+ * Returns Always return NFCSTATUS_SUCCESS (0).
+ *
+ ******************************************************************************/
+int phNxpNciHal_power_cycle(void)
+{
+ NXPLOG_NCIHAL_D("Power Cycle");
+
+ NFCSTATUS status = NFCSTATUS_FAILED;
+
+ status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
+
+ if(NFCSTATUS_SUCCESS == status)
+ {
+ NXPLOG_NCIHAL_D("PN54X Reset - SUCCESS\n");
+ }
+ else
+ {
+ NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n");
+ }
+
+ phNxpNciHal_power_cycle_complete(NFCSTATUS_SUCCESS);
+
+ return NFCSTATUS_SUCCESS;
+}
+
+/******************************************************************************
+ * Function phNxpNciHal_power_cycle_complete
+ *
+ * Description This function is called to provide the status of
+ * phNxpNciHal_power_cycle to libnfc-nci through callback.
+ *
+ * Returns void.
+ *
+ ******************************************************************************/
+static void phNxpNciHal_power_cycle_complete(NFCSTATUS status)
+{
+ static phLibNfc_Message_t msg;
+
+ if (status == NFCSTATUS_SUCCESS)
+ {
+ msg.eMsgType = NCI_HAL_OPEN_CPLT_MSG;
+ }
+ else
+ {
+ msg.eMsgType = NCI_HAL_ERROR_MSG;
+ }
+ msg.pMsgData = NULL;
+ msg.Size = 0;
+
+ phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
+ &msg);
+
+ return;
+}
+
+
+/******************************************************************************
+ * Function phNxpNciHal_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", __FUNCTION__, arg);
+
+ int ret = -1;
+ NFCSTATUS status = NFCSTATUS_FAILED;
+#if(ESE_NFC_POWER_MANAGEMENT == TRUE)
+ switch(arg)
+ {
+ case 0:
+ status = phTmlNfc_IoCtl(phTmlNfc_e_SetP61IdleMode);
+ break;
+ case 1:
+ status = phTmlNfc_IoCtl(phTmlNfc_e_SetP61WiredMode);
+ break;
+ case 2:
+ status = phTmlNfc_IoCtl(phTmlNfc_e_GetP61PwrMode);
+ break;
+ default:
+ NXPLOG_NCIHAL_E("%s : Wrong arg = %ld", __FUNCTION__, arg);
+ break;
+ }
+#endif
+ if(NFCSTATUS_FAILED != status)
+ {
+ *(uint16_t*)p_data = (uint16_t)status;
+ ret = 0;
+ }
+ NXPLOG_NCIHAL_D("%s : exit - ret = %d", __FUNCTION__, ret);
+ return ret;
+}
+
+/******************************************************************************
+ * Function phNxpNciHal_set_clock
+ *
+ * Description This function is called after successfull download
+ * to apply the clock setting provided in config file
+ *
+ * Returns void.
+ *
+ ******************************************************************************/
+static void phNxpNciHal_set_clock(void)
+{
+ NFCSTATUS status = NFCSTATUS_FAILED;
+ int retryCount = 0;
+
+retrySetclock:
+ phNxpNciClock.isClockSet = TRUE;
+ if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_PLL)
+ {
+ static uint8_t set_clock_cmd[] = {0x20, 0x02,0x09, 0x02, 0xA0, 0x03, 0x01, 0x11,
+ 0xA0, 0x04, 0x01, 0x01};
+ uint8_t param_clock_src = CLK_SRC_PLL;
+ param_clock_src = param_clock_src << 3;
+
+ if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_13MHZ)
+ {
+ param_clock_src |= 0x00;
+ }
+ else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_19_2MHZ)
+ {
+ param_clock_src |= 0x01;
+ }
+ else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_24MHZ)
+ {
+ param_clock_src |= 0x02;
+ }
+ else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_26MHZ)
+ {
+ param_clock_src |= 0x03;
+ }
+ else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_38_4MHZ)
+ {
+ param_clock_src |= 0x04;
+ }
+ else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_52MHZ)
+ {
+ param_clock_src |= 0x05;
+ }
+ else
+ {
+ NXPLOG_NCIHAL_E("Wrong clock freq, send default PLL@19.2MHz");
+ param_clock_src = 0x11;
+ }
+
+ set_clock_cmd[7] = param_clock_src;
+ set_clock_cmd[11] = nxpprofile_ctrl.bTimeout;
+ status = phNxpNciHal_send_ext_cmd(sizeof(set_clock_cmd), set_clock_cmd);
+ if (status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E("PLL colck setting failed !!");
+ }
+ }
+ else if(nxpprofile_ctrl.bClkSrcVal == CLK_SRC_XTAL)
+ {
+ static uint8_t set_clock_cmd[] = {0x20, 0x02, 0x05, 0x01, 0xA0, 0x03, 0x01, 0x08};
+ status = phNxpNciHal_send_ext_cmd(sizeof(set_clock_cmd), set_clock_cmd);
+ if (status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E("XTAL colck setting failed !!");
+ }
+ }
+ else
+ {
+ NXPLOG_NCIHAL_E("Wrong clock source. Dont apply any modification")
+ }
+
+ // Checking for SET CONFG SUCCESS, re-send the command if not.
+ phNxpNciClock.isClockSet = FALSE;
+ if(phNxpNciClock.p_rx_data[3] != NFCSTATUS_SUCCESS )
+ {
+ if(retryCount++ < 3)
+ {
+ NXPLOG_NCIHAL_E("Set-clk failed retry again ");
+ goto retrySetclock;
+ }
+ else
+ {
+ NXPLOG_NCIHAL_D("Set clk failed - max count = 0x%x exceeded ", retryCount);
+// NXPLOG_NCIHAL_E("Set Config is failed for Clock Due to elctrical disturbances, aborting the NFC process");
+// abort ();
+ }
+ }
+}
+
+/******************************************************************************
+ * Function phNxpNciHal_check_clock_config
+ *
+ * Description This function is called after successfull download
+ * to check if clock settings in config file and chip
+ * is same
+ *
+ * Returns void.
+ *
+ ******************************************************************************/
+NFCSTATUS phNxpNciHal_check_clock_config(void)
+{
+ NFCSTATUS status = NFCSTATUS_SUCCESS;
+ uint8_t param_clock_src;
+ static uint8_t get_clock_cmd[] = {0x20, 0x03,0x07, 0x03, 0xA0, 0x02,
+ 0xA0, 0x03, 0xA0, 0x04};
+ phNxpNciClock.isClockSet = TRUE;
+ phNxpNciHal_get_clk_freq();
+ status = phNxpNciHal_send_ext_cmd(sizeof(get_clock_cmd),get_clock_cmd);
+
+ if(status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E("unable to retrieve get_clk_src_sel");
+ return status;
+ }
+ param_clock_src = check_config_parameter();
+ if( phNxpNciClock.p_rx_data[12] == param_clock_src && phNxpNciClock.p_rx_data[16] == nxpprofile_ctrl.bTimeout)
+ {
+ phNxpNciClock.issetConfig = FALSE;
+ }else {
+ phNxpNciClock.issetConfig = TRUE;
+ }
+ phNxpNciClock.isClockSet = FALSE;
+
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpNciHal_china_tianjin_rf_setting
+ *
+ * Description This function is called to check RF Setting
+ *
+ * Returns Status.
+ *
+ ******************************************************************************/
+NFCSTATUS phNxpNciHal_china_tianjin_rf_setting(void)
+{
+ NFCSTATUS status = NFCSTATUS_SUCCESS;
+ int isfound = 0;
+ int rf_enable = FALSE;
+ int rf_val = 0;
+ int send_flag;
+ uint8_t retry_cnt =0;
+ int enable_bit =0;
+ static uint8_t get_rf_cmd[] = {0x20, 0x03,0x03, 0x01, 0xA0, 0x85};
+
+retry_send_ext:
+ if(retry_cnt > 3)
+ {
+ return NFCSTATUS_FAILED;
+ }
+ send_flag = TRUE;
+ phNxpNciRfSet.isGetRfSetting = TRUE;
+ status = phNxpNciHal_send_ext_cmd(sizeof(get_rf_cmd),get_rf_cmd);
+ if(status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E("unable to get the RF setting");
+ phNxpNciRfSet.isGetRfSetting = FALSE;
+ retry_cnt++;
+ goto retry_send_ext;
+ }
+ phNxpNciRfSet.isGetRfSetting = FALSE;
+ if(phNxpNciRfSet.p_rx_data[3] != 0x00)
+ {
+ NXPLOG_NCIHAL_E("GET_CONFIG_RSP is FAILED for CHINA TIANJIN");
+ return status;
+ }
+ rf_val = phNxpNciRfSet.p_rx_data[10];
+ isfound = (GetNxpNumValue(NAME_NXP_CHINA_TIANJIN_RF_ENABLED, (void *)&rf_enable, sizeof(rf_enable)));
+ if(isfound >0)
+ {
+ enable_bit = rf_val & 0x40;
+ if((enable_bit != 0x40) && (rf_enable == 1))
+ {
+ phNxpNciRfSet.p_rx_data[10] |= 0x40; // Enable if it is disabled
+ }
+ else if((enable_bit == 0x40) && (rf_enable == 0))
+ {
+ phNxpNciRfSet.p_rx_data[10] &= 0xBF; // Disable if it is Enabled
+ }
+ else
+ {
+ send_flag = FALSE; // No need to change in RF setting
+ }
+
+ if(send_flag == TRUE)
+ {
+ static uint8_t set_rf_cmd[] = {0x20, 0x02, 0x08, 0x01, 0xA0, 0x85, 0x04, 0x50, 0x08, 0x68, 0x00};
+ memcpy(&set_rf_cmd[4],&phNxpNciRfSet.p_rx_data[5],7);
+ status = phNxpNciHal_send_ext_cmd(sizeof(set_rf_cmd),set_rf_cmd);
+ if(status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E("unable to set the RF setting");
+ retry_cnt++;
+ goto retry_send_ext;
+ }
+ }
+ }
+
+ return status;
+}
+
+int check_config_parameter()
+{
+ NFCSTATUS status = NFCSTATUS_FAILED;
+ uint8_t param_clock_src = CLK_SRC_PLL;
+ if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_PLL)
+ {
+ param_clock_src = param_clock_src << 3;
+
+ if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_13MHZ)
+ {
+ param_clock_src |= 0x00;
+ }
+ else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_19_2MHZ)
+ {
+ param_clock_src |= 0x01;
+ }
+ else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_24MHZ)
+ {
+ param_clock_src |= 0x02;
+ }
+ else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_26MHZ)
+ {
+ param_clock_src |= 0x03;
+ }
+ else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_38_4MHZ)
+ {
+ param_clock_src |= 0x04;
+ }
+ else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_52MHZ)
+ {
+ param_clock_src |= 0x05;
+ }
+ else
+ {
+ NXPLOG_NCIHAL_E("Wrong clock freq, send default PLL@19.2MHz");
+ param_clock_src = 0x11;
+ }
+ }
+ else if(nxpprofile_ctrl.bClkSrcVal == CLK_SRC_XTAL)
+ {
+ param_clock_src = 0x08;
+
+ }
+ else
+ {
+ NXPLOG_NCIHAL_E("Wrong clock source. Dont apply any modification")
+ }
+ return param_clock_src;
+}
+/******************************************************************************
+ * Function phNxpNciHal_enable_i2c_fragmentation
+ *
+ * Description This function is called to process the response status
+ * and print the status byte.
+ *
+ * Returns void.
+ *
+ ******************************************************************************/
+void phNxpNciHal_enable_i2c_fragmentation()
+{
+ NFCSTATUS status = NFCSTATUS_FAILED;
+ static uint8_t fragmentation_enable_config_cmd[] = { 0x20, 0x02, 0x05, 0x01, 0xA0, 0x05, 0x01, 0x10};
+ int isfound = 0;
+ long i2c_status = 0x00;
+ long config_i2c_vlaue = 0xff;
+ /*NCI_RESET_CMD*/
+ static uint8_t cmd_reset_nci[] = {0x20,0x00,0x01,0x01};
+ /*NCI_INIT_CMD*/
+ static uint8_t cmd_init_nci[] = {0x20,0x01,0x00};
+ static uint8_t get_i2c_fragmentation_cmd[] = {0x20, 0x03, 0x03, 0x01 ,0xA0 ,0x05};
+ isfound = (GetNxpNumValue(NAME_NXP_I2C_FRAGMENTATION_ENABLED, (void *)&i2c_status, sizeof(i2c_status)));
+ status = phNxpNciHal_send_ext_cmd(sizeof(get_i2c_fragmentation_cmd),get_i2c_fragmentation_cmd);
+ if(status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E("unable to retrieve get_i2c_fragmentation_cmd");
+ }
+ else
+ {
+ if(nxpncihal_ctrl.p_rx_data[8] == 0x10)
+ {
+ config_i2c_vlaue = 0x01;
+ phNxpNciHal_notify_i2c_fragmentation();
+ phTmlNfc_set_fragmentation_enabled(I2C_FRAGMENTATION_ENABLED);
+ }
+ else if(nxpncihal_ctrl.p_rx_data[8] == 0x00)
+ {
+ config_i2c_vlaue = 0x00;
+ }
+ if( config_i2c_vlaue == i2c_status)
+ {
+ NXPLOG_NCIHAL_E("i2c_fragmentation_status existing");
+ }
+ else
+ {
+ if (i2c_status == 0x01)
+ {
+ /* NXP I2C fragmenation enabled*/
+ status = phNxpNciHal_send_ext_cmd(sizeof(fragmentation_enable_config_cmd), fragmentation_enable_config_cmd);
+ if (status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E("NXP fragmentation enable failed");
+ }
+ }
+ else if (i2c_status == 0x00 || config_i2c_vlaue == 0xff)
+ {
+ fragmentation_enable_config_cmd[7] = 0x00;
+ /* NXP I2C fragmentation disabled*/
+ status = phNxpNciHal_send_ext_cmd(sizeof(fragmentation_enable_config_cmd), fragmentation_enable_config_cmd);
+ if (status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E("NXP fragmentation disable failed");
+ }
+ }
+ status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci),cmd_reset_nci);
+ if(status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E ("NCI_CORE_RESET: Failed");
+ }
+ status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci),cmd_init_nci);
+ if(status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E ("NCI_CORE_INIT : Failed");
+ }
+ else if(i2c_status == 0x01)
+ {
+ phNxpNciHal_notify_i2c_fragmentation();
+ phTmlNfc_set_fragmentation_enabled(I2C_FRAGMENTATION_ENABLED);
+ }
+ }
+ }
+}
+/******************************************************************************
+ * Function phNxpNciHal_check_factory_reset
+ *
+ * Description This function is called at init time to check
+ * the presence of ese related info. If file are not
+ * present set the SWP_INT_SESSION_ID_CFG to FF to
+ * force the NFCEE to re-run its initialization sequence.
+ *
+ * Returns void.
+ *
+ ******************************************************************************/
+static void phNxpNciHal_check_factory_reset(void)
+{
+ struct stat st;
+ int ret = 0;
+ NFCSTATUS status = NFCSTATUS_FAILED;
+ const char config_eseinfo_path[] = "/data/nfc/nfaStorage.bin1";
+ static uint8_t reset_ese_session_identity_set[] = { 0x20, 0x02, 0x17, 0x02,
+ 0xA0, 0xEA, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xA0, 0xEB, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+#ifdef PN547C2_FACTORY_RESET_DEBUG
+ static uint8_t reset_ese_session_identity[] = { 0x20, 0x03, 0x05, 0x02,
+ 0xA0, 0xEA, 0xA0, 0xEB};
+#endif
+ if (stat(config_eseinfo_path, &st) == -1)
+ {
+ NXPLOG_NCIHAL_D("%s file not present = %s", __FUNCTION__, config_eseinfo_path);
+ ret = -1;
+ }
+ else
+ {
+ ret = 0;
+ }
+
+ if(ret == -1)
+ {
+#ifdef PN547C2_FACTORY_RESET_DEBUG
+ /* NXP ACT Proprietary Ext */
+ status = phNxpNciHal_send_ext_cmd(sizeof(reset_ese_session_identity),
+ reset_ese_session_identity);
+ if (status != NFCSTATUS_SUCCESS) {
+ NXPLOG_NCIHAL_E("NXP reset_ese_session_identity command failed");
+ }
+#endif
+ status = phNxpNciHal_send_ext_cmd(sizeof(reset_ese_session_identity_set),
+ reset_ese_session_identity_set);
+ if (status != NFCSTATUS_SUCCESS) {
+ NXPLOG_NCIHAL_E("NXP reset_ese_session_identity_set command failed");
+ }
+#ifdef PN547C2_FACTORY_RESET_DEBUG
+ /* NXP ACT Proprietary Ext */
+ status = phNxpNciHal_send_ext_cmd(sizeof(reset_ese_session_identity),
+ reset_ese_session_identity);
+ if (status != NFCSTATUS_SUCCESS) {
+ NXPLOG_NCIHAL_E("NXP reset_ese_session_identity command failed");
+ }
+#endif
+
+ }
+}
+
+/******************************************************************************
+ * Function phNxpNciHal_print_res_status
+ *
+ * Description This function is called to process the response status
+ * and print the status byte.
+ *
+ * Returns void.
+ *
+ ******************************************************************************/
+static void phNxpNciHal_print_res_status( uint8_t *p_rx_data, uint16_t *p_len)
+{
+ static uint8_t response_buf[][30] = {"STATUS_OK",
+ "STATUS_REJECTED",
+ "STATUS_RF_FRAME_CORRUPTED" ,
+ "STATUS_FAILED" ,
+ "STATUS_NOT_INITIALIZED" ,
+ "STATUS_SYNTAX_ERROR",
+ "STATUS_SEMANTIC_ERROR",
+ "RFU",
+ "RFU",
+ "STATUS_INVALID_PARAM",
+ "STATUS_MESSAGE_SIZE_EXCEEDED",
+ "STATUS_UNDEFINED"};
+ int status_byte;
+ if(p_rx_data[0] == 0x40 && (p_rx_data[1] == 0x02 || p_rx_data[1] == 0x03))
+ {
+ if(p_rx_data[2] && p_rx_data[3]<=10)
+ {
+ status_byte = p_rx_data[CORE_RES_STATUS_BYTE];
+ NXPLOG_NCIHAL_D("%s: response status =%s",__FUNCTION__,response_buf[status_byte]);
+ }
+ else
+ {
+ NXPLOG_NCIHAL_D("%s: response status =%s",__FUNCTION__,response_buf[11]);
+ }
+ if(phNxpNciClock.isClockSet)
+ {
+ int i;
+ for(i=0; i<* p_len; i++)
+ {
+ phNxpNciClock.p_rx_data[i] = p_rx_data[i];
+ }
+ }
+
+ if(phNxpNciRfSet.isGetRfSetting)
+ {
+ int i;
+ for(i=0; i<* p_len; i++)
+ {
+ phNxpNciRfSet.p_rx_data[i] = p_rx_data[i];
+ //NXPLOG_NCIHAL_D("%s: response status =0x%x",__FUNCTION__,p_rx_data[i]);
+ }
+
+ }
+ }
+
+if((p_rx_data[2])&&(config_access == TRUE))
+ {
+ if(p_rx_data[3]!=NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_W("Invalid Data from config file . Aborting..");
+ phNxpNciHal_close();
+ }
+ }
+}
diff --git a/halimpl/pn54x/hal/phNxpNciHal.h b/halimpl/pn54x/hal/phNxpNciHal.h
new file mode 100644
index 0000000..0ded653
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal.h
@@ -0,0 +1,129 @@
+/*
+ * 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>
+
+/********************* Definitions and structures *****************************/
+#define MAX_RETRY_COUNT 5
+#define NCI_MAX_DATA_LEN 300
+#define NCI_POLL_DURATION 500
+#define HAL_NFC_ENABLE_I2C_FRAGMENTATION_EVT 0x07
+#undef P2P_PRIO_LOGIC_HAL_IMP
+
+typedef void (phNxpNciHal_control_granted_callback_t)();
+
+/* NCI Data */
+typedef struct nci_data
+{
+ uint16_t len;
+ uint8_t p_data[NCI_MAX_DATA_LEN];
+} nci_data_t;
+
+typedef enum
+{
+ HAL_STATUS_OPEN = 0,
+ HAL_STATUS_CLOSE
+} phNxpNci_HalStatus;
+
+/* Macros to enable and disable extensions */
+#define HAL_ENABLE_EXT() (nxpncihal_ctrl.hal_ext_enabled = 1)
+#define HAL_DISABLE_EXT() (nxpncihal_ctrl.hal_ext_enabled = 0)
+
+/* NCI Control structure */
+typedef struct phNxpNciHal_Control
+{
+ phNxpNci_HalStatus halStatus; /* Indicate if hal is open or closed */
+ pthread_t client_thread; /* Integration thread handle */
+ uint8_t thread_running; /* Thread running if set to 1, else set to 0 */
+ phLibNfc_sConfig_t gDrvCfg; /* Driver config data */
+
+ /* Rx data */
+ uint8_t *p_rx_data;
+ uint16_t rx_data_len;
+
+ /* libnfc-nci callbacks */
+ nfc_stack_callback_t *p_nfc_stack_cback;
+ nfc_stack_data_callback_t *p_nfc_stack_data_cback;
+
+ /* control granted callback */
+ phNxpNciHal_control_granted_callback_t *p_control_granted_cback;
+
+ /* HAL open status */
+ bool_t hal_open_status;
+
+ /* HAL extensions */
+ uint8_t hal_ext_enabled;
+
+ /* Waiting semaphore */
+ phNxpNciHal_Sem_t ext_cb_data;
+
+ uint16_t cmd_len;
+ uint8_t p_cmd_data[NCI_MAX_DATA_LEN];
+ uint16_t rsp_len;
+ uint8_t p_rsp_data[NCI_MAX_DATA_LEN];
+
+ /* retry count used to force download */
+ uint16_t retry_cnt;
+ uint8_t read_retry_cnt;
+} phNxpNciHal_Control_t;
+
+typedef struct phNxpNciClock{
+ bool_t isClockSet;
+ uint8_t p_rx_data[20];
+ bool_t issetConfig;
+}phNxpNciClock_t;
+
+typedef struct phNxpNciRfSetting{
+ bool_t isGetRfSetting;
+ uint8_t p_rx_data[20];
+}phNxpNciRfSetting_t;
+
+
+typedef enum {
+ NFC_FORUM_PROFILE,
+ EMV_CO_PROFILE,
+ INVALID_PROFILe
+}phNxpNciProfile_t;
+/* NXP Poll Profile control structure */
+typedef struct phNxpNciProfile_Control
+{
+ phNxpNciProfile_t profile_type;
+ uint8_t bClkSrcVal; /* Holds the System clock source read from config file */
+ uint8_t bClkFreqVal; /* Holds the System clock frequency read from config file */
+ uint8_t bTimeout; /* Holds the Timeout Value */
+} phNxpNciProfile_Control_t;
+
+/* Internal messages to handle callbacks */
+#define NCI_HAL_OPEN_CPLT_MSG 0x411
+#define NCI_HAL_CLOSE_CPLT_MSG 0x412
+#define NCI_HAL_POST_INIT_CPLT_MSG 0x413
+#define NCI_HAL_PRE_DISCOVER_CPLT_MSG 0x414
+#define NCI_HAL_ERROR_MSG 0x415
+#define NCI_HAL_RX_MSG 0xF01
+
+#define NCIHAL_CMD_CODE_LEN_BYTE_OFFSET (2U)
+#define NCIHAL_CMD_CODE_BYTE_LEN (3U)
+
+/******************** NCI HAL exposed functions *******************************/
+
+void phNxpNciHal_request_control (void);
+void phNxpNciHal_release_control (void);
+int phNxpNciHal_write_unlocked (uint16_t data_len, const uint8_t *p_data);
+
+#endif /* _PHNXPNCIHAL_H_ */
diff --git a/halimpl/pn54x/hal/phNxpNciHal_Kovio.c b/halimpl/pn54x/hal/phNxpNciHal_Kovio.c
new file mode 100644
index 0000000..99ca605
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal_Kovio.c
@@ -0,0 +1,267 @@
+/*
+ * 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>
+
+
+#define KOVIO_TIMEOUT 1000 /* Timeout value to wait for RF INTF Activated NTF.*/
+#define KOVIO_ACT_NTF_TEMP_BUFF_LEN 32 /* length of temp buffer to manipulate
+ the activated notification to match BCM format*/
+#define MAX_WRITE_RETRY 5
+
+/******************* Global variables *****************************************/
+extern phNxpNciHal_Control_t nxpncihal_ctrl;
+extern NFCSTATUS phNxpNciHal_send_ext_cmd(uint16_t cmd_len, uint8_t *p_cmd);
+
+int kovio_detected = 0x00;
+int send_to_upper_kovio = 0x01;
+int disable_kovio=0x00;
+bool_t rf_deactive_cmd = FALSE;
+static uint8_t rf_deactivate_cmd[] = { 0x21, 0x06, 0x01, 0x03 }; /* discovery */
+static uint8_t rf_deactivated_ntf[] = { 0x61, 0x06, 0x02, 0x03, 0x01 };
+static uint8_t reset_ntf[] = {0x60, 0x00, 0x06, 0xA0, 0x00, 0xC7, 0xD4, 0x00, 0x00};
+
+static uint32_t kovio_timer;
+
+/************** Kovio functions ***************************************/
+
+static NFCSTATUS phNxpNciHal_rf_deactivate(void);
+
+/*******************************************************************************
+**
+** Function hal_write_cb
+**
+** Description Callback function for hal write.
+**
+** Returns None
+**
+*******************************************************************************/
+static void hal_write_cb(void *pContext, phTmlNfc_TransactInfo_t *pInfo)
+{
+ UNUSED(pContext);
+ UNUSED(pInfo);
+ return;
+}
+
+/*******************************************************************************
+**
+** Function kovio_timer_handler
+**
+** Description Callback function for kovio timer.
+**
+** Returns None
+**
+*******************************************************************************/
+static void kovio_timer_handler(uint32_t timerId, void *pContext)
+{
+ UNUSED(timerId);
+ UNUSED(pContext);
+ NXPLOG_NCIHAL_D(">> kovio_timer_handler. Did not receive RF_INTF_ACTIVATED_NTF, Kovio TAG must be removed.");
+
+ phOsalNfc_Timer_Delete(kovio_timer);
+
+ kovio_detected = 0x00;
+ send_to_upper_kovio=0x01;
+ disable_kovio=0x00;
+ /*
+ * send kovio deactivated ntf to upper layer.
+ */
+ NXPLOG_NCIHAL_D(">> send kovio deactivated ntf to upper layer.");
+ if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL)
+ {
+ (*nxpncihal_ctrl.p_nfc_stack_data_cback)(
+ sizeof(rf_deactivated_ntf), rf_deactivated_ntf);
+ }
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_rf_deactivate
+**
+** Description Sends rf deactivate cmd to NFCC
+**
+** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_rf_deactivate()
+{
+ NFCSTATUS status = NFCSTATUS_SUCCESS;
+ int cb_data;
+ int retryCnt = 0;
+
+ do
+ {
+ retryCnt++;
+ status = phTmlNfc_Write(rf_deactivate_cmd,
+ sizeof(rf_deactivate_cmd),
+ (pphTmlNfc_TransactCompletionCb_t) &hal_write_cb, &cb_data);
+ } while(status != NFCSTATUS_PENDING && retryCnt <= MAX_WRITE_RETRY);
+
+ if(status != NFCSTATUS_PENDING)
+ {
+ //phNxpNciHal_emergency_recovery();
+ if (nxpncihal_ctrl.p_nfc_stack_data_cback!= NULL &&
+ nxpncihal_ctrl.hal_open_status == TRUE)
+ {
+ NXPLOG_NCIHAL_D("Send the Core Reset NTF to upper layer, which will trigger the recovery\n");
+ //Send the Core Reset NTF to upper layer, which will trigger the recovery.
+ nxpncihal_ctrl.rx_data_len = sizeof(reset_ntf);
+ memcpy(nxpncihal_ctrl.p_rx_data, reset_ntf, sizeof(reset_ntf));
+ //(*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rx_data_len, nxpncihal_ctrl.p_rx_data);
+ }
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_kovio_rsp_ext
+**
+** Description Implements kovio presence check. In BCM controller this is
+** managed by NFCC. But since PN54X does not handle this, the
+** presence check is mimiced here.
+** For the very first time Kovio is detected, NTF has to be
+** passed on to upper layer. for every NTF, DH send a deactivated
+** command to NFCC and NFCC follows this up with another activated
+** notification. When the tag is removed, activated notification
+** stops coming and this is indicated to upper layer with a HAL
+** generated deactivated notification.
+** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED
+**
+*******************************************************************************/
+NFCSTATUS phNxpNciHal_kovio_rsp_ext(uint8_t *p_ntf, uint16_t *p_len)
+{
+ NFCSTATUS status = NFCSTATUS_SUCCESS;
+ uint8_t tBuff[KOVIO_ACT_NTF_TEMP_BUFF_LEN];
+
+ send_to_upper_kovio = 1;
+ if((p_ntf[0]==0x61)&&(p_ntf[1]==0x05))
+ {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ if((p_ntf[5]==0x81)&&(p_ntf[6]==0x70))
+#else
+ if((p_ntf[5]==0x8A)&&(p_ntf[6]==0x77))
+#endif
+ {
+ if (kovio_detected == 0)
+ {
+ if((*p_len-9)<KOVIO_ACT_NTF_TEMP_BUFF_LEN)
+ {
+ p_ntf[2]+=1;
+ memcpy(tBuff, &p_ntf[9], *p_len-9);
+ p_ntf[9]=p_ntf[9]+1;
+ memcpy(&p_ntf[10], tBuff, *p_len-9);
+ *p_len+=1;
+ }else
+ {
+ NXPLOG_NCIHAL_D("Kovio Act ntf payload exceeded temp buffer size");
+ }
+ kovio_detected = 1;
+ kovio_timer = phOsalNfc_Timer_Create();
+ NXPLOG_NCIHAL_D("custom kovio timer Created - %d", kovio_timer);
+ }
+ else
+ {
+ send_to_upper_kovio = 0;
+ }
+
+ if(!rf_deactive_cmd)
+ {
+ NXPLOG_NCIHAL_D("Send RF deactivate command to NFCC");
+ status = phNxpNciHal_rf_deactivate();
+ }
+ else
+ {
+ NXPLOG_NCIHAL_D("RF deactivate command is already sent to NFCC");
+ disable_kovio = TRUE;
+ 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))
+ {
+ rf_deactive_cmd = FALSE;
+ 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..5262d86
--- /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..b1fcdc1
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal_NfcDepSWPrio.c
@@ -0,0 +1,621 @@
+/*
+ * 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>
+
+#define CUSTOM_POLL_TIMEOUT 160 /* Timeout value to wait for NFC-DEP detection.*/
+#define CLEAN_UP_TIMEOUT 250
+#define MAX_WRITE_RETRY 5
+
+/******************* Global variables *****************************************/
+extern phNxpNciHal_Control_t nxpncihal_ctrl;
+extern NFCSTATUS phNxpNciHal_send_ext_cmd(uint16_t cmd_len, uint8_t *p_cmd);
+static uint8_t cmd_stop_rf_discovery[] = { 0x21, 0x06, 0x01, 0x00 }; /* IDLE */
+static uint8_t cmd_resume_rf_discovery[] = { 0x21, 0x06, 0x01, 0x03 }; /* RF_DISCOVER */
+
+/*RF_DISCOVER_SELECT_CMD*/
+static uint8_t cmd_select_rf_discovery[] = {0x21,0x04,0x03,0x01,0x04,0x02 };
+
+static uint8_t cmd_poll[64];
+static uint8_t cmd_poll_len = 0;
+int discover_type = 0xFF;
+uint32_t cleanup_timer;
+
+/*PRIO LOGIC related dead functions undefined*/
+#ifdef P2P_PRIO_LOGIC_HAL_IMP
+
+static int iso_dep_detected = 0x00;
+static int poll_timer_fired = 0x00;
+static uint8_t bIgnorep2plogic = 0;
+static uint8_t *p_iso_ntf_buff = NULL; /* buffer to store second notification */
+static uint8_t bIgnoreIsoDep = 0;
+static uint32_t custom_poll_timer;
+
+/************** NFC-DEP SW PRIO functions ***************************************/
+
+static NFCSTATUS phNxpNciHal_start_polling_loop(void);
+static NFCSTATUS phNxpNciHal_stop_polling_loop(void);
+static NFCSTATUS phNxpNciHal_resume_polling_loop(void);
+static void phNxpNciHal_NfcDep_store_ntf(uint8_t *p_cmd_data, uint16_t cmd_len);
+
+
+/*******************************************************************************
+**
+** Function cleanup_timer_handler
+**
+** Description Callback function for cleanup timer.
+**
+** Returns None
+**
+*******************************************************************************/
+static void cleanup_timer_handler(uint32_t timerId, void *pContext)
+{
+ NXPLOG_NCIHAL_D(">> cleanup_timer_handler.");
+
+ NXPLOG_NCIHAL_D(">> cleanup_timer_handler. ISO_DEP not detected second time.");
+
+ phOsalNfc_Timer_Delete(cleanup_timer);
+ cleanup_timer=0;
+ iso_dep_detected = 0x00;
+ EnableP2P_PrioLogic = FALSE;
+ return;
+}
+
+/*******************************************************************************
+**
+** Function custom_poll_timer_handler
+**
+** Description Callback function for custom poll timer.
+**
+** Returns None
+**
+*******************************************************************************/
+static void custom_poll_timer_handler(uint32_t timerId, void *pContext)
+{
+ NXPLOG_NCIHAL_D(">> custom_poll_timer_handler.");
+
+ NXPLOG_NCIHAL_D(">> custom_poll_timer_handler. NFC_DEP not detected. so giving early chance to ISO_DEP.");
+
+ phOsalNfc_Timer_Delete(custom_poll_timer);
+
+ if (iso_dep_detected == 0x01)
+ {
+ poll_timer_fired = 0x01;
+
+ /*
+ * Restart polling loop.
+ * When the polling loop is stopped, polling will be restarted.
+ */
+ NXPLOG_NCIHAL_D(">> custom_poll_timer_handler - restart polling loop.");
+
+ phNxpNciHal_stop_polling_loop();
+ }
+ else
+ {
+ NXPLOG_NCIHAL_E(">> custom_poll_timer_handler - invalid flag state (iso_dep_detected)");
+ }
+
+ return;
+}
+/*******************************************************************************
+**
+** Function phNxpNciHal_stop_polling_loop
+**
+** Description Sends stop polling cmd to NFCC
+**
+** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_stop_polling_loop()
+{
+ NFCSTATUS status = NFCSTATUS_SUCCESS;
+ phNxpNciHal_Sem_t cb_data;
+ pthread_t pthread;
+ discover_type = STOP_POLLING;
+
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ if(pthread_create(&pthread, &attr, tmp_thread, (void*) &discover_type) != 0)
+ {
+ NXPLOG_NCIHAL_E("phNxpNciHal_resume_polling_loop");
+ }
+ 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");
+ 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..15c72a3
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal_NfcDepSWPrio.h
@@ -0,0 +1,38 @@
+/*
+ * 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..0155c09
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal_dta.c
@@ -0,0 +1,260 @@
+/*
+ * 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..a8efd2d
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal_dta.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_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..81121ff
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal_ext.c
@@ -0,0 +1,920 @@
+/*
+ * 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>
+
+#define HAL_EXTNS_WRITE_RSP_TIMEOUT (1000) /* Timeout value to wait for response from PN548AD */
+
+#undef P2P_PRIO_LOGIC_HAL_IMP
+
+/******************* Global variables *****************************************/
+extern phNxpNciHal_Control_t nxpncihal_ctrl;
+extern phNxpNciProfile_Control_t nxpprofile_ctrl;
+
+extern int kovio_detected;
+extern int disable_kovio;
+extern int send_to_upper_kovio;
+extern uint32_t cleanup_timer;
+static uint8_t icode_detected = 0x00;
+uint8_t icode_send_eof = 0x00;
+static uint8_t ee_disc_done = 0x00;
+uint8_t EnableP2P_PrioLogic = FALSE;
+static uint32_t RfDiscID = 1;
+static uint32_t RfProtocolType = 4;
+/* NFCEE Set mode */
+static uint8_t setEEModeDone = 0x00;
+static uint8_t cmd_nfcee_setmode_enable[] = { 0x22, 0x01, 0x02, 0x01, 0x01 };
+
+/* External global variable to get FW version from NCI response*/
+extern uint32_t wFwVerRsp;
+/* External global variable to get FW version from FW file*/
+extern uint16_t wFwVer;
+
+/* local buffer to store CORE_INIT response */
+static uint32_t bCoreInitRsp[40];
+static uint32_t iCoreInitRspLen;
+
+extern uint32_t timeoutTimerId;
+
+extern NFCSTATUS read_retry();
+/************** HAL extension functions ***************************************/
+static void hal_extns_write_rsp_timeout_cb(uint32_t TimerId, void *pContext);
+
+/*Proprietary cmd sent to HAL to send reader mode flag
+ * Last byte of 4 byte proprietary cmd data contains ReaderMode flag
+ * If this flag is enabled, NFC-DEP protocol is modified to T3T protocol
+ * if FrameRF interface is selected. This needs to be done as the FW
+ * always sends Ntf for FrameRF with NFC-DEP even though FrameRF with T3T is
+ * previously selected with DISCOVER_SELECT_CMD
+ */
+#define PROPRIETARY_CMD_FELICA_READER_MODE 0xFE
+static uint8_t gFelicaReaderMode;
+
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_ext_init
+**
+** Description initialize extension function
+**
+*******************************************************************************/
+void phNxpNciHal_ext_init (void)
+{
+ icode_detected = 0x00;
+ icode_send_eof = 0x00;
+ setEEModeDone = 0x00;
+ kovio_detected = 0x00;
+ disable_kovio = 0x00;
+ send_to_upper_kovio = 0x01;
+ EnableP2P_PrioLogic = FALSE;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_process_ext_rsp
+**
+** Description Process extension function response
+**
+** Returns NFCSTATUS_SUCCESS if success
+**
+*******************************************************************************/
+NFCSTATUS phNxpNciHal_process_ext_rsp (uint8_t *p_ntf, uint16_t *p_len)
+{
+
+ NFCSTATUS status = NFCSTATUS_SUCCESS;
+ uint16_t rf_technology_length_param = 0;
+
+ if (p_ntf[0] == 0x61 &&
+ p_ntf[1] == 0x05 &&
+ p_ntf[4] == 0x03 &&
+ p_ntf[5] == 0x05 &&
+ nxpprofile_ctrl.profile_type == EMV_CO_PROFILE)
+ {
+ p_ntf[4] = 0xFF;
+ p_ntf[5] = 0xFF;
+ p_ntf[6] = 0xFF;
+ NXPLOG_NCIHAL_D("Nfc-Dep Detect in EmvCo profile - Restart polling");
+ }
+
+ if (p_ntf[0] == 0x61 &&
+ p_ntf[1] == 0x05 &&
+ p_ntf[4] == 0x01 &&
+ p_ntf[5] == 0x05 &&
+ p_ntf[6] == 0x02 &&
+ gFelicaReaderMode)
+ {
+ /*If FelicaReaderMode is enabled,Change Protocol to T3T from NFC-DEP
+ * when FrameRF interface is selected*/
+ p_ntf[5] = 0x03;
+ NXPLOG_NCIHAL_D("FelicaReaderMode:Activity 1.1");
+ }
+
+#ifdef P2P_PRIO_LOGIC_HAL_IMP
+ if(p_ntf[0] == 0x61 &&
+ p_ntf[1] == 0x05 &&
+ p_ntf[4] == 0x02 &&
+ p_ntf[5] == 0x04 &&
+ nxpprofile_ctrl.profile_type == NFC_FORUM_PROFILE)
+ {
+ EnableP2P_PrioLogic = TRUE;
+ }
+
+ NXPLOG_NCIHAL_D("Is EnableP2P_PrioLogic: 0x0%X", EnableP2P_PrioLogic);
+ if(phNxpDta_IsEnable() == FALSE)
+ {
+ if ((icode_detected != 1)&&(kovio_detected != 1) && (EnableP2P_PrioLogic == TRUE))
+ {
+ if (phNxpNciHal_NfcDep_comapre_ntf(p_ntf, *p_len) == NFCSTATUS_FAILED)
+ {
+ status = phNxpNciHal_NfcDep_rsp_ext(p_ntf,p_len);
+ if(status != NFCSTATUS_INVALID_PARAMETER)
+ {
+ return status;
+ }
+ }
+ }
+ }
+#endif
+
+ status = NFCSTATUS_SUCCESS;
+ status = phNxpNciHal_kovio_rsp_ext(p_ntf,p_len);
+
+ if (p_ntf[0] == 0x61 &&
+ p_ntf[1] == 0x05)
+ {
+ switch (p_ntf[4])
+ {
+ case 0x00:
+ NXPLOG_NCIHAL_D("NxpNci: RF Interface = NFCEE Direct RF");
+ break;
+ case 0x01:
+ NXPLOG_NCIHAL_D("NxpNci: RF Interface = Frame RF");
+ break;
+ case 0x02:
+ NXPLOG_NCIHAL_D("NxpNci: RF Interface = ISO-DEP");
+ break;
+ case 0x03:
+ NXPLOG_NCIHAL_D("NxpNci: RF Interface = NFC-DEP");
+ break;
+ case 0x80:
+ NXPLOG_NCIHAL_D("NxpNci: RF Interface = MIFARE");
+ break;
+ default:
+ NXPLOG_NCIHAL_D("NxpNci: RF Interface = Unknown");
+ break;
+ }
+
+ switch (p_ntf[5])
+ {
+ case 0x01:
+ NXPLOG_NCIHAL_D("NxpNci: Protocol = T1T");
+ phNxpDta_T1TEnable();
+ break;
+ case 0x02:
+ NXPLOG_NCIHAL_D("NxpNci: Protocol = T2T");
+ break;
+ case 0x03:
+ NXPLOG_NCIHAL_D("NxpNci: Protocol = T3T");
+ break;
+ case 0x04:
+ NXPLOG_NCIHAL_D("NxpNci: Protocol = ISO-DEP");
+ break;
+ case 0x05:
+ NXPLOG_NCIHAL_D("NxpNci: Protocol = NFC-DEP");
+ break;
+ case 0x06:
+ NXPLOG_NCIHAL_D("NxpNci: Protocol = 15693");
+ break;
+ case 0x80:
+ NXPLOG_NCIHAL_D("NxpNci: Protocol = MIFARE");
+ break;
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ case 0x81:
+#else
+ case 0x8A:
+#endif
+ NXPLOG_NCIHAL_D("NxpNci: Protocol = Kovio");
+ break;
+ default:
+ NXPLOG_NCIHAL_D("NxpNci: Protocol = Unknown");
+ break;
+ }
+
+ switch (p_ntf[6])
+ {
+ case 0x00:
+ NXPLOG_NCIHAL_D("NxpNci: Mode = A Passive Poll");
+ break;
+ case 0x01:
+ NXPLOG_NCIHAL_D("NxpNci: Mode = B Passive Poll");
+ break;
+ case 0x02:
+ NXPLOG_NCIHAL_D("NxpNci: Mode = F Passive Poll");
+ break;
+ case 0x03:
+ NXPLOG_NCIHAL_D("NxpNci: Mode = A Active Poll");
+ break;
+ case 0x05:
+ NXPLOG_NCIHAL_D("NxpNci: Mode = F Active Poll");
+ break;
+ case 0x06:
+ NXPLOG_NCIHAL_D("NxpNci: Mode = 15693 Passive Poll");
+ break;
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ case 0x70:
+#else
+ case 0x77:
+#endif
+ NXPLOG_NCIHAL_D("NxpNci: Mode = Kovio");
+ break;
+ case 0x80:
+ NXPLOG_NCIHAL_D("NxpNci: Mode = A Passive Listen");
+ break;
+ case 0x81:
+ NXPLOG_NCIHAL_D("NxpNci: Mode = B Passive Listen");
+ break;
+ case 0x82:
+ NXPLOG_NCIHAL_D("NxpNci: Mode = F Passive Listen");
+ break;
+ case 0x83:
+ NXPLOG_NCIHAL_D("NxpNci: Mode = A Active Listen");
+ break;
+ case 0x85:
+ NXPLOG_NCIHAL_D("NxpNci: Mode = F Active Listen");
+ break;
+ case 0x86:
+ NXPLOG_NCIHAL_D("NxpNci: Mode = 15693 Passive Listen");
+ break;
+ default:
+ NXPLOG_NCIHAL_D("NxpNci: Mode = Unknown");
+ break;
+ }
+ }
+
+ if (p_ntf[0] == 0x61 &&
+ p_ntf[1] == 0x05 &&
+ p_ntf[2] == 0x15 &&
+ p_ntf[4] == 0x01 &&
+ p_ntf[5] == 0x06 &&
+ p_ntf[6] == 0x06)
+ {
+ NXPLOG_NCIHAL_D ("> 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;
+ status = NFCSTATUS_FAILED;
+ return status;
+ }
+ else if (p_ntf[0] == 0x00 &&
+ p_ntf[1] == 0x00 &&
+ icode_detected == 1)
+ {
+ if (icode_send_eof == 3)
+ {
+ icode_send_eof = 0;
+ }
+ if (p_ntf[p_ntf[2]+ 2] == 0x00)
+ {
+ NXPLOG_NCIHAL_D ("> Data of ISO-15693");
+ p_ntf[2]--;
+ (*p_len)--;
+ }
+ }
+ else if (p_ntf[2] == 0x02 &&
+ p_ntf[1] == 0x00 && icode_detected == 1)
+ {
+ NXPLOG_NCIHAL_D ("> ICODE EOF response do not send to upper layer");
+ }
+ else if(p_ntf[0] == 0x61 &&
+ p_ntf[1] == 0x06 && icode_detected == 1)
+ {
+ NXPLOG_NCIHAL_D ("> Polling Loop Re-Started");
+ icode_detected = 0;
+ icode_send_eof = 0;
+ }
+ else if(*p_len == 4 &&
+ p_ntf[0] == 0x40 &&
+ p_ntf[1] == 0x02 &&
+ p_ntf[2] == 0x01 &&
+ p_ntf[3] == 0x06 )
+ {
+ NXPLOG_NCIHAL_D ("> Deinit for LLCP set_config 0x%x 0x%x 0x%x", p_ntf[21], p_ntf[22], p_ntf[23]);
+ p_ntf[0] = 0x40;
+ p_ntf[1] = 0x02;
+ p_ntf[2] = 0x02;
+ p_ntf[3] = 0x00;
+ p_ntf[4] = 0x00;
+ *p_len = 5;
+ }
+ else if ((p_ntf[0] == 0x40) && (p_ntf[1] == 0x01))
+ {
+ int len = p_ntf[2] + 2; /*include 2 byte header*/
+ wFwVerRsp= (((uint32_t)p_ntf[len - 2])<< 16U)|(((uint32_t)p_ntf[len - 1])<< 8U)|p_ntf[len];
+ if(wFwVerRsp == 0)
+ status = NFCSTATUS_FAILED;
+ iCoreInitRspLen = *p_len;
+ memcpy(bCoreInitRsp, p_ntf, *p_len);
+ NXPLOG_NCIHAL_D ("NxpNci> FW Version: %x.%x.%x", p_ntf[len-2], p_ntf[len-1], p_ntf[len]);
+ NXPLOG_NCIHAL_D ("NxpNci> Model id: %x", p_ntf[len-3]>>4);
+ /* 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)))
+ {
+ if(0x01 == (p_ntf[len-3]>>4))
+ {
+ NXPLOG_NCIHAL_D ("NxpNci> Product: PN66T");
+ }
+ else
+ {
+ NXPLOG_NCIHAL_D ("NxpNci> Product: PN548c2");
+ }
+ }
+ else
+ { /* 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");
+ }
+ }
+ }
+ else
+ {
+ /* Do Nothing */
+ }
+ }
+ //4200 02 00 01
+ 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(p_ntf[0] == 0x60 && p_ntf[1] == 0x00)
+ {
+ NXPLOG_NCIHAL_E("CORE_RESET_NTF received!");
+ phNxpNciHal_emergency_recovery();
+ }
+#if(NFC_NXP_CHIP_TYPE == PN547C2)
+ else if(p_ntf[0] == 0x61 && p_ntf[1] == 0x05
+ && p_ntf[4] == 0x02 && p_ntf[5] == 0x80
+ && p_ntf[6] == 0x00 )
+ {
+ NXPLOG_NCIHAL_D("Going through 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;
+ }
+ }
+#endif
+ /*
+ else if(p_ntf[0] == 0x61 && p_ntf[1] == 0x05 && p_ntf[4] == 0x01 && p_ntf[5] == 0x00 && p_ntf[6] == 0x01)
+ {
+ NXPLOG_NCIHAL_D("Picopass type 3-B with undefined protocol is not supported, disabling");
+ p_ntf[4] = 0xFF;
+ p_ntf[5] = 0xFF;
+ p_ntf[6] = 0xFF;
+ }*/
+
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpNciHal_process_ext_cmd_rsp
+ *
+ * Description This function process the extension command response. It
+ * also checks the received response to expected response.
+ *
+ * Returns returns NFCSTATUS_SUCCESS if response is as expected else
+ * returns failure.
+ *
+ ******************************************************************************/
+static NFCSTATUS phNxpNciHal_process_ext_cmd_rsp(uint16_t cmd_len, uint8_t *p_cmd)
+{
+ NFCSTATUS status = NFCSTATUS_FAILED;
+ uint16_t data_written = 0;
+
+ /* Create the local semaphore */
+ if (phNxpNciHal_init_cb_data(&nxpncihal_ctrl.ext_cb_data, NULL)
+ != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_D("Create ext_cb_data failed");
+ return NFCSTATUS_FAILED;
+ }
+
+ nxpncihal_ctrl.ext_cb_data.status = NFCSTATUS_SUCCESS;
+
+ /* Send ext command */
+ data_written = phNxpNciHal_write_unlocked(cmd_len, p_cmd);
+ if (data_written != cmd_len)
+ {
+ NXPLOG_NCIHAL_D("phNxpNciHal_write failed for hal ext");
+ goto clean_and_return;
+ }
+
+ /* Start timer */
+ status = phOsalNfc_Timer_Start(timeoutTimerId,
+ HAL_EXTNS_WRITE_RSP_TIMEOUT,
+ &hal_extns_write_rsp_timeout_cb,
+ NULL);
+ if (NFCSTATUS_SUCCESS == status)
+ {
+ NXPLOG_NCIHAL_D("Response timer started");
+ }
+ else
+ {
+ NXPLOG_NCIHAL_E("Response timer not started!!!");
+ status = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ /* Wait for rsp */
+ NXPLOG_NCIHAL_D("Waiting after ext cmd sent");
+ if (SEM_WAIT(nxpncihal_ctrl.ext_cb_data))
+ {
+ NXPLOG_NCIHAL_E("p_hal_ext->ext_cb_data.sem semaphore error");
+ goto clean_and_return;
+ }
+
+ /* Stop Timer */
+ status = phOsalNfc_Timer_Stop(timeoutTimerId);
+
+ if (NFCSTATUS_SUCCESS == status)
+ {
+ NXPLOG_NCIHAL_D("Response timer stopped");
+ }
+ else
+ {
+ NXPLOG_NCIHAL_E("Response timer stop ERROR!!!");
+ status = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ if(nxpncihal_ctrl.ext_cb_data.status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E("Callback Status is failed!! Timer Expired!! Couldn't read it! 0x%x", nxpncihal_ctrl.ext_cb_data.status);
+ status = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ NXPLOG_NCIHAL_D("Checking response");
+ status = NFCSTATUS_SUCCESS;
+
+clean_and_return:
+ phNxpNciHal_cleanup_cb_data(&nxpncihal_ctrl.ext_cb_data);
+
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpNciHal_write_ext
+ *
+ * Description This function inform the status of phNxpNciHal_open
+ * function to libnfc-nci.
+ *
+ * Returns It return NFCSTATUS_SUCCESS then continue with send else
+ * sends NFCSTATUS_FAILED direct response is prepared and
+ * do not send anything to NFCC.
+ *
+ ******************************************************************************/
+
+NFCSTATUS phNxpNciHal_write_ext(uint16_t *cmd_len, uint8_t *p_cmd_data,
+ uint16_t *rsp_len, uint8_t *p_rsp_data)
+{
+ NFCSTATUS status = NFCSTATUS_SUCCESS;
+
+ unsigned long retval = 0;
+ int isfound = GetNxpNumValue(NAME_MIFARE_READER_ENABLE, &retval, sizeof(unsigned long));
+
+ phNxpNciHal_NfcDep_cmd_ext(p_cmd_data, cmd_len);
+
+ if(phNxpDta_IsEnable() == TRUE)
+ {
+ status = phNxpNHal_DtaUpdate(cmd_len, p_cmd_data,rsp_len, p_rsp_data);
+ }
+
+ if (p_cmd_data[0] == PROPRIETARY_CMD_FELICA_READER_MODE &&
+ p_cmd_data[1] == PROPRIETARY_CMD_FELICA_READER_MODE &&
+ p_cmd_data[2] == PROPRIETARY_CMD_FELICA_READER_MODE)
+ {
+ NXPLOG_NCIHAL_D ("Received proprietary command to set Felica Reader mode:%d",p_cmd_data[3]);
+ gFelicaReaderMode = p_cmd_data[3];
+ /* frame the dummy response */
+ *rsp_len = 4;
+ p_rsp_data[0] = 0x00;
+ p_rsp_data[1] = 0x00;
+ p_rsp_data[2] = 0x00;
+ p_rsp_data[3] = 0x00;
+ status = NFCSTATUS_FAILED;
+ }
+ else if (p_cmd_data[0] == 0x20 &&
+ p_cmd_data[1] == 0x02 &&
+ p_cmd_data[2] == 0x05 &&
+ p_cmd_data[3] == 0x01 &&
+ p_cmd_data[4] == 0xA0 &&
+ p_cmd_data[5] == 0x44 &&
+ p_cmd_data[6] == 0x01 &&
+ p_cmd_data[7] == 0x01)
+ {
+ nxpprofile_ctrl.profile_type = EMV_CO_PROFILE;
+ NXPLOG_NCIHAL_D ("EMV_CO_PROFILE mode - Enabled");
+ status = NFCSTATUS_SUCCESS;
+ }
+ else if (p_cmd_data[0] == 0x20 &&
+ p_cmd_data[1] == 0x02 &&
+ p_cmd_data[2] == 0x05 &&
+ p_cmd_data[3] == 0x01 &&
+ p_cmd_data[4] == 0xA0 &&
+ p_cmd_data[5] == 0x44 &&
+ p_cmd_data[6] == 0x01 &&
+ p_cmd_data[7] == 0x00)
+ {
+ NXPLOG_NCIHAL_D ("NFC_FORUM_PROFILE mode - Enabled");
+ nxpprofile_ctrl.profile_type = NFC_FORUM_PROFILE;
+ status = NFCSTATUS_SUCCESS;
+ }
+
+ if (nxpprofile_ctrl.profile_type == EMV_CO_PROFILE)
+ {
+ if (p_cmd_data[0] == 0x21 &&
+ p_cmd_data[1] == 0x06 &&
+ p_cmd_data[2] == 0x01 &&
+ p_cmd_data[3] == 0x03)
+ {
+#if 0
+ //Needs clarification whether to keep it or not
+ NXPLOG_NCIHAL_D ("EmvCo Poll mode - RF Deactivate discard");
+ phNxpNciHal_print_packet("SEND", p_cmd_data, *cmd_len);
+ *rsp_len = 4;
+ p_rsp_data[0] = 0x41;
+ p_rsp_data[1] = 0x06;
+ p_rsp_data[2] = 0x01;
+ p_rsp_data[3] = 0x00;
+ phNxpNciHal_print_packet("RECV", p_rsp_data, 4);
+ status = NFCSTATUS_FAILED;
+#endif
+ }
+ else if(p_cmd_data[0] == 0x21 &&
+ p_cmd_data[1] == 0x03 )
+ {
+ NXPLOG_NCIHAL_D ("EmvCo Poll mode - Discover map only for A and B");
+ p_cmd_data[2] = 0x05;
+ p_cmd_data[3] = 0x02;
+ p_cmd_data[4] = 0x00;
+ p_cmd_data[5] = 0x01;
+ p_cmd_data[6] = 0x01;
+ p_cmd_data[7] = 0x01;
+ *cmd_len = 8;
+ }
+ }
+#if(NFC_NXP_CHIP_TYPE == PN547C2)
+ if (retval == 0x01 &&
+ p_cmd_data[0] == 0x21 &&
+ p_cmd_data[1] == 0x00)
+ {
+ NXPLOG_NCIHAL_D ("Going through extns - Adding Mifare in RF Discovery");
+ p_cmd_data[2] += 3;
+ p_cmd_data[3] += 1;
+ p_cmd_data[*cmd_len] = 0x80;
+ p_cmd_data[*cmd_len + 1] = 0x01;
+ p_cmd_data[*cmd_len + 2] = 0x80;
+ *cmd_len += 3;
+ status = NFCSTATUS_SUCCESS;
+ NXPLOG_NCIHAL_D ("Going through extns - Adding Mifare in RF Discovery - END");
+ }
+ else
+#endif
+ if (p_cmd_data[3] == 0x81 &&
+ p_cmd_data[4] == 0x01 &&
+ p_cmd_data[5] == 0x03)
+ {
+ NXPLOG_NCIHAL_D("> Going through the set host list");
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ *cmd_len = 8;
+
+ p_cmd_data[2] = 0x05;
+ p_cmd_data[6] = 0x02;
+ p_cmd_data[7] = 0xC0;
+#else
+ *cmd_len = 7;
+
+ p_cmd_data[2] = 0x04;
+ p_cmd_data[6] = 0xC0;
+#endif
+ status = NFCSTATUS_SUCCESS;
+ }
+ else if(icode_detected)
+ {
+ if ((p_cmd_data[3] & 0x40) == 0x40 &&
+ (p_cmd_data[4] == 0x21 ||
+ p_cmd_data[4] == 0x22 ||
+ p_cmd_data[4] == 0x24 ||
+ p_cmd_data[4] == 0x27 ||
+ p_cmd_data[4] == 0x28 ||
+ p_cmd_data[4] == 0x29 ||
+ p_cmd_data[4] == 0x2a))
+ {
+ NXPLOG_NCIHAL_D ("> Send EOF set");
+ icode_send_eof = 1;
+ }
+
+ if(p_cmd_data[3] == 0x20 || p_cmd_data[3] == 0x24 ||
+ p_cmd_data[3] == 0x60)
+ {
+ NXPLOG_NCIHAL_D ("> NFC ISO_15693 Proprietary CMD ");
+ p_cmd_data[3] += 0x02;
+ }
+ }
+ else if(p_cmd_data[0] == 0x21 &&
+ p_cmd_data[1] == 0x03 )
+ {
+ NXPLOG_NCIHAL_D ("> Polling Loop Started");
+ icode_detected = 0;
+ icode_send_eof = 0;
+ }
+ //22000100
+ else if (p_cmd_data[0] == 0x22 &&
+ p_cmd_data[1] == 0x00 &&
+ p_cmd_data[2] == 0x01 &&
+ p_cmd_data[3] == 0x00
+ )
+ {
+ //ee_disc_done = 0x01;//Reader Over SWP event getting
+ *rsp_len = 0x05;
+ p_rsp_data[0] = 0x42;
+ p_rsp_data[1] = 0x00;
+ p_rsp_data[2] = 0x02;
+ p_rsp_data[3] = 0x00;
+ p_rsp_data[4] = 0x00;
+ phNxpNciHal_print_packet("RECV", p_rsp_data,5);
+ status = NFCSTATUS_FAILED;
+ }
+ //2002 0904 3000 3100 3200 5000
+ else if ( (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02 ) &&
+ ( (p_cmd_data[2] == 0x09 && p_cmd_data[3] == 0x04) /*||
+ (p_cmd_data[2] == 0x0D && p_cmd_data[3] == 0x04)*/
+ )
+ )
+ {
+ *cmd_len += 0x01;
+ p_cmd_data[2] += 0x01;
+ p_cmd_data[9] = 0x01;
+ p_cmd_data[10] = 0x40;
+ p_cmd_data[11] = 0x50;
+ p_cmd_data[12] = 0x00;
+
+ NXPLOG_NCIHAL_D ("> 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");
+ }
+ }
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpNciHal_send_ext_cmd
+ *
+ * Description This function send the extension command to NFCC. No
+ * response is checked by this function but it waits for
+ * the response to come.
+ *
+ * Returns Returns NFCSTATUS_SUCCESS if sending cmd is successful and
+ * response is received.
+ *
+ ******************************************************************************/
+NFCSTATUS phNxpNciHal_send_ext_cmd(uint16_t cmd_len, uint8_t *p_cmd)
+{
+ NFCSTATUS status = NFCSTATUS_FAILED;
+
+ HAL_ENABLE_EXT();
+ nxpncihal_ctrl.cmd_len = cmd_len;
+ memcpy(nxpncihal_ctrl.p_cmd_data, p_cmd, cmd_len);
+ status = phNxpNciHal_process_ext_cmd_rsp(nxpncihal_ctrl.cmd_len, nxpncihal_ctrl.p_cmd_data);
+ HAL_DISABLE_EXT();
+
+ return status;
+}
+
+/******************************************************************************
+ * Function hal_extns_write_rsp_timeout_cb
+ *
+ * Description Timer call back function
+ *
+ * Returns None
+ *
+ ******************************************************************************/
+static void hal_extns_write_rsp_timeout_cb(uint32_t timerId, void *pContext)
+{
+ UNUSED(timerId);
+ UNUSED(pContext);
+ NXPLOG_NCIHAL_E("hal_extns_write_rsp_timeout_cb - write timeout!!!");
+ nxpncihal_ctrl.ext_cb_data.status = NFCSTATUS_FAILED;
+ usleep(1);
+ SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
+
+ return;
+}
diff --git a/halimpl/pn54x/hal/phNxpNciHal_ext.h b/halimpl/pn54x/hal/phNxpNciHal_ext.h
new file mode 100644
index 0000000..9f8ec5e
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal_ext.h
@@ -0,0 +1,29 @@
+/*
+ * 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_write_ext(uint16_t *cmd_len, uint8_t *p_cmd_data,
+ uint16_t *rsp_len, uint8_t *p_rsp_data);
+
+#endif /* _PHNXPNICHAL_EXT_H_ */
diff --git a/halimpl/pn54x/inc/phNxpNciHal_Adaptation.h b/halimpl/pn54x/inc/phNxpNciHal_Adaptation.h
new file mode 100644
index 0000000..a8dfc61
--- /dev/null
+++ b/halimpl/pn54x/inc/phNxpNciHal_Adaptation.h
@@ -0,0 +1,42 @@
+/*
+ * 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>
+
+typedef struct
+{
+ struct nfc_nci_device nci_device;
+
+ /* Local definitions */
+} pn547_dev_t;
+
+/* NXP HAL functions */
+
+int phNxpNciHal_open(nfc_stack_callback_t *p_cback,
+ nfc_stack_data_callback_t *p_data_cback);
+int phNxpNciHal_write(uint16_t data_len, const uint8_t *p_data);
+int phNxpNciHal_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);
+
+#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..d8d48de
--- /dev/null
+++ b/halimpl/pn54x/inc/phNxpNciHal_Api.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_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..88f9cda
--- /dev/null
+++ b/halimpl/pn54x/inc/phNxpNciHal_SelfTest.h
@@ -0,0 +1,185 @@
+/*
+ * 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.
+ **
+ *******************************************************************************/
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+NFCSTATUS phNxpNciHal_PrbsTestStart (phNxpNfc_PrbsType_t prbs_type, phNxpNfc_PrbsHwType_t hw_prbs_type,
+ phNxpNfc_Tech_t tech, phNxpNfc_Bitrate_t bitrate);
+#else
+NFCSTATUS phNxpNciHal_PrbsTestStart (phNxpNfc_Tech_t tech, phNxpNfc_Bitrate_t bitrate);
+#endif
+/*******************************************************************************
+ **
+ ** Function phNxpNciHal_PrbsTestStop
+ **
+ ** Description Test function stop RF generation for RF technology started
+ ** by phNxpNciHal_PrbsTestStart.
+ **
+ ** Returns NFCSTATUS_SUCCESS if operation successful,
+ ** otherwise NFCSTATUS_FAILED.
+ **
+ *******************************************************************************/
+
+NFCSTATUS phNxpNciHal_PrbsTestStop ();
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_AntennaSelfTest
+**
+** Description Test function to validate the Antenna's discrete
+** components connection.
+**
+** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED.
+**
+*******************************************************************************/
+
+NFCSTATUS phNxpNciHal_AntennaSelfTest(phAntenna_St_Resp_t * phAntenna_St_Resp );
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_RfFieldTest
+**
+** Description Test function performs RF filed test.
+**
+** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED.
+**
+*******************************************************************************/
+
+NFCSTATUS phNxpNciHal_RfFieldTest (uint8_t on);
+
+/*******************************************************************************
+ **
+ ** Function phNxpNciHal_DownloadPinTest
+ **
+ ** Description Test function to validate the FW download pin connection.
+ **
+ ** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED.
+ **
+ *******************************************************************************/
+
+NFCSTATUS phNxpNciHal_DownloadPinTest (void);
+
+#endif /* _NXP_HW_SELF_TEST_H_ */
+#endif /* _PHNXPNCIHAL_SELFTEST_H_ */
diff --git a/halimpl/pn54x/libnfc-brcm.conf b/halimpl/pn54x/libnfc-brcm.conf
new file mode 100644
index 0000000..c98668a
--- /dev/null
+++ b/halimpl/pn54x/libnfc-brcm.conf
@@ -0,0 +1,385 @@
+###################### 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
+###############################################################################
+# When disconnecting from Oberthur secure element, perform a warm-reset of
+# the secure element to deselect the applet.
+# The default hex value of the command is 0x3. If this variable is undefined,
+# then this feature is not used.
+#OBERTHUR_WARM_RESET_COMMAND=0x03
+
+###############################################################################
+# Force UICC to only listen to the following technology(s).
+# The bits are defined as tNFA_TECHNOLOGY_MASK in nfa_api.h.
+# Default is NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B | NFA_TECHNOLOGY_MASK_F
+UICC_LISTEN_TECH_MASK=0x07
+
+###############################################################################
+# Force HOST listen feature enable or disable.
+# 0: Disable
+# 1: Enable
+HOST_LISTEN_ENABLE=0x01
+
+###############################################################################
+# Enabling/Disabling Forward functionality
+# Disable 0x00
+# Enable 0x01
+NXP_FWD_FUNCTIONALITY_ENABLE=0x01
+
+###############################################################################
+# Allow UICC to be powered off if there is no traffic.
+# Timeout is in ms. If set to 0, then UICC will not be powered off.
+#UICC_IDLE_TIMEOUT=30000
+UICC_IDLE_TIMEOUT=0
+
+###############################################################################
+# AID for Empty Select command
+# If specified, this AID will be substituted when an Empty SELECT command is
+# detected. The first byte is the length of the AID. Maximum length is 16.
+AID_FOR_EMPTY_SELECT={08:A0:00:00:01:51:00:00:00}
+###############################################################################
+# Maximum Number of Credits to be allowed by the NFCC
+# This value overrides what the NFCC specifices allowing the host to have
+# the control to work-around transport limitations. If this value does
+# not exist or is set to 0, the NFCC will provide the number of credits.
+MAX_RF_DATA_CREDITS=1
+
+###############################################################################
+# This setting allows you to disable registering the T4t Virtual SE that causes
+# the NFCC to send PPSE requests to the DH.
+# The default setting is enabled (i.e. T4t Virtual SE is registered).
+#REGISTER_VIRTUAL_SE=1
+
+###############################################################################
+# When screen is turned off, specify the desired power state of the controller.
+# 0: power-off-sleep state; DEFAULT
+# 1: full-power state
+# 2: screen-off card-emulation (CE4/CE3/CE1 modes are used)
+SCREEN_OFF_POWER_STATE=1
+
+###############################################################################
+# Firmware patch file
+# If the value is not set then patch download is disabled.
+#FW_PATCH="/vendor/firmware/bcm2079x_firmware.ncd"
+
+###############################################################################
+# Firmware pre-patch file (sent before the above patch file)
+# If the value is not set then pre-patch is not used.
+#FW_PRE_PATCH="/vendor/firmware/bcm2079x_pre_firmware.ncd"
+
+###############################################################################
+# Firmware patch format
+# 1 = HCD
+# 2 = NCD (default)
+#NFA_CONFIG_FORMAT=2
+
+###############################################################################
+# SPD Debug mode
+# If set to 1, any failure of downloading a patch will trigger a hard-stop
+#SPD_DEBUG=0
+
+###############################################################################
+# SPD Max Retry Count
+# The number of attempts to download a patch before giving up (defualt is 3).
+# Note, this resets after a power-cycle.
+#SPD_MAX_RETRY_COUNT=3
+
+###############################################################################
+# transport driver
+#
+# TRANSPORT_DRIVER=<driver>
+#
+# where <driver> can be, for example:
+# "/dev/ttyS" (UART)
+# "/dev/bcmi2cnfc" (I2C)
+# "hwtun" (HW Tunnel)
+# "/dev/bcmspinfc" (SPI)
+# "/dev/btusb0" (BT USB)
+#TRANSPORT_DRIVER="/dev/bcm2079x-i2c"
+
+###############################################################################
+# power control driver
+# Specify a kernel driver that support ioctl commands to control NFC_EN and
+# NFC_WAKE gpio signals.
+#
+# POWER_CONTRL_DRIVER=<driver>
+# where <driver> can be, for example:
+# "/dev/nfcpower"
+# "/dev/bcmi2cnfc" (I2C)
+# "/dev/bcmspinfc" (SPI)
+# i2c and spi driver may be used to control NFC_EN and NFC_WAKE signal
+#POWER_CONTROL_DRIVER="/dev/bcm2079x-i2c"
+
+###############################################################################
+# I2C transport driver options
+# Mako does not support 10-bit I2C addresses
+# Revert to 7-bit address
+#BCMI2CNFC_ADDRESS=0x77
+
+###############################################################################
+# I2C transport driver try to read multiple packets in read() if data is available
+# remove the comment below to enable this feature
+#READ_MULTIPLE_PACKETS=1
+
+###############################################################################
+# SPI transport driver options
+#SPI_NEGOTIATION={0A:F0:00:01:00:00:00:FF:FF:00:00}
+
+###############################################################################
+# UART transport driver options
+#
+# PORT=1,2,3,...
+# BAUD=115200, 19200, 9600, 4800,
+# DATABITS=8, 7, 6, 5
+# PARITY="even" | "odd" | "none"
+# STOPBITS="0" | "1" | "1.5" | "2"
+
+#UART_PORT=2
+#UART_BAUD=115200
+#UART_DATABITS=8
+#UART_PARITY="none"
+#UART_STOPBITS="1"
+
+###############################################################################
+# Insert a delay in microseconds per byte after a write to NFCC.
+# after writing a block of data to the NFCC, delay this an amopunt of time before
+# writing next block of data. the delay is calculated as below
+# NFC_WRITE_DELAY * (number of byte written) / 1000 milliseconds
+# e.g. after 259 bytes is written, delay (259 * 20 / 1000) 5 ms before next write
+#NFC_WRITE_DELAY=20
+
+###############################################################################
+# Maximum Number of Credits to be allowed by the NFCC
+# This value overrides what the NFCC specifices allowing the host to have
+# the control to work-around transport limitations. If this value does
+# not exist or is set to 0, the NFCC will provide the number of credits.
+MAX_RF_DATA_CREDITS=1
+
+###############################################################################
+# Default poll duration (in ms)
+# The defualt is 500ms if not set (see nfc_target.h)
+#NFA_DM_DISC_DURATION_POLL=333
+###############################################################################
+# Antenna Configuration - This data is used when setting 0xC8 config item
+# at startup (before discovery is started). If not used, no value is sent.
+#
+# The settings for this value are documented here:
+# http://wcgbu.broadcom.com/wpan/PM/Project%20Document%20Library/bcm20791B0/
+# Design/Doc/PHY%20register%20settings/BCM20791-B2-1027-02_PHY_Recommended_Reg_Settings.xlsx
+# This document is maintained by Paul Forshaw.
+#
+# The values marked as ?? should be tweaked per antenna or customer/app:
+# {20:C8:1E:06:??:00:??:??:??:00:??:24:00:1C:00:75:00:77:00:76:00:1C:00:03:00:0A:00:??:01:00:00:40:04}
+# array[0] = 0x20 is length of the payload from array[1] to the end
+# array[1] = 0xC8 is PREINIT_DSP_CFG
+#PREINIT_DSP_CFG={20:C8:1E:06:1F:00:0F:03:3C:00:04:24:00:1C:00:75:00:77:00:76:00:1C:00:03:00:0A:00:48:01:00:00:40:04}
+
+
+###############################################################################
+# Choose the presence-check algorithm for type-4 tag. If not defined, the default value is 1.
+# 0 NFA_RW_PRES_CHK_DEFAULT; Let stack selects an algorithm
+# 1 NFA_RW_PRES_CHK_I_BLOCK; ISO-DEP protocol's empty I-block
+# 2 NFA_RW_PRES_CHK_RESET; Deactivate to Sleep, then re-activate
+# 3 NFA_RW_PRES_CHK_RB_CH0; Type-4 tag protocol's ReadBinary command on channel 0
+# 4 NFA_RW_PRES_CHK_RB_CH3; Type-4 tag protocol's ReadBinary command on channel 3
+#PRESENCE_CHECK_ALGORITHM=0
+
+###############################################################################
+# Force tag polling for the following technology(s).
+# The bits are defined as tNFA_TECHNOLOGY_MASK in nfa_api.h.
+# Default is NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B |
+# NFA_TECHNOLOGY_MASK_F | NFA_TECHNOLOGY_MASK_ISO15693 |
+# NFA_TECHNOLOGY_MASK_B_PRIME | NFA_TECHNOLOGY_MASK_KOVIO |
+# NFA_TECHNOLOGY_MASK_A_ACTIVE | NFA_TECHNOLOGY_MASK_F_ACTIVE.
+#
+# Notable bits:
+# NFA_TECHNOLOGY_MASK_A 0x01 /* NFC Technology A */
+# NFA_TECHNOLOGY_MASK_B 0x02 /* NFC Technology B */
+# NFA_TECHNOLOGY_MASK_F 0x04 /* NFC Technology F */
+# NFA_TECHNOLOGY_MASK_ISO15693 0x08 /* Proprietary Technology */
+# NFA_TECHNOLOGY_MASK_KOVIO 0x20 /* Proprietary Technology */
+# NFA_TECHNOLOGY_MASK_A_ACTIVE 0x40 /* NFC Technology A active mode */
+# NFA_TECHNOLOGY_MASK_F_ACTIVE 0x80 /* NFC Technology F active mode */
+POLLING_TECH_MASK=0xEF
+
+###############################################################################
+# Force P2P to only listen for the following technology(s).
+# The bits are defined as tNFA_TECHNOLOGY_MASK in nfa_api.h.
+# Default is NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_F |
+# NFA_TECHNOLOGY_MASK_A_ACTIVE | NFA_TECHNOLOGY_MASK_F_ACTIVE
+#
+# Notable bits:
+# NFA_TECHNOLOGY_MASK_A 0x01 /* NFC Technology A */
+# NFA_TECHNOLOGY_MASK_F 0x04 /* NFC Technology F */
+# NFA_TECHNOLOGY_MASK_A_ACTIVE 0x40 /* NFC Technology A active mode */
+# NFA_TECHNOLOGY_MASK_F_ACTIVE 0x80 /* NFC Technology F active mode */
+P2P_LISTEN_TECH_MASK=0xC5
+
+PRESERVE_STORAGE=0x01
+
+###############################################################################
+# Override the stack default for NFA_EE_MAX_EE_SUPPORTED set in nfc_target.h.
+# The value is set to 3 by default as it assumes we will discover 0xF2,
+# 0xF3, and 0xF4. If a platform will exclude and SE, this value can be reduced
+# so that the stack will not wait any longer than necessary.
+
+# Maximum EE supported number
+# NXP PN547C2 0x02
+# NXP PN65T 0x03
+# NXP PN548C2 0x02
+# NXP PN66T 0x03
+NFA_MAX_EE_SUPPORTED=0x03
+
+###############################################################################
+# NCI Hal Module name
+NCI_HAL_MODULE="nfc_nci.pn54x"
+
+##############################################################################
+# Deactivate notification wait time out in seconds used in ETSI Reader mode
+# 0 - Infinite wait
+NFA_DM_DISC_NTF_TIMEOUT=100
+
+###############################################################################
+# AID_MATCHING constants
+# AID_MATCHING_EXACT_ONLY 0x00
+# AID_MATCHING_EXACT_OR_PREFIX 0x01
+# AID_MATCHING_PREFIX_ONLY 0x02
+AID_MATCHING_MODE=0x01
+
+###############################################################################
+# Preferred Secure Element for Technology based routing
+# eSE 0x01
+# UICC 0x02
+
+NXP_PRFD_TECH_SE=0x01
diff --git a/halimpl/pn54x/libnfc-nxp-PN547C2_example.conf b/halimpl/pn54x/libnfc-nxp-PN547C2_example.conf
new file mode 100644
index 0000000..b3a1694
--- /dev/null
+++ b/halimpl/pn54x/libnfc-nxp-PN547C2_example.conf
@@ -0,0 +1,251 @@
+## 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
+
+###############################################################################
+# 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_38_4MHZ 5
+#define CLK_FREQ_52MHZ 6
+
+NXP_SYS_CLK_FREQ_SEL=0x00
+
+###############################################################################
+# The timeout value to be used for clock request acknowledgment
+# min value = 0x01 to max = 0x19
+
+NXP_SYS_CLOCK_TO_CFG=0x01
+
+###############################################################################
+# NXP proprietary settings
+NXP_ACT_PROP_EXTN={2F, 02, 00}
+
+###############################################################################
+# NFC forum profile settings
+NXP_NFC_PROFILE_EXTN={20, 02, 05, 01, A0, 44, 01, 00}
+
+###############################################################################
+# Standby enable settings
+NXP_CORE_STANDBY={2F, 00, 01, 01}
+
+###############################################################################
+#Atonomous Mode
+#Enable 0x01
+#Disable 0x00
+NXP_CORE_SCRN_OFF_AUTONOMOUS_ENABLE=0x00
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+# NXP_RF_CONF_BLK_1={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_2={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_3={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_4={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_5={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_6={
+#}
+
+###############################################################################
+# Core configuration extensions
+# It includes
+# Wired mode settings A0ED, A0EE
+# Tag Detector A040, A041, A043
+# Low Power mode A007
+# Clock settings A002, A003
+# PbF settings A008
+NXP_CORE_CONF_EXTN={20, 02, 16, 04,
+ A0, EC, 01, 01,
+ A0, ED, 01, 01,
+ A0, 5E, 01, 01,
+ A0, 0D, 06, 3E, 2D, 15, 88, 15, 00
+ }
+# 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=0x06
+###############################################################################
+#Enable SWP full power mode when phone is power off
+NXP_SWP_FULL_PWR_ON=0x01
+
+###############################################################################
+#Set the default AID route Location :
+#This settings will be used when application does not set this parameter
+# host 0x00
+# eSE 0x01
+# UICC 0x02
+DEFAULT_AID_ROUTE=0x00
+
+###############################################################################
+#Set the Mifare Desfire route Location :
+#This settings will be used when application does not set this parameter
+# host 0x00
+# eSE 0x01
+# UICC 0x02
+DEFAULT_DESFIRE_ROUTE=0x02
+
+###############################################################################
+#Set the Mifare CLT route Location :
+#This settings will be used when application does not set this parameter
+# host 0x00
+# eSE 0x01
+# UICC 0x02
+DEFAULT_MIFARE_CLT_ROUTE=0x02
+
+##############################################################################
+#### Select the CHIP ####
+#PN547C2 0x01
+#PN65T 0x02
+#PN548AD 0x03
+#PN66T 0x04
+
+NXP_NFC_CHIP=0x01
+
+#Timeout in secs
+NXP_SWP_RD_START_TIMEOUT=0x0A
+#Timeout in secs
+NXP_SWP_RD_TAG_OP_TIMEOUT=0x01
+###############################################################################
+# CE when Screen state is locked
+# Disable 0x00
+# Enable 0x01
+NXP_CE_ROUTE_STRICT_DISABLE=0x01
+
+
+###############################################################################
+
+# AID Matching platform options
+# AID_MATCHING_L 0x01
+# AID_MATCHING_K 0x02
+AID_MATCHING_PLATFORM=0x01
+################################################################################
+#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
+##################################################################################
\ No newline at end of file
diff --git a/halimpl/pn54x/libnfc-nxp-PN548C2_example.conf b/halimpl/pn54x/libnfc-nxp-PN548C2_example.conf
new file mode 100644
index 0000000..7097766
--- /dev/null
+++ b/halimpl/pn54x/libnfc-nxp-PN548C2_example.conf
@@ -0,0 +1,277 @@
+## 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
+
+###############################################################################
+# 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_38_4MHZ 5
+#define CLK_FREQ_52MHZ 6
+
+NXP_SYS_CLK_FREQ_SEL=0x02
+
+###############################################################################
+# The timeout value to be used for clock request acknowledgment
+# min value = 0x01 to max = 0x1A
+
+NXP_SYS_CLOCK_TO_CFG=0x1A
+
+###############################################################################
+# NXP proprietary settings
+NXP_ACT_PROP_EXTN={2F, 02, 00}
+
+###############################################################################
+# NFC forum profile settings
+NXP_NFC_PROFILE_EXTN={20, 02, 05, 01, A0, 44, 01, 00}
+
+###############################################################################
+# NFCC Configuration Control
+# Allow NFCC to manage RF Config 0x01
+# Don't allow NFCC to manage RF Config 0x00
+NXP_NFC_MERGE_RF_PARAMS={20, 02, 04, 01, 85, 01, 01}
+
+###############################################################################
+# Standby enable settings
+NXP_CORE_STANDBY={2F, 00, 01, 01}
+
+###############################################################################
+# NXP TVDD configurations settings
+# Allow NFCC to configure External TVDD, There are currently three
+#configurations (1, 2 and 3) are supported, out of them only one can be
+#supported.
+
+NXP_EXT_TVDD_CFG=0x01
+
+#config1:SLALM, 3.3V for both RM and CM
+NXP_EXT_TVDD_CFG_1={20, 02, 0B, 02, A0, 66, 01, 00, A0, 0E, 03, 02, 09, 00}
+
+#config2: use DCDC in CE, use Tx_Pwr_Req, set CFG2 mode, SLALM,
+#monitoring 5V from DCDC, 4.7V for both RM and CM, DCDCWaitTime=4.2ms
+NXP_EXT_TVDD_CFG_2={20, 02, 0B, 02, A0, 66, 01, 00, A0, 0E, 03, 56, 64, 0A}
+
+#config3: use DCDC in CE, use Tx_Pwr_Req, SLALM, monitoring 5V from DCDC,
+#DCDCWaitTime=4.2ms
+NXP_EXT_TVDD_CFG_3={20, 02, 0B, 02, A0, 66, 01, 01, A0, 0E, 03, 52, 64, 0A}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_1={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_2={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_3={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_4={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_5={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_6={
+#}
+
+
+###############################################################################
+# Core configuration extensions
+# It includes
+# Wired mode settings A0ED, A0EE
+# Tag Detector A040, A041, A043
+# Low Power mode A007
+# Clock settings A002, A003
+# PbF settings A008
+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, 2B, 0D,
+ 28, 01, 00,
+ 21, 01, 00,
+ 30, 01, 08,
+ 31, 01, 03,
+ 33, 04, 01, 02, 03, 04,
+ 54, 01, 06,
+ 50, 01, 02,
+ 5B, 01, 00,
+ 60, 01, 0E,
+ 80, 01, 01,
+ 81, 01, 01,
+ 82, 01, 0E,
+ 18, 01, 01
+ }
+
+###############################################################################
+# Mifare Classic Key settings
+#NXP_CORE_MFCKEY_SETTING={20, 02, 25,04, A0, 51, 06, A0, A1, A2, A3, A4, A5,
+# A0, 52, 06, D3, F7, D3, F7, D3, F7,
+# A0, 53, 06, FF, FF, FF, FF, FF, FF,
+# A0, 54, 06, 00, 00, 00, 00, 00, 00}
+
+###############################################################################
+# Default SE Options
+# No secure element 0x00
+# eSE 0x01
+# UICC 0x02
+
+NXP_DEFAULT_SE=0x03
+
+###############################################################################
+#Enable SWP full power mode when phone is power off
+NXP_SWP_FULL_PWR_ON=0x00
+
+###############################################################################
+#### Select the CHIP ####
+#PN547C2 0x01
+#PN65T 0x02
+#PN548AD 0x03
+#PN66T 0x04
+
+NXP_NFC_CHIP=0x03
+
+###############################################################################
+# CE when Screen state is locked
+# Disable 0x00
+# Enable 0x01
+NXP_CE_ROUTE_STRICT_DISABLE=0x01
+
+#Timeout in secs to get NFCEE Discover notification
+NXP_DEFAULT_NFCEE_DISC_TIMEOUT=20
+
+NXP_DEFAULT_NFCEE_TIMEOUT=0x06
+
+#Timeout in secs
+NXP_SWP_RD_START_TIMEOUT=0x0A
+
+#Timeout in secs
+NXP_SWP_RD_TAG_OP_TIMEOUT=0x01
+
+###############################################################################
+#Set the default AID route Location :
+#This settings will be used when application does not set this parameter
+# host 0x00
+# eSE 0x01
+# UICC 0x02
+DEFAULT_AID_ROUTE=0x00
+
+###############################################################################
+#Set the Mifare Desfire route Location :
+#This settings will be used when application does not set this parameter
+# host 0x00
+# eSE 0x01
+# UICC 0x02
+DEFAULT_DESFIRE_ROUTE=0x02
+
+###############################################################################
+#Set the Mifare CLT route Location :
+#This settings will be used when application does not set this parameter
+# host 0x00
+# eSE 0x01
+# UICC 0x02
+DEFAULT_MIFARE_CLT_ROUTE=0x02
+###############################################################################
+# AID Matching platform options
+# AID_MATCHING_L 0x01
+# AID_MATCHING_K 0x02
+AID_MATCHING_PLATFORM=0x01
+###############################################################################
+#CHINA_TIANJIN_RF_SETTING
+#Enable 0x01
+#Disable 0x00
+NXP_CHINA_TIANJIN_RF_ENABLED=0x01
+###############################################################################
+#SWP_SWITCH_TIMEOUT_SETTING
+# Allowed range of swp timeout setting is 0x00 to 0x3C [0 - 60].
+# Timeout in milliseconds, for example
+# No Timeout 0x00
+# 10 millisecond timeout 0x0A
+NXP_SWP_SWITCH_TIMEOUT=0x0A
+###############################################################################
+#Dynamic RSSI feature enable
+# Disable 0x00
+# Enable 0x01
+NXP_AGC_DEBUG_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
+################################################################################
\ No newline at end of file
diff --git a/halimpl/pn54x/log/phNxpLog.c b/halimpl/pn54x/log/phNxpLog.c
new file mode 100644
index 0000000..726ef26
--- /dev/null
+++ b/halimpl/pn54x/log/phNxpLog.c
@@ -0,0 +1,256 @@
+/*
+ * 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", \
+ __FUNCTION__, gLog_level.global_log_level, gLog_level.dnld_log_level,
+ gLog_level.extns_log_level, gLog_level.hal_log_level, gLog_level.tml_log_level,
+ gLog_level.ncir_log_level, gLog_level.ncix_log_level);
+}
diff --git a/halimpl/pn54x/log/phNxpLog.h b/halimpl/pn54x/log/phNxpLog.h
new file mode 100644
index 0000000..4255a88
--- /dev/null
+++ b/halimpl/pn54x/log/phNxpLog.h
@@ -0,0 +1,248 @@
+/*
+ * 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>
+
+typedef struct nci_log_level
+{
+ uint8_t global_log_level;
+ uint8_t extns_log_level;
+ uint8_t hal_log_level;
+ uint8_t dnld_log_level;
+ uint8_t tml_log_level;
+ uint8_t ncix_log_level;
+ uint8_t ncir_log_level;
+} nci_log_level_t;
+
+/* global log level Ref */
+extern nci_log_level_t gLog_level;
+
+/* define log module included when compile */
+#define ENABLE_EXTNS_TRACES TRUE
+#define ENABLE_HAL_TRACES TRUE
+#define ENABLE_TML_TRACES TRUE
+#define ENABLE_FWDNLD_TRACES TRUE
+#define ENABLE_NCIX_TRACES TRUE
+#define ENABLE_NCIR_TRACES TRUE
+
+#define ENABLE_HCPX_TRACES FALSE
+#define ENABLE_HCPR_TRACES FALSE
+
+/* ####################### Set the log module name in .conf file ########################## */
+#define NAME_NXPLOG_EXTNS_LOGLEVEL "NXPLOG_EXTNS_LOGLEVEL"
+#define NAME_NXPLOG_HAL_LOGLEVEL "NXPLOG_NCIHAL_LOGLEVEL"
+#define NAME_NXPLOG_NCIX_LOGLEVEL "NXPLOG_NCIX_LOGLEVEL"
+#define NAME_NXPLOG_NCIR_LOGLEVEL "NXPLOG_NCIR_LOGLEVEL"
+#define NAME_NXPLOG_FWDNLD_LOGLEVEL "NXPLOG_FWDNLD_LOGLEVEL"
+#define NAME_NXPLOG_TML_LOGLEVEL "NXPLOG_TML_LOGLEVEL"
+
+/* ####################### Set the log module name by Android property ########################## */
+#define PROP_NAME_NXPLOG_GLOBAL_LOGLEVEL "nfc.nxp_log_level_global"
+#define PROP_NAME_NXPLOG_EXTNS_LOGLEVEL "nfc.nxp_log_level_extns"
+#define PROP_NAME_NXPLOG_HAL_LOGLEVEL "nfc.nxp_log_level_hal"
+#define PROP_NAME_NXPLOG_NCI_LOGLEVEL "nfc.nxp_log_level_nci"
+#define PROP_NAME_NXPLOG_FWDNLD_LOGLEVEL "nfc.nxp_log_level_dnld"
+#define PROP_NAME_NXPLOG_TML_LOGLEVEL "nfc.nxp_log_level_tml"
+
+/* ####################### Set the logging level for EVERY COMPONENT here ######################## :START: */
+#define NXPLOG_LOG_SILENT_LOGLEVEL 0x00
+#define NXPLOG_LOG_ERROR_LOGLEVEL 0x01
+#define NXPLOG_LOG_WARN_LOGLEVEL 0x02
+#define NXPLOG_LOG_DEBUG_LOGLEVEL 0x03
+/* ####################### Set the default logging level for EVERY COMPONENT here ########################## :END: */
+
+
+/* The Default log level for all the modules. */
+#define NXPLOG_DEFAULT_LOGLEVEL NXPLOG_LOG_ERROR_LOGLEVEL
+
+
+/* ################################################################################################################ */
+/* ############################################### Component Names ################################################ */
+/* ################################################################################################################ */
+
+extern const char * NXPLOG_ITEM_EXTNS; /* Android logging tag for NxpExtns */
+extern const char * NXPLOG_ITEM_NCIHAL; /* Android logging tag for NxpNciHal */
+extern const char * NXPLOG_ITEM_NCIX; /* Android logging tag for NxpNciX */
+extern const char * NXPLOG_ITEM_NCIR; /* Android logging tag for NxpNciR */
+extern const char * NXPLOG_ITEM_FWDNLD; /* Android logging tag for NxpFwDnld */
+extern const char * NXPLOG_ITEM_TML; /* Android logging tag for NxpTml */
+
+#ifdef NXP_HCI_REQ
+extern const char * NXPLOG_ITEM_HCPX; /* Android logging tag for NxpHcpX */
+extern const char * NXPLOG_ITEM_HCPR; /* Android logging tag for NxpHcpR */
+#endif /*NXP_HCI_REQ*/
+
+/* ######################################## Defines used for Logging data ######################################### */
+#ifdef NXP_VRBS_REQ
+#define NXPLOG_FUNC_ENTRY(COMP) \
+ LOG_PRI(ANDROID_LOG_VERBOSE,(COMP),"+:%s",(__FUNCTION__))
+#define NXPLOG_FUNC_EXIT(COMP) \
+ LOG_PRI(ANDROID_LOG_VERBOSE,(COMP),"-:%s",(__FUNCTION__))
+#endif /*NXP_VRBS_REQ*/
+
+/* ################################################################################################################ */
+/* ######################################## Logging APIs of actual modules ######################################## */
+/* ################################################################################################################ */
+/* Logging APIs used by NxpExtns module */
+#if (ENABLE_EXTNS_TRACES == TRUE )
+# define NXPLOG_EXTNS_D(...) {if(gLog_level.extns_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) LOG_PRI(ANDROID_LOG_DEBUG,NXPLOG_ITEM_EXTNS,__VA_ARGS__);}
+# define NXPLOG_EXTNS_W(...) {if(gLog_level.extns_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) LOG_PRI(ANDROID_LOG_WARN,NXPLOG_ITEM_EXTNS,__VA_ARGS__);}
+# define NXPLOG_EXTNS_E(...) {if(gLog_level.extns_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) LOG_PRI(ANDROID_LOG_ERROR,NXPLOG_ITEM_EXTNS,__VA_ARGS__);}
+#else
+# define NXPLOG_EXTNS_D(...)
+# define NXPLOG_EXTNS_W(...)
+# define NXPLOG_EXTNS_E(...)
+#endif /* Logging APIs used by NxpExtns module */
+
+/* Logging APIs used by NxpNciHal module */
+#if (ENABLE_HAL_TRACES == TRUE )
+# define NXPLOG_NCIHAL_D(...) {if(gLog_level.hal_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) LOG_PRI(ANDROID_LOG_DEBUG,NXPLOG_ITEM_NCIHAL,__VA_ARGS__);}
+# define NXPLOG_NCIHAL_W(...) {if(gLog_level.hal_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) LOG_PRI(ANDROID_LOG_WARN,NXPLOG_ITEM_NCIHAL,__VA_ARGS__);}
+# define NXPLOG_NCIHAL_E(...) {if(gLog_level.hal_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) LOG_PRI(ANDROID_LOG_ERROR,NXPLOG_ITEM_NCIHAL,__VA_ARGS__);}
+#else
+# define NXPLOG_NCIHAL_D(...)
+# define NXPLOG_NCIHAL_W(...)
+# define NXPLOG_NCIHAL_E(...)
+#endif /* Logging APIs used by HAL module */
+
+/* Logging APIs used by NxpNciX module */
+#if (ENABLE_NCIX_TRACES == TRUE )
+# define NXPLOG_NCIX_D(...) {if(gLog_level.ncix_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) LOG_PRI(ANDROID_LOG_DEBUG,NXPLOG_ITEM_NCIX,__VA_ARGS__);}
+# define NXPLOG_NCIX_W(...) {if(gLog_level.ncix_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) LOG_PRI(ANDROID_LOG_WARN,NXPLOG_ITEM_NCIX,__VA_ARGS__);}
+# define NXPLOG_NCIX_E(...) {if(gLog_level.ncix_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) LOG_PRI(ANDROID_LOG_ERROR,NXPLOG_ITEM_NCIX,__VA_ARGS__);}
+#else
+# define NXPLOG_NCIX_D(...)
+# define NXPLOG_NCIX_W(...)
+# define NXPLOG_NCIX_E(...)
+#endif /* Logging APIs used by NCIx module */
+
+/* Logging APIs used by NxpNciR module */
+#if (ENABLE_NCIR_TRACES == TRUE )
+# define NXPLOG_NCIR_D(...) {if(gLog_level.ncir_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) LOG_PRI(ANDROID_LOG_DEBUG,NXPLOG_ITEM_NCIR,__VA_ARGS__);}
+# define NXPLOG_NCIR_W(...) {if(gLog_level.ncir_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) LOG_PRI(ANDROID_LOG_WARN,NXPLOG_ITEM_NCIR,__VA_ARGS__);}
+# define NXPLOG_NCIR_E(...) {if(gLog_level.ncir_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) LOG_PRI(ANDROID_LOG_ERROR,NXPLOG_ITEM_NCIR,__VA_ARGS__);}
+#else
+# define NXPLOG_NCIR_D(...)
+# define NXPLOG_NCIR_W(...)
+# define NXPLOG_NCIR_E(...)
+#endif /* Logging APIs used by NCIR module */
+
+/* Logging APIs used by NxpFwDnld module */
+#if (ENABLE_FWDNLD_TRACES == TRUE )
+# define NXPLOG_FWDNLD_D(...) {if(gLog_level.dnld_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) LOG_PRI(ANDROID_LOG_DEBUG,NXPLOG_ITEM_FWDNLD,__VA_ARGS__);}
+# define NXPLOG_FWDNLD_W(...) {if(gLog_level.dnld_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) LOG_PRI(ANDROID_LOG_WARN,NXPLOG_ITEM_FWDNLD,__VA_ARGS__);}
+# define NXPLOG_FWDNLD_E(...) {if(gLog_level.dnld_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) LOG_PRI(ANDROID_LOG_ERROR,NXPLOG_ITEM_FWDNLD,__VA_ARGS__);}
+#else
+# define NXPLOG_FWDNLD_D(...)
+# define NXPLOG_FWDNLD_W(...)
+# define NXPLOG_FWDNLD_E(...)
+#endif /* Logging APIs used by NxpFwDnld module */
+
+/* Logging APIs used by NxpTml module */
+#if (ENABLE_TML_TRACES == TRUE )
+# define NXPLOG_TML_D(...) {if(gLog_level.tml_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) LOG_PRI(ANDROID_LOG_DEBUG,NXPLOG_ITEM_TML,__VA_ARGS__);}
+# define NXPLOG_TML_W(...) {if(gLog_level.tml_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) LOG_PRI(ANDROID_LOG_WARN,NXPLOG_ITEM_TML,__VA_ARGS__);}
+# define NXPLOG_TML_E(...) {if(gLog_level.tml_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) LOG_PRI(ANDROID_LOG_ERROR,NXPLOG_ITEM_TML,__VA_ARGS__);}
+#else
+# define NXPLOG_TML_D(...)
+# define NXPLOG_TML_W(...)
+# define NXPLOG_TML_E(...)
+#endif /* Logging APIs used by NxpTml module */
+
+#ifdef NXP_HCI_REQ
+/* Logging APIs used by NxpHcpX module */
+#if (ENABLE_HCPX_TRACES == TRUE )
+# define NXPLOG_HCPX_D(...) {if(gLog_level.dnld_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) LOG_PRI(ANDROID_LOG_DEBUG,NXPLOG_ITEM_FWDNLD,__VA_ARGS__);}
+# define NXPLOG_HCPX_W(...) {if(gLog_level.dnld_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) LOG_PRI(ANDROID_LOG_WARN,NXPLOG_ITEM_FWDNLD,__VA_ARGS__);}
+# define NXPLOG_HCPX_E(...) {if(gLog_level.dnld_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) LOG_PRI(ANDROID_LOG_ERROR,NXPLOG_ITEM_FWDNLD,__VA_ARGS__);}
+#else
+# define NXPLOG_HCPX_D(...)
+# define NXPLOG_HCPX_W(...)
+# define NXPLOG_HCPX_E(...)
+#endif /* Logging APIs used by NxpHcpX module */
+
+/* Logging APIs used by NxpHcpR module */
+#if (ENABLE_HCPR_TRACES == TRUE )
+# define NXPLOG_HCPR_D(...) {if(gLog_level.dnld_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) LOG_PRI(ANDROID_LOG_DEBUG,NXPLOG_ITEM_FWDNLD,__VA_ARGS__);}
+# define NXPLOG_HCPR_W(...) {if(gLog_level.dnld_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) LOG_PRI(ANDROID_LOG_WARN,NXPLOG_ITEM_FWDNLD,__VA_ARGS__);}
+# define NXPLOG_HCPR_E(...) {if(gLog_level.dnld_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) LOG_PRI(ANDROID_LOG_ERROR,NXPLOG_ITEM_FWDNLD,__VA_ARGS__);}
+#else
+# define NXPLOG_HCPR_D(...)
+# define NXPLOG_HCPR_W(...)
+# define NXPLOG_HCPR_E(...)
+#endif /* Logging APIs used by NxpHcpR module */
+#endif /* NXP_HCI_REQ */
+
+#ifdef NXP_VRBS_REQ
+#if (ENABLE_EXTNS_TRACES == TRUE )
+# define NXPLOG_EXTNS_ENTRY() NXPLOG_FUNC_ENTRY(NXPLOG_ITEM_EXTNS)
+# define NXPLOG_EXTNS_EXIT() NXPLOG_FUNC_EXIT(NXPLOG_ITEM_EXTNS)
+#else
+# define NXPLOG_EXTNS_ENTRY()
+# define NXPLOG_EXTNS_EXIT()
+#endif
+
+#if (ENABLE_HAL_TRACES == TRUE )
+# define NXPLOG_NCIHAL_ENTRY() NXPLOG_FUNC_ENTRY(NXPLOG_ITEM_NCIHAL)
+# define NXPLOG_NCIHAL_EXIT() NXPLOG_FUNC_EXIT(NXPLOG_ITEM_NCIHAL)
+#else
+# define NXPLOG_NCIHAL_ENTRY()
+# define NXPLOG_NCIHAL_EXIT()
+#endif
+
+#if (ENABLE_NCIX_TRACES == TRUE )
+# define NXPLOG_NCIX_ENTRY() NXPLOG_FUNC_ENTRY(NXPLOG_ITEM_NCIX)
+# define NXPLOG_NCIX_EXIT() NXPLOG_FUNC_EXIT(NXPLOG_ITEM_NCIX)
+#else
+# define NXPLOG_NCIX_ENTRY()
+# define NXPLOG_NCIX_EXIT()
+#endif
+
+#if (ENABLE_NCIR_TRACES == TRUE )
+# define NXPLOG_NCIR_ENTRY() NXPLOG_FUNC_ENTRY(NXPLOG_ITEM_NCIR)
+# define NXPLOG_NCIR_EXIT() NXPLOG_FUNC_EXIT(NXPLOG_ITEM_NCIR)
+#else
+# define NXPLOG_NCIR_ENTRY()
+# define NXPLOG_NCIR_EXIT()
+#endif
+
+#ifdef NXP_HCI_REQ
+
+#if (ENABLE_HCPX_TRACES == TRUE )
+# define NXPLOG_HCPX_ENTRY() NXPLOG_FUNC_ENTRY(NXPLOG_ITEM_HCPX)
+# define NXPLOG_HCPX_EXIT() NXPLOG_FUNC_EXIT(NXPLOG_ITEM_HCPX)
+#else
+# define NXPLOG_HCPX_ENTRY()
+# define NXPLOG_HCPX_EXIT()
+#endif
+
+#if (ENABLE_HCPR_TRACES == TRUE )
+# define NXPLOG_HCPR_ENTRY() NXPLOG_FUNC_ENTRY(NXPLOG_ITEM_HCPR)
+# define NXPLOG_HCPR_EXIT() NXPLOG_FUNC_EXIT(NXPLOG_ITEM_HCPR)
+#else
+# define NXPLOG_HCPR_ENTRY()
+# define NXPLOG_HCPR_EXIT()
+#endif
+#endif /* NXP_HCI_REQ */
+
+#endif /* NXP_VRBS_REQ */
+
+void phNxpLog_InitializeLogLevel(void);
+
+#endif /* NXPLOG__H_INCLUDED */
diff --git a/halimpl/pn54x/nfc_nci.c b/halimpl/pn54x/nfc_nci.c
new file mode 100644
index 0000000..b316b54
--- /dev/null
+++ b/halimpl/pn54x/nfc_nci.c
@@ -0,0 +1,264 @@
+/*
+ * 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 <utils/Log.h>
+#include <errno.h>
+#include <hardware/hardware.h>
+#include <hardware/nfc.h>
+#include <phNxpNciHal_Adaptation.h>
+
+/*****************************************************************************
+ * NXP NCI HAL Function implementations.
+ *****************************************************************************/
+
+/*******************************************************************************
+**
+** Function hal_open
+**
+** Description It opens and initialzes the physical connection with NFCC.
+**
+** Returns 0 if successful
+**
+*******************************************************************************/
+static int hal_open(const struct nfc_nci_device *p_dev,
+ nfc_stack_callback_t p_hal_cback,
+ nfc_stack_data_callback_t *p_hal_data_callback)
+{
+ int retval = 0;
+
+ pn547_dev_t *dev = (pn547_dev_t*) p_dev;
+ retval = phNxpNciHal_open(p_hal_cback, p_hal_data_callback);
+
+ return retval;
+}
+
+/*******************************************************************************
+**
+** Function hal_write
+**
+** Description Write the data to NFCC.
+**
+** Returns Number of bytes successfully written to NFCC.
+**
+*******************************************************************************/
+static int hal_write(const struct nfc_nci_device *p_dev, uint16_t data_len,
+ const uint8_t *p_data)
+{
+ int retval = 0;
+ pn547_dev_t* dev = (pn547_dev_t*) p_dev;
+
+ retval = phNxpNciHal_write(data_len, p_data);
+ return retval;
+}
+
+/*******************************************************************************
+**
+** Function hal_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;
+}
+
+/*************************************
+ * Generic device handling.
+ *************************************/
+
+/*******************************************************************************
+**
+** Function nfc_close
+**
+** Description Close the nfc device instance.
+**
+** Returns 0 if successful
+**
+*******************************************************************************/
+static int nfc_close(hw_device_t *dev)
+{
+ int retval = 0;
+ free(dev);
+ return retval;
+}
+
+/*******************************************************************************
+**
+** Function nfc_open
+**
+** Description Open the nfc device instance.
+**
+** Returns 0 if successful
+**
+*******************************************************************************/
+static int nfc_open(const hw_module_t* module, const char* name,
+ hw_device_t** device)
+{
+ ALOGD("%s: enter; name=%s", __FUNCTION__, name);
+ int retval = 0; /* 0 is ok; -1 is error */
+
+ if (strcmp(name, NFC_NCI_CONTROLLER) == 0)
+ {
+ pn547_dev_t *dev = calloc(1, sizeof(pn547_dev_t));
+
+ /* Common hw_device_t fields */
+ dev->nci_device.common.tag = HARDWARE_DEVICE_TAG;
+ dev->nci_device.common.version = 0x00010000; /* [31:16] major, [15:0] minor */
+ dev->nci_device.common.module = (struct hw_module_t*) module;
+ dev->nci_device.common.close = nfc_close;
+
+ /* NCI HAL method pointers */
+ dev->nci_device.open = hal_open;
+ dev->nci_device.write = hal_write;
+ dev->nci_device.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;
+
+ *device = (hw_device_t*) dev;
+ }
+ else
+ {
+ retval = -EINVAL;
+ }
+
+ ALOGD("%s: exit %d", __FUNCTION__, retval);
+ return retval;
+}
+
+/* Android hardware module definition */
+static struct hw_module_methods_t nfc_module_methods =
+{
+ .open = nfc_open,
+};
+
+/* NFC module definition */
+struct nfc_nci_module_t HAL_MODULE_INFO_SYM =
+{
+ .common =
+ {
+ .tag = HARDWARE_MODULE_TAG,
+ .module_api_version = 0x0100, /* [15:8] major, [7:0] minor (1.0) */
+ .hal_api_version = 0x00, /* 0 is only valid value */
+ .id = NFC_NCI_NXP_PN54X_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..5f1675d
--- /dev/null
+++ b/halimpl/pn54x/self-test/phNxpNciHal_SelfTest.c
@@ -0,0 +1,2000 @@
+/*
+ * 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>
+
+#define HAL_WRITE_RSP_TIMEOUT (2000) /* Timeout value to wait for response from PN54X */
+#define HAL_WRITE_MAX_RETRY (10)
+
+/******************* Structures and definitions *******************************/
+
+typedef uint8_t (*st_validator_t)(nci_data_t *exp, phTmlNfc_TransactInfo_t *act);
+
+phAntenna_St_Resp_t phAntenna_resp;
+
+typedef struct nci_test_data
+{
+ nci_data_t cmd;
+ nci_data_t exp_rsp;
+ nci_data_t exp_ntf;
+ st_validator_t rsp_validator;
+ st_validator_t ntf_validator;
+
+}nci_test_data_t;
+
+/******************* Global variables *****************************************/
+
+static int thread_running = 0;
+static uint32_t timeoutTimerId = 0;
+static int hal_write_timer_fired = 0;
+
+/* TML Context */
+extern phTmlNfc_Context_t *gpphTmlNfc_Context;
+
+/* Global HAL Ref */
+extern phNxpNciHal_Control_t nxpncihal_ctrl;
+
+/* Driver parameters */
+phLibNfc_sConfig_t gDrvCfg;
+
+NFCSTATUS gtxldo_status = NFCSTATUS_FAILED;
+NFCSTATUS gagc_value_status = NFCSTATUS_FAILED;
+NFCSTATUS gagc_nfcld_status = NFCSTATUS_FAILED;
+NFCSTATUS gagc_differential_status = NFCSTATUS_FAILED;
+
+
+static uint8_t st_validator_testEquals(nci_data_t *exp, phTmlNfc_TransactInfo_t *act);
+static uint8_t st_validator_null(nci_data_t *exp, phTmlNfc_TransactInfo_t *act);
+static uint8_t st_validator_testSWP1_vltg(nci_data_t *exp, phTmlNfc_TransactInfo_t *act);
+static uint8_t st_validator_testAntenna_Txldo(nci_data_t *exp, phTmlNfc_TransactInfo_t *act);
+static uint8_t st_validator_testAntenna_AgcVal(nci_data_t *exp, phTmlNfc_TransactInfo_t *act);
+static uint8_t st_validator_testAntenna_AgcVal_FixedNfcLd(nci_data_t *exp, phTmlNfc_TransactInfo_t *act);
+static uint8_t st_validator_testAntenna_AgcVal_Differential(nci_data_t *exp, phTmlNfc_TransactInfo_t *act);
+
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+NFCSTATUS phNxpNciHal_getPrbsCmd (phNxpNfc_PrbsType_t prbs_type, phNxpNfc_PrbsHwType_t hw_prbs_type,
+ uint8_t tech, uint8_t bitrate, uint8_t *prbs_cmd, uint8_t prbs_cmd_len);
+#else
+NFCSTATUS phNxpNciHal_getPrbsCmd (uint8_t tech, uint8_t bitrate, uint8_t *prbs_cmd, uint8_t prbs_cmd_len);
+#endif
+/* Test data to validate SWP line 2*/
+static nci_test_data_t swp2_test_data[] = {
+ {
+ {
+ 0x04, {0x20,0x00,0x01,0x01} /* cmd */
+ },
+ {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ 0x06, {0x40,0x00,0x03,0x00,0x11,0x01} /* exp_rsp */
+#else
+ 0x06, {0x40,0x00,0x03,0x00,0x10,0x01} /* exp_rsp */
+#endif
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_null
+ },
+ {
+ {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ 0x05, {0x20,0x01,0x02,0x00,0x00} /* cmd */
+#else
+ 0x03, {0x20,0x01,0x00}
+#endif
+ },
+ {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ 0x4, {0x40,0x01,0x19,0x00 } /* exp_rsp */
+#else
+ 0x4, {0x40,0x01,0x17,0x00 }
+#endif
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_null
+ },
+ {
+ {
+ 0x03, {0x2F,0x02,0x00} /* cmd */
+ },
+ {
+ 0x04, {0x4F,0x02,0x05,0x00} /* exp_rsp */
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_null
+ },
+ {
+ {
+ 0x04, {0x2F,0x3E,0x01,0x01} /* cmd */
+ },
+ {
+ 0x04, {0x4F,0x3E,0x01,0x00} /* exp_rsp */
+ },
+ {
+ 0x04, {0x6F,0x3E,0x02,0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_testEquals
+ },
+
+};
+
+/* Test data to validate SWP line 1*/
+static nci_test_data_t swp1_test_data[] = {
+
+ {
+ {
+ 0x04, {0x20,0x00,0x01,0x01} /* cmd */
+ },
+ {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ 0x06, {0x40,0x00,0x03,0x00,0x11,0x01} /* exp_rsp */
+#else
+ 0x06, {0x40,0x00,0x03,0x00,0x10,0x01} /* exp_rsp */
+#endif
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_null
+ },
+ {
+ {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ 0x05, {0x20,0x01,0x02,0x00,0x00} /* cmd */
+#else
+ 0x03, {0x20,0x01,0x00}
+#endif
+ },
+ {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ 0x4, {0x40,0x01,0x19,0x00 } /* exp_rsp */
+#else
+ 0x4, {0x40,0x01,0x17,0x00 }
+#endif
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_null
+ },
+ {
+ {
+ 0x03, {0x2F,0x02,0x00} /* cmd */
+ },
+ {
+ 0x04, {0x4F,0x02,0x05,0x00} /* exp_rsp */
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_null
+ },
+ {
+ {
+ 0x04, {0x2F,0x3E,0x01,0x00} /* cmd */
+ },
+ {
+ 0x04, {0x4F,0x3E,0x01,0x00} /* exp_rsp */
+ },
+ {
+ 0x04, {0x6F,0x3E,0x02,0x00} /* ext_ntf */
+ },
+
+ st_validator_testEquals, /* validator */
+ st_validator_testSWP1_vltg
+ },
+};
+
+static nci_test_data_t prbs_test_data[] = {
+ {
+ {
+ 0x04, {0x20,0x00,0x01,0x00} /* cmd */
+ },
+ {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ 0x06, {0x40,0x00,0x03,0x00,0x11,0x00} /* exp_rsp */
+#else
+ 0x06, {0x40,0x00,0x03,0x00,0x10,0x00} /* exp_rsp */
+#endif
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_null
+ },
+ {
+ {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ 0x05, {0x20,0x01,0x02,0x00,0x00} /* cmd */
+#else
+ 0x03, {0x20,0x01,0x00} /* cmd */
+#endif
+ },
+ {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ 0x4, {0x40,0x01,0x19,0x00 } /* exp_rsp */
+#else
+ 0x4, {0x40,0x01,0x17,0x00 } /* exp_rsp */
+#endif
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_null
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ },
+ {
+ {
+ 0x04, {0x2F,0x00,0x01,0x00} /* cmd */
+ },
+ {
+ 0x04, {0x4F,0x00,0x01,0x00} /* exp_rsp */
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_null
+#endif
+ }
+};
+
+/* for rf field test, first requires to disable the standby mode */
+static nci_test_data_t rf_field_on_test_data[] = {
+ {
+ {
+ 0x04, {0x20,0x00,0x01,0x00} /* cmd */
+ },
+ {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ 0x06, {0x40,0x00,0x03,0x00,0x11,0x00} /* exp_rsp */
+#else
+ 0x06, {0x40,0x00,0x03,0x00,0x10,0x00} /* exp_rsp */
+#endif
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_null
+ },
+ {
+ {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ 0x05, {0x20,0x01,0x02,0x00,0x00} /* cmd */
+#else
+ 0x03, {0x20,0x01,0x00} /* cmd */
+#endif
+ },
+ {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ 0x4, {0x40,0x01,0x19,0x00 } /* exp_rsp */
+#else
+ 0x4, {0x40,0x01,0x17,0x00 } /* exp_rsp */
+#endif
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_null
+ },
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ {
+ {
+ 0x03, {0x2F,0x02,0x00} /* cmd */
+ },
+ {
+ 0x04, {0x4F,0x02,0x05,0x00} /* exp_rsp */
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_null
+ },
+ {
+ {
+ 0x04, {0x2F,0x00,0x01,0x00} /* cmd */
+ },
+ {
+ 0x04, {0x4F,0x00,0x01,0x00} /* exp_rsp */
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_null
+ },
+#endif
+ {
+ {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ 0x05, {0x2F,0x3D,0x02,0x20,0x01} /* cmd */
+#else
+ 0x08, {0x2F,0x3D,0x05,0x20,0x01,0x00,0x00,0x00} /* cmd */
+#endif
+ },
+ {
+ 0x04, {0x4F,0x3D,0x05,0x00} /* exp_rsp */
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_null
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ },
+ {
+ {
+ 0x04, {0x2F,0x00,0x01,0x01} /* cmd */
+ },
+ {
+ 0x04, {0x4F,0x00,0x01,0x00} /* exp_rsp */
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_null
+#endif
+ }
+};
+
+static nci_test_data_t rf_field_off_test_data[] = {
+ {
+ {
+ 0x04, {0x20,0x00,0x01,0x00} /* cmd */
+ },
+ {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ 0x06, {0x40,0x00,0x03,0x00,0x11,0x00} /* exp_rsp */
+#else
+ 0x06, {0x40,0x00,0x03,0x00,0x10,0x00} /* exp_rsp */
+#endif
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_null
+ },
+ {
+ {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ 0x05, {0x20,0x01,0x02,0x00,0x00} /* cmd */
+#else
+ 0x03, {0x20,0x01,0x00} /* cmd */
+#endif
+ },
+ {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ 0x4, {0x40,0x01,0x19,0x00 } /* exp_rsp */
+#else
+ 0x4, {0x40,0x01,0x17,0x00 } /* exp_rsp */
+#endif
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_null
+ },
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ {
+ {
+ 0x03, {0x2F,0x02,0x00} /* cmd */
+ },
+ {
+ 0x04, {0x4F,0x02,0x05,0x00} /* exp_rsp */
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_null
+ },
+ {
+ {
+ 0x04, {0x2F,0x00,0x01,0x00} /* cmd */
+ },
+ {
+ 0x04, {0x4F,0x00,0x01,0x00} /* exp_rsp */
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_null
+ },
+#endif
+ {
+ {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ 0x05, {0x2F,0x3D,0x02,0x20,0x00} /* cmd */
+#else
+ 0x08, {0x2F,0x3D,0x05,0x20,0x00,0x00,0x00,0x00} /* cmd */
+#endif
+ },
+ {
+ 0x04, {0x4F,0x3D,0x05,0x00} /* exp_rsp */
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_null
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ },
+ {
+ {
+ 0x04, {0x2F,0x00,0x01,0x01} /* cmd */
+ },
+ {
+ 0x04, {0x4F,0x00,0x01,0x00} /* exp_rsp */
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_null
+#endif
+ }
+};
+
+/* Download pin test data 1 */
+static nci_test_data_t download_pin_test_data1[] = {
+ {
+ {
+ 0x04, {0x20,0x00,0x01,0x01} /* cmd */
+ },
+ {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ 0x06, {0x40,0x00,0x03,0x00,0x11,0x01} /* exp_rsp */
+#else
+ 0x06, {0x40,0x00,0x03,0x00,0x10,0x01} /* exp_rsp */
+#endif
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_null
+ },
+};
+
+/* Download pin test data 2 */
+static nci_test_data_t download_pin_test_data2[] = {
+ {
+ {
+ 0x08, {0x00, 0x04, 0xD0, 0x11, 0x00, 0x00, 0x5B, 0x46} /* cmd */
+ },
+ {
+ 0x08, {0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x87, 0x16} /* exp_rsp */
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_null
+ },
+};
+/* Antenna self test data*/
+static nci_test_data_t antenna_self_test_data[] = {
+ {
+ {
+ 0x04, {0x20,0x00,0x01,0x00} /* cmd */
+ },
+ {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ 0x06, {0x40,0x00,0x03,0x00,0x11,0x00} /* exp_rsp */
+#else
+ 0x06, {0x40,0x00,0x03,0x00,0x10,0x00} /* exp_rsp */
+#endif
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_null
+ },
+ {
+ {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ 0x05, {0x20,0x01,0x02,0x00,0x00} /* cmd */
+#else
+ 0x03, {0x20,0x01,0x00} /* cmd */
+#endif
+ },
+ {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ 0x4, {0x40,0x01,0x19,0x00 } /* exp_rsp */
+#else
+ 0x4, {0x40,0x01,0x17,0x00 } /* exp_rsp */
+#endif
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_null
+ },
+ {
+ {
+ 0x03, {0x2F,0x02,0x00} /* cmd */
+ },
+ {
+ 0x04, {0x4F,0x02,0x05,0x00} /* exp_rsp */
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_null
+ },
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ {
+ {
+ 0x04, {0x2F,0x00,0x01,0x00} /* cmd */
+ },
+ {
+ 0x04, {0x4F,0x00,0x01,0x00} /* exp_rsp */
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_null
+ },
+#endif
+ {
+ {
+ 0x05, {0x2F, 0x3D, 0x02, 0x01, 0x80} /* TxLDO cureent measurement cmd */
+ },
+ {
+ 0x03, {0x4F, 0x3D, 05} /* exp_rsp */
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testAntenna_Txldo,
+ st_validator_null
+ },
+ {
+ {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ 0x07, {0x2F, 0x3D, 0x04, 0x02, 0xC8, 0x60, 0x03} /* AGC measurement cmd */
+#else
+ 0x07, {0x2F, 0x3D, 0x04, 0x02, 0xCD, 0x60, 0x03} /* AGC measurement cmd */
+#endif
+ },
+ {
+ 0x03, {0x4F, 0x3D, 05} /* exp_rsp */
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testAntenna_AgcVal,
+ st_validator_null
+ },
+ {
+ {
+ 0x07, {0x2F, 0x3D, 0x04, 0x04, 0x20, 0x08, 0x20} /* AGC with NFCLD measurement cmd */
+ },
+ {
+ 0x03, {0x4F, 0x3D, 05} /* exp_rsp */
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testAntenna_AgcVal_FixedNfcLd,
+ st_validator_null
+ },
+ {
+ {
+ 0x07, {0x2F, 0x3D, 0x04, 0x08, 0x8C, 0x60, 0x03} /* AGC with NFCLD measurement cmd */
+ },
+ {
+ 0x03, {0x4F, 0x3D, 05} /* exp_rsp */
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testAntenna_AgcVal_Differential,
+ st_validator_null
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ },
+ {
+ {
+ 0x04, {0x2F,0x00,0x01,0x01} /* cmd */
+ },
+ {
+ 0x04, {0x4F,0x00,0x01,0x00} /* exp_rsp */
+ },
+ {
+ 0x00, {0x00} /* ext_ntf */
+ },
+ st_validator_testEquals, /* validator */
+ st_validator_null
+#endif
+ }
+};
+
+
+/************** Self test functions ***************************************/
+
+static uint8_t st_validator_testEquals(nci_data_t *exp, phTmlNfc_TransactInfo_t *act);
+static void hal_write_cb(void *pContext, phTmlNfc_TransactInfo_t *pInfo);
+static void hal_write_rsp_timeout_cb(uint32_t TimerId, void *pContext);
+static void hal_read_cb(void *pContext, phTmlNfc_TransactInfo_t *pInfo);
+
+/*******************************************************************************
+**
+** Function st_validator_null
+**
+** Description Null Validator
+**
+** Returns One
+**
+*******************************************************************************/
+static uint8_t st_validator_null(nci_data_t *exp, phTmlNfc_TransactInfo_t *act)
+{
+ UNUSED(exp);
+ UNUSED(act);
+ return 1;
+}
+
+/*******************************************************************************
+**
+** Function st_validator_testSWP1_vltg
+**
+** Description Validator function to validate swp1 connection.
+**
+** Returns One if successful otherwise Zero.
+**
+*******************************************************************************/
+static uint8_t st_validator_testSWP1_vltg(nci_data_t *exp, phTmlNfc_TransactInfo_t *act)
+{
+ uint8_t result = 0;
+
+ if(NULL == exp || NULL == act)
+ {
+ return result;
+ }
+
+ if( (act->wLength == 0x05) &&
+ (memcmp(exp->p_data,act->pBuff,exp->len) == 0))
+ {
+ if(act->pBuff[4] == 0x01 || act->pBuff[4] == 0x02)
+ {
+ result = 1;
+ }
+ }
+
+ return result;
+}
+
+/*******************************************************************************
+**
+** Function st_validator_testAntenna_Txldo
+**
+** Description Validator function to validate Antenna TxLDO current measurement.
+**
+** Returns One if successful otherwise Zero.
+**
+*******************************************************************************/
+static uint8_t st_validator_testAntenna_Txldo(nci_data_t *exp, phTmlNfc_TransactInfo_t *act)
+{
+ uint8_t result = 0;
+ uint8_t mesuredrange =0;
+ long measured_val = 0;
+ int tolerance = 0;
+
+ if(NULL == exp || NULL == act)
+ {
+ return result;
+ }
+
+ NXPLOG_NCIHAL_D("st_validator_testAntenna_Txldo = 0x%x", act->pBuff[3]);
+ if (0x05 == act->pBuff[2])
+ {
+ if (NFCSTATUS_SUCCESS == act->pBuff[3])
+ {
+ result = 1;
+ NXPLOG_NCIHAL_D("Antenna: TxLDO current measured raw value in mA : 0x%x", act->pBuff[4]);
+ if(0x00 == act->pBuff[5])
+ {
+ NXPLOG_NCIHAL_D("Measured range : 0x00 = 50 - 100 mA");
+ measured_val = ((0.40 * act->pBuff[4]) + 50);
+ NXPLOG_NCIHAL_D("TxLDO current absolute value in mA = %ld", measured_val);
+ }
+ else
+ {
+ NXPLOG_NCIHAL_D("Measured range : 0x01 = 20 - 70 mA");
+ measured_val = ((0.40 * act->pBuff[4]) + 20);
+ NXPLOG_NCIHAL_D("TxLDO current absolute value in mA = %ld", measured_val);
+ }
+
+ tolerance = (phAntenna_resp.wTxdoMeasuredRangeMax *
+ phAntenna_resp.wTxdoMeasuredTolerance)/100;
+ if ((measured_val <= phAntenna_resp.wTxdoMeasuredRangeMax + tolerance))
+ {
+ tolerance = (phAntenna_resp.wTxdoMeasuredRangeMin *
+ phAntenna_resp.wTxdoMeasuredTolerance)/100;
+ if((measured_val >= phAntenna_resp.wTxdoMeasuredRangeMin - tolerance))
+ {
+ gtxldo_status = NFCSTATUS_SUCCESS;
+ NXPLOG_NCIHAL_E("Test Antenna Response for TxLDO measurement PASS");
+ }
+ else
+ {
+ gtxldo_status = NFCSTATUS_FAILED;
+ NXPLOG_NCIHAL_E("Test Antenna Response for TxLDO measurement FAIL");
+ }
+ }
+ else
+ {
+ gtxldo_status = NFCSTATUS_FAILED;
+ NXPLOG_NCIHAL_E("Test Antenna Response for TxLDO measurement FAIL");
+ }
+ }
+ else
+ {
+ gtxldo_status = NFCSTATUS_FAILED;
+ NXPLOG_NCIHAL_E("Test Antenna Response for TxLDO measurement failed: Invalid status");
+ }
+
+ }
+ else
+ {
+ gtxldo_status = NFCSTATUS_FAILED;
+ NXPLOG_NCIHAL_E("Test Antenna Response for TxLDO measurement failed: Invalid payload length");
+ }
+
+ return result;
+}
+
+/*******************************************************************************
+**
+** Function st_validator_testAntenna_AgcVal
+**
+** Description Validator function reads AGC value of antenna and print the info
+**
+** Returns One if successful otherwise Zero.
+**
+*******************************************************************************/
+static uint8_t st_validator_testAntenna_AgcVal(nci_data_t *exp, phTmlNfc_TransactInfo_t *act)
+{
+ uint8_t result = 0;
+ int agc_tolerance = 0;
+ long agc_val = 0;
+
+ if(NULL == exp || NULL == act)
+ {
+ return result;
+ }
+
+ if (0x05 == act->pBuff[2])
+ {
+ if (NFCSTATUS_SUCCESS == act->pBuff[3])
+ {
+ result = 1;
+ agc_tolerance = (phAntenna_resp.wAgcValue * phAntenna_resp.wAgcValueTolerance)/100;
+ agc_val = ((act->pBuff[5] << 8) | (act->pBuff[4]));
+ NXPLOG_NCIHAL_D("AGC value : %ld", agc_val);
+ if(((phAntenna_resp.wAgcValue - agc_tolerance) <= agc_val) &&
+ (agc_val <= (phAntenna_resp.wAgcValue + agc_tolerance)))
+ {
+ gagc_value_status = NFCSTATUS_SUCCESS;
+ NXPLOG_NCIHAL_E("Test Antenna Response for AGC Values PASS");
+ }
+ else
+ {
+ gagc_value_status = NFCSTATUS_FAILED;
+ NXPLOG_NCIHAL_E("Test Antenna Response for AGC Values FAIL");
+ }
+ }
+ else
+ {
+ gagc_value_status = NFCSTATUS_FAILED;
+ NXPLOG_NCIHAL_E("Test Antenna Response for AGC Values FAIL");
+ }
+ }
+ else
+ {
+ gagc_value_status = NFCSTATUS_FAILED;
+ NXPLOG_NCIHAL_E("Test Antenna Response for AGC value failed: Invalid payload length");
+ }
+
+ return result;
+}
+/*******************************************************************************
+**
+** Function st_validator_testAntenna_AgcVal_FixedNfcLd
+**
+** Description Validator function reads and print AGC value of
+** antenna with fixed NFCLD
+**
+** Returns One if successful otherwise Zero.
+**
+*******************************************************************************/
+static uint8_t st_validator_testAntenna_AgcVal_FixedNfcLd(nci_data_t *exp, phTmlNfc_TransactInfo_t *act)
+{
+ uint8_t result = 0;
+ int agc_nfcld_tolerance = 0;
+ long agc_nfcld = 0;
+
+ if(NULL == exp || NULL == act)
+ {
+ return result;
+ }
+
+ if(0x05 == act->pBuff[2])
+ {
+ if(NFCSTATUS_SUCCESS == act->pBuff[3])
+ {
+ result = 1;
+ agc_nfcld_tolerance = (phAntenna_resp.wAgcValuewithfixedNFCLD *
+ phAntenna_resp.wAgcValuewithfixedNFCLDTolerance)/100;
+ agc_nfcld = ((act->pBuff[5] << 8) | (act->pBuff[4]));
+ NXPLOG_NCIHAL_D("AGC value with Fixed Nfcld : %ld", agc_nfcld);
+
+ if(((phAntenna_resp.wAgcValuewithfixedNFCLD - agc_nfcld_tolerance) <= agc_nfcld) &&
+ (agc_nfcld <= (phAntenna_resp.wAgcValuewithfixedNFCLD + agc_nfcld_tolerance)))
+ {
+ gagc_nfcld_status = NFCSTATUS_SUCCESS;
+ NXPLOG_NCIHAL_E("Test Antenna Response for AGC value with fixed NFCLD PASS");
+ }
+ else
+ {
+ gagc_nfcld_status = NFCSTATUS_FAILED;
+ NXPLOG_NCIHAL_E("Test Antenna Response for AGC value with fixed NFCLD FAIL");
+ }
+ }
+ else
+ {
+ gagc_nfcld_status = NFCSTATUS_FAILED;
+ NXPLOG_NCIHAL_E("Test Antenna Response for AGC value with fixed NFCLD failed: Invalid status");
+ }
+ }
+ else
+ {
+ gagc_nfcld_status = NFCSTATUS_FAILED;
+ NXPLOG_NCIHAL_E("Test Antenna Response for AGC value with fixed NFCLD failed: Invalid payload length");
+ }
+
+ return result;
+}
+
+/*******************************************************************************
+**
+** Function st_validator_testAntenna_AgcVal_Differential
+**
+** Description Reads the AGC value with open/short RM from buffer and print
+**
+** Returns One if successful otherwise Zero.
+**
+*******************************************************************************/
+static uint8_t st_validator_testAntenna_AgcVal_Differential(nci_data_t *exp, phTmlNfc_TransactInfo_t *act)
+{
+ uint8_t result = 0;
+ int agc_toleranceopne1 = 0;
+ int agc_toleranceopne2 = 0;
+ long agc_differentialOpne1 = 0;
+ long agc_differentialOpne2 = 0;
+
+ if(NULL == exp || NULL == act)
+ {
+ return result;
+ }
+
+ if (0x05 == act->pBuff[2])
+ {
+ if (NFCSTATUS_SUCCESS == act->pBuff[3])
+ {
+ result = 1;
+ agc_toleranceopne1=(phAntenna_resp.wAgcDifferentialWithOpen1 *
+ phAntenna_resp.wAgcDifferentialWithOpenTolerance1)/100;
+ agc_toleranceopne2=(phAntenna_resp.wAgcDifferentialWithOpen2 *
+ phAntenna_resp.wAgcDifferentialWithOpenTolerance2)/100;
+ agc_differentialOpne1 = ((act->pBuff[5] << 8) | (act->pBuff[4]));
+ agc_differentialOpne2 = ((act->pBuff[7] << 8) | (act->pBuff[6]));
+ NXPLOG_NCIHAL_D("AGC value differential Opne 1 : %ld", agc_differentialOpne1);
+ NXPLOG_NCIHAL_D("AGC value differentialOpne 2 : %ld", agc_differentialOpne2);
+
+ if(((agc_differentialOpne1 >= phAntenna_resp.wAgcDifferentialWithOpen1 - agc_toleranceopne1) &&
+ (agc_differentialOpne1 <= phAntenna_resp.wAgcDifferentialWithOpen1 + agc_toleranceopne1)) &&
+ ((agc_differentialOpne2 >= phAntenna_resp.wAgcDifferentialWithOpen2 - agc_toleranceopne2) &&
+ (agc_differentialOpne2 <= phAntenna_resp.wAgcDifferentialWithOpen2 + agc_toleranceopne2)))
+ {
+ gagc_differential_status = NFCSTATUS_SUCCESS;
+ NXPLOG_NCIHAL_E("Test Antenna Response for AGC Differential Open PASS");
+ }
+ else
+ {
+ gagc_differential_status = NFCSTATUS_FAILED;
+ NXPLOG_NCIHAL_E("Test Antenna Response for AGC Differential Open FAIL");
+ }
+ }
+ else
+ {
+ NXPLOG_NCIHAL_E("Test Antenna Response for AGC Differential failed: Invalid status");
+ gagc_differential_status = NFCSTATUS_FAILED;
+ }
+
+ }
+ else
+ {
+ NXPLOG_NCIHAL_E("Test Antenna Response for AGC Differential failed: Invalid payload length");
+ gagc_differential_status = NFCSTATUS_FAILED;
+ }
+
+ return result;
+}
+/*******************************************************************************
+**
+** Function st_validator_testEquals
+**
+** Description Validator function to validate for equality between actual
+** and expected values.
+**
+** Returns One if successful otherwise Zero.
+**
+*******************************************************************************/
+static uint8_t st_validator_testEquals(nci_data_t *exp, phTmlNfc_TransactInfo_t *act)
+{
+ uint8_t result = 0;
+
+ if(NULL == exp || NULL == act)
+ {
+ return result;
+ }
+ if(exp->len <= act->wLength &&
+ (memcmp(exp->p_data,act->pBuff,exp->len) == 0))
+ {
+ result = 1;
+ }
+
+ return result;
+}
+
+/*******************************************************************************
+**
+** Function hal_write_rsp_timeout_cb
+**
+** Description Callback function for hal write response timer.
+**
+** Returns None
+**
+*******************************************************************************/
+static void hal_write_rsp_timeout_cb(uint32_t timerId, void *pContext)
+{
+ UNUSED(timerId);
+ NXPLOG_NCIHAL_E("hal_write_rsp_timeout_cb - write timeout!!!");
+ hal_write_timer_fired = 1;
+ hal_read_cb(pContext,NULL);
+}
+
+/*******************************************************************************
+**
+** Function hal_write_cb
+**
+** Description Callback function for hal write.
+**
+** Returns None
+**
+*******************************************************************************/
+static void hal_write_cb(void *pContext, phTmlNfc_TransactInfo_t *pInfo)
+{
+ phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+
+ if (pInfo->wStatus == NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_D("write successful status = 0x%x", pInfo->wStatus);
+ }
+ else
+ {
+ NXPLOG_NCIHAL_E("write error status = 0x%x", pInfo->wStatus);
+ }
+
+ p_cb_data->status = pInfo->wStatus;
+ SEM_POST(p_cb_data);
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function hal_read_cb
+**
+** Description Callback function for hal read.
+**
+** Returns None
+**
+*******************************************************************************/
+static void hal_read_cb(void *pContext, phTmlNfc_TransactInfo_t *pInfo)
+{
+ phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+ NFCSTATUS status;
+ if(hal_write_timer_fired == 1)
+ {
+ NXPLOG_NCIHAL_D("hal_read_cb - response timeout occurred");
+
+ hal_write_timer_fired = 0;
+ p_cb_data->status = NFCSTATUS_RESPONSE_TIMEOUT;
+ status = phTmlNfc_ReadAbort();
+ }
+ else
+ {
+ NFCSTATUS status = phOsalNfc_Timer_Stop(timeoutTimerId);
+
+ if (NFCSTATUS_SUCCESS == status)
+ {
+ NXPLOG_NCIHAL_D("Response timer stopped");
+ }
+ else
+ {
+ NXPLOG_NCIHAL_E("Response timer stop ERROR!!!");
+ p_cb_data->status = NFCSTATUS_FAILED;
+ }
+
+ if (pInfo->wStatus == NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_D("hal_read_cb successful status = 0x%x", pInfo->wStatus);
+ p_cb_data->status = NFCSTATUS_SUCCESS;
+ }
+ else
+ {
+ NXPLOG_NCIHAL_E("hal_read_cb error status = 0x%x", pInfo->wStatus);
+ p_cb_data->status = NFCSTATUS_FAILED;
+ }
+
+ p_cb_data->status = pInfo->wStatus;
+
+ nci_test_data_t *test_data = (nci_test_data_t*) p_cb_data->pContext;
+
+ if(test_data->exp_rsp.len == 0)
+ {
+ /* Compare the actual notification with expected notification.*/
+ if( test_data->ntf_validator(&(test_data->exp_ntf),pInfo) == 1 )
+ {
+ p_cb_data->status = NFCSTATUS_SUCCESS;
+ }
+ else
+ {
+ p_cb_data->status = NFCSTATUS_FAILED;
+
+ }
+ }
+
+ /* Compare the actual response with expected response.*/
+ else if( test_data->rsp_validator(&(test_data->exp_rsp),pInfo) == 1)
+ {
+ p_cb_data->status = NFCSTATUS_SUCCESS;
+ }
+ else
+ {
+ p_cb_data->status = NFCSTATUS_FAILED;
+ }
+ test_data->exp_rsp.len = 0;
+ }
+
+ SEM_POST(p_cb_data);
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_test_rx_thread
+**
+** Description Thread to fetch and process messages from message queue.
+**
+** Returns NULL
+**
+*******************************************************************************/
+static void *phNxpNciHal_test_rx_thread(void *arg)
+{
+ phLibNfc_Message_t msg;
+ UNUSED(arg);
+ NXPLOG_NCIHAL_D("Self test thread started");
+
+ thread_running = 1;
+
+ while (thread_running == 1)
+ {
+ /* Fetch next message from the NFC stack message queue */
+ if (phDal4Nfc_msgrcv(gDrvCfg.nClientId,
+ &msg, 0, 0) == -1)
+ {
+ NXPLOG_NCIHAL_E("Received bad message");
+ continue;
+ }
+
+ if(thread_running == 0)
+ {
+ break;
+ }
+
+ switch (msg.eMsgType)
+ {
+ case PH_LIBNFC_DEFERREDCALL_MSG:
+ {
+ phLibNfc_DeferredCall_t *deferCall =
+ (phLibNfc_DeferredCall_t *) (msg.pMsgData);
+
+ REENTRANCE_LOCK();
+ deferCall->pCallback(deferCall->pParameter);
+ REENTRANCE_UNLOCK();
+
+ break;
+ }
+ }
+ }
+
+ NXPLOG_NCIHAL_D("Self test thread stopped");
+
+ return NULL;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_readLocked
+**
+** Description Reads response and notification from NFCC and waits for
+** read completion, for a definitive timeout value.
+**
+** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED,
+** NFCSTATUS_RESPONSE_TIMEOUT in case of timeout.
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_readLocked(nci_test_data_t *pData )
+{
+ NFCSTATUS status = NFCSTATUS_SUCCESS;
+ phNxpNciHal_Sem_t cb_data;
+ uint16_t read_len = 16;
+ /* RX Buffer */
+ uint32_t rx_data[NCI_MAX_DATA_LEN];
+
+ /* Create the local semaphore */
+ if (phNxpNciHal_init_cb_data(&cb_data, pData) != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_D("phTmlNfc_Read Create cb data failed");
+ status = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ /* call read pending */
+ status = phTmlNfc_Read(
+ (uint8_t *) rx_data,
+ (uint16_t) read_len,
+ (pphTmlNfc_TransactCompletionCb_t) &hal_read_cb,
+ &cb_data);
+
+ if (status != NFCSTATUS_PENDING)
+ {
+ NXPLOG_NCIHAL_E("TML Read status error status = %x", status);
+ status = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ status = phOsalNfc_Timer_Start(timeoutTimerId,
+ HAL_WRITE_RSP_TIMEOUT,
+ &hal_write_rsp_timeout_cb,
+ &cb_data);
+
+ if (NFCSTATUS_SUCCESS == status)
+ {
+ NXPLOG_NCIHAL_D("Response timer started");
+ }
+ else
+ {
+ NXPLOG_NCIHAL_E("Response timer not started");
+ status = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ /* Wait for callback response */
+ if (SEM_WAIT(cb_data))
+ {
+ NXPLOG_NCIHAL_E("phTmlNfc_Read semaphore error");
+ status = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ if(cb_data.status == NFCSTATUS_RESPONSE_TIMEOUT)
+ {
+ NXPLOG_NCIHAL_E("Response timeout!!!");
+ status = NFCSTATUS_RESPONSE_TIMEOUT;
+ goto clean_and_return;
+
+ }
+
+ if (cb_data.status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E("phTmlNfc_Read failed ");
+ status = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ clean_and_return:
+ phNxpNciHal_cleanup_cb_data(&cb_data);
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_writeLocked
+**
+** Description Send command to NFCC and waits for cmd write completion, for
+** a definitive timeout value.
+**
+** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED,
+** NFCSTATUS_RESPONSE_TIMEOUT in case of timeout.
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_writeLocked(nci_test_data_t *pData )
+{
+ NFCSTATUS status = NFCSTATUS_SUCCESS;
+
+ phNxpNciHal_Sem_t cb_data;
+ int retryCnt = 0;
+
+ /* Create the local semaphore */
+ if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_D("phTmlNfc_Write Create cb data failed");
+ goto clean_and_return;
+ }
+
+retry:
+ status = phTmlNfc_Write(pData->cmd.p_data, pData->cmd.len,
+ (pphTmlNfc_TransactCompletionCb_t) &hal_write_cb, &cb_data);
+
+ if (status != NFCSTATUS_PENDING)
+ {
+ NXPLOG_NCIHAL_E("phTmlNfc_Write status error");
+ goto clean_and_return;
+ }
+
+ /* Wait for callback response */
+ if (SEM_WAIT(cb_data))
+ {
+ NXPLOG_NCIHAL_E("write_unlocked semaphore error");
+ status = NFCSTATUS_FAILED;
+ goto clean_and_return;
+ }
+
+ if (cb_data.status != NFCSTATUS_SUCCESS && retryCnt < HAL_WRITE_MAX_RETRY)
+ {
+ retryCnt++;
+ NXPLOG_NCIHAL_E("write_unlocked failed - PN54X Maybe in Standby Mode - Retry %d",retryCnt);
+ goto retry;
+ }
+
+ status = cb_data.status;
+
+clean_and_return:
+ phNxpNciHal_cleanup_cb_data(&cb_data);
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_performTest
+**
+** Description Performs a single cycle of command,response and
+** notification.
+**
+** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED,
+**
+*******************************************************************************/
+NFCSTATUS phNxpNciHal_performTest(nci_test_data_t *pData )
+{
+ NFCSTATUS status = NFCSTATUS_SUCCESS;
+
+ if(NULL == pData)
+ {
+ return NFCSTATUS_FAILED;
+ }
+
+ CONCURRENCY_LOCK();
+
+ status = phNxpNciHal_writeLocked(pData);
+
+ if(status == NFCSTATUS_RESPONSE_TIMEOUT)
+ {
+ goto clean_and_return;
+ }
+ if(status != NFCSTATUS_SUCCESS)
+ {
+ goto clean_and_return;
+ }
+
+ status = phNxpNciHal_readLocked(pData);
+
+ if(status != NFCSTATUS_SUCCESS)
+ {
+ goto clean_and_return;
+ }
+
+ if(0 != pData->exp_ntf.len)
+ {
+ status = phNxpNciHal_readLocked(pData);
+
+ if(status != NFCSTATUS_SUCCESS)
+ {
+ goto clean_and_return;
+ }
+ }
+
+clean_and_return:
+ CONCURRENCY_UNLOCK();
+ return status;
+}
+
+/*******************************************************************************
+ **
+ ** Function phNxpNciHal_TestMode_open
+ **
+ ** Description It opens the physical connection with NFCC (PN54X) and
+ ** creates required client thread for operation.
+ **
+ ** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED.
+ **
+ *******************************************************************************/
+NFCSTATUS phNxpNciHal_TestMode_open (void)
+{
+ /* Thread */
+ pthread_t test_rx_thread;
+
+ phOsalNfc_Config_t tOsalConfig;
+ phTmlNfc_Config_t tTmlConfig;
+ NFCSTATUS status = NFCSTATUS_SUCCESS;
+ uint16_t read_len = 255;
+ 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));
+
+ gDrvCfg.nClientId = phDal4Nfc_msgget(0, 0600);
+ gDrvCfg.nLinkType = ENUM_LINK_TYPE_I2C;/* For PN54X */
+ tTmlConfig.pDevName = (int8_t *) "/dev/pn544";
+ tOsalConfig.dwCallbackThreadId = (uintptr_t) gDrvCfg.nClientId;
+ tOsalConfig.pLogFile = NULL;
+ tTmlConfig.dwGetMsgThreadId = (uintptr_t) gDrvCfg.nClientId;
+ nxpncihal_ctrl.gDrvCfg.nClientId = (uintptr_t) gDrvCfg.nClientId;
+
+ /* Initialize TML layer */
+ status = phTmlNfc_Init(&tTmlConfig);
+ if (status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_E("phTmlNfc_Init Failed");
+ goto clean_and_return;
+ }
+
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ 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();
+ phNxpNciHal_cleanup_monitor();
+ return NFCSTATUS_FAILED;
+}
+
+/*******************************************************************************
+ **
+ ** Function phNxpNciHal_TestMode_close
+ **
+ ** Description This function close the NFCC interface and free all
+ ** resources.
+ **
+ ** Returns None.
+ **
+ *******************************************************************************/
+
+void phNxpNciHal_TestMode_close ()
+{
+
+ NFCSTATUS status = NFCSTATUS_SUCCESS;
+
+ CONCURRENCY_LOCK();
+
+ if (NULL != gpphTmlNfc_Context->pDevHandle)
+ {
+ /* Abort any pending read and write */
+ status = phTmlNfc_ReadAbort();
+ status = phTmlNfc_WriteAbort();
+
+ phOsalNfc_Timer_Cleanup();
+
+ status = phTmlNfc_Shutdown();
+
+ NXPLOG_NCIHAL_D("phNxpNciHal_close return status = %d", status);
+
+ thread_running = 0;
+
+ phDal4Nfc_msgrelease(gDrvCfg.nClientId);
+
+ status = phOsalNfc_Timer_Delete(timeoutTimerId);
+ }
+
+ CONCURRENCY_UNLOCK();
+
+ phNxpNciHal_cleanup_monitor();
+
+ /* Return success always */
+ return;
+}
+
+/*******************************************************************************
+ **
+ ** Function phNxpNciHal_SwpTest
+ **
+ ** Description Test function to validate the SWP line. SWP line number is
+ ** is sent as parameter to the API.
+ **
+ ** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED.
+ **
+ *******************************************************************************/
+
+NFCSTATUS phNxpNciHal_SwpTest(uint8_t swp_line)
+{
+ NFCSTATUS status = NFCSTATUS_SUCCESS;
+ int len = 0;
+ int cnt = 0;
+
+ NXPLOG_NCIHAL_D("phNxpNciHal_SwpTest - start\n");
+
+ if(swp_line == 0x01)
+ {
+ len = (sizeof(swp1_test_data)/sizeof(swp1_test_data[0]));
+
+ for(cnt = 0; cnt < len; cnt++)
+ {
+ status = phNxpNciHal_performTest(&(swp1_test_data[cnt]));
+ if(status == NFCSTATUS_RESPONSE_TIMEOUT ||
+ status == NFCSTATUS_FAILED
+ )
+ {
+ break;
+ }
+ }
+ }
+ else if(swp_line == 0x02)
+ {
+ len = (sizeof(swp2_test_data)/sizeof(swp2_test_data[0]));
+
+ for(cnt = 0; cnt < len; cnt++)
+ {
+ status = phNxpNciHal_performTest(&(swp2_test_data[cnt]));
+ if(status == NFCSTATUS_RESPONSE_TIMEOUT ||
+ status == NFCSTATUS_FAILED
+ )
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ status = NFCSTATUS_FAILED;
+ }
+
+ if( status == NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_D("phNxpNciHal_SwpTest - SUCCESSS\n");
+ }
+ else
+ {
+ NXPLOG_NCIHAL_D("phNxpNciHal_SwpTest - FAILED\n");
+ }
+
+ NXPLOG_NCIHAL_D("phNxpNciHal_SwpTest - end\n");
+
+ return status;
+}
+
+/*******************************************************************************
+ **
+ ** Function phNxpNciHal_PrbsTestStart
+ **
+ ** Description Test function start RF generation for RF technology and bit
+ ** rate. RF technology and bit rate are sent as parameter to
+ ** the API.
+ **
+ ** Returns NFCSTATUS_SUCCESS if RF generation successful,
+ ** otherwise NFCSTATUS_FAILED.
+ **
+ *******************************************************************************/
+
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+NFCSTATUS phNxpNciHal_PrbsTestStart (phNxpNfc_PrbsType_t prbs_type, phNxpNfc_PrbsHwType_t hw_prbs_type,
+ phNxpNfc_Tech_t tech, phNxpNfc_Bitrate_t bitrate)
+#else
+NFCSTATUS phNxpNciHal_PrbsTestStart (phNxpNfc_Tech_t tech, phNxpNfc_Bitrate_t bitrate)
+#endif
+{
+ NFCSTATUS status = NFCSTATUS_FAILED;
+
+ nci_test_data_t prbs_cmd_data;
+
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ uint8_t rsp_cmd_info[] = {0x4F, 0x30, 0x01, 0x00};
+ prbs_cmd_data.cmd.len = 0x09;
+#else
+ uint8_t rsp_cmd_info[] = {0x4F, 0x30, 0x01, 0x00};
+ prbs_cmd_data.cmd.len = 0x07;
+#endif
+
+ memcpy(prbs_cmd_data.exp_rsp.p_data, &rsp_cmd_info[0], sizeof(rsp_cmd_info));
+ prbs_cmd_data.exp_rsp.len = sizeof(rsp_cmd_info);
+
+ //prbs_cmd_data.exp_rsp.len = 0x00;
+ prbs_cmd_data.exp_ntf.len = 0x00;
+ prbs_cmd_data.rsp_validator = st_validator_testEquals;
+ prbs_cmd_data.ntf_validator = st_validator_null;
+
+ uint8_t len = 0;
+ uint8_t cnt = 0;
+
+// [NCI] -> [0x2F 0x30 0x04 0x00 0x00 0x01 0xFF]
+
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ status = phNxpNciHal_getPrbsCmd(prbs_type, hw_prbs_type, tech, bitrate,
+ prbs_cmd_data.cmd.p_data,prbs_cmd_data.cmd.len);
+#else
+ status = phNxpNciHal_getPrbsCmd(tech, bitrate,prbs_cmd_data.cmd.p_data,prbs_cmd_data.cmd.len);
+#endif
+
+ if( status == NFCSTATUS_FAILED)
+ {
+ //Invalid Param.
+ NXPLOG_NCIHAL_D("phNxpNciHal_PrbsTestStart - INVALID_PARAM\n");
+
+ goto clean_and_return;
+ }
+
+ len = (sizeof(prbs_test_data)/sizeof(prbs_test_data[0]));
+
+ for(cnt = 0; cnt < len; cnt++)
+ {
+ status = phNxpNciHal_performTest(&(prbs_test_data[cnt]));
+ if(status == NFCSTATUS_RESPONSE_TIMEOUT ||
+ status == NFCSTATUS_FAILED
+ )
+ {
+ break;
+ }
+ }
+
+ /* Ignoring status, as there will be no response - Applicable till FW version 8.1.1*/
+ status = phNxpNciHal_performTest(&prbs_cmd_data);
+ clean_and_return:
+
+ if( status == NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_D("phNxpNciHal_PrbsTestStart - SUCCESSS\n");
+ }
+ else
+ {
+ NXPLOG_NCIHAL_D("phNxpNciHal_PrbsTestStart - FAILED\n");
+ }
+
+ NXPLOG_NCIHAL_D("phNxpNciHal_PrbsTestStart - end\n");
+
+ return status;
+}
+
+/*******************************************************************************
+ **
+ ** Function phNxpNciHal_PrbsTestStop
+ **
+ ** Description Test function stop RF generation for RF technology started
+ ** by phNxpNciHal_PrbsTestStart.
+ **
+ ** Returns NFCSTATUS_SUCCESS if operation successful,
+ ** otherwise NFCSTATUS_FAILED.
+ **
+ *******************************************************************************/
+
+NFCSTATUS phNxpNciHal_PrbsTestStop ()
+{
+ NXPLOG_NCIHAL_D("phNxpNciHal_PrbsTestStop - Start\n");
+
+ NFCSTATUS status = NFCSTATUS_SUCCESS;
+
+ status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
+
+ if(NFCSTATUS_SUCCESS == status)
+ {
+ NXPLOG_NCIHAL_D("phNxpNciHal_PrbsTestStop - SUCCESS\n");
+ }
+ else
+ {
+ NXPLOG_NCIHAL_D("phNxpNciHal_PrbsTestStop - FAILED\n");
+
+ }
+ NXPLOG_NCIHAL_D("phNxpNciHal_PrbsTestStop - end\n");
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_getPrbsCmd
+**
+** Description Test function frames the PRBS command.
+**
+** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED.
+**
+*******************************************************************************/
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+NFCSTATUS phNxpNciHal_getPrbsCmd (phNxpNfc_PrbsType_t prbs_type, phNxpNfc_PrbsHwType_t hw_prbs_type,
+ uint8_t tech, uint8_t bitrate, uint8_t *prbs_cmd, uint8_t prbs_cmd_len)
+#else
+NFCSTATUS phNxpNciHal_getPrbsCmd (uint8_t tech, uint8_t bitrate, uint8_t *prbs_cmd, uint8_t prbs_cmd_len)
+#endif
+{
+ NFCSTATUS status = NFCSTATUS_SUCCESS;
+ int position_tech_param = 0;
+ int position_bit_param = 0;
+
+ NXPLOG_NCIHAL_D("phNxpNciHal_getPrbsCmd - tech 0x%x bitrate = 0x%x", tech, bitrate);
+ if(NULL == prbs_cmd ||
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ prbs_cmd_len != 0x09)
+#else
+ prbs_cmd_len != 0x07)
+#endif
+ {
+ return status;
+ }
+
+ prbs_cmd[0] = 0x2F;
+ prbs_cmd[1] = 0x30;
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ prbs_cmd[2] = 0x06;
+ prbs_cmd[3] = (uint8_t)prbs_type;
+ //0xFF Error value used for validation.
+ prbs_cmd[4] = (uint8_t)hw_prbs_type;
+ prbs_cmd[5] = 0xFF;//TECH
+ prbs_cmd[6] = 0xFF;//BITRATE
+ prbs_cmd[7] = 0x01;
+ prbs_cmd[8] = 0xFF;
+ position_tech_param = 5;
+ position_bit_param = 6;
+#else
+ prbs_cmd[2] = 0x04;
+ //0xFF Error value used for validation.
+ prbs_cmd[3] = 0xFF;//TECH
+ //0xFF Error value used for validation.
+ prbs_cmd[4] = 0xFF;//BITRATE
+ prbs_cmd[5] = 0x01;
+ prbs_cmd[6] = 0xFF;
+ position_tech_param = 3;
+ position_bit_param = 4;
+#endif
+
+ switch (tech) {
+ case NFC_RF_TECHNOLOGY_A:
+ NXPLOG_NCIHAL_D("phNxpNciHal_getPrbsCmd - NFC_RF_TECHNOLOGY_A");
+ prbs_cmd[position_tech_param] = 0x00;
+ break;
+ case NFC_RF_TECHNOLOGY_B:
+ NXPLOG_NCIHAL_D("phNxpNciHal_getPrbsCmd - NFC_RF_TECHNOLOGY_B");
+ prbs_cmd[position_tech_param] = 0x01;
+ break;
+ case NFC_RF_TECHNOLOGY_F:
+ NXPLOG_NCIHAL_D("phNxpNciHal_getPrbsCmd - NFC_RF_TECHNOLOGY_F");
+ prbs_cmd[position_tech_param] = 0x02;
+ break;
+ default:
+ break;
+ }
+
+ switch (bitrate)
+ {
+ case NFC_BIT_RATE_106:
+ NXPLOG_NCIHAL_D("phNxpNciHal_getPrbsCmd - NFC_BIT_RATE_106");
+ if(prbs_cmd[position_tech_param] != 0x02)
+ {
+ prbs_cmd[position_bit_param] = 0x00;
+ }
+ break;
+ case NFC_BIT_RATE_212:
+ NXPLOG_NCIHAL_D("phNxpNciHal_getPrbsCmd - NFC_BIT_RATE_212");
+ prbs_cmd[position_bit_param] = 0x01;
+ break;
+ case NFC_BIT_RATE_424:
+ NXPLOG_NCIHAL_D("phNxpNciHal_getPrbsCmd - NFC_BIT_RATE_424");
+ prbs_cmd[position_bit_param] = 0x02;
+ break;
+ case NFC_BIT_RATE_848:
+ NXPLOG_NCIHAL_D("phNxpNciHal_getPrbsCmd - NFC_BIT_RATE_848");
+ if(prbs_cmd[position_tech_param] != 0x02)
+ {
+ prbs_cmd[position_bit_param] = 0x03;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if(prbs_cmd[position_tech_param] == 0xFF || prbs_cmd[position_bit_param] == 0xFF)
+ {
+ //Invalid Param.
+ status = NFCSTATUS_FAILED;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_RfFieldTest
+**
+** Description Test function performs RF filed test.
+**
+** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED.
+**
+*******************************************************************************/
+NFCSTATUS phNxpNciHal_RfFieldTest (uint8_t on)
+{
+ NFCSTATUS status = NFCSTATUS_SUCCESS;
+ int len = 0;
+ int cnt = 0;
+
+ NXPLOG_NCIHAL_D("phNxpNciHal_RfFieldTest - start %x\n",on);
+
+ if(on == 0x01)
+ {
+ len = (sizeof(rf_field_on_test_data)/sizeof(rf_field_on_test_data[0]));
+
+ for(cnt = 0; cnt < len; cnt++)
+ {
+ status = phNxpNciHal_performTest(&(rf_field_on_test_data[cnt]));
+ if(status == NFCSTATUS_RESPONSE_TIMEOUT || status == NFCSTATUS_FAILED)
+ {
+ break;
+ }
+ }
+ }
+ else if(on == 0x00)
+ {
+ len = (sizeof(rf_field_off_test_data)/sizeof(rf_field_off_test_data[0]));
+
+ for(cnt = 0; cnt < len; cnt++)
+ {
+ status = phNxpNciHal_performTest(&(rf_field_off_test_data[cnt]));
+ if(status == NFCSTATUS_RESPONSE_TIMEOUT || status == NFCSTATUS_FAILED)
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ status = NFCSTATUS_FAILED;
+ }
+
+ if( status == NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_D("phNxpNciHal_RfFieldTest - SUCCESSS\n");
+ }
+ else
+ {
+ NXPLOG_NCIHAL_D("phNxpNciHal_RfFieldTest - FAILED\n");
+ }
+
+ NXPLOG_NCIHAL_D("phNxpNciHal_RfFieldTest - end\n");
+
+ return status;
+}
+
+/*******************************************************************************
+ **
+ ** Function phNxpNciHal_AntennaTest
+ **
+ ** Description
+ **
+ ** Returns
+ **
+ *******************************************************************************/
+NFCSTATUS phNxpNciHal_AntennaTest ()
+{
+ NFCSTATUS status = NFCSTATUS_FAILED;
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function phNxpNciHal_DownloadPinTest
+**
+** Description Test function to validate the FW download pin connection.
+**
+** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED.
+**
+*******************************************************************************/
+NFCSTATUS phNxpNciHal_DownloadPinTest(void)
+{
+ NFCSTATUS status = NFCSTATUS_FAILED;
+ int len = 0;
+ int cnt = 0;
+
+ NXPLOG_NCIHAL_D("phNxpNciHal_DownloadPinTest - start\n");
+
+ len = (sizeof(download_pin_test_data1)/sizeof(download_pin_test_data1[0]));
+
+ for(cnt = 0; cnt < len; cnt++)
+ {
+ status = phNxpNciHal_performTest(&(download_pin_test_data1[cnt]));
+ if(status == NFCSTATUS_RESPONSE_TIMEOUT || status == NFCSTATUS_FAILED)
+ {
+ break;
+ }
+ }
+
+ if (status != NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_D("phNxpNciHal_DownloadPinTest - FAILED\n");
+ return status;
+ }
+
+ status = NFCSTATUS_FAILED;
+ status = phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode);
+ if (NFCSTATUS_SUCCESS != status)
+ {
+ NXPLOG_NCIHAL_D("phNxpNciHal_DownloadPinTest - FAILED\n");
+ return status;
+ }
+
+ status = NFCSTATUS_FAILED;
+ len = (sizeof(download_pin_test_data2)/sizeof(download_pin_test_data2[0]));
+
+ for(cnt = 0; cnt < len; cnt++)
+ {
+ status = phNxpNciHal_performTest(&(download_pin_test_data2[cnt]));
+ if(status == NFCSTATUS_RESPONSE_TIMEOUT || status == NFCSTATUS_FAILED)
+ {
+ break;
+ }
+ }
+
+ if( status == NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_NCIHAL_D("phNxpNciHal_DownloadPinTest - SUCCESSS\n");
+ }
+ else
+ {
+ NXPLOG_NCIHAL_D("phNxpNciHal_DownloadPinTest - FAILED\n");
+ }
+
+ NXPLOG_NCIHAL_D("phNxpNciHal_DownloadPinTest - end\n");
+
+ return status;
+}
+/*******************************************************************************
+**
+** Function phNxpNciHal_AntennaSelfTest
+**
+** Description Test function to validate the Antenna's discrete
+** components connection.
+**
+** Returns NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED.
+**
+*******************************************************************************/
+NFCSTATUS phNxpNciHal_AntennaSelfTest(phAntenna_St_Resp_t * phAntenna_St_Resp )
+{
+ NFCSTATUS status = NFCSTATUS_FAILED;
+ NFCSTATUS antenna_st_status = NFCSTATUS_FAILED;
+ int len = 0;
+ int cnt = 0;
+
+ NXPLOG_NCIHAL_D("phNxpNciHal_AntennaSelfTest - start\n");
+ memcpy(&phAntenna_resp, phAntenna_St_Resp, sizeof(phAntenna_St_Resp_t));
+ len = (sizeof(antenna_self_test_data)/sizeof(antenna_self_test_data[0]));
+
+ for(cnt = 0; cnt < len; cnt++)
+ {
+ status = phNxpNciHal_performTest(&(antenna_self_test_data[cnt]));
+ if(status == NFCSTATUS_RESPONSE_TIMEOUT || status == NFCSTATUS_FAILED)
+ {
+ NXPLOG_NCIHAL_E("phNxpNciHal_AntennaSelfTest: commnad execution - FAILED\n");
+ break;
+ }
+ }
+
+ if(status == NFCSTATUS_SUCCESS)
+ {
+ if((gtxldo_status == NFCSTATUS_SUCCESS) && (gagc_value_status == NFCSTATUS_SUCCESS) &&
+ (gagc_nfcld_status == NFCSTATUS_SUCCESS) && (gagc_differential_status == NFCSTATUS_SUCCESS))
+ {
+ antenna_st_status = NFCSTATUS_SUCCESS;
+ NXPLOG_NCIHAL_D("phNxpNciHal_AntennaSelfTest - SUCESS\n");
+ }
+ else
+ {
+ NXPLOG_NCIHAL_D("phNxpNciHal_AntennaSelfTest - FAILED\n");
+ }
+ }
+ else
+ {
+ NXPLOG_NCIHAL_D("phNxpNciHal_AntennaSelfTest - FAILED\n");
+ }
+
+ NXPLOG_NCIHAL_D("phNxpNciHal_AntennaSelfTest - end\n");
+
+ return antenna_st_status;
+}
+
+#endif /*#ifdef NXP_HW_SELF_TEST*/
diff --git a/halimpl/pn54x/tml/phDal4Nfc_messageQueueLib.c b/halimpl/pn54x/tml/phDal4Nfc_messageQueueLib.c
new file mode 100644
index 0000000..d2ac339
--- /dev/null
+++ b/halimpl/pn54x/tml/phDal4Nfc_messageQueueLib.c
@@ -0,0 +1,255 @@
+/*
+ * 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(300000);
+ if (sem_destroy(&pQueue->nProcessSemaphore))
+ {
+ NXPLOG_TML_E("Failed to destroy semaphore (errno=0x%08x)", errno);
+ }
+ pthread_mutex_destroy (&pQueue->nCriticalSectionMutex);
+
+ free(pQueue);
+ }
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phDal4Nfc_msgctl
+**
+** Description Destroys message queue
+**
+** Parameters msqid - message queue handle
+** cmd, buf - ignored, included only for Linux queue API compatibility
+**
+** Returns 0, if successful
+** -1, if invalid handle is passed
+**
+*******************************************************************************/
+int phDal4Nfc_msgctl(intptr_t msqid, int cmd, void *buf)
+{
+ phDal4Nfc_message_queue_t * pQueue;
+ phDal4Nfc_message_queue_item_t * p;
+ UNUSED(cmd);
+ UNUSED(buf);
+ if (msqid == 0)
+ return -1;
+
+ pQueue = (phDal4Nfc_message_queue_t *) msqid;
+ pthread_mutex_lock(&pQueue->nCriticalSectionMutex);
+ if (pQueue->pItems != NULL)
+ {
+ p = pQueue->pItems;
+ while (p->pNext != NULL)
+ {
+ p = p->pNext;
+ }
+ while (p->pPrev != NULL)
+ {
+ p = p->pPrev;
+ free(p->pNext);
+ p->pNext = NULL;
+ }
+ free(p);
+ }
+ pQueue->pItems = NULL;
+ pthread_mutex_unlock(&pQueue->nCriticalSectionMutex);
+ pthread_mutex_destroy(&pQueue->nCriticalSectionMutex);
+ free(pQueue);
+
+ return 0;
+}
+
+/*******************************************************************************
+**
+** Function phDal4Nfc_msgsnd
+**
+** Description Sends a message to the queue. The message will be added at the end of
+** the queue as appropriate for FIFO policy
+**
+** Parameters msqid - message queue handle
+** msgp - message to be sent
+** msgsz - message size
+** msgflg - ignored
+**
+** Returns 0, if successful
+** -1, if invalid parameter passed or failed to allocate memory
+**
+*******************************************************************************/
+intptr_t phDal4Nfc_msgsnd(intptr_t msqid, phLibNfc_Message_t * msg, int msgflg)
+{
+ phDal4Nfc_message_queue_t * pQueue;
+ phDal4Nfc_message_queue_item_t * p;
+ phDal4Nfc_message_queue_item_t * pNew;
+ UNUSED(msgflg);
+ if ((msqid == 0) || (msg == NULL) )
+ return -1;
+
+
+ pQueue = (phDal4Nfc_message_queue_t *) msqid;
+ pNew = (phDal4Nfc_message_queue_item_t *) malloc(sizeof(phDal4Nfc_message_queue_item_t));
+ if (pNew == NULL)
+ return -1;
+ memset(pNew, 0, sizeof(phDal4Nfc_message_queue_item_t));
+ memcpy(&pNew->nMsg, msg, sizeof(phLibNfc_Message_t));
+ pthread_mutex_lock(&pQueue->nCriticalSectionMutex);
+
+ if (pQueue->pItems != NULL)
+ {
+ p = pQueue->pItems;
+ while (p->pNext != NULL)
+ {
+ p = p->pNext;
+ }
+ p->pNext = pNew;
+ pNew->pPrev = p;
+ }
+ else
+ {
+ pQueue->pItems = pNew;
+ }
+ pthread_mutex_unlock(&pQueue->nCriticalSectionMutex);
+
+ sem_post(&pQueue->nProcessSemaphore);
+
+ return 0;
+}
+
+/*******************************************************************************
+**
+** Function phDal4Nfc_msgrcv
+**
+** Description Gets the oldest message from the queue.
+** If the queue is empty the function waits (blocks on a mutex)
+** until a message is posted to the queue with phDal4Nfc_msgsnd.
+**
+** Parameters msqid - message queue handle
+** msgp - message to be received
+** msgsz - message size
+** msgtyp - ignored
+** msgflg - ignored
+**
+** Returns 0, if successful
+** -1, if invalid parameter passed
+**
+*******************************************************************************/
+int phDal4Nfc_msgrcv(intptr_t msqid, phLibNfc_Message_t * msg, long msgtyp, int msgflg)
+{
+ phDal4Nfc_message_queue_t * pQueue;
+ phDal4Nfc_message_queue_item_t * p;
+ UNUSED(msgflg);
+ UNUSED(msgtyp);
+ if ((msqid == 0) || (msg == NULL))
+ return -1;
+
+ pQueue = (phDal4Nfc_message_queue_t *) msqid;
+
+ sem_wait(&pQueue->nProcessSemaphore);
+
+ pthread_mutex_lock(&pQueue->nCriticalSectionMutex);
+
+ if (pQueue->pItems != NULL)
+ {
+ memcpy(msg, &(pQueue->pItems)->nMsg, sizeof(phLibNfc_Message_t));
+ p = pQueue->pItems->pNext;
+ free(pQueue->pItems);
+ pQueue->pItems = p;
+ }
+ pthread_mutex_unlock(&pQueue->nCriticalSectionMutex);
+
+ return 0;
+}
diff --git a/halimpl/pn54x/tml/phDal4Nfc_messageQueueLib.h b/halimpl/pn54x/tml/phDal4Nfc_messageQueueLib.h
new file mode 100644
index 0000000..6ebbc38
--- /dev/null
+++ b/halimpl/pn54x/tml/phDal4Nfc_messageQueueLib.h
@@ -0,0 +1,33 @@
+/*
+ * 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..26db61a
--- /dev/null
+++ b/halimpl/pn54x/tml/phOsalNfc_Timer.c
@@ -0,0 +1,469 @@
+/*
+ * 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..63312e5
--- /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..ec03a2f
--- /dev/null
+++ b/halimpl/pn54x/tml/phTmlNfc.c
@@ -0,0 +1,1059 @@
+/*
+ * 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>
+#if((ESE_NFC_POWER_MANAGEMENT == TRUE)&&(NFC_NXP_NOT_OPEN_INCLUDED == TRUE))
+#include <sys/types.h>
+long nfc_service_pid;
+#endif
+/*
+ * Duration of Timer to wait after sending an Nci packet
+ */
+#define PHTMLNFC_MAXTIME_RETRANSMIT (200U)
+#define MAX_WRITE_RETRY_COUNT 0x03
+/* Retry Count = Standby Recovery time of NFCC / Retransmission time + 1 */
+static uint8_t bCurrentRetryCount = (2000 / PHTMLNFC_MAXTIME_RETRANSMIT) + 1;
+
+
+/* Value to reset variables of TML */
+#define PH_TMLNFC_RESET_VALUE (0x00)
+
+/* Indicates a Initial or offset value */
+#define PH_TMLNFC_VALUE_ONE (0x01)
+
+/* Initialize Context structure pointer used to access context structure */
+phTmlNfc_Context_t *gpphTmlNfc_Context = NULL;
+extern phTmlNfc_i2cfragmentation_t fragmentation_enabled = I2C_FRAGMENATATION_DISABLED;
+/* Local Function prototypes */
+static NFCSTATUS phTmlNfc_StartThread(void);
+static void phTmlNfc_CleanUp(void);
+static void phTmlNfc_ReadDeferredCb(void *pParams);
+static void phTmlNfc_WriteDeferredCb(void *pParams);
+static void phTmlNfc_TmlThread(void *pParam);
+static void phTmlNfc_TmlWriterThread(void *pParam);
+static void phTmlNfc_ReTxTimerCb(uint32_t dwTimerId, void *pContext);
+static NFCSTATUS phTmlNfc_InitiateTimer(void);
+
+
+/* Function definitions */
+
+/*******************************************************************************
+**
+** Function phTmlNfc_Init
+**
+** Description Provides initialization of TML layer and hardware interface
+** Configures given hardware interface and sends handle to the caller
+**
+** Parameters pConfig - TML configuration details as provided by the upper layer
+**
+** Returns NFC status:
+** NFCSTATUS_SUCCESS - initialization successful
+** NFCSTATUS_INVALID_PARAMETER - at least one parameter is invalid
+** NFCSTATUS_FAILED - initialization failed
+** (for example, unable to open hardware interface)
+** NFCSTATUS_INVALID_DEVICE - device has not been opened or has been disconnected
+**
+*******************************************************************************/
+NFCSTATUS phTmlNfc_Init(pphTmlNfc_Config_t pConfig)
+{
+ NFCSTATUS wInitStatus = NFCSTATUS_SUCCESS;
+ NFCSTATUS setPidStatus = NFCSTATUS_SUCCESS;
+
+ /* Check if TML layer is already Initialized */
+ if (NULL != gpphTmlNfc_Context)
+ {
+ /* TML initialization is already completed */
+ wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_ALREADY_INITIALISED);
+ }
+ /* Validate Input parameters */
+ else if ((NULL == pConfig) ||
+ (PH_TMLNFC_RESET_VALUE == pConfig->dwGetMsgThreadId))
+ {
+ /*Parameters passed to TML init are wrong */
+ wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_INVALID_PARAMETER);
+ }
+ else
+ {
+ /* Allocate memory for TML context */
+ gpphTmlNfc_Context = malloc(sizeof(phTmlNfc_Context_t));
+
+ if (NULL == gpphTmlNfc_Context)
+ {
+ wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_FAILED);
+ }
+ else
+ {
+ /* Initialise all the internal TML variables */
+ memset(gpphTmlNfc_Context, PH_TMLNFC_RESET_VALUE, sizeof(phTmlNfc_Context_t));
+ /* Make sure that the thread runs once it is created */
+ gpphTmlNfc_Context->bThreadDone = 1;
+
+ /* Open the device file to which data is read/written */
+ wInitStatus = phTmlNfc_i2c_open_and_configure(pConfig, &(gpphTmlNfc_Context->pDevHandle));
+
+ if (NFCSTATUS_SUCCESS != wInitStatus)
+ {
+ wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_INVALID_DEVICE);
+ gpphTmlNfc_Context->pDevHandle = (void *) NFCSTATUS_INVALID_DEVICE;
+ }
+ else
+ {
+ gpphTmlNfc_Context->tReadInfo.bEnable = 0;
+ gpphTmlNfc_Context->tWriteInfo.bEnable = 0;
+ gpphTmlNfc_Context->tReadInfo.bThreadBusy = FALSE;
+ gpphTmlNfc_Context->tWriteInfo.bThreadBusy = FALSE;
+
+ if(0 != sem_init(&gpphTmlNfc_Context->rxSemaphore, 0, 0))
+ {
+ wInitStatus = NFCSTATUS_FAILED;
+ }
+ else if(0 != sem_init(&gpphTmlNfc_Context->txSemaphore, 0, 0))
+ {
+ wInitStatus = NFCSTATUS_FAILED;
+ }
+ else if(0 != sem_init(&gpphTmlNfc_Context->postMsgSemaphore, 0, 0))
+ {
+ wInitStatus = NFCSTATUS_FAILED;
+ }
+ else
+ {
+ sem_post(&gpphTmlNfc_Context->postMsgSemaphore);
+ /* Start TML thread (to handle write and read operations) */
+ if (NFCSTATUS_SUCCESS != phTmlNfc_StartThread())
+ {
+ wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_FAILED);
+ }
+ else
+ {
+ /* Create Timer used for Retransmission of NCI packets */
+ gpphTmlNfc_Context->dwTimerId = phOsalNfc_Timer_Create();
+ if (PH_OSALNFC_TIMER_ID_INVALID != gpphTmlNfc_Context->dwTimerId)
+ {
+ /* Store the Thread Identifier to which Message is to be posted */
+ gpphTmlNfc_Context->dwCallbackThreadId = pConfig->dwGetMsgThreadId;
+ /* Enable retransmission of Nci packet & set retry count to default */
+ gpphTmlNfc_Context->eConfig = phTmlNfc_e_DisableRetrans;
+ /** Retry Count = Standby Recovery time of NFCC / Retransmission time + 1 */
+ gpphTmlNfc_Context->bRetryCount = (2000 / PHTMLNFC_MAXTIME_RETRANSMIT) + 1;
+ gpphTmlNfc_Context->bWriteCbInvoked = FALSE;
+ }
+ else
+ {
+ wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_FAILED);
+ }
+ }
+ }
+ }
+ }
+ }
+ /* Clean up all the TML resources if any error */
+ if (NFCSTATUS_SUCCESS != wInitStatus)
+ {
+ /* Clear all handles and memory locations initialized during init */
+ phTmlNfc_CleanUp();
+ }
+#if(ESE_NFC_POWER_MANAGEMENT == TRUE)
+ else
+ {
+ nfc_service_pid = getpid();
+ setPidStatus = phTmlNfc_IoCtl(phTmlNfc_e_SetNfcServicePid);
+ if(setPidStatus == NFCSTATUS_SUCCESS)
+ {
+ NXPLOG_TML_D("nfc service set pid done");
+ }
+ else
+ {
+ NXPLOG_TML_D("nfc service set pid failed");
+ }
+ }
+#endif
+
+ return wInitStatus;
+}
+
+/*******************************************************************************
+**
+** Function phTmlNfc_ConfigNciPktReTx
+**
+** Description Provides Enable/Disable Retransmission of NCI packets
+** Needed in case of Timeout between Transmission and Reception of NCI packets
+** Retransmission can be enabled only if standby mode is enabled
+**
+** Parameters eConfig - values from phTmlNfc_ConfigRetrans_t
+** bRetryCount - Number of times Nci packets shall be retransmitted (default = 3)
+**
+** Returns None
+**
+*******************************************************************************/
+void phTmlNfc_ConfigNciPktReTx(phTmlNfc_ConfigRetrans_t eConfiguration, uint8_t bRetryCounter)
+{
+ /* Enable/Disable Retransmission */
+
+ gpphTmlNfc_Context->eConfig = eConfiguration;
+ if (phTmlNfc_e_EnableRetrans == eConfiguration)
+ {
+ /* Check whether Retry counter passed is valid */
+ if (0 != bRetryCounter)
+ {
+ gpphTmlNfc_Context->bRetryCount = bRetryCounter;
+ }
+ /* Set retry counter to its default value */
+ else
+ {
+ /** Retry Count = Standby Recovery time of NFCC / Retransmission time + 1 */
+ gpphTmlNfc_Context->bRetryCount = (2000 / PHTMLNFC_MAXTIME_RETRANSMIT) + 1;
+ }
+ }
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phTmlNfc_StartThread
+**
+** Description Initializes comport, reader and writer threads
+**
+** Parameters None
+**
+** Returns NFC status:
+** NFCSTATUS_SUCCESS - threads initialized successfully
+** NFCSTATUS_FAILED - initialization failed due to system error
+**
+*******************************************************************************/
+static NFCSTATUS phTmlNfc_StartThread(void)
+{
+ NFCSTATUS wStartStatus = NFCSTATUS_SUCCESS;
+ void *h_threadsEvent = 0x00;
+ uint32_t dwEvent;
+ int pthread_create_status = 0;
+
+ /* Create Reader and Writer threads */
+ pthread_create_status = pthread_create(&gpphTmlNfc_Context->readerThread,NULL,(void *)&phTmlNfc_TmlThread,
+ (void *)h_threadsEvent);
+ if(0 != pthread_create_status)
+ {
+ wStartStatus = NFCSTATUS_FAILED;
+ }
+ else
+ {
+ /*Start Writer Thread*/
+ pthread_create_status = pthread_create(&gpphTmlNfc_Context->writerThread,NULL,(void *)&phTmlNfc_TmlWriterThread,
+ (void *)h_threadsEvent);
+ if(0 != pthread_create_status)
+ {
+ wStartStatus = NFCSTATUS_FAILED;
+ }
+ }
+
+ return wStartStatus;
+}
+
+/*******************************************************************************
+**
+** Function phTmlNfc_ReTxTimerCb
+**
+** Description This is the timer callback function after timer expiration.
+**
+** Parameters dwThreadId - id of the thread posting message
+** pContext - context provided by upper layer
+**
+** Returns None
+**
+*******************************************************************************/
+static void phTmlNfc_ReTxTimerCb(uint32_t dwTimerId, void *pContext)
+{
+ if ((gpphTmlNfc_Context->dwTimerId == dwTimerId) &&
+ (NULL == pContext))
+ {
+ /* If Retry Count has reached its limit,Retransmit Nci
+ packet */
+ if (0 == bCurrentRetryCount)
+ {
+ /* Since the count has reached its limit,return from timer callback
+ Upper layer Timeout would have happened */
+ }
+ else
+ {
+ bCurrentRetryCount--;
+ gpphTmlNfc_Context->tWriteInfo.bThreadBusy = TRUE;
+ gpphTmlNfc_Context->tWriteInfo.bEnable = 1;
+ }
+ sem_post(&gpphTmlNfc_Context->txSemaphore);
+ }
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phTmlNfc_InitiateTimer
+**
+** Description Start a timer for Tx and Rx thread.
+**
+** Parameters void
+**
+** Returns NFC status
+**
+*******************************************************************************/
+static NFCSTATUS phTmlNfc_InitiateTimer(void)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+
+ /* Start Timer once Nci packet is sent */
+ wStatus = phOsalNfc_Timer_Start(gpphTmlNfc_Context->dwTimerId,
+ (uint32_t) PHTMLNFC_MAXTIME_RETRANSMIT,
+ phTmlNfc_ReTxTimerCb, NULL);
+
+ return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function phTmlNfc_TmlThread
+**
+** Description Read the data from the lower layer driver
+**
+** Parameters pParam - parameters for Writer thread function
+**
+** Returns None
+**
+*******************************************************************************/
+static void phTmlNfc_TmlThread(void *pParam)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+ int32_t dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE;
+ uint8_t temp[260];
+ /* Transaction info buffer to be passed to Callback Thread */
+ static phTmlNfc_TransactInfo_t tTransactionInfo;
+ /* Structure containing Tml callback function and parameters to be invoked
+ by the callback thread */
+ static phLibNfc_DeferredCall_t tDeferredInfo;
+ /* Initialize Message structure to post message onto Callback Thread */
+ static phLibNfc_Message_t tMsg;
+ UNUSED(pParam);
+ NXPLOG_TML_D("PN54X - Tml Reader Thread Started................\n");
+
+ /* Writer thread loop shall be running till shutdown is invoked */
+ while (gpphTmlNfc_Context->bThreadDone)
+ {
+ /* If Tml write is requested */
+ /* Set the variable to success initially */
+ wStatus = NFCSTATUS_SUCCESS;
+ sem_wait(&gpphTmlNfc_Context->rxSemaphore);
+
+ /* If Tml read is requested */
+ if (1 == gpphTmlNfc_Context->tReadInfo.bEnable)
+ {
+ NXPLOG_TML_D("PN54X - Read requested.....\n");
+ /* Set the variable to success initially */
+ wStatus = NFCSTATUS_SUCCESS;
+
+ /* Variable to fetch the actual number of bytes read */
+ dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE;
+
+ /* Read the data from the file onto the buffer */
+ if (NFCSTATUS_INVALID_DEVICE != (uintptr_t)gpphTmlNfc_Context->pDevHandle)
+ {
+ NXPLOG_TML_D("PN54X - Invoking I2C Read.....\n");
+ dwNoBytesWrRd = phTmlNfc_i2c_read(gpphTmlNfc_Context->pDevHandle, temp, 260);
+
+ if (-1 == dwNoBytesWrRd)
+ {
+ NXPLOG_TML_E("PN54X - Error in I2C Read.....\n");
+ sem_post(&gpphTmlNfc_Context->rxSemaphore);
+ }
+ else
+ {
+ memcpy(gpphTmlNfc_Context->tReadInfo.pBuffer, temp, dwNoBytesWrRd);
+
+ NXPLOG_TML_D("PN54X - I2C Read successful.....\n");
+ /* This has to be reset only after a successful read */
+ gpphTmlNfc_Context->tReadInfo.bEnable = 0;
+ if ((phTmlNfc_e_EnableRetrans == gpphTmlNfc_Context->eConfig) &&
+ (0x00 != (gpphTmlNfc_Context->tReadInfo.pBuffer[0] & 0xE0)))
+ {
+
+ NXPLOG_TML_D("PN54X - Retransmission timer stopped.....\n");
+ /* Stop Timer to prevent Retransmission */
+ uint32_t timerStatus = phOsalNfc_Timer_Stop(gpphTmlNfc_Context->dwTimerId);
+ if (NFCSTATUS_SUCCESS != timerStatus)
+ {
+ NXPLOG_TML_E("PN54X - timer stopped returned failure.....\n");
+ }
+ else
+ {
+ gpphTmlNfc_Context->bWriteCbInvoked = FALSE;
+ }
+ }
+ /* Update the actual number of bytes read including header */
+ gpphTmlNfc_Context->tReadInfo.wLength = (uint16_t) (dwNoBytesWrRd);
+ phNxpNciHal_print_packet("RECV", gpphTmlNfc_Context->tReadInfo.pBuffer,
+ gpphTmlNfc_Context->tReadInfo.wLength);
+
+ dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE;
+
+ /* Fill the Transaction info structure to be passed to Callback Function */
+ tTransactionInfo.wStatus = wStatus;
+ tTransactionInfo.pBuff = gpphTmlNfc_Context->tReadInfo.pBuffer;
+ /* Actual number of bytes read is filled in the structure */
+ tTransactionInfo.wLength = gpphTmlNfc_Context->tReadInfo.wLength;
+
+ /* Read operation completed successfully. Post a Message onto Callback Thread*/
+ /* Prepare the message to be posted on User thread */
+ tDeferredInfo.pCallback = &phTmlNfc_ReadDeferredCb;
+ tDeferredInfo.pParameter = &tTransactionInfo;
+ tMsg.eMsgType = PH_LIBNFC_DEFERREDCALL_MSG;
+ tMsg.pMsgData = &tDeferredInfo;
+ tMsg.Size = sizeof(tDeferredInfo);
+ NXPLOG_TML_D("PN54X - Posting read message.....\n");
+ phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &tMsg);
+
+ }
+ }
+ else
+ {
+ NXPLOG_TML_D("PN54X - NFCSTATUS_INVALID_DEVICE == gpphTmlNfc_Context->pDevHandle");
+ }
+ }
+ else
+ {
+ NXPLOG_TML_D("PN54X - read request NOT enabled");
+ usleep(10*1000);
+ }
+ }/* End of While loop */
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phTmlNfc_TmlWriterThread
+**
+** Description Writes the requested data onto the lower layer driver
+**
+** Parameters pParam - context provided by upper layer
+**
+** Returns None
+**
+*******************************************************************************/
+static void phTmlNfc_TmlWriterThread(void *pParam)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+ int32_t dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE;
+ /* Transaction info buffer to be passed to Callback Thread */
+ static phTmlNfc_TransactInfo_t tTransactionInfo;
+ /* Structure containing Tml callback function and parameters to be invoked
+ by the callback thread */
+ static phLibNfc_DeferredCall_t tDeferredInfo;
+ /* Initialize Message structure to post message onto Callback Thread */
+ static phLibNfc_Message_t tMsg;
+ /* In case of I2C Write Retry */
+ static uint16_t retry_cnt;
+ UNUSED(pParam);
+ NXPLOG_TML_D("PN54X - Tml Writer Thread Started................\n");
+
+ /* Writer thread loop shall be running till shutdown is invoked */
+ while (gpphTmlNfc_Context->bThreadDone)
+ {
+ NXPLOG_TML_D("PN54X - Tml Writer Thread Running................\n");
+ sem_wait(&gpphTmlNfc_Context->txSemaphore);
+ /* If Tml write is requested */
+ if (1 == gpphTmlNfc_Context->tWriteInfo.bEnable)
+ {
+ NXPLOG_TML_D("PN54X - Write requested.....\n");
+ /* Set the variable to success initially */
+ wStatus = NFCSTATUS_SUCCESS;
+ if (NFCSTATUS_INVALID_DEVICE != (uintptr_t)gpphTmlNfc_Context->pDevHandle)
+ {
+ retry:
+
+ gpphTmlNfc_Context->tWriteInfo.bEnable = 0;
+ /* Variable to fetch the actual number of bytes written */
+ dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE;
+ /* Write the data in the buffer onto the file */
+ NXPLOG_TML_D("PN54X - Invoking I2C Write.....\n");
+ dwNoBytesWrRd = phTmlNfc_i2c_write(gpphTmlNfc_Context->pDevHandle,
+ gpphTmlNfc_Context->tWriteInfo.pBuffer,
+ gpphTmlNfc_Context->tWriteInfo.wLength
+ );
+
+ /* Try I2C Write Five Times, if it fails : Raju */
+ if (-1 == dwNoBytesWrRd)
+ {
+ if (getDownloadFlag() == TRUE)
+ {
+ if (retry_cnt++ < MAX_WRITE_RETRY_COUNT)
+ {
+ NXPLOG_NCIHAL_E(
+ "PN54X - Error in I2C Write - Retry 0x%x", retry_cnt);
+ goto retry;
+ }
+ }
+ NXPLOG_TML_E("PN54X - Error in I2C Write.....\n");
+ wStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_FAILED);
+ }
+ else
+ {
+ phNxpNciHal_print_packet("SEND", gpphTmlNfc_Context->tWriteInfo.pBuffer,
+ gpphTmlNfc_Context->tWriteInfo.wLength);
+ }
+ retry_cnt = 0;
+ if (NFCSTATUS_SUCCESS == wStatus)
+ {
+ NXPLOG_TML_D("PN54X - I2C Write successful.....\n");
+ dwNoBytesWrRd = PH_TMLNFC_VALUE_ONE;
+ }
+ /* Fill the Transaction info structure to be passed to Callback Function */
+ tTransactionInfo.wStatus = wStatus;
+ tTransactionInfo.pBuff = gpphTmlNfc_Context->tWriteInfo.pBuffer;
+ /* Actual number of bytes written is filled in the structure */
+ tTransactionInfo.wLength = (uint16_t) dwNoBytesWrRd;
+
+ /* Prepare the message to be posted on the User thread */
+ tDeferredInfo.pCallback = &phTmlNfc_WriteDeferredCb;
+ tDeferredInfo.pParameter = &tTransactionInfo;
+ /* Write operation completed successfully. Post a Message onto Callback Thread*/
+ tMsg.eMsgType = PH_LIBNFC_DEFERREDCALL_MSG;
+ tMsg.pMsgData = &tDeferredInfo;
+ tMsg.Size = sizeof(tDeferredInfo);
+
+ /* Check whether Retransmission needs to be started,
+ * If yes, Post message only if
+ * case 1. Message is not posted &&
+ * case 11. Write status is success ||
+ * case 12. Last retry of write is also failure
+ */
+ if ((phTmlNfc_e_EnableRetrans == gpphTmlNfc_Context->eConfig) &&
+ (0x00 != (gpphTmlNfc_Context->tWriteInfo.pBuffer[0] & 0xE0)))
+ {
+ if (FALSE == gpphTmlNfc_Context->bWriteCbInvoked)
+ {
+ if ((NFCSTATUS_SUCCESS == wStatus) ||
+ (bCurrentRetryCount == 0))
+ {
+ NXPLOG_TML_D("PN54X - Posting Write message.....\n");
+ phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
+ &tMsg);
+ gpphTmlNfc_Context->bWriteCbInvoked = TRUE;
+ }
+ }
+ }
+ else
+ {
+ NXPLOG_TML_D("PN54X - Posting Fresh Write message.....\n");
+ phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &tMsg);
+ }
+ }
+ else
+ {
+ NXPLOG_TML_D("PN54X - NFCSTATUS_INVALID_DEVICE != gpphTmlNfc_Context->pDevHandle");
+ }
+
+ /* If Data packet is sent, then NO retransmission */
+ if ((phTmlNfc_e_EnableRetrans == gpphTmlNfc_Context->eConfig) &&
+ (0x00 != (gpphTmlNfc_Context->tWriteInfo.pBuffer[0] & 0xE0)))
+ {
+ NXPLOG_TML_D("PN54X - Starting timer for Retransmission case");
+ wStatus = phTmlNfc_InitiateTimer();
+ if (NFCSTATUS_SUCCESS != wStatus)
+ {
+ /* Reset Variables used for Retransmission */
+ NXPLOG_TML_D("PN54X - Retransmission timer initiate failed");
+ gpphTmlNfc_Context->tWriteInfo.bEnable = 0;
+ bCurrentRetryCount = 0;
+ }
+ }
+ }
+ else
+ {
+ NXPLOG_TML_D("PN54X - Write request NOT enabled");
+ usleep(10000);
+ }
+
+ }/* End of While loop */
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phTmlNfc_CleanUp
+**
+** Description Clears all handles opened during TML initialization
+**
+** Parameters None
+**
+** Returns None
+**
+*******************************************************************************/
+static void phTmlNfc_CleanUp(void)
+{
+ NFCSTATUS wRetval = NFCSTATUS_SUCCESS;
+
+ if (NULL != gpphTmlNfc_Context->pDevHandle)
+ {
+ (void) phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle, 0);
+ gpphTmlNfc_Context->bThreadDone = 0;
+ }
+ sem_destroy(&gpphTmlNfc_Context->rxSemaphore);
+ sem_destroy(&gpphTmlNfc_Context->txSemaphore);
+ sem_destroy(&gpphTmlNfc_Context->postMsgSemaphore);
+ phTmlNfc_i2c_close(gpphTmlNfc_Context->pDevHandle);
+ gpphTmlNfc_Context->pDevHandle = NULL;
+ /* Clear memory allocated for storing Context variables */
+ free((void *) gpphTmlNfc_Context);
+ /* Set the pointer to NULL to indicate De-Initialization */
+ gpphTmlNfc_Context = NULL;
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phTmlNfc_Shutdown
+**
+** Description Uninitializes TML layer and hardware interface
+**
+** Parameters None
+**
+** Returns NFC status:
+** NFCSTATUS_SUCCESS - TML configuration released successfully
+** NFCSTATUS_INVALID_PARAMETER - at least one parameter is invalid
+** NFCSTATUS_FAILED - un-initialization failed (example: unable to close interface)
+**
+*******************************************************************************/
+NFCSTATUS phTmlNfc_Shutdown(void)
+{
+ NFCSTATUS wShutdownStatus = NFCSTATUS_SUCCESS;
+
+ /* Check whether TML is Initialized */
+ if (NULL != gpphTmlNfc_Context)
+ {
+ /* Reset thread variable to terminate the thread */
+ gpphTmlNfc_Context->bThreadDone = 0;
+ usleep(1000);
+ /* Clear All the resources allocated during initialization */
+ sem_post(&gpphTmlNfc_Context->rxSemaphore);
+ usleep(1000);
+ sem_post(&gpphTmlNfc_Context->txSemaphore);
+ usleep(1000);
+ sem_post(&gpphTmlNfc_Context->postMsgSemaphore);
+ usleep(1000);
+ sem_post(&gpphTmlNfc_Context->postMsgSemaphore);
+ usleep(1000);
+ if (0 != pthread_join(gpphTmlNfc_Context->readerThread, (void**)NULL))
+ {
+ NXPLOG_TML_E ("Fail to kill reader thread!");
+ }
+ if (0 != pthread_join(gpphTmlNfc_Context->writerThread, (void**)NULL))
+ {
+ NXPLOG_TML_E ("Fail to kill writer thread!");
+ }
+ NXPLOG_TML_D ("bThreadDone == 0");
+
+ phTmlNfc_CleanUp();
+ }
+ else
+ {
+ wShutdownStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_NOT_INITIALISED);
+ }
+
+ return wShutdownStatus;
+}
+
+/*******************************************************************************
+**
+** Function phTmlNfc_Write
+**
+** Description Asynchronously writes given data block to hardware interface/driver
+** Enables writer thread if there are no write requests pending
+** Returns successfully once writer thread completes write operation
+** Notifies upper layer using callback mechanism
+** NOTE:
+** * it is important to post a message with id PH_TMLNFC_WRITE_MESSAGE
+** to IntegrationThread after data has been written to PN54X
+** * if CRC needs to be computed, then input buffer should be capable to store
+** two more bytes apart from length of packet
+**
+** Parameters pBuffer - data to be sent
+** wLength - length of data buffer
+** pTmlWriteComplete - pointer to the function to be invoked upon completion
+** pContext - context provided by upper layer
+**
+** Returns NFC status:
+** NFCSTATUS_PENDING - command is yet to be processed
+** NFCSTATUS_INVALID_PARAMETER - at least one parameter is invalid
+** NFCSTATUS_BUSY - write request is already in progress
+**
+*******************************************************************************/
+NFCSTATUS phTmlNfc_Write(uint8_t *pBuffer, uint16_t wLength, pphTmlNfc_TransactCompletionCb_t pTmlWriteComplete, void *pContext)
+{
+ NFCSTATUS wWriteStatus;
+
+ /* Check whether TML is Initialized */
+
+ if (NULL != gpphTmlNfc_Context)
+ {
+ if ((NULL != gpphTmlNfc_Context->pDevHandle) && (NULL != pBuffer) &&
+ (PH_TMLNFC_RESET_VALUE != wLength) && (NULL != pTmlWriteComplete))
+ {
+ if (!gpphTmlNfc_Context->tWriteInfo.bThreadBusy)
+ {
+ /* Setting the flag marks beginning of a Write Operation */
+ gpphTmlNfc_Context->tWriteInfo.bThreadBusy = TRUE;
+ /* Copy the buffer, length and Callback function,
+ This shall be utilized while invoking the Callback function in thread */
+ gpphTmlNfc_Context->tWriteInfo.pBuffer = pBuffer;
+ gpphTmlNfc_Context->tWriteInfo.wLength = wLength;
+ gpphTmlNfc_Context->tWriteInfo.pThread_Callback = pTmlWriteComplete;
+ gpphTmlNfc_Context->tWriteInfo.pContext = pContext;
+
+ wWriteStatus = NFCSTATUS_PENDING;
+ //FIXME: If retry is going on. Stop the retry thread/timer
+ if (phTmlNfc_e_EnableRetrans == gpphTmlNfc_Context->eConfig)
+ {
+ /* Set retry count to default value */
+ //FIXME: If the timer expired there, and meanwhile we have created
+ // a new request. The expired timer will think that retry is still
+ // ongoing.
+ bCurrentRetryCount = gpphTmlNfc_Context->bRetryCount;
+ gpphTmlNfc_Context->bWriteCbInvoked = FALSE;
+ }
+ /* Set event to invoke Writer Thread */
+ gpphTmlNfc_Context->tWriteInfo.bEnable = 1;
+ sem_post(&gpphTmlNfc_Context->txSemaphore);
+ }
+ else
+ {
+ wWriteStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_BUSY);
+ }
+ }
+ else
+ {
+ wWriteStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_INVALID_PARAMETER);
+ }
+ }
+ else
+ {
+ wWriteStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_NOT_INITIALISED);
+ }
+
+ return wWriteStatus;
+}
+
+/*******************************************************************************
+**
+** Function phTmlNfc_Read
+**
+** Description Asynchronously reads data from the driver
+** Number of bytes to be read and buffer are passed by upper layer
+** Enables reader thread if there are no read requests pending
+** Returns successfully once read operation is completed
+** Notifies upper layer using callback mechanism
+**
+** Parameters pBuffer - location to send read data to the upper layer via callback
+** wLength - length of read data buffer passed by upper layer
+** pTmlReadComplete - pointer to the function to be invoked upon completion of read operation
+** pContext - context provided by upper layer
+**
+** Returns NFC status:
+** NFCSTATUS_PENDING - command is yet to be processed
+** NFCSTATUS_INVALID_PARAMETER - at least one parameter is invalid
+** NFCSTATUS_BUSY - read request is already in progress
+**
+*******************************************************************************/
+NFCSTATUS phTmlNfc_Read(uint8_t *pBuffer, uint16_t wLength, pphTmlNfc_TransactCompletionCb_t pTmlReadComplete, void *pContext)
+{
+ NFCSTATUS wReadStatus;
+
+ /* Check whether TML is Initialized */
+ if (NULL != gpphTmlNfc_Context)
+ {
+ if ((gpphTmlNfc_Context->pDevHandle != NULL) && (NULL != pBuffer) &&
+ (PH_TMLNFC_RESET_VALUE != wLength) && (NULL != pTmlReadComplete))
+ {
+ if (!gpphTmlNfc_Context->tReadInfo.bThreadBusy)
+ {
+ /* Setting the flag marks beginning of a Read Operation */
+ gpphTmlNfc_Context->tReadInfo.bThreadBusy = TRUE;
+ /* Copy the buffer, length and Callback function,
+ This shall be utilized while invoking the Callback function in thread */
+ gpphTmlNfc_Context->tReadInfo.pBuffer = pBuffer;
+ gpphTmlNfc_Context->tReadInfo.wLength = wLength;
+ gpphTmlNfc_Context->tReadInfo.pThread_Callback = pTmlReadComplete;
+ gpphTmlNfc_Context->tReadInfo.pContext = pContext;
+ wReadStatus = NFCSTATUS_PENDING;
+
+ /* Set event to invoke Reader Thread */
+ gpphTmlNfc_Context->tReadInfo.bEnable = 1;
+ sem_post(&gpphTmlNfc_Context->rxSemaphore);
+ }
+ else
+ {
+ wReadStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_BUSY);
+ }
+ }
+ else
+ {
+ wReadStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_INVALID_PARAMETER);
+ }
+ }
+ else
+ {
+ wReadStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_NOT_INITIALISED);
+ }
+
+ return wReadStatus;
+}
+
+/*******************************************************************************
+**
+** Function phTmlNfc_ReadAbort
+**
+** Description Aborts pending read request (if any)
+**
+** Parameters None
+**
+** Returns NFC status:
+** NFCSTATUS_SUCCESS - ongoing read operation aborted
+** NFCSTATUS_INVALID_PARAMETER - at least one parameter is invalid
+** NFCSTATUS_NOT_INITIALIZED - TML layer is not initialized
+** NFCSTATUS_BOARD_COMMUNICATION_ERROR - unable to cancel read operation
+**
+*******************************************************************************/
+NFCSTATUS phTmlNfc_ReadAbort(void)
+{
+ NFCSTATUS wStatus = NFCSTATUS_INVALID_PARAMETER;
+ gpphTmlNfc_Context->tReadInfo.bEnable = 0;
+
+ /*Reset the flag to accept another Read Request */
+ gpphTmlNfc_Context->tReadInfo.bThreadBusy=FALSE;
+ wStatus = NFCSTATUS_SUCCESS;
+
+ return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function phTmlNfc_WriteAbort
+**
+** Description Aborts pending write request (if any)
+**
+** Parameters None
+**
+** Returns NFC status:
+** NFCSTATUS_SUCCESS - ongoing write operation aborted
+** NFCSTATUS_INVALID_PARAMETER - at least one parameter is invalid
+** NFCSTATUS_NOT_INITIALIZED - TML layer is not initialized
+** NFCSTATUS_BOARD_COMMUNICATION_ERROR - unable to cancel write operation
+**
+*******************************************************************************/
+NFCSTATUS phTmlNfc_WriteAbort(void)
+{
+ NFCSTATUS wStatus = NFCSTATUS_INVALID_PARAMETER;
+
+ gpphTmlNfc_Context->tWriteInfo.bEnable = 0;
+ /* Stop if any retransmission is in progress */
+ bCurrentRetryCount = 0;
+
+ /* Reset the flag to accept another Write Request */
+ gpphTmlNfc_Context->tWriteInfo.bThreadBusy=FALSE;
+ wStatus = NFCSTATUS_SUCCESS;
+
+ return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function phTmlNfc_IoCtl
+**
+** Description Resets device when insisted by upper layer
+** Number of bytes to be read and buffer are passed by upper layer
+** Enables reader thread if there are no read requests pending
+** Returns successfully once read operation is completed
+** Notifies upper layer using callback mechanism
+**
+** Parameters eControlCode - control code for a specific operation
+**
+** Returns NFC status:
+** NFCSTATUS_SUCCESS - ioctl command completed successfully
+** NFCSTATUS_FAILED - ioctl command request failed
+**
+*******************************************************************************/
+NFCSTATUS phTmlNfc_IoCtl(phTmlNfc_ControlCode_t eControlCode)
+{
+ NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+
+ if (NULL == gpphTmlNfc_Context)
+ {
+ wStatus = NFCSTATUS_FAILED;
+ }
+ else
+ {
+ switch (eControlCode)
+ {
+ case phTmlNfc_e_ResetDevice:
+ {
+ /*Reset PN54X*/
+ phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle, 1);
+ usleep(100 * 1000);
+ phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle, 0);
+ usleep(100 * 1000);
+ phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle, 1);
+ break;
+ }
+ case phTmlNfc_e_EnableNormalMode:
+ {
+ /*Reset PN54X*/
+ phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle, 0);
+ usleep(10 * 1000);
+ phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle, 1);
+ usleep(100 * 1000);
+ break;
+ }
+ case phTmlNfc_e_EnableDownloadMode:
+ {
+ phTmlNfc_ConfigNciPktReTx(phTmlNfc_e_DisableRetrans, 0);
+ (void)phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle,2);
+ usleep(100 * 1000);
+ break;
+ }
+#if(ESE_NFC_POWER_MANAGEMENT == TRUE)
+ case phTmlNfc_e_SetNfcServicePid:
+ {
+ wStatus = phTmlNfc_set_pid(gpphTmlNfc_Context->pDevHandle, nfc_service_pid);
+ break;
+ }
+ case phTmlNfc_e_GetP61PwrMode:
+ {
+ wStatus = phTmlNfc_i2c_get_p61_power_state(gpphTmlNfc_Context->pDevHandle);
+ break;
+ }
+ case phTmlNfc_e_SetP61WiredMode:
+ {
+ wStatus = phTmlNfc_i2c_set_p61_power_state(gpphTmlNfc_Context->pDevHandle, 1);
+ break;
+ }
+ case phTmlNfc_e_SetP61IdleMode:
+ {
+ wStatus = phTmlNfc_i2c_set_p61_power_state(gpphTmlNfc_Context->pDevHandle, 0);
+ break;
+ }
+#endif
+ default:
+ {
+ wStatus = NFCSTATUS_INVALID_PARAMETER;
+ break;
+ }
+ }
+ }
+
+ return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function phTmlNfc_DeferredCall
+**
+** Description Posts message on upper layer thread
+** upon successful read or write operation
+**
+** Parameters dwThreadId - id of the thread posting message
+** ptWorkerMsg - message to be posted
+**
+** Returns None
+**
+*******************************************************************************/
+void phTmlNfc_DeferredCall(uintptr_t dwThreadId, phLibNfc_Message_t *ptWorkerMsg)
+{
+ intptr_t bPostStatus;
+ UNUSED(dwThreadId);
+ /* Post message on the user thread to invoke the callback function */
+ sem_wait(&gpphTmlNfc_Context->postMsgSemaphore);
+ bPostStatus = phDal4Nfc_msgsnd(gpphTmlNfc_Context->dwCallbackThreadId,
+ ptWorkerMsg,
+ 0
+ );
+ sem_post(&gpphTmlNfc_Context->postMsgSemaphore);
+}
+
+/*******************************************************************************
+**
+** Function phTmlNfc_ReadDeferredCb
+**
+** Description Read thread call back function
+**
+** Parameters pParams - context provided by upper layer
+**
+** Returns None
+**
+*******************************************************************************/
+static void phTmlNfc_ReadDeferredCb(void *pParams)
+{
+ /* Transaction info buffer to be passed to Callback Function */
+ phTmlNfc_TransactInfo_t *pTransactionInfo = (phTmlNfc_TransactInfo_t *) pParams;
+
+ /* Reset the flag to accept another Read Request */
+ gpphTmlNfc_Context->tReadInfo.bThreadBusy = FALSE;
+ gpphTmlNfc_Context->tReadInfo.pThread_Callback(gpphTmlNfc_Context->tReadInfo.pContext,
+ pTransactionInfo);
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phTmlNfc_WriteDeferredCb
+**
+** Description Write thread call back function
+**
+** Parameters pParams - context provided by upper layer
+**
+** Returns None
+**
+*******************************************************************************/
+static void phTmlNfc_WriteDeferredCb(void *pParams)
+{
+ /* Transaction info buffer to be passed to Callback Function */
+ phTmlNfc_TransactInfo_t *pTransactionInfo = (phTmlNfc_TransactInfo_t *) pParams;
+
+ /* Reset the flag to accept another Write Request */
+ gpphTmlNfc_Context->tWriteInfo.bThreadBusy = FALSE;
+ gpphTmlNfc_Context->tWriteInfo.pThread_Callback(gpphTmlNfc_Context->tWriteInfo.pContext,
+ pTransactionInfo);
+
+ return;
+}
+
+void phTmlNfc_set_fragmentation_enabled(phTmlNfc_i2cfragmentation_t result)
+{
+ fragmentation_enabled = result;
+}
+
+phTmlNfc_i2cfragmentation_t phTmlNfc_get_fragmentation_enabled()
+{
+ return fragmentation_enabled;
+}
diff --git a/halimpl/pn54x/tml/phTmlNfc.h b/halimpl/pn54x/tml/phTmlNfc.h
new file mode 100644
index 0000000..2d87cb0
--- /dev/null
+++ b/halimpl/pn54x/tml/phTmlNfc.h
@@ -0,0 +1,215 @@
+/*
+ * 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 */
+#if(ESE_NFC_POWER_MANAGEMENT == TRUE)
+ ,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*/
+#endif
+} phTmlNfc_ControlCode_t ; /* Control code for IOCTL call */
+
+/*
+ * Enable / Disable Re-Transmission of Packets
+ *
+ * phTmlNfc_ConfigNciPktReTx
+ */
+typedef enum
+{
+ phTmlNfc_e_EnableRetrans = 0x00, /*Enable retransmission of Nci packet */
+ phTmlNfc_e_DisableRetrans = 0x01 /*Disable retransmission of Nci packet */
+} phTmlNfc_ConfigRetrans_t ; /* Configuration for Retransmission */
+
+/*
+ * Structure containing details related to read and write operations
+ *
+ */
+typedef struct phTmlNfc_ReadWriteInfo
+{
+ volatile uint8_t bEnable; /*This flag shall decide whether to perform Write/Read operation */
+ uint8_t bThreadBusy; /*Flag to indicate thread is busy on respective operation */
+ /* Transaction completion Callback function */
+ pphTmlNfc_TransactCompletionCb_t pThread_Callback;
+ void *pContext; /*Context passed while invocation of operation */
+ uint8_t *pBuffer; /*Buffer passed while invocation of operation */
+ uint16_t wLength; /*Length of data read/written */
+ NFCSTATUS wWorkStatus; /*Status of the transaction performed */
+} phTmlNfc_ReadWriteInfo_t;
+
+/*
+ *Base Context Structure containing members required for entire session
+ */
+typedef struct phTmlNfc_Context
+{
+ pthread_t readerThread; /*Handle to the thread which handles write and read operations */
+ pthread_t writerThread;
+ volatile uint8_t bThreadDone; /*Flag to decide whether to run or abort the thread */
+ phTmlNfc_ConfigRetrans_t eConfig; /*Retransmission of Nci Packet during timeout */
+ uint8_t bRetryCount; /*Number of times retransmission shall happen */
+ uint8_t bWriteCbInvoked; /* Indicates whether write callback is invoked during retransmission */
+ uint32_t dwTimerId; /* Timer used to retransmit nci packet */
+ phTmlNfc_ReadWriteInfo_t tReadInfo; /*Pointer to Reader Thread Structure */
+ phTmlNfc_ReadWriteInfo_t tWriteInfo; /*Pointer to Writer Thread Structure */
+ void *pDevHandle; /* Pointer to Device Handle */
+ uintptr_t dwCallbackThreadId; /* Thread ID to which message to be posted */
+ uint8_t bEnableCrc; /*Flag to validate/not CRC for input buffer */
+ sem_t rxSemaphore;
+ sem_t txSemaphore; /* Lock/Aquire txRx Semaphore */
+ sem_t postMsgSemaphore; /* Semaphore to post message atomically by Reader & writer thread */
+} phTmlNfc_Context_t;
+
+/*
+ * TML Configuration exposed to upper layer.
+ */
+typedef struct phTmlNfc_Config
+{
+ /* Port name connected to PN54X
+ *
+ * Platform specific canonical device name to which PN54X is connected.
+ *
+ * e.g. On Linux based systems this would be /dev/PN54X
+ */
+ int8_t *pDevName;
+ /* Callback Thread ID
+ *
+ * This is the thread ID on which the Reader & Writer thread posts message. */
+ uintptr_t dwGetMsgThreadId;
+ /* Communication speed between DH and PN54X
+ *
+ * This is the baudrate of the bus for communication between DH and PN54X */
+ uint32_t dwBaudRate;
+} phTmlNfc_Config_t,*pphTmlNfc_Config_t; /* pointer to phTmlNfc_Config_t */
+
+/*
+ * TML Deferred Callback structure used to invoke Upper layer Callback function.
+ */
+typedef struct {
+ pphTmlNfc_DeferFuncPointer_t pDef_call; /*Deferred callback function to be invoked */
+ /* Source identifier
+ *
+ * Identifier of the source which posted the message
+ */
+ uint32_t dwMsgPostedThread;
+ /** Actual Message
+ *
+ * This is passed as a parameter passed to the deferred callback function pDef_call. */
+ void* pParams;
+} phTmlNfc_DeferMsg_t; /* DeferMsg structure passed to User Thread */
+
+typedef enum
+{
+ I2C_FRAGMENATATION_DISABLED, /*i2c fragmentation_disabled */
+ I2C_FRAGMENTATION_ENABLED /*i2c_fragmentation_enabled */
+} phTmlNfc_i2cfragmentation_t;
+/* Function declarations */
+NFCSTATUS phTmlNfc_Init(pphTmlNfc_Config_t pConfig);
+NFCSTATUS phTmlNfc_Shutdown(void);
+NFCSTATUS phTmlNfc_Write(uint8_t *pBuffer, uint16_t wLength, pphTmlNfc_TransactCompletionCb_t pTmlWriteComplete, void *pContext);
+NFCSTATUS phTmlNfc_Read(uint8_t *pBuffer, uint16_t wLength, pphTmlNfc_TransactCompletionCb_t pTmlReadComplete, void *pContext);
+NFCSTATUS phTmlNfc_WriteAbort(void);
+NFCSTATUS phTmlNfc_ReadAbort(void);
+NFCSTATUS phTmlNfc_IoCtl(phTmlNfc_ControlCode_t eControlCode);
+void phTmlNfc_DeferredCall(uintptr_t dwThreadId, phLibNfc_Message_t *ptWorkerMsg);
+void phTmlNfc_ConfigNciPktReTx( phTmlNfc_ConfigRetrans_t eConfig, uint8_t bRetryCount);
+void phTmlNfc_set_fragmentation_enabled(phTmlNfc_i2cfragmentation_t enable);
+phTmlNfc_i2cfragmentation_t phTmlNfc_get_fragmentation_enabled();
+#endif /* PHTMLNFC_H */
diff --git a/halimpl/pn54x/tml/phTmlNfc_i2c.c b/halimpl/pn54x/tml/phTmlNfc_i2c.c
new file mode 100644
index 0000000..e2cc921
--- /dev/null
+++ b/halimpl/pn54x/tml/phTmlNfc_i2c.c
@@ -0,0 +1,467 @@
+/*
+ * 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>
+
+#define CRC_LEN 2
+#define NORMAL_MODE_HEADER_LEN 3
+#define FW_DNLD_HEADER_LEN 2
+#define FW_DNLD_LEN_OFFSET 1
+#define NORMAL_MODE_LEN_OFFSET 2
+#define FRAGMENTSIZE_MAX PHNFC_I2C_FRAGMENT_SIZE
+static bool_t bFwDnldFlag = FALSE;
+
+/*******************************************************************************
+**
+** Function phTmlNfc_i2c_close
+**
+** Description Closes PN54X device
+**
+** Parameters pDevHandle - device handle
+**
+** Returns None
+**
+*******************************************************************************/
+void phTmlNfc_i2c_close(void *pDevHandle)
+{
+ if (NULL != pDevHandle)
+ {
+ close((intptr_t)pDevHandle);
+ }
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phTmlNfc_i2c_open_and_configure
+**
+** Description Open and configure PN54X device
+**
+** Parameters pConfig - hardware information
+** pLinkHandle - device handle
+**
+** Returns NFC status:
+** NFCSTATUS_SUCCESS - open_and_configure operation success
+** NFCSTATUS_INVALID_DEVICE - device open operation failure
+**
+*******************************************************************************/
+NFCSTATUS phTmlNfc_i2c_open_and_configure(pphTmlNfc_Config_t pConfig, void ** pLinkHandle)
+{
+ int nHandle;
+
+
+ NXPLOG_TML_D("Opening port=%s\n", pConfig->pDevName);
+ /* open port */
+ nHandle = open((char const *)pConfig->pDevName, O_RDWR);
+ if (nHandle < 0)
+ {
+ NXPLOG_TML_E("_i2c_open() Failed: retval %x",nHandle);
+ *pLinkHandle = NULL;
+ return NFCSTATUS_INVALID_DEVICE;
+ }
+
+ *pLinkHandle = (void*) ((intptr_t)nHandle);
+
+ /*Reset PN54X*/
+ phTmlNfc_i2c_reset((void *)((intptr_t)nHandle), 1);
+ usleep(100 * 1000);
+ phTmlNfc_i2c_reset((void *)((intptr_t)nHandle), 0);
+ usleep(100 * 1000);
+ phTmlNfc_i2c_reset((void *)((intptr_t)nHandle), 1);
+
+ return NFCSTATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function phTmlNfc_i2c_read
+**
+** Description Reads requested number of bytes from PN54X device into given buffer
+**
+** Parameters pDevHandle - valid device handle
+** pBuffer - buffer for read data
+** nNbBytesToRead - number of bytes requested to be read
+**
+** Returns numRead - number of successfully read bytes
+** -1 - read operation failure
+**
+*******************************************************************************/
+int phTmlNfc_i2c_read(void *pDevHandle, uint8_t * pBuffer, int nNbBytesToRead)
+{
+ int ret_Read;
+ int ret_Select;
+ int numRead = 0;
+ struct timeval tv;
+ fd_set rfds;
+ uint16_t totalBtyesToRead = 0;
+
+ int i;
+ UNUSED(nNbBytesToRead);
+ if (NULL == pDevHandle)
+ {
+ return -1;
+ }
+
+ if (FALSE == bFwDnldFlag)
+ {
+ totalBtyesToRead = NORMAL_MODE_HEADER_LEN;
+ }
+ else
+ {
+ totalBtyesToRead = FW_DNLD_HEADER_LEN;
+ }
+
+ /* Read with 2 second timeout, so that the read thread can be aborted
+ when the PN54X does not respond and we need to switch to FW download
+ mode. This should be done via a control socket instead. */
+ FD_ZERO(&rfds);
+ FD_SET((intptr_t) pDevHandle, &rfds);
+ tv.tv_sec = 2;
+ tv.tv_usec = 1;
+
+ ret_Select = select((int)((intptr_t)pDevHandle + (int)1), &rfds, NULL, NULL, &tv);
+ if (ret_Select < 0)
+ {
+ NXPLOG_TML_E("i2c select() errno : %x",errno);
+ return -1;
+ }
+ else if (ret_Select == 0)
+ {
+ NXPLOG_TML_E("i2c select() Timeout");
+ return -1;
+ }
+ else
+ {
+ ret_Read = read((intptr_t)pDevHandle, pBuffer, totalBtyesToRead - numRead);
+ if (ret_Read > 0)
+ {
+ numRead += ret_Read;
+ }
+ else if (ret_Read == 0)
+ {
+ NXPLOG_TML_E("_i2c_read() [hdr]EOF");
+ return -1;
+ }
+ else
+ {
+ NXPLOG_TML_E("_i2c_read() [hdr] errno : %x",errno);
+ return -1;
+ }
+
+ if (FALSE == bFwDnldFlag)
+ {
+ totalBtyesToRead = NORMAL_MODE_HEADER_LEN;
+ }
+ else
+ {
+ totalBtyesToRead = FW_DNLD_HEADER_LEN;
+ }
+
+ if(numRead < totalBtyesToRead)
+ {
+ ret_Read = read((intptr_t)pDevHandle, pBuffer, totalBtyesToRead - numRead);
+ if (ret_Read != totalBtyesToRead - numRead)
+ {
+ NXPLOG_TML_E("_i2c_read() [hdr] errno : %x",errno);
+ return -1;
+ }
+ else
+ {
+ numRead += ret_Read;
+ }
+ }
+ if(TRUE == bFwDnldFlag)
+ {
+ totalBtyesToRead = pBuffer[FW_DNLD_LEN_OFFSET] + FW_DNLD_HEADER_LEN + CRC_LEN;
+ }
+ else
+ {
+ totalBtyesToRead = pBuffer[NORMAL_MODE_LEN_OFFSET] + NORMAL_MODE_HEADER_LEN;
+ }
+ ret_Read = read((intptr_t)pDevHandle, (pBuffer + numRead), totalBtyesToRead - numRead);
+ if (ret_Read > 0)
+ {
+ numRead += ret_Read;
+ }
+ else if (ret_Read == 0)
+ {
+ NXPLOG_TML_E("_i2c_read() [pyld] EOF");
+ return -1;
+ }
+ else
+ {
+ if(FALSE == bFwDnldFlag)
+ {
+ NXPLOG_TML_E("_i2c_read() [hdr] received");
+ phNxpNciHal_print_packet("RECV",pBuffer, NORMAL_MODE_HEADER_LEN);
+ }
+ NXPLOG_TML_E("_i2c_read() [pyld] errno : %x",errno);
+ return -1;
+ }
+ }
+ return numRead;
+}
+
+/*******************************************************************************
+**
+** Function phTmlNfc_i2c_write
+**
+** Description Writes requested number of bytes from given buffer into PN54X device
+**
+** Parameters pDevHandle - valid device handle
+** pBuffer - buffer for read data
+** nNbBytesToWrite - number of bytes requested to be written
+**
+** Returns numWrote - number of successfully written bytes
+** -1 - write operation failure
+**
+*******************************************************************************/
+int phTmlNfc_i2c_write(void *pDevHandle, uint8_t * pBuffer, int nNbBytesToWrite)
+{
+ int ret;
+ int numWrote = 0;
+ int i;
+ int numBytes = nNbBytesToWrite;
+ if (NULL == pDevHandle)
+ {
+ return -1;
+ }
+ if(fragmentation_enabled == I2C_FRAGMENATATION_DISABLED && nNbBytesToWrite > FRAGMENTSIZE_MAX)
+ {
+ NXPLOG_TML_E("i2c_write() data larger than maximum I2C size,enable I2C fragmentation");
+ return -1;
+ }
+ while (numWrote < nNbBytesToWrite)
+ {
+ if(fragmentation_enabled == I2C_FRAGMENTATION_ENABLED && nNbBytesToWrite > FRAGMENTSIZE_MAX)
+ {
+ if(nNbBytesToWrite - numWrote > FRAGMENTSIZE_MAX)
+ {
+ numBytes = numWrote+ FRAGMENTSIZE_MAX;
+ }
+ else
+ {
+ numBytes = nNbBytesToWrite;
+ }
+ }
+ ret = write((intptr_t)pDevHandle, pBuffer + numWrote, numBytes - numWrote);
+ if (ret > 0)
+ {
+ numWrote += ret;
+ if(fragmentation_enabled == I2C_FRAGMENTATION_ENABLED && numWrote < nNbBytesToWrite)
+ {
+ usleep(500);
+ }
+ }
+ else if (ret == 0)
+ {
+ NXPLOG_TML_E("_i2c_write() EOF");
+ return -1;
+ }
+ else
+ {
+ NXPLOG_TML_E("_i2c_write() errno : %x",errno);
+ if (errno == EINTR || errno == EAGAIN)
+ {
+ continue;
+ }
+ return -1;
+ }
+ }
+
+ return numWrote;
+}
+
+/*******************************************************************************
+**
+** Function phTmlNfc_i2c_reset
+**
+** Description Reset PN54X device, using VEN pin
+**
+** Parameters pDevHandle - valid device handle
+** level - reset level
+**
+** Returns 0 - reset operation success
+** -1 - reset operation failure
+**
+*******************************************************************************/
+int phTmlNfc_i2c_reset(void *pDevHandle, long level)
+{
+ int ret;
+ NXPLOG_TML_D("phTmlNfc_i2c_reset(), VEN level %ld", level);
+
+ if (NULL == pDevHandle)
+ {
+ return -1;
+ }
+
+ ret = ioctl((intptr_t)pDevHandle, PN544_SET_PWR, level);
+ if(level == 2 && ret == 0)
+ {
+ bFwDnldFlag = TRUE;
+ }else{
+ bFwDnldFlag = FALSE;
+ }
+ return ret;
+}
+
+#if(ESE_NFC_POWER_MANAGEMENT == TRUE)
+/*******************************************************************************
+**
+** 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)
+{
+ int ret;
+ NXPLOG_TML_D("phTmlNfc_set_pid(), pid %ld", pid);
+
+ if (NULL == pDevHandle)
+ {
+ return NFCSTATUS_FAILED;
+ }
+
+ ret = ioctl((int32_t)pDevHandle, P544_SET_NFC_SERVICE_PID, pid);
+ 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)
+{
+ 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", __FUNCTION__, 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)
+{
+ 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", __FUNCTION__, errno);
+ p61_current_state = P61_STATE_INVALID;
+ }
+ wStatus = p61_current_state;
+ return wStatus;
+}
+#endif
+/*******************************************************************************
+**
+** 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..6b03b63
--- /dev/null
+++ b/halimpl/pn54x/tml/phTmlNfc_i2c.h
@@ -0,0 +1,73 @@
+/*
+ * 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>
+
+/* Function declarations */
+void phTmlNfc_i2c_close(void *pDevHandle);
+NFCSTATUS phTmlNfc_i2c_open_and_configure(pphTmlNfc_Config_t pConfig, void ** pLinkHandle);
+int phTmlNfc_i2c_read(void *pDevHandle, uint8_t * pBuffer, int nNbBytesToRead);
+int phTmlNfc_i2c_write(void *pDevHandle,uint8_t * pBuffer, int nNbBytesToWrite);
+int phTmlNfc_i2c_reset(void *pDevHandle,long level);
+bool_t getDownloadFlag(void);
+phTmlNfc_i2cfragmentation_t fragmentation_enabled;
+#define PN544_MAGIC 0xE9
+
+/*
+ * 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)
+
+#if(ESE_NFC_POWER_MANAGEMENT == TRUE)
+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);
+
+/*
+ * 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)
+
+#endif
diff --git a/halimpl/pn54x/utils/phNxpConfig.cpp b/halimpl/pn54x/utils/phNxpConfig.cpp
new file mode 100644
index 0000000..9d66f13
--- /dev/null
+++ b/halimpl/pn54x/utils/phNxpConfig.cpp
@@ -0,0 +1,1024 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2011-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * The original Work has been changed by NXP Semiconductors.
+ *
+ * Copyright (C) 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 <phNxpConfig.h>
+#include <stdio.h>
+#include <string>
+#include <vector>
+#include <list>
+#include <sys/stat.h>
+
+#include <phNxpLog.h>
+
+#if GENERIC_TARGET
+const char alternative_config_path[] = "/data/nfc/";
+#else
+const char alternative_config_path[] = "";
+#endif
+
+#if 1
+const char transport_config_path[] = "/etc/";
+#else
+const char transport_config_path[] = "res/";
+#endif
+
+#define config_name "libnfc-nxp.conf"
+#define extra_config_base "libnfc-nxp-"
+#define extra_config_ext ".conf"
+#define IsStringValue 0x80000000
+
+const char config_timestamp_path[] = "/data/nfc/libnfc-nxpConfigState.bin";
+
+using namespace::std;
+
+class CNfcParam : public string
+{
+public:
+ CNfcParam();
+ CNfcParam(const char* name, const string& value);
+ CNfcParam(const char* name, unsigned long value);
+ virtual ~CNfcParam();
+ unsigned long numValue() const {return m_numValue;}
+ const char* str_value() const {return m_str_value.c_str();}
+ size_t str_len() const {return m_str_value.length();}
+private:
+ string m_str_value;
+ unsigned long m_numValue;
+};
+
+class CNfcConfig : public vector<const CNfcParam*>
+{
+public:
+ virtual ~CNfcConfig();
+ static CNfcConfig& GetInstance();
+ friend void readOptionalConfig(const char* optional);
+ int updateTimestamp();
+ int checkTimestamp();
+
+ bool getValue(const char* name, char* pValue, size_t len) const;
+ bool getValue(const char* name, unsigned long& rValue) const;
+ bool getValue(const char* name, unsigned short & rValue) const;
+ bool getValue(const char* name, char* pValue, long len,long* readlen) const;
+ const CNfcParam* find(const char* p_name) const;
+ void clean();
+private:
+ CNfcConfig();
+ bool readConfig(const char* name, bool bResetContent);
+ void moveFromList();
+ void moveToList();
+ void add(const CNfcParam* pParam);
+ list<const CNfcParam*> m_list;
+ bool mValidFile;
+ unsigned long m_timeStamp;
+
+ unsigned long state;
+
+ inline bool Is(unsigned long f) {return (state & f) == f;}
+ inline void Set(unsigned long f) {state |= f;}
+ inline void Reset(unsigned long f) {state &= ~f;}
+};
+
+/*******************************************************************************
+**
+** Function: isPrintable()
+**
+** Description: determine if 'c' is printable
+**
+** Returns: 1, if printable, otherwise 0
+**
+*******************************************************************************/
+inline bool isPrintable(char c)
+{
+ return (c >= 'A' && c <= 'Z') ||
+ (c >= 'a' && c <= 'z') ||
+ (c >= '0' && c <= '9') ||
+ c == '/' || c == '_' || c == '-' || c == '.';
+}
+
+/*******************************************************************************
+**
+** Function: isDigit()
+**
+** Description: determine if 'c' is numeral digit
+**
+** Returns: true, if numerical digit
+**
+*******************************************************************************/
+inline bool isDigit(char c, int base)
+{
+ if ('0' <= c && c <= '9')
+ return true;
+ if (base == 16)
+ {
+ if (('A' <= c && c <= 'F') ||
+ ('a' <= c && c <= 'f') )
+ return true;
+ }
+ return false;
+}
+
+/*******************************************************************************
+**
+** Function: getDigitValue()
+**
+** Description: return numerical value of a decimal or hex char
+**
+** Returns: numerical value if decimal or hex char, otherwise 0
+**
+*******************************************************************************/
+inline int getDigitValue(char c, int base)
+{
+ if ('0' <= c && c <= '9')
+ return c - '0';
+ if (base == 16)
+ {
+ if ('A' <= c && c <= 'F')
+ return c - 'A' + 10;
+ else if ('a' <= c && c <= 'f')
+ return c - 'a' + 10;
+ }
+ return 0;
+}
+
+/*******************************************************************************
+**
+** Function: CNfcConfig::readConfig()
+**
+** Description: read Config settings and parse them into a linked list
+** move the element from linked list to a array at the end
+**
+** Returns: 1, if there are any config data, 0 otherwise
+**
+*******************************************************************************/
+bool CNfcConfig::readConfig(const char* name, bool bResetContent)
+{
+ enum {
+ BEGIN_LINE = 1,
+ TOKEN,
+ STR_VALUE,
+ NUM_VALUE,
+ BEGIN_HEX,
+ BEGIN_QUOTE,
+ END_LINE
+ };
+
+ FILE* fd;
+ struct stat buf;
+ string token;
+ string strValue;
+ unsigned long numValue = 0;
+ CNfcParam* pParam = NULL;
+ int i = 0;
+ int base = 0;
+ char c;
+ int bflag = 0;
+ state = BEGIN_LINE;
+ /* open config file, read it into a buffer */
+ if ((fd = fopen(name, "rb")) == NULL)
+ {
+ ALOGE("%s Cannot open config file %s\n", __func__, name);
+ if (bResetContent)
+ {
+ ALOGE("%s Using default value for all settings\n", __func__);
+ mValidFile = false;
+ }
+ return false;
+ }
+ stat(name, &buf);
+ m_timeStamp = (unsigned long)buf.st_mtime;
+
+ mValidFile = true;
+ if (size() > 0)
+ {
+ if (bResetContent)
+ clean();
+ else
+ moveToList();
+ }
+
+ while (!feof(fd) && fread(&c, 1, 1, fd) == 1)
+ {
+ switch (state & 0xff)
+ {
+ case BEGIN_LINE:
+ if (c == '#')
+ state = END_LINE;
+ else if (isPrintable(c))
+ {
+ i = 0;
+ token.erase();
+ strValue.erase();
+ state = TOKEN;
+ token.push_back(c);
+ }
+ break;
+ case TOKEN:
+ if (c == '=')
+ {
+ token.push_back('\0');
+ state = BEGIN_QUOTE;
+ }
+ else if (isPrintable(c))
+ token.push_back(c);
+ else
+ state = END_LINE;
+ break;
+ case BEGIN_QUOTE:
+ if (c == '"')
+ {
+ state = STR_VALUE;
+ base = 0;
+ }
+ else if (c == '0')
+ state = BEGIN_HEX;
+ else if (isDigit(c, 10))
+ {
+ state = NUM_VALUE;
+ base = 10;
+ numValue = getDigitValue(c, base);
+ i = 0;
+ }
+ else if (c == '{')
+ {
+ state = NUM_VALUE;
+ bflag = 1;
+ base = 16;
+ i = 0;
+ Set(IsStringValue);
+ }
+ else
+ state = END_LINE;
+ break;
+ case BEGIN_HEX:
+ if (c == 'x' || c == 'X')
+ {
+ state = NUM_VALUE;
+ base = 16;
+ numValue = 0;
+ i = 0;
+ break;
+ }
+ else if (isDigit(c, 10))
+ {
+ state = NUM_VALUE;
+ base = 10;
+ numValue = getDigitValue(c, base);
+ break;
+ }
+ else if (c != '\n' && c != '\r')
+ {
+ state = END_LINE;
+ break;
+ }
+ // fall through to numValue to handle numValue
+
+ case NUM_VALUE:
+ if (isDigit(c, base))
+ {
+ numValue *= base;
+ numValue += getDigitValue(c, base);
+ ++i;
+ }
+ else if(bflag == 1 && (c == ' ' || c == '\r' || c=='\n' || c=='\t'))
+ {
+ break;
+ }
+ else if (base == 16 && (c== ','|| c == ':' || c == '-' || c == ' ' || c == '}'))
+ {
+
+ if( c=='}' )
+ {
+ bflag = 0;
+ }
+ if (i > 0)
+ {
+ int n = (i+1) / 2;
+ while (n-- > 0)
+ {
+ numValue = numValue >> (n * 8);
+ unsigned char c = (numValue) & 0xFF;
+ strValue.push_back(c);
+ }
+ }
+
+ Set(IsStringValue);
+ numValue = 0;
+ i = 0;
+ }
+ else
+ {
+ if (c == '\n' || c == '\r')
+ {
+ if(bflag == 0 )
+ {
+ state = BEGIN_LINE;
+ }
+ }
+ else
+ {
+ if( bflag == 0)
+ {
+ state = END_LINE;
+ }
+ }
+ if (Is(IsStringValue) && base == 16 && i > 0)
+ {
+ int n = (i+1) / 2;
+ while (n-- > 0)
+ strValue.push_back(((numValue >> (n * 8)) & 0xFF));
+ }
+ if (strValue.length() > 0)
+ pParam = new CNfcParam(token.c_str(), strValue);
+ else
+ pParam = new CNfcParam(token.c_str(), numValue);
+ add(pParam);
+ strValue.erase();
+ numValue = 0;
+ }
+ break;
+ case STR_VALUE:
+ if (c == '"')
+ {
+ strValue.push_back('\0');
+ state = END_LINE;
+ pParam = new CNfcParam(token.c_str(), strValue);
+ add(pParam);
+ }
+ else if (isPrintable(c))
+ strValue.push_back(c);
+ break;
+ case END_LINE:
+ if (c == '\n' || c == '\r')
+ state = BEGIN_LINE;
+ break;
+ default:
+ break;
+ }
+ }
+
+ fclose(fd);
+
+ moveFromList();
+ return size() > 0;
+}
+
+/*******************************************************************************
+**
+** Function: CNfcConfig::CNfcConfig()
+**
+** Description: class constructor
+**
+** Returns: none
+**
+*******************************************************************************/
+CNfcConfig::CNfcConfig() :
+ mValidFile(true),
+ m_timeStamp(0),
+ state(0)
+{
+}
+
+/*******************************************************************************
+**
+** Function: CNfcConfig::~CNfcConfig()
+**
+** Description: class destructor
+**
+** Returns: none
+**
+*******************************************************************************/
+CNfcConfig::~CNfcConfig()
+{
+}
+
+/*******************************************************************************
+**
+** Function: CNfcConfig::GetInstance()
+**
+** Description: get class singleton object
+**
+** Returns: none
+**
+*******************************************************************************/
+CNfcConfig& CNfcConfig::GetInstance()
+{
+ static CNfcConfig theInstance;
+
+ if (theInstance.size() == 0 && theInstance.mValidFile)
+ {
+ string strPath;
+ if (alternative_config_path[0] != '\0')
+ {
+ strPath.assign(alternative_config_path);
+ strPath += config_name;
+ theInstance.readConfig(strPath.c_str(), true);
+ if (!theInstance.empty())
+ {
+ return theInstance;
+ }
+ }
+ strPath.assign(transport_config_path);
+ strPath += config_name;
+ theInstance.readConfig(strPath.c_str(), true);
+ }
+
+ return theInstance;
+}
+
+/*******************************************************************************
+**
+** Function: CNfcConfig::getValue()
+**
+** Description: get a string value of a setting
+**
+** Returns: true if setting exists
+** false if setting does not exist
+**
+*******************************************************************************/
+bool CNfcConfig::getValue(const char* name, char* pValue, size_t len) const
+{
+ const CNfcParam* pParam = find(name);
+ if (pParam == NULL)
+ return false;
+
+ if (pParam->str_len() > 0)
+ {
+ memset(pValue, 0, len);
+ memcpy(pValue, pParam->str_value(), pParam->str_len());
+ return true;
+ }
+ return false;
+}
+
+bool CNfcConfig::getValue(const char* name, char* pValue, long len,long* readlen) const
+{
+ const CNfcParam* pParam = find(name);
+ if (pParam == NULL)
+ return false;
+
+ if (pParam->str_len() > 0)
+ {
+ if(pParam->str_len() <= (unsigned long)len)
+ {
+ memset(pValue, 0, len);
+ memcpy(pValue, pParam->str_value(), pParam->str_len());
+ *readlen = pParam->str_len();
+ }
+ else
+ {
+ *readlen = -1;
+ }
+
+ return true;
+ }
+ return false;
+}
+
+/*******************************************************************************
+**
+** Function: CNfcConfig::getValue()
+**
+** Description: get a long numerical value of a setting
+**
+** Returns: true if setting exists
+** false if setting does not exist
+**
+*******************************************************************************/
+bool CNfcConfig::getValue(const char* name, unsigned long& rValue) const
+{
+ const CNfcParam* pParam = find(name);
+ if (pParam == NULL)
+ return false;
+
+ if (pParam->str_len() == 0)
+ {
+ rValue = static_cast<unsigned long>(pParam->numValue());
+ return true;
+ }
+ return false;
+}
+
+/*******************************************************************************
+**
+** Function: CNfcConfig::getValue()
+**
+** Description: get a short numerical value of a setting
+**
+** Returns: true if setting exists
+** false if setting does not exist
+**
+*******************************************************************************/
+bool CNfcConfig::getValue(const char* name, unsigned short& rValue) const
+{
+ const CNfcParam* pParam = find(name);
+ if (pParam == NULL)
+ return false;
+
+ if (pParam->str_len() == 0)
+ {
+ rValue = static_cast<unsigned short>(pParam->numValue());
+ return true;
+ }
+ return false;
+}
+
+/*******************************************************************************
+**
+** Function: CNfcConfig::find()
+**
+** Description: search if a setting exist in the setting array
+**
+** Returns: pointer to the setting object
+**
+*******************************************************************************/
+const CNfcParam* CNfcConfig::find(const char* p_name) const
+{
+ if (size() == 0)
+ return NULL;
+
+ for (const_iterator it = begin(), itEnd = end(); it != itEnd; ++it)
+ {
+ if (**it < p_name)
+ {
+ continue;
+ }
+ else if (**it == p_name)
+ {
+ if((*it)->str_len() > 0)
+ {
+ NXPLOG_EXTNS_D("%s found %s=%s\n", __func__, p_name, (*it)->str_value());
+ }
+ else
+ {
+ NXPLOG_EXTNS_D("%s found %s=(0x%lx)\n", __func__, p_name, (*it)->numValue());
+ }
+ return *it;
+ }
+ else
+ break;
+ }
+ return NULL;
+}
+
+/*******************************************************************************
+**
+** Function: CNfcConfig::clean()
+**
+** Description: reset the setting array
+**
+** Returns: none
+**
+*******************************************************************************/
+void CNfcConfig::clean()
+{
+ if (size() == 0)
+ return;
+
+ for (iterator it = begin(), itEnd = end(); it != itEnd; ++it)
+ delete *it;
+ clear();
+}
+
+/*******************************************************************************
+**
+** Function: CNfcConfig::Add()
+**
+** Description: add a setting object to the list
+**
+** Returns: none
+**
+*******************************************************************************/
+void CNfcConfig::add(const CNfcParam* pParam)
+{
+ if (m_list.size() == 0)
+ {
+ m_list.push_back(pParam);
+ return;
+ }
+ for (list<const CNfcParam*>::iterator it = m_list.begin(), itEnd = m_list.end(); it != itEnd; ++it)
+ {
+ if (**it < pParam->c_str())
+ continue;
+ m_list.insert(it, pParam);
+ return;
+ }
+ m_list.push_back(pParam);
+}
+
+/*******************************************************************************
+**
+** Function: CNfcConfig::moveFromList()
+**
+** Description: move the setting object from list to array
+**
+** Returns: none
+**
+*******************************************************************************/
+void CNfcConfig::moveFromList()
+{
+ if (m_list.size() == 0)
+ return;
+
+ for (list<const CNfcParam*>::iterator it = m_list.begin(), itEnd = m_list.end(); it != itEnd; ++it)
+ push_back(*it);
+ m_list.clear();
+}
+
+/*******************************************************************************
+**
+** Function: CNfcConfig::moveToList()
+**
+** Description: move the setting object from array to list
+**
+** Returns: none
+**
+*******************************************************************************/
+void CNfcConfig::moveToList()
+{
+ if (m_list.size() != 0)
+ m_list.clear();
+
+ for (iterator it = begin(), itEnd = end(); it != itEnd; ++it)
+ m_list.push_back(*it);
+ clear();
+}
+
+#if 0
+/*******************************************************************************
+**
+** Function: CNfcConfig::checkTimestamp()
+**
+** Description: check if config file has modified
+**
+** Returns: 0 if not modified, 1 otherwise.
+**
+*******************************************************************************/
+int CNfcConfig::checkTimestamp()
+{
+ FILE* fd;
+ struct stat st;
+ unsigned long value = 0;
+ int ret = 0;
+
+ if(stat(config_timestamp_path, &st) != 0)
+ {
+ ALOGD("%s file %s not exist, creat it.\n", __func__, config_timestamp_path);
+ if ((fd = fopen(config_timestamp_path, "w+")) != NULL)
+ {
+ fwrite(&m_timeStamp, sizeof(unsigned long), 1, fd);
+ fclose(fd);
+ }
+ return 1;
+ }
+ else
+ {
+ fd = fopen(config_timestamp_path, "r+");
+ if(fd == NULL)
+ {
+ ALOGE("%s Cannot open file %s\n", __func__, config_timestamp_path);
+ return 1;
+ }
+
+ fread(&value, sizeof(unsigned long), 1, fd);
+ ret = (value != m_timeStamp);
+ if(ret)
+ {
+ fseek(fd, 0, SEEK_SET);
+ fwrite(&m_timeStamp, sizeof(unsigned long), 1, fd);
+ }
+ fclose(fd);
+ }
+ return ret;
+}
+
+#endif
+/*******************************************************************************
+**
+** Function: CNfcConfig::checkforTimestamp()
+**
+** Description: check if config file has modified
+**
+** Returns: 0 if not modified, 1 otherwise.
+**
+*******************************************************************************/
+int CNfcConfig::checkTimestamp()
+{
+ FILE* fd;
+ struct stat st;
+ unsigned long value = 0;
+ int ret = 0;
+
+ if(stat(config_timestamp_path, &st) != 0)
+ {
+ ALOGD("%s file not exist.\n", __func__);
+ return 1;
+ }
+ else
+ {
+ fd = fopen(config_timestamp_path, "r+");
+ if(fd == NULL)
+ {
+ ALOGE("%s Cannot open file %s\n", __func__, config_timestamp_path);
+ return 1;
+ }
+
+ fread(&value, sizeof(unsigned long), 1, fd);
+ ret = (value != m_timeStamp);
+ fclose(fd);
+ }
+ return ret;
+}
+
+/*******************************************************************************
+**
+** Function: CNfcConfig::updateTimestamp()
+**
+** Description: update if config file has modified
+**
+** Returns: 0 if not modified, 1 otherwise.
+**
+*******************************************************************************/
+int CNfcConfig::updateTimestamp()
+{
+ FILE* fd;
+ struct stat st;
+ unsigned long value = 0;
+ int ret = 0;
+
+ if(stat(config_timestamp_path, &st) != 0)
+ {
+ ALOGD("%s file %s not exist, creat it.\n", __func__, config_timestamp_path);
+ if ((fd = fopen(config_timestamp_path, "w+")) != NULL)
+ {
+ fwrite(&m_timeStamp, sizeof(unsigned long), 1, fd);
+ fclose(fd);
+ }
+ return 1;
+ }
+ else
+ {
+ fd = fopen(config_timestamp_path, "r+");
+ if(fd == NULL)
+ {
+ ALOGE("%s Cannot open file %s\n", __func__, config_timestamp_path);
+ return 1;
+ }
+
+ fread(&value, sizeof(unsigned long), 1, fd);
+ ret = (value != m_timeStamp);
+ if(ret)
+ {
+ fseek(fd, 0, SEEK_SET);
+ fwrite(&m_timeStamp, sizeof(unsigned long), 1, fd);
+ }
+ fclose(fd);
+ }
+ return ret;
+}
+
+/*******************************************************************************
+**
+** Function: CNfcParam::CNfcParam()
+**
+** Description: class constructor
+**
+** Returns: none
+**
+*******************************************************************************/
+CNfcParam::CNfcParam() :
+ m_numValue(0)
+{
+}
+
+/*******************************************************************************
+**
+** Function: CNfcParam::~CNfcParam()
+**
+** Description: class destructor
+**
+** Returns: none
+**
+*******************************************************************************/
+CNfcParam::~CNfcParam()
+{
+}
+
+/*******************************************************************************
+**
+** Function: CNfcParam::CNfcParam()
+**
+** Description: class copy constructor
+**
+** Returns: none
+**
+*******************************************************************************/
+CNfcParam::CNfcParam(const char* name, const string& value) :
+ string(name),
+ m_str_value(value),
+ m_numValue(0)
+{
+}
+
+/*******************************************************************************
+**
+** Function: CNfcParam::CNfcParam()
+**
+** Description: class copy constructor
+**
+** Returns: none
+**
+*******************************************************************************/
+CNfcParam::CNfcParam(const char* name, unsigned long value) :
+ string(name),
+ m_numValue(value)
+{
+}
+
+/*******************************************************************************
+**
+** Function: GetStrValue
+**
+** Description: API function for getting a string value of a setting
+**
+** Returns: True if found, otherwise False.
+**
+*******************************************************************************/
+extern "C" int GetNxpStrValue(const char* name, char* pValue, unsigned long len)
+{
+ CNfcConfig& rConfig = CNfcConfig::GetInstance();
+
+ return rConfig.getValue(name, pValue, len);
+}
+
+/*******************************************************************************
+**
+** Function: GetByteArrayValue()
+**
+** Description: Read byte array value from the config file.
+**
+** Parameters:
+** name - name of the config param to read.
+** pValue - pointer to input buffer.
+** bufflen - input buffer length.
+** len - out parameter to return the number of bytes read from config file,
+** return -1 in case bufflen is not enough.
+**
+** Returns: TRUE[1] if config param name is found in the config file, else FALSE[0]
+**
+*******************************************************************************/
+extern "C" int GetNxpByteArrayValue(const char* name, char* pValue,long bufflen, long *len)
+{
+ CNfcConfig& rConfig = CNfcConfig::GetInstance();
+
+ return rConfig.getValue(name, pValue, bufflen,len);
+}
+
+/*******************************************************************************
+**
+** Function: GetNumValue
+**
+** Description: API function for getting a numerical value of a setting
+**
+** Returns: true, if successful
+**
+*******************************************************************************/
+extern "C" int GetNxpNumValue(const char* name, void* pValue, unsigned long len)
+{
+ if (!pValue)
+ return false;
+
+ CNfcConfig& rConfig = CNfcConfig::GetInstance();
+ const CNfcParam* pParam = rConfig.find(name);
+
+ if (pParam == NULL)
+ return false;
+ unsigned long v = pParam->numValue();
+ if (v == 0 && pParam->str_len() > 0 && pParam->str_len() < 4)
+ {
+ const unsigned char* p = (const unsigned char*)pParam->str_value();
+ for (unsigned int i = 0 ; i < pParam->str_len(); ++i)
+ {
+ v *= 256;
+ v += *p++;
+ }
+ }
+ switch (len)
+ {
+ case sizeof(unsigned long):
+ *(static_cast<unsigned long*>(pValue)) = (unsigned long)v;
+ break;
+ case sizeof(unsigned short):
+ *(static_cast<unsigned short*>(pValue)) = (unsigned short)v;
+ break;
+ case sizeof(unsigned char):
+ *(static_cast<unsigned char*> (pValue)) = (unsigned char)v;
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+/*******************************************************************************
+**
+** Function: resetConfig
+**
+** Description: reset settings array
+**
+** Returns: none
+**
+*******************************************************************************/
+extern "C" void resetNxpConfig()
+
+{
+ CNfcConfig& rConfig = CNfcConfig::GetInstance();
+
+ rConfig.clean();
+}
+
+/*******************************************************************************
+**
+** Function: readOptionalConfig()
+**
+** Description: read Config settings from an optional conf file
+**
+** Returns: none
+**
+*******************************************************************************/
+void readOptionalConfig(const char* extra)
+{
+ string strPath;
+ strPath.assign(transport_config_path);
+ if (alternative_config_path[0] != '\0')
+ strPath.assign(alternative_config_path);
+
+ strPath += extra_config_base;
+ strPath += extra;
+ strPath += extra_config_ext;
+ CNfcConfig::GetInstance().readConfig(strPath.c_str(), false);
+}
+
+/*******************************************************************************
+**
+** Function: isNxpConfigModified()
+**
+** Description: check if config file has modified
+**
+** Returns: 0 if not modified, 1 otherwise.
+**
+*******************************************************************************/
+extern "C" int isNxpConfigModified()
+{
+ CNfcConfig& rConfig = CNfcConfig::GetInstance();
+ return rConfig.checkTimestamp();
+}
+
+/*******************************************************************************
+**
+** Function: updateNxpConfigTimestamp()
+**
+** Description: update if config file has modified
+**
+** Returns: 0 if not modified, 1 otherwise.
+**
+*******************************************************************************/
+extern "C" int updateNxpConfigTimestamp()
+{
+ CNfcConfig& rConfig = CNfcConfig::GetInstance();
+ return rConfig.updateTimestamp();
+}
diff --git a/halimpl/pn54x/utils/phNxpConfig.h b/halimpl/pn54x/utils/phNxpConfig.h
new file mode 100644
index 0000000..831a3fa
--- /dev/null
+++ b/halimpl/pn54x/utils/phNxpConfig.h
@@ -0,0 +1,101 @@
+/******************************************************************************
+ *
+ * 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 isNxpConfigModified();
+int updateNxpConfigTimestamp();
+
+#ifdef __cplusplus
+};
+#endif
+
+#define NAME_NXPLOG_EXTNS_LOGLEVEL "NXPLOG_EXTNS_LOGLEVEL"
+#define NAME_NXPLOG_NCIHAL_LOGLEVEL "NXPLOG_NCIHAL_LOGLEVEL"
+#define NAME_NXPLOG_NCIX_LOGLEVEL "NXPLOG_NCIX_LOGLEVEL"
+#define NAME_NXPLOG_NCIR_LOGLEVEL "NXPLOG_NCIR_LOGLEVEL"
+#define NAME_NXPLOG_FWDNLD_LOGLEVEL "NXPLOG_FWDNLD_LOGLEVEL"
+#define NAME_NXPLOG_TML_LOGLEVEL "NXPLOG_TML_LOGLEVEL"
+
+#define NAME_MIFARE_READER_ENABLE "MIFARE_READER_ENABLE"
+#define NAME_FW_STORAGE "FW_STORAGE"
+#define NAME_NXP_FW_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_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"
+
+/* default configuration */
+#define default_storage_location "/data/nfc"
+
+#endif
diff --git a/halimpl/pn54x/utils/phNxpNciHal_utils.c b/halimpl/pn54x/utils/phNxpNciHal_utils.c
new file mode 100644
index 0000000..6363745
--- /dev/null
+++ b/halimpl/pn54x/utils/phNxpNciHal_utils.c
@@ -0,0 +1,524 @@
+/*
+ * 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()", __FUNCTION__);
+ // abort();
+}
diff --git a/halimpl/pn54x/utils/phNxpNciHal_utils.h b/halimpl/pn54x/utils/phNxpNciHal_utils.h
new file mode 100644
index 0000000..26f6629
--- /dev/null
+++ b/halimpl/pn54x/utils/phNxpNciHal_utils.h
@@ -0,0 +1,121 @@
+/*
+ * 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>
+
+/********************* Definitions and structures *****************************/
+
+/* List structures */
+struct listNode
+{
+ void* pData;
+ struct listNode* pNext;
+};
+
+struct listHead
+{
+ struct listNode* pFirst;
+ pthread_mutex_t mutex;
+};
+
+
+/* Semaphore handling structure */
+typedef struct phNxpNciHal_Sem
+{
+ /* Semaphore used to wait for callback */
+ sem_t sem;
+
+ /* Used to store the status sent by the callback */
+ NFCSTATUS status;
+
+ /* Used to provide a local context to the callback */
+ void* pContext;
+
+} phNxpNciHal_Sem_t;
+
+/* Semaphore helper macros */
+#define SEM_WAIT(cb_data) sem_wait(&((cb_data).sem))
+#define SEM_POST(p_cb_data) sem_post(&((p_cb_data)->sem))
+
+/* Semaphore and mutex monitor */
+typedef struct phNxpNciHal_Monitor
+{
+ /* Mutex protecting native library against reentrance */
+ pthread_mutex_t reentrance_mutex;
+
+ /* Mutex protecting native library against concurrency */
+ pthread_mutex_t concurrency_mutex;
+
+ /* List used to track pending semaphores waiting for callback */
+ struct listHead sem_list;
+
+} phNxpNciHal_Monitor_t;
+
+/************************ Exposed functions ***********************************/
+/* List functions */
+int listInit(struct listHead* pList);
+int listDestroy(struct listHead* pList);
+int listAdd(struct listHead* pList, void* pData);
+int listRemove(struct listHead* pList, void* pData);
+int listGetAndRemoveNext(struct listHead* pList, void** ppData);
+void listDump(struct listHead* pList);
+
+/* NXP NCI HAL utility functions */
+phNxpNciHal_Monitor_t* phNxpNciHal_init_monitor(void);
+void phNxpNciHal_cleanup_monitor(void);
+phNxpNciHal_Monitor_t* phNxpNciHal_get_monitor(void);
+NFCSTATUS phNxpNciHal_init_cb_data(phNxpNciHal_Sem_t *pCallbackData,
+ void *pContext);
+void phNxpNciHal_cleanup_cb_data(phNxpNciHal_Sem_t* pCallbackData);
+void phNxpNciHal_releaseall_cb_data(void);
+void phNxpNciHal_print_packet(const char *pString, const uint8_t *p_data,
+ uint16_t len);
+void phNxpNciHal_emergency_recovery(void);
+
+/* Lock unlock helper macros */
+/* Lock unlock helper macros */
+#define REENTRANCE_LOCK() if (phNxpNciHal_get_monitor()) pthread_mutex_lock(&phNxpNciHal_get_monitor()->reentrance_mutex)
+#define REENTRANCE_UNLOCK() if (phNxpNciHal_get_monitor()) pthread_mutex_unlock(&phNxpNciHal_get_monitor()->reentrance_mutex)
+#define CONCURRENCY_LOCK() if (phNxpNciHal_get_monitor()) pthread_mutex_lock(&phNxpNciHal_get_monitor()->concurrency_mutex)
+#define CONCURRENCY_UNLOCK() if (phNxpNciHal_get_monitor()) pthread_mutex_unlock(&phNxpNciHal_get_monitor()->concurrency_mutex)
+
+#endif /* _PHNXPNCIHAL_UTILS_H_ */
diff --git a/src/adaptation/CrcChecksum.cpp b/src/adaptation/CrcChecksum.cpp
new file mode 100644
index 0000000..e487bf0
--- /dev/null
+++ b/src/adaptation/CrcChecksum.cpp
@@ -0,0 +1,154 @@
+/******************************************************************************
+ *
+ * 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>
+#ifndef LOG_TAG
+#define LOG_TAG "NfcNciHal"
+#endif
+
+
+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.
+**
+*******************************************************************************/
+BOOLEAN crcChecksumVerifyIntegrity (const char* filename)
+{
+ ALOGD ("%s: filename=%s", __FUNCTION__, filename);
+ BOOLEAN 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=%u", __FUNCTION__, data.size());
+ if (checksum == crcChecksumCompute ((const unsigned char*) data.data(), data.size()))
+ isGood = TRUE;
+ else
+ ALOGE ("%s: checksum mismatch", __FUNCTION__);
+ }
+ else
+ ALOGE ("%s: invalid length", __FUNCTION__);
+ }
+ 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..f18e217
--- /dev/null
+++ b/src/adaptation/NfcAdaptation.cpp
@@ -0,0 +1,896 @@
+/******************************************************************************
+ *
+ * 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 "NfcAdaptation.h"
+extern "C"
+{
+ #include "gki.h"
+ #include "nfa_api.h"
+ #include "nfc_int.h"
+}
+#include "config.h"
+#include "android_logmsg.h"
+
+#define LOG_TAG "NfcAdaptation"
+
+extern "C" void GKI_shutdown();
+extern void resetConfig();
+extern "C" void verify_stack_non_volatile_store ();
+extern "C" void delete_stack_non_volatile_store (BOOLEAN forceDelete);
+
+NfcAdaptation* NfcAdaptation::mpInstance = NULL;
+ThreadMutex NfcAdaptation::sLock;
+nfc_nci_device_t* NfcAdaptation::mHalDeviceContext = NULL;
+tHAL_NFC_CBACK* NfcAdaptation::mHalCallback = NULL;
+tHAL_NFC_DATA_CBACK* NfcAdaptation::mHalDataCallback = NULL;
+ThreadCondVar NfcAdaptation::mHalOpenCompletedEvent;
+ThreadCondVar NfcAdaptation::mHalCloseCompletedEvent;
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ThreadCondVar NfcAdaptation::mHalCoreResetCompletedEvent;
+ThreadCondVar NfcAdaptation::mHalCoreInitCompletedEvent;
+ThreadCondVar NfcAdaptation::mHalInitCompletedEvent;
+#endif
+
+UINT32 ScrProtocolTraceFlag = SCR_PROTO_TRACE_ALL; //0x017F00;
+UINT8 appl_trace_level = 0xff;
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+UINT8 appl_dta_mode_flag = 0x00;
+#endif
+char bcm_nfc_location[120];
+char nci_hal_module[64];
+
+static UINT8 nfa_dm_cfg[sizeof ( tNFA_DM_CFG ) ];
+extern tNFA_DM_CFG *p_nfa_dm_cfg;
+extern UINT8 nfa_ee_max_ee_cfg;
+extern const UINT8 nfca_version_string [];
+extern const UINT8 nfa_version_string [];
+static UINT8 deviceHostWhiteList [NFA_HCI_MAX_HOST_IN_NETWORK];
+static tNFA_HCI_CFG jni_nfa_hci_cfg;
+extern tNFA_HCI_CFG *p_nfa_hci_cfg;
+
+/*******************************************************************************
+**
+** 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));
+ }
+ if ( GetNumValue ( NAME_PROTOCOL_TRACE_LEVEL, &num, sizeof ( num ) ) )
+ ScrProtocolTraceFlag = num;
+
+ if ( GetStrValue ( NAME_NFA_DM_CFG, (char*)nfa_dm_cfg, sizeof ( nfa_dm_cfg ) ) )
+ p_nfa_dm_cfg = ( tNFA_DM_CFG * ) &nfa_dm_cfg[0];
+
+ if ( GetNumValue ( NAME_NFA_MAX_EE_SUPPORTED, &num, sizeof ( num ) ) )
+ {
+ nfa_ee_max_ee_cfg = num;
+ ALOGD("%s: Overriding NFA_EE_MAX_EE_SUPPORTED to use %d", func, nfa_ee_max_ee_cfg);
+ }
+
+ //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) 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", __FUNCTION__);
+ else
+ {
+ delete_stack_non_volatile_store (FALSE);
+ }
+
+ GKI_init ();
+ GKI_enable ();
+ GKI_create_task ((TASKPTR)NFCA_TASK, BTU_TASK, (INT8*)"NFCA_TASK", 0, 0, (pthread_cond_t*)NULL, NULL);
+ {
+ AutoThreadMutex guard(mCondVar);
+ GKI_create_task ((TASKPTR)Thread, MMI_TASK, (INT8*)"NFCA_THREAD", 0, 0, (pthread_cond_t*)NULL, NULL);
+ mCondVar.wait();
+ }
+
+ mHalDeviceContext = NULL;
+ mHalCallback = NULL;
+ memset (&mHalEntryFuncs, 0, sizeof(mHalEntryFuncs));
+ InitializeHalDeviceContext ();
+ ALOGD ("%s: exit", func);
+}
+
+/*******************************************************************************
+**
+** Function: NfcAdaptation::Finalize()
+**
+** Description: class finalizer
+**
+** Returns: none
+**
+*******************************************************************************/
+void NfcAdaptation::Finalize()
+{
+ const char* func = "NfcAdaptation::Finalize";
+ AutoThreadMutex a(sLock);
+
+ ALOGD ("%s: enter", func);
+ GKI_shutdown ();
+
+ resetConfig();
+
+ nfc_nci_close(mHalDeviceContext); //close the HAL's device context
+ mHalDeviceContext = NULL;
+ mHalCallback = NULL;
+ memset (&mHalEntryFuncs, 0, sizeof(mHalEntryFuncs));
+
+ ALOGD ("%s: exit", func);
+ delete this;
+}
+
+/*******************************************************************************
+**
+** Function: NfcAdaptation::signal()
+**
+** Description: signal the CondVar to release the thread that is waiting
+**
+** Returns: none
+**
+*******************************************************************************/
+void NfcAdaptation::signal ()
+{
+ mCondVar.signal();
+}
+
+/*******************************************************************************
+**
+** Function: NfcAdaptation::NFCA_TASK()
+**
+** Description: NFCA_TASK runs the GKI main task
+**
+** Returns: none
+**
+*******************************************************************************/
+UINT32 NfcAdaptation::NFCA_TASK (UINT32 arg)
+{
+ const char* func = "NfcAdaptation::NFCA_TASK";
+ ALOGD ("%s: enter", func);
+ GKI_run (0);
+ ALOGD ("%s: exit", func);
+ return 0;
+}
+
+/*******************************************************************************
+**
+** Function: NfcAdaptation::Thread()
+**
+** Description: Creates work threads
+**
+** Returns: none
+**
+*******************************************************************************/
+UINT32 NfcAdaptation::Thread (UINT32 arg)
+{
+ const char* func = "NfcAdaptation::Thread";
+ ALOGD ("%s: enter", func);
+
+ {
+ ThreadCondVar CondVar;
+ AutoThreadMutex guard(CondVar);
+ GKI_create_task ((TASKPTR)nfc_task, NFC_TASK, (INT8*)"NFC_TASK", 0, 0, (pthread_cond_t*)CondVar, (pthread_mutex_t*)CondVar);
+ CondVar.wait();
+ }
+
+ NfcAdaptation::GetInstance().signal();
+
+ GKI_exit_task (GKI_get_taskid ());
+ ALOGD ("%s: exit", func);
+ return 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
+ if ( !GetStrValue ( NAME_NCI_HAL_MODULE, nci_hal_module, sizeof ( nci_hal_module) ) )
+ {
+ ALOGE("No HAL module specified in config, falling back to BCM2079x");
+ strlcpy (nci_hal_module, "nfc_nci.bcm2079x", sizeof(nci_hal_module));
+ }
+ const hw_module_t* hw_module = NULL;
+
+ mHalEntryFuncs.initialize = HalInitialize;
+ mHalEntryFuncs.terminate = HalTerminate;
+ mHalEntryFuncs.open = HalOpen;
+ mHalEntryFuncs.close = HalClose;
+ mHalEntryFuncs.core_initialized = HalCoreInitialized;
+ mHalEntryFuncs.write = HalWrite;
+#if((ESE_NFC_POWER_MANAGEMENT == TRUE)&&(NFC_NXP_NOT_OPEN_INCLUDED == TRUE))
+ mHalEntryFuncs.ioctl = HalIoctl;
+#endif
+ mHalEntryFuncs.prediscover = HalPrediscover;
+ mHalEntryFuncs.control_granted = HalControlGranted;
+ mHalEntryFuncs.power_cycle = HalPowerCycle;
+ mHalEntryFuncs.get_max_ee = HalGetMaxNfcee;
+
+ ret = hw_get_module (nci_hal_module, &hw_module);
+ if (ret == 0)
+ {
+ ret = nfc_nci_open (hw_module, &mHalDeviceContext);
+ if (ret != 0)
+ ALOGE ("%s: nfc_nci_open fail", func);
+ }
+ else
+ ALOGE ("%s: fail hw_get_module %s", func, nci_hal_module);
+ ALOGD ("%s: exit", func);
+}
+
+/*******************************************************************************
+**
+** Function: NfcAdaptation::HalInitialize
+**
+** Description: Not implemented because this function is only needed
+** within the HAL.
+**
+** Returns: None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalInitialize ()
+{
+ const char* func = "NfcAdaptation::HalInitialize";
+ ALOGD ("%s", func);
+}
+
+/*******************************************************************************
+**
+** Function: NfcAdaptation::HalTerminate
+**
+** Description: Not implemented because this function is only needed
+** within the HAL.
+**
+** Returns: None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalTerminate ()
+{
+ const char* func = "NfcAdaptation::HalTerminate";
+ ALOGD ("%s", func);
+}
+
+/*******************************************************************************
+**
+** Function: NfcAdaptation::HalOpen
+**
+** Description: Turn on controller, download firmware.
+**
+** Returns: None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalOpen (tHAL_NFC_CBACK *p_hal_cback, tHAL_NFC_DATA_CBACK* p_data_cback)
+{
+ const char* func = "NfcAdaptation::HalOpen";
+ ALOGD ("%s", func);
+ if (mHalDeviceContext)
+ {
+ mHalCallback = p_hal_cback;
+ mHalDataCallback = p_data_cback;
+ mHalDeviceContext->open (mHalDeviceContext, HalDeviceContextCallback, HalDeviceContextDataCallback);
+ }
+}
+
+/*******************************************************************************
+**
+** Function: NfcAdaptation::HalClose
+**
+** Description: Turn off controller.
+**
+** Returns: None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalClose ()
+{
+ const char* func = "NfcAdaptation::HalClose";
+ ALOGD ("%s", func);
+ if (mHalDeviceContext)
+ {
+ mHalDeviceContext->close (mHalDeviceContext);
+ }
+}
+
+/*******************************************************************************
+**
+** Function: NfcAdaptation::HalDeviceContextCallback
+**
+** Description: Translate generic Android HAL's callback into Broadcom-specific
+** callback function.
+**
+** Returns: None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalDeviceContextCallback (nfc_event_t event, nfc_status_t event_status)
+{
+ const char* func = "NfcAdaptation::HalDeviceContextCallback";
+ ALOGD ("%s: event=%u", func, event);
+ if (mHalCallback)
+ mHalCallback (event, (tHAL_NFC_STATUS) event_status);
+}
+
+/*******************************************************************************
+**
+** Function: NfcAdaptation::HalDeviceContextDataCallback
+**
+** Description: Translate generic Android HAL's callback into Broadcom-specific
+** callback function.
+**
+** Returns: None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalDeviceContextDataCallback (uint16_t data_len, uint8_t* p_data)
+{
+ const char* func = "NfcAdaptation::HalDeviceContextDataCallback";
+ ALOGD ("%s: len=%u", func, data_len);
+ if (mHalDataCallback)
+ mHalDataCallback (data_len, p_data);
+}
+
+/*******************************************************************************
+**
+** Function: NfcAdaptation::HalWrite
+**
+** Description: Write NCI message to the controller.
+**
+** Returns: None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalWrite (UINT16 data_len, UINT8* p_data)
+{
+ const char* func = "NfcAdaptation::HalWrite";
+ ALOGD ("%s", func);
+ if (mHalDeviceContext)
+ {
+ mHalDeviceContext->write (mHalDeviceContext, data_len, p_data);
+ }
+}
+
+#if((ESE_NFC_POWER_MANAGEMENT == TRUE)&&(NFC_NXP_NOT_OPEN_INCLUDED == TRUE))
+/*******************************************************************************
+**
+** 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";
+ ALOGD ("%s", func);
+ if (mHalDeviceContext)
+ {
+ return (mHalDeviceContext->ioctl (mHalDeviceContext, arg, p_data));
+ }
+ return -1;
+}
+
+#endif
+
+
+/*******************************************************************************
+**
+** Function: NfcAdaptation::HalCoreInitialized
+**
+** Description: Adjust the configurable parameters in the controller.
+**
+** Returns: None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalCoreInitialized (UINT8* p_core_init_rsp_params)
+{
+ const char* func = "NfcAdaptation::HalCoreInitialized";
+ ALOGD ("%s", func);
+ if (mHalDeviceContext)
+ {
+ mHalDeviceContext->core_initialized (mHalDeviceContext, p_core_init_rsp_params);
+ }
+}
+
+/*******************************************************************************
+**
+** Function: NfcAdaptation::HalPrediscover
+**
+** Description: Perform any vendor-specific pre-discovery actions (if needed)
+** If any actions were performed TRUE will be returned, and
+** HAL_PRE_DISCOVER_CPLT_EVT will notify when actions are
+** completed.
+**
+** Returns: TRUE if vendor-specific pre-discovery actions initialized
+** FALSE if no vendor-specific pre-discovery actions are needed.
+**
+*******************************************************************************/
+BOOLEAN NfcAdaptation::HalPrediscover ()
+{
+ const char* func = "NfcAdaptation::HalPrediscover";
+ ALOGD ("%s", func);
+ BOOLEAN retval = FALSE;
+
+ if (mHalDeviceContext)
+ {
+ 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);
+ if (mHalDeviceContext)
+ {
+ mHalDeviceContext->control_granted (mHalDeviceContext);
+ }
+}
+
+/*******************************************************************************
+**
+** Function: NfcAdaptation::HalPowerCycle
+**
+** Description: Turn off and turn on the controller.
+**
+** Returns: None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalPowerCycle ()
+{
+ const char* func = "NfcAdaptation::HalPowerCycle";
+ ALOGD ("%s", func);
+ if (mHalDeviceContext)
+ {
+ mHalDeviceContext->power_cycle (mHalDeviceContext);
+ }
+}
+
+/*******************************************************************************
+**
+** Function: NfcAdaptation::HalGetMaxNfcee
+**
+** Description: Turn off and turn on the controller.
+**
+** Returns: None.
+**
+*******************************************************************************/
+UINT8 NfcAdaptation::HalGetMaxNfcee()
+{
+ const char* func = "NfcAdaptation::HalPowerCycle";
+ UINT8 maxNfcee = 0;
+ ALOGD ("%s", func);
+ if (mHalDeviceContext)
+ {
+ // TODO maco call into HAL when we figure out binary compatibility.
+ return nfa_ee_max_ee_cfg;
+
+ //mHalDeviceContext->get_max_ee (mHalDeviceContext, &maxNfcee);
+ }
+
+ return maxNfcee;
+}
+
+
+/*******************************************************************************
+**
+** Function: NfcAdaptation::DownloadFirmware
+**
+** Description: Download firmware patch files.
+**
+** Returns: None.
+**
+*******************************************************************************/
+void NfcAdaptation::DownloadFirmware ()
+{
+ const char* func = "NfcAdaptation::DownloadFirmware";
+ ALOGD ("%s: enter", func);
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ static UINT8 cmd_reset_nci[] = {0x20,0x00,0x01,0x01};
+ static UINT8 cmd_init_nci[] = {0x20,0x01,0x00};
+ static UINT8 cmd_reset_nci_size = sizeof(cmd_reset_nci) / sizeof(UINT8);
+ static UINT8 cmd_init_nci_size = sizeof(cmd_init_nci) / sizeof(UINT8);
+ UINT8 p_core_init_rsp_params;
+#endif
+ HalInitialize ();
+
+ mHalOpenCompletedEvent.lock ();
+ ALOGD ("%s: try open HAL", func);
+ HalOpen (HalDownloadFirmwareCallback, HalDownloadFirmwareDataCallback);
+ mHalOpenCompletedEvent.wait ();
+#if (NFC_NXP_NOT_OPEN_INCLUDED == 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.
+ */
+ mHalCoreResetCompletedEvent.lock();
+ ALOGD("%s: send CORE_RESET", func);
+ HalWrite(cmd_reset_nci_size , cmd_reset_nci);
+ mHalCoreResetCompletedEvent.wait();
+ mHalCoreInitCompletedEvent.lock();
+ ALOGD("%s: send CORE_INIT", func);
+ HalWrite(cmd_init_nci_size , cmd_init_nci);
+ mHalCoreInitCompletedEvent.wait();
+ mHalInitCompletedEvent.lock ();
+ ALOGD ("%s: try init HAL", func);
+ HalCoreInitialized (&p_core_init_rsp_params);
+ mHalInitCompletedEvent.wait ();
+#endif
+
+ mHalCloseCompletedEvent.lock ();
+ ALOGD ("%s: try close HAL", func);
+ HalClose ();
+ mHalCloseCompletedEvent.wait ();
+
+ 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";
+ 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);
+ 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 (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ if (data_len > 3)
+ {
+ if (p_data[0] == 0x40 && p_data[1] == 0x00)
+ {
+ mHalCoreResetCompletedEvent.signal();
+ }
+ else if (p_data[0] == 0x40 && p_data[1] == 0x01)
+ {
+ 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..dce1b8a
--- /dev/null
+++ b/src/adaptation/OverrideLog.cpp
@@ -0,0 +1,114 @@
+/******************************************************************************
+ *
+ * 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 "config.h"
+#include "android_logmsg.h"
+#define LOG_TAG "BrcmNfcJni"
+
+
+/*******************************************************************************
+**
+** Function: initializeGlobalAppLogLevel
+**
+** Description: Initialize and get global logging level from .conf or
+** Android property nfc.app_log_level. The Android property
+** overrides .conf variable.
+**
+** Returns: Global log level:
+** BT_TRACE_LEVEL_NONE 0 * No trace messages to be generated
+** BT_TRACE_LEVEL_ERROR 1 * Error condition trace messages
+** BT_TRACE_LEVEL_WARNING 2 * Warning condition trace messages
+** BT_TRACE_LEVEL_API 3 * API traces
+** BT_TRACE_LEVEL_EVENT 4 * Debug messages for events
+** BT_TRACE_LEVEL_DEBUG 5 * Debug messages (general)
+**
+*******************************************************************************/
+unsigned char initializeGlobalAppLogLevel ()
+{
+ unsigned long num = 0;
+ char valueStr [PROPERTY_VALUE_MAX] = {0};
+
+ 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", __FUNCTION__, appl_trace_level);
+
+ if (appl_trace_level < BT_TRACE_LEVEL_DEBUG)
+ {
+ //display protocol traces in raw format
+ ProtoDispAdapterUseRawOutput (TRUE);
+ }
+ return appl_trace_level;
+}
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+/*******************************************************************************
+**
+** Function: initializeGlobalDtaMode
+**
+** Description: Initialize and get global DTA mode from .conf
+**
+** Returns: none:
+**
+*******************************************************************************/
+void initializeGlobalAppDtaMode ()
+{
+ appl_dta_mode_flag = 0x01;
+ ALOGD("%s: DTA Enabled", __FUNCTION__);
+
+}
+#endif
diff --git a/src/adaptation/android_logmsg.cpp b/src/adaptation/android_logmsg.cpp
new file mode 100644
index 0000000..56c4e1b
--- /dev/null
+++ b/src/adaptation/android_logmsg.cpp
@@ -0,0 +1,417 @@
+/******************************************************************************
+ *
+ * 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 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 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;
+ 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 *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;
+ 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 (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)
+ {
+ UNUSED(local_sap);
+ UNUSED(remote_sap);
+ UNUSED(p_buf);
+ UNUSED(is_first);
+ UNUSED(is_rx);
+ }
+ void DispCHO (UINT8 *pMsg, UINT32 MsgLen, BOOLEAN is_rx)
+ {
+ UNUSED(pMsg);
+ UNUSED(MsgLen);
+ UNUSED(is_rx);
+ }
+ void DispT3TagMessage(BT_HDR *p_msg, BOOLEAN is_rx)
+ {
+ UNUSED(p_msg);
+ UNUSED(is_rx);
+ }
+ void DispRWT4Tags (BT_HDR *p_buf, BOOLEAN is_rx)
+ {
+ UNUSED(p_buf);
+ UNUSED(is_rx);
+ }
+ void DispCET4Tags (BT_HDR *p_buf, BOOLEAN is_rx)
+ {
+ UNUSED(p_buf);
+ UNUSED(is_rx);
+ }
+ void DispRWI93Tag (BT_HDR *p_buf, BOOLEAN is_rx, UINT8 command_to_respond)
+ {
+ UNUSED(p_buf);
+ UNUSED(is_rx);
+ UNUSED(command_to_respond);
+ }
+ void DispNDEFMsg (UINT8 *pMsg, UINT32 MsgLen, BOOLEAN is_recv)
+ {
+ UNUSED(pMsg);
+ UNUSED(MsgLen);
+ UNUSED(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/src/adaptation/config.cpp b/src/adaptation/config.cpp
new file mode 100644
index 0000000..7e96e82
--- /dev/null
+++ b/src/adaptation/config.cpp
@@ -0,0 +1,769 @@
+/******************************************************************************
+ *
+ * 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 <string>
+#include <vector>
+#include <list>
+
+#define LOG_TAG "NfcAdaptation"
+
+const char transport_config_path[] = "/etc/";
+
+#define config_name "libnfc-brcm.conf"
+#define extra_config_base "libnfc-brcm-"
+#define extra_config_ext ".conf"
+#define IsStringValue 0x80000000
+
+using namespace::std;
+
+class CNfcParam : public string
+{
+public:
+ CNfcParam();
+ CNfcParam(const char* name, const string& value);
+ CNfcParam(const char* name, unsigned long value);
+ virtual ~CNfcParam();
+ unsigned long numValue() const {return m_numValue;}
+ const char* str_value() const {return m_str_value.c_str();}
+ size_t str_len() const {return m_str_value.length();}
+private:
+ string m_str_value;
+ unsigned long m_numValue;
+};
+
+class CNfcConfig : public vector<const CNfcParam*>
+{
+public:
+ virtual ~CNfcConfig();
+ static CNfcConfig& GetInstance();
+ friend void readOptionalConfig(const char* optional);
+
+ bool getValue(const char* name, char* pValue, size_t& len) const;
+ bool getValue(const char* name, unsigned long& rValue) const;
+ bool getValue(const char* name, unsigned short & rValue) const;
+ const CNfcParam* find(const char* p_name) const;
+ void clean();
+private:
+ CNfcConfig();
+ bool readConfig(const char* name, bool bResetContent);
+ void moveFromList();
+ void moveToList();
+ void add(const CNfcParam* pParam);
+ list<const CNfcParam*> m_list;
+ bool mValidFile;
+
+ unsigned long state;
+
+ inline bool Is(unsigned long f) {return (state & f) == f;}
+ inline void Set(unsigned long f) {state |= f;}
+ inline void Reset(unsigned long f) {state &= ~f;}
+};
+
+/*******************************************************************************
+**
+** Function: isPrintable()
+**
+** Description: detremine if a char is printable
+**
+** Returns: none
+**
+*******************************************************************************/
+inline bool isPrintable(char c)
+{
+ return (c >= 'A' && c <= 'Z') ||
+ (c >= 'a' && c <= 'z') ||
+ (c >= '0' && c <= '9') ||
+ c == '/' || c == '_' || c == '-' || c == '.';
+}
+
+/*******************************************************************************
+**
+** Function: isDigit()
+**
+** Description: detremine if a char is numeral digit
+**
+** Returns: none
+**
+*******************************************************************************/
+inline bool isDigit(char c, int base)
+{
+ if ('0' <= c && c <= '9')
+ return true;
+ if (base == 16)
+ {
+ if (('A' <= c && c <= 'F') ||
+ ('a' <= c && c <= 'f') )
+ return true;
+ }
+ return false;
+}
+
+/*******************************************************************************
+**
+** Function: getDigitValue()
+**
+** Description: return numercal value of a char
+**
+** Returns: none
+**
+*******************************************************************************/
+inline int getDigitValue(char c, int base)
+{
+ if ('0' <= c && c <= '9')
+ return c - '0';
+ if (base == 16)
+ {
+ if ('A' <= c && c <= 'F')
+ return c - 'A' + 10;
+ else if ('a' <= c && c <= 'f')
+ return c - 'a' + 10;
+ }
+ return 0;
+}
+
+/*******************************************************************************
+**
+** Function: CNfcConfig::readConfig()
+**
+** Description: read Config settings and parse them into a linked list
+** move the element from linked list to a array at the end
+**
+** Returns: none
+**
+*******************************************************************************/
+bool CNfcConfig::readConfig(const char* name, bool bResetContent)
+{
+ enum {
+ BEGIN_LINE = 1,
+ TOKEN,
+ STR_VALUE,
+ NUM_VALUE,
+ BEGIN_HEX,
+ BEGIN_QUOTE,
+ END_LINE
+ };
+
+ FILE* fd = NULL;
+ string token;
+ string strValue;
+ unsigned long numValue = 0;
+ CNfcParam* pParam = NULL;
+ int i = 0;
+ int base = 0;
+ char c = 0;
+
+ state = BEGIN_LINE;
+ /* open config file, read it into a buffer */
+ if ((fd = fopen(name, "rb")) == NULL)
+ {
+ ALOGD("%s Cannot open config file %s\n", __func__, name);
+ if (bResetContent)
+ {
+ ALOGD("%s Using default value for all settings\n", __func__);
+ mValidFile = false;
+ }
+ return false;
+ }
+ ALOGD("%s Opened %s config %s\n", __func__, (bResetContent ? "base" : "optional"), name);
+
+ mValidFile = true;
+ if (size() > 0)
+ {
+ if (bResetContent)
+ clean();
+ else
+ moveToList();
+ }
+
+ 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;
+ strPath.assign(transport_config_path);
+ strPath += config_name;
+ theInstance.readConfig(strPath.c_str(), true);
+ }
+
+ return theInstance;
+}
+
+/*******************************************************************************
+**
+** Function: CNfcConfig::getValue()
+**
+** Description: get a string value of a setting
+**
+** Returns: true if setting exists
+** false if setting does not exist
+**
+*******************************************************************************/
+bool CNfcConfig::getValue(const char* name, char* pValue, size_t& len) const
+{
+ const CNfcParam* pParam = find(name);
+ if (pParam == NULL)
+ return false;
+
+ if (pParam->str_len() > 0)
+ {
+ memset(pValue, 0, len);
+ 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;
+ strPath.assign(transport_config_path);
+ strPath += extra_config_base;
+ strPath += extra;
+ strPath += extra_config_ext;
+ CNfcConfig::GetInstance().readConfig(strPath.c_str(), false);
+}
diff --git a/src/adaptation/libmain.c b/src/adaptation/libmain.c
new file mode 100644
index 0000000..7d599c9
--- /dev/null
+++ b/src/adaptation/libmain.c
@@ -0,0 +1,278 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2011-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+#include "OverrideLog.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "buildcfg.h"
+#include "nfa_nv_co.h"
+#include "config.h"
+#include "nfc_hal_target.h"
+#include "nfc_hal_nv_co.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 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 *pBuffer, UINT16 nbytes, UINT8 block)
+{
+ char filename[256], filename2[256];
+
+ memset (filename, 0, sizeof(filename));
+ memset (filename2, 0, sizeof(filename2));
+ strcpy(filename2, bcm_nfc_location);
+ strncat(filename2, sNfaStorageBin, sizeof(filename2)-strlen(filename2)-1);
+ if (strlen(filename2) > 200)
+ {
+ ALOGE ("%s: filename too long", __FUNCTION__);
+ return;
+ }
+ sprintf (filename, "%s%u", filename2, block);
+
+ ALOGD ("%s: buffer len=%u; file=%s", __FUNCTION__, nbytes, filename);
+ int fileStream = open (filename, O_RDONLY);
+ if (fileStream >= 0)
+ {
+ 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", __FUNCTION__, actualReadData);
+ nfa_nv_ci_read (actualReadData, NFA_NV_CO_OK, block);
+ }
+ else
+ {
+ ALOGE ("%s: fail to read", __FUNCTION__);
+ nfa_nv_ci_read (0, NFA_NV_CO_FAIL, block);
+ }
+ }
+ else
+ {
+ ALOGD ("%s: fail to open", __FUNCTION__);
+ nfa_nv_ci_read (0, NFA_NV_CO_FAIL, block);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_nv_co_write
+**
+** Description This function is called by io to send file data to the
+** phone.
+**
+** Parameters pBuffer - buffer to read the data from.
+** nbytes - number of bytes to write out to the file.
+**
+** Returns void
+**
+** Note: Upon completion of the request, nfa_nv_ci_write() is
+** called with the file descriptor and the status. The
+** call-in function should only be called when ALL requested
+** bytes have been written, or an error has been detected,
+**
+*******************************************************************************/
+extern void nfa_nv_co_write(const UINT8 *pBuffer, UINT16 nbytes, UINT8 block)
+{
+ char filename[256], filename2[256];
+
+ memset (filename, 0, sizeof(filename));
+ memset (filename2, 0, sizeof(filename2));
+ strcpy(filename2, bcm_nfc_location);
+ strncat(filename2, sNfaStorageBin, sizeof(filename2)-strlen(filename2)-1);
+ if (strlen(filename2) > 200)
+ {
+ ALOGE ("%s: filename too long", __FUNCTION__);
+ return;
+ }
+ sprintf (filename, "%s%u", filename2, block);
+ ALOGD ("%s: bytes=%u; file=%s", __FUNCTION__, nbytes, filename);
+
+ int fileStream = 0;
+
+ fileStream = open (filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
+ if (fileStream >= 0)
+ {
+ 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", __FUNCTION__, actualWrittenData);
+ if ((actualWrittenData == nbytes) && (actualWrittenCrc == sizeof(checksum)))
+ {
+ nfa_nv_ci_write (NFA_NV_CO_OK);
+ }
+ else
+ {
+ ALOGE ("%s: fail to write", __FUNCTION__);
+ nfa_nv_ci_write (NFA_NV_CO_FAIL);
+ }
+ close (fileStream);
+ }
+ else
+ {
+ ALOGE ("%s: fail to open, error = %d", __FUNCTION__, errno);
+ nfa_nv_ci_write (NFA_NV_CO_FAIL);
+ }
+}
+
+/*******************************************************************************
+**
+** Function 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 (BOOLEAN forceDelete)
+{
+ static BOOLEAN firstTime = TRUE;
+ char filename[256], filename2[256];
+
+ if ((firstTime == FALSE) && (forceDelete == FALSE))
+ return;
+ firstTime = FALSE;
+
+ ALOGD ("%s", __FUNCTION__);
+
+ memset (filename, 0, sizeof(filename));
+ memset (filename2, 0, sizeof(filename2));
+ strcpy(filename2, bcm_nfc_location);
+ strncat(filename2, sNfaStorageBin, sizeof(filename2)-strlen(filename2)-1);
+ if (strlen(filename2) > 200)
+ {
+ ALOGE ("%s: filename too long", __FUNCTION__);
+ return;
+ }
+ sprintf (filename, "%s%u", filename2, DH_NV_BLOCK);
+ remove (filename);
+ sprintf (filename, "%s%u", filename2, HC_F3_NV_BLOCK);
+ remove (filename);
+ sprintf (filename, "%s%u", filename2, HC_F4_NV_BLOCK);
+ remove (filename);
+ sprintf (filename, "%s%u", filename2, HC_F2_NV_BLOCK);
+ remove (filename);
+ sprintf (filename, "%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", __FUNCTION__);
+ char filename[256], filename2[256];
+ BOOLEAN isValid = FALSE;
+
+ memset (filename, 0, sizeof(filename));
+ memset (filename2, 0, sizeof(filename2));
+ strcpy(filename2, bcm_nfc_location);
+ strncat(filename2, sNfaStorageBin, sizeof(filename2)-strlen(filename2)-1);
+ if (strlen(filename2) > 200)
+ {
+ ALOGE ("%s: filename too long", __FUNCTION__);
+ return;
+ }
+
+ sprintf (filename, "%s%u", filename2, DH_NV_BLOCK);
+ if (crcChecksumVerifyIntegrity (filename))
+ {
+ sprintf (filename, "%s%u", filename2, HC_F3_NV_BLOCK);
+ if (crcChecksumVerifyIntegrity (filename))
+ {
+ sprintf (filename, "%s%u", filename2, HC_F4_NV_BLOCK);
+ if (crcChecksumVerifyIntegrity (filename))
+ {
+ sprintf (filename, "%s%u", filename2, HC_F2_NV_BLOCK);
+ if (crcChecksumVerifyIntegrity (filename))
+ {
+ sprintf (filename, "%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..bff6d95
--- /dev/null
+++ b/src/gki/common/gki.h
@@ -0,0 +1,518 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef GKI_H
+#define GKI_H
+
+#ifdef BUILDCFG
+#include "buildcfg.h"
+#endif
+
+/* Include platform-specific over-rides */
+#if (defined(NFC_STANDALONE) && (NFC_STANDALONE == TRUE))
+ #include "gki_target.h"
+#else
+ /* For non-nfc_standalone, include Bluetooth definitions */
+ #include "bt_target.h"
+#endif
+
+
+
+#include "bt_types.h"
+
+/* Uncomment this line for verbose GKI debugging and buffer tracking */
+/*#define GKI_BUFFER_DEBUG TRUE*/
+
+
+/* Error codes */
+#define GKI_SUCCESS 0x00
+#define GKI_FAILURE 0x01
+#define GKI_INVALID_TASK 0xF0
+#define GKI_INVALID_POOL 0xFF
+
+
+/************************************************************************
+** Mailbox definitions. Each task has 4 mailboxes that are used to
+** send buffers to the task.
+*/
+#define TASK_MBOX_0 0
+#define TASK_MBOX_1 1
+#define TASK_MBOX_2 2
+#define TASK_MBOX_3 3
+
+#define NUM_TASK_MBOX 4
+
+/************************************************************************
+** Event definitions.
+**
+** There are 4 reserved events used to signal messages rcvd in task mailboxes.
+** There are 4 reserved events used to signal timeout events.
+** There are 8 general purpose events available for applications.
+*/
+#define MAX_EVENTS 16
+
+#define TASK_MBOX_0_EVT_MASK 0x0001
+#define TASK_MBOX_1_EVT_MASK 0x0002
+#define TASK_MBOX_2_EVT_MASK 0x0004
+#define TASK_MBOX_3_EVT_MASK 0x0008
+
+
+#define TIMER_0 0
+#define TIMER_1 1
+#define TIMER_2 2
+#define TIMER_3 3
+
+#define TIMER_0_EVT_MASK 0x0010
+#define TIMER_1_EVT_MASK 0x0020
+#define TIMER_2_EVT_MASK 0x0040
+#define TIMER_3_EVT_MASK 0x0080
+
+#define APPL_EVT_0 8
+#define APPL_EVT_1 9
+#define APPL_EVT_2 10
+#define APPL_EVT_3 11
+#define APPL_EVT_4 12
+#define APPL_EVT_5 13
+#define APPL_EVT_6 14
+#define APPL_EVT_7 15
+
+#define EVENT_MASK(evt) ((UINT16)(0x0001 << (evt)))
+
+/************************************************************************
+** Max Time Queue
+**/
+#ifndef GKI_MAX_TIMER_QUEUES
+#define GKI_MAX_TIMER_QUEUES 3
+#endif
+
+/************************************************************************
+** Utility macros for timer conversion
+**/
+#ifdef TICKS_PER_SEC
+#define GKI_MS_TO_TICKS(x) ((x) / (1000/TICKS_PER_SEC))
+#define GKI_SECS_TO_TICKS(x) ((x) * (TICKS_PER_SEC))
+#define GKI_TICKS_TO_MS(x) ((x) * (1000/TICKS_PER_SEC))
+#define GKI_TICKS_TO_SECS(x) ((x) * (1/TICKS_PER_SEC))
+#endif
+
+
+/************************************************************************
+** Macro to determine the pool buffer size based on the GKI POOL ID at compile time.
+** Pool IDs index from 0 to GKI_NUM_FIXED_BUF_POOLS - 1
+*/
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 1)
+
+#ifndef GKI_POOL_ID_0
+#define GKI_POOL_ID_0 0
+#endif /* ifndef GKI_POOL_ID_0 */
+
+#ifndef GKI_BUF0_SIZE
+#define GKI_BUF0_SIZE 0
+#endif /* ifndef GKI_BUF0_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 1 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 2)
+
+#ifndef GKI_POOL_ID_1
+#define GKI_POOL_ID_1 0
+#endif /* ifndef GKI_POOL_ID_1 */
+
+#ifndef GKI_BUF1_SIZE
+#define GKI_BUF1_SIZE 0
+#endif /* ifndef GKI_BUF1_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 2 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 3)
+
+#ifndef GKI_POOL_ID_2
+#define GKI_POOL_ID_2 0
+#endif /* ifndef GKI_POOL_ID_2 */
+
+#ifndef GKI_BUF2_SIZE
+#define GKI_BUF2_SIZE 0
+#endif /* ifndef GKI_BUF2_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 3 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 4)
+
+#ifndef GKI_POOL_ID_3
+#define GKI_POOL_ID_3 0
+#endif /* ifndef GKI_POOL_ID_4 */
+
+#ifndef GKI_BUF3_SIZE
+#define GKI_BUF3_SIZE 0
+#endif /* ifndef GKI_BUF3_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 4 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 5)
+
+#ifndef GKI_POOL_ID_4
+#define GKI_POOL_ID_4 0
+#endif /* ifndef GKI_POOL_ID_4 */
+
+#ifndef GKI_BUF4_SIZE
+#define GKI_BUF4_SIZE 0
+#endif /* ifndef GKI_BUF4_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 5 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 6)
+
+#ifndef GKI_POOL_ID_5
+#define GKI_POOL_ID_5 0
+#endif /* ifndef GKI_POOL_ID_5 */
+
+#ifndef GKI_BUF5_SIZE
+#define GKI_BUF5_SIZE 0
+#endif /* ifndef GKI_BUF5_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 6 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 7)
+
+#ifndef GKI_POOL_ID_6
+#define GKI_POOL_ID_6 0
+#endif /* ifndef GKI_POOL_ID_6 */
+
+#ifndef GKI_BUF6_SIZE
+#define GKI_BUF6_SIZE 0
+#endif /* ifndef GKI_BUF6_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 7 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 8)
+
+#ifndef GKI_POOL_ID_7
+#define GKI_POOL_ID_7 0
+#endif /* ifndef GKI_POOL_ID_7 */
+
+#ifndef GKI_BUF7_SIZE
+#define GKI_BUF7_SIZE 0
+#endif /* ifndef GKI_BUF7_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 8 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 9)
+
+#ifndef GKI_POOL_ID_8
+#define GKI_POOL_ID_8 0
+#endif /* ifndef GKI_POOL_ID_8 */
+
+#ifndef GKI_BUF8_SIZE
+#define GKI_BUF8_SIZE 0
+#endif /* ifndef GKI_BUF8_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 9 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 10)
+
+#ifndef GKI_POOL_ID_9
+#define GKI_POOL_ID_9 0
+#endif /* ifndef GKI_POOL_ID_9 */
+
+#ifndef GKI_BUF9_SIZE
+#define GKI_BUF9_SIZE 0
+#endif /* ifndef GKI_BUF9_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 10 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 11)
+
+#ifndef GKI_POOL_ID_10
+#define GKI_POOL_ID_10 0
+#endif /* ifndef GKI_POOL_ID_10 */
+
+#ifndef GKI_BUF10_SIZE
+#define GKI_BUF10_SIZE 0
+#endif /* ifndef GKI_BUF10_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 11 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 12)
+
+#ifndef GKI_POOL_ID_11
+#define GKI_POOL_ID_11 0
+#endif /* ifndef GKI_POOL_ID_11 */
+
+#ifndef GKI_BUF11_SIZE
+#define GKI_BUF11_SIZE 0
+#endif /* ifndef GKI_BUF11_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 12 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 13)
+
+#ifndef GKI_POOL_ID_12
+#define GKI_POOL_ID_12 0
+#endif /* ifndef GKI_POOL_ID_12 */
+
+#ifndef GKI_BUF12_SIZE
+#define GKI_BUF12_SIZE 0
+#endif /* ifndef GKI_BUF12_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 13 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 14)
+
+#ifndef GKI_POOL_ID_13
+#define GKI_POOL_ID_13 0
+#endif /* ifndef GKI_POOL_ID_13 */
+
+#ifndef GKI_BUF13_SIZE
+#define GKI_BUF13_SIZE 0
+#endif /* ifndef GKI_BUF13_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 14 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 15)
+
+#ifndef GKI_POOL_ID_14
+#define GKI_POOL_ID_14 0
+#endif /* ifndef GKI_POOL_ID_14 */
+
+#ifndef GKI_BUF14_SIZE
+#define GKI_BUF14_SIZE 0
+#endif /* ifndef GKI_BUF14_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 15 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 16)
+
+#ifndef GKI_POOL_ID_15
+#define GKI_POOL_ID_15 0
+#endif /* ifndef GKI_POOL_ID_15 */
+
+#ifndef GKI_BUF15_SIZE
+#define GKI_BUF15_SIZE 0
+#endif /* ifndef GKI_BUF15_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 16 */
+
+
+/* Timer list entry callback type
+*/
+typedef void (TIMER_CBACK)(void *p_tle);
+#ifndef TIMER_PARAM_TYPE
+#ifdef WIN2000
+#define TIMER_PARAM_TYPE void *
+#else
+#define TIMER_PARAM_TYPE UINT32
+#endif
+#endif
+/* Define a timer list entry
+*/
+typedef struct _tle
+{
+ struct _tle *p_next;
+ struct _tle *p_prev;
+ TIMER_CBACK *p_cback;
+ INT32 ticks;
+ TIMER_PARAM_TYPE param;
+ UINT16 event;
+ UINT8 in_use;
+} TIMER_LIST_ENT;
+
+/* Define a timer list queue
+*/
+typedef struct
+{
+ TIMER_LIST_ENT *p_first;
+ TIMER_LIST_ENT *p_last;
+ INT32 last_ticks;
+} TIMER_LIST_Q;
+
+
+/***********************************************************************
+** This queue is a general purpose buffer queue, for application use.
+*/
+typedef struct
+{
+ void *p_first;
+ void *p_last;
+ UINT16 count;
+} BUFFER_Q;
+
+#define GKI_IS_QUEUE_EMPTY(p_q) ((p_q)->count == 0)
+
+/* Task constants
+*/
+#ifndef TASKPTR
+typedef void (*TASKPTR)(UINT32);
+#endif
+
+
+#define GKI_PUBLIC_POOL 0 /* General pool accessible to GKI_getbuf() */
+#define GKI_RESTRICTED_POOL 1 /* Inaccessible pool to GKI_getbuf() */
+
+/***********************************************************************
+** Function prototypes
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Task management
+*/
+GKI_API extern UINT8 GKI_create_task (TASKPTR, UINT8, INT8 *, UINT16 *, UINT16, void*, void*);
+GKI_API extern void GKI_exit_task(UINT8);
+GKI_API extern UINT8 GKI_get_taskid(void);
+GKI_API extern void GKI_init(void);
+GKI_API extern INT8 *GKI_map_taskname(UINT8);
+GKI_API extern UINT8 GKI_resume_task(UINT8);
+GKI_API extern void GKI_run(void *);
+GKI_API extern void GKI_stop(void);
+GKI_API extern UINT8 GKI_suspend_task(UINT8);
+GKI_API extern UINT8 GKI_is_task_running(UINT8);
+
+/* memory management
+*/
+GKI_API extern void GKI_shiftdown (UINT8 *p_mem, UINT32 len, UINT32 shift_amount);
+GKI_API extern void GKI_shiftup (UINT8 *p_dest, UINT8 *p_src, UINT32 len);
+
+/* To send buffers and events between tasks
+*/
+GKI_API extern UINT8 GKI_isend_event (UINT8, UINT16);
+GKI_API extern void GKI_isend_msg (UINT8, UINT8, void *);
+GKI_API extern void *GKI_read_mbox (UINT8);
+GKI_API extern void GKI_send_msg (UINT8, UINT8, void *);
+GKI_API extern UINT8 GKI_send_event (UINT8, UINT16);
+
+
+/* To get and release buffers, change owner and get size
+*/
+GKI_API extern void GKI_change_buf_owner (void *, UINT8);
+GKI_API extern UINT8 GKI_create_pool (UINT16, UINT16, UINT8, void *);
+GKI_API extern void GKI_delete_pool (UINT8);
+GKI_API extern void *GKI_find_buf_start (void *);
+GKI_API extern void GKI_freebuf (void *);
+#if GKI_BUFFER_DEBUG
+#define GKI_getbuf(size) GKI_getbuf_debug(size, __FUNCTION__, __LINE__)
+GKI_API extern void *GKI_getbuf_debug (UINT16, const char *, int);
+#else
+GKI_API extern void *GKI_getbuf (UINT16);
+#endif
+GKI_API extern UINT16 GKI_get_buf_size (void *);
+#if GKI_BUFFER_DEBUG
+#define GKI_getpoolbuf(id) GKI_getpoolbuf_debug(id, __FUNCTION__, __LINE__)
+GKI_API extern void *GKI_getpoolbuf_debug (UINT8, const char *, int);
+#else
+GKI_API extern void *GKI_getpoolbuf (UINT8);
+#endif
+
+GKI_API extern UINT16 GKI_poolcount (UINT8);
+GKI_API extern UINT16 GKI_poolfreecount (UINT8);
+GKI_API extern UINT16 GKI_poolutilization (UINT8);
+GKI_API extern void GKI_register_mempool (void *p_mem);
+GKI_API extern UINT8 GKI_set_pool_permission(UINT8, UINT8);
+
+
+/* User buffer queue management
+*/
+GKI_API extern void *GKI_dequeue (BUFFER_Q *);
+GKI_API extern void GKI_enqueue (BUFFER_Q *, void *);
+GKI_API extern void GKI_enqueue_head (BUFFER_Q *, void *);
+GKI_API extern void *GKI_getfirst (BUFFER_Q *);
+GKI_API extern void *GKI_getlast (BUFFER_Q *);
+GKI_API extern void *GKI_getnext (void *);
+GKI_API extern void GKI_init_q (BUFFER_Q *);
+GKI_API extern BOOLEAN GKI_queue_is_empty(BUFFER_Q *);
+GKI_API extern void *GKI_remove_from_queue (BUFFER_Q *, void *);
+GKI_API extern UINT16 GKI_get_pool_bufsize (UINT8);
+
+/* Timer management
+*/
+GKI_API extern void GKI_add_to_timer_list (TIMER_LIST_Q *, TIMER_LIST_ENT *);
+GKI_API extern void GKI_delay(UINT32);
+GKI_API extern UINT32 GKI_get_tick_count(void);
+GKI_API extern INT8 *GKI_get_time_stamp(INT8 *);
+GKI_API extern void GKI_init_timer_list (TIMER_LIST_Q *);
+GKI_API extern void GKI_init_timer_list_entry (TIMER_LIST_ENT *);
+GKI_API extern INT32 GKI_ready_to_sleep (void);
+GKI_API extern void GKI_remove_from_timer_list (TIMER_LIST_Q *, TIMER_LIST_ENT *);
+GKI_API extern void GKI_start_timer(UINT8, INT32, BOOLEAN);
+GKI_API extern void GKI_stop_timer (UINT8);
+GKI_API extern void GKI_timer_update(INT32);
+GKI_API extern UINT16 GKI_update_timer_list (TIMER_LIST_Q *, INT32);
+GKI_API extern UINT32 GKI_get_remaining_ticks (TIMER_LIST_Q *, TIMER_LIST_ENT *);
+GKI_API extern UINT16 GKI_wait(UINT16, UINT32);
+
+/* Start and Stop system time tick callback
+ * true for start system tick if time queue is not empty
+ * false to stop system tick if time queue is empty
+*/
+typedef void (SYSTEM_TICK_CBACK)(BOOLEAN);
+
+/* Time queue management for system ticks
+*/
+GKI_API extern BOOLEAN GKI_timer_queue_empty (void);
+GKI_API extern void GKI_timer_queue_register_callback(SYSTEM_TICK_CBACK *);
+
+/* Disable Interrupts, Enable Interrupts
+*/
+GKI_API extern void GKI_enable(void);
+GKI_API extern void GKI_disable(void);
+GKI_API extern void GKI_sched_lock(void);
+GKI_API extern void GKI_sched_unlock(void);
+
+/* Allocate (Free) memory from an OS
+*/
+GKI_API extern void *GKI_os_malloc (UINT32);
+GKI_API extern void GKI_os_free (void *);
+
+/* os timer operation */
+GKI_API extern UINT32 GKI_get_os_tick_count(void);
+
+/* Exception handling
+*/
+GKI_API extern void GKI_exception (UINT16, char *);
+
+#if GKI_DEBUG == TRUE
+GKI_API extern void GKI_PrintBufferUsage(UINT8 *p_num_pools, UINT16 *p_cur_used);
+GKI_API extern void GKI_PrintBuffer(void);
+GKI_API extern void GKI_print_task(void);
+#else
+#undef GKI_PrintBufferUsage
+#define GKI_PrintBuffer() NULL
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/src/gki/common/gki_buffer.c b/src/gki/common/gki_buffer.c
new file mode 100644
index 0000000..edf353f
--- /dev/null
+++ b/src/gki/common/gki_buffer.c
@@ -0,0 +1,1558 @@
+/******************************************************************************
+ *
+ * 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/src/gki/common/gki_common.h b/src/gki/common/gki_common.h
new file mode 100644
index 0000000..5e51f5d
--- /dev/null
+++ b/src/gki/common/gki_common.h
@@ -0,0 +1,416 @@
+/******************************************************************************
+ *
+ * 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"
+#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
+*/
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define ALIGN_POOL(pl_size) ( (((pl_size) + (sizeof(UINT32)-1)) / sizeof(UINT32)) * sizeof(UINT32))
+#else
+#define ALIGN_POOL(pl_size) ( (((pl_size) + 3) / sizeof(UINT32)) * sizeof(UINT32))
+#endif
+#define BUFFER_HDR_SIZE (sizeof(BUFFER_HDR_T)) /* Offset past header */
+#define BUFFER_PADDING_SIZE (sizeof(BUFFER_HDR_T) + sizeof(UINT32)) /* Header + Magic Number */
+#define MAX_USER_BUF_SIZE ((UINT16)0xffff - BUFFER_PADDING_SIZE) /* pool size must allow for header */
+#define MAGIC_NO 0xDDBADDBA
+
+#define BUF_STATUS_FREE 0
+#define BUF_STATUS_UNLINKED 1
+#define BUF_STATUS_QUEUED 2
+
+#define GKI_USE_DEFERED_ALLOC_BUF_POOLS
+
+/* Exception related structures (Used in debug mode only)
+*/
+#if (GKI_DEBUG == TRUE)
+typedef struct
+{
+ UINT16 type;
+ UINT8 taskid;
+ UINT8 msg[GKI_MAX_EXCEPTION_MSGLEN];
+} EXCEPTION_T;
+#endif
+
+
+/* Put all GKI variables into one control block
+*/
+typedef struct
+{
+ /* Task management variables
+ */
+ /* The stack and stack size are not used on Windows
+ */
+#if (!defined GKI_USE_DEFERED_ALLOC_BUF_POOLS && (GKI_USE_DYNAMIC_BUFFERS == FALSE))
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 0)
+ UINT8 bufpool0[(ALIGN_POOL(GKI_BUF0_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF0_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 1)
+ UINT8 bufpool1[(ALIGN_POOL(GKI_BUF1_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF1_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 2)
+ UINT8 bufpool2[(ALIGN_POOL(GKI_BUF2_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF2_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 3)
+ UINT8 bufpool3[(ALIGN_POOL(GKI_BUF3_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF3_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 4)
+ UINT8 bufpool4[(ALIGN_POOL(GKI_BUF4_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF4_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 5)
+ UINT8 bufpool5[(ALIGN_POOL(GKI_BUF5_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF5_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 6)
+ UINT8 bufpool6[(ALIGN_POOL(GKI_BUF6_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF6_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 7)
+ UINT8 bufpool7[(ALIGN_POOL(GKI_BUF7_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF7_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 8)
+ UINT8 bufpool8[(ALIGN_POOL(GKI_BUF8_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF8_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 9)
+ UINT8 bufpool9[(ALIGN_POOL(GKI_BUF9_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF9_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 10)
+ UINT8 bufpool10[(ALIGN_POOL(GKI_BUF10_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF10_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 11)
+ UINT8 bufpool11[(ALIGN_POOL(GKI_BUF11_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF11_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 12)
+ UINT8 bufpool12[(ALIGN_POOL(GKI_BUF12_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF12_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 13)
+ UINT8 bufpool13[(ALIGN_POOL(GKI_BUF13_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF13_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 14)
+ UINT8 bufpool14[(ALIGN_POOL(GKI_BUF14_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF14_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 15)
+ UINT8 bufpool15[(ALIGN_POOL(GKI_BUF15_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF15_MAX];
+#endif
+
+#else
+/* Definitions for dynamic buffer use */
+#if (GKI_NUM_FIXED_BUF_POOLS > 0)
+ UINT8 *bufpool0;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 1)
+ UINT8 *bufpool1;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 2)
+ UINT8 *bufpool2;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 3)
+ UINT8 *bufpool3;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 4)
+ UINT8 *bufpool4;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 5)
+ UINT8 *bufpool5;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 6)
+ UINT8 *bufpool6;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 7)
+ UINT8 *bufpool7;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 8)
+ UINT8 *bufpool8;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 9)
+ UINT8 *bufpool9;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 10)
+ UINT8 *bufpool10;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 11)
+ UINT8 *bufpool11;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 12)
+ UINT8 *bufpool12;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 13)
+ UINT8 *bufpool13;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 14)
+ UINT8 *bufpool14;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 15)
+ UINT8 *bufpool15;
+#endif
+
+#endif
+
+ UINT8 *OSStack[GKI_MAX_TASKS]; /* pointer to beginning of stack */
+ UINT16 OSStackSize[GKI_MAX_TASKS]; /* stack size available to each task */
+
+
+ INT8 *OSTName[GKI_MAX_TASKS]; /* name of the task */
+
+ UINT8 OSRdyTbl[GKI_MAX_TASKS]; /* current state of the task */
+ UINT16 OSWaitEvt[GKI_MAX_TASKS]; /* events that have to be processed by the task */
+ UINT16 OSWaitForEvt[GKI_MAX_TASKS]; /* events the task is waiting for*/
+
+ UINT32 OSTicks; /* system ticks from start */
+ UINT32 OSIdleCnt; /* idle counter */
+ INT16 OSDisableNesting; /* counter to keep track of interrupt disable nesting */
+ INT16 OSLockNesting; /* counter to keep track of sched lock nesting */
+ INT16 OSIntNesting; /* counter to keep track of interrupt nesting */
+
+ /* Timer related variables
+ */
+ INT32 OSTicksTilExp; /* Number of ticks till next timer expires */
+#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
+ UINT32 OSTicksTilStop; /* inactivity delay timer; OS Ticks till stopping system tick */
+#endif
+ INT32 OSNumOrigTicks; /* Number of ticks between last timer expiration to the next one */
+
+ INT32 OSWaitTmr [GKI_MAX_TASKS]; /* ticks the task has to wait, for specific events */
+
+ /* Only take up space timers used in the system (GKI_NUM_TIMERS defined in target.h) */
+#if (GKI_NUM_TIMERS > 0)
+ INT32 OSTaskTmr0 [GKI_MAX_TASKS];
+ INT32 OSTaskTmr0R [GKI_MAX_TASKS];
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+ INT32 OSTaskTmr1 [GKI_MAX_TASKS];
+ INT32 OSTaskTmr1R [GKI_MAX_TASKS];
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+ INT32 OSTaskTmr2 [GKI_MAX_TASKS];
+ INT32 OSTaskTmr2R [GKI_MAX_TASKS];
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+ INT32 OSTaskTmr3 [GKI_MAX_TASKS];
+ INT32 OSTaskTmr3R [GKI_MAX_TASKS];
+#endif
+
+
+
+ /* Buffer related variables
+ */
+ BUFFER_HDR_T *OSTaskQFirst[GKI_MAX_TASKS][NUM_TASK_MBOX]; /* array of pointers to the first event in the task mailbox */
+ BUFFER_HDR_T *OSTaskQLast [GKI_MAX_TASKS][NUM_TASK_MBOX]; /* array of pointers to the last event in the task mailbox */
+
+ /* Define the buffer pool management variables
+ */
+ FREE_QUEUE_T freeq[GKI_NUM_TOTAL_BUF_POOLS];
+
+ UINT16 pool_buf_size[GKI_NUM_TOTAL_BUF_POOLS];
+ UINT16 pool_max_count[GKI_NUM_TOTAL_BUF_POOLS];
+ UINT16 pool_additions[GKI_NUM_TOTAL_BUF_POOLS];
+
+ /* Define the buffer pool start addresses
+ */
+ UINT8 *pool_start[GKI_NUM_TOTAL_BUF_POOLS]; /* array of pointers to the start of each buffer pool */
+ UINT8 *pool_end[GKI_NUM_TOTAL_BUF_POOLS]; /* array of pointers to the end of each buffer pool */
+ UINT16 pool_size[GKI_NUM_TOTAL_BUF_POOLS]; /* actual size of the buffers in a pool */
+
+ /* Define the buffer pool access control variables */
+ void *p_user_mempool; /* User O/S memory pool */
+ UINT16 pool_access_mask; /* Bits are set if the corresponding buffer pool is a restricted pool */
+ UINT8 pool_list[GKI_NUM_TOTAL_BUF_POOLS]; /* buffer pools arranged in the order of size */
+ UINT8 curr_total_no_of_pools; /* number of fixed buf pools + current number of dynamic pools */
+
+ BOOLEAN timer_nesting; /* flag to prevent timer interrupt nesting */
+
+ /* Time queue arrays */
+ TIMER_LIST_Q *timer_queues[GKI_MAX_TIMER_QUEUES];
+ /* System tick callback */
+ SYSTEM_TICK_CBACK *p_tick_cb;
+ BOOLEAN system_tick_running; /* TRUE if system tick is running. Valid only if p_tick_cb is not NULL */
+
+#if (GKI_DEBUG == TRUE)
+ UINT16 ExceptionCnt; /* number of GKI exceptions that have happened */
+ EXCEPTION_T Exception[GKI_MAX_EXCEPTION];
+#endif
+
+} tGKI_COM_CB;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Internal GKI function prototypes
+*/
+GKI_API extern BOOLEAN gki_chk_buf_damage(void *);
+extern BOOLEAN gki_chk_buf_owner(void *);
+extern void gki_buffer_init (void);
+extern void gki_timers_init(void);
+extern void gki_adjust_timer_count (INT32);
+
+extern void OSStartRdy(void);
+extern void OSCtxSw(void);
+extern void OSIntCtxSw(void);
+extern void OSSched(void);
+extern void OSIntEnter(void);
+extern void OSIntExit(void);
+
+
+/* Debug aids
+*/
+typedef void (*FP_PRINT)(char *, ...);
+
+#if (GKI_DEBUG == TRUE)
+
+typedef void (*PKT_PRINT)(UINT8 *, UINT16);
+
+extern void gki_print_task(FP_PRINT);
+extern void gki_print_exception(FP_PRINT);
+extern void gki_print_timer(FP_PRINT);
+extern void gki_print_stack(FP_PRINT);
+extern void gki_print_buffer(FP_PRINT);
+extern void gki_print_buffer_statistics(FP_PRINT, INT16);
+GKI_API extern void gki_print_used_bufs (FP_PRINT, UINT8);
+extern void gki_dump(UINT8 *, UINT16, FP_PRINT);
+extern void gki_dump2(UINT16 *, UINT16, FP_PRINT);
+extern void gki_dump4(UINT32 *, UINT16, FP_PRINT);
+
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/gki/common/gki_debug.c b/src/gki/common/gki_debug.c
new file mode 100644
index 0000000..5e95314
--- /dev/null
+++ b/src/gki/common/gki_debug.c
@@ -0,0 +1,353 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+#include "gki_int.h"
+
+#if (GKI_DEBUG == TRUE)
+
+const INT8 * const OSTaskStates[] =
+{
+ (INT8 *)"DEAD", /* 0 */
+ (INT8 *)"REDY", /* 1 */
+ (INT8 *)"WAIT", /* 2 */
+ (INT8 *)"",
+ (INT8 *)"DELY", /* 4 */
+ (INT8 *)"",
+ (INT8 *)"",
+ (INT8 *)"",
+ (INT8 *)"SUSP", /* 8 */
+};
+
+
+/*******************************************************************************
+**
+** Function GKI_PrintBufferUsage
+**
+** Description Displays Current Buffer Pool summary
+**
+** Returns void
+**
+*******************************************************************************/
+void GKI_PrintBufferUsage(UINT8 *p_num_pools, UINT16 *p_cur_used)
+{
+ int i;
+ FREE_QUEUE_T *p;
+ UINT8 num = gki_cb.com.curr_total_no_of_pools;
+ UINT16 cur[GKI_NUM_TOTAL_BUF_POOLS];
+
+ GKI_TRACE_0("");
+ GKI_TRACE_0("--- GKI Buffer Pool Summary (R - restricted, P - public) ---");
+
+ GKI_TRACE_0("POOL SIZE USED MAXU TOTAL");
+ GKI_TRACE_0("------------------------------");
+ for (i = 0; i < gki_cb.com.curr_total_no_of_pools; i++)
+ {
+ p = &gki_cb.com.freeq[i];
+ if ((1 << i) & gki_cb.com.pool_access_mask)
+ {
+ GKI_TRACE_5("%02d: (R), %4d, %3d, %3d, %3d",
+ i, p->size, p->cur_cnt, p->max_cnt, p->total);
+ }
+ else
+ {
+ GKI_TRACE_5("%02d: (P), %4d, %3d, %3d, %3d",
+ i, p->size, p->cur_cnt, p->max_cnt, p->total);
+ }
+ cur[i] = p->cur_cnt;
+ }
+ if (p_num_pools)
+ *p_num_pools = num;
+ if (p_cur_used)
+ memcpy(p_cur_used, cur, num*2);
+}
+
+/*******************************************************************************
+**
+** Function GKI_PrintBuffer
+**
+** Description Called internally by OSS to print the buffer pools
+**
+** Returns void
+**
+*******************************************************************************/
+void GKI_PrintBuffer(void)
+{
+ UINT16 i;
+ for(i=0; i<GKI_NUM_TOTAL_BUF_POOLS; i++)
+ {
+ GKI_TRACE_5("pool:%4u free %4u cur %3u max %3u total%3u", i, gki_cb.com.freeq[i].size,
+ gki_cb.com.freeq[i].cur_cnt, gki_cb.com.freeq[i].max_cnt, gki_cb.com.freeq[i].total);
+ }
+}
+
+/*******************************************************************************
+**
+** Function gki_calc_stack
+**
+** Description This function tries to calculate the amount of
+** stack used by looking non magic num. Magic num is consider
+** the first byte in the stack.
+**
+** Returns the number of unused byte on the stack. 4 in case of stack overrun
+**
+*******************************************************************************/
+UINT16 gki_calc_stack (UINT8 task)
+{
+ int j, stacksize;
+ UINT32 MagicNum;
+ UINT32 *p;
+
+ stacksize = (int) gki_cb.com.OSStackSize[task];
+ p = (UINT32 *)gki_cb.com.OSStack[task]; /* assume stack is aligned, */
+ MagicNum = *p;
+
+ for(j = 0; j < stacksize; j++)
+ {
+ if(*p++ != MagicNum) break;
+ }
+
+ return (j * sizeof(UINT32));
+}
+
+/*******************************************************************************
+**
+** Function GKI_print_task
+**
+** Description Print task stack usage.
+**
+** Returns void
+**
+*******************************************************************************/
+void GKI_print_task(void)
+{
+#ifdef _BT_WIN32
+ GKI_TRACE_0("Service not available under insight");
+#else
+ UINT8 TaskId;
+
+ GKI_TRACE_0("TID TASKNAME STATE FREE_STACK STACK");
+ for(TaskId=0; TaskId < GKI_MAX_TASKS; TaskId++)
+ {
+ if (gki_cb.com.OSRdyTbl[TaskId] != TASK_DEAD)
+ {
+ GKI_TRACE_5("%2u %-8s %-5s 0x%04X 0x%04X Bytes",
+ (UINT16)TaskId, gki_cb.com.OSTName[TaskId],
+ OSTaskStates[gki_cb.com.OSRdyTbl[TaskId]],
+ gki_calc_stack(TaskId), gki_cb.com.OSStackSize[TaskId]);
+
+ }
+ }
+#endif
+}
+
+
+/*******************************************************************************
+**
+** Function gki_print_buffer_statistics
+**
+** Description Called internally by OSS to print the buffer pools statistics
+**
+** Returns void
+**
+*******************************************************************************/
+void gki_print_buffer_statistics(FP_PRINT print, INT16 pool)
+{
+ UINT16 i;
+ BUFFER_HDR_T *hdr;
+ UINT16 size,act_size,maxbuffs;
+ UINT32 *magic;
+
+ if (pool > GKI_NUM_TOTAL_BUF_POOLS || pool < 0)
+ {
+ print("Not a valid Buffer pool\n");
+ return;
+ }
+
+ size = gki_cb.com.freeq[pool].size;
+ maxbuffs = gki_cb.com.freeq[pool].total;
+ act_size = size + BUFFER_PADDING_SIZE;
+ print("Buffer Pool[%u] size=%u cur_cnt=%u max_cnt=%u total=%u\n",
+ pool, gki_cb.com.freeq[pool].size,
+ gki_cb.com.freeq[pool].cur_cnt, gki_cb.com.freeq[pool].max_cnt, gki_cb.com.freeq[pool].total);
+
+ print(" Owner State Sanity\n");
+ print("----------------------------\n");
+ hdr = (BUFFER_HDR_T *)(gki_cb.com.pool_start[pool]);
+ for(i=0; i<maxbuffs; i++)
+ {
+ magic = (UINT32 *)((UINT8 *)hdr + BUFFER_HDR_SIZE + size);
+ print("%3d: 0x%02x %4d %10s\n", i, hdr->task_id, hdr->status, (*magic == MAGIC_NO)?"OK":"CORRUPTED");
+ hdr = (BUFFER_HDR_T *)((UINT8 *)hdr + act_size);
+ }
+ return;
+}
+
+
+/*******************************************************************************
+**
+** Function gki_print_used_bufs
+**
+** Description Dumps used buffers in the particular pool
+**
+*******************************************************************************/
+GKI_API void gki_print_used_bufs (FP_PRINT print, UINT8 pool_id)
+{
+ UINT8 *p_start;
+ UINT16 buf_size;
+ UINT16 num_bufs;
+ BUFFER_HDR_T *p_hdr;
+ UINT16 i;
+ UINT32 *magic;
+ UINT16 *p;
+
+
+ if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS && gki_cb.com.pool_start[pool_id] != 0)
+ {
+ print("Not a valid Buffer pool\n");
+ return;
+ }
+
+ p_start = gki_cb.com.pool_start[pool_id];
+ buf_size = gki_cb.com.freeq[pool_id].size + BUFFER_PADDING_SIZE;
+ num_bufs = gki_cb.com.freeq[pool_id].total;
+
+ for (i = 0; i < num_bufs; i++, p_start += buf_size)
+ {
+ p_hdr = (BUFFER_HDR_T *)p_start;
+ magic = (UINT32 *)((UINT8 *)p_hdr + buf_size - sizeof(UINT32));
+ p = (UINT16 *) p_hdr;
+
+ if (p_hdr->status != BUF_STATUS_FREE)
+ {
+ print ("%d:0x%x (Q:%d,Task:%s,Stat:%d,%s) %04x %04x %04x %04x %04x %04x %04x %04x\n",
+ i, p_hdr,
+ p_hdr->q_id,
+ GKI_map_taskname(p_hdr->task_id),
+ p_hdr->status,
+ (*magic == MAGIC_NO)? "OK" : "CORRUPTED",
+ p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+ }
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function gki_print_task
+**
+** Description This function prints the task states.
+**
+** Returns void
+**
+*******************************************************************************/
+void gki_print_task (FP_PRINT print)
+{
+ UINT8 i;
+
+ print("TID VID TASKNAME STATE WAIT WAITFOR TIMEOUT STACK\n");
+ print("-------------------------------------------------\n");
+ for(i=0; i<GKI_MAX_TASKS; i++)
+ {
+ if (gki_cb.com.OSRdyTbl[i] != TASK_DEAD)
+ {
+ print("%2u %-8s %-5s %04X %04X %7u %u/%u Bytes\n",
+ (UINT16)i, gki_cb.com.OSTName[i],
+ OSTaskStates[gki_cb.com.OSRdyTbl[i]],
+ gki_cb.com.OSWaitEvt[i], gki_cb.com.OSWaitForEvt[i],
+ gki_cb.com.OSWaitTmr[i], gki_calc_stack(i), gki_cb.com.OSStackSize[i]);
+ }
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function gki_print_exception
+**
+** Description This function prints the exception information.
+**
+** Returns void
+**
+*******************************************************************************/
+void gki_print_exception(FP_PRINT print)
+{
+ UINT16 i;
+ EXCEPTION_T *pExp;
+
+ print ("GKI Exceptions:\n");
+ for (i = 0; i < gki_cb.com.ExceptionCnt; i++)
+ {
+ pExp = &gki_cb.com.Exception[i];
+ print("%d: Type=%d, Task=%d: %s\n", i,
+ (INT32)pExp->type, (INT32)pExp->taskid, (INT8 *)pExp->msg);
+ }
+}
+
+
+/*****************************************************************************/
+void gki_dump (UINT8 *s, UINT16 len, FP_PRINT print)
+{
+ UINT16 i, j;
+
+ for(i=0, j=0; i<len; i++)
+ {
+ if(j == 0)
+ print("\n%lX: %02X, ", &s[i], s[i]);
+ else if(j == 7)
+ print("%02X, ", s[i]);
+ else
+ print("%02X, ", s[i]);
+ if(++j == 16)
+ j=0;
+ }
+ print("\n");
+}
+
+void gki_dump2 (UINT16 *s, UINT16 len, FP_PRINT print)
+{
+ UINT16 i, j;
+
+ for(i=0, j=0; i<len; i++)
+ {
+ if(j == 0)
+ print("\n%lX: %04X, ", &s[i], s[i]);
+ else
+ print("%04X, ", s[i]);
+ if(++j == 8)
+ j=0;
+ }
+ print("\n");
+}
+
+void gki_dump4 (UINT32 *s, UINT16 len, FP_PRINT print)
+{
+ UINT16 i, j;
+
+ for(i=0, j=0; i<len; i++)
+ {
+ if(j == 0)
+ print("\n%lX: %08lX, ", &s[i], s[i]);
+ else
+ print("%08lX, ", s[i]);
+ if(++j == 4)
+ j=0;
+ }
+ print("\n");
+}
+
+
+#endif
diff --git a/src/gki/common/gki_inet.h b/src/gki/common/gki_inet.h
new file mode 100644
index 0000000..e99b38c
--- /dev/null
+++ b/src/gki/common/gki_inet.h
@@ -0,0 +1,46 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef GKI_INET_H
+#define GKI_INET_H
+
+#include "data_types.h"
+
+#define htons ntohs
+#define htonl ntohl
+
+#define htonets nettohs
+#define htonetl nettohl
+
+#if BIG_ENDIAN == TRUE
+#define ntohs(n) (n)
+#define ntohl(n) (n)
+#define ntoh6(n) (n)
+
+#define nettohs(n) (n)
+#define nettohl(n) (n)
+#else
+extern UINT16 ntohs(UINT16 n);
+extern UINT32 ntohl(UINT32 n);
+extern UINT8 *ntoh6(UINT8 *p);
+
+#define nettohs(n) ((UINT16)((((n) << 8) & 0xff00) | (((n) >> 8) & 0x00ff)))
+#define nettohl(n) ((((n) & 0x000000ff) << 24) | (((n) << 8) & 0x00ff0000) | \
+ (((n) >> 8) & 0x0000ff00) | (((n) >> 24) & 0x000000ff))
+#endif
+
+#endif /* GKI_INET_H */
diff --git a/src/gki/common/gki_time.c b/src/gki/common/gki_time.c
new file mode 100644
index 0000000..e840a36
--- /dev/null
+++ b/src/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/src/gki/ulinux/data_types.h b/src/gki/ulinux/data_types.h
new file mode 100644
index 0000000..e230a47
--- /dev/null
+++ b/src/gki/ulinux/data_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 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/src/gki/ulinux/gki_int.h b/src/gki/ulinux/gki_int.h
new file mode 100644
index 0000000..7ff9d4e
--- /dev/null
+++ b/src/gki/ulinux/gki_int.h
@@ -0,0 +1,78 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef GKI_INT_H
+#define GKI_INT_H
+
+#include "gki_common.h"
+#include <pthread.h>
+
+/**********************************************************************
+** OS specific definitions
+*/
+#ifdef ANDROID
+#include <sys/times.h>
+#endif
+
+typedef struct
+{
+ pthread_mutex_t GKI_mutex;
+ pthread_t thread_id[GKI_MAX_TASKS];
+ pthread_mutex_t thread_evt_mutex[GKI_MAX_TASKS];
+ pthread_cond_t thread_evt_cond[GKI_MAX_TASKS];
+ pthread_mutex_t thread_timeout_mutex[GKI_MAX_TASKS];
+ pthread_cond_t thread_timeout_cond[GKI_MAX_TASKS];
+ int no_timer_suspend; /* 1: no suspend, 0 stop calling GKI_timer_update() */
+ pthread_mutex_t gki_timer_mutex;
+ pthread_cond_t gki_timer_cond;
+ int gki_timer_wake_lock_on;
+#if (GKI_DEBUG == TRUE)
+ pthread_mutex_t GKI_trace_mutex;
+#endif
+} tGKI_OS;
+
+/* condition to exit or continue GKI_run() timer loop */
+#define GKI_TIMER_TICK_RUN_COND 1
+#define GKI_TIMER_TICK_STOP_COND 0
+#define GKI_TIMER_TICK_EXIT_COND 2
+
+extern void gki_system_tick_start_stop_cback(BOOLEAN start);
+
+/* Contains common control block as well as OS specific variables */
+typedef struct
+{
+ tGKI_OS os;
+ tGKI_COM_CB com;
+} tGKI_CB;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if GKI_DYNAMIC_MEMORY == FALSE
+GKI_API extern tGKI_CB gki_cb;
+#else
+GKI_API extern tGKI_CB *gki_cb_ptr;
+#define gki_cb (*gki_cb_ptr)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/gki/ulinux/gki_ulinux.c b/src/gki/ulinux/gki_ulinux.c
new file mode 100644
index 0000000..7f07401
--- /dev/null
+++ b/src/gki/ulinux/gki_ulinux.c
@@ -0,0 +1,1291 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+#include <stdio.h>
+#include <stdarg.h>
+#include <errno.h>
+
+#define GKI_DEBUG FALSE
+
+#include <pthread.h> /* must be 1st header defined */
+#include <time.h>
+#include "gki_int.h"
+#include "gki_target.h"
+
+/* Temp android logging...move to android tgt config file */
+
+#ifndef LINUX_NATIVE
+#include <cutils/log.h>
+#else
+#define LOGV(format, ...) fprintf (stdout, LOG_TAG format, ## __VA_ARGS__)
+#define LOGE(format, ...) fprintf (stderr, LOG_TAG format, ## __VA_ARGS__)
+#define LOGI(format, ...) fprintf (stdout, LOG_TAG format, ## __VA_ARGS__)
+
+#define SCHED_NORMAL 0
+#define SCHED_FIFO 1
+#define SCHED_RR 2
+#define SCHED_BATCH 3
+
+#endif
+
+/* Define the structure that holds the GKI variables
+*/
+#if GKI_DYNAMIC_MEMORY == FALSE
+tGKI_CB gki_cb;
+#endif
+
+#define NANOSEC_PER_MILLISEC (1000000)
+#define NSEC_PER_SEC (1000*NANOSEC_PER_MILLISEC)
+
+/* works only for 1ms to 1000ms heart beat ranges */
+#define LINUX_SEC (1000/TICKS_PER_SEC)
+// #define GKI_TICK_TIMER_DEBUG
+
+#define LOCK(m) pthread_mutex_lock(&m)
+#define UNLOCK(m) pthread_mutex_unlock(&m)
+#define INIT(m) pthread_mutex_init(&m, NULL)
+
+
+/* this kind of mutex go into tGKI_OS control block!!!! */
+/* static pthread_mutex_t GKI_sched_mutex; */
+/*static pthread_mutex_t thread_delay_mutex;
+static pthread_cond_t thread_delay_cond;
+static pthread_mutex_t gki_timer_update_mutex;
+static pthread_cond_t gki_timer_update_cond;
+*/
+#ifdef NO_GKI_RUN_RETURN
+static pthread_t timer_thread_id = 0;
+#endif
+
+
+/* For Android */
+
+#ifndef GKI_SHUTDOWN_EVT
+#define GKI_SHUTDOWN_EVT APPL_EVT_7
+#endif
+
+typedef struct
+{
+ UINT8 task_id; /* GKI task id */
+ TASKPTR task_entry; /* Task entry function*/
+ UINT32 params; /* Extra params to pass to task entry function */
+ pthread_cond_t* pCond; /* for android*/
+ pthread_mutex_t* pMutex; /* for android*/
+} gki_pthread_info_t;
+gki_pthread_info_t gki_pthread_info[GKI_MAX_TASKS];
+
+/*******************************************************************************
+**
+** Function gki_task_entry
+**
+** Description entry point of GKI created tasks
+**
+** Returns void
+**
+*******************************************************************************/
+void gki_task_entry(UINT32 params)
+{
+ pthread_t thread_id = pthread_self();
+ gki_pthread_info_t *p_pthread_info = (gki_pthread_info_t *)params;
+ GKI_TRACE_5("gki_task_entry task_id=%i, thread_id=%x/%x, pCond/pMutex=%x/%x", p_pthread_info->task_id,
+ gki_cb.os.thread_id[p_pthread_info->task_id], pthread_self(),
+ p_pthread_info->pCond, p_pthread_info->pMutex);
+
+ gki_cb.os.thread_id[p_pthread_info->task_id] = thread_id;
+ /* Call the actual thread entry point */
+ (p_pthread_info->task_entry)(p_pthread_info->params);
+
+ GKI_TRACE_1("gki_task task_id=%i terminating", p_pthread_info->task_id);
+ gki_cb.os.thread_id[p_pthread_info->task_id] = 0;
+
+ pthread_exit(0); /* GKI tasks have no return value */
+}
+/* end android */
+
+#ifndef ANDROID
+void GKI_TRACE(char *fmt, ...)
+{
+ LOCK(gki_cb.os.GKI_trace_mutex);
+ va_list ap;
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+
+ va_end(ap);
+ UNLOCK(gki_cb.os.GKI_trace_mutex);
+}
+#endif
+
+/*******************************************************************************
+**
+** Function GKI_init
+**
+** Description This function is called once at startup to initialize
+** all the timer structures.
+**
+** Returns void
+**
+*******************************************************************************/
+
+void GKI_init(void)
+{
+ pthread_mutexattr_t attr;
+ tGKI_OS *p_os;
+
+ memset (&gki_cb, 0, sizeof (gki_cb));
+
+ gki_buffer_init();
+ gki_timers_init();
+ gki_cb.com.OSTicks = (UINT32) times(0);
+
+ pthread_mutexattr_init(&attr);
+
+#ifndef __CYGWIN__
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
+#endif
+ p_os = &gki_cb.os;
+ pthread_mutex_init(&p_os->GKI_mutex, &attr);
+ /* pthread_mutex_init(&GKI_sched_mutex, NULL); */
+#if (GKI_DEBUG == TRUE)
+ pthread_mutex_init(&p_os->GKI_trace_mutex, NULL);
+#endif
+ /* pthread_mutex_init(&thread_delay_mutex, NULL); */ /* used in GKI_delay */
+ /* pthread_cond_init (&thread_delay_cond, NULL); */
+
+ /* Initialiase GKI_timer_update suspend variables & mutexes to be in running state.
+ * this works too even if GKI_NO_TICK_STOP is defined in btld.txt */
+ p_os->no_timer_suspend = GKI_TIMER_TICK_RUN_COND;
+ pthread_mutex_init(&p_os->gki_timer_mutex, NULL);
+ pthread_cond_init(&p_os->gki_timer_cond, NULL);
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_get_os_tick_count
+**
+** Description This function is called to retrieve the native OS system tick.
+**
+** Returns Tick count of native OS.
+**
+*******************************************************************************/
+UINT32 GKI_get_os_tick_count(void)
+{
+
+ /* TODO - add any OS specific code here
+ **/
+ return (gki_cb.com.OSTicks);
+}
+
+/*******************************************************************************
+**
+** Function GKI_create_task
+**
+** Description This function is called to create a new OSS task.
+**
+** Parameters: task_entry - (input) pointer to the entry function of the task
+** task_id - (input) Task id is mapped to priority
+** taskname - (input) name given to the task
+** stack - (input) pointer to the top of the stack (highest memory location)
+** stacksize - (input) size of the stack allocated for the task
+**
+** Returns GKI_SUCCESS if all OK, GKI_FAILURE if any problem
+**
+** NOTE This function take some parameters that may not be needed
+** by your particular OS. They are here for compatability
+** of the function prototype.
+**
+*******************************************************************************/
+UINT8 GKI_create_task (TASKPTR task_entry, UINT8 task_id, INT8 *taskname, UINT16 *stack, UINT16 stacksize, void* pCondVar, void* pMutex)
+{
+ UINT16 i;
+ UINT8 *p;
+ struct sched_param param;
+ int policy, ret = 0;
+ pthread_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, ¶m)==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, ¶m);
+ }
+
+ GKI_TRACE_6( "Leaving GKI_create_task %x %d %x %s %x %d",
+ task_entry,
+ task_id,
+ gki_cb.os.thread_id[task_id],
+ taskname,
+ stack,
+ stacksize);
+
+ return (GKI_SUCCESS);
+}
+
+/*******************************************************************************
+**
+** Function GKI_shutdown
+**
+** Description shutdowns the GKI tasks/threads in from max task id to 0 and frees
+** pthread resources!
+** IMPORTANT: in case of join method, GKI_shutdown must be called outside
+** a GKI thread context!
+**
+** Returns void
+**
+*******************************************************************************/
+#define WAKE_LOCK_ID "brcm_nfca"
+#define PARTIAL_WAKE_LOCK 1
+extern int acquire_wake_lock(int lock, const char* id);
+extern int release_wake_lock(const char* id);
+
+void GKI_shutdown(void)
+{
+ UINT8 task_id;
+ volatile int *p_run_cond = &gki_cb.os.no_timer_suspend;
+ int oldCOnd = 0;
+#if ( FALSE == GKI_PTHREAD_JOINABLE )
+ int i = 0;
+#else
+ int result;
+#endif
+
+ /* release threads and set as TASK_DEAD. going from low to high priority fixes
+ * GKI_exception problem due to btu->hci sleep request events */
+ for (task_id = GKI_MAX_TASKS; task_id > 0; task_id--)
+ {
+ if (gki_cb.com.OSRdyTbl[task_id - 1] != TASK_DEAD)
+ {
+ gki_cb.com.OSRdyTbl[task_id - 1] = TASK_DEAD;
+
+ /* paranoi settings, make sure that we do not execute any mailbox events */
+ gki_cb.com.OSWaitEvt[task_id-1] &= ~(TASK_MBOX_0_EVT_MASK|TASK_MBOX_1_EVT_MASK|
+ TASK_MBOX_2_EVT_MASK|TASK_MBOX_3_EVT_MASK);
+ GKI_send_event(task_id - 1, EVENT_MASK(GKI_SHUTDOWN_EVT));
+
+#if ( FALSE == GKI_PTHREAD_JOINABLE )
+ i = 0;
+
+ while ((gki_cb.com.OSWaitEvt[task_id - 1] != 0) && (++i < 10))
+ usleep(100 * 1000);
+#else
+ /* wait for proper Arnold Schwarzenegger task state */
+ result = pthread_join( gki_cb.os.thread_id[task_id-1], NULL );
+ if ( result < 0 )
+ {
+ GKI_TRACE_1( "pthread_join() FAILED: result: %d", result );
+ }
+#endif
+ GKI_TRACE_1( "GKI_shutdown(): task %s dead", gki_cb.com.OSTName[task_id]);
+ GKI_exit_task(task_id - 1);
+ }
+ }
+
+ /* Destroy mutex and condition variable objects */
+ pthread_mutex_destroy(&gki_cb.os.GKI_mutex);
+ /* pthread_mutex_destroy(&GKI_sched_mutex); */
+#if (GKI_DEBUG == TRUE)
+ pthread_mutex_destroy(&gki_cb.os.GKI_trace_mutex);
+#endif
+ /* pthread_mutex_destroy(&thread_delay_mutex);
+ pthread_cond_destroy (&thread_delay_cond); */
+#if ( FALSE == GKI_PTHREAD_JOINABLE )
+ i = 0;
+#endif
+
+#ifdef NO_GKI_RUN_RETURN
+ shutdown_timer = 1;
+#endif
+ if (gki_cb.os.gki_timer_wake_lock_on)
+ {
+ GKI_TRACE_0("GKI_shutdown : release_wake_lock(brcm_btld)");
+ release_wake_lock(WAKE_LOCK_ID);
+ gki_cb.os.gki_timer_wake_lock_on = 0;
+ }
+ oldCOnd = *p_run_cond;
+ *p_run_cond = GKI_TIMER_TICK_EXIT_COND;
+ if (oldCOnd == GKI_TIMER_TICK_STOP_COND)
+ pthread_cond_signal( &gki_cb.os.gki_timer_cond );
+
+}
+
+/*******************************************************************************
+ **
+ ** Function GKI_run
+ **
+ ** Description This function runs a task
+ **
+ ** Parameters: start: TRUE start system tick (again), FALSE stop
+ **
+ ** Returns void
+ **
+ *********************************************************************************/
+void gki_system_tick_start_stop_cback(BOOLEAN start)
+{
+ tGKI_OS *p_os = &gki_cb.os;
+ volatile int *p_run_cond = &p_os->no_timer_suspend;
+ 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_1("%s exit", __func__);
+ pthread_exit(NULL);
+}
+#endif
+
+/*******************************************************************************
+**
+** Function GKI_run
+**
+** Description This function runs a task
+**
+** Parameters: p_task_id - (input) pointer to task id
+**
+** Returns void
+**
+** NOTE This function is only needed for operating systems where
+** starting a task is a 2-step process. Most OS's do it in
+** one step, If your OS does it in one step, this function
+** should be empty.
+*********************************************************************************/
+void GKI_run (void *p_task_id)
+{
+ GKI_TRACE_1("%s enter", __func__);
+ struct timespec delay;
+ int err = 0;
+ volatile int * p_run_cond = &gki_cb.os.no_timer_suspend;
+
+#ifndef GKI_NO_TICK_STOP
+ /* register start stop function which disable timer loop in GKI_run() when no timers are
+ * in any GKI/BTA/BTU this should save power when BTLD is idle! */
+ GKI_timer_queue_register_callback( gki_system_tick_start_stop_cback );
+ APPL_TRACE_DEBUG0( "GKI_run(): Start/Stop GKI_timer_update_registered!" );
+#endif
+
+#ifdef NO_GKI_RUN_RETURN
+ GKI_TRACE_0("GKI_run == NO_GKI_RUN_RETURN");
+ pthread_attr_t timer_attr;
+
+ shutdown_timer = 0;
+
+ pthread_attr_init(&timer_attr);
+ pthread_attr_setdetachstate(&timer_attr, PTHREAD_CREATE_DETACHED);
+ if (pthread_create( &timer_thread_id,
+ &timer_attr,
+ timer_thread,
+ NULL) != 0 )
+ {
+ GKI_TRACE_0("GKI_run: pthread_create failed to create timer_thread!");
+ return GKI_FAILURE;
+ }
+#else
+ GKI_TRACE_2("GKI_run, run_cond(%x)=%d ", p_run_cond, *p_run_cond);
+ for (;GKI_TIMER_TICK_EXIT_COND != *p_run_cond;)
+ {
+ do
+ {
+ /* adjust hear bit tick in btld by changning TICKS_PER_SEC!!!!! this formula works only for
+ * 1-1000ms heart beat units! */
+ delay.tv_sec = LINUX_SEC / 1000;
+ delay.tv_nsec = 1000 * 1000 * (LINUX_SEC % 1000);
+
+ /* [u]sleep can't be used because it uses SIGALRM */
+ do
+ {
+ err = nanosleep(&delay, &delay);
+ } while (err < 0 && errno == EINTR);
+
+ 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 (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 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]);
+ BT_TRACE_1( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, "GKI TASK_DEAD received. exit thread %d...", rtask );
+
+ gki_cb.os.thread_id[rtask] = 0;
+ pthread_exit(NULL);
+ return (EVENT_MASK(GKI_SHUTDOWN_EVT));
+ }
+ }
+
+ /* Clear the wait for event mask */
+ gki_cb.com.OSWaitForEvt[rtask] = 0;
+
+ /* Return only those bits which user wants... */
+ evt = gki_cb.com.OSWaitEvt[rtask] & flag;
+
+ /* Clear only those bits which user wants... */
+ gki_cb.com.OSWaitEvt[rtask] &= ~flag;
+
+ /* unlock thread_evt_mutex as pthread_cond_wait() does auto lock mutex when cond is met */
+ pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[rtask]);
+ GKI_TRACE_4("GKI_wait %d %x %d %x resumed", rtask, flag, timeout, evt);
+
+ return (evt);
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_delay
+**
+** Description This function is called by tasks to sleep unconditionally
+** for a specified amount of time. The duration is in milliseconds
+**
+** Parameters: timeout - (input) the duration in milliseconds
+**
+** Returns void
+**
+*******************************************************************************/
+
+void GKI_delay (UINT32 timeout)
+{
+ UINT8 rtask = GKI_get_taskid();
+ struct timespec delay;
+ int err;
+
+ GKI_TRACE_2("GKI_delay %d %d", rtask, timeout);
+
+ delay.tv_sec = timeout / 1000;
+ delay.tv_nsec = 1000 * 1000 * (timeout%1000);
+
+ /* [u]sleep can't be used because it uses SIGALRM */
+
+ do {
+ err = nanosleep(&delay, &delay);
+ } while (err < 0 && errno ==EINTR);
+
+ /* Check if task was killed while sleeping */
+ /* NOTE
+ ** if you do not implement task killing, you do not
+ ** need this check.
+ */
+ if (rtask && gki_cb.com.OSRdyTbl[rtask] == TASK_DEAD)
+ {
+ }
+
+ GKI_TRACE_2("GKI_delay %d %d done", rtask, timeout);
+ return;
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_send_event
+**
+** Description This function is called by tasks to send events to other
+** tasks. Tasks can also send events to themselves.
+**
+** Parameters: task_id - (input) The id of the task to which the event has to
+** be sent
+** event - (input) The event that has to be sent
+**
+**
+** Returns GKI_SUCCESS if all OK, else GKI_FAILURE
+**
+*******************************************************************************/
+UINT8 GKI_send_event (UINT8 task_id, UINT16 event)
+{
+ GKI_TRACE_2("GKI_send_event %d %x", task_id, event);
+
+ /* use efficient coding to avoid pipeline stalls */
+ if (task_id < GKI_MAX_TASKS)
+ {
+ /* protect OSWaitEvt[task_id] from manipulation in GKI_wait() */
+ pthread_mutex_lock(&gki_cb.os.thread_evt_mutex[task_id]);
+
+ /* Set the event bit */
+ gki_cb.com.OSWaitEvt[task_id] |= event;
+
+ pthread_cond_signal(&gki_cb.os.thread_evt_cond[task_id]);
+
+ pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[task_id]);
+
+ GKI_TRACE_2("GKI_send_event %d %x done", task_id, event);
+ return ( GKI_SUCCESS );
+ }
+ return (GKI_FAILURE);
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_isend_event
+**
+** Description This function is called from ISRs to send events to other
+** tasks. The only difference between this function and GKI_send_event
+** is that this function assumes interrupts are already disabled.
+**
+** Parameters: task_id - (input) The destination task Id for the event.
+** event - (input) The event flag
+**
+** Returns GKI_SUCCESS if all OK, else GKI_FAILURE
+**
+** NOTE This function is NOT called by the Widcomm stack and
+** profiles. If you want to use it in your own implementation,
+** put your code here, otherwise you can delete the entire
+** body of the function.
+**
+*******************************************************************************/
+UINT8 GKI_isend_event (UINT8 task_id, UINT16 event)
+{
+
+ GKI_TRACE_2("GKI_isend_event %d %x", task_id, event);
+ GKI_TRACE_2("GKI_isend_event %d %x done", task_id, event);
+ return GKI_send_event(task_id, event);
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_get_taskid
+**
+** Description This function gets the currently running task ID.
+**
+** Returns task ID
+**
+** NOTE The Widcomm upper stack and profiles may run as a single task.
+** If you only have one GKI task, then you can hard-code this
+** function to return a '1'. Otherwise, you should have some
+** OS-specific method to determine the current task.
+**
+*******************************************************************************/
+UINT8 GKI_get_taskid (void)
+{
+ int i;
+
+ pthread_t thread_id = pthread_self( );
+ for (i = 0; i < GKI_MAX_TASKS; i++) {
+ if (gki_cb.os.thread_id[i] == thread_id) {
+ GKI_TRACE_2("GKI_get_taskid %x %d done", thread_id, i);
+ return(i);
+ }
+ }
+
+ GKI_TRACE_1("GKI_get_taskid: thread id = %x, task id = -1", thread_id);
+
+ return(-1);
+}
+
+/*******************************************************************************
+**
+** Function GKI_map_taskname
+**
+** Description This function gets the task name of the taskid passed as arg.
+** If GKI_MAX_TASKS is passed as arg the currently running task
+** name is returned
+**
+** Parameters: task_id - (input) The id of the task whose name is being
+** sought. GKI_MAX_TASKS is passed to get the name of the
+** currently running task.
+**
+** Returns pointer to task name
+**
+** NOTE this function needs no customization
+**
+*******************************************************************************/
+INT8 *GKI_map_taskname (UINT8 task_id)
+{
+ GKI_TRACE_1("GKI_map_taskname %d", task_id);
+
+ if (task_id < GKI_MAX_TASKS)
+ {
+ GKI_TRACE_2("GKI_map_taskname %d %s done", task_id, gki_cb.com.OSTName[task_id]);
+ return (gki_cb.com.OSTName[task_id]);
+ }
+ else if (task_id == GKI_MAX_TASKS )
+ {
+ return (gki_cb.com.OSTName[GKI_get_taskid()]);
+ }
+ else
+ {
+ return (INT8*) "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/src/hal/include/gki_hal_target.h b/src/hal/include/gki_hal_target.h
new file mode 100644
index 0000000..afe6dff
--- /dev/null
+++ b/src/hal/include/gki_hal_target.h
@@ -0,0 +1,289 @@
+/******************************************************************************
+ *
+ * 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"
+
+/* Define export prefixes for modules exported by HAL */
+#ifndef GKI_API
+#define GKI_API
+#endif
+
+#ifndef UDRV_API
+#define UDRV_API
+#endif
+
+#ifndef EXPORT_API
+#define EXPORT_API
+#endif
+
+
+/******************************************************************************
+**
+** Task configuration
+**
+******************************************************************************/
+
+/* Definitions of task IDs for inter-task messaging */
+#ifndef NFC_HAL_TASK
+#define NFC_HAL_TASK 0
+#endif
+
+/* The number of GKI tasks in the software system. */
+#ifndef GKI_MAX_TASKS
+#define GKI_MAX_TASKS 1
+#endif
+
+
+/******************************************************************************
+**
+** 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 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..b481d26
--- /dev/null
+++ b/src/hal/include/nci_defs.h
@@ -0,0 +1,849 @@
+/******************************************************************************
+ *
+ * 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
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NCI_BRCM_CO_ID 0x2E
+
+/* Define the message header size for all NCI Commands and Notifications.
+*/
+#define NCI_MSG_HDR_SIZE 3 /* per NCI spec */
+#define NCI_DATA_HDR_SIZE 3 /* per NCI spec */
+#define NCI_MAX_PAYLOAD_SIZE 0xFE
+#define NCI_MAX_CTRL_SIZE 0xFF/* max control message size */
+#define NCI_CTRL_INIT_SIZE 32 /* initial NFCC control payload size */
+#define NCI_MAX_VSC_SIZE 0xFF
+#define NCI_VSC_MSG_HDR_SIZE 12 /* NCI header (3) + callback function pointer(8; use 8 to be safe) + HCIT (1 byte) */
+#define NCI_TL_SIZE 2
+
+#define NCI_ISO_DEP_MAX_INFO 253 /* Max frame size (256) - Prologue (1) - Epilogue (2) in ISO-DEP, CID and NAD are not used*/
+#define NCI_NFC_DEP_MAX_DATA 251 /* Max payload (254) - Protocol Header (3) in NFC-DEP, DID and NAD are not used */
+
+/* NCI Command and Notification Format:
+ * 3 byte message header:
+ * byte 0: MT PBF GID
+ * byte 1: OID
+ * byte 2: Message Length */
+/* MT: Message Type (byte 0) */
+#define NCI_MT_MASK 0xE0
+#define NCI_MT_SHIFT 5
+#define NCI_MT_DATA 0x00
+#define NCI_MT_CMD 1 /* (NCI_MT_CMD << NCI_MT_SHIFT) = 0x20 */
+#define NCI_MT_RSP 2 /* (NCI_MT_RSP << NCI_MT_SHIFT) = 0x40 */
+#define NCI_MT_NTF 3 /* (NCI_MT_NTF << NCI_MT_SHIFT) = 0x60 */
+#define NCI_MT_CFG 4 /* (NCI_MT_CFG << NCI_MT_SHIFT) = 0x80 */
+
+#define NCI_MTS_CMD 0x20
+#define NCI_MTS_RSP 0x40
+#define NCI_MTS_NTF 0x60
+#define NCI_MTS_CFG 0x80
+
+#define NCI_NTF_BIT 0x80 /* the tNFC_VS_EVT is a notification */
+#define NCI_RSP_BIT 0x40 /* the tNFC_VS_EVT is a response */
+
+/* for internal use only; not from specification */
+/* the following 2 flags are used in layer_specific for fragmentation/reassembly of data packets */
+#define NCI_LS_DATA 0x00
+#define NCI_LS_DATA_PBF 0x01
+
+/* PBF: Packet Boundary Flag (byte 0) */
+#define NCI_PBF_MASK 0x10
+#define NCI_PBF_SHIFT 4
+#define NCI_PBF_NO_OR_LAST 0x00 /* not fragmented or last fragment */
+#define NCI_PBF_ST_CONT 0x10 /* start or continuing fragment */
+
+/* GID: Group Identifier (byte 0) */
+#define NCI_GID_MASK 0x0F
+#define NCI_GID_SHIFT 0
+#define NCI_GID_CORE 0x00 /* 0000b NCI Core group */
+#define NCI_GID_RF_MANAGE 0x01 /* 0001b RF Management group */
+#define NCI_GID_EE_MANAGE 0x02 /* 0010b NFCEE Management group */
+#define NCI_GID_PROP 0x0F /* 1111b Proprietary */
+/* 0111b - 1110b RFU */
+
+/* OID: Opcode Identifier (byte 1) */
+#define NCI_OID_MASK 0x3F
+#define NCI_OID_SHIFT 0
+
+/* For routing */
+#define NCI_DH_ID 0 /* for DH */
+/* To identify the loopback test */
+#define NCI_TEST_ID 0xFE/* for loopback test */
+
+/* Destination Type */
+#define NCI_DEST_TYPE_NFCC 1 /* NFCC - loopback */
+#define NCI_DEST_TYPE_REMOTE 2 /* Remote NFC Endpoint */
+#define NCI_DEST_TYPE_NFCEE 3 /* NFCEE */
+
+/* builds byte0 of NCI Command and Notification packet */
+#define NCI_MSG_BLD_HDR0(p, mt, gid) \
+ *(p)++ = (UINT8) (((mt) << NCI_MT_SHIFT) | (gid));
+
+#define NCI_MSG_PBLD_HDR0(p, mt, pbf, gid) \
+ *(p)++ = (UINT8) (((mt) << NCI_MT_SHIFT) | ((pbf) << NCI_PBF_SHIFT) | (gid));
+
+/* builds byte1 of NCI Command and Notification packet */
+#define NCI_MSG_BLD_HDR1(p, oid) \
+ *(p)++ = (UINT8) (((oid) << NCI_OID_SHIFT));
+
+/* parse byte0 of NCI packet */
+#define NCI_MSG_PRS_HDR0(p, mt, pbf, gid) \
+ mt = (*(p) & NCI_MT_MASK) >> NCI_MT_SHIFT; \
+ pbf = (*(p) & NCI_PBF_MASK) >> NCI_PBF_SHIFT; \
+ gid = *(p)++ & NCI_GID_MASK;
+
+/* parse MT and PBF bits of NCI packet */
+#define NCI_MSG_PRS_MT_PBF(p, mt, pbf) \
+ mt = (*(p) & NCI_MT_MASK) >> NCI_MT_SHIFT; \
+ pbf = (*(p) & NCI_PBF_MASK) >> NCI_PBF_SHIFT;
+
+/* parse byte1 of NCI Cmd/Ntf */
+#define NCI_MSG_PRS_HDR1(p, oid) \
+ oid = (*(p) & NCI_OID_MASK); (p)++;
+
+/* NCI Data Format:
+ * byte 0: MT(0) PBF CID
+ * byte 1: RFU
+ * byte 2: Data Length */
+/* CID: Connection Identifier (byte 0) 1-0xF Dynamically assigned (by NFCC), 0 is predefined */
+#define NCI_CID_MASK 0x0F
+
+/* builds 3-byte message header of NCI Data packet */
+#define NCI_DATA_BLD_HDR(p, cid, len) \
+ *(p)++ = (UINT8) (cid); *(p)++ = 0; *(p)++ = (UINT8) (len);
+
+#define NCI_DATA_PBLD_HDR(p, pbf, cid, len) \
+ *(p)++ = (UINT8) (((pbf) << NCI_PBF_SHIFT) | (cid)); *(p)++=0; *(p)++ = (len);
+
+#define NCI_DATA_PRS_HDR(p, pbf, cid, len) \
+ (pbf) = (*(p) & NCI_PBF_MASK) >> NCI_PBF_SHIFT; (cid) = (*(p) & NCI_CID_MASK); p++; p++; (len) = *(p)++;
+
+
+/* Logical target ID 0x01-0xFE */
+
+
+
+/* Status Codes */
+#define NCI_STATUS_OK 0x00
+#define NCI_STATUS_REJECTED 0x01
+#define NCI_STATUS_MESSAGE_CORRUPTED 0x02
+#define NCI_STATUS_BUFFER_FULL 0xE0
+#define NCI_STATUS_FAILED 0x03
+#define NCI_STATUS_NOT_INITIALIZED 0x04
+#define NCI_STATUS_SYNTAX_ERROR 0x05
+#define NCI_STATUS_SEMANTIC_ERROR 0x06
+#define NCI_STATUS_UNKNOWN_GID 0x07
+#define NCI_STATUS_UNKNOWN_OID 0x08
+#define NCI_STATUS_INVALID_PARAM 0x09
+#define NCI_STATUS_MSG_SIZE_TOO_BIG 0x0A
+/* discovery */
+#define NCI_STATUS_ALREADY_STARTED 0xA0
+#define NCI_STATUS_ACTIVATION_FAILED 0xA1
+#define NCI_STATUS_TEAR_DOWN 0xA2
+/* RF Interface */
+#define NCI_STATUS_RF_TRANSMISSION_ERR 0xB0
+#define NCI_STATUS_RF_PROTOCOL_ERR 0xB1
+#define NCI_STATUS_TIMEOUT 0xB2
+/* NFCEE Interface */
+#define NCI_STATUS_EE_INTF_ACTIVE_FAIL 0xC0
+#define NCI_STATUS_EE_TRANSMISSION_ERR 0xC1
+#define NCI_STATUS_EE_PROTOCOL_ERR 0xC2
+#define NCI_STATUS_EE_TIMEOUT 0xC3
+
+
+typedef UINT8 tNCI_STATUS;
+
+/* RF Technologies */
+#define NCI_RF_TECHNOLOGY_A 0x00
+#define NCI_RF_TECHNOLOGY_B 0x01
+#define NCI_RF_TECHNOLOGY_F 0x02
+#define NCI_RF_TECHNOLOGY_15693 0x03
+
+/* Bit Rates */
+#define NCI_BIT_RATE_106 0x00/* 106 kbit/s */
+#define NCI_BIT_RATE_212 0x01/* 212 kbit/s */
+#define NCI_BIT_RATE_424 0x02/* 424 kbit/s */
+#define NCI_BIT_RATE_848 0x03/* 848 Kbit/s */
+#define NCI_BIT_RATE_1696 0x04/* 1696 Kbit/s*/
+#define NCI_BIT_RATE_3392 0x05/* 3392 Kbit/s*/
+#define NCI_BIT_RATE_6784 0x06/* 6784 Kbit/s*/
+
+/**********************************************
+ * NCI Core Group Opcode - 0
+ **********************************************/
+#define NCI_MSG_CORE_RESET 0
+#define NCI_MSG_CORE_INIT 1
+#define NCI_MSG_CORE_SET_CONFIG 2
+#define NCI_MSG_CORE_GET_CONFIG 3
+#define NCI_MSG_CORE_CONN_CREATE 4
+#define NCI_MSG_CORE_CONN_CLOSE 5
+#define NCI_MSG_CORE_CONN_CREDITS 6
+#define NCI_MSG_CORE_GEN_ERR_STATUS 7
+#define NCI_MSG_CORE_INTF_ERR_STATUS 8
+
+/**********************************************
+ * RF MANAGEMENT Group Opcode - 1
+ **********************************************/
+#define NCI_MSG_RF_DISCOVER_MAP 0
+#define NCI_MSG_RF_SET_ROUTING 1
+#define NCI_MSG_RF_GET_ROUTING 2
+#define NCI_MSG_RF_DISCOVER 3
+#define NCI_MSG_RF_DISCOVER_SELECT 4
+#define NCI_MSG_RF_INTF_ACTIVATED 5
+#define NCI_MSG_RF_DEACTIVATE 6
+#define NCI_MSG_RF_FIELD 7
+#define NCI_MSG_RF_T3T_POLLING 8
+#define NCI_MSG_RF_EE_ACTION 9
+#define NCI_MSG_RF_EE_DISCOVERY_REQ 10
+#define NCI_MSG_RF_PARAMETER_UPDATE 11
+/**********************************************
+ * NFCEE MANAGEMENT Group Opcode - 2
+ **********************************************/
+#define NCI_MSG_NFCEE_DISCOVER 0
+#define NCI_MSG_NFCEE_MODE_SET 1
+
+/**********************************************
+ * NCI Proprietary Group - F
+ **********************************************/
+
+/**********************************************
+ * NCI Core Group Params
+ **********************************************/
+#define NCI_CORE_PARAM_SIZE_RESET 0x01
+#define NCI_CORE_PARAM_SIZE_RESET_RSP 0x03
+#define NCI_CORE_PARAM_SIZE_RESET_NTF 0x02
+#define NCI_CORE_PARAM_SIZE_INIT 0x00
+#define NCI_CORE_PARAM_SIZE_INIT_RSP 0x11
+#define NCI_CORE_INIT_RSP_OFFSET_NUM_INTF 0x05
+
+#define NCI_CORE_PARAM_SIZE_SET_CONFIG_RSP 0x02 /* Status (1 octet) and number of params */
+
+
+/* octet 0 */
+#define NCI_FEAT_DISCOVERY_FREG 0x00000001
+#define NCI_FEAT_DISCOVERY_CFGM 0x00000006
+/* octet 1 */
+#define NCI_FEAT_TECHNOLOGY_ROUTING 0x00000200
+#define NCI_FEAT_PROTOCOL_ROUTING 0x00000400
+#define NCI_FEAT_AID_ROUTING 0x00000800
+/* octet 2 */
+#define NCI_FEAT_BATTERY_OFF_MD 0x00010000
+#define NCI_FEAT_SWITCH_OFF_MD 0x00020000
+
+
+/* supported Interfaces */
+#define NCI_SUP_INTF_FRAME 0x0001
+#define NCI_SUP_INTF_ISO_DEP 0x0002
+#define NCI_SUP_INTF_NFC_DEP 0x0004
+
+
+
+#define NCI_CORE_PARAM_SIZE_CON_CREATE 0x02 /* handle, num_tlv, (tlv) */
+#define NCI_CORE_PARAM_SIZE_CON_CREATE_RSP 0x04 /* status, size, credits, conn_id */
+#define NCI_CON_CREATE_TAG_EE_INTF 0x00 /* old */
+#define NCI_CON_CREATE_TAG_RF_DISC_ID 0x00
+#define NCI_CON_CREATE_TAG_NFCEE_VAL 0x01
+
+#define NCI_CORE_PARAM_SIZE_CON_CLOSE 0x01 /* Conn ID (1 octet) */
+#define NCI_CORE_PARAM_SIZE_CON_CLOSE_RSP 0x01 /* Status (1 octet) */
+
+#define NCI_CORE_PARAM_SIZE_RF_FIELD_NTF 0x01 /* RF Field Status (1 octet) */
+
+#define NCI_RESET_TYPE_KEEP_CFG 0x00 /* Keep the NCI configuration (if possible) and perform NCI initialization. */
+#define NCI_RESET_TYPE_RESET_CFG 0x01 /* Reset the NCI configuration, and perform NCI initialization. */
+
+#define NCI_RESET_STATUS_KEPT_CFG 0x00 /* NCI Configuration has been kept */
+#define NCI_RESET_STATUS_RESET_CFG 0x01 /* NCI Configuration has been reset */
+
+#define NCI_RF_STS_NO_REMOTE 0x00 /* No operating field generated by remote device */
+#define NCI_RF_STS_REMOTE 0x01 /* Operating field generated by remote device */
+
+
+#define NCI_PARAM_SIZE_DISCOVER_NFCEE 0x01 /* Discovery Action (1 octet) */
+#define NCI_PARAM_SIZE_DISCOVER_NFCEE_RSP 0x02 /* Status (1 octet)Number of NFCEEs (1 octet) */
+
+#define NCI_DISCOVER_ACTION_DISABLE 0
+#define NCI_DISCOVER_ACTION_ENABLE 1
+
+#define NCI_EE_DISCOVER_REQ_TYPE_LISTEN 0x01
+#define NCI_EE_DISCOVER_REQ_TYPE_POLL 0x02
+
+#define NCI_RF_PARAM_ID_TECH_N_MODE 0x00 /* RF Technology and Mode */
+#define NCI_RF_PARAM_ID_TX_BIT_RATE 0x01 /* Transmit Bit Rate */
+#define NCI_RF_PARAM_ID_RX_BIT_RATE 0x02 /* Receive Bit Rate */
+#define NCI_RF_PARAM_ID_B_DATA_EX_PARAM 0x03 /* B Data Exchange config param */
+
+
+#define NCI_NFCEE_INTERFACE_APDU 0x00
+#define NCI_NFCEE_INTERFACE_HCI_ACCESS 0x01
+#define NCI_NFCEE_INTERFACE_T3T 0x02
+#define NCI_NFCEE_INTERFACE_TRANSPARENT 0x03
+#define NCI_NFCEE_INTERFACE_PROPRIETARY 0x80
+
+#define NCI_NFCEE_STS_CONN_ACTIVE 0x00
+#define NCI_NFCEE_STS_CONN_INACTIVE 0x01
+#define NCI_NFCEE_STS_REMOVED 0x02
+#define NCI_NUM_NFCEE_STS 3
+
+#define NCI_CORE_PARAM_SIZE_NFCEE_MODE_SET 0x02 /* Logical Target ID (1 octet)NFCEE Mode (1 octet) */
+#define NCI_CORE_PARAM_SIZE_NFCEE_MODE_SET_RSP 0x01 /* Status (1 octet) */
+
+#define NCI_NFCEE_MD_DEACTIVATE 0x00 /* Deactivate the connected NFCEE */
+#define NCI_NFCEE_MD_ACTIVATE 0x01 /* Activate the connected NFCEE */
+#define NCI_NUM_NFCEE_MODE 2
+
+/**********************************************
+ * NCI Deactivation Type
+ **********************************************/
+#define NCI_DEACTIVATE_TYPE_IDLE 0 /* Idle Mode */
+#define NCI_DEACTIVATE_TYPE_SLEEP 1 /* Sleep Mode */
+#define NCI_DEACTIVATE_TYPE_SLEEP_AF 2 /* Sleep_AF Mode */
+#define NCI_DEACTIVATE_TYPE_DISCOVERY 3 /* Discovery */
+
+/**********************************************
+ * NCI Deactivation Reasons
+ **********************************************/
+#define NCI_DEACTIVATE_REASON_DH_REQ 0 /* DH Request */
+#define NCI_DEACTIVATE_REASON_ENDPOINT_REQ 1 /* Endpoint Request */
+#define NCI_DEACTIVATE_REASON_RF_LINK_LOSS 2 /* RF Link Loss */
+#define NCI_DEACTIVATE_REASON_NFCB_BAD_AFI 3 /* NFC-B Bad AFI */
+
+ /**********************************************
+ * NCI Interface Mode
+ **********************************************/
+#define NCI_INTERFACE_MODE_POLL 1
+#define NCI_INTERFACE_MODE_LISTEN 2
+#define NCI_INTERFACE_MODE_POLL_N_LISTEN 3
+
+/**********************************************
+ * NCI Interface Types
+ **********************************************/
+#define NCI_INTERFACE_EE_DIRECT_RF 0
+#define NCI_INTERFACE_FRAME 1
+#define NCI_INTERFACE_ISO_DEP 2
+#define NCI_INTERFACE_NFC_DEP 3
+
+#define NCI_INTERFACE_MAX NCI_INTERFACE_NFC_DEP
+
+#define NCI_INTERFACE_FIRST_VS 0x80
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define NCI_INTERFACE_MIFARE 0x80
+#if (NFC_NXP_CHIP_TYPE != PN547C2)
+#define NCI_INTERFACE_UICC_DIRECT 0x82
+#define NCI_INTERFACE_ESE_DIRECT 0x83
+#else
+#define NCI_INTERFACE_UICC_DIRECT 0x81
+#define NCI_INTERFACE_ESE_DIRECT 0x82
+#endif
+#endif
+typedef UINT8 tNCI_INTF_TYPE;
+
+/**********************************************
+ * NCI RF Management / DISCOVERY Group Params
+ **********************************************/
+#define NCI_DISCOVER_PARAM_SIZE_RSP 0x01
+
+#define NCI_DISCOVER_PARAM_SIZE_SELECT 0x03 /* ID, protocol, interface */
+#define NCI_DISCOVER_PARAM_SIZE_SELECT_RSP 0x01 /* Status (1 octet) */
+#define NCI_DISCOVER_PARAM_SIZE_STOP 0x00 /* */
+#define NCI_DISCOVER_PARAM_SIZE_STOP_RSP 0x01 /* Status (1 octet) */
+#define NCI_DISCOVER_PARAM_SIZE_DEACT 0x01 /* type */
+#define NCI_DISCOVER_PARAM_SIZE_DEACT_RSP 0x01 /* Status (1 octet) */
+#define NCI_DISCOVER_PARAM_SIZE_DEACT_NTF 0x01 /* type */
+
+/**********************************************
+ * Supported Protocols
+ **********************************************/
+#define NCI_PROTOCOL_UNKNOWN 0x00
+#define NCI_PROTOCOL_T1T 0x01
+#define NCI_PROTOCOL_T2T 0x02
+#define NCI_PROTOCOL_T3T 0x03
+#define NCI_PROTOCOL_ISO_DEP 0x04
+#define NCI_PROTOCOL_NFC_DEP 0x05
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define NCI_PROTOCOL_ISO7816 0xA0
+#endif
+/**********************************************
+ * Proprietary Protocols
+ **********************************************/
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#ifndef NCI_PROTOCOL_ISO7816
+#define NCI_PROTOCOL_ISO7816 0xA0
+#endif
+#ifndef NCI_PROTOCOL_MIFARE
+#define NCI_PROTOCOL_MIFARE 0x80
+#endif
+#ifndef NCI_PROTOCOL_18092_ACTIVE
+#define NCI_PROTOCOL_18092_ACTIVE 0x05
+#endif
+#else
+#ifndef NCI_PROTOCOL_MIFARE
+#define NCI_PROTOCOL_MIFARE 0xFF
+#endif
+#ifndef NCI_PROTOCOL_18092_ACTIVE
+#define NCI_PROTOCOL_18092_ACTIVE 0x80
+#endif
+#endif
+
+#ifndef NCI_PROTOCOL_B_PRIME
+#define NCI_PROTOCOL_B_PRIME 0x81
+#endif
+#ifndef NCI_PROTOCOL_DUAL
+#define NCI_PROTOCOL_DUAL 0x82
+#endif
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#ifndef NCI_PROTOCOL_15693
+#define NCI_PROTOCOL_15693 0x06
+#endif
+#else
+#ifndef NCI_PROTOCOL_15693
+#define NCI_PROTOCOL_15693 0x83
+#endif
+#endif
+
+
+#ifndef NCI_PROTOCOL_KOVIO
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+#define NCI_PROTOCOL_KOVIO 0x81
+#else
+#define NCI_PROTOCOL_KOVIO 0x8A
+#endif
+#else
+#define NCI_PROTOCOL_KOVIO 0x8A
+#endif
+#endif
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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_POLL_B_PRIME 0x74
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+#define NCI_DISCOVERY_TYPE_POLL_KOVIO 0x70
+#else
+#define NCI_DISCOVERY_TYPE_POLL_KOVIO 0x77
+#endif
+#else
+#define NCI_DISCOVERY_TYPE_POLL_KOVIO 0x77
+#endif
+#define NCI_DISCOVERY_TYPE_LISTEN_A 0x80
+#define NCI_DISCOVERY_TYPE_LISTEN_B 0x81
+#define NCI_DISCOVERY_TYPE_LISTEN_F 0x82
+#define NCI_DISCOVERY_TYPE_LISTEN_A_ACTIVE 0x83
+#define NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE 0x85
+#define NCI_DISCOVERY_TYPE_LISTEN_B_PRIME 0xF4
+#define NCI_DISCOVERY_TYPE_POLL_ISO15693 0x06
+#define NCI_DISCOVERY_TYPE_LISTEN_ISO15693 0x86
+#define NCI_DISCOVERY_TYPE_MAX NCI_DISCOVERY_TYPE_LISTEN_ISO15693
+
+typedef UINT8 tNCI_DISCOVERY_TYPE;
+
+#define NCI_EE_TRIG_7816_SELECT 0x00
+#define NCI_EE_TRIG_RF_PROTOCOL 0x01
+#define NCI_EE_TRIG_RF_TECHNOLOGY 0x02
+#define NCI_EE_TRIG_APP_INIT 0x10
+
+#define NCI_EE_ACT_TAG_AID 0xC0 /* AID */
+#define NCI_EE_ACT_TAG_PROTO 0xC1 /* RF protocol */
+#define NCI_EE_ACT_TAG_TECH 0xC2 /* RF technology */
+#define NCI_EE_ACT_TAG_DATA 0xC3 /* hex data for app */
+#define NCI_EE_ACT_TAG_DEBUG 0xC4 /* debug trace */
+
+#define NCI_ROUTE_TAG_TECH 0x00 /* Technology based routing */
+#define NCI_ROUTE_TAG_PROTO 0x01 /* Protocol based routing */
+#define NCI_ROUTE_TAG_AID 0x02 /* AID routing */
+
+#define NCI_ROUTE_PWR_STATE_ON 0x01 /* The device is on */
+#define NCI_ROUTE_PWR_STATE_SWITCH_OFF 0x02 /* The device is switched off */
+#define NCI_ROUTE_PWR_STATE_BATT_OFF 0x04 /* The device's battery is removed */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define NCI_ROUTE_PWR_STATE_SCREEN_LOCK 0x40 /* The device is screen lock mode */
+#define NCI_ROUTE_PWR_STATE_SCREEN_OFF 0x80 /* The device is screen off mode */
+#endif
+
+#define NCI_NFCEE_TAG_HW_ID 0x00 /* Hardware / Registration Identification */
+#define NCI_NFCEE_TAG_ATR_BYTES 0x01 /* ATR Bytes */
+#define NCI_NFCEE_TAG_T3T_INFO 0x02 /* T3T Command Set Interface Supplementary Info */
+#define NCI_NFCEE_TAG_HCI_HOST_ID 0xA0 /* HCI host ID */
+
+#define NCI_DISCOVER_NTF_LAST 0x00
+#define NCI_DISCOVER_NTF_LAST_ABORT 0x01
+#define NCI_DISCOVER_NTF_MORE 0x02
+
+
+/* NCI RF Management Group Params */
+#define NCI_RF_PARAM_SIZE_T3T_POLLING 0x04 /* System Code, RC, TSN */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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_PA_BAILOUT 0x08
+#define NCI_PARAM_ID_PB_AFI 0x10
+#define NCI_PARAM_ID_PB_BAILOUT 0x11
+#define NCI_PARAM_ID_PB_ATTRIB_PARAM1 0x12
+#define NCI_PARAM_ID_PF_BIT_RATE 0x18
+#define NCI_PARAM_ID_PB_H_INFO 0x20
+#define NCI_PARAM_ID_PI_BIT_RATE 0x21
+
+#define NCI_PARAM_ID_BITR_NFC_DEP 0x28
+#define NCI_PARAM_ID_ATR_REQ_GEN_BYTES 0x29
+#define NCI_PARAM_ID_ATR_REQ_CONFIG 0x2A
+
+#define NCI_PARAM_ID_LA_BIT_FRAME_SDD 0x30
+#define NCI_PARAM_ID_LA_PLATFORM_CONFIG 0x31
+#define NCI_PARAM_ID_LA_SEL_INFO 0x32
+#define NCI_PARAM_ID_LA_NFCID1 0x33
+#define NCI_PARAM_ID_LB_SENSB_INFO 0x38
+#define NCI_PARAM_ID_LB_NFCID0 0x39
+#define NCI_PARAM_ID_LB_APPDATA 0x3A
+#define NCI_PARAM_ID_LB_SFGI 0x3B
+#define NCI_PARAM_ID_LB_ADC_FO 0x3C
+#define NCI_PARAM_ID_LB_PROTOCOL NCI_PARAM_ID_LB_SENSB_INFO
+
+#define NCI_PARAM_ID_LF_T3T_ID1 0x40
+#define NCI_PARAM_ID_LF_T3T_ID2 0x41
+#define NCI_PARAM_ID_LF_T3T_ID3 0x42
+#define NCI_PARAM_ID_LF_T3T_ID4 0x43
+#define NCI_PARAM_ID_LF_T3T_ID5 0x44
+#define NCI_PARAM_ID_LF_T3T_ID6 0x45
+#define NCI_PARAM_ID_LF_T3T_ID7 0x46
+#define NCI_PARAM_ID_LF_T3T_ID8 0x47
+#define NCI_PARAM_ID_LF_T3T_ID9 0x48
+#define NCI_PARAM_ID_LF_T3T_ID10 0x49
+#define NCI_PARAM_ID_LF_T3T_ID11 0x4A
+#define NCI_PARAM_ID_LF_T3T_ID12 0x4B
+#define NCI_PARAM_ID_LF_T3T_ID13 0x4C
+#define NCI_PARAM_ID_LF_T3T_ID14 0x4D
+#define NCI_PARAM_ID_LF_T3T_ID15 0x4E
+#define NCI_PARAM_ID_LF_T3T_ID16 0x4F
+#define NCI_PARAM_ID_LF_PROTOCOL 0x50
+#define NCI_PARAM_ID_LF_T3T_PMM 0x51
+#define NCI_PARAM_ID_LF_T3T_MAX 0x52 /* max num of LF_T3T_ID supported by NFCC (1 for now) */
+#define NCI_PARAM_ID_LF_T3T_FLAGS2 0x53
+#define NCI_PARAM_ID_LF_CON_BITR_F 0x54
+#define NCI_PARAM_ID_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) */
+#define NCI_LISTEN_MASK_A 0x01 /* (0x01 << (NCI_DISCOVERY_TYPE_LISTEN_A_PASSIVE & 0x0F)) */
+#define NCI_LISTEN_MASK_B 0x02 /* (0x01 << (NCI_DISCOVERY_TYPE_LISTEN_B_PASSIVE & 0x0F)) */
+#define NCI_LISTEN_MASK_F 0x04 /* (0x01 << (NCI_DISCOVERY_TYPE_LISTEN_F_PASSIVE & 0x0F)) */
+#define NCI_LISTEN_MASK_A_ACTIVE 0x08 /* (0x01 << (NCI_DISCOVERY_TYPE_LISTEN_A_ACTIVE & 0x0F)) */
+#define NCI_LISTEN_MASK_B_PRIME 0x10 /* (0x01 << (NCI_DISCOVERY_TYPE_LISTEN_B_PRIME & 0x0F)) */
+#define NCI_LISTEN_MASK_F_ACTIVE 0x20 /* (0x01 << (NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE & 0x0F)) */
+#define NCI_LISTEN_MASK_ISO15693 0x40 /* (0x01 << (NCI_DISCOVERY_TYPE_LISTEN_ISO15693 & 0x0F)) */
+
+/* Type A Parameters */
+#define NCI_PARAM_PLATFORM_T1T 0x0C
+#define NCI_PARAM_SEL_INFO_ISODEP 0x20
+#define NCI_PARAM_SEL_INFO_NFCDEP 0x40
+/**********************************************
+ * NCI Parameter ID Lens
+ **********************************************/
+#define NCI_PARAM_LEN_TOTAL_DURATION 2
+
+#define NCI_PARAM_LEN_PA_FSDI 1
+
+#define NCI_PARAM_LEN_LA_BIT_FRAME_SDD 1
+#define NCI_PARAM_LEN_LA_PLATFORM_CONFIG 1
+#define NCI_PARAM_LEN_LA_SEL_INFO 1
+
+#define NCI_PARAM_LEN_LB_SENSB_INFO 1
+#define NCI_PARAM_LEN_LB_NFCID0 4
+#define NCI_PARAM_LEN_LB_APPDATA 4
+#define NCI_PARAM_LEN_LB_ADC_FO 1
+
+#define NCI_PARAM_LEN_LF_PROTOCOL 1
+#define NCI_PARAM_LEN_LF_T3T_FLAGS2 2
+#define NCI_PARAM_LEN_LF_T3T_PMM 8
+#define NCI_PARAM_LEN_LF_T3T_ID 10
+#define NCI_PARAM_LEN_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
+
+typedef struct
+{
+ UINT16 addr;
+ UINT8 len;
+ UINT8 *data;
+} NCIP_T1T_SETMEM_CMD_t;
+
+typedef struct
+{
+ UINT8 status;
+} NCIP_T1T_SETMEM_RSP_t;
+
+typedef struct
+{
+ UINT16 addr;
+} NCIP_T1T_GETMEM_CMD_t;
+
+typedef struct
+{
+ UINT8 status;
+ UINT8 *data;
+} NCIP_T1T_GETMEM_RSP_t;
+
+typedef struct
+{
+ UINT8 hr0;
+ UINT8 hr1;
+} NCIP_T1T_SETHR_CMD_t;
+
+typedef struct
+{
+ UINT8 status;
+} NCIP_T1T_SETHR_RSP_t;
+
+
+#ifndef NCI_GET_CMD_BUF
+#if (!defined (HCI_USE_VARIABLE_SIZE_CMD_BUF) || (HCI_USE_VARIABLE_SIZE_CMD_BUF == FALSE))
+/* Allocate fixed-size buffer from HCI_CMD_POOL (default case) */
+#define NCI_GET_CMD_BUF(paramlen) ((BT_HDR *) GKI_getpoolbuf (NFC_NCI_POOL_ID))
+#else
+/* Allocate smallest possible buffer (for platforms with limited RAM) */
+#define NCI_GET_CMD_BUF(paramlen) ((BT_HDR *) GKI_getbuf ((UINT16) (BT_HDR_SIZE + NCI_MSG_HDR_SIZE + NCI_MSG_OFFSET_SIZE + (paramlen))))
+#endif
+#endif /* NCI_GET_CMD_BUF */
+
+
+#define NCI_MAX_AID_LEN 16
+
+
+typedef struct
+{
+ UINT8 type;
+ UINT8 frequency;
+} tNCI_DISCOVER_PARAMS;
+
+typedef struct
+{
+ UINT8 protocol;
+ UINT8 mode;
+ UINT8 intf_type;
+} tNCI_DISCOVER_MAPS;
+
+#define NCI_NFCID1_MAX_LEN 10
+#define NCI_T1T_HR_LEN 2
+typedef struct
+{
+ UINT8 sens_res[2];/* SENS_RES Response (ATQA). Available after Technology Detection */
+ UINT8 nfcid1_len; /* 4, 7 or 10 */
+ UINT8 nfcid1[NCI_NFCID1_MAX_LEN]; /* AKA NFCID1 */
+ UINT8 sel_rsp; /* SEL_RSP (SAK) Available after Collision Resolution */
+ UINT8 hr_len; /* 2, if T1T HR0/HR1 is reported */
+ UINT8 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 sensb_res_len;/* Length of SENSB_RES Response (Byte 2 - Byte 12 or 13) Available after Technology Detection */
+ UINT8 sensb_res[NCI_MAX_SENSB_RES_LEN]; /* SENSB_RES Response (ATQ) */
+} tNCI_RF_PB_PARAMS;
+
+#define NCI_MAX_SENSF_RES_LEN 18
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 bit_rate;/* NFC_BIT_RATE_212 or NFC_BIT_RATE_424 */
+ UINT8 sensf_res_len;/* Length of SENSF_RES Response (Byte 2 - Byte 17 or 19) Available after Technology Detection */
+ UINT8 sensf_res[NCI_MAX_SENSF_RES_LEN]; /* SENSB_RES Response */
+} tNCI_RF_PF_PARAMS;
+
+typedef struct
+{
+ UINT8 nfcid2[NCI_NFCID2_LEN]; /* NFCID2 generated by the Local NFCC for NFC-DEP Protocol.Available for Frame Interface */
+} tNCI_RF_LF_PARAMS;
+
+typedef struct
+{
+ tNCI_DISCOVERY_TYPE mode;
+ union
+ {
+ tNCI_RF_PA_PARAMS pa;
+ tNCI_RF_PB_PARAMS pb;
+ tNCI_RF_PF_PARAMS pf;
+ tNCI_RF_LF_PARAMS lf;
+ } param; /* Discovery Type specific parameters */
+} tNCI_RF_TECH_PARAMS;
+
+
+#ifndef NCI_MAX_ATS_LEN
+#define NCI_MAX_ATS_LEN 60
+#endif
+#ifndef NCI_MAX_HIS_BYTES_LEN
+#define NCI_MAX_HIS_BYTES_LEN 50
+#endif
+#ifndef NCI_MAX_GEN_BYTES_LEN
+#define NCI_MAX_GEN_BYTES_LEN 48
+#endif
+
+#define NCI_ATS_T0_INDEX 0
+#define NCI_ATS_TC_MASK 0x40
+#define NCI_ATS_TB_MASK 0x20
+#define NCI_ATS_TA_MASK 0x10
+#define NCI_ATS_FSCI_MASK 0x0F
+typedef struct
+{
+ UINT8 ats_res_len; /* Length of ATS RES */
+ UINT8 ats_res[NCI_MAX_ATS_LEN]; /* ATS RES defined in [DIGPROT] */
+} tNCI_INTF_PA_ISO_DEP;
+
+typedef struct
+{
+ UINT8 rats; /* RATS */
+} tNCI_INTF_LA_ISO_DEP;
+
+#define NCI_P_GEN_BYTE_INDEX 15
+#define NCI_L_GEN_BYTE_INDEX 14
+#define NCI_L_NFC_DEP_TO_INDEX 13
+typedef struct
+{
+ UINT8 atr_res_len; /* Length of ATR_RES */
+ UINT8 atr_res[NCI_MAX_ATS_LEN]; /* ATR_RES (Byte 3 - Byte 17+n) as defined in [DIGPROT] */
+} tNCI_INTF_PA_NFC_DEP;
+
+/* Note: keep tNCI_INTF_PA_NFC_DEP data member in the same order as tNCI_INTF_LA_NFC_DEP */
+typedef struct
+{
+ UINT8 atr_req_len; /* Length of ATR_REQ */
+ UINT8 atr_req[NCI_MAX_ATS_LEN]; /* ATR_REQ (Byte 3 - Byte 18+n) as defined in [DIGPROT] */
+} tNCI_INTF_LA_NFC_DEP;
+typedef tNCI_INTF_LA_NFC_DEP tNCI_INTF_LF_NFC_DEP;
+typedef tNCI_INTF_PA_NFC_DEP tNCI_INTF_PF_NFC_DEP;
+
+#define NCI_MAX_ATTRIB_LEN (10 + NCI_MAX_GEN_BYTES_LEN)
+
+typedef struct
+{
+ UINT8 attrib_res_len; /* Length of ATTRIB RES */
+ UINT8 attrib_res[NCI_MAX_ATTRIB_LEN]; /* ATTRIB RES as defined in [DIGPROT] */
+} tNCI_INTF_PB_ISO_DEP;
+
+typedef struct
+{
+ UINT8 attrib_req_len; /* Length of ATTRIB REQ */
+ UINT8 attrib_req[NCI_MAX_ATTRIB_LEN]; /* ATTRIB REQ (Byte 2 - Byte 10+k) as defined in [DIGPROT] */
+} tNCI_INTF_LB_ISO_DEP;
+
+typedef struct
+{
+ tNCI_INTF_TYPE type; /* Interface Type 1 Byte See Table 67 */
+ union
+ {
+ tNCI_INTF_LA_ISO_DEP la_iso;
+ tNCI_INTF_PA_ISO_DEP pa_iso;
+ tNCI_INTF_LB_ISO_DEP lb_iso;
+ tNCI_INTF_PB_ISO_DEP pb_iso;
+ tNCI_INTF_LA_NFC_DEP la_nfc;
+ tNCI_INTF_PA_NFC_DEP pa_nfc;
+ tNCI_INTF_LF_NFC_DEP lf_nfc;
+ tNCI_INTF_PF_NFC_DEP pf_nfc;
+ } intf_param; /* Activation Parameters 0 - n Bytes */
+} tNCI_INTF_PARAMS;
+
+#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..0775180
--- /dev/null
+++ b/src/hal/include/nfc_hal_api.h
@@ -0,0 +1,311 @@
+/******************************************************************************
+ *
+ * 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"
+
+/****************************************************************************
+** NFC_HDR header definition for NFC messages
+*****************************************************************************/
+typedef struct
+{
+ UINT16 event;
+ UINT16 len;
+ UINT16 offset;
+ UINT16 layer_specific;
+} NFC_HDR;
+#define NFC_HDR_SIZE (sizeof (NFC_HDR))
+
+/*******************************************************************************
+** 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
+
+typedef UINT8 tHAL_NFC_STATUS;
+
+/*******************************************************************************
+** 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 HAL_NFC_ENABLE_I2C_FRAGMENTATION_EVT 0x07
+/*******************************************************************************
+** tHAL_NFC_CBACK Definitions
+*******************************************************************************/
+
+/* tHAL_NFC_CBACK events */
+#define HAL_NFC_OPEN_CPLT_EVT 0x00
+#define HAL_NFC_CLOSE_CPLT_EVT 0x01
+#define HAL_NFC_POST_INIT_CPLT_EVT 0x02
+#define HAL_NFC_PRE_DISCOVER_CPLT_EVT 0x03
+#define HAL_NFC_REQUEST_CONTROL_EVT 0x04
+#define HAL_NFC_RELEASE_CONTROL_EVT 0x05
+#define HAL_NFC_ERROR_EVT 0x06
+
+
+typedef void (tHAL_NFC_STATUS_CBACK) (tHAL_NFC_STATUS status);
+typedef void (tHAL_NFC_CBACK) (UINT8 event, tHAL_NFC_STATUS status);
+typedef void (tHAL_NFC_DATA_CBACK) (UINT16 data_len, UINT8 *p_data);
+
+/*******************************************************************************
+** tHAL_NFC_ENTRY HAL entry-point lookup table
+*******************************************************************************/
+
+typedef void (tHAL_API_INITIALIZE) (void);
+typedef void (tHAL_API_TERMINATE) (void);
+typedef void (tHAL_API_OPEN) (tHAL_NFC_CBACK *p_hal_cback, tHAL_NFC_DATA_CBACK *p_data_cback);
+typedef void (tHAL_API_CLOSE) (void);
+typedef void (tHAL_API_CORE_INITIALIZED) (UINT8 *p_core_init_rsp_params);
+typedef void (tHAL_API_WRITE) (UINT16 data_len, UINT8 *p_data);
+#if((ESE_NFC_POWER_MANAGEMENT == TRUE)&&(NFC_NXP_NOT_OPEN_INCLUDED == TRUE))
+typedef int (tHAL_API_IOCTL) (long arg, void *p_data);
+#endif
+typedef BOOLEAN (tHAL_API_PREDISCOVER) (void);
+typedef void (tHAL_API_CONTROL_GRANTED) (void);
+typedef void (tHAL_API_POWER_CYCLE) (void);
+typedef UINT8 (tHAL_API_GET_MAX_NFCEE) (void);
+
+
+#define NFC_HAL_DM_PRE_SET_MEM_LEN 5
+typedef struct
+{
+ UINT32 addr;
+ UINT32 data;
+} tNFC_HAL_DM_PRE_SET_MEM;
+
+/* data members for NFC_HAL-HCI */
+typedef struct
+{
+ BOOLEAN nfc_hal_prm_nvm_required; /* 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 */
+ UINT16 nfc_hal_post_xtal_timeout; /* max time to wait for RESET NTF after setting Xtal frequency */
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+ BOOLEAN nfc_hal_first_boot; /* set nfc_hal_first_boot to TRUE, if platform enables NFC for the first time after bootup */
+ UINT8 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;
+#if((ESE_NFC_POWER_MANAGEMENT == TRUE)&&(NFC_NXP_NOT_OPEN_INCLUDED == TRUE))
+ tHAL_API_IOCTL *ioctl;
+#endif
+ tHAL_API_PREDISCOVER *prediscover;
+ tHAL_API_CONTROL_GRANTED *control_granted;
+ tHAL_API_POWER_CYCLE *power_cycle;
+ tHAL_API_GET_MAX_NFCEE *get_max_ee;
+
+
+} tHAL_NFC_ENTRY;
+
+
+/*******************************************************************************
+** HAL API Function Prototypes
+*******************************************************************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* Toolset-specific macro for exporting API funcitons */
+#if (defined(NFC_HAL_TARGET) && (NFC_HAL_TARGET == TRUE)) && (defined(_WINDLL))
+#define EXPORT_HAL_API __declspec(dllexport)
+#else
+#define EXPORT_HAL_API
+#endif
+
+/*******************************************************************************
+**
+** Function HAL_NfcInitialize
+**
+** Description Called when HAL library is loaded.
+**
+** Initialize GKI and start the HCIT task
+**
+** Returns void
+**
+*******************************************************************************/
+EXPORT_HAL_API void HAL_NfcInitialize(void);
+
+/*******************************************************************************
+**
+** Function HAL_NfcTerminate
+**
+** Description Called to terminate NFC HAL
+**
+** Returns void
+**
+*******************************************************************************/
+EXPORT_HAL_API void HAL_NfcTerminate(void);
+
+/*******************************************************************************
+**
+** Function HAL_NfcOpen
+**
+** Description Open transport and intialize the NFCC, and
+** Register callback for HAL event notifications,
+**
+** HAL_OPEN_CPLT_EVT will notify when operation is complete.
+**
+** Returns void
+**
+*******************************************************************************/
+EXPORT_HAL_API void HAL_NfcOpen (tHAL_NFC_CBACK *p_hal_cback, tHAL_NFC_DATA_CBACK *p_data_cback);
+
+/*******************************************************************************
+**
+** Function HAL_NfcClose
+**
+** Description Prepare for shutdown. A HAL_CLOSE_CPLT_EVT will be
+** reported when complete.
+**
+** Returns void
+**
+*******************************************************************************/
+EXPORT_HAL_API void HAL_NfcClose (void);
+
+/*******************************************************************************
+**
+** Function HAL_NfcCoreInitialized
+**
+** Description Called after the CORE_INIT_RSP is received from the NFCC.
+** At this time, the HAL can do any chip-specific configuration,
+** and when finished signal the libnfc-nci with event
+** HAL_POST_INIT_CPLT_EVT.
+**
+** Returns void
+**
+*******************************************************************************/
+EXPORT_HAL_API void HAL_NfcCoreInitialized (UINT8 *p_core_init_rsp_params);
+
+/*******************************************************************************
+**
+** Function HAL_NfcWrite
+**
+** Description Send an NCI control message or data packet to the
+** transport. If an NCI command message exceeds the transport
+** size, HAL is responsible for fragmenting it, Data packets
+** must be of the correct size.
+**
+** Returns void
+**
+*******************************************************************************/
+EXPORT_HAL_API void HAL_NfcWrite (UINT16 data_len, UINT8 *p_data);
+
+/*******************************************************************************
+**
+** Function HAL_NfcPreDiscover
+**
+** Description Perform any vendor-specific pre-discovery actions (if needed)
+** If any actions were performed TRUE will be returned, and
+** HAL_PRE_DISCOVER_CPLT_EVT will notify when actions are
+** completed.
+**
+** Returns TRUE if vendor-specific pre-discovery actions initialized
+** FALSE if no vendor-specific pre-discovery actions are needed.
+**
+*******************************************************************************/
+EXPORT_HAL_API BOOLEAN HAL_NfcPreDiscover (void);
+
+/*******************************************************************************
+**
+** Function HAL_NfcControlGranted
+**
+** Description Grant control to HAL control for sending NCI commands.
+**
+** Call in response to HAL_REQUEST_CONTROL_EVT.
+**
+** Must only be called when there are no NCI commands pending.
+**
+** HAL_RELEASE_CONTROL_EVT will notify when HAL no longer
+** needs control of NCI.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+EXPORT_HAL_API void HAL_NfcControlGranted (void);
+
+/*******************************************************************************
+**
+** Function HAL_NfcPowerCycle
+**
+** Description Restart NFCC by power cyle
+**
+** HAL_OPEN_CPLT_EVT will notify when operation is complete.
+**
+** Returns void
+**
+*******************************************************************************/
+EXPORT_HAL_API void HAL_NfcPowerCycle (void);
+
+/*******************************************************************************
+**
+** Function HAL_NfcGetMaxNfcee
+**
+** Description Retrieve the maximum number of NFCEEs supported by NFCC
+**
+** Returns the maximum number of NFCEEs supported by NFCC
+**
+*******************************************************************************/
+EXPORT_HAL_API UINT8 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..fcf5a4b
--- /dev/null
+++ b/src/hal/include/nfc_hal_target.h
@@ -0,0 +1,280 @@
+/******************************************************************************
+ *
+ * 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)(p1))
+#define NCI_TRACE_2(l,t,m,p1,p2) LogMsg(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINTPTR)(p1), \
+ (UINTPTR)(p2))
+#define NCI_TRACE_3(l,t,m,p1,p2,p3) LogMsg(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINTPTR)(p1), \
+ (UINTPTR)(p2),(UINTPTR)(p3))
+#define NCI_TRACE_4(l,t,m,p1,p2,p3,p4) LogMsg(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINTPTR)(p1), \
+ (UINTPTR)(p2),(UINTPTR)(p3),(UINTPTR)(p4))
+#define NCI_TRACE_5(l,t,m,p1,p2,p3,p4,p5) LogMsg(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINTPTR)(p1), \
+ (UINTPTR)(p2),(UINTPTR)(p3),(UINTPTR)(p4), \
+ (UINTPTR)(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)(p1), \
+ (UINTPTR)(p2),(UINTPTR)(p3),(UINTPTR)(p4), \
+ (UINTPTR)(p5),(UINTPTR)(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..02018f6
--- /dev/null
+++ b/src/hal/include/nfc_types.h
@@ -0,0 +1,146 @@
+/******************************************************************************
+ *
+ * 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
+
+/* Mask for NFC_HDR event field */
+#define NFC_EVT_MASK 0xFF00
+#define NFC_SUB_EVT_MASK 0x00FF
+
+/****************************************************************************
+** NFC_HAL_TASK definitions
+*****************************************************************************/
+
+/* NFC_HAL_TASK event messages */
+#define NFC_HAL_EVT_TO_NFC_NCI 0x0100 /* NCI message for sending to NFCC */
+#define NFC_HAL_EVT_POST_CORE_RESET 0x0200 /* Request to start NCIT quick timer */
+#define NFC_HAL_EVT_TO_START_QUICK_TIMER 0x0300 /* Request to start chip-specific config */
+#define NFC_HAL_EVT_HCI 0x0400 /* NCI message for hci persistency data */
+#define NFC_HAL_EVT_PRE_DISCOVER 0x0500 /* NCI message to issue prediscover config */
+#define NFC_HAL_EVT_CONTROL_GRANTED 0x0600 /* permission to send commands queued in HAL*/
+
+/* NFC_HAL_TASK sub event messages */
+#define NFC_HAL_HCI_RSP_NV_READ_EVT (0x01 | NFC_HAL_EVT_HCI)
+#define NFC_HAL_HCI_RSP_NV_WRITE_EVT (0x02 | NFC_HAL_EVT_HCI)
+#define NFC_HAL_HCI_VSC_TIMEOUT_EVT (0x03 | NFC_HAL_EVT_HCI)
+
+
+/* Event masks for NFC_TASK messages */
+#define NFC_EVT_TO_NFC_NCI 0x4000 /* NCI message for sending to host stack */
+#define NFC_EVT_TO_NFC_ERR 0x4100 /* Error notification to NFC Task */
+#define NFC_EVT_TO_NFC_MSGS 0x4200 /* Messages between NFC and NCI task */
+
+/*****************************************************************************
+** Macros to get and put bytes to and from a stream (Little Endian format).
+*****************************************************************************/
+
+#define UINT32_TO_STREAM(p, u32) {*(p)++ = (UINT8)(u32); *(p)++ = (UINT8)((u32) >> 8); *(p)++ = (UINT8)((u32) >> 16); *(p)++ = (UINT8)((u32) >> 24);}
+#define UINT24_TO_STREAM(p, u24) {*(p)++ = (UINT8)(u24); *(p)++ = (UINT8)((u24) >> 8); *(p)++ = (UINT8)((u24) >> 16);}
+#define UINT16_TO_STREAM(p, u16) {*(p)++ = (UINT8)(u16); *(p)++ = (UINT8)((u16) >> 8);}
+#define UINT8_TO_STREAM(p, u8) {*(p)++ = (UINT8)(u8);}
+#define INT8_TO_STREAM(p, u8) {*(p)++ = (INT8)(u8);}
+#define ARRAY32_TO_STREAM(p, a) {register int ijk; for (ijk = 0; ijk < 32; ijk++) *(p)++ = (UINT8) a[31 - ijk];}
+#define ARRAY16_TO_STREAM(p, a) {register int ijk; for (ijk = 0; ijk < 16; ijk++) *(p)++ = (UINT8) a[15 - ijk];}
+#define ARRAY8_TO_STREAM(p, a) {register int ijk; for (ijk = 0; ijk < 8; ijk++) *(p)++ = (UINT8) a[7 - ijk];}
+#define BDADDR_TO_STREAM(p, a) {register int ijk; for (ijk = 0; ijk < BD_ADDR_LEN; ijk++) *(p)++ = (UINT8) a[BD_ADDR_LEN - 1 - ijk];}
+#define LAP_TO_STREAM(p, a) {register int ijk; for (ijk = 0; ijk < LAP_LEN; ijk++) *(p)++ = (UINT8) a[LAP_LEN - 1 - ijk];}
+#define DEVCLASS_TO_STREAM(p, a) {register int ijk; for (ijk = 0; ijk < DEV_CLASS_LEN;ijk++) *(p)++ = (UINT8) a[DEV_CLASS_LEN - 1 - ijk];}
+#define ARRAY_TO_STREAM(p, a, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) *(p)++ = (UINT8) a[ijk];}
+#define REVERSE_ARRAY_TO_STREAM(p, a, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) *(p)++ = (UINT8) a[len - 1 - ijk];}
+
+#define STREAM_TO_UINT8(u8, p) {u8 = (UINT8)(*(p)); (p) += 1;}
+#define STREAM_TO_UINT16(u16, p) {u16 = ((UINT16)(*(p)) + (((UINT16)(*((p) + 1))) << 8)); (p) += 2;}
+#define STREAM_TO_UINT24(u32, p) {u32 = (((UINT32)(*(p))) + ((((UINT32)(*((p) + 1)))) << 8) + ((((UINT32)(*((p) + 2)))) << 16) ); (p) += 3;}
+#define STREAM_TO_UINT32(u32, p) {u32 = (((UINT32)(*(p))) + ((((UINT32)(*((p) + 1)))) << 8) + ((((UINT32)(*((p) + 2)))) << 16) + ((((UINT32)(*((p) + 3)))) << 24)); (p) += 4;}
+#define STREAM_TO_BDADDR(a, p) {register int ijk; register UINT8 *pbda = (UINT8 *)a + BD_ADDR_LEN - 1; for (ijk = 0; ijk < BD_ADDR_LEN; ijk++) *pbda-- = *p++;}
+#define STREAM_TO_ARRAY32(a, p) {register int ijk; register UINT8 *_pa = (UINT8 *)a + 31; for (ijk = 0; ijk < 32; ijk++) *_pa-- = *p++;}
+#define STREAM_TO_ARRAY16(a, p) {register int ijk; register UINT8 *_pa = (UINT8 *)a + 15; for (ijk = 0; ijk < 16; ijk++) *_pa-- = *p++;}
+#define STREAM_TO_ARRAY8(a, p) {register int ijk; register UINT8 *_pa = (UINT8 *)a + 7; for (ijk = 0; ijk < 8; ijk++) *_pa-- = *p++;}
+#define STREAM_TO_DEVCLASS(a, p) {register int ijk; register UINT8 *_pa = (UINT8 *)a + DEV_CLASS_LEN - 1; for (ijk = 0; ijk < DEV_CLASS_LEN; ijk++) *_pa-- = *p++;}
+#define STREAM_TO_LAP(a, p) {register int ijk; register UINT8 *plap = (UINT8 *)a + LAP_LEN - 1; for (ijk = 0; ijk < LAP_LEN; ijk++) *plap-- = *p++;}
+#define STREAM_TO_ARRAY(a, p, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) ((UINT8 *) a)[ijk] = *p++;}
+#define REVERSE_STREAM_TO_ARRAY(a, p, len) {register int ijk; register UINT8 *_pa = (UINT8 *)a + len - 1; for (ijk = 0; ijk < len; ijk++) *_pa-- = *p++;}
+
+/*****************************************************************************
+** Macros to get and put bytes to and from a field (Little Endian format).
+** These are the same as to stream, except the pointer is not incremented.
+*****************************************************************************/
+
+#define UINT32_TO_FIELD(p, u32) {*(UINT8 *)(p) = (UINT8)(u32); *((UINT8 *)(p)+1) = (UINT8)((u32) >> 8); *((UINT8 *)(p)+2) = (UINT8)((u32) >> 16); *((UINT8 *)(p)+3) = (UINT8)((u32) >> 24);}
+#define UINT24_TO_FIELD(p, u24) {*(UINT8 *)(p) = (UINT8)(u24); *((UINT8 *)(p)+1) = (UINT8)((u24) >> 8); *((UINT8 *)(p)+2) = (UINT8)((u24) >> 16);}
+#define UINT16_TO_FIELD(p, u16) {*(UINT8 *)(p) = (UINT8)(u16); *((UINT8 *)(p)+1) = (UINT8)((u16) >> 8);}
+#define UINT8_TO_FIELD(p, u8) {*(UINT8 *)(p) = (UINT8)(u8);}
+
+
+/*****************************************************************************
+** Macros to get and put bytes to and from a stream (Big Endian format)
+*****************************************************************************/
+
+#define UINT32_TO_BE_STREAM(p, u32) {*(p)++ = (UINT8)((u32) >> 24); *(p)++ = (UINT8)((u32) >> 16); *(p)++ = (UINT8)((u32) >> 8); *(p)++ = (UINT8)(u32); }
+#define UINT24_TO_BE_STREAM(p, u24) {*(p)++ = (UINT8)((u24) >> 16); *(p)++ = (UINT8)((u24) >> 8); *(p)++ = (UINT8)(u24);}
+#define UINT16_TO_BE_STREAM(p, u16) {*(p)++ = (UINT8)((u16) >> 8); *(p)++ = (UINT8)(u16);}
+#define UINT8_TO_BE_STREAM(p, u8) {*(p)++ = (UINT8)(u8);}
+#define ARRAY_TO_BE_STREAM(p, a, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) *(p)++ = (UINT8) a[ijk];}
+
+#define BE_STREAM_TO_UINT8(u8, p) {u8 = (UINT8)(*(p)); (p) += 1;}
+#define BE_STREAM_TO_UINT16(u16, p) {u16 = (UINT16)(((UINT16)(*(p)) << 8) + (UINT16)(*((p) + 1))); (p) += 2;}
+#define BE_STREAM_TO_UINT24(u32, p) {u32 = (((UINT32)(*((p) + 2))) + ((UINT32)(*((p) + 1)) << 8) + ((UINT32)(*(p)) << 16)); (p) += 3;}
+#define BE_STREAM_TO_UINT32(u32, p) {u32 = ((UINT32)(*((p) + 3)) + ((UINT32)(*((p) + 2)) << 8) + ((UINT32)(*((p) + 1)) << 16) + ((UINT32)(*(p)) << 24)); (p) += 4;}
+#define BE_STREAM_TO_ARRAY(p, a, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) ((UINT8 *) a)[ijk] = *p++;}
+
+
+/*****************************************************************************
+** Macros to get and put bytes to and from a field (Big Endian format).
+** These are the same as to stream, except the pointer is not incremented.
+*****************************************************************************/
+
+#define UINT32_TO_BE_FIELD(p, u32) {*(UINT8 *)(p) = (UINT8)((u32) >> 24); *((UINT8 *)(p)+1) = (UINT8)((u32) >> 16); *((UINT8 *)(p)+2) = (UINT8)((u32) >> 8); *((UINT8 *)(p)+3) = (UINT8)(u32); }
+#define UINT24_TO_BE_FIELD(p, u24) {*(UINT8 *)(p) = (UINT8)((u24) >> 16); *((UINT8 *)(p)+1) = (UINT8)((u24) >> 8); *((UINT8 *)(p)+2) = (UINT8)(u24);}
+#define UINT16_TO_BE_FIELD(p, u16) {*(UINT8 *)(p) = (UINT8)((u16) >> 8); *((UINT8 *)(p)+1) = (UINT8)(u16);}
+#define UINT8_TO_BE_FIELD(p, u8) {*(UINT8 *)(p) = (UINT8)(u8);}
+
+/*****************************************************************************
+** Define trace levels
+*****************************************************************************/
+
+#define BT_TRACE_LEVEL_NONE 0 /* No trace messages to be generated */
+#define BT_TRACE_LEVEL_ERROR 1 /* Error condition trace messages */
+#define BT_TRACE_LEVEL_WARNING 2 /* Warning condition trace messages */
+#define BT_TRACE_LEVEL_API 3 /* API traces */
+#define BT_TRACE_LEVEL_EVENT 4 /* Debug messages for events */
+#define BT_TRACE_LEVEL_DEBUG 5 /* Full debug messages */
+
+
+#define TRACE_CTRL_GENERAL 0x00000000
+#define TRACE_LAYER_NCI 0x00280000
+#define TRACE_LAYER_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..6e8670a
--- /dev/null
+++ b/src/hal/int/nfc_brcm_defs.h
@@ -0,0 +1,415 @@
+/******************************************************************************
+ *
+ * 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
+#define NCI_MSG_RESET_ALL_UICC_CFG 0x0D /* reset HCI network/close all pipes (S,D) register */
+#define NCI_MSG_GET_NFCEE_INFO 0x0E
+#define NCI_MSG_DISABLE_INIT_CHECK 0x0F
+#define NCI_MSG_ANTENNA_SELF_TEST 0x10
+#define NCI_MSG_SET_MAX_PKT_SIZE 0x11
+#define NCI_MSG_NCIP_CLK_REQ_OR_CAR_DET 0x12
+#define NCI_MSG_NCIP_CONFIG_DBUART 0x13
+#define NCI_MSG_NCIP_ENABLE_DVT_DRIVER 0x14
+#define NCI_MSG_SET_ASWP 0x15
+#define NCI_MSG_ENCAPSULATE_NCI 0x16
+#define NCI_MSG_CONFIGURE_ARM_JTAG 0x17
+#define NCI_MSG_STATISTICS 0x18
+#define NCI_MSG_SET_DSP_TABLE 0x19
+#define NCI_MSG_GET_DSP_TABLE 0x1a
+#define NCI_MSG_READY_RX_CMD 0x1b
+#define NCI_MSG_GET_VBAT 0x1c
+#define NCI_MSG_GET_XTAL_INDEX_FROM_DH 0x1d
+#define NCI_MSG_SWP_LOG 0x1e
+#define NCI_MSG_GET_PWRLEVEL 0x1f
+#define NCI_MSG_SET_VBAT_MONITOR 0x20
+#define NCI_MSG_SET_TINT_MODE 0x21
+#define NCI_MSG_ACCESS_APP 0x22
+#define NCI_MSG_SET_SECURE_MODE 0x23
+#define NCI_MSG_GET_NV_DEVICE 0x24
+#define NCI_MSG_LPTD 0x25
+#define NCI_MSG_SET_CE4_AS_SNOOZE 0x26
+#define NCI_MSG_NFCC_SEND_HCI 0x27
+#define NCI_MSG_CE4_PATCH_DOWNLOAD_DONE 0x28
+#define NCI_MSG_EEPROM_RW 0x29
+#define NCI_MSG_GET_CLF_REGISTERS 0x2A
+#define NCI_MSG_RF_TEST 0x2B
+#define NCI_MSG_DEBUG_PRINT 0x2C
+#define NCI_MSG_GET_PATCH_VERSION 0x2D
+#define NCI_MSG_SECURE_PATCH_DOWNLOAD 0x2E
+#define NCI_MSG_SPD_FORMAT_NVM 0x2F
+#define NCI_MSG_SPD_READ_NVM 0x30
+#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
+
+
+#define NCI_NFCC_PIPE_INFO_NV_SIZE 24 /* Static and dynamic pipe id and status for each pipe to uicc0 and uicc1. */
+#define NCI_PERSONALITY_SLOT_SIZE 19
+#define NCI_DYNAMIC_PIPE_SIZE 8
+
+#define NCI_SWP_INTERFACE_TYPE 0xFF /* Type of TLV in NCI_MSG_HCI_NETWK */
+#define NCI_HCI_GATE_TYPE 0xFE /* Type of TLV in NCI_MSG_HCI_NETWK */
+
+/* Secure Patch Download definitions (patch type definitions) */
+#define NCI_SPD_TYPE_HEADER 0x00
+#define NCI_SPD_TYPE_SRAM 0x01
+#define NCI_SPD_TYPE_AON 0x02
+#define NCI_SPD_TYPE_PATCH_TABLE 0x03
+#define NCI_SPD_TYPE_SECURE_CONFIG 0x04
+#define NCI_SPD_TYPE_CONTROLLED_CONFIG 0x05
+#define NCI_SPD_TYPE_SIGNATURE 0x06
+#define NCI_SPD_TYPE_SIGCHEK 0x07
+
+/* Secure Patch Download definitions (NCI_SPD_TYPE_HEADER definitions) */
+#define NCI_SPD_HEADER_OFFSET_CHIPVERLEN 0x18
+#define NCI_SPD_HEADER_CHIPVER_LEN 16
+
+/* NVM Type (in GET_PATCH_VERSION RSP) */
+#define NCI_SPD_NVM_TYPE_NONE 0x00
+#define NCI_SPD_NVM_TYPE_EEPROM 0x01
+#define NCI_SPD_NVM_TYPE_UICC 0x02
+
+/**********************************************
+ * NCI NFCC proprietary features in octet 3
+ **********************************************/
+#define NCI_FEAT_SIGNED_PATCH 0x01000000
+
+/**********************************************
+ * NCI Interface Types
+ **********************************************/
+#define NCI_INTERFACE_VS_CALYPSO_CE 0x81
+#define NCI_INTERFACE_VS_T2T_CE 0x82 /* for Card Emulation side */
+#define NCI_INTERFACE_VS_15693 0x83 /* for both Reader/Writer and Card Emulation side */
+#define NCI_INTERFACE_VS_T1T_CE 0x84 /* for Card Emulation side */
+
+/**********************************************
+ * NCI Proprietary Parameter IDs
+ **********************************************/
+#define NCI_PARAM_ID_LA_FSDI 0xA0
+#define NCI_PARAM_ID_LB_FSDI 0xA1
+#define NCI_PARAM_ID_HOST_LISTEN_MASK 0xA2
+#define NCI_PARAM_ID_CHIP_TYPE 0xA3 /* NFCDEP */
+#define NCI_PARAM_ID_PA_ANTICOLL 0xA4
+#define NCI_PARAM_ID_CONTINUE_MODE 0xA5
+#define NCI_PARAM_ID_LBP 0xA6
+#define NCI_PARAM_ID_T1T_RDR_ONLY 0xA7
+#define NCI_PARAM_ID_LA_SENS_RES 0xA8
+#define NCI_PARAM_ID_PWR_SETTING_BITMAP 0xA9
+#define NCI_PARAM_ID_WI_NTF_ENABLE 0xAA
+#define NCI_PARAM_ID_LN_BITRATE 0xAB /* NFCDEP Listen Bitrate */
+#define NCI_PARAM_ID_LF_BITRATE 0xAC /* FeliCa */
+#define NCI_PARAM_ID_SWP_BITRATE_MASK 0xAD
+#define NCI_PARAM_ID_KOVIO 0xAE
+#define NCI_PARAM_ID_UICC_NTF_TO 0xAF
+#define NCI_PARAM_ID_NFCDEP 0xB0
+#define NCI_PARAM_ID_CLF_REGS_CFG 0xB1
+#define NCI_PARAM_ID_NFCDEP_TRANS_TIME 0xB2
+#define NCI_PARAM_ID_CREDIT_TIMER 0xB3
+#define NCI_PARAM_ID_CORRUPT_RX 0xB4
+#define NCI_PARAM_ID_ISODEP 0xB5
+#define NCI_PARAM_ID_LF_CONFIG 0xB6
+#define NCI_PARAM_ID_I93_DATARATE 0xB7
+#define NCI_PARAM_ID_CREDITS_THRESHOLD 0xB8
+#define NCI_PARAM_ID_TAGSNIFF_CFG 0xB9
+#define NCI_PARAM_ID_PA_FSDI 0xBA /* ISODEP */
+#define NCI_PARAM_ID_PB_FSDI 0xBB /* ISODEP */
+#define NCI_PARAM_ID_FRAME_INTF_RETXN 0xBC
+
+#define NCI_PARAM_ID_UICC_RDR_PRIORITY 0xBD
+#define NCI_PARAM_ID_GUARD_TIME 0xBE
+#define NCI_PARAM_ID_STDCONFIG 0xBF /* dont not use this config item */
+#define NCI_PARAM_ID_PROPCFG 0xC0 /* dont not use this config item */
+#define NCI_PARAM_ID_MAXTRY2ACTIVATE 0xC1
+#define NCI_PARAM_ID_SWPCFG 0xC2
+#define NCI_PARAM_ID_CLF_LPM_CFG 0xC3
+#define NCI_PARAM_ID_DCLB 0xC4
+#define NCI_PARAM_ID_ACT_ORDER 0xC5
+#define NCI_PARAM_ID_DEP_DELAY_ACT 0xC6
+#define NCI_PARAM_ID_DH_PARITY_CRC_CTL 0xC7
+#define NCI_PARAM_ID_PREINIT_DSP_CFG 0xC8
+#define NCI_PARAM_ID_FW_WORKAROUND 0xC9
+#define NCI_PARAM_ID_RFU_CONFIG 0xCA
+#define NCI_PARAM_ID_EMVCO_ENABLE 0xCB
+#define NCI_PARAM_ID_ANTDRIVER_PARAM 0xCC
+#define NCI_PARAM_ID_PLL325_CFG_PARAM 0xCD
+#define NCI_PARAM_ID_OPNLP_ADPLL_ENABLE 0xCE
+#define NCI_PARAM_ID_CONFORMANCE_MODE 0xCF
+
+#define NCI_PARAM_ID_LPO_ON_OFF_ENABLE 0xD0
+#define NCI_PARAM_ID_FORCE_VANT 0xD1
+#define NCI_PARAM_ID_COEX_CONFIG 0xD2
+#define NCI_PARAM_ID_INTEL_MODE 0xD3
+
+#define NCI_PARAM_ID_AID 0xFF
+
+/**********************************************
+ * NCI Parameter ID Lens
+ **********************************************/
+#define NCI_PARAM_LEN_PWR_SETTING_BITMAP 3
+#define NCI_PARAM_LEN_HOST_LISTEN_MASK 2
+#define NCI_PARAM_LEN_PLL325_CFG_PARAM 14
+
+/**********************************************
+ * Snooze Mode
+ **********************************************/
+#define NFC_SNOOZE_MODE_NONE 0x00 /* Snooze mode disabled */
+#define NFC_SNOOZE_MODE_UART 0x01 /* Snooze mode for UART */
+#define NFC_SNOOZE_MODE_SPI_I2C 0x08 /* Snooze mode for SPI/I2C */
+
+#define NFC_SNOOZE_ACTIVE_LOW 0x00 /* high to low voltage is asserting */
+#define NFC_SNOOZE_ACTIVE_HIGH 0x01 /* low to high voltage is asserting */
+
+
+/**********************************************
+ * 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 pipe_id; /* if MSB is set then valid, 7 bits for Pipe ID */
+ UINT8 mode; /* Type A card emulation enabled indicator, 0x02:enabled */
+ UINT8 sak;
+ UINT8 uid_reg_len;
+ UINT8 uid_reg[NFC_HAL_HCI_CE_RF_A_UID_REG_LEN];
+ UINT8 atqa[NFC_HAL_HCI_CE_RF_A_ATQA_RSP_CODE_LEN]; /* ATQA response code */
+ UINT8 app_data_len;
+ UINT8 app_data[NFC_HAL_HCI_CE_RF_A_MAX_HIST_DATA_LEN]; /* 15 bytes optional storage for historic data, use 2 slots */
+ UINT8 fwi_sfgi; /* FRAME WAITING TIME, START-UP FRAME GUARD TIME */
+ UINT8 cid_support;
+ UINT8 datarate_max[NFC_HAL_HCI_CE_RF_A_MAX_DATA_RATE_LEN];
+ UINT8 clt_support;
+} tNCI_HCI_CE_RF_A;
+
+/* Card emulation RF Gate B registry information */
+typedef struct
+{
+ UINT8 pipe_id; /* if MSB is set then valid, 7 bits for Pipe ID */
+ UINT8 mode; /* Type B card emulation enabled indicator, 0x02:enabled */
+ UINT8 pupi_len;
+ UINT8 pupi_reg[NFC_HAL_HCI_CE_RF_B_PUPI_LEN];
+ UINT8 afi;
+ UINT8 atqb[NFC_HAL_HCI_CE_RF_B_ATQB_LEN]; /* 4 bytes ATQB application data */
+ UINT8 higherlayer_resp[NFC_HAL_HCI_CE_RF_B_HIGHER_LAYER_RSP_LEN]; /* 0~ 61 bytes ATRB_INF use 1~4 personality slots */
+ UINT8 datarate_max[NFC_HAL_HCI_CE_RF_B_MAX_DATA_RATE_LEN];
+ UINT8 natrb;
+} tNCI_HCI_CE_RF_B;
+
+/* Card emulation RF Gate BP registry information */
+typedef struct
+{
+ UINT8 pipe_id; /* if MSB is set then valid, 7 bits for Pipe ID */
+ UINT8 mode; /* Type B prime card emulation enabled indicator, 0x02:enabled */
+ UINT8 pat_in_len;
+ UINT8 pat_in[NFC_HAL_HCI_CE_RF_BP_MAX_PAT_IN_LEN];
+ UINT8 dat_out_len;
+ UINT8 dat_out[NFC_HAL_HCI_CE_RF_BP_DATA_OUT_LEN]; /* ISO7816-3 <=64 byte, and other fields are 9 bytes */
+ UINT8 natr;
+} tNCI_HCI_CE_RF_BP;
+
+/* Card emulation RF Gate F registry information */
+typedef struct
+{
+ UINT8 pipe_id; /* if MSB is set then valid, 7 bits for Pipe ID */
+ UINT8 mode; /* Type F card emulation enabled indicator, 0x02:enabled */
+ UINT8 speed_cap;
+ UINT8 clt_support;
+} tNCI_HCI_CE_RF_F;
+
+/* Reader RF Gate A registry information */
+typedef struct
+{
+ UINT8 pipe_id; /* if MSB is set then valid, 7 bits for Pipe ID */
+ UINT8 datarate_max;
+} tNCI_HCI_RD_RF_A;
+
+/* Reader RF Gate B registry information */
+typedef struct
+{
+ UINT8 pipe_id; /* if MSB is set then valid, 7 bits for Pipe ID */
+ UINT8 afi;
+ UINT8 hldata_len;
+ UINT8 high_layer_data[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 source_host;
+ UINT8 dest_host;
+ UINT8 source_gate;
+ UINT8 dest_gate;
+ UINT8 pipe_id; /* if MSB is set then valid, 7 bits for Pipe ID */
+} tNCI_HCI_DYN_PIPE_INFO;
+
+/*************************************************************
+ * HCI Network CMD/NTF structure for UICC host in the network
+ *************************************************************/
+typedef struct
+{
+ UINT8 target_handle;
+ UINT8 session_id[NFC_HAL_HCI_SESSION_ID_LEN];
+ UINT8 sync_id[NFC_HAL_HCI_SYNC_ID_LEN];
+ UINT8 static_pipe_info;
+ tNCI_HCI_CE_RF_A ce_rf_a;
+ tNCI_HCI_CE_RF_B ce_rf_b;
+ tNCI_HCI_CE_RF_BP ce_rf_bp;
+ tNCI_HCI_CE_RF_F ce_rf_f;
+ tNCI_HCI_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 target_handle;
+ UINT8 session_id[NFC_HAL_HCI_SESSION_ID_LEN];
+ UINT8 static_pipe_info;
+ UINT8 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..8269e14
--- /dev/null
+++ b/src/hal/int/nfc_hal_int.h
@@ -0,0 +1,528 @@
+/******************************************************************************
+ *
+ * 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 */
+#define NFC_HAL_WAIT_RSP_CMD 0x10 /* wait response on an NCI command */
+#define NFC_HAL_WAIT_RSP_VSC 0x20 /* wait response on an NCI vendor specific command */
+#define NFC_HAL_WAIT_RSP_PROP 0x40 /* wait response on a proprietary command */
+#define NFC_HAL_WAIT_RSP_NONE 0x00 /* not waiting for anything */
+
+typedef UINT8 tNFC_HAL_WAIT_RSP;
+
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+
+typedef UINT16 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
+#define NFC_HAL_HCI_HOST_ID_UICC0 0x02 /* Host ID for UICC 0 */
+#define NFC_HAL_HCI_HOST_ID_UICC1 0x03 /* Host ID for UICC 1 */
+#define NFC_HAL_HCI_HOST_ID_UICC2 0x04 /* Host ID for UICC 2 */
+#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 */
+#define NFC_HAL_NVM_FLAGS_NO_NVM 0x01 /* No NVM available */
+#define NFC_HAL_NVM_FLAGS_LPM_BAD 0x02 /* FPM patch in NVM failed CRC check */
+#define NFC_HAL_NVM_FLAGS_FPM_BAD 0x04 /* LPM patch in NVM failed CRC check */
+#define NFC_HAL_NVM_FLAGS_PATCH_PRESENT 0x08 /* Patch is present in NVM */
+
+/* NFC HAL transport configuration */
+typedef struct
+{
+ BOOLEAN shared_transport; /* TRUE if using shared HCI/NCI transport */
+ UINT8 userial_baud;
+ UINT8 userial_fc;
+} tNFC_HAL_TRANS_CFG;
+
+#ifdef TESTER
+#define NFC_HAL_TRANS_CFG_QUALIFIER /* For Insight, ncit_cfg is runtime-configurable */
+#else
+#define NFC_HAL_TRANS_CFG_QUALIFIER const /* For all other platforms, ncit_cfg is constant */
+#endif
+extern NFC_HAL_TRANS_CFG_QUALIFIER tNFC_HAL_TRANS_CFG nfc_hal_trans_cfg;
+
+/*****************************************************************************
+* BT HCI definitions
+*****************************************************************************/
+#define BT_HDR NFC_HDR
+
+/* Tranport message type */
+#define HCIT_TYPE_COMMAND 0x01
+#define HCIT_TYPE_EVENT 0x04
+#define HCIT_TYPE_NFC 0x10
+
+/* Vendor-Specific BT HCI definitions */
+#define HCI_SUCCESS 0x00
+#define HCI_GRP_VENDOR_SPECIFIC (0x3F << 10) /* 0xFC00 */
+#define HCI_BRCM_WRITE_SLEEP_MODE (0x0027 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_GRP_HOST_CONT_BASEBAND_CMDS (0x03 << 10) /* 0x0C00 */
+#define HCI_RESET (0x0003 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_COMMAND_COMPLETE_EVT 0x0E
+#define HCI_BRCM_WRITE_SLEEP_MODE_LENGTH 12
+#define HCI_BRCM_UPDATE_BAUD_RATE_UNENCODED_LENGTH 0x06
+#define HCIE_PREAMBLE_SIZE 2
+#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 tNFC_HAL_NCI_RAS;
+
+/* NFC HAL power mode */
+enum
+{
+ NFC_HAL_POWER_MODE_FULL, /* NFCC is full power mode */
+ NFC_HAL_POWER_MODE_LAST
+};
+typedef UINT8 tNFC_HAL_POWER_MODE;
+
+
+/* NFC HAL event for low power mode */
+enum
+{
+ NFC_HAL_LP_TX_DATA_EVT, /* DH is sending data to NFCC */
+ NFC_HAL_LP_RX_DATA_EVT, /* DH received data from NFCC */
+ NFC_HAL_LP_TIMEOUT_EVT, /* Timeout */
+ NFC_HAL_LP_LAST_EVT
+};
+typedef UINT8 tNFC_HAL_LP_EVT;
+
+#define NFC_HAL_ASSERT_NFC_WAKE 0x00 /* assert NFC_WAKE */
+#define NFC_HAL_DEASSERT_NFC_WAKE 0x01 /* deassert NFC_WAKE */
+
+#define NFC_HAL_BT_HCI_CMD_HDR_SIZE 3 /* opcode (2) + length (1) */
+#define NFC_HAL_CMD_TOUT (2000) /* timeout for NCI CMD (in ms) */
+
+#define NFC_HAL_SAVED_HDR_SIZE (2)
+#define NFC_HAL_SAVED_CMD_SIZE (2)
+
+#ifndef NFC_HAL_DEBUG
+#define NFC_HAL_DEBUG TRUE
+#endif
+
+#if (NFC_HAL_DEBUG == TRUE)
+extern const char * const nfc_hal_init_state_str[];
+#define NFC_HAL_SET_INIT_STATE(state) 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 tNFC_HAL_INIT_STATE;
+
+/* NFC HAL - NFCC config items during post initialization */
+enum
+{
+ NFC_HAL_DM_CONFIG_LPTD,
+ NFC_HAL_DM_CONFIG_PLL_325,
+ NFC_HAL_DM_CONFIG_START_UP,
+ NFC_HAL_DM_CONFIG_I93_DATA_RATE,
+ NFC_HAL_DM_CONFIG_FW_FSM,
+ NFC_HAL_DM_CONFIG_START_UP_VSC,
+ NFC_HAL_DM_CONFIG_NONE
+};
+typedef UINT8 tNFC_HAL_DM_CONFIG;
+
+/* callback function prototype */
+typedef struct
+{
+ UINT16 opcode;
+ UINT16 param_len;
+ UINT8 *p_param_buf;
+} tNFC_HAL_BTVSC_CPLT;
+
+typedef void (tNFC_HAL_BTVSC_CPLT_CBACK) (tNFC_HAL_BTVSC_CPLT *p1);
+
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+
+/* data type for NFC_HAL_HCI_RSP_NV_READ_EVT */
+typedef struct
+{
+ NFC_HDR hdr;
+ UINT8 block;
+ UINT16 size;
+ tHAL_NFC_STATUS status;
+} tNFC_HAL_HCI_RSP_NV_READ_EVT;
+
+/* data type for NFC_HAL_HCI_RSP_NV_WRITE_EVT */
+typedef struct
+{
+ NFC_HDR hdr;
+ tHAL_NFC_STATUS status;
+} tNFC_HAL_HCI_RSP_NV_WRITE_EVT;
+
+
+/* union of all event data types */
+typedef union
+{
+ NFC_HDR hdr;
+ /* Internal events */
+ tNFC_HAL_HCI_RSP_NV_READ_EVT nv_read;
+ tNFC_HAL_HCI_RSP_NV_WRITE_EVT nv_write;
+} tNFC_HAL_HCI_EVENT_DATA;
+
+#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 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 power_mode;
+ UINT16 len;
+} tNFC_HAL_PRM_PATCHDESC;
+
+typedef struct
+{
+ tNFC_HAL_PRM_STATE state; /* download state */
+ UINT32 flags; /* internal flags */
+ UINT16 cur_patch_len_remaining;/* bytes remaining in patchfile to process */
+ const UINT8* p_cur_patch_data; /* pointer to patch currently being downloaded */
+ UINT16 cur_patch_offset; /* offset of next byte to process */
+ UINT32 dest_ram;
+ TIMER_LIST_ENT timer; /* Timer for patch download */
+ void *p_param; /* general purpose param for PRM */
+ UINT8 param_idx; /* information related to general purpose param*/
+
+ /* Secure Patch Download */
+ UINT32 spd_patch_needed_mask; /* Mask of patches that need to be downloaded */
+ UINT8 spd_patch_count; /* Number of patches left to download */
+ UINT8 spd_cur_patch_idx; /* Current patch being downloaded */
+
+ tNFC_HAL_PRM_PATCHDESC spd_patch_desc[NFC_HAL_PRM_MAX_PATCH_COUNT];
+
+ /* I2C-patch */
+ UINT8 *p_spd_patch; /* pointer to spd patch */
+ UINT16 spd_patch_len_remaining;/* patch length */
+ UINT16 spd_patch_offset; /* offset of next byte to process */
+
+ tNFC_HAL_PRM_FORMAT format; /* format of patch ram */
+ tNFC_HAL_PRM_CBACK *p_cback; /* Callback for download status notifications */
+ UINT32 patchram_delay; /* the dealy after patch */
+} tNFC_HAL_PRM_CB;
+
+/* Information about current patch in NVM */
+typedef struct
+{
+ UINT16 project_id; /* Current project_id of patch in nvm */
+ UINT16 ver_major; /* Current major version of patch in nvm */
+ UINT16 ver_minor; /* Current minor version of patch in nvm */
+ UINT16 fpm_size; /* Current size of FPM patch in nvm */
+ UINT16 lpm_size; /* Current size of LPM patch in nvm */
+ UINT8 flags; /* See NFC_HAL_NVM_FLAGS_* flag definitions */
+ UINT8 nvm_type; /* Current NVM Type - UICC/EEPROM */
+ UINT8 chip_ver[NFC_HAL_PRM_MAX_CHIP_VER_LEN]; /* patch chip version */
+} tNFC_HAL_NVM;
+
+/* Patch for I2C fix */
+typedef struct
+{
+ UINT8 *p_patch; /* patch for i2c fix */
+ UINT32 prei2c_delay; /* the dealy after preI2C patch */
+ UINT16 len; /* i2c patch length */
+} tNFC_HAL_PRM_I2C_FIX_CB;
+
+/* Control block for NCI transport */
+typedef struct
+{
+ UINT8 nci_ctrl_size; /* Max size for NCI messages */
+ UINT8 rcv_state; /* current rx state */
+ UINT16 rcv_len; /* bytes remaining to be received in current rx state */
+ NFC_HDR *p_rcv_msg; /* buffer to receive NCI message */
+ NFC_HDR *p_frag_msg; /* fragmented NCI message; waiting for last fragment */
+ NFC_HDR *p_pend_cmd; /* pending NCI message; waiting for NFCC state to be free */
+ tNFC_HAL_NCI_RAS nci_ras; /* nci reassembly error status */
+ TIMER_LIST_ENT nci_wait_rsp_timer; /* Timer for waiting for nci command response */
+ tNFC_HAL_WAIT_RSP nci_wait_rsp; /* nci wait response flag */
+ UINT8 last_hdr[NFC_HAL_SAVED_HDR_SIZE];/* part of last NCI command header */
+ UINT8 last_cmd[NFC_HAL_SAVED_CMD_SIZE];/* part of last NCI command payload */
+ void *p_vsc_cback; /* the callback function for last VSC command */
+} tNFC_HAL_NCIT_CB;
+
+/* Control block for device initialization */
+typedef struct
+{
+ tNFC_HAL_INIT_STATE initializing_state; /* state of initializing NFCC */
+
+ UINT32 brcm_hw_id; /* BRCM NFCC HW ID */
+ tNFC_HAL_DM_CONFIG next_dm_config; /* next config in post initialization */
+ UINT8 next_startup_vsc; /* next start-up VSC offset in post init */
+
+ tNFC_HAL_POWER_MODE power_mode; /* NFCC power mode */
+ UINT8 snooze_mode; /* current snooze mode */
+ UINT8 new_snooze_mode; /* next snooze mode after receiving cmpl */
+ UINT8 nfc_wake_active_mode; /* NFC_HAL_LP_ACTIVE_LOW/HIGH */
+ TIMER_LIST_ENT lp_timer; /* timer for low power mode */
+
+
+ tHAL_NFC_STATUS_CBACK *p_prop_cback; /* callback to notify complete of proprietary update */
+} tNFC_HAL_DEV_CB;
+
+#if (defined(NFC_HAL_HCI_INCLUDED) && (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 *p_hci_netwk_info_buf; /* Buffer for reading HCI Network information */
+ UINT8 *p_hci_netwk_dh_info_buf; /* Buffer for reading HCI Network DH information */
+ UINT8 hci_netwk_config_block; /* Rsp awaiting for hci network configuration block */
+ BOOLEAN b_wait_hcp_conn_create_rsp; /* Waiting for hcp connection create response */
+ BOOLEAN clear_all_pipes_to_uicc1; /* UICC1 was restarted for patch download */
+ BOOLEAN update_session_id; /* Next response from NFCC is to Get Session id cmd */
+ BOOLEAN hci_fw_validate_netwk_cmd;/* Flag to indicate if hci network ntf to validate */
+ UINT8 hcp_conn_id; /* NCI Connection id for HCP */
+ UINT8 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 (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+ /* data members for NFC_HAL-HCI */
+ tNFC_HAL_HCI_CB hci_cb;
+#endif
+
+ UINT8 pre_discover_done; /* TRUE, when the prediscover config is complete */
+ UINT8 pre_set_mem_idx;
+
+ UINT8 max_rf_credits; /* NFC Max RF data credits */
+ UINT8 max_ee; /* NFC Max number of NFCEE supported by NFCC */
+ UINT8 trace_level; /* NFC HAL trace level */
+} tNFC_HAL_CB;
+
+/* Global NCI data */
+#if NFC_DYNAMIC_MEMORY == FALSE
+extern tNFC_HAL_CB nfc_hal_cb;
+#else
+#define nfc_hal_cb (*nfc_hal_cb_ptr)
+extern tNFC_HAL_CB *nfc_hal_cb_ptr;
+#endif
+extern UINT8 *p_nfc_hal_pre_discover_cfg;
+/****************************************************************************
+** Internal nfc functions
+****************************************************************************/
+
+/* From nfc_hal_main.c */
+UINT32 nfc_hal_main_task (UINT32 param);
+void nfc_hal_main_init (void);
+void nfc_hal_main_pre_init_done (tHAL_NFC_STATUS);
+void nfc_hal_main_start_quick_timer (TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout);
+void nfc_hal_main_stop_quick_timer (TIMER_LIST_ENT *p_tle);
+void nfc_hal_main_send_error (tHAL_NFC_STATUS status);
+void nfc_hal_send_nci_msg_to_nfc_task (NFC_HDR * p_msg);
+
+/* nfc_hal_nci.c */
+BOOLEAN nfc_hal_nci_receive_msg (UINT8 byte);
+BOOLEAN 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 *p_data, UINT16 len, tNFC_HAL_NCI_CBACK *p_cback);
+void nfc_hal_dm_send_bt_cmd (const UINT8 *p_data, UINT16 len, tNFC_HAL_BTVSC_CPLT_CBACK *p_cback);
+void nfc_hal_dm_set_nfc_wake (UINT8 cmd);
+void nfc_hal_dm_pre_init_nfcc (void);
+void nfc_hal_dm_shutting_down_nfcc (void);
+BOOLEAN nfc_hal_dm_power_mode_execute (tNFC_HAL_LP_EVT event);
+void nfc_hal_dm_send_pend_cmd (void);
+tHAL_NFC_STATUS nfc_hal_dm_set_config (UINT8 tlv_size, UINT8 *p_param_tlvs, tNFC_HAL_NCI_CBACK *p_cback);
+BOOLEAN nfc_hal_dm_check_pre_set_mem (void);
+
+
+/* nfc_hal_prm.c */
+void nfc_hal_prm_spd_reset_ntf (UINT8 reset_reason, UINT8 reset_type);
+void nfc_hal_prm_nci_command_complete_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data);
+void nfc_hal_prm_process_timeout (void *p_tle);
+
+#if (defined(NFC_HAL_HCI_INCLUDED) && (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 *p_data);
+void nfc_hal_hci_handle_hcp_pkt_from_hc (UINT8 *p_data);
+NFC_HDR* nfc_hal_hci_postproc_hcp (void);
+BOOLEAN nfc_hal_hci_handle_hcp_pkt_to_hc (UINT8 *p_data);
+void nfc_hal_hci_timeout_cback (void *p_tle);
+void nfc_hal_hci_handle_build_info (UINT8 chipverlen, UINT8 *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 (defined(NFC_HAL_TRACE_PROTOCOL) && (NFC_HAL_TRACE_PROTOCOL == TRUE))
+#if !defined (DISP_NCI)
+#define DISP_NCI (DispNci)
+void DispNci (UINT8 *p, UINT16 len, BOOLEAN is_recv);
+#endif /* DISP_NCI */
+
+/* For displaying vendor-specific HCI commands */
+void DispHciCmd (BT_HDR *p_buf);
+void DispHciEvt (BT_HDR *p_buf);
+#endif /* NFC_HAL_TRACE_PROTOCOL */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_HAL_INT_H */
diff --git a/src/hal/int/nfc_hal_int_api.h b/src/hal/int/nfc_hal_int_api.h
new file mode 100644
index 0000000..dc694d9
--- /dev/null
+++ b/src/hal/int/nfc_hal_int_api.h
@@ -0,0 +1,298 @@
+/******************************************************************************
+ *
+ * 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 tNFC_HAL_XTAL_INDEX;
+
+/* Broadcom specific device initialization before sending NCI reset */
+
+typedef struct
+{
+ UINT32 brcm_hw_id;
+ UINT16 xtal_freq;
+ UINT8 xtal_index;
+} tNFC_HAL_DEV_INIT_XTAL_CFG;
+
+#define NFC_HAL_DEV_INIT_MAX_XTAL_CFG 5
+
+typedef struct
+{
+ UINT8 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
+*****************************************************************************/
+
+#define NFC_HAL_LP_SNOOZE_MODE_NONE NFC_SNOOZE_MODE_NONE /* Snooze mode disabled */
+#define NFC_HAL_LP_SNOOZE_MODE_UART NFC_SNOOZE_MODE_UART /* Snooze mode for UART */
+#define NFC_HAL_LP_SNOOZE_MODE_SPI_I2C NFC_SNOOZE_MODE_SPI_I2C /* Snooze mode for SPI/I2C */
+
+#define NFC_HAL_LP_ACTIVE_LOW NFC_SNOOZE_ACTIVE_LOW /* high to low voltage is asserting */
+#define NFC_HAL_LP_ACTIVE_HIGH NFC_SNOOZE_ACTIVE_HIGH /* low to high voltage is asserting */
+
+/*****************************************************************************
+** Patch RAM Constants
+*****************************************************************************/
+
+/* patch format type */
+#define NFC_HAL_PRM_FORMAT_BIN 0x00
+#define NFC_HAL_PRM_FORMAT_HCD 0x01
+#define NFC_HAL_PRM_FORMAT_NCD 0x02
+typedef UINT8 tNFC_HAL_PRM_FORMAT;
+
+/*****************************************************************************
+** Patch RAM Callback for event notificaton
+*****************************************************************************/
+/* Events for tNFC_HAL_PRM_CBACK */
+enum
+{
+ NFC_HAL_PRM_CONTINUE_EVT,
+ NFC_HAL_PRM_COMPLETE_EVT,
+ NFC_HAL_PRM_ABORT_EVT,
+ NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT, /* Patch is invalid (bad version, project id, or chip) */
+ NFC_HAL_PRM_ABORT_BAD_SIGNATURE_EVT, /* Patch has invalid signature */
+ NFC_HAL_PRM_SPD_GET_PATCHFILE_HDR_EVT, /* Secure Patch Download: request for patchfile header */
+ NFC_HAL_PRM_SPD_GET_NEXT_PATCH, /* Get first command of next patch in patchfile */
+ NFC_HAL_PRM_ABORT_NO_NVM_EVT /* nfc_hal_prm_nvm_required is TRUE and NVM is unavail */
+};
+
+typedef void (tNFC_HAL_PRM_CBACK) (UINT8 event);
+
+typedef UINT8 tNFC_HAL_NCI_EVT; /* MT + Opcode */
+typedef void (tNFC_HAL_NCI_CBACK) (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+**
+** Function HAL_NfcPreInitDone
+**
+** Description Notify that pre-initialization of NFCC is complete
+**
+** Returns void
+**
+*******************************************************************************/
+void HAL_NfcPreInitDone (tHAL_NFC_STATUS status);
+
+/*******************************************************************************
+**
+** Function HAL_NfcReInit
+**
+** Description This function is called to 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 snooze_mode,
+ UINT8 idle_threshold_dh,
+ UINT8 idle_threshold_nfcc,
+ UINT8 nfc_wake_active_mode,
+ UINT8 dh_wake_active_mode,
+ tHAL_NFC_STATUS_CBACK *p_snooze_cback);
+
+/*******************************************************************************
+**
+** Function HAL_NfcPrmDownloadStart
+**
+** Description Initiate patch download
+**
+** Input Params
+** format_type patch format type
+** (NFC_HAL_PRM_FORMAT_BIN, NFC_HAL_PRM_FORMAT_HCD, or
+** NFC_HAL_PRM_FORMAT_NCD)
+**
+** dest_address destination adderess (needed for BIN format only)
+**
+** p_patchram_buf pointer to patchram buffer. If NULL,
+** then app must call HAL_NfcPrmDownloadContinue when
+** NFC_HAL_PRM_CONTINUE_EVT is received, to send the next
+** segment of patchram
+**
+** patchram_len size of p_patchram_buf (if non-NULL)
+**
+** patchram_delay The delay after each patch.
+** If the given value is less than the size of the patchram,
+** the size of patchram is used instead.
+**
+** p_cback callback for download status
+**
+**
+** Returns TRUE if successful, otherwise FALSE
+**
+**
+*******************************************************************************/
+BOOLEAN HAL_NfcPrmDownloadStart (tNFC_HAL_PRM_FORMAT format_type,
+ UINT32 dest_address,
+ UINT8 *p_patchram_buf,
+ UINT32 patchram_len,
+ UINT32 patchram_delay,
+ tNFC_HAL_PRM_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function HAL_NfcPrmDownloadContinue
+**
+** Description Send next segment of patchram to controller. Called when
+** NFC_HAL_PRM_CONTINUE_EVT is received.
+**
+** Only needed if HAL_NfcPrmDownloadStart was called with
+** p_patchram_buf=NULL
+**
+** Input Params p_patch_data pointer to patch data
+** patch_data_len patch data len
+**
+** Returns TRUE if successful, otherwise FALSE
+**
+*******************************************************************************/
+BOOLEAN HAL_NfcPrmDownloadContinue (UINT8 *p_patch_data,
+ UINT16 patch_data_len);
+
+/*******************************************************************************
+**
+** Function HAL_NfcPrmSetI2cPatch
+**
+** Description Specify patchfile for BCM20791B3 I2C fix. This fix
+** must be downloaded prior to initial patch download for I2C
+** transport
+**
+** Input Params p_i2c_patchfile_buf: pointer to patch for i2c fix
+** i2c_patchfile_len: length of patch
+** prei2c_delay: the delay before downloading main patch
+** if 0 is given, NFC_HAL_PRM_POST_I2C_FIX_DELAY is used instead.
+**
+** Returns Nothing
+**
+**
+*******************************************************************************/
+void HAL_NfcPrmSetI2cPatch (UINT8 *p_i2c_patchfile_buf,
+ UINT16 i2c_patchfile_len, UINT32 prei2c_delay);
+
+/*******************************************************************************
+**
+** Function HAL_NfcPrmSetSpdNciCmdPayloadSize
+**
+** Description Set Host-to-NFCC NCI message size for secure patch download
+**
+** This API must be called before calling HAL_NfcPrmDownloadStart.
+** If the API is not called, then PRM will use the default
+** message size.
+**
+** Typically, this API is only called for platforms that have
+** message-size limitations in the transport/driver.
+**
+** Valid message size range: NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE to 255.
+**
+** Returns HAL_NFC_STATUS_OK if successful
+** HAL_NFC_STATUS_FAILED otherwise
+**
+**
+*******************************************************************************/
+tHAL_NFC_STATUS HAL_NfcPrmSetSpdNciCmdPayloadSize (UINT8 max_payload_size);
+
+/*******************************************************************************
+**
+** Function HAL_NfcSetMaxRfDataCredits
+**
+** Description This function sets the maximum RF data credit for HAL.
+** If 0, use the value reported from NFCC.
+**
+** Returns none
+**
+*******************************************************************************/
+void HAL_NfcSetMaxRfDataCredits (UINT8 max_credits);
+
+/*******************************************************************************
+**
+** Function HAL_NfcSetTraceLevel
+**
+** Description This function sets the trace level for HAL. If called with
+** a value of 0xFF, it simply returns the current trace level.
+**
+** Returns The new or current trace level
+**
+*******************************************************************************/
+UINT8 HAL_NfcSetTraceLevel (UINT8 new_level);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_HAL_INT_API_H */
diff --git a/src/hal/int/nfc_hal_nv_ci.h b/src/hal/int/nfc_hal_nv_ci.h
new file mode 100644
index 0000000..d6877f0
--- /dev/null
+++ b/src/hal/int/nfc_hal_nv_ci.h
@@ -0,0 +1,92 @@
+/******************************************************************************
+ *
+ * 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
+
+#if (defined(NFC_HAL_HCI_INCLUDED) && (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 num_bytes_read,
+ tNFC_HAL_NV_CO_STATUS status,
+ UINT8 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..7ddf46f
--- /dev/null
+++ b/src/hal/int/nfc_hal_nv_co.h
@@ -0,0 +1,112 @@
+/******************************************************************************
+ *
+ * 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
+
+#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
+#define NFC_HAL_NV_CO_ENOSPACE 0x06 /* Returned in nfa_nv_ci_open if no room */
+#define NFC_HAL_NV_CO_EIS_DIR 0x07
+#define NFC_HAL_NV_CO_RESUME 0x08 /* used in nfa_nv_ci_open, on resume */
+#define NFC_HAL_NV_CO_NONE 0x09 /* used in nfa_nv_ci_open, on resume (no file to resume) */
+
+typedef UINT8 tNFC_HAL_NV_CO_STATUS;
+
+#define DH_NV_BLOCK 0x01
+#define HC_F3_NV_BLOCK 0x02
+#define HC_F4_NV_BLOCK 0x03
+#define HC_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 *p_buf, UINT16 nbytes, UINT8 block);
+
+/*******************************************************************************
+**
+** Function nfc_hal_nv_co_write
+**
+** Description This function is called by io to send file data to the
+** phone.
+**
+** Parameters p_buf - buffer to read the data from.
+** nbytes - number of bytes to write out to the file.
+**
+** Returns void
+**
+** Note: Upon completion of the request, nfa_nv_ci_write () is
+** called with the file descriptor and the status. The
+** call-in function should only be called when ALL requested
+** bytes have been written, or an error has been detected,
+**
+*******************************************************************************/
+void nfc_hal_nv_co_write (const UINT8 *p_buf, UINT16 nbytes, UINT8 block);
+
+#endif /* NFC_HAL_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..e224f9a
--- /dev/null
+++ b/src/hal/int/nfc_hal_post_reset.h
@@ -0,0 +1,74 @@
+/******************************************************************************
+ *
+ * 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 prm_file[NFA_APP_PATCHFILE_MAX_PATH+1]; /* Filename of patchram */
+ UINT8 *p_prm_buf; /* Pointer to buffer for holding patchram data */
+
+ /* Patchfile for I2C fix */
+ UINT8 prm_i2c_patchfile[NFA_APP_PATCHFILE_MAX_PATH+1];
+ UINT8 *p_prm_i2c_buf;
+
+ UINT8 userial_baud;
+
+ tNFC_HAL_DEV_INIT_CFG dev_init_config;
+
+ /* snooze mode setting */
+ UINT8 snooze_mode;
+ UINT8 idle_threshold_dh;
+ UINT8 idle_threshold_nfcc;
+ UINT8 nfc_wake_active_mode;
+ UINT8 dh_wake_active_mode;
+
+ /* NVM detection retry (some platforms require re-attempts to detect NVM) */
+ UINT8 spd_nvm_detection_max_count; /* max retry to get NVM type */
+ UINT8 spd_nvm_detection_cur_count; /* current retry count */
+
+ /* handling for failure to download patch */
+ BOOLEAN spd_debug_mode; /* debug mode for downloading patchram, report failure immediately and obviously */
+ BOOLEAN 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 brcm_hw_id, UINT8 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..e952ee6
--- /dev/null
+++ b/src/include/CrcChecksum.h
@@ -0,0 +1,53 @@
+/******************************************************************************
+ *
+ * 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
+
+
+#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.
+**
+*******************************************************************************/
+BOOLEAN 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..556a353
--- /dev/null
+++ b/src/include/NfcAdaptation.h
@@ -0,0 +1,132 @@
+/******************************************************************************
+ *
+ * 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>
+#ifndef UINT32
+typedef unsigned long UINT32;
+#endif
+#include "nfc_target.h"
+#include "nfc_hal_api.h"
+#include <hardware/nfc.h>
+
+
+class ThreadMutex
+{
+public:
+ ThreadMutex();
+ virtual ~ThreadMutex();
+ void lock();
+ void unlock();
+ operator pthread_mutex_t* () {return &mMutex;}
+private:
+ pthread_mutex_t mMutex;
+};
+
+class ThreadCondVar : public ThreadMutex
+{
+public:
+ ThreadCondVar();
+ virtual ~ThreadCondVar();
+ void signal();
+ void wait();
+ operator pthread_cond_t* () {return &mCondVar;}
+ operator pthread_mutex_t* () {return ThreadMutex::operator pthread_mutex_t*();}
+private:
+ pthread_cond_t mCondVar;
+};
+
+class AutoThreadMutex
+{
+public:
+ AutoThreadMutex(ThreadMutex &m);
+ virtual ~AutoThreadMutex();
+ operator ThreadMutex& () {return mm;}
+ operator pthread_mutex_t* () {return (pthread_mutex_t*)mm;}
+private:
+ ThreadMutex &mm;
+};
+
+class NfcAdaptation
+{
+public:
+ virtual ~NfcAdaptation();
+ void Initialize();
+ void Finalize();
+ static NfcAdaptation& GetInstance();
+ tHAL_NFC_ENTRY* GetHalEntryFuncs ();
+ void DownloadFirmware ();
+
+private:
+ NfcAdaptation();
+ void signal();
+ static NfcAdaptation* mpInstance;
+ static ThreadMutex sLock;
+ ThreadCondVar mCondVar;
+ tHAL_NFC_ENTRY mHalEntryFuncs; // function pointers for HAL entry points
+ static nfc_nci_device_t* mHalDeviceContext;
+ static tHAL_NFC_CBACK* mHalCallback;
+ static tHAL_NFC_DATA_CBACK* mHalDataCallback;
+ static ThreadCondVar mHalOpenCompletedEvent;
+ static ThreadCondVar mHalCloseCompletedEvent;
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ pthread_t mThreadId;
+ static ThreadCondVar mHalCoreResetCompletedEvent;
+ static ThreadCondVar mHalCoreInitCompletedEvent;
+ static ThreadCondVar mHalInitCompletedEvent;
+#endif
+ static UINT32 NFCA_TASK (UINT32 arg);
+ static UINT32 Thread (UINT32 arg);
+ void InitializeHalDeviceContext ();
+ static void HalDeviceContextCallback (nfc_event_t event, nfc_status_t event_status);
+ static void HalDeviceContextDataCallback (uint16_t data_len, uint8_t* p_data);
+
+ static void HalInitialize ();
+ static void HalTerminate ();
+ static void HalOpen (tHAL_NFC_CBACK* p_hal_cback, tHAL_NFC_DATA_CBACK* p_data_cback);
+ static void HalClose ();
+ static void HalCoreInitialized (UINT8* p_core_init_rsp_params);
+ static void HalWrite (UINT16 data_len, UINT8* p_data);
+#if((ESE_NFC_POWER_MANAGEMENT == TRUE)&&(NFC_NXP_NOT_OPEN_INCLUDED == TRUE))
+ static int HalIoctl (long arg, void* p_data);
+#endif
+ static BOOLEAN HalPrediscover ();
+ static void HalControlGranted ();
+ static void HalPowerCycle ();
+ static UINT8 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..91edb43
--- /dev/null
+++ b/src/include/OverrideLog.h
@@ -0,0 +1,101 @@
+/******************************************************************************
+ *
+ * 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 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;
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 ();
+
+
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+/*******************************************************************************
+**
+** Function: initializeGlobalDtaMode
+**
+** Description: Initialize and get global DTA mode from .conf
+**
+** Returns: none:
+**
+*******************************************************************************/
+void initializeGlobalAppDtaMode ();
+#endif
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/include/android_logmsg.h b/src/include/android_logmsg.h
new file mode 100644
index 0000000..c18b4ad
--- /dev/null
+++ b/src/include/android_logmsg.h
@@ -0,0 +1,83 @@
+/******************************************************************************
+ *
+ * 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"
+
+
+#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/src/include/bt_target.h b/src/include/bt_target.h
new file mode 100644
index 0000000..769bcee
--- /dev/null
+++ b/src/include/bt_target.h
@@ -0,0 +1,3981 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef BT_TARGET_H
+#define BT_TARGET_H
+
+#include "data_types.h"
+
+#ifdef BUILDCFG
+#include "buildcfg.h"
+#endif
+
+/* Include common GKI definitions used by this platform */
+#include "gki_target.h"
+
+#include "bt_types.h" /* This must be defined AFTER buildcfg.h */
+#include "dyn_mem.h" /* defines static and/or dynamic memory for components */
+
+/* #define BYPASS_AVDATATRACE */
+
+/******************************************************************************
+**
+** Platform-Specific
+**
+******************************************************************************/
+
+#ifndef BT_BRCM_VS_INCLUDED
+#define BT_BRCM_VS_INCLUDED TRUE
+#endif
+
+/* set to FALSE unless using Zeevo */
+#ifndef ZEEVO_CTRL_DEFINED
+#define ZEEVO_CTRL_DEFINED FALSE
+#endif
+
+/* Supporting GPS shared transport */
+#ifndef GPS_INCLUDED
+#define GPS_INCLUDED TRUE
+#endif
+
+/* API macros for simulator */
+
+#define BTAPI
+
+#ifndef BTE_BSE_WRAPPER
+#ifdef BTE_SIM_APP
+#undef BTAPI
+#define BTAPI __declspec(dllexport)
+#endif
+#endif
+
+#define BT_API BTAPI
+#define BTU_API BTAPI
+#define A2D_API BTAPI
+#define VDP_API BTAPI
+#define AVDT_API BTAPI
+#define AVCT_API BTAPI
+#define AVRC_API BTAPI
+#define BIP_API BTAPI
+#define BNEP_API BTAPI
+#define BPP_API BTAPI
+#define BTM_API BTAPI
+#define CTP_API BTAPI
+#define DUN_API BTAPI
+#define FTP_API BTAPI
+#define GAP_API BTAPI
+#define GOEP_API BTAPI
+#define HCI_API BTAPI
+#define HCRP_API BTAPI
+#define HID_API BTAPI
+#define HFP_API BTAPI
+#define HSP2_API BTAPI
+#define ICP_API BTAPI
+#define L2C_API BTAPI
+#define OBX_API BTAPI
+#define OPP_API BTAPI
+#define PAN_API BTAPI
+#define RFC_API BTAPI
+#define RPC_API BTAPI
+#define SDP_API BTAPI
+#define SPP_API BTAPI
+#define TCS_API BTAPI
+#define XML_API BTAPI
+#define BTA_API BTAPI
+#define SBC_API BTAPI
+#define LPM_API BTAPI
+#define AMP_API BTAPI
+#define MCE_API BTAPI
+#define MCA_API BTAPI
+#define GATT_API BTAPI
+#define SMP_API BTAPI
+
+
+/******************************************************************************
+**
+** GKI Buffer Pools
+**
+******************************************************************************/
+
+/* Receives HCI events from the lower-layer. */
+#ifndef HCI_CMD_POOL_ID
+#define HCI_CMD_POOL_ID GKI_POOL_ID_2
+#endif
+
+#ifndef HCI_CMD_POOL_BUF_SIZE
+#define HCI_CMD_POOL_BUF_SIZE GKI_BUF2_SIZE
+#endif
+
+/* Receives ACL data packets from thelower-layer. */
+#ifndef HCI_ACL_POOL_ID
+#define HCI_ACL_POOL_ID GKI_POOL_ID_3
+#endif
+
+#ifndef HCI_ACL_POOL_BUF_SIZE
+#define HCI_ACL_POOL_BUF_SIZE GKI_BUF3_SIZE
+#endif
+
+/* Maximum number of buffers available for ACL receive data. */
+#ifndef HCI_ACL_BUF_MAX
+#define HCI_ACL_BUF_MAX GKI_BUF3_MAX
+#endif
+
+/* Receives SCO data packets from the lower-layer. */
+#ifndef HCI_SCO_POOL_ID
+#define HCI_SCO_POOL_ID GKI_POOL_ID_6
+#endif
+
+/* Not used. */
+#ifndef HCI_DATA_DESCR_POOL_ID
+#define HCI_DATA_DESCR_POOL_ID GKI_POOL_ID_0
+#endif
+
+/* Sends SDP data packets. */
+#ifndef SDP_POOL_ID
+#define SDP_POOL_ID GKI_POOL_ID_2
+#endif
+
+/* Sends RFCOMM command packets. */
+#ifndef RFCOMM_CMD_POOL_ID
+#define RFCOMM_CMD_POOL_ID GKI_POOL_ID_2
+#endif
+
+#ifndef RFCOMM_CMD_POOL_BUF_SIZE
+#define RFCOMM_CMD_POOL_BUF_SIZE GKI_BUF2_SIZE
+#endif
+
+/* Sends RFCOMM data packets. */
+#ifndef RFCOMM_DATA_POOL_ID
+#define RFCOMM_DATA_POOL_ID GKI_POOL_ID_3
+#endif
+
+#ifndef RFCOMM_DATA_POOL_BUF_SIZE
+#define RFCOMM_DATA_POOL_BUF_SIZE GKI_BUF3_SIZE
+#endif
+
+/* Sends L2CAP packets to the peer and HCI messages to the controller. */
+#ifndef L2CAP_CMD_POOL_ID
+#define L2CAP_CMD_POOL_ID GKI_POOL_ID_2
+#endif
+
+/* Sends L2CAP segmented packets in ERTM mode */
+#ifndef L2CAP_FCR_TX_POOL_ID
+#define L2CAP_FCR_TX_POOL_ID HCI_ACL_POOL_ID
+#endif
+
+/* Receives L2CAP segmented packets in ERTM mode */
+#ifndef L2CAP_FCR_RX_POOL_ID
+#define L2CAP_FCR_RX_POOL_ID HCI_ACL_POOL_ID
+#endif
+
+/* Used by BTM when it sends HCI commands to the controller. */
+#ifndef BTM_CMD_POOL_ID
+#define BTM_CMD_POOL_ID GKI_POOL_ID_2
+#endif
+
+/* Sends TCS messages. */
+#ifndef TCS_MSG_POOL_ID
+#define TCS_MSG_POOL_ID GKI_POOL_ID_2
+#endif
+
+#ifndef OBX_CMD_POOL_SIZE
+#define OBX_CMD_POOL_SIZE GKI_BUF2_SIZE
+#endif
+
+#ifndef OBX_LRG_DATA_POOL_SIZE
+#define OBX_LRG_DATA_POOL_SIZE GKI_BUF4_SIZE
+#endif
+
+#ifndef OBX_LRG_DATA_POOL_ID
+#define OBX_LRG_DATA_POOL_ID GKI_POOL_ID_4
+#endif
+
+/* Used for CTP discovery database. */
+#ifndef CTP_SDP_DB_POOL_ID
+#define CTP_SDP_DB_POOL_ID GKI_POOL_ID_3
+#endif
+
+/* Used for CTP data exchange feature. */
+#ifndef CTP_DATA_EXCHG_POOL_ID
+#define CTP_DATA_EXCHG_POOL_ID GKI_POOL_ID_2
+#endif
+
+/* Used to send data to L2CAP. */
+#ifndef GAP_DATA_POOL_ID
+#define GAP_DATA_POOL_ID GKI_POOL_ID_3
+#endif
+
+/* Used for SPP inquiry and discovery databases. */
+#ifndef SPP_DB_POOL_ID
+#define SPP_DB_POOL_ID GKI_POOL_ID_3
+#endif
+
+#ifndef SPP_DB_SIZE
+#define SPP_DB_SIZE GKI_BUF3_SIZE
+#endif
+
+/* HCRP protocol and internal commands. */
+#ifndef HCRP_CMD_POOL_ID
+#define HCRP_CMD_POOL_ID GKI_POOL_ID_2
+#endif
+
+#ifndef HCRP_CMD_POOL_SIZE
+#define HCRP_CMD_POOL_SIZE GKI_BUF2_SIZE
+#endif
+
+#ifndef BIP_EVT_POOL_SIZE
+#define BIP_EVT_POOL_SIZE GKI_BUF3_SIZE
+#endif
+
+#ifndef BIP_DB_SIZE
+#define BIP_DB_SIZE GKI_BUF3_SIZE
+#endif
+
+
+/* BNEP data and protocol messages. */
+#ifndef BNEP_POOL_ID
+#define BNEP_POOL_ID GKI_POOL_ID_3
+#endif
+
+/* RPC pool for temporary trace message buffers. */
+#ifndef RPC_SCRATCH_POOL_ID
+#define RPC_SCRATCH_POOL_ID GKI_POOL_ID_2
+#endif
+
+/* RPC scratch buffer size (not related to RPC_SCRATCH_POOL_ID) */
+#ifndef RPC_SCRATCH_BUF_SIZE
+#define RPC_SCRATCH_BUF_SIZE GKI_BUF3_SIZE
+#endif
+
+/* RPC pool for protocol messages */
+#ifndef RPC_MSG_POOL_ID
+#define RPC_MSG_POOL_ID GKI_POOL_ID_3
+#endif
+
+#ifndef RPC_MSG_POOL_SIZE
+#define RPC_MSG_POOL_SIZE GKI_BUF3_SIZE
+#endif
+
+/* AVDTP pool for protocol messages */
+#ifndef AVDT_CMD_POOL_ID
+#define AVDT_CMD_POOL_ID GKI_POOL_ID_2
+#endif
+
+/* AVDTP pool size for media packets in case of fragmentation */
+#ifndef AVDT_DATA_POOL_SIZE
+#define AVDT_DATA_POOL_SIZE GKI_BUF3_SIZE
+#endif
+
+#ifndef PAN_POOL_ID
+#define PAN_POOL_ID GKI_POOL_ID_3
+#endif
+
+/* UNV pool for read/write serialization */
+#ifndef UNV_MSG_POOL_ID
+#define UNV_MSG_POOL_ID GKI_POOL_ID_2
+#endif
+
+#ifndef UNV_MSG_POOL_SIZE
+#define UNV_MSG_POOL_SIZE GKI_BUF2_SIZE
+#endif
+
+/* AVCTP pool for protocol messages */
+#ifndef AVCT_CMD_POOL_ID
+#define AVCT_CMD_POOL_ID GKI_POOL_ID_1
+#endif
+
+#ifndef AVCT_META_CMD_POOL_ID
+#define AVCT_META_CMD_POOL_ID GKI_POOL_ID_2
+#endif
+
+/* AVRCP pool for protocol messages */
+#ifndef AVRC_CMD_POOL_ID
+#define AVRC_CMD_POOL_ID GKI_POOL_ID_1
+#endif
+
+/* AVRCP pool size for protocol messages */
+#ifndef AVRC_CMD_POOL_SIZE
+#define AVRC_CMD_POOL_SIZE GKI_BUF1_SIZE
+#endif
+
+/* AVRCP Metadata pool for protocol messages */
+#ifndef AVRC_META_CMD_POOL_ID
+#define AVRC_META_CMD_POOL_ID GKI_POOL_ID_2
+#endif
+
+/* AVRCP Metadata pool size for protocol messages */
+#ifndef AVRC_META_CMD_POOL_SIZE
+#define AVRC_META_CMD_POOL_SIZE GKI_BUF2_SIZE
+#endif
+
+
+/* AVRCP buffer size for browsing channel messages */
+#ifndef AVRC_BROWSE_POOL_SIZE
+#define AVRC_BROWSE_POOL_SIZE GKI_MAX_BUF_SIZE
+#endif
+
+/* HDP buffer size for the Pulse Oximeter */
+#ifndef BTA_HL_LRG_DATA_POOL_SIZE
+#define BTA_HL_LRG_DATA_POOL_SIZE GKI_BUF7_SIZE
+#endif
+
+#ifndef BTA_HL_LRG_DATA_POOL_ID
+#define BTA_HL_LRG_DATA_POOL_ID GKI_POOL_ID_7
+#endif
+
+/* GATT Server Database pool ID */
+#ifndef GATT_DB_POOL_ID
+#define GATT_DB_POOL_ID GKI_POOL_ID_8
+#endif
+
+
+/******************************************************************************
+**
+** Lower Layer Interface
+**
+******************************************************************************/
+
+/* Sends ACL data received over HCI to the upper stack. */
+#ifndef HCI_ACL_DATA_TO_UPPER
+#define HCI_ACL_DATA_TO_UPPER(p) {((BT_HDR *)p)->event = BT_EVT_TO_BTU_HCI_ACL; GKI_send_msg (BTU_TASK, BTU_HCI_RCV_MBOX, p);}
+#endif
+
+/* Sends SCO data received over HCI to the upper stack. */
+#ifndef HCI_SCO_DATA_TO_UPPER
+#define HCI_SCO_DATA_TO_UPPER(p) {((BT_HDR *)p)->event = BT_EVT_TO_BTU_HCI_SCO; GKI_send_msg (BTU_TASK, BTU_HCI_RCV_MBOX, p);}
+#endif
+
+/* Sends an HCI event received over HCI to theupper stack. */
+#ifndef HCI_EVT_TO_UPPER
+#define HCI_EVT_TO_UPPER(p) {((BT_HDR *)p)->event = BT_EVT_TO_BTU_HCI_EVT; GKI_send_msg (BTU_TASK, BTU_HCI_RCV_MBOX, p);}
+#endif
+
+/* HCI 4 wire power management protocol. */
+#ifndef HCILL_INCLUDED
+#define HCILL_INCLUDED FALSE
+#endif
+
+/* Macro for allocating buffer for HCI commands */
+#ifndef HCI_GET_CMD_BUF
+#if (!defined(HCI_USE_VARIABLE_SIZE_CMD_BUF) || (HCI_USE_VARIABLE_SIZE_CMD_BUF == FALSE))
+/* Allocate fixed-size buffer from HCI_CMD_POOL (default case) */
+#define HCI_GET_CMD_BUF(paramlen) ((BT_HDR *)GKI_getpoolbuf (HCI_CMD_POOL_ID))
+#else
+/* Allocate smallest possible buffer (for platforms with limited RAM) */
+#define HCI_GET_CMD_BUF(paramlen) ((BT_HDR *)GKI_getbuf ((UINT16)(BT_HDR_SIZE + HCIC_PREAMBLE_SIZE + (paramlen))))
+#endif
+#endif /* HCI_GET_CMD_BUF */
+
+/******************************************************************************
+**
+** HCI Services (H4)
+**
+******************************************************************************/
+#ifndef HCISU_H4_INCLUDED
+#define HCISU_H4_INCLUDED FALSE
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+BT_API extern void bte_ncisu_send (BT_HDR *p_pkt, UINT16 event);
+BT_API extern void bte_hcisu_send (BT_HDR *p_msg, UINT16 event);
+#if (HCISU_H4_INCLUDED == TRUE)
+BT_API extern void bte_hcisu_lp_allow_bt_device_sleep (void);
+BT_API extern void bte_hcisu_lp_wakeup_host (void);
+BT_API extern void bte_hcisu_lp_h4ibss_evt(UINT8 *p, UINT8 evt_len);
+#endif
+
+/* HCILL API for the applications */
+typedef void (tHCILL_SLEEP_ACK)(void);
+BT_API extern void HCILL_GoToSleep( tHCILL_SLEEP_ACK *sl_ack_fn);
+typedef void (tHCILL_STATE_CBACK)(BOOLEAN is_sleep);
+BT_API extern void HCILL_RegState( tHCILL_STATE_CBACK *p_cback);
+#ifdef __cplusplus
+}
+#endif
+
+/* Sends ACL data received from the upper stack to the BD/EDR HCI transport. */
+#ifndef HCI_ACL_DATA_TO_LOWER
+#define HCI_ACL_DATA_TO_LOWER(p) bte_hcisu_send((BT_HDR *)(p), BT_EVT_TO_LM_HCI_ACL);
+#endif
+
+#ifndef HCI_BLE_ACL_DATA_TO_LOWER
+#define HCI_BLE_ACL_DATA_TO_LOWER(p) bte_hcisu_send((BT_HDR *)(p), (UINT16)(BT_EVT_TO_LM_HCI_ACL|LOCAL_BLE_CONTROLLER_ID));
+#endif
+
+/* Sends ACL data received from the upper stack to the AMP HCI transport. */
+#ifndef HCI_AMP_DATA_TO_LOWER
+#define HCI_AMP_DATA_TO_LOWER(p,x) bte_hcisu_send((BT_HDR *)(p), (UINT16)(BT_EVT_TO_LM_HCI_ACL|((UINT16)(x))));
+#endif
+
+/* Sends SCO data received from the upper stack to the HCI transport. */
+#ifndef HCI_SCO_DATA_TO_LOWER
+#define HCI_SCO_DATA_TO_LOWER(p) bte_hcisu_send((BT_HDR *)(p), BT_EVT_TO_LM_HCI_SCO);
+#endif
+
+/* Sends an HCI command received from the upper stack to the BD/EDR HCI transport. */
+#ifndef HCI_CMD_TO_LOWER
+#define HCI_CMD_TO_LOWER(p) bte_hcisu_send((BT_HDR *)(p), BT_EVT_TO_LM_HCI_CMD);
+#endif
+
+/* Sends an HCI command received from the upper stack to the AMP HCI transport. */
+#ifndef HCI_CMD_TO_AMP
+#define HCI_CMD_TO_AMP(x,p) bte_hcisu_send((BT_HDR *)(p), (UINT16)(BT_EVT_TO_LM_HCI_CMD|((UINT16)(x))));
+#endif
+
+/* Sends an LM Diagnosic command received from the upper stack to the HCI transport. */
+#ifndef HCI_LM_DIAG_TO_LOWER
+#define HCI_LM_DIAG_TO_LOWER(p) bte_hcisu_send((BT_HDR *)(p), BT_EVT_TO_LM_DIAG);
+#endif
+
+/* Send HCISU a message to allow BT sleep */
+#ifndef HCI_LP_ALLOW_BT_DEVICE_SLEEP
+#if (HCISU_H4_INCLUDED == TRUE)
+#define HCI_LP_ALLOW_BT_DEVICE_SLEEP() bte_hcisu_lp_allow_bt_device_sleep()
+#else
+#define HCI_LP_ALLOW_BT_DEVICE_SLEEP() HCILP_AllowBTDeviceSleep()
+#endif
+#endif
+
+/* Send HCISU a message to wakeup host */
+#ifndef HCI_LP_WAKEUP_HOST
+#if (HCISU_H4_INCLUDED == TRUE)
+#define HCI_LP_WAKEUP_HOST() bte_hcisu_lp_wakeup_host()
+#else
+#define HCI_LP_WAKEUP_HOST() HCILP_WakeupHost()
+#endif
+#endif
+
+/* Send HCISU the received H4IBSS event from controller */
+#ifndef HCI_LP_RCV_H4IBSS_EVT
+#if (HCISU_H4_INCLUDED == TRUE)
+#define HCI_LP_RCV_H4IBSS_EVT(p1, p2) bte_hcisu_lp_h4ibss_evt((UINT8*)(p1), (UINT8)(p2))
+#else
+#define HCI_LP_RCV_H4IBSS_EVT(p1, p2) h4ibss_sleep_mode_evt((UINT8*)(p1), (UINT8)(p2))
+#endif
+#endif
+
+/* If nonzero, the upper-layer sends at most this number of HCI commands to the lower-layer. */
+#ifndef HCI_MAX_SIMUL_CMDS
+#define HCI_MAX_SIMUL_CMDS 0
+#endif
+
+/* Timeout for receiving response to HCI command */
+#ifndef BTU_CMD_CMPL_TIMEOUT
+#define BTU_CMD_CMPL_TIMEOUT 8
+#endif
+
+/* If TRUE, BTU task will check HCISU again when HCI command timer expires */
+#ifndef BTU_CMD_CMPL_TOUT_DOUBLE_CHECK
+#define BTU_CMD_CMPL_TOUT_DOUBLE_CHECK FALSE
+#endif
+
+/* If TRUE, stack is compiled to include MM dual stack functionality */
+#ifndef BTU_DUAL_STACK_MM_INCLUDED
+#define BTU_DUAL_STACK_MM_INCLUDED FALSE
+#endif
+
+/* If TRUE, stack is compiled to support Embedded Lite Stack in BT chip */
+#ifndef BTU_DUAL_STACK_BTC_INCLUDED
+#define BTU_DUAL_STACK_BTC_INCLUDED FALSE
+#endif
+
+/* If TRUE, stack is compiled to support Embedded Lite Stack for AV SNK in BT chip */
+#ifndef BTU_BTC_SNK_INCLUDED
+#define BTU_BTC_SNK_INCLUDED FALSE
+#endif
+
+/* If TRUE, stack is compiled as Lite Stack in Multimedia chip */
+/* If FALSE, stack is compiled as Full Stack in Baseband chip */
+#ifndef BTU_STACK_LITE_ENABLED
+#define BTU_STACK_LITE_ENABLED FALSE
+#endif
+
+/* Transport pause time (BT slot(0.625ms) unit) when switching between BB and MM */
+/* FW is using a tick which is 20 slot unit so if timeout is between 0 to 20 slot */
+/* then actual timeout would be 0 to 12.5ms because it could be beteen ticks. */
+/* if timeout is between 20 to 40 slot then actual timeout would be 12.5 to 25ms */
+#ifndef BTU_DUAL_TRANSPORT_PAUSE_TIME
+#define BTU_DUAL_TRANSPORT_PAUSE_TIME 40
+#endif
+
+/* if UART baudrate is different between BB and MM, it will be updated during switching */
+#ifndef BTU_DUAL_TRANSPORT_BB_BAUDRATE
+#define BTU_DUAL_TRANSPORT_BB_BAUDRATE 115200
+#endif
+
+#ifndef BTU_DUAL_TRANSPORT_MM_BAUDRATE
+#define BTU_DUAL_TRANSPORT_MM_BAUDRATE 921600
+#endif
+
+/* If TRUE, stack is compiled to include the multi-av feature (A2DP packets are duplicated inside controller) */
+#ifndef BTU_MULTI_AV_INCLUDED
+#define BTU_MULTI_AV_INCLUDED FALSE
+#endif
+
+/* Use 2 second for low-resolution systems, override to 1 for high-resolution systems */
+#ifndef BT_1SEC_TIMEOUT
+#define BT_1SEC_TIMEOUT (2)
+#endif
+
+/* Quick Timer */
+/* minimum should have 100 millisecond resolution for eL2CAP */
+/* if HCILP_INCLUDED is TRUE then it should have 100 millisecond resolution */
+/* if SLIP_INCLUDED is TRUE then it should have 10 millisecond resolution */
+/* if BRCM_USE_DELAY is FALSE then it should have 10 millisecond resolution */
+/* if none of them is included then QUICK_TIMER_TICKS_PER_SEC is set to 0 to exclude quick timer */
+#ifndef QUICK_TIMER_TICKS_PER_SEC
+#define QUICK_TIMER_TICKS_PER_SEC 100 /* 10ms timer */
+#endif
+
+/******************************************************************************
+**
+** BTM
+**
+******************************************************************************/
+/* if set to TRUE, stack will automatically send an HCI reset at start-up. To be
+set to FALSE for advanced start-up / shut-down procedures using USER_HW_ENABLE_API
+and USER_HW_DISABLE_API macros */
+#ifndef BTM_AUTOMATIC_HCI_RESET
+#define BTM_AUTOMATIC_HCI_RESET TRUE
+#endif
+
+/* Cancel Inquiry on incoming SSP - Work around code for a FW issue (CQ#167446). */
+#ifndef BTM_NO_SSP_ON_INQUIRY
+#define BTM_NO_SSP_ON_INQUIRY FALSE
+#endif
+
+/* Include the implemenation needed by Pre-Lisbon controller (2.0_EDR or older) */
+#ifndef BTM_PRE_LISBON_INCLUDED
+#define BTM_PRE_LISBON_INCLUDED TRUE
+#endif
+
+/* Includes SCO if TRUE */
+#ifndef BTM_SCO_INCLUDED
+#define BTM_SCO_INCLUDED TRUE /* TRUE includes SCO code */
+#endif
+
+/* Includes SCO if TRUE */
+#ifndef BTM_SCO_HCI_INCLUDED
+#define BTM_SCO_HCI_INCLUDED FALSE /* TRUE includes SCO over HCI code */
+#endif
+
+/* Includes WBS if TRUE */
+#ifndef BTM_WBS_INCLUDED
+#define BTM_WBS_INCLUDED FALSE /* TRUE includes WBS code */
+#endif
+
+/* Includes PCM2 support if TRUE */
+#ifndef BTM_PCM2_INCLUDED
+#define BTM_PCM2_INCLUDED FALSE
+#endif
+
+/* If FALSE, AFH channel automatically adjusted based on AMP channel in use */
+/* Set TRUE, if want to bypass AFH channel automatic adjustment and use */
+/* BTA_DM_API_SET_AFH_CHANNELS_ API */
+
+#ifndef BTM_BYPASS_AMP_AUTO_AFH
+#define BTM_BYPASS_AMP_AUTO_AFH FALSE
+#endif
+
+
+/**************************
+** Initial SCO TX credit
+*************************/
+/* max TX SCO data packet size */
+#ifndef BTM_SCO_DATA_SIZE_MAX
+#define BTM_SCO_DATA_SIZE_MAX 240
+#endif
+
+/* maximum BTM buffering capacity */
+#ifndef BTM_SCO_MAX_BUF_CAP
+#define BTM_SCO_MAX_BUF_CAP (BTM_SCO_INIT_XMIT_CREDIT * 4)
+#endif
+
+/* The size in bytes of the BTM inquiry database. */
+#ifndef BTM_INQ_DB_SIZE
+#define BTM_INQ_DB_SIZE 12
+#endif
+
+/* This is set to always try to acquire the remote device name. */
+#ifndef BTM_INQ_GET_REMOTE_NAME
+#define BTM_INQ_GET_REMOTE_NAME FALSE
+#endif
+
+/* The inquiry duration in 1.28 second units when auto inquiry is enabled. */
+#ifndef BTM_DEFAULT_INQ_DUR
+#define BTM_DEFAULT_INQ_DUR 5
+#endif
+
+/* The inquiry mode when auto inquiry is enabled. */
+#ifndef BTM_DEFAULT_INQ_MODE
+#define BTM_DEFAULT_INQ_MODE BTM_GENERAL_INQUIRY
+#endif
+
+/* The default periodic inquiry maximum delay when auto inquiry is enabled, in 1.28 second units. */
+#ifndef BTM_DEFAULT_INQ_MAX_DELAY
+#define BTM_DEFAULT_INQ_MAX_DELAY 30
+#endif
+
+/* The default periodic inquiry minimum delay when auto inquiry is enabled, in 1.28 second units. */
+#ifndef BTM_DEFAULT_INQ_MIN_DELAY
+#define BTM_DEFAULT_INQ_MIN_DELAY 20
+#endif
+
+/* TRUE if controller does not support inquiry event filtering. */
+#ifndef BTM_BYPASS_EVENT_FILTERING
+#define BTM_BYPASS_EVENT_FILTERING FALSE
+#endif
+
+/* TRUE if inquiry filtering is desired from BTM. */
+#ifndef BTM_USE_INQ_RESULTS_FILTER
+#define BTM_USE_INQ_RESULTS_FILTER TRUE
+#endif
+
+/* The default scan mode */
+#ifndef BTM_DEFAULT_SCAN_TYPE
+#define BTM_DEFAULT_SCAN_TYPE BTM_SCAN_TYPE_INTERLACED
+#endif
+
+/* Should connections to unknown devices be allowed when not discoverable? */
+#ifndef BTM_ALLOW_CONN_IF_NONDISCOVER
+#define BTM_ALLOW_CONN_IF_NONDISCOVER FALSE
+#endif
+
+/* When connectable mode is set to TRUE, the device will respond to paging. */
+#ifndef BTM_IS_CONNECTABLE
+#define BTM_IS_CONNECTABLE FALSE
+#endif
+
+/* Sets the Page_Scan_Window: the length of time that the device is performing a page scan. */
+#ifndef BTM_DEFAULT_CONN_WINDOW
+#define BTM_DEFAULT_CONN_WINDOW 0x0012
+#endif
+
+/* Sets the Page_Scan_Activity: the interval between the start of two consecutive page scans. */
+#ifndef BTM_DEFAULT_CONN_INTERVAL
+#define BTM_DEFAULT_CONN_INTERVAL 0x0800
+#endif
+
+/* This is set to automatically perform inquiry scan on startup. */
+#ifndef BTM_IS_DISCOVERABLE
+#define BTM_IS_DISCOVERABLE FALSE
+#endif
+
+/* When automatic inquiry scan is enabled, this sets the discovery mode. */
+#ifndef BTM_DEFAULT_DISC_MODE
+#define BTM_DEFAULT_DISC_MODE BTM_GENERAL_DISCOVERABLE
+#endif
+
+/* When automatic inquiry scan is enabled, this sets the inquiry scan window. */
+#ifndef BTM_DEFAULT_DISC_WINDOW
+#define BTM_DEFAULT_DISC_WINDOW 0x0012
+#endif
+
+/* When automatic inquiry scan is enabled, this sets the inquiry scan interval. */
+#ifndef BTM_DEFAULT_DISC_INTERVAL
+#define BTM_DEFAULT_DISC_INTERVAL 0x0800
+#endif
+
+/* Number of milliseconds to delay BTU task startup upon device initialization. */
+#ifndef BTU_STARTUP_DELAY
+#define BTU_STARTUP_DELAY 0
+#endif
+
+/* Whether BTA is included in BTU task. */
+#ifndef BTU_BTA_INCLUDED
+#define BTU_BTA_INCLUDED FALSE
+#endif
+
+/* Number of seconds to wait to send an HCI Reset command upon device initialization. */
+#ifndef BTM_FIRST_RESET_DELAY
+#define BTM_FIRST_RESET_DELAY 0
+#endif
+
+/* The number of seconds to wait for controller module to reset after issuing an HCI Reset command. */
+#ifndef BTM_AFTER_RESET_TIMEOUT
+#define BTM_AFTER_RESET_TIMEOUT 0
+#endif
+
+/* The default class of device. */
+#ifndef BTM_INIT_CLASS_OF_DEVICE
+#define BTM_INIT_CLASS_OF_DEVICE "\x00\x1F\x00"
+#endif
+
+/* The number of SCO links. */
+#ifndef BTM_MAX_SCO_LINKS
+#define BTM_MAX_SCO_LINKS 3
+#endif
+
+/* The preferred type of SCO links (2-eSCO, 0-SCO). */
+#ifndef BTM_DEFAULT_SCO_MODE
+#define BTM_DEFAULT_SCO_MODE 2
+#endif
+
+/* The number of security records for peer devices. */
+#ifndef BTM_SEC_MAX_DEVICE_RECORDS
+#define BTM_SEC_MAX_DEVICE_RECORDS 8
+#endif
+
+/* The number of security records for services. */
+#ifndef BTM_SEC_MAX_SERVICE_RECORDS
+#define BTM_SEC_MAX_SERVICE_RECORDS 24
+#endif
+
+/* If True, force a retrieval of remote device name for each bond in case it's changed */
+#ifndef BTM_SEC_FORCE_RNR_FOR_DBOND
+#define BTM_SEC_FORCE_RNR_FOR_DBOND TRUE
+#endif
+
+/* Maximum device name length used in btm database. */
+#ifndef BTM_MAX_REM_BD_NAME_LEN
+#define BTM_MAX_REM_BD_NAME_LEN 20
+#endif
+
+/* Maximum local device name length stored btm database.
+ '0' disables storage of the local name in BTM */
+#ifndef BTM_MAX_LOC_BD_NAME_LEN
+#define BTM_MAX_LOC_BD_NAME_LEN 31
+#endif
+
+/* TRUE if default string is used, FALSE if device name is set in the application */
+#ifndef BTM_USE_DEF_LOCAL_NAME
+#define BTM_USE_DEF_LOCAL_NAME FALSE
+#endif
+
+/* Fixed Default String (Ignored if BTM_USE_DEF_LOCAL_NAME is FALSE) */
+#ifndef BTM_DEF_LOCAL_NAME
+#define BTM_DEF_LOCAL_NAME ""
+#endif
+
+/* Maximum service name stored with security authorization (0 if not needed) */
+#ifndef BTM_SEC_SERVICE_NAME_LEN
+#define BTM_SEC_SERVICE_NAME_LEN BT_MAX_SERVICE_NAME_LEN
+#endif
+
+/* Maximum number of pending security callback */
+#ifndef BTM_SEC_MAX_CALLBACKS
+#define BTM_SEC_MAX_CALLBACKS 7
+#endif
+
+/* Maximum length of the service name. */
+#ifndef BT_MAX_SERVICE_NAME_LEN
+#define BT_MAX_SERVICE_NAME_LEN 21
+#endif
+
+/* ACL buffer size in HCI Host Buffer Size command. */
+#ifndef BTM_ACL_BUF_SIZE
+#define BTM_ACL_BUF_SIZE 0
+#endif
+
+/* This is set to use the BTM power manager. */
+#ifndef BTM_PWR_MGR_INCLUDED
+#define BTM_PWR_MGR_INCLUDED TRUE
+#endif
+
+/* The maximum number of clients that can register with the power manager. */
+#ifndef BTM_MAX_PM_RECORDS
+#define BTM_MAX_PM_RECORDS 2
+#endif
+
+/* This is set to show debug trace messages for the power manager. */
+#ifndef BTM_PM_DEBUG
+#define BTM_PM_DEBUG FALSE
+#endif
+
+/* This is set to TRUE if link is to be unparked due to BTM_CreateSCO API. */
+#ifndef BTM_SCO_WAKE_PARKED_LINK
+#define BTM_SCO_WAKE_PARKED_LINK TRUE
+#endif
+
+/* May be set to the the name of a function used for vendor specific chip initialization */
+#ifndef BTM_APP_DEV_INIT
+/* #define BTM_APP_DEV_INIT myInitFunction() */
+#endif
+
+/* This is set to TRUE if the busy level change event is desired. (replace ACL change event) */
+#ifndef BTM_BUSY_LEVEL_CHANGE_INCLUDED
+#define BTM_BUSY_LEVEL_CHANGE_INCLUDED TRUE
+#endif
+
+/* If the user does not respond to security process requests within this many seconds,
+ * a negative response would be sent automatically.
+ * It's recommended to use a value between 30 and OBX_TIMEOUT_VALUE
+ * 30 is LMP response timeout value */
+#ifndef BTM_SEC_TIMEOUT_VALUE
+#define BTM_SEC_TIMEOUT_VALUE 35
+#endif
+
+/* Maximum number of callbacks that can be registered using BTM_RegisterForVSEvents */
+#ifndef BTM_MAX_VSE_CALLBACKS
+#define BTM_MAX_VSE_CALLBACKS 6
+#endif
+
+/* Number of streams for dual stack */
+#ifndef BTM_SYNC_INFO_NUM_STR
+#define BTM_SYNC_INFO_NUM_STR 2
+#endif
+
+/* Number of streams for dual stack in BT Controller */
+#ifndef BTM_SYNC_INFO_NUM_STR_BTC
+#define BTM_SYNC_INFO_NUM_STR_BTC 2
+#endif
+
+/******************************************
+** Lisbon Features
+*******************************************/
+/* This is set to TRUE if the server Extended Inquiry Response feature is desired. */
+/* server sends EIR to client */
+#ifndef BTM_EIR_SERVER_INCLUDED
+#define BTM_EIR_SERVER_INCLUDED TRUE
+#endif
+
+/* This is set to TRUE if the client Extended Inquiry Response feature is desired. */
+/* client inquiry to server */
+#ifndef BTM_EIR_CLIENT_INCLUDED
+#define BTM_EIR_CLIENT_INCLUDED TRUE
+#endif
+
+/* This is set to TRUE if the FEC is required for EIR packet. */
+#ifndef BTM_EIR_DEFAULT_FEC_REQUIRED
+#define BTM_EIR_DEFAULT_FEC_REQUIRED TRUE
+#endif
+
+/* User defined UUID look up table */
+#ifndef BTM_EIR_UUID_LKUP_TBL
+#endif
+
+/* The IO capability of the local device (for Simple Pairing) */
+#ifndef BTM_LOCAL_IO_CAPS
+#define BTM_LOCAL_IO_CAPS BTM_IO_CAP_IO
+#endif
+
+/* The default MITM Protection Requirement (for Simple Pairing)
+ * Possible values are BTM_AUTH_SP_YES or BTM_AUTH_SP_NO */
+#ifndef BTM_DEFAULT_AUTH_REQ
+#define BTM_DEFAULT_AUTH_REQ BTM_AUTH_SP_NO
+#endif
+
+/* The default MITM Protection Requirement for dedicated bonding using Simple Pairing
+ * Possible values are BTM_AUTH_AP_YES or BTM_AUTH_AP_NO */
+#ifndef BTM_DEFAULT_DD_AUTH_REQ
+#define BTM_DEFAULT_DD_AUTH_REQ BTM_AUTH_AP_YES
+#endif
+
+/* Include Out-of-Band implementation for Simple Pairing */
+#ifndef BTM_OOB_INCLUDED
+#define BTM_OOB_INCLUDED TRUE
+#endif
+
+/* TRUE to include Sniff Subrating */
+#ifndef BTM_SSR_INCLUDED
+#define BTM_SSR_INCLUDED TRUE
+#endif
+
+/*************************
+** End of Lisbon Features
+**************************/
+
+/* This is set to use the BTM TBFC Supported. */
+#ifndef BTM_TBFC_INCLUDED
+#define BTM_TBFC_INCLUDED FALSE
+#endif
+
+/* TRUE to include bi-directionnal TBFC */
+#ifndef BTM_BI_DIR_TBFC_INCLUDED
+#define BTM_BI_DIR_TBFC_INCLUDED FALSE
+#endif
+
+/* TRUE to include CLB (ConnectionLess Slave Broadcast) */
+#ifndef BTM_CLB_INCLUDED
+#define BTM_CLB_INCLUDED FALSE
+#endif
+
+/* TRUE to include CLB Rx (ConnectionLess Broadcast Reception) */
+#ifndef BTM_CLB_RX_INCLUDED
+#define BTM_CLB_RX_INCLUDED FALSE
+#endif
+
+/* Used for conformance testing ONLY */
+#ifndef BTM_BLE_CONFORMANCE_TESTING
+#define BTM_BLE_CONFORMANCE_TESTING FALSE
+#endif
+
+
+/******************************************************************************
+**
+** L2CAP
+**
+******************************************************************************/
+
+/* The maximum number of simultaneous links that L2CAP can support. */
+#ifndef MAX_L2CAP_LINKS
+#define MAX_L2CAP_LINKS 4
+#endif
+
+/* The maximum number of simultaneous channels that L2CAP can support. */
+#ifndef MAX_L2CAP_CHANNELS
+#define MAX_L2CAP_CHANNELS 10
+#endif
+
+/* The maximum number of simultaneous applications that can register with L2CAP. */
+#ifndef MAX_L2CAP_CLIENTS
+#define MAX_L2CAP_CLIENTS 8
+#endif
+
+/* The number of seconds of link inactivity before a link is disconnected. */
+#ifndef L2CAP_LINK_INACTIVITY_TOUT
+#define L2CAP_LINK_INACTIVITY_TOUT 3
+#endif
+
+/* The number of seconds of link inactivity after bonding before a link is disconnected. */
+#ifndef L2CAP_BONDING_TIMEOUT
+#define L2CAP_BONDING_TIMEOUT 3
+#endif
+
+/* The time from the HCI connection complete to disconnect if no channel is established. */
+#ifndef L2CAP_LINK_STARTUP_TOUT
+#define L2CAP_LINK_STARTUP_TOUT 60
+#endif
+
+/* The L2CAP MTU; must be in accord with the HCI ACL pool size. */
+#ifndef L2CAP_MTU_SIZE
+#define L2CAP_MTU_SIZE 1691
+#endif
+
+/* The L2CAP MPS over Bluetooth; must be in accord with the FCR tx pool size and ACL down buffer size. */
+#ifndef L2CAP_MPS_OVER_BR_EDR
+#define L2CAP_MPS_OVER_BR_EDR 1010
+#endif
+
+/* The L2CAP MPS over AMP; must be in accord with the FCR tx pool size and ACL down buffer size. */
+#ifndef L2CAP_MPS_OVER_AMP
+#define L2CAP_MPS_OVER_AMP 1480
+#endif
+
+/* This is set to enable host flow control. */
+#ifndef L2CAP_HOST_FLOW_CTRL
+#define L2CAP_HOST_FLOW_CTRL FALSE
+#endif
+
+/* If host flow control enabled, this is the number of buffers the controller can have unacknowledged. */
+#ifndef L2CAP_HOST_FC_ACL_BUFS
+#define L2CAP_HOST_FC_ACL_BUFS 20
+#endif
+
+/* The percentage of the queue size allowed before a congestion event is sent to the L2CAP client (typically 120%). */
+#ifndef L2CAP_FWD_CONG_THRESH
+#define L2CAP_FWD_CONG_THRESH 120
+#endif
+
+/* This is set to enable L2CAP to take the ACL link out of park mode when ACL data is to be sent. */
+#ifndef L2CAP_WAKE_PARKED_LINK
+#define L2CAP_WAKE_PARKED_LINK TRUE
+#endif
+
+/* Whether link wants to be the master or the slave. */
+#ifndef L2CAP_DESIRED_LINK_ROLE
+#define L2CAP_DESIRED_LINK_ROLE HCI_ROLE_SLAVE
+#endif
+
+/* Include Non-Flushable Packet Boundary Flag feature of Lisbon */
+#ifndef L2CAP_NON_FLUSHABLE_PB_INCLUDED
+#define L2CAP_NON_FLUSHABLE_PB_INCLUDED TRUE
+#endif
+
+/* max queued Multi-AV packets per link including controller */
+#ifndef L2CAP_MULTI_AV_TOTAL_QUEUED_BUF
+#define L2CAP_MULTI_AV_TOTAL_QUEUED_BUF 6
+#endif
+
+/* max links supported by Multi-AV feature */
+#ifndef L2CAP_MAX_MULTI_AV_CID
+#define L2CAP_MAX_MULTI_AV_CID 5
+#endif
+
+/* Minimum number of ACL credit for high priority link */
+#ifndef L2CAP_HIGH_PRI_MIN_XMIT_QUOTA
+#define L2CAP_HIGH_PRI_MIN_XMIT_QUOTA 4
+#endif
+
+/* used for monitoring HCI ACL credit management */
+#ifndef L2CAP_HCI_FLOW_CONTROL_DEBUG
+#define L2CAP_HCI_FLOW_CONTROL_DEBUG TRUE
+#endif
+
+/* Used for calculating transmit buffers off of */
+#ifndef L2CAP_NUM_XMIT_BUFFS
+#define L2CAP_NUM_XMIT_BUFFS HCI_ACL_BUF_MAX
+#endif
+
+/* Unicast Connectionless Data */
+#ifndef L2CAP_UCD_INCLUDED
+#define L2CAP_UCD_INCLUDED FALSE
+#endif
+
+/* Unicast Connectionless Data MTU */
+#ifndef L2CAP_UCD_MTU
+#define L2CAP_UCD_MTU L2CAP_MTU_SIZE
+#endif
+
+/* Unicast Connectionless Data Idle Timeout */
+#ifndef L2CAP_UCD_IDLE_TIMEOUT
+#define L2CAP_UCD_IDLE_TIMEOUT 2
+#endif
+
+/* Unicast Connectionless Data Idle Timeout */
+#ifndef L2CAP_UCD_CH_PRIORITY
+#define L2CAP_UCD_CH_PRIORITY L2CAP_CHNL_PRIORITY_MEDIUM
+#endif
+
+/* Max clients on Unicast Connectionless Data */
+#ifndef L2CAP_MAX_UCD_CLIENTS
+#define L2CAP_MAX_UCD_CLIENTS 5
+#endif
+
+/* Used for features using fixed channels; set to zero if no fixed channels supported (AMP, BLE, etc.) */
+/* Excluding L2CAP signaling channel and UCD */
+#ifndef L2CAP_NUM_FIXED_CHNLS
+#define L2CAP_NUM_FIXED_CHNLS 4
+#endif
+
+/* First fixed channel supported; 3 if AMP supported */
+#ifndef L2CAP_FIRST_FIXED_CHNL
+#define L2CAP_FIRST_FIXED_CHNL 3
+#endif
+
+#ifndef L2CAP_LAST_FIXED_CHNL
+#define L2CAP_LAST_FIXED_CHNL (L2CAP_FIRST_FIXED_CHNL + L2CAP_NUM_FIXED_CHNLS - 1)
+#endif
+
+/* Round Robin service channels in link */
+#ifndef L2CAP_ROUND_ROBIN_CHANNEL_SERVICE
+#define L2CAP_ROUND_ROBIN_CHANNEL_SERVICE TRUE
+#endif
+
+/* Reconfig after move channel between BR/EDR and AMP */
+#ifndef L2CAP_MOVE_CH_RECONFIG_INCLUDED
+#define L2CAP_MOVE_CH_RECONFIG_INCLUDED FALSE
+#endif
+
+/* Initiate reconfig after move channel between BR/EDR and AMP */
+#ifndef L2CAP_MOVE_CH_RECONFIG_INTITIATOR
+#define L2CAP_MOVE_CH_RECONFIG_INTITIATOR FALSE
+#endif
+
+/* Adjust our monitor timeout in ms plus peer's processing time on class 2 AMP controller */
+#ifndef L2CAP_AMP_ADJUST_MONITOR_TOUT
+#define L2CAP_AMP_ADJUST_MONITOR_TOUT 500
+#endif
+
+/* Adjust our retrans timeout in ms plus peer's processing time on class 2 AMP controller */
+#ifndef L2CAP_AMP_ADJUST_RETRANS_TOUT
+#define L2CAP_AMP_ADJUST_RETRANS_TOUT 500
+#endif
+
+/* Default local device's processing time (ms) */
+#ifndef L2CAP_AMP_PROCESSING_TIME
+#define L2CAP_AMP_PROCESSING_TIME 500
+#endif
+
+/* Used for calculating transmit buffers off of */
+#ifndef L2CAP_NUM_XMIT_BUFFS
+#define L2CAP_NUM_XMIT_BUFFS HCI_ACL_BUF_MAX
+#endif
+
+/* Used for features using fixed channels; set to zero if no fixed channels supported (AMP, BLE, etc.) */
+#ifndef L2CAP_NUM_FIXED_CHNLS
+#define L2CAP_NUM_FIXED_CHNLS 1
+#endif
+
+/* First fixed channel supported; 3 if AMP supported */
+#ifndef L2CAP_FIRST_FIXED_CHNL
+#define L2CAP_FIRST_FIXED_CHNL 3
+#endif
+
+#ifndef L2CAP_LAST_FIXED_CHNL
+#define L2CAP_LAST_FIXED_CHNL (L2CAP_FIRST_FIXED_CHNL + L2CAP_NUM_FIXED_CHNLS - 1)
+#endif
+
+/* used for monitoring eL2CAP data flow */
+#ifndef L2CAP_ERTM_STATS
+#define L2CAP_ERTM_STATS FALSE
+#endif
+
+/* USED FOR FCR TEST ONLY: When TRUE generates bad tx and rx packets */
+#ifndef L2CAP_CORRUPT_ERTM_PKTS
+#define L2CAP_CORRUPT_ERTM_PKTS FALSE
+#endif
+
+/* Used for conformance testing ONLY: When TRUE lets scriptwrapper overwrite info response */
+#ifndef L2CAP_CONFORMANCE_TESTING
+#define L2CAP_CONFORMANCE_TESTING FALSE
+#endif
+
+/******************************************************************************
+**
+** AMP
+**
+******************************************************************************/
+
+#ifndef AMP_INCLUDED
+#define AMP_INCLUDED FALSE
+#endif
+
+/* TRUE if AMP includes debug functionality. */
+#ifndef AMP_DEBUG
+#define AMP_DEBUG FALSE
+#endif
+
+/* Maximum number of simultaneous remote AMP Hosts in system */
+#ifndef AMP_MAX_REMOTE_HOSTS
+#define AMP_MAX_REMOTE_HOSTS MAX_L2CAP_LINKS
+#endif
+
+/* Maximum number of simultaneous remote AMP controllers in system (BR/EDR excluded) */
+#ifndef AMP_MAX_REMOTE_CTRLS
+#define AMP_MAX_REMOTE_CTRLS 2
+#endif
+
+/* Maximum number of UUIDs per remote AMP host */
+#ifndef AMP_MAX_UUIDS_PER_REM_HOST
+#define AMP_MAX_UUIDS_PER_REM_HOST 4
+#endif
+
+/* Maximum number of simultaneous local AMP controllers in system (BR/EDR excluded) */
+#ifndef AMP_MAX_LOCAL_CTRLS
+#define AMP_MAX_LOCAL_CTRLS 1
+#endif
+
+/* Maximum number of simultaneous Physical Links in system */
+#ifndef AMP_MAX_PHYS_LINKS
+#define AMP_MAX_PHYS_LINKS 1
+#endif
+
+/* The maximum number of simultaneous AMP logical links that L2CAP can support. */
+#ifndef AMP_MAX_L2C_LOG_LINKS
+#define AMP_MAX_L2C_LOG_LINKS (MAX_L2CAP_LINKS * 2)
+#endif
+
+/* The number of seconds of link inactivity on AMP fixed channel before the ACL is disconnected. */
+#ifndef AMP_L2C_INACTIVITY_TIMER
+#define AMP_L2C_INACTIVITY_TIMER 7
+#endif
+
+#ifndef AMP_NUM_ALWAYS_PRESENT_LOC_CTRLRS
+#define AMP_NUM_ALWAYS_PRESENT_LOC_CTRLRS AMP_MAX_LOCAL_CTRLS
+#endif
+
+/* If this is non-zero value then l2cap overwrites total ACL credit on AMP. */
+/* This temporarily needs until number in dhd driver is finalized */
+#ifndef AMP_TOTAL_NUM_BLOCKS
+#define AMP_TOTAL_NUM_BLOCKS 0
+#endif
+
+/****************************
+** AMP Autoswitch Constants
+*****************************/
+/* AMP physical link inactivity timeout
+** This is started when the last logical channel got disconnected */
+#ifndef AMP_PHYS_LINK_INACT_DISC_TOUT
+#define AMP_PHYS_LINK_INACT_DISC_TOUT 20
+#endif
+
+/* interval between the moments to check if auto-switch ready connections
+** on this AMP controller have to be moved to BR/EDR and if yes - to
+** start to move the connections */
+#ifndef AMP_AS_TOUT_ON_AMP
+#define AMP_AS_TOUT_ON_AMP 1
+#endif
+
+/* on timeout all auto-switch ready connections
+** have to be moved from BR/EDR to AMP */
+#ifndef AMP_AS_TOUT_ON_BR_EDR
+#define AMP_AS_TOUT_ON_BR_EDR 1
+#endif
+
+/* min time to stay on BR/EDR after auto-switch from AMP
+** (during this time conditions to switch from BR/EDR to
+** AMP are ignored) */
+#ifndef AMP_AS_TOUT_NO_MOVE_TO_AMP
+#define AMP_AS_TOUT_NO_MOVE_TO_AMP 4
+#endif
+
+/* TRUE means that "tout to check throughput on BR/EDR"
+** is restarted after "no move to AMP" timer expires,
+** i.e. move from BR/EDR will start not earlier than
+** AMP_AS_TOUT_NO_MOVE_TO_AMP + AMP_AS_TOUT_ON_BR_EDR
+** FALSE means that "tout no move to AMP" and "tout
+** to check throughput on BR/EDR" run in parallel, i.e.
+** connections can be moved from BR/EDR any moment after
+** "tout no move to AMP" expires. */
+#ifndef AMP_AS_TOUT_ON_BR_EDR_AFTER_NO_MOVE_TO_AMP
+#define AMP_AS_TOUT_ON_BR_EDR_AFTER_NO_MOVE_TO_AMP TRUE
+#endif
+
+/* Until the number of packets sent to L2CAP is <= than this
+** value preparations for auto-switch BR/EDR->AMP do not start.
+** If the number of packets sent to L2CAP falls to this
+** value preparations for auto-switch BR/EDR->AMP stop. */
+#ifndef AMP_AS_THRESHOLD_ON_BR_EDR
+#define AMP_AS_THRESHOLD_ON_BR_EDR 3
+#endif
+
+/* the number of counters used to collect throughput data
+** on AMP controller. Check for auto-switch conditions starts
+** AMP_AMP_AS_COUNT_ARRAY_SIZE * AMP_AS_TOUT_ON_AMP
+** sec after the first auto-switch ready connection is moved
+** to this controller */
+#ifndef AMP_AMP_AS_COUNT_ARRAY_SIZE
+#define AMP_AMP_AS_COUNT_ARRAY_SIZE 10
+#endif
+
+/* meaning: flow spec modify is never sent to controller
+** best effort logical link is created with all
+** parameters sent to unknown...*/
+#ifndef AMP_SIMPLISTIC_AGGREGATION
+#define AMP_SIMPLISTIC_AGGREGATION TRUE
+#endif
+
+/* meaning: auto-switch ready connections start move
+** BR/EDR->AMP after throughput to remote host passes
+** some threshold in bytes (as opposite to move that
+** starts if during some time the number of UNACKED
+** L2CAP packets to remote host stays bigger than some
+** threshold) */
+#ifndef AMP_AUTO_SW_TO_AMP_BY_THROUGHPUT
+#define AMP_AUTO_SW_TO_AMP_BY_THROUGHPUT TRUE
+#endif
+
+/* the number of counters used to collect throughput data
+** on BR/EDR controller. Check for auto-switch conditions starts
+** AMP_BR_EDR_AS_COUNT_ARRAY_SIZE * AMP_AS_TOUT_ON_BR_EDR
+** sec after the first auto-switch ready connection is moved
+** to this controller */
+#ifndef AMP_BR_EDR_AS_COUNT_ARRAY_SIZE
+#define AMP_BR_EDR_AS_COUNT_ARRAY_SIZE 7
+#endif
+
+/* if it takes more than this amount of time to transfer object on BR/EDR
+** application(BTA) will initiate to AMP connection. */
+#ifndef AMP_AS_TRANSFER_TIME_ON_BR_EDR
+#define AMP_AS_TRANSFER_TIME_ON_BR_EDR 5
+#endif
+
+
+#ifndef AMP_RFC_TEST
+#define AMP_RFC_TEST FALSE
+#endif
+
+
+/******************************************************************************
+**
+** BLE
+**
+******************************************************************************/
+
+#ifndef BLE_INCLUDED
+#define BLE_INCLUDED FALSE
+#endif
+
+#ifndef LOCAL_BLE_CONTROLLER_ID
+#define LOCAL_BLE_CONTROLLER_ID (AMP_MAX_LOCAL_CTRLS + 1)
+#endif
+
+#ifndef BTM_BLE_PRIVACY_SPT
+#define BTM_BLE_PRIVACY_SPT FALSE
+#endif
+
+#ifndef BTM_PERIPHERAL_ENABLED
+#define BTM_PERIPHERAL_ENABLED FALSE
+#endif
+
+#ifndef HID_LE_INCLUDED
+#define HID_LE_INCLUDED FALSE
+#endif
+
+#ifndef BLE_BRCM_INCLUDED
+#define BLE_BRCM_INCLUDED FALSE
+#endif
+
+#ifndef BTM_DUMO_ADDR_CENTRAL_ENABLED
+#define BTM_DUMO_ADDR_CENTRAL_ENABLED FALSE
+#endif
+
+
+/******************************************************************************
+**
+** ATT/GATT Protocol/Profile Settings
+**
+******************************************************************************/
+#ifndef ATT_DEBUG
+#define ATT_DEBUG FALSE
+#endif
+
+#ifndef GATT_MAX_SR_PROFILES
+#define GATT_MAX_SR_PROFILES 32 /* max is 32 */
+#endif
+
+#ifndef GATT_MAX_APPS
+#define GATT_MAX_APPS 10 /* note: 2 apps used internally GATT and GAP */
+#endif
+
+#ifndef GATT_MAX_PHY_CHANNEL
+#define GATT_MAX_PHY_CHANNEL 4 /* limited by the BLE controller upto 15 */
+#endif
+
+/* Used for conformance testing ONLY */
+#ifndef GATT_CONFORMANCE_TESTING
+#define GATT_CONFORMANCE_TESTING FALSE
+#endif
+
+/* number of background connection device allowence, ideally to be the same as WL size
+*/
+#ifndef GATT_MAX_BG_CONN_DEV
+#define GATT_MAX_BG_CONN_DEV 32
+#endif
+
+/******************************************************************************
+**
+** SMP
+**
+******************************************************************************/
+#ifndef SMP_INCLUDED
+#define SMP_INCLUDED FALSE
+#endif
+
+#ifndef SMP_DEBUG
+#define SMP_DEBUG FALSE
+#endif
+
+#ifndef SMP_DEFAULT_AUTH_REQ
+#define SMP_DEFAULT_AUTH_REQ SMP_AUTH_NB_ENC_ONLY
+#endif
+
+#ifndef SMP_MAX_ENC_KEY_SIZE
+#define SMP_MAX_ENC_KEY_SIZE 16
+#endif
+
+#ifndef SMP_MIN_ENC_KEY_SIZE
+#define SMP_MIN_ENC_KEY_SIZE 7
+#endif
+
+/* Used for conformance testing ONLY */
+#ifndef SMP_CONFORMANCE_TESTING
+#define SMP_CONFORMANCE_TESTING FALSE
+#endif
+
+/******************************************************************************
+**
+** SDP
+**
+******************************************************************************/
+
+/* This is set to enable SDP server functionality. */
+#ifndef SDP_SERVER_ENABLED
+#define SDP_SERVER_ENABLED TRUE
+#endif
+
+/* The maximum number of SDP records the server can support. */
+#ifndef SDP_MAX_RECORDS
+#define SDP_MAX_RECORDS 20
+#endif
+
+/* The maximum number of attributes in each record. */
+#ifndef SDP_MAX_REC_ATTR
+#define SDP_MAX_REC_ATTR 25
+#endif
+
+#ifndef SDP_MAX_PAD_LEN
+#define SDP_MAX_PAD_LEN 350
+#endif
+
+/* The maximum length, in bytes, of an attribute. */
+#ifndef SDP_MAX_ATTR_LEN
+#define SDP_MAX_ATTR_LEN 256
+#endif
+
+/* The maximum number of attribute filters supported by SDP databases. */
+#ifndef SDP_MAX_ATTR_FILTERS
+#define SDP_MAX_ATTR_FILTERS 12
+#endif
+
+/* The maximum number of UUID filters supported by SDP databases. */
+#ifndef SDP_MAX_UUID_FILTERS
+#define SDP_MAX_UUID_FILTERS 3
+#endif
+
+/* This is set to enable SDP client functionality. */
+#ifndef SDP_CLIENT_ENABLED
+#define SDP_CLIENT_ENABLED TRUE
+#endif
+
+/* The maximum number of record handles retrieved in a search. */
+#ifndef SDP_MAX_DISC_SERVER_RECS
+#define SDP_MAX_DISC_SERVER_RECS 21
+#endif
+
+/* The size of a scratchpad buffer, in bytes, for storing the response to an attribute request. */
+#ifndef SDP_MAX_LIST_BYTE_COUNT
+#define SDP_MAX_LIST_BYTE_COUNT 1000
+#endif
+
+/* The maximum number of parameters in an SDP protocol element. */
+#ifndef SDP_MAX_PROTOCOL_PARAMS
+#define SDP_MAX_PROTOCOL_PARAMS 2
+#endif
+
+/* The maximum number of simultaneous client and server connections. */
+#ifndef SDP_MAX_CONNECTIONS
+#define SDP_MAX_CONNECTIONS 4
+#endif
+
+/* The MTU size for the L2CAP configuration. */
+#ifndef SDP_MTU_SIZE
+#define SDP_MTU_SIZE 256
+#endif
+
+/* The flush timeout for the L2CAP configuration. */
+#ifndef SDP_FLUSH_TO
+#define SDP_FLUSH_TO 0xFFFF
+#endif
+
+/* The name for security authorization. */
+#ifndef SDP_SERVICE_NAME
+#define SDP_SERVICE_NAME "Service Discovery"
+#endif
+
+/* The security level for BTM. */
+#ifndef SDP_SECURITY_LEVEL
+#define SDP_SECURITY_LEVEL BTM_SEC_NONE
+#endif
+
+/******************************************************************************
+**
+** RFCOMM
+**
+******************************************************************************/
+
+#ifndef RFCOMM_INCLUDED
+#define RFCOMM_INCLUDED FALSE
+#endif
+
+/* The maximum number of ports supported. */
+#ifndef MAX_RFC_PORTS
+#define MAX_RFC_PORTS 5
+#endif
+
+/* The maximum simultaneous links to different devices. */
+#ifndef MAX_BD_CONNECTIONS
+#define MAX_BD_CONNECTIONS 1
+#endif
+
+/* The port receive queue low watermark level, in bytes. */
+#ifndef PORT_RX_LOW_WM
+#define PORT_RX_LOW_WM 5000
+#endif
+
+/* The port receive queue high watermark level, in bytes. */
+#ifndef PORT_RX_HIGH_WM
+#define PORT_RX_HIGH_WM 8000
+#endif
+
+/* The port receive queue critical watermark level, in bytes. */
+#ifndef PORT_RX_CRITICAL_WM
+#define PORT_RX_CRITICAL_WM 12000
+#endif
+
+/* The port receive queue low watermark level, in number of buffers. */
+#ifndef PORT_RX_BUF_LOW_WM
+#define PORT_RX_BUF_LOW_WM 8
+#endif
+
+/* The port receive queue high watermark level, in number of buffers. */
+#ifndef PORT_RX_BUF_HIGH_WM
+#define PORT_RX_BUF_HIGH_WM 16
+#endif
+
+/* The port receive queue critical watermark level, in number of buffers. */
+#ifndef PORT_RX_BUF_CRITICAL_WM
+#define PORT_RX_BUF_CRITICAL_WM 22
+#endif
+
+/* The port transmit queue high watermark level, in bytes. */
+#ifndef PORT_TX_HIGH_WM
+#define PORT_TX_HIGH_WM 8000
+#endif
+
+/* The port transmit queue critical watermark level, in bytes. */
+#ifndef PORT_TX_CRITICAL_WM
+#define PORT_TX_CRITICAL_WM 10000
+#endif
+
+/* The port transmit queue high watermark level, in number of buffers. */
+#ifndef PORT_TX_BUF_HIGH_WM
+#define PORT_TX_BUF_HIGH_WM 16
+#endif
+
+/* The port transmit queue high watermark level, in number of buffers. */
+#ifndef PORT_TX_BUF_CRITICAL_WM
+#define PORT_TX_BUF_CRITICAL_WM 22
+#endif
+
+/* The RFCOMM multiplexer preferred flow control mechanism. */
+#ifndef PORT_FC_DEFAULT
+#define PORT_FC_DEFAULT PORT_FC_CREDIT
+#endif
+
+/* The maximum number of credits receiver sends to peer when using credit-based flow control. */
+#ifndef PORT_CREDIT_RX_MAX
+#define PORT_CREDIT_RX_MAX 16
+#endif
+
+/* The credit low watermark level. */
+#ifndef PORT_CREDIT_RX_LOW
+#define PORT_CREDIT_RX_LOW 8
+#endif
+
+/* if application like BTA, Java or script test engine is running on other than BTU thread, */
+/* PORT_SCHEDULE_LOCK shall be defined as GKI_sched_lock() or GKI_disable() */
+#ifndef PORT_SCHEDULE_LOCK
+#define PORT_SCHEDULE_LOCK GKI_disable()
+#endif
+
+/* if application like BTA, Java or script test engine is running on other than BTU thread, */
+/* PORT_SCHEDULE_LOCK shall be defined as GKI_sched_unlock() or GKI_enable() */
+#ifndef PORT_SCHEDULE_UNLOCK
+#define PORT_SCHEDULE_UNLOCK GKI_enable()
+#endif
+
+/******************************************************************************
+**
+** TCS
+**
+******************************************************************************/
+
+#ifndef TCS_INCLUDED
+#define TCS_INCLUDED FALSE
+#endif
+
+/* If set to TRUE, gives lean TCS state machine configuration. */
+#ifndef TCS_LEAN
+#define TCS_LEAN FALSE
+#endif
+
+/* To include/exclude point-to-multipoint broadcast SETUP configuration. */
+#ifndef TCS_BCST_SETUP_INCLUDED
+#define TCS_BCST_SETUP_INCLUDED TRUE
+#endif
+
+/* To include/exclude supplementary services. */
+#ifndef TCS_SUPP_SVCS_INCLUDED
+#define TCS_SUPP_SVCS_INCLUDED TRUE
+#endif
+
+/* To include/exclude WUG master role. */
+#ifndef TCS_WUG_MASTER_INCLUDED
+#define TCS_WUG_MASTER_INCLUDED TRUE
+#endif
+
+/* To include/exclude WUG member role. */
+#ifndef TCS_WUG_MEMBER_INCLUDED
+#define TCS_WUG_MEMBER_INCLUDED TRUE
+#endif
+
+/* Maximum number of WUG members. */
+#ifndef TCS_MAX_WUG_MEMBERS
+#define TCS_MAX_WUG_MEMBERS 7
+#endif
+
+/* Widcomm specific acknowledgement message to ensure fast and robust operation of WUG FIMA procedure. */
+#ifndef TCS_WUG_LISTEN_ACPT_ACK_INCLUDED
+#define TCS_WUG_LISTEN_ACPT_ACK_INCLUDED TRUE
+#endif
+
+/* The number of simultaneous calls supported. */
+#ifndef TCS_MAX_NUM_SIMUL_CALLS
+#define TCS_MAX_NUM_SIMUL_CALLS 3
+#endif
+
+/* The number of devices the device can connect to. */
+#ifndef TCS_MAX_NUM_ACL_CONNS
+#define TCS_MAX_NUM_ACL_CONNS 7
+#endif
+
+/* The maximum length, in bytes, of the company specific information element. */
+#ifndef TCS_MAX_CO_SPEC_LEN
+#define TCS_MAX_CO_SPEC_LEN 40
+#endif
+
+/* The maximum length, in bytes, of the audio control information element . */
+#ifndef TCS_MAX_AUDIO_CTL_LEN
+#define TCS_MAX_AUDIO_CTL_LEN 40
+#endif
+
+/* (Dis)allow EDR ESCO */
+#ifndef TCS_AUDIO_USE_ESCO_EDR
+#define TCS_AUDIO_USE_ESCO_EDR FALSE
+#endif
+
+/******************************************************************************
+**
+** OBX
+**
+******************************************************************************/
+#ifndef OBX_INCLUDED
+#define OBX_INCLUDED FALSE
+#endif
+
+#ifndef OBX_CLIENT_INCLUDED
+#define OBX_CLIENT_INCLUDED TRUE
+#endif
+
+#ifndef OBX_SERVER_INCLUDED
+#define OBX_SERVER_INCLUDED TRUE
+#endif
+
+/* TRUE to include OBEX authentication/MD5 test code */
+#ifndef OBX_MD5_TEST_INCLUDED
+#define OBX_MD5_TEST_INCLUDED FALSE
+#endif
+
+/* The timeout value (in seconds) for reliable sessions to remain in suspend. 0xFFFFFFFF for no timeout event. */
+#ifndef OBX_SESS_TIMEOUT_VALUE
+#define OBX_SESS_TIMEOUT_VALUE 600
+#endif
+
+/* The idle timeout value. 0 for no timeout event. */
+#ifndef OBX_TIMEOUT_VALUE
+#define OBX_TIMEOUT_VALUE 60
+#endif
+
+/* Timeout value used for disconnect */
+#ifndef OBX_DISC_TOUT_VALUE
+#define OBX_DISC_TOUT_VALUE 5
+#endif
+
+/* The maximum number of registered servers. */
+#ifndef OBX_NUM_SERVERS
+#define OBX_NUM_SERVERS 12
+#endif
+
+/* The maximum number of sessions for all registered servers.
+ * (must be equal or bigger than OBX_NUM_SERVERS) */
+#ifndef OBX_NUM_SR_SESSIONS
+#define OBX_NUM_SR_SESSIONS 26
+#endif
+
+/* The maximum number of sessions per registered server.
+ * must be less than MAX_BD_CONNECTIONS */
+#ifndef OBX_MAX_SR_SESSION
+#define OBX_MAX_SR_SESSION 4
+#endif
+
+/* The maximum number of suspended sessions per registered servers. */
+#ifndef OBX_MAX_SUSPEND_SESSIONS
+#define OBX_MAX_SUSPEND_SESSIONS 4
+#endif
+
+/* The maximum number of active clients. */
+#ifndef OBX_NUM_CLIENTS
+#define OBX_NUM_CLIENTS 8
+#endif
+
+/* The maximum length of OBEX target header.*/
+#ifndef OBX_MAX_TARGET_LEN
+#define OBX_MAX_TARGET_LEN 16
+#endif
+
+/* The maximum length of authentication challenge realm.*/
+#ifndef OBX_MAX_REALM_LEN
+#define OBX_MAX_REALM_LEN 30
+#endif
+
+/* The maximum of GKI buffer queued at OBX before flow control L2CAP */
+#ifndef OBX_MAX_RX_QUEUE_COUNT
+#define OBX_MAX_RX_QUEUE_COUNT 3
+#endif
+
+/* This option is application when OBEX over L2CAP is in use
+ Pool ID where to reassemble the SDU.
+ This Pool will allow buffers to be used that are larger than
+ the L2CAP_MAX_MTU. */
+#ifndef OBX_USER_RX_POOL_ID
+#define OBX_USER_RX_POOL_ID OBX_LRG_DATA_POOL_ID
+#endif
+
+/* This option is application when OBEX over L2CAP is in use
+ Pool ID where to hold the SDU.
+ This Pool will allow buffers to be used that are larger than
+ the L2CAP_MAX_MTU. */
+#ifndef OBX_USER_TX_POOL_ID
+#define OBX_USER_TX_POOL_ID OBX_LRG_DATA_POOL_ID
+#endif
+
+/* This option is application when OBEX over L2CAP is in use
+GKI Buffer Pool ID used to hold MPS segments during SDU reassembly
+*/
+#ifndef OBX_FCR_RX_POOL_ID
+#define OBX_FCR_RX_POOL_ID HCI_ACL_POOL_ID
+#endif
+
+/* This option is application when OBEX over L2CAP is in use
+GKI Buffer Pool ID used to hold MPS segments used in (re)transmissions.
+L2CAP_DEFAULT_ERM_POOL_ID is specified to use the HCI ACL data pool.
+Note: This pool needs to have enough buffers to hold two times the window size negotiated
+ in the L2CA_SetFCROptions (2 * tx_win_size) to allow for retransmissions.
+ The size of each buffer must be able to hold the maximum MPS segment size passed in
+ L2CA_SetFCROptions plus BT_HDR (8) + HCI preamble (4) + L2CAP_MIN_OFFSET (11 - as of BT 2.1 + EDR Spec).
+*/
+#ifndef OBX_FCR_TX_POOL_ID
+#define OBX_FCR_TX_POOL_ID HCI_ACL_POOL_ID
+#endif
+
+/* This option is application when OBEX over L2CAP is in use
+Size of the transmission window when using enhanced retransmission mode. Not used
+in basic and streaming modes. Range: 1 - 63
+This is used when AMP_INCLUDED == FALSE
+*/
+#ifndef OBX_FCR_OPT_TX_WINDOW_SIZE_BR_EDR
+#define OBX_FCR_OPT_TX_WINDOW_SIZE_BR_EDR 20
+#endif
+
+/* This option is application when OBEX over L2CAP is in use
+Size of the transmission window when using enhanced retransmission mode. Not used
+in basic and streaming modes. Range: 1 - 63
+This is used when AMP_INCLUDED == TRUE
+*/
+#ifndef OBX_FCR_OPT_TX_WINDOW_SIZE_AMP
+#define OBX_FCR_OPT_TX_WINDOW_SIZE_AMP 45
+#endif
+
+/* This option is application when OBEX over L2CAP is in use
+Number of transmission attempts for a single I-Frame before taking
+Down the connection. Used In ERTM mode only. Value is Ignored in basic and
+Streaming modes.
+Range: 0, 1-0xFF
+0 - infinite retransmissions
+1 - single transmission
+*/
+#ifndef OBX_FCR_OPT_MAX_TX_B4_DISCNT
+#define OBX_FCR_OPT_MAX_TX_B4_DISCNT 20
+#endif
+
+/* This option is application when OBEX over L2CAP is in use
+Retransmission Timeout
+Range: Minimum 2000 (2 secs) on BR/EDR when supporting PBF.
+ */
+#ifndef OBX_FCR_OPT_RETX_TOUT
+#define OBX_FCR_OPT_RETX_TOUT 2000
+#endif
+
+/* This option is application when OBEX over L2CAP is in use
+Monitor Timeout
+Range: Minimum 12000 (12 secs) on BR/EDR when supporting PBF.
+*/
+#ifndef OBX_FCR_OPT_MONITOR_TOUT
+#define OBX_FCR_OPT_MONITOR_TOUT 12000
+#endif
+
+/******************************************************************************
+**
+** BNEP
+**
+******************************************************************************/
+
+#ifndef BNEP_INCLUDED
+#define BNEP_INCLUDED FALSE
+#endif
+
+/* Protocol filtering is an optional feature. Bydefault it will be turned on */
+#ifndef BNEP_SUPPORTS_PROT_FILTERS
+#define BNEP_SUPPORTS_PROT_FILTERS TRUE
+#endif
+
+/* Multicast filtering is an optional feature. Bydefault it will be turned on */
+#ifndef BNEP_SUPPORTS_MULTI_FILTERS
+#define BNEP_SUPPORTS_MULTI_FILTERS TRUE
+#endif
+
+/* BNEP status API call is used mainly to get the L2CAP handle */
+#ifndef BNEP_SUPPORTS_STATUS_API
+#define BNEP_SUPPORTS_STATUS_API TRUE
+#endif
+
+/* This is just a debug function */
+#ifndef BNEP_SUPPORTS_DEBUG_DUMP
+#define BNEP_SUPPORTS_DEBUG_DUMP TRUE
+#endif
+
+#ifndef BNEP_SUPPORTS_ALL_UUID_LENGTHS
+#define BNEP_SUPPORTS_ALL_UUID_LENGTHS TRUE /* Otherwise it will support only 16bit UUIDs */
+#endif
+
+/*
+** When BNEP connection changes roles after the connection is established
+** we will do an authentication check again on the new role
+*/
+#ifndef BNEP_DO_AUTH_FOR_ROLE_SWITCH
+#define BNEP_DO_AUTH_FOR_ROLE_SWITCH TRUE
+#endif
+
+
+/* Maximum number of protocol filters supported. */
+#ifndef BNEP_MAX_PROT_FILTERS
+#define BNEP_MAX_PROT_FILTERS 5
+#endif
+
+/* Maximum number of multicast filters supported. */
+#ifndef BNEP_MAX_MULTI_FILTERS
+#define BNEP_MAX_MULTI_FILTERS 5
+#endif
+
+/* Minimum MTU size. */
+#ifndef BNEP_MIN_MTU_SIZE
+#define BNEP_MIN_MTU_SIZE L2CAP_MTU_SIZE
+#endif
+
+/* Preferred MTU size. */
+#ifndef BNEP_MTU_SIZE
+#define BNEP_MTU_SIZE BNEP_MIN_MTU_SIZE
+#endif
+
+/* Maximum size of user data, in bytes. */
+#ifndef BNEP_MAX_USER_DATA_SIZE
+#define BNEP_MAX_USER_DATA_SIZE 1500
+#endif
+
+/* Maximum number of buffers allowed in transmit data queue. */
+#ifndef BNEP_MAX_XMITQ_DEPTH
+#define BNEP_MAX_XMITQ_DEPTH 20
+#endif
+
+/* Maximum number BNEP of connections supported. */
+#ifndef BNEP_MAX_CONNECTIONS
+#define BNEP_MAX_CONNECTIONS 7
+#endif
+
+
+/******************************************************************************
+**
+** AVDTP
+**
+******************************************************************************/
+
+#ifndef AVDT_INCLUDED
+#define AVDT_INCLUDED FALSE
+#endif
+
+/* Include reporting capability in AVDTP */
+#ifndef AVDT_REPORTING
+#define AVDT_REPORTING TRUE
+#endif
+
+/* Include multiplexing capability in AVDTP */
+#ifndef AVDT_MULTIPLEXING
+#define AVDT_MULTIPLEXING TRUE
+#endif
+
+/* Number of simultaneous links to different peer devices. */
+#ifndef AVDT_NUM_LINKS
+#define AVDT_NUM_LINKS 2
+#endif
+
+/* Number of simultaneous stream endpoints. */
+#ifndef AVDT_NUM_SEPS
+#define AVDT_NUM_SEPS 3
+#endif
+
+/* Number of transport channels setup per media stream(audio or video) */
+#ifndef AVDT_NUM_CHANNELS
+
+#if AVDT_REPORTING == TRUE
+/* signaling, media and reporting channels */
+#define AVDT_NUM_CHANNELS 3
+#else
+/* signaling and media channels */
+#define AVDT_NUM_CHANNELS 2
+#endif
+
+#endif
+
+/* Number of transport channels setup by AVDT for all media streams
+ * AVDT_NUM_CHANNELS * Number of simultaneous streams.
+ */
+#ifndef AVDT_NUM_TC_TBL
+#define AVDT_NUM_TC_TBL 6
+#endif
+
+
+/* Maximum size in bytes of the codec capabilities information element. */
+#ifndef AVDT_CODEC_SIZE
+#define AVDT_CODEC_SIZE 10
+#endif
+
+/* Maximum size in bytes of the content protection information element. */
+#ifndef AVDT_PROTECT_SIZE
+#define AVDT_PROTECT_SIZE 90
+#endif
+
+/* Maximum number of GKI buffers in the fragment queue (for video frames).
+ * Must be less than the number of buffers in the buffer pool of size AVDT_DATA_POOL_SIZE */
+#ifndef AVDT_MAX_FRAG_COUNT
+#define AVDT_MAX_FRAG_COUNT 15
+#endif
+
+/******************************************************************************
+**
+** PAN
+**
+******************************************************************************/
+
+#ifndef PAN_INCLUDED
+#define PAN_INCLUDED FALSE
+#endif
+
+/* This will enable the PANU role */
+#ifndef PAN_SUPPORTS_ROLE_PANU
+#define PAN_SUPPORTS_ROLE_PANU TRUE
+#endif
+
+/* This will enable the GN role */
+#ifndef PAN_SUPPORTS_ROLE_GN
+#define PAN_SUPPORTS_ROLE_GN TRUE
+#endif
+
+/* This will enable the NAP role */
+#ifndef PAN_SUPPORTS_ROLE_NAP
+#define PAN_SUPPORTS_ROLE_NAP TRUE
+#endif
+
+/* This is just for debugging purposes */
+#ifndef PAN_SUPPORTS_DEBUG_DUMP
+#define PAN_SUPPORTS_DEBUG_DUMP TRUE
+#endif
+
+
+/* Maximum number of PAN connections allowed */
+#ifndef MAX_PAN_CONNS
+#define MAX_PAN_CONNS 7
+#endif
+
+/* Default service name for NAP role */
+#ifndef PAN_NAP_DEFAULT_SERVICE_NAME
+#define PAN_NAP_DEFAULT_SERVICE_NAME "Network Access Point Service"
+#endif
+
+/* Default service name for GN role */
+#ifndef PAN_GN_DEFAULT_SERVICE_NAME
+#define PAN_GN_DEFAULT_SERVICE_NAME "Group Network Service"
+#endif
+
+/* Default service name for PANU role */
+#ifndef PAN_PANU_DEFAULT_SERVICE_NAME
+#define PAN_PANU_DEFAULT_SERVICE_NAME "PAN User Service"
+#endif
+
+/* Default description for NAP role service */
+#ifndef PAN_NAP_DEFAULT_DESCRIPTION
+#define PAN_NAP_DEFAULT_DESCRIPTION "Public NAP"
+#endif
+
+/* Default description for GN role service */
+#ifndef PAN_GN_DEFAULT_DESCRIPTION
+#define PAN_GN_DEFAULT_DESCRIPTION "Widcomm GN"
+#endif
+
+/* Default description for PANU role service */
+#ifndef PAN_PANU_DEFAULT_DESCRIPTION
+#define PAN_PANU_DEFAULT_DESCRIPTION "Laptop's PANU"
+#endif
+
+/* Default Security level for PANU role. */
+#ifndef PAN_PANU_SECURITY_LEVEL
+#define PAN_PANU_SECURITY_LEVEL 0
+#endif
+
+/* Default Security level for GN role. */
+#ifndef PAN_GN_SECURITY_LEVEL
+#define PAN_GN_SECURITY_LEVEL 0
+#endif
+
+/* Default Security level for NAP role. */
+#ifndef PAN_NAP_SECURITY_LEVEL
+#define PAN_NAP_SECURITY_LEVEL 0
+#endif
+
+
+
+
+/******************************************************************************
+**
+** GAP
+**
+******************************************************************************/
+
+#ifndef GAP_INCLUDED
+#define GAP_INCLUDED FALSE
+#endif
+
+/* This is set to enable use of GAP L2CAP connections. */
+#ifndef GAP_CONN_INCLUDED
+#define GAP_CONN_INCLUDED TRUE
+#endif
+
+/* This is set to enable posting event for data write */
+#ifndef GAP_CONN_POST_EVT_INCLUDED
+#define GAP_CONN_POST_EVT_INCLUDED FALSE
+#endif
+
+/* The maximum number of simultaneous GAP L2CAP connections. */
+#ifndef GAP_MAX_CONNECTIONS
+#define GAP_MAX_CONNECTIONS 8
+#endif
+
+/******************************************************************************
+**
+** CTP
+**
+******************************************************************************/
+
+#ifndef CTP_INCLUDED
+#define CTP_INCLUDED FALSE
+#endif
+
+/* To include CTP gateway functionality or not. */
+#ifndef CTP_GW_INCLUDED
+#define CTP_GW_INCLUDED TRUE
+#endif
+
+/* The number of terminals supported. */
+#ifndef CTP_MAX_NUM_TLS
+#define CTP_MAX_NUM_TLS 7
+#endif
+
+/* If the controller can not support sniff mode when the SCO is up, set this to FALSE. */
+#ifndef CTP_USE_SNIFF_ON_SCO
+#define CTP_USE_SNIFF_ON_SCO FALSE
+#endif
+
+/* When ACL link between TL and GW is idle for more than this amount of seconds, the ACL may be put to low power mode. */
+#ifndef CTP_TL_IDLE_TIMEOUT
+#define CTP_TL_IDLE_TIMEOUT 90
+#endif
+
+/* To include CTP terminal functionality or not. */
+#ifndef CTP_TL_INCLUDED
+#define CTP_TL_INCLUDED TRUE
+#endif
+
+/* To include CTP device discovery functionality or not. */
+#ifndef CTP_DISCOVERY_INCLUDED
+#define CTP_DISCOVERY_INCLUDED TRUE
+#endif
+
+/* set to TRUE for controllers that do not support multi-point */
+#ifndef CTP_TL_WAIT_DISC
+#define CTP_TL_WAIT_DISC TRUE
+#endif
+
+/* The CTP inquiry database size. */
+#ifndef CTP_INQ_DB_SIZE
+#define CTP_INQ_DB_SIZE CTP_DISC_REC_SIZE
+#endif
+
+/* The CTP discovery record size. */
+#ifndef CTP_DISC_REC_SIZE
+#define CTP_DISC_REC_SIZE 60
+#endif
+
+/* CTP TL would try to re-establish L2CAP channel after channel is disconnected for this amount of seconds. */
+#ifndef CTP_GUARD_LINK_LOST
+#define CTP_GUARD_LINK_LOST 1
+#endif
+
+/* The link policy bitmap. */
+#ifndef CTP_DEFAULT_LINK_POLICY
+#define CTP_DEFAULT_LINK_POLICY 0x000F
+#endif
+
+/* The minimum period interval used for the sniff and park modes. */
+#ifndef CTP_DEF_LOWPWR_MIN_PERIOD
+#define CTP_DEF_LOWPWR_MIN_PERIOD 0x100
+#endif
+
+/* The maximum period interval used for the sniff and park modes. */
+#ifndef CTP_DEF_LOWPWR_MAX_PERIOD
+#define CTP_DEF_LOWPWR_MAX_PERIOD 0x1E0
+#endif
+
+/* The number of baseband receive slot sniff attempts. */
+#ifndef CTP_DEF_LOWPWR_ATTEMPT
+#define CTP_DEF_LOWPWR_ATTEMPT 0x200
+#endif
+
+/* The number of baseband receive slots for sniff timeout. */
+#ifndef CTP_DEF_LOWPWR_TIMEOUT
+#define CTP_DEF_LOWPWR_TIMEOUT 0x200
+#endif
+
+/* This is set if CTP is to use park mode. */
+#ifndef CTP_PARK_INCLUDED
+#define CTP_PARK_INCLUDED TRUE
+#endif
+
+/* This is set if CTP is to use sniff mode. */
+#ifndef CTP_SNIFF_INCLUDED
+#define CTP_SNIFF_INCLUDED TRUE
+#endif
+
+/* To include CTP data exchange functionality or not. */
+#ifndef CTP_DATA_EXCHG_FEATURE
+#define CTP_DATA_EXCHG_FEATURE FALSE
+#endif
+
+/* To include CTP GW intercom functionality or not. */
+#ifndef CTP_GW_INTERCOM_FEATURE
+#define CTP_GW_INTERCOM_FEATURE FALSE
+#endif
+
+/* The MTU size for L2CAP channel. */
+#ifndef CTP_MTU_SIZE
+#define CTP_MTU_SIZE 200
+#endif
+
+/* The L2CAP PSM for the data exchange feature. */
+#ifndef CTP_DATA_EXCHG_PSM
+#define CTP_DATA_EXCHG_PSM 13
+#endif
+
+/* The flush timeout for L2CAP channels. */
+#ifndef CTP_FLUSH_TO
+#define CTP_FLUSH_TO 0xFFFF
+#endif
+
+/* The default service name for CTP. */
+#ifndef CTP_DEFAULT_SERVICE_NAME
+#define CTP_DEFAULT_SERVICE_NAME "Cordless Telephony"
+#endif
+
+/* The CTP security level. */
+#ifndef CTP_SECURITY_LEVEL
+#define CTP_SECURITY_LEVEL (BTM_SEC_IN_AUTHORIZE | BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT)
+#endif
+
+/* The number of lines to the external network. */
+#ifndef CTP_MAX_LINES
+#define CTP_MAX_LINES 1
+#endif
+
+/* Test if the number of resources in TCS is consistent with CTP setting. */
+#ifndef CTP_TEST_FULL_TCS
+#define CTP_TEST_FULL_TCS TRUE
+#endif
+
+/* The default inquiry mode. */
+#ifndef CTP_DEFAULT_INQUIRY_MODE
+#define CTP_DEFAULT_INQUIRY_MODE BTM_GENERAL_INQUIRY
+#endif
+
+/* The default inquiry duration. */
+#ifndef CTP_DEFAULT_INQ_DURATION
+#define CTP_DEFAULT_INQ_DURATION 4
+#endif
+
+/* The maximum number of inquiry responses. */
+#ifndef CTP_DEFAULT_INQ_MAX_RESP
+#define CTP_DEFAULT_INQ_MAX_RESP 3
+#endif
+
+/* When TL does not create another L2CAP channel within this period of time GW declares that it's "Connected Limited". */
+#ifndef CTP_TL_CONN_TIMEOUT
+#define CTP_TL_CONN_TIMEOUT 5
+#endif
+
+/* The delay for ACL to completely disconnect (for intercom) before sending the connect request to GW. */
+#ifndef CTP_RECONNECT_DELAY
+#define CTP_RECONNECT_DELAY 5
+#endif
+
+/* How many times to retry connection when it has failed. */
+#ifndef CTP_RETRY_ON_CONN_ERR
+#define CTP_RETRY_ON_CONN_ERR 5
+#endif
+
+/******************************************************************************
+**
+** ICP
+**
+******************************************************************************/
+
+#ifndef ICP_INCLUDED
+#define ICP_INCLUDED FALSE
+#endif
+
+/* The ICP default MTU. */
+#ifndef ICP_MTU_SIZE
+#define ICP_MTU_SIZE 100
+#endif
+
+/* The ICP security level. */
+#ifndef ICP_SECURITY_LEVEL
+#define ICP_SECURITY_LEVEL BTM_SEC_NONE
+#endif
+
+/* The default service name for ICP. */
+#ifndef ICP_DEFAULT_SERVICE_NAME
+#define ICP_DEFAULT_SERVICE_NAME "Intercom"
+#endif
+
+/* The flush timeout for L2CAP channels. */
+#ifndef ICP_FLUSH_TO
+#define ICP_FLUSH_TO 0xFFFF
+#endif
+
+/******************************************************************************
+**
+** SPP
+**
+******************************************************************************/
+
+#ifndef SPP_INCLUDED
+#define SPP_INCLUDED FALSE
+#endif
+
+/* The SPP default MTU. */
+#ifndef SPP_DEFAULT_MTU
+#define SPP_DEFAULT_MTU 127
+#endif
+
+/* The interval, in seconds, that a client tries to reconnect to a service. */
+#ifndef SPP_RETRY_CONN_INTERVAL
+#define SPP_RETRY_CONN_INTERVAL 1
+#endif
+
+/* The SPP discoverable mode: limited or general. */
+#ifndef SPP_DISCOVERABLE_MODE
+#define SPP_DISCOVERABLE_MODE BTM_GENERAL_DISCOVERABLE
+#endif
+
+/* The maximum number of inquiry results returned in by inquiry procedure. */
+#ifndef SPP_DEF_INQ_MAX_RESP
+#define SPP_DEF_INQ_MAX_RESP 10
+#endif
+
+/* The SPP discovery record size. */
+#ifndef SPP_DISC_REC_SIZE
+#define SPP_DISC_REC_SIZE 60
+#endif
+
+#ifndef SPP_MAX_RECS_PER_DEVICE
+#define SPP_MAX_RECS_PER_DEVICE (SPP_DB_SIZE / SPP_DISC_REC_SIZE)
+#endif
+
+/* Inquiry duration in 1.28 second units. */
+#ifndef SPP_DEF_INQ_DURATION
+#define SPP_DEF_INQ_DURATION 9
+#endif
+
+/* keep the raw data received from SDP server in database. */
+#ifndef SDP_RAW_DATA_INCLUDED
+#define SDP_RAW_DATA_INCLUDED FALSE
+#endif
+
+/* TRUE, to allow JV to create L2CAP connection on SDP PSM. */
+#ifndef SDP_FOR_JV_INCLUDED
+#define SDP_FOR_JV_INCLUDED FALSE
+#endif
+
+/* Inquiry duration in 1.28 second units. */
+#ifndef SDP_DEBUG
+#define SDP_DEBUG TRUE
+#endif
+
+/******************************************************************************
+**
+** HSP2, HFP
+**
+******************************************************************************/
+
+#ifndef HSP2_INCLUDED
+#define HSP2_INCLUDED FALSE
+#endif
+
+/* Include the ability to perform inquiry for peer devices. */
+#ifndef HSP2_INQUIRY_INCLUDED
+#define HSP2_INQUIRY_INCLUDED TRUE
+#endif
+
+/* Include Audio Gateway specific code. */
+#ifndef HSP2_AG_INCLUDED
+#define HSP2_AG_INCLUDED TRUE
+#endif
+
+/* Include Headset Specific Code. */
+#ifndef HSP2_HS_INCLUDED
+#define HSP2_HS_INCLUDED TRUE
+#endif
+
+/* Include the ability to open an SCO connection for In-Band Ringing. */
+#ifndef HSP2_IB_RING_INCLUDED
+#define HSP2_IB_RING_INCLUDED TRUE
+#endif
+
+/* Include the ability to repeat a ring. */
+#ifndef HSP2_AG_REPEAT_RING
+#define HSP2_AG_REPEAT_RING TRUE
+#endif
+
+#ifndef HSP2_APP_CLOSES_ON_CKPD
+#define HSP2_APP_CLOSES_ON_CKPD FALSE
+#endif
+
+
+/* Include the ability to park a connection. */
+#ifndef HSP2_PARK_INCLUDED
+#define HSP2_PARK_INCLUDED TRUE
+#endif
+
+/* Include HSP State Machine debug trace messages. */
+#ifndef HSP2_FSM_DEBUG
+#define HSP2_FSM_DEBUG TRUE
+#endif
+
+/* The Module's Inquiry Scan Window. */
+#ifndef HSP2_INQ_SCAN_WINDOW
+#define HSP2_INQ_SCAN_WINDOW 0
+#endif
+
+/* The Module's Inquiry Scan Interval. */
+#ifndef HSP2_INQ_SCAN_INTERVAL
+#define HSP2_INQ_SCAN_INTERVAL 0
+#endif
+
+/* The Module's Page Scan Interval. */
+#ifndef HSP2_PAGE_SCAN_INTERVAL
+#define HSP2_PAGE_SCAN_INTERVAL 0
+#endif
+
+/* The Module's Page Scan Window. */
+#ifndef HSP2_PAGE_SCAN_WINDOW
+#define HSP2_PAGE_SCAN_WINDOW 0
+#endif
+
+/* The Park Mode's Minimum Beacon Period. */
+#ifndef HSP2_BEACON_MIN_PERIOD
+#define HSP2_BEACON_MIN_PERIOD 450
+#endif
+
+/* The Park Mode's Maximum Beacon Period. */
+#ifndef HSP2_BEACON_MAX_PERIOD
+#define HSP2_BEACON_MAX_PERIOD 500
+#endif
+
+/* The duration of the inquiry in seconds. */
+#ifndef HSP2_INQ_DURATION
+#define HSP2_INQ_DURATION 4
+#endif
+
+/* Maximum number of peer responses during an inquiry. */
+#ifndef HSP2_INQ_MAX_NUM_RESPS
+#define HSP2_INQ_MAX_NUM_RESPS 3
+#endif
+
+/* Maximum number of times to retry an inquiry prior to failure. */
+#ifndef HSP2_MAX_INQ_RETRY
+#define HSP2_MAX_INQ_RETRY 6
+#endif
+
+/* Maximum number of times to retry an RFCOMM connection prior to failure. */
+#ifndef HSP2_MAX_CONN_RETRY
+#define HSP2_MAX_CONN_RETRY 3
+#endif
+
+/* If the connect request failed for authentication reasons, do not retry */
+#ifndef HSP2_NO_RETRY_ON_AUTH_FAIL
+#define HSP2_NO_RETRY_ON_AUTH_FAIL TRUE
+#endif
+
+/* Maximum number of characters in an HSP2 device name. */
+#ifndef HSP2_MAX_NAME_LEN
+#define HSP2_MAX_NAME_LEN 32
+#endif
+
+/* The minimum speaker and/or microphone gain setting. */
+#ifndef HSP2_MIN_GAIN
+#define HSP2_MIN_GAIN 0
+#endif
+
+/* The maximum speaker and/or microphone setting. */
+#ifndef HSP2_MAX_GAIN
+#define HSP2_MAX_GAIN 15
+#endif
+
+/* The default value to send on an AT+CKPD. */
+#ifndef HSP2_KEYPRESS_DEFAULT
+#define HSP2_KEYPRESS_DEFAULT 200
+#endif
+
+/* Maximum amount a data that can be received per RFCOMM frame. */
+#ifndef HSP2_MAX_RFC_READ_LEN
+#define HSP2_MAX_RFC_READ_LEN 128
+#endif
+
+/* The time in seconds to wait for completion of a partial AT command or response from the peer. */
+#ifndef HSP2_AT_TO_INTERVAL
+#define HSP2_AT_TO_INTERVAL 30
+#endif
+
+/* The time to wait before repeating a ring to a peer Headset. */
+#ifndef HSP2_REPEAT_RING_TO
+#define HSP2_REPEAT_RING_TO 4
+#endif
+
+/* Time to wait for a response for an AT command */
+#ifndef HSP2_AT_RSP_TO
+#define HSP2_AT_RSP_TO 20
+#endif
+
+/* SCO packet type(s) to use (bitmask: see spec), 0 - device default (recommended) */
+#ifndef HSP2_SCO_PKT_TYPES
+#define HSP2_SCO_PKT_TYPES ((UINT16)0x0000)
+#endif
+
+/* The default settings of the SCO voice link. */
+#ifndef HSP2_DEFAULT_VOICE_SETTINGS
+#define HSP2_DEFAULT_VOICE_SETTINGS (HCI_INP_CODING_LINEAR | HCI_INP_DATA_FMT_2S_COMPLEMENT | HCI_INP_SAMPLE_SIZE_16BIT | HCI_AIR_CODING_FORMAT_CVSD)
+#endif
+
+#ifndef HSP2_MAX_AT_CMD_LENGTH
+#define HSP2_MAX_AT_CMD_LENGTH 16
+#endif
+
+#ifndef HSP2_MAX_AT_VAL_LENGTH
+#if (defined(HFP_INCLUDED) && HFP_INCLUDED == TRUE)
+#define HSP2_MAX_AT_VAL_LENGTH 310
+#else
+#define HSP2_MAX_AT_VAL_LENGTH 5
+#endif
+#endif
+
+
+#ifndef HSP2_SDP_DB_SIZE
+#define HSP2_SDP_DB_SIZE 300
+#endif
+
+
+/******************************************************************************
+**
+** HFP
+**
+******************************************************************************/
+
+#ifndef HFP_INCLUDED
+#define HFP_INCLUDED FALSE
+#endif
+
+/* Include Audio Gateway specific code. */
+#ifndef HFP_AG_INCLUDED
+#define HFP_AG_INCLUDED TRUE
+#endif
+
+/* Include Hand Free Specific Code. */
+#ifndef HFP_HF_INCLUDED
+#define HFP_HF_INCLUDED TRUE
+#endif
+
+/* Use AT interface instead of full blown API */
+#ifndef AT_INTERFACE
+#define AT_INTERFACE FALSE
+#endif
+
+/* HFP Manages SCO establishement for various procedures */
+#ifndef HFP_SCO_MGMT_INCLUDED
+#define HFP_SCO_MGMT_INCLUDED TRUE
+#endif
+
+/* CCAP compliant features and behavior desired */
+#ifndef CCAP_COMPLIANCE
+#define CCAP_COMPLIANCE TRUE
+#endif
+
+/* Caller ID string, part of +CLIP result code */
+#ifndef HFP_MAX_CLIP_INFO
+#define HFP_MAX_CLIP_INFO 45
+#endif
+
+#ifndef HFP_RPT_PEER_INFO_INCLUDED
+#define HFP_RPT_PEER_INFO_INCLUDED TRUE /* Reporting of peer features enabled */
+#endif
+
+/******************************************************************************
+**
+** HID
+**
+******************************************************************************/
+
+/* HID Device Role Included */
+#ifndef HID_DEV_INCLUDED
+#define HID_DEV_INCLUDED FALSE
+#endif
+
+#ifndef HID_DEV_PM_INCLUDED
+#define HID_DEV_PM_INCLUDED TRUE
+#endif
+
+/* The HID Device is a virtual cable */
+#ifndef HID_DEV_VIRTUAL_CABLE
+#define HID_DEV_VIRTUAL_CABLE TRUE
+#endif
+
+/* The HID device initiates the reconnections */
+#ifndef HID_DEV_RECONN_INITIATE
+#define HID_DEV_RECONN_INITIATE TRUE
+#endif
+
+/* THe HID device is normally connectable */
+#ifndef HID_DEV_NORMALLY_CONN
+#define HID_DEV_NORMALLY_CONN FALSE
+#endif
+
+/* The device is battery powered */
+#ifndef HID_DEV_BATTERY_POW
+#define HID_DEV_BATTERY_POW TRUE
+#endif
+
+/* Device is capable of waking up the host */
+#ifndef HID_DEV_REMOTE_WAKE
+#define HID_DEV_REMOTE_WAKE TRUE
+#endif
+
+/* Device needs host to close SDP channel after SDP is over */
+#ifndef HID_DEV_SDP_DISABLE
+#define HID_DEV_SDP_DISABLE TRUE
+#endif
+
+#ifndef HID_DEV_MTU_SIZE
+#define HID_DEV_MTU_SIZE 64
+#endif
+
+#ifndef HID_DEV_FLUSH_TO
+#define HID_DEV_FLUSH_TO 0xffff
+#endif
+
+#ifndef HID_DEV_PAGE_SCAN_WIN
+#define HID_DEV_PAGE_SCAN_WIN (0)
+#endif
+
+#ifndef HID_DEV_PAGE_SCAN_INT
+#define HID_DEV_PAGE_SCAN_INT (0)
+#endif
+
+#ifndef HID_DEV_MAX_CONN_RETRY
+#define HID_DEV_MAX_CONN_RETRY (15)
+#endif
+
+#ifndef HID_DEV_REPAGE_WIN
+#define HID_DEV_REPAGE_WIN (1)
+#endif
+
+#ifndef HID_DEV_SVC_NAME
+#define HID_DEV_SVC_NAME "HID"
+#endif
+
+#ifndef HID_DEV_SVC_DESCR
+#define HID_DEV_SVC_DESCR "3-button mouse and keyboard"
+#endif
+
+#ifndef HID_DEV_PROVIDER_NAME
+#define HID_DEV_PROVIDER_NAME "Widcomm"
+#endif
+
+#ifndef HID_DEV_REL_NUM
+#define HID_DEV_REL_NUM 0x0100
+#endif
+
+#ifndef HID_DEV_PARSER_VER
+#define HID_DEV_PARSER_VER 0x0111
+#endif
+
+#ifndef HID_DEV_SUBCLASS
+#define HID_DEV_SUBCLASS COD_MINOR_POINTING
+#endif
+
+#ifndef HID_DEV_COUNTRY_CODE
+#define HID_DEV_COUNTRY_CODE 0x33
+#endif
+
+#ifndef HID_DEV_SUP_TOUT
+#define HID_DEV_SUP_TOUT 0x8000
+#endif
+
+#ifndef HID_DEV_NUM_LANGS
+#define HID_DEV_NUM_LANGS 1
+#endif
+
+#ifndef HID_DEV_INACT_TIMEOUT
+#define HID_DEV_INACT_TIMEOUT 60
+#endif
+
+#ifndef HID_DEV_BUSY_MODE_PARAMS
+#define HID_DEV_BUSY_MODE_PARAMS { 320, 160, 10, 20, HCI_MODE_ACTIVE }
+#endif
+
+#ifndef HID_DEV_IDLE_MODE_PARAMS
+#define HID_DEV_IDLE_MODE_PARAMS { 320, 160, 10, 20, HCI_MODE_SNIFF }
+#endif
+
+#ifndef HID_DEV_SUSP_MODE_PARAMS
+#define HID_DEV_SUSP_MODE_PARAMS { 640, 320, 0, 0, HCI_MODE_PARK }
+#endif
+
+#ifndef HID_DEV_MAX_DESCRIPTOR_SIZE
+#define HID_DEV_MAX_DESCRIPTOR_SIZE 128 /* Max descriptor size */
+#endif
+
+#ifndef HID_DEV_LANGUAGELIST
+#define HID_DEV_LANGUAGELIST {0x35, 0x06, 0x09, 0x04, 0x09, 0x09, 0x01, 0x00}
+#endif
+
+#ifndef HID_DEV_LINK_SUPERVISION_TO
+#define HID_DEV_LINK_SUPERVISION_TO 0x8000
+#endif
+
+#ifndef HID_CONTROL_POOL_ID
+#define HID_CONTROL_POOL_ID 2
+#endif
+
+#ifndef HID_INTERRUPT_POOL_ID
+#define HID_INTERRUPT_POOL_ID 2
+#endif
+
+#ifndef UCD_HID_INCLUDED
+#define UCD_HID_INCLUDED FALSE
+#endif
+
+#ifndef BRR_HID_INCLUDED
+#define BRR_HID_INCLUDED FALSE
+#endif
+
+/*************************************************************************
+** Definitions for Both HID-Host & Device
+*/
+#ifndef HID_MAX_SVC_NAME_LEN
+#define HID_MAX_SVC_NAME_LEN 32
+#endif
+
+#ifndef HID_MAX_SVC_DESCR_LEN
+#define HID_MAX_SVC_DESCR_LEN 32
+#endif
+
+#ifndef HID_MAX_PROV_NAME_LEN
+#define HID_MAX_PROV_NAME_LEN 32
+#endif
+
+/*************************************************************************
+** Definitions for HID-Host
+*/
+#ifndef HID_HOST_INCLUDED
+#define HID_HOST_INCLUDED FALSE
+#endif
+
+#ifndef HID_HOST_MAX_DEVICES
+#define HID_HOST_MAX_DEVICES 7
+#endif
+
+#ifndef HID_HOST_MTU
+#define HID_HOST_MTU 640
+#endif
+
+#ifndef HID_HOST_FLUSH_TO
+#define HID_HOST_FLUSH_TO 0xffff
+#endif
+
+#ifndef HID_HOST_MAX_CONN_RETRY
+#define HID_HOST_MAX_CONN_RETRY (15)
+#endif
+
+#ifndef HID_HOST_REPAGE_WIN
+#define HID_HOST_REPAGE_WIN (2)
+#endif
+
+
+/******************************************************************************
+**
+** DUN and FAX
+**
+******************************************************************************/
+
+#ifndef DUN_INCLUDED
+#define DUN_INCLUDED FALSE
+#endif
+
+
+/******************************************************************************
+**
+** GOEP
+**
+******************************************************************************/
+
+#ifndef GOEP_INCLUDED
+#define GOEP_INCLUDED FALSE
+#endif
+
+/* This is set to enable GOEP non-blocking file system access functions. */
+#ifndef GOEP_FS_INCLUDED
+#define GOEP_FS_INCLUDED TRUE
+#endif
+
+/* GOEP authentication key size. */
+#ifndef GOEP_MAX_AUTH_KEY_SIZE
+#define GOEP_MAX_AUTH_KEY_SIZE 16
+#endif
+
+/* Maximum size of the realm authentication string. */
+#ifndef GOEP_MAX_AUTH_REALM_SIZE
+#define GOEP_MAX_AUTH_REALM_SIZE 16
+#endif
+
+/* Realm Character Set */
+#ifndef GOEP_REALM_CHARSET
+#define GOEP_REALM_CHARSET 0 /* ASCII */
+#endif
+
+/* This is set to the maximum length of path name allowed in the system (_MAX_PATH). */
+#ifndef GOEP_MAX_PATH_SIZE
+#define GOEP_MAX_PATH_SIZE 255
+#endif
+
+/* Specifies whether or not client's user id is required during obex authentication */
+#ifndef GOEP_SERVER_USERID_REQUIRED
+#define GOEP_SERVER_USERID_REQUIRED FALSE
+#endif
+
+/* This is set to the maximum length of file name allowed in the system (_MAX_FNAME). */
+#ifndef GOEP_MAX_FILE_SIZE
+#define GOEP_MAX_FILE_SIZE 128
+#endif
+
+/* Character used as path separator */
+#ifndef GOEP_PATH_SEPARATOR
+#define GOEP_PATH_SEPARATOR ((char) 0x5c) /* 0x2f ('/'), or 0x5c ('\') */
+#endif
+
+/******************************************************************************
+**
+** OPP
+**
+******************************************************************************/
+
+#ifndef OPP_INCLUDED
+#define OPP_INCLUDED FALSE
+#endif
+
+/* This is set to enable OPP client capabilities. */
+#ifndef OPP_CLIENT_INCLUDED
+#define OPP_CLIENT_INCLUDED FALSE
+#endif
+
+/* This is set to enable OPP server capabilities. */
+#ifndef OPP_SERVER_INCLUDED
+#define OPP_SERVER_INCLUDED FALSE
+#endif
+
+/* if the optional formating functions are to be included or not */
+#ifndef OPP_FORMAT_INCLUDED
+#define OPP_FORMAT_INCLUDED FALSE
+#endif
+
+/* Maximum number of client sessions allowed by server */
+#ifndef OPP_MAX_SRVR_SESS
+#define OPP_MAX_SRVR_SESS 3
+#endif
+
+/******************************************************************************
+**
+** FTP
+**
+******************************************************************************/
+
+#ifndef FTP_INCLUDED
+#define FTP_INCLUDED FALSE
+#endif
+
+/* This is set to enable FTP client capabilities. */
+#ifndef FTP_CLIENT_INCLUDED
+#define FTP_CLIENT_INCLUDED TRUE
+#endif
+
+/* This is set to enable FTP server capabilities. */
+#ifndef FTP_SERVER_INCLUDED
+#define FTP_SERVER_INCLUDED TRUE
+#endif
+
+/******************************************************************************
+**
+** XML Parser
+**
+******************************************************************************/
+
+#ifndef XML_STACK_SIZE
+#define XML_STACK_SIZE 7
+#endif
+
+/******************************************************************************
+**
+** BPP Printer
+**
+******************************************************************************/
+#ifndef BPP_DEBUG
+#define BPP_DEBUG FALSE
+#endif
+
+#ifndef BPP_INCLUDED
+#define BPP_INCLUDED FALSE
+#endif
+
+#ifndef BPP_SND_INCLUDED
+#define BPP_SND_INCLUDED FALSE
+#endif
+
+/* Maximum number of senders allowed to connect simultaneously
+** The maximum is 6 or (OBX_NUM_SERVERS / 2), whichever is smaller
+*/
+#ifndef BPP_PR_MAX_CON
+#define BPP_PR_MAX_CON 3
+#endif
+
+/* Service Name. maximum length: 248
+#ifndef BPP_SERVICE_NAME
+#define BPP_SERVICE_NAME "Basic Printing"
+#endif
+ */
+/* Document Format Supported. ASCII comma-delimited list of MIME type:version string
+#ifndef BPP_DOC_FORMAT_SUPPORTED
+#define BPP_DOC_FORMAT_SUPPORTED "application/vnd.pwg-xhtml-print:1.0,application/vnd.hp-PCL:5E,application/PDF"
+#endif
+
+#ifndef BPP_DOC_FORMAT_SUPPORTED_LEN
+#define BPP_DOC_FORMAT_SUPPORTED_LEN 77
+#endif
+ */
+/* Character repertoires.
+#ifndef BPP_CHARACTER_REPERTOIRES
+#define BPP_CHARACTER_REPERTOIRES {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}
+#endif
+ */
+/* XHTML formats.
+#ifndef BPP_XHTML_PRINT_FORMATS
+#define BPP_XHTML_PRINT_FORMATS "image/gif:89A,image/jpeg"
+#endif
+
+#ifndef BPP_XHTML_PRINT_FORMATS_LEN
+#define BPP_XHTML_PRINT_FORMATS_LEN 24
+#endif
+ */
+/* Color supported.
+#ifndef BPP_COLOR_SUPORTED
+#define BPP_COLOR_SUPORTED FALSE
+#endif
+ */
+/* 1284 ID string. First 2 bytes are the length.
+#ifndef BPP_1284ID
+#define BPP_1284ID "\x00\x48MANUFACTURER:ACME Manufacturing;COMMAND SET:PCL,MPL;MODEL:LaserBeam \?;"
+#endif
+
+#ifndef BPP_1284ID_LEN
+#define BPP_1284ID_LEN 72
+#endif
+ */
+/* Printer name.
+#ifndef BPP_PRINTER_NAME
+#define BPP_PRINTER_NAME "My Printer"
+#endif
+
+#ifndef BPP_PRINTER_NAME_LEN
+#define BPP_PRINTER_NAME_LEN 10
+#endif
+ */
+
+/* Printer location.
+#ifndef BPP_PRINTER_LOCATION
+#define BPP_PRINTER_LOCATION "Hotel Lobby"
+#endif
+
+#ifndef BPP_PRINTER_LOCATION_LEN
+#define BPP_PRINTER_LOCATION_LEN 11
+#endif
+ */
+/* Duplex printing supported.
+#ifndef BPP_DUPLEX_SUPPORTED
+#define BPP_DUPLEX_SUPPORTED TRUE
+#endif
+ */
+
+/* Media types supported.
+#ifndef BPP_MEDIA_TYPES_SUPPORTED
+#define BPP_MEDIA_TYPES_SUPPORTED "stationary,continuous-long,photographic-high-gloss,cardstock"
+#endif
+
+#ifndef BPP_MEDIA_TYPES_SUPPORTED_LEN
+#define BPP_MEDIA_TYPES_SUPPORTED_LEN 60
+#endif
+ */
+/* Maximum media with supported.
+#ifndef BPP_MAX_MEDIA_WIDTH
+#define BPP_MAX_MEDIA_WIDTH 205
+#endif
+ */
+/* Maximum media length supported.
+#ifndef BPP_MAX_MEDIA_LENGTH
+#define BPP_MAX_MEDIA_LENGTH 285
+#endif
+ */
+/* the maximum string len for the media size of medium loaded */
+#ifndef BPP_MEDIA_SIZE_LEN
+#define BPP_MEDIA_SIZE_LEN 33
+#endif
+
+/* Debug Trace the SOAP object, if TRUE */
+#ifndef BPP_TRACE_XML
+#define BPP_TRACE_XML TRUE
+#endif
+
+/* in case that the SOAP object does not all come in one OBEX packet,
+ * this size of data may be kept in the BPP control block for continuing parsing.
+ * The maximum is the size of the biggest GKI buffer (GKI_MAX_BUF_SIZE) */
+#ifndef BPP_SOAP_KEEP_SIZE
+#define BPP_SOAP_KEEP_SIZE 200
+#endif
+
+
+/******************************************************************************
+**
+** BIP
+**
+******************************************************************************/
+#ifndef BIP_INCLUDED
+#define BIP_INCLUDED FALSE
+#endif
+
+/* TRUE to include imaging initiator */
+#ifndef BIP_INITR_INCLUDED
+#define BIP_INITR_INCLUDED FALSE
+#endif
+
+/* TRUE to include imaging responder */
+#ifndef BIP_RSPDR_INCLUDED
+#define BIP_RSPDR_INCLUDED FALSE
+#endif
+
+/* TRUE to include image push feature */
+#ifndef BIP_PUSH_INCLUDED
+#define BIP_PUSH_INCLUDED TRUE
+#endif
+
+/* TRUE to include image pull feature */
+#ifndef BIP_PULL_INCLUDED
+#define BIP_PULL_INCLUDED TRUE
+#endif
+
+/* TRUE to include advanced image printing feature */
+#ifndef BIP_PRINTING_INCLUDED
+#define BIP_PRINTING_INCLUDED TRUE
+#endif
+
+/* TRUE to include automatic archive feature */
+#ifndef BIP_ARCHIVE_INCLUDED
+#define BIP_ARCHIVE_INCLUDED TRUE
+#endif
+
+/* TRUE to include remote camera feature */
+#ifndef BIP_CAMERA_INCLUDED
+#define BIP_CAMERA_INCLUDED TRUE
+#endif
+
+/* TRUE to include remote display feature */
+#ifndef BIP_DISPLAY_INCLUDED
+#define BIP_DISPLAY_INCLUDED TRUE
+#endif
+
+/* TRUE to include sanity check code for API functions */
+#ifndef BIP_SANITY_CHECKS
+#define BIP_SANITY_CHECKS TRUE
+#endif
+
+/* TRUE to show the received XML object in trace for conformance tests */
+#ifndef BIP_TRACE_XML
+#define BIP_TRACE_XML TRUE
+#endif
+
+/* in case that the received XML object is not complete, the XML parser state machine needs
+ * to keep a copy of the data from the last '<'
+ * This macro specifies the maximun amount of data for this purpose */
+#ifndef BIP_XML_CARRY_OVER_LEN
+#define BIP_XML_CARRY_OVER_LEN 100
+#endif
+
+/* minimum 4, maximum is 255. The value should be set to the maximum size of encoding string + 1. JPEG2000.
+ * If vendor specific format is supported, it might be bigger than 9 */
+#ifndef BIP_IMG_ENCODE_SIZE
+#define BIP_IMG_ENCODE_SIZE 9
+#endif
+
+/* MIME type: text/plain */
+#ifndef BIP_TYPE_SIZE
+#define BIP_TYPE_SIZE 20
+#endif
+
+/* example: iso-8895-1 */
+#ifndef BIP_CHARSET_SIZE
+#define BIP_CHARSET_SIZE 10
+#endif
+
+/* friendly name */
+#ifndef BIP_FNAME_SIZE
+#define BIP_FNAME_SIZE 20
+#endif
+
+/* service name */
+#ifndef BIP_SNAME_SIZE
+#define BIP_SNAME_SIZE 60
+#endif
+
+/* temporary storage file name(for file system access, may include path) */
+#ifndef BIP_TEMP_NAME_SIZE
+#define BIP_TEMP_NAME_SIZE 200
+#endif
+
+/* image file name */
+#ifndef BIP_IMG_NAME_SIZE
+#define BIP_IMG_NAME_SIZE 200
+#endif
+
+/* attachment file name */
+#ifndef BIP_ATT_NAME_SIZE
+#define BIP_ATT_NAME_SIZE 200
+#endif
+
+/* object (image, attachment, thumbnail) file name (may be used for file system) */
+#ifndef BIP_OBJ_NAME_SIZE
+#define BIP_OBJ_NAME_SIZE 200
+#endif
+
+
+
+/******************************************************************************
+**
+** HCRP
+**
+******************************************************************************/
+
+#ifndef HCRP_INCLUDED
+#define HCRP_INCLUDED FALSE
+#endif
+
+/* This is set to enable server. */
+#ifndef HCRP_SERVER_INCLUDED
+#define HCRP_SERVER_INCLUDED FALSE
+#endif
+
+/* This is set to enable client. */
+#ifndef HCRP_CLIENT_INCLUDED
+#define HCRP_CLIENT_INCLUDED FALSE
+#endif
+
+/* TRUE enables the notification option of the profile. */
+#ifndef HCRP_NOTIFICATION_INCLUDED
+#define HCRP_NOTIFICATION_INCLUDED TRUE
+#endif
+
+/* TRUE enables the vendor specific option of the profile. */
+#ifndef HCRP_VENDOR_SPEC_INCLUDED
+#define HCRP_VENDOR_SPEC_INCLUDED TRUE
+#endif
+
+/* TRUE enables state machine traces. */
+#ifndef HCRP_FSM_DEBUG
+#define HCRP_FSM_DEBUG FALSE
+#endif
+
+/* TRUE enables protocol message traces. */
+#ifndef HCRP_PROTO_DEBUG
+#define HCRP_PROTO_DEBUG FALSE
+#endif
+
+/* Maximum length used to store the service name (Minimum 1). */
+#ifndef HCRP_MAX_SERVICE_NAME_LEN
+#define HCRP_MAX_SERVICE_NAME_LEN 32
+#endif
+
+/* Maximum length used to store the device name (Minimum 1). */
+#ifndef HCRP_MAX_DEVICE_NAME_LEN
+#define HCRP_MAX_DEVICE_NAME_LEN 32
+#endif
+
+/* Maximum length of device location (Minimum 1) */
+#ifndef HCRP_MAX_DEVICE_LOC_LEN
+#define HCRP_MAX_DEVICE_LOC_LEN 32
+#endif
+
+/* Maximum length used to store the friendly name (Minimum 1). */
+#ifndef HCRP_MAX_FRIENDLY_NAME_LEN
+#define HCRP_MAX_FRIENDLY_NAME_LEN 32
+#endif
+
+/* Maximum length used to store the 1284 id string (Minimum 2 byte length field). */
+#ifndef HCRP_MAX_SDP_1284_ID_LEN
+#define HCRP_MAX_SDP_1284_ID_LEN 128
+#endif
+
+/* Maximum length for parameters to be processed for vendor specific commands. */
+#ifndef HCRP_MAX_VEND_SPEC_LEN
+#define HCRP_MAX_VEND_SPEC_LEN 4
+#endif
+
+/* Number of seconds to wait for 2nd GAP to open. */
+#ifndef HCRP_OPEN_CHAN_TOUT
+#define HCRP_OPEN_CHAN_TOUT 5
+#endif
+
+/* Number of seconds to wait for 2nd GAP to close. */
+#ifndef HCRP_CLOSE_CHAN_TOUT
+#define HCRP_CLOSE_CHAN_TOUT 3
+#endif
+
+/* Number of seconds to wait for the application to respond to a protocol request. */
+#ifndef HCRP_APPL_RSP_TOUT
+#define HCRP_APPL_RSP_TOUT 5
+#endif
+
+/* Number of seconds to wait for the peer device to respond to a protocol request. */
+#ifndef HCRP_CMD_RSP_TOUT
+#define HCRP_CMD_RSP_TOUT 7
+#endif
+
+/* Number of seconds between subsequent credit requests to the server when the send watermark has been exceeded. */
+#ifndef HCRP_CREDIT_REQ_UPDATES
+#define HCRP_CREDIT_REQ_UPDATES 1
+#endif
+
+/* Maximum number of results to return in a HCRP_FindServices search. */
+#ifndef HCRP_MAX_SEARCH_RESULTS
+#define HCRP_MAX_SEARCH_RESULTS 1
+#endif
+
+/* Maximum number of bytes to be reserved for searching for the client's notification record. */
+#ifndef HCRP_MAX_NOTIF_DISC_BUF
+#define HCRP_MAX_NOTIF_DISC_BUF 300
+#endif
+
+/* Maximum number of clients the server will allow to be registered for notifications. */
+#ifndef HCRP_MAX_NOTIF_CLIENTS
+#define HCRP_MAX_NOTIF_CLIENTS 3
+#endif
+
+/* Spec says minimum of two notification retries. */
+#ifndef HCRP_NOTIF_NUM_RETRIES
+#define HCRP_NOTIF_NUM_RETRIES 4
+#endif
+
+/*************************************************************************
+** Definitions for Multi-Client Server HCRP
+** Note: Many of the above HCRP definitions are also used
+** Maximum number of clients allowed to connect simultaneously
+** Must be less than ((GAP_MAX_CONNECTIONS - 1) / 2)
+*/
+#ifndef HCRPM_MAX_CLIENTS
+#define HCRPM_MAX_CLIENTS 3
+#endif
+
+
+/******************************************************************************
+**
+** PAN
+**
+******************************************************************************/
+
+#ifndef PAN_INCLUDED
+#define PAN_INCLUDED FALSE
+#endif
+
+
+/******************************************************************************
+**
+** SAP
+**
+******************************************************************************/
+
+#ifndef SAP_SERVER_INCLUDED
+#define SAP_SERVER_INCLUDED FALSE
+#endif
+
+
+/*************************************************************************
+ * A2DP Definitions
+ */
+#ifndef A2D_INCLUDED
+#define A2D_INCLUDED FALSE
+#endif
+
+/* TRUE to include SBC utility functions */
+#ifndef A2D_SBC_INCLUDED
+#define A2D_SBC_INCLUDED A2D_INCLUDED
+#endif
+
+/* TRUE to include MPEG-1,2 (mp3) utility functions */
+#ifndef A2D_M12_INCLUDED
+#define A2D_M12_INCLUDED A2D_INCLUDED
+#endif
+
+/* TRUE to include MPEG-2,4 (aac) utility functions */
+#ifndef A2D_M24_INCLUDED
+#define A2D_M24_INCLUDED A2D_INCLUDED
+#endif
+
+/*************************************************************************
+ * VDP Definitions
+ */
+#ifndef VDP_INCLUDED
+#define VDP_INCLUDED FALSE
+#endif
+
+/******************************************************************************
+**
+** AVCTP
+**
+******************************************************************************/
+
+#ifndef AVCT_INCLUDED
+#define AVCT_INCLUDED FALSE
+#endif
+
+/* Number of simultaneous ACL links to different peer devices. */
+#ifndef AVCT_NUM_LINKS
+#define AVCT_NUM_LINKS 2
+#endif
+
+/* Number of simultaneous AVCTP connections. */
+#ifndef AVCT_NUM_CONN
+#define AVCT_NUM_CONN 3
+#endif
+
+/* TRUE to support the browsing channel. */
+#ifndef AVCT_BROWSE_INCLUDED
+#define AVCT_BROWSE_INCLUDED TRUE
+#endif
+
+/* Pool ID where to reassemble the SDU.
+ This Pool allows buffers to be used that are larger than
+ the L2CAP_MAX_MTU. */
+#ifndef AVCT_BR_USER_RX_POOL_ID
+#define AVCT_BR_USER_RX_POOL_ID HCI_ACL_POOL_ID
+#endif
+
+/* Pool ID where to hold the SDU.
+ This Pool allows buffers to be used that are larger than
+ the L2CAP_MAX_MTU. */
+#ifndef AVCT_BR_USER_TX_POOL_ID
+#define AVCT_BR_USER_TX_POOL_ID HCI_ACL_POOL_ID
+#endif
+
+/*
+GKI Buffer Pool ID used to hold MPS segments during SDU reassembly
+*/
+#ifndef AVCT_BR_FCR_RX_POOL_ID
+#define AVCT_BR_FCR_RX_POOL_ID HCI_ACL_POOL_ID
+#endif
+
+/*
+GKI Buffer Pool ID used to hold MPS segments used in (re)transmissions.
+L2CAP_DEFAULT_ERM_POOL_ID is specified to use the HCI ACL data pool.
+Note: This pool needs to have enough buffers to hold two times the window size negotiated
+ in the tL2CAP_FCR_OPTIONS (2 * tx_win_size) to allow for retransmissions.
+ The size of each buffer must be able to hold the maximum MPS segment size passed in
+ tL2CAP_FCR_OPTIONS plus BT_HDR (8) + HCI preamble (4) + L2CAP_MIN_OFFSET (11 - as of BT 2.1 + EDR Spec).
+*/
+#ifndef AVCT_BR_FCR_TX_POOL_ID
+#define AVCT_BR_FCR_TX_POOL_ID HCI_ACL_POOL_ID
+#endif
+
+/* AVCTP Browsing channel FCR Option:
+Size of the transmission window when using enhanced retransmission mode. Not used
+in basic and streaming modes. Range: 1 - 63
+*/
+#ifndef AVCT_BR_FCR_OPT_TX_WINDOW_SIZE
+#define AVCT_BR_FCR_OPT_TX_WINDOW_SIZE 10
+#endif
+
+/* AVCTP Browsing channel FCR Option:
+Number of transmission attempts for a single I-Frame before taking
+Down the connection. Used In ERTM mode only. Value is Ignored in basic and
+Streaming modes.
+Range: 0, 1-0xFF
+0 - infinite retransmissions
+1 - single transmission
+*/
+#ifndef AVCT_BR_FCR_OPT_MAX_TX_B4_DISCNT
+#define AVCT_BR_FCR_OPT_MAX_TX_B4_DISCNT 20
+#endif
+
+/* AVCTP Browsing channel FCR Option: Retransmission Timeout
+The AVRCP specification set a value in the range of 300 - 2000 ms
+Timeout (in msecs) to detect Lost I-Frames. Only used in Enhanced retransmission mode.
+Range: Minimum 2000 (2 secs) when supporting PBF.
+ */
+#ifndef AVCT_BR_FCR_OPT_RETX_TOUT
+#define AVCT_BR_FCR_OPT_RETX_TOUT 2000
+#endif
+
+/* AVCTP Browsing channel FCR Option: Monitor Timeout
+The AVRCP specification set a value in the range of 300 - 2000 ms
+Timeout (in msecs) to detect Lost S-Frames. Only used in Enhanced retransmission mode.
+Range: Minimum 12000 (12 secs) when supporting PBF.
+*/
+#ifndef AVCT_BR_FCR_OPT_MONITOR_TOUT
+#define AVCT_BR_FCR_OPT_MONITOR_TOUT 12000
+#endif
+
+/******************************************************************************
+**
+** AVRCP
+**
+******************************************************************************/
+
+#ifndef AVRC_INCLUDED
+#define AVRC_INCLUDED FALSE
+#endif
+
+/* TRUE to support AVRCP 1.3 - Metadata. */
+#ifndef AVRC_METADATA_INCLUDED
+#define AVRC_METADATA_INCLUDED TRUE
+#endif
+
+/* TRUE to support AVRCP 1.4 - Advanced Control. */
+#ifndef AVRC_ADV_CTRL_INCLUDED
+#define AVRC_ADV_CTRL_INCLUDED TRUE
+#endif
+
+/******************************************************************************
+**
+** MCAP
+**
+******************************************************************************/
+#ifndef MCA_INCLUDED
+#define MCA_INCLUDED FALSE
+#endif
+
+/* TRUE to support Clock Synchronization OpCodes */
+#ifndef MCA_SYNC_INCLUDED
+#define MCA_SYNC_INCLUDED FALSE
+#endif
+
+/* The MTU size for the L2CAP configuration on control channel. 48 is the minimal */
+#ifndef MCA_CTRL_MTU
+#define MCA_CTRL_MTU 60
+#endif
+
+/* The maximum number of registered MCAP instances. */
+#ifndef MCA_NUM_REGS
+#define MCA_NUM_REGS 3
+#endif
+
+/* The maximum number of control channels (to difference devices) per registered MCAP instances. */
+#ifndef MCA_NUM_LINKS
+#define MCA_NUM_LINKS 3
+#endif
+
+/* The maximum number of MDEP (including HDP echo) per registered MCAP instances. */
+#ifndef MCA_NUM_DEPS
+#define MCA_NUM_DEPS 3
+#endif
+
+/* The maximum number of MDL link per control channel. */
+#ifndef MCA_NUM_MDLS
+#define MCA_NUM_MDLS 4
+#endif
+
+/* Pool ID where to reassemble the SDU. */
+#ifndef MCA_USER_RX_POOL_ID
+#define MCA_USER_RX_POOL_ID HCI_ACL_POOL_ID
+#endif
+
+/* Pool ID where to hold the SDU. */
+#ifndef MCA_USER_TX_POOL_ID
+#define MCA_USER_TX_POOL_ID HCI_ACL_POOL_ID
+#endif
+
+/*
+GKI Buffer Pool ID used to hold MPS segments during SDU reassembly
+*/
+#ifndef MCA_FCR_RX_POOL_ID
+#define MCA_FCR_RX_POOL_ID HCI_ACL_POOL_ID
+#endif
+
+/*
+GKI Buffer Pool ID used to hold MPS segments used in (re)transmissions.
+L2CAP_DEFAULT_ERM_POOL_ID is specified to use the HCI ACL data pool.
+Note: This pool needs to have enough buffers to hold two times the window size negotiated
+ in the tL2CAP_FCR_OPTIONS (2 * tx_win_size) to allow for retransmissions.
+ The size of each buffer must be able to hold the maximum MPS segment size passed in
+ tL2CAP_FCR_OPTIONS plus BT_HDR (8) + HCI preamble (4) + L2CAP_MIN_OFFSET (11 - as of BT 2.1 + EDR Spec).
+*/
+#ifndef MCA_FCR_TX_POOL_ID
+#define MCA_FCR_TX_POOL_ID HCI_ACL_POOL_ID
+#endif
+
+/* MCAP control channel FCR Option:
+Size of the transmission window when using enhanced retransmission mode.
+1 is defined by HDP specification for control channel.
+*/
+#ifndef MCA_FCR_OPT_TX_WINDOW_SIZE
+#define MCA_FCR_OPT_TX_WINDOW_SIZE 1
+#endif
+
+/* MCAP control channel FCR Option:
+Number of transmission attempts for a single I-Frame before taking
+Down the connection. Used In ERTM mode only. Value is Ignored in basic and
+Streaming modes.
+Range: 0, 1-0xFF
+0 - infinite retransmissions
+1 - single transmission
+*/
+#ifndef MCA_FCR_OPT_MAX_TX_B4_DISCNT
+#define MCA_FCR_OPT_MAX_TX_B4_DISCNT 20
+#endif
+
+/* MCAP control channel FCR Option: Retransmission Timeout
+The AVRCP specification set a value in the range of 300 - 2000 ms
+Timeout (in msecs) to detect Lost I-Frames. Only used in Enhanced retransmission mode.
+Range: Minimum 2000 (2 secs) when supporting PBF.
+ */
+#ifndef MCA_FCR_OPT_RETX_TOUT
+#define MCA_FCR_OPT_RETX_TOUT 2000
+#endif
+
+/* MCAP control channel FCR Option: Monitor Timeout
+The AVRCP specification set a value in the range of 300 - 2000 ms
+Timeout (in msecs) to detect Lost S-Frames. Only used in Enhanced retransmission mode.
+Range: Minimum 12000 (12 secs) when supporting PBF.
+*/
+#ifndef MCA_FCR_OPT_MONITOR_TOUT
+#define MCA_FCR_OPT_MONITOR_TOUT 12000
+#endif
+
+/* MCAP control channel FCR Option: Maximum PDU payload size.
+The maximum number of payload octets that the local device can receive in a single PDU.
+*/
+#ifndef MCA_FCR_OPT_MPS_SIZE
+#define MCA_FCR_OPT_MPS_SIZE 1000
+#endif
+
+/* Shared transport */
+#ifndef NFC_SHARED_TRANSPORT_ENABLED
+#define NFC_SHARED_TRANSPORT_ENABLED FALSE
+#endif
+
+/******************************************************************************
+**
+** SER
+**
+******************************************************************************/
+
+#ifndef SER_INCLUDED
+#define SER_INCLUDED FALSE
+#endif
+
+/* Task which runs the serial application. */
+#ifndef SER_TASK
+#define SER_TASK BTE_APPL_TASK
+#endif
+
+/* Mailbox used by serial application. */
+#ifndef SER_MBOX
+#define SER_MBOX TASK_MBOX_1
+#endif
+
+/* Mailbox mask. */
+#ifndef SER_MBOX_MASK
+#define SER_MBOX_MASK TASK_MBOX_1_EVT_MASK
+#endif
+
+/* TX path application event. */
+#ifndef SER_TX_PATH_APPL_EVT
+#define SER_TX_PATH_APPL_EVT EVENT_MASK(APPL_EVT_3)
+#endif
+
+/* RX path application event. */
+#ifndef SER_RX_PATH_APPL_EVT
+#define SER_RX_PATH_APPL_EVT EVENT_MASK(APPL_EVT_4)
+#endif
+
+/******************************************************************************
+**
+** HCI Services
+**
+******************************************************************************/
+/* Event mask reserved for handling HCIS events HCISU_TASK */
+#ifndef HCISU_EVT_MASK
+#define HCISU_EVT_MASK EVENT_MASK(APPL_EVT_0)
+#endif
+
+/* MBox reserved for handling HCIS events HCISU_TASK */
+#ifndef HCISU_MBOX
+#define HCISU_MBOX TASK_MBOX_2
+#endif
+
+/* MBox event mask reserved for handling HCIS events HCISU_TASK */
+#ifndef HCISU_MBOX_EVT_MASK
+#define HCISU_MBOX_EVT_MASK TASK_MBOX_2_EVT_MASK
+#endif
+
+/* Timer reserved for handling HCIS events HCISU_TASK */
+#ifndef HCISU_TIMER
+#define HCISU_TIMER TIMER_2
+#endif
+
+/* Timer event mask reserved for handling HCIS events HCISU_TASK */
+#ifndef HCISU_TIMER_EVT_MASK
+#define HCISU_TIMER_EVT_MASK TIMER_2_EVT_MASK
+#endif
+
+/******************************************************************************
+**
+** HCI UART
+**
+******************************************************************************/
+#ifndef BAUDRATE_UPDATE_ENCODED_INCLUDED
+#define BAUDRATE_UPDATE_ENCODED_INCLUDED FALSE
+#endif
+
+/******************************************************************************
+**
+** HCI Services (H5 3 wired uart), H4 plus SLIP enabled
+**
+******************************************************************************/
+#ifndef SLIP_INCLUDED
+#define SLIP_INCLUDED TRUE
+#endif
+
+#ifndef SLIP_STATIS_INCLUDED
+#define SLIP_STATIS_INCLUDED TRUE
+#endif
+
+#ifndef SLIP_SW_FLOW_CTRL
+#define SLIP_SW_FLOW_CTRL TRUE
+#endif
+
+#ifndef BT_TRACE_SLIP
+#define BT_TRACE_SLIP FALSE
+#endif
+
+#ifndef SLIP_HOST_SLIDING_WINDOW_SIZE
+#define SLIP_HOST_SLIDING_WINDOW_SIZE 7
+#endif
+
+#ifndef SLIP_MAX_RETRANSMIT
+#define SLIP_MAX_RETRANSMIT 10
+#endif
+
+/* time (in ms) interval between WAKEUP messages */
+#ifndef SLIP_WAKEUP_INTERVAL
+#define SLIP_WAKEUP_INTERVAL 10
+#endif
+
+/* max trial to send WAKEUP messages up to 255 */
+#ifndef SLIP_MAX_WAKEUP_TRIAL
+#define SLIP_MAX_WAKEUP_TRIAL 10
+#endif
+
+/*
+The H5 work around sequence will be:
+
+1. controller sends CONFIG with configuration field. (This is not spec compliance.
+ Controller shall not have configuration field. This initiates work around.)
+2. host ignore the configuration field.
+3. Host sends CONFIG with configuration field.
+4. controller reponse CONFIG_RESPONSE with configuration field. This shall be the
+ final configuration both FW and STACK use. (spec compliance).
+5. Host copied the configuration field over and sent CONFIG_RESPONSE with this
+ configuration field (workaround)
+*/
+
+#ifndef SLIP_CONFIG_FIELD_WORK_AROUND_INCLUDED
+#define SLIP_CONFIG_FIELD_WORK_AROUND_INCLUDED TRUE
+#endif
+
+/******************************************************************************
+**
+** Sleep Mode (Low Power Mode)
+**
+******************************************************************************/
+#ifndef HCILP_INCLUDED
+#define HCILP_INCLUDED TRUE
+#endif
+
+/* sleep mode
+
+ 0: disable
+ 1: UART with Host wake/BT wake out of band signals
+ 4: H4IBSS, UART with in band signal without Host/BT wake
+ 9: H5 with in band signal of SLIP without Host/BT wake
+*/
+#ifndef HCILP_SLEEP_MODE
+#define HCILP_SLEEP_MODE (0)
+#endif
+
+/* Host Stack Idle Threshold in 300ms or 25ms, it depends on controller
+
+ In sleep mode 1, this is the number of firmware loops executed with no activity
+ before the Host wake line is deasserted. Activity includes HCI traffic excluding
+ certain sleep mode commands and the presence of SCO connections if the
+ "Allow Host Sleep During SCO" flag is not set to 1. Each count of this
+ parameter is roughly equivalent to 300ms or 25ms.
+
+ Not applicable for sleep mode 4(H4IBSS) and 9(H5)
+*/
+#ifndef HCILP_IDLE_THRESHOLD
+#define HCILP_IDLE_THRESHOLD (1)
+#endif
+
+/* Host Controller Idle Threshold in 300ms or 25ms, it depends on controller
+
+ This is the number of firmware loops executed with no activity before the HC is
+ considered idle. Depending on the mode, HC may then attempt to sleep.
+ Activity includes HCI traffic excluding certain sleep mode commands and
+ the presence of ACL/SCO connections.
+
+ Not applicable for sleep mode 4(H4IBSS)
+*/
+#ifndef HCILP_HC_IDLE_THRESHOLD
+#define HCILP_HC_IDLE_THRESHOLD (1)
+#endif
+
+/* GPIO for BT_WAKE signal */
+/* Not applicable for sleep mode 4(H4IBSS) and 9(H5) */
+#ifndef HCILP_BT_WAKE_GPIO
+#define HCILP_BT_WAKE_GPIO UPIO_GENERAL1
+#endif
+
+/* GPIO for HOST_WAKE signal */
+/* Not applicable for sleep mode 4(H4IBSS) and 9(H5) */
+#ifndef HCILP_HOST_WAKE_GPIO
+#define HCILP_HOST_WAKE_GPIO UPIO_GENERAL2
+#endif
+
+/* BT_WAKE Polarity - 0=Active Low, 1= Active High */
+/* Not applicable for sleep mode 4(H4IBSS) and 9(H5) */
+#ifndef HCILP_BT_WAKE_POLARITY
+#define HCILP_BT_WAKE_POLARITY 0
+#endif
+
+/* HOST_WAKE Polarity - 0=Active Low, 1= Active High */
+/* Not applicable for sleep mode 4(H4IBSS) and 9(H5) */
+#ifndef HCILP_HOST_WAKE_POLARITY
+#define HCILP_HOST_WAKE_POLARITY 0
+#endif
+
+/* HCILP_ALLOW_HOST_SLEEP_DURING_SCO
+
+ When this flag is set to 0, the host is not allowed to sleep while
+ an SCO is active. In sleep mode 1, the device will keep the host
+ wake line asserted while an SCO is active.
+ When this flag is set to 1, the host can sleep while an SCO is active.
+ This flag should only be set to 1 if SCO traffic is directed to the PCM interface.
+
+ Not applicable for sleep mode 4(H4IBSS) and 9(H5)
+*/
+#ifndef HCILP_ALLOW_HOST_SLEEP_DURING_SCO
+#define HCILP_ALLOW_HOST_SLEEP_DURING_SCO 1
+#endif
+
+/* HCILP_COMBINE_SLEEP_MODE_AND_LPM
+
+ In Mode 0, always set byte 7 to 0. In sleep mode 1, device always
+ requires permission to sleep between scans / periodic inquiries regardless
+ of the setting of this byte. In sleep mode 1, if byte is set, device must
+ have "permission" to sleep during the low power modes of sniff, hold, and park.
+ If byte is not set, device can sleep without permission during these modes.
+ Permission to sleep in Mode 1 is obtained if the BT_WAKE signal is not asserted.
+
+ Not applicable for sleep mode 4(H4IBSS) and 9(H5)
+*/
+#ifndef HCILP_COMBINE_SLEEP_MODE_AND_LPM
+#define HCILP_COMBINE_SLEEP_MODE_AND_LPM 1
+#endif
+
+/* HCILP_ENABLE_UART_TXD_TRI_STATE
+
+ When set to 0, the device will not tristate its UART TX line before going to sleep.
+ When set to 1, the device will tristate its UART TX line before going to sleep.
+
+ Not applicable for sleep mode 4(H4IBSS) and 9(H5)
+*/
+#ifndef HCILP_ENABLE_UART_TXD_TRI_STATE
+#define HCILP_ENABLE_UART_TXD_TRI_STATE 0
+#endif
+
+/* HCILP_PULSED_HOST_WAKE
+
+ Not applicable for sleep mode 4(H4IBSS) and 9(H5)
+*/
+#ifndef HCILP_PULSED_HOST_WAKE
+#define HCILP_PULSED_HOST_WAKE 0
+#endif
+
+/* HCILP_SLEEP_GUARD_TIME
+
+ Only for sleep mode 4(H4IBSS)
+ Time in 12.5ms between starting to monitor controller's CTS and raising its RTS
+*/
+#ifndef HCILP_SLEEP_GUARD_TIME
+#define HCILP_SLEEP_GUARD_TIME 5
+#endif
+
+/* HCILP_WAKEUP_GUARD_TIME
+
+ Only for sleep mode 4(H4IBSS)
+ Time in 12.5ms between starting to monitor controller's CTS and lowering its RTS
+*/
+#ifndef HCILP_WAKEUP_GUARD_TIME
+#define HCILP_WAKEUP_GUARD_TIME 5
+#endif
+
+/* HCILP_TXD_CONFIG
+
+ Only for sleep mode 4(H4IBSS)
+ 0: controller's TXD stays low in sleep mode
+ 1: controller's TXD stays high in sleep mode (default)
+*/
+#ifndef HCILP_TXD_CONFIG
+#define HCILP_TXD_CONFIG 1
+#endif
+
+/* HCILP_BT_WAKE_IDLE_TIMEOUT
+
+ host's idle time in ms before initiating sleep procedure
+*/
+#ifndef HCILP_BT_WAKE_IDLE_TIMEOUT
+#define HCILP_BT_WAKE_IDLE_TIMEOUT 50
+#endif
+
+#ifndef H4IBSS_INCLUDED
+#define H4IBSS_INCLUDED FALSE /* !!!! Android must use FALSE */
+#endif
+
+/* display H4IBSS state and event in text */
+#ifndef H4IBSS_DEBUG
+#define H4IBSS_DEBUG TRUE
+#endif
+
+/* time interval before going into sleep after having sent or received SLEEP_REQ_ACK */
+/* Valid range is 20 - 50 ms */
+#ifndef H4IBSS_SLEEP_GUARD_TIME
+#define H4IBSS_SLEEP_GUARD_TIME (40)
+#endif
+
+/* timeout(msec) to wait for response of sleep request */
+#ifndef H4IBSS_SLEEP_REQ_RESP_TIME
+#define H4IBSS_SLEEP_REQ_RESP_TIME (50)
+#endif
+
+/******************************************************************************
+**
+** RPC
+**
+******************************************************************************/
+
+#ifndef RPC_INCLUDED
+#define RPC_INCLUDED FALSE
+#endif
+
+/* RPCT task mailbox ID for messages coming from rpcgen code. */
+#ifndef RPCT_MBOX
+#define RPCT_MBOX TASK_MBOX_0
+#endif
+
+/* RPCT task event for mailbox. */
+#ifndef RPCT_RPC_MBOX_EVT
+#define RPCT_RPC_MBOX_EVT TASK_MBOX_0_EVT_MASK
+#endif
+
+/* RPCT task event from driver indicating RX data is ready. */
+#ifndef RPCT_RX_READY_EVT
+#define RPCT_RX_READY_EVT APPL_EVT_0
+#endif
+
+/* RPCT task event from driver indicating data TX is done. */
+#ifndef RPCT_TX_DONE_EVT
+#define RPCT_TX_DONE_EVT APPL_EVT_1
+#endif
+
+/* RPCT task event indicating data is in the circular buffer. */
+#ifndef RPCT_UCBUF_EVT
+#define RPCT_UCBUF_EVT APPL_EVT_2
+#endif
+
+/* Task ID of RPCGEN task. */
+#ifndef RPCGEN_TASK
+#define RPCGEN_TASK BTU_TASK
+#endif
+
+/* RPCGEN task event for messages coming from RPCT. */
+#ifndef RPCGEN_MSG_EVT
+#define RPCGEN_MSG_EVT TASK_MBOX_1_EVT_MASK
+#endif
+
+#ifndef RPCGEN_MSG_MBOX
+#define RPCGEN_MSG_MBOX TASK_MBOX_1
+#endif
+
+/* Size of circular buffer used to store diagnostic messages. */
+#ifndef RPCT_UCBUF_SIZE
+#define RPCT_UCBUF_SIZE 2000
+#endif
+
+/******************************************************************************
+**
+** SAP - Sample ICP and HSP applications
+**
+******************************************************************************/
+
+#ifndef SAP_INCLUDED
+#define SAP_INCLUDED FALSE
+#endif
+
+#ifndef ICA_INCLUDED
+#define ICA_INCLUDED FALSE
+#endif
+
+#ifndef HSA_HS_INCLUDED
+#define HSA_HS_INCLUDED FALSE
+#endif
+
+#ifndef HSA_AG_INCLUDED
+#define HSA_AG_INCLUDED FALSE
+#endif
+
+#ifndef MMI_INCLUDED
+#define MMI_INCLUDED FALSE
+#endif
+
+/* MMI task event from driver indicating RX data is ready. */
+#ifndef MMI_RX_READY_EVT
+#define MMI_RX_READY_EVT APPL_EVT_0
+#endif
+
+/******************************************************************************
+**
+** APPL - Application Task
+**
+******************************************************************************/
+/* When TRUE indicates that an application task is to be run */
+#ifndef APPL_INCLUDED
+#define APPL_INCLUDED FALSE
+#endif
+
+/* When TRUE remote terminal code included (RPC MUST be included) */
+#ifndef RSI_INCLUDED
+#define RSI_INCLUDED FALSE
+#endif
+
+
+
+#define L2CAP_FEATURE_REQ_ID 73
+#define L2CAP_FEATURE_RSP_ID 173
+
+
+#define L2CAP_ENHANCED_FEATURES 0
+
+
+
+/* Use gki_delay for patch ram */
+#ifndef BRCM_USE_DELAY
+#if ( SLIP_INCLUDED == TRUE )
+/* H5 need to be initialized after sending download mini driver HCI command */
+#define BRCM_USE_DELAY FALSE
+#else
+#define BRCM_USE_DELAY TRUE
+#endif
+#endif
+
+/******************************************************************************
+**
+** BTA
+**
+******************************************************************************/
+/* BTA EIR canned UUID list (default is dynamic) */
+#ifndef BTA_EIR_CANNED_UUID_LIST
+#define BTA_EIR_CANNED_UUID_LIST FALSE
+#endif
+
+/* Number of supported customer UUID in EIR */
+#ifndef BTA_EIR_SERVER_NUM_CUSTOM_UUID
+#define BTA_EIR_SERVER_NUM_CUSTOM_UUID 8
+#endif
+
+/* MIP A2DP Feature enabled */
+#ifndef BTA_MIP_INCLUDED
+#define BTA_MIP_INCLUDED FALSE
+#endif
+
+/* No 3D sync profile debug by default */
+#ifndef BTA_3DS_DEBUG
+#define BTA_3DS_DEBUG FALSE
+#endif
+/******************************************************************************
+**
+** BTE
+**
+******************************************************************************/
+#ifndef BTE_PLATFORM_IDLE
+#define BTE_PLATFORM_IDLE
+#endif
+
+#ifndef BTE_IDLE_TASK_INCLUDED
+#define BTE_IDLE_TASK_INCLUDED TRUE
+#endif
+
+#ifndef BTE_PLATFORM_INITHW
+#define BTE_PLATFORM_INITHW
+#endif
+
+#ifndef BTE_BTA_CODE_INCLUDED
+#define BTE_BTA_CODE_INCLUDED FALSE
+#endif
+
+
+/******************************************************************************
+**
+** BTTRC
+**
+******************************************************************************/
+/* Whether to parse and display traces-> Platform specific implementation */
+#ifndef BTTRC_DISP
+#define BTTRC_DISP BTTRC_DispOnInsight
+#endif
+
+/******************************************************************************
+**
+** Tracing: Include trace header file here.
+**
+******************************************************************************/
+
+#include "bt_trace.h"
+
+#endif /* BT_TARGET_H */
diff --git a/src/include/bt_trace.h b/src/include/bt_trace.h
new file mode 100644
index 0000000..1584983
--- /dev/null
+++ b/src/include/bt_trace.h
@@ -0,0 +1,4835 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef BT_TRACE_H
+#define BT_TRACE_H
+
+#ifndef BTTRC_INCLUDED
+#define BTTRC_INCLUDED FALSE
+#endif
+#ifndef BTTRC_PARSER_INCLUDED
+#define BTTRC_PARSER_INCLUDED FALSE
+#endif
+#ifndef MAX_TRACE_RAM_SIZE
+#define MAX_TRACE_RAM_SIZE 10000
+#endif
+
+/* BTE tracing IDs for debug purposes */
+/* LayerIDs for stack */
+#define BTTRC_ID_STK_GKI 1
+#define BTTRC_ID_STK_BTU 2
+#define BTTRC_ID_STK_HCI 3
+#define BTTRC_ID_STK_L2CAP 4
+#define BTTRC_ID_STK_RFCM_MX 5
+#define BTTRC_ID_STK_RFCM_PRT 6
+#define BTTRC_ID_STK_OBEX_C 7
+#define BTTRC_ID_STK_OBEX_S 8
+#define BTTRC_ID_STK_AVCT 9
+#define BTTRC_ID_STK_AVDT 10
+#define BTTRC_ID_STK_AVRC 11
+#define BTTRC_ID_STK_BIC 12
+#define BTTRC_ID_STK_BIS 13
+#define BTTRC_ID_STK_BNEP 14
+#define BTTRC_ID_STK_BPP 15
+#define BTTRC_ID_STK_BTM_ACL 16
+#define BTTRC_ID_STK_BTM_PM 17
+#define BTTRC_ID_STK_BTM_DEV_CTRL 18
+#define BTTRC_ID_STK_BTM_SVC_DSC 19
+#define BTTRC_ID_STK_BTM_INQ 20
+#define BTTRC_ID_STK_BTM_SCO 21
+#define BTTRC_ID_STK_BTM_SEC 22
+#define BTTRC_ID_STK_DUN 23
+#define BTTRC_ID_STK_HID 24
+#define BTTRC_ID_STK_HSP2 25
+#define BTTRC_ID_STK_CTP 26
+#define BTTRC_ID_STK_FTC 27
+#define BTTRC_ID_STK_FTS 28
+#define BTTRC_ID_STK_GAP 29
+#define BTTRC_ID_STK_GOEP 30
+#define BTTRC_ID_STK_HCRP 31
+#define BTTRC_ID_STK_ICP 32
+#define BTTRC_ID_STK_OPC 33
+#define BTTRC_ID_STK_OPS 34
+#define BTTRC_ID_STK_PAN 35
+#define BTTRC_ID_STK_SAP 36
+#define BTTRC_ID_STK_SDP 37
+#define BTTRC_ID_STK_SLIP 38
+#define BTTRC_ID_STK_SPP 39
+#define BTTRC_ID_STK_TCS 40
+#define BTTRC_ID_STK_VDP 41
+#define BTTRC_ID_STK_AMP 42
+#define BTTRC_ID_STK_MCAP 43
+#define BTTRC_ID_STK_GATT 44
+#define BTTRC_ID_STK_SMP 45
+#define BTTRC_ID_STK_NFC 46
+#define BTTRC_ID_STK_NCI 47
+#define BTTRC_ID_STK_IDEP 48
+#define BTTRC_ID_STK_NDEP 49
+#define BTTRC_ID_STK_LLCP 50
+#define BTTRC_ID_STK_RW 51
+#define BTTRC_ID_STK_CE 52
+#define BTTRC_ID_STK_SNEP 53
+#define BTTRC_ID_STK_NDEF 54
+
+
+/* LayerIDs for BTA */
+#define BTTRC_ID_BTA_ACC 55 /* Advanced Camera Client */
+#define BTTRC_ID_BTA_AG 56 /* audio gateway */
+#define BTTRC_ID_BTA_AV 57 /* Advanced audio */
+#define BTTRC_ID_BTA_BIC 58 /* Basic Imaging Client */
+#define BTTRC_ID_BTA_BIS 59 /* Basic Imaging Server */
+#define BTTRC_ID_BTA_BP 60 /* Basic Printing Client */
+#define BTTRC_ID_BTA_CG 61
+#define BTTRC_ID_BTA_CT 62 /* cordless telephony terminal */
+#define BTTRC_ID_BTA_DG 63 /* data gateway */
+#define BTTRC_ID_BTA_DM 64 /* device manager */
+#define BTTRC_ID_BTA_DM_SRCH 65 /* device manager search */
+#define BTTRC_ID_BTA_DM_SEC 66 /* device manager security */
+#define BTTRC_ID_BTA_FM 67
+#define BTTRC_ID_BTA_FTC 68 /* file transfer client */
+#define BTTRC_ID_BTA_FTS 69 /* file transfer server */
+#define BTTRC_ID_BTA_HIDH 70
+#define BTTRC_ID_BTA_HIDD 71
+#define BTTRC_ID_BTA_JV 72
+#define BTTRC_ID_BTA_OPC 73 /* object push client */
+#define BTTRC_ID_BTA_OPS 74 /* object push server */
+#define BTTRC_ID_BTA_PAN 75 /* Personal Area Networking */
+#define BTTRC_ID_BTA_PR 76 /* Printer client */
+#define BTTRC_ID_BTA_SC 77 /* SIM Card Access server */
+#define BTTRC_ID_BTA_SS 78 /* synchronization server */
+#define BTTRC_ID_BTA_SYS 79 /* system manager */
+#define BTTRC_ID_AVDT_SCB 80 /* avdt scb */
+#define BTTRC_ID_AVDT_CCB 81 /* avdt ccb */
+
+/* LayerIDs for BT APP */
+#define BTTRC_ID_BTAPP 82
+#define BTTRC_ID_MAX_ID BTTRC_ID_BTAPP
+#define BTTRC_ID_ALL_LAYERS 0xFF /* all trace layers */
+typedef UINT8 tBTTRC_LAYER_ID;
+
+/* Trace type definitions. Note that these are mutually exclusive in a trace. This
+means that any trace can be either error,warning,api,event or dbg */
+#if (BTU_STACK_LITE_ENABLED == TRUE)
+#define BTTRC_TYPE_ERROR 0x81
+#define BTTRC_TYPE_WARNING 0x82
+#define BTTRC_TYPE_API 0x84
+#define BTTRC_TYPE_EVENT 0x88
+#define BTTRC_TYPE_ACTION 0x90
+#define BTTRC_TYPE_DBG 0xA0
+#else
+#define BTTRC_TYPE_ERROR 0x01 /* Traces for error situation */
+#define BTTRC_TYPE_WARNING 0x02 /* Traces for warning situation */
+#define BTTRC_TYPE_API 0x04 /* Traces for API */
+#define BTTRC_TYPE_EVENT 0x08 /* Traces for EVENT */
+#define BTTRC_TYPE_ACTION 0x10 /* Traces for Action functions */
+#define BTTRC_TYPE_DBG 0x20 /* Traces for debugging purpose */
+#endif
+typedef UINT8 tBTTRC_TYPE;
+
+/* Masks to identify the stack that originated the trace */
+#define BTTRC_TRACE_LITE 0x80 /* MM Lite stack */
+#define BTTRC_TRACE_EMBD 0x40 /* Embedded host stack */
+
+/* Parameter datatypes used in Trace APIs */
+#define BTTRC_PARAM_UINT8 1
+#define BTTRC_PARAM_UINT16 2
+#define BTTRC_PARAM_UINT32 3
+typedef UINT8 tBTTRC_PARAM_TYPE;
+
+/* Special token definitions */
+#define BTTRC_TOKEN_SM_STATE 0xFFFF /* Token indicating the State of a State m/c */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* External declaration for appl_trace_level here to avoid to add the declaration in all the files using APPL_TRACExxx macros */
+extern UINT8 appl_trace_level ;
+
+/* Prototype for message logging function. */
+EXPORT_API extern void LogMsg (UINT32 trace_set_mask, const char *fmt_str, ...);
+extern void LogMsg_0 (UINT32 trace_set_mask, const char *p_str);
+extern void LogMsg_1 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1);
+extern void LogMsg_2 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2);
+extern void LogMsg_3 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2,
+ UINT32 p3);
+extern void LogMsg_4 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2,
+ UINT32 p3, UINT32 p4);
+extern void LogMsg_5 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2,
+ UINT32 p3, UINT32 p4, UINT32 p5);
+extern void LogMsg_6 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2,
+ UINT32 p3, UINT32 p4, UINT32 p5, UINT32 p6);
+
+/* Prototype for stack tracing function. */
+EXPORT_API extern void BTTRC_StackTrace0(tBTTRC_LAYER_ID layer_id,
+ tBTTRC_TYPE type,
+ UINT16 token);
+EXPORT_API extern void BTTRC_StackTrace1(tBTTRC_LAYER_ID layer_id,
+ tBTTRC_TYPE type,
+ UINT16 token,
+ tBTTRC_PARAM_TYPE p1_type, UINT32 p1_val);
+EXPORT_API extern void BTTRC_StackTrace2(tBTTRC_LAYER_ID layer_id,
+ tBTTRC_TYPE type,
+ UINT16 token,
+ tBTTRC_PARAM_TYPE p1_type, UINT32 p1_val,
+ tBTTRC_PARAM_TYPE p2_type, UINT32 p2_val);
+EXPORT_API extern void BTTRC_StackTrace3(tBTTRC_LAYER_ID layer_id,
+ tBTTRC_TYPE type,
+ UINT16 token,
+ tBTTRC_PARAM_TYPE p1_type, UINT32 p1_val,
+ tBTTRC_PARAM_TYPE p2_type, UINT32 p2_val,
+ tBTTRC_PARAM_TYPE p3_type, UINT32 p3_val);
+EXPORT_API extern void BTTRC_StackTrace4(tBTTRC_LAYER_ID layer_id,
+ tBTTRC_TYPE type,
+ UINT16 token,
+ tBTTRC_PARAM_TYPE p1_type, UINT32 p1_val,
+ tBTTRC_PARAM_TYPE p2_type, UINT32 p2_val,
+ tBTTRC_PARAM_TYPE p3_type, UINT32 p3_val,
+ tBTTRC_PARAM_TYPE p4_type, UINT32 p4_val);
+EXPORT_API extern void BTTRC_StackTrace5(tBTTRC_LAYER_ID layer_id,
+ tBTTRC_TYPE type,
+ UINT16 token,
+ tBTTRC_PARAM_TYPE p1_type, UINT32 p1_val,
+ tBTTRC_PARAM_TYPE p2_type, UINT32 p2_val,
+ tBTTRC_PARAM_TYPE p3_type, UINT32 p3_val,
+ tBTTRC_PARAM_TYPE p4_type, UINT32 p4_val,
+ tBTTRC_PARAM_TYPE p5_type, UINT32 p5_val);
+EXPORT_API extern void BTTRC_StackTrace6(tBTTRC_LAYER_ID layer_id,
+ tBTTRC_TYPE type,
+ UINT16 token,
+ tBTTRC_PARAM_TYPE p1_type, UINT32 p1_val,
+ tBTTRC_PARAM_TYPE p2_type, UINT32 p2_val,
+ tBTTRC_PARAM_TYPE p3_type, UINT32 p3_val,
+ tBTTRC_PARAM_TYPE p4_type, UINT32 p4_val,
+ tBTTRC_PARAM_TYPE p5_type, UINT32 p5_val,
+ tBTTRC_PARAM_TYPE p6_type, UINT32 p6_val);
+
+#ifdef __cplusplus
+}
+#endif
+
+/******************************************************************************
+**
+** Trace configurable parameters
+**
+******************************************************************************/
+
+/* Enables or disables verbose trace information. */
+#ifndef BT_TRACE_VERBOSE
+#define BT_TRACE_VERBOSE FALSE
+#endif
+
+/* Enables or disables all trace messages. */
+#ifndef BT_USE_TRACES
+#define BT_USE_TRACES TRUE
+#endif
+
+/* Enables or disables protocol trace information. */
+#ifndef BT_TRACE_PROTOCOL
+#define BT_TRACE_PROTOCOL TRUE /* Android requires TRUE */
+#endif
+
+/******************************************************************************
+**
+** Trace Levels
+**
+** The following values may be used for different levels:
+** BT_TRACE_LEVEL_NONE 0 * No trace messages to be generated
+** BT_TRACE_LEVEL_ERROR 1 * Error condition trace messages
+** BT_TRACE_LEVEL_WARNING 2 * Warning condition trace messages
+** BT_TRACE_LEVEL_API 3 * API traces
+** BT_TRACE_LEVEL_EVENT 4 * Debug messages for events
+** BT_TRACE_LEVEL_DEBUG 5 * Debug messages (general)
+******************************************************************************/
+
+/* Core Stack default trace levels */
+#ifndef HCI_INITIAL_TRACE_LEVEL
+#define HCI_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef BTM_INITIAL_TRACE_LEVEL
+#define BTM_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef L2CAP_INITIAL_TRACE_LEVEL
+#define L2CAP_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef LLCP_INITIAL_TRACE_LEVEL
+#define LLCP_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef AMP_INITIAL_TRACE_LEVEL
+#define AMP_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef RFCOMM_INITIAL_TRACE_LEVEL
+#define RFCOMM_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef OBX_INITIAL_TRACE_LEVEL
+#define OBX_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef SDP_INITIAL_TRACE_LEVEL
+#define SDP_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef TCS_INITIAL_TRACE_LEVEL
+#define TCS_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+/* Profile default trace levels */
+#ifndef DUN_INITIAL_TRACE_LEVEL
+#define DUN_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef GAP_INITIAL_TRACE_LEVEL
+#define GAP_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef GOEP_INITIAL_TRACE_LEVEL
+#define GOEP_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef HSP2_INITIAL_TRACE_LEVEL
+#define HSP2_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef SPP_INITIAL_TRACE_LEVEL
+#define SPP_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef ICP_INITIAL_TRACE_LEVEL
+#define ICP_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef CTP_INITIAL_TRACE_LEVEL
+#define CTP_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef HCRP_INITIAL_TRACE_LEVEL
+#define HCRP_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef HCRPM_INITIAL_TRACE_LEVEL
+#define HCRPM_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef BPP_INITIAL_TRACE_LEVEL
+#define BPP_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef BIP_INITIAL_TRACE_LEVEL
+#define BIP_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef BNEP_INITIAL_TRACE_LEVEL
+#define BNEP_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef PAN_INITIAL_TRACE_LEVEL
+#define PAN_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef SAP_INITIAL_TRACE_LEVEL
+#define SAP_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef FTP_INITIAL_TRACE_LEVEL
+#define FTP_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef OPP_INITIAL_TRACE_LEVEL
+#define OPP_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef HFP_INITIAL_TRACE_LEVEL
+#define HFP_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef A2D_INITIAL_TRACE_LEVEL
+#define A2D_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef VDP_INITIAL_TRACE_LEVEL
+#define VDP_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef AVDT_INITIAL_TRACE_LEVEL
+#define AVDT_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef AVCT_INITIAL_TRACE_LEVEL
+#define AVCT_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef AVRC_INITIAL_TRACE_LEVEL
+#define AVRC_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef MCA_INITIAL_TRACE_LEVEL
+#define MCA_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef HID_INITIAL_TRACE_LEVEL
+#define HID_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+/* Application and other default trace levels */
+#ifndef RPC_INITIAL_TRACE_LEVEL
+#define RPC_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef APPL_INITIAL_TRACE_LEVEL
+#define APPL_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef BT_TRACE_APPL
+#define BT_TRACE_APPL BT_USE_TRACES
+#endif
+
+#ifndef NFC_INITIAL_TRACE_LEVEL
+#define NFC_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef GATT_INITIAL_TRACE_LEVEL
+#define GATT_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef SMP_INITIAL_TRACE_LEVEL
+#define SMP_INITIAL_TRACE_LEVEL BT_TRACE_LEVEL_DEBUG
+#endif
+
+
+#if (BTTRC_INCLUDED == TRUE)
+/***************************************************************************************/
+/* BTTRC MACROS */
+
+#define BTTRC_EVENT(lid, event, state) \
+ {BTTRC_StackTrace1(lid, BTTRC_TYPE_EVENT, event, BTTRC_PARAM_UINT8, state);}
+#define BTTRC_ACTION(lid, action) \
+ {BTTRC_StackTrace0(lid, BTTRC_TYPE_ACTION, action);}
+#define BTTRC_STATE(lid, state) \
+ {BTTRC_StackTrace1(lid, BTTRC_TYPE_EVENT, BTTRC_TOKEN_SM_STATE, BTTRC_PARAM_UINT8, state);}
+
+#define BTTRC_API0(lid, api) \
+ {BTTRC_StackTrace0(lid, BTTRC_TYPE_API, api);}
+#define BTTRC_API1(lid, api, p1_t,p1_v) \
+ {BTTRC_StackTrace1(lid, BTTRC_TYPE_API, api, p1_t,p1_v);}
+#define BTTRC_API2(lid, api, p1_t,p1_v,p2_t,p2_v) \
+ {BTTRC_StackTrace2(lid, BTTRC_TYPE_API, api, p1_t,p1_v,p2_t,p2_v);}
+#define BTTRC_API3(lid, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v) \
+ {BTTRC_StackTrace3(lid, BTTRC_TYPE_API, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v);}
+#define BTTRC_API4(lid, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v) \
+ {BTTRC_StackTrace4(lid, BTTRC_TYPE_API, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v);}
+#define BTTRC_API5(lid, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v) \
+ {BTTRC_StackTrace5(lid, BTTRC_TYPE_API, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v);}
+#define BTTRC_API6(lid, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v) \
+ {BTTRC_StackTrace6(lid, BTTRC_TYPE_API, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v);}
+
+
+#define BTTRC_DBG0(lid, dbg) \
+ {BTTRC_StackTrace0(lid, BTTRC_TYPE_DBG, dbg);}
+#define BTTRC_DBG1(lid, dbg, p1_t,p1_v) \
+ {BTTRC_StackTrace1(lid, BTTRC_TYPE_DBG, dbg, p1_t,p1_v);}
+#define BTTRC_DBG2(lid, dbg, p1_t,p1_v,p2_t,p2_v) \
+ {BTTRC_StackTrace2(lid, BTTRC_TYPE_DBG, dbg, p1_t,p1_v,p2_t,p2_v);}
+#define BTTRC_DBG3(lid, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v) \
+ {BTTRC_StackTrace3(lid, BTTRC_TYPE_DBG, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v);}
+#define BTTRC_DBG4(lid, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v) \
+ {BTTRC_StackTrace4(lid, BTTRC_TYPE_DBG, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v);}
+#define BTTRC_DBG5(lid, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v) \
+ {BTTRC_StackTrace5(lid, BTTRC_TYPE_DBG, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v);}
+#define BTTRC_DBG6(lid, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v) \
+ {BTTRC_StackTrace6(lid, BTTRC_TYPE_DBG, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v);}
+
+/***************************************************************************************/
+/*AVDT MACROS */
+
+#define BTTRC_AVDT_API0(api) \
+ BTTRC_API0(BTTRC_ID_STK_AVDT, api)
+#define BTTRC_AVDT_API1(api, p1_t, p1_v) \
+ BTTRC_API1(BTTRC_ID_STK_AVDT, api, p1_t, p1_v)
+#define BTTRC_AVDT_API2(api, p1_t, p1_v, p2_t, p2_v) \
+ BTTRC_API2(BTTRC_ID_STK_AVDT, api, p1_t, p1_v, p2_t, p2_v)
+/***************************************************************************************/
+/*AVDT_SCB MACROS */
+
+#define BTTRC_AVDT_SCB_EVENT(event, state) \
+ BTTRC_EVENT(BTTRC_ID_AVDT_SCB, event, state)
+#define BTTRC_AVDT_SCB_ACTION(action) \
+ BTTRC_ACTION(BTTRC_ID_AVDT_SCB, action)
+#define BTTRC_AVDT_SCB_STATE(next_state) \
+ BTTRC_STATE(BTTRC_ID_AVDT_SCB, next_state)
+
+#define BTTRC_AVDT_SCB_DBG0(dbg) \
+ BTTRC_DBG0(BTTRC_ID_AVDT_SCB, dbg)
+#define BTTRC_AVDT_SCB_DBG1(dbg, p1_t,p1_v) \
+ BTTRC_DBG1(BTTRC_ID_AVDT_SCB, dbg, p1_t,p1_v)
+#define BTTRC_AVDT_SCB_DBG2(dbg, p1_t,p1_v,p2_t,p2_v) \
+ BTTRC_DBG2(BTTRC_ID_AVDT_SCB, dbg, p1_t,p1_v,p2_t,p2_v)
+#define BTTRC_AVDT_SCB_DBG3(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v) \
+ BTTRC_DBG3(BTTRC_ID_AVDT_SCB, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v)
+#define BTTRC_AVDT_SCB_DBG4(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v) \
+ BTTRC_DBG4(BTTRC_ID_AVDT_SCB, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v)
+#define BTTRC_AVDT_SCB_DBG5(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v) \
+ BTTRC_DBG5(BTTRC_ID_AVDT_SCB, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v)
+#define BTTRC_AVDT_SCB_DBG6(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v) \
+ BTTRC_DBG6(BTTRC_ID_AVDT_SCB, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v)
+/***************************************************************************************/
+/*AVDT_CCB MACROS */
+
+#define BTTRC_AVDT_CCB_EVENT(event, state) \
+ BTTRC_EVENT(BTTRC_ID_AVDT_CCB, event, state)
+#define BTTRC_AVDT_CCB_ACTION(action) \
+ BTTRC_ACTION(BTTRC_ID_AVDT_CCB, action)
+#define BTTRC_AVDT_CCB_STATE(next_state) \
+ BTTRC_STATE(BTTRC_ID_AVDT_CCB, next_state)
+
+#define BTTRC_AVDT_CCB_DBG0(dbg) \
+ BTTRC_DBG0(BTTRC_ID_AVDT_CCB, dbg)
+#define BTTRC_AVDT_CCB_DBG1(dbg, p1_t,p1_v) \
+ BTTRC_DBG1(BTTRC_ID_AVDT_CCB, dbg, p1_t,p1_v)
+#define BTTRC_AVDT_CCB_DBG2(dbg, p1_t,p1_v,p2_t,p2_v) \
+ BTTRC_DBG2(BTTRC_ID_AVDT_CCB, dbg, p1_t,p1_v,p2_t,p2_v)
+#define BTTRC_AVDT_CCB_DBG3(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v) \
+ BTTRC_DBG3(BTTRC_ID_AVDT_CCB, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v)
+#define BTTRC_AVDT_CCB_DBG4(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v) \
+ BTTRC_DBG4(BTTRC_ID_AVDT_CCB, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v)
+#define BTTRC_AVDT_CCB_DBG5(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v) \
+ BTTRC_DBG5(BTTRC_ID_AVDT_CCB, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v)
+#define BTTRC_AVDT_CCB_DBG6(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v) \
+ BTTRC_DBG6(BTTRC_ID_AVDT_CCB, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v)
+/***************************************************************************************/
+
+#else /*BTTRC_INCLUDED*/
+
+/***************************************************************************************/
+/* BTTRC MACROS */
+
+#define BTTRC_EVENT(lid, event, state)
+#define BTTRC_ACTION(lid, action)
+#define BTTRC_STATE(lid, state)
+
+#define BTTRC_API0(lid, api)
+#define BTTRC_API1(lid, api, p1_t, p1_v)
+#define BTTRC_API2(lid, api, p1_t, p1_v, p2_t, p2_v)
+#define BTTRC_API3(lid, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v)
+#define BTTRC_API4(lid, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v)
+#define BTTRC_API5(lid, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v)
+#define BTTRC_API6(lid, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v)
+
+
+#define BTTRC_DBG0(lid, dbg)
+#define BTTRC_DBG1(lid, dbg, p1_t,p1_v)
+#define BTTRC_DBG2(lid, dbg, p1_t,p1_v,p2_t,p2_v)
+#define BTTRC_DBG3(lid, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v)
+#define BTTRC_DBG4(lid, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v)
+#define BTTRC_DBG5(lid, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v)
+#define BTTRC_DBG6(lid, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v)
+
+/***************************************************************************************/
+/*AVDT MACROS */
+#define BTTRC_AVDT_API0(api)
+#define BTTRC_AVDT_API1(api, p1_t,p1_v)
+#define BTTRC_AVDT_API2(api, p1_t,p1_v,p2_t,p2_v)
+/***************************************************************************************/
+/*AVDT_SCB MACROS */
+
+#define BTTRC_AVDT_SCB_EVENT(event, state)
+#define BTTRC_AVDT_SCB_ACTION(action)
+#define BTTRC_AVDT_SCB_STATE(next_state)
+
+#define BTTRC_AVDT_SCB_DBG0(dbg)
+#define BTTRC_AVDT_SCB_DBG1(dbg, p1_t,p1_v)
+#define BTTRC_AVDT_SCB_DBG2(dbg, p1_t,p1_v,p2_t,p2_v)
+#define BTTRC_AVDT_SCB_DBG3(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v)
+#define BTTRC_AVDT_SCB_DBG4(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v)
+#define BTTRC_AVDT_SCB_DBG5(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v)
+#define BTTRC_AVDT_SCB_DBG6(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v)
+
+/***************************************************************************************/
+/*AVDT_CCB MACROS */
+
+#define BTTRC_AVDT_CCB_EVENT(event, state)
+#define BTTRC_AVDT_CCB_ACTION(action)
+#define BTTRC_AVDT_CCB_STATE(next_state)
+
+#define BTTRC_AVDT_CCB_DBG0(dbg)
+#define BTTRC_AVDT_CCB_DBG1(dbg, p1_t,p1_v)
+#define BTTRC_AVDT_CCB_DBG2(dbg, p1_t,p1_v,p2_t,p2_v)
+#define BTTRC_AVDT_CCB_DBG3(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v)
+#define BTTRC_AVDT_CCB_DBG4(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v)
+#define BTTRC_AVDT_CCB_DBG5(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v)
+#define BTTRC_AVDT_CCB_DBG6(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v)
+
+/***************************************************************************************/
+
+#endif /*BTTRC_INCLUDED*/
+
+
+#if (BT_USE_TRACES == TRUE)
+
+#define BT_TRACE_0(l,t,m) LogMsg_0((TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t)),(m))
+#define BT_TRACE_1(l,t,m,p1) LogMsg_1(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1))
+#define BT_TRACE_2(l,t,m,p1,p2) LogMsg_2(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1), \
+ (UINT32)(p2))
+#define BT_TRACE_3(l,t,m,p1,p2,p3) LogMsg_3(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1), \
+ (UINT32)(p2),(UINT32)(p3))
+#define BT_TRACE_4(l,t,m,p1,p2,p3,p4) LogMsg_4(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1), \
+ (UINT32)(p2),(UINT32)(p3),(UINT32)(p4))
+#define BT_TRACE_5(l,t,m,p1,p2,p3,p4,p5) LogMsg_5(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1), \
+ (UINT32)(p2),(UINT32)(p3),(UINT32)(p4), \
+ (UINT32)(p5))
+#define BT_TRACE_6(l,t,m,p1,p2,p3,p4,p5,p6) LogMsg_6(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1), \
+ (UINT32)(p2),(UINT32)(p3),(UINT32)(p4), \
+ (UINT32)(p5),(UINT32)(p6))
+
+#define BT_ERROR_TRACE_0(l,m) LogMsg_0(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | TRACE_TYPE_ERROR,(m))
+#define BT_ERROR_TRACE_1(l,m,p1) LogMsg_1(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | TRACE_TYPE_ERROR,(m),(UINT32)(p1))
+#define BT_ERROR_TRACE_2(l,m,p1,p2) LogMsg_2(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | TRACE_TYPE_ERROR,(m),(UINT32)(p1),(UINT32)(p2))
+#define BT_ERROR_TRACE_3(l,m,p1,p2,p3) LogMsg_3(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | TRACE_TYPE_ERROR,(m),(UINT32)(p1),(UINT32)(p2),(UINT32)(p3))
+
+/* Define tracing for the HCI unit
+*/
+#define HCI_TRACE_ERROR0(m) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_HCI, TRACE_TYPE_ERROR, m);}
+#define HCI_TRACE_ERROR1(m,p1) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_HCI, TRACE_TYPE_ERROR, m,p1);}
+#define HCI_TRACE_ERROR2(m,p1,p2) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_HCI, TRACE_TYPE_ERROR, m,p1,p2);}
+#define HCI_TRACE_ERROR3(m,p1,p2,p3) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_HCI, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define HCI_TRACE_ERROR4(m,p1,p2,p3,p4) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_HCI, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define HCI_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_HCI, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define HCI_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_HCI, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCI_TRACE_WARNING0(m) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_HCI, TRACE_TYPE_WARNING, m);}
+#define HCI_TRACE_WARNING1(m,p1) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_HCI, TRACE_TYPE_WARNING, m,p1);}
+#define HCI_TRACE_WARNING2(m,p1,p2) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_HCI, TRACE_TYPE_WARNING, m,p1,p2);}
+#define HCI_TRACE_WARNING3(m,p1,p2,p3) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_HCI, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define HCI_TRACE_WARNING4(m,p1,p2,p3,p4) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_HCI, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define HCI_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_HCI, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define HCI_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_HCI, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCI_TRACE_EVENT0(m) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_HCI, TRACE_TYPE_EVENT, m);}
+#define HCI_TRACE_EVENT1(m,p1) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_HCI, TRACE_TYPE_EVENT, m, p1);}
+#define HCI_TRACE_EVENT2(m,p1,p2) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_HCI, TRACE_TYPE_EVENT, m,p1,p2);}
+#define HCI_TRACE_EVENT3(m,p1,p2,p3) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_HCI, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define HCI_TRACE_EVENT4(m,p1,p2,p3,p4) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_HCI, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define HCI_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_HCI, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define HCI_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_HCI, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCI_TRACE_DEBUG0(m) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, m);}
+#define HCI_TRACE_DEBUG1(m,p1) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, m,p1);}
+#define HCI_TRACE_DEBUG2(m,p1,p2) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define HCI_TRACE_DEBUG3(m,p1,p2,p3) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define HCI_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define HCI_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define HCI_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+
+/* Define tracing for BTM
+*/
+#define BTM_TRACE_ERROR0(m) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_BTM, TRACE_TYPE_ERROR, m);}
+#define BTM_TRACE_ERROR1(m,p1) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_BTM, TRACE_TYPE_ERROR, m,p1);}
+#define BTM_TRACE_ERROR2(m,p1,p2) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_BTM, TRACE_TYPE_ERROR, m,p1,p2);}
+#define BTM_TRACE_ERROR3(m,p1,p2,p3) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_BTM, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define BTM_TRACE_ERROR4(m,p1,p2,p3,p4) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_BTM, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define BTM_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_BTM, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define BTM_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_BTM, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define BTM_TRACE_WARNING0(m) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_BTM, TRACE_TYPE_WARNING, m);}
+#define BTM_TRACE_WARNING1(m,p1) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_BTM, TRACE_TYPE_WARNING, m,p1);}
+#define BTM_TRACE_WARNING2(m,p1,p2) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_BTM, TRACE_TYPE_WARNING, m,p1,p2);}
+#define BTM_TRACE_WARNING3(m,p1,p2,p3) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_BTM, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define BTM_TRACE_WARNING4(m,p1,p2,p3,p4) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_BTM, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define BTM_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_BTM, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define BTM_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_BTM, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define BTM_TRACE_API0(m) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_BTM, TRACE_TYPE_API, m);}
+#define BTM_TRACE_API1(m,p1) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_BTM, TRACE_TYPE_API, m, p1);}
+#define BTM_TRACE_API2(m,p1,p2) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_BTM, TRACE_TYPE_API, m,p1,p2);}
+#define BTM_TRACE_API3(m,p1,p2,p3) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_BTM, TRACE_TYPE_API, m,p1,p2,p3);}
+#define BTM_TRACE_API4(m,p1,p2,p3,p4) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_BTM, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define BTM_TRACE_API5(m,p1,p2,p3,p4,p5) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_BTM, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define BTM_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_BTM, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define BTM_TRACE_EVENT0(m) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_BTM, TRACE_TYPE_EVENT, m);}
+#define BTM_TRACE_EVENT1(m,p1) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_BTM, TRACE_TYPE_EVENT, m, p1);}
+#define BTM_TRACE_EVENT2(m,p1,p2) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_BTM, TRACE_TYPE_EVENT, m,p1,p2);}
+#define BTM_TRACE_EVENT3(m,p1,p2,p3) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_BTM, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define BTM_TRACE_EVENT4(m,p1,p2,p3,p4) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_BTM, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define BTM_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_BTM, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define BTM_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_BTM, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define BTM_TRACE_DEBUG0(m) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_BTM, TRACE_TYPE_DEBUG, m);}
+#define BTM_TRACE_DEBUG1(m,p1) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_BTM, TRACE_TYPE_DEBUG, m,p1);}
+#define BTM_TRACE_DEBUG2(m,p1,p2) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_BTM, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define BTM_TRACE_DEBUG3(m,p1,p2,p3) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_BTM, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define BTM_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_BTM, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define BTM_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_BTM, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define BTM_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_BTM, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+
+/* Define tracing for the L2CAP unit
+*/
+#define L2CAP_TRACE_ERROR0(m) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_L2CAP, TRACE_TYPE_ERROR, m);}
+#define L2CAP_TRACE_ERROR1(m,p1) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_L2CAP, TRACE_TYPE_ERROR, m,p1);}
+#define L2CAP_TRACE_ERROR2(m,p1,p2) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_L2CAP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define L2CAP_TRACE_ERROR3(m,p1,p2,p3) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_L2CAP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define L2CAP_TRACE_ERROR4(m,p1,p2,p3,p4) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_L2CAP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define L2CAP_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_L2CAP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define L2CAP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_L2CAP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define L2CAP_TRACE_WARNING0(m) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_L2CAP, TRACE_TYPE_WARNING, m);}
+#define L2CAP_TRACE_WARNING1(m,p1) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_L2CAP, TRACE_TYPE_WARNING, m,p1);}
+#define L2CAP_TRACE_WARNING2(m,p1,p2) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_L2CAP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define L2CAP_TRACE_WARNING3(m,p1,p2,p3) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_L2CAP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define L2CAP_TRACE_WARNING4(m,p1,p2,p3,p4) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_L2CAP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define L2CAP_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_L2CAP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define L2CAP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_L2CAP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define L2CAP_TRACE_API0(m) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_L2CAP, TRACE_TYPE_API, m);}
+#define L2CAP_TRACE_API1(m,p1) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_L2CAP, TRACE_TYPE_API, m,p1);}
+#define L2CAP_TRACE_API2(m,p1,p2) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_L2CAP, TRACE_TYPE_API, m,p1,p2);}
+#define L2CAP_TRACE_API3(m,p1,p2,p3) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_L2CAP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define L2CAP_TRACE_API4(m,p1,p2,p3,p4) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_L2CAP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define L2CAP_TRACE_API5(m,p1,p2,p3,p4,p5) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_L2CAP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define L2CAP_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_L2CAP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define L2CAP_TRACE_EVENT0(m) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_L2CAP, TRACE_TYPE_EVENT, m);}
+#define L2CAP_TRACE_EVENT1(m,p1) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_L2CAP, TRACE_TYPE_EVENT, m, p1);}
+#define L2CAP_TRACE_EVENT2(m,p1,p2) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_L2CAP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define L2CAP_TRACE_EVENT3(m,p1,p2,p3) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_L2CAP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define L2CAP_TRACE_EVENT4(m,p1,p2,p3,p4) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_L2CAP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define L2CAP_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_L2CAP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define L2CAP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_L2CAP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define L2CAP_TRACE_DEBUG0(m) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_L2CAP, TRACE_TYPE_DEBUG, m);}
+#define L2CAP_TRACE_DEBUG1(m,p1) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_L2CAP, TRACE_TYPE_DEBUG, m,p1);}
+#define L2CAP_TRACE_DEBUG2(m,p1,p2) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_L2CAP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define L2CAP_TRACE_DEBUG3(m,p1,p2,p3) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_L2CAP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define L2CAP_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_L2CAP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define L2CAP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_L2CAP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define L2CAP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_L2CAP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the LLCP unit
+*/
+#define LLCP_TRACE_ERROR0(m) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_LLCP, TRACE_TYPE_ERROR, m);}
+#define LLCP_TRACE_ERROR1(m,p1) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_LLCP, TRACE_TYPE_ERROR, m,p1);}
+#define LLCP_TRACE_ERROR2(m,p1,p2) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_LLCP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define LLCP_TRACE_ERROR3(m,p1,p2,p3) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_LLCP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define LLCP_TRACE_ERROR4(m,p1,p2,p3,p4) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_LLCP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define LLCP_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_LLCP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define LLCP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_LLCP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define LLCP_TRACE_WARNING0(m) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_LLCP, TRACE_TYPE_WARNING, m);}
+#define LLCP_TRACE_WARNING1(m,p1) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_LLCP, TRACE_TYPE_WARNING, m,p1);}
+#define LLCP_TRACE_WARNING2(m,p1,p2) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_LLCP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define LLCP_TRACE_WARNING3(m,p1,p2,p3) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_LLCP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define LLCP_TRACE_WARNING4(m,p1,p2,p3,p4) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_LLCP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define LLCP_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_LLCP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define LLCP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_LLCP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define LLCP_TRACE_API0(m) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_LLCP, TRACE_TYPE_API, m);}
+#define LLCP_TRACE_API1(m,p1) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_LLCP, TRACE_TYPE_API, m,p1);}
+#define LLCP_TRACE_API2(m,p1,p2) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_LLCP, TRACE_TYPE_API, m,p1,p2);}
+#define LLCP_TRACE_API3(m,p1,p2,p3) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_LLCP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define LLCP_TRACE_API4(m,p1,p2,p3,p4) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_LLCP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define LLCP_TRACE_API5(m,p1,p2,p3,p4,p5) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_LLCP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define LLCP_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_LLCP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define LLCP_TRACE_EVENT0(m) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_LLCP, TRACE_TYPE_EVENT, m);}
+#define LLCP_TRACE_EVENT1(m,p1) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_LLCP, TRACE_TYPE_EVENT, m, p1);}
+#define LLCP_TRACE_EVENT2(m,p1,p2) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_LLCP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define LLCP_TRACE_EVENT3(m,p1,p2,p3) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_LLCP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define LLCP_TRACE_EVENT4(m,p1,p2,p3,p4) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_LLCP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define LLCP_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_LLCP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define LLCP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_LLCP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define LLCP_TRACE_DEBUG0(m) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_LLCP, TRACE_TYPE_DEBUG, m);}
+#define LLCP_TRACE_DEBUG1(m,p1) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_LLCP, TRACE_TYPE_DEBUG, m,p1);}
+#define LLCP_TRACE_DEBUG2(m,p1,p2) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_LLCP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define LLCP_TRACE_DEBUG3(m,p1,p2,p3) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_LLCP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define LLCP_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_LLCP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define LLCP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_LLCP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define LLCP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_LLCP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the SDP unit
+*/
+#define SDP_TRACE_ERROR0(m) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_SDP, TRACE_TYPE_ERROR, m);}
+#define SDP_TRACE_ERROR1(m,p1) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_SDP, TRACE_TYPE_ERROR, m,p1);}
+#define SDP_TRACE_ERROR2(m,p1,p2) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_SDP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define SDP_TRACE_ERROR3(m,p1,p2,p3) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_SDP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define SDP_TRACE_ERROR4(m,p1,p2,p3,p4) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_SDP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define SDP_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_SDP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define SDP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_SDP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define SDP_TRACE_WARNING0(m) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_SDP, TRACE_TYPE_WARNING, m);}
+#define SDP_TRACE_WARNING1(m,p1) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_SDP, TRACE_TYPE_WARNING, m,p1);}
+#define SDP_TRACE_WARNING2(m,p1,p2) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_SDP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define SDP_TRACE_WARNING3(m,p1,p2,p3) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_SDP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define SDP_TRACE_WARNING4(m,p1,p2,p3,p4) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_SDP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define SDP_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_SDP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define SDP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_SDP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define SDP_TRACE_API0(m) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_SDP, TRACE_TYPE_API, m);}
+#define SDP_TRACE_API1(m,p1) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_SDP, TRACE_TYPE_API, m,p1);}
+#define SDP_TRACE_API2(m,p1,p2) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_SDP, TRACE_TYPE_API, m,p1,p2);}
+#define SDP_TRACE_API3(m,p1,p2,p3) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_SDP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define SDP_TRACE_API4(m,p1,p2,p3,p4) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_SDP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define SDP_TRACE_API5(m,p1,p2,p3,p4,p5) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_SDP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define SDP_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_SDP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define SDP_TRACE_EVENT0(m) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_SDP, TRACE_TYPE_EVENT, m);}
+#define SDP_TRACE_EVENT1(m,p1) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_SDP, TRACE_TYPE_EVENT, m, p1);}
+#define SDP_TRACE_EVENT2(m,p1,p2) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_SDP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define SDP_TRACE_EVENT3(m,p1,p2,p3) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_SDP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define SDP_TRACE_EVENT4(m,p1,p2,p3,p4) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_SDP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define SDP_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_SDP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define SDP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_SDP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define SDP_TRACE_DEBUG0(m) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_SDP, TRACE_TYPE_DEBUG, m);}
+#define SDP_TRACE_DEBUG1(m,p1) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_SDP, TRACE_TYPE_DEBUG, m,p1);}
+#define SDP_TRACE_DEBUG2(m,p1,p2) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_SDP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define SDP_TRACE_DEBUG3(m,p1,p2,p3) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_SDP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define SDP_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_SDP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define SDP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_SDP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define SDP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_SDP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the RFCOMM unit
+*/
+#define RFCOMM_TRACE_ERROR0(m) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_RFCOMM, TRACE_TYPE_ERROR, m);}
+#define RFCOMM_TRACE_ERROR1(m,p1) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_RFCOMM, TRACE_TYPE_ERROR, m,p1);}
+#define RFCOMM_TRACE_ERROR2(m,p1,p2) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_RFCOMM, TRACE_TYPE_ERROR, m,p1,p2);}
+#define RFCOMM_TRACE_ERROR3(m,p1,p2,p3) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_RFCOMM, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define RFCOMM_TRACE_ERROR4(m,p1,p2,p3,p4) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_RFCOMM, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define RFCOMM_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_RFCOMM, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define RFCOMM_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_RFCOMM, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define RFCOMM_TRACE_WARNING0(m) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_RFCOMM, TRACE_TYPE_WARNING, m);}
+#define RFCOMM_TRACE_WARNING1(m,p1) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_RFCOMM, TRACE_TYPE_WARNING, m,p1);}
+#define RFCOMM_TRACE_WARNING2(m,p1,p2) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_RFCOMM, TRACE_TYPE_WARNING, m,p1,p2);}
+#define RFCOMM_TRACE_WARNING3(m,p1,p2,p3) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_RFCOMM, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define RFCOMM_TRACE_WARNING4(m,p1,p2,p3,p4) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_RFCOMM, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define RFCOMM_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_RFCOMM, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define RFCOMM_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_RFCOMM, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define RFCOMM_TRACE_API0(m) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_RFCOMM, TRACE_TYPE_API, m);}
+#define RFCOMM_TRACE_API1(m,p1) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_RFCOMM, TRACE_TYPE_API, m,p1);}
+#define RFCOMM_TRACE_API2(m,p1,p2) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_RFCOMM, TRACE_TYPE_API, m,p1,p2);}
+#define RFCOMM_TRACE_API3(m,p1,p2,p3) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_RFCOMM, TRACE_TYPE_API, m,p1,p2,p3);}
+#define RFCOMM_TRACE_API4(m,p1,p2,p3,p4) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_RFCOMM, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define RFCOMM_TRACE_API5(m,p1,p2,p3,p4,p5) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_RFCOMM, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define RFCOMM_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_RFCOMM, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define RFCOMM_TRACE_EVENT0(m) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_RFCOMM, TRACE_TYPE_EVENT, m);}
+#define RFCOMM_TRACE_EVENT1(m,p1) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_RFCOMM, TRACE_TYPE_EVENT, m, p1);}
+#define RFCOMM_TRACE_EVENT2(m,p1,p2) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_RFCOMM, TRACE_TYPE_EVENT, m,p1,p2);}
+#define RFCOMM_TRACE_EVENT3(m,p1,p2,p3) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_RFCOMM, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define RFCOMM_TRACE_EVENT4(m,p1,p2,p3,p4) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_RFCOMM, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define RFCOMM_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_RFCOMM, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define RFCOMM_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_RFCOMM, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define RFCOMM_TRACE_DEBUG0(m) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_RFCOMM, TRACE_TYPE_DEBUG, m);}
+#define RFCOMM_TRACE_DEBUG1(m,p1) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_RFCOMM, TRACE_TYPE_DEBUG, m,p1);}
+#define RFCOMM_TRACE_DEBUG2(m,p1,p2) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_RFCOMM, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define RFCOMM_TRACE_DEBUG3(m,p1,p2,p3) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_RFCOMM, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define RFCOMM_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_RFCOMM, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define RFCOMM_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_RFCOMM, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define RFCOMM_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_RFCOMM, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for Serial Port Profile
+*/
+#define SPP_TRACE_ERROR0(m) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_SPP, TRACE_TYPE_ERROR, m);}
+#define SPP_TRACE_ERROR1(m,p1) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_SPP, TRACE_TYPE_ERROR, m,p1);}
+#define SPP_TRACE_ERROR2(m,p1,p2) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_SPP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define SPP_TRACE_ERROR3(m,p1,p2,p3) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_SPP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define SPP_TRACE_ERROR4(m,p1,p2,p3,p4) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_SPP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define SPP_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_SPP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define SPP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_SPP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define SPP_TRACE_WARNING0(m) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_SPP, TRACE_TYPE_WARNING, m);}
+#define SPP_TRACE_WARNING1(m,p1) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_SPP, TRACE_TYPE_WARNING, m,p1);}
+#define SPP_TRACE_WARNING2(m,p1,p2) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_SPP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define SPP_TRACE_WARNING3(m,p1,p2,p3) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_SPP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define SPP_TRACE_WARNING4(m,p1,p2,p3,p4) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_SPP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define SPP_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_SPP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define SPP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_SPP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define SPP_TRACE_EVENT0(m) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_SPP, TRACE_TYPE_EVENT, m);}
+#define SPP_TRACE_EVENT1(m,p1) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_SPP, TRACE_TYPE_EVENT, m, p1);}
+#define SPP_TRACE_EVENT2(m,p1,p2) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_SPP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define SPP_TRACE_EVENT3(m,p1,p2,p3) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_SPP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define SPP_TRACE_EVENT4(m,p1,p2,p3,p4) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_SPP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define SPP_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_SPP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define SPP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_SPP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define SPP_TRACE_API0(m) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_SPP, TRACE_TYPE_API, m);}
+#define SPP_TRACE_API1(m,p1) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_SPP, TRACE_TYPE_API, m, p1);}
+#define SPP_TRACE_API2(m,p1,p2) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_SPP, TRACE_TYPE_API, m,p1,p2);}
+#define SPP_TRACE_API3(m,p1,p2,p3) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_SPP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define SPP_TRACE_API4(m,p1,p2,p3,p4) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_SPP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define SPP_TRACE_API5(m,p1,p2,p3,p4,p5) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_SPP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define SPP_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_SPP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define SPP_TRACE_DEBUG0(m) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_SPP, TRACE_TYPE_DEBUG, m);}
+#define SPP_TRACE_DEBUG1(m,p1) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_SPP, TRACE_TYPE_DEBUG, m,p1);}
+#define SPP_TRACE_DEBUG2(m,p1,p2) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_SPP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define SPP_TRACE_DEBUG3(m,p1,p2,p3) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_SPP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define SPP_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_SPP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define SPP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_SPP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define SPP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_SPP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Generic Access Profile traces */
+#define GAP_TRACE_ERROR0(m) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_GAP, TRACE_TYPE_ERROR, m);}
+#define GAP_TRACE_ERROR1(m,p1) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_GAP, TRACE_TYPE_ERROR, m, p1);}
+#define GAP_TRACE_ERROR2(m,p1,p2) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_GAP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define GAP_TRACE_ERROR3(m,p1,p2,p3) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_GAP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define GAP_TRACE_ERROR4(m,p1,p2,p3,p4) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_GAP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define GAP_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_GAP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define GAP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_GAP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define GAP_TRACE_EVENT0(m) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_GAP, TRACE_TYPE_EVENT, m);}
+#define GAP_TRACE_EVENT1(m,p1) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_GAP, TRACE_TYPE_EVENT, m, p1);}
+#define GAP_TRACE_EVENT2(m,p1,p2) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_GAP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define GAP_TRACE_EVENT3(m,p1,p2,p3) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_GAP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define GAP_TRACE_EVENT4(m,p1,p2,p3,p4) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_GAP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define GAP_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_GAP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define GAP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_GAP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define GAP_TRACE_API0(m) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_GAP, TRACE_TYPE_API, m);}
+#define GAP_TRACE_API1(m,p1) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_GAP, TRACE_TYPE_API, m, p1);}
+#define GAP_TRACE_API2(m,p1,p2) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_GAP, TRACE_TYPE_API, m,p1,p2);}
+#define GAP_TRACE_API3(m,p1,p2,p3) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_GAP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define GAP_TRACE_API4(m,p1,p2,p3,p4) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_GAP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define GAP_TRACE_API5(m,p1,p2,p3,p4,p5) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_GAP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define GAP_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_GAP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define GAP_TRACE_WARNING0(m) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_GAP, TRACE_TYPE_WARNING, m);}
+#define GAP_TRACE_WARNING1(m,p1) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_GAP, TRACE_TYPE_WARNING, m, p1);}
+#define GAP_TRACE_WARNING2(m,p1,p2) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_GAP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define GAP_TRACE_WARNING3(m,p1,p2,p3) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_GAP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define GAP_TRACE_WARNING4(m,p1,p2,p3,p4) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_GAP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define GAP_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_GAP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define GAP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_GAP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+
+/* Define tracing for OBX
+*/
+#define OBX_TRACE_ERROR0(m) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_OBEX, TRACE_TYPE_ERROR, m);}
+#define OBX_TRACE_ERROR1(m,p1) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_OBEX, TRACE_TYPE_ERROR, m,p1);}
+#define OBX_TRACE_ERROR2(m,p1,p2) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_OBEX, TRACE_TYPE_ERROR, m,p1,p2);}
+#define OBX_TRACE_ERROR3(m,p1,p2,p3) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_OBEX, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define OBX_TRACE_ERROR4(m,p1,p2,p3,p4) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_OBEX, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define OBX_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_OBEX, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define OBX_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_OBEX, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define OBX_TRACE_WARNING0(m) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_OBEX, TRACE_TYPE_WARNING, m);}
+#define OBX_TRACE_WARNING1(m,p1) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_OBEX, TRACE_TYPE_WARNING, m,p1);}
+#define OBX_TRACE_WARNING2(m,p1,p2) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_OBEX, TRACE_TYPE_WARNING, m,p1,p2);}
+#define OBX_TRACE_WARNING3(m,p1,p2,p3) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_OBEX, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define OBX_TRACE_WARNING4(m,p1,p2,p3,p4) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_OBEX, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define OBX_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_OBEX, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define OBX_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_OBEX, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define OBX_TRACE_EVENT0(m) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_OBEX, TRACE_TYPE_EVENT, m);}
+#define OBX_TRACE_EVENT1(m,p1) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_OBEX, TRACE_TYPE_EVENT, m, p1);}
+#define OBX_TRACE_EVENT2(m,p1,p2) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_OBEX, TRACE_TYPE_EVENT, m,p1,p2);}
+#define OBX_TRACE_EVENT3(m,p1,p2,p3) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_OBEX, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define OBX_TRACE_EVENT4(m,p1,p2,p3,p4) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_OBEX, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define OBX_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_OBEX, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define OBX_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_OBEX, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define OBX_TRACE_DEBUG0(m) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_OBEX, TRACE_TYPE_DEBUG, m);}
+#define OBX_TRACE_DEBUG1(m,p1) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_OBEX, TRACE_TYPE_DEBUG, m,p1);}
+#define OBX_TRACE_DEBUG2(m,p1,p2) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_OBEX, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define OBX_TRACE_DEBUG3(m,p1,p2,p3) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_OBEX, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define OBX_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_OBEX, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define OBX_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_OBEX, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define OBX_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_OBEX, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define OBX_TRACE_API0(m) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_OBEX, TRACE_TYPE_API, m);}
+#define OBX_TRACE_API1(m,p1) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_OBEX, TRACE_TYPE_API, m, p1);}
+#define OBX_TRACE_API2(m,p1,p2) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_OBEX, TRACE_TYPE_API, m,p1,p2);}
+#define OBX_TRACE_API3(m,p1,p2,p3) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_OBEX, TRACE_TYPE_API, m,p1,p2,p3);}
+#define OBX_TRACE_API4(m,p1,p2,p3,p4) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_OBEX, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define OBX_TRACE_API5(m,p1,p2,p3,p4,p5) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_OBEX, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define OBX_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (obx_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_OBEX, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for OBEX application profiles
+*/
+#define GOEP_TRACE_ERROR0(m) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_GOEP, TRACE_TYPE_ERROR, m);}
+#define GOEP_TRACE_ERROR1(m,p1) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_GOEP, TRACE_TYPE_ERROR, m,p1);}
+#define GOEP_TRACE_ERROR2(m,p1,p2) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_GOEP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define GOEP_TRACE_ERROR3(m,p1,p2,p3) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_GOEP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define GOEP_TRACE_ERROR4(m,p1,p2,p3,p4) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_GOEP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define GOEP_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_GOEP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define GOEP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_GOEP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define GOEP_TRACE_WARNING0(m) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_GOEP, TRACE_TYPE_WARNING, m);}
+#define GOEP_TRACE_WARNING1(m,p1) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_GOEP, TRACE_TYPE_WARNING, m,p1);}
+#define GOEP_TRACE_WARNING2(m,p1,p2) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_GOEP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define GOEP_TRACE_WARNING3(m,p1,p2,p3) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_GOEP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define GOEP_TRACE_WARNING4(m,p1,p2,p3,p4) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_GOEP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define GOEP_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_GOEP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define GOEP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_GOEP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define GOEP_TRACE_EVENT0(m) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_GOEP, TRACE_TYPE_EVENT, m);}
+#define GOEP_TRACE_EVENT1(m,p1) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_GOEP, TRACE_TYPE_EVENT, m, p1);}
+#define GOEP_TRACE_EVENT2(m,p1,p2) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_GOEP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define GOEP_TRACE_EVENT3(m,p1,p2,p3) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_GOEP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define GOEP_TRACE_EVENT4(m,p1,p2,p3,p4) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_GOEP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define GOEP_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_GOEP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define GOEP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_GOEP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define GOEP_TRACE_DEBUG0(m) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_GOEP, TRACE_TYPE_DEBUG, m);}
+#define GOEP_TRACE_DEBUG1(m,p1) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_GOEP, TRACE_TYPE_DEBUG, m,p1);}
+#define GOEP_TRACE_DEBUG2(m,p1,p2) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_GOEP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define GOEP_TRACE_DEBUG3(m,p1,p2,p3) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_GOEP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define GOEP_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_GOEP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define GOEP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_GOEP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define GOEP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_GOEP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define GOEP_TRACE_API0(m) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_GOEP, TRACE_TYPE_API, m);}
+#define GOEP_TRACE_API1(m,p1) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_GOEP, TRACE_TYPE_API, m, p1);}
+#define GOEP_TRACE_API2(m,p1,p2) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_GOEP, TRACE_TYPE_API, m,p1,p2);}
+#define GOEP_TRACE_API3(m,p1,p2,p3) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_GOEP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define GOEP_TRACE_API4(m,p1,p2,p3,p4) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_GOEP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define GOEP_TRACE_API5(m,p1,p2,p3,p4,p5) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_GOEP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define GOEP_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_GOEP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the BPP profile
+*/
+#define BPP_TRACE_ERROR0(m) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_BPP, TRACE_TYPE_ERROR, m);}
+#define BPP_TRACE_ERROR1(m,p1) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_BPP, TRACE_TYPE_ERROR, m,p1);}
+#define BPP_TRACE_ERROR2(m,p1,p2) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_BPP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define BPP_TRACE_ERROR3(m,p1,p2,p3) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_BPP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define BPP_TRACE_ERROR4(m,p1,p2,p3,p4) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_BPP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define BPP_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_BPP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define BPP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_BPP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define BPP_TRACE_WARNING0(m) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_BPP, TRACE_TYPE_WARNING, m);}
+#define BPP_TRACE_WARNING1(m,p1) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_BPP, TRACE_TYPE_WARNING, m,p1);}
+#define BPP_TRACE_WARNING2(m,p1,p2) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_BPP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define BPP_TRACE_WARNING3(m,p1,p2,p3) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_BPP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define BPP_TRACE_WARNING4(m,p1,p2,p3,p4) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_BPP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define BPP_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_BPP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define BPP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_BPP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define BPP_TRACE_EVENT0(m) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_BPP, TRACE_TYPE_EVENT, m);}
+#define BPP_TRACE_EVENT1(m,p1) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_BPP, TRACE_TYPE_EVENT, m, p1);}
+#define BPP_TRACE_EVENT2(m,p1,p2) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_BPP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define BPP_TRACE_EVENT3(m,p1,p2,p3) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_BPP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define BPP_TRACE_EVENT4(m,p1,p2,p3,p4) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_BPP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define BPP_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_BPP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define BPP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_BPP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define BPP_TRACE_DEBUG0(m) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_BPP, TRACE_TYPE_DEBUG, m);}
+#define BPP_TRACE_DEBUG1(m,p1) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_BPP, TRACE_TYPE_DEBUG, m,p1);}
+#define BPP_TRACE_DEBUG2(m,p1,p2) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_BPP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define BPP_TRACE_DEBUG3(m,p1,p2,p3) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_BPP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define BPP_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_BPP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define BPP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_BPP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define BPP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_BPP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define BPP_TRACE_API0(m) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_BPP, TRACE_TYPE_API, m);}
+#define BPP_TRACE_API1(m,p1) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_BPP, TRACE_TYPE_API, m, p1);}
+#define BPP_TRACE_API2(m,p1,p2) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_BPP, TRACE_TYPE_API, m,p1,p2);}
+#define BPP_TRACE_API3(m,p1,p2,p3) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_BPP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define BPP_TRACE_API4(m,p1,p2,p3,p4) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_BPP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define BPP_TRACE_API5(m,p1,p2,p3,p4,p5) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_BPP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define BPP_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_BPP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the BIP profile
+*/
+#define BIP_TRACE_ERROR0(m) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_BIP, TRACE_TYPE_ERROR, m);}
+#define BIP_TRACE_ERROR1(m,p1) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_BIP, TRACE_TYPE_ERROR, m,p1);}
+#define BIP_TRACE_ERROR2(m,p1,p2) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_BIP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define BIP_TRACE_ERROR3(m,p1,p2,p3) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_BIP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define BIP_TRACE_ERROR4(m,p1,p2,p3,p4) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_BIP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define BIP_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_BIP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define BIP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_BIP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define BIP_TRACE_WARNING0(m) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_BIP, TRACE_TYPE_WARNING, m);}
+#define BIP_TRACE_WARNING1(m,p1) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_BIP, TRACE_TYPE_WARNING, m,p1);}
+#define BIP_TRACE_WARNING2(m,p1,p2) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_BIP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define BIP_TRACE_WARNING3(m,p1,p2,p3) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_BIP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define BIP_TRACE_WARNING4(m,p1,p2,p3,p4) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_BIP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define BIP_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_BIP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define BIP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_BIP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define BIP_TRACE_EVENT0(m) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_BIP, TRACE_TYPE_EVENT, m);}
+#define BIP_TRACE_EVENT1(m,p1) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_BIP, TRACE_TYPE_EVENT, m, p1);}
+#define BIP_TRACE_EVENT2(m,p1,p2) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_BIP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define BIP_TRACE_EVENT3(m,p1,p2,p3) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_BIP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define BIP_TRACE_EVENT4(m,p1,p2,p3,p4) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_BIP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define BIP_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_BIP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define BIP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_BIP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define BIP_TRACE_DEBUG0(m) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_BIP, TRACE_TYPE_DEBUG, m);}
+#define BIP_TRACE_DEBUG1(m,p1) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_BIP, TRACE_TYPE_DEBUG, m,p1);}
+#define BIP_TRACE_DEBUG2(m,p1,p2) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_BIP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define BIP_TRACE_DEBUG3(m,p1,p2,p3) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_BIP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define BIP_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_BIP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define BIP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_BIP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define BIP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_BIP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define BIP_TRACE_API0(m) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_BIP, TRACE_TYPE_API, m);}
+#define BIP_TRACE_API1(m,p1) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_BIP, TRACE_TYPE_API, m, p1);}
+#define BIP_TRACE_API2(m,p1,p2) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_BIP, TRACE_TYPE_API, m,p1,p2);}
+#define BIP_TRACE_API3(m,p1,p2,p3) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_BIP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define BIP_TRACE_API4(m,p1,p2,p3,p4) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_BIP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define BIP_TRACE_API5(m,p1,p2,p3,p4,p5) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_BIP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define BIP_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (bip_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_BIP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for TCS
+*/
+#define TCS_TRACE_ERROR0(m) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_TCS, TRACE_TYPE_ERROR, m);}
+#define TCS_TRACE_ERROR1(m,p1) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_TCS, TRACE_TYPE_ERROR, m,p1);}
+#define TCS_TRACE_ERROR2(m,p1,p2) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_TCS, TRACE_TYPE_ERROR, m,p1,p2);}
+#define TCS_TRACE_ERROR3(m,p1,p2,p3) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_TCS, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define TCS_TRACE_ERROR4(m,p1,p2,p3,p4) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_TCS, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define TCS_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_TCS, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define TCS_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_TCS, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define TCS_TRACE_WARNING0(m) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_TCS, TRACE_TYPE_WARNING, m);}
+#define TCS_TRACE_WARNING1(m,p1) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_TCS, TRACE_TYPE_WARNING, m,p1);}
+#define TCS_TRACE_WARNING2(m,p1,p2) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_TCS, TRACE_TYPE_WARNING, m,p1,p2);}
+#define TCS_TRACE_WARNING3(m,p1,p2,p3) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_TCS, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define TCS_TRACE_WARNING4(m,p1,p2,p3,p4) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_TCS, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define TCS_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_TCS, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define TCS_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_TCS, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define TCS_TRACE_EVENT0(m) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_TCS, TRACE_TYPE_EVENT, m);}
+#define TCS_TRACE_EVENT1(m,p1) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_TCS, TRACE_TYPE_EVENT, m, p1);}
+#define TCS_TRACE_EVENT2(m,p1,p2) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_TCS, TRACE_TYPE_EVENT, m,p1,p2);}
+#define TCS_TRACE_EVENT3(m,p1,p2,p3) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_TCS, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define TCS_TRACE_EVENT4(m,p1,p2,p3,p4) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_TCS, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define TCS_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_TCS, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define TCS_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_TCS, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define TCS_TRACE_DEBUG0(m) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_TCS, TRACE_TYPE_DEBUG, m);}
+#define TCS_TRACE_DEBUG1(m,p1) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_TCS, TRACE_TYPE_DEBUG, m,p1);}
+#define TCS_TRACE_DEBUG2(m,p1,p2) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_TCS, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define TCS_TRACE_DEBUG3(m,p1,p2,p3) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_TCS, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define TCS_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_TCS, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define TCS_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_TCS, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define TCS_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_TCS, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define TCS_TRACE_API0(m) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_TCS, TRACE_TYPE_API, m);}
+#define TCS_TRACE_API1(m,p1) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_TCS, TRACE_TYPE_API, m, p1);}
+#define TCS_TRACE_API2(m,p1,p2) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_TCS, TRACE_TYPE_API, m,p1,p2);}
+#define TCS_TRACE_API3(m,p1,p2,p3) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_TCS, TRACE_TYPE_API, m,p1,p2,p3);}
+#define TCS_TRACE_API4(m,p1,p2,p3,p4) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_TCS, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define TCS_TRACE_API5(m,p1,p2,p3,p4,p5) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_TCS, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define TCS_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_TCS, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for ICP
+*/
+#define ICP_TRACE_ERROR0(m) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_ICP, TRACE_TYPE_ERROR, m);}
+#define ICP_TRACE_ERROR1(m,p1) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_ICP, TRACE_TYPE_ERROR, m,p1);}
+#define ICP_TRACE_ERROR2(m,p1,p2) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_ICP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define ICP_TRACE_ERROR3(m,p1,p2,p3) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_ICP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define ICP_TRACE_ERROR4(m,p1,p2,p3,p4) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_ICP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define ICP_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_ICP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define ICP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_ICP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define ICP_TRACE_WARNING0(m) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_ICP, TRACE_TYPE_WARNING, m);}
+#define ICP_TRACE_WARNING1(m,p1) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_ICP, TRACE_TYPE_WARNING, m,p1);}
+#define ICP_TRACE_WARNING2(m,p1,p2) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_ICP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define ICP_TRACE_WARNING3(m,p1,p2,p3) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_ICP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define ICP_TRACE_WARNING4(m,p1,p2,p3,p4) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_ICP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define ICP_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_ICP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define ICP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_ICP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define ICP_TRACE_EVENT0(m) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_ICP, TRACE_TYPE_EVENT, m);}
+#define ICP_TRACE_EVENT1(m,p1) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_ICP, TRACE_TYPE_EVENT, m, p1);}
+#define ICP_TRACE_EVENT2(m,p1,p2) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_ICP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define ICP_TRACE_EVENT3(m,p1,p2,p3) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_ICP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define ICP_TRACE_EVENT4(m,p1,p2,p3,p4) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_ICP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define ICP_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_ICP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define ICP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_ICP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define ICP_TRACE_DEBUG0(m) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_ICP, TRACE_TYPE_DEBUG, m);}
+#define ICP_TRACE_DEBUG1(m,p1) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_ICP, TRACE_TYPE_DEBUG, m,p1);}
+#define ICP_TRACE_DEBUG2(m,p1,p2) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_ICP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define ICP_TRACE_DEBUG3(m,p1,p2,p3) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_ICP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define ICP_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_ICP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define ICP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_ICP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define ICP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_ICP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define ICP_TRACE_API0(m) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_ICP, TRACE_TYPE_API, m);}
+#define ICP_TRACE_API1(m,p1) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_ICP, TRACE_TYPE_API, m, p1);}
+#define ICP_TRACE_API2(m,p1,p2) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_ICP, TRACE_TYPE_API, m,p1,p2);}
+#define ICP_TRACE_API3(m,p1,p2,p3) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_ICP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define ICP_TRACE_API4(m,p1,p2,p3,p4) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_ICP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define ICP_TRACE_API5(m,p1,p2,p3,p4,p5) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_ICP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define ICP_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_ICP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+/* CTP */
+#define CTP_TRACE_ERROR0(m) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_CTP, TRACE_TYPE_ERROR, m);}
+#define CTP_TRACE_ERROR1(m,p1) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_CTP, TRACE_TYPE_ERROR, m,p1);}
+#define CTP_TRACE_ERROR2(m,p1,p2) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_CTP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define CTP_TRACE_ERROR3(m,p1,p2,p3) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_CTP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define CTP_TRACE_ERROR4(m,p1,p2,p3,p4) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_CTP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define CTP_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_CTP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define CTP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_CTP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define CTP_TRACE_WARNING0(m) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_CTP, TRACE_TYPE_WARNING, m);}
+#define CTP_TRACE_WARNING1(m,p1) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_CTP, TRACE_TYPE_WARNING, m,p1);}
+#define CTP_TRACE_WARNING2(m,p1,p2) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_CTP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define CTP_TRACE_WARNING3(m,p1,p2,p3) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_CTP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define CTP_TRACE_WARNING4(m,p1,p2,p3,p4) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_CTP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define CTP_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_CTP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define CTP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_CTP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define CTP_TRACE_EVENT0(m) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_CTP, TRACE_TYPE_EVENT, m);}
+#define CTP_TRACE_EVENT1(m,p1) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_CTP, TRACE_TYPE_EVENT, m, p1);}
+#define CTP_TRACE_EVENT2(m,p1,p2) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_CTP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define CTP_TRACE_EVENT3(m,p1,p2,p3) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_CTP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define CTP_TRACE_EVENT4(m,p1,p2,p3,p4) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_CTP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define CTP_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_CTP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define CTP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_CTP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define CTP_TRACE_DEBUG0(m) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_CTP, TRACE_TYPE_DEBUG, m);}
+#define CTP_TRACE_DEBUG1(m,p1) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_CTP, TRACE_TYPE_DEBUG, m,p1);}
+#define CTP_TRACE_DEBUG2(m,p1,p2) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_CTP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define CTP_TRACE_DEBUG3(m,p1,p2,p3) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_CTP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define CTP_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_CTP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define CTP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_CTP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define CTP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_CTP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+
+/* define traces for HID Host */
+#define HIDH_TRACE_ERROR0(m) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m);}
+#define HIDH_TRACE_ERROR1(m,p1) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m, p1);}
+#define HIDH_TRACE_ERROR2(m,p1,p2) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2);}
+#define HIDH_TRACE_ERROR3(m,p1,p2,p3) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define HIDH_TRACE_ERROR4(m,p1,p2,p3,p4) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define HIDH_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define HIDH_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define HIDH_TRACE_WARNING0(m) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m);}
+#define HIDH_TRACE_WARNING1(m,p1) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1);}
+#define HIDH_TRACE_WARNING2(m,p1,p2) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2);}
+#define HIDH_TRACE_WARNING3(m,p1,p2,p3) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define HIDH_TRACE_WARNING4(m,p1,p2,p3,p4) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define HIDH_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define HIDH_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define HIDH_TRACE_API0(m) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_API, m);}
+#define HIDH_TRACE_API1(m,p1) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_API, m, p1);}
+#define HIDH_TRACE_API2(m,p1,p2) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2);}
+#define HIDH_TRACE_API3(m,p1,p2,p3) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2,p3);}
+#define HIDH_TRACE_API4(m,p1,p2,p3,p4) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define HIDH_TRACE_API5(m,p1,p2,p3,p4,p5) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define HIDH_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define HIDH_TRACE_EVENT0(m) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m);}
+#define HIDH_TRACE_EVENT1(m,p1) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m, p1);}
+#define HIDH_TRACE_EVENT2(m,p1,p2) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2);}
+#define HIDH_TRACE_EVENT3(m,p1,p2,p3) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define HIDH_TRACE_EVENT4(m,p1,p2,p3,p4) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define HIDH_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define HIDH_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define HIDH_TRACE_DEBUG0(m) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m);}
+#define HIDH_TRACE_DEBUG1(m,p1) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1);}
+#define HIDH_TRACE_DEBUG2(m,p1,p2) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define HIDH_TRACE_DEBUG3(m,p1,p2,p3) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define HIDH_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define HIDH_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define HIDH_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* define traces for HID Device */
+#define HIDD_TRACE_ERROR0(m) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m);}
+#define HIDD_TRACE_ERROR1(m,p1) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m, p1);}
+#define HIDD_TRACE_ERROR2(m,p1,p2) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2);}
+#define HIDD_TRACE_ERROR3(m,p1,p2,p3) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define HIDD_TRACE_ERROR4(m,p1,p2,p3,p4) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define HIDD_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define HIDD_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define HIDD_TRACE_WARNING0(m) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m);}
+#define HIDD_TRACE_WARNING1(m,p1) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1);}
+#define HIDD_TRACE_WARNING2(m,p1,p2) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2);}
+#define HIDD_TRACE_WARNING3(m,p1,p2,p3) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define HIDD_TRACE_WARNING4(m,p1,p2,p3,p4) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define HIDD_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define HIDD_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define HIDD_TRACE_API0(m) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_API, m);}
+#define HIDD_TRACE_API1(m,p1) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_API, m, p1);}
+#define HIDD_TRACE_API2(m,p1,p2) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2);}
+#define HIDD_TRACE_API3(m,p1,p2,p3) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2,p3);}
+#define HIDD_TRACE_API4(m,p1,p2,p3,p4) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define HIDD_TRACE_API5(m,p1,p2,p3,p4,p5) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define HIDD_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define HIDD_TRACE_EVENT0(m) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m);}
+#define HIDD_TRACE_EVENT1(m,p1) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m, p1);}
+#define HIDD_TRACE_EVENT2(m,p1,p2) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2);}
+#define HIDD_TRACE_EVENT3(m,p1,p2,p3) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define HIDD_TRACE_EVENT4(m,p1,p2,p3,p4) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define HIDD_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define HIDD_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define HIDD_TRACE_DEBUG0(m) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m);}
+#define HIDD_TRACE_DEBUG1(m,p1) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1);}
+#define HIDD_TRACE_DEBUG2(m,p1,p2) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define HIDD_TRACE_DEBUG3(m,p1,p2,p3) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define HIDD_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define HIDD_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define HIDD_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* define traces for headset profile */
+#define HSP2_TRACE_ERROR0(pcb,m) {if (pcb->trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_HSP2, TRACE_TYPE_ERROR, m);}
+#define HSP2_TRACE_ERROR1(pcb,m,p1) {if (pcb->trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_HSP2, TRACE_TYPE_ERROR, m, p1);}
+#define HSP2_TRACE_ERROR2(pcb,m,p1,p2) {if (pcb->trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_HSP2, TRACE_TYPE_ERROR, m,p1,p2);}
+#define HSP2_TRACE_ERROR3(pcb,m,p1,p2,p3) {if (pcb->trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_HSP2, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define HSP2_TRACE_ERROR4(pcb,m,p1,p2,p3,p4) {if (pcb->trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_HSP2, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define HSP2_TRACE_ERROR5(pcb,m,p1,p2,p3,p4,p5) {if (pcb->trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_HSP2, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define HSP2_TRACE_ERROR6(pcb,m,p1,p2,p3,p4,p5,p6) {if (pcb->trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_HSP2, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define HSP2_TRACE_WARNING0(pcb,m) {if (pcb->trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_HSP2, TRACE_TYPE_WARNING, m);}
+#define HSP2_TRACE_WARNING1(pcb,m,p1) {if (pcb->trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_HSP2, TRACE_TYPE_WARNING, m,p1);}
+#define HSP2_TRACE_WARNING2(pcb,m,p1,p2) {if (pcb->trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_HSP2, TRACE_TYPE_WARNING, m,p1,p2);}
+#define HSP2_TRACE_WARNING3(pcb,m,p1,p2,p3) {if (pcb->trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_HSP2, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define HSP2_TRACE_WARNING4(pcb,m,p1,p2,p3,p4) {if (pcb->trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_HSP2, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define HSP2_TRACE_WARNING5(pcb,m,p1,p2,p3,p4,p5) {if (pcb->trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_HSP2, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define HSP2_TRACE_WARNING6(pcb,m,p1,p2,p3,p4,p5,p6) {if (pcb->trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_HSP2, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define HSP2_TRACE_API0(pcb,m) {if (pcb->trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_HSP2, TRACE_TYPE_API, m);}
+#define HSP2_TRACE_API1(pcb,m,p1) {if (pcb->trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_HSP2, TRACE_TYPE_API, m, p1);}
+#define HSP2_TRACE_API2(pcb,m,p1,p2) {if (pcb->trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_HSP2, TRACE_TYPE_API, m,p1,p2);}
+#define HSP2_TRACE_API3(pcb,m,p1,p2,p3) {if (pcb->trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_HSP2, TRACE_TYPE_API, m,p1,p2,p3);}
+#define HSP2_TRACE_API4(pcb,m,p1,p2,p3,p4) {if (pcb->trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_HSP2, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define HSP2_TRACE_API5(pcb,m,p1,p2,p3,p4,p5) {if (pcb->trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_HSP2, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define HSP2_TRACE_API6(pcb,m,p1,p2,p3,p4,p5,p6) {if (pcb->trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_HSP2, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define HSP2_TRACE_EVENT0(pcb,m) {if (pcb->trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_HSP2, TRACE_TYPE_EVENT, m);}
+#define HSP2_TRACE_EVENT1(pcb,m,p1) {if (pcb->trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_HSP2, TRACE_TYPE_EVENT, m, p1);}
+#define HSP2_TRACE_EVENT2(pcb,m,p1,p2) {if (pcb->trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_HSP2, TRACE_TYPE_EVENT, m,p1,p2);}
+#define HSP2_TRACE_EVENT3(pcb,m,p1,p2,p3) {if (pcb->trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_HSP2, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define HSP2_TRACE_EVENT4(pcb,m,p1,p2,p3,p4) {if (pcb->trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_HSP2, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define HSP2_TRACE_EVENT5(pcb,m,p1,p2,p3,p4,p5) {if (pcb->trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_HSP2, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define HSP2_TRACE_EVENT6(pcb,m,p1,p2,p3,p4,p5,p6) {if (pcb->trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_HSP2, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define HSP2_TRACE_DEBUG0(pcb,m) {if (pcb->trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_HSP2, TRACE_TYPE_DEBUG, m);}
+#define HSP2_TRACE_DEBUG1(pcb,m,p1) {if (pcb->trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_HSP2, TRACE_TYPE_DEBUG, m,p1);}
+#define HSP2_TRACE_DEBUG2(pcb,m,p1,p2) {if (pcb->trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_HSP2, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define HSP2_TRACE_DEBUG3(pcb,m,p1,p2,p3) {if (pcb->trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_HSP2, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define HSP2_TRACE_DEBUG4(pcb,m,p1,p2,p3,p4) {if (pcb->trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_HSP2, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define HSP2_TRACE_DEBUG5(pcb,m,p1,p2,p3,p4,p5) {if (pcb->trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_HSP2, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define HSP2_TRACE_DEBUG6(pcb,m,p1,p2,p3,p4,p5,p6) {if (pcb->trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_HSP2, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the NFC unit
+*/
+#define NFC_TRACE_ERROR0(m) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_NFC, TRACE_TYPE_ERROR, m);}
+#define NFC_TRACE_ERROR1(m,p1) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_NFC, TRACE_TYPE_ERROR, m,p1);}
+#define NFC_TRACE_ERROR2(m,p1,p2) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_NFC, TRACE_TYPE_ERROR, m,p1,p2);}
+#define NFC_TRACE_ERROR3(m,p1,p2,p3) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_NFC, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define NFC_TRACE_ERROR4(m,p1,p2,p3,p4) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_NFC, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define NFC_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_NFC, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define NFC_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_NFC, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define NFC_TRACE_WARNING0(m) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_NFC, TRACE_TYPE_WARNING, m);}
+#define NFC_TRACE_WARNING1(m,p1) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_NFC, TRACE_TYPE_WARNING, m,p1);}
+#define NFC_TRACE_WARNING2(m,p1,p2) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_NFC, TRACE_TYPE_WARNING, m,p1,p2);}
+#define NFC_TRACE_WARNING3(m,p1,p2,p3) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_NFC, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define NFC_TRACE_WARNING4(m,p1,p2,p3,p4) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_NFC, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define NFC_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_NFC, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define NFC_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_NFC, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define NFC_TRACE_API0(m) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_NFC, TRACE_TYPE_API, m);}
+#define NFC_TRACE_API1(m,p1) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_NFC, TRACE_TYPE_API, m,p1);}
+#define NFC_TRACE_API2(m,p1,p2) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_NFC, TRACE_TYPE_API, m,p1,p2);}
+#define NFC_TRACE_API3(m,p1,p2,p3) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_NFC, TRACE_TYPE_API, m,p1,p2,p3);}
+#define NFC_TRACE_API4(m,p1,p2,p3,p4) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_NFC, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define NFC_TRACE_API5(m,p1,p2,p3,p4,p5) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_NFC, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define NFC_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_NFC, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define NFC_TRACE_EVENT0(m) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_NFC, TRACE_TYPE_EVENT, m);}
+#define NFC_TRACE_EVENT1(m,p1) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_NFC, TRACE_TYPE_EVENT, m, p1);}
+#define NFC_TRACE_EVENT2(m,p1,p2) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_NFC, TRACE_TYPE_EVENT, m,p1,p2);}
+#define NFC_TRACE_EVENT3(m,p1,p2,p3) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_NFC, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define NFC_TRACE_EVENT4(m,p1,p2,p3,p4) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_NFC, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define NFC_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_NFC, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define NFC_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_NFC, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define NFC_TRACE_DEBUG0(m) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_NFC, TRACE_TYPE_DEBUG, m);}
+#define NFC_TRACE_DEBUG1(m,p1) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_NFC, TRACE_TYPE_DEBUG, m,p1);}
+#define NFC_TRACE_DEBUG2(m,p1,p2) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_NFC, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define NFC_TRACE_DEBUG3(m,p1,p2,p3) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_NFC, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define NFC_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_NFC, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define NFC_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_NFC, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define NFC_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_NFC, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define NCI_TRACE_ERROR0(m) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m);}
+#define NCI_TRACE_ERROR1(m,p1) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1);}
+#define NCI_TRACE_ERROR2(m,p1,p2) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1,p2);}
+#define NCI_TRACE_ERROR3(m,p1,p2,p3) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define NCI_TRACE_ERROR4(m,p1,p2,p3,p4) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define NCI_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define NCI_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define NCI_TRACE_WARNING0(m) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m);}
+#define NCI_TRACE_WARNING1(m,p1) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1);}
+#define NCI_TRACE_WARNING2(m,p1,p2) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1,p2);}
+#define NCI_TRACE_WARNING3(m,p1,p2,p3) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define NCI_TRACE_WARNING4(m,p1,p2,p3,p4) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define NCI_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define NCI_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define NCI_TRACE_API0(m) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_API, m);}
+#define NCI_TRACE_API1(m,p1) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1);}
+#define NCI_TRACE_API2(m,p1,p2) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1,p2);}
+#define NCI_TRACE_API3(m,p1,p2,p3) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1,p2,p3);}
+#define NCI_TRACE_API4(m,p1,p2,p3,p4) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define NCI_TRACE_API5(m,p1,p2,p3,p4,p5) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define NCI_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define NCI_TRACE_EVENT0(m) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m);}
+#define NCI_TRACE_EVENT1(m,p1) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m, p1);}
+#define NCI_TRACE_EVENT2(m,p1,p2) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m,p1,p2);}
+#define NCI_TRACE_EVENT3(m,p1,p2,p3) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define NCI_TRACE_EVENT4(m,p1,p2,p3,p4) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define NCI_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define NCI_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define NCI_TRACE_DEBUG0(m) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m);}
+#define NCI_TRACE_DEBUG1(m,p1) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1);}
+#define NCI_TRACE_DEBUG2(m,p1,p2) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define NCI_TRACE_DEBUG3(m,p1,p2,p3) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define NCI_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define NCI_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define NCI_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define RW_TRACE_ERROR0(m) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_RW, TRACE_TYPE_ERROR, m);}
+#define RW_TRACE_ERROR1(m,p1) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_RW, TRACE_TYPE_ERROR, m,p1);}
+#define RW_TRACE_ERROR2(m,p1,p2) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_RW, TRACE_TYPE_ERROR, m,p1,p2);}
+#define RW_TRACE_ERROR3(m,p1,p2,p3) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_RW, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define RW_TRACE_ERROR4(m,p1,p2,p3,p4) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_RW, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define RW_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_RW, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define RW_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_RW, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define RW_TRACE_WARNING0(m) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_RW, TRACE_TYPE_WARNING, m);}
+#define RW_TRACE_WARNING1(m,p1) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_RW, TRACE_TYPE_WARNING, m,p1);}
+#define RW_TRACE_WARNING2(m,p1,p2) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_RW, TRACE_TYPE_WARNING, m,p1,p2);}
+#define RW_TRACE_WARNING3(m,p1,p2,p3) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_RW, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define RW_TRACE_WARNING4(m,p1,p2,p3,p4) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_RW, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define RW_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_RW, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define RW_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_RW, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define RW_TRACE_API0(m) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_RW, TRACE_TYPE_API, m);}
+#define RW_TRACE_API1(m,p1) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_RW, TRACE_TYPE_API, m,p1);}
+#define RW_TRACE_API2(m,p1,p2) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_RW, TRACE_TYPE_API, m,p1,p2);}
+#define RW_TRACE_API3(m,p1,p2,p3) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_RW, TRACE_TYPE_API, m,p1,p2,p3);}
+#define RW_TRACE_API4(m,p1,p2,p3,p4) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_RW, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define RW_TRACE_API5(m,p1,p2,p3,p4,p5) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_RW, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define RW_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_RW, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define RW_TRACE_EVENT0(m) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_RW, TRACE_TYPE_EVENT, m);}
+#define RW_TRACE_EVENT1(m,p1) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_RW, TRACE_TYPE_EVENT, m, p1);}
+#define RW_TRACE_EVENT2(m,p1,p2) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_RW, TRACE_TYPE_EVENT, m,p1,p2);}
+#define RW_TRACE_EVENT3(m,p1,p2,p3) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_RW, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define RW_TRACE_EVENT4(m,p1,p2,p3,p4) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_RW, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define RW_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_RW, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define RW_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_RW, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define RW_TRACE_DEBUG0(m) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_RW, TRACE_TYPE_DEBUG, m);}
+#define RW_TRACE_DEBUG1(m,p1) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_RW, TRACE_TYPE_DEBUG, m,p1);}
+#define RW_TRACE_DEBUG2(m,p1,p2) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_RW, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define RW_TRACE_DEBUG3(m,p1,p2,p3) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_RW, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define RW_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_RW, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define RW_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_RW, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define RW_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_RW, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define CE_TRACE_ERROR0(m) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_CE, TRACE_TYPE_ERROR, m);}
+#define CE_TRACE_ERROR1(m,p1) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_CE, TRACE_TYPE_ERROR, m,p1);}
+#define CE_TRACE_ERROR2(m,p1,p2) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_CE, TRACE_TYPE_ERROR, m,p1,p2);}
+#define CE_TRACE_ERROR3(m,p1,p2,p3) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_CE, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define CE_TRACE_ERROR4(m,p1,p2,p3,p4) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_CE, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define CE_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_CE, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define CE_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_CE, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define CE_TRACE_WARNING0(m) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_CE, TRACE_TYPE_WARNING, m);}
+#define CE_TRACE_WARNING1(m,p1) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_CE, TRACE_TYPE_WARNING, m,p1);}
+#define CE_TRACE_WARNING2(m,p1,p2) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_CE, TRACE_TYPE_WARNING, m,p1,p2);}
+#define CE_TRACE_WARNING3(m,p1,p2,p3) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_CE, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define CE_TRACE_WARNING4(m,p1,p2,p3,p4) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_CE, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define CE_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_CE, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define CE_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_CE, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define CE_TRACE_API0(m) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_CE, TRACE_TYPE_API, m);}
+#define CE_TRACE_API1(m,p1) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_CE, TRACE_TYPE_API, m,p1);}
+#define CE_TRACE_API2(m,p1,p2) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_CE, TRACE_TYPE_API, m,p1,p2);}
+#define CE_TRACE_API3(m,p1,p2,p3) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_CE, TRACE_TYPE_API, m,p1,p2,p3);}
+#define CE_TRACE_API4(m,p1,p2,p3,p4) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_CE, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define CE_TRACE_API5(m,p1,p2,p3,p4,p5) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_CE, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define CE_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_CE, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define CE_TRACE_EVENT0(m) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_CE, TRACE_TYPE_EVENT, m);}
+#define CE_TRACE_EVENT1(m,p1) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_CE, TRACE_TYPE_EVENT, m, p1);}
+#define CE_TRACE_EVENT2(m,p1,p2) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_CE, TRACE_TYPE_EVENT, m,p1,p2);}
+#define CE_TRACE_EVENT3(m,p1,p2,p3) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_CE, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define CE_TRACE_EVENT4(m,p1,p2,p3,p4) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_CE, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define CE_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_CE, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define CE_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_CE, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define CE_TRACE_DEBUG0(m) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_CE, TRACE_TYPE_DEBUG, m);}
+#define CE_TRACE_DEBUG1(m,p1) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_CE, TRACE_TYPE_DEBUG, m,p1);}
+#define CE_TRACE_DEBUG2(m,p1,p2) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_CE, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define CE_TRACE_DEBUG3(m,p1,p2,p3) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_CE, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define CE_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_CE, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define CE_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_CE, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define CE_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_CE, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define NDEF_TRACE_ERROR0(m) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_NDEF, TRACE_TYPE_ERROR, m);}
+#define NDEF_TRACE_ERROR1(m,p1) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_NDEF, TRACE_TYPE_ERROR, m,p1);}
+#define NDEF_TRACE_ERROR2(m,p1,p2) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_NDEF, TRACE_TYPE_ERROR, m,p1,p2);}
+#define NDEF_TRACE_ERROR3(m,p1,p2,p3) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_NDEF, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define NDEF_TRACE_ERROR4(m,p1,p2,p3,p4) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_NDEF, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define NDEF_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_NDEF, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define NDEF_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_NDEF, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define NDEF_TRACE_WARNING0(m) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_NDEF, TRACE_TYPE_WARNING, m);}
+#define NDEF_TRACE_WARNING1(m,p1) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_NDEF, TRACE_TYPE_WARNING, m,p1);}
+#define NDEF_TRACE_WARNING2(m,p1,p2) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_NDEF, TRACE_TYPE_WARNING, m,p1,p2);}
+#define NDEF_TRACE_WARNING3(m,p1,p2,p3) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_NDEF, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define NDEF_TRACE_WARNING4(m,p1,p2,p3,p4) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_NDEF, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define NDEF_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_NDEF, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define NDEF_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_NDEF, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define NDEF_TRACE_API0(m) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_NDEF, TRACE_TYPE_API, m);}
+#define NDEF_TRACE_API1(m,p1) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_NDEF, TRACE_TYPE_API, m,p1);}
+#define NDEF_TRACE_API2(m,p1,p2) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_NDEF, TRACE_TYPE_API, m,p1,p2);}
+#define NDEF_TRACE_API3(m,p1,p2,p3) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_NDEF, TRACE_TYPE_API, m,p1,p2,p3);}
+#define NDEF_TRACE_API4(m,p1,p2,p3,p4) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_NDEF, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define NDEF_TRACE_API5(m,p1,p2,p3,p4,p5) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_NDEF, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define NDEF_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_NDEF, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define NDEF_TRACE_EVENT0(m) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_NDEF, TRACE_TYPE_EVENT, m);}
+#define NDEF_TRACE_EVENT1(m,p1) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_NDEF, TRACE_TYPE_EVENT, m, p1);}
+#define NDEF_TRACE_EVENT2(m,p1,p2) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_NDEF, TRACE_TYPE_EVENT, m,p1,p2);}
+#define NDEF_TRACE_EVENT3(m,p1,p2,p3) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_NDEF, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define NDEF_TRACE_EVENT4(m,p1,p2,p3,p4) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_NDEF, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define NDEF_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_NDEF, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define NDEF_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_NDEF, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define NDEF_TRACE_DEBUG0(m) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_NDEF, TRACE_TYPE_DEBUG, m);}
+#define NDEF_TRACE_DEBUG1(m,p1) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_NDEF, TRACE_TYPE_DEBUG, m,p1);}
+#define NDEF_TRACE_DEBUG2(m,p1,p2) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_NDEF, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define NDEF_TRACE_DEBUG3(m,p1,p2,p3) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_NDEF, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define NDEF_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_NDEF, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define NDEF_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_NDEF, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define NDEF_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_NDEF, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the NFA unit
+*/
+#define NFA_TRACE_ERROR0(m) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_NFA, TRACE_TYPE_ERROR, m);}
+#define NFA_TRACE_ERROR1(m,p1) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_NFA, TRACE_TYPE_ERROR, m,p1);}
+#define NFA_TRACE_ERROR2(m,p1,p2) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_NFA, TRACE_TYPE_ERROR, m,p1,p2);}
+#define NFA_TRACE_ERROR3(m,p1,p2,p3) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_NFA, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define NFA_TRACE_ERROR4(m,p1,p2,p3,p4) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_NFA, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define NFA_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_NFA, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define NFA_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_NFA, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define NFA_TRACE_WARNING0(m) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_NFA, TRACE_TYPE_WARNING, m);}
+#define NFA_TRACE_WARNING1(m,p1) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_NFA, TRACE_TYPE_WARNING, m,p1);}
+#define NFA_TRACE_WARNING2(m,p1,p2) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_NFA, TRACE_TYPE_WARNING, m,p1,p2);}
+#define NFA_TRACE_WARNING3(m,p1,p2,p3) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_NFA, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define NFA_TRACE_WARNING4(m,p1,p2,p3,p4) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_NFA, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define NFA_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_NFA, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define NFA_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_NFA, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define NFA_TRACE_API0(m) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_NFA, TRACE_TYPE_API, m);}
+#define NFA_TRACE_API1(m,p1) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_NFA, TRACE_TYPE_API, m,p1);}
+#define NFA_TRACE_API2(m,p1,p2) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_NFA, TRACE_TYPE_API, m,p1,p2);}
+#define NFA_TRACE_API3(m,p1,p2,p3) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_NFA, TRACE_TYPE_API, m,p1,p2,p3);}
+#define NFA_TRACE_API4(m,p1,p2,p3,p4) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_NFA, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define NFA_TRACE_API5(m,p1,p2,p3,p4,p5) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_NFA, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define NFA_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_NFA, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define NFA_TRACE_EVENT0(m) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_NFA, TRACE_TYPE_EVENT, m);}
+#define NFA_TRACE_EVENT1(m,p1) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_NFA, TRACE_TYPE_EVENT, m, p1);}
+#define NFA_TRACE_EVENT2(m,p1,p2) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_NFA, TRACE_TYPE_EVENT, m,p1,p2);}
+#define NFA_TRACE_EVENT3(m,p1,p2,p3) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_NFA, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define NFA_TRACE_EVENT4(m,p1,p2,p3,p4) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_NFA, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define NFA_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_NFA, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define NFA_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_NFA, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define NFA_TRACE_DEBUG0(m) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_NFA, TRACE_TYPE_DEBUG, m);}
+#define NFA_TRACE_DEBUG1(m,p1) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_NFA, TRACE_TYPE_DEBUG, m,p1);}
+#define NFA_TRACE_DEBUG2(m,p1,p2) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_NFA, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define NFA_TRACE_DEBUG3(m,p1,p2,p3) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_NFA, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define NFA_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_NFA, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define NFA_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_NFA, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define NFA_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_NFA, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the NFA P2P unit
+*/
+#define P2P_TRACE_ERROR0(m) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_P2P, TRACE_TYPE_ERROR, m);}
+#define P2P_TRACE_ERROR1(m,p1) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_P2P, TRACE_TYPE_ERROR, m,p1);}
+#define P2P_TRACE_ERROR2(m,p1,p2) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_P2P, TRACE_TYPE_ERROR, m,p1,p2);}
+#define P2P_TRACE_ERROR3(m,p1,p2,p3) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_P2P, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define P2P_TRACE_ERROR4(m,p1,p2,p3,p4) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_P2P, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define P2P_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_P2P, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define P2P_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_P2P, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define P2P_TRACE_WARNING0(m) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_P2P, TRACE_TYPE_WARNING, m);}
+#define P2P_TRACE_WARNING1(m,p1) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_P2P, TRACE_TYPE_WARNING, m,p1);}
+#define P2P_TRACE_WARNING2(m,p1,p2) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_P2P, TRACE_TYPE_WARNING, m,p1,p2);}
+#define P2P_TRACE_WARNING3(m,p1,p2,p3) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_P2P, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define P2P_TRACE_WARNING4(m,p1,p2,p3,p4) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_P2P, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define P2P_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_P2P, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define P2P_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_P2P, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define P2P_TRACE_API0(m) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_P2P, TRACE_TYPE_API, m);}
+#define P2P_TRACE_API1(m,p1) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_P2P, TRACE_TYPE_API, m,p1);}
+#define P2P_TRACE_API2(m,p1,p2) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_P2P, TRACE_TYPE_API, m,p1,p2);}
+#define P2P_TRACE_API3(m,p1,p2,p3) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_P2P, TRACE_TYPE_API, m,p1,p2,p3);}
+#define P2P_TRACE_API4(m,p1,p2,p3,p4) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_P2P, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define P2P_TRACE_API5(m,p1,p2,p3,p4,p5) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_P2P, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define P2P_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_P2P, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define P2P_TRACE_EVENT0(m) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_P2P, TRACE_TYPE_EVENT, m);}
+#define P2P_TRACE_EVENT1(m,p1) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_P2P, TRACE_TYPE_EVENT, m, p1);}
+#define P2P_TRACE_EVENT2(m,p1,p2) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_P2P, TRACE_TYPE_EVENT, m,p1,p2);}
+#define P2P_TRACE_EVENT3(m,p1,p2,p3) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_P2P, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define P2P_TRACE_EVENT4(m,p1,p2,p3,p4) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_P2P, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define P2P_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_P2P, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define P2P_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_P2P, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define P2P_TRACE_DEBUG0(m) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_P2P, TRACE_TYPE_DEBUG, m);}
+#define P2P_TRACE_DEBUG1(m,p1) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_P2P, TRACE_TYPE_DEBUG, m,p1);}
+#define P2P_TRACE_DEBUG2(m,p1,p2) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_P2P, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define P2P_TRACE_DEBUG3(m,p1,p2,p3) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_P2P, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define P2P_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_P2P, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define P2P_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_P2P, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define P2P_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_P2P, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the NFA CHO unit
+*/
+#define CHO_TRACE_ERROR0(m) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_CHO, TRACE_TYPE_ERROR, m);}
+#define CHO_TRACE_ERROR1(m,p1) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_CHO, TRACE_TYPE_ERROR, m,p1);}
+#define CHO_TRACE_ERROR2(m,p1,p2) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_CHO, TRACE_TYPE_ERROR, m,p1,p2);}
+#define CHO_TRACE_ERROR3(m,p1,p2,p3) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_CHO, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define CHO_TRACE_ERROR4(m,p1,p2,p3,p4) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_CHO, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define CHO_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_CHO, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define CHO_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_CHO, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define CHO_TRACE_WARNING0(m) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_CHO, TRACE_TYPE_WARNING, m);}
+#define CHO_TRACE_WARNING1(m,p1) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_CHO, TRACE_TYPE_WARNING, m,p1);}
+#define CHO_TRACE_WARNING2(m,p1,p2) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_CHO, TRACE_TYPE_WARNING, m,p1,p2);}
+#define CHO_TRACE_WARNING3(m,p1,p2,p3) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_CHO, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define CHO_TRACE_WARNING4(m,p1,p2,p3,p4) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_CHO, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define CHO_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_CHO, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define CHO_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_CHO, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define CHO_TRACE_API0(m) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_CHO, TRACE_TYPE_API, m);}
+#define CHO_TRACE_API1(m,p1) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_CHO, TRACE_TYPE_API, m,p1);}
+#define CHO_TRACE_API2(m,p1,p2) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_CHO, TRACE_TYPE_API, m,p1,p2);}
+#define CHO_TRACE_API3(m,p1,p2,p3) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_CHO, TRACE_TYPE_API, m,p1,p2,p3);}
+#define CHO_TRACE_API4(m,p1,p2,p3,p4) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_CHO, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define CHO_TRACE_API5(m,p1,p2,p3,p4,p5) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_CHO, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define CHO_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_CHO, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define CHO_TRACE_EVENT0(m) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_CHO, TRACE_TYPE_EVENT, m);}
+#define CHO_TRACE_EVENT1(m,p1) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_CHO, TRACE_TYPE_EVENT, m, p1);}
+#define CHO_TRACE_EVENT2(m,p1,p2) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_CHO, TRACE_TYPE_EVENT, m,p1,p2);}
+#define CHO_TRACE_EVENT3(m,p1,p2,p3) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_CHO, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define CHO_TRACE_EVENT4(m,p1,p2,p3,p4) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_CHO, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define CHO_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_CHO, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define CHO_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_CHO, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define CHO_TRACE_DEBUG0(m) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_CHO, TRACE_TYPE_DEBUG, m);}
+#define CHO_TRACE_DEBUG1(m,p1) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_CHO, TRACE_TYPE_DEBUG, m,p1);}
+#define CHO_TRACE_DEBUG2(m,p1,p2) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_CHO, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define CHO_TRACE_DEBUG3(m,p1,p2,p3) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_CHO, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define CHO_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_CHO, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define CHO_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_CHO, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define CHO_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_CHO, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the NFA SNEP unit
+*/
+#define SNEP_TRACE_ERROR0(m) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_SNEP, TRACE_TYPE_ERROR, m);}
+#define SNEP_TRACE_ERROR1(m,p1) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_SNEP, TRACE_TYPE_ERROR, m,p1);}
+#define SNEP_TRACE_ERROR2(m,p1,p2) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_SNEP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define SNEP_TRACE_ERROR3(m,p1,p2,p3) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_SNEP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define SNEP_TRACE_ERROR4(m,p1,p2,p3,p4) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_SNEP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define SNEP_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_SNEP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define SNEP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_SNEP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define SNEP_TRACE_WARNING0(m) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_SNEP, TRACE_TYPE_WARNING, m);}
+#define SNEP_TRACE_WARNING1(m,p1) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_SNEP, TRACE_TYPE_WARNING, m,p1);}
+#define SNEP_TRACE_WARNING2(m,p1,p2) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_SNEP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define SNEP_TRACE_WARNING3(m,p1,p2,p3) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_SNEP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define SNEP_TRACE_WARNING4(m,p1,p2,p3,p4) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_SNEP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define SNEP_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_SNEP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define SNEP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_SNEP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define SNEP_TRACE_API0(m) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_SNEP, TRACE_TYPE_API, m);}
+#define SNEP_TRACE_API1(m,p1) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_SNEP, TRACE_TYPE_API, m,p1);}
+#define SNEP_TRACE_API2(m,p1,p2) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_SNEP, TRACE_TYPE_API, m,p1,p2);}
+#define SNEP_TRACE_API3(m,p1,p2,p3) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_SNEP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define SNEP_TRACE_API4(m,p1,p2,p3,p4) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_SNEP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define SNEP_TRACE_API5(m,p1,p2,p3,p4,p5) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_SNEP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define SNEP_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_SNEP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define SNEP_TRACE_EVENT0(m) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_SNEP, TRACE_TYPE_EVENT, m);}
+#define SNEP_TRACE_EVENT1(m,p1) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_SNEP, TRACE_TYPE_EVENT, m, p1);}
+#define SNEP_TRACE_EVENT2(m,p1,p2) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_SNEP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define SNEP_TRACE_EVENT3(m,p1,p2,p3) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_SNEP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define SNEP_TRACE_EVENT4(m,p1,p2,p3,p4) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_SNEP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define SNEP_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_SNEP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define SNEP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_SNEP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define SNEP_TRACE_DEBUG0(m) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_SNEP, TRACE_TYPE_DEBUG, m);}
+#define SNEP_TRACE_DEBUG1(m,p1) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_SNEP, TRACE_TYPE_DEBUG, m,p1);}
+#define SNEP_TRACE_DEBUG2(m,p1,p2) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_SNEP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define SNEP_TRACE_DEBUG3(m,p1,p2,p3) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_SNEP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define SNEP_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_SNEP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define SNEP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_SNEP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define SNEP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_SNEP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define MMI_TRACE_0(m)
+#define MMI_TRACE_1(m,p1)
+#define MMI_TRACE_2(m,p1,p2)
+#define MMI_TRACE_3(m,p1,p2,p3)
+#define MMI_TRACE_4(m,p1,p2,p3,p4)
+#define MMI_TRACE_5(m,p1,p2,p3,p4,p5)
+#define MMI_TRACE_6(m,p1,p2,p3,p4,p5,p6)
+
+#define MMI_DEBUG_0(m) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m)
+#define MMI_DEBUG_1(m,p1) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1)
+#define MMI_DEBUG_2(m,p1,p2) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2)
+#define MMI_DEBUG_3(m,p1,p2,p3) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3)
+#define MMI_DEBUG_4(m,p1,p2,p3,p4) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4)
+#define MMI_DEBUG_5(m,p1,p2,p3,p4,p5) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5)
+#define MMI_DEBUG_6(m,p1,p2,p3,p4,p5,p6) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6)
+
+#define MMI_WARNING_0(m) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m)
+#define MMI_WARNING_1(m,p1) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1)
+#define MMI_WARNING_2(m,p1,p2) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2)
+#define MMI_WARNING_3(m,p1,p2,p3) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3)
+#define MMI_WARNING_4(m,p1,p2,p3,p4) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3,p4)
+#define MMI_WARNING_5(m,p1,p2,p3,p4,p5) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5)
+#define MMI_WARNING_6(m,p1,p2,p3,p4,p5,p6) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6)
+
+#define MMI_ERROR_0(m) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m)
+#define MMI_ERROR_1(m,p1) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1)
+#define MMI_ERROR_2(m,p1,p2) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2)
+#define MMI_ERROR_3(m,p1,p2,p3) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3)
+#define MMI_ERROR_4(m,p1,p2,p3,p4) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3,p4)
+#define MMI_ERROR_5(m,p1,p2,p3,p4,p5) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5)
+#define MMI_ERROR_6(m,p1,p2,p3,p4,p5,p6) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6)
+
+#define TAK_TRACE_0(m) MMI_Echo(m)
+
+/* hid mouse module traces */
+
+#define MSKB_TRACE_0(m) MMI_Echo(m)
+#define MSKB_TRACE_1(m,p1) MMI_Echo(m,p1)
+#define MSKB_TRACE_2(m,p1,p2) MMI_Echo(m,p1,p2)
+#define MSKB_TRACE_3(m,p1,p2,p3) MMI_Echo(m,p1,p2,p3)
+#define MSKB_TRACE_4(m,p1,p2,p3,p4) MMI_Echo(m,p1,p2,p3,p4)
+#define MSKB_TRACE_5(m,p1,p2,p3,p4,p5) MMI_Echo(m,p1,p2,p3,p4,p5)
+#define MSKB_TRACE_6(m,p1,p2,p3,p4,p5,p6) MMI_Echo(m,p1,p2,p3,p4,p5,p6)
+
+#define MSKB_DEBUG_0(m) MMI_Echo(m)
+#define MSKB_DEBUG_1(m,p1) MMI_Echo(m,p1)
+#define MSKB_DEBUG_2(m,p1,p2) MMI_Echo(m,p1,p2)
+#define MSKB_DEBUG_3(m,p1,p2,p3) MMI_Echo(m,p1,p2,p3)
+#define MSKB_DEBUG_4(m,p1,p2,p3,p4) MMI_Echo(m,p1,p2,p3,p4)
+#define MSKB_DEBUG_5(m,p1,p2,p3,p4,p5) MMI_Echo(m,p1,p2,p3,p4,p5)
+#define MSKB_DEBUG_6(m,p1,p2,p3,p4,p5,p6) MMI_Echo(m,p1,p2,p3,p4,p5,p6)
+
+#define MSKB_ERROR_0(m) MMI_Echo(m)
+#define MSKB_ERROR_1(m,p1) MMI_Echo(m,p1)
+#define MSKB_ERROR_2(m,p1,p2) MMI_Echo(m,p1,p2)
+#define MSKB_ERROR_3(m,p1,p2,p3) MMI_Echo(m,p1,p2,p3)
+#define MSKB_ERROR_4(m,p1,p2,p3,p4) MMI_Echo(m,p1,p2,p3,p4)
+#define MSKB_ERROR_5(m,p1,p2,p3,p4,p5) MMI_Echo(m,p1,p2,p3,p4,p5)
+#define MSKB_ERROR_6(m,p1,p2,p3,p4,p5,p6) MMI_Echo(m,p1,p2,p3,p4,p5,p6)
+
+/* define traces for DUN */
+
+#define DUN_TRACE_ERROR0(m) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_DUN, TRACE_TYPE_ERROR, m);}
+#define DUN_TRACE_ERROR1(m,p1) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_DUN, TRACE_TYPE_ERROR, m, p1);}
+#define DUN_TRACE_ERROR2(m,p1,p2) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_DUN, TRACE_TYPE_ERROR, m,p1,p2);}
+#define DUN_TRACE_ERROR3(m,p1,p2,p3) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_DUN, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define DUN_TRACE_ERROR4(m,p1,p2,p3,p4) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_DUN, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define DUN_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_DUN, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define DUN_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_DUN, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define DUN_TRACE_WARNING0(m) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_DUN, TRACE_TYPE_WARNING, m);}
+#define DUN_TRACE_WARNING1(m,p1) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_DUN, TRACE_TYPE_WARNING, m,p1);}
+#define DUN_TRACE_WARNING2(m,p1,p2) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_DUN, TRACE_TYPE_WARNING, m,p1,p2);}
+#define DUN_TRACE_WARNING3(m,p1,p2,p3) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_DUN, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define DUN_TRACE_WARNING4(m,p1,p2,p3,p4) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_DUN, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define DUN_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_DUN, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define DUN_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_DUN, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define DUN_TRACE_API0(m) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_DUN, TRACE_TYPE_API, m);}
+#define DUN_TRACE_API1(m,p1) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_DUN, TRACE_TYPE_API, m, p1);}
+#define DUN_TRACE_API2(m,p1,p2) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_DUN, TRACE_TYPE_API, m,p1,p2);}
+#define DUN_TRACE_API3(m,p1,p2,p3) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_DUN, TRACE_TYPE_API, m,p1,p2,p3);}
+#define DUN_TRACE_API4(m,p1,p2,p3,p4) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_DUN, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define DUN_TRACE_API5(m,p1,p2,p3,p4,p5) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_DUN, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define DUN_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_DUN, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define DUN_TRACE_EVENT0(m) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_DUN, TRACE_TYPE_EVENT, m);}
+#define DUN_TRACE_EVENT1(m,p1) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_DUN, TRACE_TYPE_EVENT, m, p1);}
+#define DUN_TRACE_EVENT2(m,p1,p2) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_DUN, TRACE_TYPE_EVENT, m,p1,p2);}
+#define DUN_TRACE_EVENT3(m,p1,p2,p3) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_DUN, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define DUN_TRACE_EVENT4(m,p1,p2,p3,p4) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_DUN, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define DUN_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_DUN, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define DUN_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_DUN, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define DUN_TRACE_DEBUG0(m) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_DUN, TRACE_TYPE_DEBUG, m);}
+#define DUN_TRACE_DEBUG1(m,p1) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_DUN, TRACE_TYPE_DEBUG, m,p1);}
+#define DUN_TRACE_DEBUG2(m,p1,p2) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_DUN, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define DUN_TRACE_DEBUG3(m,p1,p2,p3) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_DUN, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define DUN_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_DUN, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define DUN_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_DUN, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define DUN_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_DUN, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* define traces for hardcopy cable replacement profile */
+
+#define HCRP_TRACE_ERROR0(m) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m);}
+#define HCRP_TRACE_ERROR1(m,p1) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m, p1);}
+#define HCRP_TRACE_ERROR2(m,p1,p2) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define HCRP_TRACE_ERROR3(m,p1,p2,p3) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define HCRP_TRACE_ERROR4(m,p1,p2,p3,p4) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define HCRP_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define HCRP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCRP_TRACE_WARNING0(m) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m);}
+#define HCRP_TRACE_WARNING1(m,p1) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1);}
+#define HCRP_TRACE_WARNING2(m,p1,p2) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define HCRP_TRACE_WARNING3(m,p1,p2,p3) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define HCRP_TRACE_WARNING4(m,p1,p2,p3,p4) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define HCRP_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define HCRP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCRP_TRACE_API0(m) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_API, m);}
+#define HCRP_TRACE_API1(m,p1) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_API, m, p1);}
+#define HCRP_TRACE_API2(m,p1,p2) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2);}
+#define HCRP_TRACE_API3(m,p1,p2,p3) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define HCRP_TRACE_API4(m,p1,p2,p3,p4) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define HCRP_TRACE_API5(m,p1,p2,p3,p4,p5) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define HCRP_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCRP_TRACE_EVENT0(m) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m);}
+#define HCRP_TRACE_EVENT1(m,p1) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m, p1);}
+#define HCRP_TRACE_EVENT2(m,p1,p2) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define HCRP_TRACE_EVENT3(m,p1,p2,p3) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define HCRP_TRACE_EVENT4(m,p1,p2,p3,p4) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define HCRP_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define HCRP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCRP_TRACE_DEBUG0(m) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m);}
+#define HCRP_TRACE_DEBUG1(m,p1) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1);}
+#define HCRP_TRACE_DEBUG2(m,p1,p2) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define HCRP_TRACE_DEBUG3(m,p1,p2,p3) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define HCRP_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define HCRP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define HCRP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* define traces for multi-client server hardcopy cable replacement profile */
+
+#define HCRPM_TRACE_ERROR0(m) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m);}
+#define HCRPM_TRACE_ERROR1(m,p1) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m, p1);}
+#define HCRPM_TRACE_ERROR2(m,p1,p2) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define HCRPM_TRACE_ERROR3(m,p1,p2,p3) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define HCRPM_TRACE_ERROR4(m,p1,p2,p3,p4) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define HCRPM_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define HCRPM_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCRPM_TRACE_WARNING0(m) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m);}
+#define HCRPM_TRACE_WARNING1(m,p1) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1);}
+#define HCRPM_TRACE_WARNING2(m,p1,p2) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define HCRPM_TRACE_WARNING3(m,p1,p2,p3) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define HCRPM_TRACE_WARNING4(m,p1,p2,p3,p4) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define HCRPM_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define HCRPM_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCRPM_TRACE_API0(m) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_API, m);}
+#define HCRPM_TRACE_API1(m,p1) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_API, m, p1);}
+#define HCRPM_TRACE_API2(m,p1,p2) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2);}
+#define HCRPM_TRACE_API3(m,p1,p2,p3) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define HCRPM_TRACE_API4(m,p1,p2,p3,p4) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define HCRPM_TRACE_API5(m,p1,p2,p3,p4,p5) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define HCRPM_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCRPM_TRACE_EVENT0(m) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m);}
+#define HCRPM_TRACE_EVENT1(m,p1) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m, p1);}
+#define HCRPM_TRACE_EVENT2(m,p1,p2) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define HCRPM_TRACE_EVENT3(m,p1,p2,p3) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define HCRPM_TRACE_EVENT4(m,p1,p2,p3,p4) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define HCRPM_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define HCRPM_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCRPM_TRACE_DEBUG0(m) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m);}
+#define HCRPM_TRACE_DEBUG1(m,p1) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1);}
+#define HCRPM_TRACE_DEBUG2(m,p1,p2) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define HCRPM_TRACE_DEBUG3(m,p1,p2,p3) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define HCRPM_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define HCRPM_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define HCRPM_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* define traces for RPC */
+
+#define RPC_TRACE_ERROR0(m) {if (rpc_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_ERROR, (m));}
+#define RPC_TRACE_ERROR1(m,p1) {if (rpc_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_ERROR, \
+ (m), (UINT32)(p1));}
+#define RPC_TRACE_ERROR2(m,p1,p2) {if (rpc_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_ERROR, \
+ (m), (UINT32)(p1), (UINT32)(p2));}
+#define RPC_TRACE_ERROR3(m,p1,p2,p3) {if (rpc_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_ERROR, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define RPC_TRACE_ERROR4(m,p1,p2,p3,p4) {if (rpc_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_ERROR, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define RPC_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (rpc_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_ERROR, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define RPC_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (rpc_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_ERROR, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+
+#define RPC_TRACE_WARNING0(m) {if (rpc_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_WARNING, (m));}
+#define RPC_TRACE_WARNING1(m,p1) {if (rpc_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_WARNING, \
+ (m), (UINT32)(p1));}
+#define RPC_TRACE_WARNING2(m,p1,p2) {if (rpc_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_WARNING, \
+ (m), (UINT32)(p1), (UINT32)(p2));}
+#define RPC_TRACE_WARNING3(m,p1,p2,p3) {if (rpc_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_WARNING, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define RPC_TRACE_WARNING4(m,p1,p2,p3,p4) {if (rpc_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_WARNING, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define RPC_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (rpc_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_WARNING, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define RPC_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (rpc_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_WARNING, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+
+#define RPC_TRACE_API0(m) {if (rpc_trace_level >= BT_TRACE_LEVEL_API) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_API, (m));}
+#define RPC_TRACE_API1(m,p1) {if (rpc_trace_level >= BT_TRACE_LEVEL_API) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_API, \
+ (m), (UINT32)(p1));}
+#define RPC_TRACE_API2(m,p1,p2) {if (rpc_trace_level >= BT_TRACE_LEVEL_API) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_API, \
+ (m), (UINT32)(p1), (UINT32)(p2));}
+#define RPC_TRACE_API3(m,p1,p2,p3) {if (rpc_trace_level >= BT_TRACE_LEVEL_API) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_API, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define RPC_TRACE_API4(m,p1,p2,p3,p4) {if (rpc_trace_level >= BT_TRACE_LEVEL_API) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_API, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define RPC_TRACE_API5(m,p1,p2,p3,p4,p5) {if (rpc_trace_level >= BT_TRACE_LEVEL_API) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_API, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define RPC_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (rpc_trace_level >= BT_TRACE_LEVEL_API) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_API, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+
+#define RPC_TRACE_EVENT0(m) {if (rpc_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_EVENT, (m));}
+#define RPC_TRACE_EVENT1(m,p1) {if (rpc_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_EVENT, \
+ (m), (UINT32)(p1));}
+#define RPC_TRACE_EVENT2(m,p1,p2) {if (rpc_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_EVENT, \
+ (m), (UINT32)(p1), (UINT32)(p2));}
+#define RPC_TRACE_EVENT3(m,p1,p2,p3) {if (rpc_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_EVENT, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define RPC_TRACE_EVENT4(m,p1,p2,p3,p4) {if (rpc_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_EVENT, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define RPC_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (rpc_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_EVENT, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define RPC_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (rpc_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_EVENT, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+
+#define RPC_TRACE_DEBUG0(m) {if (rpc_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_DEBUG, (m));}
+#define RPC_TRACE_DEBUG1(m,p1) {if (rpc_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_DEBUG, \
+ (m), (UINT32)(p1));}
+#define RPC_TRACE_DEBUG2(m,p1,p2) {if (rpc_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_DEBUG, \
+ (m), (UINT32)(p1), (UINT32)(p2));}
+#define RPC_TRACE_DEBUG3(m,p1,p2,p3) {if (rpc_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_DEBUG, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define RPC_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (rpc_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_DEBUG, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define RPC_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (rpc_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_DEBUG, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define RPC_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (rpc_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_DEBUG, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+
+/* define traces for BNEP */
+
+#define BNEP_TRACE_ERROR0(m) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_BNEP, TRACE_TYPE_ERROR, m);}
+#define BNEP_TRACE_ERROR1(m,p1) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_BNEP, TRACE_TYPE_ERROR, m, p1);}
+#define BNEP_TRACE_ERROR2(m,p1,p2) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_BNEP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define BNEP_TRACE_ERROR3(m,p1,p2,p3) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_BNEP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define BNEP_TRACE_ERROR4(m,p1,p2,p3,p4) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_BNEP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define BNEP_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_BNEP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define BNEP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_BNEP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define BNEP_TRACE_WARNING0(m) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_BNEP, TRACE_TYPE_WARNING, m);}
+#define BNEP_TRACE_WARNING1(m,p1) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_BNEP, TRACE_TYPE_WARNING, m,p1);}
+#define BNEP_TRACE_WARNING2(m,p1,p2) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_BNEP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define BNEP_TRACE_WARNING3(m,p1,p2,p3) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_BNEP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define BNEP_TRACE_WARNING4(m,p1,p2,p3,p4) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_BNEP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define BNEP_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_BNEP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define BNEP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_BNEP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define BNEP_TRACE_API0(m) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_BNEP, TRACE_TYPE_API, m);}
+#define BNEP_TRACE_API1(m,p1) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_BNEP, TRACE_TYPE_API, m, p1);}
+#define BNEP_TRACE_API2(m,p1,p2) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_BNEP, TRACE_TYPE_API, m,p1,p2);}
+#define BNEP_TRACE_API3(m,p1,p2,p3) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_BNEP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define BNEP_TRACE_API4(m,p1,p2,p3,p4) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_BNEP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define BNEP_TRACE_API5(m,p1,p2,p3,p4,p5) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_BNEP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define BNEP_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_BNEP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define BNEP_TRACE_EVENT0(m) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_BNEP, TRACE_TYPE_EVENT, m);}
+#define BNEP_TRACE_EVENT1(m,p1) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_BNEP, TRACE_TYPE_EVENT, m, p1);}
+#define BNEP_TRACE_EVENT2(m,p1,p2) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_BNEP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define BNEP_TRACE_EVENT3(m,p1,p2,p3) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_BNEP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define BNEP_TRACE_EVENT4(m,p1,p2,p3,p4) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_BNEP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define BNEP_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_BNEP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define BNEP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_BNEP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define BNEP_TRACE_DEBUG0(m) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_BNEP, TRACE_TYPE_DEBUG, m);}
+#define BNEP_TRACE_DEBUG1(m,p1) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_BNEP, TRACE_TYPE_DEBUG, m,p1);}
+#define BNEP_TRACE_DEBUG2(m,p1,p2) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_BNEP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define BNEP_TRACE_DEBUG3(m,p1,p2,p3) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_BNEP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define BNEP_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_BNEP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define BNEP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_BNEP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define BNEP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_BNEP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* define traces for PAN */
+
+#define PAN_TRACE_ERROR0(m) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_PAN, TRACE_TYPE_ERROR, m);}
+#define PAN_TRACE_ERROR1(m,p1) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_PAN, TRACE_TYPE_ERROR, m, p1);}
+#define PAN_TRACE_ERROR2(m,p1,p2) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_PAN, TRACE_TYPE_ERROR, m,p1,p2);}
+#define PAN_TRACE_ERROR3(m,p1,p2,p3) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_PAN, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define PAN_TRACE_ERROR4(m,p1,p2,p3,p4) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_PAN, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define PAN_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_PAN, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define PAN_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_PAN, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define PAN_TRACE_WARNING0(m) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_PAN, TRACE_TYPE_WARNING, m);}
+#define PAN_TRACE_WARNING1(m,p1) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_PAN, TRACE_TYPE_WARNING, m,p1);}
+#define PAN_TRACE_WARNING2(m,p1,p2) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_PAN, TRACE_TYPE_WARNING, m,p1,p2);}
+#define PAN_TRACE_WARNING3(m,p1,p2,p3) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_PAN, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define PAN_TRACE_WARNING4(m,p1,p2,p3,p4) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_PAN, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define PAN_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_PAN, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define PAN_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_PAN, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define PAN_TRACE_API0(m) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_PAN, TRACE_TYPE_API, m);}
+#define PAN_TRACE_API1(m,p1) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_PAN, TRACE_TYPE_API, m, p1);}
+#define PAN_TRACE_API2(m,p1,p2) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_PAN, TRACE_TYPE_API, m,p1,p2);}
+#define PAN_TRACE_API3(m,p1,p2,p3) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_PAN, TRACE_TYPE_API, m,p1,p2,p3);}
+#define PAN_TRACE_API4(m,p1,p2,p3,p4) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_PAN, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define PAN_TRACE_API5(m,p1,p2,p3,p4,p5) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_PAN, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define PAN_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_PAN, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define PAN_TRACE_EVENT0(m) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_PAN, TRACE_TYPE_EVENT, m);}
+#define PAN_TRACE_EVENT1(m,p1) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_PAN, TRACE_TYPE_EVENT, m, p1);}
+#define PAN_TRACE_EVENT2(m,p1,p2) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_PAN, TRACE_TYPE_EVENT, m,p1,p2);}
+#define PAN_TRACE_EVENT3(m,p1,p2,p3) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_PAN, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define PAN_TRACE_EVENT4(m,p1,p2,p3,p4) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_PAN, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define PAN_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_PAN, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define PAN_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_PAN, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define PAN_TRACE_DEBUG0(m) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_PAN, TRACE_TYPE_DEBUG, m);}
+#define PAN_TRACE_DEBUG1(m,p1) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_PAN, TRACE_TYPE_DEBUG, m,p1);}
+#define PAN_TRACE_DEBUG2(m,p1,p2) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_PAN, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define PAN_TRACE_DEBUG3(m,p1,p2,p3) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_PAN, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define PAN_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_PAN, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define PAN_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_PAN, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define PAN_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_PAN, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* define traces for SIM */
+
+#define SAP_TRACE_ERROR0(m) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_SAP, TRACE_TYPE_ERROR, m);}
+#define SAP_TRACE_ERROR1(m,p1) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_SAP, TRACE_TYPE_ERROR, m, p1);}
+#define SAP_TRACE_ERROR2(m,p1,p2) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_SAP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define SAP_TRACE_ERROR3(m,p1,p2,p3) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_SAP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define SAP_TRACE_ERROR4(m,p1,p2,p3,p4) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_SAP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define SAP_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_SAP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define SAP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_SAP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define SAP_TRACE_WARNING0(m) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_SAP, TRACE_TYPE_WARNING, m);}
+#define SAP_TRACE_WARNING1(m,p1) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_SAP, TRACE_TYPE_WARNING, m,p1);}
+#define SAP_TRACE_WARNING2(m,p1,p2) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_SAP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define SAP_TRACE_WARNING3(m,p1,p2,p3) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_SAP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define SAP_TRACE_WARNING4(m,p1,p2,p3,p4) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_SAP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define SAP_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_SAP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define SAP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_SAP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define SAP_TRACE_API0(m) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_SAP, TRACE_TYPE_API, m);}
+#define SAP_TRACE_API1(m,p1) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_SAP, TRACE_TYPE_API, m, p1);}
+#define SAP_TRACE_API2(m,p1,p2) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_SAP, TRACE_TYPE_API, m,p1,p2);}
+#define SAP_TRACE_API3(m,p1,p2,p3) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_SAP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define SAP_TRACE_API4(m,p1,p2,p3,p4) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_SAP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define SAP_TRACE_API5(m,p1,p2,p3,p4,p5) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_SAP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define SAP_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_SAP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define SAP_TRACE_EVENT0(m) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_SAP, TRACE_TYPE_EVENT, m);}
+#define SAP_TRACE_EVENT1(m,p1) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_SAP, TRACE_TYPE_EVENT, m, p1);}
+#define SAP_TRACE_EVENT2(m,p1,p2) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_SAP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define SAP_TRACE_EVENT3(m,p1,p2,p3) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_SAP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define SAP_TRACE_EVENT4(m,p1,p2,p3,p4) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_SAP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define SAP_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_SAP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define SAP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_SAP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define SAP_TRACE_DEBUG0(m) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_SAP, TRACE_TYPE_DEBUG, m);}
+#define SAP_TRACE_DEBUG1(m,p1) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_SAP, TRACE_TYPE_DEBUG, m,p1);}
+#define SAP_TRACE_DEBUG2(m,p1,p2) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_SAP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define SAP_TRACE_DEBUG3(m,p1,p2,p3) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_SAP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define SAP_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_SAP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define SAP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_SAP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define SAP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_SAP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for OPP profile
+*/
+#define OPP_TRACE_ERROR0(m) {if (opp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_OPP, TRACE_TYPE_ERROR, m);}
+#define OPP_TRACE_ERROR1(m,p1) {if (opp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_OPP, TRACE_TYPE_ERROR, m,p1);}
+#define OPP_TRACE_ERROR2(m,p1,p2) {if (opp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_OPP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define OPP_TRACE_ERROR3(m,p1,p2,p3) {if (opp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_OPP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define OPP_TRACE_ERROR4(m,p1,p2,p3,p4) {if (opp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_OPP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define OPP_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (opp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_OPP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define OPP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (opp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_OPP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define OPP_TRACE_WARNING0(m) {if (opp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_OPP, TRACE_TYPE_WARNING, m);}
+#define OPP_TRACE_WARNING1(m,p1) {if (opp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_OPP, TRACE_TYPE_WARNING, m,p1);}
+#define OPP_TRACE_WARNING2(m,p1,p2) {if (opp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_OPP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define OPP_TRACE_WARNING3(m,p1,p2,p3) {if (opp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_OPP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define OPP_TRACE_WARNING4(m,p1,p2,p3,p4) {if (opp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_OPP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define OPP_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (opp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_OPP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define OPP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (opp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_OPP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define OPP_TRACE_EVENT0(m) {if (opp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_OPP, TRACE_TYPE_EVENT, m);}
+#define OPP_TRACE_EVENT1(m,p1) {if (opp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_OPP, TRACE_TYPE_EVENT, m, p1);}
+#define OPP_TRACE_EVENT2(m,p1,p2) {if (opp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_OPP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define OPP_TRACE_EVENT3(m,p1,p2,p3) {if (opp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_OPP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define OPP_TRACE_EVENT4(m,p1,p2,p3,p4) {if (opp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_OPP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define OPP_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (opp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_OPP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define OPP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (opp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_OPP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define OPP_TRACE_DEBUG0(m) {if (opp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_OPP, TRACE_TYPE_DEBUG, m);}
+#define OPP_TRACE_DEBUG1(m,p1) {if (opp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_OPP, TRACE_TYPE_DEBUG, m,p1);}
+#define OPP_TRACE_DEBUG2(m,p1,p2) {if (opp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_OPP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define OPP_TRACE_DEBUG3(m,p1,p2,p3) {if (opp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_OPP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define OPP_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (opp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_OPP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define OPP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (opp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_OPP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define OPP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (opp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_OPP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for FTP profile
+*/
+#define FTP_TRACE_ERROR0(m) {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_FTP, TRACE_TYPE_ERROR, m);}
+#define FTP_TRACE_ERROR1(m,p1) {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_FTP, TRACE_TYPE_ERROR, m,p1);}
+#define FTP_TRACE_ERROR2(m,p1,p2) {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_FTP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define FTP_TRACE_ERROR3(m,p1,p2,p3) {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_FTP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define FTP_TRACE_ERROR4(m,p1,p2,p3,p4) {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_FTP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define FTP_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_FTP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define FTP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_FTP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define FTP_TRACE_WARNING0(m) {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_FTP, TRACE_TYPE_WARNING, m);}
+#define FTP_TRACE_WARNING1(m,p1) {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_FTP, TRACE_TYPE_WARNING, m,p1);}
+#define FTP_TRACE_WARNING2(m,p1,p2) {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_FTP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define FTP_TRACE_WARNING3(m,p1,p2,p3) {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_FTP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define FTP_TRACE_WARNING4(m,p1,p2,p3,p4) {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_FTP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define FTP_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_FTP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define FTP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_FTP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define FTP_TRACE_EVENT0(m) {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_FTP, TRACE_TYPE_EVENT, m);}
+#define FTP_TRACE_EVENT1(m,p1) {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_FTP, TRACE_TYPE_EVENT, m, p1);}
+#define FTP_TRACE_EVENT2(m,p1,p2) {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_FTP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define FTP_TRACE_EVENT3(m,p1,p2,p3) {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_FTP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define FTP_TRACE_EVENT4(m,p1,p2,p3,p4) {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_FTP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define FTP_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_FTP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define FTP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_FTP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define FTP_TRACE_DEBUG0(m) {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_FTP, TRACE_TYPE_DEBUG, m);}
+#define FTP_TRACE_DEBUG1(m,p1) {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_FTP, TRACE_TYPE_DEBUG, m,p1);}
+#define FTP_TRACE_DEBUG2(m,p1,p2) {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_FTP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define FTP_TRACE_DEBUG3(m,p1,p2,p3) {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_FTP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define FTP_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_FTP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define FTP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_FTP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define FTP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_FTP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the A2DP profile
+*/
+#define A2D_TRACE_ERROR0(m) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_A2D, TRACE_TYPE_ERROR,m);}
+#define A2D_TRACE_ERROR1(m,p1) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_A2D, TRACE_TYPE_ERROR,m,p1);}
+#define A2D_TRACE_ERROR2(m,p1,p2) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_A2D, TRACE_TYPE_ERROR,m,p1,p2);}
+#define A2D_TRACE_ERROR3(m,p1,p2,p3) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_A2D, TRACE_TYPE_ERROR,m,p1,p2,p3);}
+#define A2D_TRACE_ERROR4(m,p1,p2,p3,p4) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_A2D, TRACE_TYPE_ERROR,m,p1,p2,p3,p4);}
+#define A2D_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_A2D, TRACE_TYPE_ERROR,m,p1,p2,p3,p4,p5);}
+#define A2D_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_A2D, TRACE_TYPE_ERROR,m,p1,p2,p3,p4,p5,p6);}
+
+#define A2D_TRACE_WARNING0(m) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_A2D, TRACE_TYPE_WARNING,m);}
+#define A2D_TRACE_WARNING1(m,p1) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_A2D, TRACE_TYPE_WARNING,m,p1);}
+#define A2D_TRACE_WARNING2(m,p1,p2) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_A2D, TRACE_TYPE_WARNING,m,p1,p2);}
+#define A2D_TRACE_WARNING3(m,p1,p2,p3) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_A2D, TRACE_TYPE_WARNING,m,p1,p2,p3);}
+#define A2D_TRACE_WARNING4(m,p1,p2,p3,p4) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_A2D, TRACE_TYPE_WARNING,m,p1,p2,p3,p4);}
+#define A2D_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_A2D, TRACE_TYPE_WARNING,m,p1,p2,p3,p4,p5);}
+#define A2D_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_A2D, TRACE_TYPE_WARNING,m,p1,p2,p3,p4,p5,p6);}
+
+#define A2D_TRACE_EVENT0(m) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_A2D, TRACE_TYPE_EVENT,m);}
+#define A2D_TRACE_EVENT1(m,p1) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_A2D, TRACE_TYPE_EVENT,m, p1);}
+#define A2D_TRACE_EVENT2(m,p1,p2) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_A2D, TRACE_TYPE_EVENT,m,p1,p2);}
+#define A2D_TRACE_EVENT3(m,p1,p2,p3) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_A2D, TRACE_TYPE_EVENT,m,p1,p2,p3);}
+#define A2D_TRACE_EVENT4(m,p1,p2,p3,p4) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_A2D, TRACE_TYPE_EVENT,m,p1,p2,p3,p4);}
+#define A2D_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_A2D, TRACE_TYPE_EVENT,m,p1,p2,p3,p4,p5);}
+#define A2D_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_A2D, TRACE_TYPE_EVENT,m,p1,p2,p3,p4,p5,p6);}
+
+#define A2D_TRACE_DEBUG0(m) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_A2D, TRACE_TYPE_DEBUG,m);}
+#define A2D_TRACE_DEBUG1(m,p1) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_A2D, TRACE_TYPE_DEBUG,m,p1);}
+#define A2D_TRACE_DEBUG2(m,p1,p2) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_A2D, TRACE_TYPE_DEBUG,m,p1,p2);}
+#define A2D_TRACE_DEBUG3(m,p1,p2,p3) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_A2D, TRACE_TYPE_DEBUG,m,p1,p2,p3);}
+#define A2D_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_A2D, TRACE_TYPE_DEBUG,m,p1,p2,p3,p4);}
+#define A2D_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_A2D, TRACE_TYPE_DEBUG,m,p1,p2,p3,p4,p5);}
+#define A2D_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_A2D, TRACE_TYPE_DEBUG,m,p1,p2,p3,p4,p5,p6);}
+
+#define A2D_TRACE_API0(m) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_A2D, TRACE_TYPE_API,m);}
+#define A2D_TRACE_API1(m,p1) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_A2D, TRACE_TYPE_API,m, p1);}
+#define A2D_TRACE_API2(m,p1,p2) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_A2D, TRACE_TYPE_API,m,p1,p2);}
+#define A2D_TRACE_API3(m,p1,p2,p3) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_A2D, TRACE_TYPE_API,m,p1,p2,p3);}
+#define A2D_TRACE_API4(m,p1,p2,p3,p4) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_A2D, TRACE_TYPE_API,m,p1,p2,p3,p4);}
+#define A2D_TRACE_API5(m,p1,p2,p3,p4,p5) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_A2D, TRACE_TYPE_API,m,p1,p2,p3,p4,p5);}
+#define A2D_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_A2D, TRACE_TYPE_API,m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the VDP profile
+*/
+#define VDP_TRACE_ERROR0(m) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m);}
+#define VDP_TRACE_ERROR1(m,p1) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1);}
+#define VDP_TRACE_ERROR2(m,p1,p2) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2);}
+#define VDP_TRACE_ERROR3(m,p1,p2,p3) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2,p3);}
+#define VDP_TRACE_ERROR4(m,p1,p2,p3,p4) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2,p3,p4);}
+#define VDP_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2,p3,p4,p5);}
+#define VDP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2,p3,p4,p5,p6);}
+
+#define VDP_TRACE_WARNING0(m) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m);}
+#define VDP_TRACE_WARNING1(m,p1) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1);}
+#define VDP_TRACE_WARNING2(m,p1,p2) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2);}
+#define VDP_TRACE_WARNING3(m,p1,p2,p3) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2,p3);}
+#define VDP_TRACE_WARNING4(m,p1,p2,p3,p4) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2,p3,p4);}
+#define VDP_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2,p3,p4,p5);}
+#define VDP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2,p3,p4,p5,p6);}
+
+#define VDP_TRACE_EVENT0(m) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m);}
+#define VDP_TRACE_EVENT1(m,p1) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m, p1);}
+#define VDP_TRACE_EVENT2(m,p1,p2) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2);}
+#define VDP_TRACE_EVENT3(m,p1,p2,p3) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2,p3);}
+#define VDP_TRACE_EVENT4(m,p1,p2,p3,p4) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2,p3,p4);}
+#define VDP_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2,p3,p4,p5);}
+#define VDP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2,p3,p4,p5,p6);}
+
+#define VDP_TRACE_DEBUG0(m) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m);}
+#define VDP_TRACE_DEBUG1(m,p1) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1);}
+#define VDP_TRACE_DEBUG2(m,p1,p2) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2);}
+#define VDP_TRACE_DEBUG3(m,p1,p2,p3) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2,p3);}
+#define VDP_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2,p3,p4);}
+#define VDP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2,p3,p4,p5);}
+#define VDP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2,p3,p4,p5,p6);}
+
+#define VDP_TRACE_API0(m) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_API,m);}
+#define VDP_TRACE_API1(m,p1) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_API,m, p1);}
+#define VDP_TRACE_API2(m,p1,p2) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2);}
+#define VDP_TRACE_API3(m,p1,p2,p3) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2,p3);}
+#define VDP_TRACE_API4(m,p1,p2,p3,p4) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2,p3,p4);}
+#define VDP_TRACE_API5(m,p1,p2,p3,p4,p5) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2,p3,p4,p5);}
+#define VDP_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2,p3,p4,p5,p6);}
+
+
+/* Define tracing for the LM unit
+*/
+#define LMP_TRACE_ERROR0(m) {if (lmp_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_LM, TRACE_TYPE_ERROR, m);}
+#define LMP_TRACE_ERROR1(m,p1) {if (lmp_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_LM, TRACE_TYPE_ERROR, m,p1);}
+#define LMP_TRACE_ERROR2(m,p1,p2) {if (lmp_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_LM, TRACE_TYPE_ERROR, m,p1,p2);}
+#define LMP_TRACE_ERROR3(m,p1,p2,p3) {if (lmp_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_LM, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define LMP_TRACE_ERROR4(m,p1,p2,p3,p4) {if (lmp_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_LM, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define LMP_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (lmp_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_LM, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define LMP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (lmp_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_LM, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define LMP_TRACE_WARNING0(m) {if (lmp_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_LM, TRACE_TYPE_WARNING, m);}
+#define LMP_TRACE_WARNING1(m,p1) {if (lmp_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_LM, TRACE_TYPE_WARNING, m,p1);}
+#define LMP_TRACE_WARNING2(m,p1,p2) {if (lmp_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_LM, TRACE_TYPE_WARNING, m,p1,p2);}
+#define LMP_TRACE_WARNING3(m,p1,p2,p3) {if (lmp_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_LM, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define LMP_TRACE_WARNING4(m,p1,p2,p3,p4) {if (lmp_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_LM, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define LMP_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (lmp_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_LM, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define LMP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (lmp_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_LM, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define LMP_TRACE_EVENT0(m) {if (lmp_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_LM, TRACE_TYPE_EVENT, m);}
+#define LMP_TRACE_EVENT1(m,p1) {if (lmp_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_LM, TRACE_TYPE_EVENT, m, p1);}
+#define LMP_TRACE_EVENT2(m,p1,p2) {if (lmp_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_LM, TRACE_TYPE_EVENT, m,p1,p2);}
+#define LMP_TRACE_EVENT3(m,p1,p2,p3) {if (lmp_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_LM, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define LMP_TRACE_EVENT4(m,p1,p2,p3,p4) {if (lmp_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_LM, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define LMP_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (lmp_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_LM, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define LMP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (lmp_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_LM, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define LMP_TRACE_DEBUG0(m) {if (lmp_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_LM, TRACE_TYPE_DEBUG, m);}
+#define LMP_TRACE_DEBUG1(m,p1) {if (lmp_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_LM, TRACE_TYPE_DEBUG, m,p1);}
+#define LMP_TRACE_DEBUG2(m,p1,p2) {if (lmp_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_LM, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define LMP_TRACE_DEBUG3(m,p1,p2,p3) {if (lmp_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_LM, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define LMP_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (lmp_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_LM, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define LMP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (lmp_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_LM, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define LMP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (lmp_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_LM, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the LC unit
+*/
+#define LC_TRACE_ERROR0(m) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_ERROR]) BT_TRACE_0(TRACE_LAYER_LC, TRACE_TYPE_ERROR, m);}
+#define LC_TRACE_ERROR1(m,p1) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_ERROR]) BT_TRACE_1(TRACE_LAYER_LC, TRACE_TYPE_ERROR, m,p1);}
+#define LC_TRACE_ERROR2(m,p1,p2) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_ERROR]) BT_TRACE_2(TRACE_LAYER_LC, TRACE_TYPE_ERROR, m,p1,p2);}
+#define LC_TRACE_ERROR3(m,p1,p2,p3) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_ERROR]) BT_TRACE_3(TRACE_LAYER_LC, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define LC_TRACE_ERROR4(m,p1,p2,p3,p4) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_ERROR]) BT_TRACE_4(TRACE_LAYER_LC, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define LC_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_ERROR]) BT_TRACE_5(TRACE_LAYER_LC, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define LC_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_ERROR]) BT_TRACE_6(TRACE_LAYER_LC, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define LC_TRACE_WARNING0(m) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_WARNING]) BT_TRACE_0(TRACE_LAYER_LC, TRACE_TYPE_WARNING, m);}
+#define LC_TRACE_WARNING1(m,p1) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_WARNING]) BT_TRACE_1(TRACE_LAYER_LC, TRACE_TYPE_WARNING, m,p1);}
+#define LC_TRACE_WARNING2(m,p1,p2) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_WARNING]) BT_TRACE_2(TRACE_LAYER_LC, TRACE_TYPE_WARNING, m,p1,p2);}
+#define LC_TRACE_WARNING3(m,p1,p2,p3) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_WARNING]) BT_TRACE_3(TRACE_LAYER_LC, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define LC_TRACE_WARNING4(m,p1,p2,p3,p4) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_WARNING]) BT_TRACE_4(TRACE_LAYER_LC, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define LC_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_WARNING]) BT_TRACE_5(TRACE_LAYER_LC, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define LC_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_WARNING]) BT_TRACE_6(TRACE_LAYER_LC, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define LC_TRACE_EVENT0(m) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_EVENT]) BT_TRACE_0(TRACE_LAYER_LC, TRACE_TYPE_EVENT, m);}
+#define LC_TRACE_EVENT1(m,p1) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_EVENT]) BT_TRACE_1(TRACE_LAYER_LC, TRACE_TYPE_EVENT, m, p1);}
+#define LC_TRACE_EVENT2(m,p1,p2) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_EVENT]) BT_TRACE_2(TRACE_LAYER_LC, TRACE_TYPE_EVENT, m,p1,p2);}
+#define LC_TRACE_EVENT3(m,p1,p2,p3) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_EVENT]) BT_TRACE_3(TRACE_LAYER_LC, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define LC_TRACE_EVENT4(m,p1,p2,p3,p4) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_EVENT]) BT_TRACE_4(TRACE_LAYER_LC, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define LC_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_EVENT]) BT_TRACE_5(TRACE_LAYER_LC, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define LC_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_EVENT]) BT_TRACE_6(TRACE_LAYER_LC, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define LC_TRACE_DEBUG0(m) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_DEBUG]) BT_TRACE_0(TRACE_LAYER_LC, TRACE_TYPE_DEBUG, m);}
+#define LC_TRACE_DEBUG1(m,p1) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_DEBUG]) BT_TRACE_1(TRACE_LAYER_LC, TRACE_TYPE_DEBUG, m,p1);}
+#define LC_TRACE_DEBUG2(m,p1,p2) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_DEBUG]) BT_TRACE_2(TRACE_LAYER_LC, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define LC_TRACE_DEBUG3(m,p1,p2,p3) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_DEBUG]) BT_TRACE_3(TRACE_LAYER_LC, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define LC_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_DEBUG]) BT_TRACE_5(TRACE_LAYER_LC, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define LC_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_DEBUG]) BT_TRACE_6(TRACE_LAYER_LC, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the Serial Dongle Application SDA
+*/
+#define SDA_TRACE_ERROR0(m) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(m);}
+#define SDA_TRACE_ERROR1(m,p1) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(m,p1);}
+#define SDA_TRACE_ERROR2(m,p1,p2) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(m,p1,p2);}
+#define SDA_TRACE_ERROR3(m,p1,p2,p3) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(m,p1,p2,p3);}
+#define SDA_TRACE_ERROR4(m,p1,p2,p3,p4) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(m,p1,p2,p3,p4);}
+#define SDA_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(m,p1,p2,p3,p4,p5);}
+#define SDA_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(m,p1,p2,p3,p4,p5,p6);}
+
+#define SDA_TRACE_WARNING0(m) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(m);}
+#define SDA_TRACE_WARNING1(m,p1) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(m,p1);}
+#define SDA_TRACE_WARNING2(m,p1,p2) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(m,p1,p2);}
+#define SDA_TRACE_WARNING3(m,p1,p2,p3) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(m,p1,p2,p3);}
+#define SDA_TRACE_WARNING4(m,p1,p2,p3,p4) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(m,p1,p2,p3,p4);}
+#define SDA_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(m,p1,p2,p3,p4,p5);}
+#define SDA_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(m,p1,p2,p3,p4,p5,p6);}
+
+#define SDA_TRACE_EVENT0(m) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(m);}
+#define SDA_TRACE_EVENT1(m,p1) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(m, p1);}
+#define SDA_TRACE_EVENT2(m,p1,p2) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(m,p1,p2);}
+#define SDA_TRACE_EVENT3(m,p1,p2,p3) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(m,p1,p2,p3);}
+#define SDA_TRACE_EVENT4(m,p1,p2,p3,p4) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(m,p1,p2,p3,p4);}
+#define SDA_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(m,p1,p2,p3,p4,p5);}
+#define SDA_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(m,p1,p2,p3,p4,p5,p6);}
+
+#define SDA_TRACE_DEBUG0(m) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(m);}
+#define SDA_TRACE_DEBUG1(m,p1) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(m,p1);}
+#define SDA_TRACE_DEBUG2(m,p1,p2) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(m,p1,p2);}
+#define SDA_TRACE_DEBUG3(m,p1,p2,p3) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(m,p1,p2,p3);}
+#define SDA_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(m,p1,p2,p3,p4);}
+#define SDA_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(m,p1,p2,p3,p4,p5);}
+#define SDA_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(m,p1,p2,p3,p4,p5,p6);}
+
+/* AVDTP
+*/
+#define AVDT_TRACE_ERROR0(m) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m);}
+#define AVDT_TRACE_ERROR1(m,p1) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1);}
+#define AVDT_TRACE_ERROR2(m,p1,p2) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define AVDT_TRACE_ERROR3(m,p1,p2,p3) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define AVDT_TRACE_ERROR4(m,p1,p2,p3,p4) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define AVDT_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define AVDT_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define AVDT_TRACE_WARNING0(m) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m);}
+#define AVDT_TRACE_WARNING1(m,p1) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1);}
+#define AVDT_TRACE_WARNING2(m,p1,p2) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define AVDT_TRACE_WARNING3(m,p1,p2,p3) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define AVDT_TRACE_WARNING4(m,p1,p2,p3,p4) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define AVDT_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define AVDT_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define AVDT_TRACE_EVENT0(m) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m);}
+#define AVDT_TRACE_EVENT1(m,p1) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m, p1);}
+#define AVDT_TRACE_EVENT2(m,p1,p2) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define AVDT_TRACE_EVENT3(m,p1,p2,p3) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define AVDT_TRACE_EVENT4(m,p1,p2,p3,p4) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define AVDT_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define AVDT_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define AVDT_TRACE_DEBUG0(m) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m);}
+#define AVDT_TRACE_DEBUG1(m,p1) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1);}
+#define AVDT_TRACE_DEBUG2(m,p1,p2) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define AVDT_TRACE_DEBUG3(m,p1,p2,p3) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define AVDT_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define AVDT_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define AVDT_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define AVDT_TRACE_API0(m) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_API, m);}
+#define AVDT_TRACE_API1(m,p1) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1);}
+#define AVDT_TRACE_API2(m,p1,p2) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2);}
+#define AVDT_TRACE_API3(m,p1,p2,p3) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define AVDT_TRACE_API4(m,p1,p2,p3,p4) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define AVDT_TRACE_API5(m,p1,p2,p3,p4,p5) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define AVDT_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the AVCTP protocol
+*/
+#define AVCT_TRACE_ERROR0(m) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m);}
+#define AVCT_TRACE_ERROR1(m,p1) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1);}
+#define AVCT_TRACE_ERROR2(m,p1,p2) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define AVCT_TRACE_ERROR3(m,p1,p2,p3) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define AVCT_TRACE_ERROR4(m,p1,p2,p3,p4) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define AVCT_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define AVCT_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define AVCT_TRACE_WARNING0(m) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m);}
+#define AVCT_TRACE_WARNING1(m,p1) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1);}
+#define AVCT_TRACE_WARNING2(m,p1,p2) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define AVCT_TRACE_WARNING3(m,p1,p2,p3) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define AVCT_TRACE_WARNING4(m,p1,p2,p3,p4) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define AVCT_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define AVCT_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define AVCT_TRACE_EVENT0(m) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m);}
+#define AVCT_TRACE_EVENT1(m,p1) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m, p1);}
+#define AVCT_TRACE_EVENT2(m,p1,p2) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define AVCT_TRACE_EVENT3(m,p1,p2,p3) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define AVCT_TRACE_EVENT4(m,p1,p2,p3,p4) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define AVCT_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define AVCT_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define AVCT_TRACE_DEBUG0(m) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m);}
+#define AVCT_TRACE_DEBUG1(m,p1) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1);}
+#define AVCT_TRACE_DEBUG2(m,p1,p2) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define AVCT_TRACE_DEBUG3(m,p1,p2,p3) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define AVCT_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define AVCT_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define AVCT_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define AVCT_TRACE_API0(m) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_API, m);}
+#define AVCT_TRACE_API1(m,p1) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1);}
+#define AVCT_TRACE_API2(m,p1,p2) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2);}
+#define AVCT_TRACE_API3(m,p1,p2,p3) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define AVCT_TRACE_API4(m,p1,p2,p3,p4) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define AVCT_TRACE_API5(m,p1,p2,p3,p4,p5) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define AVCT_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+
+/* Define tracing for the AVRCP profile
+*/
+#define AVRC_TRACE_ERROR0(m) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m);}
+#define AVRC_TRACE_ERROR1(m,p1) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1);}
+#define AVRC_TRACE_ERROR2(m,p1,p2) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2);}
+#define AVRC_TRACE_ERROR3(m,p1,p2,p3) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2,p3);}
+#define AVRC_TRACE_ERROR4(m,p1,p2,p3,p4) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2,p3,p4);}
+#define AVRC_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2,p3,p4,p5);}
+#define AVRC_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2,p3,p4,p5,p6);}
+
+#define AVRC_TRACE_WARNING0(m) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m);}
+#define AVRC_TRACE_WARNING1(m,p1) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1);}
+#define AVRC_TRACE_WARNING2(m,p1,p2) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2);}
+#define AVRC_TRACE_WARNING3(m,p1,p2,p3) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2,p3);}
+#define AVRC_TRACE_WARNING4(m,p1,p2,p3,p4) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2,p3,p4);}
+#define AVRC_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2,p3,p4,p5);}
+#define AVRC_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2,p3,p4,p5,p6);}
+
+#define AVRC_TRACE_EVENT0(m) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m);}
+#define AVRC_TRACE_EVENT1(m,p1) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m, p1);}
+#define AVRC_TRACE_EVENT2(m,p1,p2) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2);}
+#define AVRC_TRACE_EVENT3(m,p1,p2,p3) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2,p3);}
+#define AVRC_TRACE_EVENT4(m,p1,p2,p3,p4) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2,p3,p4);}
+#define AVRC_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2,p3,p4,p5);}
+#define AVRC_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2,p3,p4,p5,p6);}
+
+#define AVRC_TRACE_DEBUG0(m) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m);}
+#define AVRC_TRACE_DEBUG1(m,p1) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1);}
+#define AVRC_TRACE_DEBUG2(m,p1,p2) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2);}
+#define AVRC_TRACE_DEBUG3(m,p1,p2,p3) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2,p3);}
+#define AVRC_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2,p3,p4);}
+#define AVRC_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2,p3,p4,p5);}
+#define AVRC_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2,p3,p4,p5,p6);}
+
+#define AVRC_TRACE_API0(m) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_API,m);}
+#define AVRC_TRACE_API1(m,p1) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_API,m, p1);}
+#define AVRC_TRACE_API2(m,p1,p2) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2);}
+#define AVRC_TRACE_API3(m,p1,p2,p3) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2,p3);}
+#define AVRC_TRACE_API4(m,p1,p2,p3,p4) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2,p3,p4);}
+#define AVRC_TRACE_API5(m,p1,p2,p3,p4,p5) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2,p3,p4,p5);}
+#define AVRC_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2,p3,p4,p5,p6);}
+
+/* MCAP
+*/
+#define MCA_TRACE_ERROR0(m) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_MCA, TRACE_TYPE_ERROR, m);}
+#define MCA_TRACE_ERROR1(m,p1) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_MCA, TRACE_TYPE_ERROR, m,p1);}
+#define MCA_TRACE_ERROR2(m,p1,p2) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_MCA, TRACE_TYPE_ERROR, m,p1,p2);}
+#define MCA_TRACE_ERROR3(m,p1,p2,p3) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_MCA, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define MCA_TRACE_ERROR4(m,p1,p2,p3,p4) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_MCA, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define MCA_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_MCA, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define MCA_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_MCA, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define MCA_TRACE_WARNING0(m) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_MCA, TRACE_TYPE_WARNING, m);}
+#define MCA_TRACE_WARNING1(m,p1) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_MCA, TRACE_TYPE_WARNING, m,p1);}
+#define MCA_TRACE_WARNING2(m,p1,p2) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_MCA, TRACE_TYPE_WARNING, m,p1,p2);}
+#define MCA_TRACE_WARNING3(m,p1,p2,p3) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_MCA, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define MCA_TRACE_WARNING4(m,p1,p2,p3,p4) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_MCA, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define MCA_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_MCA, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define MCA_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_MCA, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define MCA_TRACE_EVENT0(m) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_MCA, TRACE_TYPE_EVENT, m);}
+#define MCA_TRACE_EVENT1(m,p1) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_MCA, TRACE_TYPE_EVENT, m, p1);}
+#define MCA_TRACE_EVENT2(m,p1,p2) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_MCA, TRACE_TYPE_EVENT, m,p1,p2);}
+#define MCA_TRACE_EVENT3(m,p1,p2,p3) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_MCA, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define MCA_TRACE_EVENT4(m,p1,p2,p3,p4) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_MCA, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define MCA_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_MCA, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define MCA_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_MCA, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define MCA_TRACE_DEBUG0(m) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_MCA, TRACE_TYPE_DEBUG, m);}
+#define MCA_TRACE_DEBUG1(m,p1) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_MCA, TRACE_TYPE_DEBUG, m,p1);}
+#define MCA_TRACE_DEBUG2(m,p1,p2) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_MCA, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define MCA_TRACE_DEBUG3(m,p1,p2,p3) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_MCA, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define MCA_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_MCA, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define MCA_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_MCA, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define MCA_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_MCA, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define MCA_TRACE_API0(m) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_MCA, TRACE_TYPE_API, m);}
+#define MCA_TRACE_API1(m,p1) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_MCA, TRACE_TYPE_API, m,p1);}
+#define MCA_TRACE_API2(m,p1,p2) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_MCA, TRACE_TYPE_API, m,p1,p2);}
+#define MCA_TRACE_API3(m,p1,p2,p3) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_MCA, TRACE_TYPE_API, m,p1,p2,p3);}
+#define MCA_TRACE_API4(m,p1,p2,p3,p4) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_MCA, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define MCA_TRACE_API5(m,p1,p2,p3,p4,p5) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_MCA, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define MCA_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_MCA, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the AMP unit
+*/
+#define AMP_TRACE_ERROR0(m) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_AMP, TRACE_TYPE_ERROR, m);}
+#define AMP_TRACE_ERROR1(m,p1) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_AMP, TRACE_TYPE_ERROR, m,p1);}
+#define AMP_TRACE_ERROR2(m,p1,p2) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_AMP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define AMP_TRACE_ERROR3(m,p1,p2,p3) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_AMP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define AMP_TRACE_ERROR4(m,p1,p2,p3,p4) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_AMP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define AMP_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_AMP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define AMP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_AMP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define AMP_TRACE_WARNING0(m) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_AMP, TRACE_TYPE_WARNING, m);}
+#define AMP_TRACE_WARNING1(m,p1) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_AMP, TRACE_TYPE_WARNING, m,p1);}
+#define AMP_TRACE_WARNING2(m,p1,p2) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_AMP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define AMP_TRACE_WARNING3(m,p1,p2,p3) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_AMP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define AMP_TRACE_WARNING4(m,p1,p2,p3,p4) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_AMP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define AMP_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_AMP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define AMP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_AMP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define AMP_TRACE_API0(m) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_AMP, TRACE_TYPE_API, m);}
+#define AMP_TRACE_API1(m,p1) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_AMP, TRACE_TYPE_API, m,p1);}
+#define AMP_TRACE_API2(m,p1,p2) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_AMP, TRACE_TYPE_API, m,p1,p2);}
+#define AMP_TRACE_API3(m,p1,p2,p3) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_AMP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define AMP_TRACE_API4(m,p1,p2,p3,p4) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_AMP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define AMP_TRACE_API5(m,p1,p2,p3,p4,p5) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_AMP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define AMP_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_AMP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define AMP_TRACE_EVENT0(m) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_AMP, TRACE_TYPE_EVENT, m);}
+#define AMP_TRACE_EVENT1(m,p1) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_AMP, TRACE_TYPE_EVENT, m, p1);}
+#define AMP_TRACE_EVENT2(m,p1,p2) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_AMP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define AMP_TRACE_EVENT3(m,p1,p2,p3) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_AMP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define AMP_TRACE_EVENT4(m,p1,p2,p3,p4) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_AMP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define AMP_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_AMP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define AMP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_AMP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define AMP_TRACE_DEBUG0(m) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_AMP, TRACE_TYPE_DEBUG, m);}
+#define AMP_TRACE_DEBUG1(m,p1) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_AMP, TRACE_TYPE_DEBUG, m,p1);}
+#define AMP_TRACE_DEBUG2(m,p1,p2) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_AMP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define AMP_TRACE_DEBUG3(m,p1,p2,p3) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_AMP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define AMP_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_AMP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define AMP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_AMP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define AMP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_AMP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the ATT/GATT unit
+*/
+#define GATT_TRACE_ERROR0(m) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_ATT, TRACE_TYPE_ERROR, m);}
+#define GATT_TRACE_ERROR1(m,p1) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_ATT, TRACE_TYPE_ERROR, m,p1);}
+#define GATT_TRACE_ERROR2(m,p1,p2) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_ATT, TRACE_TYPE_ERROR, m,p1,p2);}
+#define GATT_TRACE_ERROR3(m,p1,p2,p3) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_ATT, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define GATT_TRACE_ERROR4(m,p1,p2,p3,p4) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_ATT, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define GATT_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_ATT, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define GATT_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_ATT, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define GATT_TRACE_WARNING0(m) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_ATT, TRACE_TYPE_WARNING, m);}
+#define GATT_TRACE_WARNING1(m,p1) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_ATT, TRACE_TYPE_WARNING, m,p1);}
+#define GATT_TRACE_WARNING2(m,p1,p2) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_ATT, TRACE_TYPE_WARNING, m,p1,p2);}
+#define GATT_TRACE_WARNING3(m,p1,p2,p3) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_ATT, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define GATT_TRACE_WARNING4(m,p1,p2,p3,p4) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_ATT, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define GATT_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_ATT, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define GATT_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_ATT, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define GATT_TRACE_API0(m) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_ATT, TRACE_TYPE_API, m);}
+#define GATT_TRACE_API1(m,p1) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_ATT, TRACE_TYPE_API, m,p1);}
+#define GATT_TRACE_API2(m,p1,p2) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_ATT, TRACE_TYPE_API, m,p1,p2);}
+#define GATT_TRACE_API3(m,p1,p2,p3) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_ATT, TRACE_TYPE_API, m,p1,p2,p3);}
+#define GATT_TRACE_API4(m,p1,p2,p3,p4) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_ATT, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define GATT_TRACE_API5(m,p1,p2,p3,p4,p5) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_ATT, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define GATT_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_ATT, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define GATT_TRACE_EVENT0(m) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_ATT, TRACE_TYPE_EVENT, m);}
+#define GATT_TRACE_EVENT1(m,p1) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_ATT, TRACE_TYPE_EVENT, m, p1);}
+#define GATT_TRACE_EVENT2(m,p1,p2) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_ATT, TRACE_TYPE_EVENT, m,p1,p2);}
+#define GATT_TRACE_EVENT3(m,p1,p2,p3) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_ATT, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define GATT_TRACE_EVENT4(m,p1,p2,p3,p4) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_ATT, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define GATT_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_ATT, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define GATT_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_ATT, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define GATT_TRACE_DEBUG0(m) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_ATT, TRACE_TYPE_DEBUG, m);}
+#define GATT_TRACE_DEBUG1(m,p1) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_ATT, TRACE_TYPE_DEBUG, m,p1);}
+#define GATT_TRACE_DEBUG2(m,p1,p2) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_ATT, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define GATT_TRACE_DEBUG3(m,p1,p2,p3) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_ATT, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define GATT_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_ATT, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define GATT_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_ATT, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define GATT_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_ATT, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the SMP unit
+*/
+#define SMP_TRACE_ERROR0(m) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_SMP, TRACE_TYPE_ERROR, m);}
+#define SMP_TRACE_ERROR1(m,p1) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_SMP, TRACE_TYPE_ERROR, m,p1);}
+#define SMP_TRACE_ERROR2(m,p1,p2) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_SMP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define SMP_TRACE_ERROR3(m,p1,p2,p3) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_SMP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define SMP_TRACE_ERROR4(m,p1,p2,p3,p4) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_SMP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define SMP_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_SMP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define SMP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_SMP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define SMP_TRACE_WARNING0(m) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_SMP, TRACE_TYPE_WARNING, m);}
+#define SMP_TRACE_WARNING1(m,p1) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_SMP, TRACE_TYPE_WARNING, m,p1);}
+#define SMP_TRACE_WARNING2(m,p1,p2) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_SMP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define SMP_TRACE_WARNING3(m,p1,p2,p3) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_SMP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define SMP_TRACE_WARNING4(m,p1,p2,p3,p4) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_SMP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define SMP_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_SMP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define SMP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_SMP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define SMP_TRACE_API0(m) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_SMP, TRACE_TYPE_API, m);}
+#define SMP_TRACE_API1(m,p1) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_SMP, TRACE_TYPE_API, m,p1);}
+#define SMP_TRACE_API2(m,p1,p2) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_SMP, TRACE_TYPE_API, m,p1,p2);}
+#define SMP_TRACE_API3(m,p1,p2,p3) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_SMP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define SMP_TRACE_API4(m,p1,p2,p3,p4) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_SMP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define SMP_TRACE_API5(m,p1,p2,p3,p4,p5) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_SMP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define SMP_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_SMP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define SMP_TRACE_EVENT0(m) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_SMP, TRACE_TYPE_EVENT, m);}
+#define SMP_TRACE_EVENT1(m,p1) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_SMP, TRACE_TYPE_EVENT, m, p1);}
+#define SMP_TRACE_EVENT2(m,p1,p2) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_SMP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define SMP_TRACE_EVENT3(m,p1,p2,p3) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_SMP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define SMP_TRACE_EVENT4(m,p1,p2,p3,p4) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_SMP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define SMP_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_SMP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define SMP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_SMP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define SMP_TRACE_DEBUG0(m) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_SMP, TRACE_TYPE_DEBUG, m);}
+#define SMP_TRACE_DEBUG1(m,p1) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_SMP, TRACE_TYPE_DEBUG, m,p1);}
+#define SMP_TRACE_DEBUG2(m,p1,p2) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_SMP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define SMP_TRACE_DEBUG3(m,p1,p2,p3) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_SMP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define SMP_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_SMP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define SMP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_SMP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define SMP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_SMP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* END OF USE TRACES */
+#else
+
+#define BT_TRACE_0(l,t,m)
+#define BT_TRACE_1(l,t,m,p1)
+#define BT_TRACE_2(l,t,m,p1,p2)
+#define BT_TRACE_3(l,t,m,p1,p2,p3)
+#define BT_TRACE_4(l,t,m,p1,p2,p3,p4)
+#define BT_TRACE_5(l,t,m,p1,p2,p3,p4,p5)
+#define BT_TRACE_6(l,t,m,p1,p2,p3,p4,p5,p6)
+
+#define BT_ERROR_TRACE_0(l,m)
+#define BT_ERROR_TRACE_1(l,m,p1)
+#define BT_ERROR_TRACE_2(l,m,p1,p2)
+#define BT_ERROR_TRACE_3(l,m,p1,p2,p3)
+
+/* Define tracing for the HCI unit
+*/
+#define HCI_TRACE_ERROR0(m)
+#define HCI_TRACE_ERROR1(m,p1)
+#define HCI_TRACE_ERROR2(m,p1,p2)
+#define HCI_TRACE_ERROR3(m,p1,p2,p3)
+#define HCI_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define HCI_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define HCI_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCI_TRACE_WARNING0(m)
+#define HCI_TRACE_WARNING1(m,p1)
+#define HCI_TRACE_WARNING2(m,p1,p2)
+#define HCI_TRACE_WARNING3(m,p1,p2,p3)
+#define HCI_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define HCI_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define HCI_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCI_TRACE_EVENT0(m)
+#define HCI_TRACE_EVENT1(m,p1)
+#define HCI_TRACE_EVENT2(m,p1,p2)
+#define HCI_TRACE_EVENT3(m,p1,p2,p3)
+#define HCI_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define HCI_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define HCI_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCI_TRACE_DEBUG0(m)
+#define HCI_TRACE_DEBUG1(m,p1)
+#define HCI_TRACE_DEBUG2(m,p1,p2)
+#define HCI_TRACE_DEBUG3(m,p1,p2,p3)
+#define HCI_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define HCI_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define HCI_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+
+/* Define tracing for BTM
+*/
+#define BTM_TRACE_ERROR0(m)
+#define BTM_TRACE_ERROR1(m,p1)
+#define BTM_TRACE_ERROR2(m,p1,p2)
+#define BTM_TRACE_ERROR3(m,p1,p2,p3)
+#define BTM_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define BTM_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define BTM_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define BTM_TRACE_WARNING0(m)
+#define BTM_TRACE_WARNING1(m,p1)
+#define BTM_TRACE_WARNING2(m,p1,p2)
+#define BTM_TRACE_WARNING3(m,p1,p2,p3)
+#define BTM_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define BTM_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define BTM_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define BTM_TRACE_API0(m)
+#define BTM_TRACE_API1(m,p1)
+#define BTM_TRACE_API2(m,p1,p2)
+#define BTM_TRACE_API3(m,p1,p2,p3)
+#define BTM_TRACE_API4(m,p1,p2,p3,p4)
+#define BTM_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define BTM_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define BTM_TRACE_EVENT0(m)
+#define BTM_TRACE_EVENT1(m,p1)
+#define BTM_TRACE_EVENT2(m,p1,p2)
+#define BTM_TRACE_EVENT3(m,p1,p2,p3)
+#define BTM_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define BTM_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define BTM_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define BTM_TRACE_DEBUG0(m)
+#define BTM_TRACE_DEBUG1(m,p1)
+#define BTM_TRACE_DEBUG2(m,p1,p2)
+#define BTM_TRACE_DEBUG3(m,p1,p2,p3)
+#define BTM_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define BTM_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define BTM_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+
+/* Define tracing for the L2CAP unit
+*/
+#define L2CAP_TRACE_ERROR0(m)
+#define L2CAP_TRACE_ERROR1(m,p1)
+#define L2CAP_TRACE_ERROR2(m,p1,p2)
+#define L2CAP_TRACE_ERROR3(m,p1,p2,p3)
+#define L2CAP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define L2CAP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define L2CAP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define L2CAP_TRACE_WARNING0(m)
+#define L2CAP_TRACE_WARNING1(m,p1)
+#define L2CAP_TRACE_WARNING2(m,p1,p2)
+#define L2CAP_TRACE_WARNING3(m,p1,p2,p3)
+#define L2CAP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define L2CAP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define L2CAP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define L2CAP_TRACE_API0(m)
+#define L2CAP_TRACE_API1(m,p1)
+#define L2CAP_TRACE_API2(m,p1,p2)
+#define L2CAP_TRACE_API3(m,p1,p2,p3)
+#define L2CAP_TRACE_API4(m,p1,p2,p3,p4)
+#define L2CAP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define L2CAP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define L2CAP_TRACE_EVENT0(m)
+#define L2CAP_TRACE_EVENT1(m,p1)
+#define L2CAP_TRACE_EVENT2(m,p1,p2)
+#define L2CAP_TRACE_EVENT3(m,p1,p2,p3)
+#define L2CAP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define L2CAP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define L2CAP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define L2CAP_TRACE_DEBUG0(m)
+#define L2CAP_TRACE_DEBUG1(m,p1)
+#define L2CAP_TRACE_DEBUG2(m,p1,p2)
+#define L2CAP_TRACE_DEBUG3(m,p1,p2,p3)
+#define L2CAP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define L2CAP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define L2CAP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the LLCP unit
+*/
+#define LLCP_TRACE_ERROR0(m)
+#define LLCP_TRACE_ERROR1(m,p1)
+#define LLCP_TRACE_ERROR2(m,p1,p2)
+#define LLCP_TRACE_ERROR3(m,p1,p2,p3)
+#define LLCP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define LLCP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define LLCP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define LLCP_TRACE_WARNING0(m)
+#define LLCP_TRACE_WARNING1(m,p1)
+#define LLCP_TRACE_WARNING2(m,p1,p2)
+#define LLCP_TRACE_WARNING3(m,p1,p2,p3)
+#define LLCP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define LLCP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define LLCP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define LLCP_TRACE_API0(m)
+#define LLCP_TRACE_API1(m,p1)
+#define LLCP_TRACE_API2(m,p1,p2)
+#define LLCP_TRACE_API3(m,p1,p2,p3)
+#define LLCP_TRACE_API4(m,p1,p2,p3,p4)
+#define LLCP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define LLCP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define LLCP_TRACE_EVENT0(m)
+#define LLCP_TRACE_EVENT1(m,p1)
+#define LLCP_TRACE_EVENT2(m,p1,p2)
+#define LLCP_TRACE_EVENT3(m,p1,p2,p3)
+#define LLCP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define LLCP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define LLCP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define LLCP_TRACE_DEBUG0(m)
+#define LLCP_TRACE_DEBUG1(m,p1)
+#define LLCP_TRACE_DEBUG2(m,p1,p2)
+#define LLCP_TRACE_DEBUG3(m,p1,p2,p3)
+#define LLCP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define LLCP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define LLCP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the SDP unit
+*/
+#define SDP_TRACE_ERROR0(m)
+#define SDP_TRACE_ERROR1(m,p1)
+#define SDP_TRACE_ERROR2(m,p1,p2)
+#define SDP_TRACE_ERROR3(m,p1,p2,p3)
+#define SDP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define SDP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define SDP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define SDP_TRACE_WARNING0(m)
+#define SDP_TRACE_WARNING1(m,p1)
+#define SDP_TRACE_WARNING2(m,p1,p2)
+#define SDP_TRACE_WARNING3(m,p1,p2,p3)
+#define SDP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define SDP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define SDP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define SDP_TRACE_API0(m)
+#define SDP_TRACE_API1(m,p1)
+#define SDP_TRACE_API2(m,p1,p2)
+#define SDP_TRACE_API3(m,p1,p2,p3)
+#define SDP_TRACE_API4(m,p1,p2,p3,p4)
+#define SDP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define SDP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define SDP_TRACE_EVENT0(m)
+#define SDP_TRACE_EVENT1(m,p1)
+#define SDP_TRACE_EVENT2(m,p1,p2)
+#define SDP_TRACE_EVENT3(m,p1,p2,p3)
+#define SDP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define SDP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define SDP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define SDP_TRACE_DEBUG0(m)
+#define SDP_TRACE_DEBUG1(m,p1)
+#define SDP_TRACE_DEBUG2(m,p1,p2)
+#define SDP_TRACE_DEBUG3(m,p1,p2,p3)
+#define SDP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define SDP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define SDP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the RFCOMM unit
+*/
+#define RFCOMM_TRACE_ERROR0(m)
+#define RFCOMM_TRACE_ERROR1(m,p1)
+#define RFCOMM_TRACE_ERROR2(m,p1,p2)
+#define RFCOMM_TRACE_ERROR3(m,p1,p2,p3)
+#define RFCOMM_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define RFCOMM_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define RFCOMM_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define RFCOMM_TRACE_WARNING0(m)
+#define RFCOMM_TRACE_WARNING1(m,p1)
+#define RFCOMM_TRACE_WARNING2(m,p1,p2)
+#define RFCOMM_TRACE_WARNING3(m,p1,p2,p3)
+#define RFCOMM_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define RFCOMM_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define RFCOMM_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define RFCOMM_TRACE_API0(m)
+#define RFCOMM_TRACE_API1(m,p1)
+#define RFCOMM_TRACE_API2(m,p1,p2)
+#define RFCOMM_TRACE_API3(m,p1,p2,p3)
+#define RFCOMM_TRACE_API4(m,p1,p2,p3,p4)
+#define RFCOMM_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define RFCOMM_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define RFCOMM_TRACE_EVENT0(m)
+#define RFCOMM_TRACE_EVENT1(m,p1)
+#define RFCOMM_TRACE_EVENT2(m,p1,p2)
+#define RFCOMM_TRACE_EVENT3(m,p1,p2,p3)
+#define RFCOMM_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define RFCOMM_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define RFCOMM_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define RFCOMM_TRACE_DEBUG0(m)
+#define RFCOMM_TRACE_DEBUG1(m,p1)
+#define RFCOMM_TRACE_DEBUG2(m,p1,p2)
+#define RFCOMM_TRACE_DEBUG3(m,p1,p2,p3)
+#define RFCOMM_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define RFCOMM_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define RFCOMM_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for Serial Port Profile
+*/
+#define SPP_TRACE_ERROR0(m)
+#define SPP_TRACE_ERROR1(m,p1)
+#define SPP_TRACE_ERROR2(m,p1,p2)
+#define SPP_TRACE_ERROR3(m,p1,p2,p3)
+#define SPP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define SPP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define SPP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define SPP_TRACE_WARNING0(m)
+#define SPP_TRACE_WARNING1(m,p1)
+#define SPP_TRACE_WARNING2(m,p1,p2)
+#define SPP_TRACE_WARNING3(m,p1,p2,p3)
+#define SPP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define SPP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define SPP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define SPP_TRACE_EVENT0(m)
+#define SPP_TRACE_EVENT1(m,p1)
+#define SPP_TRACE_EVENT2(m,p1,p2)
+#define SPP_TRACE_EVENT3(m,p1,p2,p3)
+#define SPP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define SPP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define SPP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define SPP_TRACE_API0(m)
+#define SPP_TRACE_API1(m,p1)
+#define SPP_TRACE_API2(m,p1,p2)
+#define SPP_TRACE_API3(m,p1,p2,p3)
+#define SPP_TRACE_API4(m,p1,p2,p3,p4)
+#define SPP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define SPP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define SPP_TRACE_DEBUG0(m)
+#define SPP_TRACE_DEBUG1(m,p1)
+#define SPP_TRACE_DEBUG2(m,p1,p2)
+#define SPP_TRACE_DEBUG3(m,p1,p2,p3)
+#define SPP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define SPP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define SPP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+
+/* Generic Access Profile traces */
+#define GAP_TRACE_ERROR0(m)
+#define GAP_TRACE_ERROR1(m,p1)
+#define GAP_TRACE_ERROR2(m,p1,p2)
+#define GAP_TRACE_ERROR3(m,p1,p2,p3)
+#define GAP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define GAP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define GAP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define GAP_TRACE_EVENT0(m)
+#define GAP_TRACE_EVENT1(m,p1)
+#define GAP_TRACE_EVENT2(m,p1,p2)
+#define GAP_TRACE_EVENT3(m,p1,p2,p3)
+#define GAP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define GAP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define GAP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define GAP_TRACE_API0(m)
+#define GAP_TRACE_API1(m,p1)
+#define GAP_TRACE_API2(m,p1,p2)
+#define GAP_TRACE_API3(m,p1,p2,p3)
+#define GAP_TRACE_API4(m,p1,p2,p3,p4)
+#define GAP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define GAP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define GAP_TRACE_WARNING0(m)
+#define GAP_TRACE_WARNING1(m,p1)
+#define GAP_TRACE_WARNING2(m,p1,p2)
+#define GAP_TRACE_WARNING3(m,p1,p2,p3)
+#define GAP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define GAP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define GAP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+
+/* Define tracing for OBX
+*/
+#define OBX_TRACE_ERROR0(m)
+#define OBX_TRACE_ERROR1(m,p1)
+#define OBX_TRACE_ERROR2(m,p1,p2)
+#define OBX_TRACE_ERROR3(m,p1,p2,p3)
+#define OBX_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define OBX_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define OBX_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define OBX_TRACE_WARNING0(m)
+#define OBX_TRACE_WARNING1(m,p1)
+#define OBX_TRACE_WARNING2(m,p1,p2)
+#define OBX_TRACE_WARNING3(m,p1,p2,p3)
+#define OBX_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define OBX_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define OBX_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define OBX_TRACE_EVENT0(m)
+#define OBX_TRACE_EVENT1(m,p1)
+#define OBX_TRACE_EVENT2(m,p1,p2)
+#define OBX_TRACE_EVENT3(m,p1,p2,p3)
+#define OBX_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define OBX_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define OBX_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define OBX_TRACE_DEBUG0(m)
+#define OBX_TRACE_DEBUG1(m,p1)
+#define OBX_TRACE_DEBUG2(m,p1,p2)
+#define OBX_TRACE_DEBUG3(m,p1,p2,p3)
+#define OBX_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define OBX_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define OBX_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define OBX_TRACE_API0(m)
+#define OBX_TRACE_API1(m,p1)
+#define OBX_TRACE_API2(m,p1,p2)
+#define OBX_TRACE_API3(m,p1,p2,p3)
+#define OBX_TRACE_API4(m,p1,p2,p3,p4)
+#define OBX_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define OBX_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for GOEP application profiles
+*/
+#define GOEP_TRACE_ERROR0(m)
+#define GOEP_TRACE_ERROR1(m,p1)
+#define GOEP_TRACE_ERROR2(m,p1,p2)
+#define GOEP_TRACE_ERROR3(m,p1,p2,p3)
+#define GOEP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define GOEP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define GOEP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define GOEP_TRACE_WARNING0(m)
+#define GOEP_TRACE_WARNING1(m,p1)
+#define GOEP_TRACE_WARNING2(m,p1,p2)
+#define GOEP_TRACE_WARNING3(m,p1,p2,p3)
+#define GOEP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define GOEP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define GOEP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define GOEP_TRACE_EVENT0(m)
+#define GOEP_TRACE_EVENT1(m,p1)
+#define GOEP_TRACE_EVENT2(m,p1,p2)
+#define GOEP_TRACE_EVENT3(m,p1,p2,p3)
+#define GOEP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define GOEP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define GOEP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define GOEP_TRACE_DEBUG0(m)
+#define GOEP_TRACE_DEBUG1(m,p1)
+#define GOEP_TRACE_DEBUG2(m,p1,p2)
+#define GOEP_TRACE_DEBUG3(m,p1,p2,p3)
+#define GOEP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define GOEP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define GOEP_TRACE_API0(m)
+#define GOEP_TRACE_API1(m,p1)
+#define GOEP_TRACE_API2(m,p1,p2)
+#define GOEP_TRACE_API3(m,p1,p2,p3)
+#define GOEP_TRACE_API4(m,p1,p2,p3,p4)
+#define GOEP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define GOEP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the BPP profile
+*/
+#define BPP_TRACE_ERROR0(m)
+#define BPP_TRACE_ERROR1(m,p1)
+#define BPP_TRACE_ERROR2(m,p1,p2)
+#define BPP_TRACE_ERROR3(m,p1,p2,p3)
+#define BPP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define BPP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define BPP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define BPP_TRACE_WARNING0(m)
+#define BPP_TRACE_WARNING1(m,p1)
+#define BPP_TRACE_WARNING2(m,p1,p2)
+#define BPP_TRACE_WARNING3(m,p1,p2,p3)
+#define BPP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define BPP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define BPP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define BPP_TRACE_EVENT0(m)
+#define BPP_TRACE_EVENT1(m,p1)
+#define BPP_TRACE_EVENT2(m,p1,p2)
+#define BPP_TRACE_EVENT3(m,p1,p2,p3)
+#define BPP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define BPP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define BPP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define BPP_TRACE_DEBUG0(m)
+#define BPP_TRACE_DEBUG1(m,p1)
+#define BPP_TRACE_DEBUG2(m,p1,p2)
+#define BPP_TRACE_DEBUG3(m,p1,p2,p3)
+#define BPP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define BPP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define BPP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define BPP_TRACE_API0(m)
+#define BPP_TRACE_API1(m,p1)
+#define BPP_TRACE_API2(m,p1,p2)
+#define BPP_TRACE_API3(m,p1,p2,p3)
+#define BPP_TRACE_API4(m,p1,p2,p3,p4)
+#define BPP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define BPP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the BIP profile
+*/
+#define BIP_TRACE_ERROR0(m)
+#define BIP_TRACE_ERROR1(m,p1)
+#define BIP_TRACE_ERROR2(m,p1,p2)
+#define BIP_TRACE_ERROR3(m,p1,p2,p3)
+#define BIP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define BIP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define BIP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define BIP_TRACE_WARNING0(m)
+#define BIP_TRACE_WARNING1(m,p1)
+#define BIP_TRACE_WARNING2(m,p1,p2)
+#define BIP_TRACE_WARNING3(m,p1,p2,p3)
+#define BIP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define BIP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define BIP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define BIP_TRACE_EVENT0(m)
+#define BIP_TRACE_EVENT1(m,p1)
+#define BIP_TRACE_EVENT2(m,p1,p2)
+#define BIP_TRACE_EVENT3(m,p1,p2,p3)
+#define BIP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define BIP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define BIP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define BIP_TRACE_DEBUG0(m)
+#define BIP_TRACE_DEBUG1(m,p1)
+#define BIP_TRACE_DEBUG2(m,p1,p2)
+#define BIP_TRACE_DEBUG3(m,p1,p2,p3)
+#define BIP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define BIP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define BIP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define BIP_TRACE_API0(m)
+#define BIP_TRACE_API1(m,p1)
+#define BIP_TRACE_API2(m,p1,p2)
+#define BIP_TRACE_API3(m,p1,p2,p3)
+#define BIP_TRACE_API4(m,p1,p2,p3,p4)
+#define BIP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define BIP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for TCS
+*/
+#define TCS_TRACE_ERROR0(m)
+#define TCS_TRACE_ERROR1(m,p1)
+#define TCS_TRACE_ERROR2(m,p1,p2)
+#define TCS_TRACE_ERROR3(m,p1,p2,p3)
+#define TCS_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define TCS_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define TCS_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define TCS_TRACE_WARNING0(m)
+#define TCS_TRACE_WARNING1(m,p1)
+#define TCS_TRACE_WARNING2(m,p1,p2)
+#define TCS_TRACE_WARNING3(m,p1,p2,p3)
+#define TCS_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define TCS_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define TCS_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define TCS_TRACE_EVENT0(m)
+#define TCS_TRACE_EVENT1(m,p1)
+#define TCS_TRACE_EVENT2(m,p1,p2)
+#define TCS_TRACE_EVENT3(m,p1,p2,p3)
+#define TCS_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define TCS_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define TCS_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define TCS_TRACE_DEBUG0(m)
+#define TCS_TRACE_DEBUG1(m,p1)
+#define TCS_TRACE_DEBUG2(m,p1,p2)
+#define TCS_TRACE_DEBUG3(m,p1,p2,p3)
+#define TCS_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define TCS_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define TCS_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define TCS_TRACE_API0(m)
+#define TCS_TRACE_API1(m,p1)
+#define TCS_TRACE_API2(m,p1,p2)
+#define TCS_TRACE_API3(m,p1,p2,p3)
+#define TCS_TRACE_API4(m,p1,p2,p3,p4)
+#define TCS_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define TCS_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for ICP
+*/
+#define ICP_TRACE_ERROR0(m)
+#define ICP_TRACE_ERROR1(m,p1)
+#define ICP_TRACE_ERROR2(m,p1,p2)
+#define ICP_TRACE_ERROR3(m,p1,p2,p3)
+#define ICP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define ICP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define ICP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define ICP_TRACE_WARNING0(m)
+#define ICP_TRACE_WARNING1(m,p1)
+#define ICP_TRACE_WARNING2(m,p1,p2)
+#define ICP_TRACE_WARNING3(m,p1,p2,p3)
+#define ICP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define ICP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define ICP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define ICP_TRACE_EVENT0(m)
+#define ICP_TRACE_EVENT1(m,p1)
+#define ICP_TRACE_EVENT2(m,p1,p2)
+#define ICP_TRACE_EVENT3(m,p1,p2,p3)
+#define ICP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define ICP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define ICP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define ICP_TRACE_DEBUG0(m)
+#define ICP_TRACE_DEBUG1(m,p1)
+#define ICP_TRACE_DEBUG2(m,p1,p2)
+#define ICP_TRACE_DEBUG3(m,p1,p2,p3)
+#define ICP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define ICP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define ICP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define ICP_TRACE_API0(m)
+#define ICP_TRACE_API1(m,p1)
+#define ICP_TRACE_API2(m,p1,p2)
+#define ICP_TRACE_API3(m,p1,p2,p3)
+#define ICP_TRACE_API4(m,p1,p2,p3,p4)
+#define ICP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define ICP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for CTP
+*/
+#define CTP_TRACE_ERROR0(m)
+#define CTP_TRACE_ERROR1(m,p1)
+#define CTP_TRACE_ERROR2(m,p1,p2)
+#define CTP_TRACE_ERROR3(m,p1,p2,p3)
+#define CTP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define CTP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define CTP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define CTP_TRACE_WARNING0(m)
+#define CTP_TRACE_WARNING1(m,p1)
+#define CTP_TRACE_WARNING2(m,p1,p2)
+#define CTP_TRACE_WARNING3(m,p1,p2,p3)
+#define CTP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define CTP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define CTP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define CTP_TRACE_EVENT0(m)
+#define CTP_TRACE_EVENT1(m,p1)
+#define CTP_TRACE_EVENT2(m,p1,p2)
+#define CTP_TRACE_EVENT3(m,p1,p2,p3)
+#define CTP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define CTP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define CTP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define CTP_TRACE_DEBUG0(m)
+#define CTP_TRACE_DEBUG1(m,p1)
+#define CTP_TRACE_DEBUG2(m,p1,p2)
+#define CTP_TRACE_DEBUG3(m,p1,p2,p3)
+#define CTP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define CTP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define CTP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define CTP_TRACE_API0(m)
+#define CTP_TRACE_API1(m,p1)
+#define CTP_TRACE_API2(m,p1,p2)
+#define CTP_TRACE_API3(m,p1,p2,p3)
+#define CTP_TRACE_API4(m,p1,p2,p3,p4)
+#define CTP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define CTP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* define traces for headset profile */
+
+#define HSP2_TRACE_ERROR0(pcb,m)
+#define HSP2_TRACE_ERROR1(pcb,m,p1)
+#define HSP2_TRACE_ERROR2(pcb,m,p1,p2)
+#define HSP2_TRACE_ERROR3(pcb,m,p1,p2,p3)
+#define HSP2_TRACE_ERROR4(pcb,m,p1,p2,p3,p4)
+#define HSP2_TRACE_ERROR5(pcb,m,p1,p2,p3,p4,p5)
+#define HSP2_TRACE_ERROR6(pcb,m,p1,p2,p3,p4,p5,p6)
+
+#define HSP2_TRACE_WARNING0(pcb,m)
+#define HSP2_TRACE_WARNING1(pcb,m,p1)
+#define HSP2_TRACE_WARNING2(pcb,m,p1,p2)
+#define HSP2_TRACE_WARNING3(pcb,m,p1,p2,p3)
+#define HSP2_TRACE_WARNING4(pcb,m,p1,p2,p3,p4)
+#define HSP2_TRACE_WARNING5(pcb,m,p1,p2,p3,p4,p5)
+#define HSP2_TRACE_WARNING6(pcb,m,p1,p2,p3,p4,p5,p6)
+
+#define HSP2_TRACE_API0(pcb,m)
+#define HSP2_TRACE_API1(pcb,m,p1)
+#define HSP2_TRACE_API2(pcb,m,p1,p2)
+#define HSP2_TRACE_API3(pcb,m,p1,p2,p3)
+#define HSP2_TRACE_API4(pcb,m,p1,p2,p3,p4)
+#define HSP2_TRACE_API5(pcb,m,p1,p2,p3,p4,p5)
+#define HSP2_TRACE_API6(pcb,m,p1,p2,p3,p4,p5,p6)
+
+#define HSP2_TRACE_EVENT0(pcb,m)
+#define HSP2_TRACE_EVENT1(pcb,m,p1)
+#define HSP2_TRACE_EVENT2(pcb,m,p1,p2)
+#define HSP2_TRACE_EVENT3(pcb,m,p1,p2,p3)
+#define HSP2_TRACE_EVENT4(pcb,m,p1,p2,p3,p4)
+#define HSP2_TRACE_EVENT5(pcb,m,p1,p2,p3,p4,p5)
+#define HSP2_TRACE_EVENT6(pcb,m,p1,p2,p3,p4,p5,p6)
+
+#define HSP2_TRACE_DEBUG0(pcb,m)
+#define HSP2_TRACE_DEBUG1(pcb,m,p1)
+#define HSP2_TRACE_DEBUG2(pcb,m,p1,p2)
+#define HSP2_TRACE_DEBUG3(pcb,m,p1,p2,p3)
+#define HSP2_TRACE_DEBUG4(pcb,m,p1,p2,p3,p4)
+#define HSP2_TRACE_DEBUG5(pcb,m,p1,p2,p3,p4,p5)
+#define HSP2_TRACE_DEBUG6(pcb,m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the NFC unit
+*/
+#define NFC_TRACE_ERROR0(m)
+#define NFC_TRACE_ERROR1(m,p1)
+#define NFC_TRACE_ERROR2(m,p1,p2)
+#define NFC_TRACE_ERROR3(m,p1,p2,p3)
+#define NFC_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define NFC_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define NFC_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define NFC_TRACE_WARNING0(m)
+#define NFC_TRACE_WARNING1(m,p1)
+#define NFC_TRACE_WARNING2(m,p1,p2)
+#define NFC_TRACE_WARNING3(m,p1,p2,p3)
+#define NFC_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define NFC_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define NFC_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define NFC_TRACE_API0(m)
+#define NFC_TRACE_API1(m,p1)
+#define NFC_TRACE_API2(m,p1,p2)
+#define NFC_TRACE_API3(m,p1,p2,p3)
+#define NFC_TRACE_API4(m,p1,p2,p3,p4)
+#define NFC_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define NFC_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define NFC_TRACE_EVENT0(m)
+#define NFC_TRACE_EVENT1(m,p1)
+#define NFC_TRACE_EVENT2(m,p1,p2)
+#define NFC_TRACE_EVENT3(m,p1,p2,p3)
+#define NFC_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define NFC_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define NFC_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define NFC_TRACE_DEBUG0(m)
+#define NFC_TRACE_DEBUG1(m,p1)
+#define NFC_TRACE_DEBUG2(m,p1,p2)
+#define NFC_TRACE_DEBUG3(m,p1,p2,p3)
+#define NFC_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define NFC_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define NFC_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define NCI_TRACE_ERROR0(m)
+#define NCI_TRACE_ERROR1(m,p1)
+#define NCI_TRACE_ERROR2(m,p1,p2)
+#define NCI_TRACE_ERROR3(m,p1,p2,p3)
+#define NCI_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define NCI_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define NCI_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define NCI_TRACE_WARNING0(m)
+#define NCI_TRACE_WARNING1(m,p1)
+#define NCI_TRACE_WARNING2(m,p1,p2)
+#define NCI_TRACE_WARNING3(m,p1,p2,p3)
+#define NCI_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define NCI_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define NCI_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define NCI_TRACE_API0(m)
+#define NCI_TRACE_API1(m,p1)
+#define NCI_TRACE_API2(m,p1,p2)
+#define NCI_TRACE_API3(m,p1,p2,p3)
+#define NCI_TRACE_API4(m,p1,p2,p3,p4)
+#define NCI_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define NCI_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define NCI_TRACE_EVENT0(m)
+#define NCI_TRACE_EVENT1(m,p1)
+#define NCI_TRACE_EVENT2(m,p1,p2)
+#define NCI_TRACE_EVENT3(m,p1,p2,p3)
+#define NCI_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define NCI_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define NCI_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define NCI_TRACE_DEBUG0(m)
+#define NCI_TRACE_DEBUG1(m,p1)
+#define NCI_TRACE_DEBUG2(m,p1,p2)
+#define NCI_TRACE_DEBUG3(m,p1,p2,p3)
+#define NCI_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define NCI_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define NCI_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define RW_TRACE_ERROR0(m)
+#define RW_TRACE_ERROR1(m,p1)
+#define RW_TRACE_ERROR2(m,p1,p2)
+#define RW_TRACE_ERROR3(m,p1,p2,p3)
+#define RW_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define RW_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define RW_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define RW_TRACE_WARNING0(m)
+#define RW_TRACE_WARNING1(m,p1)
+#define RW_TRACE_WARNING2(m,p1,p2)
+#define RW_TRACE_WARNING3(m,p1,p2,p3)
+#define RW_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define RW_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define RW_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) }
+
+#define RW_TRACE_API0(m)
+#define RW_TRACE_API1(m,p1)
+#define RW_TRACE_API2(m,p1,p2)
+#define RW_TRACE_API3(m,p1,p2,p3)
+#define RW_TRACE_API4(m,p1,p2,p3,p4)
+#define RW_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define RW_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define RW_TRACE_EVENT0(m)
+#define RW_TRACE_EVENT1(m,p1)
+#define RW_TRACE_EVENT2(m,p1,p2)
+#define RW_TRACE_EVENT3(m,p1,p2,p3)
+#define RW_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define RW_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define RW_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define RW_TRACE_DEBUG0(m)
+#define RW_TRACE_DEBUG1(m,p1)
+#define RW_TRACE_DEBUG2(m,p1,p2)
+#define RW_TRACE_DEBUG3(m,p1,p2,p3)
+#define RW_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define RW_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define RW_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define CE_TRACE_ERROR0(m)
+#define CE_TRACE_ERROR1(m,p1)
+#define CE_TRACE_ERROR2(m,p1,p2)
+#define CE_TRACE_ERROR3(m,p1,p2,p3)
+#define CE_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define CE_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define CE_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define CE_TRACE_WARNING0(m)
+#define CE_TRACE_WARNING1(m,p1)
+#define CE_TRACE_WARNING2(m,p1,p2)
+#define CE_TRACE_WARNING3(m,p1,p2,p3)
+#define CE_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define CE_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define CE_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define CE_TRACE_API0(m)
+#define CE_TRACE_API1(m,p1)
+#define CE_TRACE_API2(m,p1,p2)
+#define CE_TRACE_API3(m,p1,p2,p3)
+#define CE_TRACE_API4(m,p1,p2,p3,p4)
+#define CE_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define CE_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define CE_TRACE_EVENT0(m)
+#define CE_TRACE_EVENT1(m,p1)
+#define CE_TRACE_EVENT2(m,p1,p2)
+#define CE_TRACE_EVENT3(m,p1,p2,p3)
+#define CE_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define CE_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define CE_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define CE_TRACE_DEBUG0(m)
+#define CE_TRACE_DEBUG1(m,p1)
+#define CE_TRACE_DEBUG2(m,p1,p2)
+#define CE_TRACE_DEBUG3(m,p1,p2,p3)
+#define CE_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define CE_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define CE_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define NDEF_TRACE_ERROR0(m)
+#define NDEF_TRACE_ERROR1(m,p1)
+#define NDEF_TRACE_ERROR2(m,p1,p2)
+#define NDEF_TRACE_ERROR3(m,p1,p2,p3)
+#define NDEF_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define NDEF_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define NDEF_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define NDEF_TRACE_WARNING0(m)
+#define NDEF_TRACE_WARNING1(m,p1)
+#define NDEF_TRACE_WARNING2(m,p1,p2)
+#define NDEF_TRACE_WARNING3(m,p1,p2,p3)
+#define NDEF_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define NDEF_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define NDEF_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define NDEF_TRACE_API0(m)
+#define NDEF_TRACE_API1(m,p1)
+#define NDEF_TRACE_API2(m,p1,p2)
+#define NDEF_TRACE_API3(m,p1,p2,p3)
+#define NDEF_TRACE_API4(m,p1,p2,p3,p4)
+#define NDEF_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define NDEF_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define NDEF_TRACE_EVENT0(m)
+#define NDEF_TRACE_EVENT1(m,p1)
+#define NDEF_TRACE_EVENT2(m,p1,p2)
+#define NDEF_TRACE_EVENT3(m,p1,p2,p3)
+#define NDEF_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define NDEF_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define NDEF_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define NDEF_TRACE_DEBUG0(m)
+#define NDEF_TRACE_DEBUG1(m,p1)
+#define NDEF_TRACE_DEBUG2(m,p1,p2)
+#define NDEF_TRACE_DEBUG3(m,p1,p2,p3)
+#define NDEF_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define NDEF_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define NDEF_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the NFA unit
+*/
+#define NFA_TRACE_ERROR0(m)
+#define NFA_TRACE_ERROR1(m,p1)
+#define NFA_TRACE_ERROR2(m,p1,p2)
+#define NFA_TRACE_ERROR3(m,p1,p2,p3)
+#define NFA_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define NFA_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define NFA_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define NFA_TRACE_WARNING0(m)
+#define NFA_TRACE_WARNING1(m,p1)
+#define NFA_TRACE_WARNING2(m,p1,p2)
+#define NFA_TRACE_WARNING3(m,p1,p2,p3)
+#define NFA_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define NFA_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define NFA_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define NFA_TRACE_API0(m)
+#define NFA_TRACE_API1(m,p1)
+#define NFA_TRACE_API2(m,p1,p2)
+#define NFA_TRACE_API3(m,p1,p2,p3)
+#define NFA_TRACE_API4(m,p1,p2,p3,p4)
+#define NFA_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define NFA_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define NFA_TRACE_EVENT0(m)
+#define NFA_TRACE_EVENT1(m,p1)
+#define NFA_TRACE_EVENT2(m,p1,p2)
+#define NFA_TRACE_EVENT3(m,p1,p2,p3)
+#define NFA_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define NFA_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define NFA_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define NFA_TRACE_DEBUG0(m)
+#define NFA_TRACE_DEBUG1(m,p1)
+#define NFA_TRACE_DEBUG2(m,p1,p2)
+#define NFA_TRACE_DEBUG3(m,p1,p2,p3)
+#define NFA_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define NFA_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define NFA_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the NFA P2P unit
+*/
+#define P2P_TRACE_ERROR0(m)
+#define P2P_TRACE_ERROR1(m,p1)
+#define P2P_TRACE_ERROR2(m,p1,p2)
+#define P2P_TRACE_ERROR3(m,p1,p2,p3)
+#define P2P_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define P2P_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define P2P_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define P2P_TRACE_WARNING0(m)
+#define P2P_TRACE_WARNING1(m,p1)
+#define P2P_TRACE_WARNING2(m,p1,p2)
+#define P2P_TRACE_WARNING3(m,p1,p2,p3)
+#define P2P_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define P2P_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define P2P_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define P2P_TRACE_API0(m)
+#define P2P_TRACE_API1(m,p1)
+#define P2P_TRACE_API2(m,p1,p2)
+#define P2P_TRACE_API3(m,p1,p2,p3)
+#define P2P_TRACE_API4(m,p1,p2,p3,p4)
+#define P2P_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define P2P_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define P2P_TRACE_EVENT0(m)
+#define P2P_TRACE_EVENT1(m,p1)
+#define P2P_TRACE_EVENT2(m,p1,p2)
+#define P2P_TRACE_EVENT3(m,p1,p2,p3)
+#define P2P_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define P2P_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define P2P_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define P2P_TRACE_DEBUG0(m)
+#define P2P_TRACE_DEBUG1(m,p1)
+#define P2P_TRACE_DEBUG2(m,p1,p2)
+#define P2P_TRACE_DEBUG3(m,p1,p2,p3)
+#define P2P_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define P2P_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define P2P_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the NFA CHO unit
+*/
+#define CHO_TRACE_ERROR0(m)
+#define CHO_TRACE_ERROR1(m,p1)
+#define CHO_TRACE_ERROR2(m,p1,p2)
+#define CHO_TRACE_ERROR3(m,p1,p2,p3)
+#define CHO_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define CHO_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define CHO_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define CHO_TRACE_WARNING0(m)
+#define CHO_TRACE_WARNING1(m,p1)
+#define CHO_TRACE_WARNING2(m,p1,p2)
+#define CHO_TRACE_WARNING3(m,p1,p2,p3)
+#define CHO_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define CHO_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define CHO_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define CHO_TRACE_API0(m)
+#define CHO_TRACE_API1(m,p1)
+#define CHO_TRACE_API2(m,p1,p2)
+#define CHO_TRACE_API3(m,p1,p2,p3)
+#define CHO_TRACE_API4(m,p1,p2,p3,p4)
+#define CHO_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define CHO_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define CHO_TRACE_EVENT0(m)
+#define CHO_TRACE_EVENT1(m,p1)
+#define CHO_TRACE_EVENT2(m,p1,p2)
+#define CHO_TRACE_EVENT3(m,p1,p2,p3)
+#define CHO_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define CHO_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define CHO_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define CHO_TRACE_DEBUG0(m)
+#define CHO_TRACE_DEBUG1(m,p1)
+#define CHO_TRACE_DEBUG2(m,p1,p2)
+#define CHO_TRACE_DEBUG3(m,p1,p2,p3)
+#define CHO_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define CHO_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define CHO_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the NFA SNEP unit
+*/
+#define SNEP_TRACE_ERROR0(m)
+#define SNEP_TRACE_ERROR1(m,p1)
+#define SNEP_TRACE_ERROR2(m,p1,p2)
+#define SNEP_TRACE_ERROR3(m,p1,p2,p3)
+#define SNEP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define SNEP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define SNEP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define SNEP_TRACE_WARNING0(m)
+#define SNEP_TRACE_WARNING1(m,p1)
+#define SNEP_TRACE_WARNING2(m,p1,p2)
+#define SNEP_TRACE_WARNING3(m,p1,p2,p3)
+#define SNEP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define SNEP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define SNEP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define SNEP_TRACE_API0(m)
+#define SNEP_TRACE_API1(m,p1)
+#define SNEP_TRACE_API2(m,p1,p2)
+#define SNEP_TRACE_API3(m,p1,p2,p3)
+#define SNEP_TRACE_API4(m,p1,p2,p3,p4)
+#define SNEP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define SNEP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define SNEP_TRACE_EVENT0(m)
+#define SNEP_TRACE_EVENT1(m,p1)
+#define SNEP_TRACE_EVENT2(m,p1,p2)
+#define SNEP_TRACE_EVENT3(m,p1,p2,p3)
+#define SNEP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define SNEP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define SNEP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define SNEP_TRACE_DEBUG0(m)
+#define SNEP_TRACE_DEBUG1(m,p1)
+#define SNEP_TRACE_DEBUG2(m,p1,p2)
+#define SNEP_TRACE_DEBUG3(m,p1,p2,p3)
+#define SNEP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define SNEP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define SNEP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+
+/* define traces for HID Host */
+#define HIDH_TRACE_ERROR0(m)
+#define HIDH_TRACE_ERROR1(m,p1)
+#define HIDH_TRACE_ERROR2(m,p1,p2)
+#define HIDH_TRACE_ERROR3(m,p1,p2,p3)
+#define HIDH_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define HIDH_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define HIDH_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define HIDH_TRACE_WARNING0(m)
+#define HIDH_TRACE_WARNING1(m,p1)
+#define HIDH_TRACE_WARNING2(m,p1,p2)
+#define HIDH_TRACE_WARNING3(m,p1,p2,p3)
+#define HIDH_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define HIDH_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define HIDH_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define HIDH_TRACE_API0(m)
+#define HIDH_TRACE_API1(m,p1)
+#define HIDH_TRACE_API2(m,p1,p2)
+#define HIDH_TRACE_API3(m,p1,p2,p3)
+#define HIDH_TRACE_API4(m,p1,p2,p3,p4)
+#define HIDH_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define HIDH_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define HIDH_TRACE_EVENT0(m)
+#define HIDH_TRACE_EVENT1(m,p1)
+#define HIDH_TRACE_EVENT2(m,p1,p2)
+#define HIDH_TRACE_EVENT3(m,p1,p2,p3)
+#define HIDH_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define HIDH_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define HIDH_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define HIDH_TRACE_DEBUG0(m)
+#define HIDH_TRACE_DEBUG1(m,p1)
+#define HIDH_TRACE_DEBUG2(m,p1,p2)
+#define HIDH_TRACE_DEBUG3(m,p1,p2,p3)
+#define HIDH_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define HIDH_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define HIDH_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* define traces for HID Device */
+#define HIDD_TRACE_ERROR0(m)
+#define HIDD_TRACE_ERROR1(m,p1)
+#define HIDD_TRACE_ERROR2(m,p1,p2)
+#define HIDD_TRACE_ERROR3(m,p1,p2,p3)
+#define HIDD_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define HIDD_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define HIDD_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define HIDD_TRACE_WARNING0(m)
+#define HIDD_TRACE_WARNING1(m,p1)
+#define HIDD_TRACE_WARNING2(m,p1,p2)
+#define HIDD_TRACE_WARNING3(m,p1,p2,p3)
+#define HIDD_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define HIDD_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define HIDD_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define HIDD_TRACE_API0(m)
+#define HIDD_TRACE_API1(m,p1)
+#define HIDD_TRACE_API2(m,p1,p2)
+#define HIDD_TRACE_API3(m,p1,p2,p3)
+#define HIDD_TRACE_API4(m,p1,p2,p3,p4)
+#define HIDD_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define HIDD_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define HIDD_TRACE_EVENT0(m)
+#define HIDD_TRACE_EVENT1(m,p1)
+#define HIDD_TRACE_EVENT2(m,p1,p2)
+#define HIDD_TRACE_EVENT3(m,p1,p2,p3)
+#define HIDD_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define HIDD_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define HIDD_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define HIDD_TRACE_DEBUG0(m)
+#define HIDD_TRACE_DEBUG1(m,p1)
+#define HIDD_TRACE_DEBUG2(m,p1,p2)
+#define HIDD_TRACE_DEBUG3(m,p1,p2,p3)
+#define HIDD_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define HIDD_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define HIDD_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* define traces for DUN */
+
+#define DUN_TRACE_ERROR0(m)
+#define DUN_TRACE_ERROR1(m,p1)
+#define DUN_TRACE_ERROR2(m,p1,p2)
+#define DUN_TRACE_ERROR3(m,p1,p2,p3)
+#define DUN_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define DUN_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define DUN_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define DUN_TRACE_WARNING0(m)
+#define DUN_TRACE_WARNING1(m,p1)
+#define DUN_TRACE_WARNING2(m,p1,p2)
+#define DUN_TRACE_WARNING3(m,p1,p2,p3)
+#define DUN_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define DUN_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define DUN_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define DUN_TRACE_API0(m)
+#define DUN_TRACE_API1(m,p1)
+#define DUN_TRACE_API2(m,p1,p2)
+#define DUN_TRACE_API3(m,p1,p2,p3)
+#define DUN_TRACE_API4(m,p1,p2,p3,p4)
+#define DUN_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define DUN_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define DUN_TRACE_EVENT0(m)
+#define DUN_TRACE_EVENT1(m,p1)
+#define DUN_TRACE_EVENT2(m,p1,p2)
+#define DUN_TRACE_EVENT3(m,p1,p2,p3)
+#define DUN_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define DUN_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define DUN_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define DUN_TRACE_DEBUG0(m)
+#define DUN_TRACE_DEBUG1(m,p1)
+#define DUN_TRACE_DEBUG2(m,p1,p2)
+#define DUN_TRACE_DEBUG3(m,p1,p2,p3)
+#define DUN_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define DUN_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define DUN_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* define traces for HCRP */
+
+#define HCRP_TRACE_ERROR0(m)
+#define HCRP_TRACE_ERROR1(m,p1)
+#define HCRP_TRACE_ERROR2(m,p1,p2)
+#define HCRP_TRACE_ERROR3(m,p1,p2,p3)
+#define HCRP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define HCRP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define HCRP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCRP_TRACE_WARNING0(m)
+#define HCRP_TRACE_WARNING1(m,p1)
+#define HCRP_TRACE_WARNING2(m,p1,p2)
+#define HCRP_TRACE_WARNING3(m,p1,p2,p3)
+#define HCRP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define HCRP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define HCRP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCRP_TRACE_API0(m)
+#define HCRP_TRACE_API1(m,p1)
+#define HCRP_TRACE_API2(m,p1,p2)
+#define HCRP_TRACE_API3(m,p1,p2,p3)
+#define HCRP_TRACE_API4(m,p1,p2,p3,p4)
+#define HCRP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define HCRP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCRP_TRACE_EVENT0(m)
+#define HCRP_TRACE_EVENT1(m,p1)
+#define HCRP_TRACE_EVENT2(m,p1,p2)
+#define HCRP_TRACE_EVENT3(m,p1,p2,p3)
+#define HCRP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define HCRP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define HCRP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCRP_TRACE_DEBUG0(m)
+#define HCRP_TRACE_DEBUG1(m,p1)
+#define HCRP_TRACE_DEBUG2(m,p1,p2)
+#define HCRP_TRACE_DEBUG3(m,p1,p2,p3)
+#define HCRP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define HCRP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define HCRP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+
+/* define traces for HCRP */
+
+#define HCRPM_TRACE_ERROR0(m)
+#define HCRPM_TRACE_ERROR1(m,p1)
+#define HCRPM_TRACE_ERROR2(m,p1,p2)
+#define HCRPM_TRACE_ERROR3(m,p1,p2,p3)
+#define HCRPM_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define HCRPM_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define HCRPM_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCRPM_TRACE_WARNING0(m)
+#define HCRPM_TRACE_WARNING1(m,p1)
+#define HCRPM_TRACE_WARNING2(m,p1,p2)
+#define HCRPM_TRACE_WARNING3(m,p1,p2,p3)
+#define HCRPM_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define HCRPM_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define HCRPM_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCRPM_TRACE_API0(m)
+#define HCRPM_TRACE_API1(m,p1)
+#define HCRPM_TRACE_API2(m,p1,p2)
+#define HCRPM_TRACE_API3(m,p1,p2,p3)
+#define HCRPM_TRACE_API4(m,p1,p2,p3,p4)
+#define HCRPM_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define HCRPM_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCRPM_TRACE_EVENT0(m)
+#define HCRPM_TRACE_EVENT1(m,p1)
+#define HCRPM_TRACE_EVENT2(m,p1,p2)
+#define HCRPM_TRACE_EVENT3(m,p1,p2,p3)
+#define HCRPM_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define HCRPM_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define HCRPM_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCRPM_TRACE_DEBUG0(m)
+#define HCRPM_TRACE_DEBUG1(m,p1)
+#define HCRPM_TRACE_DEBUG2(m,p1,p2)
+#define HCRPM_TRACE_DEBUG3(m,p1,p2,p3)
+#define HCRPM_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define HCRPM_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define HCRPM_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* define traces for RPC */
+
+#define RPC_TRACE_ERROR0(m)
+#define RPC_TRACE_ERROR1(m,p1)
+#define RPC_TRACE_ERROR2(m,p1,p2)
+#define RPC_TRACE_ERROR3(m,p1,p2,p3)
+#define RPC_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define RPC_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define RPC_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define RPC_TRACE_WARNING0(m)
+#define RPC_TRACE_WARNING1(m,p1)
+#define RPC_TRACE_WARNING2(m,p1,p2)
+#define RPC_TRACE_WARNING3(m,p1,p2,p3)
+#define RPC_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define RPC_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define RPC_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define RPC_TRACE_API0(m)
+#define RPC_TRACE_API1(m,p1)
+#define RPC_TRACE_API2(m,p1,p2)
+#define RPC_TRACE_API3(m,p1,p2,p3)
+#define RPC_TRACE_API4(m,p1,p2,p3,p4)
+#define RPC_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define RPC_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define RPC_TRACE_EVENT0(m)
+#define RPC_TRACE_EVENT1(m,p1)
+#define RPC_TRACE_EVENT2(m,p1,p2)
+#define RPC_TRACE_EVENT3(m,p1,p2,p3)
+#define RPC_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define RPC_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define RPC_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define RPC_TRACE_DEBUG0(m)
+#define RPC_TRACE_DEBUG1(m,p1)
+#define RPC_TRACE_DEBUG2(m,p1,p2)
+#define RPC_TRACE_DEBUG3(m,p1,p2,p3)
+#define RPC_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define RPC_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define RPC_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* define traces for BNEP */
+
+#define BNEP_TRACE_ERROR0(m)
+#define BNEP_TRACE_ERROR1(m,p1)
+#define BNEP_TRACE_ERROR2(m,p1,p2)
+#define BNEP_TRACE_ERROR3(m,p1,p2,p3)
+#define BNEP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define BNEP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define BNEP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define BNEP_TRACE_WARNING0(m)
+#define BNEP_TRACE_WARNING1(m,p1)
+#define BNEP_TRACE_WARNING2(m,p1,p2)
+#define BNEP_TRACE_WARNING3(m,p1,p2,p3)
+#define BNEP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define BNEP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define BNEP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define BNEP_TRACE_API0(m)
+#define BNEP_TRACE_API1(m,p1)
+#define BNEP_TRACE_API2(m,p1,p2)
+#define BNEP_TRACE_API3(m,p1,p2,p3)
+#define BNEP_TRACE_API4(m,p1,p2,p3,p4)
+#define BNEP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define BNEP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define BNEP_TRACE_EVENT0(m)
+#define BNEP_TRACE_EVENT1(m,p1)
+#define BNEP_TRACE_EVENT2(m,p1,p2)
+#define BNEP_TRACE_EVENT3(m,p1,p2,p3)
+#define BNEP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define BNEP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define BNEP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define BNEP_TRACE_DEBUG0(m)
+#define BNEP_TRACE_DEBUG1(m,p1)
+#define BNEP_TRACE_DEBUG2(m,p1,p2)
+#define BNEP_TRACE_DEBUG3(m,p1,p2,p3)
+#define BNEP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define BNEP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define BNEP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* hid module traces */
+
+#define MSKB_TRACE_0(m)
+#define MSKB_TRACE_1(m,p1)
+#define MSKB_TRACE_2(m,p1,p2)
+#define MSKB_TRACE_3(m,p1,p2,p3)
+#define MSKB_TRACE_4(m,p1,p2,p3,p4)
+#define MSKB_TRACE_5(m,p1,p2,p3,p4,p5)
+#define MSKB_TRACE_6(m,p1,p2,p3,p4,p5,p6)
+
+#define MSKB_DEBUG_0(m)
+#define MSKB_DEBUG_1(m,p1)
+#define MSKB_DEBUG_2(m,p1,p2)
+#define MSKB_DEBUG_3(m,p1,p2,p3)
+#define MSKB_DEBUG_4(m,p1,p2,p3,p4)
+#define MSKB_DEBUG_5(m,p1,p2,p3,p4,p5)
+#define MSKB_DEBUG_6(m,p1,p2,p3,p4,p5,p6)
+
+#define MSKB_ERROR_0(m)
+#define MSKB_ERROR_1(m,p1)
+#define MSKB_ERROR_2(m,p1,p2)
+#define MSKB_ERROR_3(m,p1,p2,p3)
+#define MSKB_ERROR_4(m,p1,p2,p3,p4)
+#define MSKB_ERROR_5(m,p1,p2,p3,p4,p5)
+#define MSKB_ERROR_6(m,p1,p2,p3,p4,p5,p6)
+
+/* define traces for PAN */
+
+#define PAN_TRACE_ERROR0(m)
+#define PAN_TRACE_ERROR1(m,p1)
+#define PAN_TRACE_ERROR2(m,p1,p2)
+#define PAN_TRACE_ERROR3(m,p1,p2,p3)
+#define PAN_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define PAN_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define PAN_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define PAN_TRACE_WARNING0(m)
+#define PAN_TRACE_WARNING1(m,p1)
+#define PAN_TRACE_WARNING2(m,p1,p2)
+#define PAN_TRACE_WARNING3(m,p1,p2,p3)
+#define PAN_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define PAN_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define PAN_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define PAN_TRACE_API0(m)
+#define PAN_TRACE_API1(m,p1)
+#define PAN_TRACE_API2(m,p1,p2)
+#define PAN_TRACE_API3(m,p1,p2,p3)
+#define PAN_TRACE_API4(m,p1,p2,p3,p4)
+#define PAN_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define PAN_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define PAN_TRACE_EVENT0(m)
+#define PAN_TRACE_EVENT1(m,p1)
+#define PAN_TRACE_EVENT2(m,p1,p2)
+#define PAN_TRACE_EVENT3(m,p1,p2,p3)
+#define PAN_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define PAN_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define PAN_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define PAN_TRACE_DEBUG0(m)
+#define PAN_TRACE_DEBUG1(m,p1)
+#define PAN_TRACE_DEBUG2(m,p1,p2)
+#define PAN_TRACE_DEBUG3(m,p1,p2,p3)
+#define PAN_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define PAN_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define PAN_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* define traces for SIM */
+
+#define SAP_TRACE_ERROR0(m)
+#define SAP_TRACE_ERROR1(m,p1)
+#define SAP_TRACE_ERROR2(m,p1,p2)
+#define SAP_TRACE_ERROR3(m,p1,p2,p3)
+#define SAP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define SAP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define SAP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define SAP_TRACE_WARNING0(m)
+#define SAP_TRACE_WARNING1(m,p1)
+#define SAP_TRACE_WARNING2(m,p1,p2)
+#define SAP_TRACE_WARNING3(m,p1,p2,p3)
+#define SAP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define SAP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define SAP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define SAP_TRACE_API0(m)
+#define SAP_TRACE_API1(m,p1)
+#define SAP_TRACE_API2(m,p1,p2)
+#define SAP_TRACE_API3(m,p1,p2,p3)
+#define SAP_TRACE_API4(m,p1,p2,p3,p4)
+#define SAP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define SAP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define SAP_TRACE_EVENT0(m)
+#define SAP_TRACE_EVENT1(m,p1)
+#define SAP_TRACE_EVENT2(m,p1,p2)
+#define SAP_TRACE_EVENT3(m,p1,p2,p3)
+#define SAP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define SAP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define SAP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define SAP_TRACE_DEBUG0(m)
+#define SAP_TRACE_DEBUG1(m,p1)
+#define SAP_TRACE_DEBUG2(m,p1,p2)
+#define SAP_TRACE_DEBUG3(m,p1,p2,p3)
+#define SAP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define SAP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define SAP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the OPP profile
+*/
+#define OPP_TRACE_ERROR0(m)
+#define OPP_TRACE_ERROR1(m,p1)
+#define OPP_TRACE_ERROR2(m,p1,p2)
+#define OPP_TRACE_ERROR3(m,p1,p2,p3)
+#define OPP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define OPP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define OPP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define OPP_TRACE_WARNING0(m)
+#define OPP_TRACE_WARNING1(m,p1)
+#define OPP_TRACE_WARNING2(m,p1,p2)
+#define OPP_TRACE_WARNING3(m,p1,p2,p3)
+#define OPP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define OPP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define OPP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define OPP_TRACE_EVENT0(m)
+#define OPP_TRACE_EVENT1(m,p1)
+#define OPP_TRACE_EVENT2(m,p1,p2)
+#define OPP_TRACE_EVENT3(m,p1,p2,p3)
+#define OPP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define OPP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define OPP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define OPP_TRACE_DEBUG0(m)
+#define OPP_TRACE_DEBUG1(m,p1)
+#define OPP_TRACE_DEBUG2(m,p1,p2)
+#define OPP_TRACE_DEBUG3(m,p1,p2,p3)
+#define OPP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define OPP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define OPP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define OPP_TRACE_API0(m)
+#define OPP_TRACE_API1(m,p1)
+#define OPP_TRACE_API2(m,p1,p2)
+#define OPP_TRACE_API3(m,p1,p2,p3)
+#define OPP_TRACE_API4(m,p1,p2,p3,p4)
+#define OPP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define OPP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the FTP profile
+*/
+#define FTP_TRACE_ERROR0(m)
+#define FTP_TRACE_ERROR1(m,p1)
+#define FTP_TRACE_ERROR2(m,p1,p2)
+#define FTP_TRACE_ERROR3(m,p1,p2,p3)
+#define FTP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define FTP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define FTP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define FTP_TRACE_WARNING0(m)
+#define FTP_TRACE_WARNING1(m,p1)
+#define FTP_TRACE_WARNING2(m,p1,p2)
+#define FTP_TRACE_WARNING3(m,p1,p2,p3)
+#define FTP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define FTP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define FTP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define FTP_TRACE_EVENT0(m)
+#define FTP_TRACE_EVENT1(m,p1)
+#define FTP_TRACE_EVENT2(m,p1,p2)
+#define FTP_TRACE_EVENT3(m,p1,p2,p3)
+#define FTP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define FTP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define FTP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define FTP_TRACE_DEBUG0(m)
+#define FTP_TRACE_DEBUG1(m,p1)
+#define FTP_TRACE_DEBUG2(m,p1,p2)
+#define FTP_TRACE_DEBUG3(m,p1,p2,p3)
+#define FTP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define FTP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define FTP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define FTP_TRACE_API0(m)
+#define FTP_TRACE_API1(m,p1)
+#define FTP_TRACE_API2(m,p1,p2)
+#define FTP_TRACE_API3(m,p1,p2,p3)
+#define FTP_TRACE_API4(m,p1,p2,p3,p4)
+#define FTP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define FTP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+
+/* Define tracing for the A2DP profile
+*/
+#define A2D_TRACE_ERROR0(m)
+#define A2D_TRACE_ERROR1(m,p1)
+#define A2D_TRACE_ERROR2(m,p1,p2)
+#define A2D_TRACE_ERROR3(m,p1,p2,p3)
+#define A2D_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define A2D_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define A2D_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define A2D_TRACE_WARNING0(m)
+#define A2D_TRACE_WARNING1(m,p1)
+#define A2D_TRACE_WARNING2(m,p1,p2)
+#define A2D_TRACE_WARNING3(m,p1,p2,p3)
+#define A2D_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define A2D_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define A2D_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define A2D_TRACE_EVENT0(m)
+#define A2D_TRACE_EVENT1(m,p1)
+#define A2D_TRACE_EVENT2(m,p1,p2)
+#define A2D_TRACE_EVENT3(m,p1,p2,p3)
+#define A2D_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define A2D_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define A2D_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define A2D_TRACE_DEBUG0(m)
+#define A2D_TRACE_DEBUG1(m,p1)
+#define A2D_TRACE_DEBUG2(m,p1,p2)
+#define A2D_TRACE_DEBUG3(m,p1,p2,p3)
+#define A2D_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define A2D_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define A2D_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define A2D_TRACE_API0(m)
+#define A2D_TRACE_API1(m,p1)
+#define A2D_TRACE_API2(m,p1,p2)
+#define A2D_TRACE_API3(m,p1,p2,p3)
+#define A2D_TRACE_API4(m,p1,p2,p3,p4)
+#define A2D_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define A2D_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the VDP profile
+*/
+#define VDP_TRACE_ERROR0(m)
+#define VDP_TRACE_ERROR1(m,p1)
+#define VDP_TRACE_ERROR2(m,p1,p2)
+#define VDP_TRACE_ERROR3(m,p1,p2,p3)
+#define VDP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define VDP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define VDP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define VDP_TRACE_WARNING0(m)
+#define VDP_TRACE_WARNING1(m,p1)
+#define VDP_TRACE_WARNING2(m,p1,p2)
+#define VDP_TRACE_WARNING3(m,p1,p2,p3)
+#define VDP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define VDP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define VDP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define VDP_TRACE_EVENT0(m)
+#define VDP_TRACE_EVENT1(m,p1)
+#define VDP_TRACE_EVENT2(m,p1,p2)
+#define VDP_TRACE_EVENT3(m,p1,p2,p3)
+#define VDP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define VDP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define VDP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define VDP_TRACE_DEBUG0(m)
+#define VDP_TRACE_DEBUG1(m,p1)
+#define VDP_TRACE_DEBUG2(m,p1,p2)
+#define VDP_TRACE_DEBUG3(m,p1,p2,p3)
+#define VDP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define VDP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define VDP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define VDP_TRACE_API0(m)
+#define VDP_TRACE_API1(m,p1)
+#define VDP_TRACE_API2(m,p1,p2)
+#define VDP_TRACE_API3(m,p1,p2,p3)
+#define VDP_TRACE_API4(m,p1,p2,p3,p4)
+#define VDP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define VDP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+
+/* Define tracing for the LM unit
+*/
+#define LMP_TRACE_ERROR0(m)
+#define LMP_TRACE_ERROR1(m,p1)
+#define LMP_TRACE_ERROR2(m,p1,p2)
+#define LMP_TRACE_ERROR3(m,p1,p2,p3)
+#define LMP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define LMP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define LMP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define LMP_TRACE_WARNING0(m)
+#define LMP_TRACE_WARNING1(m,p1)
+#define LMP_TRACE_WARNING2(m,p1,p2)
+#define LMP_TRACE_WARNING3(m,p1,p2,p3)
+#define LMP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define LMP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define LMP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define LMP_TRACE_EVENT0(m)
+#define LMP_TRACE_EVENT1(m,p1)
+#define LMP_TRACE_EVENT2(m,p1,p2)
+#define LMP_TRACE_EVENT3(m,p1,p2,p3)
+#define LMP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define LMP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define LMP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define LMP_TRACE_DEBUG0(m)
+#define LMP_TRACE_DEBUG1(m,p1)
+#define LMP_TRACE_DEBUG2(m,p1,p2)
+#define LMP_TRACE_DEBUG3(m,p1,p2,p3)
+#define LMP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define LMP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define LMP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the LC unit
+*/
+#define LC_TRACE_ERROR0(m)
+#define LC_TRACE_ERROR1(m,p1)
+#define LC_TRACE_ERROR2(m,p1,p2)
+#define LC_TRACE_ERROR3(m,p1,p2,p3)
+#define LC_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define LC_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define LC_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define LC_TRACE_WARNING0(m)
+#define LC_TRACE_WARNING1(m,p1)
+#define LC_TRACE_WARNING2(m,p1,p2)
+#define LC_TRACE_WARNING3(m,p1,p2,p3)
+#define LC_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define LC_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define LC_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define LC_TRACE_EVENT0(m)
+#define LC_TRACE_EVENT1(m,p1)
+#define LC_TRACE_EVENT2(m,p1,p2)
+#define LC_TRACE_EVENT3(m,p1,p2,p3)
+#define LC_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define LC_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define LC_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define LC_TRACE_DEBUG0(m)
+#define LC_TRACE_DEBUG1(m,p1)
+#define LC_TRACE_DEBUG2(m,p1,p2)
+#define LC_TRACE_DEBUG3(m,p1,p2,p3)
+#define LC_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define LC_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define LC_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define SDA_TRACE_ERROR0(m)
+#define SDA_TRACE_ERROR1(m,p1)
+#define SDA_TRACE_ERROR2(m,p1,p2)
+#define SDA_TRACE_ERROR3(m,p1,p2,p3)
+#define SDA_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define SDA_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define SDA_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define SDA_TRACE_WARNING0(m)
+#define SDA_TRACE_WARNING1(m,p1)
+#define SDA_TRACE_WARNING2(m,p1,p2)
+#define SDA_TRACE_WARNING3(m,p1,p2,p3)
+#define SDA_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define SDA_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define SDA_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define SDA_TRACE_EVENT0(m)
+#define SDA_TRACE_EVENT1(m,p1)
+#define SDA_TRACE_EVENT2(m,p1,p2)
+#define SDA_TRACE_EVENT3(m,p1,p2,p3)
+#define SDA_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define SDA_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define SDA_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define SDA_TRACE_DEBUG0(m)
+#define SDA_TRACE_DEBUG1(m,p1)
+#define SDA_TRACE_DEBUG2(m,p1,p2)
+#define SDA_TRACE_DEBUG3(m,p1,p2,p3)
+#define SDA_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define SDA_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define SDA_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* AVDTP
+*/
+#define AVDT_TRACE_ERROR0(m)
+#define AVDT_TRACE_ERROR1(m,p1)
+#define AVDT_TRACE_ERROR2(m,p1,p2)
+#define AVDT_TRACE_ERROR3(m,p1,p2,p3)
+#define AVDT_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define AVDT_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define AVDT_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVDT_TRACE_WARNING0(m)
+#define AVDT_TRACE_WARNING1(m,p1)
+#define AVDT_TRACE_WARNING2(m,p1,p2)
+#define AVDT_TRACE_WARNING3(m,p1,p2,p3)
+#define AVDT_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define AVDT_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define AVDT_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVDT_TRACE_EVENT0(m)
+#define AVDT_TRACE_EVENT1(m,p1)
+#define AVDT_TRACE_EVENT2(m,p1,p2)
+#define AVDT_TRACE_EVENT3(m,p1,p2,p3)
+#define AVDT_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define AVDT_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define AVDT_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVDT_TRACE_DEBUG0(m)
+#define AVDT_TRACE_DEBUG1(m,p1)
+#define AVDT_TRACE_DEBUG2(m,p1,p2)
+#define AVDT_TRACE_DEBUG3(m,p1,p2,p3)
+#define AVDT_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define AVDT_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define AVDT_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVDT_TRACE_API0(m)
+#define AVDT_TRACE_API1(m,p1)
+#define AVDT_TRACE_API2(m,p1,p2)
+#define AVDT_TRACE_API3(m,p1,p2,p3)
+#define AVDT_TRACE_API4(m,p1,p2,p3,p4)
+#define AVDT_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define AVDT_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the AVCTP protocol
+*/
+#define AVCT_TRACE_ERROR0(m)
+#define AVCT_TRACE_ERROR1(m,p1)
+#define AVCT_TRACE_ERROR2(m,p1,p2)
+#define AVCT_TRACE_ERROR3(m,p1,p2,p3)
+#define AVCT_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define AVCT_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define AVCT_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVCT_TRACE_WARNING0(m)
+#define AVCT_TRACE_WARNING1(m,p1)
+#define AVCT_TRACE_WARNING2(m,p1,p2)
+#define AVCT_TRACE_WARNING3(m,p1,p2,p3)
+#define AVCT_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define AVCT_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define AVCT_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVCT_TRACE_EVENT0(m)
+#define AVCT_TRACE_EVENT1(m,p1)
+#define AVCT_TRACE_EVENT2(m,p1,p2)
+#define AVCT_TRACE_EVENT3(m,p1,p2,p3)
+#define AVCT_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define AVCT_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define AVCT_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVCT_TRACE_DEBUG0(m)
+#define AVCT_TRACE_DEBUG1(m,p1)
+#define AVCT_TRACE_DEBUG2(m,p1,p2)
+#define AVCT_TRACE_DEBUG3(m,p1,p2,p3)
+#define AVCT_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define AVCT_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define AVCT_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVCT_TRACE_API0(m)
+#define AVCT_TRACE_API1(m,p1)
+#define AVCT_TRACE_API2(m,p1,p2)
+#define AVCT_TRACE_API3(m,p1,p2,p3)
+#define AVCT_TRACE_API4(m,p1,p2,p3,p4)
+#define AVCT_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define AVCT_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+
+/* Define tracing for the AVRCP profile
+*/
+#define AVRC_TRACE_ERROR0(m)
+#define AVRC_TRACE_ERROR1(m,p1)
+#define AVRC_TRACE_ERROR2(m,p1,p2)
+#define AVRC_TRACE_ERROR3(m,p1,p2,p3)
+#define AVRC_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define AVRC_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define AVRC_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVRC_TRACE_WARNING0(m)
+#define AVRC_TRACE_WARNING1(m,p1)
+#define AVRC_TRACE_WARNING2(m,p1,p2)
+#define AVRC_TRACE_WARNING3(m,p1,p2,p3)
+#define AVRC_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define AVRC_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define AVRC_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVRC_TRACE_EVENT0(m)
+#define AVRC_TRACE_EVENT1(m,p1)
+#define AVRC_TRACE_EVENT2(m,p1,p2)
+#define AVRC_TRACE_EVENT3(m,p1,p2,p3)
+#define AVRC_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define AVRC_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define AVRC_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVRC_TRACE_DEBUG0(m)
+#define AVRC_TRACE_DEBUG1(m,p1)
+#define AVRC_TRACE_DEBUG2(m,p1,p2)
+#define AVRC_TRACE_DEBUG3(m,p1,p2,p3)
+#define AVRC_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define AVRC_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define AVRC_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVRC_TRACE_API0(m)
+#define AVRC_TRACE_API1(m,p1)
+#define AVRC_TRACE_API2(m,p1,p2)
+#define AVRC_TRACE_API3(m,p1,p2,p3)
+#define AVRC_TRACE_API4(m,p1,p2,p3,p4)
+#define AVRC_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define AVRC_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* MCAP
+*/
+#define MCA_TRACE_ERROR0(m)
+#define MCA_TRACE_ERROR1(m,p1)
+#define MCA_TRACE_ERROR2(m,p1,p2)
+#define MCA_TRACE_ERROR3(m,p1,p2,p3)
+#define MCA_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define MCA_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define MCA_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define MCA_TRACE_WARNING0(m)
+#define MCA_TRACE_WARNING1(m,p1)
+#define MCA_TRACE_WARNING2(m,p1,p2)
+#define MCA_TRACE_WARNING3(m,p1,p2,p3)
+#define MCA_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define MCA_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define MCA_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define MCA_TRACE_EVENT0(m)
+#define MCA_TRACE_EVENT1(m,p1)
+#define MCA_TRACE_EVENT2(m,p1,p2)
+#define MCA_TRACE_EVENT3(m,p1,p2,p3)
+#define MCA_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define MCA_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define MCA_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define MCA_TRACE_DEBUG0(m)
+#define MCA_TRACE_DEBUG1(m,p1)
+#define MCA_TRACE_DEBUG2(m,p1,p2)
+#define MCA_TRACE_DEBUG3(m,p1,p2,p3)
+#define MCA_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define MCA_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define MCA_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define MCA_TRACE_API0(m)
+#define MCA_TRACE_API1(m,p1)
+#define MCA_TRACE_API2(m,p1,p2)
+#define MCA_TRACE_API3(m,p1,p2,p3)
+#define MCA_TRACE_API4(m,p1,p2,p3,p4)
+#define MCA_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define MCA_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the AMP unit
+*/
+#define AMP_TRACE_ERROR0(m)
+#define AMP_TRACE_ERROR1(m,p1)
+#define AMP_TRACE_ERROR2(m,p1,p2)
+#define AMP_TRACE_ERROR3(m,p1,p2,p3)
+#define AMP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define AMP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define AMP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define AMP_TRACE_WARNING0(m)
+#define AMP_TRACE_WARNING1(m,p1)
+#define AMP_TRACE_WARNING2(m,p1,p2)
+#define AMP_TRACE_WARNING3(m,p1,p2,p3)
+#define AMP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define AMP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define AMP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define AMP_TRACE_API0(m)
+#define AMP_TRACE_API1(m,p1)
+#define AMP_TRACE_API2(m,p1,p2)
+#define AMP_TRACE_API3(m,p1,p2,p3)
+#define AMP_TRACE_API4(m,p1,p2,p3,p4)
+#define AMP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define AMP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define AMP_TRACE_EVENT0(m)
+#define AMP_TRACE_EVENT1(m,p1)
+#define AMP_TRACE_EVENT2(m,p1,p2)
+#define AMP_TRACE_EVENT3(m,p1,p2,p3)
+#define AMP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define AMP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define AMP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define AMP_TRACE_DEBUG0(m)
+#define AMP_TRACE_DEBUG1(m,p1)
+#define AMP_TRACE_DEBUG2(m,p1,p2)
+#define AMP_TRACE_DEBUG3(m,p1,p2,p3)
+#define AMP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define AMP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define AMP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the GATT
+*/
+#define GATT_TRACE_ERROR0(m)
+#define GATT_TRACE_ERROR1(m,p1)
+#define GATT_TRACE_ERROR2(m,p1,p2)
+#define GATT_TRACE_ERROR3(m,p1,p2,p3)
+#define GATT_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define GATT_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define GATT_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define GATT_TRACE_WARNING0(m)
+#define GATT_TRACE_WARNING1(m,p1)
+#define GATT_TRACE_WARNING2(m,p1,p2)
+#define GATT_TRACE_WARNING3(m,p1,p2,p3)
+#define GATT_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define GATT_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define GATT_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define GATT_TRACE_API0(m)
+#define GATT_TRACE_API1(m,p1)
+#define GATT_TRACE_API2(m,p1,p2)
+#define GATT_TRACE_API3(m,p1,p2,p3)
+#define GATT_TRACE_API4(m,p1,p2,p3,p4)
+#define GATT_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define GATT_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define GATT_TRACE_EVENT0(m)
+#define GATT_TRACE_EVENT1(m,p1)
+#define GATT_TRACE_EVENT2(m,p1,p2)
+#define GATT_TRACE_EVENT3(m,p1,p2,p3)
+#define GATT_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define GATT_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define GATT_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define GATT_TRACE_DEBUG0(m)
+#define GATT_TRACE_DEBUG1(m,p1)
+#define GATT_TRACE_DEBUG2(m,p1,p2)
+#define GATT_TRACE_DEBUG3(m,p1,p2,p3)
+#define GATT_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define GATT_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define GATT_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the SMP unit
+*/
+#define SMP_TRACE_ERROR0(m)
+#define SMP_TRACE_ERROR1(m,p1)
+#define SMP_TRACE_ERROR2(m,p1,p2)
+#define SMP_TRACE_ERROR3(m,p1,p2,p3)
+#define SMP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define SMP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define SMP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define SMP_TRACE_WARNING0(m)
+#define SMP_TRACE_WARNING1(m,p1)
+#define SMP_TRACE_WARNING2(m,p1,p2)
+#define SMP_TRACE_WARNING3(m,p1,p2,p3)
+#define SMP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define SMP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define SMP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define SMP_TRACE_API0(m)
+#define SMP_TRACE_API1(m,p1)
+#define SMP_TRACE_API2(m,p1,p2)
+#define SMP_TRACE_API3(m,p1,p2,p3)
+#define SMP_TRACE_API4(m,p1,p2,p3,p4)
+#define SMP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define SMP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define SMP_TRACE_EVENT0(m)
+#define SMP_TRACE_EVENT1(m,p1)
+#define SMP_TRACE_EVENT2(m,p1,p2)
+#define SMP_TRACE_EVENT3(m,p1,p2,p3)
+#define SMP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define SMP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define SMP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define SMP_TRACE_DEBUG0(m)
+#define SMP_TRACE_DEBUG1(m,p1)
+#define SMP_TRACE_DEBUG2(m,p1,p2)
+#define SMP_TRACE_DEBUG3(m,p1,p2,p3)
+#define SMP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define SMP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define SMP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#endif
+
+#if (BT_USE_TRACES == TRUE || BT_TRACE_APPL == TRUE)
+
+/* define traces for application */
+#define APPL_TRACE_ERROR0(m) {if (appl_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_ERROR, (m));}
+#define APPL_TRACE_ERROR1(m,p1) {if (appl_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_ERROR, \
+ (m), (UINT32)(p1));}
+#define APPL_TRACE_ERROR2(m,p1,p2) {if (appl_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_ERROR, \
+ (m), (UINT32)(p1), (UINT32)(p2));}
+#define APPL_TRACE_ERROR3(m,p1,p2,p3) {if (appl_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_ERROR, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define APPL_TRACE_ERROR4(m,p1,p2,p3,p4) {if (appl_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_ERROR, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define APPL_TRACE_ERROR5(m,p1,p2,p3,p4,p5) {if (appl_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_ERROR, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define APPL_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) {if (appl_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_ERROR, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+
+#define APPL_TRACE_WARNING0(m) {if (appl_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_WARNING, (m));}
+#define APPL_TRACE_WARNING1(m,p1) {if (appl_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_WARNING, \
+ (m), (UINT32)(p1));}
+#define APPL_TRACE_WARNING2(m,p1,p2) {if (appl_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_WARNING, \
+ (m), (UINT32)(p1), (UINT32)(p2));}
+#define APPL_TRACE_WARNING3(m,p1,p2,p3) {if (appl_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_WARNING, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define APPL_TRACE_WARNING4(m,p1,p2,p3,p4) {if (appl_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_WARNING, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define APPL_TRACE_WARNING5(m,p1,p2,p3,p4,p5) {if (appl_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_WARNING, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define APPL_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (appl_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_WARNING, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+
+#define APPL_TRACE_API0(m) {if (appl_trace_level >= BT_TRACE_LEVEL_API) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_API, (m));}
+#define APPL_TRACE_API1(m,p1) {if (appl_trace_level >= BT_TRACE_LEVEL_API) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_API, \
+ (m), (UINT32)(p1));}
+#define APPL_TRACE_API2(m,p1,p2) {if (appl_trace_level >= BT_TRACE_LEVEL_API) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_API, \
+ (m), (UINT32)(p1), (UINT32)(p2));}
+#define APPL_TRACE_API3(m,p1,p2,p3) {if (appl_trace_level >= BT_TRACE_LEVEL_API) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_API, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define APPL_TRACE_API4(m,p1,p2,p3,p4) {if (appl_trace_level >= BT_TRACE_LEVEL_API) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_API, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define APPL_TRACE_API5(m,p1,p2,p3,p4,p5) {if (appl_trace_level >= BT_TRACE_LEVEL_API) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_API, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define APPL_TRACE_API6(m,p1,p2,p3,p4,p5,p6) {if (appl_trace_level >= BT_TRACE_LEVEL_API) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_API, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+
+#define APPL_TRACE_EVENT0(m) {if (appl_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_EVENT, (m));}
+#define APPL_TRACE_EVENT1(m,p1) {if (appl_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_EVENT, \
+ (m), (UINT32)(p1));}
+#define APPL_TRACE_EVENT2(m,p1,p2) {if (appl_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_EVENT, \
+ (m), (UINT32)(p1), (UINT32)(p2));}
+#define APPL_TRACE_EVENT3(m,p1,p2,p3) {if (appl_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_EVENT, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define APPL_TRACE_EVENT4(m,p1,p2,p3,p4) {if (appl_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_EVENT, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define APPL_TRACE_EVENT5(m,p1,p2,p3,p4,p5) {if (appl_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_EVENT, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define APPL_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6) {if (appl_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_EVENT, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+
+#define APPL_TRACE_DEBUG0(m) {if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_DEBUG, (m));}
+#define APPL_TRACE_DEBUG1(m,p1) {if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_DEBUG, \
+ (m), (UINT32)(p1));}
+#define APPL_TRACE_DEBUG2(m,p1,p2) {if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_DEBUG, \
+ (m), (UINT32)(p1), (UINT32)(p2));}
+#define APPL_TRACE_DEBUG3(m,p1,p2,p3) {if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_DEBUG, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define APPL_TRACE_DEBUG4(m,p1,p2,p3,p4) {if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_DEBUG, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define APPL_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) {if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_DEBUG, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define APPL_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) {if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_DEBUG, \
+ (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+#else
+/* define traces for Application */
+
+#define APPL_TRACE_ERROR0(m)
+#define APPL_TRACE_ERROR1(m,p1)
+#define APPL_TRACE_ERROR2(m,p1,p2)
+#define APPL_TRACE_ERROR3(m,p1,p2,p3)
+#define APPL_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define APPL_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define APPL_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define APPL_TRACE_WARNING0(m)
+#define APPL_TRACE_WARNING1(m,p1)
+#define APPL_TRACE_WARNING2(m,p1,p2)
+#define APPL_TRACE_WARNING3(m,p1,p2,p3)
+#define APPL_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define APPL_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define APPL_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define APPL_TRACE_API0(m)
+#define APPL_TRACE_API1(m,p1)
+#define APPL_TRACE_API2(m,p1,p2)
+#define APPL_TRACE_API3(m,p1,p2,p3)
+#define APPL_TRACE_API4(m,p1,p2,p3,p4)
+#define APPL_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define APPL_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define APPL_TRACE_EVENT0(m)
+#define APPL_TRACE_EVENT1(m,p1)
+#define APPL_TRACE_EVENT2(m,p1,p2)
+#define APPL_TRACE_EVENT3(m,p1,p2,p3)
+#define APPL_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define APPL_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define APPL_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define APPL_TRACE_DEBUG0(m)
+#define APPL_TRACE_DEBUG1(m,p1)
+#define APPL_TRACE_DEBUG2(m,p1,p2)
+#define APPL_TRACE_DEBUG3(m,p1,p2,p3)
+#define APPL_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define APPL_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define APPL_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#endif
+
+#if ((MMI_INCLUDED == TRUE) && (!defined(HID_MSKB_INCLUDED) || (HID_MSKB_INCLUDED == FALSE)))
+/* UI for sample applications */
+#define SAP_TRACE_0(m) MMI_Echo(m)
+#define SAP_TRACE_1(m,p1) MMI_Echo(m,p1)
+#define SAP_TRACE_2(m,p1,p2) MMI_Echo(m,p1,p2)
+#define SAP_TRACE_3(m,p1,p2,p3) MMI_Echo(m,p1,p2,p3)
+#define SAP_TRACE_4(m,p1,p2,p3,p4) MMI_Echo(m,p1,p2,p3,p4)
+#define SAP_TRACE_5(m,p1,p2,p3,p4,p5) MMI_Echo(m,p1,p2,p3,p4,p5)
+#define SAP_TRACE_6(m,p1,p2,p3,p4,p5,p6) MMI_Echo(m,p1,p2,p3,p4,p5,p6)
+#else
+#define SAP_TRACE_0(m)
+#define SAP_TRACE_1(m,p1)
+#define SAP_TRACE_2(m,p1,p2)
+#define SAP_TRACE_3(m,p1,p2,p3)
+#define SAP_TRACE_4(m,p1,p2,p3,p4)
+#define SAP_TRACE_5(m,p1,p2,p3,p4,p5)
+#define SAP_TRACE_6(m,p1,p2,p3,p4,p5,p6)
+
+#endif /* End of MMI_INCLUDED */
+#if defined(DRV_DEBUG_MSG) && (DRV_DEBUG_MSG == TRUE)
+/* Driver Trace macros
+*/
+#define DRV_TRACE_WARNING0(m) APPL_TRACE_WARNING0(m)
+#define DRV_TRACE_WARNING1(m,p1) APPL_TRACE_WARNING1(m,p1)
+#define DRV_TRACE_WARNING2(m,p1,p2) APPL_TRACE_WARNING2(m,p1,p2)
+#define DRV_TRACE_WARNING3(m,p1,p2,p3) APPL_TRACE_WARNING3(m,p1,p2,p3)
+#define DRV_TRACE_WARNING4(m,p1,p2,p3,p4) APPL_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define DRV_TRACE_WARNING5(m,p1,p2,p3,p4,p5) APPL_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define DRV_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) APPL_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+#else
+/* Driver Trace macros
+*/
+#define DRV_TRACE_WARNING0(m)
+#define DRV_TRACE_WARNING1(m,p1)
+#define DRV_TRACE_WARNING2(m,p1,p2)
+#define DRV_TRACE_WARNING3(m,p1,p2,p3)
+#define DRV_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define DRV_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define DRV_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+#endif
+
+#define DRV_TRACE_ERROR0(m) APPL_TRACE_ERROR0(m)
+#define DRV_TRACE_ERROR1(m,p1) APPL_TRACE_ERROR1(m,p1)
+#define DRV_TRACE_ERROR2(m,p1,p2) APPL_TRACE_ERROR2(m,p1,p2)
+#define DRV_TRACE_ERROR3(m,p1,p2,p3) APPL_TRACE_ERROR3(m,p1,p2,p3)
+#define DRV_TRACE_ERROR4(m,p1,p2,p3,p4) APPL_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define DRV_TRACE_ERROR5(m,p1,p2,p3,p4,p5) APPL_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define DRV_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6) APPL_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+/* Driver Trace macros
+*/
+#define DRV_TRACE_DEBUG0(m) APPL_TRACE_DEBUG0(m)
+#define DRV_TRACE_DEBUG1(m,p1) APPL_TRACE_DEBUG1(m,p1)
+#define DRV_TRACE_DEBUG2(m,p1,p2) APPL_TRACE_DEBUG2(m,p1,p2)
+#define DRV_TRACE_DEBUG3(m,p1,p2,p3) APPL_TRACE_DEBUG3(m,p1,p2,p3)
+#define DRV_TRACE_DEBUG4(m,p1,p2,p3,p4) APPL_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define DRV_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) APPL_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define DRV_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) APPL_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+
+#endif /* BT_TRACE_H */
diff --git a/src/include/bt_types.h b/src/include/bt_types.h
new file mode 100644
index 0000000..ec12331
--- /dev/null
+++ b/src/include/bt_types.h
@@ -0,0 +1,709 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+#ifndef BT_TYPES_H
+#define BT_TYPES_H
+
+#include "data_types.h"
+
+#ifdef _WIN32
+#ifdef BLUESTACK_TESTER
+ #include "bte_stack_entry.h"
+#endif
+#endif
+
+/* READ WELL !!
+**
+** This section defines global events. These are events that cross layers.
+** Any event that passes between layers MUST be one of these events. Tasks
+** can use their own events internally, but a FUNDAMENTAL design issue is
+** that global events MUST be one of these events defined below.
+**
+** The convention used is the the event name contains the layer that the
+** event is going to.
+*/
+#define BT_EVT_MASK 0xFF00
+#define BT_SUB_EVT_MASK 0x00FF
+ /* To Bluetooth Upper Layers */
+ /************************************/
+#define BT_EVT_TO_BTU_L2C_EVT 0x0900 /* L2CAP event */
+#define BT_EVT_TO_BTU_HCI_EVT 0x1000 /* HCI Event */
+#define BT_EVT_TO_BTU_HCI_BR_EDR_EVT (0x0000 | BT_EVT_TO_BTU_HCI_EVT) /* event from BR/EDR controller */
+#define BT_EVT_TO_BTU_HCI_AMP1_EVT (0x0001 | BT_EVT_TO_BTU_HCI_EVT) /* event from local AMP 1 controller */
+#define BT_EVT_TO_BTU_HCI_AMP2_EVT (0x0002 | BT_EVT_TO_BTU_HCI_EVT) /* event from local AMP 2 controller */
+#define BT_EVT_TO_BTU_HCI_AMP3_EVT (0x0003 | BT_EVT_TO_BTU_HCI_EVT) /* event from local AMP 3 controller */
+
+#define BT_EVT_TO_BTU_HCI_ACL 0x1100 /* ACL Data from HCI */
+#define BT_EVT_TO_BTU_HCI_SCO 0x1200 /* SCO Data from HCI */
+#define BT_EVT_TO_BTU_HCIT_ERR 0x1300 /* HCI Transport Error */
+
+#define BT_EVT_TO_BTU_SP_EVT 0x1400 /* Serial Port Event */
+#define BT_EVT_TO_BTU_SP_DATA 0x1500 /* Serial Port Data */
+
+#define BT_EVT_TO_BTU_HCI_CMD 0x1600 /* HCI command from upper layer */
+
+
+#define BT_EVT_TO_BTU_L2C_SEG_XMIT 0x1900 /* L2CAP segment(s) transmitted */
+
+#define BT_EVT_PROXY_INCOMING_MSG 0x1A00 /* BlueStackTester event: incoming message from target */
+
+#define BT_EVT_BTSIM 0x1B00 /* Insight BTSIM event */
+#define BT_EVT_BTISE 0x1C00 /* Insight Script Engine event */
+
+ /* To LM */
+ /************************************/
+#define BT_EVT_TO_LM_HCI_CMD 0x2000 /* HCI Command */
+#define BT_EVT_TO_LM_HCI_ACL 0x2100 /* HCI ACL Data */
+#define BT_EVT_TO_LM_HCI_SCO 0x2200 /* HCI SCO Data */
+#define BT_EVT_TO_LM_HCIT_ERR 0x2300 /* HCI Transport Error */
+#define BT_EVT_TO_LM_LC_EVT 0x2400 /* LC event */
+#define BT_EVT_TO_LM_LC_LMP 0x2500 /* LC Received LMP command frame */
+#define BT_EVT_TO_LM_LC_ACL 0x2600 /* LC Received ACL data */
+#define BT_EVT_TO_LM_LC_SCO 0x2700 /* LC Received SCO data (not used) */
+#define BT_EVT_TO_LM_LC_ACL_TX 0x2800 /* LMP data transmit complete */
+#define BT_EVT_TO_LM_LC_LMPC_TX 0x2900 /* LMP Command transmit complete */
+#define BT_EVT_TO_LM_LOCAL_ACL_LB 0x2a00 /* Data to be locally loopbacked */
+#define BT_EVT_TO_LM_HCI_ACL_ACK 0x2b00 /* HCI ACL Data ack (not used) */
+#define BT_EVT_TO_LM_DIAG 0x2c00 /* LM Diagnostics commands */
+
+
+#define BT_EVT_TO_BTM_CMDS 0x2f00
+#define BT_EVT_TO_BTM_PM_MDCHG_EVT (0x0001 | BT_EVT_TO_BTM_CMDS)
+
+#define BT_EVT_TO_TCS_CMDS 0x3000
+
+#define BT_EVT_TO_OBX_CL_MSG 0x3100
+#define BT_EVT_TO_OBX_SR_MSG 0x3200
+
+#define BT_EVT_TO_CTP_CMDS 0x3300
+
+/* Obex Over L2CAP */
+#define BT_EVT_TO_OBX_CL_L2C_MSG 0x3400
+#define BT_EVT_TO_OBX_SR_L2C_MSG 0x3500
+
+/* ftp events */
+#define BT_EVT_TO_FTP_SRVR_CMDS 0x3600
+#define BT_EVT_TO_FTP_CLNT_CMDS 0x3700
+
+#define BT_EVT_TO_BTU_SAP 0x3800 /* SIM Access Profile events */
+
+/* opp events */
+#define BT_EVT_TO_OPP_SRVR_CMDS 0x3900
+#define BT_EVT_TO_OPP_CLNT_CMDS 0x3a00
+
+/* gap events */
+#define BT_EVT_TO_GAP_MSG 0x3b00
+
+/* start timer */
+#define BT_EVT_TO_START_TIMER 0x3c00
+
+/* stop timer */
+#define BT_EVT_TO_STOP_TIMER 0x3d00
+
+/* start quick timer */
+#define BT_EVT_TO_START_QUICK_TIMER 0x3e00
+
+
+/* for NFC */
+ /************************************/
+#define BT_EVT_TO_NFC_NCI 0x4000 /* NCI Command, Notification or Data*/
+#define BT_EVT_TO_NFC_NCI_VS 0x4200 /* Vendor specific message */
+#define BT_EVT_TO_NFC_MSGS 0x4300 /* messages between NFC and NCI task */
+
+#define BT_EVT_TO_NFCCSIM_NCI 0x4a00 /* events to NFCC simulation (NCI packets) */
+
+/* HCISU Events */
+
+#define BT_EVT_HCISU 0x5000
+
+#define BT_EVT_TO_HCISU_LP_APP_SLEEPING_EVT (0x0005 | BT_EVT_HCISU)
+#define BT_EVT_TO_HCISU_LP_ALLOW_BT_SLEEP_EVT (0x0006 | BT_EVT_HCISU)
+#define BT_EVT_TO_HCISU_LP_WAKEUP_HOST_EVT (0x0007 | BT_EVT_HCISU)
+#define BT_EVT_TO_HCISU_LP_RCV_H4IBSS_EVT (0x0008 | BT_EVT_HCISU)
+#define BT_EVT_TO_HCISU_H5_RESET_EVT (0x0009 | BT_EVT_HCISU)
+#define BT_EVT_HCISU_START_QUICK_TIMER (0x000a | BT_EVT_HCISU)
+
+#define BT_EVT_DATA_TO_AMP_1 0x5100
+#define BT_EVT_DATA_TO_AMP_15 0x5f00
+
+/* HSP Events */
+
+#define BT_EVT_BTU_HSP2 0x6000
+
+#define BT_EVT_TO_BTU_HSP2_EVT (0x0001 | BT_EVT_BTU_HSP2)
+
+/* BPP Events */
+#define BT_EVT_TO_BPP_PR_CMDS 0x6100 /* Printer Events */
+#define BT_EVT_TO_BPP_SND_CMDS 0x6200 /* BPP Sender Events */
+
+/* BIP Events */
+#define BT_EVT_TO_BIP_CMDS 0x6300
+
+/* HCRP Events */
+
+#define BT_EVT_BTU_HCRP 0x7000
+
+#define BT_EVT_TO_BTU_HCRP_EVT (0x0001 | BT_EVT_BTU_HCRP)
+#define BT_EVT_TO_BTU_HCRPM_EVT (0x0002 | BT_EVT_BTU_HCRP)
+
+
+#define BT_EVT_BTU_HFP 0x8000
+#define BT_EVT_TO_BTU_HFP_EVT (0x0001 | BT_EVT_BTU_HFP)
+
+#define BT_EVT_BTU_IPC_EVT 0x9000
+#define BT_EVT_BTU_IPC_LOGMSG_EVT (0x0000 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_ACL_EVT (0x0001 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_BTU_EVT (0x0002 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_L2C_EVT (0x0003 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_L2C_MSG_EVT (0x0004 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_BTM_EVT (0x0005 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_AVDT_EVT (0x0006 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_SLIP_EVT (0x0007 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_MGMT_EVT (0x0008 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_BTTRC_EVT (0x0009 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_BURST_EVT (0x000A | BT_EVT_BTU_IPC_EVT)
+
+/* Define the header of each buffer used in the Bluetooth stack.
+*/
+typedef struct
+{
+ UINT16 event;
+ UINT16 len;
+ UINT16 offset;
+ UINT16 layer_specific;
+} BT_HDR;
+
+#define BT_HDR_SIZE (sizeof (BT_HDR))
+
+#define BT_PSM_SDP 0x0001
+#define BT_PSM_RFCOMM 0x0003
+#define BT_PSM_TCS 0x0005
+#define BT_PSM_CTP 0x0007
+#define BT_PSM_BNEP 0x000F
+#define BT_PSM_HIDC 0x0011
+#define BT_PSM_HIDI 0x0013
+#define BT_PSM_UPNP 0x0015
+#define BT_PSM_AVCTP 0x0017
+#define BT_PSM_AVDTP 0x0019
+#define BT_PSM_AVCTP_13 0x001B /* Advanced Control - Browsing */
+#define BT_PSM_UDI_CP 0x001D /* Unrestricted Digital Information Profile C-Plane */
+#define BT_PSM_ATT 0x001F /* Attribute Protocol */
+#define BT_PSM_3DS 0x0021 /* 3D sync */
+
+
+/* These macros extract the HCI opcodes from a buffer
+*/
+#define HCI_GET_CMD_HDR_OPCODE(p) (UINT16)((*((UINT8 *)((p) + 1) + p->offset) + \
+ (*((UINT8 *)((p) + 1) + p->offset + 1) << 8)))
+#define HCI_GET_CMD_HDR_PARAM_LEN(p) (UINT8) (*((UINT8 *)((p) + 1) + p->offset + 2))
+
+#define HCI_GET_EVT_HDR_OPCODE(p) (UINT8)(*((UINT8 *)((p) + 1) + p->offset))
+#define HCI_GET_EVT_HDR_PARAM_LEN(p) (UINT8) (*((UINT8 *)((p) + 1) + p->offset + 1))
+
+
+/********************************************************************************
+** Macros to get and put bytes to and from a stream (Little Endian format).
+*/
+#define UINT32_TO_STREAM(p, u32) {*(p)++ = (UINT8)(u32); *(p)++ = (UINT8)((u32) >> 8); *(p)++ = (UINT8)((u32) >> 16); *(p)++ = (UINT8)((u32) >> 24);}
+#define UINT24_TO_STREAM(p, u24) {*(p)++ = (UINT8)(u24); *(p)++ = (UINT8)((u24) >> 8); *(p)++ = (UINT8)((u24) >> 16);}
+#define UINT16_TO_STREAM(p, u16) {*(p)++ = (UINT8)(u16); *(p)++ = (UINT8)((u16) >> 8);}
+#define UINT8_TO_STREAM(p, u8) {*(p)++ = (UINT8)(u8);}
+#define INT8_TO_STREAM(p, u8) {*(p)++ = (INT8)(u8);}
+#define ARRAY32_TO_STREAM(p, a) {register int ijk; for (ijk = 0; ijk < 32; ijk++) *(p)++ = (UINT8) a[31 - ijk];}
+#define ARRAY16_TO_STREAM(p, a) {register int ijk; for (ijk = 0; ijk < 16; ijk++) *(p)++ = (UINT8) a[15 - ijk];}
+#define ARRAY8_TO_STREAM(p, a) {register int ijk; for (ijk = 0; ijk < 8; ijk++) *(p)++ = (UINT8) a[7 - ijk];}
+#define BDADDR_TO_STREAM(p, a) {register int ijk; for (ijk = 0; ijk < BD_ADDR_LEN; ijk++) *(p)++ = (UINT8) a[BD_ADDR_LEN - 1 - ijk];}
+#define LAP_TO_STREAM(p, a) {register int ijk; for (ijk = 0; ijk < LAP_LEN; ijk++) *(p)++ = (UINT8) a[LAP_LEN - 1 - ijk];}
+#define DEVCLASS_TO_STREAM(p, a) {register int ijk; for (ijk = 0; ijk < DEV_CLASS_LEN;ijk++) *(p)++ = (UINT8) a[DEV_CLASS_LEN - 1 - ijk];}
+#define ARRAY_TO_STREAM(p, a, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) *(p)++ = (UINT8) a[ijk];}
+#define REVERSE_ARRAY_TO_STREAM(p, a, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) *(p)++ = (UINT8) a[len - 1 - ijk];}
+
+#define STREAM_TO_UINT8(u8, p) {u8 = (UINT8)(*(p)); (p) += 1;}
+#define STREAM_TO_UINT16(u16, p) {u16 = ((UINT16)(*(p)) + (((UINT16)(*((p) + 1))) << 8)); (p) += 2;}
+#define STREAM_TO_UINT24(u32, p) {u32 = (((UINT32)(*(p))) + ((((UINT32)(*((p) + 1)))) << 8) + ((((UINT32)(*((p) + 2)))) << 16) ); (p) += 3;}
+#define STREAM_TO_UINT32(u32, p) {u32 = (((UINT32)(*(p))) + ((((UINT32)(*((p) + 1)))) << 8) + ((((UINT32)(*((p) + 2)))) << 16) + ((((UINT32)(*((p) + 3)))) << 24)); (p) += 4;}
+#define STREAM_TO_BDADDR(a, p) {register int ijk; register UINT8 *pbda = (UINT8 *)a + BD_ADDR_LEN - 1; for (ijk = 0; ijk < BD_ADDR_LEN; ijk++) *pbda-- = *p++;}
+#define STREAM_TO_ARRAY32(a, p) {register int ijk; register UINT8 *_pa = (UINT8 *)a + 31; for (ijk = 0; ijk < 32; ijk++) *_pa-- = *p++;}
+#define STREAM_TO_ARRAY16(a, p) {register int ijk; register UINT8 *_pa = (UINT8 *)a + 15; for (ijk = 0; ijk < 16; ijk++) *_pa-- = *p++;}
+#define STREAM_TO_ARRAY8(a, p) {register int ijk; register UINT8 *_pa = (UINT8 *)a + 7; for (ijk = 0; ijk < 8; ijk++) *_pa-- = *p++;}
+#define STREAM_TO_DEVCLASS(a, p) {register int ijk; register UINT8 *_pa = (UINT8 *)a + DEV_CLASS_LEN - 1; for (ijk = 0; ijk < DEV_CLASS_LEN; ijk++) *_pa-- = *p++;}
+#define STREAM_TO_LAP(a, p) {register int ijk; register UINT8 *plap = (UINT8 *)a + LAP_LEN - 1; for (ijk = 0; ijk < LAP_LEN; ijk++) *plap-- = *p++;}
+#define STREAM_TO_ARRAY(a, p, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) ((UINT8 *) a)[ijk] = *p++;}
+#define REVERSE_STREAM_TO_ARRAY(a, p, len) {register int ijk; register UINT8 *_pa = (UINT8 *)a + len - 1; for (ijk = 0; ijk < len; ijk++) *_pa-- = *p++;}
+
+/********************************************************************************
+** Macros to get and put bytes to and from a field (Little Endian format).
+** These are the same as to stream, except the pointer is not incremented.
+*/
+#define UINT32_TO_FIELD(p, u32) {*(UINT8 *)(p) = (UINT8)(u32); *((UINT8 *)(p)+1) = (UINT8)((u32) >> 8); *((UINT8 *)(p)+2) = (UINT8)((u32) >> 16); *((UINT8 *)(p)+3) = (UINT8)((u32) >> 24);}
+#define UINT24_TO_FIELD(p, u24) {*(UINT8 *)(p) = (UINT8)(u24); *((UINT8 *)(p)+1) = (UINT8)((u24) >> 8); *((UINT8 *)(p)+2) = (UINT8)((u24) >> 16);}
+#define UINT16_TO_FIELD(p, u16) {*(UINT8 *)(p) = (UINT8)(u16); *((UINT8 *)(p)+1) = (UINT8)((u16) >> 8);}
+#define UINT8_TO_FIELD(p, u8) {*(UINT8 *)(p) = (UINT8)(u8);}
+
+
+/********************************************************************************
+** Macros to get and put bytes to and from a stream (Big Endian format)
+*/
+#define UINT32_TO_BE_STREAM(p, u32) {*(p)++ = (UINT8)((u32) >> 24); *(p)++ = (UINT8)((u32) >> 16); *(p)++ = (UINT8)((u32) >> 8); *(p)++ = (UINT8)(u32); }
+#define UINT24_TO_BE_STREAM(p, u24) {*(p)++ = (UINT8)((u24) >> 16); *(p)++ = (UINT8)((u24) >> 8); *(p)++ = (UINT8)(u24);}
+#define UINT16_TO_BE_STREAM(p, u16) {*(p)++ = (UINT8)((u16) >> 8); *(p)++ = (UINT8)(u16);}
+#define UINT8_TO_BE_STREAM(p, u8) {*(p)++ = (UINT8)(u8);}
+#define ARRAY_TO_BE_STREAM(p, a, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) *(p)++ = (UINT8) a[ijk];}
+
+#define BE_STREAM_TO_UINT8(u8, p) {u8 = (UINT8)(*(p)); (p) += 1;}
+#define BE_STREAM_TO_UINT16(u16, p) {u16 = (UINT16)(((UINT16)(*(p)) << 8) + (UINT16)(*((p) + 1))); (p) += 2;}
+#define BE_STREAM_TO_UINT24(u32, p) {u32 = (((UINT32)(*((p) + 2))) + ((UINT32)(*((p) + 1)) << 8) + ((UINT32)(*(p)) << 16)); (p) += 3;}
+#define BE_STREAM_TO_UINT32(u32, p) {u32 = ((UINT32)(*((p) + 3)) + ((UINT32)(*((p) + 2)) << 8) + ((UINT32)(*((p) + 1)) << 16) + ((UINT32)(*(p)) << 24)); (p) += 4;}
+#define BE_STREAM_TO_ARRAY(p, a, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) ((UINT8 *) a)[ijk] = *p++;}
+
+
+/********************************************************************************
+** Macros to get and put bytes to and from a field (Big Endian format).
+** These are the same as to stream, except the pointer is not incremented.
+*/
+#define UINT32_TO_BE_FIELD(p, u32) {*(UINT8 *)(p) = (UINT8)((u32) >> 24); *((UINT8 *)(p)+1) = (UINT8)((u32) >> 16); *((UINT8 *)(p)+2) = (UINT8)((u32) >> 8); *((UINT8 *)(p)+3) = (UINT8)(u32); }
+#define UINT24_TO_BE_FIELD(p, u24) {*(UINT8 *)(p) = (UINT8)((u24) >> 16); *((UINT8 *)(p)+1) = (UINT8)((u24) >> 8); *((UINT8 *)(p)+2) = (UINT8)(u24);}
+#define UINT16_TO_BE_FIELD(p, u16) {*(UINT8 *)(p) = (UINT8)((u16) >> 8); *((UINT8 *)(p)+1) = (UINT8)(u16);}
+#define UINT8_TO_BE_FIELD(p, u8) {*(UINT8 *)(p) = (UINT8)(u8);}
+
+
+/* Common Bluetooth field definitions */
+#define BD_ADDR_LEN 6 /* Device address length */
+typedef UINT8 BD_ADDR[BD_ADDR_LEN]; /* Device address */
+typedef UINT8 *BD_ADDR_PTR; /* Pointer to Device Address */
+
+#define AMP_KEY_TYPE_GAMP 0
+#define AMP_KEY_TYPE_WIFI 1
+#define AMP_KEY_TYPE_UWB 2
+typedef UINT8 tAMP_KEY_TYPE;
+
+#define BT_OCTET8_LEN 8
+typedef UINT8 BT_OCTET8[BT_OCTET8_LEN]; /* octet array: size 16 */
+
+#define LINK_KEY_LEN 16
+typedef UINT8 LINK_KEY[LINK_KEY_LEN]; /* Link Key */
+
+#define AMP_LINK_KEY_LEN 32
+typedef UINT8 AMP_LINK_KEY[AMP_LINK_KEY_LEN]; /* Dedicated AMP and GAMP Link Keys */
+
+#define BT_OCTET16_LEN 16
+typedef UINT8 BT_OCTET16[BT_OCTET16_LEN]; /* octet array: size 16 */
+
+#define PIN_CODE_LEN 16
+typedef UINT8 PIN_CODE[PIN_CODE_LEN]; /* Pin Code (upto 128 bits) MSB is 0 */
+typedef UINT8 *PIN_CODE_PTR; /* Pointer to Pin Code */
+
+#define DEV_CLASS_LEN 3
+typedef UINT8 DEV_CLASS[DEV_CLASS_LEN]; /* Device class */
+typedef UINT8 *DEV_CLASS_PTR; /* Pointer to Device class */
+
+#define EXT_INQ_RESP_LEN 3
+typedef UINT8 EXT_INQ_RESP[EXT_INQ_RESP_LEN];/* Extended Inquiry Response */
+typedef UINT8 *EXT_INQ_RESP_PTR; /* Pointer to Extended Inquiry Response */
+
+#define BD_NAME_LEN 248
+typedef UINT8 BD_NAME[BD_NAME_LEN + 1]; /* Device name */
+typedef UINT8 *BD_NAME_PTR; /* Pointer to Device name */
+
+#define BD_FEATURES_LEN 8
+typedef UINT8 BD_FEATURES[BD_FEATURES_LEN]; /* LMP features supported by device */
+
+#define BT_EVENT_MASK_LEN 8
+typedef UINT8 BT_EVENT_MASK[BT_EVENT_MASK_LEN]; /* Event Mask */
+
+#define LAP_LEN 3
+typedef UINT8 LAP[LAP_LEN]; /* IAC as passed to Inquiry (LAP) */
+typedef UINT8 INQ_LAP[LAP_LEN]; /* IAC as passed to Inquiry (LAP) */
+
+#define RAND_NUM_LEN 16
+typedef UINT8 RAND_NUM[RAND_NUM_LEN];
+
+#define ACO_LEN 12
+typedef UINT8 ACO[ACO_LEN]; /* Authenticated ciphering offset */
+
+#define COF_LEN 12
+typedef UINT8 COF[COF_LEN]; /* ciphering offset number */
+
+typedef struct {
+ UINT8 qos_flags; /* TBD */
+ UINT8 service_type; /* see below */
+ UINT32 token_rate; /* bytes/second */
+ UINT32 token_bucket_size; /* bytes */
+ UINT32 peak_bandwidth; /* bytes/second */
+ UINT32 latency; /* microseconds */
+ UINT32 delay_variation; /* microseconds */
+} FLOW_SPEC;
+
+/* Values for service_type */
+#define NO_TRAFFIC 0
+#define BEST_EFFORT 1
+#define GUARANTEED 2
+
+/* Service class of the CoD */
+#define SERV_CLASS_NETWORKING (1 << 1)
+#define SERV_CLASS_RENDERING (1 << 2)
+#define SERV_CLASS_CAPTURING (1 << 3)
+#define SERV_CLASS_OBJECT_TRANSFER (1 << 4)
+#define SERV_CLASS_OBJECT_AUDIO (1 << 5)
+#define SERV_CLASS_OBJECT_TELEPHONY (1 << 6)
+#define SERV_CLASS_OBJECT_INFORMATION (1 << 7)
+
+/* Second byte */
+#define SERV_CLASS_LIMITED_DISC_MODE (0x20)
+
+/* Field size definitions. Note that byte lengths are rounded up. */
+#define ACCESS_CODE_BIT_LEN 72
+#define ACCESS_CODE_BYTE_LEN 9
+#define SHORTENED_ACCESS_CODE_BIT_LEN 68
+
+typedef UINT8 ACCESS_CODE[ACCESS_CODE_BYTE_LEN];
+
+#define SYNTH_TX 1 /* want synth code to TRANSMIT at this freq */
+#define SYNTH_RX 2 /* want synth code to RECEIVE at this freq */
+
+#define SYNC_REPS 1 /* repeats of sync word transmitted to start of burst */
+
+/* Bluetooth CLK27 */
+#define BT_CLK27 (2 << 26)
+
+/* Bluetooth CLK12 is 1.28 sec */
+#define BT_CLK12_TO_MS(x) ((x) * 1280)
+#define BT_MS_TO_CLK12(x) ((x) / 1280)
+#define BT_CLK12_TO_SLOTS(x) ((x) << 11)
+
+/* Bluetooth CLK is 0.625 msec */
+#define BT_CLK_TO_MS(x) (((x) * 5 + 3) / 8)
+#define BT_MS_TO_CLK(x) (((x) * 8 + 2) / 5)
+
+#define BT_CLK_TO_MICROSECS(x) (((x) * 5000 + 3) / 8)
+#define BT_MICROSECS_TO_CLK(x) (((x) * 8 + 2499) / 5000)
+
+/* Maximum UUID size - 16 bytes, and structure to hold any type of UUID. */
+#define MAX_UUID_SIZE 16
+typedef struct
+{
+#define LEN_UUID_16 2
+#define LEN_UUID_32 4
+#define LEN_UUID_128 16
+
+ UINT16 len;
+
+ union
+ {
+ UINT16 uuid16;
+ UINT32 uuid32;
+ UINT8 uuid128[MAX_UUID_SIZE];
+ } uu;
+
+} tBT_UUID;
+
+#define BT_EIR_FLAGS_TYPE 0x01
+#define BT_EIR_MORE_16BITS_UUID_TYPE 0x02
+#define BT_EIR_COMPLETE_16BITS_UUID_TYPE 0x03
+#define BT_EIR_MORE_32BITS_UUID_TYPE 0x04
+#define BT_EIR_COMPLETE_32BITS_UUID_TYPE 0x05
+#define BT_EIR_MORE_128BITS_UUID_TYPE 0x06
+#define BT_EIR_COMPLETE_128BITS_UUID_TYPE 0x07
+#define BT_EIR_SHORTENED_LOCAL_NAME_TYPE 0x08
+#define BT_EIR_COMPLETE_LOCAL_NAME_TYPE 0x09
+#define BT_EIR_TX_POWER_LEVEL_TYPE 0x0A
+#define BT_EIR_OOB_BD_ADDR_TYPE 0x0C
+#define BT_EIR_OOB_COD_TYPE 0x0D
+#define BT_EIR_OOB_SSP_HASH_C_TYPE 0x0E
+#define BT_EIR_OOB_SSP_RAND_R_TYPE 0x0F
+#define BT_EIR_3D_SYNC_TYPE 0x3D
+#define BT_EIR_MANUFACTURER_SPECIFIC_TYPE 0xFF
+
+#define BT_OOB_COD_SIZE 3
+#define BT_OOB_HASH_C_SIZE 16
+#define BT_OOB_RAND_R_SIZE 16
+
+/* Broadcom proprietary UUIDs and reserved PSMs
+**
+** The lowest 4 bytes byte of the UUID or GUID depends on the feature. Typically,
+** the value of those bytes will be the PSM or SCN, but it is up to the features.
+*/
+#define BRCM_PROPRIETARY_UUID_BASE 0xDA, 0x23, 0x41, 0x02, 0xA3, 0xBB, 0xC1, 0x71, 0xBA, 0x09, 0x6f, 0x21
+#define BRCM_PROPRIETARY_GUID_BASE 0xda23, 0x4102, 0xa3, 0xbb, 0xc1, 0x71, 0xba, 0x09, 0x6f, 0x21
+
+/* We will not allocate a PSM in the reserved range to 3rd party apps
+*/
+#define BRCM_RESERVED_PSM_START 0x5AE1
+#define BRCM_RESERVED_PSM_END 0x5AFF
+
+#define BRCM_UTILITY_SERVICE_PSM 0x5AE1
+#define BRCM_MATCHER_PSM 0x5AE3
+
+/* Connection statistics
+*/
+
+/* Structure to hold connection stats */
+#ifndef BT_CONN_STATS_DEFINED
+#define BT_CONN_STATS_DEFINED
+
+/* These bits are used in the bIsConnected field */
+#define BT_CONNECTED_USING_BREDR 1
+#define BT_CONNECTED_USING_AMP 2
+
+typedef struct
+{
+ UINT32 is_connected;
+ INT32 rssi;
+ UINT32 bytes_sent;
+ UINT32 bytes_rcvd;
+ UINT32 duration;
+} tBT_CONN_STATS;
+
+#endif
+
+/* AMP transport selection criteria definitions.
+** NOTE: if underlying L2CAP connection uses basic mode than it can use only BR/EDR.
+** For such L2CAP connections AMP connection the criteria provided by application
+** is reset by AMP manager to AMP_USE_AMP_NEVER.
+*/
+#define AMP_USE_AMP_NEVER 0 /* Connection only via BR/EDR controller, no AMP allowed */
+#define AMP_USE_AMP_IF_PEER_TRIES_IT 1 /* Allow AMP to be used if the peer tries to use it */
+#define AMP_USE_AMP_IF_PHY_CONN_EXISTS 2 /* Use AMP if there is already a physical connection (default) */
+#define AMP_USE_AMP_IF_LC_POWER_ON 3 /* Only try to use AMP if the Local Controller is powered on */
+#define AMP_USE_AMP_IF_LC_AND_PEER_POWER_ON 4 /* Only try to use AMP if both LC and peer are powered on */
+#define AMP_USE_AMP_IF_POSSIBLE 5 /* Try to use AMP if at all possible */
+#define AMP_USE_AMP_ONLY 6 /* Only use AMP, never use BR/EDR */
+#define AMP_USE_AMP_MAX_DEF AMP_USE_AMP_ONLY /* Maximum enum defined for AMP Criteria */
+
+#define AMP_AUTOSWITCH_ALLOWED 0x80000000 /* flag to indicate that this connection is auto-switch ready */
+#define AMP_USE_CURRENT_CRITERIA 0xFFFFFFFF /* Flag if previous criteria was to be still used */
+
+typedef UINT32 tAMP_CRITERIA;
+
+
+/*****************************************************************************
+** Low Energy definitions
+**
+** Address types
+*/
+#define BLE_ADDR_PUBLIC 0x00
+#define BLE_ADDR_RANDOM 0x01
+#define BLE_ADDR_TYPE_MASK (BLE_ADDR_RANDOM | BLE_ADDR_PUBLIC)
+typedef UINT8 tBLE_ADDR_TYPE;
+
+#define BLE_ADDR_IS_STATIC(x) ((x[0] & 0xC0) == 0xC0)
+
+typedef struct
+{
+ tBLE_ADDR_TYPE type;
+ BD_ADDR bda;
+} tBLE_BD_ADDR;
+
+/* Device Types
+*/
+#define BT_DEVICE_TYPE_BREDR 0x01
+#define BT_DEVICE_TYPE_BLE 0x02
+#define BT_DEVICE_TYPE_DUMO 0x03
+typedef UINT8 tBT_DEVICE_TYPE;
+/*****************************************************************************/
+
+
+/* Define trace levels */
+#define BT_TRACE_LEVEL_NONE 0 /* No trace messages to be generated */
+#define BT_TRACE_LEVEL_ERROR 1 /* Error condition trace messages */
+#define BT_TRACE_LEVEL_WARNING 2 /* Warning condition trace messages */
+#define BT_TRACE_LEVEL_API 3 /* API traces */
+#define BT_TRACE_LEVEL_EVENT 4 /* Debug messages for events */
+#define BT_TRACE_LEVEL_DEBUG 5 /* Full debug messages */
+
+#define MAX_TRACE_LEVEL 5
+
+
+/* Define New Trace Type Definition */
+/* TRACE_CTRL_TYPE 0x^^000000*/
+#define TRACE_CTRL_MASK 0xff000000
+#define TRACE_GET_CTRL(x) ((((UINT32)(x)) & TRACE_CTRL_MASK) >> 24)
+
+#define TRACE_CTRL_GENERAL 0x00000000
+#define TRACE_CTRL_STR_RESOURCE 0x01000000
+#define TRACE_CTRL_SEQ_FLOW 0x02000000
+#define TRACE_CTRL_MAX_NUM 3
+
+/* LAYER SPECIFIC 0x00^^0000*/
+#define TRACE_LAYER_MASK 0x00ff0000
+#define TRACE_GET_LAYER(x) ((((UINT32)(x)) & TRACE_LAYER_MASK) >> 16)
+
+#define TRACE_LAYER_NONE 0x00000000
+#define TRACE_LAYER_USB 0x00010000
+#define TRACE_LAYER_SERIAL 0x00020000
+#define TRACE_LAYER_SOCKET 0x00030000
+#define TRACE_LAYER_RS232 0x00040000
+#define TRACE_LAYER_TRANS_MAX_NUM 5
+#define TRACE_LAYER_TRANS_ALL 0x007f0000
+#define TRACE_LAYER_LC 0x00050000
+#define TRACE_LAYER_LM 0x00060000
+#define TRACE_LAYER_HCI 0x00070000
+#define TRACE_LAYER_L2CAP 0x00080000
+#define TRACE_LAYER_RFCOMM 0x00090000
+#define TRACE_LAYER_SDP 0x000a0000
+#define TRACE_LAYER_TCS 0x000b0000
+#define TRACE_LAYER_OBEX 0x000c0000
+#define TRACE_LAYER_BTM 0x000d0000
+#define TRACE_LAYER_GAP 0x000e0000
+#define TRACE_LAYER_DUN 0x000f0000
+#define TRACE_LAYER_GOEP 0x00100000
+#define TRACE_LAYER_ICP 0x00110000
+#define TRACE_LAYER_HSP2 0x00120000
+#define TRACE_LAYER_SPP 0x00130000
+#define TRACE_LAYER_CTP 0x00140000
+#define TRACE_LAYER_BPP 0x00150000
+#define TRACE_LAYER_HCRP 0x00160000
+#define TRACE_LAYER_FTP 0x00170000
+#define TRACE_LAYER_OPP 0x00180000
+#define TRACE_LAYER_BTU 0x00190000
+#define TRACE_LAYER_GKI 0x001a0000
+#define TRACE_LAYER_BNEP 0x001b0000
+#define TRACE_LAYER_PAN 0x001c0000
+#define TRACE_LAYER_HFP 0x001d0000
+#define TRACE_LAYER_HID 0x001e0000
+#define TRACE_LAYER_BIP 0x001f0000
+#define TRACE_LAYER_AVP 0x00200000
+#define TRACE_LAYER_A2D 0x00210000
+#define TRACE_LAYER_SAP 0x00220000
+#define TRACE_LAYER_AMP 0x00230000
+#define TRACE_LAYER_MCA 0x00240000
+#define TRACE_LAYER_ATT 0x00250000
+#define TRACE_LAYER_SMP 0x00260000
+#define TRACE_LAYER_NFC 0x00270000
+#define TRACE_LAYER_NCI 0x00280000 /*it's overwritten in nfc_types.h*/
+#define TRACE_LAYER_LLCP 0x00290000
+#define TRACE_LAYER_NDEF 0x002a0000
+#define TRACE_LAYER_RW 0x002b0000
+#define TRACE_LAYER_CE 0x002c0000
+#define TRACE_LAYER_P2P 0x002d0000
+#define TRACE_LAYER_SNEP 0x002e0000
+#define TRACE_LAYER_CHO 0x002f0000
+#define TRACE_LAYER_NFA 0x00300000
+#define TRACE_LAYER_HAL 0x00310000 /*it's overwritten in nfc_types.h*/
+#define TRACE_LAYER_MAX_NUM 0x0032
+
+
+/* TRACE_ORIGINATOR 0x0000^^00*/
+#define TRACE_ORG_MASK 0x0000ff00
+#define TRACE_GET_ORG(x) ((((UINT32)(x)) & TRACE_ORG_MASK) >> 8)
+
+#define TRACE_ORG_STACK 0x00000000
+#define TRACE_ORG_HCI_TRANS 0x00000100
+#define TRACE_ORG_PROTO_DISP 0x00000200
+#define TRACE_ORG_RPC 0x00000300
+#define TRACE_ORG_GKI 0x00000400
+#define TRACE_ORG_APPL 0x00000500
+#define TRACE_ORG_SCR_WRAPPER 0x00000600
+#define TRACE_ORG_SCR_ENGINE 0x00000700
+#define TRACE_ORG_USER_SCR 0x00000800
+#define TRACE_ORG_TESTER 0x00000900
+#define TRACE_ORG_MAX_NUM 10 /* 32-bit mask; must be < 32 */
+#define TRACE_LITE_ORG_MAX_NUM 6
+#define TRACE_ORG_ALL 0x03ff
+#define TRACE_ORG_RPC_TRANS 0x04
+
+#define TRACE_ORG_REG 0x00000909
+#define TRACE_ORG_REG_SUCCESS 0x0000090a
+
+/* TRACE_TYPE 0x000000^^*/
+#define TRACE_TYPE_MASK 0x000000ff
+#define TRACE_GET_TYPE(x) (((UINT32)(x)) & TRACE_TYPE_MASK)
+
+#define TRACE_TYPE_ERROR 0x00000000
+#define TRACE_TYPE_WARNING 0x00000001
+#define TRACE_TYPE_API 0x00000002
+#define TRACE_TYPE_EVENT 0x00000003
+#define TRACE_TYPE_DEBUG 0x00000004
+#define TRACE_TYPE_STACK_ONLY_MAX TRACE_TYPE_DEBUG
+#define TRACE_TYPE_TX 0x00000005
+#define TRACE_TYPE_RX 0x00000006
+#define TRACE_TYPE_DEBUG_ASSERT 0x00000007
+#define TRACE_TYPE_GENERIC 0x00000008
+#define TRACE_TYPE_REG 0x00000009
+#define TRACE_TYPE_REG_SUCCESS 0x0000000a
+#define TRACE_TYPE_CMD_TX 0x0000000b
+#define TRACE_TYPE_EVT_TX 0x0000000c
+#define TRACE_TYPE_ACL_TX 0x0000000d
+#define TRACE_TYPE_CMD_RX 0x0000000e
+#define TRACE_TYPE_EVT_RX 0x0000000f
+#define TRACE_TYPE_ACL_RX 0x00000010
+#define TRACE_TYPE_TARGET_TRACE 0x00000011
+#define TRACE_TYPE_SCO_TX 0x00000012
+#define TRACE_TYPE_SCO_RX 0x00000013
+
+
+#define TRACE_TYPE_MAX_NUM 20
+#define TRACE_TYPE_ALL 0xffff
+
+/* Define color for script type */
+#define SCR_COLOR_DEFAULT 0
+#define SCR_COLOR_TYPE_COMMENT 1
+#define SCR_COLOR_TYPE_COMMAND 2
+#define SCR_COLOR_TYPE_EVENT 3
+#define SCR_COLOR_TYPE_SELECT 4
+
+/* Define protocol trace flag values */
+#define SCR_PROTO_TRACE_HCI_SUMMARY 0x00000001
+#define SCR_PROTO_TRACE_HCI_DATA 0x00000002
+#define SCR_PROTO_TRACE_L2CAP 0x00000004
+#define SCR_PROTO_TRACE_RFCOMM 0x00000008
+#define SCR_PROTO_TRACE_SDP 0x00000010
+#define SCR_PROTO_TRACE_TCS 0x00000020
+#define SCR_PROTO_TRACE_OBEX 0x00000040
+#define SCR_PROTO_TRACE_OAPP 0x00000080 /* OBEX Application Profile */
+#define SCR_PROTO_TRACE_AMP 0x00000100
+#define SCR_PROTO_TRACE_BNEP 0x00000200
+#define SCR_PROTO_TRACE_AVP 0x00000400
+#define SCR_PROTO_TRACE_MCA 0x00000800
+#define SCR_PROTO_TRACE_ATT 0x00001000
+#define SCR_PROTO_TRACE_SMP 0x00002000
+#define SCR_PROTO_TRACE_NCI 0x00004000
+#define SCR_PROTO_TRACE_LLCP 0x00008000
+#define SCR_PROTO_TRACE_NDEF 0x00010000
+#define SCR_PROTO_TRACE_RW 0x00020000
+#define SCR_PROTO_TRACE_CE 0x00040000
+#define SCR_PROTO_TRACE_SNEP 0x00080000
+#define SCR_PROTO_TRACE_CHO 0x00100000
+#define SCR_PROTO_TRACE_ALL 0x001fffff
+#define SCR_PROTO_TRACE_HCI_LOGGING_VSE 0x0800 /* Brcm vs event for logmsg and protocol traces */
+
+#define MAX_SCRIPT_TYPE 5
+
+#define TCS_PSM_INTERCOM 5
+#define TCS_PSM_CORDLESS 7
+#define BT_PSM_BNEP 0x000F
+/* Define PSMs HID uses */
+#define HID_PSM_CONTROL 0x0011
+#define HID_PSM_INTERRUPT 0x0013
+
+#if defined(UCD_HID_INCLUDED) && (UCD_HID_INCLUDED == TRUE)
+#define UCD_PSM_MIN 0x8001
+#define UCD_PSM_MAX 0x8003
+#define UCD_PSM_HID_CTRL 0x8001
+#define UCD_PSM_HID_INTR 0x8003
+#endif
+
+#if defined(HIDH_UCD_INCLUDED) && (HIDH_UCD_INCLUDED == TRUE)
+#define HID_UCD_PSM_CONTROL 0x8001
+#define HID_UCD_PSM_INTERRUPT 0x8003
+#endif
+
+/* Define a function for logging */
+typedef void (BT_LOG_FUNC) (int trace_type, const char *fmt_str, ...);
+
+#endif
diff --git a/src/include/btu_api.h b/src/include/btu_api.h
new file mode 100644
index 0000000..83c7d87
--- /dev/null
+++ b/src/include/btu_api.h
@@ -0,0 +1,20 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef BTU_API_H
+#define BTU_API_H
+#endif /* BTU_APU_H */
diff --git a/src/include/buildcfg.h b/src/include/buildcfg.h
new file mode 100644
index 0000000..540fd3a
--- /dev/null
+++ b/src/include/buildcfg.h
@@ -0,0 +1,137 @@
+/******************************************************************************
+ *
+ * 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 (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define GKI_BUF3_MAX 70
+#else
+#define GKI_BUF3_MAX 30
+#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
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define GKI_BUF2_MAX 70
+#else
+#define GKI_BUF2_MAX 50
+#endif
+
+#define GKI_BUF0_SIZE 268
+#define GKI_BUF0_MAX 40
+
+#define NCI_BUF_POOL_ID GKI_POOL_ID_0
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define GKI_NUM_FIXED_BUF_POOLS 9
+#else
+#define GKI_NUM_FIXED_BUF_POOLS 4
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+// +++from bte.h...
+enum
+{
+ /* BTE BBY */
+ /* J3 J4 SW3-3 SW3-2 SW3-1 */
+ /* -------------------------------------------- */
+ BTE_MODE_SERIAL_APP, /* OUT OUT OFF OFF OFF Sample serial port application */
+ BTE_MODE_APPL, /* IN OUT OFF OFF ON Target used with Tester through RPC */
+ BTE_MODE_RESERVED, /* OUT IN OFF ON OFF Reserved */
+ BTE_MODE_SAMPLE_APPS, /* IN IN OFF ON ON Sample applications (ICP/HSP) */
+ BTE_MODE_DONGLE, /* not yet supported ON OFF OFF Dongle mode */
+ BTE_MODE_APPL_PROTOCOL_TRACE, /* this is a fake mode do allow protocol tracing in application without rpc */
+ BTE_MODE_INVALID
+};
+/* Protocol trace mask */
+extern UINT32 bte_proto_trace_mask;/* = 0xFFFFFFFF;*/
+extern volatile UINT8 bte_target_mode;
+// ---from bte.h...
+
+
+extern UINT8 *scru_dump_hex (UINT8 *p, char *p_title, UINT32 len, UINT32 trace_layer, UINT32 trace_type);
+extern void ScrLog(UINT32 trace_set_mask, const char *fmt_str, ...);
+extern void DispNci (UINT8 *p, UINT16 len, BOOLEAN is_recv);
+
+extern void downloadFirmwarePatchFile (UINT32 brcm_hw_id);
+
+void ProtoDispAdapterDisplayNciPacket (UINT8* nciPacket, UINT16 nciPacketLen, BOOLEAN 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..7e49e53
--- /dev/null
+++ b/src/include/config.h
@@ -0,0 +1,158 @@
+/******************************************************************************
+ *
+ * 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"
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define NAME_APPL_DTA_MODE "APPL_DTA_MODE"
+#endif
+#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"
+#if(NFC_NXP_NOT_OPEN_INCLUDED != 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_UICC_LISTEN_TECH_EX_MASK "UICC_LISTEN_TECH_EXCLUDE_MASK"
+#define NAME_HOST_LISTEN_ENABLE "HOST_LISTEN_ENABLE"
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#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_NFA_DM_DISC_NTF_TIMEOUT "NFA_DM_DISC_NTF_TIMEOUT"
+#define NAME_NXP_FWD_FUNCTIONALITY_ENABLE "NXP_FWD_FUNCTIONALITY_ENABLE"
+#endif
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+#define NAME_NXP_PRFD_TECH_SE "NXP_PRFD_TECH_SE"
+#endif
+#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_NXP_NFCC_STANDBY_TIMEOUT "NXP_NFCC_STANDBY_TIMEOUT"
+#define NAME_NXP_CP_TIMEOUT "NXP_CP_TIMEOUT"
+#if(NFC_NXP_CHIP_TYPE == PN547C2)
+#define NAME_NXP_CORE_SCRN_OFF_AUTONOMOUS_ENABLE "NXP_CORE_SCRN_OFF_AUTONOMOUS_ENABLE"
+#endif
+
+#define LPTD_PARAM_LEN (40)
+
+// default configuration
+#define default_transport "/dev/bcm2079x"
+#define default_storage_location "/data/nfc"
+
+struct tUART_CONFIG {
+ int m_iBaudrate; // 115200
+ int m_iDatabits; // 8
+ int m_iParity; // 0 - none, 1 = odd, 2 = even
+ int m_iStopbits;
+};
+
+extern struct tUART_CONFIG uartConfig;
+#define MAX_CHIPID_LEN (16)
+void readOptionalConfig(const char* option);
+
+/* Snooze mode configuration structure */
+typedef struct
+{
+ unsigned char snooze_mode; /* Snooze Mode */
+ unsigned char idle_threshold_dh; /* Idle Threshold Host */
+ unsigned char idle_threshold_nfcc; /* Idle Threshold NFCC */
+ unsigned char nfc_wake_active_mode; /* NFC_LP_ACTIVE_LOW or NFC_LP_ACTIVE_HIGH */
+ unsigned char dh_wake_active_mode; /* NFC_LP_ACTIVE_LOW or NFC_LP_ACTIVE_HIGH */
+} tSNOOZE_MODE_CONFIG;
+#endif
diff --git a/src/include/dyn_mem.h b/src/include/dyn_mem.h
new file mode 100644
index 0000000..9e605d5
--- /dev/null
+++ b/src/include/dyn_mem.h
@@ -0,0 +1,194 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef DYN_MEM_H
+#define DYN_MEM_H
+
+/****************************************************************************
+** Define memory usage for GKI (if not defined in buildcfg.h)
+** The default for GKI is to use static memory allocation for its control
+** block.
+*/
+#ifndef GKI_DYNAMIC_MEMORY
+#define GKI_DYNAMIC_MEMORY FALSE
+#endif
+
+/****************************************************************************
+** Define memory usage for each CORE component (if not defined in buildcfg.h)
+** The default for each component is to use static memory allocations.
+*/
+#ifndef BTU_DYNAMIC_MEMORY
+#define BTU_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef BTM_DYNAMIC_MEMORY
+#define BTM_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef SDP_DYNAMIC_MEMORY
+#define SDP_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef L2C_DYNAMIC_MEMORY
+#define L2C_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef A2MP_DYNAMIC_MEMORY
+#define A2MP_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef RFC_DYNAMIC_MEMORY
+#define RFC_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef TCS_DYNAMIC_MEMORY
+#define TCS_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef OBX_DYNAMIC_MEMORY
+#define OBX_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef BNEP_DYNAMIC_MEMORY
+#define BNEP_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef AVDT_DYNAMIC_MEMORY
+#define AVDT_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef AVCT_DYNAMIC_MEMORY
+#define AVCT_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef MCA_DYNAMIC_MEMORY
+#define MCA_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef GATT_DYNAMIC_MEMORY
+#define GATT_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef SMP_DYNAMIC_MEMORY
+#define SMP_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef BRCM_DYNAMIC_MEMORY
+#define BRCM_DYNAMIC_MEMORY FALSE
+#endif
+
+/****************************************************************************
+** Define memory usage for each PROFILE component (if not defined in buildcfg.h)
+** The default for each component is to use static memory allocations.
+*/
+#ifndef A2D_DYNAMIC_MEMORY
+#define A2D_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef VDP_DYNAMIC_MEMORY
+#define VDP_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef AVRC_DYNAMIC_MEMORY
+#define AVRC_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef BIP_DYNAMIC_MEMORY
+#define BIP_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef BPP_DYNAMIC_MEMORY
+#define BPP_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef CTP_DYNAMIC_MEMORY
+#define CTP_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef DUN_DYNAMIC_MEMORY
+#define DUN_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef FTP_DYNAMIC_MEMORY
+#define FTP_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef GAP_DYNAMIC_MEMORY
+#define GAP_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef GOEP_DYNAMIC_MEMORY
+#define GOEP_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef HCRP_DYNAMIC_MEMORY
+#define HCRP_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef HFP_DYNAMIC_MEMORY
+#define HFP_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef HID_DYNAMIC_MEMORY
+#define HID_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef HSP2_DYNAMIC_MEMORY
+#define HSP2_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef ICP_DYNAMIC_MEMORY
+#define ICP_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef OPP_DYNAMIC_MEMORY
+#define OPP_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef PAN_DYNAMIC_MEMORY
+#define PAN_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef SPP_DYNAMIC_MEMORY
+#define SPP_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef SLIP_DYNAMIC_MEMORY
+#define SLIP_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef LLCP_DYNAMIC_MEMORY
+#define LLCP_DYNAMIC_MEMORY FALSE
+#endif
+
+/****************************************************************************
+** Define memory usage for BTA (if not defined in buildcfg.h)
+** The default for each component is to use static memory allocations.
+*/
+#ifndef BTA_DYNAMIC_MEMORY
+#define BTA_DYNAMIC_MEMORY FALSE
+#endif
+
+/****************************************************************************
+** Define memory usage for BT Trace (if not defined in buildcfg.h)
+** The default is to use static memory allocations.
+*/
+#ifndef BTTRC_DYNAMIC_MEMORY
+#define BTTRC_DYNAMIC_MEMORY FALSE
+#endif
+
+#endif /* #ifdef DYN_MEM_H */
diff --git a/src/include/gki_target.h b/src/include/gki_target.h
new file mode 100644
index 0000000..489f584
--- /dev/null
+++ b/src/include/gki_target.h
@@ -0,0 +1,450 @@
+/******************************************************************************
+ *
+ * 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
+
+/* define prefix for exporting APIs from libraries */
+#define EXPORT_API
+
+#ifndef BTE_BSE_WRAPPER
+#ifdef BTE_SIM_APP
+#undef EXPORT_API
+#define EXPORT_API __declspec(dllexport)
+#endif
+#endif
+
+#define GKI_API EXPORT_API
+#define UDRV_API EXPORT_API
+
+
+/******************************************************************************
+**
+** Task configuration
+**
+******************************************************************************/
+
+/* Definitions of task IDs for inter-task messaging */
+#ifndef MMI_TASK
+#define MMI_TASK 0
+#endif
+
+#ifndef HCISU_TASK
+#define HCISU_TASK 1
+#endif
+
+#ifndef NCIT_TASK
+#define NCIT_TASK 2
+#endif
+
+#ifndef NFC_TASK
+#define NFC_TASK 3
+#endif
+
+#ifndef BTU_TASK
+#define BTU_TASK 4
+#endif
+
+/* BTE Application, Sample Apps, or Serial port Demo based on JP3 and JP4 setting) */
+#ifndef BTE_APPL_TASK
+#define BTE_APPL_TASK 5
+#endif
+
+#ifndef DEV_MGR_TASK
+#define DEV_MGR_TASK 6
+#endif
+
+#ifndef ISE_SCR_TASK
+#define ISE_SCR_TASK 7
+#endif
+
+#ifndef UCODEC_TASK
+#define UCODEC_TASK 8
+#endif
+
+#ifndef RPCT_TASK
+#define RPCT_TASK 9
+#endif
+
+#ifndef UNV_TASK
+#define UNV_TASK 10
+#endif
+
+#ifndef BTE_IDLE_TASK
+#define BTE_IDLE_TASK 11
+#endif
+
+#ifndef UIPC_TASK
+#define UIPC_TASK 12
+#endif
+
+#ifndef HCISU_AMP_TASK
+#define HCISU_AMP_TASK 13
+#endif
+
+
+/* The number of GKI tasks in the software system. */
+#ifndef GKI_MAX_TASKS
+#define GKI_MAX_TASKS 14
+#endif
+
+/******************************************************************************
+**
+** Timer configuration
+**
+******************************************************************************/
+
+/* The number of GKI timers in the software system. */
+#ifndef GKI_NUM_TIMERS
+#define GKI_NUM_TIMERS 3
+#endif
+
+/* A conversion value for translating ticks to calculate GKI timer. */
+#ifndef TICKS_PER_SEC
+#define TICKS_PER_SEC 100
+#endif
+
+/* delay in ticks before stopping system tick. */
+#ifndef GKI_DELAY_STOP_SYS_TICK
+#define GKI_DELAY_STOP_SYS_TICK 10
+#endif
+
+/******************************************************************************
+**
+** Buffer configuration
+**
+******************************************************************************/
+
+/* TRUE if GKI uses dynamic buffers. */
+#ifndef GKI_USE_DYNAMIC_BUFFERS
+#define GKI_USE_DYNAMIC_BUFFERS FALSE
+#endif
+
+/* The size of the buffers in pool 0. */
+#ifndef GKI_BUF0_SIZE
+#define GKI_BUF0_SIZE 64
+#endif
+
+/* The number of buffers in buffer pool 0. */
+#ifndef GKI_BUF0_MAX
+#define GKI_BUF0_MAX 48
+#endif
+
+/* The ID of buffer pool 0. */
+#ifndef GKI_POOL_ID_0
+#define GKI_POOL_ID_0 0
+#endif
+
+/* The size of the buffers in pool 1. */
+#ifndef GKI_BUF1_SIZE
+#define GKI_BUF1_SIZE 128
+#endif
+
+/* The number of buffers in buffer pool 1. */
+#ifndef GKI_BUF1_MAX
+#define GKI_BUF1_MAX 26
+#endif
+
+/* The ID of buffer pool 1. */
+#ifndef GKI_POOL_ID_1
+#define GKI_POOL_ID_1 1
+#endif
+
+/* The size of the buffers in pool 2. */
+#ifndef GKI_BUF2_SIZE
+#define GKI_BUF2_SIZE 660
+#endif
+
+/* The number of buffers in buffer pool 2. */
+#ifndef GKI_BUF2_MAX
+#define GKI_BUF2_MAX 45
+#endif
+
+/* The ID of buffer pool 2. */
+#ifndef GKI_POOL_ID_2
+#define GKI_POOL_ID_2 2
+#endif
+
+/* The size of the buffers in pool 3. */
+#ifndef GKI_BUF3_SIZE
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 (OBX_NUM_SERVERS + OBX_NUM_CLIENTS)
+#endif
+
+/* The ID of buffer pool 4. */
+#ifndef GKI_POOL_ID_4
+#define GKI_POOL_ID_4 4
+#endif
+
+/* The number of fixed GKI buffer pools.
+If L2CAP_FCR_INCLUDED is FALSE, Pool ID 5 is unnecessary
+If BTM_SCO_HCI_INCLUDED is FALSE, Pool ID 6 is unnecessary, otherwise set to 7
+If BTA_HL_INCLUDED is FALSE then Pool ID 7 is uncessary and set the following to 7, otherwise set to 8
+If GATT_SERVER_ENABLED is FALSE then Pool ID 8 is uncessary and set the following to 8, otherwise set to 9
+*/
+#ifndef GKI_NUM_FIXED_BUF_POOLS
+#define GKI_NUM_FIXED_BUF_POOLS 9
+#endif
+
+/* The buffer pool usage mask. */
+#ifndef GKI_DEF_BUFPOOL_PERM_MASK
+#define GKI_DEF_BUFPOOL_PERM_MASK 0xfff0
+#endif
+
+/* The number of fixed and dynamic buffer pools.
+If L2CAP_FCR_INCLUDED is FALSE, Pool ID 4 is unnecessary */
+#ifndef GKI_NUM_TOTAL_BUF_POOLS
+#define GKI_NUM_TOTAL_BUF_POOLS 10
+#endif
+
+/* The following is intended to be a reserved pool for L2CAP
+Flow control and retransmissions and intentionally kept out
+of order */
+
+/* The number of buffers in buffer pool 5. */
+#ifndef GKI_BUF5_MAX
+#define GKI_BUF5_MAX 64
+#endif
+
+/* The ID of buffer pool 5. */
+#ifndef GKI_POOL_ID_5
+#define GKI_POOL_ID_5 5
+#endif
+
+/* The size of the buffers in pool 5
+** Special pool used by l2cap retransmissions only. This size based on segment
+** that will fit into both DH5 and 2-DH3 packet types after accounting for GKI
+** header. 13 bytes of max headers allows us a 339 payload max. (in btui_app.txt)
+** Note: 748 used for insight scriptwrapper with CAT-2 scripts.
+*/
+#ifndef GKI_BUF5_SIZE
+#define GKI_BUF5_SIZE 748
+#endif
+
+/* The buffer corruption check flag. */
+#ifndef GKI_ENABLE_BUF_CORRUPTION_CHECK
+#define GKI_ENABLE_BUF_CORRUPTION_CHECK TRUE
+#endif
+
+/* The GKI severe error macro. */
+#ifndef GKI_SEVERE
+#define GKI_SEVERE(code)
+#endif
+
+/* TRUE if GKI includes debug functionality. */
+#ifndef GKI_DEBUG
+#define GKI_DEBUG FALSE
+#endif
+
+/* Maximum number of exceptions logged. */
+#ifndef GKI_MAX_EXCEPTION
+#define GKI_MAX_EXCEPTION 8
+#endif
+
+/* Maximum number of chars stored for each exception message. */
+#ifndef GKI_MAX_EXCEPTION_MSGLEN
+#define GKI_MAX_EXCEPTION_MSGLEN 64
+#endif
+
+#ifndef GKI_SEND_MSG_FROM_ISR
+#define GKI_SEND_MSG_FROM_ISR FALSE
+#endif
+
+
+/* The following is intended to be a reserved pool for SCO
+over HCI data and intentionally kept out of order */
+
+/* The ID of buffer pool 6. */
+#ifndef GKI_POOL_ID_6
+#define GKI_POOL_ID_6 6
+#endif
+
+/* The size of the buffers in pool 6,
+ BUF_SIZE = max SCO data 255 + sizeof(BT_HDR) = 8 + SCO packet header 3 + padding 2 = 268 */
+#ifndef GKI_BUF6_SIZE
+#define GKI_BUF6_SIZE 268
+#endif
+
+/* The number of buffers in buffer pool 6. */
+#ifndef GKI_BUF6_MAX
+#define GKI_BUF6_MAX 60
+#endif
+
+
+/* The following pool is a dedicated pool for HDP
+ If a shared pool is more desirable then
+ 1. set BTA_HL_LRG_DATA_POOL_ID to the desired Gki Pool ID
+ 2. make sure that the shared pool size is larger than 9472
+ 3. adjust GKI_NUM_FIXED_BUF_POOLS accordingly since
+ POOL ID 7 is not needed
+*/
+
+/* The ID of buffer pool 7. */
+#ifndef GKI_POOL_ID_7
+#define GKI_POOL_ID_7 7
+#endif
+
+/* The size of the buffers in pool 7 */
+#ifndef GKI_BUF7_SIZE
+#define GKI_BUF7_SIZE 9472
+#endif
+
+/* The number of buffers in buffer pool 7. */
+#ifndef GKI_BUF7_MAX
+#define GKI_BUF7_MAX 2
+#endif
+
+/* The following pool is a dedicated pool for GATT
+ If a shared pool is more desirable then
+ 1. set GATT_DB_POOL_ID to the desired Gki Pool ID
+ 2. make sure that the shared pool size fit a common GATT database needs
+ 3. adjust GKI_NUM_FIXED_BUF_POOLS accordingly since
+ POOL ID 8 is not needed
+*/
+
+/* The ID of buffer pool 8. */
+#ifndef GKI_POOL_ID_8
+#define GKI_POOL_ID_8 8
+#endif
+
+/* The size of the buffers in pool 8 */
+#ifndef GKI_BUF8_SIZE
+#define GKI_BUF8_SIZE 128
+#endif
+
+/* The number of buffers in buffer pool 8. */
+#ifndef GKI_BUF8_MAX
+#define GKI_BUF8_MAX 30
+#endif
+
+#if defined(GKI_DEBUG) && (GKI_DEBUG == TRUE)
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "GKI_LINUX"
+/* GKI Trace Macros */
+#define GKI_TRACE_0(m) LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_GENERIC,m)
+#define GKI_TRACE_1(m,p1) LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_GENERIC,m,p1)
+#define GKI_TRACE_2(m,p1,p2) LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_GENERIC,m,p1,p2)
+#define GKI_TRACE_3(m,p1,p2,p3) LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_GENERIC,m,p1,p2,p3)
+#define GKI_TRACE_4(m,p1,p2,p3,p4) LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_GENERIC,m,p1,p2,p3,p4)
+#define GKI_TRACE_5(m,p1,p2,p3,p4,p5) LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_GENERIC,m,p1,p2,p3,p4,p5)
+#define GKI_TRACE_6(m,p1,p2,p3,p4,p5,p6) LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_GENERIC,m,p1,p2,p3,p4,p5,p6)
+#else
+#define GKI_TRACE_0(m)
+#define GKI_TRACE_1(m,p1)
+#define GKI_TRACE_2(m,p1,p2)
+#define GKI_TRACE_3(m,p1,p2,p3)
+#define GKI_TRACE_4(m,p1,p2,p3,p4)
+#define GKI_TRACE_5(m,p1,p2,p3,p4,p5)
+#define GKI_TRACE_6(m,p1,p2,p3,p4,p5,p6)
+
+#endif
+
+#define GKI_TRACE_ERROR_0(m) LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR,m)
+#define GKI_TRACE_ERROR_1(m,p1) LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR,m,p1)
+#define GKI_TRACE_ERROR_2(m,p1,p2) LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR,m,p1,p2)
+#define GKI_TRACE_ERROR_3(m,p1,p2,p3) LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR,m,p1,p2,p3)
+#define GKI_TRACE_ERROR_4(m,p1,p2,p3,p4) LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR,m,p1,p2,p3,p4)
+#define GKI_TRACE_ERROR_5(m,p1,p2,p3,p4,p5) LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR,m,p1,p2,p3,p4,p5)
+#define GKI_TRACE_ERROR_6(m,p1,p2,p3,p4,p5,p6) LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR,m,p1,p2,p3,p4,p5,p6)
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+EXPORT_API extern void LogMsg (UINT32 trace_set_mask, const char *fmt_str, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GKI_TARGET_H */
diff --git a/src/include/hcidefs.h b/src/include/hcidefs.h
new file mode 100644
index 0000000..1cb8e49
--- /dev/null
+++ b/src/include/hcidefs.h
@@ -0,0 +1,2606 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2013 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+#ifndef HCIDEFS_H
+#define HCIDEFS_H
+
+#define HCI_PROTO_VERSION 0x01 /* Version for BT spec 1.1 */
+#define HCI_PROTO_VERSION_1_2 0x02 /* Version for BT spec 1.2 */
+#define HCI_PROTO_VERSION_2_0 0x03 /* Version for BT spec 2.0 */
+#define HCI_PROTO_VERSION_2_1 0x04 /* Version for BT spec 2.1 [Lisbon] */
+#define HCI_PROTO_VERSION_3_0 0x05 /* Version for BT spec 3.0 */
+#define HCI_PROTO_REVISION 0x000C /* Current implementation version */
+/*
+** Definitions for HCI groups
+*/
+#define HCI_GRP_LINK_CONTROL_CMDS (0x01 << 10) /* 0x0400 */
+#define HCI_GRP_LINK_POLICY_CMDS (0x02 << 10) /* 0x0800 */
+#define HCI_GRP_HOST_CONT_BASEBAND_CMDS (0x03 << 10) /* 0x0C00 */
+#define HCI_GRP_INFORMATIONAL_PARAMS (0x04 << 10) /* 0x1000 */
+#define HCI_GRP_STATUS_PARAMS (0x05 << 10) /* 0x1400 */
+#define HCI_GRP_TESTING_CMDS (0x06 << 10) /* 0x1800 */
+
+#define HCI_GRP_VENDOR_SPECIFIC (0x3F << 10) /* 0xFC00 */
+
+/* Group occupies high 6 bits of the HCI command rest is opcode itself */
+#define HCI_OGF(p) (UINT8)((0xFC00 & (p)) >> 10)
+#define HCI_OCF(p) ( 0x3FF & (p))
+
+/*
+** Definitions for Link Control Commands
+*/
+/* Following opcode is used only in command complete event for flow control */
+#define HCI_COMMAND_NONE 0x0000
+
+/* Commands of HCI_GRP_LINK_CONTROL_CMDS group */
+#define HCI_INQUIRY (0x0001 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_INQUIRY_CANCEL (0x0002 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_PERIODIC_INQUIRY_MODE (0x0003 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_EXIT_PERIODIC_INQUIRY_MODE (0x0004 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_CREATE_CONNECTION (0x0005 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_DISCONNECT (0x0006 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_ADD_SCO_CONNECTION (0x0007 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_CREATE_CONNECTION_CANCEL (0x0008 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_ACCEPT_CONNECTION_REQUEST (0x0009 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_REJECT_CONNECTION_REQUEST (0x000A | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_LINK_KEY_REQUEST_REPLY (0x000B | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_LINK_KEY_REQUEST_NEG_REPLY (0x000C | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_PIN_CODE_REQUEST_REPLY (0x000D | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_PIN_CODE_REQUEST_NEG_REPLY (0x000E | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_CHANGE_CONN_PACKET_TYPE (0x000F | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_AUTHENTICATION_REQUESTED (0x0011 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_SET_CONN_ENCRYPTION (0x0013 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_CHANGE_CONN_LINK_KEY (0x0015 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_MASTER_LINK_KEY (0x0017 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_RMT_NAME_REQUEST (0x0019 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_RMT_NAME_REQUEST_CANCEL (0x001A | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_READ_RMT_FEATURES (0x001B | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_READ_RMT_EXT_FEATURES (0x001C | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_READ_RMT_VERSION_INFO (0x001D | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_READ_RMT_CLOCK_OFFSET (0x001F | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_READ_LMP_HANDLE (0x0020 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_SETUP_ESCO_CONNECTION (0x0028 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_ACCEPT_ESCO_CONNECTION (0x0029 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_REJECT_ESCO_CONNECTION (0x002A | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_IO_CAPABILITY_RESPONSE (0x002B | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_USER_CONF_REQUEST_REPLY (0x002C | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_USER_CONF_VALUE_NEG_REPLY (0x002D | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_USER_PASSKEY_REQ_REPLY (0x002E | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_USER_PASSKEY_REQ_NEG_REPLY (0x002F | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_REM_OOB_DATA_REQ_REPLY (0x0030 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_REM_OOB_DATA_REQ_NEG_REPLY (0x0033 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_IO_CAP_REQ_NEG_REPLY (0x0034 | HCI_GRP_LINK_CONTROL_CMDS)
+
+/* AMP HCI */
+#define HCI_CREATE_PHYSICAL_LINK (0x0035 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_ACCEPT_PHYSICAL_LINK (0x0036 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_DISCONNECT_PHYSICAL_LINK (0x0037 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_CREATE_LOGICAL_LINK (0x0038 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_ACCEPT_LOGICAL_LINK (0x0039 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_DISCONNECT_LOGICAL_LINK (0x003A | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_LOGICAL_LINK_CANCEL (0x003B | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_FLOW_SPEC_MODIFY (0x003C | HCI_GRP_LINK_CONTROL_CMDS)
+/* End of AMP HCI */
+
+#define HCI_ENH_SETUP_ESCO_CONNECTION (0x003D | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_ENH_ACCEPT_ESCO_CONNECTION (0x003E | HCI_GRP_LINK_CONTROL_CMDS)
+
+/* ConnectionLess Broadcast */
+#define HCI_TRUNCATED_PAGE (0x003F | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_TRUNCATED_PAGE_CANCEL (0x0040 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_SET_CLB (0x0041 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_RECEIVE_CLB (0x0042 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_START_SYNC_TRAIN (0x0043 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_RECEIVE_SYNC_TRAIN (0x0044 | HCI_GRP_LINK_CONTROL_CMDS)
+
+#define HCI_LINK_CTRL_CMDS_FIRST HCI_INQUIRY
+#define HCI_LINK_CTRL_CMDS_LAST HCI_RECEIVE_SYNC_TRAIN
+
+/* Commands of HCI_GRP_LINK_POLICY_CMDS */
+#define HCI_HOLD_MODE (0x0001 | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_SNIFF_MODE (0x0003 | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_EXIT_SNIFF_MODE (0x0004 | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_PARK_MODE (0x0005 | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_EXIT_PARK_MODE (0x0006 | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_QOS_SETUP (0x0007 | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_ROLE_DISCOVERY (0x0009 | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_SWITCH_ROLE (0x000B | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_READ_POLICY_SETTINGS (0x000C | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_WRITE_POLICY_SETTINGS (0x000D | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_READ_DEF_POLICY_SETTINGS (0x000E | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_WRITE_DEF_POLICY_SETTINGS (0x000F | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_FLOW_SPECIFICATION (0x0010 | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_SNIFF_SUB_RATE (0x0011 | HCI_GRP_LINK_POLICY_CMDS)
+
+#define HCI_LINK_POLICY_CMDS_FIRST HCI_HOLD_MODE
+#define HCI_LINK_POLICY_CMDS_LAST HCI_SNIFF_SUB_RATE
+
+
+/* Commands of HCI_GRP_HOST_CONT_BASEBAND_CMDS */
+#define HCI_SET_EVENT_MASK (0x0001 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_RESET (0x0003 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_SET_EVENT_FILTER (0x0005 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_FLUSH (0x0008 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_PIN_TYPE (0x0009 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_PIN_TYPE (0x000A | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_CREATE_NEW_UNIT_KEY (0x000B | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_GET_MWS_TRANS_LAYER_CFG (0x000C | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_STORED_LINK_KEY (0x000D | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_STORED_LINK_KEY (0x0011 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_DELETE_STORED_LINK_KEY (0x0012 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_CHANGE_LOCAL_NAME (0x0013 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_LOCAL_NAME (0x0014 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_CONN_ACCEPT_TOUT (0x0015 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_CONN_ACCEPT_TOUT (0x0016 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_PAGE_TOUT (0x0017 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_PAGE_TOUT (0x0018 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_SCAN_ENABLE (0x0019 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_SCAN_ENABLE (0x001A | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_PAGESCAN_CFG (0x001B | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_PAGESCAN_CFG (0x001C | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_INQUIRYSCAN_CFG (0x001D | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_INQUIRYSCAN_CFG (0x001E | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_AUTHENTICATION_ENABLE (0x001F | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_AUTHENTICATION_ENABLE (0x0020 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_ENCRYPTION_MODE (0x0021 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_ENCRYPTION_MODE (0x0022 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_CLASS_OF_DEVICE (0x0023 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_CLASS_OF_DEVICE (0x0024 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_VOICE_SETTINGS (0x0025 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_VOICE_SETTINGS (0x0026 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_AUTO_FLUSH_TOUT (0x0027 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_AUTO_FLUSH_TOUT (0x0028 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_NUM_BCAST_REXMITS (0x0029 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_NUM_BCAST_REXMITS (0x002A | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_HOLD_MODE_ACTIVITY (0x002B | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_HOLD_MODE_ACTIVITY (0x002C | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_TRANSMIT_POWER_LEVEL (0x002D | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_SCO_FLOW_CTRL_ENABLE (0x002E | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_SCO_FLOW_CTRL_ENABLE (0x002F | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_SET_HC_TO_HOST_FLOW_CTRL (0x0031 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_HOST_BUFFER_SIZE (0x0033 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_HOST_NUM_PACKETS_DONE (0x0035 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_LINK_SUPER_TOUT (0x0036 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_LINK_SUPER_TOUT (0x0037 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_NUM_SUPPORTED_IAC (0x0038 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_CURRENT_IAC_LAP (0x0039 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_CURRENT_IAC_LAP (0x003A | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_PAGESCAN_PERIOD_MODE (0x003B | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_PAGESCAN_PERIOD_MODE (0x003C | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_PAGESCAN_MODE (0x003D | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_PAGESCAN_MODE (0x003E | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_SET_AFH_CHANNELS (0x003F | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+
+#define HCI_READ_INQSCAN_TYPE (0x0042 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_INQSCAN_TYPE (0x0043 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_INQUIRY_MODE (0x0044 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_INQUIRY_MODE (0x0045 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_PAGESCAN_TYPE (0x0046 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_PAGESCAN_TYPE (0x0047 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_AFH_ASSESSMENT_MODE (0x0048 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_AFH_ASSESSMENT_MODE (0x0049 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_EXT_INQ_RESPONSE (0x0051 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_EXT_INQ_RESPONSE (0x0052 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_REFRESH_ENCRYPTION_KEY (0x0053 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_SIMPLE_PAIRING_MODE (0x0055 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_SIMPLE_PAIRING_MODE (0x0056 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_LOCAL_OOB_DATA (0x0057 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_INQ_TX_POWER_LEVEL (0x0058 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_INQ_TX_POWER_LEVEL (0x0059 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_ERRONEOUS_DATA_RPT (0x005A | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_ERRONEOUS_DATA_RPT (0x005B | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_ENHANCED_FLUSH (0x005F | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_SEND_KEYPRESS_NOTIF (0x0060 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+
+#define HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT (0x0061 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT (0x0062 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_SET_EVENT_MASK_PAGE_2 (0x0063 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_LOCATION_DATA (0x0064 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_LOCATION_DATA (0x0065 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_FLOW_CONTROL_MODE (0x0066 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_FLOW_CONTROL_MODE (0x0067 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_BE_FLUSH_TOUT (0x0069 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_BE_FLUSH_TOUT (0x006A | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_SHORT_RANGE_MODE (0x006B | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_LE_HOST_SUPPORTED (0x006C | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_LE_HOST_SUPPORTED (0x006D | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+
+
+/* MWS coexistence */
+#define HCI_SET_MWS_CHANNEL_PARAMETERS (0x006E | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_SET_EXTERNAL_FRAME_CONFIGURATION (0x006F | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_SET_MWS_SIGNALING (0x0070 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_SET_MWS_TRANSPORT_LAYER (0x0071 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_SET_MWS_SCAN_FREQUENCY_TABLE (0x0072 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_SET_MWS_PATTERN_CONFIGURATION (0x0073 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+
+/* ConnectionLess Broadcast */
+#define HCI_SET_RESERVED_LT_ADDR (0x0074 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_DELETE_RESERVED_LT_ADDR (0x0075 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_CLB_DATA (0x0076 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_SYNC_TRAIN_PARAM (0x0077 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_SYNC_TRAIN_PARAM (0x0078 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+
+
+#define HCI_CONT_BASEBAND_CMDS_FIRST HCI_SET_EVENT_MASK
+#define HCI_CONT_BASEBAND_CMDS_LAST HCI_READ_SYNC_TRAIN_PARAM
+
+
+/* Commands of HCI_GRP_INFORMATIONAL_PARAMS group */
+#define HCI_READ_LOCAL_VERSION_INFO (0x0001 | HCI_GRP_INFORMATIONAL_PARAMS)
+#define HCI_READ_LOCAL_SUPPORTED_CMDS (0x0002 | HCI_GRP_INFORMATIONAL_PARAMS)
+#define HCI_READ_LOCAL_FEATURES (0x0003 | HCI_GRP_INFORMATIONAL_PARAMS)
+#define HCI_READ_LOCAL_EXT_FEATURES (0x0004 | HCI_GRP_INFORMATIONAL_PARAMS)
+#define HCI_READ_BUFFER_SIZE (0x0005 | HCI_GRP_INFORMATIONAL_PARAMS)
+#define HCI_READ_COUNTRY_CODE (0x0007 | HCI_GRP_INFORMATIONAL_PARAMS)
+#define HCI_READ_BD_ADDR (0x0009 | HCI_GRP_INFORMATIONAL_PARAMS)
+#define HCI_READ_DATA_BLOCK_SIZE (0x000A | HCI_GRP_INFORMATIONAL_PARAMS)
+#define HCI_READ_LOCAL_SUPPORTED_CODECS (0x000B | HCI_GRP_INFORMATIONAL_PARAMS)
+
+
+#define HCI_INFORMATIONAL_CMDS_FIRST HCI_READ_LOCAL_VERSION_INFO
+#define HCI_INFORMATIONAL_CMDS_LAST HCI_READ_LOCAL_SUPPORTED_CODECS
+
+
+/* Commands of HCI_GRP_STATUS_PARAMS group */
+#define HCI_READ_FAILED_CONTACT_COUNT (0x0001 | HCI_GRP_STATUS_PARAMS)
+#define HCI_RESET_FAILED_CONTACT_COUNT (0x0002 | HCI_GRP_STATUS_PARAMS)
+#define HCI_GET_LINK_QUALITY (0x0003 | HCI_GRP_STATUS_PARAMS)
+#define HCI_READ_RSSI (0x0005 | HCI_GRP_STATUS_PARAMS)
+#define HCI_READ_AFH_CH_MAP (0x0006 | HCI_GRP_STATUS_PARAMS)
+#define HCI_READ_CLOCK (0x0007 | HCI_GRP_STATUS_PARAMS)
+#define HCI_READ_ENCR_KEY_SIZE (0x0008 | HCI_GRP_STATUS_PARAMS)
+
+/* AMP HCI */
+#define HCI_READ_LOCAL_AMP_INFO (0x0009 | HCI_GRP_STATUS_PARAMS)
+#define HCI_READ_LOCAL_AMP_ASSOC (0x000A | HCI_GRP_STATUS_PARAMS)
+#define HCI_WRITE_REMOTE_AMP_ASSOC (0x000B | HCI_GRP_STATUS_PARAMS)
+
+/* CSA4 (Trigger Clock) */
+#define HCI_SET_TRIGGERED_CLOCK_CAPTURE (0x000D | HCI_GRP_STATUS_PARAMS)
+
+#define HCI_STATUS_PARAMS_CMDS_FIRST HCI_READ_FAILED_CONTACT_COUNT
+#define HCI_STATUS_PARAMS_CMDS_LAST HCI_SET_TRIGGERED_CLOCK_CAPTURE
+
+/* Commands of HCI_GRP_TESTING_CMDS group */
+#define HCI_READ_LOOPBACK_MODE (0x0001 | HCI_GRP_TESTING_CMDS)
+#define HCI_WRITE_LOOPBACK_MODE (0x0002 | HCI_GRP_TESTING_CMDS)
+#define HCI_ENABLE_DEV_UNDER_TEST_MODE (0x0003 | HCI_GRP_TESTING_CMDS)
+#define HCI_WRITE_SIMP_PAIR_DEBUG_MODE (0x0004 | HCI_GRP_TESTING_CMDS)
+
+/* AMP HCI */
+#define HCI_ENABLE_AMP_RCVR_REPORTS (0x0007 | HCI_GRP_TESTING_CMDS)
+#define HCI_AMP_TEST_END (0x0008 | HCI_GRP_TESTING_CMDS)
+#define HCI_AMP_TEST (0x0009 | HCI_GRP_TESTING_CMDS)
+
+#define HCI_TESTING_CMDS_FIRST HCI_READ_LOOPBACK_MODE
+#define HCI_TESTING_CMDS_LAST HCI_AMP_TEST
+
+#define HCI_VENDOR_CMDS_FIRST 0x0001
+#define HCI_VENDOR_CMDS_LAST 0xFFFF
+#define HCI_VSC_MULTI_AV_HANDLE 0x0AAA
+#define HCI_VSC_BURST_MODE_HANDLE 0x0BBB
+
+/* BLE HCI */
+#define HCI_GRP_BLE_CMDS (0x08 << 10)
+/* Commands of BLE Controller setup and configuration */
+#define HCI_BLE_SET_EVENT_MASK (0x0001 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_READ_BUFFER_SIZE (0x0002 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_READ_LOCAL_SPT_FEAT (0x0003 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_WRITE_LOCAL_SPT_FEAT (0x0004 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_WRITE_RANDOM_ADDR (0x0005 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_WRITE_ADV_PARAMS (0x0006 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_READ_ADV_CHNL_TX_POWER (0x0007 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_WRITE_ADV_DATA (0x0008 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_WRITE_SCAN_RSP_DATA (0x0009 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_WRITE_ADV_ENABLE (0x000A | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_WRITE_SCAN_PARAMS (0x000B | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_WRITE_SCAN_ENABLE (0x000C | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_CREATE_LL_CONN (0x000D | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_CREATE_CONN_CANCEL (0x000E | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_READ_WHITE_LIST_SIZE (0x000F | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_CLEAR_WHITE_LIST (0x0010 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_ADD_WHITE_LIST (0x0011 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_REMOVE_WHITE_LIST (0x0012 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_UPD_LL_CONN_PARAMS (0x0013 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_SET_HOST_CHNL_CLASS (0x0014 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_READ_CHNL_MAP (0x0015 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_READ_REMOTE_FEAT (0x0016 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_ENCRYPT (0x0017 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_RAND (0x0018 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_START_ENC (0x0019 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_LTK_REQ_REPLY (0x001A | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_LTK_REQ_NEG_REPLY (0x001B | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_READ_SUPPORTED_STATES (0x001C | HCI_GRP_BLE_CMDS)
+
+#define HCI_BLE_RESET (0x0020 | HCI_GRP_BLE_CMDS)
+
+/* LE supported states definition */
+#define HCI_LE_ADV_STATE 0x00000001
+#define HCI_LE_SCAN_STATE 0x00000002
+#define HCI_LE_INIT_STATE 0x00000004
+#define HCI_LE_CONN_SL_STATE 0x00000008
+#define HCI_LE_ADV_SCAN_STATE 0x00000010
+#define HCI_LE_ADV_INIT_STATE 0x00000020
+#define HCI_LE_ADV_MA_STATE 0x00000040
+#define HCI_LE_ADV_SL_STATE 0x00000080
+#define HCI_LE_SCAN_INIT_STATE 0x00000100
+#define HCI_LE_SCAN_MA_STATE 0x00000200
+#define HCI_LE_SCAN_SL_STATE 0x00000400
+#define HCI_LE_INIT_MA_STATE 0x00000800
+
+
+/*
+** Definitions for HCI Events
+*/
+#define HCI_INQUIRY_COMP_EVT 0x01
+#define HCI_INQUIRY_RESULT_EVT 0x02
+#define HCI_CONNECTION_COMP_EVT 0x03
+#define HCI_CONNECTION_REQUEST_EVT 0x04
+#define HCI_DISCONNECTION_COMP_EVT 0x05
+#define HCI_AUTHENTICATION_COMP_EVT 0x06
+#define HCI_RMT_NAME_REQUEST_COMP_EVT 0x07
+#define HCI_ENCRYPTION_CHANGE_EVT 0x08
+#define HCI_CHANGE_CONN_LINK_KEY_EVT 0x09
+#define HCI_MASTER_LINK_KEY_COMP_EVT 0x0A
+#define HCI_READ_RMT_FEATURES_COMP_EVT 0x0B
+#define HCI_READ_RMT_VERSION_COMP_EVT 0x0C
+#define HCI_QOS_SETUP_COMP_EVT 0x0D
+#define HCI_COMMAND_COMPLETE_EVT 0x0E
+#define HCI_COMMAND_STATUS_EVT 0x0F
+#define HCI_HARDWARE_ERROR_EVT 0x10
+#define HCI_FLUSH_OCCURED_EVT 0x11
+#define HCI_ROLE_CHANGE_EVT 0x12
+#define HCI_NUM_COMPL_DATA_PKTS_EVT 0x13
+#define HCI_MODE_CHANGE_EVT 0x14
+#define HCI_RETURN_LINK_KEYS_EVT 0x15
+#define HCI_PIN_CODE_REQUEST_EVT 0x16
+#define HCI_LINK_KEY_REQUEST_EVT 0x17
+#define HCI_LINK_KEY_NOTIFICATION_EVT 0x18
+#define HCI_LOOPBACK_COMMAND_EVT 0x19
+#define HCI_DATA_BUF_OVERFLOW_EVT 0x1A
+#define HCI_MAX_SLOTS_CHANGED_EVT 0x1B
+#define HCI_READ_CLOCK_OFF_COMP_EVT 0x1C
+#define HCI_CONN_PKT_TYPE_CHANGE_EVT 0x1D
+#define HCI_QOS_VIOLATION_EVT 0x1E
+#define HCI_PAGE_SCAN_MODE_CHANGE_EVT 0x1F
+#define HCI_PAGE_SCAN_REP_MODE_CHNG_EVT 0x20
+#define HCI_FLOW_SPECIFICATION_COMP_EVT 0x21
+#define HCI_INQUIRY_RSSI_RESULT_EVT 0x22
+#define HCI_READ_RMT_EXT_FEATURES_COMP_EVT 0x23
+#define HCI_ESCO_CONNECTION_COMP_EVT 0x2C
+#define HCI_ESCO_CONNECTION_CHANGED_EVT 0x2D
+#define HCI_SNIFF_SUB_RATE_EVT 0x2E
+#define HCI_EXTENDED_INQUIRY_RESULT_EVT 0x2F
+#define HCI_ENCRYPTION_KEY_REFRESH_COMP_EVT 0x30
+#define HCI_IO_CAPABILITY_REQUEST_EVT 0x31
+#define HCI_IO_CAPABILITY_RESPONSE_EVT 0x32
+#define HCI_USER_CONFIRMATION_REQUEST_EVT 0x33
+#define HCI_USER_PASSKEY_REQUEST_EVT 0x34
+#define HCI_REMOTE_OOB_DATA_REQUEST_EVT 0x35
+#define HCI_SIMPLE_PAIRING_COMPLETE_EVT 0x36
+#define HCI_LINK_SUPER_TOUT_CHANGED_EVT 0x38
+#define HCI_ENHANCED_FLUSH_COMPLETE_EVT 0x39
+#define HCI_USER_PASSKEY_NOTIFY_EVT 0x3B
+#define HCI_KEYPRESS_NOTIFY_EVT 0x3C
+#define HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT 0x3D
+
+/*#define HCI_GENERIC_AMP_LINK_KEY_NOTIF_EVT 0x3E Removed from spec */
+#define HCI_PHYSICAL_LINK_COMP_EVT 0x40
+#define HCI_CHANNEL_SELECTED_EVT 0x41
+#define HCI_DISC_PHYSICAL_LINK_COMP_EVT 0x42
+#define HCI_PHY_LINK_LOSS_EARLY_WARNING_EVT 0x43
+#define HCI_PHY_LINK_RECOVERY_EVT 0x44
+#define HCI_LOGICAL_LINK_COMP_EVT 0x45
+#define HCI_DISC_LOGICAL_LINK_COMP_EVT 0x46
+#define HCI_FLOW_SPEC_MODIFY_COMP_EVT 0x47
+#define HCI_NUM_COMPL_DATA_BLOCKS_EVT 0x48
+#define HCI_SHORT_RANGE_MODE_COMPLETE_EVT 0x4C
+#define HCI_AMP_STATUS_CHANGE_EVT 0x4D
+#define HCI_SET_TRIGGERED_CLOCK_CAPTURE_EVT 0x4E
+
+
+
+/* ULP HCI Event */
+#define HCI_BLE_EVENT 0x03E
+/* ULP Event sub code */
+#define HCI_BLE_CONN_COMPLETE_EVT 0x01
+#define HCI_BLE_ADV_PKT_RPT_EVT 0x02
+#define HCI_BLE_LL_CONN_PARAM_UPD_EVT 0x03
+#define HCI_BLE_READ_REMOTE_FEAT_CMPL_EVT 0x04
+#define HCI_BLE_LTK_REQ_EVT 0x05
+
+/* ConnectionLess Broadcast events */
+#define HCI_SYNC_TRAIN_COMP_EVT 0x4F
+#define HCI_SYNC_TRAIN_RECEIVED_EVT 0x50
+#define HCI_CLB_RX_DATA_EVT 0x51
+#define HCI_CLB_RX_TIMEOUT_EVT 0x52
+#define HCI_TRUNCATED_PAGE_COMP_EVT 0x53
+#define HCI_SLAVE_PAGE_RESP_TIMEOUT_EVT 0x54
+#define HCI_CLB_CHANNEL_CHANGE_EVT 0x55
+#define HCI_INQUIRY_RESPONSE_NOTIF 0x56
+
+#define HCI_EVENT_RSP_FIRST HCI_INQUIRY_COMP_EVT
+#define HCI_EVENT_RSP_LAST HCI_CLB_CHANNEL_CHANGE_EVT
+
+#define HCI_VENDOR_SPECIFIC_EVT 0xFF /* Vendor specific events */
+#define HCI_NAP_TRACE_EVT 0xFF /* was define 0xFE, 0xFD, change to 0xFF
+ because conflict w/ TCI_EVT and per
+ specification compliant */
+
+/*
+** Defentions for HCI Error Codes that are past in the events
+*/
+#define HCI_SUCCESS 0x00
+#define HCI_PENDING 0x00
+#define HCI_ERR_ILLEGAL_COMMAND 0x01
+#define HCI_ERR_NO_CONNECTION 0x02
+#define HCI_ERR_HW_FAILURE 0x03
+#define HCI_ERR_PAGE_TIMEOUT 0x04
+#define HCI_ERR_AUTH_FAILURE 0x05
+#define HCI_ERR_KEY_MISSING 0x06
+#define HCI_ERR_MEMORY_FULL 0x07
+#define HCI_ERR_CONNECTION_TOUT 0x08
+#define HCI_ERR_MAX_NUM_OF_CONNECTIONS 0x09
+#define HCI_ERR_MAX_NUM_OF_SCOS 0x0A
+#define HCI_ERR_CONNECTION_EXISTS 0x0B
+#define HCI_ERR_COMMAND_DISALLOWED 0x0C
+#define HCI_ERR_HOST_REJECT_RESOURCES 0x0D
+#define HCI_ERR_HOST_REJECT_SECURITY 0x0E
+#define HCI_ERR_HOST_REJECT_DEVICE 0x0F
+#define HCI_ERR_HOST_TIMEOUT 0x10
+#define HCI_ERR_UNSUPPORTED_VALUE 0x11
+#define HCI_ERR_ILLEGAL_PARAMETER_FMT 0x12
+#define HCI_ERR_PEER_USER 0x13
+#define HCI_ERR_PEER_LOW_RESOURCES 0x14
+#define HCI_ERR_PEER_POWER_OFF 0x15
+#define HCI_ERR_CONN_CAUSE_LOCAL_HOST 0x16
+#define HCI_ERR_REPEATED_ATTEMPTS 0x17
+#define HCI_ERR_PAIRING_NOT_ALLOWED 0x18
+#define HCI_ERR_UNKNOWN_LMP_PDU 0x19
+#define HCI_ERR_UNSUPPORTED_REM_FEATURE 0x1A
+#define HCI_ERR_SCO_OFFSET_REJECTED 0x1B
+#define HCI_ERR_SCO_INTERVAL_REJECTED 0x1C
+#define HCI_ERR_SCO_AIR_MODE 0x1D
+#define HCI_ERR_INVALID_LMP_PARAM 0x1E
+#define HCI_ERR_UNSPECIFIED 0x1F
+#define HCI_ERR_UNSUPPORTED_LMP_FEATURE 0x20
+#define HCI_ERR_ROLE_CHANGE_NOT_ALLOWED 0x21
+#define HCI_ERR_LMP_RESPONSE_TIMEOUT 0x22
+#define HCI_ERR_LMP_ERR_TRANS_COLLISION 0x23
+#define HCI_ERR_LMP_PDU_NOT_ALLOWED 0x24
+#define HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE 0x25
+#define HCI_ERR_UNIT_KEY_USED 0x26
+#define HCI_ERR_QOS_NOT_SUPPORTED 0x27
+#define HCI_ERR_INSTANT_PASSED 0x28
+#define HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED 0x29
+#define HCI_ERR_DIFF_TRANSACTION_COLLISION 0x2A
+#define HCI_ERR_UNDEFINED_0x2B 0x2B
+#define HCI_ERR_QOS_UNACCEPTABLE_PARAM 0x2C
+#define HCI_ERR_QOS_REJECTED 0x2D
+#define HCI_ERR_CHAN_CLASSIF_NOT_SUPPORTED 0x2E
+#define HCI_ERR_INSUFFCIENT_SECURITY 0x2F
+#define HCI_ERR_PARAM_OUT_OF_RANGE 0x30
+#define HCI_ERR_UNDEFINED_0x31 0x31
+#define HCI_ERR_ROLE_SWITCH_PENDING 0x32
+#define HCI_ERR_UNDEFINED_0x33 0x33
+#define HCI_ERR_RESERVED_SLOT_VIOLATION 0x34
+#define HCI_ERR_ROLE_SWITCH_FAILED 0x35
+#define HCI_ERR_INQ_RSP_DATA_TOO_LARGE 0x36
+#define HCI_ERR_SIMPLE_PAIRING_NOT_SUPPORTED 0x37
+#define HCI_ERR_HOST_BUSY_PAIRING 0x38
+#define HCI_ERR_REJ_NO_SUITABLE_CHANNEL 0x39
+#define HCI_ERR_CONTROLLER_BUSY 0x3A
+#define HCI_ERR_UNACCEPT_CONN_INTERVAL 0x3B
+#define HCI_ERR_DIRECTED_ADVERTISING_TIMEOUT 0x3C
+#define HCI_ERR_CONN_TOUT_DUE_TO_MIC_FAILURE 0x3D
+#define HCI_ERR_CONN_FAILED_ESTABLISHMENT 0x3E
+#define HCI_ERR_MAC_CONNECTION_FAILED 0x3F
+
+/* ConnectionLess Broadcast errors */
+#define HCI_ERR_LT_ADDR_ALREADY_IN_USE 0x40
+#define HCI_ERR_LT_ADDR_NOT_ALLOCATED 0x41
+#define HCI_ERR_CLB_NOT_ENABLED 0x42
+#define HCI_ERR_CLB_DATA_TOO_BIG 0x43
+
+#define HCI_ERR_MAX_ERR 0x43
+
+#define HCI_HINT_TO_RECREATE_AMP_PHYS_LINK 0xFF
+
+/*
+** Definitions for HCI enable event
+*/
+#define HCI_INQUIRY_COMPLETE_EV(p) (*((UINT32 *)(p)) & 0x00000001)
+#define HCI_INQUIRY_RESULT_EV(p) (*((UINT32 *)(p)) & 0x00000002)
+#define HCI_CONNECTION_COMPLETE_EV(p) (*((UINT32 *)(p)) & 0x00000004)
+#define HCI_CONNECTION_REQUEST_EV(p) (*((UINT32 *)(p)) & 0x00000008)
+#define HCI_DISCONNECTION_COMPLETE_EV(p) (*((UINT32 *)(p)) & 0x00000010)
+#define HCI_AUTHENTICATION_COMPLETE_EV(p) (*((UINT32 *)(p)) & 0x00000020)
+#define HCI_RMT_NAME_REQUEST_COMPL_EV(p) (*((UINT32 *)(p)) & 0x00000040)
+#define HCI_CHANGE_CONN_ENCRPT_ENABLE_EV(p) (*((UINT32 *)(p)) & 0x00000080)
+#define HCI_CHANGE_CONN_LINK_KEY_EV(p) (*((UINT32 *)(p)) & 0x00000100)
+#define HCI_MASTER_LINK_KEY_COMPLETE_EV(p) (*((UINT32 *)(p)) & 0x00000200)
+#define HCI_READ_RMT_FEATURES_COMPL_EV(p) (*((UINT32 *)(p)) & 0x00000400)
+#define HCI_READ_RMT_VERSION_COMPL_EV(p) (*((UINT32 *)(p)) & 0x00000800)
+#define HCI_QOS_SETUP_COMPLETE_EV(p) (*((UINT32 *)(p)) & 0x00001000)
+#define HCI_COMMAND_COMPLETE_EV(p) (*((UINT32 *)(p)) & 0x00002000)
+#define HCI_COMMAND_STATUS_EV(p) (*((UINT32 *)(p)) & 0x00004000)
+#define HCI_HARDWARE_ERROR_EV(p) (*((UINT32 *)(p)) & 0x00008000)
+#define HCI_FLASH_OCCURED_EV(p) (*((UINT32 *)(p)) & 0x00010000)
+#define HCI_ROLE_CHANGE_EV(p) (*((UINT32 *)(p)) & 0x00020000)
+#define HCI_NUM_COMPLETED_PKTS_EV(p) (*((UINT32 *)(p)) & 0x00040000)
+#define HCI_MODE_CHANGE_EV(p) (*((UINT32 *)(p)) & 0x00080000)
+#define HCI_RETURN_LINK_KEYS_EV(p) (*((UINT32 *)(p)) & 0x00100000)
+#define HCI_PIN_CODE_REQUEST_EV(p) (*((UINT32 *)(p)) & 0x00200000)
+#define HCI_LINK_KEY_REQUEST_EV(p) (*((UINT32 *)(p)) & 0x00400000)
+#define HCI_LINK_KEY_NOTIFICATION_EV(p) (*((UINT32 *)(p)) & 0x00800000)
+#define HCI_LOOPBACK_COMMAND_EV(p) (*((UINT32 *)(p)) & 0x01000000)
+#define HCI_DATA_BUF_OVERFLOW_EV(p) (*((UINT32 *)(p)) & 0x02000000)
+#define HCI_MAX_SLOTS_CHANGE_EV(p) (*((UINT32 *)(p)) & 0x04000000)
+#define HCI_READ_CLOCK_OFFSET_COMP_EV(p) (*((UINT32 *)(p)) & 0x08000000)
+#define HCI_CONN_PKT_TYPE_CHANGED_EV(p) (*((UINT32 *)(p)) & 0x10000000)
+#define HCI_QOS_VIOLATION_EV(p) (*((UINT32 *)(p)) & 0x20000000)
+#define HCI_PAGE_SCAN_MODE_CHANGED_EV(p) (*((UINT32 *)(p)) & 0x40000000)
+#define HCI_PAGE_SCAN_REP_MODE_CHNG_EV(p) (*((UINT32 *)(p)) & 0x80000000)
+
+/* the default event mask for 2.1+EDR (Lisbon) does not include Lisbon events */
+#define HCI_DEFAULT_EVENT_MASK_0 0xFFFFFFFF
+#define HCI_DEFAULT_EVENT_MASK_1 0x00001FFF
+
+/* the event mask for 2.0 + EDR and later (includes Lisbon events) */
+#define HCI_LISBON_EVENT_MASK_0 0xFFFFFFFF
+#define HCI_LISBON_EVENT_MASK_1 0x1DBFFFFF
+#define HCI_LISBON_EVENT_MASK "\x0D\xBF\xFF\xFF\xFF\xFF\xFF\xFF"
+#define HCI_LISBON_EVENT_MASK_EXT "\x1D\xBF\xFF\xFF\xFF\xFF\xFF\xFF"
+#define HCI_DUMO_EVENT_MASK_EXT "\x3D\xBF\xFF\xFF\xFF\xFF\xFF\xFF"
+/* 0x00001FFF FFFFFFFF Default - no Lisbon events
+ 0x00000800 00000000 Synchronous Connection Complete Event
+ 0x00001000 00000000 Synchronous Connection Changed Event
+ 0x00002000 00000000 Sniff Subrate Event
+ 0x00004000 00000000 Extended Inquiry Result Event
+ 0x00008000 00000000 Encryption Key Refresh Complete Event
+ 0x00010000 00000000 IO Capability Request Event
+ 0x00020000 00000000 IO Capability Response Event
+ 0x00040000 00000000 User Confirmation Request Event
+ 0x00080000 00000000 User Passkey Request Event
+ 0x00100000 00000000 Remote OOB Data Request Event
+ 0x00200000 00000000 Simple Pairing Complete Event
+ 0x00400000 00000000 Generic AMP Link Key Notification Event
+ 0x00800000 00000000 Link Supervision Timeout Changed Event
+ 0x01000000 00000000 Enhanced Flush Complete Event
+ 0x04000000 00000000 User Passkey Notification Event
+ 0x08000000 00000000 Keypress Notification Event
+ 0x10000000 00000000 Remote Host Supported Features Notification Event
+ 0x20000000 00000000 LE Meta Event
+ */
+
+
+/* the event mask for AMP controllers */
+#define HCI_AMP_EVENT_MASK_3_0 "\x00\x00\x00\x00\x00\x00\x3F\xFF"
+
+/* 0x0000000000000000 No events specified (default)
+ 0x0000000000000001 Physical Link Complete Event
+ 0x0000000000000002 Channel Selected Event
+ 0x0000000000000004 Disconnection Physical Link Event
+ 0x0000000000000008 Physical Link Loss Early Warning Event
+ 0x0000000000000010 Physical Link Recovery Event
+ 0x0000000000000020 Logical Link Complete Event
+ 0x0000000000000040 Disconnection Logical Link Complete Event
+ 0x0000000000000080 Flow Spec Modify Complete Event
+ 0x0000000000000100 Number of Completed Data Blocks Event
+ 0x0000000000000200 AMP Start Test Event
+ 0x0000000000000400 AMP Test End Event
+ 0x0000000000000800 AMP Receiver Report Event
+ 0x0000000000001000 Short Range Mode Change Complete Event
+ 0x0000000000002000 AMP Status Change Event
+*/
+
+/* the event mask page 2 (CLB + CSA4) for BR/EDR controller */
+#define HCI_PAGE_2_EVENT_MASK "\x00\x00\x00\x00\x00\x7F\xC0\x00"
+/* 0x0000000000004000 Triggered Clock Capture Event
+ 0x0000000000008000 Sync Train Complete Event
+ 0x0000000000010000 Sync Train Received Event
+ 0x0000000000020000 Connectionless Broadcast Receive Event
+ 0x0000000000040000 Connectionless Broadcast Timeout Event
+ 0x0000000000080000 Truncated Page Complete Event
+ 0x0000000000100000 Salve Page Response Timeout Event
+ 0x0000000000200000 Connectionless Broadcast Channel Map Change Event
+ 0x0000000000400000 Inquiry Response Notification Event
+*/
+
+/*
+** Definitions for packet type masks (BT1.2 and BT2.0 definitions)
+*/
+#define HCI_PKT_TYPES_MASK_NO_2_DH1 0x0002
+#define HCI_PKT_TYPES_MASK_NO_3_DH1 0x0004
+#define HCI_PKT_TYPES_MASK_DM1 0x0008
+#define HCI_PKT_TYPES_MASK_DH1 0x0010
+#define HCI_PKT_TYPES_MASK_HV1 0x0020
+#define HCI_PKT_TYPES_MASK_HV2 0x0040
+#define HCI_PKT_TYPES_MASK_HV3 0x0080
+#define HCI_PKT_TYPES_MASK_NO_2_DH3 0x0100
+#define HCI_PKT_TYPES_MASK_NO_3_DH3 0x0200
+#define HCI_PKT_TYPES_MASK_DM3 0x0400
+#define HCI_PKT_TYPES_MASK_DH3 0x0800
+#define HCI_PKT_TYPES_MASK_NO_2_DH5 0x1000
+#define HCI_PKT_TYPES_MASK_NO_3_DH5 0x2000
+#define HCI_PKT_TYPES_MASK_DM5 0x4000
+#define HCI_PKT_TYPES_MASK_DH5 0x8000
+
+/* Packet type should be one of valid but at least one should be specified */
+#define HCI_VALID_SCO_PKT_TYPE(t) (((((t) & ~(HCI_PKT_TYPES_MASK_HV1 \
+ | HCI_PKT_TYPES_MASK_HV2 \
+ | HCI_PKT_TYPES_MASK_HV3)) == 0)) \
+ && ((t) != 0))
+
+
+
+
+
+/* Packet type should not be invalid and at least one should be specified */
+#define HCI_VALID_ACL_PKT_TYPE(t) (((((t) & ~(HCI_PKT_TYPES_MASK_DM1 \
+ | HCI_PKT_TYPES_MASK_DH1 \
+ | HCI_PKT_TYPES_MASK_DM3 \
+ | HCI_PKT_TYPES_MASK_DH3 \
+ | HCI_PKT_TYPES_MASK_DM5 \
+ | HCI_PKT_TYPES_MASK_DH5 \
+ | HCI_PKT_TYPES_MASK_NO_2_DH1 \
+ | HCI_PKT_TYPES_MASK_NO_3_DH1 \
+ | HCI_PKT_TYPES_MASK_NO_2_DH3 \
+ | HCI_PKT_TYPES_MASK_NO_3_DH3 \
+ | HCI_PKT_TYPES_MASK_NO_2_DH5 \
+ | HCI_PKT_TYPES_MASK_NO_3_DH5 )) == 0)) \
+ && (((t) & (HCI_PKT_TYPES_MASK_DM1 \
+ | HCI_PKT_TYPES_MASK_DH1 \
+ | HCI_PKT_TYPES_MASK_DM3 \
+ | HCI_PKT_TYPES_MASK_DH3 \
+ | HCI_PKT_TYPES_MASK_DM5 \
+ | HCI_PKT_TYPES_MASK_DH5)) != 0))
+
+/*
+** Definitions for eSCO packet type masks (BT1.2 and BT2.0 definitions)
+*/
+#define HCI_ESCO_PKT_TYPES_MASK_HV1 0x0001
+#define HCI_ESCO_PKT_TYPES_MASK_HV2 0x0002
+#define HCI_ESCO_PKT_TYPES_MASK_HV3 0x0004
+#define HCI_ESCO_PKT_TYPES_MASK_EV3 0x0008
+#define HCI_ESCO_PKT_TYPES_MASK_EV4 0x0010
+#define HCI_ESCO_PKT_TYPES_MASK_EV5 0x0020
+#define HCI_ESCO_PKT_TYPES_MASK_NO_2_EV3 0x0040
+#define HCI_ESCO_PKT_TYPES_MASK_NO_3_EV3 0x0080
+#define HCI_ESCO_PKT_TYPES_MASK_NO_2_EV5 0x0100
+#define HCI_ESCO_PKT_TYPES_MASK_NO_3_EV5 0x0200
+
+/* Packet type should be one of valid but at least one should be specified for 1.2 */
+#define HCI_VALID_ESCO_PKT_TYPE(t) (((((t) & ~(HCI_ESCO_PKT_TYPES_MASK_EV3 \
+ | HCI_ESCO_PKT_TYPES_MASK_EV4 \
+ | HCI_ESCO_PKT_TYPES_MASK_EV5)) == 0)) \
+ && ((t) != 0))/* Packet type should be one of valid but at least one should be specified */
+
+#define HCI_VALID_ESCO_SCOPKT_TYPE(t) (((((t) & ~(HCI_ESCO_PKT_TYPES_MASK_HV1 \
+ | HCI_ESCO_PKT_TYPES_MASK_HV2 \
+ | HCI_ESCO_PKT_TYPES_MASK_HV3)) == 0)) \
+ && ((t) != 0))
+
+#define HCI_VALID_SCO_ALL_PKT_TYPE(t) (((((t) & ~(HCI_ESCO_PKT_TYPES_MASK_HV1 \
+ | HCI_ESCO_PKT_TYPES_MASK_HV2 \
+ | HCI_ESCO_PKT_TYPES_MASK_HV3 \
+ | HCI_ESCO_PKT_TYPES_MASK_EV3 \
+ | HCI_ESCO_PKT_TYPES_MASK_EV4 \
+ | HCI_ESCO_PKT_TYPES_MASK_EV5)) == 0)) \
+ && ((t) != 0))
+
+/*
+** Define parameters to allow role switch during create connection
+*/
+#define HCI_CR_CONN_NOT_ALLOW_SWITCH 0x00
+#define HCI_CR_CONN_ALLOW_SWITCH 0x01
+
+/*
+** Hold Mode command destination
+*/
+#define HOLD_MODE_DEST_LOCAL_DEVICE 0x00
+#define HOLD_MODE_DEST_RMT_DEVICE 0x01
+
+/*
+** Definitions for different HCI parameters
+*/
+#define HCI_PER_INQ_MIN_MAX_PERIOD 0x0003
+#define HCI_PER_INQ_MAX_MAX_PERIOD 0xFFFF
+#define HCI_PER_INQ_MIN_MIN_PERIOD 0x0002
+#define HCI_PER_INQ_MAX_MIN_PERIOD 0xFFFE
+
+#define HCI_MAX_INQUIRY_LENGTH 0x30
+
+#define HCI_MIN_INQ_LAP 0x9E8B00
+#define HCI_MAX_INQ_LAP 0x9E8B3F
+
+/* HCI role defenitions */
+#define HCI_ROLE_MASTER 0x00
+#define HCI_ROLE_SLAVE 0x01
+#define HCI_ROLE_UNKNOWN 0xff
+
+/* HCI mode defenitions */
+#define HCI_MODE_ACTIVE 0x00
+#define HCI_MODE_HOLD 0x01
+#define HCI_MODE_SNIFF 0x02
+#define HCI_MODE_PARK 0x03
+
+/* HCI Flow Control Mode defenitions */
+#define HCI_PACKET_BASED_FC_MODE 0x00
+#define HCI_BLOCK_BASED_FC_MODE 0x01
+
+/* Define Packet types as requested by the Host */
+#define HCI_ACL_PKT_TYPE_NONE 0x0000
+#define HCI_ACL_PKT_TYPE_DM1 0x0008
+#define HCI_ACL_PKT_TYPE_DH1 0x0010
+#define HCI_ACL_PKT_TYPE_AUX1 0x0200
+#define HCI_ACL_PKT_TYPE_DM3 0x0400
+#define HCI_ACL_PKT_TYPE_DH3 0x0800
+#define HCI_ACL_PKT_TYPE_DM5 0x4000
+#define HCI_ACL_PKT_TYPE_DH5 0x8000
+
+/* Define key type in the Master Link Key command */
+#define HCI_USE_SEMI_PERMANENT_KEY 0x00
+#define HCI_USE_TEMPORARY_KEY 0x01
+
+/* Page scan period modes */
+#define HCI_PAGE_SCAN_REP_MODE_R0 0x00
+#define HCI_PAGE_SCAN_REP_MODE_R1 0x01
+#define HCI_PAGE_SCAN_REP_MODE_R2 0x02
+
+/* Define limits for page scan repetition modes */
+#define HCI_PAGE_SCAN_R1_LIMIT 0x0800
+#define HCI_PAGE_SCAN_R2_LIMIT 0x1000
+
+/* Page scan period modes */
+#define HCI_PAGE_SCAN_PER_MODE_P0 0x00
+#define HCI_PAGE_SCAN_PER_MODE_P1 0x01
+#define HCI_PAGE_SCAN_PER_MODE_P2 0x02
+
+/* Page scan modes */
+#define HCI_MANDATARY_PAGE_SCAN_MODE 0x00
+#define HCI_OPTIONAL_PAGE_SCAN_MODE1 0x01
+#define HCI_OPTIONAL_PAGE_SCAN_MODE2 0x02
+#define HCI_OPTIONAL_PAGE_SCAN_MODE3 0x03
+
+/* Page and inquiry scan types */
+#define HCI_SCAN_TYPE_STANDARD 0x00
+#define HCI_SCAN_TYPE_INTERLACED 0x01 /* 1.2 devices or later */
+#define HCI_DEF_SCAN_TYPE HCI_SCAN_TYPE_STANDARD
+
+/* Definitions for quality of service service types */
+#define HCI_SERVICE_NO_TRAFFIC 0x00
+#define HCI_SERVICE_BEST_EFFORT 0x01
+#define HCI_SERVICE_GUARANTEED 0x02
+
+#define HCI_QOS_LATENCY_DO_NOT_CARE 0xFFFFFFFF
+#define HCI_QOS_DELAY_DO_NOT_CARE 0xFFFFFFFF
+
+/* Definitions for Flow Specification */
+#define HCI_FLOW_SPEC_LATENCY_DO_NOT_CARE 0xFFFFFFFF
+
+/* Definitions for AFH Channel Map */
+#define HCI_AFH_CHANNEL_MAP_LEN 10
+
+/* Definitions for Extended Inquiry Response */
+#define HCI_EXT_INQ_RESPONSE_LEN 240
+#define HCI_EIR_FLAGS_TYPE BT_EIR_FLAGS_TYPE
+#define HCI_EIR_MORE_16BITS_UUID_TYPE BT_EIR_MORE_16BITS_UUID_TYPE
+#define HCI_EIR_COMPLETE_16BITS_UUID_TYPE BT_EIR_COMPLETE_16BITS_UUID_TYPE
+#define HCI_EIR_MORE_32BITS_UUID_TYPE BT_EIR_MORE_32BITS_UUID_TYPE
+#define HCI_EIR_COMPLETE_32BITS_UUID_TYPE BT_EIR_COMPLETE_32BITS_UUID_TYPE
+#define HCI_EIR_MORE_128BITS_UUID_TYPE BT_EIR_MORE_128BITS_UUID_TYPE
+#define HCI_EIR_COMPLETE_128BITS_UUID_TYPE BT_EIR_COMPLETE_128BITS_UUID_TYPE
+#define HCI_EIR_SHORTENED_LOCAL_NAME_TYPE BT_EIR_SHORTENED_LOCAL_NAME_TYPE
+#define HCI_EIR_COMPLETE_LOCAL_NAME_TYPE BT_EIR_COMPLETE_LOCAL_NAME_TYPE
+#define HCI_EIR_TX_POWER_LEVEL_TYPE BT_EIR_TX_POWER_LEVEL_TYPE
+#define HCI_EIR_MANUFACTURER_SPECIFIC_TYPE BT_EIR_MANUFACTURER_SPECIFIC_TYPE
+#define HCI_EIR_OOB_BD_ADDR_TYPE BT_EIR_OOB_BD_ADDR_TYPE
+#define HCI_EIR_OOB_COD_TYPE BT_EIR_OOB_COD_TYPE
+#define HCI_EIR_OOB_SSP_HASH_C_TYPE BT_EIR_OOB_SSP_HASH_C_TYPE
+#define HCI_EIR_OOB_SSP_RAND_R_TYPE BT_EIR_OOB_SSP_RAND_R_TYPE
+#define HCI_EIR_3D_SYNC_TYPE BT_EIR_3D_SYNC_TYPE
+
+/* Definitions for Write Simple Pairing Mode */
+#define HCI_SP_MODE_UNDEFINED 0x00
+#define HCI_SP_MODE_ENABLED 0x01
+
+/* Definitions for Write Simple Pairing Debug Mode */
+#define HCI_SPD_MODE_DISABLED 0x00
+#define HCI_SPD_MODE_ENABLED 0x01
+
+/* Definitions for IO Capability Response/Command */
+#define HCI_IO_CAP_DISPLAY_ONLY 0x00
+#define HCI_IO_CAP_DISPLAY_YESNO 0x01
+#define HCI_IO_CAP_KEYBOARD_ONLY 0x02
+#define HCI_IO_CAP_NO_IO 0x03
+
+#define HCI_OOB_AUTH_DATA_NOT_PRESENT 0x00
+#define HCI_OOB_REM_AUTH_DATA_PRESENT 0x01
+
+#define HCI_MITM_PROTECT_NOT_REQUIRED 0x00
+#define HCI_MITM_PROTECT_REQUIRED 0x01
+
+
+/* Policy settings status */
+#define HCI_DISABLE_ALL_LM_MODES 0x0000
+#define HCI_ENABLE_MASTER_SLAVE_SWITCH 0x0001
+#define HCI_ENABLE_HOLD_MODE 0x0002
+#define HCI_ENABLE_SNIFF_MODE 0x0004
+#define HCI_ENABLE_PARK_MODE 0x0008
+
+/* By default allow switch, because host can not allow that */
+/* that until he created the connection */
+#define HCI_DEFAULT_POLICY_SETTINGS HCI_DISABLE_ALL_LM_MODES
+
+/* Filters that are sent in set filter command */
+#define HCI_FILTER_TYPE_CLEAR_ALL 0x00
+#define HCI_FILTER_INQUIRY_RESULT 0x01
+#define HCI_FILTER_CONNECTION_SETUP 0x02
+
+#define HCI_FILTER_COND_NEW_DEVICE 0x00
+#define HCI_FILTER_COND_DEVICE_CLASS 0x01
+#define HCI_FILTER_COND_BD_ADDR 0x02
+
+#define HCI_DO_NOT_AUTO_ACCEPT_CONNECT 1
+#define HCI_DO_AUTO_ACCEPT_CONNECT 2 /* role switch disabled */
+#define HCI_DO_AUTO_ACCEPT_CONNECT_RS 3 /* role switch enabled (1.1 errata 1115) */
+
+/* Auto accept flags */
+#define HCI_AUTO_ACCEPT_OFF 0x00
+#define HCI_AUTO_ACCEPT_ACL_CONNECTIONS 0x01
+#define HCI_AUTO_ACCEPT_SCO_CONNECTIONS 0x02
+
+/* PIN type */
+#define HCI_PIN_TYPE_VARIABLE 0
+#define HCI_PIN_TYPE_FIXED 1
+
+/* Loopback Modes */
+#define HCI_LOOPBACK_MODE_DISABLED 0
+#define HCI_LOOPBACK_MODE_LOCAL 1
+#define HCI_LOOPBACK_MODE_REMOTE 2
+
+#define SLOTS_PER_10MS 16 /* 0.625 ms slots in a 10 ms tick */
+
+/* Maximum connection accept timeout in 0.625msec */
+#define HCI_MAX_CONN_ACCEPT_TOUT 0xB540 /* 29 sec */
+#define HCI_DEF_CONN_ACCEPT_TOUT 0x1F40 /* 5 sec */
+
+/* Page timeout is used in LC only and LC is counting down slots not using OS */
+#define HCI_DEFAULT_PAGE_TOUT 0x2000 /* 5.12 sec (in slots) */
+
+/* Scan enable flags */
+#define HCI_NO_SCAN_ENABLED 0x00
+#define HCI_INQUIRY_SCAN_ENABLED 0x01
+#define HCI_PAGE_SCAN_ENABLED 0x02
+
+/* Pagescan timer definitions in 0.625 ms */
+#define HCI_MIN_PAGESCAN_INTERVAL 0x12 /* 11.25 ms */
+#define HCI_MAX_PAGESCAN_INTERVAL 0x1000 /* 2.56 sec */
+#define HCI_DEF_PAGESCAN_INTERVAL 0x0800 /* 1.28 sec */
+
+/* Parameter for pagescan window is passed to LC and is kept in slots */
+#define HCI_MIN_PAGESCAN_WINDOW 0x11 /* 10.625 ms */
+#define HCI_MAX_PAGESCAN_WINDOW 0x1000 /* 2.56 sec */
+#define HCI_DEF_PAGESCAN_WINDOW 0x12 /* 11.25 ms */
+
+/* Inquiryscan timer definitions in 0.625 ms */
+#define HCI_MIN_INQUIRYSCAN_INTERVAL 0x12 /* 11.25 ms */
+#define HCI_MAX_INQUIRYSCAN_INTERVAL 0x1000 /* 2.56 sec */
+#define HCI_DEF_INQUIRYSCAN_INTERVAL 0x1000 /* 2.56 sec */
+
+/* Parameter for inquiryscan window is passed to LC and is kept in slots */
+#define HCI_MIN_INQUIRYSCAN_WINDOW 0x11 /* 10.625 ms */
+#define HCI_MAX_INQUIRYSCAN_WINDOW 0x1000 /* 2.56 sec */
+#define HCI_DEF_INQUIRYSCAN_WINDOW 0x12 /* 11.25 ms */
+
+/* Encryption modes */
+#define HCI_ENCRYPT_MODE_DISABLED 0x00
+#define HCI_ENCRYPT_MODE_POINT_TO_POINT 0x01
+#define HCI_ENCRYPT_MODE_ALL 0x02
+
+/* Voice settings */
+#define HCI_INP_CODING_LINEAR 0x0000 /* 0000000000 */
+#define HCI_INP_CODING_U_LAW 0x0100 /* 0100000000 */
+#define HCI_INP_CODING_A_LAW 0x0200 /* 1000000000 */
+#define HCI_INP_CODING_MASK 0x0300 /* 1100000000 */
+
+#define HCI_INP_DATA_FMT_1S_COMPLEMENT 0x0000 /* 0000000000 */
+#define HCI_INP_DATA_FMT_2S_COMPLEMENT 0x0040 /* 0001000000 */
+#define HCI_INP_DATA_FMT_SIGN_MAGNITUDE 0x0080 /* 0010000000 */
+#define HCI_INP_DATA_FMT_UNSIGNED 0x00c0 /* 0011000000 */
+#define HCI_INP_DATA_FMT_MASK 0x00c0 /* 0011000000 */
+
+#define HCI_INP_SAMPLE_SIZE_8BIT 0x0000 /* 0000000000 */
+#define HCI_INP_SAMPLE_SIZE_16BIT 0x0020 /* 0000100000 */
+#define HCI_INP_SAMPLE_SIZE_MASK 0x0020 /* 0000100000 */
+
+#define HCI_INP_LINEAR_PCM_BIT_POS_MASK 0x001c /* 0000011100 */
+#define HCI_INP_LINEAR_PCM_BIT_POS_OFFS 2
+
+#define HCI_AIR_CODING_FORMAT_CVSD 0x0000 /* 0000000000 */
+#define HCI_AIR_CODING_FORMAT_U_LAW 0x0001 /* 0000000001 */
+#define HCI_AIR_CODING_FORMAT_A_LAW 0x0002 /* 0000000010 */
+#define HCI_AIR_CODING_FORMAT_TRANSPNT 0x0003 /* 0000000011 */
+#define HCI_AIR_CODING_FORMAT_MASK 0x0003 /* 0000000011 */
+
+/* default 0001100000 */
+#define HCI_DEFAULT_VOICE_SETTINGS (HCI_INP_CODING_LINEAR \
+ | HCI_INP_DATA_FMT_2S_COMPLEMENT \
+ | HCI_INP_SAMPLE_SIZE_16BIT \
+ | HCI_AIR_CODING_FORMAT_CVSD)
+
+#define HCI_CVSD_SUPPORTED(x) (((x) & HCI_AIR_CODING_FORMAT_MASK) == HCI_AIR_CODING_FORMAT_CVSD)
+#define HCI_U_LAW_SUPPORTED(x) (((x) & HCI_AIR_CODING_FORMAT_MASK) == HCI_AIR_CODING_FORMAT_U_LAW)
+#define HCI_A_LAW_SUPPORTED(x) (((x) & HCI_AIR_CODING_FORMAT_MASK) == HCI_AIR_CODING_FORMAT_A_LAW)
+#define HCI_TRANSPNT_SUPPORTED(x) (((x) & HCI_AIR_CODING_FORMAT_MASK) == HCI_AIR_CODING_FORMAT_TRANSPNT)
+
+/* Retransmit timer definitions in 0.625 */
+#define HCI_MAX_AUTO_FLUSH_TOUT 0x07FF
+#define HCI_DEFAULT_AUTO_FLUSH_TOUT 0 /* No auto flush */
+
+/* Broadcast retransmitions */
+#define HCI_DEFAULT_NUM_BCAST_RETRAN 1
+
+/* Define broadcast data types as passed in the hci data packet */
+#define HCI_DATA_POINT_TO_POINT 0x00
+#define HCI_DATA_ACTIVE_BCAST 0x01
+#define HCI_DATA_PICONET_BCAST 0x02
+
+/* Hold mode activity */
+#define HCI_MAINTAIN_CUR_POWER_STATE 0x00
+#define HCI_SUSPEND_PAGE_SCAN 0x01
+#define HCI_SUSPEND_INQUIRY_SCAN 0x02
+#define HCI_SUSPEND_PERIODIC_INQUIRIES 0x04
+
+/* Default Link Supervision timeoout */
+#define HCI_DEFAULT_INACT_TOUT 0x7D00 /* BR/EDR (20 seconds) */
+#define HCI_DEFAULT_AMP_INACT_TOUT 0x3E80 /* AMP (10 seconds) */
+
+/* Read transmit power level parameter */
+#define HCI_READ_CURRENT 0x00
+#define HCI_READ_MAXIMUM 0x01
+
+/* Link types for connection complete event */
+#define HCI_LINK_TYPE_SCO 0x00
+#define HCI_LINK_TYPE_ACL 0x01
+#define HCI_LINK_TYPE_ESCO 0x02
+
+/* Link Key Notification Event (Key Type) definitions */
+#define HCI_LKEY_TYPE_COMBINATION 0x00
+#define HCI_LKEY_TYPE_LOCAL_UNIT 0x01
+#define HCI_LKEY_TYPE_REMOTE_UNIT 0x02
+#define HCI_LKEY_TYPE_DEBUG_COMB 0x03
+#define HCI_LKEY_TYPE_UNAUTH_COMB 0x04
+#define HCI_LKEY_TYPE_AUTH_COMB 0x05
+#define HCI_LKEY_TYPE_CHANGED_COMB 0x06
+
+/* Internal definitions - not used over HCI */
+#define HCI_LKEY_TYPE_AMP_WIFI 0x80
+#define HCI_LKEY_TYPE_AMP_UWB 0x81
+#define HCI_LKEY_TYPE_UNKNOWN 0xff
+
+/* Read Local Version HCI Version return values (Command Complete Event) */
+#define HCI_VERSION_1_0B 0x00
+#define HCI_VERSION_1_1 0x01
+
+/* Define an invalid value for a handle */
+#define HCI_INVALID_HANDLE 0xFFFF
+
+/* Define max ammount of data in the HCI command */
+#define HCI_COMMAND_SIZE 255
+
+/* Define the preamble length for all HCI Commands.
+** This is 2-bytes for opcode and 1 byte for length
+*/
+#define HCIC_PREAMBLE_SIZE 3
+
+/* Define the preamble length for all HCI Events
+** This is 1-byte for opcode and 1 byte for length
+*/
+#define HCIE_PREAMBLE_SIZE 2
+#define HCI_SCO_PREAMBLE_SIZE 3
+#define HCI_DATA_PREAMBLE_SIZE 4
+
+/* local Bluetooth controller id for AMP HCI */
+#define LOCAL_BR_EDR_CONTROLLER_ID 0
+
+/* controller id types for AMP HCI */
+#define HCI_CONTROLLER_TYPE_BR_EDR 0
+#define HCI_CONTROLLER_TYPE_802_11 1
+#define HCI_CONTROLLER_TYPE_ECMA 2
+#define HCI_MAX_CONTROLLER_TYPES 3
+
+/* ConnectionLess Broadcast */
+#define HCI_CLB_DISABLE 0x00
+#define HCI_CLB_ENABLE 0x01
+
+/* ConnectionLess Broadcast Data fragment */
+#define HCI_CLB_FRAGMENT_CONT 0x00
+#define HCI_CLB_FRAGMENT_START 0x01
+#define HCI_CLB_FRAGMENT_END 0x02
+#define HCI_CLB_FRAGMENT_SINGLE 0x03
+
+/* AMP Controller Status codes
+*/
+#define HCI_AMP_CTRLR_PHYSICALLY_DOWN 0
+#define HCI_AMP_CTRLR_USABLE_BY_BT 1
+#define HCI_AMP_CTRLR_UNUSABLE_FOR_BT 2
+#define HCI_AMP_CTRLR_LOW_CAP_FOR_BT 3
+#define HCI_AMP_CTRLR_MED_CAP_FOR_BT 4
+#define HCI_AMP_CTRLR_HIGH_CAP_FOR_BT 5
+#define HCI_AMP_CTRLR_FULL_CAP_FOR_BT 6
+
+#define HCI_MAX_AMP_STATUS_TYPES 7
+
+
+/* Define the extended flow specification fields used by AMP */
+typedef struct
+{
+ UINT8 id;
+ UINT8 stype;
+ UINT16 max_sdu_size;
+ UINT32 sdu_inter_time;
+ UINT32 access_latency;
+ UINT32 flush_timeout;
+} tHCI_EXT_FLOW_SPEC;
+
+
+/* HCI message type definitions (for H4 messages) */
+#define HCIT_TYPE_COMMAND 1
+#define HCIT_TYPE_ACL_DATA 2
+#define HCIT_TYPE_SCO_DATA 3
+#define HCIT_TYPE_EVENT 4
+#define HCIT_TYPE_LM_DIAG 7
+#define HCIT_TYPE_NFC 16
+
+#define HCIT_LM_DIAG_LENGTH 63
+
+/* Define values for LMP Test Control parameters
+** Test Scenario, Hopping Mode, Power Control Mode
+*/
+#define LMP_TESTCTL_TESTSC_PAUSE 0
+#define LMP_TESTCTL_TESTSC_TXTEST_0 1
+#define LMP_TESTCTL_TESTSC_TXTEST_1 2
+#define LMP_TESTCTL_TESTSC_TXTEST_1010 3
+#define LMP_TESTCTL_TESTSC_PSRND_BITSEQ 4
+#define LMP_TESTCTL_TESTSC_CLOSEDLB_ACL 5
+#define LMP_TESTCTL_TESTSC_CLOSEDLB_SCO 6
+#define LMP_TESTCTL_TESTSC_ACL_NOWHIT 7
+#define LMP_TESTCTL_TESTSC_SCO_NOWHIT 8
+#define LMP_TESTCTL_TESTSC_TXTEST_11110000 9
+#define LMP_TESTCTL_TESTSC_EXITTESTMODE 255
+
+#define LMP_TESTCTL_HOPMOD_RXTX1FREQ 0
+#define LMP_TESTCTL_HOPMOD_HOP_EURUSA 1
+#define LMP_TESTCTL_HOPMOD_HOP_JAPAN 2
+#define LMP_TESTCTL_HOPMOD_HOP_FRANCE 3
+#define LMP_TESTCTL_HOPMOD_HOP_SPAIN 4
+#define LMP_TESTCTL_HOPMOD_REDUCED_HOP 5
+
+#define LMP_TESTCTL_POWCTL_FIXEDTX_OP 0
+#define LMP_TESTCTL_POWCTL_ADAPTIVE 1
+
+
+/*
+** Define company IDs (from Bluetooth Assigned Numbers v1.1, section 2.2)
+*/
+#define LMP_COMPID_ERICSSON 0
+#define LMP_COMPID_NOKIA 1
+#define LMP_COMPID_INTEL 2
+#define LMP_COMPID_IBM 3
+#define LMP_COMPID_TOSHIBA 4
+#define LMP_COMPID_3COM 5
+#define LMP_COMPID_MICROSOFT 6
+#define LMP_COMPID_LUCENT 7
+#define LMP_COMPID_MOTOROLA 8
+#define LMP_COMPID_INFINEON 9
+#define LMP_COMPID_CSR 10
+#define LMP_COMPID_SILICON_WAVE 11
+#define LMP_COMPID_DIGIANSWER 12
+#define LMP_COMPID_TEXAS_INSTRUMENTS 13
+#define LMP_COMPID_PARTHUS 14
+#define LMP_COMPID_BROADCOM 15
+#define LMP_COMPID_MITEL_SEMI 16
+#define LMP_COMPID_WIDCOMM 17
+#define LMP_COMPID_ZEEVO 18
+#define LMP_COMPID_ATMEL 19
+#define LMP_COMPID_MITSUBISHI 20
+#define LMP_COMPID_RTX_TELECOM 21
+#define LMP_COMPID_KC_TECH 22
+#define LMP_COMPID_NEWLOGIC 23
+#define LMP_COMPID_TRANSILICA 24
+#define LMP_COMPID_ROHDE_SCHWARZ 25
+#define LMP_COMPID_TTPCOM 26
+#define LMP_COMPID_SIGNIA 27
+#define LMP_COMPID_CONEXANT 28
+#define LMP_COMPID_QUALCOMM 29
+#define LMP_COMPID_INVENTEL 30
+#define LMP_COMPID_AVM 31
+#define LMP_COMPID_BANDSPEED 32
+#define LMP_COMPID_MANSELLA 33
+#define LMP_COMPID_NEC_CORP 34
+#define LMP_COMPID_WAVEPLUS 35
+#define LMP_COMPID_ALCATEL 36
+#define LMP_COMPID_PHILIPS 37
+#define LMP_COMPID_C_TECHNOLOGIES 38
+#define LMP_COMPID_OPEN_INTERFACE 39
+#define LMP_COMPID_RF_MICRO 40
+#define LMP_COMPID_HITACHI 41
+#define LMP_COMPID_SYMBOL_TECH 42
+#define LMP_COMPID_TENOVIS 43
+#define LMP_COMPID_MACRONIX 44
+#define LMP_COMPID_GCT_SEMI 45
+#define LMP_COMPID_NORWOOD_SYSTEMS 46
+#define LMP_COMPID_MEWTEL_TECH 47
+#define LMP_COMPID_STM 48
+#define LMP_COMPID_SYNOPSYS 49
+#define LMP_COMPID_RED_M_LTD 50
+#define LMP_COMPID_COMMIL_LTD 51
+#define LMP_COMPID_CATC 52
+#define LMP_COMPID_ECLIPSE 53
+#define LMP_COMPID_RENESAS_TECH 54
+#define LMP_COMPID_MOBILIAN_CORP 55
+#define LMP_COMPID_TERAX 56
+#define LMP_COMPID_ISSC 57
+#define LMP_COMPID_MATSUSHITA 58
+#define LMP_COMPID_GENNUM_CORP 59
+#define LMP_COMPID_RESEARCH_IN_MOTION 60
+#define LMP_COMPID_IPEXTREME 61
+#define LMP_COMPID_SYSTEMS_AND_CHIPS 62
+#define LMP_COMPID_BLUETOOTH_SIG 63
+#define LMP_COMPID_SEIKO_EPSON_CORP 64
+#define LMP_COMPID_ISS_TAIWAN 65
+#define LMP_COMPID_CONWISE_TECHNOLOGIES 66
+#define LMP_COMPID_PARROT_SA 67
+#define LMP_COMPID_SOCKET_COMM 68
+#define LMP_COMPID_ALTHEROS 69
+#define LMP_COMPID_MEDIATEK 70
+#define LMP_COMPID_BLUEGIGA 71
+#define LMP_COMPID_MARVELL 72
+#define LMP_COMPID_3DSP_CORP 73
+#define LMP_COMPID_ACCEL_SEMICONDUCTOR 74
+#define LMP_COMPID_CONTINENTAL_AUTO 75
+#define LMP_COMPID_APPLE 76
+#define LMP_COMPID_STACCATO 77
+#define LMP_COMPID_AVAGO_TECHNOLOGIES 78
+#define LMP_COMPID_APT_LTD 79
+#define LMP_COMPID_SIRF_TECHNOLOGY 80
+#define LMP_COMPID_TZERO_TECHNOLOGY 81
+#define LMP_COMPID_J_AND_M_CORP 82
+#define LMP_COMPID_FREE_2_MOVE 83
+#define LMP_COMPID_3DIJOY_CORP 84
+#define LMP_COMPID_PLANTRONICS 85
+#define LMP_COMPID_SONY_ERICSSON_MOBILE 86
+#define LMP_COMPID_HARMON_INTL_IND 87
+#define LMP_COMPID_VIZIO 88
+#define LMP_COMPID_NORDIC SEMI 89
+#define LMP_COMPID_EM_MICRO 90
+#define LMP_COMPID_RALINK_TECH 91
+#define LMP_COMPID_BELKIN_INC 92
+#define LMP_COMPID_REALTEK_SEMI 93
+#define LMP_COMPID_STONESTREET_ONE 94
+#define LMP_COMPID_WICENTRIC 95
+#define LMP_COMPID_RIVIERAWAVES 96
+#define LMP_COMPID_RDA_MICRO 97
+#define LMP_COMPID_GIBSON_GUITARS 98
+#define LMP_COMPID_MICOMMAND_INC 99
+#define LMP_COMPID_BAND_XI 100
+#define LMP_COMPID_HP_COMPANY 101
+#define LMP_COMPID_9SOLUTIONS_OY 102
+#define LMP_COMPID_GN_NETCOM 103
+#define LMP_COMPID_GENERAL_MOTORS 104
+#define LMP_COMPID_AD_ENGINEERING 105
+#define LMP_COMPID_MINDTREE_LTD 106
+#define LMP_COMPID_POLAR_ELECTRO 107
+#define LMP_COMPID_BEAUTIFUL_ENTERPRISE 108
+#define LMP_COMPID_BRIARTEK 109
+#define LMP_COMPID_SUMMIT_DATA_COMM 110
+#define LMP_COMPID_SOUND_ID 111
+#define LMP_COMPID_MONSTER LLC 112
+#define LMP_COMPID_CONNECTBLU 113
+
+#define LMP_COMPID_SHANGHAI_SSE 114
+#define LMP_COMPID_GROUP_SENSE 115
+#define LMP_COMPID_ZOMM 116
+#define LMP_COMPID_SAMSUNG 117
+#define LMP_COMPID_CREATIVE_TECH 118
+#define LMP_COMPID_LAIRD_TECH 119
+#define LMP_COMPID_NIKE 120
+#define LMP_COMPID_LESSWIRE 121
+#define LMP_COMPID_MSTAR_SEMI 122
+#define LMP_COMPID_HANLYNN_TECH 123
+#define LMP_COMPID_AR_CAMBRIDGE 124
+#define LMP_COMPID_SEERS_TECH 125
+#define LMP_COMPID_SPORTS_TRACKING 126
+#define LMP_COMPID_AUTONET_MOBILE 127
+#define LMP_COMPID_DELORME_PUBLISH 128
+#define LMP_COMPID_WUXI_VIMICRO 129
+#define LMP_COMPID_SENNHEISER 130
+#define LMP_COMPID_TIME_KEEPING_SYS 131
+#define LMP_COMPID_LUDUS_HELSINKI 132
+#define LMP_COMPID_BLUE_RADIOS 133
+#define LMP_COMPID_EQUINUX 134
+#define LMP_COMPID_GARMIN_INTL 135
+#define LMP_COMPID_ECOTEST 136
+#define LMP_COMPID_GN_RESOUND 137
+#define LMP_COMPID_JAWBONE 138
+#define LMP_COMPID_TOPCON_POSITIONING 139
+#define LMP_COMPID_QUALCOMM_LABS 140
+#define LMP_COMPID_ZSCAN_SOFTWARE 141
+#define LMP_COMPID_QUINTIC 142
+#define LMP_COMPID_STOLLMAN_EV 143
+#define LMP_COMPID_FUNAI_ELECTRONIC 144
+#define LMP_COMPID_ADV_PANMOBILE 145
+#define LMP_COMPID_THINK_OPTICS 146
+#define LMP_COMPID_UNIVERSAL_ELEC 147
+#define LMP_COMPID_AIROHA_TECH 148
+#define LMP_COMPID_MAX_ID 149 /* this is a place holder */
+#define LMP_COMPID_INTERNAL 65535
+
+#define MAX_LMP_COMPID (LMP_COMPID_MAX_ID)
+/*
+** Define the packet types in the packet header, and a couple extra
+*/
+#define PKT_TYPE_NULL 0x00
+#define PKT_TYPE_POLL 0x01
+#define PKT_TYPE_FHS 0x02
+#define PKT_TYPE_DM1 0x03
+
+#define PKT_TYPE_DH1 0x04
+#define PKT_TYPE_HV1 0x05
+#define PKT_TYPE_HV2 0x06
+#define PKT_TYPE_HV3 0x07
+#define PKT_TYPE_DV 0x08
+#define PKT_TYPE_AUX1 0x09
+
+#define PKT_TYPE_DM3 0x0a
+#define PKT_TYPE_DH3 0x0b
+
+#define PKT_TYPE_DM5 0x0e
+#define PKT_TYPE_DH5 0x0f
+
+
+#define PKT_TYPE_ID 0x10 /* Internally used packet types */
+#define PKT_TYPE_BAD 0x11
+#define PKT_TYPE_NONE 0x12
+
+/*
+** Define packet size
+*/
+#define HCI_DM1_PACKET_SIZE 17
+#define HCI_DH1_PACKET_SIZE 27
+#define HCI_DM3_PACKET_SIZE 121
+#define HCI_DH3_PACKET_SIZE 183
+#define HCI_DM5_PACKET_SIZE 224
+#define HCI_DH5_PACKET_SIZE 339
+#define HCI_AUX1_PACKET_SIZE 29
+#define HCI_HV1_PACKET_SIZE 10
+#define HCI_HV2_PACKET_SIZE 20
+#define HCI_HV3_PACKET_SIZE 30
+#define HCI_DV_PACKET_SIZE 9
+#define HCI_EDR2_DH1_PACKET_SIZE 54
+#define HCI_EDR2_DH3_PACKET_SIZE 367
+#define HCI_EDR2_DH5_PACKET_SIZE 679
+#define HCI_EDR3_DH1_PACKET_SIZE 83
+#define HCI_EDR3_DH3_PACKET_SIZE 552
+#define HCI_EDR3_DH5_PACKET_SIZE 1021
+
+/* Feature Pages */
+#define HCI_EXT_FEATURES_PAGE_0 0 /* Extended Feature Page 0 (regular features) */
+#define HCI_EXT_FEATURES_PAGE_1 1 /* Extended Feature Page 1 */
+#define HCI_EXT_FEATURES_PAGE_2 2 /* Extended Feature Page 2 */
+#define HCI_EXT_FEATURES_PAGE_MAX HCI_EXT_FEATURES_PAGE_2
+
+#define HCI_FEATURE_BYTES_PER_PAGE 8
+
+#define HCI_FEATURES_KNOWN(x) ((x[0] | x[1] | x[2] | x[3] | x[4] | x[5] | x[6] | x[7]) != 0)
+
+/*
+** LMP features encoding - page 0
+*/
+#define HCI_FEATURE_3_SLOT_PACKETS_MASK 0x01
+#define HCI_FEATURE_3_SLOT_PACKETS_OFF 0
+#define HCI_3_SLOT_PACKETS_SUPPORTED(x) ((x)[HCI_FEATURE_3_SLOT_PACKETS_OFF] & HCI_FEATURE_3_SLOT_PACKETS_MASK)
+
+#define HCI_FEATURE_5_SLOT_PACKETS_MASK 0x02
+#define HCI_FEATURE_5_SLOT_PACKETS_OFF 0
+#define HCI_5_SLOT_PACKETS_SUPPORTED(x) ((x)[HCI_FEATURE_5_SLOT_PACKETS_OFF] & HCI_FEATURE_5_SLOT_PACKETS_MASK)
+
+#define HCI_FEATURE_ENCRYPTION_MASK 0x04
+#define HCI_FEATURE_ENCRYPTION_OFF 0
+#define HCI_ENCRYPTION_SUPPORTED(x) ((x)[HCI_FEATURE_ENCRYPTION_OFF] & HCI_FEATURE_ENCRYPTION_MASK)
+
+#define HCI_FEATURE_SLOT_OFFSET_MASK 0x08
+#define HCI_FEATURE_SLOT_OFFSET_OFF 0
+#define HCI_SLOT_OFFSET_SUPPORTED(x) ((x)[HCI_FEATURE_SLOT_OFFSET_OFF] & HCI_FEATURE_SLOT_OFFSET_MASK)
+
+#define HCI_FEATURE_TIMING_ACC_MASK 0x10
+#define HCI_FEATURE_TIMING_ACC_OFF 0
+#define HCI_TIMING_ACC_SUPPORTED(x) ((x)[HCI_FEATURE_TIMING_ACC_OFF] & HCI_FEATURE_TIMING_ACC_MASK)
+
+#define HCI_FEATURE_SWITCH_MASK 0x20
+#define HCI_FEATURE_SWITCH_OFF 0
+#define HCI_SWITCH_SUPPORTED(x) ((x)[HCI_FEATURE_SWITCH_OFF] & HCI_FEATURE_SWITCH_MASK)
+
+#define HCI_FEATURE_HOLD_MODE_MASK 0x40
+#define HCI_FEATURE_HOLD_MODE_OFF 0
+#define HCI_HOLD_MODE_SUPPORTED(x) ((x)[HCI_FEATURE_HOLD_MODE_OFF] & HCI_FEATURE_HOLD_MODE_MASK)
+
+#define HCI_FEATURE_SNIFF_MODE_MASK 0x80
+#define HCI_FEATURE_SNIFF_MODE_OFF 0
+#define HCI_SNIFF_MODE_SUPPORTED(x) ((x)[HCI_FEATURE_SNIFF_MODE_OFF] & HCI_FEATURE_SNIFF_MODE_MASK)
+
+#define HCI_FEATURE_PARK_MODE_MASK 0x01
+#define HCI_FEATURE_PARK_MODE_OFF 1
+#define HCI_PARK_MODE_SUPPORTED(x) ((x)[HCI_FEATURE_PARK_MODE_OFF] & HCI_FEATURE_PARK_MODE_MASK)
+
+#define HCI_FEATURE_RSSI_MASK 0x02
+#define HCI_FEATURE_RSSI_OFF 1
+#define HCI_RSSI_SUPPORTED(x) ((x)[HCI_FEATURE_RSSI_OFF] & HCI_FEATURE_RSSI_MASK)
+
+#define HCI_FEATURE_CQM_DATA_RATE_MASK 0x04
+#define HCI_FEATURE_CQM_DATA_RATE_OFF 1
+#define HCI_CQM_DATA_RATE_SUPPORTED(x) ((x)[HCI_FEATURE_CQM_DATA_RATE_OFF] & HCI_FEATURE_CQM_DATA_RATE_MASK)
+
+#define HCI_FEATURE_SCO_LINK_MASK 0x08
+#define HCI_FEATURE_SCO_LINK_OFF 1
+#define HCI_SCO_LINK_SUPPORTED(x) ((x)[HCI_FEATURE_SCO_LINK_OFF] & HCI_FEATURE_SCO_LINK_MASK)
+
+#define HCI_FEATURE_HV2_PACKETS_MASK 0x10
+#define HCI_FEATURE_HV2_PACKETS_OFF 1
+#define HCI_HV2_PACKETS_SUPPORTED(x) ((x)[HCI_FEATURE_HV2_PACKETS_OFF] & HCI_FEATURE_HV2_PACKETS_MASK)
+
+#define HCI_FEATURE_HV3_PACKETS_MASK 0x20
+#define HCI_FEATURE_HV3_PACKETS_OFF 1
+#define HCI_HV3_PACKETS_SUPPORTED(x) ((x)[HCI_FEATURE_HV3_PACKETS_OFF] & HCI_FEATURE_HV3_PACKETS_MASK)
+
+#define HCI_FEATURE_U_LAW_MASK 0x40
+#define HCI_FEATURE_U_LAW_OFF 1
+#define HCI_LMP_U_LAW_SUPPORTED(x) ((x)[HCI_FEATURE_U_LAW_OFF] & HCI_FEATURE_U_LAW_MASK)
+
+#define HCI_FEATURE_A_LAW_MASK 0x80
+#define HCI_FEATURE_A_LAW_OFF 1
+#define HCI_LMP_A_LAW_SUPPORTED(x) ((x)[HCI_FEATURE_A_LAW_OFF] & HCI_FEATURE_A_LAW_MASK)
+
+#define HCI_FEATURE_CVSD_MASK 0x01
+#define HCI_FEATURE_CVSD_OFF 2
+#define HCI_LMP_CVSD_SUPPORTED(x) ((x)[HCI_FEATURE_CVSD_OFF] & HCI_FEATURE_CVSD_MASK)
+
+#define HCI_FEATURE_PAGING_SCHEME_MASK 0x02
+#define HCI_FEATURE_PAGING_SCHEME_OFF 2
+#define HCI_PAGING_SCHEME_SUPPORTED(x) ((x)[HCI_FEATURE_PAGING_SCHEME_OFF] & HCI_FEATURE_PAGING_SCHEME_MASK)
+
+#define HCI_FEATURE_POWER_CTRL_MASK 0x04
+#define HCI_FEATURE_POWER_CTRL_OFF 2
+#define HCI_POWER_CTRL_SUPPORTED(x) ((x)[HCI_FEATURE_POWER_CTRL_OFF] & HCI_FEATURE_POWER_CTRL_MASK)
+
+#define HCI_FEATURE_TRANSPNT_MASK 0x08
+#define HCI_FEATURE_TRANSPNT_OFF 2
+#define HCI_LMP_TRANSPNT_SUPPORTED(x) ((x)[HCI_FEATURE_TRANSPNT_OFF] & HCI_FEATURE_TRANSPNT_MASK)
+
+#define HCI_FEATURE_FLOW_CTRL_LAG_MASK 0x70
+#define HCI_FEATURE_FLOW_CTRL_LAG_OFF 2
+#define HCI_FLOW_CTRL_LAG_VALUE(x) (((x)[HCI_FEATURE_FLOW_CTRL_LAG_OFF] & HCI_FEATURE_FLOW_CTRL_LAG_MASK) >> 4)
+
+#define HCI_FEATURE_BROADCAST_ENC_MASK 0x80
+#define HCI_FEATURE_BROADCAST_ENC_OFF 2
+#define HCI_LMP_BCAST_ENC_SUPPORTED(x) ((x)[HCI_FEATURE_BROADCAST_ENC_OFF] & HCI_FEATURE_BROADCAST_ENC_MASK)
+
+#define HCI_FEATURE_SCATTER_MODE_MASK 0x01
+#define HCI_FEATURE_SCATTER_MODE_OFF 3
+#define HCI_LMP_SCATTER_MODE_SUPPORTED(x) ((x)[HCI_FEATURE_SCATTER_MODE_OFF] & HCI_FEATURE_SCATTER_MODE_MASK)
+
+#define HCI_FEATURE_EDR_ACL_2MPS_MASK 0x02
+#define HCI_FEATURE_EDR_ACL_2MPS_OFF 3
+#define HCI_EDR_ACL_2MPS_SUPPORTED(x) ((x)[HCI_FEATURE_EDR_ACL_2MPS_OFF] & HCI_FEATURE_EDR_ACL_2MPS_MASK)
+
+#define HCI_FEATURE_EDR_ACL_3MPS_MASK 0x04
+#define HCI_FEATURE_EDR_ACL_3MPS_OFF 3
+#define HCI_EDR_ACL_3MPS_SUPPORTED(x) ((x)[HCI_FEATURE_EDR_ACL_3MPS_OFF] & HCI_FEATURE_EDR_ACL_3MPS_MASK)
+
+#define HCI_FEATURE_ENHANCED_INQ_MASK 0x08
+#define HCI_FEATURE_ENHANCED_INQ_OFF 3
+#define HCI_ENHANCED_INQ_SUPPORTED(x) ((x)[HCI_FEATURE_ENHANCED_INQ_OFF] & HCI_FEATURE_ENHANCED_INQ_MASK)
+
+#define HCI_FEATURE_INTERLACED_INQ_SCAN_MASK 0x10
+#define HCI_FEATURE_INTERLACED_INQ_SCAN_OFF 3
+#define HCI_LMP_INTERLACED_INQ_SCAN_SUPPORTED(x) ((x)[HCI_FEATURE_INTERLACED_INQ_SCAN_OFF] & HCI_FEATURE_INTERLACED_INQ_SCAN_MASK)
+
+#define HCI_FEATURE_INTERLACED_PAGE_SCAN_MASK 0x20
+#define HCI_FEATURE_INTERLACED_PAGE_SCAN_OFF 3
+#define HCI_LMP_INTERLACED_PAGE_SCAN_SUPPORTED(x) ((x)[HCI_FEATURE_INTERLACED_PAGE_SCAN_OFF] & HCI_FEATURE_INTERLACED_PAGE_SCAN_MASK)
+
+#define HCI_FEATURE_INQ_RSSI_MASK 0x40
+#define HCI_FEATURE_INQ_RSSI_OFF 3
+#define HCI_LMP_INQ_RSSI_SUPPORTED(x) ((x)[HCI_FEATURE_INQ_RSSI_OFF] & HCI_FEATURE_INQ_RSSI_MASK)
+
+#define HCI_FEATURE_ESCO_EV3_MASK 0x80
+#define HCI_FEATURE_ESCO_EV3_OFF 3
+#define HCI_ESCO_EV3_SUPPORTED(x) ((x)[HCI_FEATURE_ESCO_EV3_OFF] & HCI_FEATURE_ESCO_EV3_MASK)
+
+#define HCI_FEATURE_ESCO_EV4_MASK 0x01
+#define HCI_FEATURE_ESCO_EV4_OFF 4
+#define HCI_ESCO_EV4_SUPPORTED(x) ((x)[HCI_FEATURE_ESCO_EV4_OFF] & HCI_FEATURE_ESCO_EV4_MASK)
+
+#define HCI_FEATURE_ESCO_EV5_MASK 0x02
+#define HCI_FEATURE_ESCO_EV5_OFF 4
+#define HCI_ESCO_EV5_SUPPORTED(x) ((x)[HCI_FEATURE_ESCO_EV5_OFF] & HCI_FEATURE_ESCO_EV5_MASK)
+
+#define HCI_FEATURE_ABSENCE_MASKS_MASK 0x04
+#define HCI_FEATURE_ABSENCE_MASKS_OFF 4
+#define HCI_LMP_ABSENCE_MASKS_SUPPORTED(x) ((x)[HCI_FEATURE_ABSENCE_MASKS_OFF] & HCI_FEATURE_ABSENCE_MASKS_MASK)
+
+#define HCI_FEATURE_AFH_CAP_SLAVE_MASK 0x08
+#define HCI_FEATURE_AFH_CAP_SLAVE_OFF 4
+#define HCI_LMP_AFH_CAP_SLAVE_SUPPORTED(x) ((x)[HCI_FEATURE_AFH_CAP_SLAVE_OFF] & HCI_FEATURE_AFH_CAP_SLAVE_MASK)
+
+#define HCI_FEATURE_AFH_CLASS_SLAVE_MASK 0x10
+#define HCI_FEATURE_AFH_CLASS_SLAVE_OFF 4
+#define HCI_LMP_AFH_CLASS_SLAVE_SUPPORTED(x) ((x)[HCI_FEATURE_AFH_CLASS_SLAVE_OFF] & HCI_FEATURE_AFH_CLASS_SLAVE_MASK)
+
+#if 1
+#define HCI_FEATURE_BREDR_NOT_SPT_MASK 0x20
+#define HCI_FEATURE_BREDR_NOT_SPT_OFF 4
+#define HCI_BREDR_NOT_SPT_SUPPORTED(x) ((x)[HCI_FEATURE_BREDR_NOT_SPT_OFF] & HCI_FEATURE_BREDR_NOT_SPT_MASK)
+
+#define HCI_FEATURE_LE_SPT_MASK 0x40
+#define HCI_FEATURE_LE_SPT_OFF 4
+#define HCI_LE_SPT_SUPPORTED(x) ((x)[HCI_FEATURE_LE_SPT_OFF] & HCI_FEATURE_LE_SPT_MASK)
+#else
+
+#define HCI_FEATURE_ALIAS_AUTH_MASK 0x20
+#define HCI_FEATURE_ALIAS_AUTH_OFF 4
+#define HCI_LMP_ALIAS_AUTH_SUPPORTED(x) ((x)[HCI_FEATURE_ALIAS_AUTH_OFF] & HCI_FEATURE_ALIAS_AUTH_MASK)
+
+#define HCI_FEATURE_ANON_MODE_MASK 0x40
+#define HCI_FEATURE_ANON_MODE_OFF 4
+#define HCI_LMP_ANON_MODE_SUPPORTED(x) ((x)[HCI_FEATURE_ANON_MODE_OFF] & HCI_FEATURE_ANON_MODE_MASK)
+#endif
+
+#define HCI_FEATURE_3_SLOT_EDR_ACL_MASK 0x80
+#define HCI_FEATURE_3_SLOT_EDR_ACL_OFF 4
+#define HCI_3_SLOT_EDR_ACL_SUPPORTED(x) ((x)[HCI_FEATURE_3_SLOT_EDR_ACL_OFF] & HCI_FEATURE_3_SLOT_EDR_ACL_MASK)
+
+#define HCI_FEATURE_5_SLOT_EDR_ACL_MASK 0x01
+#define HCI_FEATURE_5_SLOT_EDR_ACL_OFF 5
+#define HCI_5_SLOT_EDR_ACL_SUPPORTED(x) ((x)[HCI_FEATURE_5_SLOT_EDR_ACL_OFF] & HCI_FEATURE_5_SLOT_EDR_ACL_MASK)
+
+#define HCI_FEATURE_SNIFF_SUB_RATE_MASK 0x02
+#define HCI_FEATURE_SNIFF_SUB_RATE_OFF 5
+#define HCI_SNIFF_SUB_RATE_SUPPORTED(x) ((x)[HCI_FEATURE_SNIFF_SUB_RATE_OFF] & HCI_FEATURE_SNIFF_SUB_RATE_MASK)
+
+#define HCI_FEATURE_ATOMIC_ENCRYPT_MASK 0x04
+#define HCI_FEATURE_ATOMIC_ENCRYPT_OFF 5
+#define HCI_ATOMIC_ENCRYPT_SUPPORTED(x) ((x)[HCI_FEATURE_ATOMIC_ENCRYPT_OFF] & HCI_FEATURE_ATOMIC_ENCRYPT_MASK)
+
+#define HCI_FEATURE_AFH_CAP_MASTR_MASK 0x08
+#define HCI_FEATURE_AFH_CAP_MASTR_OFF 5
+#define HCI_LMP_AFH_CAP_MASTR_SUPPORTED(x) ((x)[HCI_FEATURE_AFH_CAP_MASTR_OFF] & HCI_FEATURE_AFH_CAP_MASTR_MASK)
+
+#define HCI_FEATURE_AFH_CLASS_MASTR_MASK 0x10
+#define HCI_FEATURE_AFH_CLASS_MASTR_OFF 5
+#define HCI_LMP_AFH_CLASS_MASTR_SUPPORTED(x) ((x)[HCI_FEATURE_AFH_CLASS_MASTR_OFF] & HCI_FEATURE_AFH_CLASS_MASTR_MASK)
+
+#define HCI_FEATURE_EDR_ESCO_2MPS_MASK 0x20
+#define HCI_FEATURE_EDR_ESCO_2MPS_OFF 5
+#define HCI_EDR_ESCO_2MPS_SUPPORTED(x) ((x)[HCI_FEATURE_EDR_ESCO_2MPS_OFF] & HCI_FEATURE_EDR_ESCO_2MPS_MASK)
+
+#define HCI_FEATURE_EDR_ESCO_3MPS_MASK 0x40
+#define HCI_FEATURE_EDR_ESCO_3MPS_OFF 5
+#define HCI_EDR_ESCO_3MPS_SUPPORTED(x) ((x)[HCI_FEATURE_EDR_ESCO_3MPS_OFF] & HCI_FEATURE_EDR_ESCO_3MPS_MASK)
+
+#define HCI_FEATURE_3_SLOT_EDR_ESCO_MASK 0x80
+#define HCI_FEATURE_3_SLOT_EDR_ESCO_OFF 5
+#define HCI_3_SLOT_EDR_ESCO_SUPPORTED(x) ((x)[HCI_FEATURE_3_SLOT_EDR_ESCO_OFF] & HCI_FEATURE_3_SLOT_EDR_ESCO_MASK)
+
+#define HCI_FEATURE_EXT_INQ_RSP_MASK 0x01
+#define HCI_FEATURE_EXT_INQ_RSP_OFF 6
+#define HCI_EXT_INQ_RSP_SUPPORTED(x) ((x)[HCI_FEATURE_EXT_INQ_RSP_OFF] & HCI_FEATURE_EXT_INQ_RSP_MASK)
+
+#if 1 /* TOKYO spec definition */
+#define HCI_FEATURE_SIMUL_LE_BREDR_MASK 0x02
+#define HCI_FEATURE_SIMUL_LE_BREDR_OFF 6
+#define HCI_SIMUL_LE_BREDR_SUPPORTED(x) ((x)[HCI_FEATURE_SIMUL_LE_BREDR_OFF] & HCI_FEATURE_SIMUL_LE_BREDR_MASK)
+
+#else
+#define HCI_FEATURE_ANUM_PIN_AWARE_MASK 0x02
+#define HCI_FEATURE_ANUM_PIN_AWARE_OFF 6
+#define HCI_ANUM_PIN_AWARE_SUPPORTED(x) ((x)[HCI_FEATURE_ANUM_PIN_AWARE_OFF] & HCI_FEATURE_ANUM_PIN_AWARE_MASK)
+#endif
+
+#define HCI_FEATURE_ANUM_PIN_CAP_MASK 0x04
+#define HCI_FEATURE_ANUM_PIN_CAP_OFF 6
+#define HCI_ANUM_PIN_CAP_SUPPORTED(x) ((x)[HCI_FEATURE_ANUM_PIN_CAP_OFF] & HCI_FEATURE_ANUM_PIN_CAP_MASK)
+
+#define HCI_FEATURE_SIMPLE_PAIRING_MASK 0x08
+#define HCI_FEATURE_SIMPLE_PAIRING_OFF 6
+#define HCI_SIMPLE_PAIRING_SUPPORTED(x) ((x)[HCI_FEATURE_SIMPLE_PAIRING_OFF] & HCI_FEATURE_SIMPLE_PAIRING_MASK)
+
+#define HCI_FEATURE_ENCAP_PDU_MASK 0x10
+#define HCI_FEATURE_ENCAP_PDU_OFF 6
+#define HCI_ENCAP_PDU_SUPPORTED(x) ((x)[HCI_FEATURE_ENCAP_PDU_OFF] & HCI_FEATURE_ENCAP_PDU_MASK)
+
+#define HCI_FEATURE_ERROR_DATA_MASK 0x20
+#define HCI_FEATURE_ERROR_DATA_OFF 6
+#define HCI_ERROR_DATA_SUPPORTED(x) ((x)[HCI_FEATURE_ERROR_DATA_OFF] & HCI_FEATURE_ERROR_DATA_MASK)
+
+#define HCI_FEATURE_NON_FLUSHABLE_PB_MASK 0x40
+#define HCI_FEATURE_NON_FLUSHABLE_PB_OFF 6
+#define HCI_NON_FLUSHABLE_PB_SUPPORTED(x) ((x)[HCI_FEATURE_NON_FLUSHABLE_PB_OFF] & HCI_FEATURE_NON_FLUSHABLE_PB_MASK)
+
+#define HCI_FEATURE_LINK_SUP_TO_EVT_MASK 0x01
+#define HCI_FEATURE_LINK_SUP_TO_EVT_OFF 7
+#define HCI_LINK_SUP_TO_EVT_SUPPORTED(x) ((x)[HCI_FEATURE_LINK_SUP_TO_EVT_OFF] & HCI_FEATURE_LINK_SUP_TO_EVT_MASK)
+
+#define HCI_FEATURE_INQ_RESP_TX_MASK 0x02
+#define HCI_FEATURE_INQ_RESP_TX_OFF 7
+#define HCI_INQ_RESP_TX_SUPPORTED(x) ((x)[HCI_FEATURE_INQ_RESP_TX_OFF] & HCI_FEATURE_INQ_RESP_TX_MASK)
+
+#define HCI_FEATURE_EXTENDED_MASK 0x80
+#define HCI_FEATURE_EXTENDED_OFF 7
+#define HCI_LMP_EXTENDED_SUPPORTED(x) ((x)[HCI_FEATURE_EXTENDED_OFF] & HCI_FEATURE_EXTENDED_MASK)
+
+/*
+** LMP features encoding - page 1
+*/
+#define HCI_EXT_FEATURE_SSP_HOST_MASK 0x01
+#define HCI_EXT_FEATURE_SSP_HOST_OFF 0
+#define HCI_SSP_HOST_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_SSP_HOST_OFF] & HCI_EXT_FEATURE_SSP_HOST_MASK)
+
+#define HCI_EXT_FEATURE_LE_HOST_MASK 0x02
+#define HCI_EXT_FEATURE_LE_HOST_OFF 0
+#define HCI_LE_HOST_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_LE_HOST_OFF] & HCI_EXT_FEATURE_LE_HOST_MASK)
+
+#define HCI_EXT_FEATURE_SIMUL_DUMO_HOST_MASK 0x04
+#define HCI_EXT_FEATURE_SIMUL_DUMO_HOST_OFF 0
+#define HCI_SIMUL_DUMO_HOST_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_SIMUL_DUMO_HOST_OFF] & HCI_EXT_FEATURE_SIMUL_DUMO_HOST_MASK)
+
+/*
+** LMP features encoding - page 2
+*/
+#define HCI_EXT_FEATURE_CSB_MASTER_MASK 0x01
+#define HCI_EXT_FEATURE_CSB_MASTER_OFF 0
+#define HCI_CSB_MASTER_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_CSB_MASTER_OFF] & HCI_EXT_FEATURE_CSB_MASTER_MASK)
+
+#define HCI_EXT_FEATURE_CSB_SLAVE_MASK 0x02
+#define HCI_EXT_FEATURE_CSB_SLAVE_OFF 0
+#define HCI_CSB_SLAVE_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_CSB_SLAVE_OFF] & HCI_EXT_FEATURE_CSB_SLAVE_MASK)
+
+#define HCI_EXT_FEATURE_SYNC_TRAIN_MASTER_MASK 0x04
+#define HCI_EXT_FEATURE_SYNC_TRAIN_MASTER_OFF 0
+#define HCI_SYNC_TRAIN_MASTER_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_SYNC_TRAIN_MASTER_OFF] & HCI_EXT_FEATURE_SYNC_TRAIN_MASTER_MASK)
+
+#define HCI_EXT_FEATURE_SYNC_SCAN_SLAVE_MASK 0x08
+#define HCI_EXT_FEATURE_SYNC_SCAN_SLAVE_OFF 0
+#define HCI_SYNC_SCAN_SLAVE_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_SYNC_SCAN_SLAVE_OFF] & HCI_EXT_FEATURE_SYNC_SCAN_SLAVE_MASK)
+
+#define HCI_EXT_FEATURE_INQ_RESP_NOTIF_MASK 0x10
+#define HCI_EXT_FEATURE_INQ_RESP_NOTIF_OFF 0
+#define HCI_INQ_RESP_NOTIF_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_INQ_RESP_NOTIF_OFF] & HCI_EXT_FEATURE_INQ_RESP_NOTIF_MASK)
+
+/*
+** LE features encoding - page 0 (the only page for now)
+*/
+#define HCI_LE_FEATURE_LE_ENCRYPTION_MASK 0x01
+#define HCI_LE_FEATURE_LE_ENCRYPTION_OFF 0
+#define HCI_LE_ENCRYPTION_SUPPORTED(x) ((x)[HCI_LE_FEATURE_LE_ENCRYPTION_OFF] & HCI_LE_FEATURE_LE_ENCRYPTION_MASK)
+
+
+/*
+** Local Supported Commands encoding
+*/
+#define HCI_NUM_SUPP_COMMANDS_BYTES 64
+
+/* Supported Commands Byte 0 */
+#define HCI_SUPP_COMMANDS_INQUIRY_MASK 0x01
+#define HCI_SUPP_COMMANDS_INQUIRY_OFF 0
+#define HCI_INQUIRY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_INQUIRY_OFF] & HCI_SUPP_COMMANDS_INQUIRY_MASK)
+
+#define HCI_SUPP_COMMANDS_INQUIRY_CANCEL_MASK 0x02
+#define HCI_SUPP_COMMANDS_INQUIRY_CANCEL_OFF 0
+#define HCI_INQUIRY_CANCEL_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_INQUIRY_CANCEL_OFF] & HCI_SUPP_COMMANDS_INQUIRY_CANCEL_MASK)
+
+#define HCI_SUPP_COMMANDS_PERIODIC_INQUIRY_MASK 0x04
+#define HCI_SUPP_COMMANDS_PERIODIC_INQUIRY_OFF 0
+#define HCI_PERIODIC_INQUIRY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_PERIODIC_INQUIRY_OFF] & HCI_SUPP_COMMANDS_PERIODIC_INQUIRY_MASK)
+
+#define HCI_SUPP_COMMANDS_EXIT_PERIODIC_INQUIRY_MASK 0x08
+#define HCI_SUPP_COMMANDS_EXIT_PERIODIC_INQUIRY_OFF 0
+#define HCI_EXIT_PERIODIC_INQUIRY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_EXIT_PERIODIC_INQUIRY_OFF] & HCI_SUPP_COMMANDS_EXIT_PERIODIC_INQUIRY_MASK)
+
+#define HCI_SUPP_COMMANDS_CREATE_CONN_MASK 0x10
+#define HCI_SUPP_COMMANDS_CREATE_CONN_OFF 0
+#define HCI_CREATE_CONN_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_CREATE_CONN_OFF] & HCI_SUPP_COMMANDS_CREATE_CONN_MASK)
+
+#define HCI_SUPP_COMMANDS_DISCONNECT_MASK 0x20
+#define HCI_SUPP_COMMANDS_DISCONNECT_OFF 0
+#define HCI_DISCONNECT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_DISCONNECT_OFF] & HCI_SUPP_COMMANDS_DISCONNECT_MASK)
+
+#define HCI_SUPP_COMMANDS_ADD_SCO_CONN_MASK 0x40
+#define HCI_SUPP_COMMANDS_ADD_SCO_CONN_OFF 0
+#define HCI_ADD_SCO_CONN_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_ADD_SCO_CONN_OFF] & HCI_SUPP_COMMANDS_ADD_SCO_CONN_MASK)
+
+#define HCI_SUPP_COMMANDS_CANCEL_CREATE_CONN_MASK 0x80
+#define HCI_SUPP_COMMANDS_CANCEL_CREATE_CONN_OFF 0
+#define HCI_CANCEL_CREATE_CONN_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_CANCEL_CREATE_CONN_OFF] & HCI_SUPP_COMMANDS_CANCEL_CREATE_CONN_MASK)
+
+/* Supported Commands Byte 1 */
+#define HCI_SUPP_COMMANDS_ACCEPT_CONN_REQUEST_MASK 0x01
+#define HCI_SUPP_COMMANDS_ACCEPT_CONN_REQUEST_OFF 1
+#define HCI_ACCEPT_CONN_REQUEST_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_ACCEPT_CONN_REQUEST_OFF] & HCI_SUPP_COMMANDS_ACCEPT_CONN_REQUEST_MASK)
+
+#define HCI_SUPP_COMMANDS_REJECT_CONN_REQUEST_MASK 0x02
+#define HCI_SUPP_COMMANDS_REJECT_CONN_REQUEST_OFF 1
+#define HCI_REJECT_CONN_REQUEST_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_REJECT_CONN_REQUEST_OFF] & HCI_SUPP_COMMANDS_REJECT_CONN_REQUEST_MASK)
+
+#define HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_REPLY_MASK 0x04
+#define HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_REPLY_OFF 1
+#define HCI_LINK_KEY_REQUEST_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_REPLY_OFF] & HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_NEG_REPLY_MASK 0x08
+#define HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_NEG_REPLY_OFF 1
+#define HCI_LINK_KEY_REQUEST_NEG_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_NEG_REPLY_OFF] & HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_NEG_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_REPLY_MASK 0x10
+#define HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_REPLY_OFF 1
+#define HCI_PIN_CODE_REQUEST_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_REPLY_OFF] & HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_NEG_REPLY_MASK 0x20
+#define HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_NEG_REPLY_OFF 1
+#define HCI_PIN_CODE_REQUEST_NEG_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_NEG_REPLY_OFF] & HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_NEG_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_CHANGE_CONN_PKT_TYPE_MASK 0x40
+#define HCI_SUPP_COMMANDS_CHANGE_CONN_PKT_TYPE_OFF 1
+#define HCI_CHANGE_CONN_PKT_TYPE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_CHANGE_CONN_PKT_TYPE_OFF] & HCI_SUPP_COMMANDS_CHANGE_CONN_PKT_TYPE_MASK)
+
+#define HCI_SUPP_COMMANDS_AUTH_REQUEST_MASK 0x80
+#define HCI_SUPP_COMMANDS_AUTH_REQUEST_OFF 1
+#define HCI_AUTH_REQUEST_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_AUTH_REQUEST_OFF] & HCI_SUPP_COMMANDS_AUTH_REQUEST_MASK)
+
+/* Supported Commands Byte 2 */
+#define HCI_SUPP_COMMANDS_SET_CONN_ENCRYPTION_MASK 0x01
+#define HCI_SUPP_COMMANDS_SET_CONN_ENCRYPTION_OFF 2
+#define HCI_SET_CONN_ENCRYPTION_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_CONN_ENCRYPTION_OFF] & HCI_SUPP_COMMANDS_SET_CONN_ENCRYPTION_MASK)
+
+#define HCI_SUPP_COMMANDS_CHANGE_CONN_LINK_KEY_MASK 0x02
+#define HCI_SUPP_COMMANDS_CHANGE_CONN_LINK_KEY_OFF 2
+#define HCI_CHANGE_CONN_LINK_KEY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_CHANGE_CONN_LINK_KEY_OFF] & HCI_SUPP_COMMANDS_CHANGE_CONN_LINK_KEY_MASK)
+
+#define HCI_SUPP_COMMANDS_MASTER_LINK_KEY_MASK 0x04
+#define HCI_SUPP_COMMANDS_MASTER_LINK_KEY_OFF 2
+#define HCI_MASTER_LINK_KEY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_MASTER_LINK_KEY_OFF] & HCI_SUPP_COMMANDS_MASTER_LINK_KEY_MASK)
+
+#define HCI_SUPP_COMMANDS_REMOTE_NAME_REQUEST_MASK 0x08
+#define HCI_SUPP_COMMANDS_REMOTE_NAME_REQUEST_OFF 2
+#define HCI_REMOTE_NAME_REQUEST_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_REMOTE_NAME_REQUEST_OFF] & HCI_SUPP_COMMANDS_REMOTE_NAME_REQUEST_MASK)
+
+#define HCI_SUPP_COMMANDS_CANCEL_REMOTE_NAME_REQUEST_MASK 0x10
+#define HCI_SUPP_COMMANDS_CANCEL_REMOTE_NAME_REQUEST_OFF 2
+#define HCI_CANCEL_REMOTE_NAME_REQUEST_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_CANCEL_REMOTE_NAME_REQUEST_OFF] & HCI_SUPP_COMMANDS_CANCEL_REMOTE_NAME_REQUEST_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_REMOTE_SUPP_FEATURES_MASK 0x20
+#define HCI_SUPP_COMMANDS_READ_REMOTE_SUPP_FEATURES_OFF 2
+#define HCI_READ_REMOTE_SUPP_FEATURES_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_REMOTE_SUPP_FEATURES_OFF] & HCI_SUPP_COMMANDS_READ_REMOTE_SUPP_FEATURES_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_REMOTE_EXT_FEATURES_MASK 0x40
+#define HCI_SUPP_COMMANDS_READ_REMOTE_EXT_FEATURES_OFF 2
+#define HCI_READ_REMOTE_EXT_FEATURES_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_REMOTE_EXT_FEATURES_OFF] & HCI_SUPP_COMMANDS_READ_REMOTE_EXT_FEATURES_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_REMOTE_VER_INFO_MASK 0x80
+#define HCI_SUPP_COMMANDS_READ_REMOTE_VER_INFO_OFF 2
+#define HCI_READ_REMOTE_VER_INFO_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_REMOTE_VER_INFO_OFF] & HCI_SUPP_COMMANDS_READ_REMOTE_VER_INFO_MASK)
+
+/* Supported Commands Byte 3, bits 2-7 reserved */
+#define HCI_SUPP_COMMANDS_READ_CLOCK_OFFSET_MASK 0x01
+#define HCI_SUPP_COMMANDS_READ_CLOCK_OFFSET_OFF 3
+#define HCI_READ_CLOCK_OFFSET_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_CLOCK_OFFSET_OFF] & HCI_SUPP_COMMANDS_READ_CLOCK_OFFSET_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LMP_HANDLE_MASK 0x02
+#define HCI_SUPP_COMMANDS_READ_LMP_HANDLE_OFF 3
+#define HCI_READ_LMP_HANDLE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LMP_HANDLE_OFF] & HCI_SUPP_COMMANDS_READ_LMP_HANDLE_MASK)
+
+/* Supported Commands Byte 4, bit 0 reserved */
+#define HCI_SUPP_COMMANDS_HOLD_MODE_CMD_MASK 0x02
+#define HCI_SUPP_COMMANDS_HOLD_MODE_CMD_OFF 4
+#define HCI_HOLD_MODE_CMD_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_HOLD_MODE_CMD_OFF] & HCI_SUPP_COMMANDS_HOLD_MODE_CMD_MASK)
+
+#define HCI_SUPP_COMMANDS_SNIFF_MODE_CMD_MASK 0x04
+#define HCI_SUPP_COMMANDS_SNIFF_MODE_CMD_OFF 4
+#define HCI_SNIFF_MODE_CMD_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SNIFF_MODE_CMD_OFF] & HCI_SUPP_COMMANDS_SNIFF_MODE_CMD_MASK)
+
+#define HCI_SUPP_COMMANDS_EXIT_SNIFF_MODE_MASK 0x08
+#define HCI_SUPP_COMMANDS_EXIT_SNIFF_MODE_OFF 4
+#define HCI_EXIT_SNIFF_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_EXIT_SNIFF_MODE_OFF] & HCI_SUPP_COMMANDS_EXIT_SNIFF_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_PARK_STATE_MASK 0x10
+#define HCI_SUPP_COMMANDS_PARK_STATE_OFF 4
+#define HCI_PARK_STATE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_PARK_STATE_OFF] & HCI_SUPP_COMMANDS_PARK_STATE_MASK)
+
+#define HCI_SUPP_COMMANDS_EXIT_PARK_STATE_MASK 0x20
+#define HCI_SUPP_COMMANDS_EXIT_PARK_STATE_OFF 4
+#define HCI_EXIT_PARK_STATE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_EXIT_PARK_STATE_OFF] & HCI_SUPP_COMMANDS_EXIT_PARK_STATE_MASK)
+
+#define HCI_SUPP_COMMANDS_QOS_SETUP_MASK 0x40
+#define HCI_SUPP_COMMANDS_QOS_SETUP_OFF 4
+#define HCI_QOS_SETUP_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_QOS_SETUP_OFF] & HCI_SUPP_COMMANDS_QOS_SETUP_MASK)
+
+#define HCI_SUPP_COMMANDS_ROLE_DISCOVERY_MASK 0x80
+#define HCI_SUPP_COMMANDS_ROLE_DISCOVERY_OFF 4
+#define HCI_ROLE_DISCOVERY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_ROLE_DISCOVERY_OFF] & HCI_SUPP_COMMANDS_ROLE_DISCOVERY_MASK)
+
+/* Supported Commands Byte 5 */
+#define HCI_SUPP_COMMANDS_SWITCH_ROLE_MASK 0x01
+#define HCI_SUPP_COMMANDS_SWITCH_ROLE_OFF 5
+#define HCI_SWITCH_ROLE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SWITCH_ROLE_OFF] & HCI_SUPP_COMMANDS_SWITCH_ROLE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LINK_POLICY_SET_MASK 0x02
+#define HCI_SUPP_COMMANDS_READ_LINK_POLICY_SET_OFF 5
+#define HCI_READ_LINK_POLICY_SET_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LINK_POLICY_SET_OFF] & HCI_SUPP_COMMANDS_READ_LINK_POLICY_SET_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_LINK_POLICY_SET_MASK 0x04
+#define HCI_SUPP_COMMANDS_WRITE_LINK_POLICY_SET_OFF 5
+#define HCI_WRITE_LINK_POLICY_SET_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_LINK_POLICY_SET_OFF] & HCI_SUPP_COMMANDS_WRITE_LINK_POLICY_SET_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_DEF_LINK_POLICY_SET_MASK 0x08
+#define HCI_SUPP_COMMANDS_READ_DEF_LINK_POLICY_SET_OFF 5
+#define HCI_READ_DEF_LINK_POLICY_SET_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_DEF_LINK_POLICY_SET_OFF] & HCI_SUPP_COMMANDS_READ_DEF_LINK_POLICY_SET_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_DEF_LINK_POLICY_SET_MASK 0x10
+#define HCI_SUPP_COMMANDS_WRITE_DEF_LINK_POLICY_SET_OFF 5
+#define HCI_WRITE_DEF_LINK_POLICY_SET_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_DEF_LINK_POLICY_SET_OFF] & HCI_SUPP_COMMANDS_WRITE_DEF_LINK_POLICY_SET_MASK)
+
+#define HCI_SUPP_COMMANDS_FLOW_SPECIFICATION_MASK 0x20
+#define HCI_SUPP_COMMANDS_FLOW_SPECIFICATION_OFF 5
+#define HCI_FLOW_SPECIFICATION_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_FLOW_SPECIFICATION_OFF] & HCI_SUPP_COMMANDS_FLOW_SPECIFICATION_MASK)
+
+#define HCI_SUPP_COMMANDS_SET_EVENT_MASK_MASK 0x40
+#define HCI_SUPP_COMMANDS_SET_EVENT_MASK_OFF 5
+#define HCI_SET_EVENT_MASK_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_EVENT_MASK_OFF] & HCI_SUPP_COMMANDS_SET_EVENT_MASK_MASK)
+
+#define HCI_SUPP_COMMANDS_RESET_MASK 0x80
+#define HCI_SUPP_COMMANDS_RESET_OFF 5
+#define HCI_RESET_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_RESET_OFF] & HCI_SUPP_COMMANDS_RESET_MASK)
+
+/* Supported Commands Byte 6 */
+#define HCI_SUPP_COMMANDS_SET_EVENT_FILTER_MASK 0x01
+#define HCI_SUPP_COMMANDS_SET_EVENT_FILTER_OFF 6
+#define HCI_SET_EVENT_FILTER_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_EVENT_FILTER_OFF] & HCI_SUPP_COMMANDS_SET_EVENT_FILTER_MASK)
+
+#define HCI_SUPP_COMMANDS_FLUSH_MASK 0x02
+#define HCI_SUPP_COMMANDS_FLUSH_OFF 6
+#define HCI_FLUSH_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_FLUSH_OFF] & HCI_SUPP_COMMANDS_FLUSH_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_PIN_TYPE_MASK 0x04
+#define HCI_SUPP_COMMANDS_READ_PIN_TYPE_OFF 6
+#define HCI_READ_PIN_TYPE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_PIN_TYPE_OFF] & HCI_SUPP_COMMANDS_READ_PIN_TYPE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_PIN_TYPE_MASK 0x08
+#define HCI_SUPP_COMMANDS_WRITE_PIN_TYPE_OFF 6
+#define HCI_WRITE_PIN_TYPE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_PIN_TYPE_OFF] & HCI_SUPP_COMMANDS_WRITE_PIN_TYPE_MASK)
+
+#define HCI_SUPP_COMMANDS_CREATE_NEW_UNIT_KEY_MASK 0x10
+#define HCI_SUPP_COMMANDS_CREATE_NEW_UNIT_KEY_OFF 6
+#define HCI_CREATE_NEW_UNIT_KEY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_CREATE_NEW_UNIT_KEY_OFF] & HCI_SUPP_COMMANDS_CREATE_NEW_UNIT_KEY_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_STORED_LINK_KEY_MASK 0x20
+#define HCI_SUPP_COMMANDS_READ_STORED_LINK_KEY_OFF 6
+#define HCI_READ_STORED_LINK_KEY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_STORED_LINK_KEY_OFF] & HCI_SUPP_COMMANDS_READ_STORED_LINK_KEY_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_STORED_LINK_KEY_MASK 0x40
+#define HCI_SUPP_COMMANDS_WRITE_STORED_LINK_KEY_OFF 6
+#define HCI_WRITE_STORED_LINK_KEY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_STORED_LINK_KEY_OFF] & HCI_SUPP_COMMANDS_WRITE_STORED_LINK_KEY_MASK)
+
+#define HCI_SUPP_COMMANDS_DELETE_STORED_LINK_KEY_MASK 0x80
+#define HCI_SUPP_COMMANDS_DELETE_STORED_LINK_KEY_OFF 6
+#define HCI_DELETE_STORED_LINK_KEY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_DELETE_STORED_LINK_KEY_OFF] & HCI_SUPP_COMMANDS_DELETE_STORED_LINK_KEY_MASK)
+
+/* Supported Commands Byte 7 */
+#define HCI_SUPP_COMMANDS_WRITE_LOCAL_NAME_MASK 0x01
+#define HCI_SUPP_COMMANDS_WRITE_LOCAL_NAME_OFF 7
+#define HCI_WRITE_LOCAL_NAME_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_LOCAL_NAME_OFF] & HCI_SUPP_COMMANDS_WRITE_LOCAL_NAME_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCAL_NAME_MASK 0x02
+#define HCI_SUPP_COMMANDS_READ_LOCAL_NAME_OFF 7
+#define HCI_READ_LOCAL_NAME_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_NAME_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_NAME_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_CONN_ACCEPT_TOUT_MASK 0x04
+#define HCI_SUPP_COMMANDS_READ_CONN_ACCEPT_TOUT_OFF 7
+#define HCI_READ_CONN_ACCEPT_TOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_CONN_ACCEPT_TOUT_OFF] & HCI_SUPP_COMMANDS_READ_CONN_ACCEPT_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_CONN_ACCEPT_TOUT_MASK 0x08
+#define HCI_SUPP_COMMANDS_WRITE_CONN_ACCEPT_TOUT_OFF 7
+#define HCI_WRITE_CONN_ACCEPT_TOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_CONN_ACCEPT_TOUT_OFF] & HCI_SUPP_COMMANDS_WRITE_CONN_ACCEPT_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_PAGE_TOUT_MASK 0x10
+#define HCI_SUPP_COMMANDS_READ_PAGE_TOUT_OFF 7
+#define HCI_READ_PAGE_TOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_PAGE_TOUT_OFF] & HCI_SUPP_COMMANDS_READ_PAGE_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_TOUT_MASK 0x20
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_TOUT_OFF 7
+#define HCI_WRITE_PAGE_TOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_PAGE_TOUT_OFF] & HCI_SUPP_COMMANDS_WRITE_PAGE_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_SCAN_ENABLE_MASK 0x40
+#define HCI_SUPP_COMMANDS_READ_SCAN_ENABLE_OFF 7
+#define HCI_READ_SCAN_ENABLE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_SCAN_ENABLE_OFF] & HCI_SUPP_COMMANDS_READ_SCAN_ENABLE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_SCAN_ENABLE_MASK 0x80
+#define HCI_SUPP_COMMANDS_WRITE_SCAN_ENABLE_OFF 7
+#define HCI_WRITE_SCAN_ENABLE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_SCAN_ENABLE_OFF] & HCI_SUPP_COMMANDS_WRITE_SCAN_ENABLE_MASK)
+
+/* Supported Commands Byte 8, bits 4-5 are reserved in the specs but are successfully used in our host/controller */
+#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_ACTIVITY_MASK 0x01
+#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_ACTIVITY_OFF 8
+#define HCI_READ_PAGE_SCAN_ACTIVITY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_PAGE_SCAN_ACTIVITY_OFF] & HCI_SUPP_COMMANDS_READ_PAGE_SCAN_ACTIVITY_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_ACTIVITY_MASK 0x02
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_ACTIVITY_OFF 8
+#define HCI_WRITE_PAGE_SCAN_ACTIVITY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_ACTIVITY_OFF] & HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_ACTIVITY_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_INQURIY_SCAN_ACTIVITY_MASK 0x04
+#define HCI_SUPP_COMMANDS_READ_INQURIY_SCAN_ACTIVITY_OFF 8
+#define HCI_READ_INQURIY_SCAN_ACTIVITY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_INQURIY_SCAN_ACTIVITY_OFF] & HCI_SUPP_COMMANDS_READ_INQURIY_SCAN_ACTIVITY_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_INQURIY_SCAN_ACTIVITY_MASK 0x08
+#define HCI_SUPP_COMMANDS_WRITE_INQURIY_SCAN_ACTIVITY_OFF 8
+#define HCI_WRITE_INQURIY_SCAN_ACTIVITY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_INQURIY_SCAN_ACTIVITY_OFF] & HCI_SUPP_COMMANDS_WRITE_INQURIY_SCAN_ACTIVITY_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_AUTH_ENABLE_MASK 0x10
+#define HCI_SUPP_COMMANDS_READ_AUTH_ENABLE_OFF 8
+#define HCI_READ_AUTH_ENABLE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_AUTH_ENABLE_OFF] & HCI_SUPP_COMMANDS_READ_AUTH_ENABLE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_AUTH_ENABLE_MASK 0x20
+#define HCI_SUPP_COMMANDS_WRITE_AUTH_ENABLE_OFF 8
+#define HCI_WRITE_AUTH_ENABLE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_AUTH_ENABLE_OFF] & HCI_SUPP_COMMANDS_WRITE_AUTH_ENABLE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_ENCRYPT_ENABLE_MASK 0x40
+#define HCI_SUPP_COMMANDS_READ_ENCRYPT_ENABLE_OFF 8
+#define HCI_READ_ENCRYPT_ENABLE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_ENCRYPT_ENABLE_OFF] & HCI_SUPP_COMMANDS_READ_ENCRYPT_ENABLE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_ENCRYPT_ENABLE_MASK 0x80
+#define HCI_SUPP_COMMANDS_WRITE_ENCRYPT_ENABLE_OFF 8
+#define HCI_WRITE_ENCRYPT_ENABLE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_ENCRYPT_ENABLE_OFF] & HCI_SUPP_COMMANDS_WRITE_ENCRYPT_ENABLE_MASK)
+
+/* Supported Commands Byte 9 */
+#define HCI_SUPP_COMMANDS_READ_CLASS_DEVICE_MASK 0x01
+#define HCI_SUPP_COMMANDS_READ_CLASS_DEVICE_OFF 9
+#define HCI_READ_CLASS_DEVICE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_CLASS_DEVICE_OFF] & HCI_SUPP_COMMANDS_READ_CLASS_DEVICE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_CLASS_DEVICE_MASK 0x02
+#define HCI_SUPP_COMMANDS_WRITE_CLASS_DEVICE_OFF 9
+#define HCI_WRITE_CLASS_DEVICE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_CLASS_DEVICE_OFF] & HCI_SUPP_COMMANDS_WRITE_CLASS_DEVICE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_VOICE_SETTING_MASK 0x04
+#define HCI_SUPP_COMMANDS_READ_VOICE_SETTING_OFF 9
+#define HCI_READ_VOICE_SETTING_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_VOICE_SETTING_OFF] & HCI_SUPP_COMMANDS_READ_VOICE_SETTING_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_VOICE_SETTING_MASK 0x08
+#define HCI_SUPP_COMMANDS_WRITE_VOICE_SETTING_OFF 9
+#define HCI_WRITE_VOICE_SETTING_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_VOICE_SETTING_OFF] & HCI_SUPP_COMMANDS_WRITE_VOICE_SETTING_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_AUTO_FLUSH_TOUT_MASK 0x10
+#define HCI_SUPP_COMMANDS_READ_AUTO_FLUSH_TOUT_OFF 9
+#define HCI_READ_AUTO_FLUSH_TOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_AUTO_FLUSH_TOUT_OFF] & HCI_SUPP_COMMANDS_READ_AUTO_FLUSH_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_AUTO_FLUSH_TOUT_MASK 0x20
+#define HCI_SUPP_COMMANDS_WRITE_AUTO_FLUSH_TOUT_OFF 9
+#define HCI_WRITE_AUTO_FLUSH_TOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_AUTO_FLUSH_TOUT_OFF] & HCI_SUPP_COMMANDS_WRITE_AUTO_FLUSH_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_NUM_BROAD_RETRANS_MASK 0x40
+#define HCI_SUPP_COMMANDS_READ_NUM_BROAD_RETRANS_OFF 9
+#define HCI_READ_NUM_BROAD_RETRANS_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_NUM_BROAD_RETRANS_OFF] & HCI_SUPP_COMMANDS_READ_NUM_BROAD_RETRANS_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_NUM_BROAD_RETRANS_MASK 0x80
+#define HCI_SUPP_COMMANDS_WRITE_NUM_BROAD_RETRANS_OFF 9
+#define HCI_WRITE_NUM_BROAD_RETRANS_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_NUM_BROAD_RETRANS_OFF] & HCI_SUPP_COMMANDS_WRITE_NUM_BROAD_RETRANS_MASK)
+
+/* Supported Commands Byte 10 */
+#define HCI_SUPP_COMMANDS_READ_HOLD_MODE_ACTIVITY_MASK 0x01
+#define HCI_SUPP_COMMANDS_READ_HOLD_MODE_ACTIVITY_OFF 10
+#define HCI_READ_HOLD_MODE_ACTIVITY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_HOLD_MODE_ACTIVITY_OFF] & HCI_SUPP_COMMANDS_READ_HOLD_MODE_ACTIVITY_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_HOLD_MODE_ACTIVITY_MASK 0x02
+#define HCI_SUPP_COMMANDS_WRITE_HOLD_MODE_ACTIVITY_OFF 10
+#define HCI_WRITE_HOLD_MODE_ACTIVITY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_HOLD_MODE_ACTIVITY_OFF] & HCI_SUPP_COMMANDS_WRITE_HOLD_MODE_ACTIVITY_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_TRANS_PWR_LEVEL_MASK 0x04
+#define HCI_SUPP_COMMANDS_READ_TRANS_PWR_LEVEL_OFF 10
+#define HCI_READ_TRANS_PWR_LEVEL_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_TRANS_PWR_LEVEL_OFF] & HCI_SUPP_COMMANDS_READ_TRANS_PWR_LEVEL_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_SYNCH_FLOW_CTRL_ENABLE_MASK 0x08
+#define HCI_SUPP_COMMANDS_READ_SYNCH_FLOW_CTRL_ENABLE_OFF 10
+#define HCI_READ_SYNCH_FLOW_CTRL_ENABLE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_SYNCH_FLOW_CTRL_ENABLE_OFF] & HCI_SUPP_COMMANDS_READ_SYNCH_FLOW_CTRL_ENABLE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_SYNCH_FLOW_CTRL_ENABLE_MASK 0x10
+#define HCI_SUPP_COMMANDS_WRITE_SYNCH_FLOW_CTRL_ENABLE_OFF 10
+#define HCI_WRITE_SYNCH_FLOW_CTRL_ENABLE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_SYNCH_FLOW_CTRL_ENABLE_OFF] & HCI_SUPP_COMMANDS_WRITE_SYNCH_FLOW_CTRL_ENABLE_MASK)
+
+#define HCI_SUPP_COMMANDS_SET_HOST_CTRLR_TO_HOST_FC_MASK 0x20
+#define HCI_SUPP_COMMANDS_SET_HOST_CTRLR_TO_HOST_FC_OFF 10
+#define HCI_SET_HOST_CTRLR_TO_HOST_FC_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_HOST_CTRLR_TO_HOST_FC_OFF] & HCI_SUPP_COMMANDS_SET_HOST_CTRLR_TO_HOST_FC_MASK)
+
+#define HCI_SUPP_COMMANDS_HOST_BUFFER_SIZE_MASK 0x40
+#define HCI_SUPP_COMMANDS_HOST_BUFFER_SIZE_OFF 10
+#define HCI_HOST_BUFFER_SIZE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_HOST_BUFFER_SIZE_OFF] & HCI_SUPP_COMMANDS_HOST_BUFFER_SIZE_MASK)
+
+#define HCI_SUPP_COMMANDS_HOST_NUM_COMPLETED_PKTS_MASK 0x80
+#define HCI_SUPP_COMMANDS_HOST_NUM_COMPLETED_PKTS_OFF 10
+#define HCI_HOST_NUM_COMPLETED_PKTS_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_HOST_NUM_COMPLETED_PKTS_OFF] & HCI_SUPP_COMMANDS_HOST_NUM_COMPLETED_PKTS_MASK)
+
+/* Supported Commands Byte 11 */
+#define HCI_SUPP_COMMANDS_READ_LINK_SUP_TOUT_MASK 0x01
+#define HCI_SUPP_COMMANDS_READ_LINK_SUP_TOUT_OFF 11
+#define HCI_READ_LINK_SUP_TOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LINK_SUP_TOUT_OFF] & HCI_SUPP_COMMANDS_READ_LINK_SUP_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_LINK_SUP_TOUT_MASK 0x02
+#define HCI_SUPP_COMMANDS_WRITE_LINK_SUP_TOUT_OFF 11
+#define HCI_WRITE_LINK_SUP_TOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_LINK_SUP_TOUT_OFF] & HCI_SUPP_COMMANDS_WRITE_LINK_SUP_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_NUM_SUPP_IAC_MASK 0x04
+#define HCI_SUPP_COMMANDS_READ_NUM_SUPP_IAC_OFF 11
+#define HCI_READ_NUM_SUPP_IAC_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_NUM_SUPP_IAC_OFF] & HCI_SUPP_COMMANDS_READ_NUM_SUPP_IAC_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_CURRENT_IAC_LAP_MASK 0x08
+#define HCI_SUPP_COMMANDS_READ_CURRENT_IAC_LAP_OFF 11
+#define HCI_READ_CURRENT_IAC_LAP_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_CURRENT_IAC_LAP_OFF] & HCI_SUPP_COMMANDS_READ_CURRENT_IAC_LAP_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_CURRENT_IAC_LAP_MASK 0x10
+#define HCI_SUPP_COMMANDS_WRITE_CURRENT_IAC_LAP_OFF 11
+#define HCI_WRITE_CURRENT_IAC_LAP_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_CURRENT_IAC_LAP_OFF] & HCI_SUPP_COMMANDS_WRITE_CURRENT_IAC_LAP_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_PER_MODE_MASK 0x20
+#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_PER_MODE_OFF 11
+#define HCI_READ_PAGE_SCAN_PER_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_PAGE_SCAN_PER_MODE_OFF] & HCI_SUPP_COMMANDS_READ_PAGE_SCAN_PER_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_PER_MODE_MASK 0x40
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_PER_MODE_OFF 11
+#define HCI_WRITE_PAGE_SCAN_PER_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_PER_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_PER_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_MODE_MASK 0x80
+#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_MODE_OFF 11
+#define HCI_READ_PAGE_SCAN_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_PAGE_SCAN_MODE_OFF] & HCI_SUPP_COMMANDS_READ_PAGE_SCAN_MODE_MASK)
+
+/* Supported Commands Byte 12, bits 2-3 reserved */
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_MODE_MASK 0x01
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_MODE_OFF 12
+#define HCI_WRITE_PAGE_SCAN_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_SET_AFH_CHNL_CLASS_MASK 0x02
+#define HCI_SUPP_COMMANDS_SET_AFH_CHNL_CLASS_OFF 12
+#define HCI_SET_AFH_CHNL_CLASS_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_AFH_CHNL_CLASS_OFF] & HCI_SUPP_COMMANDS_SET_AFH_CHNL_CLASS_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_INQUIRY_SCAN_TYPE_MASK 0x10
+#define HCI_SUPP_COMMANDS_READ_INQUIRY_SCAN_TYPE_OFF 12
+#define HCI_READ_INQUIRY_SCAN_TYPE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_INQUIRY_SCAN_TYPE_OFF] & HCI_SUPP_COMMANDS_READ_INQUIRY_SCAN_TYPE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_SCAN_TYPE_MASK 0x20
+#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_SCAN_TYPE_OFF 12
+#define HCI_WRITE_INQUIRY_SCAN_TYPE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_INQUIRY_SCAN_TYPE_OFF] & HCI_SUPP_COMMANDS_WRITE_INQUIRY_SCAN_TYPE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_INQUIRY_MODE_MASK 0x40
+#define HCI_SUPP_COMMANDS_READ_INQUIRY_MODE_OFF 12
+#define HCI_READ_INQUIRY_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_INQUIRY_MODE_OFF] & HCI_SUPP_COMMANDS_READ_INQUIRY_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_MODE_MASK 0x80
+#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_MODE_OFF 12
+#define HCI_WRITE_INQUIRY_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_INQUIRY_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_INQUIRY_MODE_MASK)
+
+/* Supported Commands Byte 13, bits 4-7 reserved */
+#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_TYPE_MASK 0x01
+#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_TYPE_OFF 13
+#define HCI_READ_PAGE_SCAN_TYPE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_PAGE_SCAN_TYPE_OFF] & HCI_SUPP_COMMANDS_READ_PAGE_SCAN_TYPE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_TYPE_MASK 0x02
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_TYPE_OFF 13
+#define HCI_WRITE_PAGE_SCAN_TYPE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_TYPE_OFF] & HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_TYPE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_AFH_CHNL_ASSESS_MODE_MASK 0x04
+#define HCI_SUPP_COMMANDS_READ_AFH_CHNL_ASSESS_MODE_OFF 13
+#define HCI_READ_AFH_CHNL_ASSESS_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_AFH_CHNL_ASSESS_MODE_OFF] & HCI_SUPP_COMMANDS_READ_AFH_CHNL_ASSESS_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_AFH_CHNL_ASSESS_MODE_MASK 0x08
+#define HCI_SUPP_COMMANDS_WRITE_AFH_CHNL_ASSESS_MODE_OFF 13
+#define HCI_WRITE_AFH_CHNL_ASSESS_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_AFH_CHNL_ASSESS_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_AFH_CHNL_ASSESS_MODE_MASK)
+
+/* Supported Commands Byte 14, bits 0-2 and 4 reserved */
+#define HCI_SUPP_COMMANDS_READ_LOCAL_VER_INFO_MASK 0x08
+#define HCI_SUPP_COMMANDS_READ_LOCAL_VER_INFO_OFF 14
+#define HCI_READ_LOCAL_VER_INFO_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_VER_INFO_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_VER_INFO_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCAL_SUP_CMDS_MASK 0x10
+#define HCI_SUPP_COMMANDS_READ_LOCAL_SUP_CMDS_OFF 14
+#define HCI_READ_LOCAL_SUP_CMDS_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_SUP_CMDS_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_SUP_CMDS_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCAL_SUPP_FEATURES_MASK 0x20
+#define HCI_SUPP_COMMANDS_READ_LOCAL_SUPP_FEATURES_OFF 14
+#define HCI_READ_LOCAL_SUPP_FEATURES_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_SUPP_FEATURES_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_SUPP_FEATURES_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCAL_EXT_FEATURES_MASK 0x40
+#define HCI_SUPP_COMMANDS_READ_LOCAL_EXT_FEATURES_OFF 14
+#define HCI_READ_LOCAL_EXT_FEATURES_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_EXT_FEATURES_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_EXT_FEATURES_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_BUFFER_SIZE_MASK 0x80
+#define HCI_SUPP_COMMANDS_READ_BUFFER_SIZE_OFF 14
+#define HCI_READ_BUFFER_SIZE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_BUFFER_SIZE_OFF] & HCI_SUPP_COMMANDS_READ_BUFFER_SIZE_MASK)
+
+/* Supported Commands Byte 15 */
+#define HCI_SUPP_COMMANDS_READ_COUNTRY_CODE_MASK 0x01
+#define HCI_SUPP_COMMANDS_READ_COUNTRY_CODE_OFF 15
+#define HCI_READ_COUNTRY_CODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_COUNTRY_CODE_OFF] & HCI_SUPP_COMMANDS_READ_COUNTRY_CODE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_BD_ADDR_MASK 0x02
+#define HCI_SUPP_COMMANDS_READ_BD_ADDR_OFF 15
+#define HCI_READ_BD_ADDR_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_BD_ADDR_OFF] & HCI_SUPP_COMMANDS_READ_BD_ADDR_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_FAIL_CONTACT_CNTR_MASK 0x04
+#define HCI_SUPP_COMMANDS_READ_FAIL_CONTACT_CNTR_OFF 15
+#define HCI_READ_FAIL_CONTACT_CNTR_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_FAIL_CONTACT_CNTR_OFF] & HCI_SUPP_COMMANDS_READ_FAIL_CONTACT_CNTR_MASK)
+
+#define HCI_SUPP_COMMANDS_RESET_FAIL_CONTACT_CNTR_MASK 0x08
+#define HCI_SUPP_COMMANDS_RESET_FAIL_CONTACT_CNTR_OFF 15
+#define HCI_RESET_FAIL_CONTACT_CNTR_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_RESET_FAIL_CONTACT_CNTR_OFF] & HCI_SUPP_COMMANDS_RESET_FAIL_CONTACT_CNTR_MASK)
+
+#define HCI_SUPP_COMMANDS_GET_LINK_QUALITY_MASK 0x10
+#define HCI_SUPP_COMMANDS_GET_LINK_QUALITY_OFF 15
+#define HCI_GET_LINK_QUALITY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_GET_LINK_QUALITY_OFF] & HCI_SUPP_COMMANDS_GET_LINK_QUALITY_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_RSSI_MASK 0x20
+#define HCI_SUPP_COMMANDS_READ_RSSI_OFF 15
+#define HCI_READ_RSSI_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_RSSI_OFF] & HCI_SUPP_COMMANDS_READ_RSSI_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_AFH_CH_MAP_MASK 0x40
+#define HCI_SUPP_COMMANDS_READ_AFH_CH_MAP_OFF 15
+#define HCI_READ_AFH_CH_MAP_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_AFH_CH_MAP_OFF] & HCI_SUPP_COMMANDS_READ_AFH_CH_MAP_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_BD_CLOCK_MASK 0x80
+#define HCI_SUPP_COMMANDS_READ_BD_CLOCK_OFF 15
+#define HCI_READ_BD_CLOCK_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_BD_CLOCK_OFF] & HCI_SUPP_COMMANDS_READ_BD_CLOCK_MASK)
+
+/* Supported Commands Byte 16, bits 6-7 reserved */
+#define HCI_SUPP_COMMANDS_READ_LOOPBACK_MODE_MASK 0x01
+#define HCI_SUPP_COMMANDS_READ_LOOPBACK_MODE_OFF 16
+#define HCI_READ_LOOPBACK_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LOOPBACK_MODE_OFF] & HCI_SUPP_COMMANDS_READ_LOOPBACK_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_LOOPBACK_MODE_MASK 0x02
+#define HCI_SUPP_COMMANDS_WRITE_LOOPBACK_MODE_OFF 16
+#define HCI_WRITE_LOOPBACK_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_LOOPBACK_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_LOOPBACK_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_ENABLE_DEV_UNDER_TEST_MASK 0x04
+#define HCI_SUPP_COMMANDS_ENABLE_DEV_UNDER_TEST_OFF 16
+#define HCI_ENABLE_DEV_UNDER_TEST_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_ENABLE_DEV_UNDER_TEST_OFF] & HCI_SUPP_COMMANDS_ENABLE_DEV_UNDER_TEST_MASK)
+
+#define HCI_SUPP_COMMANDS_SETUP_SYNCH_CONN_MASK 0x08
+#define HCI_SUPP_COMMANDS_SETUP_SYNCH_CONN_OFF 16
+#define HCI_SETUP_SYNCH_CONN_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SETUP_SYNCH_CONN_OFF] & HCI_SUPP_COMMANDS_SETUP_SYNCH_CONN_MASK)
+
+#define HCI_SUPP_COMMANDS_ACCEPT_SYNCH_CONN_MASK 0x10
+#define HCI_SUPP_COMMANDS_ACCEPT_SYNCH_CONN_OFF 16
+#define HCI_ACCEPT_SYNCH_CONN_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_ACCEPT_SYNCH_CONN_OFF] & HCI_SUPP_COMMANDS_ACCEPT_SYNCH_CONN_MASK)
+
+#define HCI_SUPP_COMMANDS_REJECT_SYNCH_CONN_MASK 0x20
+#define HCI_SUPP_COMMANDS_REJECT_SYNCH_CONN_OFF 16
+#define HCI_REJECT_SYNCH_CONN_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_REJECT_SYNCH_CONN_OFF] & HCI_SUPP_COMMANDS_REJECT_SYNCH_CONN_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_EXT_INQUIRY_RESP_MASK 0x01
+#define HCI_SUPP_COMMANDS_READ_EXT_INQUIRY_RESP_OFF 17
+#define HCI_READ_EXT_INQUIRY_RESP_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_EXT_INQUIRY_RESP_OFF] & HCI_SUPP_COMMANDS_READ_EXT_INQUIRY_RESP_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_EXT_INQUIRY_RESP_MASK 0x02
+#define HCI_SUPP_COMMANDS_WRITE_EXT_INQUIRY_RESP_OFF 17
+#define HCI_WRITE_EXT_INQUIRY_RESP_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_EXT_INQUIRY_RESP_OFF] & HCI_SUPP_COMMANDS_WRITE_EXT_INQUIRY_RESP_MASK)
+
+#define HCI_SUPP_COMMANDS_REFRESH_ENCRYPTION_KEY_MASK 0x04
+#define HCI_SUPP_COMMANDS_REFRESH_ENCRYPTION_KEY_OFF 17
+#define HCI_REFRESH_ENCRYPTION_KEY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_REFRESH_ENCRYPTION_KEY_OFF] & HCI_SUPP_COMMANDS_REFRESH_ENCRYPTION_KEY_MASK)
+
+/* Supported Commands Byte 17, bit 3 reserved */
+#define HCI_SUPP_COMMANDS_SNIFF_SUB_RATE_MASK 0x10
+#define HCI_SUPP_COMMANDS_SNIFF_SUB_RATE_OFF 17
+#define HCI_SNIFF_SUB_RATE_CMD_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SNIFF_SUB_RATE_OFF] & HCI_SUPP_COMMANDS_SNIFF_SUB_RATE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_SIMPLE_PAIRING_MODE_MASK 0x20
+#define HCI_SUPP_COMMANDS_READ_SIMPLE_PAIRING_MODE_OFF 17
+#define HCI_READ_SIMPLE_PAIRING_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_SIMPLE_PAIRING_MODE_OFF] & HCI_SUPP_COMMANDS_READ_SIMPLE_PAIRING_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_MODE_MASK 0x40
+#define HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_MODE_OFF 17
+#define HCI_WRITE_SIMPLE_PAIRING_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCAL_OOB_DATA_MASK 0x80
+#define HCI_SUPP_COMMANDS_READ_LOCAL_OOB_DATA_OFF 17
+#define HCI_READ_LOCAL_OOB_DATA_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_OOB_DATA_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_OOB_DATA_MASK)
+
+/* Supported Commands Byte 18, bits 4-7 reserved */
+#define HCI_SUPP_COMMANDS_READ_INQUIRY_RESPONSE_TX_POWER_MASK 0x01
+#define HCI_SUPP_COMMANDS_READ_INQUIRY_RESPONSE_TX_POWER_OFF 18
+#define HCI_READ_INQUIRY_RESPONSE_TX_POWER_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_INQUIRY_RESPONSE_TX_POWER_OFF] & HCI_SUPP_COMMANDS_READ_INQUIRY_RESPONSE_TX_POWER_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_RESPONSE_TX_POWER_MASK 0x02
+#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_RESPONSE_TX_POWER_OFF 18
+#define HCI_WRITE_INQUIRY_RESPONSE_TX_POWER_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_INQUIRY_RESPONSE_TX_POWER_OFF] & HCI_SUPP_COMMANDS_WRITE_INQUIRY_RESPONSE_TX_POWER_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_MASK 0x04
+#define HCI_SUPP_COMMANDS_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_OFF 18
+#define HCI_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_OFF] & HCI_SUPP_COMMANDS_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_MASK 0x08
+#define HCI_SUPP_COMMANDS_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_OFF 18
+#define HCI_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_OFF] & HCI_SUPP_COMMANDS_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_MASK)
+
+#define HCI_SUPP_COMMANDS_IO_CAPABILITY_RESPONSE_MASK 0x80
+#define HCI_SUPP_COMMANDS_IO_CAPABILITY_RESPONSE_OFF 18
+#define HCI_IO_CAPABILITY_RESPONSE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_IO_CAPABILITY_RESPONSE_OFF] & HCI_SUPP_COMMANDS_IO_CAPABILITY_RESPONSE_MASK)
+
+/* Supported Commands Byte 19 */
+#define HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_REPLY_MASK 0x01
+#define HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_REPLY_OFF 19
+#define HCI_USER_CONFIRMATION_REQUEST_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_REPLY_OFF] & HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_NEG_REPLY_MASK 0x02
+#define HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_NEG_REPLY_OFF 19
+#define HCI_USER_CONFIRMATION_REQUEST_NEG_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_NEG_REPLY_OFF] & HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_NEG_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_REPLY_MASK 0x04
+#define HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_REPLY_OFF 19
+#define HCI_USER_PASSKEY_REQUEST_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_REPLY_OFF] & HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_NEG_REPLY_MASK 0x08
+#define HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_NEG_REPLY_OFF 19
+#define HCI_USER_PASSKEY_REQUEST_NEG_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_NEG_REPLY_OFF] & HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_NEG_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_REPLY_MASK 0x10
+#define HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_REPLY_OFF 19
+#define HCI_REMOTE_OOB_DATA_REQUEST_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_REPLY_OFF] & HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_DBG_MODE_MASK 0x20
+#define HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_DBG_MODE_OFF 19
+#define HCI_WRITE_SIMPLE_PAIRING_DBG_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_DBG_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_DBG_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_ENHANCED_FLUSH_MASK 0x40
+#define HCI_SUPP_COMMANDS_ENHANCED_FLUSH_OFF 19
+#define HCI_ENHANCED_FLUSH_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_ENHANCED_FLUSH_OFF] & HCI_SUPP_COMMANDS_ENHANCED_FLUSH_MASK)
+
+#define HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_NEG_REPLY_MASK 0x80
+#define HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_NEG_REPLY_OFF 19
+#define HCI_REMOTE_OOB_DATA_REQUEST_NEG_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_NEG_REPLY_OFF] & HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_NEG_REPLY_MASK)
+
+/* Supported Commands Byte 20, bits 0-1 and 5-7 reserved */
+#define HCI_SUPP_COMMANDS_SEND_KEYPRESS_NOTIF_MASK 0x04
+#define HCI_SUPP_COMMANDS_SEND_KEYPRESS_NOTIF_OFF 20
+#define HCI_SEND_NOTIF_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SEND_KEYPRESS_NOTIF_OFF] & HCI_SUPP_COMMANDS_SEND_KEYPRESS_NOTIF_MASK)
+
+#define HCI_SUPP_COMMANDS_IO_CAP_REQ_NEG_REPLY_MASK 0x08
+#define HCI_SUPP_COMMANDS_IO_CAP_REQ_NEG_REPLY_OFF 20
+#define HCI_IO_CAP_REQ_NEG_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_IO_CAP_REQ_NEG_REPLY_OFF] & HCI_SUPP_COMMANDS_IO_CAP_REQ_NEG_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_ENCR_KEY_SIZE_MASK 0x10
+#define HCI_SUPP_COMMANDS_READ_ENCR_KEY_SIZE_OFF 20
+#define HCI_READ_ENCR_KEY_SIZE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_ENCR_KEY_SIZE_OFF] & HCI_SUPP_COMMANDS_READ_ENCR_KEY_SIZE_MASK)
+
+/* Supported Commands Byte 21 */
+#define HCI_SUPP_COMMANDS_CREATE_PHYSICAL_LINK_MASK 0x01
+#define HCI_SUPP_COMMANDS_CREATE_PHYSICAL_LINK_OFF 21
+#define HCI_CREATE_PHYSICAL_LINK_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_CREATE_PHYSICAL_LINK_OFF] & HCI_SUPP_COMMANDS_CREATE_PHYSICAL_LINK_MASK)
+
+#define HCI_SUPP_COMMANDS_ACCEPT_PHYSICAL_LINK_MASK 0x02
+#define HCI_SUPP_COMMANDS_ACCEPT_PHYSICAL_LINK_OFF 21
+#define HCI_ACCEPT_PHYSICAL_LINK_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_ACCEPT_PHYSICAL_LINK_OFF] & HCI_SUPP_COMMANDS_ACCEPT_PHYSICAL_LINK_MASK)
+
+#define HCI_SUPP_COMMANDS_DISCONNECT_PHYSICAL_LINK_MASK 0x04
+#define HCI_SUPP_COMMANDS_DISCONNECT_PHYSICAL_LINK_OFF 21
+#define HCI_DISCONNECT_PHYSICAL_LINK_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_DISCONNECT_PHYSICAL_LINK_OFF] & HCI_SUPP_COMMANDS_DISCONNECT_PHYSICAL_LINK_MASK)
+
+#define HCI_SUPP_COMMANDS_CREATE_LOGICAL_LINK_MASK 0x08
+#define HCI_SUPP_COMMANDS_CREATE_LOGICAL_LINK_OFF 21
+#define HCI_CREATE_LOGICAL_LINK_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_CREATE_LOGICAL_LINK_OFF] & HCI_SUPP_COMMANDS_CREATE_LOGICAL_LINK_MASK)
+
+#define HCI_SUPP_COMMANDS_ACCEPT_LOGICAL_LINK_MASK 0x10
+#define HCI_SUPP_COMMANDS_ACCEPT_LOGICAL_LINK_OFF 21
+#define HCI_ACCEPT_LOGICAL_LINK_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_ACCEPT_LOGICAL_LINK_OFF] & HCI_SUPP_COMMANDS_ACCEPT_LOGICAL_LINK_MASK)
+
+#define HCI_SUPP_COMMANDS_DISCONNECT_LOGICAL_LINK_MASK 0x20
+#define HCI_SUPP_COMMANDS_DISCONNECT_LOGICAL_LINK_OFF 21
+#define HCI_DISCONNECT_LOGICAL_LINK_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_DISCONNECT_LOGICAL_LINK_OFF] & HCI_SUPP_COMMANDS_DISCONNECT_LOGICAL_LINK_MASK)
+
+#define HCI_SUPP_COMMANDS_LOGICAL_LINK_CANCEL_MASK 0x40
+#define HCI_SUPP_COMMANDS_LOGICAL_LINK_CANCEL_OFF 21
+#define HCI_LOGICAL_LINK_CANCEL_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LOGICAL_LINK_CANCEL_OFF] & HCI_SUPP_COMMANDS_LOGICAL_LINK_CANCEL_MASK)
+
+#define HCI_SUPP_COMMANDS_FLOW_SPEC_MODIFY_MASK 0x80
+#define HCI_SUPP_COMMANDS_FLOW_SPEC_MODIFY_OFF 21
+#define HCI_FLOW_SPEC_MODIFY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_FLOW_SPEC_MODIFY_OFF] & HCI_SUPP_COMMANDS_FLOW_SPEC_MODIFY_MASK)
+
+/* Supported Commands Byte 22 */
+#define HCI_SUPP_COMMANDS_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_MASK 0x01
+#define HCI_SUPP_COMMANDS_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_OFF 22
+#define HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_OFF] & HCI_SUPP_COMMANDS_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_MASK 0x02
+#define HCI_SUPP_COMMANDS_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_OFF 22
+#define HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_OFF] & HCI_SUPP_COMMANDS_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_SET_EVENT_MASK_PAGE_2_MASK 0x04
+#define HCI_SUPP_COMMANDS_SET_EVENT_MASK_PAGE_2_OFF 22
+#define HCI_SET_EVENT_MASK_PAGE_2_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_EVENT_MASK_PAGE_2_OFF] & HCI_SUPP_COMMANDS_SET_EVENT_MASK_PAGE_2_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCATION_DATA_MASK 0x08
+#define HCI_SUPP_COMMANDS_READ_LOCATION_DATA_OFF 22
+#define HCI_READ_LOCATION_DATA_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LOCATION_DATA_OFF] & HCI_SUPP_COMMANDS_READ_LOCATION_DATA_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_LOCATION_DATA_MASK 0x10
+#define HCI_SUPP_COMMANDS_WRITE_LOCATION_DATA_OFF 22
+#define HCI_WRITE_LOCATION_DATA_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_LOCATION_DATA_OFF] & HCI_SUPP_COMMANDS_WRITE_LOCATION_DATA_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCAL_AMP_INFO_MASK 0x20
+#define HCI_SUPP_COMMANDS_READ_LOCAL_AMP_INFO_OFF 22
+#define HCI_READ_LOCAL_AMP_INFO_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_AMP_INFO_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_AMP_INFO_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCAL_AMP_ASSOC_MASK 0x40
+#define HCI_SUPP_COMMANDS_READ_LOCAL_AMP_ASSOC_OFF 22
+#define HCI_READ_LOCAL_AMP_ASSOC_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_AMP_ASSOC_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_AMP_ASSOC_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_REMOTE_AMP_ASSOC_MASK 0x80
+#define HCI_SUPP_COMMANDS_WRITE_REMOTE_AMP_ASSOC_OFF 22
+#define HCI_WRITE_REMOTE_AMP_ASSOC_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_REMOTE_AMP_ASSOC_OFF] & HCI_SUPP_COMMANDS_WRITE_REMOTE_AMP_ASSOC_MASK)
+
+/* Supported Commands Byte 23, bits 3-4 reserved */
+#define HCI_SUPP_COMMANDS_READ_FLOW_CONTROL_MODE_MASK 0x01
+#define HCI_SUPP_COMMANDS_READ_FLOW_CONTROL_MODE_OFF 23
+#define HCI_READ_FLOW_CONTROL_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_FLOW_CONTROL_MODE_OFF] & HCI_SUPP_COMMANDS_READ_FLOW_CONTROL_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_FLOW_CONTROL_MODE_MASK 0x02
+#define HCI_SUPP_COMMANDS_WRITE_FLOW_CONTROL_MODE_OFF 23
+#define HCI_WRITE_FLOW_CONTROL_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_FLOW_CONTROL_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_FLOW_CONTROL_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_DATA_BLOCK_SIZE_MASK 0x04
+#define HCI_SUPP_COMMANDS_READ_DATA_BLOCK_SIZE_OFF 23
+#define HCI_READ_DATA_BLOCK_SIZE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_DATA_BLOCK_SIZE_OFF] & HCI_SUPP_COMMANDS_READ_DATA_BLOCK_SIZE_MASK)
+
+#define HCI_SUPP_COMMANDS_ENABLE_AMP_RCVR_REPORTS_MASK 0x20
+#define HCI_SUPP_COMMANDS_ENABLE_AMP_RCVR_REPORTS_OFF 23
+#define HCI_ENABLE_AMP_RCVR_REPORTS_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_ENABLE_AMP_RCVR_REPORTS_OFF] & HCI_SUPP_COMMANDS_ENABLE_AMP_RCVR_REPORTS_MASK)
+
+#define HCI_SUPP_COMMANDS_AMP_TEST_END_MASK 0x40
+#define HCI_SUPP_COMMANDS_AMP_TEST_END_OFF 23
+#define HCI_AMP_TEST_END_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_AMP_TEST_END_OFF] & HCI_SUPP_COMMANDS_AMP_TEST_END_MASK)
+
+#define HCI_SUPP_COMMANDS_AMP_TEST_MASK 0x80
+#define HCI_SUPP_COMMANDS_AMP_TEST_OFF 23
+#define HCI_AMP_TEST_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_AMP_TEST_OFF] & HCI_SUPP_COMMANDS_AMP_TEST_MASK)
+
+/* Supported Commands Byte 24, bits 1, 7 reserved */
+#define HCI_SUPP_COMMANDS_READ_TRANSMIT_POWER_LEVEL_MASK 0x01
+#define HCI_SUPP_COMMANDS_READ_TRANSMIT_POWER_LEVEL_OFF 24
+#define HCI_READ_TRANSMIT_POWER_LEVEL_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_TRANSMIT_POWER_LEVEL_OFF] & HCI_SUPP_COMMANDS_READ_TRANSMIT_POWER_LEVEL_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_BE_FLUSH_TOUT_MASK 0x04
+#define HCI_SUPP_COMMANDS_READ_BE_FLUSH_TOUT_OFF 24
+#define HCI_READ_BE_FLUSH_TOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_BE_FLUSH_TOUT_OFF] & HCI_SUPP_COMMANDS_READ_BE_FLUSH_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_BE_FLUSH_TOUT_MASK 0x08
+#define HCI_SUPP_COMMANDS_WRITE_BE_FLUSH_TOUT_OFF 24
+#define HCI_WRITE_BE_FLUSH_TOUT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_BE_FLUSH_TOUT_OFF] & HCI_SUPP_COMMANDS_WRITE_BE_FLUSH_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_SHORT_RANGE_MODE_MASK 0x10
+#define HCI_SUPP_COMMANDS_SHORT_RANGE_MODE_OFF 24
+#define HCI_SHORT_RANGE_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SHORT_RANGE_MODE_OFF] & HCI_SUPP_COMMANDS_SHORT_RANGE_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LE_HOST_SUPPORT_MASK 0x20
+#define HCI_SUPP_COMMANDS_READ_LE_HOST_SUPPORT_OFF 24
+#define HCI_READ_LE_HOST_SUPPORT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LE_HOST_SUPPORT_OFF] & HCI_SUPP_COMMANDS_READ_LE_HOST_SUPPORT_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_LE_HOST_SUPPORT_MASK 0x20
+#define HCI_SUPP_COMMANDS_WRITE_LE_HOST_SUPPORT_OFF 24
+#define HCI_WRITE_LE_HOST_SUPPORT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_LE_HOST_SUPPORT_OFF] & HCI_SUPP_COMMANDS_WRITE_LE_HOST_SUPPORT_MASK)
+
+/* Supported Commands Byte 25, bit 3 reserved */
+#define HCI_SUPP_COMMANDS_LE_SET_EVENT_MASK_MASK 0x01
+#define HCI_SUPP_COMMANDS_LE_SET_EVENT_MASK_OFF 25
+#define HCI_LE_SET_EVENT_MASK_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_SET_EVENT_MASK_OFF] & HCI_SUPP_COMMANDS_LE_SET_EVENT_MASK_MASK)
+
+#define HCI_SUPP_COMMANDS_LE_READ_BUFFER_SIZE_MASK 0x02
+#define HCI_SUPP_COMMANDS_LE_READ_BUFFER_SIZE_OFF 25
+#define HCI_LE_READ_BUFFER_SIZE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_READ_BUFFER_SIZE_OFF] & HCI_SUPP_COMMANDS_LE_READ_BUFFER_SIZE_MASK)
+
+#define HCI_SUPP_COMMANDS_LE_READ_LOCAL_SUPPORTED_FEATURES_MASK 0x04
+#define HCI_SUPP_COMMANDS_LE_READ_LOCAL_SUPPORTED_FEATURES_OFF 25
+#define HCI_LE_READ_LOCAL_SUPPORTED_FEATURES_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_READ_LOCAL_SUPPORTED_FEATURES_OFF] & HCI_SUPP_COMMANDS_LE_READ_LOCAL_SUPPORTED_FEATURES_MASK)
+
+#define HCI_SUPP_COMMANDS_LE_SET_RANDOM_ADDRESS_MASK 0x10
+#define HCI_SUPP_COMMANDS_LE_SET_RANDOM_ADDRESS_OFF 25
+#define HCI_LE_SET_RANDOM_ADDRESS_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_SET_RANDOM_ADDRESS_OFF] & HCI_SUPP_COMMANDS_LE_SET_RANDOM_ADDRESS_MASK)
+
+#define HCI_SUPP_COMMANDS_LE_SET_ADVERTISING_PARAMETERS_MASK 0x20
+#define HCI_SUPP_COMMANDS_LE_SET_ADVERTISING_PARAMETERS_OFF 25
+#define HCI_LE_SET_ADVERTISING_PARAMETERS_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_SET_ADVERTISING_PARAMETERS_OFF] & HCI_SUPP_COMMANDS_LE_SET_ADVERTISING_PARAMETERS_MASK)
+
+#define HCI_SUPP_COMMANDS_LE_READ_ADVERTISING_CHANNEL_TX_POWER_MASK 0x40
+#define HCI_SUPP_COMMANDS_LE_READ_ADVERTISING_CHANNEL_TX_POWER_OFF 25
+#define HCI_LE_READ_ADVERTISING_CHANNEL_TX_POWER_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_READ_ADVERTISING_CHANNEL_TX_POWER_OFF] & HCI_SUPP_COMMANDS_LE_READ_ADVERTISING_CHANNEL_TX_POWER_MASK)
+
+#define HCI_SUPP_COMMANDS_LE_SET_ADVERTISING_DATA_MASK 0x80
+#define HCI_SUPP_COMMANDS_LE_SET_ADVERTISING_DATA_OFF 25
+#define HCI_LE_SET_ADVERTISING_DATA_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_SET_ADVERTISING_DATA_OFF] & HCI_SUPP_COMMANDS_LE_SET_ADVERTISING_DATA_MASK)
+
+/* Supported Commands Byte 26 */
+#define HCI_SUPP_COMMANDS_LE_SET_SCAN_RESPONSE_DATA_MASK 0x01
+#define HCI_SUPP_COMMANDS_LE_SET_SCAN_RESPONSE_DATA_OFF 26
+#define HCI_LE_SET_SCAN_RESPONSE_DATA_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_SET_SCAN_RESPONSE_DATA_OFF] & HCI_SUPP_COMMANDS_LE_SET_SCAN_RESPONSE_DATA_MASK)
+
+#define HCI_SUPP_COMMANDS_LE_SET_ADVERTISE_ENABLE_MASK 0x02
+#define HCI_SUPP_COMMANDS_LE_SET_ADVERTISE_ENABLE_OFF 26
+#define HCI_LE_SET_ADVERTISE_ENABLE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_SET_ADVERTISE_ENABLE_OFF] & HCI_SUPP_COMMANDS_LE_SET_ADVERTISE_ENABLE_MASK)
+
+#define HCI_SUPP_COMMANDS_LE_SET_SCAN_PARAMETERS_MASK 0x04
+#define HCI_SUPP_COMMANDS_LE_SET_SCAN_PARAMETERS_OFF 26
+#define HCI_LE_SET_SCAN_PARAMETERS_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_SET_SCAN_PARAMETERS_OFF] & HCI_SUPP_COMMANDS_LE_SET_SCAN_PARAMETERS_MASK)
+
+#define HCI_SUPP_COMMANDS_LE_SET_SCAN_ENABLE_MASK 0x08
+#define HCI_SUPP_COMMANDS_LE_SET_SCAN_ENABLE_OFF 26
+#define HCI_LE_SET_SCAN_ENABLE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_SET_SCAN_ENABLE_OFF] & HCI_SUPP_COMMANDS_LE_SET_SCAN_ENABLE_MASK)
+
+#define HCI_SUPP_COMMANDS_LE_CREATE_CONNECTION_MASK 0x10
+#define HCI_SUPP_COMMANDS_LE_CREATE_CONNECTION_OFF 26
+#define HCI_LE_CREATE_CONNECTION_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_CREATE_CONNECTION_OFF] & HCI_SUPP_COMMANDS_LE_CREATE_CONNECTION_MASK)
+
+#define HCI_SUPP_COMMANDS_LE_CREATE_CONNECTION_CANCEL_MASK 0x20
+#define HCI_SUPP_COMMANDS_LE_CREATE_CONNECTION_CANCEL_OFF 26
+#define HCI_LE_CREATE_CONNECTION_CANCEL_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_CREATE_CONNECTION_CANCEL_OFF] & HCI_SUPP_COMMANDS_LE_CREATE_CONNECTION_CANCEL_MASK)
+
+#define HCI_SUPP_COMMANDS_LE_READ_WHITE_LIST_SIZE_MASK 0x40
+#define HCI_SUPP_COMMANDS_LE_READ_WHITE_LIST_SIZE_OFF 26
+#define HCI_LE_READ_WHITE_LIST_SIZE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_READ_WHITE_LIST_SIZE_OFF] & HCI_SUPP_COMMANDS_LE_READ_WHITE_LIST_SIZE_MASK)
+
+#define HCI_SUPP_COMMANDS_LE_CLEAR_WHITE_LIST_MASK 0x80
+#define HCI_SUPP_COMMANDS_LE_CLEAR_WHITE_LIST_OFF 26
+#define HCI_LE_CLEAR_WHITE_LIST_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_CLEAR_WHITE_LIST_OFF] & HCI_SUPP_COMMANDS_LE_CLEAR_WHITE_LIST_MASK)
+
+/* Supported Commands Byte 27 */
+#define HCI_SUPP_COMMANDS_LE_ADD_DEVICE_TO_WHITE_LIST_MASK 0x01
+#define HCI_SUPP_COMMANDS_LE_ADD_DEVICE_TO_WHITE_LIST_OFF 27
+#define HCI_LE_ADD_DEVICE_TO_WHITE_LIST_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_ADD_DEVICE_TO_WHITE_LIST_OFF] & HCI_SUPP_COMMANDS_LE_ADD_DEVICE_TO_WHITE_LIST_MASK)
+
+#define HCI_SUPP_COMMANDS_LE_REMOVE_DEVICE_FROM_WHITE_LIST_MASK 0x02
+#define HCI_SUPP_COMMANDS_LE_REMOVE_DEVICE_FROM_WHITE_LIST_OFF 27
+#define HCI_LE_REMOVE_DEVICE_FROM_WHITE_LIST_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_REMOVE_DEVICE_FROM_WHITE_LIST_OFF] & HCI_SUPP_COMMANDS_LE_REMOVE_DEVICE_FROM_WHITE_LIST_MASK)
+
+#define HCI_SUPP_COMMANDS_LE_CONNECTION_UPDATE_MASK 0x04
+#define HCI_SUPP_COMMANDS_LE_CONNECTION_UPDATE_OFF 27
+#define HCI_LE_CONNECTION_UPDATE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_CONNECTION_UPDATE_OFF] & HCI_SUPP_COMMANDS_LE_CONNECTION_UPDATE_MASK)
+
+#define HCI_SUPP_COMMANDS_LE_SET_HOST_CHANNEL_CLASSIFICATION_MASK 0x08
+#define HCI_SUPP_COMMANDS_LE_SET_HOST_CHANNEL_CLASSIFICATION_OFF 27
+#define HCI_LE_SET_HOST_CHANNEL_CLASSIFICATION_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_SET_HOST_CHANNEL_CLASSIFICATION_OFF] & HCI_SUPP_COMMANDS_LE_SET_HOST_CHANNEL_CLASSIFICATION_MASK)
+
+#define HCI_SUPP_COMMANDS_LE_READ_CHANNEL_MAP_MASK 0x10
+#define HCI_SUPP_COMMANDS_LE_READ_CHANNEL_MAP_OFF 27
+#define HCI_LE_READ_CHANNEL_MAP_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_READ_CHANNEL_MAP_OFF] & HCI_SUPP_COMMANDS_LE_READ_CHANNEL_MAP_MASK)
+
+#define HCI_SUPP_COMMANDS_LE_READ_REMOTE_USED_FEATURES_MASK 0x20
+#define HCI_SUPP_COMMANDS_LE_READ_REMOTE_USED_FEATURES_OFF 27
+#define HCI_LE_READ_REMOTE_USED_FEATURES_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_READ_REMOTE_USED_FEATURES_OFF] & HCI_SUPP_COMMANDS_LE_READ_REMOTE_USED_FEATURES_MASK)
+
+#define HCI_SUPP_COMMANDS_LE_ENCRYPT_MASK 0x40
+#define HCI_SUPP_COMMANDS_LE_ENCRYPT_OFF 27
+#define HCI_LE_ENCRYPT_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_ENCRYPT_OFF] & HCI_SUPP_COMMANDS_LE_ENCRYPT_MASK)
+
+#define HCI_SUPP_COMMANDS_LE_RAND_MASK 0x80
+#define HCI_SUPP_COMMANDS_LE_RAND_OFF 27
+#define HCI_LE_RAND_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_RAND_OFF] & HCI_SUPP_COMMANDS_LE_RAND_MASK)
+
+
+/* Supported Commands Byte 28, bit 7 reserved */
+#define HCI_SUPP_COMMANDS_LE_START_ENCRYPTION_MASK 0x01
+#define HCI_SUPP_COMMANDS_LE_START_ENCRYPTION_OFF 28
+#define HCI_LE_START_ENCRYPTION_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_START_ENCRYPTION_OFF] & HCI_SUPP_COMMANDS_LE_START_ENCRYPTION_MASK)
+
+#define HCI_SUPP_COMMANDS_LE_LONG_TERM_KEY_REQUEST_REPLY_MASK 0x02
+#define HCI_SUPP_COMMANDS_LE_LONG_TERM_KEY_REQUEST_REPLY_OFF 28
+#define HCI_LE_LONG_TERM_KEY_REQUEST_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_LONG_TERM_KEY_REQUEST_REPLY_OFF] & HCI_SUPP_COMMANDS_LE_LONG_TERM_KEY_REQUEST_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY_MASK 0x04
+#define HCI_SUPP_COMMANDS_LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY_OFF 28
+#define HCI_LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY_OFF] & HCI_SUPP_COMMANDS_LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_LE_READ_SUPPORTED_STATES_MASK 0x08
+#define HCI_SUPP_COMMANDS_LE_READ_SUPPORTED_STATES_OFF 28
+#define HCI_LE_READ_SUPPORTED_STATES_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_READ_SUPPORTED_STATES_OFF] & HCI_SUPP_COMMANDS_LE_READ_SUPPORTED_STATES_MASK)
+
+#define HCI_SUPP_COMMANDS_LE_RECEIVER_TEST_MASK 0x10
+#define HCI_SUPP_COMMANDS_LE_RECEIVER_TEST_OFF 28
+#define HCI_LE_RECEIVER_TEST_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_RECEIVER_TEST_OFF] & HCI_SUPP_COMMANDS_LE_RECEIVER_TEST_MASK)
+
+#define HCI_SUPP_COMMANDS_LE_TRANSMITTER_TEST_MASK 0x20
+#define HCI_SUPP_COMMANDS_LE_TRANSMITTER_TEST_OFF 28
+#define HCI_LE_TRANSMITTER_TEST_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_TRANSMITTER_TEST_OFF] & HCI_SUPP_COMMANDS_LE_TRANSMITTER_TEST_MASK)
+
+#define HCI_SUPP_COMMANDS_LE_TEST_END_MASK 0x40
+#define HCI_SUPP_COMMANDS_LE_TEST_END_OFF 28
+#define HCI_LE_TEST_END_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_LE_TEST_END_OFF] & HCI_SUPP_COMMANDS_LE_TEST_END_MASK)
+
+/* Supported Commands Byte 29, bits 0-2 reserved */
+#define HCI_SUPP_COMMANDS_ENH_SETUP_SYNCH_CONN_MASK 0x08
+#define HCI_SUPP_COMMANDS_ENH_SETUP_SYNCH_CONN_OFF 29
+#define HCI_READ_ENH_SETUP_SYNCH_CONN_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_ENH_SETUP_SYNCH_CONN_OFF] & HCI_SUPP_COMMANDS_ENH_SETUP_SYNCH_CONN_MASK)
+
+#define HCI_SUPP_COMMANDS_ENH_ACCEPT_SYNCH_CONN_MASK 0x10
+#define HCI_SUPP_COMMANDS_ENH_ACCEPT_SYNCH_CONN_OFF 29
+#define HCI_READ_ENH_ACCEPT_SYNCH_CONN_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_ENH_ACCEPT_SYNCH_CONN_OFF] & HCI_SUPP_COMMANDS_ENH_ACCEPT_SYNCH_CONN_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCAL_CODECS_MASK 0x20
+#define HCI_SUPP_COMMANDS_READ_LOCAL_CODECS_OFF 29
+#define HCI_READ_LOCAL_CODECS_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_CODECS_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_CODECS_MASK)
+
+#define HCI_SUPP_COMMANDS_SET_MWS_CHANN_PARAM_MASK 0x40
+#define HCI_SUPP_COMMANDS_SET_MWS_CHANN_PARAM_OFF 29
+#define HCI_SET_MWS_CHANNEL_PARAMETERS_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_MWS_CHANN_PARAM_OFF] & HCI_SUPP_COMMANDS_SET_MWS_CHANN_PARAM_MASK)
+
+#define HCI_SUPP_COMMANDS_SET_EXT_FRAME_CONF_MASK 0x80
+#define HCI_SUPP_COMMANDS_SET_EXT_FRAME_CONF_OFF 29
+#define HCI_SET_EXTERNAL_FRAME_CONFIGURATION_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_EXT_FRAME_CONF_OFF] & HCI_SUPP_COMMANDS_SET_EXT_FRAME_CONF_MASK)
+
+
+/* Supported Commands Byte 30 */
+#define HCI_SUPP_COMMANDS_SET_MWS_SIGNALING_MASK 0x01
+#define HCI_SUPP_COMMANDS_SET_MWS_SIGNALING_OFF 30
+#define HCI_SET_MWS_SIGNALING_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_MWS_SIGNALING_OFF] & HCI_SUPP_COMMANDS_SET_MWS_SIGNALING_MASK)
+
+#define HCI_SUPP_COMMANDS_SET_MWS_TRANS_LAYER_MASK 0x02
+#define HCI_SUPP_COMMANDS_SET_MWS_TRANS_LAYER_OFF 30
+#define HCI_SET_MWS_TRANSPORT_LAYER_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_MWS_TRANS_LAYER_OFF] & HCI_SUPP_COMMANDS_SET_MWS_TRANS_LAYER_MASK)
+
+#define HCI_SUPP_COMMANDS_SET_MWS_SCAN_FREQ_TABLE_MASK 0x04
+#define HCI_SUPP_COMMANDS_SET_MWS_SCAN_FREQ_TABLE_OFF 30
+#define HCI_SET_MWS_SCAN_FREQUENCY_TABLE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_MWS_SCAN_FREQ_TABLE_OFF] & HCI_SUPP_COMMANDS_SET_MWS_SCAN_FREQ_TABLE_MASK)
+
+#define HCI_SUPP_COMMANDS_GET_TRANS_LAYER_CONF_MASK 0x08
+#define HCI_SUPP_COMMANDS_GET_TRANS_LAYER_CONF_OFF 30
+#define HCI_GET_MWS_TRANS_LAYER_CFG_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_GET_TRANS_LAYER_CONF_OFF] & HCI_SUPP_COMMANDS_GET_TRANS_LAYER_CONF_MASK)
+
+#define HCI_SUPP_COMMANDS_SET_MWS_PATTERN_CONF_MASK 0x10
+#define HCI_SUPP_COMMANDS_SET_MWS_PATTERN_CONF_OFF 30
+#define HCI_SET_MWS_PATTERN_CONFIGURATION_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_MWS_PATTERN_CONF_OFF] & HCI_SUPP_COMMANDS_SET_MWS_PATTERN_CONF_MASK)
+
+/* Supported Commands (Byte 30 bit 5) */
+#define HCI_SUPP_COMMANDS_SET_TRIG_CLK_CAP_MASK 0x20
+#define HCI_SUPP_COMMANDS_SET_TRIG_CLK_CAP_OFF 30
+#define HCI_SET_TRIG_CLK_CAP_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_TRIG_CLK_CAP_OFF] & HCI_SUPP_COMMANDS_SET_TRIG_CLK_CAP_MASK)
+
+
+/* Supported Commands (Byte 30 bit 6-7) */
+#define HCI_SUPP_COMMANDS_TRUNCATED_PAGE 0x06
+#define HCI_SUPP_COMMANDS_TRUNCATED_PAGE_OFF 30
+#define HCI_TRUNCATED_PAGE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_TRUNCATED_PAGE_OFF] & HCI_SUPP_COMMANDS_TRUNCATED_PAGE)
+
+#define HCI_SUPP_COMMANDS_TRUNCATED_PAGE_CANCEL 0x07
+#define HCI_SUPP_COMMANDS_TRUNCATED_PAGE_CANCEL_OFF 30
+#define HCI_TRUNCATED_PAGE_CANCEL_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_TRUNCATED_PAGE_CANCEL_OFF] & HCI_SUPP_COMMANDS_TRUNCATED_PAGE_CANCEL)
+
+/* Supported Commands Byte 31 */
+#define HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST 0x00
+#define HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_OFF 31
+#define HCI_SET_CONLESS_SLAVE_BRCST_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_OFF] & HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST)
+
+#define HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_RECEIVE 0x01
+#define HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_RECEIVE_OFF 31
+#define HCI_SET_CONLESS_SLAVE_BRCST_RECEIVE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_RECEIVE_OFF] & HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_RECEIVE)
+
+#define HCI_SUPP_COMMANDS_START_SYNC_TRAIN 0x02
+#define HCI_SUPP_COMMANDS_START_SYNC_TRAIN_OFF 31
+#define HCI_START_SYNC_TRAIN_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_START_SYNC_TRAIN_OFF] & HCI_SUPP_COMMANDS_START_SYNC_TRAIN)
+
+#define HCI_SUPP_COMMANDS_RECEIVE_SYNC_TRAIN 0x03
+#define HCI_SUPP_COMMANDS_RECEIVE_SYNC_TRAIN_OFF 31
+#define HCI_RECEIVE_SYNC_TRAIN_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_RECEIVE_SYNC_TRAIN_OFF] & HCI_SUPP_COMMANDS_RECEIVE_SYNC_TRAIN)
+
+#define HCI_SUPP_COMMANDS_SET_RESERVED_LT_ADDR 0x04
+#define HCI_SUPP_COMMANDS_SET_RESERVED_LT_ADDR_OFF 31
+#define HCI_SET_RESERVED_LT_ADDR_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_RESERVED_LT_ADDR_OFF] & HCI_SUPP_COMMANDS_SET_RESERVED_LT_ADDR)
+
+#define HCI_SUPP_COMMANDS_DELETE_RESERVED_LT_ADDR 0x05
+#define HCI_SUPP_COMMANDS_DELETE_RESERVED_LT_ADDR_OFF 31
+#define HCI_DELETE_RESERVED_LT_ADDR_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_DELETE_RESERVED_LT_ADDR_OFF] & HCI_SUPP_COMMANDS_DELETE_RESERVED_LT_ADDR)
+
+#define HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_DATA 0x06
+#define HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_DATA_OFF 31
+#define HCI_SET_CONLESS_SLAVE_BRCST_DATA_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_DATA_OFF] & HCI_SUPP_COMMANDS_SET_CONLESS_SLAVE_BRCST_DATA)
+
+#define HCI_SUPP_COMMANDS_READ_SYNC_TRAIN_PARAM 0x07
+#define HCI_SUPP_COMMANDS_READ_SYNC_TRAIN_PARAM_OFF 31
+#define HCI_READ_SYNC_TRAIN_PARAM_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_SYNC_TRAIN_PARAM_OFF] & HCI_SUPP_COMMANDS_READ_SYNC_TRAIN_PARAM)
+
+/* Supported Commands Byte 32 bit 0 */
+#define HCI_SUPP_COMMANDS_WRITE_SYNC_TRAIN_PARAM 0x00
+#define HCI_SUPP_COMMANDS_WRITE_SYNC_TRAIN_PARAM_OFF 32
+#define HCI_WRITE_SYNC_TRAIN_PARAM_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_SYNC_TRAIN_PARAM_OFF] & HCI_SUPP_COMMANDS_WRITE_SYNC_TRAIN_PARAM)
+
+
+/*
+Commands of HCI_GRP_VENDOR_SPECIFIC group for WIDCOMM SW LM Simulator
+*/
+#ifdef _WIDCOMM
+
+#define HCI_SET_HCI_TRACE (0x0001 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_SET_LM_TRACE (0x0002 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_WRITE_COUNTRY_CODE (0x0004 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_READ_LM_HISTORY (0x0005 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_WRITE_BD_ADDR (0x0006 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_DISABLE_ENCRYPTION (0x0007 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_DISABLE_AUTHENTICATION (0x0008 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_GENERIC_LC_CMD (0x000A | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_INCR_POWER (0x000B | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_DECR_POWER (0x000C | HCI_GRP_VENDOR_SPECIFIC)
+
+/* Definitions for the local transactions */
+#define LM_DISCONNECT (0x00D0 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_AUTHENTICATION_REQUESTED (0x00D1 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_SET_CONN_ENCRYPTION (0x00D2 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_START_ENCRYPT_KEY_SIZE (0x00D3 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_START_ENCRYPTION (0x00D4 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_STOP_ENCRYPTION (0x00D5 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_CHANGE_CONN_PACKET_TYPE (0x00D6 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_RMT_NAME_REQUEST (0x00D7 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_READ_RMT_FEATURES (0x00D8 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_READ_RMT_VERSION_INFO (0x00D9 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_READ_RMT_TIMING_INFO (0x00DA | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_READ_RMT_CLOCK_OFFSET (0x00DB | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HOLD_MODE (0x00DC | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_EXIT_PARK_MODE (0x00DD | HCI_GRP_VENDOR_SPECIFIC)
+
+#define LM_SCO_LINK_REQUEST (0x00E0 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_SCO_CHANGE (0x00E4 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_SCO_REMOVE (0x00E8 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_MAX_SLOTS (0x00F1 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_MAX_SLOTS_REQUEST (0x00F2 | HCI_GRP_VENDOR_SPECIFIC)
+
+#ifdef INCLUDE_OPTIONAL_PAGING_SCHEME
+#define LM_OPTIONAL_PAGE_REQUEST (0x00F3 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_OPTIONAL_PAGESCAN_REQUEST (0x00F4 | HCI_GRP_VENDOR_SPECIFIC)
+#endif
+
+#define LM_SETUP_COMPLETE (0x00FF | HCI_GRP_VENDOR_SPECIFIC)
+
+#define LM_HIST_SEND_LMP_FRAME (0x0100 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_RECV_LMP_FRAME (0x0101 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_HCIT_ERROR (0x0102 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_PER_INQ_TOUT (0x0103 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_INQ_SCAN_TOUT (0x0104 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_PAGE_SCAN_TOUT (0x0105 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_RESET_TOUT (0x0106 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_MANDAT_PSCAN_TOUT (0x0107 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_ACL_START_TRANS (0x0108 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_ACL_HOST_REPLY (0x0109 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_ACL_TIMEOUT (0x010A | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_ACL_TX_COMP (0x010B | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_ACL_HCID_SUSPENDED (0x010C | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_ACL_FAILED (0x010D | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_HCI_COMMAND (0x010E | HCI_GRP_VENDOR_SPECIFIC)
+
+#define LM_HIST_HCI_EVENT (0x010F | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_HCI_UPDATA (0x0110 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_HCI_DNDATA (0x0111 | HCI_GRP_VENDOR_SPECIFIC)
+
+#define HCI_ENTER_TEST_MODE (0x0300 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_LMP_TEST_CNTRL (0x0301 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_DEBUG_LC_CMD_MIN (0x0300 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_DEBUG_LC_CMD_MAX (0x03FF | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_DEBUG_LC_COMMAND HCI_DEBUG_LC_CMD_MAX
+#endif
+
+#endif
diff --git a/src/include/nfc_target.h b/src/include/nfc_target.h
new file mode 100644
index 0000000..594c378
--- /dev/null
+++ b/src/include/nfc_target.h
@@ -0,0 +1,754 @@
+/******************************************************************************
+ *
+ * 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 */
+#include "dyn_mem.h" /* defines static and/or dynamic memory for components */
+#ifndef LMP_TEST
+#include "bt_trace.h"
+#endif
+
+
+/* API macros for DLL (needed to export API functions from DLLs) */
+#define NFC_API EXPORT_API
+#define LLCP_API EXPORT_API
+
+/******************************************************************************
+**
+** GKI Mail Box and Timer
+**
+******************************************************************************/
+
+/* Mailbox event mask for NFC stack */
+#ifndef NFC_MBOX_EVT_MASK
+#define NFC_MBOX_EVT_MASK (TASK_MBOX_0_EVT_MASK)
+#endif
+
+/* Mailbox ID for NFC stack */
+#ifndef NFC_MBOX_ID
+#define NFC_MBOX_ID (TASK_MBOX_0)
+#endif
+
+/* Mailbox event mask for NFA */
+#ifndef NFA_MBOX_EVT_MASK
+#define NFA_MBOX_EVT_MASK (TASK_MBOX_2_EVT_MASK)
+#endif
+
+/* Mailbox ID for NFA */
+#ifndef NFA_MBOX_ID
+#define NFA_MBOX_ID (TASK_MBOX_2)
+#endif
+
+/* GKI timer id used for protocol timer in NFC stack */
+#ifndef NFC_TIMER_ID
+#define NFC_TIMER_ID (TIMER_0)
+#endif
+
+/* GKI timer event mask used for protocol timer in NFC stack */
+#ifndef NFC_TIMER_EVT_MASK
+#define NFC_TIMER_EVT_MASK (TIMER_0_EVT_MASK)
+#endif
+
+/* GKI timer id used for quick timer in NFC stack */
+#ifndef NFC_QUICK_TIMER_ID
+#define NFC_QUICK_TIMER_ID (TIMER_1)
+#endif
+
+/* GKI timer event mask used for quick timer in NFC stack */
+#ifndef NFC_QUICK_TIMER_EVT_MASK
+#define NFC_QUICK_TIMER_EVT_MASK (TIMER_1_EVT_MASK)
+#endif
+
+/* GKI timer id used for protocol timer in NFA */
+#ifndef NFA_TIMER_ID
+#define NFA_TIMER_ID (TIMER_2)
+#endif
+
+/* GKI timer event mask used for protocol timer in NFA */
+#ifndef NFA_TIMER_EVT_MASK
+#define NFA_TIMER_EVT_MASK (TIMER_2_EVT_MASK)
+#endif
+
+/******************************************************************************
+**
+** GKI Buffer Pools
+**
+******************************************************************************/
+
+/* NCI command/notification/data */
+#ifndef NFC_NCI_POOL_ID
+#define NFC_NCI_POOL_ID GKI_POOL_ID_2
+#endif
+
+#ifndef NFC_NCI_POOL_BUF_SIZE
+#define NFC_NCI_POOL_BUF_SIZE GKI_BUF2_SIZE
+#endif
+
+/* Reader/Write commands (NCI data payload) */
+#ifndef NFC_RW_POOL_ID
+#define NFC_RW_POOL_ID GKI_POOL_ID_2
+#endif
+
+#ifndef NFC_RW_POOL_BUF_SIZE
+#define NFC_RW_POOL_BUF_SIZE GKI_BUF2_SIZE
+#endif
+
+/* Card Emulation responses (NCI data payload) */
+#ifndef NFC_CE_POOL_ID
+#define NFC_CE_POOL_ID GKI_POOL_ID_2
+#endif
+
+#ifndef NFC_CE_POOL_BUF_SIZE
+#define NFC_CE_POOL_BUF_SIZE GKI_BUF2_SIZE
+#endif
+
+
+/* NCI 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_0_F 0x0F
+#define NCI_VERSION_1_0 0x10
+
+#ifndef NCI_VERSION
+#define NCI_VERSION NCI_VERSION_1_0
+#endif
+
+/* TRUE I2C patch is needed */
+#ifndef NFC_I2C_PATCH_INCLUDED
+#define NFC_I2C_PATCH_INCLUDED TRUE /* NFC-Android uses this!!! */
+#endif
+
+/******************************************************************************
+**
+** NFC
+**
+******************************************************************************/
+#ifndef NFC_INCLUDED
+#define NFC_INCLUDED TRUE
+#endif
+
+/* Define to TRUE to include Broadcom Vendor Specific implementation */
+#ifndef NFC_BRCM_VS_INCLUDED
+#define NFC_BRCM_VS_INCLUDED TRUE
+#endif
+
+/* Define to TRUE if compling for NFC Reader/Writer Only mode */
+#ifndef NFC_RW_ONLY
+#define NFC_RW_ONLY FALSE
+#endif
+
+/* Define to TRUE to use dynamic memory allocation.
+ * The default is FALSE - to use static memory allocations.
+*/
+#ifndef NFC_DYNAMIC_MEMORY
+#define NFC_DYNAMIC_MEMORY FALSE
+#endif
+
+/* Timeout for receiving response to NCI command */
+#ifndef NFC_CMD_CMPL_TIMEOUT
+#define NFC_CMD_CMPL_TIMEOUT 2
+#endif
+
+/* Timeout for waiting on data credit/NFC-DEP */
+#ifndef NFC_DEACTIVATE_TIMEOUT
+#define NFC_DEACTIVATE_TIMEOUT 2
+#endif
+
+/* the maximum number of Vendor Specific callback functions allowed to be registered. 1-14 */
+#ifndef NFC_NUM_VS_CBACKS
+#define NFC_NUM_VS_CBACKS 3
+#endif
+
+/* the maximum number of NCI connections allowed. 1-14 */
+#ifndef NCI_MAX_CONN_CBS
+#define NCI_MAX_CONN_CBS 4
+#endif
+
+/* Maximum number of NCI commands that the NFCC accepts without needing to wait for response */
+#ifndef NCI_MAX_CMD_WINDOW
+#define NCI_MAX_CMD_WINDOW 1
+#endif
+
+/* Define to TRUE to include the NFCEE related functionalities */
+#ifndef NFC_NFCEE_INCLUDED
+#define NFC_NFCEE_INCLUDED TRUE
+#endif
+
+/* the maximum number of NFCEE interface supported */
+#ifndef NFC_MAX_EE_INTERFACE
+#define NFC_MAX_EE_INTERFACE 3
+#endif
+
+/* the maximum number of NFCEE information supported. */
+#ifndef NFC_MAX_EE_INFO
+#define NFC_MAX_EE_INFO 8
+#endif
+
+/* the maximum number of NFCEE TLVs supported */
+#ifndef NFC_MAX_EE_TLVS
+#define NFC_MAX_EE_TLVS 1
+#endif
+
+/* the maximum size of NFCEE TLV list supported */
+#ifndef NFC_MAX_EE_TLV_SIZE
+#define NFC_MAX_EE_TLV_SIZE 150
+#endif
+
+/* Maximum time to discover NFCEE */
+#ifndef NFA_EE_DISCV_TIMEOUT_VAL
+#define NFA_EE_DISCV_TIMEOUT_VAL 2000
+#endif
+
+/* Number of times reader/writer should attempt to resend a command on failure */
+#ifndef RW_MAX_RETRIES
+#define RW_MAX_RETRIES 5
+#endif
+
+/* RW NDEF Support */
+#ifndef RW_NDEF_INCLUDED
+#define RW_NDEF_INCLUDED TRUE
+#endif
+
+/* RW Type 1 Tag timeout for each API call, in ms */
+#ifndef RW_T1T_TOUT_RESP
+#define RW_T1T_TOUT_RESP 100
+#endif
+
+/* CE Type 2 Tag timeout for controller command, in ms */
+#ifndef CE_T2T_TOUT_RESP
+#define CE_T2T_TOUT_RESP 1000
+#endif
+
+/* RW Type 2 Tag timeout for each API call, in ms */
+#ifndef RW_T2T_TOUT_RESP
+#define RW_T2T_TOUT_RESP 150 /* Android requires 150 instead of 100 for presence-check*/
+#endif
+
+/* RW Type 2 Tag timeout for each API call, in ms */
+#ifndef RW_T2T_SEC_SEL_TOUT_RESP
+#define RW_T2T_SEC_SEL_TOUT_RESP 10
+#endif
+
+/* RW Type 3 Tag timeout for each API call, in ms */
+#ifndef RW_T3T_TOUT_RESP
+#define RW_T3T_TOUT_RESP 100 /* NFC-Android will use 100 instead of 75 for T3t presence-check */
+#endif
+
+/* CE Type 3 Tag maximum response timeout index (for check and update, used in SENSF_RES) */
+#ifndef CE_T3T_MRTI_C
+#define CE_T3T_MRTI_C 0xFF
+#endif
+#ifndef CE_T3T_MRTI_U
+#define CE_T3T_MRTI_U 0xFF
+#endif
+
+/* Default maxblocks for CE_T3T UPDATE/CHECK operations */
+#ifndef CE_T3T_DEFAULT_UPDATE_MAXBLOCKS
+#define CE_T3T_DEFAULT_UPDATE_MAXBLOCKS 3
+#endif
+
+#ifndef CE_T3T_DEFAULT_CHECK_MAXBLOCKS
+#define CE_T3T_DEFAULT_CHECK_MAXBLOCKS 3
+#endif
+
+/* CE Type 4 Tag, Frame Waiting time Integer */
+#ifndef CE_T4T_ISO_DEP_FWI
+#define CE_T4T_ISO_DEP_FWI 7
+#endif
+
+/* RW Type 4 Tag timeout for each API call, in ms */
+#ifndef RW_T4T_TOUT_RESP
+#define RW_T4T_TOUT_RESP 1000
+#endif
+
+/* CE Type 4 Tag timeout for update file, in ms */
+#ifndef CE_T4T_TOUT_UPDATE
+#define CE_T4T_TOUT_UPDATE 1000
+#endif
+
+/* CE Type 4 Tag, mandatory NDEF File ID */
+#ifndef CE_T4T_MANDATORY_NDEF_FILE_ID
+#define CE_T4T_MANDATORY_NDEF_FILE_ID 0x1000
+#endif
+
+/* CE Type 4 Tag, max number of AID supported */
+#ifndef CE_T4T_MAX_REG_AID
+#define CE_T4T_MAX_REG_AID 4
+#endif
+
+/* Sub carrier */
+#ifndef RW_I93_FLAG_SUB_CARRIER
+#define RW_I93_FLAG_SUB_CARRIER I93_FLAG_SUB_CARRIER_SINGLE
+#endif
+
+/* Data rate for 15693 command/response */
+#ifndef RW_I93_FLAG_DATA_RATE
+#define RW_I93_FLAG_DATA_RATE I93_FLAG_DATA_RATE_HIGH
+#endif
+
+/* TRUE, to include Card Emulation related test commands */
+#ifndef CE_TEST_INCLUDED
+#define CE_TEST_INCLUDED FALSE
+#endif
+
+
+/* Quick Timer */
+#ifndef QUICK_TIMER_TICKS_PER_SEC
+#define QUICK_TIMER_TICKS_PER_SEC 100 /* 10ms timer */
+#endif
+
+
+/******************************************************************************
+**
+** LLCP
+**
+******************************************************************************/
+
+#ifndef LLCP_TEST_INCLUDED
+#define LLCP_TEST_INCLUDED FALSE
+#endif
+
+#ifndef LLCP_POOL_ID
+#define LLCP_POOL_ID GKI_POOL_ID_3
+#endif
+
+#ifndef LLCP_POOL_BUF_SIZE
+#define LLCP_POOL_BUF_SIZE GKI_BUF3_SIZE
+#endif
+
+/* LLCP Maximum Information Unit (between LLCP_DEFAULT_MIU(128) and LLCP_MAX_MIU (2175)*/
+#ifndef LLCP_MIU
+#define LLCP_MIU (LLCP_POOL_BUF_SIZE - BT_HDR_SIZE - NCI_MSG_OFFSET_SIZE - NCI_DATA_HDR_SIZE - LLCP_PDU_HEADER_SIZE)
+#endif
+
+/* Link Timeout, LTO */
+#ifndef LLCP_LTO_VALUE
+#define LLCP_LTO_VALUE 1000 /* Default is 100ms. It should be sufficiently larger than RWT */
+#endif
+
+/*
+** LTO is max time interval between the last bit received and the first bit sent over the air.
+** Link timeout must be delayed as much as time between the packet sent from LLCP and the last bit transmitted at NFCC.
+** - 200ms, max OTA transmitting time between the first bit and the last bit at NFCC
+** Largest MIU(2175bytes) of LLCP must be fragmented and sent on NFC-DEP over the air.
+** 8 * (DEP_REQ/RES+ACK) + DEP_REQ/RES for 2175 MIU at 106kbps bit rate.
+** - 10ms, processing time
+*/
+#ifndef LLCP_INTERNAL_TX_DELAY
+#define LLCP_INTERNAL_TX_DELAY 210
+#endif
+
+/*
+** LTO is max time interval between the last bit received and the first bit sent over the air.
+** Link timeout must be delayed as much as time between the first bit received at NFCC and the packet received at LLCP.
+** - 200ms, max OTA transmitting time between the first bit and the last bit at NFCC
+** LLCP cannot receive data packet until all bit are received and reassembled in NCI.
+** 8 * (DEP_REQ/RES+ACK) + DEP_REQ/RES for 2175 MIU at 106kbps bit rate.
+** - 10ms, processing time
+*/
+#ifndef LLCP_INTERNAL_RX_DELAY
+#define LLCP_INTERNAL_RX_DELAY 210
+#endif
+
+/* Wait for application layer sending data before sending SYMM */
+#ifndef LLCP_DELAY_RESP_TIME
+#define LLCP_DELAY_RESP_TIME 20 /* in ms */
+#endif
+
+/* LLCP inactivity timeout for initiator */
+#ifndef LLCP_INIT_INACTIVITY_TIMEOUT
+#define LLCP_INIT_INACTIVITY_TIMEOUT 0 /* in ms */
+#endif
+
+/* LLCP inactivity timeout for target */
+#ifndef LLCP_TARGET_INACTIVITY_TIMEOUT
+#define LLCP_TARGET_INACTIVITY_TIMEOUT 0 /* in ms */
+#endif
+
+/* LLCP delay timeout to send the first PDU as initiator */
+#ifndef LLCP_DELAY_TIME_TO_SEND_FIRST_PDU
+#define LLCP_DELAY_TIME_TO_SEND_FIRST_PDU 50 /* in ms */
+#endif
+
+/* Response Waiting Time */
+#ifndef LLCP_WAITING_TIME
+#define LLCP_WAITING_TIME 7 /* its scaled value should be less than LTO */
+#endif
+
+/* Options Parameters */
+#ifndef LLCP_OPT_VALUE
+#define LLCP_OPT_VALUE LLCP_LSC_3 /* Link Service Class 3 */
+#endif
+
+/* Data link connection timeout */
+#ifndef LLCP_DATA_LINK_CONNECTION_TOUT
+#define LLCP_DATA_LINK_CONNECTION_TOUT 1000
+#endif
+
+/* Max length of service name */
+#ifndef LLCP_MAX_SN_LEN
+#define LLCP_MAX_SN_LEN 255 /* max length of service name */
+#endif
+
+/* Max number of well-known services, at least 2 for LM and SDP and up to 16 */
+#ifndef LLCP_MAX_WKS
+#define LLCP_MAX_WKS 5
+#endif
+
+/* Max number of services advertised by local SDP, up to 16 */
+#ifndef LLCP_MAX_SERVER
+#define LLCP_MAX_SERVER 10
+#endif
+
+/* Max number of services not advertised by local SDP, up to 32 */
+#ifndef LLCP_MAX_CLIENT
+#define LLCP_MAX_CLIENT 20
+#endif
+
+/* Max number of data link connections */
+#ifndef LLCP_MAX_DATA_LINK
+#define LLCP_MAX_DATA_LINK 16
+#endif
+
+/* Max number of outstanding service discovery requests */
+#ifndef LLCP_MAX_SDP_TRANSAC
+#define LLCP_MAX_SDP_TRANSAC 16
+#endif
+
+/* Percentage of LLCP buffer pool for receiving data */
+#ifndef LLCP_RX_BUFF_RATIO
+#define LLCP_RX_BUFF_RATIO 30
+#endif
+
+/* Rx congestion end threshold as percentage of receiving buffers */
+#ifndef LLCP_RX_CONGEST_END
+#define LLCP_RX_CONGEST_END 50
+#endif
+
+/* Rx congestion start threshold as percentage of receiving buffers */
+#ifndef LLCP_RX_CONGEST_START
+#define LLCP_RX_CONGEST_START 70
+#endif
+
+/* limitation of rx UI PDU as percentage of receiving buffers */
+#ifndef LLCP_LL_RX_BUFF_LIMIT
+#define LLCP_LL_RX_BUFF_LIMIT 30
+#endif
+
+/* minimum rx congestion threshold (number of rx I PDU in queue) for data link connection */
+#ifndef LLCP_DL_MIN_RX_CONGEST
+#define LLCP_DL_MIN_RX_CONGEST 4
+#endif
+
+/* limitation of tx UI PDU as percentage of transmitting buffers */
+#ifndef LLCP_LL_TX_BUFF_LIMIT
+#define LLCP_LL_TX_BUFF_LIMIT 30
+#endif
+
+/******************************************************************************
+**
+** NFA
+**
+******************************************************************************/
+#ifndef NFA_DYNAMIC_MEMORY
+#define NFA_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef NFA_INCLUDED
+#define NFA_INCLUDED TRUE
+#endif
+
+#ifndef NFA_P2P_INCLUDED
+#define NFA_P2P_INCLUDED TRUE
+#endif
+
+/* 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
+
+/* Max number of Application that can be registered to NFA-HCI */
+#ifndef NFA_HCI_MAX_APP_CB
+#define NFA_HCI_MAX_APP_CB 0x05
+#endif
+
+/* Max number of HCI gates that can be created */
+#ifndef NFA_HCI_MAX_GATE_CB
+#define NFA_HCI_MAX_GATE_CB 0x06
+#endif
+
+/* Max number of HCI pipes that can be created for the whole system */
+#ifndef NFA_HCI_MAX_PIPE_CB
+#define NFA_HCI_MAX_PIPE_CB 0x08
+#endif
+
+/* Timeout for waiting for the response to HCP Command packet */
+#ifndef NFA_HCI_RESPONSE_TIMEOUT
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+/*
+ * 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
+#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
+#define NFA_DM_PRESENCE_CHECK_OPTION 0x03 /* !!!!! Android needs value 3 */
+#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(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define NFA_CE_LISTEN_INFO_MAX 10
+#else
+#define NFA_CE_LISTEN_INFO_MAX 5
+#endif
+#endif
+
+#ifndef NFA_CHO_INCLUDED
+#define NFA_CHO_INCLUDED FALSE /* Anddroid must use FALSE to exclude CHO */
+#endif
+
+/* MIU for CHO */
+#ifndef NFA_CHO_MIU
+#define NFA_CHO_MIU 499
+#endif
+
+/* Receiving Window for CHO */
+#ifndef NFA_CHO_RW
+#define NFA_CHO_RW 4
+#endif
+
+/* Max number of alternative carrier information */
+#ifndef NFA_CHO_MAX_AC_INFO
+#define NFA_CHO_MAX_AC_INFO 2
+#endif
+
+/* Max reference character length, it is up to 255 but it's RECOMMENDED short */
+#ifndef NFA_CHO_MAX_REF_NAME_LEN
+#define NFA_CHO_MAX_REF_NAME_LEN 8
+#endif
+
+/* Max auxiliary data count */
+#ifndef NFA_CHO_MAX_AUX_DATA_COUNT
+#define NFA_CHO_MAX_AUX_DATA_COUNT 2
+#endif
+
+#ifndef NFA_CHO_TEST_INCLUDED
+#define NFA_CHO_TEST_INCLUDED FALSE
+#endif
+
+#ifndef NFA_SNEP_INCLUDED
+#define NFA_SNEP_INCLUDED FALSE /* Android must use FALSE to exclude SNEP */
+#endif
+
+/* Max acceptable length */
+#ifndef NFA_SNEP_DEFAULT_SERVER_MAX_NDEF_SIZE
+#define NFA_SNEP_DEFAULT_SERVER_MAX_NDEF_SIZE 500000
+#endif
+
+/* Max number of SNEP server/client and data link connection */
+#ifndef NFA_SNEP_MAX_CONN
+#define NFA_SNEP_MAX_CONN 6
+#endif
+
+/* Max number data link connection of SNEP default server*/
+#ifndef NFA_SNEP_DEFAULT_MAX_CONN
+#define NFA_SNEP_DEFAULT_MAX_CONN 3
+#endif
+
+/* MIU for SNEP */
+#ifndef NFA_SNEP_MIU
+#define NFA_SNEP_MIU 1980 /* Modified for NFC-A */
+#endif
+
+/* Receiving Window for SNEP */
+#ifndef NFA_SNEP_RW
+#define NFA_SNEP_RW 2 /* Modified for NFC-A */
+#endif
+
+/* Max number of NFCEE supported */
+#ifndef NFA_EE_MAX_EE_SUPPORTED
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define NFA_EE_MAX_EE_SUPPORTED 3 //Wait for UICC Init complete.
+#else
+#define NFA_EE_MAX_EE_SUPPORTED 4 /* Modified for NFC-A until we add dynamic support */
+#endif
+#endif
+
+/* Maximum number of AID entries per target_handle */
+#ifndef NFA_EE_MAX_AID_ENTRIES
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+#define NFA_EE_MAX_AID_ENTRIES (50)
+#else
+#define NFA_EE_MAX_AID_ENTRIES (20)
+#endif
+#else
+#define NFA_EE_MAX_AID_ENTRIES (10)
+#endif
+#endif
+
+/* Maximum number of callback functions can be registered through NFA_EeRegister() */
+#ifndef NFA_EE_MAX_CBACKS
+#define NFA_EE_MAX_CBACKS (3)
+#endif
+
+#ifndef NFA_DTA_INCLUDED
+#define NFA_DTA_INCLUDED TRUE
+#endif
+
+
+/*****************************************************************************
+** 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 *)(p+1) + p->offset); GKI_freebuf(p);}
+
+#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..f55de66
--- /dev/null
+++ b/src/include/trace_api.h
@@ -0,0 +1,107 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Contains API for BTE Test Tool trace related functions.
+ *
+ ******************************************************************************/
+
+
+#ifndef TRACE_API_H
+#define TRACE_API_H
+
+#include "bt_target.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Trace API Function External Declarations */
+BT_API extern void DispAMPFrame (BT_HDR *p_buf, BOOLEAN is_recv, BD_ADDR bd_addr);
+BT_API extern void DispRFCOMMFrame (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void DispL2CCmd(BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void DispSdp (BT_HDR *p_msg, BOOLEAN is_rcv, BOOLEAN is_segment);
+BT_API extern void DispSdpFullList (UINT8 *p, UINT16 list_len, BOOLEAN is_rcv);
+BT_API extern void DispTcsMsg (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void DispHciEvt (BT_HDR *p_buf);
+BT_API extern void DispHciAclData (BT_HDR *p_buf, BOOLEAN is_rcvd);
+BT_API extern void DispHciScoData (BT_HDR *p_buf, BOOLEAN is_rcvd);
+BT_API extern void DispHciCmd (BT_HDR *p_buf);
+BT_API extern void DispBnep (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void DispAvdtMsg (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void DispAvct (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void DispMca (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void DispObxMsg (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void DispLMDiagEvent (BT_HDR *p_buf);
+BT_API extern void DispHidFrame (BT_HDR *p_buf, BOOLEAN is_recv, BOOLEAN is_control);
+BT_API extern void DispRawFrame(UINT8 *p, UINT16 len, BOOLEAN is_rcv);
+BT_API extern void DispSlipPacket(UINT8 *p, UINT16 len, BOOLEAN is_rcv, BOOLEAN oof_flow_ctrl);
+BT_API extern void DispNci (UINT8 *p, UINT16 len, BOOLEAN is_recv);
+BT_API extern void DispHcp (UINT8 *p, UINT16 len, BOOLEAN is_recv, BOOLEAN is_first_seg);
+BT_API extern void DispNDEFRecord (UINT8 *pRec, INT8 *pDescr);
+BT_API extern void DispNDEFMsg (UINT8 *pMsg, UINT32 MsgLen, BOOLEAN is_recv);
+BT_API extern void DispSmpMsg (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void DispAttMsg (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void DispLLCP (BT_HDR *p_buf, BOOLEAN is_rx);
+BT_API extern void DispSNEP (UINT8 local_sap, UINT8 remote_sap, UINT8 *p_data, UINT16 length, BOOLEAN is_rx);
+BT_API extern void DispCHO (UINT8 *pMsg, UINT32 MsgLen, BOOLEAN is_rx);
+BT_API extern void DispT3TagMessage(BT_HDR *p_msg, BOOLEAN is_rx);
+BT_API extern void DispRWT4Tags (BT_HDR *p_buf, BOOLEAN is_rx);
+BT_API extern void DispCET4Tags (BT_HDR *p_buf, BOOLEAN is_rx);
+BT_API extern void DispRWI93Tag (BT_HDR *p_buf, BOOLEAN is_rx, UINT8 command_to_respond);
+
+BT_API extern void RPC_DispAMPFrame (BT_HDR *p_buf, BOOLEAN is_recv, BD_ADDR bd_addr);
+BT_API extern void RPC_DispRFCOMMFrame (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void RPC_DispL2CCmd(BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void RPC_DispSdp (BT_HDR *p_msg, BOOLEAN is_rcv, BOOLEAN is_segment);
+BT_API extern void RPC_DispSdpFullList (UINT8 *p, UINT16 list_len, BOOLEAN is_rcv);
+BT_API extern void RPC_DispTcsMsg (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void RPC_DispHciEvt (BT_HDR *p_buf);
+BT_API extern void RPC_DispHciAclData (BT_HDR *p_buf, BOOLEAN is_rcvd);
+BT_API extern void RPC_DispHciScoData (BT_HDR *p_buf, BOOLEAN is_rcvd);
+BT_API extern void RPC_DispHciCmd (BT_HDR *p_buf);
+BT_API extern void RPC_DispLMDiagEvent (BT_HDR *p_buf);
+BT_API extern void RPC_DispBnep (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void RPC_DispAvdtMsg (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void RPC_DispAvct (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void RPC_DispMca (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void RPC_DispObxMsg (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void RPC_DispLMDiagEvent (BT_HDR *p_buf);
+BT_API extern void RPC_DispHidFrame (BT_HDR *p_buf, BOOLEAN is_recv, BOOLEAN is_control);
+BT_API extern void RPC_DispSmpMsg (BT_HDR *p_msg, BOOLEAN is_rcv);
+BT_API extern void RPC_DispAttMsg (BT_HDR *p_msg, BOOLEAN is_rcv);
+BT_API extern void RPC_DispNci (UINT8 *p, UINT16 len, BOOLEAN is_recv);
+BT_API extern void RPC_DispHcp (UINT8 *p, UINT16 len, BOOLEAN is_recv, BOOLEAN is_first_seg);
+BT_API extern void RPC_DispNDEFRecord (UINT8 *pRec, INT8 *pDescr);
+BT_API extern void RPC_DispNDEFMsg (UINT8 *pMsg, UINT32 MsgLen, BOOLEAN is_recv);
+BT_API extern void RPC_DispLLCP (BT_HDR *p_buf, BOOLEAN is_rx);
+BT_API extern void RPC_DispSNEP (UINT8 local_sap, UINT8 remote_sap, UINT8 *p_data, UINT16 length, BOOLEAN is_rx);
+BT_API extern void RPC_DispCHO (UINT8 *pMsg, UINT32 MsgLen, BOOLEAN is_rx);
+BT_API extern void RPC_DispT3TagMessage(BT_HDR *p_msg, BOOLEAN is_rx);
+BT_API extern void RPC_DispRWT4Tags (BT_HDR *p_buf, BOOLEAN is_rx);
+BT_API extern void RPC_DispCET4Tags (BT_HDR *p_buf, BOOLEAN is_rx);
+BT_API extern void RPC_DispRWI93Tag (BT_HDR *p_buf, BOOLEAN is_rx, UINT8 command_to_respond);
+
+EXPORT_API extern void LogMsg (UINT32 trace_set_mask, const char *fmt_str, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TRACE_API_H */
diff --git a/src/nfa/ce/nfa_ce_act.c b/src/nfa/ce/nfa_ce_act.c
new file mode 100644
index 0000000..fdc0c94
--- /dev/null
+++ b/src/nfa/ce/nfa_ce_act.c
@@ -0,0 +1,1656 @@
+/******************************************************************************
+ *
+ * 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);
+
+ 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 *) (p_ce_data->raw_frame.p_data + 1) + p_ce_data->raw_frame.p_data->offset;
+ conn_evt.data.len = p_ce_data->raw_frame.p_data->len;
+ (*p_cb->p_active_conn_cback) (NFA_DATA_EVT, &conn_evt);
+ }
+ else
+ {
+ conn_evt.ce_data.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 *) (p_ce_data->raw_frame.p_data + 1) + p_ce_data->raw_frame.p_data->offset;
+ conn_evt.ce_data.len = p_ce_data->raw_frame.p_data->len;
+ (*p_cb->p_active_conn_cback) (NFA_CE_DATA_EVT, &conn_evt);
+ }
+ GKI_freebuf (p_ce_data->raw_frame.p_data);
+ break;
+
+ default:
+ NFA_TRACE_DEBUG1 ("nfa_ce_handle_t3t_evt unhandled event=0x%02x", event);
+ break;
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_ce_handle_t4t_evt
+**
+** Description Handler for Type-4 tag card emulation events (for NDEF case)
+**
+** Returns Nothing
+**
+*******************************************************************************/
+void nfa_ce_handle_t4t_evt (tCE_EVENT event, tCE_DATA *p_ce_data)
+{
+ tNFA_CE_CB *p_cb = &nfa_ce_cb;
+ tNFA_CONN_EVT_DATA conn_evt;
+
+ NFA_TRACE_DEBUG1 ("nfa_ce_handle_t4t_evt: event 0x%x", event);
+
+ /* AID for NDEF selected. we had notified the app of activation. */
+ p_cb->idx_cur_active = NFA_CE_LISTEN_INFO_IDX_NDEF;
+ if (p_cb->listen_info[p_cb->idx_cur_active].flags & NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND)
+ {
+ p_cb->p_active_conn_cback = p_cb->listen_info[p_cb->idx_cur_active].p_conn_cback;
+ }
+
+ switch (event)
+ {
+ case CE_T4T_NDEF_UPDATE_START_EVT:
+ conn_evt.status = NFA_STATUS_OK;
+ (*p_cb->p_active_conn_cback) (NFA_CE_NDEF_WRITE_START_EVT, &conn_evt);
+ break;
+
+ case CE_T4T_NDEF_UPDATE_CPLT_EVT:
+ conn_evt.ndef_write_cplt.len = p_ce_data->update_info.length;
+ conn_evt.ndef_write_cplt.p_data = p_ce_data->update_info.p_data;
+
+ if (NDEF_MsgValidate (p_ce_data->update_info.p_data, p_ce_data->update_info.length, TRUE) != NDEF_OK)
+ conn_evt.ndef_write_cplt.status = NFA_STATUS_FAILED;
+ else
+ conn_evt.ndef_write_cplt.status = NFA_STATUS_OK;
+
+ (*p_cb->p_active_conn_cback) (NFA_CE_NDEF_WRITE_CPLT_EVT, &conn_evt);
+ break;
+
+ case CE_T4T_NDEF_UPDATE_ABORT_EVT:
+ conn_evt.ndef_write_cplt.len = 0;
+ conn_evt.ndef_write_cplt.status = NFA_STATUS_FAILED;
+ conn_evt.ndef_write_cplt.p_data = NULL;
+ (*p_cb->p_active_conn_cback) (NFA_CE_NDEF_WRITE_CPLT_EVT, &conn_evt);
+ break;
+
+ default:
+ /* CE_T4T_RAW_FRAME_EVT is not used in NFA CE */
+ NFA_TRACE_DEBUG1 ("nfa_ce_handle_t4t_evt unhandled event=0x%02x", event);
+ break;
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function nfa_ce_handle_t4t_aid_evt
+**
+** Description Handler for Type-4 tag AID events (for AIDs registered using
+** NFA_CeRegisterT4tAidOnDH)
+**
+** Returns Nothing
+**
+*******************************************************************************/
+void nfa_ce_handle_t4t_aid_evt (tCE_EVENT event, tCE_DATA *p_ce_data)
+{
+ tNFA_CE_CB *p_cb = &nfa_ce_cb;
+ UINT8 listen_info_idx;
+ tNFA_CONN_EVT_DATA conn_evt;
+
+ NFA_TRACE_DEBUG1 ("nfa_ce_handle_t4t_aid_evt: event 0x%x", event);
+
+ /* Get listen_info for this aid callback */
+ for (listen_info_idx=0; listen_info_idx<NFA_CE_LISTEN_INFO_IDX_INVALID; listen_info_idx++)
+ {
+ if ((p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_IN_USE) &&
+ (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_T4T_AID) &&
+ (p_cb->listen_info[listen_info_idx].t4t_aid_handle == p_ce_data->raw_frame.aid_handle))
+ {
+ p_cb->idx_cur_active = listen_info_idx;
+ p_cb->p_active_conn_cback = p_cb->listen_info[p_cb->idx_cur_active].p_conn_cback;
+ break;
+ }
+ }
+
+ if (event == CE_T4T_RAW_FRAME_EVT)
+ {
+ if (listen_info_idx != NFA_CE_LISTEN_INFO_IDX_INVALID)
+ {
+ /* Found listen_info entry */
+ conn_evt.ce_activated.handle = NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE) p_cb->idx_cur_active);
+
+ /* If we have not notified the app of activation, do so now */
+ if (p_cb->listen_info[p_cb->idx_cur_active].flags & NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND)
+ {
+ p_cb->listen_info[p_cb->idx_cur_active].flags &= ~NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND;
+
+ memcpy (&(conn_evt.ce_activated.activate_ntf), &p_cb->activation_params, sizeof (tNFC_ACTIVATE_DEVT));
+ conn_evt.ce_activated.status = NFA_STATUS_OK;
+ (*p_cb->p_active_conn_cback) (NFA_CE_ACTIVATED_EVT, &conn_evt);
+ }
+
+ /* Notify app of AID data */
+ conn_evt.ce_data.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 *) (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 (NFC_NXP_NOT_OPEN_INCLUDED == 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 ((BT_HDR *) &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;
+ nfa_ce_hdl_event ((BT_HDR *) &ce_msg);
+ }
+ break;
+
+ default:
+ NFA_TRACE_ERROR0 ("Unexpected event");
+ break;
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_ce_t3t_set_listen_params
+**
+** Description Set t3t listening parameters
+**
+** Returns Nothing
+**
+*******************************************************************************/
+void nfc_ce_t3t_set_listen_params (void)
+{
+ UINT8 i;
+ tNFA_CE_CB *p_cb = &nfa_ce_cb;
+ UINT8 tlv[32], *p_params;
+ UINT8 tlv_size;
+ UINT16 t3t_flags2_mask = 0xFFFF; /* Mask of which T3T_IDs are disabled */
+ UINT8 t3t_idx = 0;
+ UINT8 adv_Feat = 1;
+ /* Point to start of tlv buffer */
+ p_params = tlv;
+
+ /* Set system code and NFCID2 */
+ for (i=0; i<NFA_CE_LISTEN_INFO_MAX; i++)
+ {
+ if ((p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE) &&
+ (p_cb->listen_info[i].protocol_mask & NFA_PROTOCOL_MASK_T3T))
+ {
+ /* Set tag's system code and NFCID2 */
+ UINT8_TO_STREAM (p_params, NFC_PMID_LF_T3T_ID1+t3t_idx); /* type */
+ UINT8_TO_STREAM (p_params, NCI_PARAM_LEN_LF_T3T_ID); /* length */
+ UINT16_TO_BE_STREAM (p_params, p_cb->listen_info[i].t3t_system_code); /* System Code */
+ ARRAY_TO_BE_STREAM (p_params, p_cb->listen_info[i].t3t_nfcid2, NCI_RF_F_UID_LEN);
+
+ /* Set mask for this ID */
+ t3t_flags2_mask &= ~((UINT16) (1<<t3t_idx));
+ t3t_idx++;
+ }
+ }
+
+ /* For NCI draft 22+, the polarity of NFC_PMID_LF_T3T_FLAGS2 is flipped */
+ t3t_flags2_mask = ~t3t_flags2_mask;
+
+ UINT8_TO_STREAM (p_params, NFC_PMID_LF_T3T_FLAGS2); /* type */
+ UINT8_TO_STREAM (p_params, NCI_PARAM_LEN_LF_T3T_FLAGS2); /* length */
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+
+
+//FelicaOnHost
+ UINT16_TO_BE_STREAM (p_params, t3t_flags2_mask);
+ 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); /* Mask of IDs to disable listening */
+
+#else
+ UINT16_TO_STREAM (p_params, t3t_flags2_mask); /* Mask of IDs to disable listening */
+#endif
+ tlv_size = (UINT8) (p_params-tlv);
+ nfa_dm_check_set_config (tlv_size, (UINT8 *)tlv, FALSE);
+}
+
+/*******************************************************************************
+**
+** Function nfa_ce_t3t_generate_rand_nfcid
+**
+** Description Generate a random NFCID2 for Type-3 tag
+**
+** Returns Nothing
+**
+*******************************************************************************/
+void nfa_ce_t3t_generate_rand_nfcid (UINT8 nfcid2[NCI_RF_F_UID_LEN])
+{
+ UINT32 rand_seed = GKI_get_tick_count ();
+
+ /* For Type-3 tag, nfcid2 starts witn 02:fe */
+ nfcid2[0] = 0x02;
+ nfcid2[1] = 0xFE;
+
+ /* The remaining 6 bytes are random */
+ nfcid2[2] = (UINT8) (rand_seed & 0xFF);
+ nfcid2[3] = (UINT8) (rand_seed>>8 & 0xFF);
+ rand_seed>>=(rand_seed&3);
+ nfcid2[4] = (UINT8) (rand_seed & 0xFF);
+ nfcid2[5] = (UINT8) (rand_seed>>8 & 0xFF);
+ rand_seed>>=(rand_seed&3);
+ nfcid2[6] = (UINT8) (rand_seed & 0xFF);
+ nfcid2[7] = (UINT8) (rand_seed>>8 & 0xFF);
+}
+
+/*******************************************************************************
+**
+** Function nfa_ce_start_listening
+**
+** Description Start listening
+**
+** Returns NFA_STATUS_OK if successful
+**
+*******************************************************************************/
+tNFA_STATUS nfa_ce_start_listening (void)
+{
+ tNFA_DM_DISC_TECH_PROTO_MASK listen_mask;
+ tNFA_CE_CB *p_cb = &nfa_ce_cb;
+ tNFA_HANDLE disc_handle;
+ UINT8 listen_info_idx;
+
+ /*************************************************************************/
+ /* Construct protocol preference list to listen for */
+
+ /* First, get protocol preference for active NDEF (if any) */
+ if ( (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags & NFA_CE_LISTEN_INFO_IN_USE)
+ &&(p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle == NFA_HANDLE_INVALID))
+ {
+ listen_mask = 0;
+
+ if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask & NFA_PROTOCOL_MASK_T3T)
+ {
+ /* set T3T config params */
+ nfc_ce_t3t_set_listen_params ();
+
+ listen_mask |= NFA_DM_DISC_MASK_LF_T3T;
+ }
+
+ if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask & NFA_PROTOCOL_MASK_ISO_DEP)
+ {
+ listen_mask |= nfa_ce_cb.isodep_disc_mask;
+ }
+
+ disc_handle = nfa_dm_add_rf_discover (listen_mask, NFA_DM_DISC_HOST_ID_DH, nfa_ce_discovery_cback);
+
+ if (disc_handle == NFA_HANDLE_INVALID)
+ return (NFA_STATUS_FAILED);
+ else
+ p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle = disc_handle;
+ }
+
+ /* Next, add protocols from non-NDEF, if any */
+ for (listen_info_idx=0; listen_info_idx<NFA_CE_LISTEN_INFO_IDX_INVALID; listen_info_idx++)
+ {
+ /* add RF discovery to DM only if it is not added yet */
+ if ( (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_IN_USE)
+ &&(p_cb->listen_info[listen_info_idx].rf_disc_handle == NFA_HANDLE_INVALID))
+ {
+ if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_FELICA)
+ {
+ /* set T3T config params */
+ nfc_ce_t3t_set_listen_params ();
+
+ disc_handle = nfa_dm_add_rf_discover (NFA_DM_DISC_MASK_LF_T3T,
+ NFA_DM_DISC_HOST_ID_DH,
+ nfa_ce_discovery_cback);
+
+ if (disc_handle == NFA_HANDLE_INVALID)
+ return (NFA_STATUS_FAILED);
+ else
+ p_cb->listen_info[listen_info_idx].rf_disc_handle = disc_handle;
+ }
+ else if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_T4T_AID)
+ {
+ disc_handle = nfa_dm_add_rf_discover (nfa_ce_cb.isodep_disc_mask,
+ NFA_DM_DISC_HOST_ID_DH,
+ nfa_ce_discovery_cback);
+
+ if (disc_handle == NFA_HANDLE_INVALID)
+ return (NFA_STATUS_FAILED);
+ else
+ p_cb->listen_info[listen_info_idx].rf_disc_handle = disc_handle;
+ }
+#if (NFC_NFCEE_INCLUDED == TRUE)
+ else if (p_cb->listen_info[listen_info_idx].flags &
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED == 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
+ }
+ }
+
+ return NFA_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function nfa_ce_restart_listen_check
+**
+** Description Called on deactivation. Check if any active listen_info entries to listen for
+**
+** Returns TRUE if listening is restarted.
+** FALSE if listening not restarted
+**
+*******************************************************************************/
+BOOLEAN nfa_ce_restart_listen_check (void)
+{
+ tNFA_CE_CB *p_cb = &nfa_ce_cb;
+ UINT8 listen_info_idx;
+
+ /* Check if any active entries in listen_info table */
+ for (listen_info_idx=0; listen_info_idx<NFA_CE_LISTEN_INFO_MAX; listen_info_idx++)
+ {
+ if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_IN_USE)
+ break;
+ }
+
+ /* Restart listening if there are any active listen_info entries */
+ if (listen_info_idx != NFA_CE_LISTEN_INFO_IDX_INVALID)
+ {
+ /* restart listening */
+ nfa_ce_start_listening ();
+ }
+ else
+ {
+ /* No active listen_info entries */
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_ce_remove_listen_info_entry
+**
+** Description Remove entry from listen_info table. (when API deregister is called or listen_start failed)
+**
+**
+** Returns Nothing
+**
+*******************************************************************************/
+void nfa_ce_remove_listen_info_entry (UINT8 listen_info_idx, BOOLEAN notify_app)
+{
+ tNFA_CE_CB *p_cb = &nfa_ce_cb;
+ tNFA_CONN_EVT_DATA conn_evt;
+
+ NFA_TRACE_DEBUG1 ("NFA_CE: removing listen_info entry %i", listen_info_idx);
+
+ /* Notify app that listening has stopped if requested (for API deregister) */
+ /* For LISTEN_START failures, app has already notified of NFA_LISTEN_START_EVT failure */
+ if (notify_app)
+ {
+ if (listen_info_idx == NFA_CE_LISTEN_INFO_IDX_NDEF)
+ {
+ conn_evt.status = NFA_STATUS_OK;
+ (*p_cb->listen_info[listen_info_idx].p_conn_cback) (NFA_CE_LOCAL_TAG_CONFIGURED_EVT, &conn_evt);
+ }
+#if (NFC_NFCEE_INCLUDED == TRUE)
+ else if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_UICC)
+ {
+ conn_evt.status = NFA_STATUS_OK;
+ (*p_cb->listen_info[listen_info_idx].p_conn_cback) (NFA_CE_UICC_LISTEN_CONFIGURED_EVT, &conn_evt);
+ }
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 ();
+
+ if ((nfa_ce_cb.p_scratch_buf = (UINT8 *) nfa_mem_co_alloc (nfa_ce_cb.ndef_max_size)) != NULL)
+ {
+ nfa_ce_cb.scratch_buf_size = nfa_ce_cb.ndef_max_size;
+ }
+ else
+ {
+ NFA_TRACE_ERROR1 ("Unable to allocate scratch buffer for writable NDEF message (%i bytes)", nfa_ce_cb.ndef_max_size);
+ result=NFA_STATUS_FAILED;
+ }
+ }
+ }
+
+ return (result);
+}
+
+/*******************************************************************************
+**
+** Function nfa_ce_set_content
+**
+** Description Set NDEF contents
+**
+** Returns void
+**
+*******************************************************************************/
+tNFC_STATUS nfa_ce_set_content (void)
+{
+ tNFC_STATUS status;
+ tNFA_CE_CB *p_cb = &nfa_ce_cb;
+ tNFA_PROTOCOL_MASK ndef_protocol_mask;
+ BOOLEAN readonly;
+
+ /* Check if listening for NDEF */
+ if (!(p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags & NFA_CE_LISTEN_INFO_IN_USE))
+ {
+ /* Not listening for NDEF */
+ return (NFA_STATUS_OK);
+ }
+
+ NFA_TRACE_DEBUG0 ("Setting NDEF contents");
+
+ readonly = (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags & NFC_CE_LISTEN_INFO_READONLY_NDEF) ? TRUE : FALSE;
+ ndef_protocol_mask = p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask;
+
+ /* Allocate a scratch buffer if needed (for handling write-requests) */
+ if ((status = nfa_ce_realloc_scratch_buffer ()) == NFA_STATUS_OK)
+ {
+ if ((ndef_protocol_mask & NFA_PROTOCOL_MASK_T3T) && (status == NFA_STATUS_OK))
+ {
+ /* Type3Tag - NFC-F */
+ status = CE_T3tSetLocalNDEFMsg (readonly,
+ p_cb->ndef_max_size,
+ p_cb->ndef_cur_size,
+ p_cb->p_ndef_data,
+ p_cb->p_scratch_buf);
+ }
+
+ if ((ndef_protocol_mask & NFA_PROTOCOL_MASK_ISO_DEP) && (status == NFA_STATUS_OK))
+ {
+ /* ISODEP/4A,4B- NFC-A or NFC-B */
+ status = CE_T4tSetLocalNDEFMsg (readonly,
+ p_cb->ndef_max_size,
+ p_cb->ndef_cur_size,
+ p_cb->p_ndef_data,
+ p_cb->p_scratch_buf);
+ }
+ }
+
+ if (status != NFA_STATUS_OK)
+ {
+ /* clear NDEF contents */
+ CE_T3tSetLocalNDEFMsg (TRUE, 0, 0, NULL, NULL);
+ CE_T4tSetLocalNDEFMsg (TRUE, 0, 0, NULL, NULL);
+
+ NFA_TRACE_ERROR1 ("Unable to set contents (error %02x)", status);
+ }
+
+ return (status);
+}
+
+
+/*******************************************************************************
+**
+** Function nfa_ce_activate_ntf
+**
+** Description Action when activation has occured (NFA_CE_ACTIVATE_NTF_EVT)
+**
+** - Find the listen_info entry assocated with this activation
+** - get the app callback that registered for this listen
+** - call CE_SetActivatedTagType with activation parameters
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_ce_activate_ntf (tNFA_CE_MSG *p_ce_msg)
+{
+ tNFC_ACTIVATE_DEVT *p_activation_params = p_ce_msg->activate_ntf.p_activation_params;
+ tNFA_CE_CB *p_cb = &nfa_ce_cb;
+ tNFA_CONN_EVT_DATA conn_evt;
+ tCE_CBACK *p_ce_cback = NULL;
+ UINT16 t3t_system_code = 0xFFFF;
+ UINT8 listen_info_idx = NFA_CE_LISTEN_INFO_IDX_INVALID;
+ UINT8 *p_nfcid2 = NULL;
+ UINT8 i;
+ BOOLEAN t4t_activate_pending = FALSE;
+
+ NFA_TRACE_DEBUG1 ("nfa_ce_activate_ntf () protocol=%d", p_ce_msg->activate_ntf.p_activation_params->protocol);
+
+ /* Tag is in listen active state */
+ p_cb->flags |= NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP;
+
+ /* Store activation parameters */
+ memcpy (&p_cb->activation_params, p_activation_params, sizeof (tNFC_ACTIVATE_DEVT));
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ if (p_cb->activation_params.intf_param.type == NCI_INTERFACE_UICC_DIRECT || p_cb->activation_params.intf_param.type == 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)
+#else
+ /* Find the listen_info entry corresponding to this activation */
+ if (p_cb->activation_params.protocol == NFA_PROTOCOL_T3T)
+#endif
+ {
+ /* 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;
+ }
+ }
+
+#if (NFC_NXP_NOT_OPEN_INCLUDED == FALSE)
+ /* 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;
+ }
+#endif
+ }
+ }
+
+ p_ce_cback = nfa_ce_handle_t3t_evt;
+ }
+ else if (p_cb->activation_params.protocol == NFA_PROTOCOL_ISO_DEP)
+ {
+ p_ce_cback = nfa_ce_handle_t4t_evt;
+
+ /* For T4T, we do not know which AID will be selected yet */
+
+
+ /* For all T4T entries in listen_info, set T4T_ACTIVATE_NOTIFY_PENDING flag */
+ for (i=0; i<NFA_CE_LISTEN_INFO_IDX_INVALID; i++)
+ {
+ if (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE)
+ {
+ if (p_cb->listen_info[i].protocol_mask & NFA_PROTOCOL_MASK_ISO_DEP)
+ {
+ /* Found listen_info table entry for T4T raw listen */
+ p_cb->listen_info[i].flags |= NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND;
+
+ /* If entry if for NDEF, select it, so application gets nofitifed of ACTIVATE_EVT now */
+ if (i == NFA_CE_LISTEN_INFO_IDX_NDEF)
+ {
+ listen_info_idx = NFA_CE_LISTEN_INFO_IDX_NDEF;
+ }
+
+ t4t_activate_pending = TRUE;
+ }
+
+#if (NFC_NFCEE_INCLUDED == TRUE)
+ /* Check if entry is for ISO_DEP UICC */
+ if (p_cb->listen_info[i].flags &
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ (NFA_CE_LISTEN_INFO_UICC | NFA_CE_LISTEN_INFO_ESE)
+#else
+ NFA_CE_LISTEN_INFO_UICC
+#endif
+ ))
+ {
+ listen_info_idx = i;
+ break;
+ }
+ }
+ }
+
+#if (NFC_NXP_NOT_OPEN_INCLUDED == 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;
+
+ /* 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(NFC_NXP_NOT_OPEN_INCLUDED == 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)
+**
+*******************************************************************************/
+BOOLEAN nfa_ce_deactivate_ntf (tNFA_CE_MSG *p_ce_msg)
+{
+ tNFC_DEACT_TYPE deact_type = (tNFC_DEACT_TYPE) p_ce_msg->hdr.layer_specific;
+ tNFA_CE_CB *p_cb = &nfa_ce_cb;
+ tNFA_CONN_EVT_DATA conn_evt;
+ UINT8 i;
+
+ NFA_TRACE_DEBUG1 ("nfa_ce_deactivate_ntf () deact_type=%d", deact_type);
+
+ /* Check if deactivating to SLEEP mode */
+ if ( (deact_type == NFC_DEACTIVATE_TYPE_SLEEP)
+ ||(deact_type == NFC_DEACTIVATE_TYPE_SLEEP_AF) )
+ {
+ 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(NFC_NXP_NOT_OPEN_INCLUDED == 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 (i == NFA_CE_LISTEN_INFO_IDX_NDEF)
+ {
+ conn_evt.deactivated.type = deact_type;
+ (*p_cb->p_active_conn_cback) (NFA_DEACTIVATED_EVT, &conn_evt);
+ }
+ else
+ {
+ conn_evt.ce_deactivated.handle = NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)i);
+ conn_evt.ce_deactivated.type = deact_type;
+ (*p_cb->p_active_conn_cback) (NFA_CE_DEACTIVATED_EVT, &conn_evt);
+ }
+ }
+ }
+ }
+
+ /* Check if app initiated the deactivation (due to API deregister). If so, remove entry from listen_info table. */
+ if (p_cb->flags & NFA_CE_FLAGS_APP_INIT_DEACTIVATION)
+ {
+ p_cb->flags &= ~NFA_CE_FLAGS_APP_INIT_DEACTIVATION;
+ nfa_ce_remove_listen_info_entry (p_cb->idx_cur_active, TRUE);
+ }
+
+ p_cb->p_active_conn_cback = NULL;
+ p_cb->idx_cur_active = NFA_CE_LISTEN_INFO_IDX_INVALID;
+
+ /* Restart listening (if any listen_info entries are still active) */
+ nfa_ce_restart_listen_check ();
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_ce_disable_local_tag
+**
+** Description Disable local NDEF tag
+** - clean up control block
+** - remove NDEF discovery configuration
+**
+** Returns Nothing
+**
+*******************************************************************************/
+void nfa_ce_disable_local_tag (void)
+{
+ tNFA_CE_CB *p_cb = &nfa_ce_cb;
+ tNFA_CONN_EVT_DATA evt_data;
+
+ NFA_TRACE_DEBUG0 ("Disabling local NDEF tag");
+
+ /* If local NDEF tag is in use, then disable it */
+ if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags & NFA_CE_LISTEN_INFO_IN_USE)
+ {
+ /* NDEF Tag is in not idle state */
+ if ( (p_cb->flags & NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP)
+ &&(p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF) )
+ {
+ /* wait for deactivation */
+ p_cb->flags |= NFA_CE_FLAGS_APP_INIT_DEACTIVATION;
+ nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_IDLE);
+ }
+ else
+ {
+ /* Notify DM to stop listening for ndef */
+ if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle != NFA_HANDLE_INVALID)
+ {
+ nfa_dm_delete_rf_discover (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle);
+ p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle = NFA_HANDLE_INVALID;
+ }
+ nfa_ce_remove_listen_info_entry (NFA_CE_LISTEN_INFO_IDX_NDEF, TRUE);
+ }
+ }
+ else
+ {
+ /* Notify application */
+ evt_data.status = NFA_STATUS_OK;
+ nfa_dm_conn_cback_event_notify (NFA_CE_LOCAL_TAG_CONFIGURED_EVT, &evt_data);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_ce_api_cfg_local_tag
+**
+** Description Configure local NDEF tag
+** - store ndef attributes in to control block
+** - update discovery configuration
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_ce_api_cfg_local_tag (tNFA_CE_MSG *p_ce_msg)
+{
+ tNFA_CE_CB *p_cb = &nfa_ce_cb;
+ tNFA_CONN_EVT_DATA conn_evt;
+
+ /* Check if disabling local tag */
+ if (p_ce_msg->local_tag.protocol_mask == 0)
+ {
+ nfa_ce_disable_local_tag ();
+ return TRUE;
+ }
+
+ NFA_TRACE_DEBUG5 ("Configuring local NDEF tag: protocol_mask=%01x cur_size=%i, max_size=%i, readonly=%i",
+ p_ce_msg->local_tag.protocol_mask,
+ p_ce_msg->local_tag.ndef_cur_size,
+ p_ce_msg->local_tag.ndef_max_size,
+ p_ce_msg->local_tag.read_only,
+ p_ce_msg->local_tag.uid_len);
+
+ /* If local tag was already set, then check if NFA_CeConfigureLocalTag called to change protocol mask */
+ if ( (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags & NFA_CE_LISTEN_INFO_IN_USE)
+ &&(p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle != NFA_HANDLE_INVALID)
+ &&((p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask & (NFA_PROTOCOL_MASK_T3T | NFA_PROTOCOL_MASK_ISO_DEP))
+ != (p_ce_msg->local_tag.protocol_mask & (NFA_PROTOCOL_MASK_T3T | NFA_PROTOCOL_MASK_ISO_DEP))) )
+ {
+ /* Listening for different tag protocols. Stop discovery */
+ nfa_dm_delete_rf_discover (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle);
+ p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle = NFA_HANDLE_INVALID;
+
+ /* clear NDEF contents */
+ CE_T3tSetLocalNDEFMsg (TRUE, 0, 0, NULL, NULL);
+ CE_T4tSetLocalNDEFMsg (TRUE, 0, 0, NULL, NULL);
+ }
+
+ /* Store NDEF info to control block */
+ p_cb->p_ndef_data = p_ce_msg->local_tag.p_ndef_data;
+ p_cb->ndef_cur_size = p_ce_msg->local_tag.ndef_cur_size;
+ p_cb->ndef_max_size = p_ce_msg->local_tag.ndef_max_size;
+
+ /* Fill in LISTEN_INFO entry for NDEF */
+ p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags = NFA_CE_LISTEN_INFO_IN_USE;
+ p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask = p_ce_msg->local_tag.protocol_mask;
+ p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].p_conn_cback = nfa_dm_conn_cback_event_notify;
+ if (p_ce_msg->local_tag.read_only)
+ p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags |= NFC_CE_LISTEN_INFO_READONLY_NDEF;
+ p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].t3t_system_code = T3T_SYSTEM_CODE_NDEF;
+
+ /* Set NDEF contents */
+ conn_evt.status = NFA_STATUS_FAILED;
+
+ if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask & (NFA_PROTOCOL_MASK_T3T | NFA_PROTOCOL_MASK_ISO_DEP))
+ {
+ /* Ok to set contents now */
+ if (nfa_ce_set_content () != NFA_STATUS_OK)
+ {
+ NFA_TRACE_ERROR0 ("nfa_ce_api_cfg_local_tag: could not set contents");
+ nfa_dm_conn_cback_event_notify (NFA_CE_LOCAL_TAG_CONFIGURED_EVT, &conn_evt);
+ return TRUE;
+ }
+
+ /* Start listening and notify app of status */
+ conn_evt.status = nfa_ce_start_listening ();
+ nfa_dm_conn_cback_event_notify (NFA_CE_LOCAL_TAG_CONFIGURED_EVT, &conn_evt);
+ }
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_ce_api_reg_listen
+**
+** Description Register listen params for Felica system code, T4T AID,
+** or UICC
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_ce_api_reg_listen (tNFA_CE_MSG *p_ce_msg)
+{
+ tNFA_CE_CB *p_cb = &nfa_ce_cb;
+ tNFA_CONN_EVT_DATA conn_evt;
+ UINT8 i;
+ UINT8 listen_info_idx = NFA_CE_LISTEN_INFO_IDX_INVALID;
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ NFA_TRACE_DEBUG1 ("Registering UICC/ESE/Felica/Type-4 tag listener. Type=%i", p_ce_msg->reg_listen.listen_type);
+#else
+ NFA_TRACE_DEBUG1 ("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(NFC_NXP_NOT_OPEN_INCLUDED == 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;
+ }
+ }
+
+ /* 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(NFC_NXP_NOT_OPEN_INCLUDED == 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 */
+ if ((p_cb->listen_info[listen_info_idx].t4t_aid_handle = CE_T4tRegisterAID (p_ce_msg->reg_listen.aid_len,
+ p_ce_msg->reg_listen.aid,
+ nfa_ce_handle_t4t_aid_evt)) == 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);
+ break;
+
+#if (NFC_NFCEE_INCLUDED == TRUE)
+ case NFA_CE_REG_TYPE_UICC:
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+
+ for (i=1; i<NFA_CE_LISTEN_INFO_MAX; i++)
+ {
+ UINT8 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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ case NFA_CE_REG_TYPE_ESE:
+
+ for (i=1; i<NFA_CE_LISTEN_INFO_MAX; i++)
+ {
+ UINT8 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 */
+ if ((conn_evt.status = nfa_ce_start_listening ()) != NFA_STATUS_OK)
+ {
+ NFA_TRACE_ERROR0 ("nfa_ce_api_reg_listen: unable to register new listen params with DM");
+ p_cb->listen_info[listen_info_idx].flags = 0;
+ }
+
+ /* Nofitify app of status */
+ if (p_ce_msg->reg_listen.listen_type == NFA_CE_REG_TYPE_UICC)
+ {
+ (*p_cb->listen_info[listen_info_idx].p_conn_cback) (NFA_CE_UICC_LISTEN_CONFIGURED_EVT, &conn_evt);
+ }
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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)
+**
+*******************************************************************************/
+BOOLEAN nfa_ce_api_dereg_listen (tNFA_CE_MSG *p_ce_msg)
+{
+ tNFA_CE_CB *p_cb = &nfa_ce_cb;
+ UINT8 listen_info_idx;
+ tNFA_CONN_EVT_DATA conn_evt;
+
+#if (NFC_NFCEE_INCLUDED == TRUE)
+ /* Check if deregistering UICC/ESE , or virtual secure element listen */
+ if (p_ce_msg->dereg_listen.listen_info
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED == 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)
+ {
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ NFA_TRACE_ERROR0 ("nfa_ce_api_dereg_listen (): cannot find listen_info for UICC/ESE");
+#else
+ NFA_TRACE_ERROR0 ("nfa_ce_api_dereg_listen (): cannot find listen_info for UICC");
+#endif
+ conn_evt.status = NFA_STATUS_INVALID_PARAM;
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ 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_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)
+**
+*******************************************************************************/
+BOOLEAN nfa_ce_api_cfg_isodep_tech (tNFA_CE_MSG *p_ce_msg)
+{
+ nfa_ce_cb.isodep_disc_mask = 0;
+ if (p_ce_msg->hdr.layer_specific & NFA_TECHNOLOGY_MASK_A)
+ nfa_ce_cb.isodep_disc_mask = NFA_DM_DISC_MASK_LA_ISO_DEP;
+
+ if (p_ce_msg->hdr.layer_specific & NFA_TECHNOLOGY_MASK_B)
+ nfa_ce_cb.isodep_disc_mask |= NFA_DM_DISC_MASK_LB_ISO_DEP;
+ return TRUE;
+}
diff --git a/src/nfa/ce/nfa_ce_api.c b/src/nfa/ce/nfa_ce_api.c
new file mode 100644
index 0000000..e578851
--- /dev/null
+++ b/src/nfa/ce/nfa_ce_api.c
@@ -0,0 +1,506 @@
+/******************************************************************************
+ *
+ * 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 listen_info)
+{
+ tNFA_CE_MSG *p_ce_msg;
+
+ /* Validate handle */
+ if ( (listen_info != NFA_CE_LISTEN_INFO_UICC
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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);
+ }
+
+ if ((p_ce_msg = (tNFA_CE_MSG *) GKI_getbuf ((UINT16) (sizeof (tNFA_CE_MSG)))) != NULL)
+ {
+ p_ce_msg->hdr.event = NFA_CE_API_DEREG_LISTEN_EVT;
+ p_ce_msg->dereg_listen.handle = handle;
+ p_ce_msg->dereg_listen.listen_info = listen_info;
+
+ nfa_sys_sendmsg (p_ce_msg);
+
+ return (NFA_STATUS_OK);
+ }
+ else
+ {
+ NFA_TRACE_ERROR0 ("nfa_ce_api_reregister_listen: Out of buffers");
+ return (NFA_STATUS_FAILED);
+ }
+}
+
+/*****************************************************************************
+** APIs
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function NFA_CeConfigureLocalTag
+**
+** Description Configure local NDEF tag.
+**
+** Tag events will be notifed using the tNFA_CONN_CBACK
+** (registered during NFA_Enable)
+**
+** The NFA_CE_LOCAL_TAG_CONFIGURED_EVT reports the status of the
+** operation.
+**
+** Activation and deactivation are reported using the
+** NFA_ACTIVATED_EVT and NFA_DEACTIVATED_EVT events
+**
+** If a write-request is received to update the tag memory,
+** an NFA_CE_NDEF_WRITE_CPLT_EVT will notify the application, along
+** with a buffer containing the updated contents.
+**
+** To disable the local NDEF tag, set protocol_mask=0
+**
+** The NDEF data provided by p_ndef_data must be persistent
+** as long as the local NDEF tag is enabled.
+**
+**
+** 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 *p_ndef_data,
+ UINT16 ndef_cur_size,
+ UINT16 ndef_max_size,
+ BOOLEAN read_only,
+ UINT8 uid_len,
+ UINT8 *p_uid)
+
+{
+ tNFA_CE_MSG *p_msg;
+
+ NFA_TRACE_API0 ("NFA_CeConfigureLocalTag ()");
+
+ if (protocol_mask)
+ {
+ /* If any protocols are specified, then NDEF buffer pointer must be non-NULL */
+ if (p_ndef_data == NULL)
+ {
+ NFA_TRACE_ERROR0 ("NFA_CeConfigureLocalTag: NULL ndef data pointer");
+ return (NFA_STATUS_INVALID_PARAM);
+ }
+
+ if ((protocol_mask & NFA_PROTOCOL_MASK_T1T) || (protocol_mask & NFA_PROTOCOL_MASK_T2T))
+ {
+ NFA_TRACE_ERROR0 ("NFA_CeConfigureLocalTag: Cannot emulate 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);
+ }
+ }
+ if ((p_msg = (tNFA_CE_MSG *) GKI_getbuf ((UINT16) sizeof(tNFA_CE_MSG))) != NULL)
+ {
+ p_msg->local_tag.hdr.event = NFA_CE_API_CFG_LOCAL_TAG_EVT;
+
+ /* Copy ndef info */
+ p_msg->local_tag.protocol_mask = protocol_mask;
+ p_msg->local_tag.p_ndef_data = p_ndef_data;
+ p_msg->local_tag.ndef_cur_size = ndef_cur_size;
+ p_msg->local_tag.ndef_max_size = ndef_max_size;
+ p_msg->local_tag.read_only = read_only;
+ p_msg->local_tag.uid_len = uid_len;
+
+ if (uid_len)
+ memcpy (p_msg->local_tag.uid, p_uid, uid_len);
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+
+/*******************************************************************************
+**
+** Function NFA_CeConfigureUiccListenTech
+**
+** Description Configure listening for the UICC, using the specified
+** technologies.
+**
+** Events will be notifed using the tNFA_CONN_CBACK
+** (registered during NFA_Enable)
+**
+** The NFA_CE_UICC_LISTEN_CONFIGURED_EVT reports the status of the
+** operation.
+**
+** Activation and deactivation are reported using the
+** NFA_ACTIVATED_EVT and NFA_DEACTIVATED_EVT events
+**
+** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function
+**
+** Returns:
+** NFA_STATUS_OK, if command accepted
+** NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_CeConfigureUiccListenTech (tNFA_HANDLE ee_handle,
+ tNFA_TECHNOLOGY_MASK tech_mask)
+{
+#if (NFC_NFCEE_INCLUDED == TRUE)
+ tNFA_CE_MSG *p_msg;
+
+ NFA_TRACE_API1 ("NFA_CeConfigureUiccListenTech () ee_handle = 0x%x", ee_handle);
+
+ /* If tech_mask is zero, then app is disabling listening for specified uicc */
+ if (tech_mask == 0)
+ {
+ return (nfa_ce_api_deregister_listen (ee_handle, NFA_CE_LISTEN_INFO_UICC));
+ }
+
+ /* Otherwise then app is configuring uicc listen for the specificed technologies */
+ if ((p_msg = (tNFA_CE_MSG *) GKI_getbuf ((UINT16) sizeof(tNFA_CE_MSG))) != NULL)
+ {
+ p_msg->reg_listen.hdr.event = NFA_CE_API_REG_LISTEN_EVT;
+ p_msg->reg_listen.listen_type = NFA_CE_REG_TYPE_UICC;
+
+ p_msg->reg_listen.ee_handle = ee_handle;
+ p_msg->reg_listen.tech_mask = tech_mask;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+#else
+ NFA_TRACE_ERROR0 ("NFA_CeConfigureUiccListenTech () NFCEE related functions are not enabled!");
+#endif
+ return (NFA_STATUS_FAILED);
+}
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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) 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 system_code,
+ UINT8 nfcid2[NCI_RF_F_UID_LEN],
+ tNFA_CONN_CBACK *p_conn_cback)
+{
+ tNFA_CE_MSG *p_msg;
+
+ NFA_TRACE_API0 ("NFA_CeRegisterFelicaSystemCodeOnDH ()");
+
+ /* Validate parameters */
+ if (p_conn_cback==NULL)
+ return (NFA_STATUS_INVALID_PARAM);
+
+ if ((p_msg = (tNFA_CE_MSG *) GKI_getbuf ((UINT16) sizeof(tNFA_CE_MSG))) != NULL)
+ {
+ p_msg->reg_listen.hdr.event = NFA_CE_API_REG_LISTEN_EVT;
+ p_msg->reg_listen.p_conn_cback = p_conn_cback;
+ p_msg->reg_listen.listen_type = NFA_CE_REG_TYPE_FELICA;
+
+ /* Listen info */
+ memcpy (p_msg->reg_listen.nfcid2, nfcid2, NCI_RF_F_UID_LEN);
+ p_msg->reg_listen.system_code = system_code;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_CeDeregisterFelicaSystemCodeOnDH
+**
+** Description Deregister listening callback for Felica
+** (previously registered using NFA_CeRegisterFelicaSystemCodeOnDH)
+**
+** The NFA_CE_DEREGISTERED_EVT reports the status of the
+** operation.
+**
+** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if invalid handle
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_CeDeregisterFelicaSystemCodeOnDH (tNFA_HANDLE handle)
+{
+ NFA_TRACE_API1 ("NFA_CeDeregisterFelicaSystemCodeOnDH (): handle:0x%X", handle);
+ return (nfa_ce_api_deregister_listen (handle, NFA_CE_LISTEN_INFO_FELICA));
+}
+
+/*******************************************************************************
+**
+** Function NFA_CeRegisterAidOnDH
+**
+** Description Register listening callback for the specified ISODEP AID
+**
+** The NFA_CE_REGISTERED_EVT reports the status of the
+** operation.
+**
+** If no AID is specified (aid_len=0), then p_conn_cback will
+** will get notifications for any AIDs routed to the DH. This
+** over-rides callbacks registered for specific AIDs.
+**
+** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function
+**
+** Returns:
+** NFA_STATUS_OK, if command accepted
+** NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_CeRegisterAidOnDH (UINT8 aid[NFC_MAX_AID_LEN],
+ UINT8 aid_len,
+ tNFA_CONN_CBACK *p_conn_cback)
+{
+ tNFA_CE_MSG *p_msg;
+
+ NFA_TRACE_API0 ("NFA_CeRegisterAidOnDH ()");
+
+ /* Validate parameters */
+ if (p_conn_cback==NULL)
+ return (NFA_STATUS_INVALID_PARAM);
+
+ if ((p_msg = (tNFA_CE_MSG *) GKI_getbuf ((UINT16) sizeof(tNFA_CE_MSG))) != NULL)
+ {
+ p_msg->reg_listen.hdr.event = NFA_CE_API_REG_LISTEN_EVT;
+ p_msg->reg_listen.p_conn_cback = p_conn_cback;
+ p_msg->reg_listen.listen_type = NFA_CE_REG_TYPE_ISO_DEP;
+
+ /* Listen info */
+ memcpy (p_msg->reg_listen.aid, aid, aid_len);
+ p_msg->reg_listen.aid_len = aid_len;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_CeDeregisterAidOnDH
+**
+** Description Deregister listening callback for ISODEP AID
+** (previously registered using NFA_CeRegisterAidOnDH)
+**
+** The NFA_CE_DEREGISTERED_EVT reports the status of the
+** operation.
+**
+** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if invalid handle
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_CeDeregisterAidOnDH (tNFA_HANDLE handle)
+{
+ NFA_TRACE_API1 ("NFA_CeDeregisterAidOnDH (): handle:0x%X", handle);
+ return (nfa_ce_api_deregister_listen (handle, NFA_CE_LISTEN_INFO_T4T_AID));
+}
+
+/*******************************************************************************
+**
+** Function NFA_CeSetIsoDepListenTech
+**
+** Description Set the technologies (NFC-A and/or NFC-B) to listen for when
+** NFA_CeConfigureLocalTag or NFA_CeDeregisterAidOnDH are called.
+**
+** By default (if this API is not called), NFA will listen
+** for both NFC-A and NFC-B for ISODEP.
+**
+** Note: If listening for ISODEP on UICC, the DH listen callbacks
+** may still get activate notifications for ISODEP if the reader/
+** writer selects an AID that is not routed to the UICC (regardless
+** of whether A or B was disabled using NFA_CeSetIsoDepListenTech)
+**
+** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function
+**
+** Returns:
+** NFA_STATUS_OK, if command accepted
+** NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_CeSetIsoDepListenTech (tNFA_TECHNOLOGY_MASK tech_mask)
+{
+ tNFA_CE_MSG *p_msg;
+ tNFA_TECHNOLOGY_MASK use_mask = (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B);
+
+ NFA_TRACE_API1 ("NFA_CeSetIsoDepListenTech (): 0x%x", tech_mask);
+ if (((tech_mask & use_mask) == 0) ||
+ ((tech_mask & ~use_mask) != 0) )
+ {
+ NFA_TRACE_ERROR0 ("NFA_CeSetIsoDepListenTech: Invalid technology mask");
+ return (NFA_STATUS_INVALID_PARAM);
+ }
+
+ if ((p_msg = (tNFA_CE_MSG *) GKI_getbuf ((UINT16) sizeof(tNFA_CE_MSG))) != NULL)
+ {
+ p_msg->hdr.event = NFA_CE_API_CFG_ISODEP_TECH_EVT;
+ p_msg->hdr.layer_specific = tech_mask;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
diff --git a/src/nfa/ce/nfa_ce_main.c b/src/nfa/ce/nfa_ce_main.c
new file mode 100644
index 0000000..0ca541c
--- /dev/null
+++ b/src/nfa/ce/nfa_ce_main.c
@@ -0,0 +1,236 @@
+/******************************************************************************
+ *
+ * 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 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 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 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 nfcc_power_mode)
+{
+ tNFA_CE_CB *p_cb = &nfa_ce_cb;
+ UINT8 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 BOOLEAN
+**
+*******************************************************************************/
+BOOLEAN nfa_ce_hdl_event (BT_HDR *p_msg)
+{
+ UINT16 act_idx;
+ BOOLEAN freebuf = TRUE;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ NFA_TRACE_EVENT3 ("nfa_ce_handle_event event: %s (0x%02x), flags: %08x", nfa_ce_evt_2_str (p_msg->event), p_msg->event, nfa_ce_cb.flags);
+#else
+ NFA_TRACE_EVENT2 ("nfa_ce_handle_event event: 0x%x, flags: %08x",p_msg->event, nfa_ce_cb.flags);
+#endif
+
+ /* Get NFA_RW sub-event */
+ if ((act_idx = (p_msg->event & 0x00FF)) < NFA_CE_ACTION_TBL_SIZE)
+ {
+ freebuf = (*nfa_ce_action_tbl[act_idx]) ((tNFA_CE_MSG*) p_msg);
+ }
+
+ /* if vendor specific event handler is registered */
+ if (nfa_ce_cb.p_vs_evt_hdlr)
+ {
+ (*nfa_ce_cb.p_vs_evt_hdlr) (p_msg);
+ }
+
+ return freebuf;
+}
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function nfa_ce_evt_2_str
+**
+** Description convert nfc evt to string
+**
+*******************************************************************************/
+static char *nfa_ce_evt_2_str (UINT16 event)
+{
+ switch (event)
+ {
+ case NFA_CE_API_CFG_LOCAL_TAG_EVT:
+ return "NFA_CE_API_CFG_LOCAL_TAG_EVT";
+
+ case NFA_CE_API_REG_LISTEN_EVT:
+ return "NFA_CE_API_REG_LISTEN_EVT";
+
+ case NFA_CE_API_DEREG_LISTEN_EVT:
+ return "NFA_CE_API_DEREG_LISTEN_EVT";
+
+ case NFA_CE_API_CFG_ISODEP_TECH_EVT:
+ return "NFA_CE_API_CFG_ISODEP_TECH_EVT";
+
+ case NFA_CE_ACTIVATE_NTF_EVT:
+ return "NFA_CE_ACTIVATE_NTF_EVT";
+
+ case NFA_CE_DEACTIVATE_NTF_EVT:
+ return "NFA_CE_DEACTIVATE_NTF_EVT";
+
+ default:
+ return "Unknown";
+ }
+}
+#endif /* BT_TRACE_VERBOSE */
diff --git a/src/nfa/dm/nfa_dm_act.c b/src/nfa/dm/nfa_dm_act.c
new file mode 100644
index 0000000..4cf48a7
--- /dev/null
+++ b/src/nfa/dm/nfa_dm_act.c
@@ -0,0 +1,2116 @@
+/******************************************************************************
+ *
+ * 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 (defined (NFA_CHO_INCLUDED) && (NFA_CHO_INCLUDED==TRUE))
+#include "nfa_cho_int.h"
+#endif
+
+#if (NFC_NFCEE_INCLUDED == TRUE)
+#include "nfa_ee_int.h"
+#include "nfa_hci_int.h"
+#endif
+
+#if (defined (NFA_SNEP_INCLUDED) && (NFA_SNEP_INCLUDED==TRUE))
+#include "nfa_snep_int.h"
+#endif
+
+/* This is the timeout value to guarantee disable is performed within reasonable amount of time */
+#ifndef NFA_DM_DISABLE_TIMEOUT_VAL
+#define NFA_DM_DISABLE_TIMEOUT_VAL 1000
+#endif
+
+static void nfa_dm_set_init_nci_params (void);
+static tNFA_STATUS nfa_dm_start_polling (void);
+static BOOLEAN nfa_dm_deactivate_polling (void);
+static void nfa_dm_excl_disc_cback (tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER *p_data);
+static void nfa_dm_poll_disc_cback (tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER *p_data);
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+extern BOOLEAN 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, (tNFA_DM_CBACK_DATA*) &power_mode_change);
+}
+/*******************************************************************************
+**
+** Function nfa_dm_sys_enable
+**
+** Description This function on enable
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_dm_sys_enable (void)
+{
+ nfa_dm_set_init_nci_params ();
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_set_init_nci_params
+**
+** Description Set initial NCI configuration parameters
+**
+** Returns void
+**
+*******************************************************************************/
+static void nfa_dm_set_init_nci_params (void)
+{
+ UINT8 xx;
+
+ /* set NCI default value if other than zero */
+
+ /* LF_T3T_IDENTIFIERS_1/2/.../16 */
+ for (xx = 0; xx < NFA_CE_LISTEN_INFO_MAX; xx++)
+ {
+ nfa_dm_cb.params.lf_t3t_id[xx][0] = 0xFF;
+ nfa_dm_cb.params.lf_t3t_id[xx][1] = 0xFF;
+ nfa_dm_cb.params.lf_t3t_id[xx][2] = 0x02;
+ nfa_dm_cb.params.lf_t3t_id[xx][2] = 0xFE;
+ }
+
+ /* LF_T3T_PMM */
+ for (xx = 0; xx < NCI_PARAM_LEN_LF_T3T_PMM; xx++)
+ {
+ nfa_dm_cb.params.lf_t3t_pmm[xx] = 0xFF;
+ }
+
+ /* LF_T3T_FLAGS:
+ ** DH needs to set this configuration, even if default value (not listening) is used,
+ ** to let NFCC know of intention (not listening) of DH.
+ */
+
+ /* FWI */
+ nfa_dm_cb.params.fwi[0] = 0x04;
+
+ /* WT */
+ nfa_dm_cb.params.wt[0] = 14;
+
+ // LF_T3T_PMM is not supported.
+ /* Set CE default configuration */
+#if (NFC_NXP_NOT_OPEN_INCLUDED != 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)
+ {
+ NFC_DiscoveryMap (nfa_dm_num_dm_interface_mapping, p_nfa_dm_interface_mapping, NULL);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_proc_nfcc_power_mode
+**
+** Description Processing NFCC power mode changes
+**
+** Returns None
+**
+*******************************************************************************/
+void nfa_dm_proc_nfcc_power_mode (UINT8 nfcc_power_mode)
+{
+ NFA_TRACE_DEBUG1 ("nfa_dm_proc_nfcc_power_mode (): nfcc_power_mode=%d",
+ nfcc_power_mode);
+
+ /* if NFCC power mode is change to full power */
+ if (nfcc_power_mode == NFA_DM_PWR_MODE_FULL)
+ {
+ memset (&nfa_dm_cb.params, 0x00, sizeof (tNFA_DM_PARAMS));
+ NFA_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_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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ tNFA_GET_ROUTING *p_nfa_get_routing;
+#endif
+ tNFA_CONN_EVT_DATA conn_evt;
+ UINT8 dm_cback_evt;
+ UINT8 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 */
+
+ /* 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_DISABLE_REVT: /* 1 Disable event */
+ nfa_dm_disable_event ();
+ break;
+
+ case NFC_SET_CONFIG_REVT: /* 2 Set Config Response */
+ /* If this setconfig was due to NFA_SetConfig, then notify the app */
+ if (nfa_dm_cb.setcfg_pending_mask & 1) /* lsb=whether last NCI_SET_CONFIG was due to NFA_SetConfig */
+ {
+ dm_cback_data.set_config.status = p_data->set_config.status;
+ dm_cback_data.set_config.num_param_id = p_data->set_config.num_param_id;
+ memcpy (dm_cback_data.set_config.param_ids, p_data->set_config.param_ids, p_data->set_config.num_param_id);
+ (*nfa_dm_cb.p_dm_cback) (NFA_DM_SET_CONFIG_EVT, &dm_cback_data);
+ }
+
+ /* Update the pending mask */
+ if (nfa_dm_cb.setcfg_pending_num>0)
+ {
+ nfa_dm_cb.setcfg_pending_mask >>= 1;
+ nfa_dm_cb.setcfg_pending_num--;
+ }
+ else
+ {
+ /* This should not occur (means we got a SET_CONFIG_NTF that's unaccounted for */
+ NFA_TRACE_ERROR0 ("NFA received unexpected NFC_SET_CONFIG_REVT");
+ }
+ break;
+
+ case NFC_GET_CONFIG_REVT: /* 3 Get Config Response */
+ if (p_data->get_config.status == NFC_STATUS_OK)
+ {
+ if ((p_nfa_get_confg = (tNFA_GET_CONFIG *) GKI_getbuf ((UINT16) (sizeof (tNFA_GET_CONFIG) + p_data->get_config.tlv_size))) != NULL)
+ {
+ p_nfa_get_confg->status = NFA_STATUS_OK;
+ p_nfa_get_confg->tlv_size = p_data->get_config.tlv_size;
+ memcpy (p_nfa_get_confg->param_tlvs, p_data->get_config.p_param_tlvs, p_data->get_config.tlv_size);
+ (*nfa_dm_cb.p_dm_cback) (NFA_DM_GET_CONFIG_EVT, (tNFA_DM_CBACK_DATA *) p_nfa_get_confg);
+
+ GKI_freebuf (p_nfa_get_confg);
+ return;
+ }
+ else
+ {
+ NFA_TRACE_DEBUG0 ("nfa_dm_nfc_response_cback unable to allocate buffer");
+ }
+ }
+
+ /* Return result of getconfig to the app */
+ dm_cback_data.get_config.status = NFA_STATUS_FAILED;
+ (*nfa_dm_cb.p_dm_cback) (NFA_DM_GET_CONFIG_EVT, &dm_cback_data);
+ break;
+
+#if (NFC_NFCEE_INCLUDED == TRUE)
+ case NFC_NFCEE_DISCOVER_REVT: /* NFCEE Discover response */
+ case NFC_NFCEE_INFO_REVT: /* NFCEE Discover Notification */
+ case NFC_EE_ACTION_REVT: /* EE Action notification */
+ case NFC_NFCEE_MODE_SET_REVT: /* NFCEE Mode Set response */
+ case NFC_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 (nfa_dm_is_active() &&
+// (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_DISCOVERY) )
+// {
+// nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_IDLE);
+// }
+ nfa_ee_proc_evt (event, p_data);
+ break;
+
+#endif
+
+ case NFC_RF_FIELD_REVT: /* RF Field information */
+ dm_cback_data.rf_field.status = NFA_STATUS_OK;
+ dm_cback_data.rf_field.rf_field_status = p_data->rf_field.rf_field;
+ (*nfa_dm_cb.p_dm_cback) (NFA_DM_RF_FIELD_EVT, &dm_cback_data);
+ break;
+
+
+ case NFC_GET_ROUTING_REVT: /* Retrieve Routing response */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ if ((p_nfa_get_routing = (tNFA_GET_ROUTING *) GKI_getbuf ((UINT16) (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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ if (p_data->status == 0xE4) //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(NFC_NXP_ESE == TRUE && NFC_NXP_CHIP_TYPE == PN548C2)
+ 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);
+ dm_cback_evt = (event == NFC_NFCC_TIMEOUT_REVT) ? NFA_DM_NFCC_TIMEOUT_EVT : NFA_DM_NFCC_TRANSPORT_ERR_EVT;
+ (*nfa_dm_cb.p_dm_cback) (dm_cback_evt, NULL);
+ break;
+
+ case NFC_NFCC_POWER_OFF_REVT:
+ nfa_dm_cb.nfcc_pwr_mode = NFA_DM_PWR_MODE_OFF_SLEEP;
+
+ /* Notify NFA submodules change of NFCC power mode */
+ nfa_sys_cback_reg_nfcc_power_mode_proc_complete (nfa_dm_nfcc_power_mode_proc_complete_cback);
+ nfa_sys_notify_nfcc_power_mode (NFA_DM_PWR_MODE_OFF_SLEEP);
+ break;
+
+ case NFC_RF_COMM_PARAMS_UPDATE_REVT:
+ conn_evt.status = p_data->status;
+ nfa_dm_conn_cback_event_notify (NFA_UPDATE_RF_PARAM_RESULT_EVT, &conn_evt);
+ break;
+
+
+ default:
+ break;
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function nfa_dm_enable
+**
+** Description Initialises the NFC device manager
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_enable (tNFA_DM_MSG *p_data)
+{
+ tNFA_DM_CBACK_DATA dm_cback_data;
+ NFA_TRACE_DEBUG0 ("nfa_dm_enable ()");
+
+ /* Check if NFA is already enabled */
+ if (!(nfa_dm_cb.flags & NFA_DM_FLAGS_DM_IS_ACTIVE))
+ {
+ /* Initialize BRCM control block, it musb be called before setting any flags */
+ nfa_dm_cb.flags |= (NFA_DM_FLAGS_DM_IS_ACTIVE | NFA_DM_FLAGS_ENABLE_EVT_PEND);
+ nfa_sys_cback_reg_enable_complete (nfa_dm_module_init_cback);
+
+
+ /* Store Enable parameters */
+ nfa_dm_cb.p_dm_cback = p_data->enable.p_dm_cback;
+ nfa_dm_cb.p_conn_cback = p_data->enable.p_conn_cback;
+
+ /* Enable NFC stack */
+ NFC_Enable (nfa_dm_nfc_response_cback);
+ }
+ else
+ {
+ NFA_TRACE_ERROR0 ("nfa_dm_enable: ERROR ALREADY ENABLED.");
+ dm_cback_data.status = NFA_STATUS_ALREADY_STARTED;
+ (*(p_data->enable.p_dm_cback)) (NFA_DM_ENABLE_EVT, &dm_cback_data);
+ }
+
+ return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_disable
+**
+** Description Disables the NFC device manager
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_disable (tNFA_DM_MSG *p_data)
+{
+ tNFC_DEACT_TYPE deactivate_type = NFA_DEACTIVATE_TYPE_IDLE;
+
+ NFA_TRACE_DEBUG1 ("nfa_dm_disable (): graceful:%d", p_data->disable.graceful);
+
+ if (p_data->disable.graceful)
+ {
+ /* if RF discovery is enabled */
+ if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_ENABLED)
+ {
+ nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_ENABLED;
+
+ if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_IDLE)
+ {
+ /* if waiting RSP in idle state */
+ if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)
+ {
+ nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_DISABLING;
+ }
+ }
+ else
+ {
+ nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_DISABLING;
+ nfa_dm_disc_sm_execute (NFA_DM_RF_DEACTIVATE_CMD, (tNFA_DM_RF_DISC_DATA *) &deactivate_type);
+ if ((nfa_dm_cb.disc_cb.disc_flags & (NFA_DM_DISC_FLAGS_W4_RSP|NFA_DM_DISC_FLAGS_W4_NTF)) == 0)
+ {
+ /* not waiting to deactivate, clear the flag now */
+ nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_DISABLING;
+ }
+ }
+ }
+ /* Start timeout for graceful shutdown. If timer expires, then force an ungraceful shutdown */
+ nfa_sys_start_timer (&nfa_dm_cb.tle, NFA_DM_TIMEOUT_DISABLE_EVT, NFA_DM_DISABLE_TIMEOUT_VAL);
+ }
+
+ /* Disable all subsystems other than DM (DM will be disabled after all */
+ /* the other subsystem have been disabled) */
+ nfa_sys_disable_subsystems (p_data->disable.graceful);
+ return (TRUE);
+}
+
+
+/*******************************************************************************
+**
+** Function nfa_dm_disable_complete
+**
+** Description Called when all NFA subsytems are disabled.
+**
+** NFC core stack can now be disabled.
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_dm_disable_complete (void)
+{
+ NFA_TRACE_DEBUG0 ("nfa_dm_disable_complete ()");
+
+ if ((nfa_dm_cb.flags & NFA_DM_FLAGS_DM_DISABLING_NFC) == 0)
+ {
+ NFA_TRACE_DEBUG0 ("nfa_dm_disable_complete (): proceeding with nfc core shutdown.");
+
+ nfa_dm_cb.flags |= NFA_DM_FLAGS_DM_DISABLING_NFC;
+
+ nfa_sys_stop_timer (&nfa_dm_cb.tle);
+
+ /* Free all buffers for NDEF handlers */
+ nfa_dm_ndef_dereg_all();
+
+ /* Disable nfc core stack */
+ NFC_Disable ();
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_set_config
+**
+** Description Process set config command
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_set_config (tNFA_DM_MSG *p_data)
+{
+ tNFC_STATUS status;
+ UINT8 buff[255];
+ UINT8 *p = buff;
+
+ tNFA_DM_CBACK_DATA dm_cback_data;
+
+ if (p_data->setconfig.length + 2 > 255)
+ {
+ /* Total length of TLV must be less than 256 (1 byte) */
+ status = NFC_STATUS_FAILED;
+ }
+ else
+ {
+ UINT8_TO_STREAM (p, p_data->setconfig.param_id);
+ UINT8_TO_STREAM (p, p_data->setconfig.length);
+ ARRAY_TO_STREAM (p, p_data->setconfig.p_data, p_data->setconfig.length)
+ status = nfa_dm_check_set_config ((UINT8) (p_data->setconfig.length + 2), buff, TRUE);
+ }
+
+ if (status != NFC_STATUS_OK)
+ {
+ dm_cback_data.set_config.status = NFA_STATUS_INVALID_PARAM;
+ (*nfa_dm_cb.p_dm_cback) (NFA_DM_SET_CONFIG_EVT, &dm_cback_data);
+ }
+
+ return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_get_config
+**
+** Description Process get config command
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_get_config (tNFA_DM_MSG *p_data)
+{
+ NFC_GetConfig (p_data->getconfig.num_ids, p_data->getconfig.p_pmids);
+
+ return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_conn_cback_event_notify
+**
+** Description Notify application of CONN_CBACK event, using appropriate
+** callback
+**
+** Returns nothing
+**
+*******************************************************************************/
+void nfa_dm_conn_cback_event_notify (UINT8 event, tNFA_CONN_EVT_DATA *p_data)
+{
+ if (nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE)
+ {
+ /* Use exclusive RF mode callback */
+ if (nfa_dm_cb.p_excl_conn_cback)
+ (*nfa_dm_cb.p_excl_conn_cback) (event, p_data);
+ }
+ else
+ {
+ (*nfa_dm_cb.p_conn_cback) (event, p_data);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_rel_excl_rf_control_and_notify
+**
+** Description Stop exclusive RF control and notify app of
+** NFA_EXCLUSIVE_RF_CONTROL_STOPPED_EVT
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_dm_rel_excl_rf_control_and_notify (void)
+{
+ tNFA_CONN_EVT_DATA conn_evt;
+
+ NFA_TRACE_DEBUG0 ("nfa_dm_rel_excl_rf_control_and_notify ()");
+
+ /* Exclusive RF control stopped. Notify app */
+ nfa_dm_cb.flags &= ~NFA_DM_FLAGS_EXCL_RF_ACTIVE;
+
+ /* Stop exclusive RF discovery for exclusive RF mode */
+ nfa_dm_stop_excl_discovery ();
+
+ /* Notify app that exclusive RF control has stopped */
+ conn_evt.status = NFA_STATUS_OK;
+ (*nfa_dm_cb.p_excl_conn_cback) (NFA_EXCLUSIVE_RF_CONTROL_STOPPED_EVT, &conn_evt);
+ nfa_dm_cb.p_excl_conn_cback = NULL;
+ nfa_dm_cb.p_excl_ndef_cback = NULL;
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_act_request_excl_rf_ctrl
+**
+** Description Request exclusive RF control
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_request_excl_rf_ctrl (tNFA_DM_MSG *p_data)
+{
+ tNFA_CONN_EVT_DATA conn_evt;
+
+ NFA_TRACE_DEBUG0 ("nfa_dm_act_request_excl_rf_ctrl ()");
+
+ if (!nfa_dm_cb.p_excl_conn_cback)
+ {
+ if (nfa_dm_cb.disc_cb.disc_state != NFA_DM_RFST_IDLE)
+ {
+ conn_evt.status = NFA_STATUS_FAILED;
+ (*p_data->req_excl_rf_ctrl.p_conn_cback) (NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT, &conn_evt);
+ return TRUE;
+ }
+
+ /* Store callbacks */
+ nfa_dm_cb.p_excl_conn_cback = p_data->req_excl_rf_ctrl.p_conn_cback;
+ nfa_dm_cb.p_excl_ndef_cback = p_data->req_excl_rf_ctrl.p_ndef_cback;
+
+ nfa_dm_cb.flags |= NFA_DM_FLAGS_EXCL_RF_ACTIVE;
+
+ /* start exclusive RF discovery */
+ nfa_dm_start_excl_discovery (p_data->req_excl_rf_ctrl.poll_mask,
+ &p_data->req_excl_rf_ctrl.listen_cfg,
+ nfa_dm_excl_disc_cback);
+ }
+ else
+ {
+ NFA_TRACE_ERROR0 ("Exclusive rf control already requested");
+
+ conn_evt.status = NFA_STATUS_FAILED;
+ (*p_data->req_excl_rf_ctrl.p_conn_cback) (NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT, &conn_evt);
+ }
+
+ return TRUE;
+}
+
+
+/*******************************************************************************
+**
+** Function nfa_dm_act_release_excl_rf_ctrl
+**
+** Description Release exclusive RF control
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_release_excl_rf_ctrl (tNFA_DM_MSG *p_data)
+{
+ NFA_TRACE_DEBUG0 ("nfa_dm_act_release_excl_rf_ctrl ()");
+
+ /* nfa_dm_rel_excl_rf_control_and_notify() is called when discovery state goes IDLE */
+ nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_STOPPING;
+
+ /* if discover command has been sent in IDLE state and waiting for response
+ ** then just wait for responose. Otherwise initiate deactivating.
+ */
+ if (!( (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_IDLE)
+ &&(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP) ))
+ {
+ nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_IDLE);
+ }
+
+ 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)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_deactivate (tNFA_DM_MSG *p_data)
+{
+ tNFA_CONN_EVT_DATA conn_evt;
+ tNFA_DEACTIVATE_TYPE deact_type;
+
+ NFA_TRACE_DEBUG0 ("nfa_dm_act_deactivate ()");
+
+ if ( (p_data->deactivate.sleep_mode == FALSE) /* Always allow deactivate to IDLE */
+ ||( (nfa_dm_cb.disc_cb.activated_protocol != NFA_PROTOCOL_T1T) /* Do not allow deactivate to SLEEP for T1T,NFCDEP */
+ &&
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ (
+#endif
+ (nfa_dm_cb.disc_cb.activated_protocol != NFA_PROTOCOL_NFC_DEP)
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED == 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)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_power_off_sleep (tNFA_DM_MSG *p_data)
+{
+ NFA_TRACE_DEBUG0 ("nfa_dm_act_power_off_sleep ()");
+
+ NFC_SetPowerOffSleep ((BOOLEAN) (p_data->hdr.layer_specific));
+
+ return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_act_reg_vsc
+**
+** Description Process registers VSC callback
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_reg_vsc(tNFA_DM_MSG *p_data)
+{
+ if (NFC_RegVSCback(p_data->reg_vsc.is_register, p_data->reg_vsc.p_cback) != NFC_STATUS_OK)
+ {
+ NFA_TRACE_ERROR0 ("NFC_RegVSCback failed");
+ }
+ return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_act_send_vsc
+**
+** Description Send the NCI Vendor Specific command to the NCI command queue
+**
+** Returns FALSE (message buffer is NOT freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_send_vsc(tNFA_DM_MSG *p_data)
+{
+ BT_HDR *p_cmd = (BT_HDR *)p_data;
+
+ p_cmd->offset = sizeof (tNFA_DM_API_SEND_VSC) - BT_HDR_SIZE;
+ p_cmd->len = p_data->send_vsc.cmd_params_len;
+ NFC_SendVsCommand (p_data->send_vsc.oid, p_cmd, p_data->send_vsc.p_cback);
+
+ /* Most dm action functions return TRUE, so nfa-sys frees the GKI buffer carrying the message,
+ * This action function re-use the GKI buffer to send the VSC, so the GKI buffer can not be freed by nfa-sys */
+ return (FALSE);
+}
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_send_nxp(tNFA_DM_MSG *p_data)
+{
+ BT_HDR *p_cmd = (BT_HDR *)p_data;
+
+ p_cmd->offset = sizeof (tNFA_DM_API_SEND_VSC) - BT_HDR_SIZE;
+ p_cmd->len = p_data->send_vsc.cmd_params_len;
+ NFC_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 (poll_tech_mask & NFA_TECHNOLOGY_MASK_F)
+ {
+ poll_disc_mask |= NFA_DM_DISC_MASK_PF_T3T;
+ poll_disc_mask |= NFA_DM_DISC_MASK_PF_NFC_DEP;
+ }
+ if (poll_tech_mask & NFA_TECHNOLOGY_MASK_F_ACTIVE)
+ {
+ poll_disc_mask |= NFA_DM_DISC_MASK_PFA_NFC_DEP;
+ }
+ if (poll_tech_mask & NFA_TECHNOLOGY_MASK_ISO15693)
+ {
+ poll_disc_mask |= NFA_DM_DISC_MASK_P_ISO15693;
+ }
+ if (poll_tech_mask & NFA_TECHNOLOGY_MASK_B_PRIME)
+ {
+ poll_disc_mask |= NFA_DM_DISC_MASK_P_B_PRIME;
+ }
+ if (poll_tech_mask & NFA_TECHNOLOGY_MASK_KOVIO)
+ {
+ poll_disc_mask |= NFA_DM_DISC_MASK_P_KOVIO;
+ }
+
+ nfa_dm_cb.poll_disc_handle = nfa_dm_add_rf_discover (poll_disc_mask,
+ NFA_DM_DISC_HOST_ID_DH,
+ nfa_dm_poll_disc_cback);
+
+ if (nfa_dm_cb.poll_disc_handle != NFA_HANDLE_INVALID)
+ status = NFA_STATUS_OK;
+ else
+ status = NFA_STATUS_FAILED;
+ }
+ else
+ {
+ status = NFA_STATUS_OK;
+ }
+
+ return (status);
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_act_enable_polling
+**
+** Description Process enable polling command
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_enable_polling (tNFA_DM_MSG *p_data)
+{
+ tNFA_CONN_EVT_DATA evt_data;
+
+ NFA_TRACE_DEBUG0 ("nfa_dm_act_enable_polling ()");
+
+ if ( (!(nfa_dm_cb.flags & NFA_DM_FLAGS_POLLING_ENABLED))
+ &&(!(nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE) ) )
+ {
+ nfa_dm_cb.poll_mask = p_data->enable_poll.poll_mask;
+
+ if (nfa_dm_start_polling () == NFA_STATUS_OK)
+ {
+ nfa_dm_cb.flags |= NFA_DM_FLAGS_POLLING_ENABLED;
+
+ evt_data.status = NFA_STATUS_OK;
+ nfa_dm_conn_cback_event_notify (NFA_POLL_ENABLED_EVT, &evt_data);
+ return (TRUE);
+ }
+ }
+ else
+ {
+ NFA_TRACE_ERROR0 ("nfa_dm_act_enable_polling (): already started");
+ }
+
+ /* send NFA_POLL_ENABLED_EVT with NFA_STATUS_FAILED */
+ evt_data.status = NFA_STATUS_FAILED;
+ nfa_dm_conn_cback_event_notify (NFA_POLL_ENABLED_EVT, &evt_data);
+
+ return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_deactivate_polling
+**
+** Description Deactivate any polling state
+**
+** Returns TRUE if need to wait for deactivation
+**
+*******************************************************************************/
+static BOOLEAN nfa_dm_deactivate_polling (void)
+{
+ NFA_TRACE_DEBUG0 ("nfa_dm_deactivate_polling ()");
+
+ if ( (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_W4_ALL_DISCOVERIES)
+ ||(nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_W4_HOST_SELECT) )
+ {
+ nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_IDLE);
+ return FALSE;
+ }
+ else if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE)
+ {
+ if (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_NFC_DEP)
+ {
+ /* NFA P2P will deactivate NFC link after deactivating LLCP link */
+ nfa_p2p_deactivate_llcp ();
+ }
+ else
+ {
+ nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_IDLE);
+ }
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_act_disable_polling
+**
+** Description Process disable polling command
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_disable_polling (tNFA_DM_MSG *p_data)
+{
+ tNFA_CONN_EVT_DATA evt_data;
+
+ NFA_TRACE_DEBUG0 ("nfa_dm_act_disable_polling ()");
+
+ if (nfa_dm_cb.poll_disc_handle != NFA_HANDLE_INVALID)
+ {
+ nfa_dm_cb.flags &= ~NFA_DM_FLAGS_POLLING_ENABLED;
+
+ if (nfa_dm_deactivate_polling () == FALSE)
+ {
+ nfa_dm_delete_rf_discover (nfa_dm_cb.poll_disc_handle);
+ nfa_dm_cb.poll_disc_handle = NFA_HANDLE_INVALID;
+
+ evt_data.status = NFA_STATUS_OK;
+ nfa_dm_conn_cback_event_notify (NFA_POLL_DISABLED_EVT, &evt_data);
+ }
+ else
+ {
+ nfa_dm_cb.flags |= NFA_DM_FLAGS_SEND_POLL_STOP_EVT;
+ }
+ }
+ else
+ {
+ evt_data.status = NFA_STATUS_FAILED;
+ nfa_dm_conn_cback_event_notify (NFA_POLL_DISABLED_EVT, &evt_data);
+ }
+
+ return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_act_enable_listening
+**
+** Description Process enable listening command
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_enable_listening (tNFA_DM_MSG *p_data)
+{
+ tNFA_CONN_EVT_DATA evt_data;
+
+ NFA_TRACE_DEBUG0 ("nfa_dm_act_enable_listening ()");
+
+ nfa_dm_cb.flags &= ~NFA_DM_FLAGS_LISTEN_DISABLED;
+ 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)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_disable_listening (tNFA_DM_MSG *p_data)
+{
+ tNFA_CONN_EVT_DATA evt_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);
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_act_pause_p2p
+**
+** Description Process Pause P2P command
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_pause_p2p (tNFA_DM_MSG *p_data)
+{
+ tNFA_CONN_EVT_DATA evt_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)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_resume_p2p (tNFA_DM_MSG *p_data)
+{
+ tNFA_CONN_EVT_DATA evt_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)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_send_raw_frame (tNFA_DM_MSG *p_data)
+{
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+
+ NFA_TRACE_DEBUG0 ("nfa_dm_act_send_raw_frame ()");
+
+ /* If NFC link is activated */
+ if ( (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE)
+ ||(nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_LISTEN_ACTIVE) )
+ {
+ 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 ((BT_HDR*)p_data);
+ }
+ else
+ {
+ status = NFC_SendData (NFC_RF_CONN_ID, (BT_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)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_set_p2p_listen_tech (tNFA_DM_MSG *p_data)
+{
+ NFA_TRACE_DEBUG1 ("nfa_dm_set_p2p_listen_tech () tech_mask = %d",
+ p_data->set_p2p_listen_tech.tech_mask);
+
+ nfa_p2p_update_listen_tech (p_data->set_p2p_listen_tech.tech_mask);
+ nfa_dm_conn_cback_event_notify (NFA_SET_P2P_LISTEN_TECH_EVT, NULL);
+
+ return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_act_start_rf_discovery
+**
+** Description Process start RF discovery command
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_start_rf_discovery (tNFA_DM_MSG *p_data)
+{
+ tNFA_CONN_EVT_DATA evt_data;
+
+ NFA_TRACE_DEBUG0 ("nfa_dm_act_start_rf_discovery ()");
+
+ if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_ENABLED)
+ {
+ evt_data.status = NFA_STATUS_OK;
+ nfa_dm_conn_cback_event_notify (NFA_RF_DISCOVERY_STARTED_EVT, &evt_data);
+ }
+ else if (nfa_dm_cb.disc_cb.disc_state != NFA_DM_RFST_IDLE)
+ {
+ evt_data.status = NFA_STATUS_SEMANTIC_ERROR;
+ nfa_dm_conn_cback_event_notify (NFA_RF_DISCOVERY_STARTED_EVT, &evt_data);
+ }
+ else
+ {
+ nfa_dm_cb.disc_cb.disc_flags |= (NFA_DM_DISC_FLAGS_ENABLED|NFA_DM_DISC_FLAGS_NOTIFY);
+ nfa_dm_start_rf_discover ();
+ }
+
+ return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_act_stop_rf_discovery
+**
+** Description Process stop RF discovery command
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_stop_rf_discovery (tNFA_DM_MSG *p_data)
+{
+ tNFA_CONN_EVT_DATA evt_data;
+
+ NFA_TRACE_DEBUG0 ("nfa_dm_act_stop_rf_discovery ()");
+
+ if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_ENABLED) ||
+ (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_IDLE) )
+ {
+ nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_ENABLED;
+
+ /* if discover command has been sent in IDLE state and waiting for response */
+ if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)
+ {
+ nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_STOPPING;
+ }
+ else
+ {
+ evt_data.status = NFA_STATUS_OK;
+ nfa_dm_conn_cback_event_notify (NFA_RF_DISCOVERY_STOPPED_EVT, &evt_data);
+ }
+ }
+ else
+ {
+ nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_ENABLED;
+ nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_STOPPING;
+
+ 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)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_set_rf_disc_duration (tNFA_DM_MSG *p_data)
+{
+ nfa_dm_cb.disc_cb.disc_duration = p_data->disc_duration.rf_disc_dur_ms;
+ return (TRUE);
+}
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+/*******************************************************************************
+**
+** Function nfa_dm_act_get_rf_disc_duration
+**
+** Description Get duration for RF discovery
+**
+** Returns UINT16
+**
+*******************************************************************************/
+UINT16 nfa_dm_act_get_rf_disc_duration ( )
+{
+ return (nfa_dm_cb.disc_cb.disc_duration);
+}
+#endif
+/*******************************************************************************
+**
+** Function nfa_dm_act_select
+**
+** Description Process RF select command
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_select (tNFA_DM_MSG *p_data)
+{
+ NFA_TRACE_DEBUG0 ("nfa_dm_act_select ()");
+
+ nfa_dm_rf_discover_select (p_data->select.rf_disc_id,
+ p_data->select.protocol,
+ p_data->select.rf_interface);
+ return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_act_update_rf_params
+**
+** Description Process update RF communication parameters command
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_update_rf_params (tNFA_DM_MSG *p_data)
+{
+ tNFA_CONN_EVT_DATA conn_evt;
+
+ NFA_TRACE_DEBUG0 ("nfa_dm_act_update_rf_params ()");
+
+ if (NFC_UpdateRFCommParams (&p_data->update_rf_params.params) != NFC_STATUS_OK)
+ {
+ conn_evt.status = NFA_STATUS_FAILED;
+ nfa_dm_conn_cback_event_notify (NFA_UPDATE_RF_PARAM_RESULT_EVT, &conn_evt);
+ }
+
+ return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_act_disable_timeout
+**
+** Description timeout on disable process. Shutdown immediately
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_disable_timeout (tNFA_DM_MSG *p_data)
+{
+ tNFA_DM_API_DISABLE disable;
+
+ disable.graceful = FALSE;
+ nfa_dm_disable ((tNFA_DM_MSG *) &disable);
+ return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_act_conn_cback_notify
+**
+** Description Notify app of reader/writer/ndef events
+**
+** Returns nothing
+**
+*******************************************************************************/
+void nfa_dm_act_conn_cback_notify (UINT8 event, tNFA_CONN_EVT_DATA *p_data)
+{
+ NFA_TRACE_DEBUG1 ("nfa_dm_act_conn_cback_notify (): event:0x%X", event);
+
+ /* Notify event using appropriate CONN_CBACK */
+ nfa_dm_conn_cback_event_notify (event, p_data);
+
+ /* If not in exclusive RF mode, then read NDEF message from tag (if automatic reading is enabled) */
+ if (!(nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE))
+ {
+ if ( (event == NFA_NDEF_DETECT_EVT)
+ &&(nfa_dm_cb.flags & NFA_DM_FLAGS_AUTO_READING_NDEF) )
+ {
+ /* read NDEF message from tag */
+ if (p_data->ndef_detect.status == NFA_STATUS_OK)
+ {
+ NFA_RwReadNDef ();
+ }
+ else if (p_data->ndef_detect.status == NFA_STATUS_FAILED)
+ {
+ nfa_dm_cb.flags &= ~NFA_DM_FLAGS_AUTO_READING_NDEF;
+ }
+ /* ignore NFA_STATUS_BUSY */
+ }
+ else if ( (event == NFA_READ_CPLT_EVT)
+ &&(nfa_dm_cb.flags & NFA_DM_FLAGS_AUTO_READING_NDEF))
+ {
+ /* reading NDEF message is done */
+ nfa_dm_cb.flags &= ~NFA_DM_FLAGS_AUTO_READING_NDEF;
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_act_data_cback
+**
+** Description Processing data from RF link
+**
+** Returns None
+**
+*******************************************************************************/
+static void nfa_dm_act_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
+{
+ BT_HDR *p_msg;
+ tNFA_CONN_EVT_DATA evt_data;
+
+ NFA_TRACE_DEBUG1 ("nfa_dm_act_data_cback (): event = 0x%X", event);
+
+ if (event == NFC_DATA_CEVT)
+ {
+ p_msg = (BT_HDR *) p_data->data.p_data;
+
+ if (p_msg)
+ {
+ evt_data.data.status = p_data->data.status;
+ evt_data.data.p_data = (UINT8 *) (p_msg + 1) + p_msg->offset;
+ evt_data.data.len = p_msg->len;
+
+ nfa_dm_conn_cback_event_notify (NFA_DATA_EVT, &evt_data);
+
+ GKI_freebuf (p_msg);
+ }
+ else
+ {
+ NFA_TRACE_ERROR0 ("nfa_dm_act_data_cback (): received NFC_DATA_CEVT with NULL data pointer");
+ }
+ }
+ else if (event == NFC_DEACTIVATE_CEVT)
+ {
+ NFC_SetStaticRfCback (NULL);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_excl_disc_cback
+**
+** Description Processing event from discovery callback
+**
+** Returns None
+**
+*******************************************************************************/
+static void nfa_dm_excl_disc_cback (tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER *p_data)
+{
+ tNFA_CONN_EVT_DATA evt_data;
+
+ NFA_TRACE_DEBUG1 ("nfa_dm_excl_disc_cback (): event:0x%02X", event);
+
+ switch (event)
+ {
+ case NFA_DM_RF_DISC_START_EVT:
+ evt_data.status = NFA_STATUS_OK;
+ nfa_dm_conn_cback_event_notify (NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT, &evt_data);
+ break;
+
+ case NFA_DM_RF_DISC_ACTIVATED_EVT:
+ if (nfa_dm_cb.disc_cb.activated_tech_mode == NFC_DISCOVERY_TYPE_POLL_A)
+ {
+ /* store SEL_RES response */
+ nfa_dm_cb.disc_cb.activated_sel_res = p_data->activate.rf_tech_param.param.pa.sel_rsp;
+ }
+
+ if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_LISTEN_ACTIVE)
+ {
+ /* Set data callback to receive raw frame */
+ NFC_SetStaticRfCback (nfa_dm_act_data_cback);
+
+ memset (&(evt_data.activated.params), 0x00, sizeof (tNFA_TAG_PARAMS));
+ memcpy (&(evt_data.activated.activate_ntf), &(p_data->activate), sizeof (tNFC_ACTIVATE_DEVT));
+
+ nfa_dm_conn_cback_event_notify (NFA_ACTIVATED_EVT, &evt_data);
+ }
+ else
+ {
+ /* holding activation notification until sub-module is ready */
+ nfa_dm_cb.p_activate_ntf = (UINT8*) GKI_getbuf (sizeof (tNFC_ACTIVATE_DEVT));
+
+ if (nfa_dm_cb.p_activate_ntf)
+ {
+ memcpy (nfa_dm_cb.p_activate_ntf,
+ &(p_data->activate),
+ sizeof (tNFC_ACTIVATE_DEVT));
+
+ if ( (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_T1T)
+ ||(nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_T2T)
+ ||(nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_T3T)
+ ||(nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_ISO_DEP)
+ ||(nfa_dm_cb.disc_cb.activated_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*) 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(NFC_NXP_NOT_OPEN_INCLUDED == 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 == 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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ GKI_freebuf (nfa_dm_cb.p_activate_ntf);
+ nfa_dm_cb.p_activate_ntf = NULL;
+#endif
+ }
+ else
+ {
+ NFA_TRACE_DEBUG0 ("P2P is paused");
+ nfa_dm_notify_activation_status (NFA_STATUS_OK, NULL);
+ }
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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)
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ ||(nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_MIFARE)
+ ||(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(NFC_NXP_NOT_OPEN_INCLUDED == 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 *p_nfcid = NULL, nfcid_len;
+
+ NFA_TRACE_DEBUG1 ("nfa_dm_notify_activation_status (): status:0x%X", status);
+
+ if (!nfa_dm_cb.p_activate_ntf)
+ {
+ /* this is for NFA P2P listen */
+ return;
+ }
+
+ if (status == NFA_STATUS_OK)
+ {
+ /* notify NFC link activation */
+ memcpy ( &(evt_data.activated.activate_ntf),
+ nfa_dm_cb.p_activate_ntf,
+ sizeof (tNFC_ACTIVATE_DEVT));
+
+ p_tech_params = &evt_data.activated.activate_ntf.rf_tech_param;
+
+ 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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ 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(nfcid_len > 0 && p_nfcid != NULL)
+ {
+ memcpy (evt_data.activated.activate_ntf.rf_tech_param.param.pa.nfcid1,p_nfcid,nfcid_len);
+ }
+ }
+ else
+ {
+#endif
+ nfcid_len = p_tech_params->param.pa.nfcid1_len;
+ p_nfcid = p_tech_params->param.pa.nfcid1;
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ }
+#endif
+ }
+ 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(NFC_NXP_NOT_OPEN_INCLUDED == 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";
+
+ 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..cf9f4d4
--- /dev/null
+++ b/src/nfa/dm/nfa_dm_api.c
@@ -0,0 +1,1351 @@
+/******************************************************************************
+ *
+ * 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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+UINT32 gFelicaReaderMode;
+#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 ()");
+ nfa_sys_init();
+ nfa_dm_init();
+ nfa_p2p_init();
+ nfa_cho_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();
+ }
+
+
+ /* Initialize NFC module */
+ NFC_Init (p_hal_entry_tbl);
+}
+
+/*******************************************************************************
+**
+** Function NFA_Enable
+**
+** Description This function enables NFC. Prior to calling NFA_Enable,
+** the NFCC must be powered up, and ready to receive commands.
+** This function enables the tasks needed by NFC, opens the NCI
+** transport, resets the NFC controller, downloads patches to
+** the NFCC (if necessary), and initializes the NFC subsystems.
+**
+** This function should only be called once - typically when NFC
+** is enabled during boot-up, or when NFC is enabled from a
+** settings UI. Subsequent calls to NFA_Enable while NFA is
+** enabling or enabled will be ignored. When the NFC startup
+** procedure is completed, an NFA_DM_ENABLE_EVT is returned to the
+** application using the tNFA_DM_CBACK.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_Enable (tNFA_DM_CBACK *p_dm_cback,
+ tNFA_CONN_CBACK *p_conn_cback)
+{
+ tNFA_DM_API_ENABLE *p_msg;
+
+ NFA_TRACE_API0 ("NFA_Enable ()");
+
+ /* Validate parameters */
+ if ((!p_dm_cback) || (!p_conn_cback))
+ {
+ NFA_TRACE_ERROR0 ("NFA_Enable (): error null callback");
+ return (NFA_STATUS_FAILED);
+ }
+
+ if ((p_msg = (tNFA_DM_API_ENABLE *) GKI_getbuf (sizeof (tNFA_DM_API_ENABLE))) != NULL)
+ {
+ p_msg->hdr.event = NFA_DM_API_ENABLE_EVT;
+ p_msg->p_dm_cback = p_dm_cback;
+ p_msg->p_conn_cback = p_conn_cback;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_Disable
+**
+** Description This function is called to shutdown NFC. The tasks for NFC
+** are terminated, and clean up routines are performed. This
+** function is typically called during platform shut-down, or
+** when NFC is disabled from a settings UI. When the NFC
+** shutdown procedure is completed, an NFA_DM_DISABLE_EVT is
+** returned to the application using the tNFA_DM_CBACK.
+**
+** The platform should wait until the NFC_DISABLE_REVT is
+** received before powering down the NFC chip and NCI transport.
+** This is required to so that NFA can gracefully shut down any
+** open connections.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_Disable (BOOLEAN graceful)
+{
+ tNFA_DM_API_DISABLE *p_msg;
+
+ NFA_TRACE_API1 ("NFA_Disable (graceful=%i)", graceful);
+
+ if ((p_msg = (tNFA_DM_API_DISABLE *) GKI_getbuf (sizeof (tNFA_DM_API_DISABLE))) != NULL)
+ {
+ p_msg->hdr.event = NFA_DM_API_DISABLE_EVT;
+ p_msg->graceful = graceful;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_SetConfig
+**
+** Description Set the configuration parameters to NFCC. The result is
+** reported with an NFA_DM_SET_CONFIG_EVT in the tNFA_DM_CBACK
+** callback.
+**
+** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function. Most Configuration
+** parameters are related to RF discovery.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BUSY if previous setting is on-going
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_SetConfig (tNFA_PMID param_id,
+ UINT8 length,
+ UINT8 *p_data)
+{
+ tNFA_DM_API_SET_CONFIG *p_msg;
+
+ NFA_TRACE_API1 ("NFA_SetConfig (): param_id:0x%X", param_id);
+
+ if ((p_msg = (tNFA_DM_API_SET_CONFIG *) GKI_getbuf ((UINT16) (sizeof (tNFA_DM_API_SET_CONFIG) + length))) != NULL)
+ {
+ p_msg->hdr.event = NFA_DM_API_SET_CONFIG_EVT;
+
+ p_msg->param_id = param_id;
+ p_msg->length = length;
+ p_msg->p_data = (UINT8 *) (p_msg + 1);
+
+ /* Copy parameter data */
+ memcpy (p_msg->p_data, p_data, length);
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_GetConfig
+**
+** Description Get the configuration parameters from NFCC. The result is
+** reported with an NFA_DM_GET_CONFIG_EVT in the tNFA_DM_CBACK
+** callback.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_GetConfig (UINT8 num_ids,
+ tNFA_PMID *p_param_ids)
+{
+ tNFA_DM_API_GET_CONFIG *p_msg;
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ UINT8 bytes;
+ UINT8 propConfigCnt;
+
+ NFA_TRACE_API1 ("NFA_GetConfig (): num_ids: %i", num_ids);
+ //NXP_EXTN code added to handle propritory config IDs
+ UINT32 idx = 0;
+ UINT8 *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);
+
+ if ((p_msg = (tNFA_DM_API_GET_CONFIG *) GKI_getbuf ((UINT16) (sizeof (tNFA_DM_API_GET_CONFIG) + bytes))) != NULL)
+#else
+ NFA_TRACE_API1 ("NFA_GetConfig (): num_ids: %i", num_ids);
+ if ((p_msg = (tNFA_DM_API_GET_CONFIG *) GKI_getbuf ((UINT16) (sizeof (tNFA_DM_API_GET_CONFIG) + num_ids))) != NULL)
+#endif
+ {
+ 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(NFC_NXP_NOT_OPEN_INCLUDED == 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);
+ }
+
+ if ((p_msg = (tNFA_DM_API_REQ_EXCL_RF_CTRL *) GKI_getbuf (sizeof (tNFA_DM_API_REQ_EXCL_RF_CTRL))) != NULL)
+ {
+ p_msg->hdr.event = NFA_DM_API_REQUEST_EXCL_RF_CTRL_EVT;
+ p_msg->poll_mask = poll_mask;
+ p_msg->p_conn_cback = p_conn_cback;
+ p_msg->p_ndef_cback = p_ndef_cback;
+
+ if (p_listen_cfg)
+ memcpy (&p_msg->listen_cfg, p_listen_cfg, sizeof (tNFA_LISTEN_CFG));
+ else
+ memset (&p_msg->listen_cfg, 0x00, sizeof (tNFA_LISTEN_CFG));
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_ReleaseExclusiveRfControl
+**
+** Description Release exclusive control of NFC. Once released, behavior
+** prior to obtaining exclusive RF control will resume.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_ReleaseExclusiveRfControl (void)
+{
+ BT_HDR *p_msg;
+
+ NFA_TRACE_API0 ("NFA_ReleaseExclusiveRfControl ()");
+
+ if (!nfa_dm_cb.p_excl_conn_cback)
+ {
+ NFA_TRACE_ERROR0 ("NFA_ReleaseExclusiveRfControl (): Exclusive rf control is not in progress");
+ return (NFA_STATUS_FAILED);
+ }
+
+ if ((p_msg = (BT_HDR *) GKI_getbuf (sizeof (BT_HDR))) != NULL)
+ {
+ p_msg->event = NFA_DM_API_RELEASE_EXCL_RF_CTRL_EVT;
+ nfa_sys_sendmsg (p_msg);
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+
+/*******************************************************************************
+**
+** Function NFA_EnablePolling
+**
+** Description Enable polling for technologies specified by poll_mask.
+**
+** The following events (notified using the connection
+** callback registered with NFA_Enable) are generated during
+** polling:
+**
+** - NFA_POLL_ENABLED_EVT indicates whether or not polling
+** successfully enabled.
+** - NFA_DISC_RESULT_EVT indicates there are more than one devices,
+** so application must select one of tags by calling NFA_Select().
+** - NFA_SELECT_RESULT_EVT indicates whether previous selection was
+** successful or not. If it was failed then application must select
+** again or deactivate by calling NFA_Deactivate().
+** - NFA_ACTIVATED_EVT is generated when an NFC link is activated.
+** - NFA_NDEF_DETECT_EVT is generated if tag is activated
+** - NFA_LLCP_ACTIVATED_EVT/NFA_LLCP_DEACTIVATED_EVT is generated
+** if NFC-DEP is activated
+** - NFA_DEACTIVATED_EVT will be returned after deactivating NFC link.
+**
+** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EnablePolling (tNFA_TECHNOLOGY_MASK poll_mask)
+{
+ tNFA_DM_API_ENABLE_POLL *p_msg;
+
+ NFA_TRACE_API1 ("NFA_EnablePolling () 0x%X", poll_mask);
+
+ if ((p_msg = (tNFA_DM_API_ENABLE_POLL *) GKI_getbuf (sizeof (tNFA_DM_API_ENABLE_POLL))) != NULL)
+ {
+ p_msg->hdr.event = NFA_DM_API_ENABLE_POLLING_EVT;
+ p_msg->poll_mask = poll_mask;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_DisablePolling
+**
+** Description Disable polling
+** NFA_POLL_DISABLED_EVT will be returned after stopping polling.
+**
+** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_DisablePolling (void)
+{
+ BT_HDR *p_msg;
+
+ NFA_TRACE_API0 ("NFA_DisablePolling ()");
+
+ if ((p_msg = (BT_HDR *) GKI_getbuf (sizeof (BT_HDR))) != NULL)
+ {
+ p_msg->event = NFA_DM_API_DISABLE_POLLING_EVT;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_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)
+{
+ BT_HDR *p_msg;
+
+ NFA_TRACE_API0 ("NFA_EnableListening ()");
+
+ if ((p_msg = (BT_HDR *) GKI_getbuf (sizeof (BT_HDR))) != 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)
+{
+ BT_HDR *p_msg;
+
+ NFA_TRACE_API0 ("NFA_DisableListening ()");
+
+ if ((p_msg = (BT_HDR *) GKI_getbuf (sizeof (BT_HDR))) != NULL)
+ {
+ p_msg->event = NFA_DM_API_DISABLE_LISTENING_EVT;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** 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)
+{
+ BT_HDR *p_msg;
+
+ NFA_TRACE_API0 ("NFA_PauseP2p ()");
+
+ if ((p_msg = (BT_HDR *) GKI_getbuf (sizeof (BT_HDR))) != 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)
+{
+ BT_HDR *p_msg;
+
+ NFA_TRACE_API0 ("NFA_ResumeP2p ()");
+
+ if ((p_msg = (BT_HDR *) GKI_getbuf (sizeof (BT_HDR))) != 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);
+
+ if ((p_msg = (tNFA_DM_API_SET_P2P_LISTEN_TECH *) GKI_getbuf (sizeof (tNFA_DM_API_SET_P2P_LISTEN_TECH))) != NULL)
+ {
+ p_msg->hdr.event = NFA_DM_API_SET_P2P_LISTEN_TECH_EVT;
+ p_msg->tech_mask = tech_mask;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_StartRfDiscovery
+**
+** Description Start RF discovery
+** RF discovery parameters shall be set by other APIs.
+**
+** An NFA_RF_DISCOVERY_STARTED_EVT indicates whether starting was successful or not.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_StartRfDiscovery (void)
+{
+ BT_HDR *p_msg;
+
+ NFA_TRACE_API0 ("NFA_StartRfDiscovery ()");
+
+ if ((p_msg = (BT_HDR *) GKI_getbuf (sizeof (BT_HDR))) != NULL)
+ {
+ p_msg->event = NFA_DM_API_START_RF_DISCOVERY_EVT;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_StopRfDiscovery
+**
+** Description Stop RF discovery
+**
+** An NFA_RF_DISCOVERY_STOPPED_EVT indicates whether stopping was successful or not.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_StopRfDiscovery (void)
+{
+ BT_HDR *p_msg;
+
+ NFA_TRACE_API0 ("NFA_StopRfDiscovery ()");
+
+ if ((p_msg = (BT_HDR *) GKI_getbuf (sizeof (BT_HDR))) != NULL)
+ {
+ p_msg->event = NFA_DM_API_STOP_RF_DISCOVERY_EVT;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_SetRfDiscoveryDuration
+**
+** Description Set the duration of the single discovery period in [ms].
+** Allowable range: 0 ms to 0xFFFF ms.
+**
+** If discovery is already started, the application should
+** call NFA_StopRfDiscovery prior to calling
+** NFA_SetRfDiscoveryDuration, and then call
+** NFA_StartRfDiscovery afterwards to restart discovery using
+** the new duration.
+**
+** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function
+**
+** Returns:
+** NFA_STATUS_OK, if command accepted
+** NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_SetRfDiscoveryDuration (UINT16 discovery_period_ms)
+{
+ tNFA_DM_API_SET_RF_DISC_DUR *p_msg;
+
+ NFA_TRACE_API0 ("NFA_SetRfDiscoveryDuration ()");
+
+ /* Post the API message */
+ if ((p_msg = (tNFA_DM_API_SET_RF_DISC_DUR *) GKI_getbuf (sizeof (BT_HDR))) != NULL)
+ {
+ p_msg->hdr.event = NFA_DM_API_SET_RF_DISC_DURATION_EVT;
+
+ /* Set discovery duration */
+ p_msg->rf_disc_dur_ms = discovery_period_ms;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_Select
+**
+** Description Select one from detected devices during discovery
+** (from NFA_DISC_RESULT_EVTs). The application should wait for
+** the final NFA_DISC_RESULT_EVT before selecting.
+**
+** An NFA_SELECT_RESULT_EVT indicates whether selection was successful or not.
+** If failed then application must select again or deactivate by NFA_Deactivate().
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_INVALID_PARAM if RF interface is not matched protocol
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_Select (UINT8 rf_disc_id,
+ tNFA_NFC_PROTOCOL protocol,
+ tNFA_INTF_TYPE rf_interface)
+{
+ tNFA_DM_API_SELECT *p_msg;
+
+ NFA_TRACE_API3 ("NFA_Select (): rf_disc_id:0x%X, protocol:0x%X, rf_interface:0x%X",
+ rf_disc_id, protocol, rf_interface);
+
+ if ( ((rf_interface == NFA_INTERFACE_ISO_DEP) && (protocol != NFA_PROTOCOL_ISO_DEP))
+ ||((rf_interface == NFA_INTERFACE_NFC_DEP) && (protocol != NFA_PROTOCOL_NFC_DEP)) )
+ {
+ NFA_TRACE_ERROR0 ("NFA_Select (): RF interface is not matched protocol");
+ return (NFA_STATUS_INVALID_PARAM);
+ }
+
+ if ((p_msg = (tNFA_DM_API_SELECT *) GKI_getbuf ((UINT16) (sizeof (tNFA_DM_API_SELECT)))) != NULL)
+ {
+ p_msg->hdr.event = NFA_DM_API_SELECT_EVT;
+ p_msg->rf_disc_id = rf_disc_id;
+ p_msg->protocol = protocol;
+ p_msg->rf_interface = rf_interface;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_UpdateRFCommParams
+**
+** Description This function is called to update RF Communication parameters
+** once the Frame RF Interface has been activated.
+**
+** An NFA_UPDATE_RF_PARAM_RESULT_EVT indicates whether updating
+** was successful or not.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_UpdateRFCommParams (tNFA_RF_COMM_PARAMS *p_params)
+{
+ tNFA_DM_API_UPDATE_RF_PARAMS *p_msg;
+
+ NFA_TRACE_API0 ("NFA_UpdateRFCommParams ()");
+
+ if ((p_msg = (tNFA_DM_API_UPDATE_RF_PARAMS *) GKI_getbuf ((UINT16) (sizeof (tNFA_DM_API_UPDATE_RF_PARAMS)))) != NULL)
+ {
+ p_msg->hdr.event = NFA_DM_API_UPDATE_RF_PARAMS_EVT;
+ memcpy (&p_msg->params, p_params, sizeof (tNFA_RF_COMM_PARAMS));
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_Deactivate
+**
+** Description
+** If sleep_mode=TRUE:
+** Deselect the activated device by deactivating into sleep mode.
+**
+** An NFA_DEACTIVATE_FAIL_EVT indicates that selection was not successful.
+** Application can select another discovered device or deactivate by NFA_Deactivate ()
+** after receiving NFA_DEACTIVATED_EVT.
+**
+** Deactivating to sleep mode is not allowed when NFCC is in wait-for-host-select
+** mode, or in listen-sleep states; NFA will deactivate to idle or discovery state
+** for these cases respectively.
+**
+**
+** If sleep_mode=FALSE:
+** Deactivate the connection (e.g. as a result of presence check failure)
+** NFA_DEACTIVATED_EVT will indicate that link is deactivated.
+** Polling/listening will resume (unless the nfcc is in wait_for-all-discoveries state)
+**
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_Deactivate (BOOLEAN sleep_mode)
+{
+ tNFA_DM_API_DEACTIVATE *p_msg;
+
+ NFA_TRACE_API1 ("NFA_Deactivate (): sleep_mode:%i", sleep_mode);
+
+ if ((p_msg = (tNFA_DM_API_DEACTIVATE *) GKI_getbuf ((UINT16) (sizeof (tNFA_DM_API_DEACTIVATE)))) != NULL)
+ {
+ p_msg->hdr.event = NFA_DM_API_DEACTIVATE_EVT;
+ p_msg->sleep_mode = sleep_mode;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_SendRawFrame
+**
+** Description Send a raw frame over the activated interface with the NFCC.
+** This function can only be called after NFC link is activated.
+**
+** 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 *p_raw_data,
+ UINT16 data_len,
+ UINT16 presence_check_start_delay)
+{
+ BT_HDR *p_msg;
+ UINT16 size;
+ UINT8 *p;
+
+ NFA_TRACE_API1 ("NFA_SendRawFrame () data_len:%d", data_len);
+
+ /* Validate parameters */
+ if ((data_len == 0) || (p_raw_data == NULL))
+ return (NFA_STATUS_INVALID_PARAM);
+
+ size = BT_HDR_SIZE + NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + data_len;
+ if ((p_msg = (BT_HDR *) GKI_getbuf (size)) != NULL)
+ {
+ p_msg->event = NFA_DM_API_RAW_FRAME_EVT;
+ p_msg->layer_specific = presence_check_start_delay;
+ p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p_msg->len = data_len;
+
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+ memcpy (p, p_raw_data, data_len);
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+** NDEF Handler APIs
+*******************************************************************************/
+
+/*******************************************************************************
+**
+** Function NFA_RegisterNDefTypeHandler
+**
+** Description This function allows the applications to register for
+** specific types of NDEF records. When NDEF records are
+** received, NFA will parse the record-type field, and pass
+** the record to the registered tNFA_NDEF_CBACK.
+**
+** For records types which were not registered, the record will
+** be sent to the default handler. A default type-handler may
+** be registered by calling this NFA_RegisterNDefTypeHandler
+** with tnf=NFA_TNF_DEFAULT. In this case, all un-registered
+** record types will be sent to the callback. Only one default
+** handler may be registered at a time.
+**
+** An NFA_NDEF_REGISTER_EVT will be sent to the tNFA_NDEF_CBACK
+** to indicate that registration was successful, and provide a
+** handle for this record type.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RegisterNDefTypeHandler (BOOLEAN handle_whole_message,
+ tNFA_TNF tnf,
+ UINT8 *p_type_name,
+ UINT8 type_name_len,
+ tNFA_NDEF_CBACK *p_ndef_cback)
+{
+ tNFA_DM_API_REG_NDEF_HDLR *p_msg;
+
+ NFA_TRACE_API2 ("NFA_RegisterNDefTypeHandler (): handle whole ndef message: %i, tnf=0x%02x", handle_whole_message, tnf);
+
+ /* Check for NULL callback */
+ if (!p_ndef_cback)
+ {
+ NFA_TRACE_ERROR0 ("NFA_RegisterNDefTypeHandler (): error - null callback");
+ return (NFA_STATUS_INVALID_PARAM);
+ }
+
+
+ if ((p_msg = (tNFA_DM_API_REG_NDEF_HDLR *) GKI_getbuf ((UINT16) (sizeof (tNFA_DM_API_REG_NDEF_HDLR) + type_name_len))) != NULL)
+ {
+ p_msg->hdr.event = NFA_DM_API_REG_NDEF_HDLR_EVT;
+
+ p_msg->flags = (handle_whole_message ? NFA_NDEF_FLAGS_HANDLE_WHOLE_MESSAGE : 0);
+ p_msg->tnf = tnf;
+ p_msg->name_len = type_name_len;
+ p_msg->p_ndef_cback = p_ndef_cback;
+ memcpy (p_msg->name, p_type_name, type_name_len);
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RegisterNDefUriHandler
+**
+** Description This API is a special-case of NFA_RegisterNDefTypeHandler
+** with TNF=NFA_TNF_WKT, and type_name='U' (URI record); and allows
+** registering for specific URI types (e.g. 'tel:' or 'mailto:').
+**
+** An NFA_NDEF_REGISTER_EVT will be sent to the tNFA_NDEF_CBACK
+** to indicate that registration was successful, and provide a
+** handle for this registration.
+**
+** If uri_id=NFA_NDEF_URI_ID_ABSOLUTE, then p_abs_uri contains the
+** unabridged URI. For all other uri_id values, the p_abs_uri
+** parameter is ignored (i.e the URI prefix is implied by uri_id).
+** See [NFC RTD URI] for more information.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RegisterNDefUriHandler (BOOLEAN handle_whole_message,
+ tNFA_NDEF_URI_ID uri_id,
+ UINT8 *p_abs_uri,
+ UINT8 uri_id_len,
+ tNFA_NDEF_CBACK *p_ndef_cback)
+{
+ tNFA_DM_API_REG_NDEF_HDLR *p_msg;
+
+ NFA_TRACE_API2 ("NFA_RegisterNDefUriHandler (): handle whole ndef message: %i, uri_id=0x%02x", handle_whole_message, uri_id);
+
+ /* Check for NULL callback */
+ if (!p_ndef_cback)
+ {
+ NFA_TRACE_ERROR0 ("NFA_RegisterNDefUriHandler (): error - null callback");
+ return (NFA_STATUS_INVALID_PARAM);
+ }
+
+
+ if ((p_msg = (tNFA_DM_API_REG_NDEF_HDLR *) GKI_getbuf ((UINT16) (sizeof (tNFA_DM_API_REG_NDEF_HDLR) + uri_id_len))) != NULL)
+ {
+ p_msg->hdr.event = NFA_DM_API_REG_NDEF_HDLR_EVT;
+
+ p_msg->flags = NFA_NDEF_FLAGS_WKT_URI;
+
+ if (handle_whole_message)
+ {
+ p_msg->flags |= NFA_NDEF_FLAGS_HANDLE_WHOLE_MESSAGE;
+ }
+
+ /* abs_uri is only valid fir uri_id=NFA_NDEF_URI_ID_ABSOLUTE */
+ if (uri_id != NFA_NDEF_URI_ID_ABSOLUTE)
+ {
+ uri_id_len = 0;
+ }
+
+ p_msg->tnf = NFA_TNF_WKT;
+ p_msg->uri_id = uri_id;
+ p_msg->name_len = uri_id_len;
+ p_msg->p_ndef_cback = p_ndef_cback;
+ memcpy (p_msg->name, p_abs_uri, uri_id_len);
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_DeregisterNDefTypeHandler
+**
+** Description Deregister NDEF record type handler.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_DeregisterNDefTypeHandler (tNFA_HANDLE ndef_type_handle)
+{
+ tNFA_DM_API_DEREG_NDEF_HDLR *p_msg;
+
+ NFA_TRACE_API1 ("NFA_DeregisterNDefHandler (): handle 0x%08x", ndef_type_handle);
+
+
+ if ((p_msg = (tNFA_DM_API_DEREG_NDEF_HDLR *) GKI_getbuf ((UINT16) (sizeof (tNFA_DM_API_DEREG_NDEF_HDLR)))) != NULL)
+ {
+ p_msg->hdr.event = NFA_DM_API_DEREG_NDEF_HDLR_EVT;
+ p_msg->ndef_type_handle = ndef_type_handle;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_PowerOffSleepMode
+**
+** Description This function is called to enter or leave NFCC Power Off Sleep mode
+** NFA_DM_PWR_MODE_CHANGE_EVT will be sent to indicate status.
+**
+** start_stop : TRUE if entering Power Off Sleep mode
+** FALSE if leaving Power Off Sleep mode
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_PowerOffSleepMode (BOOLEAN start_stop)
+{
+ BT_HDR *p_msg;
+
+ NFA_TRACE_API1 ("NFA_PowerOffSleepState () start_stop=%d", start_stop);
+
+ if (nfa_dm_cb.flags & NFA_DM_FLAGS_SETTING_PWR_MODE)
+ {
+ NFA_TRACE_ERROR0 ("NFA_PowerOffSleepState (): NFA DM is busy to update power mode");
+ return (NFA_STATUS_FAILED);
+ }
+ else
+ {
+ nfa_dm_cb.flags |= NFA_DM_FLAGS_SETTING_PWR_MODE;
+ }
+
+ if ((p_msg = (BT_HDR *) GKI_getbuf (sizeof (BT_HDR))) != NULL)
+ {
+ p_msg->event = NFA_DM_API_POWER_OFF_SLEEP_EVT;
+ p_msg->layer_specific = start_stop;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RegVSCback
+**
+** Description This function is called to register or de-register a callback
+** function to receive Proprietary NCI response and notification
+** events.
+** The maximum number of callback functions allowed is NFC_NUM_VS_CBACKS
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFA_RegVSCback (BOOLEAN is_register,
+ tNFA_VSC_CBACK *p_cback)
+{
+ tNFA_DM_API_REG_VSC *p_msg;
+
+ NFA_TRACE_API1 ("NFA_RegVSCback() is_register=%d", is_register);
+
+ if (p_cback == NULL)
+ {
+ NFA_TRACE_ERROR0 ("NFA_RegVSCback() requires a valid callback function");
+ return (NFA_STATUS_FAILED);
+ }
+
+ if ((p_msg = (tNFA_DM_API_REG_VSC *) GKI_getbuf (sizeof(tNFA_DM_API_REG_VSC))) != NULL)
+ {
+ p_msg->hdr.event = NFA_DM_API_REG_VSC_EVT;
+ p_msg->is_register = is_register;
+ p_msg->p_cback = p_cback;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_SendVsCommand
+**
+** Description This function is called to send an NCI Vendor Specific
+** command to NFCC.
+**
+** oid - The opcode of the VS command.
+** cmd_params_len - The command parameter len
+** p_cmd_params - The command parameter
+** p_cback - The callback function to receive the command
+** status
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_SendVsCommand (UINT8 oid,
+ UINT8 cmd_params_len,
+ UINT8 *p_cmd_params,
+ tNFA_VSC_CBACK *p_cback)
+{
+ tNFA_DM_API_SEND_VSC *p_msg;
+ UINT16 size = sizeof(tNFA_DM_API_SEND_VSC) + cmd_params_len;
+
+ NFA_TRACE_API1 ("NFA_SendVsCommand() oid=0x%x", oid);
+
+ if ((p_msg = (tNFA_DM_API_SEND_VSC *) GKI_getbuf (size)) != NULL)
+ {
+ p_msg->hdr.event = NFA_DM_API_SEND_VSC_EVT;
+ p_msg->oid = oid;
+ p_msg->p_cback = p_cback;
+ if (cmd_params_len && p_cmd_params)
+ {
+ p_msg->cmd_params_len = cmd_params_len;
+ p_msg->p_cmd_params = (UINT8 *)(p_msg + 1);
+ memcpy (p_msg->p_cmd_params, p_cmd_params, cmd_params_len);
+ }
+ else
+ {
+ p_msg->cmd_params_len = 0;
+ p_msg->p_cmd_params = NULL;
+ }
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 cmd_params_len,
+ UINT8 *p_cmd_params,
+ tNFA_VSC_CBACK *p_cback)
+{
+ tNFA_DM_API_SEND_VSC *p_msg;
+ UINT16 size = sizeof(tNFA_DM_API_SEND_VSC) + cmd_params_len;
+
+ 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 *)(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 NFA_SetTraceLevel (UINT8 new_level)
+{
+ if (new_level != 0xFF)
+ nfa_sys_set_trace_level (new_level);
+
+ return (nfa_sys_cb.trace_level);
+}
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 (BOOLEAN ReaderModeFlag, UINT32 Technologies)
+{
+ NFA_TRACE_API1 ("NFA_SetReaderMode =0x%x", ReaderModeFlag);
+ gFelicaReaderMode = ReaderModeFlag;
+ return;
+}
+/*******************************************************************************
+**
+** 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_PN548AD << 2) |
+ (NXP_EN_PN66T << 3));
+ 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;
+}
+#endif
diff --git a/src/nfa/dm/nfa_dm_cfg.c b/src/nfa/dm/nfa_dm_cfg.c
new file mode 100644
index 0000000..202e213
--- /dev/null
+++ b/src/nfa/dm/nfa_dm_cfg.c
@@ -0,0 +1,123 @@
+/******************************************************************************
+ *
+ * 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 nfa_dm_ce_cfg[] =
+{
+ 13, /* total length */
+ NFC_PMID_LF_T3T_PMM, /* Type-3 tag default PMM */
+ NCI_PARAM_LEN_LF_T3T_PMM,
+ 0x20,
+ 0x79,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ 0xFF,
+ NFC_PMID_FWI, /* FWI for ISO-DEP */
+ 1,
+ CE_T4T_ISO_DEP_FWI
+};
+
+UINT8 *p_nfa_dm_ce_cfg = (UINT8 *) nfa_dm_ce_cfg;
+
+/* the SetConfig for optional general NFC stack functions */
+const UINT8 nfa_dm_gen_cfg[] =
+{
+ 3, /* total length */
+ NFC_PMID_RF_FIELD_INFO, /* Instruct NFCC to report RF field generated by remote device (or not) */
+ 1,
+ 0x01
+};
+
+UINT8 *p_nfa_dm_gen_cfg = NULL;
+
+
+/* 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 nfa_ee_max_ee_cfg = NFA_EE_MAX_EE_SUPPORTED;
+
+
+const tNCI_DISCOVER_MAPS nfa_dm_interface_mapping[NFA_DM_NUM_INTERFACE_MAP] =
+{
+ /* Protocols that use Frame Interface do not need to be included in the interface mapping */
+ {
+ NCI_PROTOCOL_ISO_DEP,
+ NCI_INTERFACE_MODE_POLL_N_LISTEN,
+ NCI_INTERFACE_ISO_DEP
+ },
+ {
+ NCI_PROTOCOL_NFC_DEP,
+ NCI_INTERFACE_MODE_POLL_N_LISTEN,
+ NCI_INTERFACE_NFC_DEP
+ }
+};
+/* set to NULL to use the default mapping set by stack */
+tNCI_DISCOVER_MAPS *p_nfa_dm_interface_mapping = NULL;
+UINT8 nfa_dm_num_dm_interface_mapping = 0;
+
+
+const tNFA_DM_CFG nfa_dm_cfg =
+{
+ NFA_DM_AUTO_DETECT_NDEF, /* Automatic NDEF detection (when not in exclusive RF mode) */
+ NFA_DM_AUTO_READ_NDEF, /* Automatic NDEF read (when not in exclusive RF mode) */
+ NFA_DM_AUTO_PRESENCE_CHECK, /* Automatic presence check */
+ NFA_DM_PRESENCE_CHECK_OPTION, /* Use sleep/wake(last interface) for ISODEP presence check */
+ NFA_DM_MAX_PRESENCE_CHECK_TIMEOUT /* Maximum time to wait for presence check response */
+};
+
+tNFA_DM_CFG *p_nfa_dm_cfg = (tNFA_DM_CFG *) &nfa_dm_cfg;
+
+const UINT8 nfa_hci_whitelist[] =
+{
+ 0x02,
+ 0x03,
+ 0x04
+};
+
+const tNFA_HCI_CFG nfa_hci_cfg =
+{
+ NFA_HCI_NETWK_INIT_IDLE_TIMEOUT, /* Max HCI Network IDLE time to wait for EE DISC REQ Ntf(s) */
+ NFA_HCI_RESPONSE_TIMEOUT, /* Maximum HCP Response time to any HCP Command */
+ 0x03, /* Number of host in the whitelist of Terminal host */
+ (UINT8 *) nfa_hci_whitelist /* Pointer to the Whitelist of Terminal Host */
+};
+
+tNFA_HCI_CFG *p_nfa_hci_cfg = (tNFA_HCI_CFG *) &nfa_hci_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..b0ca146
--- /dev/null
+++ b/src/nfa/dm/nfa_dm_discover.c
@@ -0,0 +1,3527 @@
+/******************************************************************************
+ *
+ * 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"
+#if (NFC_NFCEE_INCLUDED == TRUE)
+#include "nfa_ee_api.h"
+#include "nfa_ee_int.h"
+#endif
+#include "nfa_rw_int.h"
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#include "nfc_int.h"
+#include "nci_hmsgs.h"
+#include<config.h>
+#endif
+/*
+** static functions
+*/
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+static BOOLEAN reconnect_in_progress;
+static BOOLEAN is_emvco_active;
+#endif
+
+static UINT8 nfa_dm_get_rf_discover_config (tNFA_DM_DISC_TECH_PROTO_MASK dm_disc_mask,
+ tNFC_DISCOVER_PARAMS disc_params[],
+ UINT8 max_params);
+static tNFA_STATUS nfa_dm_set_rf_listen_mode_config (tNFA_DM_DISC_TECH_PROTO_MASK tech_proto_mask);
+static void nfa_dm_set_rf_listen_mode_raw_config (tNFA_DM_DISC_TECH_PROTO_MASK *p_disc_mask);
+static tNFA_DM_DISC_TECH_PROTO_MASK nfa_dm_disc_get_disc_mask (tNFC_RF_TECH_N_MODE tech_n_mode,
+ tNFC_PROTOCOL protocol);
+static void nfa_dm_notify_discovery (tNFA_DM_RF_DISC_DATA *p_data);
+static tNFA_STATUS nfa_dm_disc_notify_activation (tNFC_DISCOVER *p_data);
+static void nfa_dm_disc_notify_deactivation (tNFA_DM_RF_DISC_SM_EVENT sm_event, tNFC_DISCOVER *p_data);
+static void nfa_dm_disc_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data);
+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 state);
+static char *nfa_dm_disc_event_2_str (UINT8 event);
+#endif
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+typedef struct nfa_dm_p2p_prio_logic
+{
+ UINT8 isodep_detected; /*flag to check if ISO-DEP is detected */
+ UINT8 timer_expired; /*flag to check whether timer is expired */
+ TIMER_LIST_ENT timer_list; /*timer structure pointer */
+ UINT8 first_tech_mode;
+}nfa_dm_p2p_prio_logic_t;
+
+static nfa_dm_p2p_prio_logic_t p2p_prio_logic_data;
+
+#define P2P_RESUME_POLL_TIMEOUT 16 /*mili second timeout value*/
+static UINT16 P2P_PRIO_LOGIC_CLEANUP_TIMEOUT = 50; /*timeout value 500 ms for p2p_prio_logic_cleanup*/
+#endif
+
+#if(NFC_NXP_ESE == TRUE && NFC_NXP_CHIP_TYPE == PN548C2)
+BOOLEAN 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 nfa_dm_get_rf_discover_config (tNFA_DM_DISC_TECH_PROTO_MASK dm_disc_mask,
+ tNFC_DISCOVER_PARAMS disc_params[],
+ UINT8 max_params)
+{
+ UINT8 num_params = 0;
+
+ if (nfa_dm_cb.flags & NFA_DM_FLAGS_LISTEN_DISABLED)
+ {
+ NFA_TRACE_DEBUG1 ("nfa_dm_get_rf_discover_config () listen disabled, rm listen from 0x%x", dm_disc_mask);
+ dm_disc_mask &= NFA_DM_DISC_MASK_POLL;
+ }
+ if (nfa_dm_is_p2p_paused ())
+ {
+ dm_disc_mask &= ~NFA_DM_DISC_MASK_NFC_DEP;
+ }
+
+ /* 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)
+ {
+ 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(NFC_NXP_NOT_OPEN_INCLUDED == 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 nfa_dm_get_sak(tNFA_DM_DISC_TECH_PROTO_MASK tech_proto_mask)
+{
+ UINT8 sak = 0;
+ UINT8 tech_list = 0;
+ unsigned long hostEnable = TRUE, fwdEnable = TRUE;
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ if ((GetNumValue(NAME_HOST_LISTEN_ENABLE, &hostEnable, sizeof(hostEnable))))
+ {
+ NFA_TRACE_DEBUG2 ("%s:HOST_LISTEN_ENABLE=0x0%lu;", __FUNCTION__, hostEnable);
+ }
+ if((GetNumValue(NAME_NXP_FWD_FUNCTIONALITY_ENABLE, &fwdEnable, sizeof(fwdEnable))))
+ {
+ NFA_TRACE_DEBUG2 ("%s:NXP_FWD_FUNCTIONALITY_ENABLE=0x0%lu;", __FUNCTION__, fwdEnable);
+ }
+#endif
+
+ tech_list = nfa_ee_get_supported_tech_list(0x02);
+ if(hostEnable)
+ {
+ 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;
+}
+#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 params[40], *p;
+ UINT8 platform = 0;
+ UINT8 sens_info = 0;
+
+ NFA_TRACE_DEBUG1 ("nfa_dm_set_rf_listen_mode_config () tech_proto_mask = 0x%08X",
+ tech_proto_mask);
+
+ /*
+ ** T1T listen LA_PROT 0x80, LA_SENS_RES byte1:0x00 byte2:0x0C
+ ** T2T listen LA_PROT 0x00
+ ** T3T listen No bit for T3T in LF_PROT (CE T3T set listen parameters, system code, NFCID2, etc.)
+ ** ISO-DEP listen LA_PROT 0x01, LB_PROT 0x01
+ ** NFC-DEP listen LA_PROT 0x02, LF_PROT 0x02
+ */
+ 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(NFC_NXP_NOT_OPEN_INCLUDED == 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;", __FUNCTION__, sens_info);
+#endif
+ }
+#if (NFC_NXP_NOT_OPEN_INCLUDED == 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 (NFC_NXP_NOT_OPEN_INCLUDED != 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 (NFC_NXP_NOT_OPEN_INCLUDED != 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 (NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED == 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) (p - params), params, FALSE);
+ }
+
+ return NFA_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_set_total_duration
+**
+** Description Update total duration to NFCC
+**
+** Returns void
+**
+*******************************************************************************/
+static void nfa_dm_set_total_duration (void)
+{
+ UINT8 params[10], *p;
+
+ NFA_TRACE_DEBUG0 ("nfa_dm_set_total_duration ()");
+
+ p = params;
+
+ /* for total duration */
+ UINT8_TO_STREAM (p, NFC_PMID_TOTAL_DURATION);
+ UINT8_TO_STREAM (p, NCI_PARAM_LEN_TOTAL_DURATION);
+ UINT16_TO_STREAM (p, nfa_dm_cb.disc_cb.disc_duration);
+
+ if (p > params)
+ {
+ nfa_dm_check_set_config ((UINT8) (p - params), params, FALSE);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_set_rf_listen_mode_raw_config
+**
+** Description Set raw listen parameters
+**
+** Returns void
+**
+*******************************************************************************/
+static void nfa_dm_set_rf_listen_mode_raw_config (tNFA_DM_DISC_TECH_PROTO_MASK *p_disc_mask)
+{
+ tNFA_DM_DISC_TECH_PROTO_MASK disc_mask = 0;
+ tNFA_LISTEN_CFG *p_cfg = &nfa_dm_cb.disc_cb.excl_listen_config;
+ UINT8 params[250], *p, xx;
+
+ NFA_TRACE_DEBUG0 ("nfa_dm_set_rf_listen_mode_raw_config ()");
+
+ /*
+ ** Discovery Configuration Parameters for Listen A
+ */
+ if ( (nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_A] == NFA_DM_DISC_HOST_ID_DH)
+ &&(p_cfg->la_enable) )
+ {
+ p = params;
+
+ UINT8_TO_STREAM (p, NFC_PMID_LA_BIT_FRAME_SDD);
+ UINT8_TO_STREAM (p, NCI_PARAM_LEN_LA_BIT_FRAME_SDD);
+ UINT8_TO_STREAM (p, p_cfg->la_bit_frame_sdd);
+
+ UINT8_TO_STREAM (p, NFC_PMID_LA_PLATFORM_CONFIG);
+ UINT8_TO_STREAM (p, NCI_PARAM_LEN_LA_PLATFORM_CONFIG);
+ UINT8_TO_STREAM (p, p_cfg->la_platform_config);
+
+ UINT8_TO_STREAM (p, NFC_PMID_LA_SEL_INFO);
+ UINT8_TO_STREAM (p, NCI_PARAM_LEN_LA_SEL_INFO);
+ UINT8_TO_STREAM (p, p_cfg->la_sel_info);
+
+ if (p_cfg->la_platform_config == NCI_PARAM_PLATFORM_T1T)
+ {
+ disc_mask |= NFA_DM_DISC_MASK_LA_T1T;
+ }
+ else
+ {
+ /* If T4T or NFCDEP */
+ if (p_cfg->la_sel_info & NCI_PARAM_SEL_INFO_ISODEP)
+ {
+ disc_mask |= NFA_DM_DISC_MASK_LA_ISO_DEP;
+ }
+
+ if (p_cfg->la_sel_info & NCI_PARAM_SEL_INFO_NFCDEP)
+ {
+ disc_mask |= NFA_DM_DISC_MASK_LA_NFC_DEP;
+ }
+
+ /* If neither, T4T nor NFCDEP, then its T2T */
+ if (disc_mask == 0)
+ {
+ disc_mask |= NFA_DM_DISC_MASK_LA_T2T;
+ }
+ }
+
+ UINT8_TO_STREAM (p, NFC_PMID_LA_NFCID1);
+ UINT8_TO_STREAM (p, p_cfg->la_nfcid1_len);
+ ARRAY_TO_STREAM (p, p_cfg->la_nfcid1, p_cfg->la_nfcid1_len);
+
+ nfa_dm_check_set_config ((UINT8) (p - params), params, FALSE);
+ }
+
+ /*
+ ** Discovery Configuration Parameters for Listen B
+ */
+ if ( (nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_B] == NFA_DM_DISC_HOST_ID_DH)
+ &&(p_cfg->lb_enable) )
+ {
+ p = params;
+
+ UINT8_TO_STREAM (p, NFC_PMID_LB_SENSB_INFO);
+ UINT8_TO_STREAM (p, NCI_PARAM_LEN_LB_SENSB_INFO);
+ UINT8_TO_STREAM (p, p_cfg->lb_sensb_info);
+
+ UINT8_TO_STREAM (p, NFC_PMID_LB_NFCID0);
+ UINT8_TO_STREAM (p, p_cfg->lb_nfcid0_len);
+ ARRAY_TO_STREAM (p, p_cfg->lb_nfcid0, p_cfg->lb_nfcid0_len);
+
+ UINT8_TO_STREAM (p, NFC_PMID_LB_APPDATA);
+ UINT8_TO_STREAM (p, NCI_PARAM_LEN_LB_APPDATA);
+ ARRAY_TO_STREAM (p, p_cfg->lb_app_data, NCI_PARAM_LEN_LB_APPDATA);
+
+ UINT8_TO_STREAM (p, NFC_PMID_LB_SFGI);
+ UINT8_TO_STREAM (p, 1);
+ UINT8_TO_STREAM (p, p_cfg->lb_adc_fo);
+
+ UINT8_TO_STREAM (p, NFC_PMID_LB_ADC_FO);
+ UINT8_TO_STREAM (p, NCI_PARAM_LEN_LB_ADC_FO);
+ UINT8_TO_STREAM (p, p_cfg->lb_adc_fo);
+
+ nfa_dm_check_set_config ((UINT8) (p - params), params, FALSE);
+
+ if (p_cfg->lb_sensb_info & NCI_LISTEN_PROTOCOL_ISO_DEP)
+ {
+ disc_mask |= NFA_DM_DISC_MASK_LB_ISO_DEP;
+ }
+ }
+
+ /*
+ ** Discovery Configuration Parameters for Listen F
+ */
+ if ( (nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_F] == NFA_DM_DISC_HOST_ID_DH)
+ &&(p_cfg->lf_enable) )
+ {
+ p = params;
+
+ UINT8_TO_STREAM (p, NFC_PMID_LF_CON_BITR_F);
+ UINT8_TO_STREAM (p, 1);
+ UINT8_TO_STREAM (p, p_cfg->lf_con_bitr_f);
+
+ UINT8_TO_STREAM (p, NFC_PMID_LF_PROTOCOL);
+ UINT8_TO_STREAM (p, NCI_PARAM_LEN_LF_PROTOCOL);
+ UINT8_TO_STREAM (p, p_cfg->lf_protocol_type);
+
+ UINT8_TO_STREAM (p, NFC_PMID_LF_T3T_FLAGS2);
+ UINT8_TO_STREAM (p, NCI_PARAM_LEN_LF_T3T_FLAGS2);
+ UINT16_TO_STREAM(p, p_cfg->lf_t3t_flags);
+
+ /* if the bit at position X is set to 0, SC/NFCID2 with index X shall be ignored */
+ for (xx = 0; xx < NFA_LF_MAX_SC_NFCID2; xx++)
+ {
+ if ((p_cfg->lf_t3t_flags & (0x0001 << xx)) != 0x0000)
+ {
+ UINT8_TO_STREAM (p, NFC_PMID_LF_T3T_ID1 + xx);
+ UINT8_TO_STREAM (p, NCI_SYSTEMCODE_LEN + NCI_NFCID2_LEN);
+ ARRAY_TO_STREAM (p, p_cfg->lf_t3t_identifier[xx], NCI_SYSTEMCODE_LEN + NCI_NFCID2_LEN);
+ }
+ }
+
+#if (NFC_NXP_NOT_OPEN_INCLUDED != 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) (p - params), params, FALSE);
+
+ if (p_cfg->lf_t3t_flags != NCI_LF_T3T_FLAGS2_ALL_DISABLED)
+ {
+ disc_mask |= NFA_DM_DISC_MASK_LF_T3T;
+ }
+ if (p_cfg->lf_protocol_type & NCI_LISTEN_PROTOCOL_NFC_DEP)
+ {
+ disc_mask |= NFA_DM_DISC_MASK_LF_NFC_DEP;
+ }
+ }
+
+ /*
+ ** Discovery Configuration Parameters for Listen ISO-DEP
+ */
+ if ((disc_mask & (NFA_DM_DISC_MASK_LA_ISO_DEP|NFA_DM_DISC_MASK_LB_ISO_DEP))
+ &&(p_cfg->li_enable))
+ {
+ p = params;
+
+ UINT8_TO_STREAM (p, NFC_PMID_FWI);
+ UINT8_TO_STREAM (p, NCI_PARAM_LEN_FWI);
+ UINT8_TO_STREAM (p, p_cfg->li_fwi);
+
+ if (disc_mask & NFA_DM_DISC_MASK_LA_ISO_DEP)
+ {
+ UINT8_TO_STREAM (p, NFC_PMID_LA_HIST_BY);
+ UINT8_TO_STREAM (p, p_cfg->la_hist_bytes_len);
+ ARRAY_TO_STREAM (p, p_cfg->la_hist_bytes, p_cfg->la_hist_bytes_len);
+ }
+
+ if (disc_mask & NFA_DM_DISC_MASK_LB_ISO_DEP)
+ {
+ UINT8_TO_STREAM (p, NFC_PMID_LB_H_INFO);
+ UINT8_TO_STREAM (p, p_cfg->lb_h_info_resp_len);
+ ARRAY_TO_STREAM (p, p_cfg->lb_h_info_resp, p_cfg->lb_h_info_resp_len);
+ }
+
+ nfa_dm_check_set_config ((UINT8) (p - params), params, FALSE);
+ }
+
+ /*
+ ** Discovery Configuration Parameters for Listen NFC-DEP
+ */
+ if ( (disc_mask & (NFA_DM_DISC_MASK_LA_NFC_DEP|NFA_DM_DISC_MASK_LF_NFC_DEP))
+ &&(p_cfg->ln_enable))
+ {
+ p = params;
+
+ UINT8_TO_STREAM (p, NFC_PMID_WT);
+ UINT8_TO_STREAM (p, NCI_PARAM_LEN_WT);
+ UINT8_TO_STREAM (p, p_cfg->ln_wt);
+
+ UINT8_TO_STREAM (p, NFC_PMID_ATR_RES_GEN_BYTES);
+ UINT8_TO_STREAM (p, p_cfg->ln_atr_res_gen_bytes_len);
+ ARRAY_TO_STREAM (p, p_cfg->ln_atr_res_gen_bytes, p_cfg->ln_atr_res_gen_bytes_len);
+
+ UINT8_TO_STREAM (p, NFC_PMID_ATR_RSP_CONFIG);
+ UINT8_TO_STREAM (p, 1);
+ UINT8_TO_STREAM (p, p_cfg->ln_atr_res_config);
+
+ nfa_dm_check_set_config ((UINT8) (p - params), params, FALSE);
+ }
+
+ *p_disc_mask = disc_mask;
+
+ NFA_TRACE_DEBUG1 ("nfa_dm_set_rf_listen_mode_raw_config () disc_mask = 0x%x", disc_mask);
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_disc_get_disc_mask
+**
+** Description Convert RF technology, mode and protocol to bit mask
+**
+** Returns tNFA_DM_DISC_TECH_PROTO_MASK
+**
+*******************************************************************************/
+static tNFA_DM_DISC_TECH_PROTO_MASK nfa_dm_disc_get_disc_mask (tNFC_RF_TECH_N_MODE tech_n_mode,
+ tNFC_PROTOCOL protocol)
+{
+ /* Set initial disc_mask to legacy poll or listen */
+ tNFA_DM_DISC_TECH_PROTO_MASK disc_mask = ((tech_n_mode & 0x80) ? NFA_DM_DISC_MASK_L_LEGACY : NFA_DM_DISC_MASK_P_LEGACY);
+
+ switch (tech_n_mode)
+ {
+ case NFC_DISCOVERY_TYPE_POLL_A:
+ switch (protocol)
+ {
+ case NFC_PROTOCOL_T1T:
+ disc_mask = NFA_DM_DISC_MASK_PA_T1T;
+ break;
+ case NFC_PROTOCOL_T2T:
+ disc_mask = NFA_DM_DISC_MASK_PA_T2T;
+ break;
+ case NFC_PROTOCOL_ISO_DEP:
+ disc_mask = NFA_DM_DISC_MASK_PA_ISO_DEP;
+ break;
+ case NFC_PROTOCOL_NFC_DEP:
+ disc_mask = NFA_DM_DISC_MASK_PA_NFC_DEP;
+ break;
+ }
+ break;
+ case NFC_DISCOVERY_TYPE_POLL_B:
+ if (protocol == NFC_PROTOCOL_ISO_DEP)
+ disc_mask = NFA_DM_DISC_MASK_PB_ISO_DEP;
+ break;
+ case NFC_DISCOVERY_TYPE_POLL_F:
+ if (protocol == NFC_PROTOCOL_T3T)
+ disc_mask = NFA_DM_DISC_MASK_PF_T3T;
+ else if (protocol == NFC_PROTOCOL_NFC_DEP)
+ disc_mask = NFA_DM_DISC_MASK_PF_NFC_DEP;
+ break;
+ case NFC_DISCOVERY_TYPE_POLL_ISO15693:
+ disc_mask = NFA_DM_DISC_MASK_P_ISO15693;
+ break;
+ case NFC_DISCOVERY_TYPE_POLL_B_PRIME:
+ disc_mask = NFA_DM_DISC_MASK_P_B_PRIME;
+ break;
+ case NFC_DISCOVERY_TYPE_POLL_KOVIO:
+ disc_mask = NFA_DM_DISC_MASK_P_KOVIO;
+ break;
+ case NFC_DISCOVERY_TYPE_POLL_A_ACTIVE:
+ disc_mask = NFA_DM_DISC_MASK_PAA_NFC_DEP;
+ break;
+ case NFC_DISCOVERY_TYPE_POLL_F_ACTIVE:
+ disc_mask = NFA_DM_DISC_MASK_PFA_NFC_DEP;
+ break;
+
+ case NFC_DISCOVERY_TYPE_LISTEN_A:
+ switch (protocol)
+ {
+ case NFC_PROTOCOL_T1T:
+ disc_mask = NFA_DM_DISC_MASK_LA_T1T;
+ break;
+ case NFC_PROTOCOL_T2T:
+ disc_mask = NFA_DM_DISC_MASK_LA_T2T;
+ break;
+ case NFC_PROTOCOL_ISO_DEP:
+ disc_mask = NFA_DM_DISC_MASK_LA_ISO_DEP;
+ break;
+ case NFC_PROTOCOL_NFC_DEP:
+ disc_mask = NFA_DM_DISC_MASK_LA_NFC_DEP;
+ break;
+ }
+ break;
+ case NFC_DISCOVERY_TYPE_LISTEN_B:
+ if (protocol == NFC_PROTOCOL_ISO_DEP)
+ disc_mask = NFA_DM_DISC_MASK_LB_ISO_DEP;
+ break;
+ case NFC_DISCOVERY_TYPE_LISTEN_F:
+ if (protocol == NFC_PROTOCOL_T3T)
+ disc_mask = NFA_DM_DISC_MASK_LF_T3T;
+ else if (protocol == NFC_PROTOCOL_NFC_DEP)
+ disc_mask = NFA_DM_DISC_MASK_LF_NFC_DEP;
+ break;
+ case NFC_DISCOVERY_TYPE_LISTEN_ISO15693:
+ disc_mask = NFA_DM_DISC_MASK_L_ISO15693;
+ break;
+ case NFC_DISCOVERY_TYPE_LISTEN_B_PRIME:
+ disc_mask = NFA_DM_DISC_MASK_L_B_PRIME;
+ break;
+ case NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE:
+ disc_mask = NFA_DM_DISC_MASK_LAA_NFC_DEP;
+ break;
+ case NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE:
+ disc_mask = NFA_DM_DISC_MASK_LFA_NFC_DEP;
+ break;
+ }
+
+ NFA_TRACE_DEBUG3 ("nfa_dm_disc_get_disc_mask (): tech_n_mode:0x%X, protocol:0x%X, disc_mask:0x%X",
+ tech_n_mode, protocol, disc_mask);
+ return (disc_mask);
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_disc_discovery_cback
+**
+** Description Discovery callback event from NFC
+**
+** Returns void
+**
+*******************************************************************************/
+static void nfa_dm_disc_discovery_cback (tNFC_DISCOVER_EVT event, tNFC_DISCOVER *p_data)
+{
+ tNFA_DM_RF_DISC_SM_EVENT dm_disc_event = NFA_DM_DISC_SM_MAX_EVENT;
+
+ NFA_TRACE_DEBUG1 ("nfa_dm_disc_discovery_cback (): event:0x%X", event);
+
+ switch (event)
+ {
+ case NFC_START_DEVT:
+ dm_disc_event = NFA_DM_RF_DISCOVER_RSP;
+ break;
+ case NFC_RESULT_DEVT:
+ dm_disc_event = NFA_DM_RF_DISCOVER_NTF;
+ break;
+ case NFC_SELECT_DEVT:
+ dm_disc_event = NFA_DM_RF_DISCOVER_SELECT_RSP;
+ break;
+ case NFC_ACTIVATE_DEVT:
+ dm_disc_event = NFA_DM_RF_INTF_ACTIVATED_NTF;
+ break;
+ case NFC_DEACTIVATE_DEVT:
+ if (p_data->deactivate.is_ntf)
+ {
+ dm_disc_event = NFA_DM_RF_DEACTIVATE_NTF;
+ 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 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);
+
+ if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF) /* do not execute more than one */
+ {
+ 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)
+{
+ NFA_TRACE_ERROR0 ("nfa_dm_disc_deact_ntf_timeout_cback()");
+#if(NFC_NXP_ESE == TRUE && NFC_NXP_CHIP_TYPE == PN548C2)
+ if (nfc_cb.num_disc_maps == 1)
+ {
+ NFC_TRACE_ERROR0 ("reset Nfc..!!");
+ etsi_reader_in_progress = TRUE;
+ nfc_ncif_cmd_timeout();
+ }
+ else
+ {
+#endif
+ nfa_dm_disc_force_to_idle();
+#if(NFC_NXP_ESE == TRUE && NFC_NXP_CHIP_TYPE == PN548C2)
+ }
+#endif
+}
+
+/*******************************************************************************
+**
+** 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 (NFC_NXP_NOT_OPEN_INCLUDED == 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 (NFC_NXP_NOT_OPEN_INCLUDED == 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 = 0, poll_mask, listen_mask;
+ UINT8 num_params, xx;
+ unsigned long fwdEnable = FALSE, hostEnable =FALSE;
+ UINT8 tech_list = 0;
+
+ NFA_TRACE_DEBUG0 ("nfa_dm_start_rf_discover ()");
+ /* Make sure that RF discovery was enabled, or some app has exclusive control */
+ if ( (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_ENABLED))
+ &&(nfa_dm_cb.disc_cb.excl_disc_entry.in_use == FALSE) )
+ {
+ return;
+ }
+
+ /* get listen mode routing table for technology */
+ nfa_ee_get_tech_route (NFA_EE_PWR_STATE_ON, nfa_dm_cb.disc_cb.listen_RT);
+
+ if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use)
+ {
+ nfa_dm_set_rf_listen_mode_raw_config (&dm_disc_mask);
+ dm_disc_mask |= (nfa_dm_cb.disc_cb.excl_disc_entry.requested_disc_mask & NFA_DM_DISC_MASK_POLL);
+ nfa_dm_cb.disc_cb.excl_disc_entry.selected_disc_mask = dm_disc_mask;
+ }
+ else
+ {
+ /* Collect RF discovery request from sub-modules */
+ for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++)
+ {
+ if (nfa_dm_cb.disc_cb.entry[xx].in_use)
+ {
+ poll_mask = (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask & NFA_DM_DISC_MASK_POLL);
+ NFA_TRACE_DEBUG2 ("requested_disc_mask = 0x%x, xx=%d", nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask, xx);
+ /* clear poll mode technolgies and protocols which are already used by others */
+ poll_mask &= ~(dm_disc_mask & NFA_DM_DISC_MASK_POLL);
+
+ listen_mask = 0;
+
+ /*
+ ** add listen mode technolgies and protocols if host ID is matched to listen mode routing table
+ */
+
+ /* NFC-A */
+ if (nfa_dm_cb.disc_cb.entry[xx].host_id == nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_A])
+ {
+ listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask
+ & ( NFA_DM_DISC_MASK_LA_T1T
+ |NFA_DM_DISC_MASK_LA_T2T
+ |NFA_DM_DISC_MASK_LA_ISO_DEP
+ |NFA_DM_DISC_MASK_LA_NFC_DEP
+ |NFA_DM_DISC_MASK_LAA_NFC_DEP );
+ }
+ else
+ {
+ /* host can listen ISO-DEP based on AID routing */
+ listen_mask |= (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask & NFA_DM_DISC_MASK_LA_ISO_DEP);
+
+ /* 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;
+ }
+ }
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ if((GetNumValue(NAME_NXP_FWD_FUNCTIONALITY_ENABLE, &fwdEnable, sizeof(fwdEnable))) == FALSE)
+ {
+ fwdEnable = TRUE; //default value
+ }
+ if ((GetNumValue(NAME_HOST_LISTEN_ENABLE, &hostEnable, sizeof(hostEnable))) == FALSE)
+ {
+ hostEnable = TRUE;
+ NFA_TRACE_DEBUG2 ("%s:HOST_LISTEN_ENABLE=0x0%lu;", __FUNCTION__, hostEnable);
+ }
+
+ tech_list = nfa_ee_get_supported_tech_list(0x02);
+ if((fwdEnable == FALSE) || (hostEnable == FALSE))
+ {
+ 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);
+ }
+ }
+
+ NFA_TRACE_DEBUG1 ("dm_disc_mask = 0x%x", dm_disc_mask);
+
+ /* Get Discovery Technology parameters */
+ num_params = nfa_dm_get_rf_discover_config (dm_disc_mask, disc_params, NFA_DM_MAX_DISC_PARAMS);
+
+ if (num_params)
+ {
+ /*
+ ** NFCC will abort programming personality slots if not available.
+ ** NFCC programs the personality slots in the following order of RF technologies:
+ ** NFC-A, NFC-B, NFC-BP, NFC-I93
+ */
+
+ /* if this is not for exclusive control */
+ if (!nfa_dm_cb.disc_cb.excl_disc_entry.in_use)
+ {
+ /* update listening protocols in each NFC technology */
+ nfa_dm_set_rf_listen_mode_config (dm_disc_mask);
+ }
+
+ /* Set polling duty cycle */
+ nfa_dm_set_total_duration ();
+ nfa_dm_cb.disc_cb.dm_disc_mask = dm_disc_mask;
+
+ NFC_DiscoveryStart (num_params, disc_params, nfa_dm_disc_discovery_cback);
+ /* set flag about waiting for response in IDLE state */
+ nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
+
+ /* register callback to get interface error NTF */
+ NFC_SetStaticRfCback (nfa_dm_disc_data_cback);
+ }
+ else
+ {
+ /* RF discovery is started but there is no valid technology or protocol to discover */
+ nfa_dm_disc_notify_started (NFA_STATUS_OK);
+ }
+
+ /* 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
+**
+*******************************************************************************/
+BOOLEAN 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 xx, host_id_in_LRT;
+ UINT8 iso_dep_t3t__listen = NFA_DM_DISC_NUM_ENTRIES;
+
+ tNFC_RF_TECH_N_MODE tech_n_mode = p_data->activate.rf_tech_param.mode;
+ tNFC_PROTOCOL protocol = p_data->activate.protocol;
+
+ tNFA_DM_DISC_TECH_PROTO_MASK activated_disc_mask;
+
+ NFA_TRACE_DEBUG2 ("nfa_dm_disc_notify_activation (): tech_n_mode:0x%X, proto:0x%X",
+ tech_n_mode, protocol);
+
+ if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use)
+ {
+ nfa_dm_cb.disc_cb.activated_tech_mode = tech_n_mode;
+ nfa_dm_cb.disc_cb.activated_rf_disc_id = p_data->activate.rf_disc_id;
+ nfa_dm_cb.disc_cb.activated_rf_interface = p_data->activate.intf_param.type;
+ nfa_dm_cb.disc_cb.activated_protocol = protocol;
+ nfa_dm_cb.disc_cb.activated_handle = NFA_HANDLE_INVALID;
+
+ if (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(NFC_NXP_NOT_OPEN_INCLUDED == 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 == NCI_INTERFACE_UICC_DIRECT || p_data->activate.intf_param.type == 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 (NFC_NXP_NOT_OPEN_INCLUDED != 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(NFC_NXP_NOT_OPEN_INCLUDED == 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
+**
+*******************************************************************************/
+BOOLEAN 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
+**
+*******************************************************************************/
+BOOLEAN 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,
+ (tNFA_DM_RF_DISC_DATA *) &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;
+
+ 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, (tNFC_DISCOVER*)&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,
+ (tNFA_DM_RF_DISC_DATA *) &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 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
+{
+ NFA_TRACE_DEBUG0 ("nfa_dm_disc_data_cback ()");
+
+ /* if selection failed */
+ if (event == NFC_ERROR_CEVT)
+ {
+ nfa_dm_disc_sm_execute (NFA_DM_CORE_INTF_ERROR_NTF, NULL);
+ }
+ else if (event == NFC_DATA_CEVT)
+ {
+ GKI_freebuf (p_data->data.p_data);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_disc_new_state
+**
+** Description Processing discovery events in NFA_DM_RFST_IDLE state
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_dm_disc_new_state (tNFA_DM_RF_DISC_STATE new_state)
+{
+ tNFA_CONN_EVT_DATA evt_data;
+ tNFA_DM_RF_DISC_STATE old_state = nfa_dm_cb.disc_cb.disc_state;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ NFA_TRACE_DEBUG5 ("nfa_dm_disc_new_state (): old_state: %s (%d), new_state: %s (%d) disc_flags: 0x%x",
+ nfa_dm_disc_state_2_str (nfa_dm_cb.disc_cb.disc_state), nfa_dm_cb.disc_cb.disc_state,
+ nfa_dm_disc_state_2_str (new_state), new_state, nfa_dm_cb.disc_cb.disc_flags);
+#else
+ NFA_TRACE_DEBUG3 ("nfa_dm_disc_new_state(): old_state: %d, new_state: %d disc_flags: 0x%x",
+ nfa_dm_cb.disc_cb.disc_state, new_state, nfa_dm_cb.disc_cb.disc_flags);
+#endif
+
+ nfa_dm_cb.disc_cb.disc_state = new_state;
+
+ if ( (new_state == NFA_DM_RFST_IDLE)
+ &&(!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)) ) /* not error recovering */
+ {
+ if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING)
+ {
+ nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_STOPPING;
+
+ /* if exclusive RF control is stopping */
+ if (nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE)
+ {
+ if (old_state > NFA_DM_RFST_DISCOVERY)
+ {
+ /* notify deactivation to application */
+ evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE;
+ nfa_dm_conn_cback_event_notify (NFA_DEACTIVATED_EVT, &evt_data);
+ }
+
+ nfa_dm_rel_excl_rf_control_and_notify ();
+ }
+ else
+ {
+ evt_data.status = NFA_STATUS_OK;
+ nfa_dm_conn_cback_event_notify (NFA_RF_DISCOVERY_STOPPED_EVT, &evt_data);
+ }
+ }
+ if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_DISABLING)
+ {
+ nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_DISABLING;
+ nfa_sys_check_disabled ();
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_disc_sm_idle
+**
+** Description Processing discovery events in NFA_DM_RFST_IDLE state
+**
+** Returns void
+**
+*******************************************************************************/
+static void nfa_dm_disc_sm_idle (tNFA_DM_RF_DISC_SM_EVENT event,
+ tNFA_DM_RF_DISC_DATA *p_data)
+{
+ UINT8 xx;
+
+ switch (event)
+ {
+ case NFA_DM_RF_DISCOVER_CMD:
+ nfa_dm_start_rf_discover ();
+ break;
+
+ case NFA_DM_RF_DISCOVER_RSP:
+ nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
+
+ if (p_data->nfc_discover.status == NFC_STATUS_OK)
+ {
+ nfa_dm_disc_new_state (NFA_DM_RFST_DISCOVERY);
+
+ /* if RF discovery was stopped while waiting for response */
+ if (nfa_dm_cb.disc_cb.disc_flags & (NFA_DM_DISC_FLAGS_STOPPING|NFA_DM_DISC_FLAGS_DISABLING))
+ {
+ /* stop discovery */
+ nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
+ NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
+ break;
+ }
+
+ if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use)
+ {
+ if (nfa_dm_cb.disc_cb.excl_disc_entry.disc_flags & NFA_DM_DISC_FLAGS_NOTIFY)
+ {
+ nfa_dm_cb.disc_cb.excl_disc_entry.disc_flags &= ~NFA_DM_DISC_FLAGS_NOTIFY;
+
+ if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)
+ (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)) (NFA_DM_RF_DISC_START_EVT, (tNFC_DISCOVER*) p_data);
+ }
+ }
+ else
+ {
+ /* notify event to each module which is waiting for start */
+ for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++)
+ {
+ /* if registered module is waiting for starting discovery */
+ if ( (nfa_dm_cb.disc_cb.entry[xx].in_use)
+ &&(nfa_dm_cb.disc_cb.dm_disc_mask & nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask)
+ &&(nfa_dm_cb.disc_cb.entry[xx].disc_flags & NFA_DM_DISC_FLAGS_NOTIFY) )
+ {
+ nfa_dm_cb.disc_cb.entry[xx].disc_flags &= ~NFA_DM_DISC_FLAGS_NOTIFY;
+
+ if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
+ (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)) (NFA_DM_RF_DISC_START_EVT, (tNFC_DISCOVER*) p_data);
+ }
+ }
+
+ }
+ nfa_dm_disc_notify_started (p_data->nfc_discover.status);
+ }
+ else
+ {
+ /* in rare case that the discovery states of NFCC and DH mismatch and NFCC rejects Discover Cmd
+ * deactivate idle and then start disvocery when got deactivate rsp */
+ nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
+ NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
+ }
+ break;
+
+ case NFA_DM_RF_DEACTIVATE_RSP:
+ 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(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED == 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 == NCI_INTERFACE_UICC_DIRECT ||
+ p_data->nfc_discover.activate.intf_param.type == 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(NFC_NXP_NOT_OPEN_INCLUDED == 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);
+ BOOLEAN sleep_wakeup_event = FALSE;
+ BOOLEAN 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);
+ /* 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));
+ 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);
+ nfa_rw_set_cback(&(p_data->nfc_discover));
+ }
+ 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(NFC_NXP_NOT_OPEN_INCLUDED == 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);
+ BOOLEAN sleep_wakeup_event = FALSE;
+ BOOLEAN sleep_wakeup_event_processed = FALSE;
+ tNFC_DEACTIVATE_DEVT deact;
+
+ switch (event)
+ {
+ case NFA_DM_RF_DEACTIVATE_CMD:
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ 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;
+ }
+#endif
+ 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, (tNFC_DISCOVER*)&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(NFC_NXP_NOT_OPEN_INCLUDED != 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, (tNFC_DISCOVER*)&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);
+ nfa_dm_disc_notify_activation (&(p_data->nfc_discover));
+ 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 xx;
+
+ NFA_TRACE_DEBUG1 ("nfa_dm_add_rf_discover () disc_mask=0x%x", disc_mask);
+
+ for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++)
+ {
+ if (!nfa_dm_cb.disc_cb.entry[xx].in_use)
+ {
+ NFA_TRACE_DEBUG2 ("nfa_dm_add_rf_discover () disc_mask=0x%x, xx=%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 rf_disc_id,
+ tNFA_NFC_PROTOCOL protocol,
+ tNFA_INTF_TYPE rf_interface)
+{
+ tNFA_DM_DISC_SELECT_PARAMS select_params;
+ tNFA_CONN_EVT_DATA conn_evt;
+
+ NFA_TRACE_DEBUG3 ("nfa_dm_disc_select () rf_disc_id:0x%X, protocol:0x%X, rf_interface:0x%X",
+ rf_disc_id, protocol, rf_interface);
+
+ if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_W4_HOST_SELECT)
+ {
+ /* state is OK: notify the status when the response is received from NFCC */
+ select_params.rf_disc_id = rf_disc_id;
+ select_params.protocol = protocol;
+ select_params.rf_interface = rf_interface;
+
+ nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_NOTIFY;
+ nfa_dm_disc_sm_execute (NFA_DM_RF_DISCOVER_SELECT_CMD, (tNFA_DM_RF_DISC_DATA *) &select_params);
+ }
+ else
+ {
+ /* Wrong state: notify failed status right away */
+ conn_evt.status = NFA_STATUS_FAILED;
+ nfa_dm_conn_cback_event_notify (NFA_SELECT_RESULT_EVT, &conn_evt);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_rf_deactivate
+**
+** Description Deactivate NFC link
+**
+** Returns NFA_STATUS_OK if success
+**
+*******************************************************************************/
+tNFA_STATUS nfa_dm_rf_deactivate (tNFA_DEACTIVATE_TYPE deactivate_type)
+{
+ NFA_TRACE_DEBUG1 ("nfa_dm_rf_deactivate () deactivate_type:0x%X", deactivate_type);
+
+ if (deactivate_type == NFA_DEACTIVATE_TYPE_SLEEP)
+ {
+ if (nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_NFC_DEP)
+ deactivate_type = NFC_DEACTIVATE_TYPE_SLEEP_AF;
+ else
+ deactivate_type = NFC_DEACTIVATE_TYPE_SLEEP;
+ }
+
+ if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_IDLE)
+ {
+ return NFA_STATUS_FAILED;
+ }
+ else 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, (tNFA_DM_RF_DISC_DATA *) &deactivate_type);
+ return NFA_STATUS_OK;
+ }
+ else
+ {
+ return NFA_STATUS_FAILED;
+ }
+ }
+ else
+ {
+ nfa_dm_disc_sm_execute (NFA_DM_RF_DEACTIVATE_CMD, (tNFA_DM_RF_DISC_DATA *) &deactivate_type);
+ return NFA_STATUS_OK;
+ }
+}
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function nfa_dm_disc_state_2_str
+**
+** Description convert nfc discovery state to string
+**
+*******************************************************************************/
+static char *nfa_dm_disc_state_2_str (UINT8 state)
+{
+ switch (state)
+ {
+ case NFA_DM_RFST_IDLE:
+ return "IDLE";
+
+ case NFA_DM_RFST_DISCOVERY:
+ return "DISCOVERY";
+
+ case NFA_DM_RFST_W4_ALL_DISCOVERIES:
+ return "W4_ALL_DISCOVERIES";
+
+ case NFA_DM_RFST_W4_HOST_SELECT:
+ return "W4_HOST_SELECT";
+
+ case NFA_DM_RFST_POLL_ACTIVE:
+ return "POLL_ACTIVE";
+
+ case NFA_DM_RFST_LISTEN_ACTIVE:
+ return "LISTEN_ACTIVE";
+
+ case NFA_DM_RFST_LISTEN_SLEEP:
+ return "LISTEN_SLEEP";
+
+ case NFA_DM_RFST_LP_LISTEN:
+ return "LP_LISTEN";
+
+ case NFA_DM_RFST_LP_ACTIVE:
+ return "LP_ACTIVE";
+ }
+ return "Unknown";
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_disc_event_2_str
+**
+** Description convert nfc discovery RSP/NTF to string
+**
+*******************************************************************************/
+static char *nfa_dm_disc_event_2_str (UINT8 event)
+{
+ switch (event)
+ {
+ case NFA_DM_RF_DISCOVER_CMD:
+ return "DISCOVER_CMD";
+
+ case NFA_DM_RF_DISCOVER_RSP:
+ return "DISCOVER_RSP";
+
+ case NFA_DM_RF_DISCOVER_NTF:
+ return "DISCOVER_NTF";
+
+ case NFA_DM_RF_DISCOVER_SELECT_CMD:
+ return "SELECT_CMD";
+
+ case NFA_DM_RF_DISCOVER_SELECT_RSP:
+ return "SELECT_RSP";
+
+ case NFA_DM_RF_INTF_ACTIVATED_NTF:
+ return "ACTIVATED_NTF";
+
+ case NFA_DM_RF_DEACTIVATE_CMD:
+ return "DEACTIVATE_CMD";
+
+ case NFA_DM_RF_DEACTIVATE_RSP:
+ return "DEACTIVATE_RSP";
+
+ case NFA_DM_RF_DEACTIVATE_NTF:
+ return "DEACTIVATE_NTF";
+
+ case NFA_DM_LP_LISTEN_CMD:
+ return "NFA_DM_LP_LISTEN_CMD";
+
+ case NFA_DM_CORE_INTF_ERROR_NTF:
+ return "INTF_ERROR_NTF";
+
+ }
+ return "Unknown";
+}
+#endif /* BT_TRACE_VERBOSE */
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+/*******************************************************************************
+**
+** Function P2P_Prio_Logic
+**
+** Description Implements algorithm for NFC-DEP protocol priority over
+** ISO-DEP protocol.
+**
+** Returns True if success
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_p2p_prio_logic(UINT8 event, UINT8 *p, UINT8 ntf_rsp)
+{
+
+ 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 (TRUE == reconnect_in_progress ||
+ TRUE == is_emvco_active)
+ {
+ NFA_TRACE_DEBUG0("returning from nfa_dm_p2p_prio_logic reconnect_in_progress || is_emvco_active");
+ return TRUE;
+ }
+ if(0x01 == appl_dta_mode_flag)
+ {
+ /*Disable the P2P Prio Logic when DTA is running*/
+ return TRUE;
+ }
+ if(event == NCI_MSG_RF_DISCOVER && p2p_prio_logic_data.timer_expired == 1 && ntf_rsp == 1)
+ {
+ NFA_TRACE_DEBUG0("nfa_dm_p2p_prio_logic starting a timer for next rf intf activated ntf");
+ P2P_PRIO_LOGIC_CLEANUP_TIMEOUT = (nfa_dm_act_get_rf_disc_duration()/10); /*timeout value 50 ms multiplied by 10 for p2p_prio_logic_cleanup*/
+
+ nfc_start_quick_timer (&p2p_prio_logic_data.timer_list,
+ NFC_TTYPE_P2P_PRIO_LOGIC_CLEANUP, P2P_PRIO_LOGIC_CLEANUP_TIMEOUT);
+ return TRUE;
+ }
+ if(event == NCI_MSG_RF_INTF_ACTIVATED && p2p_prio_logic_data.timer_expired == 1)
+ {
+ 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 rf_disc_id = 0xFF;
+ UINT8 type = 0xFF;
+ UINT8 protocol = 0xFF;
+ UINT8 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 type = 0x%x", type);
+
+
+ if(type == NCI_INTERFACE_UICC_DIRECT || type == NCI_INTERFACE_ESE_DIRECT )
+ {
+ NFA_TRACE_DEBUG0 ("Disable the p2p prio logic RDR_SWP");
+ return TRUE;
+ }
+
+ 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 ");
+ memset(&p2p_prio_logic_data, 0x00, sizeof(nfa_dm_p2p_prio_logic_t));
+ }
+
+ if ((tech_mode < 0x80) &&
+ event == NCI_MSG_RF_INTF_ACTIVATED &&
+ protocol == NCI_PROTOCOL_ISO_DEP &&
+ p2p_prio_logic_data.isodep_detected == 0)
+ {
+ memset(&p2p_prio_logic_data, 0x00, sizeof(nfa_dm_p2p_prio_logic_t));
+ p2p_prio_logic_data.isodep_detected = 1;
+ 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);
+ return FALSE;
+ }
+
+ else if(event == NCI_MSG_RF_INTF_ACTIVATED &&
+ protocol == NCI_PROTOCOL_ISO_DEP &&
+ p2p_prio_logic_data.isodep_detected == 1 &&
+ p2p_prio_logic_data.first_tech_mode != tech_mode)
+ {
+ p2p_prio_logic_data.isodep_detected = 1;
+ p2p_prio_logic_data.timer_expired = 0;
+ 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);
+ return FALSE;
+ }
+
+ else if (event == NCI_MSG_RF_INTF_ACTIVATED &&
+ protocol == NCI_PROTOCOL_ISO_DEP &&
+ p2p_prio_logic_data.isodep_detected == 1 &&
+ p2p_prio_logic_data.timer_expired == 1)
+ {
+ NFA_TRACE_DEBUG0 ("ISO-DEP Detected TimerExpired, Final Notifying the Event");
+ nfc_stop_quick_timer (&p2p_prio_logic_data.timer_list);
+ memset(&p2p_prio_logic_data, 0x00, sizeof(nfa_dm_p2p_prio_logic_t));
+ }
+
+ else if (event == NCI_MSG_RF_INTF_ACTIVATED &&
+ protocol == NCI_PROTOCOL_ISO_DEP &&
+ p2p_prio_logic_data.isodep_detected == 1 &&
+ 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");
+ memset(&p2p_prio_logic_data, 0x00, sizeof(nfa_dm_p2p_prio_logic_t));
+ }
+
+ else if (event == NCI_MSG_RF_INTF_ACTIVATED &&
+ protocol != NCI_PROTOCOL_ISO_DEP &&
+ p2p_prio_logic_data.isodep_detected == 1)
+ {
+ 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");
+ memset(&p2p_prio_logic_data, 0x00, sizeof(nfa_dm_p2p_prio_logic_t));
+ }
+
+ else if (event == NCI_MSG_RF_DEACTIVATE &&
+ p2p_prio_logic_data.isodep_detected == 1 &&
+ p2p_prio_logic_data.timer_expired == 0 &&
+ ntf_rsp == 1)
+ {
+ NFA_TRACE_DEBUG0 ("NFA_DM_RF_DEACTIVATE_RSP");
+ return FALSE;
+ }
+
+ else if (event == NCI_MSG_RF_DEACTIVATE &&
+ p2p_prio_logic_data.isodep_detected == 1 &&
+ p2p_prio_logic_data.timer_expired == 0 && ntf_rsp == 2)
+ {
+ NFA_TRACE_DEBUG0 ("NFA_DM_RF_DEACTIVATE_NTF");
+
+ nfc_start_quick_timer (&p2p_prio_logic_data.timer_list,
+ NFC_TTYPE_P2P_PRIO_RESPONSE, P2P_RESUME_POLL_TIMEOUT);
+
+ NFA_TRACE_DEBUG0 ("P2P_Start_Timer");
+
+ return FALSE;
+ }
+ }
+
+ NFA_TRACE_DEBUG0("returning TRUE");
+ return TRUE;
+}
+void NFA_SetReconnectState (BOOLEAN flag)
+{
+ reconnect_in_progress = flag;
+ NFA_TRACE_DEBUG1("NFA_SetReconnectState = 0x%x", reconnect_in_progress);
+}
+
+void NFA_SetEmvCoState (BOOLEAN flag)
+{
+ is_emvco_active = flag;
+ NFA_TRACE_DEBUG1("NFA_SetEmvCoState = 0x%x", is_emvco_active);
+}
+
+/*******************************************************************************
+**
+** 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));
+}
+#endif
diff --git a/src/nfa/dm/nfa_dm_main.c b/src/nfa/dm/nfa_dm_main.c
new file mode 100644
index 0000000..e17b751
--- /dev/null
+++ b/src/nfa/dm/nfa_dm_main.c
@@ -0,0 +1,607 @@
+/******************************************************************************
+ *
+ * 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"
+
+
+/*****************************************************************************
+** 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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+tNFA_DM_CB nfa_dm_cb;
+#else
+tNFA_DM_CB nfa_dm_cb = {FALSE};
+#endif
+
+
+#define NFA_DM_NUM_ACTIONS (NFA_DM_MAX_EVT & 0x00ff)
+
+/* type for action functions */
+typedef BOOLEAN (*tNFA_DM_ACTION) (tNFA_DM_MSG *p_data);
+
+/* action function list */
+const tNFA_DM_ACTION nfa_dm_action[] =
+{
+ /* device manager local device API events */
+ nfa_dm_enable, /* NFA_DM_API_ENABLE_EVT */
+ nfa_dm_disable, /* NFA_DM_API_DISABLE_EVT */
+ nfa_dm_set_config, /* NFA_DM_API_SET_CONFIG_EVT */
+ nfa_dm_get_config, /* NFA_DM_API_GET_CONFIG_EVT */
+ nfa_dm_act_request_excl_rf_ctrl, /* NFA_DM_API_REQUEST_EXCL_RF_CTRL_EVT */
+ nfa_dm_act_release_excl_rf_ctrl, /* NFA_DM_API_RELEASE_EXCL_RF_CTRL_EVT */
+ nfa_dm_act_enable_polling, /* NFA_DM_API_ENABLE_POLLING_EVT */
+ nfa_dm_act_disable_polling, /* NFA_DM_API_DISABLE_POLLING_EVT */
+ nfa_dm_act_enable_listening, /* NFA_DM_API_ENABLE_LISTENING_EVT */
+ nfa_dm_act_disable_listening, /* NFA_DM_API_DISABLE_LISTENING_EVT */
+ 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 (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ , nfa_dm_act_send_nxp /* NFA_DM_API_SEND_NXP_EVT */
+#endif
+};
+
+/*****************************************************************************
+** Local function prototypes
+*****************************************************************************/
+#if (BT_TRACE_VERBOSE == TRUE)
+static char *nfa_dm_evt_2_str (UINT16 event);
+#endif
+/*******************************************************************************
+**
+** Function nfa_dm_init
+**
+** Description Initialises the NFC device manager
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_dm_init (void)
+{
+ NFA_TRACE_DEBUG0 ("nfa_dm_init ()");
+ memset (&nfa_dm_cb, 0, sizeof (tNFA_DM_CB));
+ nfa_dm_cb.poll_disc_handle = NFA_HANDLE_INVALID;
+ nfa_dm_cb.disc_cb.disc_duration = NFA_DM_DISC_DURATION_POLL;
+ nfa_dm_cb.nfcc_pwr_mode = NFA_DM_PWR_MODE_FULL;
+
+ /* register message handler on NFA SYS */
+ nfa_sys_register (NFA_ID_DM, &nfa_dm_sys_reg);
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_evt_hdlr
+**
+** Description Event handling function for DM
+**
+**
+** Returns void
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_evt_hdlr (BT_HDR *p_msg)
+{
+ BOOLEAN freebuf = TRUE;
+ UINT16 event = p_msg->event & 0x00ff;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ NFA_TRACE_EVENT2 ("nfa_dm_evt_hdlr event: %s (0x%02x)", nfa_dm_evt_2_str (event), event);
+#else
+ NFA_TRACE_EVENT1 ("nfa_dm_evt_hdlr event: 0x%x", event);
+#endif
+
+ /* execute action functions */
+ if (event < NFA_DM_NUM_ACTIONS)
+ {
+ freebuf = (*nfa_dm_action[event]) ((tNFA_DM_MSG*) p_msg);
+ }
+ return freebuf;
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_sys_disable
+**
+** Description This function is called after all subsystems have been disabled.
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_dm_sys_disable (void)
+{
+ /* Disable the DM sub-system */
+ /* If discovery state is not IDLE or DEACTIVATED and graceful disable, */
+ /* then we need to deactivate link or stop discovery */
+
+ if (nfa_sys_is_graceful_disable ())
+ {
+ if ( (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_IDLE)
+ &&((nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_DISABLING) == 0) )
+ {
+ /* discovery is not started */
+ nfa_dm_disable_complete ();
+ }
+ else
+ {
+ /* probably waiting to be disabled */
+ NFA_TRACE_WARNING2 ("DM disc_state state = %d disc_flags:0x%x", nfa_dm_cb.disc_cb.disc_state, nfa_dm_cb.disc_cb.disc_flags);
+ }
+
+ }
+ else
+ {
+ nfa_dm_disable_complete ();
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_is_protocol_supported
+**
+** Description Check if protocol is supported by RW module
+**
+** Returns TRUE if protocol is supported by NFA
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_is_protocol_supported (tNFC_PROTOCOL protocol, UINT8 sel_res)
+{
+ return ( (protocol == NFC_PROTOCOL_T1T)
+ ||((protocol == NFC_PROTOCOL_T2T) && (sel_res == NFC_SEL_RES_NFC_FORUM_T2T))
+ ||(protocol == NFC_PROTOCOL_T3T)
+ ||(protocol == NFC_PROTOCOL_ISO_DEP)
+ ||(protocol == NFC_PROTOCOL_NFC_DEP)
+ ||(protocol == NFC_PROTOCOL_15693)
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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
+**
+*******************************************************************************/
+BOOLEAN 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 tlv_list_len, UINT8 *p_tlv_list, BOOLEAN app_init)
+{
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ UINT8 type, len, *p_value, *p_stored = NULL, max_len = 0;
+#else
+ UINT8 type, len, *p_value, *p_stored, max_len;
+#endif
+ UINT8 xx = 0, updated_len = 0, *p_cur_len;
+ BOOLEAN update;
+ tNFC_STATUS nfc_status;
+ UINT32 cur_bit;
+
+ NFA_TRACE_DEBUG0 ("nfa_dm_check_set_config ()");
+
+ /* We only allow 32 pending SET_CONFIGs */
+ if (nfa_dm_cb.setcfg_pending_num >= NFA_DM_SETCONFIG_PENDING_MAX)
+ {
+ NFA_TRACE_ERROR0 ("nfa_dm_check_set_config () error: pending number of SET_CONFIG exceeded");
+ return NFA_STATUS_FAILED;
+ }
+
+ while (tlv_list_len - xx >= 2) /* at least type and len */
+ {
+ update = FALSE;
+ type = *(p_tlv_list + xx);
+ len = *(p_tlv_list + xx + 1);
+ p_value = p_tlv_list + xx + 2;
+ p_cur_len = NULL;
+
+ switch (type)
+ {
+ case NFC_PMID_TOTAL_DURATION:
+ p_stored = nfa_dm_cb.params.total_duration;
+ max_len = NCI_PARAM_LEN_TOTAL_DURATION;
+ break;
+
+ /*
+ ** Listen A Configuration
+ */
+ case NFC_PMID_LA_BIT_FRAME_SDD:
+ p_stored = nfa_dm_cb.params.la_bit_frame_sdd;
+ max_len = NCI_PARAM_LEN_LA_BIT_FRAME_SDD;
+ p_cur_len = &nfa_dm_cb.params.la_bit_frame_sdd_len;
+ break;
+ case NFC_PMID_LA_PLATFORM_CONFIG:
+ p_stored = nfa_dm_cb.params.la_platform_config;
+ max_len = NCI_PARAM_LEN_LA_PLATFORM_CONFIG;
+ p_cur_len = &nfa_dm_cb.params.la_platform_config_len;
+ break;
+ case NFC_PMID_LA_SEL_INFO:
+ p_stored = nfa_dm_cb.params.la_sel_info;
+ max_len = NCI_PARAM_LEN_LA_SEL_INFO;
+ p_cur_len = &nfa_dm_cb.params.la_sel_info_len;
+ break;
+ case NFC_PMID_LA_NFCID1:
+ p_stored = nfa_dm_cb.params.la_nfcid1;
+ max_len = NCI_NFCID1_MAX_LEN;
+ p_cur_len = &nfa_dm_cb.params.la_nfcid1_len;
+ break;
+ case NFC_PMID_LA_HIST_BY:
+ p_stored = nfa_dm_cb.params.la_hist_by;
+ max_len = NCI_MAX_HIS_BYTES_LEN;
+ p_cur_len = &nfa_dm_cb.params.la_hist_by_len;
+ break;
+
+ /*
+ ** Listen B Configuration
+ */
+ case NFC_PMID_LB_SENSB_INFO:
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED != 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;
+#endif
+ /*
+ ** ISO-DEP and NFC-DEP Configuration
+ */
+#if(NFC_NXP_NOT_OPEN_INCLUDED != TRUE)
+ 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;
+ }
+ 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(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ ((
+#endif
+ (updated_len || app_init)
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ && (appl_dta_mode_flag == 0x00 ))
+ || ((appl_dta_mode_flag) && (app_init)))
+#endif
+ {
+ if ((nfc_status = NFC_SetConfig (updated_len, p_tlv_list)) == NFC_STATUS_OK)
+ {
+ /* Keep track of whether we will need to notify NFA_DM_SET_CONFIG_EVT on NFC_SET_CONFIG_REVT */
+
+ /* Get the next available bit offset for this setconfig (based on how many SetConfigs are outstanding) */
+ cur_bit = (UINT32) (1 << nfa_dm_cb.setcfg_pending_num);
+
+ /* If setconfig is due to NFA_SetConfig: then set the bit (NFA_DM_SET_CONFIG_EVT needed on NFC_SET_CONFIG_REVT) */
+ if (app_init)
+ {
+ nfa_dm_cb.setcfg_pending_mask |= cur_bit;
+ }
+ /* Otherwise setconfig is internal: clear the bit (NFA_DM_SET_CONFIG_EVT not needed on NFC_SET_CONFIG_REVT) */
+ else
+ {
+ nfa_dm_cb.setcfg_pending_mask &= ~cur_bit;
+ }
+
+ /* Increment setcfg_pending counter */
+ nfa_dm_cb.setcfg_pending_num++;
+ }
+ return (nfc_status);
+
+ }
+ else
+ {
+ return NFA_STATUS_OK;
+ }
+}
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function nfa_dm_nfc_revt_2_str
+**
+** Description convert nfc revt to string
+**
+*******************************************************************************/
+static char *nfa_dm_evt_2_str (UINT16 event)
+{
+ switch (NFA_SYS_EVT_START (NFA_ID_DM) | event)
+ {
+ case NFA_DM_API_ENABLE_EVT:
+ return "NFA_DM_API_ENABLE_EVT";
+
+ case NFA_DM_API_DISABLE_EVT:
+ return "NFA_DM_API_DISABLE_EVT";
+
+ case NFA_DM_API_SET_CONFIG_EVT:
+ return "NFA_DM_API_SET_CONFIG_EVT";
+
+ case NFA_DM_API_GET_CONFIG_EVT:
+ return "NFA_DM_API_GET_CONFIG_EVT";
+
+ case NFA_DM_API_REQUEST_EXCL_RF_CTRL_EVT:
+ return "NFA_DM_API_REQUEST_EXCL_RF_CTRL_EVT";
+
+ case NFA_DM_API_RELEASE_EXCL_RF_CTRL_EVT:
+ return "NFA_DM_API_RELEASE_EXCL_RF_CTRL_EVT";
+
+ case NFA_DM_API_ENABLE_POLLING_EVT:
+ return "NFA_DM_API_ENABLE_POLLING_EVT";
+
+ case NFA_DM_API_DISABLE_POLLING_EVT:
+ return "NFA_DM_API_DISABLE_POLLING_EVT";
+
+ case NFA_DM_API_ENABLE_LISTENING_EVT:
+ return "NFA_DM_API_ENABLE_LISTENING_EVT";
+
+ case NFA_DM_API_DISABLE_LISTENING_EVT:
+ return "NFA_DM_API_DISABLE_LISTENING_EVT";
+
+ 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";
+
+ }
+
+ 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..5427dd9
--- /dev/null
+++ b/src/nfa/dm/nfa_dm_ndef.c
@@ -0,0 +1,533 @@
+/******************************************************************************
+ *
+ * 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 *nfa_dm_ndef_wkt_uri_str_tbl[] = {
+ NULL, /* 0x00 */
+ (const UINT8*) "http://www.", /* 0x01 */
+ (const UINT8*) "https://www.", /* 0x02 */
+ (const UINT8*) "http://", /* 0x03 */
+ (const UINT8*) "https://", /* 0x04 */
+ (const UINT8*) "tel:", /* 0x05 */
+ (const UINT8*) "mailto:", /* 0x06 */
+ (const UINT8*) "ftp://anonymous:anonymous@", /* 0x07 */
+ (const UINT8*) "ftp://ftp.", /* 0x08 */
+ (const UINT8*) "ftps://", /* 0x09 */
+ (const UINT8*) "sftp://", /* 0x0A */
+ (const UINT8*) "smb://", /* 0x0B */
+ (const UINT8*) "nfs://", /* 0x0C */
+ (const UINT8*) "ftp://", /* 0x0D */
+ (const UINT8*) "dav://", /* 0x0E */
+ (const UINT8*) "news:", /* 0x0F */
+ (const UINT8*) "telnet://", /* 0x10 */
+ (const UINT8*) "imap:", /* 0x11 */
+ (const UINT8*) "rtsp://", /* 0x12 */
+ (const UINT8*) "urn:", /* 0x13 */
+ (const UINT8*) "pop:", /* 0x14 */
+ (const UINT8*) "sip:", /* 0x15 */
+ (const UINT8*) "sips:", /* 0x16 */
+ (const UINT8*) "tftp:", /* 0x17 */
+ (const UINT8*) "btspp://", /* 0x18 */
+ (const UINT8*) "btl2cap://", /* 0x19 */
+ (const UINT8*) "btgoep://", /* 0x1A */
+ (const UINT8*) "tcpobex://", /* 0x1B */
+ (const UINT8*) "irdaobex://", /* 0x1C */
+ (const UINT8*) "file://", /* 0x1D */
+ (const UINT8*) "urn:epc:id:", /* 0x1E */
+ (const UINT8*) "urn:epc:tag:", /* 0x1F */
+ (const UINT8*) "urn:epc:pat:", /* 0x20 */
+ (const UINT8*) "urn:epc:raw:", /* 0x21 */
+ (const UINT8*) "urn:epc:", /* 0x22 */
+ (const UINT8*) "urn:nfc:" /* 0x23 */
+};
+#define NFA_DM_NDEF_WKT_URI_STR_TBL_SIZE (sizeof (nfa_dm_ndef_wkt_uri_str_tbl) / sizeof (UINT8 *))
+
+/*******************************************************************************
+**
+** Function nfa_dm_ndef_dereg_hdlr_by_handle
+**
+** Description Deregister NDEF record type handler
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+void nfa_dm_ndef_dereg_hdlr_by_handle (tNFA_HANDLE ndef_type_handle)
+{
+ tNFA_DM_CB *p_cb = &nfa_dm_cb;
+ UINT16 hdlr_idx;
+ hdlr_idx = (UINT16) (ndef_type_handle & NFA_HANDLE_MASK);
+
+ if (p_cb->p_ndef_handler[hdlr_idx])
+ {
+ GKI_freebuf (p_cb->p_ndef_handler[hdlr_idx]);
+ p_cb->p_ndef_handler[hdlr_idx] = NULL;
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_ndef_dereg_all
+**
+** Description Deregister all NDEF record type handlers (called during
+** shutdown(.
+**
+** Returns Nothing
+**
+*******************************************************************************/
+void nfa_dm_ndef_dereg_all (void)
+{
+ tNFA_DM_CB *p_cb = &nfa_dm_cb;
+ UINT32 i;
+
+ for (i = 0; i < NFA_NDEF_MAX_HANDLERS; i++)
+ {
+ /* If this is a free slot, then remember it */
+ if (p_cb->p_ndef_handler[i] != NULL)
+ {
+ GKI_freebuf (p_cb->p_ndef_handler[i]);
+ p_cb->p_ndef_handler[i] = NULL;
+ }
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function nfa_dm_ndef_reg_hdlr
+**
+** Description Register NDEF record type handler
+**
+** Returns TRUE if message buffer is to be freed by caller
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_ndef_reg_hdlr (tNFA_DM_MSG *p_data)
+{
+ tNFA_DM_CB *p_cb = &nfa_dm_cb;
+ UINT32 hdlr_idx, i;
+ tNFA_DM_API_REG_NDEF_HDLR *p_reg_info = (tNFA_DM_API_REG_NDEF_HDLR *) p_data;
+ tNFA_NDEF_REGISTER ndef_register;
+
+ /* If registering default handler, check to see if one is already registered */
+ if (p_reg_info->tnf == NFA_TNF_DEFAULT)
+ {
+ /* check if default handler is already registered */
+ if (p_cb->p_ndef_handler[NFA_NDEF_DEFAULT_HANDLER_IDX])
+ {
+ NFA_TRACE_WARNING0 ("Default NDEF handler being changed.");
+
+ /* Free old registration info */
+ nfa_dm_ndef_dereg_hdlr_by_handle ((tNFA_HANDLE) NFA_NDEF_DEFAULT_HANDLER_IDX);
+ }
+ NFA_TRACE_DEBUG0 ("Default NDEF handler successfully registered.");
+ hdlr_idx = NFA_NDEF_DEFAULT_HANDLER_IDX;
+ }
+ /* Get available entry in ndef_handler table, and check if requested type is already registered */
+ else
+ {
+ hdlr_idx = NFA_HANDLE_INVALID;
+
+ /* Check if this type is already registered */
+ for (i = (NFA_NDEF_DEFAULT_HANDLER_IDX+1); i < NFA_NDEF_MAX_HANDLERS; i++)
+ {
+ /* If this is a free slot, then remember it */
+ if (p_cb->p_ndef_handler[i] == NULL)
+ {
+ hdlr_idx = i;
+ break;
+ }
+ }
+ }
+
+ if (hdlr_idx != NFA_HANDLE_INVALID)
+ {
+ /* Update the table */
+ p_cb->p_ndef_handler[hdlr_idx] = p_reg_info;
+
+ p_reg_info->ndef_type_handle = (tNFA_HANDLE) (NFA_HANDLE_GROUP_NDEF_HANDLER | hdlr_idx);
+
+ ndef_register.ndef_type_handle = p_reg_info->ndef_type_handle;
+ ndef_register.status = NFA_STATUS_OK;
+
+ NFA_TRACE_DEBUG1 ("NDEF handler successfully registered. Handle=0x%08x", p_reg_info->ndef_type_handle);
+ (*(p_reg_info->p_ndef_cback)) (NFA_NDEF_REGISTER_EVT, (tNFA_NDEF_EVT_DATA *) &ndef_register);
+
+ return FALSE; /* indicate that we will free message buffer when type_handler is deregistered */
+ }
+ else
+ {
+ /* Error */
+ NFA_TRACE_ERROR0 ("NDEF handler failed to register.");
+ ndef_register.ndef_type_handle = NFA_HANDLE_INVALID;
+ ndef_register.status = NFA_STATUS_FAILED;
+ (*(p_reg_info->p_ndef_cback)) (NFA_NDEF_REGISTER_EVT, (tNFA_NDEF_EVT_DATA *) &ndef_register);
+
+ return TRUE;
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_ndef_dereg_hdlr
+**
+** Description Deregister NDEF record type handler
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_ndef_dereg_hdlr (tNFA_DM_MSG *p_data)
+{
+ tNFA_DM_API_DEREG_NDEF_HDLR *p_dereginfo = (tNFA_DM_API_DEREG_NDEF_HDLR *) p_data;
+
+ /* Make sure this is a NDEF_HDLR handle */
+ if ( ((p_dereginfo->ndef_type_handle & NFA_HANDLE_GROUP_MASK) != NFA_HANDLE_GROUP_NDEF_HANDLER)
+ ||((p_dereginfo->ndef_type_handle & NFA_HANDLE_MASK) >= NFA_NDEF_MAX_HANDLERS) )
+ {
+ NFA_TRACE_ERROR1 ("Invalid handle for NDEF type handler: 0x%08x", p_dereginfo->ndef_type_handle);
+ }
+ else
+ {
+ nfa_dm_ndef_dereg_hdlr_by_handle (p_dereginfo->ndef_type_handle);
+ }
+
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_ndef_find_next_handler
+**
+** Description Find next ndef handler for a given record type
+**
+** Returns void
+**
+*******************************************************************************/
+tNFA_DM_API_REG_NDEF_HDLR *nfa_dm_ndef_find_next_handler (tNFA_DM_API_REG_NDEF_HDLR *p_init_handler,
+ UINT8 tnf,
+ UINT8 *p_type_name,
+ UINT8 type_name_len,
+ UINT8 *p_payload,
+ UINT32 payload_len)
+{
+ tNFA_DM_CB *p_cb = &nfa_dm_cb;
+ UINT8 i;
+
+ /* if init_handler is NULL, then start with the first non-default handler */
+ if (!p_init_handler)
+ i=NFA_NDEF_DEFAULT_HANDLER_IDX+1;
+ else
+ {
+ /* Point to handler index after p_init_handler */
+ i = (p_init_handler->ndef_type_handle & NFA_HANDLE_MASK) + 1;
+ }
+
+
+ /* Look for next handler */
+ for (; i < NFA_NDEF_MAX_HANDLERS; i++)
+ {
+ /* Check if TNF matches */
+ if ( (p_cb->p_ndef_handler[i])
+ &&(p_cb->p_ndef_handler[i]->tnf == tnf) )
+ {
+ /* TNF matches. */
+ /* If handler is for a specific URI type, check if type is WKT URI, */
+ /* and that the URI prefix abrieviation for this handler matches */
+ if (p_cb->p_ndef_handler[i]->flags & NFA_NDEF_FLAGS_WKT_URI)
+ {
+ /* This is a handler for a specific URI type */
+ /* Check if this recurd is WKT URI */
+ if ((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 i;
+
+ for (i = 0; i < NFA_NDEF_MAX_HANDLERS; i++)
+ {
+ if (p_cb->p_ndef_handler[i])
+ {
+ p_cb->p_ndef_handler[i]->flags &= ~NFA_NDEF_FLAGS_WHOLE_MESSAGE_NOTIFIED;
+ }
+ }
+
+
+}
+
+/*******************************************************************************
+**
+** Function nfa_dm_ndef_handle_message
+**
+** Description Handle incoming ndef message
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_dm_ndef_handle_message (tNFA_STATUS status, UINT8 *p_msg_buf, UINT32 len)
+{
+ tNFA_DM_CB *p_cb = &nfa_dm_cb;
+ tNDEF_STATUS ndef_status;
+ UINT8 *p_rec, *p_ndef_start, *p_type, *p_payload, *p_rec_end;
+ UINT32 payload_len;
+ UINT8 tnf, type_len, rec_hdr_flags, id_len;
+ tNFA_DM_API_REG_NDEF_HDLR *p_handler;
+ tNFA_NDEF_DATA ndef_data;
+ UINT8 rec_count = 0;
+ BOOLEAN record_handled, entire_message_handled;
+
+ NFA_TRACE_DEBUG3 ("nfa_dm_ndef_handle_message status=%i, msgbuf=%08x, len=%i", status, p_msg_buf, len);
+
+ if (status != NFA_STATUS_OK)
+ {
+ /* If problem reading NDEF message, then exit (no action required) */
+ return;
+ }
+
+ /* If in exclusive RF mode is activer, then route NDEF message callback registered with NFA_StartExclusiveRfControl */
+ if ((p_cb->flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE) && (p_cb->p_excl_ndef_cback))
+ {
+ ndef_data.ndef_type_handle = 0; /* No ndef-handler handle, since this callback is not from RegisterNDefHandler */
+ ndef_data.p_data = p_msg_buf;
+ ndef_data.len = len;
+ (*p_cb->p_excl_ndef_cback) (NFA_NDEF_DATA_EVT, (tNFA_NDEF_EVT_DATA *) &ndef_data);
+ return;
+ }
+
+ /* Handle zero length - notify default handler */
+ if (len == 0)
+ {
+ if ((p_handler = p_cb->p_ndef_handler[NFA_NDEF_DEFAULT_HANDLER_IDX]) != NULL)
+ {
+ NFA_TRACE_DEBUG0 ("Notifying default handler of zero-length NDEF message...");
+ ndef_data.ndef_type_handle = p_handler->ndef_type_handle;
+ ndef_data.p_data = NULL; /* Start of record */
+ ndef_data.len = 0;
+ (*p_handler->p_ndef_cback) (NFA_NDEF_DATA_EVT, (tNFA_NDEF_EVT_DATA *) &ndef_data);
+ }
+ return;
+ }
+
+ /* Validate the NDEF message */
+ if ((ndef_status = NDEF_MsgValidate (p_msg_buf, len, TRUE)) != NDEF_OK)
+ {
+ NFA_TRACE_ERROR1 ("Received invalid NDEF message. NDEF status=0x%x", ndef_status);
+ return;
+ }
+
+ /* NDEF message received from backgound polling. Pass the NDEF message to the NDEF handlers */
+
+ /* New NDEF message. Clear 'notified' flag for all the handlers */
+ nfa_dm_ndef_clear_notified_flag ();
+
+ /* Indicate that no handler has handled this entire NDEF message (e.g. connection-handover handler *) */
+ entire_message_handled = FALSE;
+
+ /* Get first record in message */
+ p_rec = p_ndef_start = p_msg_buf;
+
+ /* Check each record in the NDEF message */
+ while (p_rec != NULL)
+ {
+ /* Get record type */
+ p_type = NDEF_RecGetType (p_rec, &tnf, &type_len);
+
+ /* Indicate record not handled yet */
+ record_handled = FALSE;
+
+ /* Get pointer to record payload */
+ p_payload = NDEF_RecGetPayload (p_rec, &payload_len);
+
+ /* Find first handler for this type */
+ if ((p_handler = nfa_dm_ndef_find_next_handler (NULL, tnf, p_type, type_len, p_payload, payload_len)) == NULL)
+ {
+ /* Not a registered NDEF type. Use default handler */
+ if ((p_handler = p_cb->p_ndef_handler[NFA_NDEF_DEFAULT_HANDLER_IDX]) != NULL)
+ {
+ NFA_TRACE_DEBUG0 ("No handler found. Using default handler...");
+ }
+ }
+
+ while (p_handler)
+ {
+ /* If handler is for whole NDEF message, and it has already been notified, then skip notification */
+ if (p_handler->flags & NFA_NDEF_FLAGS_WHOLE_MESSAGE_NOTIFIED)
+ {
+ /* Look for next handler */
+ p_handler = nfa_dm_ndef_find_next_handler (p_handler, tnf, p_type, type_len, p_payload, payload_len);
+ continue;
+ }
+
+ /* Get pointer to record payload */
+ NFA_TRACE_DEBUG1 ("Calling ndef type handler (%x)", p_handler->ndef_type_handle);
+
+ ndef_data.ndef_type_handle = p_handler->ndef_type_handle;
+ ndef_data.p_data = p_rec; /* Start of record */
+
+ /* Calculate length of NDEF record */
+ if (p_payload != NULL)
+ ndef_data.len = payload_len + (UINT32) (p_payload - p_rec);
+ else
+ {
+ /* If no payload, calculate length of ndef record header */
+ p_rec_end = p_rec;
+
+ /* First byte is the header flags */
+ rec_hdr_flags = *p_rec_end++;
+
+ /* Next byte is the type field length */
+ type_len = *p_rec_end++;
+
+ /* Next is the payload length (1 or 4 bytes) */
+ if (rec_hdr_flags & NDEF_SR_MASK)
+ {
+ p_rec_end++;
+ }
+ else
+ {
+ p_rec_end+=4;
+ }
+
+ /* ID field Length */
+ if (rec_hdr_flags & NDEF_IL_MASK)
+ id_len = *p_rec_end++;
+ else
+ id_len = 0;
+ p_rec_end+=id_len;
+
+ ndef_data.len = (UINT32) (p_rec_end - p_rec);
+ }
+
+ /* If handler wants entire ndef message, then pass pointer to start of message and */
+ /* set 'notified' flag so handler won't get notified on subsequent records for this */
+ /* NDEF message. */
+ if (p_handler->flags & NFA_NDEF_FLAGS_HANDLE_WHOLE_MESSAGE)
+ {
+ ndef_data.p_data = p_ndef_start; /* Start of NDEF message */
+ ndef_data.len = len;
+ p_handler->flags |= NFA_NDEF_FLAGS_WHOLE_MESSAGE_NOTIFIED;
+
+ /* Indicate that at least one handler has received entire NDEF message */
+ entire_message_handled = TRUE;
+ }
+
+ /* Notify NDEF type handler */
+ (*p_handler->p_ndef_cback) (NFA_NDEF_DATA_EVT, (tNFA_NDEF_EVT_DATA *) &ndef_data);
+
+ /* Indicate that at lease one handler has received this record */
+ record_handled = TRUE;
+
+ /* Look for next handler */
+ p_handler = nfa_dm_ndef_find_next_handler (p_handler, tnf, p_type, type_len, p_payload, payload_len);
+ }
+
+
+ /* Check if at least one handler was notified of this record (only happens if no default handler was register) */
+ if ((!record_handled) && (!entire_message_handled))
+ {
+ /* Unregistered NDEF record type; no default handler */
+ NFA_TRACE_WARNING1 ("Unhandled NDEF record (#%i)", rec_count);
+ }
+
+ rec_count++;
+ p_rec = NDEF_MsgGetNextRec (p_rec);
+ }
+}
diff --git a/src/nfa/ee/nfa_ee_act.c b/src/nfa/ee/nfa_ee_act.c
new file mode 100644
index 0000000..f973d1a
--- /dev/null
+++ b/src/nfa/ee/nfa_ee_act.c
@@ -0,0 +1,2870 @@
+/******************************************************************************
+ *
+ * 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 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"
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+#include <config.h>
+#endif
+
+
+/* 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
+
+#if(NFC_NXP_CHIP_PN548AD == TRUE)
+#define NFA_EE_ROUT_BUF_SIZE 720
+#else
+#define NFA_EE_ROUT_BUF_SIZE 200
+#endif
+#define NFA_EE_ROUT_MAX_TLV_SIZE 0xFD
+
+
+/* the following 2 tables convert the technology mask in API and control block to the command for NFCC */
+#define NFA_EE_NUM_TECH 3
+const UINT8 nfa_ee_tech_mask_list[NFA_EE_NUM_TECH] =
+{
+ NFA_TECHNOLOGY_MASK_A,
+ NFA_TECHNOLOGY_MASK_B,
+ NFA_TECHNOLOGY_MASK_F
+};
+
+const UINT8 nfa_ee_tech_list[NFA_EE_NUM_TECH] =
+{
+ NFC_RF_TECHNOLOGY_A,
+ NFC_RF_TECHNOLOGY_B,
+ NFC_RF_TECHNOLOGY_F
+};
+
+/* the following 2 tables convert the protocol mask in API and control block to the command for NFCC */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define NFA_EE_NUM_PROTO 6
+#else
+#define NFA_EE_NUM_PROTO 5
+#endif
+const UINT8 nfa_ee_proto_mask_list[NFA_EE_NUM_PROTO] =
+{
+ NFA_PROTOCOL_MASK_T1T,
+ NFA_PROTOCOL_MASK_T2T,
+ NFA_PROTOCOL_MASK_T3T,
+ NFA_PROTOCOL_MASK_ISO_DEP,
+ NFA_PROTOCOL_MASK_NFC_DEP
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ ,NFC_PROTOCOL_MASK_ISO7816
+#endif
+};
+
+const UINT8 nfa_ee_proto_list[NFA_EE_NUM_PROTO] =
+{
+ NFC_PROTOCOL_T1T,
+ NFC_PROTOCOL_T2T,
+ NFC_PROTOCOL_T3T,
+ NFC_PROTOCOL_ISO_DEP,
+ NFC_PROTOCOL_NFC_DEP
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ ,NFC_PROTOCOL_ISO7816
+#endif
+};
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+static UINT8 *proto_route_buff;
+static UINT8 *tech_route_buff;
+static UINT8 *proto_pp;
+static UINT8 *tech_pp;
+static UINT8 proto_tlv_ctr;
+static UINT8 tech_tlv_ctr;
+#define NFA_EE_PROTO_BUFF_SIZE 120 /* num of proto= 6, proto_mask =5 and num of EEs 4, total size = (6x5x4) */
+#define NFA_EE_TECH_BUFF_SIZE 60 /* num of tech =3 , tech_mask =5 and num of EEs 4, total size = (3x5x4) */
+
+UINT8 NFA_REMOVE_ALL_AID[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
+UINT8 nfa_ee_ce_route_strict_disable = 0x01;
+#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);
+/*******************************************************************************
+**
+** Function nfa_ee_trace_aid
+**
+** Description trace AID
+**
+** Returns void
+**
+*******************************************************************************/
+static void nfa_ee_trace_aid (char *p_str, UINT8 id, UINT8 aid_len, UINT8 *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 += sprintf (&buff[yy], "%02x ", *p);
+ p++;
+ }
+ NFA_TRACE_DEBUG4 ("%s id:0x%x len=%d aid:%s", p_str, id, aid_len, buff);
+
+}
+
+/*******************************************************************************
+**
+** 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 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_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 *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
+**
+*******************************************************************************/
+static UINT16 nfa_ee_total_lmrt_size(void)
+{
+ int xx;
+ UINT16 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;
+ 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;
+ }
+ }
+ NFA_TRACE_DEBUG1 ("nfa_ee_total_lmrt_size size:%d", lmrt_size);
+ return lmrt_size;
+}
+
+/*******************************************************************************
+**
+** Function nfa_ee_conn_cback
+**
+** Description process connection callback event from stack
+**
+** Returns void
+**
+*******************************************************************************/
+static void nfa_ee_conn_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
+{
+ BT_HDR *p_msg;
+ tNFA_EE_NCI_CONN cbk;
+
+ NFA_TRACE_DEBUG2("nfa_ee_conn_cback: conn_id: %d, event=0x%02x", conn_id, event);
+
+ cbk.hdr.event = NFA_EE_NCI_CONN_EVT;
+ if (event == NFC_DATA_CEVT)
+ {
+ /* Treat data event specially to avoid potential memory leak */
+ cbk.hdr.event = NFA_EE_NCI_DATA_EVT;
+ }
+ cbk.conn_id = conn_id;
+ cbk.event = event;
+ cbk.p_data = p_data;
+ p_msg = (BT_HDR *)&cbk;
+
+ nfa_ee_evt_hdlr (p_msg);
+}
+
+
+/*******************************************************************************
+**
+** Function nfa_ee_find_total_aid_len
+**
+** Description Find the total len in aid_cfg from start_entry to the last
+**
+** Returns void
+**
+*******************************************************************************/
+int nfa_ee_find_total_aid_len(tNFA_EE_ECB *p_cb, int start_entry)
+{
+ int len = 0, xx;
+
+ if (p_cb->aid_entries > start_entry)
+ {
+ for (xx = start_entry; xx < p_cb->aid_entries; xx++)
+ {
+ len += p_cb->aid_len[xx];
+ }
+ }
+ return len;
+}
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 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_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;
+}
+#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 aid_len, UINT8 *p_aid, int *p_offset, int *p_entry)
+{
+ int xx, yy, aid_len_offset, offset;
+ tNFA_EE_ECB *p_ret = NULL, *p_ecb;
+
+ p_ecb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH];
+ aid_len_offset = 1; /* skip the tag */
+ for (yy = 0; yy < nfa_ee_cb.cur_ee; yy++, p_ecb++)
+ {
+ if (p_ecb->aid_entries)
+ {
+ offset = 0;
+ for (xx = 0; xx < p_ecb->aid_entries; xx++)
+ {
+ if ( (p_ecb->aid_cfg[offset + aid_len_offset] == aid_len)
+ &&(memcmp(&p_ecb->aid_cfg[offset + aid_len_offset + 1], p_aid, aid_len) == 0) )
+ {
+ p_ret = p_ecb;
+ if (p_offset)
+ *p_offset = offset;
+ if (p_entry)
+ *p_entry = xx;
+ break;
+ }
+ offset += p_ecb->aid_len[xx];
+ }
+
+ if (p_ret)
+ {
+ /* found the entry already */
+ break;
+ }
+ }
+ p_ecb = &nfa_ee_cb.ecb[yy];
+ }
+
+ return p_ret;
+}
+
+/*******************************************************************************
+**
+** Function nfa_ee_report_event
+**
+** Description report the given event to the callback
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_ee_report_event(tNFA_EE_CBACK *p_cback, tNFA_EE_EVT event, tNFA_EE_CBACK_DATA *p_data)
+{
+ int xx;
+
+ /* use the given callback, if not NULL */
+ if (p_cback)
+ {
+ (*p_cback)(event, p_data);
+ return;
+ }
+ /* if the given is NULL, report to all registered ones */
+ for (xx = 0; xx < NFA_EE_MAX_CBACKS; xx++)
+ {
+ if (nfa_ee_cb.p_ee_cback[xx] != NULL)
+ {
+ (*nfa_ee_cb.p_ee_cback[xx])(event, p_data);
+ }
+ }
+}
+/*******************************************************************************
+**
+** Function nfa_ee_start_timer
+**
+** Description start the de-bounce timer
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_ee_start_timer(void)
+{
+ 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);
+ NFC_NfceeDiscover(FALSE);
+ }
+ if (nfa_ee_cb.p_ee_disc_cback == NULL && NFC_NfceeDiscover(TRUE) == NFC_STATUS_OK)
+ {
+ nfa_ee_cb.p_ee_disc_cback = p_cback;
+ }
+ else
+ {
+ evt_data.status = NFA_STATUS_FAILED;
+ nfa_ee_report_event (p_cback, NFA_EE_DISCOVER_EVT, &evt_data);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_ee_api_register
+**
+** Description process register command from user
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_ee_api_register(tNFA_EE_MSG *p_data)
+{
+ int xx;
+ tNFA_EE_CBACK *p_cback = p_data->ee_register.p_cback;
+ tNFA_EE_CBACK_DATA evt_data = {0};
+ BOOLEAN found = FALSE;
+
+ evt_data.ee_register = NFA_STATUS_FAILED;
+ /* loop through all entries to see if there's a matching callback */
+ for (xx = 0; xx < NFA_EE_MAX_CBACKS; xx++)
+ {
+ if (nfa_ee_cb.p_ee_cback[xx] == p_cback)
+ {
+ evt_data.ee_register = NFA_STATUS_OK;
+ found = TRUE;
+ break;
+ }
+ }
+
+ /* If no matching callback, allocated an entry */
+ if (!found)
+ {
+ for (xx = 0; xx < NFA_EE_MAX_CBACKS; xx++)
+ {
+ if (nfa_ee_cb.p_ee_cback[xx] == NULL)
+ {
+ nfa_ee_cb.p_ee_cback[xx] = p_cback;
+ evt_data.ee_register = NFA_STATUS_OK;
+ break;
+ }
+ }
+ }
+ /* This callback is verified (not NULL) in NFA_EeRegister() */
+ (*p_cback)(NFA_EE_REGISTER_EVT, &evt_data);
+
+ /* 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;
+ int index = p_data->deregister.index;
+ tNFA_EE_CBACK_DATA evt_data = {0};
+
+ NFA_TRACE_DEBUG0 ("nfa_ee_api_deregister");
+ p_cback = nfa_ee_cb.p_ee_cback[index];
+ nfa_ee_cb.p_ee_cback[index] = NULL;
+ if (p_cback)
+ (*p_cback)(NFA_EE_DEREGISTER_EVT, &evt_data);
+}
+
+
+/*******************************************************************************
+**
+** Function nfa_ee_api_mode_set
+**
+** Description process mode set command from user
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_ee_api_mode_set(tNFA_EE_MSG *p_data)
+{
+ tNFA_EE_ECB *p_cb= p_data->cfg_hdr.p_cb;
+
+ NFA_TRACE_DEBUG2 ("nfa_ee_api_mode_set() handle:0x%02x mode:%d", p_cb->nfcee_id, p_data->mode_set.mode);
+ NFC_NfceeModeSet (p_cb->nfcee_id, p_data->mode_set.mode);
+ /* set the NFA_EE_STATUS_PENDING bit to indicate the status is not exactly active */
+ if (p_data->mode_set.mode == NFC_MODE_ACTIVATE)
+ p_cb->ee_status = NFA_EE_STATUS_PENDING | NFA_EE_STATUS_ACTIVE;
+ else
+ {
+ p_cb->ee_status = NFA_EE_STATUS_INACTIVE;
+ /* DH should release the NCI connection before deactivate the NFCEE */
+ if (p_cb->conn_st == NFA_EE_CONN_ST_CONN)
+ {
+ p_cb->conn_st = NFA_EE_CONN_ST_DISC;
+ NFC_ConnClose(p_cb->conn_id);
+ }
+ }
+ /* report the NFA_EE_MODE_SET_EVT status on the response from NFCC */
+}
+
+
+
+/*******************************************************************************
+**
+** Function nfa_ee_api_set_tech_cfg
+**
+** Description process set technology routing configuration from user
+** start a 1 second timer. When the timer expires,
+** the configuration collected in control block is sent to NFCC
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_ee_api_set_tech_cfg(tNFA_EE_MSG *p_data)
+{
+ tNFA_EE_ECB *p_cb = p_data->cfg_hdr.p_cb;
+ tNFA_EE_CBACK_DATA evt_data = {0};
+ 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(NFC_NXP_NOT_OPEN_INCLUDED == 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;
+#endif
+ UINT8 old_size_mask = p_cb->size_mask;
+
+ 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(NFC_NXP_NOT_OPEN_INCLUDED == 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;
+#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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ p_cb->tech_screen_lock = old_tech_screen_lock;
+ p_cb->tech_screen_off = old_tech_screen_off;
+#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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ | p_cb->tech_screen_lock | p_cb->tech_screen_off
+#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(NFC_NXP_NOT_OPEN_INCLUDED == 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;
+#endif
+ UINT8 old_size_mask = p_cb->size_mask;
+
+ 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(NFC_NXP_NOT_OPEN_INCLUDED == 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;
+#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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ p_cb->proto_screen_lock = old_proto_screen_lock;
+ p_cb->proto_screen_off = old_proto_screen_off;
+#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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ | p_cb->proto_screen_lock | p_cb->proto_screen_off
+#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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ tNFA_EE_ECB *dh_ecb = NULL;
+ UINT8 vs_info = p_add->vs_info;
+#endif
+ tNFA_EE_ECB *p_chk_cb;
+ UINT8 *p, *p_start;
+ int len, len_needed;
+ tNFA_EE_CBACK_DATA evt_data = {0};
+ int offset = 0, entry = 0;
+ UINT16 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 (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;
+ 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;
+ }
+ }
+ 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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ len = nfa_all_ee_find_total_aid_len();
+#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 ((len_needed + len) > NFA_EE_MAX_AID_CFG_LEN)
+ {
+ 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);
+ evt_data.status = NFA_STATUS_BUFFER_FULL;
+ }
+ else if (p_cb->aid_entries < NFA_EE_MAX_AID_ENTRIES)
+ {
+ new_size = nfa_ee_total_lmrt_size() + 4 + p_add->aid_len; /* 4 = 1 (tag) + 1 (len) + 1(nfcee_id) + 1(power cfg) */
+ if (new_size > NFC_GetLmrtSize())
+ {
+ NFA_TRACE_ERROR1 ("Exceed LMRT size:%d", new_size);
+ evt_data.status = NFA_STATUS_BUFFER_FULL;
+ }
+ else
+ {
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+// len = nfa_ee_find_total_aid_len(p_cb, 0);
+ dh_ecb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH];
+ len = nfa_ee_find_total_aid_len(dh_ecb, 0);
+
+#endif
+ /* add AID */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ //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 | ((NFA_EE_AE_NXP_PREFIX_MATCH & vs_info)?NFA_EE_AE_NXP_PREFIX_MATCH:0x00);
+ dh_ecb->aid_rt_loc[dh_ecb->aid_entries] = p_cb->nfcee_id;
+ p = dh_ecb->aid_cfg + len;
+#else
+ p_cb->aid_pwr_cfg[p_cb->aid_entries] = p_add->power_state;
+ p_cb->aid_rt_info[p_cb->aid_entries] = NFA_EE_AE_ROUTE;
+ p = p_cb->aid_cfg + len;
+#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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ dh_ecb->aid_len[dh_ecb->aid_entries++] = (UINT8)(p - p_start);
+#else
+ p_cb->aid_len[p_cb->aid_entries++] = (UINT8)(p - p_start);
+#endif
+ }
+ }
+ else
+ {
+ NFA_TRACE_ERROR1 ("Exceed NFA_EE_MAX_AID_ENTRIES:%d", NFA_EE_MAX_AID_ENTRIES);
+ 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_rt_info[entry], &p_cb->aid_rt_info[entry + 1], rest_len);
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED == 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 xx;
+ tNFA_EE_ECB *p_cb = nfa_ee_cb.ecb;
+ for (xx = 0; xx < NFA_EE_MAX_EE_SUPPORTED; xx++, p_cb++)
+ {
+ memset(&p_cb->aid_cfg[0],0x00, sizeof(p_cb->aid_cfg));
+ memset(&p_cb->aid_len[0], 0x00, sizeof(p_cb->aid_len));
+ memset(&p_cb->aid_pwr_cfg[0], 0x00, sizeof(p_cb->aid_pwr_cfg));
+ memset(&p_cb->aid_rt_info[0], 0x00, sizeof(p_cb->aid_rt_info));
+ 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];
+
+ memset(&p_ecb->aid_cfg[0],0x00, sizeof(p_ecb->aid_cfg));
+ memset(&p_ecb->aid_len[0], 0x00, sizeof(p_ecb->aid_len));
+ memset(&p_ecb->aid_pwr_cfg[0], 0x00, sizeof(p_ecb->aid_pwr_cfg));
+ memset(&p_ecb->aid_rt_info[0], 0x00, sizeof(p_ecb->aid_rt_info));
+ 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_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 total_size = NFC_GetLmrtSize();
+
+ 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,
+ p_data->connect.ee_interface, nfa_ee_conn_cback);
+ /* report the NFA_EE_CONNECT_EVT status on the response from NFCC */
+ break;
+ }
+ }
+ }
+
+ if (evt_data.connect.status != NCI_STATUS_OK)
+ {
+ evt_data.connect.ee_handle = (tNFA_HANDLE)p_data->connect.nfcee_id | NFA_HANDLE_GROUP_EE;
+ evt_data.connect.status = NFA_STATUS_INVALID_PARAM;
+ evt_data.connect.ee_interface = p_data->connect.ee_interface;
+ nfa_ee_report_event (p_data->connect.p_cback, NFA_EE_CONNECT_EVT, &evt_data);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_ee_api_send_data
+**
+** Description Send the given data packet to the given NFCEE
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_ee_api_send_data(tNFA_EE_MSG *p_data)
+{
+ tNFA_EE_ECB *p_cb = p_data->send_data.p_cb;
+ BT_HDR *p_pkt;
+ UINT16 size = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + p_data->send_data.data_len + BT_HDR_SIZE;
+ UINT8 *p;
+ tNFA_STATUS status = NFA_STATUS_FAILED;
+
+ if (p_cb->conn_st == NFA_EE_CONN_ST_CONN)
+ {
+ p_pkt = (BT_HDR *)GKI_getbuf(size);
+ if (p_pkt)
+ {
+ p_pkt->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p_pkt->len = p_data->send_data.data_len;
+ p = (UINT8 *)(p_pkt+1) + p_pkt->offset;
+ memcpy(p, p_data->send_data.p_data, p_pkt->len);
+ NFC_SendData (p_cb->conn_id, p_pkt);
+ }
+ else
+ {
+ nfa_ee_report_event( p_cb->p_ee_cback, NFA_EE_NO_MEM_ERR_EVT, (tNFA_EE_CBACK_DATA *)&status);
+ }
+ }
+ else
+ {
+ nfa_ee_report_event( p_cb->p_ee_cback, NFA_EE_NO_CB_ERR_EVT, (tNFA_EE_CBACK_DATA *)&status);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_ee_api_disconnect
+**
+** Description Initiates closing of the connection to the given NFCEE
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_ee_api_disconnect(tNFA_EE_MSG *p_data)
+{
+ tNFA_EE_ECB *p_cb = p_data->disconnect.p_cb;
+ tNFA_EE_CBACK_DATA evt_data = {0};
+
+ if (p_cb->conn_st == NFA_EE_CONN_ST_CONN)
+ {
+ p_cb->conn_st = NFA_EE_CONN_ST_DISC;
+ NFC_ConnClose(p_cb->conn_id);
+ }
+ evt_data.handle = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE;
+ nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_DISCONNECT_EVT, &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function nfa_ee_report_disc_done
+**
+** Description Process the callback for NFCEE discovery response
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_ee_report_disc_done(BOOLEAN notify_enable_done)
+{
+ tNFA_EE_CBACK *p_cback;
+ tNFA_EE_CBACK_DATA evt_data = {0};
+
+ NFA_TRACE_DEBUG3("nfa_ee_report_disc_done() em_state:%d num_ee_expecting:%d notify_enable_done:%d", nfa_ee_cb.em_state, nfa_ee_cb.num_ee_expecting, notify_enable_done);
+ if (nfa_ee_cb.num_ee_expecting == 0)
+ {
+ if (notify_enable_done)
+ {
+ if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_INIT_DONE)
+ {
+ nfa_sys_cback_notify_enable_complete (NFA_ID_EE);
+ if (nfa_ee_cb.p_enable_cback)
+ (*nfa_ee_cb.p_enable_cback)(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 = 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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ else
+ {
+ evt_data.status = NFA_STATUS_OK;
+ evt_data.ee_discover.num_ee = 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);
+ }
+#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
+**
+*******************************************************************************/
+BOOLEAN nfa_ee_restore_ntf_done(void)
+{
+ tNFA_EE_ECB *p_cb;
+ BOOLEAN is_done = TRUE;
+ int xx;
+
+ p_cb = nfa_ee_cb.ecb;
+ for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++)
+ {
+ if ((p_cb->nfcee_id != NFA_EE_INVALID) && (p_cb->ee_old_status & NFA_EE_STATUS_RESTORING))
+ {
+ is_done = FALSE;
+ break;
+ }
+ }
+ return is_done;
+}
+
+/*******************************************************************************
+**
+** Function nfa_ee_remove_pending
+**
+** Description check if any ee_status still has NFA_EE_STATUS_RESTORING bit
+**
+** Returns TRUE, if all NFA_EE_STATUS_RESTORING bits are removed
+**
+*******************************************************************************/
+static void nfa_ee_remove_pending(void)
+{
+ tNFA_EE_ECB *p_cb;
+ tNFA_EE_ECB *p_cb_n, *p_cb_end;
+ int xx, num_removed = 0;
+ int first_removed = NFA_EE_MAX_EE_SUPPORTED;
+
+ p_cb = nfa_ee_cb.ecb;
+ for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++)
+ {
+ if ((p_cb->nfcee_id != NFA_EE_INVALID) && (p_cb->ee_status & NFA_EE_STATUS_RESTORING))
+ {
+ p_cb->nfcee_id = NFA_EE_INVALID;
+ num_removed ++;
+ if (first_removed == NFA_EE_MAX_EE_SUPPORTED)
+ first_removed = xx;
+ }
+ }
+
+ NFA_TRACE_DEBUG3("nfa_ee_remove_pending() cur_ee:%d, num_removed:%d first_removed:%d", nfa_ee_cb.cur_ee, num_removed, first_removed);
+ if (num_removed && (first_removed != (nfa_ee_cb.cur_ee - num_removed)))
+ {
+ /* if the removes ECB entried are not at the end, move the entries up */
+ p_cb_end = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1];
+ p_cb = &nfa_ee_cb.ecb[first_removed];
+ for (p_cb_n = p_cb + 1; p_cb_n <= p_cb_end;)
+ {
+ while ((p_cb_n->nfcee_id == NFA_EE_INVALID) && (p_cb_n <= p_cb_end))
+ {
+ p_cb_n++;
+ }
+
+ if (p_cb_n <= p_cb_end)
+ {
+ memcpy(p_cb, p_cb_n, sizeof(tNFA_EE_ECB));
+ p_cb_n->nfcee_id = NFA_EE_INVALID;
+ }
+ p_cb++;
+ p_cb_n++;
+ }
+ }
+ nfa_ee_cb.cur_ee -= (UINT8)num_removed;
+}
+
+
+/*******************************************************************************
+**
+** Function nfa_ee_nci_disc_rsp
+**
+** Description Process the callback for NFCEE discovery response
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_ee_nci_disc_rsp(tNFA_EE_MSG *p_data)
+{
+ tNFC_NFCEE_DISCOVER_REVT *p_evt = p_data->disc_rsp.p_data;
+ tNFA_EE_ECB *p_cb;
+ UINT8 xx;
+ UINT8 num_nfcee = p_evt->num_nfcee;
+ BOOLEAN notify_enable_done = FALSE;
+
+ NFA_TRACE_DEBUG3("nfa_ee_nci_disc_rsp() em_state:%d cur_ee:%d, num_nfcee:%d", nfa_ee_cb.em_state, nfa_ee_cb.cur_ee, num_nfcee);
+ switch (nfa_ee_cb.em_state)
+ {
+ case NFA_EE_EM_STATE_INIT:
+ nfa_ee_cb.cur_ee = 0;
+ nfa_ee_cb.num_ee_expecting = 0;
+ if (num_nfcee == 0)
+ {
+ nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
+ notify_enable_done = TRUE;
+ if (p_evt->status != NFC_STATUS_OK)
+ {
+ nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
+ }
+ }
+ break;
+
+ case NFA_EE_EM_STATE_INIT_DONE:
+ if (num_nfcee)
+ {
+ /* if this is initiated by api function,
+ * check if the number of NFCEE expected is more than what's currently in CB */
+ if (num_nfcee > NFA_EE_MAX_EE_SUPPORTED)
+ num_nfcee = NFA_EE_MAX_EE_SUPPORTED;
+ if (nfa_ee_cb.cur_ee < num_nfcee)
+ {
+ p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee];
+ for (xx = nfa_ee_cb.cur_ee; xx < num_nfcee; xx++, p_cb++)
+ {
+ /* mark the new entries as a new one */
+ p_cb->nfcee_id = NFA_EE_INVALID;
+ }
+ }
+ nfa_ee_cb.cur_ee = num_nfcee;
+ }
+ break;
+
+ case NFA_EE_EM_STATE_RESTORING:
+ if (num_nfcee == 0)
+ {
+ nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
+ nfa_ee_remove_pending();
+ nfa_ee_check_restore_complete();
+ if (p_evt->status != NFC_STATUS_OK)
+ {
+ nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
+ }
+ }
+ break;
+ }
+
+ if (p_evt->status == NFC_STATUS_OK)
+ {
+ nfa_ee_cb.num_ee_expecting = p_evt->num_nfcee;
+ if (nfa_ee_cb.num_ee_expecting > NFA_EE_MAX_EE_SUPPORTED)
+ {
+ NFA_TRACE_ERROR2 ("NFA-EE num_ee_expecting:%d > max:%d", nfa_ee_cb.num_ee_expecting, NFA_EE_MAX_EE_SUPPORTED);
+ }
+ }
+ nfa_ee_report_disc_done(notify_enable_done);
+ NFA_TRACE_DEBUG3("nfa_ee_nci_disc_rsp() em_state:%d cur_ee:%d num_ee_expecting:%d", nfa_ee_cb.em_state, nfa_ee_cb.cur_ee, nfa_ee_cb.num_ee_expecting);
+}
+
+/*******************************************************************************
+**
+** Function nfa_ee_nci_disc_ntf
+**
+** Description Process the callback for NFCEE discovery notification
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_ee_nci_disc_ntf(tNFA_EE_MSG *p_data)
+{
+ tNFC_NFCEE_INFO_REVT *p_ee = p_data->disc_ntf.p_data;
+ tNFA_EE_ECB *p_cb = NULL;
+ BOOLEAN notify_enable_done = FALSE;
+ BOOLEAN notify_new_ee = FALSE;
+ tNFA_EE_CBACK_DATA evt_data = {0};
+ tNFA_EE_INFO *p_info;
+ tNFA_EE_EM_STATE new_em_state = NFA_EE_EM_STATE_MAX;
+
+ NFA_TRACE_DEBUG4("nfa_ee_nci_disc_ntf() em_state:%d ee_flags:0x%x cur_ee:%d num_ee_expecting:%d", nfa_ee_cb.em_state, nfa_ee_cb.ee_flags, nfa_ee_cb.cur_ee, nfa_ee_cb.num_ee_expecting);
+ if (nfa_ee_cb.num_ee_expecting)
+ {
+ nfa_ee_cb.num_ee_expecting--;
+ if ((nfa_ee_cb.num_ee_expecting == 0) && (nfa_ee_cb.p_ee_disc_cback != NULL))
+ {
+ /* Discovery triggered by API function */
+ NFC_NfceeDiscover(FALSE);
+ }
+ }
+ switch (nfa_ee_cb.em_state)
+ {
+ case NFA_EE_EM_STATE_INIT:
+ if (nfa_ee_cb.cur_ee < NFA_EE_MAX_EE_SUPPORTED)
+ {
+ /* the cb can collect up to NFA_EE_MAX_EE_SUPPORTED ee_info */
+ p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee++];
+ }
+
+ if (nfa_ee_cb.num_ee_expecting == 0)
+ {
+ /* notify init_done callback */
+ nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
+ notify_enable_done = TRUE;
+ }
+ break;
+
+ case NFA_EE_EM_STATE_INIT_DONE:
+ p_cb = nfa_ee_find_ecb (p_ee->nfcee_id);
+ if (p_cb == NULL)
+ {
+ /* the NFCEE ID is not in the last NFCEE discovery
+ * maybe it's a new one */
+ p_cb = nfa_ee_find_ecb (NFA_EE_INVALID);
+ if (p_cb)
+ {
+ nfa_ee_cb.cur_ee++;
+ notify_new_ee = TRUE;
+ }
+ }
+ else if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ORDER)
+ {
+ nfa_ee_cb.cur_ee++;
+ notify_new_ee = TRUE;
+ }
+ else
+ {
+ NFA_TRACE_DEBUG3 ("cur_ee:%d ecb_flags=0x%02x ee_status=0x%x", nfa_ee_cb.cur_ee, p_cb->ecb_flags, p_cb->ee_status);
+ }
+ break;
+
+ case NFA_EE_EM_STATE_RESTORING:
+ p_cb = nfa_ee_find_ecb (p_ee->nfcee_id);
+ if (p_cb == NULL)
+ {
+ /* the NFCEE ID is not in the last NFCEE discovery
+ * maybe it's a new one */
+ p_cb = nfa_ee_find_ecb (NFA_EE_INVALID);
+ if (p_cb)
+ {
+ nfa_ee_cb.cur_ee++;
+ notify_new_ee = TRUE;
+ }
+ }
+ if (nfa_ee_cb.num_ee_expecting == 0)
+ {
+ /* notify init_done callback */
+ notify_enable_done = TRUE;
+ if (nfa_ee_restore_ntf_done())
+ {
+ new_em_state = NFA_EE_EM_STATE_INIT_DONE;
+ }
+ }
+ break;
+ }
+ NFA_TRACE_DEBUG1 ("nfa_ee_nci_disc_ntf cur_ee:%d", nfa_ee_cb.cur_ee);
+
+ if (p_cb)
+ {
+ p_cb->nfcee_id = p_ee->nfcee_id;
+ p_cb->ee_status = p_ee->ee_status;
+ p_cb->num_interface = p_ee->num_interface;
+ memcpy(p_cb->ee_interface, p_ee->ee_interface, p_ee->num_interface);
+ p_cb->num_tlvs = p_ee->num_tlvs;
+ memcpy(p_cb->ee_tlv, p_ee->ee_tlv, p_ee->num_tlvs * sizeof(tNFA_EE_TLV));
+
+ if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_RESTORING)
+ {
+ /* NCI spec says: An NFCEE_DISCOVER_NTF that contains a Protocol type of "HCI Access"
+ * SHALL NOT contain any other additional Protocol
+ * i.e. check only first supported NFCEE interface is HCI access */
+ /* NFA_HCI module handles restoring configurations for HCI access */
+ if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS)
+ {
+ if ((nfa_ee_cb.ee_flags & NFA_EE_FLAG_WAIT_HCI) == 0)
+ {
+ nfa_ee_restore_one_ecb (p_cb);
+ }
+ /* else wait for NFA-HCI module to restore the HCI network information before enabling the NFCEE */
+ }
+ }
+
+ if ((nfa_ee_cb.p_ee_disc_cback == NULL) && (notify_new_ee == TRUE))
+ {
+ if (nfa_dm_is_active() && (p_cb->ee_status != NFA_EE_STATUS_REMOVED))
+ {
+ /* report this NFA_EE_NEW_EE_EVT only after NFA_DM_ENABLE_EVT is reported */
+ p_info = &evt_data.new_ee;
+ p_info->ee_handle = NFA_HANDLE_GROUP_EE | (tNFA_HANDLE)p_cb->nfcee_id;
+ p_info->ee_status = p_cb->ee_status;
+ p_info->num_interface = p_cb->num_interface;
+ p_info->num_tlvs = p_cb->num_tlvs;
+ memcpy(p_info->ee_interface, p_cb->ee_interface, p_cb->num_interface);
+ memcpy(p_info->ee_tlv, p_cb->ee_tlv, p_cb->num_tlvs * sizeof(tNFA_EE_TLV));
+ nfa_ee_report_event (NULL, NFA_EE_NEW_EE_EVT, &evt_data);
+ }
+ }
+ else
+ nfa_ee_report_disc_done(notify_enable_done);
+
+ if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ORDER)
+ {
+ NFA_TRACE_DEBUG0 ("NFA_EE_ECB_FLAGS_ORDER");
+ p_cb->ecb_flags &= ~NFA_EE_ECB_FLAGS_ORDER;
+ nfa_ee_report_discover_req_evt();
+ }
+
+ }
+
+ if (new_em_state != NFA_EE_EM_STATE_MAX)
+ {
+ nfa_ee_cb.em_state = new_em_state;
+ nfa_ee_check_restore_complete();
+ }
+
+ if ((nfa_ee_cb.cur_ee == nfa_ee_max_ee_cfg) && (nfa_ee_cb.em_state == NFA_EE_EM_STATE_INIT_DONE) )
+ {
+ if (nfa_ee_cb.discv_timer.in_use)
+ {
+ nfa_sys_stop_timer (&nfa_ee_cb.discv_timer);
+ p_data->hdr.event = NFA_EE_DISCV_TIMEOUT_EVT;
+ nfa_ee_evt_hdlr((BT_HDR *)p_data);
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_ee_check_restore_complete
+**
+** Description Check if restore the NFA-EE related configuration to the
+** state prior to low power mode is complete.
+** If complete, notify sys.
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_ee_check_restore_complete(void)
+{
+ UINT32 xx;
+ tNFA_EE_ECB *p_cb;
+ BOOLEAN proc_complete = TRUE;
+
+ p_cb = nfa_ee_cb.ecb;
+ for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++)
+ {
+ if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE)
+ {
+ /* NFA_HCI module handles restoring configurations for HCI access.
+ * ignore the restoring status for HCI Access */
+ if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS)
+ {
+ proc_complete = FALSE;
+ break;
+ }
+ }
+ }
+
+ NFA_TRACE_DEBUG2 ("nfa_ee_check_restore_complete nfa_ee_cb.ee_cfg_sts:0x%02x proc_complete:%d", nfa_ee_cb.ee_cfg_sts, proc_complete);
+ if (proc_complete)
+ {
+ /* update routing table when NFA_EE_ROUT_TIMEOUT_EVT is received */
+ if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_PREV_ROUTING)
+ nfa_ee_api_update_now(NULL);
+
+ nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
+ nfa_sys_cback_notify_nfcc_power_mode_proc_complete (NFA_ID_EE);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_ee_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 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(NFC_NXP_NOT_OPEN_INCLUDED == 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, (tNFA_EE_CBACK_DATA *)&evt_data);
+}
+
+/*******************************************************************************
+**
+** Function nfa_ee_nci_mode_set_rsp
+**
+** Description Process the result for NFCEE ModeSet response
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_ee_nci_mode_set_rsp(tNFA_EE_MSG *p_data)
+{
+ tNFA_EE_ECB *p_cb;
+ tNFA_EE_MODE_SET mode_set;
+ tNFC_NFCEE_MODE_SET_REVT *p_rsp = p_data->mode_set_rsp.p_data;
+
+ NFA_TRACE_DEBUG2 ("nfa_ee_nci_mode_set_rsp() handle:0x%02x mode:%d", p_rsp->nfcee_id, p_rsp->mode);
+ p_cb = nfa_ee_find_ecb (p_rsp->nfcee_id);
+ if (p_cb == NULL)
+ {
+ NFA_TRACE_ERROR1 ("nfa_ee_nci_mode_set_rsp() Can not find cb for handle:0x%02x", p_rsp->nfcee_id);
+ return;
+ }
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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)
+ {
+ p_cb->ee_status = NFC_NFCEE_STATUS_ACTIVE;
+ }
+ else
+ {
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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)
+ {
+ /* this NFCEE still has configuration when deactivated. clear the configuration */
+ nfa_ee_cb.ee_cfged &= ~nfa_ee_ecb_to_mask(p_cb);
+ nfa_ee_cb.ee_cfg_sts|= NFA_EE_STS_CHANGED_ROUTING;
+ NFA_TRACE_DEBUG0("deactivating/still configured. Force update");
+ }
+ p_cb->tech_switch_on = p_cb->tech_switch_off = p_cb->tech_battery_off = 0;
+ p_cb->proto_switch_on = p_cb->proto_switch_off= p_cb->proto_battery_off = 0;
+ p_cb->aid_entries = 0;
+#endif
+ p_cb->ee_status = NFC_NFCEE_STATUS_INACTIVE;
+ }
+ }
+ NFA_TRACE_DEBUG4 ("status:%d ecb_flags :0x%02x ee_cfged:0x%02x ee_status:%d",
+ p_rsp->status, p_cb->ecb_flags , nfa_ee_cb.ee_cfged, p_cb->ee_status);
+ if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE)
+ {
+ if (p_cb->conn_st == NFA_EE_CONN_ST_CONN)
+ {
+ /* NFA_HCI module handles restoring configurations for HCI access */
+ if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS)
+ {
+ NFC_ConnCreate(NCI_DEST_TYPE_NFCEE, p_cb->nfcee_id, p_cb->use_interface, nfa_ee_conn_cback);
+ }
+ }
+ else
+ {
+ p_cb->ecb_flags &= ~NFA_EE_ECB_FLAGS_RESTORE;
+ nfa_ee_check_restore_complete();
+ }
+ }
+ else
+ {
+ mode_set.status = p_rsp->status;
+ mode_set.ee_handle = (tNFA_HANDLE)p_rsp->nfcee_id | NFA_HANDLE_GROUP_EE;
+ mode_set.ee_status = p_cb->ee_status;
+
+ nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_MODE_SET_EVT, (tNFA_EE_CBACK_DATA *)&mode_set);
+
+ if ((p_cb->ee_status == NFC_NFCEE_STATUS_INACTIVE)
+ || (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE))
+ {
+ /* Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE */
+ nfa_ee_report_discover_req_evt();
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** 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;
+ BT_HDR *p_pkt = NULL;
+ tNFA_EE_CBACK_DATA evt_data = {0};
+ tNFA_EE_EVT event = NFA_EE_INVALID;
+ tNFA_EE_CBACK *p_cback = NULL;
+
+ if (p_cbk->event == NFC_CONN_CREATE_CEVT)
+ {
+ p_cb = nfa_ee_find_ecb (p_cbk->p_data->conn_create.id);
+ }
+ else
+ {
+ p_cb = nfa_ee_find_ecb_by_conn_id (p_cbk->conn_id);
+ if (p_cbk->event == NFC_DATA_CEVT)
+ p_pkt = p_conn->data.p_data;
+ }
+
+ if (p_cb)
+ {
+ p_cback = p_cb->p_ee_cback;
+ evt_data.handle = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE;
+ switch (p_cbk->event)
+ {
+ case NFC_CONN_CREATE_CEVT:
+ if (p_conn->conn_create.status == NFC_STATUS_OK)
+ {
+ p_cb->conn_id = p_cbk->conn_id;
+ p_cb->conn_st = NFA_EE_CONN_ST_CONN;
+ }
+ else
+ {
+ p_cb->conn_st = NFA_EE_CONN_ST_NONE;
+ }
+ if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE)
+ {
+ p_cb->ecb_flags &= ~NFA_EE_ECB_FLAGS_RESTORE;
+ nfa_ee_check_restore_complete();
+ }
+ else
+ {
+ evt_data.connect.status = p_conn->conn_create.status;
+ evt_data.connect.ee_interface = p_cb->use_interface;
+ event = NFA_EE_CONNECT_EVT;
+ }
+ break;
+
+ case NFC_CONN_CLOSE_CEVT:
+ if (p_cb->conn_st != NFA_EE_CONN_ST_DISC)
+ event = NFA_EE_DISCONNECT_EVT;
+ p_cb->conn_st = NFA_EE_CONN_ST_NONE;
+ p_cb->p_ee_cback = NULL;
+ p_cb->conn_id = 0;
+ if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_DISABLING)
+ {
+ 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 *)(p_pkt+1) + p_pkt->offset;
+ event = NFA_EE_DATA_EVT;
+ p_pkt = NULL; /* so this function does not free this GKI buffer */
+ }
+ }
+ break;
+ }
+
+ if ((event != NFA_EE_INVALID) && (p_cback))
+ (*p_cback)(event, &evt_data);
+ }
+ if (p_pkt)
+ GKI_freebuf (p_pkt);
+}
+
+
+/*******************************************************************************
+**
+** Function nfa_ee_nci_action_ntf
+**
+** Description process the NFCEE action callback event
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_ee_nci_action_ntf(tNFA_EE_MSG *p_data)
+{
+ tNFC_EE_ACTION_REVT *p_cbk = p_data->act.p_data;
+ tNFA_EE_ACTION evt_data;
+
+ evt_data.ee_handle = (tNFA_HANDLE)p_cbk->nfcee_id | NFA_HANDLE_GROUP_EE;
+ evt_data.trigger = p_cbk->act_data.trigger;
+ memcpy (&(evt_data.param), &(p_cbk->act_data.param), sizeof (tNFA_EE_ACTION_PARAM));
+ nfa_ee_report_event(NULL, NFA_EE_ACTION_EVT, (tNFA_EE_CBACK_DATA *)&evt_data);
+}
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+/*******************************************************************************
+**
+** Function nfa_ee_get_supported_tech_list
+**
+** Description provides the supported technology list of given nfcee id
+**
+** Returns UINT8
+**
+*******************************************************************************/
+UINT8 nfa_ee_get_supported_tech_list(UINT8 nfcee_id)
+{
+ UINT8 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 report_ntf = 0;
+ UINT8 xx;
+
+ NFA_TRACE_DEBUG2 ("nfa_ee_nci_disc_req_ntf () num_info: %d cur_ee:%d", p_cbk->num_info, nfa_ee_cb.cur_ee );
+
+ for (xx = 0; xx < p_cbk->num_info; xx++)
+ {
+ ee_handle = NFA_HANDLE_GROUP_EE|p_cbk->info[xx].nfcee_id;
+
+ p_cb = nfa_ee_find_ecb (p_cbk->info[xx].nfcee_id);
+ if (!p_cb)
+ {
+ NFA_TRACE_DEBUG1 ("Cannot find cb for NFCEE: 0x%x", p_cbk->info[xx].nfcee_id);
+ p_cb = nfa_ee_find_ecb (NFA_EE_INVALID);
+ if (p_cb)
+ {
+ p_cb->nfcee_id = p_cbk->info[xx].nfcee_id;
+ p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_ORDER;
+ }
+ else
+ {
+ NFA_TRACE_ERROR1 ("Cannot allocate cb for NFCEE: 0x%x", p_cbk->info[xx].nfcee_id);
+ continue;
+ }
+ }
+ else
+ {
+ report_ntf |= nfa_ee_ecb_to_mask (p_cb);
+ }
+
+ p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_DISC_REQ;
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED == 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
+**
+*******************************************************************************/
+BOOLEAN nfa_ee_is_active (tNFA_HANDLE nfcee_id)
+{
+ BOOLEAN is_active = FALSE;
+ int xx;
+ tNFA_EE_ECB *p_cb = nfa_ee_cb.ecb;
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED == 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 power_state, UINT8 *p_handles)
+{
+ int xx, yy;
+ tNFA_EE_ECB *p_cb;
+ UINT8 tech_mask_list[NFA_EE_MAX_TECH_ROUTE] =
+ {
+ NFA_TECHNOLOGY_MASK_A,
+ NFA_TECHNOLOGY_MASK_B,
+ NFA_TECHNOLOGY_MASK_F,
+ NFA_TECHNOLOGY_MASK_B_PRIME
+ };
+
+ NFA_TRACE_DEBUG1("nfa_ee_get_tech_route(): %d", power_state);
+
+ for (xx = 0; xx < NFA_EE_MAX_TECH_ROUTE; xx++)
+ {
+ p_handles[xx] = NFC_DH_ID;
+ p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1];
+ for (yy = 0; yy < nfa_ee_cb.cur_ee; yy++, p_cb--)
+ {
+ if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE)
+ {
+ switch (power_state)
+ {
+ case NFA_EE_PWR_STATE_ON:
+ if (p_cb->tech_switch_on & tech_mask_list[xx])
+ p_handles[xx] = p_cb->nfcee_id;
+ break;
+ case NFA_EE_PWR_STATE_SWITCH_OFF:
+ if (p_cb->tech_switch_off & tech_mask_list[xx])
+ p_handles[xx] = p_cb->nfcee_id;
+ break;
+ case NFA_EE_PWR_STATE_BATT_OFF:
+ if (p_cb->tech_battery_off & tech_mask_list[xx])
+ p_handles[xx] = p_cb->nfcee_id;
+ break;
+ }
+ }
+ }
+ }
+ NFA_TRACE_DEBUG4("0x%x, 0x%x, 0x%x, 0x%x", p_handles[0], p_handles[1], p_handles[2], p_handles[3]);
+}
+
+/*******************************************************************************
+**
+** Function nfa_ee_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 new_size, int *p_max_len, UINT8 *p, int *p_cur_offset)
+{
+ UINT8 max_tlv = (UINT8)((*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, BOOLEAN more, UINT8 *ps, int *p_cur_offset)
+{
+ UINT8 *p, *pa;
+ UINT16 tlv_size;
+ UINT8 num_tlv, len;
+ int xx;
+ int start_offset;
+ UINT8 power_cfg = 0;
+ UINT8 *pp = ps + *p_cur_offset;
+ UINT8 entry_size;
+ UINT8 max_tlv;
+ UINT8 *p_start;
+ UINT8 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)((*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)*p_cur_offset;
+ /* Routing entries in the order of AID entries,protocol entries and technology entries*/
+ /* add the AID routing */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ if(p_cb->aid_rt_info[xx] & NFA_EE_AE_NXP_PREFIX_MATCH) {
+ //This aid is for prefix match.
+ *pp++ = NFC_ROUTE_TAG_AID|NFA_EE_AE_NXP_PREFIX_MATCH;
+ } else {
+ //This aid is for exact match.
+ *pp++ = NFC_ROUTE_TAG_AID;
+ }
+#else
+ *pp++ = NFC_ROUTE_TAG_AID;
+#endif
+ *pp++ = len + 2;
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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)(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)*p_cur_offset;
+ max_tlv = (UINT8)((*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;
+ }
+ }
+ }
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ /* 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 (p_cb->nfcee_id == NFC_DH_ID)
+ power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_LOCK;
+ else
+
+ {
+ if (p_cb->proto_screen_lock & nfa_ee_proto_mask_list[xx])
+ power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_LOCK;
+ if (p_cb->proto_screen_off & nfa_ee_proto_mask_list[xx])
+ power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_OFF;
+ }
+ }
+ if (power_cfg)
+ {
+ *proto_pp++ = NFC_ROUTE_TAG_PROTO;
+ *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;
+ *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_LOCK;
+ if (p_cb->tech_screen_off & nfa_ee_tech_mask_list[xx])
+ power_cfg |= NCI_ROUTE_PWR_STATE_SCREEN_OFF;
+ }
+
+ 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;
+ }
+}
+#endif
+
+ 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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+/* add the protocol entries and technology entries after AID entries*/
+ new_size = (UINT8)(proto_pp - proto_route_buff);
+ new_size += (UINT8)(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)(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)(tech_pp - tech_route_buff);
+ memcpy (p,tech_route_buff,new_size);
+ *p_cur_offset += new_size;
+ }
+#endif
+ /* 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)(*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_need_recfg
+**
+** Description Check if any API function to configure the routing table or
+** VS is called since last update
+**
+** The algorithm for the NFCEE configuration handling is as follows:
+**
+** Each NFCEE_ID/DH has its own control block - tNFA_EE_ECB
+** Each control block uses ecb_flags to keep track if an API
+** that changes routing/VS is invoked.
+** This ecb_flags is cleared at the end of nfa_ee_update_rout().
+**
+** nfa_ee_cb.ee_cfged is the bitmask of the control blocks with
+** routing/VS configuration and NFA_EE_CFGED_UPDATE_NOW.
+** nfa_ee_cb.ee_cfged is cleared and re-calculated at the end of
+** nfa_ee_update_rout().
+**
+** nfa_ee_cb.ee_cfg_sts is used to check is any status is changed
+** and the associated command is issued to NFCC.
+** nfa_ee_cb.ee_cfg_sts is AND with NFA_EE_STS_PREV at the end of
+** nfa_ee_update_rout() to clear the NFA_EE_STS_CHANGED bits
+** (except NFA_EE_STS_CHANGED_CANNED_VS is cleared in nfa_ee_vs_cback)
+**
+** Returns TRUE if any configuration is changed
+**
+*******************************************************************************/
+static BOOLEAN nfa_ee_need_recfg(void)
+{
+ BOOLEAN needed = FALSE;
+ UINT32 xx;
+ tNFA_EE_ECB *p_cb;
+ UINT8 mask;
+
+ NFA_TRACE_DEBUG2("nfa_ee_need_recfg() ee_cfged: 0x%02x ee_cfg_sts: 0x%02x", nfa_ee_cb.ee_cfged, nfa_ee_cb.ee_cfg_sts);
+ /* if no routing/vs is configured, do not need to send the info to NFCC */
+ if (nfa_ee_cb.ee_cfged || nfa_ee_cb.ee_cfg_sts)
+ {
+ if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_CHANGED)
+ {
+ needed = TRUE;
+ }
+ else
+ {
+ p_cb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH];
+ mask = 1 << NFA_EE_CB_4_DH;
+ for (xx = 0; xx <= nfa_ee_cb.cur_ee; xx++)
+ {
+ NFA_TRACE_DEBUG3("%d: ecb_flags : 0x%02x, mask: 0x%02x", xx, p_cb->ecb_flags , mask);
+ if ((p_cb->ecb_flags ) && (nfa_ee_cb.ee_cfged & mask))
+ {
+ needed = TRUE;
+ break;
+ }
+ p_cb = &nfa_ee_cb.ecb[xx];
+ mask = 1 << xx;
+ }
+ }
+ }
+
+ return needed;
+}
+
+/*******************************************************************************
+**
+** Function nfa_ee_rout_timeout
+**
+** Description Anytime VS or routing entries are changed,
+** a 1 second timer is started. This function is called when
+** the timer expires or NFA_EeUpdateNow() is called.
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_ee_rout_timeout(tNFA_EE_MSG *p_data)
+{
+ UINT8 ee_cfged = nfa_ee_cb.ee_cfged;
+
+ NFA_TRACE_DEBUG0("nfa_ee_rout_timeout()");
+ if (nfa_ee_need_recfg())
+ {
+ /* discovery is not started */
+ 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)
+{
+ 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 *p = NULL;
+ BOOLEAN more = TRUE;
+ UINT8 last_active = NFA_EE_INVALID;
+ int max_len, len;
+ tNFA_STATUS status = NFA_STATUS_FAILED;
+ int cur_offset;
+ UINT8 max_tlv;
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ tNFA_EE_CBACK_DATA evt_data = {0};
+#endif
+
+ /* update routing table: DH and the activated NFCEEs */
+ p = (UINT8 *)GKI_getbuf(NFA_EE_ROUT_BUF_SIZE);
+ if (p == NULL)
+ {
+ NFA_TRACE_ERROR0 ("nfa_ee_lmrt_to_nfcc() no buffer to send routing info.");
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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;
+ }
+
+ proto_route_buff = (UINT8 *)GKI_getbuf(NFA_EE_PROTO_BUFF_SIZE); /* Temporary buffer to store proto route entries */
+ tech_route_buff = (UINT8 *)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.");
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ proto_tlv_ctr = 0;
+ tech_tlv_ctr = 0;
+ proto_pp = proto_route_buff;
+ tech_pp = tech_route_buff;
+#endif
+
+ /* find the last active NFCEE. */
+ p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1];
+ for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb--)
+ {
+ if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE)
+ {
+ if (last_active == NFA_EE_INVALID)
+ {
+ last_active = p_cb->nfcee_id;
+ NFA_TRACE_DEBUG1 ("last_active: 0x%x", last_active);
+ }
+ }
+ }
+ if (last_active == NFA_EE_INVALID)
+ {
+ more = FALSE;
+ }
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ find_and_resolve_tech_conflict();
+#endif
+ /* add the routing for DH first */
+ status = NFA_STATUS_OK;
+ max_len = NFC_GetLmrtSize();
+ max_tlv = (UINT8)((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;
+ status = nfa_ee_route_add_one_ecb(&nfa_ee_cb.ecb[NFA_EE_CB_4_DH], &max_len, more, p, &cur_offset);
+
+ /* add only what is supported by NFCC. report overflow */
+ if (status == NFA_STATUS_OK)
+ {
+ /* add the routing for NFCEEs */
+ p_cb = &nfa_ee_cb.ecb[0];
+ for (xx = 0; (xx < nfa_ee_cb.cur_ee) && more; xx++, p_cb++)
+ {
+ len = 0;
+ if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE)
+ {
+ NFA_TRACE_DEBUG2 ("nfcee_id:0x%x, last_active: 0x%x", p_cb->nfcee_id, last_active);
+ if (last_active == p_cb->nfcee_id)
+ more = FALSE;
+ status = nfa_ee_route_add_one_ecb(p_cb, &max_len, more, p, &cur_offset);
+ if (status != NFA_STATUS_OK)
+ {
+ more = FALSE;
+ }
+ }
+ }
+ }
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ nfa_ee_cb.ee_flags &= ~NFA_EE_FLAG_CFG_NFC_DEP;
+ evt_data.status = status;
+#endif
+ if (status != NFA_STATUS_OK)
+ {
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED == 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
+}
+
+
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+/*******************************************************************************
+**
+** 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()
+{
+ int yy,xx;
+ tNFA_EE_ECB *p_cb = nfa_ee_cb.ecb;
+ UINT8 techA_found=0, techF_found=0;
+ UINT8 techA_ee, techF_ee;
+ unsigned long preferred_se = 0x01;
+ BOOLEAN conflict = FALSE;
+ UINT8 tech_to_rm, ee_from_rm;
+
+ NFA_TRACE_DEBUG1 ("%s:Enter",__FUNCTION__);
+
+ //Finding the Technology and nfcee_id supported
+ for (yy = 0; yy < 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", __FUNCTION__, 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_NXP_PRFD_TECH_SE, &preferred_se, sizeof(preferred_se))))
+ {
+ NFA_TRACE_DEBUG2 ("%s:NXP_PRFD_TECH_SE=0x0%lu;", __FUNCTION__, 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;", __FUNCTION__, techF_found,techF_ee);
+ NFA_TRACE_DEBUG3 ("%s:techA_found=0x%x,techA_ee= 0x%x;", __FUNCTION__, 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 < 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",__FUNCTION__);
+ }
+}
+#endif
+
+/*******************************************************************************
+**
+** Function nfa_ee_update_rout
+**
+** Description This function would set the VS and listen mode routing table
+** to NFCC.
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_ee_update_rout(void)
+{
+ int xx;
+ tNFA_EE_ECB *p_cb;
+ UINT8 mask;
+ BT_HDR msg;
+
+ NFA_TRACE_DEBUG1 ("nfa_ee_update_rout ee_cfg_sts:0x%02x", nfa_ee_cb.ee_cfg_sts);
+
+ /* use action function to send routing and VS configuration to NFCC */
+ msg.event = NFA_EE_CFG_TO_NFCC_EVT;
+ nfa_ee_evt_hdlr (&msg);
+
+ /* all configuration is updated to NFCC, clear the status mask */
+ nfa_ee_cb.ee_cfg_sts &= NFA_EE_STS_PREV;
+ nfa_ee_cb.ee_cfged = 0;
+ p_cb = &nfa_ee_cb.ecb[0];
+ for (xx = 0; xx < NFA_EE_NUM_ECBS; xx++, p_cb++)
+ {
+ p_cb->ecb_flags = 0;
+ mask = (1 << xx);
+ if (p_cb->tech_switch_on | p_cb->tech_switch_off | p_cb->tech_battery_off |
+ p_cb->proto_switch_on| p_cb->proto_switch_off| p_cb->proto_battery_off |
+ p_cb->aid_entries)
+ {
+ /* this entry has routing configuration. mark it configured */
+ nfa_ee_cb.ee_cfged |= mask;
+ }
+ }
+ NFA_TRACE_DEBUG2 ("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(NFC_NXP_NOT_OPEN_INCLUDED == 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 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*/;
+
+ return len < NFA_EE_MAX_AID_CFG_LEN?len:NFA_EE_MAX_AID_CFG_LEN;
+}
+
+BOOLEAN nfa_ee_nfeeid_active(UINT8 nfee_id)
+{
+ int xx;
+ tNFA_EE_ECB *p_cb;
+ BOOLEAN 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;
+}
+#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..6071f6b
--- /dev/null
+++ b/src/nfa/ee/nfa_ee_api.c
@@ -0,0 +1,924 @@
+/******************************************************************************
+ *
+ * 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 if ((p_msg = (tNFA_EE_API_DISCOVER *) GKI_getbuf (sizeof(tNFA_EE_API_DISCOVER))) != NULL)
+ {
+ p_msg->hdr.event = NFA_EE_API_DISCOVER_EVT;
+ p_msg->p_cback = p_cback;
+
+ nfa_sys_sendmsg (p_msg);
+
+ status = NFA_STATUS_OK;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function NFA_EeGetInfo
+**
+** Description This function retrieves the NFCEE information from NFA.
+** The actual number of NFCEE is returned in p_num_nfcee
+** and NFCEE information is returned in p_info
+**
+** Returns NFA_STATUS_OK if information is retrieved successfully
+** NFA_STATUS_FAILED If wrong state (retry later)
+** NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeGetInfo(UINT8 *p_num_nfcee,
+ tNFA_EE_INFO *p_info)
+{
+ int xx, ret = nfa_ee_cb.cur_ee;
+ tNFA_EE_ECB *p_cb = nfa_ee_cb.ecb;
+ UINT8 max_ret;
+ UINT8 num_ret = 0;
+
+ NFA_TRACE_DEBUG2 ("NFA_EeGetInfo em_state:%d cur_ee:%d", nfa_ee_cb.em_state, nfa_ee_cb.cur_ee);
+ /* validate parameters */
+ if (p_info == NULL || p_num_nfcee == NULL)
+ {
+ NFA_TRACE_ERROR0 ("NFA_EeGetInfo bad parameter");
+ return (NFA_STATUS_INVALID_PARAM);
+ }
+ max_ret = *p_num_nfcee;
+ *p_num_nfcee = 0;
+ if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_INIT)
+ {
+ NFA_TRACE_ERROR1 ("NFA_EeGetInfo bad em state: %d", nfa_ee_cb.em_state);
+ return (NFA_STATUS_FAILED);
+ }
+
+ /* compose output */
+ for (xx = 0; (xx < ret) && (num_ret < max_ret); xx++, p_cb++)
+ {
+ NFA_TRACE_DEBUG4 ("xx:%d max_ret:%d, num_ret:%d ee_status:0x%x", xx, max_ret, num_ret, p_cb->ee_status);
+ if ((p_cb->ee_status & NFA_EE_STATUS_INT_MASK) || (p_cb->ee_status == NFA_EE_STATUS_REMOVED))
+ {
+ continue;
+ }
+ p_info->ee_handle = NFA_HANDLE_GROUP_EE | (tNFA_HANDLE)p_cb->nfcee_id;
+ p_info->ee_status = p_cb->ee_status;
+ p_info->num_interface = p_cb->num_interface;
+ p_info->num_tlvs = p_cb->num_tlvs;
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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++;
+ num_ret++;
+ }
+ NFA_TRACE_DEBUG1 ("num_ret:%d", num_ret);
+ *p_num_nfcee = num_ret;
+ return (NFA_STATUS_OK);
+}
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 *p_num_nfcee,
+ tNFA_EE_INFO *p_info)
+{
+ int xx, ret = nfa_ee_cb.cur_ee;
+ tNFA_EE_ECB *p_cb = nfa_ee_cb.ecb;
+ UINT8 max_ret;
+ UINT8 num_ret = 0;
+
+ NFA_TRACE_DEBUG2 ("NFA_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_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)
+ {
+ 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(NFC_NXP_NOT_OPEN_INCLUDED == 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++;
+ num_ret++;
+ }
+ NFA_TRACE_DEBUG1 ("num_ret:%d", num_ret);
+ *p_num_nfcee = num_ret;
+ return (NFA_STATUS_OK);
+}
+#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 if ((p_msg = (tNFA_EE_API_REGISTER *) GKI_getbuf (sizeof(tNFA_EE_API_REGISTER))) != NULL)
+ {
+ p_msg->hdr.event = NFA_EE_API_REGISTER_EVT;
+ p_msg->p_cback = p_cback;
+
+ nfa_sys_sendmsg (p_msg);
+
+ status = NFA_STATUS_OK;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function NFA_EeDeregister
+**
+** Description This function de-registers the callback function
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+** NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeDeregister(tNFA_EE_CBACK *p_cback)
+{
+ tNFA_EE_API_DEREGISTER *p_msg;
+ tNFA_STATUS status = NFA_STATUS_INVALID_PARAM;
+ int index = NFA_EE_MAX_CBACKS;
+ int xx;
+
+ for (xx = 0; xx < NFA_EE_MAX_CBACKS; xx++)
+ {
+ if (nfa_ee_cb.p_ee_cback[xx] == p_cback)
+ {
+ index = xx;
+ status = NFA_STATUS_FAILED;
+ break;
+ }
+ }
+
+ NFA_TRACE_API2 ("NFA_EeDeregister() %d, status:%d", index, status);
+ if ((status != NFA_STATUS_INVALID_PARAM) &&
+ (p_msg = (tNFA_EE_API_DEREGISTER *) GKI_getbuf (sizeof(tNFA_EE_API_DEREGISTER))) != NULL)
+ {
+ p_msg->hdr.event = NFA_EE_API_DEREGISTER_EVT;
+ p_msg->index = index;
+
+ nfa_sys_sendmsg (p_msg);
+
+ status = NFA_STATUS_OK;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function NFA_EeModeSet
+**
+** Description This function is called to activate (mode = NFA_EE_MD_ACTIVATE)
+** or deactivate (mode = NFA_EE_MD_DEACTIVATE) the NFCEE
+** identified by the given ee_handle. The result of this
+** operation is reported with the NFA_EE_MODE_SET_EVT.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+** NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeModeSet(tNFA_HANDLE ee_handle,
+ tNFA_EE_MD mode)
+{
+ tNFA_EE_API_MODE_SET *p_msg;
+ tNFA_STATUS status = NFA_STATUS_FAILED;
+ tNFA_EE_ECB *p_cb, *p_found = NULL;
+ UINT32 xx;
+ UINT8 nfcee_id = (ee_handle & 0xFF);
+
+ p_cb = nfa_ee_cb.ecb;
+ for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++)
+ {
+ if (nfcee_id == p_cb->nfcee_id)
+ {
+ p_found = p_cb;
+ break;
+ }
+ }
+ NFA_TRACE_API2 ("NFA_EeModeSet(): handle:<0x%x>, mode:0x%02X", ee_handle, mode);
+
+ if (p_found == NULL)
+ {
+ NFA_TRACE_ERROR1 ("NFA_EeModeSet() invalid NFCEE:0x%04x", ee_handle);
+ status = NFA_STATUS_INVALID_PARAM;
+ }
+ else if ((p_msg = (tNFA_EE_API_MODE_SET *) GKI_getbuf (sizeof(tNFA_EE_API_MODE_SET))) != NULL)
+ {
+ p_msg->hdr.event = NFA_EE_API_MODE_SET_EVT;
+ p_msg->nfcee_id = nfcee_id;
+ p_msg->mode = mode;
+ p_msg->p_cb = p_found;
+
+ nfa_sys_sendmsg (p_msg);
+
+ status = NFA_STATUS_OK;
+ }
+
+
+ return status;
+}
+
+
+/*******************************************************************************
+**
+** Function NFA_EeSetDefaultTechRouting
+**
+** Description This function is called to add, change or remove the
+** default routing based on RF technology in the listen mode
+** routing table for the given ee_handle. The status of this
+** operation is reported as the NFA_EE_SET_TECH_CFG_EVT.
+**
+** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function
+**
+** Note: NFA_EeUpdateNow() should be called after last NFA-EE function
+** to change the listen mode routing is called.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+** NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeSetDefaultTechRouting(tNFA_HANDLE ee_handle,
+ tNFA_TECHNOLOGY_MASK technologies_switch_on,
+ tNFA_TECHNOLOGY_MASK technologies_switch_off,
+ tNFA_TECHNOLOGY_MASK technologies_battery_off
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ ,tNFA_TECHNOLOGY_MASK technologies_screen_lock,
+ tNFA_TECHNOLOGY_MASK technologies_screen_off
+#endif
+)
+{
+ tNFA_EE_API_SET_TECH_CFG *p_msg;
+ tNFA_STATUS status = NFA_STATUS_FAILED;
+ UINT8 nfcee_id = (UINT8)(ee_handle & 0xFF);
+ tNFA_EE_ECB *p_cb;
+
+ NFA_TRACE_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 );
+ p_cb = nfa_ee_find_ecb (nfcee_id);
+
+ if (p_cb == NULL)
+ {
+ NFA_TRACE_ERROR0 ("Bad ee_handle");
+ status = NFA_STATUS_INVALID_PARAM;
+ }
+ else if ((p_msg = (tNFA_EE_API_SET_TECH_CFG *) GKI_getbuf (sizeof(tNFA_EE_API_SET_TECH_CFG))) != NULL)
+ {
+ p_msg->hdr.event = NFA_EE_API_SET_TECH_CFG_EVT;
+ p_msg->nfcee_id = nfcee_id;
+ p_msg->p_cb = p_cb;
+ p_msg->technologies_switch_on = technologies_switch_on;
+ p_msg->technologies_switch_off = technologies_switch_off;
+ p_msg->technologies_battery_off = technologies_battery_off;
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ p_msg->technologies_screen_lock = technologies_screen_lock;
+ p_msg->technologies_screen_off = technologies_screen_off;
+#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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ ,tNFA_PROTOCOL_MASK protocols_screen_lock,
+ tNFA_PROTOCOL_MASK protocols_screen_off
+#endif
+)
+{
+ tNFA_EE_API_SET_PROTO_CFG *p_msg;
+ tNFA_STATUS status = NFA_STATUS_FAILED;
+ UINT8 nfcee_id = (UINT8)(ee_handle & 0xFF);
+ tNFA_EE_ECB *p_cb;
+
+ NFA_TRACE_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);
+ p_cb = nfa_ee_find_ecb (nfcee_id);
+
+ if (p_cb == NULL)
+ {
+ NFA_TRACE_ERROR0 ("Bad ee_handle");
+ status = NFA_STATUS_INVALID_PARAM;
+ }
+ else if ((p_msg = (tNFA_EE_API_SET_PROTO_CFG *) GKI_getbuf (sizeof(tNFA_EE_API_SET_PROTO_CFG))) != NULL)
+ {
+ p_msg->hdr.event = NFA_EE_API_SET_PROTO_CFG_EVT;
+ p_msg->nfcee_id = nfcee_id;
+ p_msg->p_cb = p_cb;
+ p_msg->protocols_switch_on = protocols_switch_on;
+ p_msg->protocols_switch_off = protocols_switch_off;
+ p_msg->protocols_battery_off = protocols_battery_off;
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ p_msg->protocols_screen_lock = protocols_screen_lock;
+ p_msg->protocols_screen_off = protocols_screen_off;
+#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 aid_len,
+ UINT8 *p_aid,
+ tNFA_EE_PWR_STATE power_state
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ , UINT8 vs_info)
+#else
+)
+#endif
+{
+ tNFA_EE_API_ADD_AID *p_msg;
+ tNFA_STATUS status = NFA_STATUS_FAILED;
+ UINT16 size = sizeof(tNFA_EE_API_ADD_AID) + aid_len;
+ UINT8 nfcee_id = (UINT8)(ee_handle & 0xFF);
+ tNFA_EE_ECB *p_cb;
+
+ NFA_TRACE_API1 ("NFA_EeAddAidRouting(): handle:<0x%x>", ee_handle);
+ p_cb = nfa_ee_find_ecb (nfcee_id);
+
+ /* validate parameters - make sure the AID is in valid length range */
+ if ((p_cb == NULL) || (aid_len == 0) || (p_aid == NULL) || (aid_len < NFA_MIN_AID_LEN) || (aid_len > NFA_MAX_AID_LEN))
+ {
+ NFA_TRACE_ERROR1 ("Bad ee_handle or AID (len=%d)", aid_len);
+ status = NFA_STATUS_INVALID_PARAM;
+ }
+ else if ((p_msg = (tNFA_EE_API_ADD_AID *) GKI_getbuf (size)) != NULL)
+ {
+ NFA_TRACE_DEBUG2 ("aid:<%02x%02x>", p_aid[0], p_aid[1]);
+ p_msg->hdr.event = NFA_EE_API_ADD_AID_EVT;
+ p_msg->nfcee_id = nfcee_id;
+ p_msg->p_cb = p_cb;
+ p_msg->aid_len = aid_len;
+ p_msg->power_state = power_state;
+ p_msg->p_aid = (UINT8 *)(p_msg + 1);
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ p_msg->vs_info = vs_info;
+#endif
+ memcpy(p_msg->p_aid, p_aid, aid_len);
+
+ nfa_sys_sendmsg (p_msg);
+
+ status = NFA_STATUS_OK;
+ }
+
+ return status;
+}
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 nfcee_id = (UINT8)(ee_handle & 0xFF);
+ tNFA_EE_ECB *p_cb;
+ UINT8 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 NFA_GetAidTableSize()
+{
+ return NFA_EE_MAX_AID_CFG_LEN;
+}
+
+/*******************************************************************************
+**
+** Function NFA_GetRemainingAidTableSize
+**
+** Description This function is called to get the remaining AID routing
+** table size.
+**
+** Returns Remaining AID routing table size.
+**
+*******************************************************************************/
+UINT16 NFA_GetRemainingAidTableSize()
+{
+ UINT16 size = 0;
+
+ size = NFA_EE_MAX_AID_CFG_LEN - 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 state)
+{
+ nfa_ee_ce_route_strict_disable = (UINT8)state;
+}
+#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 aid_len,
+ UINT8 *p_aid)
+{
+ tNFA_EE_API_REMOVE_AID *p_msg;
+ tNFA_STATUS status = NFA_STATUS_FAILED;
+ UINT16 size = sizeof(tNFA_EE_API_REMOVE_AID) + aid_len;
+
+ NFA_TRACE_API0 ("NFA_EeRemoveAidRouting()");
+ if ((aid_len == 0) || (p_aid == NULL) || (aid_len > NFA_MAX_AID_LEN))
+ {
+ NFA_TRACE_ERROR0 ("Bad AID");
+ status = NFA_STATUS_INVALID_PARAM;
+ }
+ else if ((p_msg = (tNFA_EE_API_REMOVE_AID *) GKI_getbuf (size)) != NULL)
+ {
+ p_msg->hdr.event = NFA_EE_API_REMOVE_AID_EVT;
+ p_msg->aid_len = aid_len;
+ p_msg->p_aid = (UINT8 *)(p_msg + 1);
+ memcpy(p_msg->p_aid, p_aid, aid_len);
+
+ nfa_sys_sendmsg (p_msg);
+
+ status = NFA_STATUS_OK;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function NFA_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()");
+ if ((p_msg = (tNFA_EE_API_LMRT_SIZE *) GKI_getbuf (sizeof(tNFA_EE_API_LMRT_SIZE))) != 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)
+{
+ BT_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 if ((p_msg = (BT_HDR *) GKI_getbuf (BT_HDR_SIZE)) != NULL)
+ {
+ p_msg->event = NFA_EE_API_UPDATE_NOW_EVT;
+
+ nfa_sys_sendmsg (p_msg);
+
+ status = NFA_STATUS_OK;
+ }
+
+ return status;
+}
+
+
+/*******************************************************************************
+**
+** Function NFA_EeConnect
+**
+** Description Open connection to an NFCEE attached to the NFCC
+**
+** The status of this operation is
+** reported with the NFA_EE_CONNECT_EVT.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+** NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeConnect(tNFA_HANDLE ee_handle,
+ UINT8 ee_interface,
+ tNFA_EE_CBACK *p_cback)
+{
+ tNFA_EE_API_CONNECT *p_msg;
+ tNFA_STATUS status = NFA_STATUS_FAILED;
+ UINT8 nfcee_id = (UINT8)(ee_handle & 0xFF);
+ tNFA_EE_ECB *p_cb;
+
+ NFA_TRACE_API2 ("NFA_EeConnect(): handle:<0x%x> ee_interface:0x%x", ee_handle, ee_interface);
+ p_cb = nfa_ee_find_ecb (nfcee_id);
+
+ if ((p_cb == NULL) || (p_cback == NULL))
+ {
+ NFA_TRACE_ERROR0 ("Bad ee_handle or NULL callback function");
+ status = NFA_STATUS_INVALID_PARAM;
+ }
+ else if ((p_msg = (tNFA_EE_API_CONNECT *) GKI_getbuf (sizeof(tNFA_EE_API_CONNECT))) != NULL)
+ {
+ p_msg->hdr.event = NFA_EE_API_CONNECT_EVT;
+ p_msg->nfcee_id = nfcee_id;
+ p_msg->p_cb = p_cb;
+ p_msg->ee_interface = ee_interface;
+ p_msg->p_cback = p_cback;
+
+ nfa_sys_sendmsg (p_msg);
+
+ status = NFA_STATUS_OK;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function NFA_EeSendData
+**
+** Description Send data to the given NFCEE.
+** This function shall be called after NFA_EE_CONNECT_EVT is reported
+** and before NFA_EeDisconnect is called on the given ee_handle.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+** NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeSendData (tNFA_HANDLE ee_handle,
+ UINT16 data_len,
+ UINT8 *p_data)
+{
+ tNFA_EE_API_SEND_DATA *p_msg;
+ tNFA_STATUS status = NFA_STATUS_FAILED;
+ UINT8 nfcee_id = (UINT8)(ee_handle & 0xFF);
+ tNFA_EE_ECB *p_cb;
+
+ NFA_TRACE_API1 ("NFA_EeSendData(): handle:<0x%x>", ee_handle);
+
+ p_cb = nfa_ee_find_ecb (nfcee_id);
+
+ if ((p_cb == NULL) || (p_cb->conn_st != NFA_EE_CONN_ST_CONN) || (p_data == NULL))
+ {
+ NFA_TRACE_ERROR0 ("Bad ee_handle or NULL data");
+ status = NFA_STATUS_INVALID_PARAM;
+ }
+ else if ((p_msg = (tNFA_EE_API_SEND_DATA *) GKI_getbuf ((UINT16)(sizeof(tNFA_EE_API_SEND_DATA) + data_len))) != NULL)
+ {
+ p_msg->hdr.event = NFA_EE_API_SEND_DATA_EVT;
+ p_msg->nfcee_id = nfcee_id;
+ p_msg->p_cb = p_cb;
+ p_msg->data_len = data_len;
+ p_msg->p_data = (UINT8 *)(p_msg + 1);
+ memcpy(p_msg->p_data, p_data, data_len);
+
+ nfa_sys_sendmsg (p_msg);
+
+ status = NFA_STATUS_OK;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function NFA_EeDisconnect
+**
+** Description Disconnect (if a connection is currently open) from an
+** NFCEE interface. The result of this operation is reported
+** with the NFA_EE_DISCONNECT_EVT.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+** NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeDisconnect(tNFA_HANDLE ee_handle)
+{
+ tNFA_EE_API_DISCONNECT *p_msg;
+ tNFA_STATUS status = NFA_STATUS_FAILED;
+ UINT8 nfcee_id = (UINT8)(ee_handle & 0xFF);
+ tNFA_EE_ECB *p_cb;
+
+ NFA_TRACE_API1 ("NFA_EeDisconnect(): handle:<0x%x>", ee_handle);
+ p_cb = nfa_ee_find_ecb (nfcee_id);
+
+ if ((p_cb == NULL) || (p_cb->conn_st != NFA_EE_CONN_ST_CONN))
+ {
+ NFA_TRACE_ERROR0 ("NFA_EeDisconnect() Bad ee_handle");
+ status = NFA_STATUS_INVALID_PARAM;
+ }
+ else if ((p_msg = (tNFA_EE_API_DISCONNECT *) GKI_getbuf (sizeof(tNFA_EE_API_DISCONNECT))) != NULL)
+ {
+ p_msg->hdr.event = NFA_EE_API_DISCONNECT_EVT;
+ p_msg->nfcee_id = nfcee_id;
+ p_msg->p_cb = p_cb;
+
+ nfa_sys_sendmsg (p_msg);
+
+ status = NFA_STATUS_OK;
+ }
+
+ return status;
+}
diff --git a/src/nfa/ee/nfa_ee_main.c b/src/nfa/ee/nfa_ee_main.c
new file mode 100644
index 0000000..90633c8
--- /dev/null
+++ b/src/nfa/ee/nfa_ee_main.c
@@ -0,0 +1,738 @@
+/******************************************************************************
+ *
+ * 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"
+
+extern void nfa_ee_vs_cback (tNFC_VS_EVT event, BT_HDR *p_data);
+/*****************************************************************************
+** Global Variables
+*****************************************************************************/
+
+/* system manager control block definition */
+#if NFA_DYNAMIC_MEMORY == FALSE
+tNFA_EE_CB nfa_ee_cb;
+#endif
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 */
+ 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 */
+};
+
+
+/*******************************************************************************
+**
+** Function nfa_ee_init
+**
+** Description Initialize NFA EE control block
+** register to NFA SYS
+**
+** Returns None
+**
+*******************************************************************************/
+void nfa_ee_init (void)
+{
+ int xx;
+
+ NFA_TRACE_DEBUG0 ("nfa_ee_init ()");
+
+ /* initialize control block */
+ memset (&nfa_ee_cb, 0, sizeof (tNFA_EE_CB));
+ for (xx = 0; xx < NFA_EE_MAX_EE_SUPPORTED; xx++)
+ {
+ nfa_ee_cb.ecb[xx].nfcee_id = NFA_EE_INVALID;
+ nfa_ee_cb.ecb[xx].ee_status = NFC_NFCEE_STATUS_INACTIVE;
+ }
+
+ nfa_ee_cb.ecb[NFA_EE_CB_4_DH].ee_status = NFC_NFCEE_STATUS_ACTIVE;
+ nfa_ee_cb.ecb[NFA_EE_CB_4_DH].nfcee_id = NFC_DH_ID;
+
+ /* register message handler on NFA SYS */
+ nfa_sys_register (NFA_ID_EE, &nfa_ee_sys_reg);
+}
+
+/*******************************************************************************
+**
+** Function nfa_ee_sys_enable
+**
+** Description Enable NFA EE
+**
+** Returns None
+**
+*******************************************************************************/
+void nfa_ee_sys_enable (void)
+{
+ 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 mask;
+ tNFC_NFCEE_MODE_SET_REVT rsp;
+ tNFA_EE_NCI_MODE_SET ee_msg;
+
+ NFA_TRACE_DEBUG4 ("nfa_ee_restore_one_ecb () nfcee_id:0x%x, ecb_flags:0x%x ee_status:0x%x ee_old_status: 0x%x", p_cb->nfcee_id, p_cb->ecb_flags, p_cb->ee_status, p_cb->ee_old_status);
+ if ((p_cb->nfcee_id != NFA_EE_INVALID) && (p_cb->ee_status & NFA_EE_STATUS_RESTORING) == 0 && (p_cb->ee_old_status & NFA_EE_STATUS_RESTORING) != 0)
+ {
+ p_cb->ee_old_status &= ~NFA_EE_STATUS_RESTORING;
+ mask = nfa_ee_ecb_to_mask(p_cb);
+ if (p_cb->ee_status != p_cb->ee_old_status)
+ {
+ p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_RESTORE;
+ if (p_cb->ee_old_status == NFC_NFCEE_STATUS_ACTIVE)
+ {
+ NFC_NfceeModeSet (p_cb->nfcee_id, NFC_MODE_ACTIVATE);
+
+ if (nfa_ee_cb.ee_cfged & mask)
+ {
+ /* if any routing is configured on this NFCEE. need to mark this NFCEE as changed
+ * to cause the configuration to be sent to NFCC again */
+ p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_ROUTING;
+ p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_VS;
+ }
+ }
+ else
+ {
+ NFC_NfceeModeSet (p_cb->nfcee_id, NFC_MODE_DEACTIVATE);
+ }
+ }
+ else if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE)
+ {
+ /* the initial NFCEE status after start up is the same as the current status and it's active:
+ * process the same as the host gets activate rsp */
+ p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_RESTORE;
+ if (nfa_ee_cb.ee_cfged & mask)
+ {
+ /* if any routing is configured on this NFCEE. need to mark this NFCEE as changed
+ * to cause the configuration to be sent to NFCC again */
+ p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_ROUTING;
+ p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_VS;
+ }
+ rsp.mode = NFA_EE_MD_ACTIVATE;
+ rsp.nfcee_id = p_cb->nfcee_id;
+ rsp.status = NFA_STATUS_OK;
+ ee_msg.p_data = &rsp;
+ nfa_ee_nci_mode_set_rsp ((tNFA_EE_MSG *) &ee_msg);
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_ee_proc_nfcc_power_mode
+**
+** Description Restore NFA EE sub-module
+**
+** Returns None
+**
+*******************************************************************************/
+void nfa_ee_proc_nfcc_power_mode (UINT8 nfcc_power_mode)
+{
+ UINT32 xx;
+ tNFA_EE_ECB *p_cb;
+ BOOLEAN proc_complete = TRUE;
+
+ NFA_TRACE_DEBUG1 ("nfa_ee_proc_nfcc_power_mode (): nfcc_power_mode=%d", nfcc_power_mode);
+ /* if NFCC power state is change to full power */
+ if (nfcc_power_mode == NFA_DM_PWR_MODE_FULL)
+ {
+ if (nfa_ee_max_ee_cfg)
+ {
+ p_cb = nfa_ee_cb.ecb;
+ for (xx = 0; xx < NFA_EE_MAX_EE_SUPPORTED; xx++, p_cb++)
+ {
+ p_cb->ee_old_status = 0;
+ if (xx >= nfa_ee_cb.cur_ee)
+ p_cb->nfcee_id = NFA_EE_INVALID;
+
+ if ((p_cb->nfcee_id != NFA_EE_INVALID) && (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) && (p_cb->ee_status != NFA_EE_STATUS_REMOVED))
+ {
+ proc_complete = FALSE;
+ /* NFA_EE_STATUS_RESTORING bit makes sure the ee_status restore to ee_old_status
+ * NFA_EE_STATUS_RESTORING bit is cleared in ee_status at NFCEE_DISCOVER NTF.
+ * NFA_EE_STATUS_RESTORING bit is cleared in ee_old_status at restoring the activate/inactive status after NFCEE_DISCOVER NTF */
+ p_cb->ee_status |= NFA_EE_STATUS_RESTORING;
+ p_cb->ee_old_status = p_cb->ee_status;
+ /* NFA_EE_FLAGS_RESTORE bit makes sure the routing/nci logical connection is restore to prior to entering low power mode */
+ p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_RESTORE;
+ }
+ }
+ nfa_ee_cb.em_state = NFA_EE_EM_STATE_RESTORING;
+ 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 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 < 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((BT_HDR *)&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;
+ BT_HDR *p_hdr;
+
+ switch (event)
+ {
+ case NFC_NFCEE_DISCOVER_REVT: /* 4 NFCEE Discover response */
+ int_event = NFA_EE_NCI_DISC_RSP_EVT;
+ break;
+
+ case NFC_NFCEE_INFO_REVT: /* 5 NFCEE Discover Notification */
+ int_event = NFA_EE_NCI_DISC_NTF_EVT;
+ break;
+
+ case NFC_NFCEE_MODE_SET_REVT: /* 6 NFCEE Mode Set response */
+ int_event = NFA_EE_NCI_MODE_SET_RSP_EVT;
+ break;
+
+ case NFC_EE_ACTION_REVT:
+ int_event = NFA_EE_NCI_ACTION_NTF_EVT;
+ break;
+
+ case NFC_EE_DISCOVER_REQ_REVT: /* 10 EE Discover Req notification */
+ int_event = NFA_EE_NCI_DISC_REQ_NTF_EVT;
+ break;
+
+ case NFC_SET_ROUTING_REVT:
+ int_event = NFA_EE_NCI_WAIT_RSP_EVT;
+ cbk.opcode = NCI_MSG_RF_SET_ROUTING;
+ break;
+ }
+
+ NFA_TRACE_DEBUG2 ("nfa_ee_proc_evt: event=0x%02x int_event:0x%x", event, int_event);
+ if (int_event)
+ {
+ p_hdr = (BT_HDR *) &cbk;
+ cbk.hdr.event = int_event;
+ cbk.p_data = p_data;
+
+ nfa_ee_evt_hdlr (p_hdr);
+ }
+
+}
+
+/*******************************************************************************
+**
+** Function nfa_ee_ecb_to_mask
+**
+** Description Given a ecb, return the bit mask to be used in nfa_ee_cb.ee_cfged
+**
+** Returns the bitmask for the given ecb.
+**
+*******************************************************************************/
+UINT8 nfa_ee_ecb_to_mask (tNFA_EE_ECB *p_cb)
+{
+ UINT8 mask;
+ UINT8 index;
+
+ index = (UINT8) (p_cb - nfa_ee_cb.ecb);
+ mask = 1 << index;
+
+ return mask;
+}
+
+/*******************************************************************************
+**
+** Function nfa_ee_find_ecb
+**
+** Description Return the ecb associated with the given nfcee_id
+**
+** Returns tNFA_EE_ECB
+**
+*******************************************************************************/
+tNFA_EE_ECB * nfa_ee_find_ecb (UINT8 nfcee_id)
+{
+ UINT32 xx;
+ tNFA_EE_ECB *p_ret = NULL, *p_cb;
+ NFA_TRACE_DEBUG0 ("nfa_ee_find_ecb ()");
+
+ if (nfcee_id == NFC_DH_ID)
+ {
+ p_ret = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH];
+ }
+ else
+ {
+ p_cb = nfa_ee_cb.ecb;
+ for (xx = 0; xx < NFA_EE_MAX_EE_SUPPORTED; xx++, p_cb++)
+ {
+ if (nfcee_id == p_cb->nfcee_id)
+ {
+ p_ret = p_cb;
+ break;
+ }
+ }
+ }
+
+ return p_ret;
+}
+
+/*******************************************************************************
+**
+** Function nfa_ee_find_ecb_by_conn_id
+**
+** Description Return the ecb associated with the given connection id
+**
+** Returns tNFA_EE_ECB
+**
+*******************************************************************************/
+tNFA_EE_ECB * nfa_ee_find_ecb_by_conn_id (UINT8 conn_id)
+{
+ UINT32 xx;
+ tNFA_EE_ECB *p_ret = NULL, *p_cb;
+ NFA_TRACE_DEBUG0 ("nfa_ee_find_ecb_by_conn_id ()");
+
+ p_cb = nfa_ee_cb.ecb;
+ for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++)
+ {
+ if (conn_id == p_cb->conn_id)
+ {
+ p_ret = p_cb;
+ break;
+ }
+ }
+
+ return p_ret;
+}
+
+/*******************************************************************************
+**
+** Function nfa_ee_sys_disable
+**
+** Description Deregister NFA EE from NFA SYS/DM
+**
+**
+** Returns None
+**
+*******************************************************************************/
+void nfa_ee_sys_disable (void)
+{
+ UINT32 xx;
+ tNFA_EE_ECB *p_cb;
+ tNFA_EE_MSG msg;
+
+ NFA_TRACE_DEBUG0 ("nfa_ee_sys_disable ()");
+
+ nfa_ee_cb.em_state = NFA_EE_EM_STATE_DISABLED;
+ /* report NFA_EE_DEREGISTER_EVT to all registered to EE */
+ for (xx = 0; xx < NFA_EE_MAX_CBACKS; xx++)
+ {
+ if (nfa_ee_cb.p_ee_cback[xx])
+ {
+ msg.deregister.index = xx;
+ nfa_ee_api_deregister (&msg);
+ }
+ }
+
+ 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;
+ nfa_ee_api_disconnect (&msg);
+ nfa_ee_cb.num_ee_expecting++;
+ }
+ 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);
+
+}
+
+/*******************************************************************************
+**
+** 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 state)
+{
+ switch (state)
+ {
+ case NFA_EE_EM_STATE_INIT:
+ return "INIT";
+
+ case NFA_EE_EM_STATE_INIT_DONE:
+ return "INIT_DONE";
+
+ case NFA_EE_EM_STATE_RESTORING:
+ return "RESTORING";
+
+ case NFA_EE_EM_STATE_DISABLING:
+ return "DISABLING";
+
+ case NFA_EE_EM_STATE_DISABLED:
+ return "DISABLED";
+
+ default:
+ return "Unknown";
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_ee_sm_evt_2_str
+**
+** Description convert nfa-ee evt to string
+**
+*******************************************************************************/
+static char *nfa_ee_sm_evt_2_str (UINT16 event)
+{
+ switch (event)
+ {
+ case NFA_EE_API_DISCOVER_EVT:
+ return "API_DISCOVER";
+ case NFA_EE_API_REGISTER_EVT:
+ return "API_REGISTER";
+ case NFA_EE_API_DEREGISTER_EVT:
+ return "API_DEREGISTER";
+ case NFA_EE_API_MODE_SET_EVT:
+ return "API_MODE_SET";
+ case NFA_EE_API_SET_TECH_CFG_EVT:
+ return "API_SET_TECH_CFG";
+ case NFA_EE_API_SET_PROTO_CFG_EVT:
+ return "API_SET_PROTO_CFG";
+ case NFA_EE_API_ADD_AID_EVT:
+ return "API_ADD_AID";
+ case NFA_EE_API_REMOVE_AID_EVT:
+ return "API_REMOVE_AID";
+ case NFA_EE_API_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";
+ 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
+**
+*******************************************************************************/
+BOOLEAN nfa_ee_evt_hdlr (BT_HDR *p_msg)
+{
+ tNFA_EE_MSG *p_evt_data = (tNFA_EE_MSG *) p_msg;
+ UINT16 event = p_msg->event & 0x00ff;
+ BOOLEAN act = FALSE;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ NFA_TRACE_DEBUG4 ("nfa_ee_evt_hdlr (): Event %s(0x%02x), State: %s(%d)",
+ nfa_ee_sm_evt_2_str (p_evt_data->hdr.event), p_evt_data->hdr.event,
+ nfa_ee_sm_st_2_str (nfa_ee_cb.em_state), nfa_ee_cb.em_state);
+#else
+ NFA_TRACE_DEBUG2 ("nfa_ee_evt_hdlr (): Event 0x%02x, State: %d", p_evt_data->hdr.event, nfa_ee_cb.em_state);
+#endif
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ /*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..f06eeeb
--- /dev/null
+++ b/src/nfa/hci/nfa_hci_act.c
@@ -0,0 +1,2307 @@
+/******************************************************************************
+ *
+ * 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 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"
+
+
+/* Static local functions */
+static void nfa_hci_api_register (tNFA_HCI_EVENT_DATA *p_evt_data);
+static void nfa_hci_api_get_gate_pipe_list (tNFA_HCI_EVENT_DATA *p_evt_data);
+static void nfa_hci_api_alloc_gate (tNFA_HCI_EVENT_DATA *p_evt_data);
+static void nfa_hci_api_get_host_list (tNFA_HCI_EVENT_DATA *p_evt_data);
+static BOOLEAN nfa_hci_api_get_reg_value (tNFA_HCI_EVENT_DATA *p_evt_data);
+static BOOLEAN nfa_hci_api_set_reg_value (tNFA_HCI_EVENT_DATA *p_evt_data);
+static BOOLEAN nfa_hci_api_create_pipe (tNFA_HCI_EVENT_DATA *p_evt_data);
+static void nfa_hci_api_open_pipe (tNFA_HCI_EVENT_DATA *p_evt_data);
+static void nfa_hci_api_close_pipe (tNFA_HCI_EVENT_DATA *p_evt_data);
+static void nfa_hci_api_delete_pipe (tNFA_HCI_EVENT_DATA *p_evt_data);
+static BOOLEAN nfa_hci_api_send_event (tNFA_HCI_EVENT_DATA *p_evt_data);
+static BOOLEAN nfa_hci_api_send_cmd (tNFA_HCI_EVENT_DATA *p_evt_data);
+static void nfa_hci_api_send_rsp (tNFA_HCI_EVENT_DATA *p_evt_data);
+static void nfa_hci_api_add_static_pipe (tNFA_HCI_EVENT_DATA *p_evt_data);
+
+static void nfa_hci_handle_identity_mgmt_gate_pkt (UINT8 *p_data, tNFA_HCI_DYN_PIPE *p_pipe);
+static void nfa_hci_handle_loopback_gate_pkt (UINT8 *p_data, UINT16 data_len, tNFA_HCI_DYN_PIPE *p_pipe);
+static void nfa_hci_handle_connectivity_gate_pkt (UINT8 *p_data, UINT16 data_len, tNFA_HCI_DYN_PIPE *p_pipe);
+static void nfa_hci_handle_generic_gate_cmd (UINT8 *p_data, UINT8 data_len, tNFA_HCI_DYN_GATE *p_gate, tNFA_HCI_DYN_PIPE *p_pipe);
+static void nfa_hci_handle_generic_gate_rsp (UINT8 *p_data, UINT8 data_len, tNFA_HCI_DYN_GATE *p_gate, tNFA_HCI_DYN_PIPE *p_pipe);
+static void nfa_hci_handle_generic_gate_evt (UINT8 *p_data, UINT16 data_len, tNFA_HCI_DYN_GATE *p_gate, tNFA_HCI_DYN_PIPE *p_pipe);
+
+
+/*******************************************************************************
+**
+** Function nfa_hci_check_pending_api_requests
+**
+** Description This function handles pending API requests
+**
+** Returns none
+**
+*******************************************************************************/
+void nfa_hci_check_pending_api_requests (void)
+{
+ BT_HDR *p_msg;
+ tNFA_HCI_EVENT_DATA *p_evt_data;
+ BOOLEAN b_free;
+
+ /* If busy, or API queue is empty, then exit */
+ if ( (nfa_hci_cb.hci_state != NFA_HCI_STATE_IDLE)
+ ||((p_msg = (BT_HDR *) GKI_dequeue (&nfa_hci_cb.hci_host_reset_api_q)) == NULL) )
+ return;
+
+ /* Process API request */
+ p_evt_data = (tNFA_HCI_EVENT_DATA *)p_msg;
+
+ /* Save the application handle */
+ nfa_hci_cb.app_in_use = p_evt_data->comm.hci_handle;
+
+ b_free = TRUE;
+ switch (p_msg->event)
+ {
+ case NFA_HCI_API_CREATE_PIPE_EVT:
+ if (nfa_hci_api_create_pipe (p_evt_data) == FALSE)
+ b_free = FALSE;
+ break;
+
+ case NFA_HCI_API_GET_REGISTRY_EVT:
+ if (nfa_hci_api_get_reg_value (p_evt_data) == FALSE)
+ b_free = FALSE;
+ break;
+
+ case NFA_HCI_API_SET_REGISTRY_EVT:
+ if (nfa_hci_api_set_reg_value (p_evt_data) == FALSE)
+ b_free = FALSE;
+ break;
+
+ case NFA_HCI_API_SEND_CMD_EVT:
+ if (nfa_hci_api_send_cmd (p_evt_data) == FALSE)
+ b_free = FALSE;
+ break;
+ case NFA_HCI_API_SEND_EVENT_EVT:
+ if (nfa_hci_api_send_event (p_evt_data) == FALSE)
+ b_free = FALSE;
+ break;
+ }
+
+ if (b_free)
+ GKI_freebuf (p_msg);
+}
+
+/*******************************************************************************
+**
+** Function nfa_hci_check_api_requests
+**
+** Description This function handles API requests
+**
+** Returns none
+**
+*******************************************************************************/
+void nfa_hci_check_api_requests (void)
+{
+ BT_HDR *p_msg;
+ tNFA_HCI_EVENT_DATA *p_evt_data;
+
+ for ( ; ; )
+ {
+ /* If busy, or API queue is empty, then exit */
+ if ( (nfa_hci_cb.hci_state != NFA_HCI_STATE_IDLE)
+ ||((p_msg = (BT_HDR *) GKI_dequeue (&nfa_hci_cb.hci_api_q)) == NULL) )
+ break;
+
+ /* Process API request */
+ p_evt_data = (tNFA_HCI_EVENT_DATA *)p_msg;
+
+ /* Save the application handle */
+ nfa_hci_cb.app_in_use = p_evt_data->comm.hci_handle;
+
+ switch (p_msg->event)
+ {
+ case NFA_HCI_API_REGISTER_APP_EVT:
+ nfa_hci_api_register (p_evt_data);
+ break;
+
+ case NFA_HCI_API_DEREGISTER_APP_EVT:
+ nfa_hci_api_deregister (p_evt_data);
+ break;
+
+ case NFA_HCI_API_GET_APP_GATE_PIPE_EVT:
+ nfa_hci_api_get_gate_pipe_list (p_evt_data);
+ break;
+
+ case NFA_HCI_API_ALLOC_GATE_EVT:
+ nfa_hci_api_alloc_gate (p_evt_data);
+ break;
+
+ case NFA_HCI_API_DEALLOC_GATE_EVT:
+ nfa_hci_api_dealloc_gate (p_evt_data);
+ break;
+
+ case NFA_HCI_API_GET_HOST_LIST_EVT:
+ nfa_hci_api_get_host_list (p_evt_data);
+ break;
+
+ case NFA_HCI_API_GET_REGISTRY_EVT:
+ if (nfa_hci_api_get_reg_value (p_evt_data) == FALSE)
+ continue;
+ break;
+
+ case NFA_HCI_API_SET_REGISTRY_EVT:
+ if (nfa_hci_api_set_reg_value (p_evt_data) == FALSE)
+ continue;
+ break;
+
+ case NFA_HCI_API_CREATE_PIPE_EVT:
+ if (nfa_hci_api_create_pipe (p_evt_data) == FALSE)
+ continue;
+ break;
+
+ case NFA_HCI_API_OPEN_PIPE_EVT:
+ nfa_hci_api_open_pipe (p_evt_data);
+ break;
+
+ case NFA_HCI_API_CLOSE_PIPE_EVT:
+ nfa_hci_api_close_pipe (p_evt_data);
+ break;
+
+ case NFA_HCI_API_DELETE_PIPE_EVT:
+ nfa_hci_api_delete_pipe (p_evt_data);
+ break;
+
+ case NFA_HCI_API_SEND_CMD_EVT:
+ if (nfa_hci_api_send_cmd (p_evt_data) == FALSE)
+ continue;
+ break;
+
+ case NFA_HCI_API_SEND_RSP_EVT:
+ nfa_hci_api_send_rsp (p_evt_data);
+ break;
+
+ case NFA_HCI_API_SEND_EVENT_EVT:
+ if (nfa_hci_api_send_event (p_evt_data) == FALSE)
+ continue;
+ break;
+
+ case NFA_HCI_API_ADD_STATIC_PIPE_EVT:
+ nfa_hci_api_add_static_pipe (p_evt_data);
+ break;
+
+ default:
+ NFA_TRACE_ERROR1 ("nfa_hci_check_api_requests () Unknown event: 0x%04x", p_msg->event);
+ break;
+ }
+
+ GKI_freebuf (p_msg);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_hci_api_register
+**
+** Description action function to register the events for the given AID
+**
+** Returns None
+**
+*******************************************************************************/
+static void nfa_hci_api_register (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+ tNFA_HCI_EVT_DATA evt_data;
+ char *p_app_name = p_evt_data->app_info.app_name;
+ tNFA_HCI_CBACK *p_cback = p_evt_data->app_info.p_cback;
+ int xx,yy;
+ UINT8 num_gates = 0,num_pipes = 0;
+ tNFA_HCI_DYN_GATE *pg = nfa_hci_cb.cfg.dyn_gates;
+
+ /* First, see if the application was already registered */
+ for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++)
+ {
+ if ( (nfa_hci_cb.cfg.reg_app_names[xx][0] != 0)
+ && !strncmp (p_app_name, &nfa_hci_cb.cfg.reg_app_names[xx][0], strlen (p_app_name)) )
+ {
+ NFA_TRACE_EVENT2 ("nfa_hci_api_register (%s) Reusing: %u", p_app_name, xx);
+ break;
+ }
+ }
+
+ if (xx != NFA_HCI_MAX_APP_CB)
+ {
+ nfa_hci_cb.app_in_use = (tNFA_HANDLE) (xx | NFA_HANDLE_GROUP_HCI);
+ /* The app was registered, find the number of gates and pipes associated to the app */
+
+ for ( yy = 0; yy < NFA_HCI_MAX_GATE_CB; yy++, pg++)
+ {
+ if (pg->gate_owner == nfa_hci_cb.app_in_use)
+ {
+ num_gates++;
+ num_pipes += nfa_hciu_count_pipes_on_gate (pg);
+ }
+ }
+ }
+ else
+ {
+ /* Not registered, look for a free entry */
+ for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++)
+ {
+ if (nfa_hci_cb.cfg.reg_app_names[xx][0] == 0)
+ {
+ memset (&nfa_hci_cb.cfg.reg_app_names[xx][0], 0, sizeof (nfa_hci_cb.cfg.reg_app_names[xx]));
+ BCM_STRNCPY_S (&nfa_hci_cb.cfg.reg_app_names[xx][0], sizeof (nfa_hci_cb.cfg.reg_app_names[xx]), p_app_name, NFA_MAX_HCI_APP_NAME_LEN);
+ nfa_hci_cb.nv_write_needed = TRUE;
+ NFA_TRACE_EVENT2 ("nfa_hci_api_register (%s) Allocated: %u", p_app_name, xx);
+ break;
+ }
+ }
+
+ if (xx == NFA_HCI_MAX_APP_CB)
+ {
+ NFA_TRACE_ERROR1 ("nfa_hci_api_register (%s) NO ENTRIES", p_app_name);
+
+ evt_data.hci_register.status = NFA_STATUS_FAILED;
+ p_evt_data->app_info.p_cback (NFA_HCI_REGISTER_EVT, &evt_data);
+ return;
+ }
+ }
+
+ evt_data.hci_register.num_pipes = num_pipes;
+ evt_data.hci_register.num_gates = num_gates;
+ nfa_hci_cb.p_app_cback[xx] = p_cback;
+
+ nfa_hci_cb.cfg.b_send_conn_evts[xx] = p_evt_data->app_info.b_send_conn_evts;
+
+ evt_data.hci_register.hci_handle = (tNFA_HANDLE) (xx | NFA_HANDLE_GROUP_HCI);
+
+ evt_data.hci_register.status = NFA_STATUS_OK;
+
+ /* notify NFA_HCI_REGISTER_EVT to the application */
+ p_evt_data->app_info.p_cback (NFA_HCI_REGISTER_EVT, &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function nfa_hci_api_deregister
+**
+** Description action function to deregister the given application
+**
+** Returns None
+**
+*******************************************************************************/
+void nfa_hci_api_deregister (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+ tNFA_HCI_EVT_DATA evt_data;
+ tNFA_HCI_CBACK *p_cback = NULL;
+ int xx;
+ tNFA_HCI_DYN_PIPE *p_pipe;
+ tNFA_HCI_DYN_GATE *p_gate;
+
+ /* If needed, find the application registration handle */
+ if (p_evt_data != NULL)
+ {
+ for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++)
+ {
+ if ( (nfa_hci_cb.cfg.reg_app_names[xx][0] != 0)
+ && !strncmp (p_evt_data->app_info.app_name, &nfa_hci_cb.cfg.reg_app_names[xx][0], strlen (p_evt_data->app_info.app_name)) )
+ {
+ NFA_TRACE_EVENT2 ("nfa_hci_api_deregister (%s) inx: %u", p_evt_data->app_info.app_name, xx);
+ break;
+ }
+ }
+
+ if (xx == NFA_HCI_MAX_APP_CB)
+ {
+ NFA_TRACE_WARNING1 ("nfa_hci_api_deregister () Unknown app: %s", p_evt_data->app_info.app_name);
+ return;
+ }
+ nfa_hci_cb.app_in_use = (tNFA_HANDLE) (xx | NFA_HANDLE_GROUP_HCI);
+ p_cback = nfa_hci_cb.p_app_cback[xx];
+ }
+ else
+ {
+ nfa_sys_stop_timer (&nfa_hci_cb.timer);
+ /* We are recursing through deleting all the app's pipes and gates */
+ p_cback = nfa_hci_cb.p_app_cback[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK];
+ }
+
+ /* See if any pipe is owned by this app */
+ if (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 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 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 BOOLEAN nfa_hci_api_create_pipe (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+ tNFA_HCI_DYN_GATE *p_gate = nfa_hciu_find_gate_by_gid (p_evt_data->create_pipe.source_gate);
+ tNFA_HCI_EVT_DATA evt_data;
+ BOOLEAN 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, (BT_HDR *) p_evt_data);
+ return FALSE;
+ }
+
+ nfa_hci_cb.local_gate_in_use = p_evt_data->create_pipe.source_gate;
+ nfa_hci_cb.remote_gate_in_use = p_evt_data->create_pipe.dest_gate;
+ nfa_hci_cb.remote_host_in_use = p_evt_data->create_pipe.dest_host;
+ nfa_hci_cb.app_in_use = p_evt_data->create_pipe.hci_handle;
+
+ nfa_hciu_send_create_pipe_cmd (p_evt_data->create_pipe.source_gate, p_evt_data->create_pipe.dest_host, p_evt_data->create_pipe.dest_gate);
+ }
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_hci_api_open_pipe
+**
+** Description action function to open a pipe
+**
+** Returns None
+**
+*******************************************************************************/
+static void nfa_hci_api_open_pipe (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+ tNFA_HCI_EVT_DATA evt_data;
+ tNFA_HCI_DYN_PIPE *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->open_pipe.pipe);
+ tNFA_HCI_DYN_GATE *p_gate = NULL;
+
+ if (p_pipe != NULL)
+ p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
+
+ if ( (p_pipe != NULL)
+ &&(p_gate != NULL)
+ &&(nfa_hciu_is_active_host (p_pipe->dest_host))
+ &&(p_gate->gate_owner == p_evt_data->open_pipe.hci_handle))
+ {
+ if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED)
+ {
+ nfa_hciu_send_open_pipe_cmd (p_evt_data->open_pipe.pipe);
+ }
+ else
+ {
+ evt_data.opened.pipe = p_evt_data->open_pipe.pipe;
+ evt_data.opened.status = NFA_STATUS_OK;
+
+ nfa_hciu_send_to_app (NFA_HCI_OPEN_PIPE_EVT, &evt_data, p_evt_data->open_pipe.hci_handle);
+ }
+ }
+ else
+ {
+ evt_data.opened.pipe = p_evt_data->open_pipe.pipe;
+ evt_data.opened.status = NFA_STATUS_FAILED;
+
+ nfa_hciu_send_to_app (NFA_HCI_OPEN_PIPE_EVT, &evt_data, p_evt_data->open_pipe.hci_handle);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_hci_api_get_reg_value
+**
+** Description action function to get the reg value of the specified index
+**
+** Returns TRUE, if the command is processed
+** FALSE, if command is queued for processing later
+**
+*******************************************************************************/
+static BOOLEAN nfa_hci_api_get_reg_value (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+ tNFA_HCI_DYN_PIPE *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->get_registry.pipe);
+ tNFA_HCI_DYN_GATE *p_gate;
+ tNFA_STATUS status = NFA_STATUS_FAILED;
+ tNFA_HCI_EVT_DATA evt_data;
+
+ if (p_pipe != NULL)
+ {
+ p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
+
+ if ((p_gate != NULL) && (nfa_hciu_is_active_host (p_pipe->dest_host)) && (p_gate->gate_owner == p_evt_data->get_registry.hci_handle))
+ {
+ nfa_hci_cb.app_in_use = p_evt_data->get_registry.hci_handle;
+
+ if (nfa_hciu_is_host_reseting (p_pipe->dest_host))
+ {
+ GKI_enqueue (&nfa_hci_cb.hci_host_reset_api_q, (BT_HDR *) p_evt_data);
+ return FALSE;
+ }
+
+ if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED)
+ {
+ NFA_TRACE_WARNING1 ("nfa_hci_api_get_reg_value pipe:%d not open", p_evt_data->get_registry.pipe);
+ }
+ else
+ {
+ if ((status = nfa_hciu_send_get_param_cmd (p_evt_data->get_registry.pipe, p_evt_data->get_registry.reg_inx)) == NFA_STATUS_OK)
+ return TRUE;
+ }
+ }
+ }
+
+ evt_data.cmd_sent.status = status;
+
+ /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
+ nfa_hciu_send_to_app (NFA_HCI_CMD_SENT_EVT, &evt_data, p_evt_data->get_registry.hci_handle);
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_hci_api_set_reg_value
+**
+** Description action function to set the reg value at specified index
+**
+** Returns TRUE, if the command is processed
+** FALSE, if command is queued for processing later
+**
+*******************************************************************************/
+static BOOLEAN nfa_hci_api_set_reg_value (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+ tNFA_HCI_DYN_PIPE *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->set_registry.pipe);
+ tNFA_HCI_DYN_GATE *p_gate;
+ tNFA_STATUS status = NFA_STATUS_FAILED;
+ tNFA_HCI_EVT_DATA evt_data;
+
+ if (p_pipe != NULL)
+ {
+ p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
+
+ if ((p_gate != NULL) && (nfa_hciu_is_active_host (p_pipe->dest_host)) && (p_gate->gate_owner == p_evt_data->set_registry.hci_handle))
+ {
+ nfa_hci_cb.app_in_use = p_evt_data->set_registry.hci_handle;
+
+ if (nfa_hciu_is_host_reseting (p_pipe->dest_host))
+ {
+ GKI_enqueue (&nfa_hci_cb.hci_host_reset_api_q, (BT_HDR *) p_evt_data);
+ return FALSE;
+ }
+
+ if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED)
+ {
+ NFA_TRACE_WARNING1 ("nfa_hci_api_set_reg_value pipe:%d not open", p_evt_data->set_registry.pipe);
+ }
+ else
+ {
+ if ((status = nfa_hciu_send_set_param_cmd (p_evt_data->set_registry.pipe, p_evt_data->set_registry.reg_inx, p_evt_data->set_registry.size, p_evt_data->set_registry.data)) == NFA_STATUS_OK)
+ return TRUE;
+ }
+ }
+ }
+ evt_data.cmd_sent.status = status;
+
+ /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
+ nfa_hciu_send_to_app (NFA_HCI_CMD_SENT_EVT, &evt_data, p_evt_data->set_registry.hci_handle);
+ return TRUE;
+
+}
+
+/*******************************************************************************
+**
+** Function nfa_hci_api_close_pipe
+**
+** Description action function to close a pipe
+**
+** Returns None
+**
+*******************************************************************************/
+static void nfa_hci_api_close_pipe (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+ tNFA_HCI_EVT_DATA evt_data;
+ tNFA_HCI_DYN_PIPE *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->close_pipe.pipe);
+ tNFA_HCI_DYN_GATE *p_gate = NULL;
+
+ if (p_pipe != NULL)
+ p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
+
+ if ( (p_pipe != NULL)
+ &&(p_gate != NULL)
+ &&(nfa_hciu_is_active_host (p_pipe->dest_host))
+ &&(p_gate->gate_owner == p_evt_data->close_pipe.hci_handle) )
+ {
+ if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED)
+ {
+ nfa_hciu_send_close_pipe_cmd (p_evt_data->close_pipe.pipe);
+ }
+ else
+ {
+ evt_data.closed.status = NFA_STATUS_OK;
+ evt_data.closed.pipe = p_evt_data->close_pipe.pipe;
+
+ nfa_hciu_send_to_app (NFA_HCI_CLOSE_PIPE_EVT, &evt_data, p_evt_data->close_pipe.hci_handle);
+ }
+ }
+ else
+ {
+ evt_data.closed.status = NFA_STATUS_FAILED;
+ evt_data.closed.pipe = 0x00;
+
+ nfa_hciu_send_to_app (NFA_HCI_CLOSE_PIPE_EVT, &evt_data, p_evt_data->close_pipe.hci_handle);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_hci_api_delete_pipe
+**
+** Description action function to delete a pipe
+**
+** Returns None
+**
+*******************************************************************************/
+static void nfa_hci_api_delete_pipe (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+ tNFA_HCI_EVT_DATA evt_data;
+ tNFA_HCI_DYN_PIPE *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->delete_pipe.pipe);
+ tNFA_HCI_DYN_GATE *p_gate = NULL;
+
+ if (p_pipe != NULL)
+ {
+ p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
+ if ( (p_gate != NULL)
+ &&(p_gate->gate_owner == p_evt_data->delete_pipe.hci_handle)
+ &&(nfa_hciu_is_active_host (p_pipe->dest_host)) )
+ {
+ nfa_hciu_send_delete_pipe_cmd (p_evt_data->delete_pipe.pipe);
+ return;
+ }
+ }
+
+ evt_data.deleted.status = NFA_STATUS_FAILED;
+ evt_data.deleted.pipe = 0x00;
+ nfa_hciu_send_to_app (NFA_HCI_DELETE_PIPE_EVT, &evt_data, p_evt_data->close_pipe.hci_handle);
+}
+
+/*******************************************************************************
+**
+** Function nfa_hci_api_send_cmd
+**
+** Description action function to send command on the given pipe
+**
+** Returns TRUE, if the command is processed
+** FALSE, if command is queued for processing later
+**
+*******************************************************************************/
+static BOOLEAN nfa_hci_api_send_cmd (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+ tNFA_STATUS status = NFA_STATUS_FAILED;
+ tNFA_HCI_DYN_PIPE *p_pipe;
+ tNFA_HCI_EVT_DATA evt_data;
+ tNFA_HANDLE app_handle;
+
+ if ((p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->send_cmd.pipe)) != NULL)
+ {
+ app_handle = nfa_hciu_get_pipe_owner (p_evt_data->send_cmd.pipe);
+
+ if ( (nfa_hciu_is_active_host (p_pipe->dest_host))
+ &&((app_handle == p_evt_data->send_cmd.hci_handle || 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, (BT_HDR *) p_evt_data);
+ return FALSE;
+ }
+
+ if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED)
+ {
+ nfa_hci_cb.pipe_in_use = p_evt_data->send_cmd.pipe;
+ if ((status = nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_COMMAND_TYPE, p_evt_data->send_cmd.cmd_code,
+ p_evt_data->send_cmd.cmd_len, p_evt_data->send_cmd.data)) == NFA_STATUS_OK)
+ return TRUE;
+ }
+ else
+ {
+ NFA_TRACE_WARNING1 ("nfa_hci_api_send_cmd pipe:%d not open", p_pipe->pipe_id);
+ }
+ }
+ else
+ {
+ NFA_TRACE_WARNING1 ("nfa_hci_api_send_cmd pipe:%d Owned by different application or Destination host is not active",
+ p_pipe->pipe_id);
+ }
+ }
+ else
+ {
+ NFA_TRACE_WARNING1 ("nfa_hci_api_send_cmd pipe:%d not found", p_evt_data->send_cmd.pipe);
+ }
+
+ evt_data.cmd_sent.status = status;
+
+ /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
+ nfa_hciu_send_to_app (NFA_HCI_CMD_SENT_EVT, &evt_data, p_evt_data->send_cmd.hci_handle);
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_hci_api_send_rsp
+**
+** Description action function to send response on the given pipe
+**
+** Returns None
+**
+*******************************************************************************/
+static void nfa_hci_api_send_rsp (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+ tNFA_STATUS status = NFA_STATUS_FAILED;
+ tNFA_HCI_DYN_PIPE *p_pipe;
+ tNFA_HCI_EVT_DATA evt_data;
+ tNFA_HANDLE app_handle;
+
+ if ((p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->send_rsp.pipe)) != NULL)
+ {
+ app_handle = nfa_hciu_get_pipe_owner (p_evt_data->send_rsp.pipe);
+
+ if ( (nfa_hciu_is_active_host (p_pipe->dest_host))
+ &&((app_handle == p_evt_data->send_rsp.hci_handle || p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE)) )
+ {
+ if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED)
+ {
+ if ((status = nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, p_evt_data->send_rsp.response,
+ p_evt_data->send_rsp.size, p_evt_data->send_rsp.data)) == NFA_STATUS_OK)
+ return;
+ }
+ else
+ {
+ NFA_TRACE_WARNING1 ("nfa_hci_api_send_rsp pipe:%d not open", p_pipe->pipe_id);
+ }
+ }
+ else
+ {
+ NFA_TRACE_WARNING1 ("nfa_hci_api_send_rsp pipe:%d Owned by different application or Destination host is not active",
+ p_pipe->pipe_id);
+ }
+ }
+ else
+ {
+ NFA_TRACE_WARNING1 ("nfa_hci_api_send_rsp pipe:%d not found", p_evt_data->send_rsp.pipe);
+ }
+
+ evt_data.rsp_sent.status = status;
+
+ /* Send NFA_HCI_RSP_SENT_EVT to notify failure */
+ nfa_hciu_send_to_app (NFA_HCI_RSP_SENT_EVT, &evt_data, p_evt_data->send_rsp.hci_handle);
+}
+
+/*******************************************************************************
+**
+** Function nfa_hci_api_send_event
+**
+** Description action function to send an event to the given pipe
+**
+** Returns TRUE, if the event is processed
+** FALSE, if event is queued for processing later
+**
+*******************************************************************************/
+static BOOLEAN nfa_hci_api_send_event (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+ tNFA_STATUS status = NFA_STATUS_FAILED;
+ tNFA_HCI_DYN_PIPE *p_pipe;
+ tNFA_HCI_EVT_DATA evt_data;
+ tNFA_HANDLE app_handle;
+
+ if ((p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->send_evt.pipe)) != NULL)
+ {
+ app_handle = nfa_hciu_get_pipe_owner (p_evt_data->send_evt.pipe);
+
+ if ( (nfa_hciu_is_active_host (p_pipe->dest_host))
+ &&((app_handle == p_evt_data->send_evt.hci_handle || 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, (BT_HDR *) p_evt_data);
+ return FALSE;
+ }
+
+ if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED)
+ {
+ status = nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_EVENT_TYPE, p_evt_data->send_evt.evt_code,
+ p_evt_data->send_evt.evt_len, p_evt_data->send_evt.p_evt_buf);
+
+ if (status == NFA_STATUS_OK)
+ {
+ if (p_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;
+
+ 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 */
+ if ((pg = nfa_hciu_alloc_gate (p_evt_data->add_static_pipe.gate, p_evt_data->add_static_pipe.hci_handle)) != NULL)
+ {
+ /* Assign new owner to the gate */
+ pg->gate_owner = p_evt_data->add_static_pipe.hci_handle;
+
+ /* Add the dynamic pipe to the proprietary gate */
+ if (nfa_hciu_add_pipe_to_gate (p_evt_data->add_static_pipe.pipe,pg->gate_id, p_evt_data->add_static_pipe.host, p_evt_data->add_static_pipe.gate) != NFA_HCI_ANY_OK)
+ {
+ /* Unable to add the dynamic pipe, so release the gate */
+ nfa_hciu_release_gate (pg->gate_id);
+ evt_data.pipe_added.status = NFA_STATUS_FAILED;
+ nfa_hciu_send_to_app (NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data, p_evt_data->add_static_pipe.hci_handle);
+ return;
+ }
+ if ((pp = nfa_hciu_find_pipe_by_pid (p_evt_data->add_static_pipe.pipe)) != NULL)
+ {
+ /* This pipe is always opened */
+ pp->pipe_state = NFA_HCI_PIPE_OPENED;
+ evt_data.pipe_added.status = NFA_STATUS_OK;
+ nfa_hciu_send_to_app (NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data, p_evt_data->add_static_pipe.hci_handle);
+ return;
+ }
+ }
+ /* Unable to add static pipe */
+ evt_data.pipe_added.status = NFA_STATUS_FAILED;
+ nfa_hciu_send_to_app (NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data, p_evt_data->add_static_pipe.hci_handle);
+
+}
+
+/*******************************************************************************
+**
+** Function nfa_hci_handle_link_mgm_gate_cmd
+**
+** Description This function handles incoming link management gate hci
+** commands
+**
+** Returns none
+**
+*******************************************************************************/
+void nfa_hci_handle_link_mgm_gate_cmd (UINT8 *p_data)
+{
+ UINT8 index;
+ UINT8 data[2];
+ UINT8 rsp_len = 0;
+ UINT8 response = NFA_HCI_ANY_OK;
+
+ if ( (nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state != NFA_HCI_PIPE_OPENED)
+ &&(nfa_hci_cb.inst != NFA_HCI_ANY_OPEN_PIPE) )
+ {
+ nfa_hciu_send_msg (NFA_HCI_LINK_MANAGEMENT_PIPE, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_PIPE_NOT_OPENED, 0, NULL);
+ return;
+ }
+
+ switch (nfa_hci_cb.inst)
+ {
+ case NFA_HCI_ANY_SET_PARAMETER:
+ STREAM_TO_UINT8 (index, p_data);
+
+ if (index == 1)
+ {
+ STREAM_TO_UINT16 (nfa_hci_cb.cfg.link_mgmt_gate.rec_errors, p_data);
+ }
+ else
+ response = NFA_HCI_ANY_E_REG_PAR_UNKNOWN;
+ break;
+
+ case NFA_HCI_ANY_GET_PARAMETER:
+ STREAM_TO_UINT8 (index, p_data);
+ if (index == 1)
+ {
+ data[0] = (UINT8) ((nfa_hci_cb.cfg.link_mgmt_gate.rec_errors >> 8) & 0x00FF);
+ data[1] = (UINT8) (nfa_hci_cb.cfg.link_mgmt_gate.rec_errors & 0x000F);
+ rsp_len = 2;
+ }
+ else
+ response = NFA_HCI_ANY_E_REG_PAR_UNKNOWN;
+ break;
+
+ case NFA_HCI_ANY_OPEN_PIPE:
+ data[0] = 0;
+ rsp_len = 1;
+ nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_OPENED;
+ break;
+
+ case NFA_HCI_ANY_CLOSE_PIPE:
+ nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
+ break;
+
+ default:
+ response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
+ break;
+ }
+
+ nfa_hciu_send_msg (NFA_HCI_LINK_MANAGEMENT_PIPE, NFA_HCI_RESPONSE_TYPE, response, rsp_len, data);
+}
+
+
+
+/*******************************************************************************
+**
+** Function nfa_hci_handle_pipe_open_close_cmd
+**
+** Description This function handles all generic gates (excluding
+** connectivity gate) commands
+**
+** Returns none
+**
+*******************************************************************************/
+void nfa_hci_handle_pipe_open_close_cmd (tNFA_HCI_DYN_PIPE *p_pipe)
+{
+ UINT8 data[1];
+ UINT8 rsp_len = 0;
+ tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
+ tNFA_HCI_DYN_GATE *p_gate;
+
+ if (nfa_hci_cb.inst == NFA_HCI_ANY_OPEN_PIPE)
+ {
+ if ((p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate)) != NULL)
+ data[0] = nfa_hciu_count_open_pipes_on_gate (p_gate);
+ else
+ data[0] = 0;
+
+ p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
+ rsp_len = 1;
+ }
+ else if (nfa_hci_cb.inst == NFA_HCI_ANY_CLOSE_PIPE)
+ {
+ p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
+ }
+
+ nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len, data);
+}
+
+/*******************************************************************************
+**
+** Function nfa_hci_handle_admin_gate_cmd
+**
+** Description This function handles incoming commands on ADMIN gate
+**
+** Returns none
+**
+*******************************************************************************/
+void nfa_hci_handle_admin_gate_cmd (UINT8 *p_data)
+{
+ UINT8 source_host, source_gate, dest_host, dest_gate, pipe;
+ UINT8 data = 0;
+ UINT8 rsp_len = 0;
+ tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
+ tNFA_HCI_DYN_GATE *pgate;
+ tNFA_HCI_EVT_DATA evt_data;
+
+ switch (nfa_hci_cb.inst)
+ {
+ case NFA_HCI_ANY_OPEN_PIPE:
+ nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_OPENED;
+ data = 0;
+ rsp_len = 1;
+ break;
+
+ case NFA_HCI_ANY_CLOSE_PIPE:
+ nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
+ /* Reopen the pipe immediately */
+ nfa_hciu_send_msg (NFA_HCI_ADMIN_PIPE, NFA_HCI_RESPONSE_TYPE, response, rsp_len, &data);
+ nfa_hci_cb.app_in_use = NFA_HANDLE_INVALID;
+ nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE);
+ return;
+ break;
+
+ case NFA_HCI_ADM_NOTIFY_PIPE_CREATED:
+ STREAM_TO_UINT8 (source_host, p_data);
+ STREAM_TO_UINT8 (source_gate, p_data);
+ STREAM_TO_UINT8 (dest_host, p_data);
+ STREAM_TO_UINT8 (dest_gate, p_data);
+ STREAM_TO_UINT8 (pipe, p_data);
+
+ if ( (dest_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE)
+ ||(dest_gate == NFA_HCI_LOOP_BACK_GATE)
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#ifdef GEMALTO_SE_SUPPORT
+ ||(dest_gate == NFC_HCI_DEFAULT_DEST_GATE)
+ ||(dest_gate == NFA_HCI_CONNECTIVITY_GATE)
+#endif
+#endif
+ )
+ {
+ response = nfa_hciu_add_pipe_to_static_gate (dest_gate, pipe, source_host, source_gate);
+ }
+ else
+ {
+ if ((pgate = nfa_hciu_find_gate_by_gid (dest_gate)) != NULL)
+ {
+ /* If the gate is valid, add the pipe to it */
+ if (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 if ((response = nfa_hciu_add_pipe_to_gate (pipe, dest_gate, source_host, source_gate)) == NFA_HCI_ANY_OK)
+ {
+ /* Tell the application a pipe was created with its gate */
+
+ evt_data.created.status = NFA_STATUS_OK;
+ evt_data.created.pipe = pipe;
+ evt_data.created.source_gate = dest_gate;
+ evt_data.created.dest_host = source_host;
+ evt_data.created.dest_gate = source_gate;
+
+ nfa_hciu_send_to_app (NFA_HCI_CREATE_PIPE_EVT, &evt_data, pgate->gate_owner);
+ }
+ }
+ else
+ {
+ response = NFA_HCI_ANY_E_NOK;
+ 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;
+ }
+ }
+ break;
+
+ default:
+ response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
+ break;
+ }
+
+ nfa_hciu_send_msg (NFA_HCI_ADMIN_PIPE, NFA_HCI_RESPONSE_TYPE, response, rsp_len, &data);
+}
+
+/*******************************************************************************
+**
+** Function nfa_hci_handle_admin_gate_rsp
+**
+** Description This function handles response received on admin gate
+**
+** Returns none
+**
+*******************************************************************************/
+void nfa_hci_handle_admin_gate_rsp (UINT8 *p_data, UINT8 data_len)
+{
+ UINT8 source_host;
+ UINT8 source_gate = nfa_hci_cb.local_gate_in_use;
+ UINT8 dest_host = nfa_hci_cb.remote_host_in_use;
+ UINT8 dest_gate = nfa_hci_cb.remote_gate_in_use;
+ UINT8 pipe = 0;
+ tNFA_STATUS status;
+ tNFA_HCI_EVT_DATA evt_data;
+ UINT8 default_session[NFA_HCI_SESSION_ID_LEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+ UINT8 host_count = 0;
+ UINT8 host_id = 0;
+ UINT32 os_tick;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ NFA_TRACE_DEBUG4 ("nfa_hci_handle_admin_gate_rsp - LastCmdSent: %s App: 0x%04x Gate: 0x%02x Pipe: 0x%02x",
+ nfa_hciu_instr_2_str(nfa_hci_cb.cmd_sent), nfa_hci_cb.app_in_use, nfa_hci_cb.local_gate_in_use, nfa_hci_cb.pipe_in_use);
+#else
+ NFA_TRACE_DEBUG4 ("nfa_hci_handle_admin_gate_rsp LastCmdSent: %u App: 0x%04x Gate: 0x%02x Pipe: 0x%02x",
+ nfa_hci_cb.cmd_sent, nfa_hci_cb.app_in_use, nfa_hci_cb.local_gate_in_use, nfa_hci_cb.pipe_in_use);
+#endif
+
+ /* If 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)
+ {
+ NFA_TRACE_ERROR0 ("nfa_hci_handle_admin_gate_rsp - Initialization failed");
+ nfa_hci_startup_complete (NFA_STATUS_FAILED);
+ return;
+ }
+
+ switch (nfa_hci_cb.cmd_sent)
+ {
+ case NFA_HCI_ANY_SET_PARAMETER:
+#if(NFC_NXP_NOT_OPEN_INCLUDED != 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)
+ {
+ if (nfa_hci_cb.b_hci_netwk_reset)
+ {
+ nfa_hci_cb.b_hci_netwk_reset = FALSE;
+ /* Session ID is reset, Set New session id */
+ memcpy (&nfa_hci_cb.cfg.admin_gate.session_id[NFA_HCI_SESSION_ID_LEN / 2], nfa_hci_cb.cfg.admin_gate.session_id, (NFA_HCI_SESSION_ID_LEN / 2));
+ os_tick = GKI_get_os_tick_count ();
+ memcpy (nfa_hci_cb.cfg.admin_gate.session_id, (UINT8 *)&os_tick, (NFA_HCI_SESSION_ID_LEN / 2));
+ nfa_hciu_send_set_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX, NFA_HCI_SESSION_ID_LEN, (UINT8 *) nfa_hci_cb.cfg.admin_gate.session_id);
+ }
+ else
+ {
+ /* First thing is to get the session ID */
+ nfa_hciu_send_get_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX);
+ }
+ }
+ 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) )
+ 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) *p_data++;
+
+ if ( (host_id >= NFA_HCI_HOST_ID_UICC0)
+ &&(host_id < NFA_HCI_HOST_ID_UICC0 + NFA_HCI_MAX_HOST_IN_NETWORK) )
+ {
+ nfa_hci_cb.inactive_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00;
+ nfa_hci_cb.reset_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00;
+ }
+
+ host_count++;
+ }
+ nfa_hci_startup_complete (NFA_STATUS_OK);
+ }
+ else if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX)
+ {
+ /* The only parameter we get when initializing is the session ID. Check for match. */
+ if (!memcmp ((UINT8 *) nfa_hci_cb.cfg.admin_gate.session_id, p_data, NFA_HCI_SESSION_ID_LEN) )
+ {
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ nfa_hci_network_enable();
+ 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
+ /* 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(NFC_NXP_NOT_OPEN_INCLUDED == 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 *)&os_tick, (NFA_HCI_SESSION_ID_LEN / 2));
+ nfa_hciu_send_set_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX, NFA_HCI_SESSION_ID_LEN, (UINT8 *) nfa_hci_cb.cfg.admin_gate.session_id);
+#else
+ /* 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(NFC_NXP_NOT_OPEN_INCLUDED != 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 *)&os_tick, (NFA_HCI_SESSION_ID_LEN / 2));
+ nfa_hciu_send_set_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX, NFA_HCI_SESSION_ID_LEN, (UINT8 *) nfa_hci_cb.cfg.admin_gate.session_id);
+ }
+ else
+ {
+ /* First thing is to get the session ID */
+ nfa_hciu_send_get_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX);
+ }
+#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;
+ }
+ }
+ else
+ {
+ status = (nfa_hci_cb.inst == NFA_HCI_ANY_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED;
+
+ switch (nfa_hci_cb.cmd_sent)
+ {
+ case NFA_HCI_ANY_SET_PARAMETER:
+ if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
+ nfa_hci_api_deregister (NULL);
+ else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
+ nfa_hci_api_dealloc_gate (NULL);
+ break;
+
+ case NFA_HCI_ANY_GET_PARAMETER:
+ if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX)
+ {
+ if (!memcmp ((UINT8 *) default_session, p_data , NFA_HCI_SESSION_ID_LEN))
+ {
+ memcpy (&nfa_hci_cb.cfg.admin_gate.session_id[(NFA_HCI_SESSION_ID_LEN / 2)], nfa_hci_cb.cfg.admin_gate.session_id, (NFA_HCI_SESSION_ID_LEN / 2));
+ os_tick = GKI_get_os_tick_count ();
+ memcpy (nfa_hci_cb.cfg.admin_gate.session_id, (UINT8 *) &os_tick, (NFA_HCI_SESSION_ID_LEN / 2));
+ nfa_hci_cb.nv_write_needed = TRUE;
+ nfa_hciu_send_set_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX, NFA_HCI_SESSION_ID_LEN, (UINT8 *) nfa_hci_cb.cfg.admin_gate.session_id);
+ }
+ else
+ {
+ if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
+ nfa_hci_api_deregister (NULL);
+ else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
+ nfa_hci_api_dealloc_gate (NULL);
+ }
+ }
+ else if (nfa_hci_cb.param_in_use == NFA_HCI_HOST_LIST_INDEX)
+ {
+ evt_data.hosts.status = status;
+ evt_data.hosts.num_hosts = data_len;
+ memcpy (evt_data.hosts.host, p_data, data_len);
+
+ host_count = 0;
+ while (host_count < NFA_HCI_MAX_HOST_IN_NETWORK)
+ {
+ nfa_hci_cb.inactive_host[host_count] = NFA_HCI_HOST_ID_UICC0 + host_count;
+ host_count++;
+ }
+
+ host_count = 0;
+ /* Collect active host in the Host Network */
+ while (host_count < data_len)
+ {
+ host_id = (UINT8) *p_data++;
+
+ if ( (host_id >= NFA_HCI_HOST_ID_UICC0)
+ &&(host_id < NFA_HCI_HOST_ID_UICC0 + NFA_HCI_MAX_HOST_IN_NETWORK) )
+ {
+ nfa_hci_cb.inactive_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00;
+ nfa_hci_cb.reset_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00;
+ }
+ host_count++;
+ }
+ if (nfa_hciu_is_no_host_resetting ())
+ nfa_hci_check_pending_api_requests ();
+ nfa_hciu_send_to_app (NFA_HCI_HOST_LIST_EVT, &evt_data, nfa_hci_cb.app_in_use);
+ }
+ break;
+
+ case NFA_HCI_ADM_CREATE_PIPE:
+ if (status == NFA_STATUS_OK)
+ {
+ STREAM_TO_UINT8 (source_host, p_data);
+ STREAM_TO_UINT8 (source_gate, p_data);
+ STREAM_TO_UINT8 (dest_host, p_data);
+ STREAM_TO_UINT8 (dest_gate, p_data);
+ STREAM_TO_UINT8 (pipe, p_data);
+
+ /* Sanity check */
+ if (source_gate != nfa_hci_cb.local_gate_in_use)
+ {
+ NFA_TRACE_WARNING2 ("nfa_hci_handle_admin_gate_rsp sent create pipe with gate: %u got back: %u",
+ nfa_hci_cb.local_gate_in_use, source_gate);
+ break;
+ }
+
+ nfa_hciu_add_pipe_to_gate (pipe, source_gate, dest_host, dest_gate);
+
+ }
+
+ /* Tell the application his pipe was created or not */
+ evt_data.created.status = status;
+ evt_data.created.pipe = pipe;
+ evt_data.created.source_gate = source_gate;
+ evt_data.created.dest_host = dest_host;
+ evt_data.created.dest_gate = dest_gate;
+
+ nfa_hciu_send_to_app (NFA_HCI_CREATE_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use);
+ break;
+
+ case NFA_HCI_ADM_DELETE_PIPE:
+ if (status == NFA_STATUS_OK)
+ {
+ nfa_hciu_release_pipe (nfa_hci_cb.pipe_in_use);
+
+ /* If only deleting one pipe, tell the app we are done */
+ if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE)
+ {
+ evt_data.deleted.status = status;
+ evt_data.deleted.pipe = nfa_hci_cb.pipe_in_use;
+
+ nfa_hciu_send_to_app (NFA_HCI_DELETE_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use);
+ }
+ else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
+ nfa_hci_api_deregister (NULL);
+ else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
+ nfa_hci_api_dealloc_gate (NULL);
+ }
+ else
+ {
+ /* If only deleting one pipe, tell the app we are done */
+ if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE)
+ {
+ evt_data.deleted.status = status;
+ evt_data.deleted.pipe = nfa_hci_cb.pipe_in_use;
+
+ nfa_hciu_send_to_app (NFA_HCI_DELETE_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use);
+ }
+ else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
+ {
+ nfa_hciu_release_pipe (nfa_hci_cb.pipe_in_use);
+ nfa_hci_api_deregister (NULL);
+ }
+ else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
+ {
+ nfa_hciu_release_pipe (nfa_hci_cb.pipe_in_use);
+ nfa_hci_api_dealloc_gate (NULL);
+ }
+ }
+ break;
+
+ case NFA_HCI_ANY_OPEN_PIPE:
+ nfa_hci_cb.cfg.admin_gate.pipe01_state = status ? NFA_HCI_PIPE_CLOSED:NFA_HCI_PIPE_OPENED;
+ nfa_hci_cb.nv_write_needed = TRUE;
+ if (nfa_hci_cb.cfg.admin_gate.pipe01_state == NFA_HCI_PIPE_OPENED)
+ {
+ /* First thing is to get the session ID */
+ nfa_hciu_send_get_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX);
+ }
+ break;
+
+ case NFA_HCI_ADM_CLEAR_ALL_PIPE:
+ nfa_hciu_remove_all_pipes_from_host (0);
+ nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
+ nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
+ nfa_hci_cb.nv_write_needed = TRUE;
+ /* Open admin */
+ nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE);
+ break;
+
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_hci_handle_admin_gate_evt
+**
+** Description This function handles events received on admin gate
+**
+** Returns none
+**
+*******************************************************************************/
+void nfa_hci_handle_admin_gate_evt (UINT8 *p_data)
+{
+ tNFA_HCI_EVT_DATA evt_data;
+ tNFA_HCI_API_GET_HOST_LIST *p_msg;
+
+ 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 */
+ if ((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;
+ /* 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 pipe_id, UINT8 *p_data, UINT16 data_len)
+{
+ tNFA_HCI_DYN_PIPE *p_pipe = nfa_hciu_find_pipe_by_pid (pipe_id);
+ tNFA_HCI_DYN_GATE *p_gate;
+
+ if (p_pipe == NULL)
+ {
+ /* Invalid pipe ID */
+ NFA_TRACE_ERROR1 ("nfa_hci_handle_dyn_pipe_pkt - Unknown pipe %d",pipe_id);
+ if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
+ nfa_hciu_send_msg (pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_NOK, 0, NULL);
+ return;
+ }
+
+ if (p_pipe->local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE)
+ {
+ nfa_hci_handle_identity_mgmt_gate_pkt (p_data, p_pipe);
+ }
+ else if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE)
+ {
+ nfa_hci_handle_loopback_gate_pkt (p_data, data_len, p_pipe);
+ }
+ else if (p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE)
+ {
+ nfa_hci_handle_connectivity_gate_pkt (p_data, data_len, p_pipe);
+ }
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#ifdef GEMALTO_SE_SUPPORT
+ else if (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) data_len, p_gate, p_pipe);
+ break;
+
+ case NFA_HCI_RESPONSE_TYPE:
+ nfa_hci_handle_generic_gate_rsp (p_data, (UINT8) data_len, p_gate, p_pipe);
+ break;
+
+ case NFA_HCI_EVENT_TYPE:
+ nfa_hci_handle_generic_gate_evt (p_data, data_len, p_gate, p_pipe);
+ break;
+ }
+ }
+#endif
+#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) data_len, p_gate, p_pipe);
+ break;
+
+ case NFA_HCI_RESPONSE_TYPE:
+ nfa_hci_handle_generic_gate_rsp (p_data, (UINT8) data_len, p_gate, p_pipe);
+ break;
+
+ case NFA_HCI_EVENT_TYPE:
+ nfa_hci_handle_generic_gate_evt (p_data, data_len, p_gate, p_pipe);
+ break;
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_hci_handle_identity_mgmt_gate_pkt
+**
+** Description This function handles incoming Identity Management gate hci
+** commands
+**
+** Returns none
+**
+*******************************************************************************/
+static void nfa_hci_handle_identity_mgmt_gate_pkt (UINT8 *p_data, tNFA_HCI_DYN_PIPE *p_pipe)
+{
+ UINT8 data[20];
+ UINT8 index;
+ UINT8 gate_rsp[3 + NFA_HCI_MAX_GATE_CB], num_gates;
+ UINT16 rsp_len = 0;
+ UINT8 *p_rsp = data;
+ tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
+
+ /* We never send commands on a pipe where the local gate is the identity management
+ * gate, so only commands should be processed.
+ */
+ if (nfa_hci_cb.type != NFA_HCI_COMMAND_TYPE)
+ return;
+
+ switch (nfa_hci_cb.inst)
+ {
+ case NFA_HCI_ANY_GET_PARAMETER:
+ index = *(p_data++);
+ if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED)
+ {
+ switch (index)
+ {
+ case NFA_HCI_VERSION_SW_INDEX:
+ data[0] = (UINT8) ((NFA_HCI_VERSION_SW >> 16 ) & 0xFF);
+ data[1] = (UINT8) ((NFA_HCI_VERSION_SW >> 8 ) & 0xFF);
+ data[2] = (UINT8) ((NFA_HCI_VERSION_SW ) & 0xFF);
+ rsp_len = 3;
+ break;
+
+ case NFA_HCI_HCI_VERSION_INDEX:
+ data[0] = NFA_HCI_VERSION;
+ rsp_len = 1;
+ break;
+
+ case NFA_HCI_VERSION_HW_INDEX:
+ data[0] = (UINT8) ((NFA_HCI_VERSION_HW >> 16 ) & 0xFF);
+ data[1] = (UINT8) ((NFA_HCI_VERSION_HW >> 8 ) & 0xFF);
+ data[2] = (UINT8) ((NFA_HCI_VERSION_HW ) & 0xFF);
+ rsp_len = 3;
+ break;
+
+ case NFA_HCI_VENDOR_NAME_INDEX:
+ memcpy (data,NFA_HCI_VENDOR_NAME,strlen (NFA_HCI_VENDOR_NAME));
+ rsp_len = (UINT8) strlen (NFA_HCI_VENDOR_NAME);
+ break;
+
+ case NFA_HCI_MODEL_ID_INDEX:
+ data[0] = NFA_HCI_MODEL_ID;
+ rsp_len = 1;
+ break;
+
+ case NFA_HCI_GATES_LIST_INDEX:
+ gate_rsp[0] = NFA_HCI_LOOP_BACK_GATE;
+ gate_rsp[1] = NFA_HCI_IDENTITY_MANAGEMENT_GATE;
+ gate_rsp[2] = NFA_HCI_CONNECTIVITY_GATE;
+ num_gates = nfa_hciu_get_allocated_gate_list (&gate_rsp[3]);
+ rsp_len = num_gates + 3;
+ p_rsp = gate_rsp;
+ break;
+
+ default:
+ response = NFA_HCI_ANY_E_NOK;
+ break;
+ }
+ }
+ else
+ {
+ response = NFA_HCI_ANY_E_PIPE_NOT_OPENED;
+ }
+ break;
+
+ case NFA_HCI_ANY_OPEN_PIPE:
+ data[0] = 0;
+ rsp_len = 1;
+ p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
+ break;
+
+ case NFA_HCI_ANY_CLOSE_PIPE:
+ p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
+ break;
+
+ default:
+ response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
+ break;
+ }
+
+ nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len, p_rsp);
+}
+
+/*******************************************************************************
+**
+** Function nfa_hci_handle_generic_gate_cmd
+**
+** Description This function handles all generic gates (excluding
+** connectivity gate) commands
+**
+** Returns none
+**
+*******************************************************************************/
+static void nfa_hci_handle_generic_gate_cmd (UINT8 *p_data, UINT8 data_len, tNFA_HCI_DYN_GATE *p_gate, tNFA_HCI_DYN_PIPE *p_pipe)
+{
+ tNFA_HCI_EVT_DATA evt_data;
+ tNFA_HANDLE app_handle = nfa_hciu_get_pipe_owner (p_pipe->pipe_id);
+
+ switch (nfa_hci_cb.inst)
+ {
+ case NFA_HCI_ANY_SET_PARAMETER:
+ evt_data.registry.pipe = p_pipe->pipe_id;
+ evt_data.registry.index = *p_data++;
+ if (data_len > 0)
+ data_len--;
+ evt_data.registry.data_len = data_len;
+
+ memcpy (evt_data.registry.reg_data, p_data, data_len);
+
+ nfa_hciu_send_to_app (NFA_HCI_SET_REG_CMD_EVT, &evt_data, app_handle);
+ break;
+
+ case NFA_HCI_ANY_GET_PARAMETER:
+ evt_data.registry.pipe = p_pipe->pipe_id;
+ evt_data.registry.index = *p_data;
+ evt_data.registry.data_len = 0;
+
+ nfa_hciu_send_to_app (NFA_HCI_GET_REG_CMD_EVT, &evt_data, app_handle);
+ break;
+
+ case NFA_HCI_ANY_OPEN_PIPE:
+ nfa_hci_handle_pipe_open_close_cmd (p_pipe);
+
+ evt_data.opened.pipe = p_pipe->pipe_id;
+ evt_data.opened.status = NFA_STATUS_OK;
+
+ nfa_hciu_send_to_app (NFA_HCI_OPEN_PIPE_EVT, &evt_data, app_handle);
+ break;
+
+ case NFA_HCI_ANY_CLOSE_PIPE:
+ nfa_hci_handle_pipe_open_close_cmd (p_pipe);
+
+ evt_data.closed.pipe = p_pipe->pipe_id;
+ evt_data.opened.status = NFA_STATUS_OK;
+
+ nfa_hciu_send_to_app (NFA_HCI_CLOSE_PIPE_EVT, &evt_data, app_handle);
+ break;
+
+ default:
+ /* Could be application specific command, pass it on */
+ evt_data.cmd_rcvd.status = NFA_STATUS_OK;
+ evt_data.cmd_rcvd.pipe = p_pipe->pipe_id;;
+ evt_data.cmd_rcvd.cmd_code = nfa_hci_cb.inst;
+ evt_data.cmd_rcvd.cmd_len = data_len;
+
+ if (data_len <= NFA_MAX_HCI_CMD_LEN)
+ memcpy (evt_data.cmd_rcvd.cmd_data, p_data, data_len);
+
+ nfa_hciu_send_to_app (NFA_HCI_CMD_RCVD_EVT, &evt_data, app_handle);
+ break;
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_hci_handle_generic_gate_rsp
+**
+** Description This function handles all generic gates (excluding
+** connectivity) response
+**
+** Returns none
+**
+*******************************************************************************/
+static void nfa_hci_handle_generic_gate_rsp (UINT8 *p_data, UINT8 data_len, tNFA_HCI_DYN_GATE *p_gate, tNFA_HCI_DYN_PIPE *p_pipe)
+{
+ tNFA_HCI_EVT_DATA evt_data;
+ tNFA_STATUS status = NFA_STATUS_OK;
+
+ if (nfa_hci_cb.inst != NFA_HCI_ANY_OK)
+ status = NFA_STATUS_FAILED;
+
+ if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE)
+ {
+ if (status == NFA_STATUS_OK)
+ p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
+
+ nfa_hci_cb.nv_write_needed = TRUE;
+ /* Tell application */
+ evt_data.opened.status = status;
+ evt_data.opened.pipe = p_pipe->pipe_id;
+
+ nfa_hciu_send_to_app (NFA_HCI_OPEN_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use);
+ }
+ else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE)
+ {
+ p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
+
+ nfa_hci_cb.nv_write_needed = TRUE;
+ /* Tell application */
+ evt_data.opened.status = status;;
+ evt_data.opened.pipe = p_pipe->pipe_id;
+
+ nfa_hciu_send_to_app (NFA_HCI_CLOSE_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use);
+ }
+ else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_GET_PARAMETER)
+ {
+ /* Tell application */
+ evt_data.registry.status = status;
+ evt_data.registry.pipe = p_pipe->pipe_id;
+ evt_data.registry.data_len = data_len;
+ evt_data.registry.index = nfa_hci_cb.param_in_use;
+
+ memcpy (evt_data.registry.reg_data, p_data, data_len);
+
+ nfa_hciu_send_to_app (NFA_HCI_GET_REG_RSP_EVT, &evt_data, nfa_hci_cb.app_in_use);
+ }
+ else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_SET_PARAMETER)
+ {
+ /* Tell application */
+ evt_data.registry.status = status;;
+ evt_data.registry.pipe = p_pipe->pipe_id;
+
+ nfa_hciu_send_to_app (NFA_HCI_SET_REG_RSP_EVT, &evt_data, nfa_hci_cb.app_in_use);
+ }
+ else
+ {
+ /* Could be a response to application specific command sent, pass it on */
+ evt_data.rsp_rcvd.status = NFA_STATUS_OK;
+ evt_data.rsp_rcvd.pipe = p_pipe->pipe_id;;
+ evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
+ evt_data.rsp_rcvd.rsp_len = data_len;
+
+ if (data_len <= NFA_MAX_HCI_RSP_LEN)
+ memcpy (evt_data.rsp_rcvd.rsp_data, p_data, data_len);
+
+ nfa_hciu_send_to_app (NFA_HCI_RSP_RCVD_EVT, &evt_data, nfa_hci_cb.app_in_use);
+ }
+
+}
+
+/*******************************************************************************
+**
+** Function nfa_hci_handle_connectivity_gate_pkt
+**
+** Description This function handles incoming connectivity gate packets
+**
+** Returns none
+**
+*******************************************************************************/
+static void nfa_hci_handle_connectivity_gate_pkt (UINT8 *p_data, UINT16 data_len, tNFA_HCI_DYN_PIPE *p_pipe)
+{
+ tNFA_HCI_EVT_DATA evt_data;
+
+ if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
+ {
+ switch (nfa_hci_cb.inst)
+ {
+ case NFA_HCI_ANY_OPEN_PIPE:
+ case NFA_HCI_ANY_CLOSE_PIPE:
+ nfa_hci_handle_pipe_open_close_cmd (p_pipe);
+ break;
+
+ case NFA_HCI_CON_PRO_HOST_REQUEST:
+ /* A request to the DH to activate another host. This is not supported for */
+ /* now, we will implement it when the spec is clearer and UICCs need it. */
+ nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_CMD_NOT_SUPPORTED, 0, NULL);
+ break;
+
+ default:
+ nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_CMD_NOT_SUPPORTED, 0, NULL);
+ break;
+ }
+ }
+ else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE)
+ {
+ if ((nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) && (nfa_hci_cb.inst == NFA_HCI_ANY_OK))
+ p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
+ else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE)
+ p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
+
+ /* 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 *p_data, UINT16 data_len, tNFA_HCI_DYN_PIPE *p_pipe)
+{
+ UINT8 data[1];
+ UINT8 rsp_len = 0;
+ tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
+ 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 *p_data, UINT16 data_len, tNFA_HCI_DYN_GATE *p_gate, tNFA_HCI_DYN_PIPE *p_pipe)
+{
+ tNFA_HCI_EVT_DATA evt_data;
+
+ evt_data.rcvd_evt.pipe = p_pipe->pipe_id;
+ evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
+ evt_data.rcvd_evt.evt_len = data_len;
+
+ if (nfa_hci_cb.assembly_failed)
+ evt_data.rcvd_evt.status = NFA_STATUS_BUFFER_FULL;
+ else
+ evt_data.rcvd_evt.status = NFA_STATUS_OK;
+
+ evt_data.rcvd_evt.p_evt_buf = p_data;
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ }
+#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);
+}
diff --git a/src/nfa/hci/nfa_hci_api.c b/src/nfa/hci/nfa_hci_api.c
new file mode 100644
index 0000000..335fb39
--- /dev/null
+++ b/src/nfa/hci/nfa_hci_api.c
@@ -0,0 +1,1066 @@
+/******************************************************************************
+ *
+ * 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 HCI
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_api.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "nfa_hci_api.h"
+#include "nfa_hci_int.h"
+#include "nfa_hci_defs.h"
+
+/*******************************************************************************
+**
+** Function NFA_HciRegister
+**
+** Description This function will register an application with hci and
+** returns an application handle and provides a mechanism to
+** register a callback with HCI to receive NFA HCI event notification.
+** When the application is registered (or if an error occurs),
+** the app will be notified with NFA_HCI_REGISTER_EVT. Previous
+** session information including allocated gates, created pipes
+** and pipes states will be returned as part of tNFA_HCI_REGISTER data.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciRegister (char *p_app_name, tNFA_HCI_CBACK *p_cback, BOOLEAN b_send_conn_evts)
+{
+ tNFA_HCI_API_REGISTER_APP *p_msg;
+ UINT8 app_name_len;
+
+ if (p_app_name == NULL)
+ {
+ NFA_TRACE_API0 ("NFA_HciRegister (): Invalid Application name");
+ return (NFA_STATUS_FAILED);
+ }
+
+ if (p_cback == NULL)
+ {
+ NFA_TRACE_API0 ("NFA_HciRegister (): Application should provide callback function to register!");
+ return (NFA_STATUS_FAILED);
+ }
+
+ NFA_TRACE_API1 ("NFA_HciRegister (): Application Name: %s", p_app_name);
+
+ app_name_len = (UINT8) strlen (p_app_name);
+
+ /* Register the application with HCI */
+ if ( (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
+ &&(p_app_name != NULL)
+ &&(app_name_len <= NFA_MAX_HCI_APP_NAME_LEN)
+ &&((p_msg = (tNFA_HCI_API_REGISTER_APP *) GKI_getbuf (sizeof (tNFA_HCI_API_REGISTER_APP))) != NULL))
+ {
+ p_msg->hdr.event = NFA_HCI_API_REGISTER_APP_EVT;
+
+ /* Save application name and callback */
+ memset (p_msg->app_name, 0, sizeof (p_msg->app_name));
+ BCM_STRNCPY_S (p_msg->app_name, sizeof (p_msg->app_name), p_app_name, NFA_MAX_HCI_APP_NAME_LEN);
+ p_msg->p_cback = p_cback;
+ p_msg->b_send_conn_evts = b_send_conn_evts;
+
+ nfa_sys_sendmsg (p_msg);
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_HciGetGateAndPipeList
+**
+** Description This function will get the list of gates allocated to the
+** application and list of dynamic pipes created by the
+** application. The app will be notified with
+** NFA_HCI_GET_GATE_PIPE_LIST_EVT. List of allocated dynamic
+** gates to the application and list of pipes created by the
+** application will be returned as part of
+** tNFA_HCI_GET_GATE_PIPE_LIST data.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciGetGateAndPipeList (tNFA_HANDLE hci_handle)
+{
+ tNFA_HCI_API_GET_APP_GATE_PIPE *p_msg;
+
+ if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
+ {
+ NFA_TRACE_API1 ("NFA_HciGetGateAndPipeList (): Invalid hci_handle:0x%04x", hci_handle);
+ return (NFA_STATUS_FAILED);
+ }
+
+ NFA_TRACE_API1 ("NFA_HciGetGateAndPipeList (): hci_handle:0x%04x", hci_handle);
+
+ /* Register the application with HCI */
+ if ( (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
+ &&((p_msg = (tNFA_HCI_API_GET_APP_GATE_PIPE *) GKI_getbuf (sizeof (tNFA_HCI_API_GET_APP_GATE_PIPE))) != NULL))
+ {
+ p_msg->hdr.event = NFA_HCI_API_GET_APP_GATE_PIPE_EVT;
+ p_msg->hci_handle = hci_handle;
+
+ nfa_sys_sendmsg (p_msg);
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_HciDeregister
+**
+** Description This function is called to deregister an application
+** from HCI. The app will be notified by NFA_HCI_DEREGISTER_EVT
+** after deleting all the pipes owned by the app and deallocating
+** all the gates allocated to the app or if an error occurs.
+** Even if deregistration fails, the app has to register again
+** to provide a new cback function.
+**
+** Returns NFA_STATUS_OK if the application is deregistered successfully
+** NFA_STATUS_FAILED otherwise
+
+*******************************************************************************/
+tNFA_STATUS NFA_HciDeregister (char *p_app_name)
+{
+ tNFA_HCI_API_DEREGISTER_APP *p_msg;
+ int xx;
+ UINT8 app_name_len;
+
+ if (p_app_name == NULL)
+ {
+ NFA_TRACE_API0 ("NFA_HciDeregister (): Invalid Application");
+ return (NFA_STATUS_FAILED);
+ }
+
+ NFA_TRACE_API1 ("NFA_HciDeregister (): Application Name: %s", p_app_name);
+ app_name_len = (UINT8) strlen (p_app_name);
+
+ if (app_name_len > NFA_MAX_HCI_APP_NAME_LEN)
+ return (NFA_STATUS_FAILED);
+
+ /* Find the application registration */
+ for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++)
+ {
+ if ( (nfa_hci_cb.cfg.reg_app_names[xx][0] != 0)
+ &&(!strncmp (p_app_name, &nfa_hci_cb.cfg.reg_app_names[xx][0], app_name_len)) )
+ break;
+ }
+
+ if (xx == NFA_HCI_MAX_APP_CB)
+ {
+ NFA_TRACE_ERROR1 ("NFA_HciDeregister (): Application Name: %s NOT FOUND", p_app_name);
+ return (NFA_STATUS_FAILED);
+ }
+
+ /* Deregister the application with HCI */
+ if ( (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
+ &&((p_msg = (tNFA_HCI_API_DEREGISTER_APP *) GKI_getbuf (sizeof (tNFA_HCI_API_DEREGISTER_APP))) != NULL) )
+ {
+ p_msg->hdr.event = NFA_HCI_API_DEREGISTER_APP_EVT;
+
+ memset (p_msg->app_name, 0, sizeof (p_msg->app_name));
+ BCM_STRNCPY_S (p_msg->app_name, sizeof (p_msg->app_name), p_app_name, NFA_MAX_HCI_APP_NAME_LEN);
+
+ nfa_sys_sendmsg (p_msg);
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_HciAllocGate
+**
+** Description This function will allocate 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 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 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 source_gate_id,
+ UINT8 dest_host,
+ UINT8 dest_gate)
+{
+ tNFA_HCI_API_CREATE_PIPE_EVT *p_msg;
+ UINT8 xx;
+
+ NFA_TRACE_API4 ("NFA_HciCreatePipe (): hci_handle:0x%04x, source gate:0x%02X, destination host:0x%02X , destination gate:0x%02X",
+ hci_handle, source_gate_id, dest_host, dest_gate);
+
+ if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
+ {
+ NFA_TRACE_API1 ("NFA_HciCreatePipe (): Invalid hci_handle:0x%04x", hci_handle);
+ return (NFA_STATUS_FAILED);
+ }
+
+ if ((source_gate_id < NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE) || (source_gate_id > NFA_HCI_LAST_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 pipe)
+{
+ tNFA_HCI_API_OPEN_PIPE_EVT *p_msg;
+
+ if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
+ {
+ NFA_TRACE_API1 ("NFA_HciOpenPipe (): Invalid hci_handle:0x%04x", hci_handle);
+ return (NFA_STATUS_FAILED);
+ }
+
+ if ((pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) || (pipe > NFA_HCI_LAST_DYNAMIC_PIPE))
+ {
+ NFA_TRACE_API1 ("NFA_HciOpenPipe (): Invalid Pipe:0x%02x", pipe);
+ return (NFA_STATUS_FAILED);
+ }
+
+
+ NFA_TRACE_API2 ("NFA_HciOpenPipe (): hci_handle:0x%04x, pipe:0x%02X", hci_handle, pipe);
+
+ /* Request HCI to open a pipe if it is in closed state */
+ if ( (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
+ &&(!nfa_hci_cb.b_low_power_mode)
+ &&((p_msg = (tNFA_HCI_API_OPEN_PIPE_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_OPEN_PIPE_EVT))) != NULL) )
+ {
+ p_msg->hdr.event = NFA_HCI_API_OPEN_PIPE_EVT;
+ p_msg->hci_handle = hci_handle;
+ p_msg->pipe = pipe; /* Pipe ID of the pipe to open */
+
+ nfa_sys_sendmsg (p_msg);
+ return (NFA_STATUS_OK);
+ }
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_HciGetRegistry
+**
+** Description This function requests a peer host to return the desired
+** registry field value for the gate that the pipe is on.
+**
+** When the peer host responds,the app is notified with
+** NFA_HCI_GET_REG_RSP_EVT or
+** if an error occurs in sending the command the app will be
+** notified by NFA_HCI_CMD_SENT_EVT
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciGetRegistry (tNFA_HANDLE hci_handle, UINT8 pipe, UINT8 reg_inx)
+{
+ tNFA_HCI_API_GET_REGISTRY *p_msg;
+
+ if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
+ {
+ NFA_TRACE_API1 ("NFA_HciGetRegistry (): Invalid hci_handle:0x%04x", hci_handle);
+ return (NFA_STATUS_FAILED);
+ }
+
+ if (pipe < NFA_HCI_FIRST_DYNAMIC_PIPE)
+ {
+ NFA_TRACE_API1 ("NFA_HciGetRegistry (): Invalid Pipe:0x%02x", pipe);
+ return (NFA_STATUS_FAILED);
+ }
+
+ NFA_TRACE_API2 ("NFA_HciGetRegistry (): hci_handle:0x%04x Pipe: 0x%02x", hci_handle, pipe);
+
+ /* Request HCI to get list of gates supported by the specified host */
+ if ( (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
+ &&((p_msg = (tNFA_HCI_API_GET_REGISTRY *) GKI_getbuf (sizeof (tNFA_HCI_API_GET_REGISTRY))) != NULL) )
+ {
+ p_msg->hdr.event = NFA_HCI_API_GET_REGISTRY_EVT;
+ p_msg->hci_handle = hci_handle;
+ p_msg->pipe = pipe;
+ p_msg->reg_inx = reg_inx;
+
+ nfa_sys_sendmsg (p_msg);
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_HciSetRegistry
+**
+** Description This function requests a peer host to set the desired
+** registry field value for the gate that the pipe is on.
+**
+** When the peer host responds,the app is notified with
+** NFA_HCI_SET_REG_RSP_EVT or
+** if an error occurs in sending the command the app will be
+** notified by NFA_HCI_CMD_SENT_EVT
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciSetRegistry (tNFA_HANDLE hci_handle,
+ UINT8 pipe,
+ UINT8 reg_inx,
+ UINT8 data_size,
+ UINT8 *p_data)
+{
+ tNFA_HCI_API_SET_REGISTRY *p_msg;
+
+
+ if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
+ {
+ NFA_TRACE_API1 ("NFA_HciSetRegistry (): Invalid hci_handle:0x%04x", hci_handle);
+ return (NFA_STATUS_FAILED);
+ }
+
+ if (pipe < NFA_HCI_FIRST_DYNAMIC_PIPE)
+ {
+ NFA_TRACE_API1 ("NFA_HciSetRegistry (): Invalid Pipe:0x%02x", pipe);
+ return (NFA_STATUS_FAILED);
+ }
+
+ if ((data_size == 0) || (p_data == NULL) || (data_size > NFA_MAX_HCI_CMD_LEN))
+ {
+ NFA_TRACE_API1 ("NFA_HciSetRegistry (): Invalid data size:0x%02x", data_size);
+ return (NFA_STATUS_FAILED);
+ }
+
+ NFA_TRACE_API2 ("NFA_HciSetRegistry (): hci_handle:0x%04x Pipe: 0x%02x", hci_handle, pipe);
+
+ /* Request HCI to get list of gates supported by the specified host */
+ if ( (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
+ &&((p_msg = (tNFA_HCI_API_SET_REGISTRY *) GKI_getbuf (sizeof (tNFA_HCI_API_SET_REGISTRY))) != NULL) )
+ {
+ p_msg->hdr.event = NFA_HCI_API_SET_REGISTRY_EVT;
+ p_msg->hci_handle = hci_handle;
+ p_msg->pipe = pipe;
+ p_msg->reg_inx = reg_inx;
+ p_msg->size = data_size;
+
+ memcpy (p_msg->data, p_data, data_size);
+ nfa_sys_sendmsg (p_msg);
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_HciSendCommand
+**
+** Description This function is called to send a command on a pipe created
+** by the application.
+** The app will be notified by NFA_HCI_CMD_SENT_EVT if an error
+** occurs.
+** When the peer host responds,the app is notified with
+** NFA_HCI_RSP_RCVD_EVT
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciSendCommand (tNFA_HANDLE hci_handle,
+ UINT8 pipe,
+ UINT8 cmd_code,
+ UINT16 cmd_size,
+ UINT8 *p_data)
+{
+ tNFA_HCI_API_SEND_CMD_EVT *p_msg;
+
+ if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
+ {
+ NFA_TRACE_API1 ("NFA_HciSendCommand (): Invalid hci_handle:0x%04x", hci_handle);
+ return (NFA_STATUS_FAILED);
+ }
+
+ if (pipe < NFA_HCI_FIRST_DYNAMIC_PIPE)
+ {
+ NFA_TRACE_API1 ("NFA_HciSendCommand (): Invalid Pipe:0x%02x", pipe);
+ return (NFA_STATUS_FAILED);
+ }
+
+ if ((cmd_size && (p_data == NULL)) || (cmd_size > NFA_MAX_HCI_CMD_LEN))
+ {
+ NFA_TRACE_API1 ("NFA_HciSendCommand (): Invalid cmd size:0x%02x", cmd_size);
+ return (NFA_STATUS_FAILED);
+ }
+
+ NFA_TRACE_API3 ("NFA_HciSendCommand (): hci_handle:0x%04x, pipe:0x%02x Code: 0x%02x", hci_handle, pipe, cmd_code);
+
+ /* Request HCI to post event data on a particular pipe */
+ if ( (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
+ &&((p_msg = (tNFA_HCI_API_SEND_CMD_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_SEND_CMD_EVT))) != NULL) )
+ {
+ p_msg->hdr.event = NFA_HCI_API_SEND_CMD_EVT;
+ p_msg->hci_handle = hci_handle;
+ p_msg->pipe = pipe;
+ p_msg->cmd_code = cmd_code;
+ p_msg->cmd_len = cmd_size;
+
+ if (cmd_size)
+ memcpy (p_msg->data, p_data, cmd_size);
+
+ nfa_sys_sendmsg (p_msg);
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_HciSendResponse
+**
+** Description This function is called to send a response on a pipe created
+** by the application.
+** The app will be notified by NFA_HCI_RSP_SENT_EVT if an error
+** occurs.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciSendResponse (tNFA_HANDLE hci_handle,
+ UINT8 pipe,
+ UINT8 response,
+ UINT8 data_size,
+ UINT8 *p_data)
+{
+ tNFA_HCI_API_SEND_RSP_EVT *p_msg;
+
+ if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
+ {
+ NFA_TRACE_API1 ("NFA_HciSendResponse (): Invalid hci_handle:0x%04x", hci_handle);
+ return (NFA_STATUS_FAILED);
+ }
+
+ if (pipe < NFA_HCI_FIRST_DYNAMIC_PIPE)
+ {
+ NFA_TRACE_API1 ("NFA_HciSendResponse (): Invalid Pipe:0x%02x", pipe);
+ return (NFA_STATUS_FAILED);
+ }
+
+ if ((data_size && (p_data == NULL)) || (data_size > NFA_MAX_HCI_RSP_LEN))
+ {
+ NFA_TRACE_API1 ("NFA_HciSendResponse (): Invalid data size:0x%02x", data_size);
+ return (NFA_STATUS_FAILED);
+ }
+
+ NFA_TRACE_API3 ("NFA_HciSendResponse (): hci_handle:0x%04x Pipe: 0x%02x Response: 0x%02x", hci_handle, pipe, response);
+
+ /* Request HCI to get list of gates supported by the specified host */
+ if ( (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
+ &&((p_msg = (tNFA_HCI_API_SEND_RSP_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_SEND_RSP_EVT))) != NULL) )
+ {
+ p_msg->hdr.event = NFA_HCI_API_SEND_RSP_EVT;
+ p_msg->hci_handle = hci_handle;
+ p_msg->response = response;
+ p_msg->size = data_size;
+
+ if (data_size)
+ memcpy (p_msg->data, p_data, data_size);
+
+ nfa_sys_sendmsg (p_msg);
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_HciSendEvent
+**
+** Description This function is called to send any event on a pipe created
+** by the application.
+** The app will be notified by NFA_HCI_EVENT_SENT_EVT
+** after successfully sending the event on the specified pipe
+** or if an error occurs. The application should wait for this
+** event before releasing event buffer passed as argument.
+** If the app is expecting a response to the event then it can
+** provide response buffer for collecting the response. If it
+** provides a response buffer it can also provide response
+** timeout indicating maximum timeout for the response.
+** Maximum of NFA_MAX_HCI_EVENT_LEN bytes APDU can be received
+** using internal buffer if no response buffer is provided by
+** the application. The app will be notified by
+** NFA_HCI_EVENT_RCVD_EVT after receiving the response event
+** or on timeout if app provided response buffer and response
+** timeout. If response buffer and response timeout is provided
+** by the application, it should wait for this event before
+** releasing the response buffer. If the application did not
+** provide response timeout then it should not release the
+** response buffer until it receives NFA_HCI_EVENT_RCVD_EVT or
+** after timeout it sends next event on the same pipe
+** and receives NFA_HCI_EVENT_SENT_EVT for that event.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciSendEvent (tNFA_HANDLE hci_handle,
+ UINT8 pipe,
+ UINT8 evt_code,
+ UINT16 evt_size,
+ UINT8 *p_data,
+ UINT16 rsp_size,
+ UINT8 *p_rsp_buf,
+ UINT16 rsp_timeout)
+{
+ tNFA_HCI_API_SEND_EVENT_EVT *p_msg;
+
+ NFA_TRACE_API3 ("NFA_HciSendEvent(): hci_handle:0x%04x, pipe:0x%02x Code: 0x%02x", hci_handle, pipe, evt_code);
+
+
+ if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
+ {
+ NFA_TRACE_API1 ("NFA_HciSendEvent (): Invalid hci_handle:0x%04x", hci_handle);
+ return (NFA_STATUS_FAILED);
+ }
+
+ if (pipe < NFA_HCI_FIRST_DYNAMIC_PIPE)
+ {
+ NFA_TRACE_API1 ("NFA_HciSendEvent (): Invalid Pipe:0x%02x", pipe);
+ return (NFA_STATUS_FAILED);
+ }
+
+ if (evt_size && (p_data == NULL))
+ {
+ NFA_TRACE_API1 ("NFA_HciSendEvent (): Invalid Event size:0x%02x", evt_size);
+ return (NFA_STATUS_FAILED);
+ }
+
+ if (rsp_size && (p_rsp_buf == NULL))
+ {
+ NFA_TRACE_API1 ("NFA_HciSendEvent (): No Event buffer, but invalid event buffer size :%u", rsp_size);
+ return (NFA_STATUS_FAILED);
+ }
+
+ /* Request HCI to post event data on a particular pipe */
+ if ( (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
+ &&((p_msg = (tNFA_HCI_API_SEND_EVENT_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_SEND_EVENT_EVT))) != NULL) )
+ {
+ p_msg->hdr.event = NFA_HCI_API_SEND_EVENT_EVT;
+ p_msg->hci_handle = hci_handle;
+ p_msg->pipe = pipe;
+ p_msg->evt_code = evt_code;
+ p_msg->evt_len = evt_size;
+ p_msg->p_evt_buf = p_data;
+ p_msg->rsp_len = rsp_size;
+ p_msg->p_rsp_buf = p_rsp_buf;
+ p_msg->rsp_timeout = rsp_timeout;
+
+ nfa_sys_sendmsg (p_msg);
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_HciClosePipe
+**
+** Description This function is called to close a dynamic pipe.
+** When the dynamic pipe is closed (or
+** if an error occurs), the app will be notified with
+** NFA_HCI_CLOSE_PIPE_EVT with the pipe id.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciClosePipe (tNFA_HANDLE hci_handle, UINT8 pipe)
+{
+ tNFA_HCI_API_CLOSE_PIPE_EVT *p_msg;
+
+ NFA_TRACE_API2 ("NFA_HciClosePipe (): hci_handle:0x%04x, pipe:0x%02X", hci_handle, pipe);
+
+ if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
+ {
+ NFA_TRACE_API1 ("NFA_HciClosePipe (): Invalid hci_handle:0x%04x", hci_handle);
+ return (NFA_STATUS_FAILED);
+ }
+
+ if ((pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) || (pipe > NFA_HCI_LAST_DYNAMIC_PIPE))
+ {
+ NFA_TRACE_API1 ("NFA_HciClosePipe (): Invalid Pipe:0x%02x", pipe);
+ return (NFA_STATUS_FAILED);
+ }
+
+ /* Request HCI to close a pipe if it is in opened state */
+ if ( (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
+ &&(!nfa_hci_cb.b_low_power_mode)
+ &&((p_msg = (tNFA_HCI_API_CLOSE_PIPE_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_CLOSE_PIPE_EVT))) != NULL) )
+ {
+ p_msg->hdr.event = NFA_HCI_API_CLOSE_PIPE_EVT;
+ p_msg->hci_handle = hci_handle;
+ p_msg->pipe = pipe;
+
+ nfa_sys_sendmsg (p_msg);
+ return (NFA_STATUS_OK);
+ }
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_HciDeletePipe
+**
+** Description This function is called to delete a particular dynamic pipe.
+** When the dynamic pipe is deleted (or if an error occurs),
+** the app will be notified with NFA_HCI_DELETE_PIPE_EVT with
+** the pipe id. After successful deletion of pipe, registry
+** entry will be deleted for the dynamic pipe and all
+** information related to the pipe will be deleted from non
+** volatile memory.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciDeletePipe (tNFA_HANDLE hci_handle, UINT8 pipe)
+{
+ tNFA_HCI_API_DELETE_PIPE_EVT *p_msg;
+
+ if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
+ {
+ NFA_TRACE_API1 ("NFA_HciDeletePipe (): Invalid hci_handle:0x%04x", hci_handle);
+ return (NFA_STATUS_FAILED);
+ }
+
+ if ((pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) || (pipe > NFA_HCI_LAST_DYNAMIC_PIPE))
+ {
+ NFA_TRACE_API1 ("NFA_HciDeletePipe (): Invalid Pipe:0x%02x", pipe);
+ return (NFA_STATUS_FAILED);
+ }
+
+ NFA_TRACE_API2 ("NFA_HciDeletePipe (): hci_handle:0x%04x, pipe:0x%02X", hci_handle, pipe);
+
+ /* Request HCI to delete a pipe created by the application identified by hci handle */
+ if ( (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
+ &&(!nfa_hci_cb.b_low_power_mode)
+ &&((p_msg = (tNFA_HCI_API_DELETE_PIPE_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_DELETE_PIPE_EVT))) != NULL) )
+ {
+ p_msg->hdr.event = NFA_HCI_API_DELETE_PIPE_EVT;
+ p_msg->hci_handle = hci_handle;
+ p_msg->pipe = pipe;
+
+ nfa_sys_sendmsg (p_msg);
+ return (NFA_STATUS_OK);
+ }
+ return (NFA_STATUS_FAILED);
+}
+
+
+/*******************************************************************************
+**
+** Function NFA_HciAddStaticPipe
+**
+** Description This function is called to add a static pipe for sending
+** 7816 APDUs. When the static pipe is added (or if an error occurs),
+** the app will be notified with NFA_HCI_ADD_STATIC_PIPE_EVT with
+** the status.
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciAddStaticPipe (tNFA_HANDLE hci_handle, UINT8 host, UINT8 gate, UINT8 pipe)
+{
+ tNFA_HCI_API_ADD_STATIC_PIPE_EVT *p_msg;
+ UINT8 xx;
+
+ if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
+ {
+ NFA_TRACE_API1 ("NFA_HciAddStaticPipe (): Invalid hci_handle:0x%04x", hci_handle);
+ return (NFA_STATUS_FAILED);
+ }
+
+ for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++)
+ if (nfa_hci_cb.inactive_host[xx] == host)
+ break;
+
+ if (xx != NFA_HCI_MAX_HOST_IN_NETWORK)
+ {
+ NFA_TRACE_API1 ("NFA_HciAddStaticPipe (): Host not active:0x%02x", host);
+ return (NFA_STATUS_FAILED);
+ }
+
+ if (gate <= NFA_HCI_LAST_HOST_SPECIFIC_GATE)
+ {
+ NFA_TRACE_API1 ("NFA_HciAddStaticPipe (): Invalid Gate:0x%02x", gate);
+ return (NFA_STATUS_FAILED);
+ }
+#if(NFC_NXP_NOT_OPEN_INCLUDED != 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 action, UINT8 size, UINT8 *p_data)
+{
+ int xx;
+ tNFA_HCI_DYN_GATE *pg = nfa_hci_cb.cfg.dyn_gates;
+ tNFA_HCI_DYN_PIPE *pp = nfa_hci_cb.cfg.dyn_pipes;
+ BT_HDR *p_msg;
+ UINT8 *p;
+
+ switch (action)
+ {
+ case NFA_HCI_DEBUG_DISPLAY_CB:
+ NFA_TRACE_API0 ("NFA_HciDebug Host List:");
+ for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++)
+ {
+ if (nfa_hci_cb.cfg.reg_app_names[xx][0] != 0)
+ {
+ NFA_TRACE_API2 (" Host Inx: %u Name: %s", xx, &nfa_hci_cb.cfg.reg_app_names[xx][0]);
+ }
+ }
+
+ NFA_TRACE_API0 ("NFA_HciDebug Gate List:");
+ for (xx = 0; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
+ {
+ if (pg->gate_id != 0)
+ {
+ NFA_TRACE_API4 (" Gate Inx: %x ID: 0x%02x Owner: 0x%04x PipeInxMask: 0x%08x",
+ xx, pg->gate_id, pg->gate_owner, pg->pipe_inx_mask);
+ }
+ }
+
+ NFA_TRACE_API0 ("NFA_HciDebug Pipe List:");
+ for (xx = 0; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
+ {
+ if (pp->pipe_id != 0)
+ {
+ NFA_TRACE_API6 (" Pipe Inx: %x ID: 0x%02x State: %u LocalGate: 0x%02x Dest Gate: 0x%02x Host: 0x%02x",
+ xx, pp->pipe_id, pp->pipe_state, pp->local_gate, pp->dest_gate, pp->dest_host);
+ }
+ }
+ break;
+
+ case NFA_HCI_DEBUG_SIM_HCI_EVENT:
+ if ((p_msg = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL)
+ {
+ p = (UINT8 *) (p_msg + 1);
+
+ p_msg->event = NFA_HCI_CHECK_QUEUE_EVT;
+ p_msg->len = size;
+ p_msg->offset = 0;
+
+ memcpy (p, p_data, size);
+
+ nfa_sys_sendmsg (p_msg);
+ }
+ break;
+
+ case NFA_HCI_DEBUG_ENABLE_LOOPBACK:
+ NFA_TRACE_API0 ("NFA_HciDebug HCI_LOOPBACK_DEBUG = TRUE");
+ HCI_LOOPBACK_DEBUG = TRUE;
+ break;
+
+ case NFA_HCI_DEBUG_DISABLE_LOOPBACK:
+ NFA_TRACE_API0 ("NFA_HciDebug HCI_LOOPBACK_DEBUG = FALSE");
+ HCI_LOOPBACK_DEBUG = FALSE;
+ break;
+ }
+}
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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
+**
+*******************************************************************************/
+void NFA_HciW4eSETransaction_Complete(tNFA_HCI_TRANSCV_STATE type)
+{
+ NFA_TRACE_API1 ("NFA_HciW4eSETransaction_Complete; type=%u", type);
+ UINT8 retry_cnt = 0;
+ UINT8 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");
+}
+#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..808dff0
--- /dev/null
+++ b/src/nfa/hci/nfa_hci_ci.c
@@ -0,0 +1,80 @@
+/******************************************************************************
+ *
+ * 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 num_bytes_read, tNFA_NV_CO_STATUS status, UINT8 block)
+{
+ tNFA_HCI_EVENT_DATA *p_msg;
+
+ if ((p_msg = (tNFA_HCI_EVENT_DATA *) GKI_getbuf (sizeof (tNFA_HCI_EVENT_DATA))) != NULL)
+ {
+ p_msg->nv_read.hdr.event = NFA_HCI_RSP_NV_READ_EVT;
+
+ if ( (status == NFA_STATUS_OK)
+ &&(num_bytes_read != 0) )
+ p_msg->nv_read.status = NFA_STATUS_OK;
+ 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;
+
+ if ((p_msg = (tNFA_HCI_EVENT_DATA *) GKI_getbuf (sizeof (tNFA_HCI_EVENT_DATA))) != NULL)
+ {
+ p_msg->nv_write.hdr.event = NFA_HCI_RSP_NV_WRITE_EVT;
+ p_msg->nv_write.status = 0;
+ nfa_sys_sendmsg (p_msg);
+ }
+}
diff --git a/src/nfa/hci/nfa_hci_main.c b/src/nfa/hci/nfa_hci_main.c
new file mode 100644
index 0000000..84069f7
--- /dev/null
+++ b/src/nfa/hci/nfa_hci_main.c
@@ -0,0 +1,1557 @@
+/******************************************************************************
+ *
+ * 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 HCI.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_api.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "nfa_dm_int.h"
+#include "nfa_hci_api.h"
+#include "nfa_hci_int.h"
+#include "nfa_ee_api.h"
+#include "nfa_ee_int.h"
+#include "nfa_nv_co.h"
+#include "nfa_mem_co.h"
+#include "nfa_hci_defs.h"
+#include "trace_api.h"
+
+
+/*****************************************************************************
+** Global Variables
+*****************************************************************************/
+
+tNFA_HCI_CB nfa_hci_cb;
+
+#ifndef NFA_HCI_NV_READ_TIMEOUT_VAL
+#define NFA_HCI_NV_READ_TIMEOUT_VAL 1000
+#endif
+
+#ifndef NFA_HCI_CON_CREATE_TIMEOUT_VAL
+#define NFA_HCI_CON_CREATE_TIMEOUT_VAL 1000
+#endif
+
+/*****************************************************************************
+** Static Functions
+*****************************************************************************/
+
+/* event handler function type */
+static BOOLEAN nfa_hci_evt_hdlr (BT_HDR *p_msg);
+
+static void nfa_hci_sys_enable (void);
+static void nfa_hci_sys_disable (void);
+static void nfa_hci_conn_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data);
+static void nfa_hci_set_receive_buf (UINT8 pipe);
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+void nfa_hci_rsp_timeout (tNFA_HCI_EVENT_DATA *p_evt_data);
+static void nfa_hci_assemble_msg (UINT8 *p_data, UINT16 data_len, UINT8 pipe);
+#else
+static void nfa_hci_assemble_msg (UINT8 *p_data, UINT16 data_len);
+#endif
+static void nfa_hci_handle_nv_read (UINT8 block, tNFA_STATUS status);
+
+/*****************************************************************************
+** Constants
+*****************************************************************************/
+static const tNFA_SYS_REG nfa_hci_sys_reg =
+{
+ nfa_hci_sys_enable,
+ nfa_hci_evt_hdlr,
+ nfa_hci_sys_disable,
+ nfa_hci_proc_nfcc_power_mode
+};
+
+/*******************************************************************************
+**
+** Function nfa_hci_ee_info_cback
+**
+** Description Callback function
+**
+** Returns None
+**
+*******************************************************************************/
+void nfa_hci_ee_info_cback (tNFA_EE_DISC_STS status)
+{
+ UINT8 num_nfcee = 3;
+ tNFA_EE_INFO ee_info[3];
+
+ 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 (&num_nfcee, ee_info);
+ nfa_hci_cb.num_nfcee = 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) )
+ {
+ 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);
+ }
+ }
+ }
+ 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;
+ }
+ break;
+
+ case NFA_EE_DISC_STS_REQ:
+ nfa_hci_cb.num_ee_dis_req_ntf++;
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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;
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_hci_init
+**
+** Description Initialize NFA HCI
+**
+** Returns None
+**
+*******************************************************************************/
+void nfa_hci_init (void)
+{
+ NFA_TRACE_DEBUG0 ("nfa_hci_init ()");
+
+ /* initialize control block */
+ memset (&nfa_hci_cb, 0, sizeof (tNFA_HCI_CB));
+
+ nfa_hci_cb.hci_state = NFA_HCI_STATE_STARTUP;
+
+ /* register message handler on NFA SYS */
+ nfa_sys_register (NFA_ID_HCI, &nfa_hci_sys_reg);
+}
+
+/*******************************************************************************
+**
+** Function nfa_hci_is_valid_cfg
+**
+** Description Validate hci control block config parameters
+**
+** Returns None
+**
+*******************************************************************************/
+BOOLEAN nfa_hci_is_valid_cfg (void)
+{
+ UINT8 xx,yy,zz;
+ tNFA_HANDLE reg_app[NFA_HCI_MAX_APP_CB];
+ UINT8 valid_gate[NFA_HCI_MAX_GATE_CB];
+ UINT8 app_count = 0;
+ UINT8 gate_count = 0;
+ UINT32 pipe_inx_mask = 0;
+ UINT8 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)
+ {
+ /* 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(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED == 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 *p_session_id)
+{
+ memset (&nfa_hci_cb.cfg, 0, sizeof (nfa_hci_cb.cfg));
+ memcpy (nfa_hci_cb.cfg.admin_gate.session_id, p_session_id, NFA_HCI_SESSION_ID_LEN);
+ nfa_hci_cb.nv_write_needed = TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_hci_proc_nfcc_power_mode
+**
+** Description Restore NFA HCI sub-module
+**
+** Returns None
+**
+*******************************************************************************/
+void nfa_hci_proc_nfcc_power_mode (UINT8 nfcc_power_mode)
+{
+ NFA_TRACE_DEBUG1 ("nfa_hci_proc_nfcc_power_mode () nfcc_power_mode=%d", nfcc_power_mode);
+
+ /* if NFCC power mode is change to full power */
+ if (nfcc_power_mode == NFA_DM_PWR_MODE_FULL)
+ {
+ nfa_hci_cb.b_low_power_mode = FALSE;
+ if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE)
+ {
+ nfa_hci_cb.hci_state = NFA_HCI_STATE_RESTORE;
+ nfa_hci_cb.ee_disc_cmplt = FALSE;
+ nfa_hci_cb.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)
+{
+//NFC-INIT MACH
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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);
+ }
+ }
+#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;
+ /* 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) */
+ 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);
+ }
+ else
+ {
+ evt_data.hci_init.status = status;
+
+ nfa_hciu_send_to_all_apps (NFA_HCI_INIT_EVT, &evt_data);
+ nfa_sys_cback_notify_enable_complete (NFA_ID_HCI);
+ }
+
+ if (status == NFA_STATUS_OK)
+ nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+
+ else
+ nfa_hci_cb.hci_state = NFA_HCI_STATE_DISABLED;
+}
+
+/*******************************************************************************
+**
+** Function nfa_hci_startup
+**
+** Description Perform HCI startup
+**
+** Returns None
+**
+*******************************************************************************/
+void nfa_hci_startup (void)
+{
+ tNFA_STATUS status = NFA_STATUS_FAILED;
+ tNFA_EE_INFO ee_info[2];
+ UINT8 num_nfcee = 2;
+ UINT8 target_handle;
+ UINT8 count = 0;
+ BOOLEAN found = FALSE;
+
+ if (HCI_LOOPBACK_DEBUG)
+ {
+ /* First step in initialization is to open the admin pipe */
+ nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE);
+ return;
+ }
+
+ /* We can only start up if NV Ram is read and EE discovery is complete */
+ if (nfa_hci_cb.nv_read_cmplt && nfa_hci_cb.ee_disc_cmplt && (nfa_hci_cb.conn_id == 0))
+ {
+ NFA_EeGetInfo (&num_nfcee, ee_info);
+
+ while ((count < num_nfcee) && (!found))
+ {
+ target_handle = (UINT8) ee_info[count].ee_handle;
+
+ if(ee_info[count].ee_interface[0] == NFA_EE_INTERFACE_HCI_ACCESS)
+ {
+ found = TRUE;
+#if(NFC_NXP_NOT_OPEN_INCLUDED != TRUE)
+ if (ee_info[count].ee_status == NFA_EE_STATUS_INACTIVE)
+ {
+ NFC_NfceeModeSet (target_handle, NFC_MODE_ACTIVATE);
+ }
+#endif
+ if ((status = NFC_ConnCreate (NCI_DEST_TYPE_NFCEE, target_handle, NFA_EE_INTERFACE_HCI_ACCESS, nfa_hci_conn_cback)) == NFA_STATUS_OK)
+ nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, NFA_HCI_CON_CREATE_TIMEOUT_VAL);
+ else
+ {
+ nfa_hci_cb.hci_state = NFA_HCI_STATE_DISABLED;
+ NFA_TRACE_ERROR0 ("nfa_hci_startup - Failed to Create Logical connection. HCI Initialization/Restore failed");
+ nfa_hci_startup_complete (NFA_STATUS_FAILED);
+ }
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+void nfa_hci_network_enable()
+{
+ tNFA_EE_INFO ee_info[2];
+ UINT8 num_nfcee = 2;
+ UINT8 target_handle;
+ BOOLEAN found = FALSE;
+ UINT8 count = 0;
+
+ NFA_EeGetInfo (&num_nfcee, ee_info);
+ while ((count < num_nfcee) && (!found))
+ {
+ target_handle = (UINT8) ee_info[count].ee_handle;
+
+ if(ee_info[count].ee_interface[0] == NFA_EE_INTERFACE_HCI_ACCESS)
+ {
+ found = TRUE;
+ if (ee_info[count].ee_status == NFA_EE_STATUS_INACTIVE)
+ {
+ NFC_NfceeModeSet (target_handle, NFC_MODE_ACTIVATE);
+ }
+ }
+ 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 *)&nfa_hci_cb.cfg, sizeof (nfa_hci_cb.cfg),DH_NV_BLOCK);
+ nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, NFA_HCI_NV_READ_TIMEOUT_VAL);
+}
+
+/*******************************************************************************
+**
+** Function nfa_hci_sys_disable
+**
+** Description Disable NFA HCI
+**
+** Returns None
+**
+*******************************************************************************/
+static void nfa_hci_sys_disable (void)
+{
+ tNFA_HCI_EVT_DATA evt_data;
+
+ nfa_sys_stop_timer (&nfa_hci_cb.timer);
+
+ if (nfa_hci_cb.conn_id)
+ {
+ if (nfa_sys_is_graceful_disable ())
+ {
+ /* Tell all applications stack is down */
+ nfa_hciu_send_to_all_apps (NFA_HCI_EXIT_EVT, &evt_data);
+ NFC_ConnClose (nfa_hci_cb.conn_id);
+ return;
+ }
+ nfa_hci_cb.conn_id = 0;
+ }
+
+ nfa_hci_cb.hci_state = NFA_HCI_STATE_DISABLED;
+ /* deregister message handler on NFA SYS */
+ nfa_sys_deregister (NFA_ID_HCI);
+}
+
+/*******************************************************************************
+**
+** Function nfa_hci_conn_cback
+**
+** Description This function Process event from NCI
+**
+** Returns None
+**
+*******************************************************************************/
+static void nfa_hci_conn_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
+{
+ UINT8 *p;
+ BT_HDR *p_pkt = (BT_HDR *) p_data->data.p_data;
+ UINT8 chaining_bit;
+ UINT8 pipe;
+ UINT16 pkt_len;
+#if (BT_TRACE_VERBOSE == TRUE)
+ char buff[100];
+ static BOOLEAN is_first_chain_pkt = TRUE;
+#endif
+
+ if (event == NFC_CONN_CREATE_CEVT)
+ {
+ nfa_hci_cb.conn_id = conn_id;
+ nfa_hci_cb.buff_size = p_data->conn_create.buff_size;
+
+ if (nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP)
+ {
+ nfa_hci_cb.w4_hci_netwk_init = TRUE;
+ nfa_hciu_alloc_gate (NFA_HCI_CONNECTIVITY_GATE,0);
+ }
+
+ if (nfa_hci_cb.cfg.admin_gate.pipe01_state == NFA_HCI_PIPE_CLOSED)
+ {
+ /* First step in initialization/restore is to open the admin pipe */
+ nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE);
+ }
+ else
+ {
+#if (NFC_NXP_NOT_OPEN_INCLUDED == 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;
+ /* deregister message handler on NFA SYS */
+ nfa_sys_deregister (NFA_ID_HCI);
+ }
+
+ if ((event != NFC_DATA_CEVT) || (p_pkt == NULL))
+ return;
+
+ if ( (nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE)
+ ||(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 *) (p_pkt + 1) + p_pkt->offset;
+ pkt_len = p_pkt->len;
+
+#if (BT_TRACE_PROTOCOL == TRUE)
+ DispHcp (p, pkt_len, TRUE, (BOOLEAN) !nfa_hci_cb.assembling);
+#endif
+
+ chaining_bit = ((*p) >> 0x07) & 0x01;
+ pipe = (*p++) & 0x7F;
+ if (pkt_len != 0)
+ pkt_len--;
+
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ UINT8 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))
+ {
+ 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 (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ if(pipe == NFA_HCI_CONN_ESE_PIPE ||
+ (pipe == NFA_HCI_CONN_UICC_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 (NFC_NXP_NOT_OPEN_INCLUDED == 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 (NFC_NXP_NOT_OPEN_INCLUDED == 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 (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ && (nfa_hci_cb.inst != NFA_HCI_EVT_WTX)
+#endif
+ )
+ {
+ nfa_hci_set_receive_buf (pipe);
+#if (NFC_NXP_NOT_OPEN_INCLUDED == 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))
+ {
+ 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 (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ UINT8 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))
+ {
+ 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 (NFC_NXP_NOT_OPEN_INCLUDED == 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 (NFC_NXP_NOT_OPEN_INCLUDED == 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))
+ {
+ 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 (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ if(pipe == NFA_HCI_CONN_ESE_PIPE ||
+ (pipe == NFA_HCI_CONN_UICC_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)pipe, nfa_hciu_get_type_inst_names (pipe, nfa_hci_cb.type, nfa_hci_cb.inst, buff),
+ (UINT8)chaining_bit, (UINT8)nfa_hci_cb.assembling, p_pkt->len);
+#else
+ NFA_TRACE_EVENT6 ("nfa_hci_conn_cback Recvd data pipe:%d Type: %u Inst: %u chain:%d reassm:%d len:%d",
+ pipe, nfa_hci_cb.type, nfa_hci_cb.inst, chaining_bit, nfa_hci_cb.assembling, p_pkt->len);
+#endif
+
+#if (NFC_NXP_NOT_OPEN_INCLUDED == 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 (NFC_NXP_NOT_OPEN_INCLUDED == 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 we got a response, cancel the response timer. Also, if waiting for */
+ /* a single response, we can go back to idle state */
+ if (
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ (pipe == NFA_HCI_APDU_PIPE) &&(
+#endif
+ (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 (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ )
+#endif
+ )
+ {
+ nfa_sys_stop_timer (&nfa_hci_cb.timer);
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ is_first_chain_pkt = TRUE;
+ if(nfa_hci_cb.inst == NFA_HCI_EVT_WTX)
+ {
+ if(nfa_hci_cb.w4_rsp_evt == TRUE)
+ {
+ const INT32 rsp_timeout = 3000; //3-sec
+ nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, rsp_timeout);
+ }
+ }
+ else
+#endif
+ nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+ }
+
+ switch (pipe)
+ {
+ case NFA_HCI_ADMIN_PIPE:
+ /* Check if data packet is a command, response or event */
+ if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
+ {
+ nfa_hci_handle_admin_gate_cmd (p);
+ }
+ else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE)
+ {
+ nfa_hci_handle_admin_gate_rsp (p, (UINT8) pkt_len);
+ }
+ else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)
+ {
+ nfa_hci_handle_admin_gate_evt (p);
+ }
+ break;
+
+ case NFA_HCI_LINK_MANAGEMENT_PIPE:
+ /* We don't send Link Management commands, we only get them */
+ if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
+ nfa_hci_handle_link_mgm_gate_cmd (p);
+ break;
+
+ default:
+ if (pipe >= NFA_HCI_FIRST_DYNAMIC_PIPE)
+ nfa_hci_handle_dyn_pipe_pkt (pipe, p, pkt_len);
+ break;
+ }
+
+ if (
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ (pipe == NFA_HCI_APDU_PIPE) && (
+#endif
+ (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) || (nfa_hci_cb.w4_rsp_evt && (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ && (nfa_hci_cb.inst != NFA_HCI_EVT_WTX)
+#endif
+ )
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ )
+#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 block, tNFA_STATUS status)
+{
+ UINT8 session_id[NFA_HCI_SESSION_ID_LEN];
+ UINT8 default_session[NFA_HCI_SESSION_ID_LEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+ UINT8 reset_session[NFA_HCI_SESSION_ID_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ UINT32 os_tick;
+
+ if (block == DH_NV_BLOCK)
+ {
+ /* Stop timer as NVDATA Read Completed */
+ nfa_sys_stop_timer (&nfa_hci_cb.timer);
+ nfa_hci_cb.nv_read_cmplt = TRUE;
+ if ( (status != NFA_STATUS_OK)
+ ||(!nfa_hci_is_valid_cfg ())
+ ||(!(memcmp (nfa_hci_cb.cfg.admin_gate.session_id, default_session, NFA_HCI_SESSION_ID_LEN)))
+ ||(!(memcmp (nfa_hci_cb.cfg.admin_gate.session_id, reset_session, NFA_HCI_SESSION_ID_LEN))) )
+ {
+ 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 *)&os_tick, (NFA_HCI_SESSION_ID_LEN / 2));
+ nfa_hci_restore_default_config (session_id);
+ }
+ nfa_hci_startup ();
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_hci_rsp_timeout
+**
+** Description action function to process timeout
+**
+** Returns None
+**
+*******************************************************************************/
+void nfa_hci_rsp_timeout (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+ tNFA_HCI_EVT evt = 0;
+ tNFA_HCI_EVT_DATA evt_data;
+ UINT8 delete_pipe;
+
+ NFA_TRACE_EVENT2 ("nfa_hci_rsp_timeout () State: %u Cmd: %u", nfa_hci_cb.hci_state, nfa_hci_cb.cmd_sent);
+
+ evt_data.status = NFA_STATUS_FAILED;
+
+ switch (nfa_hci_cb.hci_state)
+ {
+ case NFA_HCI_STATE_STARTUP:
+ case NFA_HCI_STATE_RESTORE:
+ NFA_TRACE_ERROR0 ("nfa_hci_rsp_timeout - Initialization failed!");
+ nfa_hci_startup_complete (NFA_STATUS_TIMEOUT);
+ break;
+
+ case NFA_HCI_STATE_WAIT_NETWK_ENABLE:
+ 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 (nfa_hci_cb.w4_rsp_evt)
+ {
+ nfa_hci_cb.w4_rsp_evt = FALSE;
+ evt = NFA_HCI_EVENT_RCVD_EVT;
+ evt_data.rcvd_evt.pipe = nfa_hci_cb.pipe_in_use;
+ evt_data.rcvd_evt.evt_code = 0;
+ evt_data.rcvd_evt.evt_len = 0;
+ evt_data.rcvd_evt.p_evt_buf = NULL;
+ nfa_hci_cb.rsp_buf_size = 0;
+ nfa_hci_cb.p_rsp_buf = NULL;
+
+ break;
+ }
+
+ delete_pipe = 0;
+ switch (nfa_hci_cb.cmd_sent)
+ {
+ case NFA_HCI_ANY_SET_PARAMETER:
+ /*
+ * As no response to the command sent on this pipe, we may assume the pipe is
+ * deleted already and release the pipe. But still send delete pipe command to be safe.
+ */
+ delete_pipe = nfa_hci_cb.pipe_in_use;
+ evt_data.registry.pipe = nfa_hci_cb.pipe_in_use;
+ evt_data.registry.data_len = 0;
+ evt_data.registry.index = nfa_hci_cb.param_in_use;
+ evt = NFA_HCI_SET_REG_RSP_EVT;
+ break;
+
+ case NFA_HCI_ANY_GET_PARAMETER:
+ /*
+ * As no response to the command sent on this pipe, we may assume the pipe is
+ * deleted already and release the pipe. But still send delete pipe command to be safe.
+ */
+ delete_pipe = nfa_hci_cb.pipe_in_use;
+ evt_data.registry.pipe = nfa_hci_cb.pipe_in_use;
+ evt_data.registry.data_len = 0;
+ evt_data.registry.index = nfa_hci_cb.param_in_use;
+#if (NFC_NXP_NOT_OPEN_INCLUDED == 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 (NFC_NXP_NOT_OPEN_INCLUDED != 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 pipe)
+{
+ if ( (pipe >= NFA_HCI_FIRST_DYNAMIC_PIPE)
+ &&(nfa_hci_cb.type == NFA_HCI_EVENT_TYPE) )
+ {
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ if(pipe == NFA_HCI_CONN_ESE_PIPE || pipe == NFA_HCI_CONN_UICC_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;
+}
+
+/*******************************************************************************
+**
+** Function nfa_hci_assemble_msg
+**
+** Description Reassemble the incoming message
+**
+** Returns None
+**
+*******************************************************************************/
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+static void nfa_hci_assemble_msg (UINT8 *p_data, UINT16 data_len, UINT8 pipe)
+#else
+static void nfa_hci_assemble_msg (UINT8 *p_data, UINT16 data_len)
+#endif
+{
+#if (NFC_NXP_NOT_OPEN_INCLUDED == 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 */
+ 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;
+ 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));
+ }
+ 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))
+ {
+ if ((nfa_hci_cb.evt_len + data_len) > nfa_hci_cb.max_evt_len)
+ {
+ /* Fill the buffer as much it can hold */
+ 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;
+ 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));
+ }
+ 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 BOOLEAN nfa_hci_evt_hdlr (BT_HDR *p_msg)
+{
+ tNFA_HCI_EVENT_DATA *p_evt_data = (tNFA_HCI_EVENT_DATA *)p_msg;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ NFA_TRACE_EVENT4 ("nfa_hci_evt_hdlr state: %s (%d) event: %s (0x%04x)",
+ nfa_hciu_get_state_name (nfa_hci_cb.hci_state), nfa_hci_cb.hci_state,
+ nfa_hciu_get_event_name (p_evt_data->hdr.event), p_evt_data->hdr.event);
+#else
+ NFA_TRACE_EVENT2 ("nfa_hci_evt_hdlr state: %d event: 0x%04x", nfa_hci_cb.hci_state, p_evt_data->hdr.event);
+#endif
+
+ /* If this is an API request, queue it up */
+ if ((p_msg->event >= NFA_HCI_FIRST_API_EVENT) && (p_msg->event <= NFA_HCI_LAST_API_EVENT))
+ {
+ GKI_enqueue (&nfa_hci_cb.hci_api_q, p_msg);
+ }
+ else
+ {
+ switch (p_msg->event)
+ {
+ case NFA_HCI_RSP_NV_READ_EVT:
+ nfa_hci_handle_nv_read (p_evt_data->nv_read.block, p_evt_data->nv_read.status);
+ break;
+
+ case NFA_HCI_RSP_NV_WRITE_EVT:
+ /* NV Ram write completed - nothing to do... */
+ break;
+
+ case NFA_HCI_RSP_TIMEOUT_EVT:
+ nfa_hci_rsp_timeout ((tNFA_HCI_EVENT_DATA *)p_msg);
+ break;
+
+ case NFA_HCI_CHECK_QUEUE_EVT:
+ if (HCI_LOOPBACK_DEBUG)
+ {
+ if (p_msg->len != 0)
+ {
+ tNFC_DATA_CEVT xx;
+ xx.p_data = p_msg;
+ nfa_hci_conn_cback (0, NFC_DATA_CEVT, (tNFC_CONN *)&xx);
+ return FALSE;
+ }
+ }
+ break;
+ }
+ }
+
+ if ((p_msg->event > NFA_HCI_LAST_API_EVENT))
+ GKI_freebuf (p_msg);
+
+ nfa_hci_check_api_requests ();
+
+ if (nfa_hciu_is_no_host_resetting ())
+ nfa_hci_check_pending_api_requests ();
+
+ if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) && (nfa_hci_cb.nv_write_needed))
+ {
+ nfa_hci_cb.nv_write_needed = FALSE;
+ nfa_nv_co_write ((UINT8 *)&nfa_hci_cb.cfg, sizeof (nfa_hci_cb.cfg),DH_NV_BLOCK);
+ }
+
+ return FALSE;
+}
+
+#if (NFC_NXP_NOT_OPEN_INCLUDED == 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);
+ }
+}
+#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..37906ff
--- /dev/null
+++ b/src/nfa/hci/nfa_hci_utils.c
@@ -0,0 +1,1473 @@
+/******************************************************************************
+ *
+ * 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 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 (BT_HDR *p_buf, UINT8 pipe, UINT8 type, UINT8 instruction);
+BOOLEAN HCI_LOOPBACK_DEBUG = FALSE;
+
+/*******************************************************************************
+**
+** Function nfa_hciu_find_pipe_by_pid
+**
+** Description look for the pipe control block based on pipe id
+**
+** Returns pointer to the pipe control block, or NULL if not found
+**
+*******************************************************************************/
+tNFA_HCI_DYN_PIPE *nfa_hciu_find_pipe_by_pid (UINT8 pipe_id)
+{
+ tNFA_HCI_DYN_PIPE *pp = nfa_hci_cb.cfg.dyn_pipes;
+ int xx = 0;
+
+ /* Loop through looking for a match */
+ for ( ; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
+ {
+ if (pp->pipe_id == pipe_id)
+ return (pp);
+ }
+
+ /* If here, not found */
+ return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_find_gate_by_gid
+**
+** Description Find the gate control block for the given gate id
+**
+** Returns pointer to the gate control block, or NULL if not found
+**
+*******************************************************************************/
+tNFA_HCI_DYN_GATE *nfa_hciu_find_gate_by_gid (UINT8 gate_id)
+{
+ tNFA_HCI_DYN_GATE *pg = nfa_hci_cb.cfg.dyn_gates;
+ int xx = 0;
+
+ for ( ; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
+ {
+ if (pg->gate_id == gate_id)
+ return (pg);
+ }
+
+ return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_find_gate_by_owner
+**
+** Description Find the the first gate control block for the given owner
+**
+** Returns pointer to the gate control block, or NULL if not found
+**
+*******************************************************************************/
+tNFA_HCI_DYN_GATE *nfa_hciu_find_gate_by_owner (tNFA_HANDLE app_handle)
+{
+ tNFA_HCI_DYN_GATE *pg = nfa_hci_cb.cfg.dyn_gates;
+ int xx = 0;
+
+ for ( ; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
+ {
+ if (pg->gate_owner == app_handle)
+ return (pg);
+ }
+
+ return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_find_gate_with_nopipes_by_owner
+**
+** Description Find the the first gate control block with no pipes
+** for the given owner
+**
+** Returns pointer to the gate control block, or NULL if not found
+**
+*******************************************************************************/
+tNFA_HCI_DYN_GATE *nfa_hciu_find_gate_with_nopipes_by_owner (tNFA_HANDLE app_handle)
+{
+ tNFA_HCI_DYN_GATE *pg = nfa_hci_cb.cfg.dyn_gates;
+ int xx = 0;
+
+ for ( ; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
+ {
+ if ( (pg->gate_owner == app_handle)
+ &&(pg->pipe_inx_mask == 0) )
+ return (pg);
+ }
+
+ return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_count_pipes_on_gate
+**
+** Description Count the number of pipes on the given gate
+**
+** Returns the number of pipes on the gate
+**
+*******************************************************************************/
+UINT8 nfa_hciu_count_pipes_on_gate (tNFA_HCI_DYN_GATE *p_gate)
+{
+ int xx = 0;
+ UINT32 mask = 1;
+ UINT8 count = 0;
+
+ for ( ; xx < NFA_HCI_MAX_PIPE_CB; xx++)
+ {
+ if ( p_gate->pipe_inx_mask & mask )
+ count++;
+
+ mask = mask << 1;
+ }
+
+ return (count);
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_count_open_pipes_on_gate
+**
+** Description Count the number of opened pipes on the given gate
+**
+** Returns the number of pipes in OPENED state on the gate
+**
+*******************************************************************************/
+UINT8 nfa_hciu_count_open_pipes_on_gate (tNFA_HCI_DYN_GATE *p_gate)
+{
+ tNFA_HCI_DYN_PIPE *pp = nfa_hci_cb.cfg.dyn_pipes;
+ int xx = 0;
+ UINT32 mask = 1;
+ UINT8 count = 0;
+
+ for ( ; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
+ {
+ /* For each pipe on this gate, check if it is open */
+ if ((p_gate->pipe_inx_mask & mask) && (pp->pipe_state == NFA_HCI_PIPE_OPENED))
+ count++;
+
+ mask = mask << 1;
+ }
+
+ return (count);
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_get_gate_owner
+**
+** Description Find the application that owns a gate
+**
+** Returns application handle
+**
+*******************************************************************************/
+tNFA_HANDLE nfa_hciu_get_gate_owner (UINT8 gate_id)
+{
+ tNFA_HCI_DYN_GATE *pg;
+
+ if ((pg = nfa_hciu_find_gate_by_gid (gate_id)) == NULL)
+ return (NFA_HANDLE_INVALID);
+
+ return (pg->gate_owner);
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_get_pipe_owner
+**
+** Description Find the application that owns a pipe
+**
+** Returns application handle
+**
+*******************************************************************************/
+tNFA_HANDLE nfa_hciu_get_pipe_owner (UINT8 pipe_id)
+{
+ tNFA_HCI_DYN_PIPE *pp;
+ tNFA_HCI_DYN_GATE *pg;
+
+ if ((pp = nfa_hciu_find_pipe_by_pid (pipe_id)) == NULL)
+ return (NFA_HANDLE_INVALID);
+
+ if ((pg = nfa_hciu_find_gate_by_gid (pp->local_gate)) == NULL)
+ return (NFA_HANDLE_INVALID);
+
+ return (pg->gate_owner);
+}
+
+
+/*******************************************************************************
+**
+** Function nfa_hciu_alloc_gate
+**
+** Description Allocate an gate control block
+**
+** Returns pointer to the allocated gate, or NULL if cannot allocate
+**
+*******************************************************************************/
+tNFA_HCI_DYN_GATE *nfa_hciu_alloc_gate (UINT8 gate_id, tNFA_HANDLE app_handle)
+{
+ tNFA_HCI_DYN_GATE *pg;
+ int xx;
+ UINT8 app_inx = app_handle & NFA_HANDLE_MASK;
+
+
+ /* First, check if the application handle is valid */
+ if ( (gate_id != NFA_HCI_CONNECTIVITY_GATE)
+ &&(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)
+ {
+ if ((pg = nfa_hciu_find_gate_by_gid (gate_id)) != NULL)
+ return (pg);
+ }
+ else
+ {
+ /* If gate_id is 0, we need to assign a free one */
+ /* Loop through all possible gate IDs checking if they are already used */
+ for (gate_id = NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE; gate_id <= NFA_HCI_LAST_PROP_GATE; gate_id++)
+ {
+ /* Skip connectivity gate */
+ if (gate_id == NFA_HCI_CONNECTIVITY_GATE) gate_id++;
+
+ /* Check if the gate is already allocated */
+ if (nfa_hciu_find_gate_by_gid (gate_id) == NULL)
+ break;
+ }
+ if (gate_id > NFA_HCI_LAST_PROP_GATE)
+ {
+ NFA_TRACE_ERROR2 ("nfa_hci_alloc_gate - no free Gate ID: %u App Handle: 0x%04x", gate_id, app_handle);
+ return (NULL);
+ }
+ }
+
+ /* Now look for a free control block */
+ for (xx = 0, pg = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
+ {
+ if (pg->gate_id == 0)
+ {
+ /* Found a free gate control block */
+ pg->gate_id = gate_id;
+ pg->gate_owner = app_handle;
+ pg->pipe_inx_mask = 0;
+
+ NFA_TRACE_DEBUG2 ("nfa_hciu_alloc_gate id:%d app_handle: 0x%04x", gate_id, app_handle);
+
+ nfa_hci_cb.nv_write_needed = TRUE;
+ return (pg);
+ }
+ }
+
+ /* If here, no free gate control block */
+ NFA_TRACE_ERROR2 ("nfa_hci_alloc_gate - no CB Gate ID: %u App Handle: 0x%04x", gate_id, app_handle);
+ return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_send_msg
+**
+** Description This function will fragment the given packet, if necessary
+** and send it on the given pipe.
+**
+** Returns status
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hciu_send_msg (UINT8 pipe_id, UINT8 type, UINT8 instruction, UINT16 msg_len, UINT8 *p_msg)
+{
+ BT_HDR *p_buf;
+ UINT8 *p_data;
+ BOOLEAN first_pkt = TRUE;
+ UINT16 data_len;
+ tNFA_STATUS status = NFA_STATUS_OK;
+ UINT16 max_seg_hcp_pkt_size = nfa_hci_cb.buff_size;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ char buff[100];
+
+ 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;
+
+ while ((first_pkt == TRUE) || (msg_len != 0))
+ {
+ if ((p_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL)
+ {
+ p_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+ /* First packet has a 2-byte header, subsequent fragments have a 1-byte header */
+ data_len = first_pkt ? (max_seg_hcp_pkt_size - 2) : (max_seg_hcp_pkt_size - 1);
+
+ p_data = (UINT8 *) (p_buf + 1) + p_buf->offset;
+
+ /* Last or only segment has "no fragmentation" bit set */
+ if (msg_len > data_len)
+ {
+ *p_data++ = (NFA_HCI_MESSAGE_FRAGMENTATION << 7) | (pipe_id & 0x7F);
+ }
+ else
+ {
+ data_len = msg_len;
+ *p_data++ = (NFA_HCI_NO_MESSAGE_FRAGMENTATION << 7) | (pipe_id & 0x7F);
+ }
+
+ p_buf->len = 1;
+
+ /* Message header only goes in the first segment */
+ if (first_pkt)
+ {
+ first_pkt = FALSE;
+ *p_data++ = (type << 6) | instruction;
+ p_buf->len++;
+ }
+
+ if (data_len != 0)
+ {
+ memcpy (p_data, p_msg, data_len);
+
+ p_buf->len += data_len;
+ msg_len -= data_len;
+ if (msg_len > 0)
+ p_msg += data_len;
+ }
+
+#if (BT_TRACE_PROTOCOL == TRUE)
+ DispHcp (((UINT8 *) (p_buf + 1) + p_buf->offset), p_buf->len, FALSE, (BOOLEAN) ((p_buf->len - data_len) == 2));
+#endif
+
+ if (HCI_LOOPBACK_DEBUG)
+ handle_debug_loopback (p_buf, pipe_id, type, instruction);
+ else
+ status = NFC_SendData (nfa_hci_cb.conn_id, p_buf);
+ }
+ else
+ {
+ NFA_TRACE_ERROR0 ("nfa_hciu_send_data_packet no buffers");
+ status = NFA_STATUS_NO_BUFFERS;
+ break;
+ }
+ }
+
+ /* Start timer if response to wait for a particular time for the response */
+ if (type == NFA_HCI_COMMAND_TYPE)
+ {
+ nfa_hci_cb.cmd_sent = instruction;
+
+ if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE)
+ nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_RSP;
+ nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, p_nfa_hci_cfg->hcp_response_timeout);
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_get_allocated_gate_list
+**
+** Description fills in a list of allocated gates
+**
+** Returns the number of gates
+**
+*******************************************************************************/
+UINT8 nfa_hciu_get_allocated_gate_list (UINT8 *p_gate_list)
+{
+ tNFA_HCI_DYN_GATE *p_cb;
+ int xx;
+ UINT8 count = 0;
+
+ for (xx = 0, p_cb = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB; xx++, p_cb++)
+ {
+ if (p_cb->gate_id != 0)
+ {
+ *p_gate_list++ = p_cb->gate_id;
+ count++;
+ }
+ }
+
+ NFA_TRACE_DEBUG1 ("nfa_hciu_get_allocated_gate_list () returns: %u", count);
+
+ return (count);
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_alloc_pipe
+**
+** Description Allocate a pipe control block
+**
+** Returns pointer to the pipe control block, or NULL if
+** cannot allocate
+**
+*******************************************************************************/
+tNFA_HCI_DYN_PIPE *nfa_hciu_alloc_pipe (UINT8 pipe_id)
+{
+ UINT8 xx;
+ tNFA_HCI_DYN_PIPE *pp;
+
+ /* If we already have a pipe of the same ID, release it first it */
+ if ((pp = nfa_hciu_find_pipe_by_pid (pipe_id)) != NULL)
+ {
+ if (pipe_id > NFA_HCI_LAST_DYNAMIC_PIPE)
+ return pp;
+ nfa_hciu_release_pipe (pipe_id);
+ }
+
+ /* Look for a free pipe control block */
+ for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes ; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
+ {
+ if (pp->pipe_id == 0)
+ {
+ NFA_TRACE_DEBUG2 ("nfa_hciu_alloc_pipe:%d, index:%d", pipe_id, xx);
+ pp->pipe_id = pipe_id;
+
+ nfa_hci_cb.nv_write_needed = TRUE;
+ return (pp);
+ }
+ }
+
+ NFA_TRACE_DEBUG1 ("nfa_hciu_alloc_pipe:%d, NO free entries !!", pipe_id);
+ return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_release_gate
+**
+** Description Remove a generic gate from gate list
+**
+** Returns none
+**
+*******************************************************************************/
+void nfa_hciu_release_gate (UINT8 gate_id)
+{
+ tNFA_HCI_DYN_GATE *p_gate = nfa_hciu_find_gate_by_gid (gate_id);
+
+ if (p_gate != NULL)
+ {
+ NFA_TRACE_DEBUG3 ("nfa_hciu_release_gate () ID: %d owner: 0x%04x pipe_inx_mask: 0x%04x",
+ gate_id, p_gate->gate_owner, p_gate->pipe_inx_mask);
+
+ p_gate->gate_id = 0;
+ p_gate->gate_owner = 0;
+ p_gate->pipe_inx_mask = 0;
+
+ nfa_hci_cb.nv_write_needed = TRUE;
+ }
+ else
+ {
+ NFA_TRACE_WARNING1 ("nfa_hciu_release_gate () ID: %d NOT FOUND", gate_id);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_add_pipe_to_gate
+**
+** Description Add pipe to generic gate
+**
+** Returns NFA_STATUS_OK, if successfully add the pipe on to the gate
+** NFA_HCI_ADM_E_NO_PIPES_AVAILABLE, otherwise
+**
+*******************************************************************************/
+tNFA_HCI_RESPONSE nfa_hciu_add_pipe_to_gate (UINT8 pipe_id, UINT8 local_gate,
+ UINT8 dest_host, UINT8 dest_gate)
+{
+ tNFA_HCI_DYN_GATE *p_gate;
+ tNFA_HCI_DYN_PIPE *p_pipe;
+ UINT8 pipe_index;
+
+ p_gate = nfa_hciu_find_gate_by_gid (local_gate);
+
+ if (p_gate != NULL)
+ {
+ /* Allocate a pipe control block */
+ if ((p_pipe = nfa_hciu_alloc_pipe (pipe_id)) != NULL)
+ {
+ p_pipe->pipe_id = pipe_id;
+ p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
+ p_pipe->dest_host = dest_host;
+ p_pipe->dest_gate = dest_gate;
+ p_pipe->local_gate = local_gate;
+
+ /* Save the pipe in the gate that it belongs to */
+ pipe_index = (UINT8) (p_pipe - nfa_hci_cb.cfg.dyn_pipes);
+ p_gate->pipe_inx_mask |= (UINT32) (1 << pipe_index);
+
+ NFA_TRACE_DEBUG4 ("nfa_hciu_add_pipe_to_gate Gate ID: 0x%02x Pipe ID: 0x%02x pipe_index: %u App Handle: 0x%08x",
+ local_gate, pipe_id, pipe_index, p_gate->gate_owner);
+ return (NFA_HCI_ANY_OK);
+ }
+ }
+
+ NFA_TRACE_DEBUG1 ("nfa_hciu_add_pipe_to_gate: 0x%02x NOT FOUND", local_gate);
+
+ return (NFA_HCI_ADM_E_NO_PIPES_AVAILABLE);
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_add_pipe_to_static_gate
+**
+** Description Add pipe to identity management gate
+**
+** Returns NFA_HCI_ANY_OK, if successfully add the pipe on to the gate
+** NFA_HCI_ADM_E_NO_PIPES_AVAILABLE, otherwise
+**
+*******************************************************************************/
+tNFA_HCI_RESPONSE nfa_hciu_add_pipe_to_static_gate (UINT8 local_gate, UINT8 pipe_id, UINT8 dest_host, UINT8 dest_gate)
+{
+ tNFA_HCI_DYN_PIPE *p_pipe;
+ UINT8 pipe_index;
+
+ NFA_TRACE_EVENT4 ("nfa_hciu_add_pipe_to_static_gate (%u) Pipe: 0x%02x Dest Host: 0x%02x Dest Gate: 0x%02x)",
+ local_gate, pipe_id, dest_host, dest_gate);
+
+ /* Allocate a pipe control block */
+ if ((p_pipe = nfa_hciu_alloc_pipe (pipe_id)) != NULL)
+ {
+ p_pipe->pipe_id = pipe_id;
+ p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
+ p_pipe->dest_host = dest_host;
+ p_pipe->dest_gate = dest_gate;
+ p_pipe->local_gate = local_gate;
+
+ /* If this is the ID gate, save the pipe index in the ID gate info */
+ /* block. Note that for loopback, it is enough to just create the pipe */
+ if (local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE)
+ {
+ pipe_index = (UINT8) (p_pipe - nfa_hci_cb.cfg.dyn_pipes);
+ nfa_hci_cb.cfg.id_mgmt_gate.pipe_inx_mask |= (UINT32) (1 << pipe_index);
+ }
+ return NFA_HCI_ANY_OK;
+ }
+
+ return NFA_HCI_ADM_E_NO_PIPES_AVAILABLE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_find_active_pipe_by_owner
+**
+** Description Find the first pipe associated with the given app
+**
+** Returns pointer to pipe, or NULL if none found
+**
+*******************************************************************************/
+tNFA_HCI_DYN_PIPE *nfa_hciu_find_active_pipe_by_owner (tNFA_HANDLE app_handle)
+{
+ tNFA_HCI_DYN_GATE *pg;
+ tNFA_HCI_DYN_PIPE *pp;
+ int xx;
+
+ NFA_TRACE_DEBUG1 ("nfa_hciu_find_pipe_by_owner () app_handle:0x%x", app_handle);
+
+ /* Loop through all pipes looking for the owner */
+ for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
+ {
+ if ( (pp->pipe_id != 0)
+ &&(pp->pipe_id >= NFA_HCI_FIRST_DYNAMIC_PIPE)
+ &&(pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE)
+ &&(nfa_hciu_is_active_host (pp->dest_host)) )
+ {
+ if ( ((pg = nfa_hciu_find_gate_by_gid (pp->local_gate)) != NULL)
+ &&(pg->gate_owner == app_handle) )
+ return (pp);
+ }
+ }
+
+ /* If here, not found */
+ return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_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
+**
+*******************************************************************************/
+BOOLEAN nfa_hciu_check_pipe_between_gates (UINT8 local_gate, UINT8 dest_host, UINT8 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 gate_id)
+{
+ tNFA_HCI_DYN_GATE *pg;
+ tNFA_HCI_DYN_PIPE *pp;
+ int xx;
+
+ NFA_TRACE_DEBUG1 ("nfa_hciu_find_pipe_on_gate () Gate:0x%x", gate_id);
+
+ /* Loop through all pipes looking for the owner */
+ for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
+ {
+ if (pp->pipe_id != 0)
+ {
+ if ( ((pg = nfa_hciu_find_gate_by_gid (pp->local_gate)) != NULL)
+ &&(pg->gate_id == gate_id) )
+ return (pp);
+ }
+ }
+
+ /* If here, not found */
+ return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_is_active_host
+**
+** Description Check if the host is currently active
+**
+** Returns TRUE, if the host is active in the host network
+** FALSE, if the host is not active in the host network
+**
+*******************************************************************************/
+BOOLEAN nfa_hciu_is_active_host (UINT8 host_id)
+{
+ UINT8 xx;
+
+ for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++)
+ {
+ if (nfa_hci_cb.inactive_host[xx] == host_id)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_is_host_reseting
+**
+** Description Check if the host is currently reseting
+**
+** Returns TRUE, if the host is reseting
+** FALSE, if the host is not reseting
+**
+*******************************************************************************/
+BOOLEAN nfa_hciu_is_host_reseting (UINT8 host_id)
+{
+ UINT8 xx;
+
+ for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++)
+ {
+ if (nfa_hci_cb.reset_host[xx] == host_id)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_is_no_host_resetting
+**
+** Description Check if no host is reseting
+**
+** Returns TRUE, if no host is resetting at this time
+** FALSE, if one or more host is resetting
+**
+*******************************************************************************/
+BOOLEAN nfa_hciu_is_no_host_resetting (void)
+{
+ UINT8 xx;
+
+ for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++)
+ {
+ if (nfa_hci_cb.reset_host[xx] != 0)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_find_active_pipe_on_gate
+**
+** Description Find the first active pipe associated with the given gate
+**
+** Returns pointer to pipe, or NULL if none found
+**
+*******************************************************************************/
+tNFA_HCI_DYN_PIPE *nfa_hciu_find_active_pipe_on_gate (UINT8 gate_id)
+{
+ tNFA_HCI_DYN_GATE *pg;
+ tNFA_HCI_DYN_PIPE *pp;
+ int xx;
+
+ NFA_TRACE_DEBUG1 ("nfa_hciu_find_active_pipe_on_gate () Gate:0x%x", gate_id);
+
+ /* Loop through all pipes looking for the owner */
+ for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
+ {
+ if ( (pp->pipe_id != 0)
+ &&(pp->pipe_id >= NFA_HCI_FIRST_DYNAMIC_PIPE)
+ &&(pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE)
+ &&(nfa_hciu_is_active_host (pp->dest_host)) )
+ {
+ if ( ((pg = nfa_hciu_find_gate_by_gid (pp->local_gate)) != NULL)
+ &&(pg->gate_id == gate_id) )
+ return (pp);
+ }
+ }
+
+ /* If here, not found */
+ return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_release_pipe
+**
+** Description remove the specified pipe
+**
+** Returns NFA_HCI_ANY_OK, if removed
+** NFA_HCI_ANY_E_NOK, if otherwise
+**
+*******************************************************************************/
+tNFA_HCI_RESPONSE nfa_hciu_release_pipe (UINT8 pipe_id)
+{
+ tNFA_HCI_DYN_GATE *p_gate;
+ tNFA_HCI_DYN_PIPE *p_pipe;
+ UINT8 pipe_index;
+
+ NFA_TRACE_EVENT1 ("nfa_hciu_release_pipe: %u", pipe_id);
+
+ if ((p_pipe = nfa_hciu_find_pipe_by_pid (pipe_id)) == NULL)
+ return (NFA_HCI_ANY_E_NOK);
+
+ if (pipe_id > NFA_HCI_LAST_DYNAMIC_PIPE)
+ {
+ NFA_TRACE_DEBUG1 ("ignore pipe: %d", pipe_id);
+ return (NFA_HCI_ANY_E_NOK);
+ }
+
+ pipe_index = (UINT8) (p_pipe - nfa_hci_cb.cfg.dyn_pipes);
+
+ if (p_pipe->local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE)
+ {
+ /* Remove pipe from ID management gate */
+ nfa_hci_cb.cfg.id_mgmt_gate.pipe_inx_mask &= ~ (UINT32) (1 << pipe_index);
+ }
+ else
+ {
+ if ((p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate)) == NULL)
+ {
+ /* Mark the pipe control block as free */
+ p_pipe->pipe_id = 0;
+ return (NFA_HCI_ANY_E_NOK);
+ }
+
+ /* Remove pipe from gate */
+ p_gate->pipe_inx_mask &= ~ (UINT32) (1 << pipe_index);
+ }
+
+ /* Reset pipe control block */
+ memset (p_pipe,0,sizeof (tNFA_HCI_DYN_PIPE));
+ nfa_hci_cb.nv_write_needed = TRUE;
+ return NFA_HCI_ANY_OK;
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_remove_all_pipes_from_host
+**
+** Description remove all the pipes that are connected to a specific host
+**
+** Returns None
+**
+*******************************************************************************/
+void nfa_hciu_remove_all_pipes_from_host (UINT8 host)
+{
+ tNFA_HCI_DYN_GATE *pg;
+ tNFA_HCI_DYN_PIPE *pp;
+ int xx;
+ tNFA_HCI_EVT_DATA evt_data;
+
+ NFA_TRACE_EVENT1 ("nfa_hciu_remove_all_pipes_from_host (0x%02x)", host);
+
+ /* Remove all pipes from the specified host connected to all generic gates */
+ for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
+ {
+ if ( (pp->pipe_id == 0)
+ ||
+ ( (host != 0)
+ &&((pp->dest_host != host) || (pp->pipe_id > NFA_HCI_LAST_DYNAMIC_PIPE))) )
+ continue;
+
+ if ((pg = nfa_hciu_find_gate_by_gid (pp->local_gate)) != NULL)
+ {
+ evt_data.deleted.status = NFA_STATUS_OK;
+ evt_data.deleted.pipe = pp->pipe_id;
+
+ nfa_hciu_send_to_app (NFA_HCI_DELETE_PIPE_EVT, &evt_data, pg->gate_owner);
+ }
+ nfa_hciu_release_pipe (pp->pipe_id);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_send_create_pipe_cmd
+**
+** Description Create dynamic pipe between the specified gates
+**
+** Returns status
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hciu_send_create_pipe_cmd (UINT8 source_gate, UINT8 dest_host, UINT8 dest_gate)
+{
+ tNFA_STATUS status;
+ UINT8 data[3];
+
+ data[0] = source_gate;
+ data[1] = dest_host;
+ data[2] = dest_gate;
+
+ NFA_TRACE_DEBUG3 ("nfa_hciu_send_create_pipe_cmd source_gate:%d, dest_host:%d, dest_gate:%d", source_gate, dest_host, dest_gate);
+
+ status = nfa_hciu_send_msg (NFA_HCI_ADMIN_PIPE, NFA_HCI_COMMAND_TYPE, NFA_HCI_ADM_CREATE_PIPE, 3, data);
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_send_delete_pipe_cmd
+**
+** Description Delete the dynamic pipe
+**
+** Returns None
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hciu_send_delete_pipe_cmd (UINT8 pipe)
+{
+ tNFA_STATUS status;
+
+ NFA_TRACE_DEBUG1 ("nfa_hciu_send_delete_pipe_cmd: %d", pipe);
+
+ if (pipe > NFA_HCI_LAST_DYNAMIC_PIPE)
+ {
+ NFA_TRACE_DEBUG1 ("ignore pipe: %d", pipe);
+ return (NFA_HCI_ANY_E_NOK);
+ }
+ nfa_hci_cb.pipe_in_use = pipe;
+
+ status = nfa_hciu_send_msg (NFA_HCI_ADMIN_PIPE, NFA_HCI_COMMAND_TYPE, NFA_HCI_ADM_DELETE_PIPE, 1, &pipe);
+
+ return status;
+}
+
+
+/*******************************************************************************
+**
+** Function nfa_hciu_send_clear_all_pipe_cmd
+**
+** Description delete all the dynamic pipe connected to device host,
+** to close all static pipes connected to device host,
+** and to set registry values related to static pipes to
+** theri default values.
+**
+** Returns None
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hciu_send_clear_all_pipe_cmd (void)
+{
+ tNFA_STATUS status;
+ UINT16 id_ref_data = 0x0102;
+
+ NFA_TRACE_DEBUG0 ("nfa_hciu_send_clear_all_pipe_cmd");
+
+ status = nfa_hciu_send_msg (NFA_HCI_ADMIN_PIPE, NFA_HCI_COMMAND_TYPE, NFA_HCI_ADM_CLEAR_ALL_PIPE, 2, (UINT8 *) &id_ref_data);
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_send_open_pipe_cmd
+**
+** Description Open a closed pipe
+**
+** Returns status
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hciu_send_open_pipe_cmd (UINT8 pipe)
+{
+ tNFA_STATUS status;
+
+ nfa_hci_cb.pipe_in_use = pipe;
+
+ status = nfa_hciu_send_msg (pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_OPEN_PIPE, 0, NULL);
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_send_close_pipe_cmd
+**
+** Description Close an opened pipe
+**
+** Returns status
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hciu_send_close_pipe_cmd (UINT8 pipe)
+{
+ tNFA_STATUS status;
+
+ nfa_hci_cb.pipe_in_use = pipe;
+
+ status = nfa_hciu_send_msg (pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_CLOSE_PIPE, 0, NULL);
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_send_get_param_cmd
+**
+** Description Read a parameter value from gate registry
+**
+** Returns None
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hciu_send_get_param_cmd (UINT8 pipe, UINT8 index)
+{
+ tNFA_STATUS status;
+
+ if ((status = nfa_hciu_send_msg (pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_GET_PARAMETER, 1, &index)) == NFC_STATUS_OK)
+ nfa_hci_cb.param_in_use = index;
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_send_set_param_cmd
+**
+** Description Set a parameter value in a gate registry
+**
+** Returns None
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hciu_send_set_param_cmd (UINT8 pipe, UINT8 index, UINT8 length, UINT8 *p_data)
+{
+ tNFA_STATUS status;
+ UINT8 data[255];
+
+ data[0] = index;
+
+ memcpy (&data[1], p_data, length);
+
+ if ((status = nfa_hciu_send_msg (pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_SET_PARAMETER, (UINT16) (length + 1), data)) == NFC_STATUS_OK)
+ nfa_hci_cb.param_in_use = index;
+
+ return status;
+}
+
+
+/*******************************************************************************
+**
+** Function nfa_hciu_send_to_app
+**
+** Description Send an event back to an application
+**
+** Returns none
+**
+*******************************************************************************/
+void nfa_hciu_send_to_app (tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA *p_evt, tNFA_HANDLE app_handle)
+{
+ UINT8 app_inx = app_handle & NFA_HANDLE_MASK;
+
+ /* First, check if the application handle is valid */
+ if ( ((app_handle & NFA_HANDLE_GROUP_MASK) == NFA_HANDLE_GROUP_HCI)
+ &&(app_inx < NFA_HCI_MAX_APP_CB) )
+ {
+ if (nfa_hci_cb.p_app_cback[app_inx] != NULL)
+ {
+ nfa_hci_cb.p_app_cback[app_inx] (event, p_evt);
+ return;
+ }
+ }
+
+ if (app_handle != NFA_HANDLE_INVALID)
+ {
+ NFA_TRACE_WARNING2 ("nfa_hciu_send_to_app no callback, event: 0x%04x app_handle: 0x%04x",
+ event, app_handle);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_send_to_all_apps
+**
+** Description Send an event back to all applications
+**
+** Returns none
+**
+*******************************************************************************/
+void nfa_hciu_send_to_all_apps (tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA *p_evt)
+{
+ UINT8 app_inx;
+
+ for (app_inx = 0; app_inx < NFA_HCI_MAX_APP_CB; app_inx++)
+ {
+ if (nfa_hci_cb.p_app_cback[app_inx] != NULL)
+ nfa_hci_cb.p_app_cback[app_inx] (event, p_evt);
+ }
+
+}
+
+/*******************************************************************************
+**
+** Function nfa_hciu_send_to_apps_handling_connectivity_evts
+**
+** Description Send a connectivity event to all the application interested
+** in connectivity events
+**
+** Returns none
+**
+*******************************************************************************/
+void nfa_hciu_send_to_apps_handling_connectivity_evts (tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA *p_evt)
+{
+ UINT8 app_inx;
+
+ for (app_inx = 0; app_inx < NFA_HCI_MAX_APP_CB; app_inx++)
+ {
+ if ( (nfa_hci_cb.p_app_cback[app_inx] != NULL)
+ &&(nfa_hci_cb.cfg.b_send_conn_evts[app_inx]))
+
+ nfa_hci_cb.p_app_cback[app_inx] (event, p_evt);
+ }
+
+}
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function nfa_hciu_get_response_name
+**
+** Description This function returns the error code name.
+**
+** NOTE conditionally compiled to save memory.
+**
+** Returns pointer to the name
+**
+*******************************************************************************/
+char *nfa_hciu_get_response_name (UINT8 rsp_code)
+{
+ 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 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 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 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");
+
+ 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 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");
+
+ 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 pipe, UINT8 type, UINT8 inst, char *p_buff)
+{
+ int xx;
+
+ xx = sprintf (p_buff, "Type: %s [0x%02x] ", nfa_hciu_type_2_str (type), type);
+
+ switch (type)
+ {
+ case NFA_HCI_COMMAND_TYPE:
+ sprintf (&p_buff[xx], "Inst: %s [0x%02x] ", nfa_hciu_instr_2_str (inst), inst);
+ break;
+ case NFA_HCI_EVENT_TYPE:
+ sprintf (&p_buff[xx], "Evt: %s [0x%02x] ", nfa_hciu_evt_2_str (pipe, inst), inst);
+ break;
+ case NFA_HCI_RESPONSE_TYPE:
+ sprintf (&p_buff[xx], "Resp: %s [0x%02x] ", nfa_hciu_get_response_name (inst), inst);
+ break;
+ default:
+ sprintf (&p_buff[xx], "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 pipe_id, UINT8 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");
+ default:
+ return ("UNKNOWN");
+ }
+}
+#endif
+
+
+static void handle_debug_loopback (BT_HDR *p_buf, UINT8 pipe, UINT8 type, UINT8 instruction)
+{
+ UINT8 *p = (UINT8 *) (p_buf + 1) + p_buf->offset;
+ static UINT8 next_pipe = 0x10;
+
+ if (type == NFA_HCI_COMMAND_TYPE)
+ {
+ switch (instruction)
+ {
+ case NFA_HCI_ADM_CREATE_PIPE:
+ p[6] = next_pipe++;
+ p[5] = p[4];
+ p[4] = p[3];
+ p[3] = p[2];
+ p[2] = 3;
+ p[1] = (NFA_HCI_RESPONSE_TYPE << 6) | NFA_HCI_ANY_OK;
+ p_buf->len = p_buf->offset + 7;
+ break;
+
+ case NFA_HCI_ANY_GET_PARAMETER:
+ p[1] = (NFA_HCI_RESPONSE_TYPE << 6) | NFA_HCI_ANY_OK;
+ memcpy (&p[2], (UINT8 *) nfa_hci_cb.cfg.admin_gate.session_id, NFA_HCI_SESSION_ID_LEN);
+ p_buf->len = p_buf->offset + 2 + NFA_HCI_SESSION_ID_LEN;
+ break;
+
+ default:
+ p[1] = (NFA_HCI_RESPONSE_TYPE << 6) | NFA_HCI_ANY_OK;
+ p_buf->len = p_buf->offset + 2;
+ break;
+ }
+ }
+ else if (type == NFA_HCI_RESPONSE_TYPE)
+ {
+ GKI_freebuf (p_buf);
+ return;
+ }
+
+ p_buf->event = NFA_HCI_CHECK_QUEUE_EVT;
+ nfa_sys_sendmsg (p_buf);
+}
diff --git a/src/nfa/include/nfa_api.h b/src/nfa/include/nfa_api.h
new file mode 100644
index 0000000..f335eda
--- /dev/null
+++ b/src/nfa/include/nfa_api.h
@@ -0,0 +1,1387 @@
+/******************************************************************************
+ *
+ * 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 */
+
+/* NFA API return status codes */
+#define NFA_STATUS_OK NCI_STATUS_OK /* Command succeeded */
+#define NFA_STATUS_REJECTED NCI_STATUS_REJECTED /* Command is rejected. */
+#define NFA_STATUS_MSG_CORRUPTED NCI_STATUS_MESSAGE_CORRUPTED /* Message is corrupted */
+#define NFA_STATUS_BUFFER_FULL NCI_STATUS_BUFFER_FULL /* buffer full */
+#define NFA_STATUS_FAILED NCI_STATUS_FAILED /* failed */
+#define NFA_STATUS_NOT_INITIALIZED NCI_STATUS_NOT_INITIALIZED /* not initialized */
+#define NFA_STATUS_SYNTAX_ERROR NCI_STATUS_SYNTAX_ERROR /* Syntax error */
+#define NFA_STATUS_SEMANTIC_ERROR NCI_STATUS_SEMANTIC_ERROR /* Semantic error */
+#define NFA_STATUS_UNKNOWN_GID NCI_STATUS_UNKNOWN_GID /* Unknown NCI Group ID */
+#define NFA_STATUS_UNKNOWN_OID NCI_STATUS_UNKNOWN_OID /* Unknown NCI Opcode */
+#define NFA_STATUS_INVALID_PARAM NCI_STATUS_INVALID_PARAM /* Invalid Parameter */
+#define NFA_STATUS_MSG_SIZE_TOO_BIG NCI_STATUS_MSG_SIZE_TOO_BIG /* Message size too big */
+#define NFA_STATUS_ALREADY_STARTED NCI_STATUS_ALREADY_STARTED /* Already started */
+#define NFA_STATUS_ACTIVATION_FAILED NCI_STATUS_ACTIVATION_FAILED /* Activation Failed */
+#define NFA_STATUS_TEAR_DOWN NCI_STATUS_TEAR_DOWN /* Tear Down Error */
+#define NFA_STATUS_RF_TRANSMISSION_ERR NCI_STATUS_RF_TRANSMISSION_ERR /* RF transmission error*/
+#define NFA_STATUS_RF_PROTOCOL_ERR NCI_STATUS_RF_PROTOCOL_ERR /* RF protocol error */
+#define NFA_STATUS_TIMEOUT NCI_STATUS_TIMEOUT /* RF Timeout */
+#define NFA_STATUS_EE_INTF_ACTIVE_FAIL NCI_STATUS_EE_INTF_ACTIVE_FAIL /* EE Intf activate err */
+#define NFA_STATUS_EE_TRANSMISSION_ERR NCI_STATUS_EE_TRANSMISSION_ERR /* EE transmission error*/
+#define NFA_STATUS_EE_PROTOCOL_ERR NCI_STATUS_EE_PROTOCOL_ERR /* EE protocol error */
+#define NFA_STATUS_EE_TIMEOUT NCI_STATUS_EE_TIMEOUT /* EE Timeout */
+
+#define NFA_STATUS_CMD_STARTED NFC_STATUS_CMD_STARTED /* Command started successfully */
+#define NFA_STATUS_HW_TIMEOUT NFC_STATUS_HW_TIMEOUT /* NFCC Timeout in responding to an NCI command */
+#define NFA_STATUS_CONTINUE NFC_STATUS_CONTINUE /* More NFA_CE_GET_ROUTING_REVT to follow */
+#define NFA_STATUS_REFUSED NFC_STATUS_REFUSED /* API is called to perform illegal function */
+#define NFA_STATUS_BAD_RESP NFC_STATUS_BAD_RESP /* Wrong format of R-APDU, CC file or NDEF file */
+#define NFA_STATUS_CMD_NOT_CMPLTD NFC_STATUS_CMD_NOT_CMPLTD /* 7816 Status Word is not command complete(0x9000) */
+#define NFA_STATUS_NO_BUFFERS NFC_STATUS_NO_BUFFERS /* Out of GKI buffers */
+#define NFA_STATUS_WRONG_PROTOCOL NFC_STATUS_WRONG_PROTOCOL /* Protocol mismatch between API and activated one */
+#define NFA_STATUS_BUSY NFC_STATUS_BUSY /* Another Tag command is already in progress */
+
+#define NFA_STATUS_BAD_LENGTH NFC_STATUS_BAD_LENGTH /* data len exceeds MIU */
+#define NFA_STATUS_BAD_HANDLE NFC_STATUS_BAD_HANDLE /* invalid handle */
+#define NFA_STATUS_CONGESTED NFC_STATUS_CONGESTED /* congested */
+typedef UINT8 tNFA_STATUS;
+
+/* Handle for NFA registrations and connections */
+typedef UINT16 tNFA_HANDLE;
+#define NFA_HANDLE_INVALID (0xFFFF)
+/* NFA Handle definitions */
+
+/* The upper byte of NFA_HANDLE signifies the handle group */
+#define NFA_HANDLE_GROUP_CONNECTION 0x0100 /* Connection handles */
+#define NFA_HANDLE_GROUP_NDEF_HANDLER 0x0200 /* NDEF Type Handler handles */
+#define NFA_HANDLE_GROUP_CE 0x0300 /* DH Card Emulation handles */
+#define NFA_HANDLE_GROUP_EE 0x0400 /* Handles to identify NFCEE */
+#define NFA_HANDLE_GROUP_P2P 0x0500 /* P2P handles */
+#define NFA_HANDLE_GROUP_CHO 0x0600 /* Connection Handvoer handles */
+#define NFA_HANDLE_GROUP_SNEP 0x0700 /* SNEP handles */
+#define NFA_HANDLE_GROUP_HCI 0x0800 /* HCI handles */
+#define NFA_HANDLE_GROUP_LOCAL_NDEF 0x0900 /* Local NDEF message handle */
+#define NFA_HANDLE_GROUP_MASK 0xFF00
+#define NFA_HANDLE_MASK 0x00FF
+
+/* NCI Parameter IDs */
+typedef UINT8 tNFA_PMID;
+
+/* Definitions for tNFA_TECHNOLOGY_MASK */
+#define NFA_TECHNOLOGY_MASK_A 0x01 /* NFC Technology A */
+#define NFA_TECHNOLOGY_MASK_B 0x02 /* NFC Technology B */
+#define NFA_TECHNOLOGY_MASK_F 0x04 /* NFC Technology F */
+#define NFA_TECHNOLOGY_MASK_ISO15693 0x08 /* Proprietary Technology */
+#define NFA_TECHNOLOGY_MASK_B_PRIME 0x10 /* Proprietary Technology */
+#define NFA_TECHNOLOGY_MASK_KOVIO 0x20 /* Proprietary Technology */
+#define NFA_TECHNOLOGY_MASK_A_ACTIVE 0x40 /* NFC Technology A active mode */
+#define NFA_TECHNOLOGY_MASK_F_ACTIVE 0x80 /* NFC Technology F active mode */
+#define NFA_TECHNOLOGY_MASK_ALL 0xFF /* All supported technologies */
+typedef UINT8 tNFA_TECHNOLOGY_MASK;
+
+/* Definitions for NFC protocol for RW, CE and P2P APIs */
+#define NFA_PROTOCOL_T1T NFC_PROTOCOL_T1T /* Type1Tag - NFC-A */
+#define NFA_PROTOCOL_T2T NFC_PROTOCOL_T2T /* MIFARE/Type2Tag - NFC-A */
+#define NFA_PROTOCOL_T3T NFC_PROTOCOL_T3T /* Felica/Type3Tag - NFC-F */
+#define NFA_PROTOCOL_ISO_DEP NFC_PROTOCOL_ISO_DEP /* Type 4A,4B - NFC-A or NFC-B */
+#define NFA_PROTOCOL_NFC_DEP NFC_PROTOCOL_NFC_DEP /* NFCDEP/LLCP - NFC-A or NFC-F */
+#define NFA_PROTOCOL_ISO15693 NFC_PROTOCOL_15693
+#define NFA_PROTOCOL_B_PRIME NFC_PROTOCOL_B_PRIME
+#define NFA_PROTOCOL_KOVIO NFC_PROTOCOL_KOVIO
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define NFA_PROTOCOL_MIFARE NFC_PROTOCOL_MIFARE
+#define NFA_PROTOCOL_T3BT NFC_PROTOCOL_T3BT
+#endif
+#define NFA_PROTOCOL_INVALID 0xFF
+#define NFA_MAX_NUM_PROTOCOLS 8
+typedef UINT8 tNFA_NFC_PROTOCOL;
+
+/* Definitions for tNFA_PROTOCOL_MASK */
+#define NFA_PROTOCOL_MASK_T1T 0x01 /* Type 1 tag */
+#define NFA_PROTOCOL_MASK_T2T 0x02 /* MIFARE / Type 2 tag */
+#define NFA_PROTOCOL_MASK_T3T 0x04 /* FeliCa / Type 3 tag */
+#define NFA_PROTOCOL_MASK_ISO_DEP 0x08 /* ISODEP/4A,4B */
+#define NFA_PROTOCOL_MASK_NFC_DEP 0x10 /* NFCDEP/LLCP */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define NFC_PROTOCOL_MASK_ISO7816 0x20 /*ISO 7816 - Aid Default Route */
+#endif
+typedef UINT8 tNFA_PROTOCOL_MASK;
+
+
+/* NFA_DM callback events */
+#define NFA_DM_ENABLE_EVT 0 /* Result of NFA_Enable */
+#define NFA_DM_DISABLE_EVT 1 /* Result of NFA_Disable */
+#define NFA_DM_SET_CONFIG_EVT 2 /* Result of NFA_SetConfig */
+#define NFA_DM_GET_CONFIG_EVT 3 /* Result of NFA_GetConfig */
+#define NFA_DM_PWR_MODE_CHANGE_EVT 4 /* Result of NFA_PowerOffSleepMode */
+#define NFA_DM_RF_FIELD_EVT 5 /* Status of RF Field */
+#define NFA_DM_NFCC_TIMEOUT_EVT 6 /* NFCC is not responding */
+#define NFA_DM_NFCC_TRANSPORT_ERR_EVT 7 /* NCI Tranport error */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define NFA_DM_EMVCO_PCD_COLLISION_EVT 8 /* Collision event in case of EMV-CO Profile (Nxp)*/
+#define NFA_DM_SET_ROUTE_CONFIG_REVT 9 /* Status of EE Route config CMD (Nxp)*/
+#define NFA_DM_GET_ROUTE_CONFIG_REVT 10 /* Result of NFA_GetRouting */
+/* 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
+
+#define NFA_T1T_HR_LEN T1T_HR_LEN /* T1T HR length */
+#define NFA_MAX_UID_LEN TAG_MAX_UID_LEN /* Max UID length of T1/T2 */
+#define NFA_T1T_UID_LEN T1T_UID_LEN /* T1T UID length */
+#define NFA_T1T_CMD_UID_LEN T1T_CMD_UID_LEN /* UID len for T1T cmds */
+#define NFA_T2T_UID_LEN T2T_UID_LEN /* T2T UID length */
+
+#define NFA_RW_NDEF_FL_READ_ONLY RW_NDEF_FL_READ_ONLY /* Tag is read only */
+#define NFA_RW_NDEF_FL_FORMATED RW_NDEF_FL_FORMATED /* Tag formated for NDEF */
+#define NFA_RW_NDEF_FL_SUPPORTED RW_NDEF_FL_SUPPORTED /* NDEF supported by the tag */
+#define NFA_RW_NDEF_FL_UNKNOWN RW_NDEF_FL_UNKNOWN /* Unable to find if tag is ndef capable/formated/read only */
+#define NFA_RW_NDEF_FL_FORMATABLE RW_NDEF_FL_FORMATABLE /* Tag supports format operation */
+#define NFA_RW_NDEF_FL_SOFT_LOCKABLE RW_NDEF_FL_SOFT_LOCKABLE /* Tag can be soft locked */
+#define NFA_RW_NDEF_FL_HARD_LOCKABLE RW_NDEF_FL_HARD_LOCKABLE /* Tag can be hard locked */
+#define NFA_RW_NDEF_FL_OTP RW_NDEF_FL_OTP /* Tag is one time programmable */
+
+typedef UINT8 tNFA_RW_NDEF_FLAG;
+
+/* Data for NFA_DM_SET_CONFIG_EVT */
+typedef struct
+{
+ tNFA_STATUS status; /* NFA_STATUS_OK if successful */
+ UINT8 num_param_id; /* Number of rejected Param ID */
+ tNFA_PMID param_ids[NFC_MAX_NUM_IDS]; /* Rejected Param ID */
+} tNFA_SET_CONFIG;
+
+/* Data for NFA_DM_GET_CONFIG_EVT */
+typedef struct
+{
+ tNFA_STATUS status; /* NFA_STATUS_OK if successful */
+ UINT16 tlv_size; /* The length of TLV */
+ UINT8 param_tlvs[1]; /* TLV (Parameter ID-Len-Value byte stream) */
+} tNFA_GET_CONFIG;
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+/* Data for NFA_DM_GET_ROUTING_EVT */
+typedef struct
+{
+ tNFA_STATUS status; /* NFA_STATUS_OK if successful */
+ UINT8 num_tlvs; /* number of TLVs */
+ UINT8 tlv_size; /* the total len of all TLVs */
+ UINT8 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 tNFA_DM_PWR_MODE;
+
+/* Data for NFA_DM_PWR_MODE_CHANGE_EVT */
+typedef struct
+{
+ tNFA_STATUS status; /* NFA_STATUS_OK if successful */
+ tNFA_DM_PWR_MODE power_mode; /* NFA_DM_PWR_MODE_FULL or NFA_DM_PWR_MODE_OFF_SLEEP */
+} tNFA_DM_PWR_MODE_CHANGE;
+
+/* Data for NFA_DM_RF_FIELD_EVT */
+#define NFA_DM_RF_FIELD_OFF 0x00
+#define NFA_DM_RF_FIELD_ON 0x01
+
+typedef struct
+{
+ tNFA_STATUS status; /* NFA_STATUS_OK if successful */
+ UINT8 rf_field_status;/* NFA_DM_RF_FIELD_ON if operating field generated by remote */
+} tNFA_DM_RF_FIELD;
+
+/* Union of all DM callback structures */
+typedef union
+{
+ tNFA_STATUS status; /* NFA_DM_ENABLE_EVT */
+ tNFA_SET_CONFIG set_config; /* NFA_DM_SET_CONFIG_EVT */
+ tNFA_GET_CONFIG get_config; /* NFA_DM_GET_CONFIG_EVT */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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_CBACK_DATA;
+
+/* NFA_DM callback */
+typedef void (tNFA_DM_CBACK) (UINT8 event, tNFA_DM_CBACK_DATA *p_data);
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+/* NFA Enable DTA Type Mode */
+typedef enum
+{
+ NFA_DTA_DEFAULT_MODE=0,
+ NFA_DTA_LLCP_MODE,
+ NFA_DTA_SNEP_MODE
+}tNFA_eDtaModes;
+typedef struct
+{
+ UINT8 validation; /* indicates on which platform validation is done like pn547, pn548, pn65T, pn66T */
+ UINT8 android_version; /* Nxp's android version */
+ UINT8 major_version; /* Major Version of MW*/
+ UINT8 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 */
+#define NFA_DISC_RESULT_EVT 2 /* NFC link/protocol discovery notificaiton */
+#define NFA_SELECT_RESULT_EVT 3 /* NFC link/protocol discovery select response */
+#define NFA_DEACTIVATE_FAIL_EVT 4 /* NFA_Deactivate failure */
+#define NFA_ACTIVATED_EVT 5 /* NFC link/protocol activated */
+#define NFA_DEACTIVATED_EVT 6 /* NFC link/protocol deactivated */
+#define NFA_TLV_DETECT_EVT 7 /* TLV Detection complete */
+#define NFA_NDEF_DETECT_EVT 8 /* NDEF Detection complete */
+#define NFA_DATA_EVT 9 /* Data message received */
+#define NFA_SELECT_CPLT_EVT 10 /* Select completed */
+#define NFA_READ_CPLT_EVT 11 /* Read completed */
+#define NFA_WRITE_CPLT_EVT 12 /* Write completed */
+#define NFA_LLCP_ACTIVATED_EVT 13 /* LLCP link is activated */
+#define NFA_LLCP_DEACTIVATED_EVT 14 /* LLCP link is deactivated */
+#define NFA_PRESENCE_CHECK_EVT 15 /* Response to NFA_RwPresenceCheck */
+#define NFA_FORMAT_CPLT_EVT 16 /* Tag Formating completed */
+#define NFA_I93_CMD_CPLT_EVT 17 /* ISO 15693 command completed */
+#define NFA_SET_TAG_RO_EVT 18 /* Tag set as Read only */
+#define NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT 19 /* Result for NFA_RequestExclusiveRfControl */
+#define NFA_EXCLUSIVE_RF_CONTROL_STOPPED_EVT 20 /* Result for NFA_ReleaseExclusiveRfControl */
+#define NFA_CE_REGISTERED_EVT 21 /* DH Card emulation: AID or System code reg'd */
+#define NFA_CE_DEREGISTERED_EVT 22 /* DH Card emulation: AID or System code dereg'd*/
+#define NFA_CE_DATA_EVT 23 /* DH Card emulation: data received event */
+#define NFA_CE_ACTIVATED_EVT 24 /* DH Card emulation: activation event */
+#define NFA_CE_DEACTIVATED_EVT 25 /* DH Card emulation: deactivation event */
+#define NFA_CE_LOCAL_TAG_CONFIGURED_EVT 26 /* DH Card emulation: local NDEF configured */
+#define NFA_CE_NDEF_WRITE_START_EVT 27 /* DH Card emulation: NDEF write started */
+#define NFA_CE_NDEF_WRITE_CPLT_EVT 28 /* DH Card emulation: NDEF write completed */
+#define NFA_CE_UICC_LISTEN_CONFIGURED_EVT 29 /* UICC Listen configured */
+#define NFA_RF_DISCOVERY_STARTED_EVT 30 /* RF Discovery started event */
+#define NFA_RF_DISCOVERY_STOPPED_EVT 31 /* RF Discovery stopped event */
+#define NFA_UPDATE_RF_PARAM_RESULT_EVT 32 /* status of updating RF communication paramters*/
+#define NFA_SET_P2P_LISTEN_TECH_EVT 33 /* status of setting P2P listen technologies */
+#define NFA_RW_INTF_ERROR_EVT 34 /* RF Interface error event */
+#define NFA_LLCP_FIRST_PACKET_RECEIVED_EVT 35 /* First packet received over LLCP link */
+#define NFA_LISTEN_ENABLED_EVT 36 /* Listening enabled event */
+#define NFA_LISTEN_DISABLED_EVT 37 /* Listening disabled event */
+#define NFA_P2P_PAUSED_EVT 38 /* P2P services paused event */
+#define NFA_P2P_RESUMED_EVT 39 /* P2P services resumed event */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define NFA_CE_ESE_LISTEN_CONFIGURED_EVT 40 /* ESE Listen configured */
+#define NFA_ACTIVATED_UPDATE_EVT 41 /* Activated intf for updating the tech variables */
+#define NFA_RECOVERY_EVT 42 /*Recovery*/
+#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 tNFA_DEACTIVATE_TYPE;
+
+/* Data for NFA_DISC_RESULT_EVT */
+typedef struct
+{
+ tNFA_STATUS status; /* NFA_STATUS_OK if successful */
+ tNFC_RESULT_DEVT discovery_ntf; /* RF discovery notification details */
+} tNFA_DISC_RESULT;
+
+/* Data for NFA_ACTIVATED_EVT */
+typedef struct
+{
+ UINT8 hr[NFA_T1T_HR_LEN]; /* HR of Type 1 tag */
+ UINT8 uid[NFA_T1T_CMD_UID_LEN]; /* UID used in T1T Commands */
+} tNFA_T1T_PARAMS;
+
+typedef struct
+{
+ UINT8 uid[NFA_MAX_UID_LEN]; /* UID of T2T tag */
+} tNFA_T2T_PARAMS;
+
+typedef struct
+{
+ UINT8 num_system_codes; /* Number of system codes supporte by tag */
+ UINT16 *p_system_codes; /* Pointer to list of system codes */
+} tNFA_T3T_PARAMS;
+
+typedef struct
+{
+ UINT8 uid[I93_UID_BYTE_LEN]; /* UID[0]:MSB, ... UID[7]:LSB */
+ UINT8 info_flags; /* information flags */
+ UINT8 dsfid; /* DSFID if I93_INFO_FLAG_DSFID */
+ UINT8 afi; /* AFI if I93_INFO_FLAG_AFI */
+ UINT16 num_block; /* number of blocks if I93_INFO_FLAG_MEM_SIZE */
+ UINT8 block_size; /* block size in byte if I93_INFO_FLAG_MEM_SIZE */
+ UINT8 IC_reference; /* IC Reference if I93_INFO_FLAG_IC_REF */
+} tNFA_I93_PARAMS;
+
+typedef union
+{
+ tNFA_T1T_PARAMS t1t; /* HR and UID of T1T */
+ tNFA_T2T_PARAMS t2t; /* UID of T2T */
+ tNFA_T3T_PARAMS t3t; /* System codes */
+ tNFA_I93_PARAMS i93; /* System Information of ISO 15693 */
+} tNFA_TAG_PARAMS;
+
+typedef struct
+{
+ tNFC_ACTIVATE_DEVT activate_ntf; /* RF discovery activation details */
+ tNFA_TAG_PARAMS params; /* additional informaiton of tag */
+} tNFA_ACTIVATED;
+
+/* Data for NFA_DEACTIVATED_EVT */
+typedef struct
+{
+ tNFA_DEACTIVATE_TYPE type; /* NFA_DEACTIVATE_TYPE_IDLE or NFA_DEACTIVATE_TYPE_SLEEP */
+} tNFA_DEACTIVATED;
+
+/* Structure for NFA_NDEF_DETECT_EVT event data */
+typedef struct
+{
+ tNFA_STATUS status; /* Status of the ndef detecton */
+ tNFA_NFC_PROTOCOL protocol; /* protocol used to detect NDEF */
+ UINT32 max_size; /* max number of bytes available for NDEF data */
+ UINT32 cur_size; /* current size of stored NDEF data (in bytes) */
+ tNFA_RW_NDEF_FLAG flags; /* Flags to indicate NDEF capability, is formated, soft/hard lockable, formatable, otp and read only */
+} tNFA_NDEF_DETECT;
+
+
+/* Structure for NFA_TLV_DETECT_EVT event data */
+typedef struct
+{
+ tNFA_STATUS status; /* Status of the tlv detecton */
+ tNFA_NFC_PROTOCOL protocol; /* protocol used to detect TLV */
+ UINT8 num_tlvs; /* number of tlvs present in the tag */
+ UINT8 num_bytes; /* number of lock/reserved bytes */
+} tNFA_TLV_DETECT;
+
+/* Structure for NFA_DATA_EVT data */
+typedef struct
+{
+ tNFA_STATUS status; /* Status of Data received */
+ UINT8 *p_data; /* Data buffer */
+ UINT16 len; /* Length of data */
+} tNFA_RX_DATA;
+
+/* Structure for NFA_CE_NDEF_WRITE_CPLT_EVT data */
+typedef struct
+{
+ tNFA_STATUS status; /* Status of the ndef write op */
+ UINT32 len; /* Update length of NDEF data */
+ UINT8 *p_data; /* data buffer */
+} tNFA_CE_NDEF_WRITE_CPLT;
+
+/* Data for NFA_LLCP_ACTIVATED_EVT */
+typedef struct
+{
+ BOOLEAN is_initiator; /* TRUE if initiator */
+ UINT16 remote_wks; /* Well-Known service mask of peer */
+ UINT8 remote_lsc; /* Link Service Class of peer */
+ UINT16 remote_link_miu;/* Link MIU of peer */
+ UINT16 local_link_miu; /* Link MIU of local */
+} tNFA_LLCP_ACTIVATED;
+
+/* Data for NFA_LLCP_DEACTIVATED_EVT */
+typedef struct
+{
+ UINT8 reason; /* reason of deactivation */
+} tNFA_LLCP_DEACTIVATED;
+
+/* Data for NFA_I93_CMD_CPLT_EVT */
+typedef struct
+{
+ UINT8 dsfid; /* DSFID */
+ UINT8 uid[I93_UID_BYTE_LEN]; /* UID[0]:MSB, ... UID[7]:LSB */
+} tNFA_I93_INVENTORY;
+
+typedef struct /* RW_I93_SYS_INFO_EVT */
+{
+ UINT8 info_flags; /* information flags */
+ UINT8 uid[I93_UID_BYTE_LEN]; /* UID */
+ UINT8 dsfid; /* DSFID if I93_INFO_FLAG_DSFID */
+ UINT8 afi; /* AFI if I93_INFO_FLAG_AFI */
+ UINT16 num_block; /* number of blocks if I93_INFO_FLAG_MEM_SIZE */
+ UINT8 block_size; /* block size in byte if I93_INFO_FLAG_MEM_SIZE */
+ UINT8 IC_reference; /* IC Reference if I93_INFO_FLAG_IC_REF */
+} tNFA_I93_SYS_INFO;
+
+typedef struct
+{
+ tNFA_STATUS status; /* Status of sending command */
+ UINT8 sent_command; /* sent command to tag */
+ union
+ {
+ UINT8 error_code; /* error code defined in ISO 15693 */
+ tNFA_I93_INVENTORY inventory; /* inventory response */
+ tNFA_I93_SYS_INFO sys_info; /* system information */
+ } params;
+} tNFA_I93_CMD_CPLT;
+
+/* Data for NFA_CE_REGISTERED_EVT */
+typedef struct
+{
+ tNFA_STATUS status; /* NFA_STATUS_OK if successful */
+ tNFA_HANDLE handle; /* handle for NFA_CeRegisterFelicaSystemCodeOnDH () */
+ /* NFA_CeRegisterT4tAidOnDH () */
+} tNFA_CE_REGISTERED;
+
+/* Data for NFA_CE_DEREGISTERED_EVT */
+typedef struct
+{
+ tNFA_HANDLE handle; /* handle from NFA_CE_REGISTERED_EVT */
+} tNFA_CE_DEREGISTERED;
+
+/* Data for NFA_CE_ACTIVATED_EVT */
+typedef struct
+{
+ tNFA_STATUS status; /* NFA_STATUS_OK if successful */
+ tNFA_HANDLE handle; /* handle from NFA_CE_REGISTERED_EVT */
+ tNFC_ACTIVATE_DEVT activate_ntf; /* RF discovery activation details */
+} tNFA_CE_ACTIVATED;
+
+/* Data for NFA_CE_DEACTIVATED_EVT */
+typedef struct
+{
+ tNFA_HANDLE handle; /* handle from NFA_CE_REGISTERED_EVT */
+ tNFA_DEACTIVATE_TYPE type; /* NFA_DEACTIVATE_TYPE_IDLE or NFA_DEACTIVATE_TYPE_SLEEP */
+} tNFA_CE_DEACTIVATED;
+
+/* Structure for NFA_CE_DATA_EVT data */
+typedef struct
+{
+ tNFA_STATUS status; /* NFA_STATUS_OK if complete packet */
+ tNFA_HANDLE handle; /* handle from NFA_CE_REGISTERED_EVT */
+ UINT8 *p_data; /* Data buffer */
+ UINT16 len; /* Length of data */
+} tNFA_CE_DATA;
+
+
+/* Union of all connection callback structures */
+typedef union
+{
+ tNFA_STATUS status; /* NFA_POLL_ENABLED_EVT */
+ /* NFA_POLL_DISABLED_EVT */
+ /* NFA_CE_UICC_LISTEN_CONFIGURED_EVT */
+ /* NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT */
+ /* NFA_EXCLUSIVE_RF_CONTROL_STOPPED_EVT */
+ /* NFA_SELECT_RESULT_EVT */
+ /* NFA_DEACTIVATE_FAIL_EVT */
+ /* NFA_CE_NDEF_WRITE_START_EVT */
+ /* NFA_SELECT_CPLT_EVT */
+ /* NFA_READ_CPLT_EVT */
+ /* NFA_WRITE_CPLT_EVT */
+ /* NFA_PRESENCE_CHECK_EVT */
+ /* NFA_FORMAT_CPLT_EVT */
+ /* NFA_SET_TAG_RO_EVT */
+ /* NFA_UPDATE_RF_PARAM_RESULT_EVT */
+ /* NFA_RW_INTF_ERROR_EVT */
+ tNFA_DISC_RESULT disc_result; /* NFA_DISC_RESULT_EVT */
+ tNFA_ACTIVATED activated; /* NFA_ACTIVATED_EVT */
+ tNFA_DEACTIVATED deactivated; /* NFA_DEACTIVATED_EVT */
+ tNFA_NDEF_DETECT ndef_detect; /* NFA_NDEF_DETECT_EVT */
+ tNFA_TLV_DETECT tlv_detect; /* NFA_TLV_DETECT_EVT */
+ tNFA_RX_DATA data; /* NFA_DATA_EVT */
+ tNFA_CE_NDEF_WRITE_CPLT ndef_write_cplt; /* NFA_CE_NDEF_WRITE_CPLT_EVT */
+ tNFA_LLCP_ACTIVATED llcp_activated; /* NFA_LLCP_ACTIVATED_EVT */
+ tNFA_LLCP_DEACTIVATED llcp_deactivated; /* NFA_LLCP_DEACTIVATED_EVT */
+ tNFA_I93_CMD_CPLT i93_cmd_cplt; /* NFA_I93_CMD_CPLT_EVT */
+ tNFA_CE_REGISTERED ce_registered; /* NFA_CE_REGISTERED_EVT */
+ tNFA_CE_DEREGISTERED ce_deregistered; /* NFA_CE_DEREGISTERED_EVT */
+ tNFA_CE_ACTIVATED ce_activated; /* NFA_CE_ACTIVATED_EVT */
+ tNFA_CE_DEACTIVATED ce_deactivated; /* NFA_CE_DEACTIVATED_EVT */
+ tNFA_CE_DATA ce_data; /* NFA_CE_DATA_EVT */
+
+} tNFA_CONN_EVT_DATA;
+
+/* NFA Connection Callback */
+typedef void (tNFA_CONN_CBACK) (UINT8 event, tNFA_CONN_EVT_DATA *p_data);
+
+#ifndef NFA_DM_NUM_INTERFACE_MAP
+#define NFA_DM_NUM_INTERFACE_MAP 3
+#endif
+
+/* compile-time configuration structure for the RF Discovery Frequency for each technology */
+typedef struct
+{
+ UINT8 pa; /* Frequency for NFC Technology A */
+ UINT8 pb; /* Frequency for NFC Technology B */
+ UINT8 pf; /* Frequency for NFC Technology F */
+ UINT8 pi93; /* Frequency for Proprietary Technology/15693 */
+ UINT8 pbp; /* Frequency for Proprietary Technology/B-Prime */
+ UINT8 pk; /* Frequency for Proprietary Technology/Kovio */
+ UINT8 paa; /* Frequency for NFC Technology A active mode */
+ UINT8 pfa; /* Frequency for NFC Technology F active mode */
+} tNFA_DM_DISC_FREQ_CFG;
+
+/* definitions for tNFA_DM_CFG.presence_check_option */
+#define NFA_DM_PCO_ISO_SLEEP_WAKE 0x01 /* if NDEF is not supported by the tag, use sleep/wake(last interface) */
+#define NFA_DM_PCO_EMPTY_I_BLOCK 0x02 /* 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 */
+
+/* compile-time configuration structure */
+typedef struct
+{
+ BOOLEAN auto_detect_ndef; /* Automatic NDEF detection (when not in exclusive RF mode) */
+ BOOLEAN auto_read_ndef; /* Automatic NDEF read (when not in exclusive RF mode) */
+ BOOLEAN auto_presence_check; /* Automatic presence check */
+ UINT8 presence_check_option; /* Use sleep/wake(last interface) for ISODEP presence check */
+ UINT16 presence_check_timeout; /* Maximum time to wait for presence check response */
+} tNFA_DM_CFG;
+
+/* compile-time configuration structure for HCI */
+typedef struct
+{
+ UINT16 hci_netwk_enable_timeout; /* Maximum idle(no HCP Pkt) time to wait for EE DISC REQ Ntf(s) */
+ UINT16 hcp_response_timeout; /* Maximum time to wait for EE DISC REQ NTF(s) after HOT PLUG EVT(s) */
+ UINT8 num_whitelist_host; /* Number of host in the whitelist of Terminal host */
+ UINT8 *p_whitelist; /* Whitelist of Terminal Host */
+} 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
+ */
+ BOOLEAN la_enable; /* TRUE if listening A */
+ UINT8 la_bit_frame_sdd; /* Bit Frame SDD in Byte 1 of SENS_RES */
+ UINT8 la_platform_config; /* Platform Config in Byte 2 of SENS_RES */
+ UINT8 la_sel_info; /* Byte of SEL_RES */
+ UINT8 la_nfcid1_len; /* NFCID1 (0, 4, 7 or 10 bytes) */
+ UINT8 la_nfcid1[NCI_NFCID1_MAX_LEN]; /* if empty, NFCC will decide */
+
+ /*
+ ** Discovery Configuration Parameters for Listen B
+ */
+ BOOLEAN lb_enable; /* TRUE if listening B */
+ UINT8 lb_sensb_info; /* Byte 2 of Protocol Info within SENSB_RES */
+ UINT8 lb_nfcid0_len; /* NFCID0 (0, 1 or 4 bytes) */
+ UINT8 lb_nfcid0[NFA_LB_MAX_NFCID0_LEN]; /* if empty, NFCC will decide */
+ UINT8 lb_app_data[NCI_PARAM_LEN_LB_APPDATA];/* Bytes 6 - 9 in SENSB_RES */
+ UINT8 lb_sfgi; /* Start-Up Frame Guard Time */
+ UINT8 lb_adc_fo; /* Byte 12 in SENSB_RES */
+
+ /*
+ ** Discovery Configuration Parameters for Listen F
+ */
+ BOOLEAN lf_enable; /* TRUE if listening F */
+ UINT8 lf_con_bitr_f; /* bit rate to listen */
+ UINT8 lf_protocol_type; /* Supported Protocols */
+ UINT16 lf_t3t_flags; /* bit field indicating which lf_t3t_identifier are enabled */
+ UINT8 lf_t3t_identifier[NFA_LF_MAX_SC_NFCID2][NCI_SYSTEMCODE_LEN + NCI_NFCID2_LEN];
+ /* System Code and NFCID2 */
+ UINT8 lf_t3t_pmm[NCI_T3T_PMM_LEN]; /* Bytes 10 - 17 in SENSF_RES */
+
+ /*
+ ** Discovery Configuration Parameters for Listen ISO-DEP
+ */
+ BOOLEAN li_enable; /* TRUE if listening ISO-DEP */
+ UINT8 li_fwi; /* Frame Waiting Time Integer */
+ UINT8 la_hist_bytes_len; /* historical bytes for Listen-A */
+ UINT8 la_hist_bytes[NFA_LA_MAX_HIST_BYTES];
+ UINT8 lb_h_info_resp_len; /* higher layer response for Listen-B */
+ UINT8 lb_h_info_resp[NFA_LB_MAX_H_INFO_LEN];
+
+ /*
+ ** Discovery Configuration Parameters for Listen NFC-DEP
+ */
+ BOOLEAN ln_enable; /* TRUE if listening NFC-DEP */
+ UINT8 ln_wt; /* Waiting Time Integer */
+ UINT8 ln_atr_res_gen_bytes_len; /* General bytes in ATR_RES */
+ UINT8 ln_atr_res_gen_bytes[NCI_MAX_GEN_BYTES_LEN];
+ UINT8 ln_atr_res_config; /* Optional parameters (PPt) in ATR_RES */
+} tNFA_LISTEN_CFG;
+
+/* Data for NFA_UpdateRFCommParams () */
+typedef tNFC_RF_COMM_PARAMS tNFA_RF_COMM_PARAMS;
+
+/* RF Interface type */
+#define NFA_INTERFACE_FRAME NFC_INTERFACE_FRAME
+#define NFA_INTERFACE_ISO_DEP NFC_INTERFACE_ISO_DEP
+#define NFA_INTERFACE_NFC_DEP NFC_INTERFACE_NFC_DEP
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define NFA_INTERFACE_MIFARE NFC_INTERFACE_MIFARE
+#endif
+typedef tNFC_INTF_TYPE tNFA_INTF_TYPE;
+
+/*******************************************************************************
+** NDEF Definitions
+*******************************************************************************/
+
+/* Definitions for tNFA_TNF (NDEF type name format ID) */
+#define NFA_TNF_EMPTY NDEF_TNF_EMPTY /* Empty or no type specified */
+#define NFA_TNF_WKT NDEF_TNF_WKT /* NFC Forum well-known type [NFC RTD] */
+#define NFA_TNF_RFC2046_MEDIA NDEF_TNF_MEDIA /* Media-type as defined in RFC 2046 [RFC 2046] */
+#define NFA_TNF_RFC3986_URI NDEF_TNF_URI /* Absolute URI as defined in RFC 3986 [RFC 3986] */
+#define NFA_TNF_EXTERNAL NDEF_TNF_EXT /* NFC Forum external type [NFC RTD] */
+#define NFA_TNF_UNKNOWN NDEF_TNF_UNKNOWN /* Unknown */
+#define NFA_TNF_UNCHANGED NDEF_TNF_UNCHANGED /* Unchanged */
+#define NFA_TNF_RESERVED NDEF_TNF_RESERVED /* Reserved */
+#define NFA_TNF_DEFAULT 0xFF /* Used to register default NDEF type handler */
+typedef UINT8 tNFA_TNF;
+
+/* Definitions for tNFA_NDEF_URI_ID (Frequently used prefixes. For additional values, see [NFC RTD URI] */
+#define NFA_NDEF_URI_ID_ABSOLUTE 0x00 /* Unabridged URI. */
+#define NFA_NDEF_URI_ID_HTTP 0x03 /* http:// */
+#define NFA_NDEF_URI_ID_HTTPS 0x04 /* https:// */
+#define NFA_NDEF_URI_ID_TEL 0x05 /* tel: */
+#define NFA_NDEF_URI_ID_MAILTO 0x06 /* mailto: */
+#define NFA_NDEF_URI_ID_FTP 0x0D /* ftp:// */
+#define NFA_NDEF_URI_ID_FILE 0x1D /* file:// */
+
+typedef UINT8 tNFA_NDEF_URI_ID;
+
+/* Events for tNFA_NDEF_CBACK */
+#define NFA_NDEF_REGISTER_EVT 0 /* NDEF record type registered. (In response to NFA_RegisterNDefTypeHandler) */
+#define NFA_NDEF_DATA_EVT 1 /* Received an NDEF message with the registered type. See [tNFA_NDEF_DATA] */
+typedef UINT8 tNFA_NDEF_EVT;
+
+/* Structure for NFA_NDEF_REGISTER_EVT event data */
+typedef struct
+{
+ tNFA_STATUS status; /* Status of the registration */
+ tNFA_HANDLE ndef_type_handle; /* Handle for this NDEF type registration. */
+} tNFA_NDEF_REGISTER;
+
+/* Structure for NFA_NDEF_DATA_EVT event data */
+typedef struct
+{
+ tNFA_HANDLE ndef_type_handle; /* Handle for NDEF type registration. */
+ UINT8 *p_data; /* Data buffer */
+ UINT32 len; /* Length of data */
+} tNFA_NDEF_DATA;
+
+/* Union of all NDEF callback structures */
+typedef union
+{
+ tNFA_NDEF_REGISTER ndef_reg; /* Structure for NFA_NDEF_REGISTER_EVT event data */
+ tNFA_NDEF_DATA ndef_data; /* Structure for NFA_NDEF_DATA_EVT event data */
+} tNFA_NDEF_EVT_DATA;
+
+/* NFA_NDEF callback */
+typedef void (tNFA_NDEF_CBACK) (tNFA_NDEF_EVT event, tNFA_NDEF_EVT_DATA *p_data);
+
+/* NFA VSC Callback */
+typedef void (tNFA_VSC_CBACK)(UINT8 event, UINT16 param_len, UINT8 *p_param);
+
+
+/*****************************************************************************
+** External Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*******************************************************************************
+**
+** Function NFA_Init
+**
+** Description This function initializes control blocks for NFA
+**
+** p_hal_entry_tbl points to a table of HAL entry points
+**
+** NOTE: the buffer that p_hal_entry_tbl points must be
+** persistent until NFA is disabled.
+**
+**
+** Returns none
+**
+*******************************************************************************/
+NFC_API extern void NFA_Init (tHAL_NFC_ENTRY *p_hal_entry_tbl);
+
+/*******************************************************************************
+**
+** Function NFA_Enable
+**
+** Description This function enables NFC. Prior to calling NFA_Enable,
+** the NFCC must be powered up, and ready to receive commands.
+** This function enables the tasks needed by NFC, opens the NCI
+** transport, resets the NFC controller, downloads patches to
+** the NFCC (if necessary), and initializes the NFC subsystems.
+**
+** This function should only be called once - typically when NFC
+** is enabled during boot-up, or when NFC is enabled from a
+** settings UI. Subsequent calls to NFA_Enable while NFA is
+** enabling or enabled will be ignored. When the NFC startup
+** procedure is completed, an NFA_DM_ENABLE_EVT is returned to the
+** application using the tNFA_DM_CBACK.
+**
+** The tNFA_CONN_CBACK parameter is used to register a callback
+** for polling, p2p and card emulation events.
+**
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_Enable (tNFA_DM_CBACK *p_dm_cback,
+ tNFA_CONN_CBACK *p_conn_cback);
+
+/*******************************************************************************
+**
+** Function NFA_Disable
+**
+** Description This function is called to shutdown NFC. The tasks for NFC
+** are terminated, and clean up routines are performed. This
+** function is typically called during platform shut-down, or
+** when NFC is disabled from a settings UI. When the NFC
+** shutdown procedure is completed, an NFA_DM_DISABLE_EVT is
+** returned to the application using the tNFA_DM_CBACK.
+**
+** The platform should wait until the NFC_DISABLE_REVT is
+** received before powering down the NFC chip and NCI transport.
+** This is required to so that NFA can gracefully shut down any
+** open connections.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_Disable (BOOLEAN graceful);
+
+/*******************************************************************************
+**
+** Function NFA_SetConfig
+**
+** Description Set the configuration parameters to NFCC. The result is
+** reported with an NFA_DM_SET_CONFIG_EVT in the tNFA_DM_CBACK
+** callback.
+**
+** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function. Most Configuration
+** parameters are related to RF discovery.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BUSY if previous setting is on-going
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SetConfig (tNFA_PMID param_id,
+ UINT8 length,
+ UINT8 *p_data);
+
+/*******************************************************************************
+**
+** Function NFA_GetConfig
+**
+** Description Get the configuration parameters from NFCC. The result is
+** reported with an NFA_DM_GET_CONFIG_EVT in the tNFA_DM_CBACK
+** callback.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_GetConfig (UINT8 num_ids, tNFA_PMID *p_param_ids);
+
+/*******************************************************************************
+**
+** Function NFA_RequestExclusiveRfControl
+**
+** Description Request exclusive control of NFC.
+** - Previous behavior (polling/tag reading, DH card emulation)
+** will be suspended .
+** - Polling and listening will be done based on the specified
+** params
+**
+** The NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT event of
+** tNFA_CONN_CBACK indicates the status of the operation.
+**
+** NFA_ACTIVATED_EVT and NFA_DEACTIVATED_EVT indicates link
+** activation/deactivation.
+**
+** NFA_SendRawFrame is used to send data to the peer. NFA_DATA_EVT
+** indicates data from the peer.
+**
+** If a tag is activated, then the NFA_RW APIs may be used to
+** send commands to the tag. Incoming NDEF messages are sent to
+** the NDEF callback.
+**
+** Once exclusive RF control has started, NFA will not activate
+** LLCP internally. The application has exclusive control of
+** the link.
+**
+** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RequestExclusiveRfControl (tNFA_TECHNOLOGY_MASK poll_mask,
+ tNFA_LISTEN_CFG *p_listen_cfg,
+ tNFA_CONN_CBACK *p_conn_cback,
+ tNFA_NDEF_CBACK *p_ndef_cback);
+
+/*******************************************************************************
+**
+** Function NFA_ReleaseExclusiveRfControl
+**
+** Description Release exclusive control of NFC. Once released, behavior
+** prior to obtaining exclusive RF control will resume.
+**
+Note??
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_ReleaseExclusiveRfControl (void);
+
+/*******************************************************************************
+**
+** Function NFA_EnablePolling
+**
+** Description Enable polling for technologies specified by poll_mask.
+**
+** The following events (notified using the connection
+** callback registered with NFA_Enable) are generated during
+** polling:
+**
+** - NFA_POLL_ENABLED_EVT indicates whether or not polling
+** successfully enabled.
+** - NFA_DISC_RESULT_EVT indicates there are more than one devices,
+** so application must select one of tags by calling NFA_Select().
+** - NFA_SELECT_RESULT_EVT indicates whether previous selection was
+** successful or not. If it was failed then application must select
+** again or deactivate by calling NFA_Deactivate().
+** - NFA_ACTIVATED_EVT is generated when an NFC link is activated.
+** - NFA_NDEF_DETECT_EVT is generated if tag is activated
+** - NFA_LLCP_ACTIVATED_EVT/NFA_LLCP_DEACTIVATED_EVT is generated
+** if NFC-DEP is activated
+** - NFA_DEACTIVATED_EVT will be returned after deactivating NFC link.
+**
+** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_EnablePolling (tNFA_TECHNOLOGY_MASK poll_mask);
+
+/*******************************************************************************
+**
+** Function NFA_DisablePolling
+**
+** Description Disable polling
+** NFA_POLL_DISABLED_EVT will be returned after stopping polling.
+**
+** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_DisablePolling (void);
+
+/*******************************************************************************
+**
+** Function NFA_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
+**
+*******************************************************************************/
+NFC_API 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
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_DisableListening (void);
+
+/*******************************************************************************
+**
+** 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
+**
+*******************************************************************************/
+NFC_API 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
+**
+*******************************************************************************/
+NFC_API 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
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SetP2pListenTech (tNFA_TECHNOLOGY_MASK tech_mask);
+
+/*******************************************************************************
+**
+** Function NFA_StartRfDiscovery
+**
+** Description Start RF discovery
+** RF discovery parameters shall be set by other APIs.
+**
+** An NFA_RF_DISCOVERY_STARTED_EVT indicates whether starting was successful or not.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_StartRfDiscovery (void);
+
+/*******************************************************************************
+**
+** Function NFA_StopRfDiscovery
+**
+** Description Stop RF discovery
+**
+** An NFA_RF_DISCOVERY_STOPPED_EVT indicates whether stopping was successful or not.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_StopRfDiscovery (void);
+
+/*******************************************************************************
+**
+** Function NFA_SetRfDiscoveryDuration
+**
+** Description Set the duration of the single discovery period in [ms].
+** Allowable range: 0 ms to 0xFFFF ms.
+**
+** Note: If discovery is already started, the application should
+** call NFA_StopRfDiscovery prior to calling
+** NFA_SetRfDiscoveryDuration, and then call
+** NFA_StartRfDiscovery afterwards to restart discovery using
+** the new duration.
+**
+** Returns:
+** NFA_STATUS_OK, if command accepted
+** NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SetRfDiscoveryDuration (UINT16 discovery_period_ms);
+
+/*******************************************************************************
+**
+** Function NFA_Select
+**
+** Description Select one from detected devices by NFA_DISC_RESULT_EVT after the
+** last discovery result is received.
+** An NFA_SELECT_RESULT_EVT indicates whether selection was successful or not.
+** If failed then application must select again or deactivate by NFA_Deactivate ().
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_INVALID_PARAM if RF interface is not matched protocol
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_Select (UINT8 rf_disc_id,
+ tNFA_NFC_PROTOCOL protocol,
+ tNFA_INTF_TYPE rf_interface);
+
+/*******************************************************************************
+**
+** Function NFA_UpdateRFCommParams
+**
+** Description This function is called to update RF Communication parameters
+** once the Frame RF Interface has been activated.
+**
+** An NFA_UPDATE_RF_PARAM_RESULT_EVT indicates whether updating
+** was successful or not.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_UpdateRFCommParams (tNFA_RF_COMM_PARAMS *p_params);
+
+/*******************************************************************************
+**
+** Function NFA_Deactivate
+**
+** Description
+** If sleep_mode=TRUE:
+** Deselect the activated device by deactivating into sleep mode.
+**
+** An NFA_DEACTIVATE_FAIL_EVT indicates that selection was not successful.
+** Application can select another discovered device or deactivate by NFA_Deactivate ()
+** after receiving NFA_DEACTIVATED_EVT.
+**
+** Deactivating to sleep mode is not allowed when NFCC is in wait-for-host-select
+** mode, or in listen-sleep states; NFA will deactivate to idle or discovery state
+** for these cases respectively.
+**
+**
+** If sleep_mode=FALSE:
+** Deactivate the connection (e.g. as a result of presence check failure)
+** NFA_DEACTIVATED_EVT will indicate that link is deactivated.
+** Polling/listening will resume (unless the nfcc is in wait_for-all-discoveries state)
+**
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_Deactivate (BOOLEAN sleep_mode);
+
+/*******************************************************************************
+**
+** Function NFA_SendRawFrame
+**
+** Description Send a raw frame over the activated interface with the NFCC.
+** This function can only be called after NFC link is activated.
+**
+** 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
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SendRawFrame (UINT8 *p_raw_data,
+ UINT16 data_len,
+ UINT16 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
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RegisterNDefTypeHandler (BOOLEAN handle_whole_message,
+ tNFA_TNF tnf,
+ UINT8 *p_type_name,
+ UINT8 type_name_len,
+ tNFA_NDEF_CBACK *p_ndef_cback);
+
+/*******************************************************************************
+**
+** Function NFA_RegisterNDefUriHandler
+**
+** Description This API is a special-case of NFA_RegisterNDefTypeHandler
+** with TNF=NFA_TNF_WKT, and type_name='U' (URI record); and allows
+** registering for specific URI types (e.g. 'tel:' or 'mailto:').
+**
+** An NFA_NDEF_REGISTER_EVT will be sent to the tNFA_NDEF_CBACK
+** to indicate that registration was successful, and provide a
+** handle for this registration.
+**
+** If uri_id=NFA_NDEF_URI_ID_ABSOLUTE, then p_abs_uri contains the
+** unabridged URI. For all other uri_id values, the p_abs_uri
+** parameter is ignored (i.e the URI prefix is implied by uri_id).
+** See [NFC RTD URI] for more information.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RegisterNDefUriHandler (BOOLEAN handle_whole_message,
+ tNFA_NDEF_URI_ID uri_id,
+ UINT8 *p_abs_uri,
+ UINT8 uri_id_len,
+ tNFA_NDEF_CBACK *p_ndef_cback);
+
+
+/*******************************************************************************
+**
+** Function NFA_DeregisterNDefTypeHandler
+**
+** Description Deregister NDEF record type handler.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_DeregisterNDefTypeHandler (tNFA_HANDLE ndef_type_handle);
+
+
+/*******************************************************************************
+**
+** Function NFA_PowerOffSleepMode
+**
+** Description This function is called to enter or leave NFCC Power Off Sleep mode
+** NFA_DM_PWR_MODE_CHANGE_EVT will be sent to indicate status.
+**
+** start_stop : TRUE if entering Power Off Sleep mode
+** FALSE if leaving Power Off Sleep mode
+**
+Note??
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_PowerOffSleepMode (BOOLEAN start_stop);
+
+/*******************************************************************************
+**
+** Function NFA_RegVSCback
+**
+** Description This function is called to register or de-register a callback
+** function to receive Proprietary NCI response and notification
+** events.
+** The maximum number of callback functions allowed is NFC_NUM_VS_CBACKS
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFA_RegVSCback (BOOLEAN is_register,
+ tNFA_VSC_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function NFA_SendVsCommand
+**
+** Description This function is called to send an NCI Vendor Specific
+** command to NFCC.
+**
+** oid - The opcode of the VS command.
+** cmd_params_len - The command parameter len
+** p_cmd_params - The command parameter
+** p_cback - The callback function to receive the command
+** status
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SendVsCommand (UINT8 oid,
+ UINT8 cmd_params_len,
+ UINT8 *p_cmd_params,
+ tNFA_VSC_CBACK *p_cback);
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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
+**
+*******************************************************************************/
+
+NFC_API extern tNFA_STATUS NFA_SendNxpNciCommand (UINT8 cmd_params_len,
+ UINT8 *p_cmd_params,
+ tNFA_VSC_CBACK *p_cback);
+
+#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
+**
+*******************************************************************************/
+NFC_API extern UINT8 NFA_SetTraceLevel (UINT8 new_level);
+
+/*******************************************************************************
+**
+** Function: NFA_EnableDTA_TypeMode
+**
+** Description: Initialize and get global DTA type mode from .conf
+**
+** Returns: none:
+**
+*******************************************************************************/
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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
+*******************************************************************************/
+NFC_API extern void NFA_SetReaderMode (BOOLEAN ReaderModeFlag, UINT32 Technologies);
+
+NFC_API 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
+**
+*******************************************************************************/
+NFC_API extern tNFA_MW_VERSION NFA_GetMwVersion ();
+#endif
+#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..fff0bce
--- /dev/null
+++ b/src/nfa/include/nfa_ce_api.h
@@ -0,0 +1,278 @@
+/******************************************************************************
+ *
+ * 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
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_CeConfigureLocalTag (tNFA_PROTOCOL_MASK protocol_mask,
+ UINT8 *p_ndef_data,
+ UINT16 ndef_cur_size,
+ UINT16 ndef_max_size,
+ BOOLEAN read_only,
+ UINT8 uid_len,
+ UINT8 *p_uid);
+
+/*******************************************************************************
+**
+** Function NFA_CeConfigureUiccListenTech
+**
+** Description Configure listening for the UICC, using the specified
+** technologies.
+**
+** Events will be notifed using the tNFA_CONN_CBACK
+** (registered during NFA_Enable)
+**
+** The NFA_CE_UICC_LISTEN_CONFIGURED_EVT reports the status of the
+** operation.
+**
+** Activation and deactivation are reported using the
+** NFA_ACTIVATED_EVT and NFA_DEACTIVATED_EVT events
+**
+** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function
+**
+** Returns:
+** NFA_STATUS_OK, if command accepted
+** NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_CeConfigureUiccListenTech (tNFA_HANDLE ee_handle,
+ tNFA_TECHNOLOGY_MASK tech_mask);
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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
+**
+*******************************************************************************/
+NFC_API 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
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_CeRegisterFelicaSystemCodeOnDH (UINT16 system_code,
+ UINT8 nfcid2[NCI_RF_F_UID_LEN],
+ tNFA_CONN_CBACK *p_conn_cback);
+
+/*******************************************************************************
+**
+** Function NFA_CeDeregisterFelicaSystemCodeOnDH
+**
+** Description Deregister listening callback for Felica
+** (previously registered using NFA_CeRegisterFelicaSystemCodeOnDH)
+**
+** The NFA_CE_DEREGISTERED_EVT reports the status of the
+** operation.
+**
+** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if invalid handle
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_CeDeregisterFelicaSystemCodeOnDH (tNFA_HANDLE handle);
+
+/*******************************************************************************
+**
+** Function NFA_CeRegisterAidOnDH
+**
+** Description Register listening callback for the specified ISODEP AID
+**
+** The NFA_CE_REGISTERED_EVT reports the status of the
+** operation.
+**
+** If no AID is specified (aid_len=0), then p_conn_cback will
+** will get notifications for any AIDs routed to the DH. This
+** over-rides callbacks registered for specific AIDs.
+**
+** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function
+**
+** Returns:
+** NFA_STATUS_OK, if command accepted
+** NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_CeRegisterAidOnDH (UINT8 aid[NFC_MAX_AID_LEN],
+ UINT8 aid_len,
+ tNFA_CONN_CBACK *p_conn_cback);
+
+/*******************************************************************************
+**
+** Function NFA_CeDeregisterAidOnDH
+**
+** Description Deregister listening callback for ISODEP AID
+** (previously registered using NFA_CeRegisterAidOnDH)
+**
+** The NFA_CE_DEREGISTERED_EVT reports the status of the
+** operation.
+**
+** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if invalid handle
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_CeDeregisterAidOnDH (tNFA_HANDLE handle);
+
+/*******************************************************************************
+**
+** Function NFA_CeSetIsoDepListenTech
+**
+** Description Set the technologies (NFC-A and/or NFC-B) to listen for when
+** NFA_CeConfigureLocalTag or NFA_CeDeregisterAidOnDH are called.
+**
+** By default (if this API is not called), NFA will listen
+** for both NFC-A and NFC-B for ISODEP.
+**
+** Note: If listening for ISODEP on UICC, the DH listen callbacks
+** may still get activate notifications for ISODEP if the reader/
+** writer selects an AID that is not routed to the UICC (regardless
+** of whether A or B was disabled using NFA_CeSetIsoDepListenTech)
+**
+** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function
+**
+** Returns:
+** NFA_STATUS_OK, if command accepted
+** NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_CeSetIsoDepListenTech (tNFA_TECHNOLOGY_MASK tech_mask);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFA_CE_API_H */
diff --git a/src/nfa/include/nfa_cho_api.h b/src/nfa/include/nfa_cho_api.h
new file mode 100644
index 0000000..3722adc
--- /dev/null
+++ b/src/nfa/include/nfa_cho_api.h
@@ -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 public interface file for NFA Connection Handover,
+ * Broadcom's NFC application layer for mobile phones.
+ *
+ ******************************************************************************/
+#ifndef NFA_CHO_API_H
+#define NFA_CHO_API_H
+
+#include "nfa_api.h"
+#include "ndef_utils.h"
+
+/*****************************************************************************
+** Constants and data types
+*****************************************************************************/
+
+/* Handover version */
+#define NFA_CHO_VERSION 0x12 /* version 1.2 */
+#define NFA_CHO_GET_MAJOR_VERSION(x) ((UINT8)(x) >> 4)
+#define NFA_CHO_GET_MINOR_VERSION(x) ((UINT8)(x) & 0x0F)
+
+/*
+** NFA Connection Handover callback events
+*/
+#define NFA_CHO_REG_EVT 0x00 /* Registered */
+#define NFA_CHO_ACTIVATED_EVT 0x01 /* LLCP link activated */
+#define NFA_CHO_DEACTIVATED_EVT 0x02 /* LLCP link deactivated */
+#define NFA_CHO_CONNECTED_EVT 0x03 /* data link connected */
+#define NFA_CHO_DISCONNECTED_EVT 0x04 /* data link disconnected */
+#define NFA_CHO_REQUEST_EVT 0x05 /* AC information in "Hr" record */
+#define NFA_CHO_SELECT_EVT 0x06 /* AC information in "Hs" record */
+#define NFA_CHO_SEL_ERR_EVT 0x07 /* Received select with error */
+#define NFA_CHO_TX_FAIL_EVT 0x08 /* Cannot send message to peer */
+
+typedef UINT8 tNFA_CHO_EVT;
+
+/*
+** Data for NFA_CHO_ACTIVATED_EVT
+*/
+typedef struct
+{
+ BOOLEAN is_initiator; /* TRUE if local LLCP is initiator */
+} tNFA_CHO_ACTIVATED;
+
+/* NFA Connection Handover Carrier Power State */
+#define NFA_CHO_CPS_INACTIVE 0x00 /* Carrier is currently off */
+#define NFA_CHO_CPS_ACTIVE 0x01 /* Carrier is currently on */
+#define NFA_CHO_CPS_ACTIVATING 0x02 /* Activating carrier */
+#define NFA_CHO_CPS_UNKNOWN 0x03 /* Unknown */
+
+typedef UINT8 tNFA_CHO_CPS;
+
+/* Data for Alternative Carrier Information */
+typedef struct
+{
+ tNFA_CHO_CPS cps; /* carrier power state */
+ UINT8 num_aux_data; /* number of Auxiliary NDEF records */
+} tNFA_CHO_AC_INFO;
+
+/* Device Role of Handover */
+#define NFA_CHO_ROLE_REQUESTER 0
+#define NFA_CHO_ROLE_SELECTOR 1
+#define NFA_CHO_ROLE_UNDECIDED 2
+
+typedef UINT8 tNFA_CHO_ROLE_TYPE;
+
+/*
+** Data for NFA_CHO_CONNECTED_EVT
+*/
+typedef struct
+{
+ tNFA_CHO_ROLE_TYPE initial_role; /* NFA_CHO_ROLE_REQUESTER if local initiated */
+ /* NFA_CHO_ROLE_SELECTOR if remote initiated */
+} tNFA_CHO_CONNECTED;
+
+/* Disconnected reason */
+#define NFA_CHO_DISC_REASON_API_REQUEST 0
+#define NFA_CHO_DISC_REASON_ALEADY_CONNECTED 1
+#define NFA_CHO_DISC_REASON_CONNECTION_FAIL 2
+#define NFA_CHO_DISC_REASON_PEER_REQUEST 3
+#define NFA_CHO_DISC_REASON_LINK_DEACTIVATED 4
+#define NFA_CHO_DISC_REASON_TIMEOUT 5
+#define NFA_CHO_DISC_REASON_UNKNOWN_MSG 6
+#define NFA_CHO_DISC_REASON_INVALID_MSG 7
+#define NFA_CHO_DISC_REASON_SEMANTIC_ERROR 8
+#define NFA_CHO_DISC_REASON_INTERNAL_ERROR 9
+
+typedef UINT8 tNFA_CHO_DISC_REASON;
+
+/*
+** Data for NFA_CHO_DISCONNECTED_EVT
+*/
+typedef struct
+{
+ tNFA_CHO_DISC_REASON reason; /* disconnected reason */
+} tNFA_CHO_DISCONNECTED;
+
+/* Reference ID */
+typedef struct
+{
+ UINT8 ref_len;
+ UINT8 ref_name[NFA_CHO_MAX_REF_NAME_LEN];
+} tNFA_CHO_REF_ID;
+
+/* Alternative Carrier records including carrier power state, carrier data reference and aux data reference */
+typedef struct
+{
+ tNFA_CHO_CPS cps; /* carrier power state */
+ tNFA_CHO_REF_ID carrier_data_ref; /* carrier data reference */
+ UINT8 aux_data_ref_count; /* number of aux data */
+ tNFA_CHO_REF_ID aux_data_ref[NFA_CHO_MAX_AUX_DATA_COUNT]; /* aux data reference */
+} tNFA_CHO_AC_REC;
+
+/*
+** Data for NFA_CHO_REQUEST_EVT
+** Application may receive it while waiting for NFA_CHO_SELECT_EVT because of handover collision.
+*/
+typedef struct
+{
+ tNFA_STATUS status;
+ UINT8 num_ac_rec; /* number of Alternative Carrier records*/
+ tNFA_CHO_AC_REC ac_rec[NFA_CHO_MAX_AC_INFO]; /* Alternative Carrier records */
+ UINT8 *p_ref_ndef; /* pointer of NDEF including AC records */
+ UINT32 ref_ndef_len; /* length of NDEF */
+} tNFA_CHO_REQUEST;
+
+/*
+** Data for NFA_CHO_SELECT_EVT
+*/
+typedef struct
+{
+ tNFA_STATUS status;
+ UINT8 num_ac_rec; /* number of Alternative Carrier records*/
+ tNFA_CHO_AC_REC ac_rec[NFA_CHO_MAX_AC_INFO]; /* Alternative Carrier records */
+ UINT8 *p_ref_ndef; /* pointer of NDEF including AC records */
+ UINT32 ref_ndef_len; /* length of NDEF */
+} tNFA_CHO_SELECT;
+
+/* Error reason */
+#define NFA_CHO_ERROR_TEMP_MEM 0x01
+#define NFA_CHO_ERROR_PERM_MEM 0x02
+#define NFA_CHO_ERROR_CARRIER 0x03
+
+/*
+** Data for NFA_CHO_SEL_ERR_EVT
+*/
+typedef struct
+{
+ UINT8 error_reason; /* Error reason */
+ UINT32 error_data; /* Error Data per reason */
+} tNFA_CHO_SEL_ERR;
+
+/* Union of all Connection Handover callback structures */
+typedef union
+{
+ tNFA_STATUS status; /* NFA_CHO_REG_EVT */
+ /* NFA_CHO_DEACTIVATED_EVT */
+ /* NFA_CHO_TX_FAIL_EVT */
+ tNFA_CHO_ACTIVATED activated; /* NFA_CHO_ACTIVATED_EVT */
+ tNFA_CHO_CONNECTED connected; /* NFA_CHO_CONNECTED_EVT */
+ tNFA_CHO_DISCONNECTED disconnected; /* NFA_CHO_DISCONNECTED_EVT */
+ tNFA_CHO_SELECT select; /* NFA_CHO_SELECT_EVT */
+ tNFA_CHO_REQUEST request; /* NFA_CHO_REQUEST_EVT */
+ tNFA_CHO_SEL_ERR sel_err; /* NFA_CHO_SEL_ERR_EVT */
+} tNFA_CHO_EVT_DATA;
+
+/* NFA Connection Handover callback */
+typedef void (tNFA_CHO_CBACK) (tNFA_CHO_EVT event, tNFA_CHO_EVT_DATA *p_data);
+
+/*****************************************************************************
+** External Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*******************************************************************************
+**
+** Function NFA_ChoRegister
+**
+** Description This function is called to register callback function to receive
+** connection handover events.
+**
+** On this registration, "urn:nfc:sn:handover" server will be
+** registered on LLCP if enable_server is TRUE.
+**
+** The result of the registration is reported with NFA_CHO_REG_EVT.
+**
+** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_ChoRegister (BOOLEAN enable_server,
+ tNFA_CHO_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function NFA_ChoDeregister
+**
+** Description This function is called to deregister callback function from NFA
+** Connection Handover Application.
+**
+** If this is the valid deregistration, NFA Connection Handover
+** Application will close the service with "urn:nfc:sn:handover"
+** on LLCP and deregister NDEF type handler if any.
+**
+** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_ChoDeregister (void);
+
+/*******************************************************************************
+**
+** Function NFA_ChoConnect
+**
+** Description This function is called to create data link connection to
+** Connection Handover server on peer device.
+**
+** It must be called after receiving NFA_CHO_ACTIVATED_EVT.
+** NFA_CHO_CONNECTED_EVT will be returned if successful.
+** Otherwise, NFA_CHO_DISCONNECTED_EVT will be returned.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_ChoConnect (void);
+
+/*******************************************************************************
+**
+** Function NFA_ChoDisconnect
+**
+** Description This function is called to disconnect data link connection with
+** Connection Handover server on peer device.
+**
+** NFA_CHO_DISCONNECTED_EVT will be returned.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_ChoDisconnect (void);
+
+/*******************************************************************************
+**
+** Function NFA_ChoSendHr
+**
+** Description This function is called to send Handover Request Message with
+** Handover Carrier records or Alternative Carrier records.
+**
+** It must be called after receiving NFA_CHO_CONNECTED_EVT.
+**
+** NDEF may include one or more Handover Carrier records or Alternative
+** Carrier records with auxiliary data.
+** The records in NDEF must be matched with tNFA_CHO_AC_INFO in order.
+** Payload ID must be unique and Payload ID length must be less than
+** or equal to NFA_CHO_MAX_REF_NAME_LEN.
+**
+** The alternative carrier information of Handover Select record
+** will be sent to application by NFA_CHO_SELECT_EVT. Application
+** may receive NFA_CHO_REQUEST_EVT because of handover collision.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_ChoSendHr (UINT8 num_ac_info,
+ tNFA_CHO_AC_INFO *p_ac_info,
+ UINT8 *p_ndef,
+ UINT32 ndef_len);
+
+/*******************************************************************************
+**
+** Function NFA_ChoSendHs
+**
+** Description This function is called to send Handover Select message with
+** Alternative Carrier records as response to Handover Request
+** message.
+**
+** NDEF may include one or more Alternative Carrier records with
+** auxiliary data.
+** The records in NDEF must be matched with tNFA_CHO_AC_INFO in order.
+** Payload ID must be unique and Payload ID length must be less than
+** or equal to NFA_CHO_MAX_REF_NAME_LEN.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_ChoSendHs (UINT8 num_ac_info,
+ tNFA_CHO_AC_INFO *p_ac_info,
+ UINT8 *p_ndef,
+ UINT32 ndef_len);
+
+/*******************************************************************************
+**
+** Function NFA_ChoSendSelectError
+**
+** Description This function is called to send Error record to indicate failure
+** to process the most recently received Handover Request message.
+**
+** error_reason : NFA_CHO_ERROR_TEMP_MEM
+** NFA_CHO_ERROR_PERM_MEM
+** NFA_CHO_ERROR_CARRIER
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_ChoSendSelectError (UINT8 error_reason,
+ UINT32 error_data);
+
+/*******************************************************************************
+**
+** Function NFA_ChoSetTraceLevel
+**
+** Description This function sets the trace level for CHO. If called with
+** a value of 0xFF, it simply returns the current trace level.
+**
+** Returns The new or current trace level
+**
+*******************************************************************************/
+NFC_API extern UINT8 NFA_ChoSetTraceLevel (UINT8 new_level);
+
+#if (defined (NFA_CHO_TEST_INCLUDED) && (NFA_CHO_TEST_INCLUDED == TRUE))
+
+#define NFA_CHO_TEST_VERSION 0x01
+#define NFA_CHO_TEST_RANDOM 0x02
+/*******************************************************************************
+**
+** Function NFA_ChoSetTestParam
+**
+** Description This function is called to set test parameters.
+**
+*******************************************************************************/
+NFC_API extern void NFA_ChoSetTestParam (UINT8 test_enable,
+ UINT8 test_version,
+ UINT16 test_random_number);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFA_CHO_API_H */
diff --git a/src/nfa/include/nfa_ee_api.h b/src/nfa/include/nfa_ee_api.h
new file mode 100644
index 0000000..9d8cbac
--- /dev/null
+++ b/src/nfa/include/nfa_ee_api.h
@@ -0,0 +1,611 @@
+/******************************************************************************
+ *
+ * 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
+*****************************************************************************/
+#define NFA_MAX_AID_LEN NFC_MAX_AID_LEN /* 16 per ISO 7816 specification */
+#define NFA_EE_HANDLE_DH (NFA_HANDLE_GROUP_EE|NFC_DH_ID)
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+extern UINT8 NFA_REMOVE_ALL_AID[];
+#define NFA_REMOVE_ALL_AID_LEN (0x08)
+extern UINT8 nfa_ee_ce_route_strict_disable;
+#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 */
+};
+typedef UINT8 tNFA_EE_EVT;
+
+/* tNFA_NFCEE_INTERFACE values */
+#define NFA_EE_INTERFACE_APDU NFC_NFCEE_INTERFACE_APDU /* APDU Interface */
+#define NFA_EE_INTERFACE_HCI_ACCESS NFC_NFCEE_INTERFACE_HCI_ACCESS /* HCI Access Interface*/
+#define NFA_EE_INTERFACE_T3T NFC_NFCEE_INTERFACE_T3T /* T3T Command Interface*/
+#define NFA_EE_INTERFACE_TRANSPARENT NFC_NFCEE_INTERFACE_TRANSPARENT /* Transparent Interface*/
+#define NFA_EE_INTERFACE_PROPRIETARY NFC_NFCEE_INTERFACE_PROPRIETARY /* Proprietary */
+typedef UINT8 tNFA_EE_INTERFACE;
+
+#define NFA_EE_TAG_HW_ID NFC_NFCEE_TAG_HW_ID /* HW/Registration ID */
+#define NFA_EE_TAG_ATR_BYTES NFC_NFCEE_TAG_ATR_BYTES /* ATR Bytes */
+#define NFA_EE_TAG_T3T_INFO NFC_NFCEE_TAG_T3T_INFO /* T3T Supplement. Info */
+#define NFA_EE_TAG_HCI_HOST_ID NFC_NFCEE_TAG_HCI_HOST_ID /* Broadcom Proprietary */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+typedef UINT16 tNFA_EE_TAG;
+#else
+typedef UINT8 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 tNFA_EE_MD;
+
+#define NFA_EE_PWR_STATE_ON 0x01 /* The device is on */
+#define NFA_EE_PWR_STATE_SWITCH_OFF 0x02 /* The device is switched off */
+#define NFA_EE_PWR_STATE_BATT_OFF 0x04 /* The device's battery is removed */
+#define NFA_EE_PWR_STATE_NONE 0 /* used to remove a particular technology or protocol based routing cfg of a handle from the routing table. */
+typedef UINT8 tNFA_EE_PWR_STATE;
+
+
+#define NFA_EE_STATUS_INACTIVE NFC_NFCEE_STATUS_INACTIVE /* NFCEE connected and inactive */
+#define NFA_EE_STATUS_ACTIVE NFC_NFCEE_STATUS_ACTIVE /* NFCEE connected and active */
+#define NFA_EE_STATUS_REMOVED NFC_NFCEE_STATUS_REMOVED /* NFCEE removed */
+#define NFA_EE_STATUS_PENDING 0x10 /* waiting for response from NFCC */
+#define NFA_EE_STATUS_ACTIVATING (NFA_EE_STATUS_PENDING+NFC_NFCEE_STATUS_ACTIVE)
+#define NFA_EE_STATUS_DEACTIVATING (NFA_EE_STATUS_PENDING+NFC_NFCEE_STATUS_INACTIVE)
+typedef UINT8 tNFA_EE_STATUS;
+
+
+
+/* additional NFCEE Info */
+typedef struct
+{
+ tNFA_EE_TAG tag;
+ UINT8 len;
+ UINT8 info[NFC_MAX_EE_INFO];
+} tNFA_EE_TLV;
+
+typedef struct
+{
+ tNFA_HANDLE ee_handle; /* handle for NFCEE oe DH */
+ tNFA_EE_STATUS ee_status; /* The NFCEE status */
+ UINT8 num_interface; /* number of NFCEE interface*/
+ tNFA_EE_INTERFACE ee_interface[NFC_MAX_EE_INTERFACE];/* NFCEE supported interface */
+ UINT8 num_tlvs; /* number of TLVs */
+ tNFA_EE_TLV ee_tlv[NFC_MAX_EE_TLVS];/* the TLV */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 num_ee; /* number of NFCEEs found */
+ tNFA_EE_INFO ee_info[NFA_EE_MAX_EE_SUPPORTED];/*NFCEE information */
+} tNFA_EE_DISCOVER;
+
+typedef struct
+{
+ tNFA_HANDLE ee_handle; /* Handle of NFCEE */
+ tNFA_STATUS status; /* NFA_STATUS_OK is successful */
+ tNFA_EE_INTERFACE ee_interface; /* NFCEE interface associated with this connection */
+} tNFA_EE_CONNECT;
+
+#define NFA_EE_TRGR_SELECT NFC_EE_TRIG_SELECT /* ISO 7816-4 SELECT command */
+#define NFA_EE_TRGR_RF_PROTOCOL NFC_EE_TRIG_RF_PROTOCOL /* RF Protocol changed */
+#define NFA_EE_TRGR_RF_TECHNOLOGY NFC_EE_TRIG_RF_TECHNOLOGY/* RF Technology changed */
+#define NFA_EE_TRGR_APP_INIT NFC_EE_TRIG_APP_INIT /* Application initiation */
+typedef tNFC_EE_TRIGGER tNFA_EE_TRIGGER;
+
+/* Union of NFCEE action parameter depending on the associated trigger */
+typedef union
+{
+ tNFA_NFC_PROTOCOL protocol; /* NFA_EE_TRGR_RF_PROTOCOL: the protocol that triggers this event */
+ tNFC_RF_TECH technology; /* NFA_EE_TRGR_RF_TECHNOLOGY:the technology that triggers this event */
+ tNFC_AID aid; /* NFA_EE_TRGR_SELECT : the AID in the received SELECT AID command */
+ tNFC_APP_INIT app_init; /* NFA_EE_TRGR_APP_INIT: The information for the application initiated trigger */
+} tNFA_EE_ACTION_PARAM;
+
+typedef struct
+{
+ tNFA_HANDLE ee_handle; /* Handle of NFCEE */
+ tNFA_EE_TRIGGER trigger; /* the trigger of this event */
+ tNFA_EE_ACTION_PARAM param;
+} tNFA_EE_ACTION;
+
+typedef struct
+{
+ tNFA_HANDLE ee_handle; /* Handle of NFCEE */
+ tNFA_STATUS status; /* NFA_STATUS_OK is successful */
+ tNFA_EE_STATUS ee_status; /* The NFCEE status */
+} tNFA_EE_MODE_SET;
+
+typedef struct
+{
+ tNFA_HANDLE ee_handle; /* Handle of MFCEE */
+ tNFA_NFC_PROTOCOL la_protocol; /* Listen A protocol */
+ tNFA_NFC_PROTOCOL lb_protocol; /* Listen B protocol */
+ tNFA_NFC_PROTOCOL lf_protocol; /* Listen F protocol */
+ tNFA_NFC_PROTOCOL lbp_protocol; /* Listen B' protocol */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ tNFA_NFC_PROTOCOL pa_protocol; /* Passive poll A SWP Reader */
+ tNFA_NFC_PROTOCOL pb_protocol; /* Passive poll B SWP Reader */
+ UINT8 ee_req_op; /* add or remove req ntf*/
+#endif
+} tNFA_EE_DISCOVER_INFO;
+
+/* Data for NFA_EE_DISCOVER_REQ_EVT */
+typedef struct
+{
+ UINT8 status; /* NFA_STATUS_OK if successful */
+ UINT8 num_ee; /* number of MFCEE information */
+ tNFA_EE_DISCOVER_INFO ee_disc_info[NFA_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 len; /* Length of data */
+ UINT8 *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 size;
+ tNFA_EE_CONNECT connect;
+ tNFA_EE_ACTION action;
+ tNFA_EE_MODE_SET mode_set;
+ tNFA_EE_INFO new_ee;
+ tNFA_EE_DISCOVER_REQ discover_req;
+} tNFA_EE_CBACK_DATA;
+
+
+/* EE callback */
+typedef void (tNFA_EE_CBACK) (tNFA_EE_EVT event, tNFA_EE_CBACK_DATA *p_data);
+
+/*****************************************************************************
+** External Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*******************************************************************************
+**
+** Function NFA_EeDiscover
+**
+** Description This function retrieves the NFCEE information from NFCC.
+** The NFCEE information is reported in NFA_EE_DISCOVER_EVT.
+**
+** This function may be called when a system supports removable
+** NFCEEs,
+**
+** Returns NFA_STATUS_OK if information is retrieved successfully
+** NFA_STATUS_FAILED If wrong state (retry later)
+** NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_EeDiscover (tNFA_EE_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function NFA_EeGetInfo
+**
+** Description This function retrieves the NFCEE information from NFA.
+** The actual number of NFCEE is returned in p_num_nfcee
+** and NFCEE information is returned in p_info
+**
+** Returns NFA_STATUS_OK if information is retrieved successfully
+** NFA_STATUS_FAILED If wrong state (retry later)
+** NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_EeGetInfo (UINT8 *p_num_nfcee,
+ tNFA_EE_INFO *p_info);
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_AllEeGetInfo (UINT8 *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
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_EeRegister (tNFA_EE_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function NFA_EeDeregister
+**
+** Description This function de-registers the callback function
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+** NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_EeDeregister (tNFA_EE_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function NFA_EeModeSet
+**
+** Description This function is called to activate (mode = NFA_EE_MD_ACTIVATE)
+** or deactivate (mode = NFA_EE_MD_DEACTIVATE) the NFCEE
+** identified by the given ee_handle. The result of this
+** operation is reported with the NFA_EE_MODE_SET_EVT.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+** NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_EeModeSet (tNFA_HANDLE ee_handle,
+ tNFA_EE_MD mode);
+
+
+/*******************************************************************************
+**
+** Function NFA_EeSetDefaultTechRouting
+**
+** Description This function is called to add, change or remove the
+** default routing based on RF technology in the listen mode
+** routing table for the given ee_handle. The status of this
+** operation is reported as the NFA_EE_SET_TECH_CFG_EVT.
+**
+** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function
+**
+** Note: NFA_EeUpdateNow() should be called after last NFA-EE function
+** to change the listen mode routing is called.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+** NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_EeSetDefaultTechRouting (tNFA_HANDLE ee_handle,
+ tNFA_TECHNOLOGY_MASK technologies_switch_on,
+ tNFA_TECHNOLOGY_MASK technologies_switch_off,
+ tNFA_TECHNOLOGY_MASK technologies_battery_off
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ ,tNFA_TECHNOLOGY_MASK technologies_screen_lock,
+ tNFA_TECHNOLOGY_MASK technologies_screen_off
+#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
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_EeSetDefaultProtoRouting (tNFA_HANDLE ee_handle,
+ tNFA_PROTOCOL_MASK protocols_switch_on,
+ tNFA_PROTOCOL_MASK protocols_switch_off,
+ tNFA_PROTOCOL_MASK protocols_battery_off
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ ,tNFA_PROTOCOL_MASK protocols_screen_lock,
+ tNFA_PROTOCOL_MASK protocols_screen_off
+#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
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_EeAddAidRouting (tNFA_HANDLE ee_handle,
+ UINT8 aid_len,
+ UINT8 *p_aid,
+ tNFA_EE_PWR_STATE power_state
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ , UINT8 vs_info);
+#else
+)
+#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
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_EeRemoveAidRouting (UINT8 aid_len,
+ UINT8 *p_aid);
+
+/*******************************************************************************
+**
+** 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
+**
+*******************************************************************************/
+NFC_API 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
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_EeUpdateNow (void);
+
+/*******************************************************************************
+**
+** Function NFA_EeConnect
+**
+** Description Open connection to an NFCEE attached to the NFCC
+**
+** The status of this operation is
+** reported with the NFA_EE_CONNECT_EVT.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+** NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_EeConnect (tNFA_HANDLE ee_handle,
+ UINT8 ee_interface,
+ tNFA_EE_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function NFA_EeSendData
+**
+** Description Send data to the given NFCEE.
+** This function shall be called after NFA_EE_CONNECT_EVT is reported
+** and before NFA_EeDisconnect is called on the given ee_handle.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+** NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_EeSendData (tNFA_HANDLE ee_handle,
+ UINT16 data_len,
+ UINT8 *p_data);
+
+/*******************************************************************************
+**
+** Function NFA_EeDisconnect
+**
+** Description Disconnect (if a connection is currently open) from an
+** NFCEE interface. The result of this operation is reported
+** with the NFA_EE_DISCONNECT_EVT.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+** NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_EeDisconnect (tNFA_HANDLE ee_handle);
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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
+**
+*******************************************************************************/
+NFC_API 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.
+**
+*******************************************************************************/
+NFC_API extern UINT16 NFA_GetAidTableSize();
+
+/*******************************************************************************
+**
+** Function NFA_GetRemainingAidTableSize
+**
+** Description This function is called to get the remaining AID routing
+** table size.
+**
+** Returns Remaining AID routing table size.
+**
+*******************************************************************************/
+NFC_API extern UINT16 NFA_GetRemainingAidTableSize();
+
+/*******************************************************************************
+**
+** Function NFA_SetCEStrictDisable
+**
+** Description This function is called to set the flag for Strict CE.
+**
+** Returns None.
+**
+*******************************************************************************/
+NFC_API extern void NFA_SetCEStrictDisable(UINT32 state);
+#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..2420c08
--- /dev/null
+++ b/src/nfa/include/nfa_hci_api.h
@@ -0,0 +1,658 @@
+/******************************************************************************
+ *
+ * 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"
+
+/*****************************************************************************
+** Constants and data types
+*****************************************************************************/
+
+/* NFA HCI Debug constants */
+#define NFA_HCI_DEBUG_DISPLAY_CB 0
+#define NFA_HCI_DEBUG_SIM_HCI_EVENT 1
+#define NFA_HCI_DEBUG_ENABLE_LOOPBACK 101
+#define NFA_HCI_DEBUG_DISABLE_LOOPBACK 102
+
+/* NFA HCI callback events */
+#define NFA_HCI_REGISTER_EVT 0x00 /* Application registered */
+#define NFA_HCI_DEREGISTER_EVT 0x01 /* Application deregistered */
+#define NFA_HCI_GET_GATE_PIPE_LIST_EVT 0x02 /* Retrieved gates,pipes assoc. to application */
+#define NFA_HCI_ALLOCATE_GATE_EVT 0x03 /* A generic gate allocated to the application */
+#define NFA_HCI_DEALLOCATE_GATE_EVT 0x04 /* A generic gate is released */
+#define NFA_HCI_CREATE_PIPE_EVT 0x05 /* Pipe is created */
+#define NFA_HCI_OPEN_PIPE_EVT 0x06 /* Pipe is opened / could not open */
+#define NFA_HCI_CLOSE_PIPE_EVT 0x07 /* Pipe is closed / could not close */
+#define NFA_HCI_DELETE_PIPE_EVT 0x08 /* Pipe is deleted */
+#define NFA_HCI_HOST_LIST_EVT 0x09 /* Received list of Host from Host controller */
+#define NFA_HCI_INIT_EVT 0x0A /* HCI subsytem initialized */
+#define NFA_HCI_EXIT_EVT 0x0B /* HCI subsytem exited */
+#define NFA_HCI_RSP_RCVD_EVT 0x0C /* Response recvd to cmd sent on app owned pipe */
+#define NFA_HCI_RSP_SENT_EVT 0x0D /* Response sent on app owned pipe */
+#define NFA_HCI_CMD_SENT_EVT 0x0E /* Command sent on app owned pipe */
+#define NFA_HCI_EVENT_SENT_EVT 0x0F /* Event sent on app owned pipe */
+#define NFA_HCI_CMD_RCVD_EVT 0x10 /* Command received on app owned pipe */
+#define NFA_HCI_EVENT_RCVD_EVT 0x11 /* Event received on app owned pipe */
+#define NFA_HCI_GET_REG_CMD_EVT 0x12 /* Registry read command sent */
+#define NFA_HCI_SET_REG_CMD_EVT 0x13 /* Registry write command sent */
+#define NFA_HCI_GET_REG_RSP_EVT 0x14 /* Received response to read registry command */
+#define NFA_HCI_SET_REG_RSP_EVT 0x15 /* Received response to write registry command */
+#define NFA_HCI_ADD_STATIC_PIPE_EVT 0x16 /* A static pipe is added */
+
+typedef UINT8 tNFA_HCI_EVT;
+
+#define NFA_MAX_HCI_APP_NAME_LEN 0x10 /* Max application name length */
+#define NFA_MAX_HCI_CMD_LEN 255 /* Max HCI command length */
+#define NFA_MAX_HCI_RSP_LEN 255 /* Max HCI event length */
+#if (NFC_NXP_NOT_OPEN_INCLUDED == 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)
+ * */
+#define NFA_MAX_HCI_EVENT_LEN 300 /* Max HCI event length */
+#else
+#define NFA_MAX_HCI_EVENT_LEN 260 /* Max HCI event length */
+#endif
+#define NFA_MAX_HCI_DATA_LEN 260 /* Max HCI data length */
+
+/* NFA HCI PIPE states */
+#define NFA_HCI_PIPE_CLOSED 0x00 /* Pipe is closed */
+#define NFA_HCI_PIPE_OPENED 0x01 /* Pipe is opened */
+
+typedef UINT8 tNFA_HCI_PIPE_STATE;
+/* Dynamic pipe control block */
+typedef struct
+{
+ UINT8 pipe_id; /* Pipe ID */
+ tNFA_HCI_PIPE_STATE pipe_state; /* State of the Pipe */
+ UINT8 local_gate; /* local gate id */
+ UINT8 dest_host; /* Peer host to which this pipe is connected */
+ UINT8 dest_gate; /* Peer gate to which this pipe is connected */
+} tNFA_HCI_PIPE_INFO;
+
+/* Data for NFA_HCI_REGISTER_EVT */
+typedef struct
+{
+ tNFA_STATUS status; /* Status of registration */
+ tNFA_HANDLE hci_handle; /* Handle assigned to the application */
+ UINT8 num_pipes; /* Number of dynamic pipes exist for the application */
+ UINT8 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 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 num_gates; /* Number of generic gates exist for the application */
+ UINT8 gate[NFA_HCI_MAX_GATE_CB]; /* List of generic gates allocated to the application */
+ UINT8 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 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 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 pipe; /* The pipe created for the application */
+ UINT8 source_gate; /* DH host gate to which the one end of pipe is attached */
+ UINT8 dest_host; /* Destination host whose gate is the other end of the pipe is attached to */
+ UINT8 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 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 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 pipe; /* The dynamic pipe for delete operation */
+} tNFA_HCI_DELETE_PIPE;
+
+/* Data for NFA_HCI_HOST_LIST_EVT */
+typedef struct
+{
+ tNFA_STATUS status; /* Status og get host list operation */
+ UINT8 num_hosts; /* Number of hosts in the host network */
+ UINT8 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 pipe; /* The pipe on which HCP packet is exchanged */
+ UINT8 rsp_code; /* Response id */
+ UINT16 rsp_len; /* Response parameter length */
+ UINT8 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 pipe; /* The pipe on which HCP EVT packet is received */
+ UINT8 evt_code; /* HCP EVT id */
+ UINT16 evt_len; /* HCP EVT parameter length */
+ UINT8 *p_evt_buf; /* HCP EVT Parameter */
+} tNFA_HCI_EVENT_RCVD;
+
+/* Data for NFA_HCI_CMD_RCVD_EVT */
+typedef struct
+{
+ tNFA_STATUS status; /* Status of Command received */
+ UINT8 pipe; /* The pipe on which HCP CMD packet is received */
+ UINT8 cmd_code; /* HCP CMD id */
+ UINT16 cmd_len; /* HCP CMD parameter length */
+ UINT8 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 */
+} 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 pipe; /* Pipe on whose registry is of interest */
+ UINT8 index; /* Index of the registry operated */
+ UINT8 data_len; /* length of the registry parameter */
+ UINT8 reg_data[NFA_MAX_HCI_DATA_LEN]; /* Registry parameter */
+} tNFA_HCI_REGISTRY;
+
+
+/* Union of all hci callback structures */
+typedef union
+{
+ tNFA_HCI_REGISTER hci_register; /* NFA_HCI_REGISTER_EVT */
+ tNFA_HCI_DEREGISTER hci_deregister; /* NFA_HCI_DEREGISTER_EVT */
+ tNFA_HCI_GET_GATE_PIPE_LIST gates_pipes; /* NFA_HCI_GET_GATE_PIPE_LIST_EVT */
+ tNFA_HCI_ALLOCATE_GATE allocated; /* NFA_HCI_ALLOCATE_GATE_EVT */
+ tNFA_HCI_DEALLOCATE_GATE deallocated; /* NFA_HCI_DEALLOCATE_GATE_EVT */
+ tNFA_HCI_CREATE_PIPE created; /* NFA_HCI_CREATE_PIPE_EVT */
+ tNFA_HCI_OPEN_PIPE opened; /* NFA_HCI_OPEN_PIPE_EVT */
+ tNFA_HCI_CLOSE_PIPE closed; /* NFA_HCI_CLOSE_PIPE_EVT */
+ tNFA_HCI_DELETE_PIPE deleted; /* NFA_HCI_DELETE_PIPE_EVT */
+ tNFA_HCI_HOST_LIST hosts; /* NFA_HCI_HOST_LIST_EVT */
+ tNFA_HCI_RSP_RCVD rsp_rcvd; /* NFA_HCI_RSP_RCVD_EVT */
+ tNFA_HCI_RSP_SENT rsp_sent; /* NFA_HCI_RSP_SENT_EVT */
+ tNFA_HCI_CMD_SENT cmd_sent; /* NFA_HCI_CMD_SENT_EVT */
+ tNFA_HCI_EVENT_SENT evt_sent; /* NFA_HCI_EVENT_SENT_EVT */
+ tNFA_HCI_CMD_RCVD cmd_rcvd; /* NFA_HCI_CMD_RCVD_EVT */
+ tNFA_HCI_EVENT_RCVD rcvd_evt; /* NFA_HCI_EVENT_RCVD_EVT */
+ tNFA_STATUS status; /* status of api command request */
+ tNFA_HCI_REGISTRY registry; /* all registry-related events - 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 */
+} tNFA_HCI_EVT_DATA;
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciRegister (char *p_app_name, tNFA_HCI_CBACK *p_cback, BOOLEAN b_send_conn_evts);
+
+/*******************************************************************************
+**
+** Function NFA_HciGetGateAndPipeList
+**
+** Description This function will retrieve the list of gates allocated to
+** the application and list of dynamic pipes created for the
+** application. The app will be notified with
+** NFA_HCI_GET_GATE_PIPE_LIST_EVT. List of allocated dynamic
+** gates to the application and list of pipes created by the
+** application will be returned as part of
+** tNFA_HCI_GET_GATE_PIPE_LIST data.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciGetGateAndPipeList (tNFA_HANDLE hci_handle);
+
+/*******************************************************************************
+**
+** Function NFA_HciDeregister
+**
+** Description This function is called to deregister an application
+** from HCI. The app will be notified by NFA_HCI_DEREGISTER_EVT
+** after deleting all the pipes owned by the app and deallocating
+** all the gates allocated to the app or if an error occurs.
+** The app can release the buffer provided for collecting long
+** APDUs after receiving NFA_HCI_DEREGISTER_EVT.
+** Even if deregistration fails, the app has to register again
+** to provide a new cback function and event buffer for receiving
+** long APDUs.
+**
+** Returns NFA_STATUS_OK if the application is deregistered successfully
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciDeregister (char *p_app_name);
+
+/*******************************************************************************
+**
+** Function NFA_HciAllocGate
+**
+** Description This function will allocate 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
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciAllocGate (tNFA_HANDLE hci_handle, UINT8 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
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciDeallocGate (tNFA_HANDLE conn_handle, UINT8 gate);
+
+/*******************************************************************************
+**
+** Function NFA_HciGetHostList
+**
+** Description This function will request the host controller to return the
+** list of hosts that are present in the host network. When
+** host controller responds with the host list (or if an error
+** occurs), the app will be notified with NFA_HCI_HOST_LIST_EVT
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciGetHostList (tNFA_HANDLE hci_handle);
+
+/*******************************************************************************
+**
+** Function NFA_HciCreatePipe
+**
+** Description This function is called to create a dynamic pipe with the
+** specified host. When the dynamic pipe is created (or
+** if an error occurs), the app will be notified with
+** NFA_HCI_CREATE_PIPE_EVT with the pipe id. If a pipe exists
+** between the two gates passed as argument and if it was
+** created earlier by the calling application then the pipe
+** id of the existing pipe will be returned and a new pipe
+** will not be created. After successful creation of pipe,
+** registry entry will be created for the dynamic pipe and
+** all information related to the pipe will be stored in non
+** volatile memory.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciCreatePipe (tNFA_HANDLE hci_handle,
+ UINT8 source_gate_id,
+ UINT8 dest_host,
+ UINT8 dest_gate);
+
+/*******************************************************************************
+**
+** Function NFA_HciOpenPipe
+**
+** Description This function is called to open a dynamic pipe.
+** When the dynamic pipe is opened (or
+** if an error occurs), the app will be notified with
+** NFA_HCI_OPEN_PIPE_EVT with the pipe id.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciOpenPipe (tNFA_HANDLE hci_handle, UINT8 pipe);
+
+/*******************************************************************************
+**
+** Function NFA_HciGetRegistry
+**
+** Description This function requests a peer host to return the desired
+** registry field value for the gate that the pipe is on.
+**
+** When the peer host responds,the app is notified with
+** NFA_HCI_GET_REG_RSP_EVT or
+** if an error occurs in sending the command the app will be
+** notified by NFA_HCI_CMD_SENT_EVT
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciGetRegistry (tNFA_HANDLE hci_handle, UINT8 pipe, UINT8 reg_inx);
+
+/*******************************************************************************
+**
+** Function NFA_HciSetRegistry
+**
+** Description This function requests a peer host to set the desired
+** registry field value for the gate that the pipe is on.
+**
+** When the peer host responds,the app is notified with
+** NFA_HCI_SET_REG_RSP_EVT or
+** if an error occurs in sending the command the app will be
+** notified by NFA_HCI_CMD_SENT_EVT
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciSetRegistry (tNFA_HANDLE hci_handle,
+ UINT8 pipe,
+ UINT8 reg_inx,
+ UINT8 data_size,
+ UINT8 *p_data);
+
+/*******************************************************************************
+**
+** Function NFA_HciSendCommand
+**
+** Description This function is called to send a command on a pipe created
+** by the application.
+** The app will be notified by NFA_HCI_CMD_SENT_EVT if an error
+** occurs.
+** When the peer host responds,the app is notified with
+** NFA_HCI_RSP_RCVD_EVT
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciSendCommand (tNFA_HANDLE hci_handle,
+ UINT8 pipe,
+ UINT8 cmd_code,
+ UINT16 cmd_size,
+ UINT8 *p_data);
+
+/*******************************************************************************
+**
+** Function NFA_HciSendResponse
+**
+** Description This function is called to send a response on a pipe created
+** by the application.
+** The app will be notified by NFA_HCI_RSP_SENT_EVT if an error
+** occurs.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciSendResponse (tNFA_HANDLE hci_handle,
+ UINT8 pipe,
+ UINT8 response,
+ UINT8 data_size,
+ UINT8 *p_data);
+
+/*******************************************************************************
+**
+** Function NFA_HciSendEvent
+**
+** Description This function is called to send any event on a pipe created
+** by the application.
+** The app will be notified by NFA_HCI_EVENT_SENT_EVT
+** after successfully sending the event on the specified pipe
+** or if an error occurs. The application should wait for this
+** event before releasing event buffer passed as argument.
+** If the app is expecting a response to the event then it can
+** provide response buffer for collecting the response. If it
+** provides a response buffer it should also provide response
+** timeout indicating duration validity of the response buffer.
+** Maximum of NFA_MAX_HCI_EVENT_LEN bytes APDU can be received
+** using internal buffer if no response buffer is provided by
+** the application. The app will be notified by
+** NFA_HCI_EVENT_RCVD_EVT after receiving the response event
+** or on timeout if app provided response buffer.
+** If response buffer is provided by the application, it should
+** wait for this event before releasing the response buffer.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciSendEvent (tNFA_HANDLE hci_handle,
+ UINT8 pipe,
+ UINT8 evt_code,
+ UINT16 evt_size,
+ UINT8 *p_data,
+ UINT16 rsp_size,
+ UINT8 *p_rsp_buf,
+ UINT16 rsp_timeout);
+
+/*******************************************************************************
+**
+** Function NFA_HciClosePipe
+**
+** Description This function is called to close a dynamic pipe.
+** When the dynamic pipe is closed (or
+** if an error occurs), the app will be notified with
+** NFA_HCI_CLOSE_PIPE_EVT with the pipe id.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciClosePipe (tNFA_HANDLE hci_handle, UINT8 pipe);
+
+/*******************************************************************************
+**
+** Function NFA_HciDeletePipe
+**
+** Description This function is called to delete a particular dynamic pipe.
+** When the dynamic pipe is deleted (or if an error occurs),
+** the app will be notified with NFA_HCI_DELETE_PIPE_EVT with
+** the pipe id. After successful deletion of pipe, registry
+** entry will be deleted for the dynamic pipe and all
+** information related to the pipe will be deleted from non
+** volatile memory.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciDeletePipe (tNFA_HANDLE hci_handle, UINT8 pipe);
+
+/*******************************************************************************
+**
+** Function NFA_HciAddStaticPipe
+**
+** Description This function is called to add a static pipe for sending
+** 7816 APDUs. When the static pipe is added (or if an error occurs),
+** the app will be notified with NFA_HCI_ADD_STATIC_PIPE_EVT with
+** status.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciAddStaticPipe (tNFA_HANDLE hci_handle, UINT8 host, UINT8 gate, UINT8 pipe);
+
+/*******************************************************************************
+**
+** Function NFA_HciDebug
+**
+** Description Debug function.
+**
+*******************************************************************************/
+NFC_API extern void NFA_HciDebug (UINT8 action, UINT8 size, UINT8 *p_data);
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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
+**
+*******************************************************************************/
+NFC_API extern void NFA_HciW4eSETransaction_Complete(tNFA_HCI_TRANSCV_STATE type);
+#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..0d2daa1
--- /dev/null
+++ b/src/nfa/include/nfa_hci_defs.h
@@ -0,0 +1,152 @@
+/******************************************************************************
+ *
+ * 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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#ifdef GEMALTO_SE_SUPPORT
+#define NFC_HCI_DEFAULT_DEST_GATE 0XF0
+#endif
+#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
+
+/* 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 (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define NFA_HCI_EVT_WTX 0x11
+#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
+
+/* Host controller and DH Link management gate registry identifier */
+#define NFA_HCI_REC_ERROR_INDEX 0x02
+
+/* DH Identity management gate registry identifier */
+#define NFA_HCI_VERSION_SW_INDEX 0x01
+#define NFA_HCI_VERSION_HW_INDEX 0x03
+#define NFA_HCI_VENDOR_NAME_INDEX 0x04
+#define NFA_HCI_MODEL_ID_INDEX 0x05
+#define NFA_HCI_HCI_VERSION_INDEX 0x02
+#define NFA_HCI_GATES_LIST_INDEX 0x06
+
+
+#endif /* NFA_HCI_DEFS_H */
diff --git a/src/nfa/include/nfa_mem_co.h b/src/nfa/include/nfa_mem_co.h
new file mode 100644
index 0000000..4dfcacb
--- /dev/null
+++ b/src/nfa/include/nfa_mem_co.h
@@ -0,0 +1,74 @@
+/******************************************************************************
+ *
+ * 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
+**
+*******************************************************************************/
+NFC_API extern void *nfa_mem_co_alloc (UINT32 num_bytes);
+
+
+/*******************************************************************************
+**
+** Function nfa_mem_co_free
+**
+** Description free buffer previously allocated using nfa_mem_co_alloc
+**
+** Returns:
+** Nothing
+**
+*******************************************************************************/
+NFC_API extern void nfa_mem_co_free (void *p_buf);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFA_MEM_CO_H */
diff --git a/src/nfa/include/nfa_nv_ci.h b/src/nfa/include/nfa_nv_ci.h
new file mode 100644
index 0000000..512bf78
--- /dev/null
+++ b/src/nfa/include/nfa_nv_ci.h
@@ -0,0 +1,108 @@
+/******************************************************************************
+ *
+ * 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
+{
+ BT_HDR hdr;
+ tNFA_NV_CO_STATUS status;
+ int fd;
+ UINT16 num_read;
+} tNFA_NV_CI_READ_EVT;
+
+/* Write Ready Event */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_NV_CO_STATUS status;
+ int fd;
+} tNFA_NV_CI_WRITE_EVT;
+
+/*****************************************************************************
+** Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*******************************************************************************
+**
+** Function nfa_nv_ci_write
+**
+** Description This function sends an event to NFAA indicating the phone
+** has written the number of bytes specified in the call-out
+** function, nfa_nv_co_write (), and is ready for more data.
+** This function is used to control the TX data flow.
+** Note: The data buffer is released by the stack aioer
+** calling this function.
+**
+** Parameters status - NFA_NV_CO_OK, NFA_NV_CO_NOSPACE, or NFA_NV_CO_FAIL
+** evt - Used Internally by NFA -> MUST be same value passed
+** in call-out function.
+**
+** Returns void
+**
+*******************************************************************************/
+NFC_API extern void nfa_nv_ci_write (tNFA_NV_CO_STATUS status);
+
+/*******************************************************************************
+**
+** Function nfa_nv_ci_read
+**
+** Description This function sends an event to NFA indicating the phone has
+** read in the requested amount of data specified in the
+** nfa_nv_co_read () call-out function. It should only be called
+** when the requested number of bytes has been read.
+**
+** Parameters num_bytes_read - number of bytes read into the buffer
+** specified in the read callout-function.
+** status - NFA_NV_CO_OK if full buffer of data,
+** NFA_NV_CO_EOF if the end of file has been reached,
+** NFA_NV_CO_FAIL if an error has occurred.
+** evt - Used Internally by NFA -> MUST be same value passed
+** in call-out function.
+**
+** Returns void
+**
+*******************************************************************************/
+NFC_API extern void nfa_nv_ci_read (UINT16 num_bytes_read,
+ tNFA_NV_CO_STATUS status,
+ UINT8 block);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BTA_FS_CI_H */
diff --git a/src/nfa/include/nfa_nv_co.h b/src/nfa/include/nfa_nv_co.h
new file mode 100644
index 0000000..154f04b
--- /dev/null
+++ b/src/nfa/include/nfa_nv_co.h
@@ -0,0 +1,114 @@
+/******************************************************************************
+ *
+ * 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 */
+#define NFA_NV_CO_NONE 0x09 /* used in nfa_nv_ci_open, on resume (no file to resume) */
+
+typedef UINT8 tNFA_NV_CO_STATUS;
+
+
+#define DH_NV_BLOCK 0x01
+#define HC_F3_NV_BLOCK 0x02
+#define HC_F4_NV_BLOCK 0x03
+#define HC_DH_NV_BLOCK 0x04
+#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.
+**
+*******************************************************************************/
+NFC_API extern void nfa_nv_co_read (UINT8 *p_buf, UINT16 nbytes, UINT8 block);
+
+/*******************************************************************************
+**
+** Function nfa_nv_co_write
+**
+** Description This function is called by io to send file data to the
+** phone.
+**
+** Parameters p_buf - buffer to read the data from.
+** nbytes - number of bytes to write out to the file.
+**
+** Returns void
+**
+** Note: Upon completion of the request, nfa_nv_ci_write () is
+** called with the file descriptor and the status. The
+** call-in function should only be called when ALL requested
+** bytes have been written, or an error has been detected,
+**
+*******************************************************************************/
+NFC_API extern void nfa_nv_co_write (const UINT8 *p_buf, UINT16 nbytes, UINT8 block);
+
+
+#endif /* NFA_NV_CO_H */
diff --git a/src/nfa/include/nfa_p2p_api.h b/src/nfa/include/nfa_p2p_api.h
new file mode 100644
index 0000000..45381ca
--- /dev/null
+++ b/src/nfa/include/nfa_p2p_api.h
@@ -0,0 +1,575 @@
+/******************************************************************************
+ *
+ * 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 */
+#define NFA_P2P_REG_SERVER_EVT 0x00 /* Server is registered */
+#define NFA_P2P_REG_CLIENT_EVT 0x01 /* Client is registered */
+#define NFA_P2P_ACTIVATED_EVT 0x02 /* LLCP Link has been activated */
+#define NFA_P2P_DEACTIVATED_EVT 0x03 /* LLCP Link has been deactivated */
+#define NFA_P2P_CONN_REQ_EVT 0x04 /* Data link connection request from peer */
+#define NFA_P2P_CONNECTED_EVT 0x05 /* Data link connection has been established */
+#define NFA_P2P_DISC_EVT 0x06 /* Data link connection has been disconnected */
+#define NFA_P2P_DATA_EVT 0x07 /* Data received from peer */
+#define NFA_P2P_CONGEST_EVT 0x08 /* Status indication of outgoing data */
+#define NFA_P2P_LINK_INFO_EVT 0x09 /* link MIU and Well-Known Service list */
+#define NFA_P2P_SDP_EVT 0x0A /* Remote SAP of SDP result */
+
+typedef UINT8 tNFA_P2P_EVT;
+
+/* NFA allocates a SAP for server */
+#define NFA_P2P_ANY_SAP LLCP_INVALID_SAP
+#define NFA_P2P_INVALID_SAP LLCP_INVALID_SAP
+
+/* Recommanded MIU's for connection-oriented */
+#define NFA_P2P_MIU_1 (NCI_NFC_DEP_MAX_DATA - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE)
+#define NFA_P2P_MIU_2 (2*NCI_NFC_DEP_MAX_DATA - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE)
+#define NFA_P2P_MIU_3 (3*NCI_NFC_DEP_MAX_DATA - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE)
+#define NFA_P2P_MIU_8 (8*NCI_NFC_DEP_MAX_DATA - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE)
+
+#define NFA_P2P_LLINK_TYPE LLCP_LINK_TYPE_LOGICAL_DATA_LINK
+#define NFA_P2P_DLINK_TYPE LLCP_LINK_TYPE_DATA_LINK_CONNECTION
+typedef UINT8 tNFA_P2P_LINK_TYPE;
+
+/* Data for NFA_P2P_REG_SERVER_EVT */
+typedef struct
+{
+ tNFA_HANDLE server_handle; /* NFA_HANDLE_INVALID if failed */
+ char service_name[LLCP_MAX_SN_LEN + 1];
+ UINT8 server_sap;
+} tNFA_P2P_REG_SERVER;
+
+/* Data for NFA_P2P_REG_CLIENT_EVT */
+typedef struct
+{
+ tNFA_HANDLE client_handle; /* NFA_HANDLE_INVALID if failed */
+} tNFA_P2P_REG_CLIENT;
+
+/* Data for NFA_P2P_ACTIVATED_EVT */
+typedef struct
+{
+ tNFA_HANDLE handle;
+ UINT16 local_link_miu;
+ UINT16 remote_link_miu;
+} tNFA_P2P_ACTIVATED;
+
+/* Data for NFA_P2P_DEACTIVATED_EVT */
+typedef struct
+{
+ tNFA_HANDLE handle;
+} tNFA_P2P_DEACTIVATED;
+
+/* Data for NFA_P2P_CONN_REQ_EVT */
+typedef struct
+{
+ tNFA_HANDLE server_handle;
+ tNFA_HANDLE conn_handle;
+ UINT8 remote_sap;
+ UINT16 remote_miu;
+ UINT8 remote_rw;
+} tNFA_P2P_CONN_REQ;
+
+/* Data for NFA_P2P_CONNECTED_EVT */
+typedef struct
+{
+ tNFA_HANDLE client_handle;
+ tNFA_HANDLE conn_handle;
+ UINT8 remote_sap;
+ UINT16 remote_miu;
+ UINT8 remote_rw;
+} tNFA_P2P_CONN;
+
+/* Data for NFA_P2P_DISC_EVT */
+typedef struct
+{
+ tNFA_HANDLE handle;
+ UINT8 reason;
+} tNFA_P2P_DISC;
+
+/* Data for NFA_P2P_DATA_EVT */
+typedef struct
+{
+ tNFA_HANDLE handle;
+ UINT8 remote_sap;
+ tNFA_P2P_LINK_TYPE link_type;
+} tNFA_P2P_DATA;
+
+/* Data for NFA_P2P_CONGEST_EVT */
+typedef struct
+{
+ tNFA_HANDLE handle;
+ BOOLEAN is_congested;
+ tNFA_P2P_LINK_TYPE link_type;
+} tNFA_P2P_CONGEST;
+
+/* Data for NFA_P2P_LINK_INFO_EVT */
+typedef struct
+{
+ tNFA_HANDLE handle;
+ UINT16 wks; /* well-known service */
+ UINT16 local_link_miu;
+ UINT16 remote_link_miu;
+} tNFA_P2P_LINK_INFO;
+
+/* Data for NFA_P2P_SDP_EVT */
+typedef struct
+{
+ tNFA_HANDLE handle;
+ UINT8 remote_sap; /* 0x00 if failed */
+} tNFA_P2P_SDP;
+
+/* Union of all P2P callback structures */
+typedef union
+{
+ tNFA_P2P_REG_SERVER reg_server; /* NFA_P2P_REG_SERVER_EVT */
+ tNFA_P2P_REG_CLIENT reg_client; /* NFA_P2P_REG_CLIENT_EVT */
+ tNFA_P2P_ACTIVATED activated; /* NFA_P2P_ACTIVATED_EVT */
+ tNFA_P2P_DEACTIVATED deactivated; /* NFA_P2P_DEACTIVATED_EVT */
+ tNFA_P2P_CONN_REQ conn_req; /* NFA_P2P_CONN_REQ_EVT */
+ tNFA_P2P_CONN connected; /* NFA_P2P_CONNECTED_EVT */
+ tNFA_P2P_DISC disc; /* NFA_P2P_DISC_EVT */
+ tNFA_P2P_DATA data; /* NFA_P2P_DATA_EVT */
+ tNFA_P2P_CONGEST congest; /* NFA_P2P_CONGEST_EVT */
+ tNFA_P2P_LINK_INFO link_info; /* NFA_P2P_LINK_INFO_EVT */
+ tNFA_P2P_SDP sdp; /* NFA_P2P_SDP_EVT */
+} tNFA_P2P_EVT_DATA;
+
+/* NFA P2P callback */
+typedef void (tNFA_P2P_CBACK)(tNFA_P2P_EVT event, tNFA_P2P_EVT_DATA *p_data);
+
+/*****************************************************************************
+** External Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*******************************************************************************
+**
+** Function NFA_P2pRegisterServer
+**
+** Description This function is called to listen to a SAP as server on LLCP.
+**
+** NFA_P2P_REG_SERVER_EVT will be returned with status and handle.
+**
+** If server_sap is set to NFA_P2P_ANY_SAP, then NFA will allocate
+** a SAP between LLCP_LOWER_BOUND_SDP_SAP and LLCP_UPPER_BOUND_SDP_SAP
+** Otherwise, server_sap must be between (LLCP_SDP_SAP + 1) and
+** LLCP_UPPER_BOUND_SDP_SAP
+**
+** link_type : NFA_P2P_LLINK_TYPE and/or NFA_P2P_DLINK_TYPE
+**
+** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pRegisterServer (UINT8 server_sap,
+ tNFA_P2P_LINK_TYPE link_type,
+ char *p_service_name,
+ tNFA_P2P_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function NFA_P2pRegisterClient
+**
+** Description This function is called to register a client service on LLCP.
+**
+** NFA_P2P_REG_CLIENT_EVT will be returned with status and handle.
+**
+** link_type : NFA_P2P_LLINK_TYPE and/or NFA_P2P_DLINK_TYPE
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pRegisterClient (tNFA_P2P_LINK_TYPE link_type,
+ tNFA_P2P_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function NFA_P2pDeregister
+**
+** Description This function is called to stop listening to a SAP as server
+** or stop client service on LLCP.
+**
+** Note: If this function is called to de-register a server and RF discovery
+** is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pDeregister (tNFA_HANDLE handle);
+
+/*******************************************************************************
+**
+** Function NFA_P2pAcceptConn
+**
+** Description This function is called to accept a request of data link
+** connection to a listening SAP on LLCP after receiving
+** NFA_P2P_CONN_REQ_EVT.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pAcceptConn (tNFA_HANDLE conn_handle,
+ UINT16 miu,
+ UINT8 rw);
+
+/*******************************************************************************
+**
+** Function NFA_P2pRejectConn
+**
+** Description This function is called to reject a request of data link
+** connection to a listening SAP on LLCP after receiving
+** NFA_P2P_CONN_REQ_EVT.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pRejectConn (tNFA_HANDLE conn_handle);
+
+/*******************************************************************************
+**
+** Function NFA_P2pDisconnect
+**
+** Description This function is called to disconnect an existing or
+** connecting data link connection.
+**
+** discard any pending data on data link connection if flush is set to TRUE
+**
+** NFA_P2P_DISC_EVT will be returned after data link connection is disconnected
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pDisconnect (tNFA_HANDLE conn_handle,
+ BOOLEAN flush);
+
+/*******************************************************************************
+**
+** Function NFA_P2pConnectByName
+**
+** Description This function is called to create a connection-oriented transport
+** by a service name.
+** NFA_P2P_CONNECTED_EVT if success
+** NFA_P2P_DISC_EVT if failed
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if client is not registered
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pConnectByName (tNFA_HANDLE client_handle,
+ char *p_service_name,
+ UINT16 miu,
+ UINT8 rw);
+
+/*******************************************************************************
+**
+** Function NFA_P2pConnectBySap
+**
+** Description This function is called to create a connection-oriented transport
+** by a SAP.
+** NFA_P2P_CONNECTED_EVT if success
+** NFA_P2P_DISC_EVT if failed
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if client is not registered
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pConnectBySap (tNFA_HANDLE client_handle,
+ UINT8 dsap,
+ UINT16 miu,
+ UINT8 rw);
+
+/*******************************************************************************
+**
+** Function NFA_P2pSendUI
+**
+** Description This function is called to send data on connectionless
+** transport.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+** NFA_STATUS_BAD_LENGTH if data length is more than remote link MIU
+** NFA_STATUS_CONGESTED if congested
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pSendUI (tNFA_HANDLE handle,
+ UINT8 dsap,
+ UINT16 length,
+ UINT8 *p_data);
+
+/*******************************************************************************
+**
+** Function NFA_P2pReadUI
+**
+** Description This function is called to read data on connectionless
+** transport when receiving NFA_P2P_DATA_EVT with NFA_P2P_LLINK_TYPE.
+**
+** - Remote SAP who sent UI PDU is returned.
+** - Information of UI PDU up to max_data_len is copied into p_data.
+** - If more information of UI PDU or more UI PDU in queue then more
+** is returned to TRUE.
+** - Information of next UI PDU is not concatenated.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pReadUI (tNFA_HANDLE handle,
+ UINT32 max_data_len,
+ UINT8 *p_remote_sap,
+ UINT32 *p_data_len,
+ UINT8 *p_data,
+ BOOLEAN *p_more);
+
+/*******************************************************************************
+**
+** Function NFA_P2pFlushUI
+**
+** Description This function is called to flush data on connectionless
+** transport.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pFlushUI (tNFA_HANDLE handle,
+ UINT32 *p_length);
+
+/*******************************************************************************
+**
+** Function NFA_P2pSendData
+**
+** Description This function is called to send data on connection-oriented
+** transport.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+** NFA_STATUS_BAD_LENGTH if data length is more than remote MIU
+** NFA_STATUS_CONGESTED if congested
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pSendData (tNFA_HANDLE conn_handle,
+ UINT16 length,
+ UINT8 *p_data);
+
+/*******************************************************************************
+**
+** Function NFA_P2pReadData
+**
+** Description This function is called to read data on connection-oriented
+** transport when receiving NFA_P2P_DATA_EVT with NFA_P2P_DLINK_TYPE.
+**
+** - Information of I PDU is copied into p_data up to max_data_len.
+** - If more information of I PDU or more I PDU in queue, then more
+** is returned to TRUE.
+** - Information of next I PDU is not concatenated.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pReadData (tNFA_HANDLE handle,
+ UINT32 max_data_len,
+ UINT32 *p_data_len,
+ UINT8 *p_data,
+ BOOLEAN *p_more);
+
+/*******************************************************************************
+**
+** Function NFA_P2pFlushData
+**
+** Description This function is called to flush data on connection-oriented
+** transport.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pFlushData (tNFA_HANDLE handle,
+ UINT32 *p_length);
+
+/*******************************************************************************
+**
+** Function NFA_P2pSetLocalBusy
+**
+** Description This function is called to stop or resume incoming data on
+** connection-oriented transport.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pSetLocalBusy (tNFA_HANDLE conn_handle,
+ BOOLEAN is_busy);
+
+/*******************************************************************************
+**
+** Function NFA_P2pGetLinkInfo
+**
+** Description This function is called to get local/remote link MIU and
+** Well-Known Service list encoded as a 16-bit field of connected LLCP.
+** NFA_P2P_LINK_INFO_EVT will be returned.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if server or client is not registered
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pGetLinkInfo (tNFA_HANDLE handle);
+
+/*******************************************************************************
+**
+** Function NFA_P2pGetRemoteSap
+**
+** Description This function is called to get SAP associated by service name
+** on connected remote LLCP.
+** NFA_P2P_SDP_EVT will be returned.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if server or client is not registered
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pGetRemoteSap (tNFA_HANDLE handle,
+ char *p_service_name);
+
+/*******************************************************************************
+**
+** Function NFA_P2pSetLLCPConfig
+**
+** Description This function is called to change LLCP config parameters.
+** Application must call while LLCP is not activated.
+**
+** Parameters descriptions (default value)
+** - Local Link MIU (LLCP_MIU)
+** - Option parameter (LLCP_OPT_VALUE)
+** - Response Waiting Time Index (LLCP_WAITING_TIME)
+** - Local Link Timeout (LLCP_LTO_VALUE)
+** - Inactivity Timeout as initiator role (LLCP_INIT_INACTIVITY_TIMEOUT)
+** - Inactivity Timeout as target role (LLCP_TARGET_INACTIVITY_TIMEOUT)
+** - Delay SYMM response (LLCP_DELAY_RESP_TIME)
+** - Data link connection timeout (LLCP_DATA_LINK_CONNECTION_TOUT)
+** - Delay timeout to send first PDU as initiator (LLCP_DELAY_TIME_TO_SEND_FIRST_PDU)
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pSetLLCPConfig (UINT16 link_miu,
+ UINT8 opt,
+ UINT8 wt,
+ UINT16 link_timeout,
+ UINT16 inact_timeout_init,
+ UINT16 inact_timeout_target,
+ UINT16 symm_delay,
+ UINT16 data_link_timeout,
+ UINT16 delay_first_pdu_timeout);
+
+/*******************************************************************************
+**
+** Function NFA_P2pGetLLCPConfig
+**
+** Description This function is called to read LLCP config parameters.
+**
+** Parameters descriptions
+** - Local Link MIU
+** - Option parameter
+** - Response Waiting Time Index
+** - Local Link Timeout
+** - Inactivity Timeout as initiator role
+** - Inactivity Timeout as target role
+** - Delay SYMM response
+** - Data link connection timeout
+** - Delay timeout to send first PDU as initiator
+**
+** Returns None
+**
+*******************************************************************************/
+NFC_API extern void NFA_P2pGetLLCPConfig (UINT16 *p_link_miu,
+ UINT8 *p_opt,
+ UINT8 *p_wt,
+ UINT16 *p_link_timeout,
+ UINT16 *p_inact_timeout_init,
+ UINT16 *p_inact_timeout_target,
+ UINT16 *p_symm_delay,
+ UINT16 *p_data_link_timeout,
+ UINT16 *p_delay_first_pdu_timeout);
+
+/*******************************************************************************
+**
+** Function NFA_P2pSetTraceLevel
+**
+** Description This function sets the trace level for P2P. If called with
+** a value of 0xFF, it simply returns the current trace level.
+**
+** Returns The new or current trace level
+**
+*******************************************************************************/
+NFC_API extern UINT8 NFA_P2pSetTraceLevel (UINT8 new_level);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFA_P2P_API_H */
diff --git a/src/nfa/include/nfa_rw_api.h b/src/nfa/include/nfa_rw_api.h
new file mode 100644
index 0000000..8c628b0
--- /dev/null
+++ b/src/nfa/include/nfa_rw_api.h
@@ -0,0 +1,802 @@
+/******************************************************************************
+ *
+ * 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 */
+};
+typedef UINT8 tNFA_RW_PRES_CHK_OPTION;
+
+/*****************************************************************************
+** NFA T3T Constants and definitions
+*****************************************************************************/
+
+/* Block descriptor. (For non-NDEF read/write */
+typedef struct
+{
+ UINT16 service_code; /* Service code for the block */
+ UINT16 block_number; /* Block number. */
+} tNFA_T3T_BLOCK_DESC;
+
+
+
+/*****************************************************************************
+** External Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*******************************************************************************
+**
+** Function NFA_RwDetectNDef
+**
+** Description Perform the NDEF detection procedure using the appropriate
+** method for the currently activated tag.
+**
+** Upon successful completion of NDEF detection, a
+** NFA_NDEF_DETECT_EVT will be sent, to notify the application
+** of the NDEF attributes (NDEF total memory size, current
+** size, etc.).
+**
+** It is not mandatory to call this function - NFA_RwReadNDef
+** and NFA_RwWriteNDef will perform NDEF detection internally if
+** not performed already. This API may be called to get a
+** tag's NDEF size before issuing a write-request.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFC_STATUS_REFUSED if tag does not support NDEF
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwDetectNDef (void);
+
+/*******************************************************************************
+**
+** Function NFA_RwReadNDef
+**
+** Description Read NDEF message from tag. This function will internally
+** perform the NDEF detection procedure (if not performed
+** previously), and read the NDEF tag data using the
+** appropriate method for the currently activated tag.
+**
+** Upon successful completion of NDEF detection (if performed),
+** a NFA_NDEF_DETECT_EVT will be sent, to notify the application
+** of the NDEF attributes (NDEF total memory size, current size,
+** etc.).
+**
+** Upon receiving the NDEF message, the message will be sent to
+** the handler registered with NFA_RegisterNDefTypeHandler or
+** NFA_RequestExclusiveRfControl (if exclusive RF mode is active)
+**
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFC_STATUS_REFUSED if tag does not support NDEF
+** NFC_STATUS_NOT_INITIALIZED if NULL NDEF was detected on the tag
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwReadNDef (void);
+
+/*******************************************************************************
+**
+** Function NFA_RwWriteNDef
+**
+** Description Write NDEF data to the activated tag. This function will
+** internally perform NDEF detection if necessary, and write
+** the NDEF tag data using the appropriate method for the
+** currently activated tag.
+**
+** When the entire message has been written, or if an error
+** occurs, the app will be notified with NFA_RW_WRITE_CPLT_EVT.
+**
+** p_data needs to be persistent until NFA_RW_WRITE_CPLT_EVT
+**
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFC_STATUS_REFUSED if tag does not support NDEF/locked
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwWriteNDef (UINT8 *p_data, UINT32 len);
+
+
+/*****************************************************************************
+**
+** Function NFA_RwPresenceCheck
+**
+** Description Check if the tag is still in the field.
+**
+** The NFA_RW_PRESENCE_CHECK_EVT w/ status is used to
+** indicate presence or non-presence.
+**
+** option is used only with ISO-DEP protocol
+**
+** Returns
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*****************************************************************************/
+NFC_API 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
+**
+*****************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwFormatTag (void);
+
+/*******************************************************************************
+** LEGACY / PROPRIETARY TAG READ AND WRITE APIs
+*******************************************************************************/
+
+
+/*******************************************************************************
+**
+** Function NFA_RwLocateTlv
+**
+** Description:
+** Search for the Lock/Memory contril TLV on the activated Type1/Type2 tag
+**
+** Data is returned to the application using the NFA_TLV_DETECT_EVT. When
+** search operation has completed, or if an error occurs, the app will be
+** notified with NFA_TLV_DETECT_EVT.
+**
+** Description Perform the TLV detection procedure using the appropriate
+** method for the currently activated tag.
+**
+** Upon successful completion of TLV detection in T1/T2 tag, a
+** NFA_TLV_DETECT_EVT will be sent, to notify the application
+** of the TLV attributes (total lock/reserved bytes etc.).
+** However if the TLV type specified is NDEF then it is same as
+** calling NFA_RwDetectNDef and should expect to receive
+** NFA_NDEF_DETECT_EVT instead of NFA_TLV_DETECT_EVT
+**
+** It is not mandatory to call this function - NFA_RwDetectNDef,
+** NFA_RwReadNDef and NFA_RwWriteNDef will perform TLV detection
+** internally if not performed already. An application may call
+** this API to check the a tag/card-emulator's total Reserved/
+** Lock bytes before issuing a write-request.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFC_STATUS_REFUSED if tlv_type is NDEF & tag won't support NDEF
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwLocateTlv (UINT8 tlv_type);
+
+/*******************************************************************************
+**
+** Function NFA_RwSetTagReadOnly
+**
+** Description:
+** Sets tag as read only.
+**
+** When tag is set as read only, or if an error occurs, the app will be
+** notified with NFA_SET_TAG_RO_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_REJECTED if protocol is not T1/T2/ISO15693
+** (or) if hard lock is not requested for protocol ISO15693
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwSetTagReadOnly (BOOLEAN b_hard_lock);
+
+/*******************************************************************************
+**
+** Function NFA_RwT1tRid
+**
+** Description:
+** Send a RID command to the activated Type 1 tag.
+**
+** Data is returned to the application using the NFA_DATA_EVT. When the read
+** operation has completed, or if an error occurs, the app will be notified with
+** NFA_READ_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_NOT_INITIALIZED: type 1 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwT1tRid (void);
+
+/*******************************************************************************
+**
+** Function NFA_RwT1tReadAll
+**
+** Description:
+** Send a RALL command to the activated Type 1 tag.
+**
+** Data is returned to the application using the NFA_DATA_EVT. When the read
+** operation has completed, or if an error occurs, the app will be notified with
+** NFA_READ_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_NOT_INITIALIZED: type 1 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwT1tReadAll (void);
+
+/*******************************************************************************
+**
+** Function NFA_RwT1tRead
+**
+** Description:
+** Send a READ command to the activated Type 1 tag.
+**
+** Data is returned to the application using the NFA_DATA_EVT. When the read
+** operation has completed, or if an error occurs, the app will be notified with
+** NFA_READ_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_NOT_INITIALIZED: type 1 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwT1tRead (UINT8 block_number, UINT8 index);
+
+/*******************************************************************************
+**
+** Function NFA_RwT1tWrite
+**
+** Description:
+** Send a WRITE command to the activated Type 1 tag.
+**
+** Data is returned to the application using the NFA_DATA_EVT. When the write
+** operation has completed, or if an error occurs, the app will be notified with
+** NFA_WRITE_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_NOT_INITIALIZED: type 1 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwT1tWrite (UINT8 block_number,
+ UINT8 index,
+ UINT8 data,
+ BOOLEAN b_erase);
+
+/*******************************************************************************
+**
+** Function NFA_RwT1tReadSeg
+**
+** Description:
+** Send a RSEG command to the activated Type 1 tag.
+**
+** Data is returned to the application using the NFA_DATA_EVT. When the read
+** operation has completed, or if an error occurs, the app will be notified with
+** NFA_READ_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_NOT_INITIALIZED: type 1 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwT1tReadSeg (UINT8 segment_number);
+
+/*******************************************************************************
+**
+** Function NFA_RwT1tRead8
+**
+** Description:
+** Send a READ8 command to the activated Type 1 tag.
+**
+** Data is returned to the application using the NFA_DATA_EVT. When the read
+** operation has completed, or if an error occurs, the app will be notified with
+** NFA_READ_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_NOT_INITIALIZED: type 1 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwT1tRead8 (UINT8 block_number);
+
+/*******************************************************************************
+**
+** Function NFA_RwT1tWrite8
+**
+** Description:
+** Send a WRITE8_E / WRITE8_NE command to the activated Type 1 tag.
+**
+** Data is returned to the application using the NFA_DATA_EVT. When the read
+** operation has completed, or if an error occurs, the app will be notified with
+** NFA_READ_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_NOT_INITIALIZED: type 1 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwT1tWrite8 (UINT8 block_number,
+ UINT8 *p_data,
+ BOOLEAN b_erase);
+
+/*******************************************************************************
+**
+** Function NFA_RwT2tRead
+**
+** Description:
+** Send a READ command to the activated Type 2 tag.
+**
+** Data is returned to the application using the NFA_DATA_EVT. When the read
+** operation has completed, or if an error occurs, the app will be notified with
+** NFA_READ_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_NOT_INITIALIZED: type 2 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwT2tRead (UINT8 block_number);
+
+/*******************************************************************************
+**
+** Function NFA_RwT2tWrite
+**
+** Description:
+** Send an WRITE command to the activated Type 2 tag.
+**
+** When the write operation has completed (or if an error occurs), the
+** app will be notified with NFA_WRITE_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_NOT_INITIALIZED: type 2 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwT2tWrite (UINT8 block_number, UINT8 *p_data);
+
+/*******************************************************************************
+**
+** Function NFA_RwT2tSectorSelect
+**
+** Description:
+** Send SECTOR SELECT command to the activated Type 2 tag.
+**
+** When the sector select operation has completed (or if an error occurs), the
+** app will be notified with NFA_SECTOR_SELECT_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_NOT_INITIALIZED: type 2 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwT2tSectorSelect (UINT8 sector_number);
+
+/*******************************************************************************
+**
+** Function NFA_RwT3tRead
+**
+** Description:
+** Send a CHECK (read) command to the activated Type 3 tag.
+**
+** Data is returned to the application using the NFA_RW_DATA_EVT. When the read
+** operation has completed, or if an error occurs, the app will be notified with
+** NFA_READ_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_NOT_INITIALIZED: type 3 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwT3tRead (UINT8 num_blocks,
+ tNFA_T3T_BLOCK_DESC *t3t_blocks);
+
+/*******************************************************************************
+**
+** Function NFA_RwT3tWrite
+**
+** Description:
+** Send an UPDATE (write) command to the activated Type 3 tag.
+**
+** When the write operation has completed (or if an error occurs), the
+** app will be notified with NFA_WRITE_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_NOT_INITIALIZED: type 3 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwT3tWrite (UINT8 num_blocks,
+ tNFA_T3T_BLOCK_DESC *t3t_blocks,
+ UINT8 *p_data);
+
+/*******************************************************************************
+**
+** Function NFA_RwI93Inventory
+**
+** Description:
+** Send Inventory command to the activated ISO 15693 tag 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
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93Inventory (BOOLEAN afi_present, UINT8 afi, UINT8 *p_uid);
+
+/*******************************************************************************
+**
+** Function NFA_RwI93StayQuiet
+**
+** Description:
+** Send Stay Quiet command to the activated ISO 15693 tag.
+**
+** When the operation has completed (or if an error occurs), the
+** app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93StayQuiet (void);
+
+/*******************************************************************************
+**
+** Function NFA_RwI93ReadSingleBlock
+**
+** Description:
+** Send Read Single Block command to the activated ISO 15693 tag.
+**
+** Data is returned to the application using the NFA_DATA_EVT. When the read
+** operation has completed, or if an error occurs, the app will be notified with
+** NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93ReadSingleBlock (UINT8 block_number);
+
+/*******************************************************************************
+**
+** Function NFA_RwI93WriteSingleBlock
+**
+** Description:
+** Send Write Single Block command to the activated ISO 15693 tag.
+**
+** When the write operation has completed (or if an error occurs), the
+** app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93WriteSingleBlock (UINT8 block_number,
+ UINT8 *p_data);
+
+/*******************************************************************************
+**
+** Function NFA_RwI93LockBlock
+**
+** Description:
+** Send Lock block command to the activated ISO 15693 tag.
+**
+** When the operation has completed (or if an error occurs), the
+** app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93LockBlock (UINT8 block_number);
+
+/*******************************************************************************
+**
+** Function NFA_RwI93ReadMultipleBlocks
+**
+** Description:
+** Send Read Multiple Block command to the activated ISO 15693 tag.
+**
+** Data is returned to the application using the NFA_DATA_EVT. When the read
+** operation has completed, or if an error occurs, the app will be notified with
+** NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93ReadMultipleBlocks (UINT8 first_block_number,
+ UINT16 number_blocks);
+
+/*******************************************************************************
+**
+** Function NFA_RwI93WriteMultipleBlocks
+**
+** Description:
+** Send Write Multiple Block command to the activated ISO 15693 tag.
+**
+** When the write operation has completed (or if an error occurs), the
+** app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93WriteMultipleBlocks (UINT8 first_block_number,
+ UINT16 number_blocks,
+ UINT8 *p_data);
+
+/*******************************************************************************
+**
+** Function NFA_RwI93Select
+**
+** Description:
+** Send Select command to the activated ISO 15693 tag.
+**
+** UID[0]: 0xE0, MSB
+** UID[1]: IC Mfg Code
+** ...
+** UID[7]: LSB
+**
+** When the operation has completed (or if an error occurs), the
+** app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93Select (UINT8 *p_uid);
+
+/*******************************************************************************
+**
+** Function NFA_RwI93ResetToReady
+**
+** Description:
+** Send Reset to ready command to the activated ISO 15693 tag.
+**
+** When the operation has completed (or if an error occurs), the
+** app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93ResetToReady (void);
+
+/*******************************************************************************
+**
+** Function NFA_RwI93WriteAFI
+**
+** Description:
+** Send Write AFI command to the activated ISO 15693 tag.
+**
+** When the operation has completed (or if an error occurs), the
+** app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93WriteAFI (UINT8 afi);
+
+/*******************************************************************************
+**
+** Function NFA_RwI93LockAFI
+**
+** Description:
+** Send Lock AFI command to the activated ISO 15693 tag.
+**
+** When the operation has completed (or if an error occurs), the
+** app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93LockAFI (void);
+
+/*******************************************************************************
+**
+** Function NFA_RwI93WriteDSFID
+**
+** Description:
+** Send Write DSFID command to the activated ISO 15693 tag.
+**
+** When the operation has completed (or if an error occurs), the
+** app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93WriteDSFID (UINT8 dsfid);
+
+/*******************************************************************************
+**
+** Function NFA_RwI93LockDSFID
+**
+** Description:
+** Send Lock DSFID command to the activated ISO 15693 tag.
+**
+** When the operation has completed (or if an error occurs), the
+** app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93LockDSFID (void);
+
+/*******************************************************************************
+**
+** Function NFA_RwI93GetSysInfo
+**
+** Description:
+** Send Get system information command to the activated ISO 15693 tag.
+** If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
+**
+** When the operation has completed (or if an error occurs), the
+** app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93GetSysInfo (UINT8 *p_uid);
+
+/*******************************************************************************
+**
+** Function NFA_RwI93GetMultiBlockSecurityStatus
+**
+** Description:
+** Send Get Multiple block security status command to the activated ISO 15693 tag.
+**
+** Data is returned to the application using the NFA_DATA_EVT. When the read
+** operation has completed, or if an error occurs, the app will be notified with
+** NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93GetMultiBlockSecurityStatus (UINT8 first_block_number,
+ UINT16 number_blocks);
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+/*******************************************************************************
+**
+** Function NFA_SetReconnectState
+**
+** Description:
+** This function enable/disable p2p prio logic if re-connect is in progress
+**
+** Returns:
+** void
+*******************************************************************************/
+NFC_API extern void NFA_SetReconnectState (BOOLEAN flag);
+
+/*******************************************************************************
+**
+** Function NFA_SetEmvCoState
+**
+** Description:
+** This function enable/disable p2p prio logic if emvco polling is enabled.
+**
+** Returns:
+** void
+*******************************************************************************/
+NFC_API extern void NFA_SetEmvCoState (BOOLEAN 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..af6ae60
--- /dev/null
+++ b/src/nfa/include/nfa_snep_api.h
@@ -0,0 +1,463 @@
+/******************************************************************************
+ *
+ * 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 */
+
+#define NFA_SNEP_REQ_CODE_CONTINUE 0x00 /* send remaining fragments */
+#define NFA_SNEP_REQ_CODE_GET 0x01 /* return an NDEF message */
+#define NFA_SNEP_REQ_CODE_PUT 0x02 /* accept an NDEF message */
+#define NFA_SNEP_REQ_CODE_REJECT 0x7F /* do not send remaining fragments */
+
+#define tNFA_SNEP_REQ_CODE UINT8
+
+#define NFA_SNEP_RESP_CODE_CONTINUE 0x80 /* continue send remaining fragments */
+#define NFA_SNEP_RESP_CODE_SUCCESS 0x81 /* the operation succeeded */
+#define NFA_SNEP_RESP_CODE_NOT_FOUND 0xC0 /* resource not found */
+#define NFA_SNEP_RESP_CODE_EXCESS_DATA 0xC1 /* resource exceeds data size limit */
+#define NFA_SNEP_RESP_CODE_BAD_REQ 0xC2 /* malformed request not understood */
+#define NFA_SNEP_RESP_CODE_NOT_IMPLM 0xE0 /* unsupported functionality requested */
+#define NFA_SNEP_RESP_CODE_UNSUPP_VER 0xE1 /* unsupported protocol version */
+#define NFA_SNEP_RESP_CODE_REJECT 0xFF /* do not send remaining fragments */
+
+#define tNFA_SNEP_RESP_CODE UINT8
+
+/* NFA SNEP callback events */
+#define NFA_SNEP_REG_EVT 0x00 /* Server/client Registeration Status */
+#define NFA_SNEP_ACTIVATED_EVT 0x01 /* LLCP link has been activated, client only */
+#define NFA_SNEP_DEACTIVATED_EVT 0x02 /* LLCP link has been deactivated, client only */
+#define NFA_SNEP_CONNECTED_EVT 0x03 /* Data link has been created */
+#define NFA_SNEP_GET_REQ_EVT 0x04 /* GET request from client */
+#define NFA_SNEP_PUT_REQ_EVT 0x05 /* PUT request from client */
+#define NFA_SNEP_GET_RESP_EVT 0x06 /* GET response from server */
+#define NFA_SNEP_PUT_RESP_EVT 0x07 /* PUT response from server */
+#define NFA_SNEP_DISC_EVT 0x08 /* Failed to connect or disconnected */
+
+#define NFA_SNEP_ALLOC_BUFF_EVT 0x09 /* Request to allocate a buffer for NDEF*/
+#define NFA_SNEP_FREE_BUFF_EVT 0x0A /* Request to deallocate buffer for NDEF*/
+#define NFA_SNEP_GET_RESP_CMPL_EVT 0x0B /* GET response sent to client */
+
+#define NFA_SNEP_DEFAULT_SERVER_STARTED_EVT 0x0C /* SNEP default server is started */
+#define NFA_SNEP_DEFAULT_SERVER_STOPPED_EVT 0x0D /* SNEP default server is stopped */
+
+typedef UINT8 tNFA_SNEP_EVT;
+
+#define NFA_SNEP_ANY_SAP LLCP_INVALID_SAP
+
+/* Data for NFA_SNEP_REG_EVT */
+typedef struct
+{
+ tNFA_STATUS status;
+ tNFA_HANDLE reg_handle; /* handle for registered server/client */
+ char service_name[LLCP_MAX_SN_LEN + 1]; /* only for server */
+} tNFA_SNEP_REG;
+
+/* Data for NFA_SNEP_ACTIVATED_EVT */
+typedef struct
+{
+ tNFA_HANDLE client_handle; /* handle for registered client */
+} tNFA_SNEP_ACTIVATED;
+
+/* Data for NFA_SNEP_DEACTIVATED_EVT */
+typedef tNFA_SNEP_ACTIVATED tNFA_SNEP_DEACTIVATED;
+
+/* Data for NFA_SNEP_CONNECTED_EVT */
+/*
+** for server, new handle will be assigned for conn_handle
+** for client, handle used in NFA_SnepConnect () is returned in conn_handle
+*/
+typedef struct
+{
+ tNFA_HANDLE reg_handle; /* server/client handle */
+ tNFA_HANDLE conn_handle; /* handle for data link connection */
+} tNFA_SNEP_CONNECT;
+
+/* Data for NFA_SNEP_GET_REQ_EVT */
+typedef struct
+{
+ tNFA_HANDLE conn_handle; /* handle for data link connection */
+ UINT32 acceptable_length; /* acceptable length from client */
+ UINT32 ndef_length; /* NDEF message length */
+ UINT8 *p_ndef; /* NDEF message */
+} tNFA_SNEP_GET_REQ;
+
+/* Data for NFA_SNEP_PUT_REQ_EVT */
+typedef struct
+{
+ tNFA_HANDLE conn_handle; /* handle for data link connection */
+ UINT32 ndef_length; /* NDEF message length */
+ UINT8 *p_ndef; /* NDEF message */
+} tNFA_SNEP_PUT_REQ;
+
+/* Data for NFA_SNEP_GET_RESP_EVT */
+typedef struct
+{
+ tNFA_HANDLE conn_handle; /* handle for data link connection */
+ tNFA_SNEP_RESP_CODE resp_code; /* response code from server */
+ UINT32 ndef_length; /* NDEF message length */
+ UINT8 *p_ndef; /* NDEF message */
+} tNFA_SNEP_GET_RESP;
+
+/* Data for NFA_SNEP_PUT_RESP_EVT */
+typedef struct
+{
+ tNFA_HANDLE conn_handle; /* handle for data link connection */
+ tNFA_SNEP_RESP_CODE resp_code; /* response code from server */
+} tNFA_SNEP_PUT_RESP;
+
+/* Data for NFA_SNEP_DISC_EVT */
+typedef struct
+{
+ tNFA_HANDLE conn_handle; /* handle for data link connection */
+ /* client_handle if connection failed */
+} tNFA_SNEP_DISC;
+
+/* Data for NFA_SNEP_ALLOC_BUFF_EVT */
+typedef struct
+{
+ tNFA_HANDLE conn_handle; /* handle for data link connection */
+ tNFA_SNEP_REQ_CODE req_code; /* NFA_SNEP_REQ_CODE_GET or NFA_SNEP_REQ_CODE_PUT */
+ tNFA_SNEP_RESP_CODE resp_code; /* Response code if cannot allocate buffer */
+ UINT32 ndef_length; /* NDEF message length */
+ UINT8 *p_buff; /* buffer for NDEF message */
+} tNFA_SNEP_ALLOC;
+
+/* Data for NFA_SNEP_FREE_BUFF_EVT */
+typedef struct
+{
+ tNFA_HANDLE conn_handle; /* handle for data link connection */
+ UINT8 *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 *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
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SnepStartDefaultServer (tNFA_SNEP_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function NFA_SnepStopDefaultServer
+**
+** Description This function is called to stop SNEP default server on LLCP.
+**
+** NFA_SNEP_DEFAULT_SERVER_STOPPED_EVT without data will be returned.
+**
+** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SnepStopDefaultServer (tNFA_SNEP_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function NFA_SnepRegisterServer
+**
+** Description This function is called to listen to a SAP as SNEP server.
+**
+** If server_sap is set to NFA_SNEP_ANY_SAP, then NFA will allocate
+** a SAP between LLCP_LOWER_BOUND_SDP_SAP and LLCP_UPPER_BOUND_SDP_SAP
+**
+** NFC Forum default SNEP server ("urn:nfc:sn:snep") may be launched
+** by NFA_SnepStartDefaultServer ().
+**
+** NFA_SNEP_REG_EVT will be returned with status, handle and service name.
+**
+** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_INVALID_PARAM if p_service_name or p_cback is NULL
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SnepRegisterServer (UINT8 server_sap,
+ char *p_service_name,
+ tNFA_SNEP_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function NFA_SnepRegisterClient
+**
+** Description This function is called to register SNEP client.
+** NFA_SNEP_REG_EVT will be returned with status, handle
+** and zero-length service name.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_INVALID_PARAM if p_cback is NULL
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SnepRegisterClient (tNFA_SNEP_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function NFA_SnepDeregister
+**
+** Description This function is called to stop listening as SNEP server
+** or SNEP client. Application shall use reg_handle returned in
+** NFA_SNEP_REG_EVT.
+**
+** Note: If this function is called to de-register a SNEP server and RF
+** discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SnepDeregister (tNFA_HANDLE reg_handle);
+
+/*******************************************************************************
+**
+** Function NFA_SnepConnect
+**
+** Description This function is called by client to create data link connection
+** to SNEP server on peer device.
+**
+** Client handle and service name of server to connect shall be provided.
+** A conn_handle will be returned in NFA_SNEP_CONNECTED_EVT, if
+** successfully connected. Otherwise NFA_SNEP_DISC_EVT will be returned.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+** NFA_STATUS_INVALID_PARAM if p_service_name or p_cback is NULL
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SnepConnect (tNFA_HANDLE client_handle,
+ char *p_service_name);
+
+/*******************************************************************************
+**
+** Function NFA_SnepGet
+**
+** Description This function is called by client to send GET request.
+**
+** Application shall allocate a buffer and put NDEF message with
+** desired record type to get from server. NDEF message from server
+** will be returned in the same buffer with NFA_SNEP_GET_RESP_EVT.
+** The size of buffer will be used as "Acceptable Length".
+**
+** NFA_SNEP_GET_RESP_EVT or NFA_SNEP_DISC_EVT will be returned
+** through registered p_cback. Application may free the buffer
+** after receiving these events.
+**
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SnepGet (tNFA_HANDLE conn_handle,
+ UINT32 buff_length,
+ UINT32 ndef_length,
+ UINT8 *p_ndef_buff);
+
+/*******************************************************************************
+**
+** Function NFA_SnepPut
+**
+** Description This function is called by client to send PUT request.
+**
+** Application shall allocate a buffer and put desired NDEF message
+** to send to server.
+**
+** NFA_SNEP_PUT_RESP_EVT or NFA_SNEP_DISC_EVT will be returned
+** through p_cback. Application may free the buffer after receiving
+** these events.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+** NFA_STATUS_INVALID_PARAM if p_service_name or p_cback is NULL
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SnepPut (tNFA_HANDLE conn_handle,
+ UINT32 ndef_length,
+ UINT8 *p_ndef_buff);
+
+/*******************************************************************************
+**
+** Function NFA_SnepGetResponse
+**
+** Description This function is called by server to send response of GET request.
+**
+** When server application receives NFA_SNEP_ALLOC_BUFF_EVT,
+** it shall allocate a buffer for incoming NDEF message and
+** pass the pointer within callback context. This buffer will be
+** returned with NFA_SNEP_GET_REQ_EVT after receiving complete
+** NDEF message. If buffer is not allocated, NFA_SNEP_RESP_CODE_NOT_FOUND
+** (Note:There is no proper response code for this case)
+** or NFA_SNEP_RESP_CODE_REJECT will be sent to client.
+**
+** Server application shall provide conn_handle which is received in
+** NFA_SNEP_GET_REQ_EVT.
+**
+** Server application shall allocate a buffer and put NDEF message if
+** response code is NFA_SNEP_RESP_CODE_SUCCESS. Otherwise, ndef_length
+** shall be set to zero.
+**
+** NFA_SNEP_GET_RESP_CMPL_EVT or NFA_SNEP_DISC_EVT will be returned
+** through registered callback function. Application may free
+** the buffer after receiving these events.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SnepGetResponse (tNFA_HANDLE conn_handle,
+ tNFA_SNEP_RESP_CODE resp_code,
+ UINT32 ndef_length,
+ UINT8 *p_ndef_buff);
+
+/*******************************************************************************
+**
+** Function NFA_SnepPutResponse
+**
+** Description This function is called by server to send response of PUT request.
+**
+** When server application receives NFA_SNEP_ALLOC_BUFF_EVT,
+** it shall allocate a buffer for incoming NDEF message and
+** pass the pointer within callback context. This buffer will be
+** returned with NFA_SNEP_PUT_REQ_EVT after receiving complete
+** NDEF message. If buffer is not allocated, NFA_SNEP_RESP_CODE_REJECT
+** will be sent to client or NFA will discard request and send
+** NFA_SNEP_RESP_CODE_SUCCESS (Note:There is no proper response code for
+** this case).
+**
+** Server application shall provide conn_handle which is received in
+** NFA_SNEP_PUT_REQ_EVT.
+**
+** NFA_SNEP_DISC_EVT will be returned through registered callback
+** function when client disconnects data link connection.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SnepPutResponse (tNFA_HANDLE conn_handle,
+ tNFA_SNEP_RESP_CODE resp_code);
+
+/*******************************************************************************
+**
+** Function NFA_SnepDisconnect
+**
+** Description This function is called to disconnect data link connection.
+** discard any pending data if flush is set to TRUE
+**
+** Client application shall provide conn_handle in NFA_SNEP_GET_RESP_EVT
+** or NFA_SNEP_PUT_RESP_EVT.
+**
+** Server application shall provide conn_handle in NFA_SNEP_GET_REQ_EVT
+** or NFA_SNEP_PUT_REQ_EVT.
+**
+** NFA_SNEP_DISC_EVT will be returned
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SnepDisconnect (tNFA_HANDLE conn_handle,
+ BOOLEAN flush);
+
+/*******************************************************************************
+**
+** Function NFA_SnepSetTraceLevel
+**
+** Description This function sets the trace level for SNEP. If called with
+** a value of 0xFF, it simply returns the current trace level.
+**
+** Returns The new or current trace level
+**
+*******************************************************************************/
+NFC_API extern UINT8 NFA_SnepSetTraceLevel (UINT8 new_level);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFA_P2P_API_H */
diff --git a/src/nfa/int/nfa_ce_int.h b/src/nfa/int/nfa_ce_int.h
new file mode 100644
index 0000000..67dd784
--- /dev/null
+++ b/src/nfa/int/nfa_ce_int.h
@@ -0,0 +1,238 @@
+/******************************************************************************
+ *
+ * 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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ , NFA_CE_REG_TYPE_ESE
+#endif
+};
+typedef UINT8 tNFA_CE_REG_TYPE;
+
+/* data type for NFA_CE_API_CFG_LOCAL_TAG_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_PROTOCOL_MASK protocol_mask;
+ UINT8 *p_ndef_data;
+ UINT16 ndef_cur_size;
+ UINT16 ndef_max_size;
+ BOOLEAN read_only;
+ UINT8 uid_len;
+ UINT8 uid[NFA_MAX_UID_LEN];
+} tNFA_CE_API_CFG_LOCAL_TAG;
+
+/* data type for NFA_CE_ACTIVATE_NTF_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFC_ACTIVATE_DEVT *p_activation_params;
+} tNFA_CE_ACTIVATE_NTF;
+
+/* data type for NFA_CE_API_REG_LISTEN_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_CONN_CBACK *p_conn_cback;
+
+ tNFA_CE_REG_TYPE listen_type;
+
+ /* For registering Felica */
+ UINT16 system_code;
+ UINT8 nfcid2[NCI_RF_F_UID_LEN];
+
+ /* For registering Type-4 */
+ UINT8 aid[NFC_MAX_AID_LEN]; /* AID to listen for (For type-4 only) */
+ UINT8 aid_len; /* AID length */
+
+ /* For registering UICC */
+ tNFA_HANDLE ee_handle;
+ tNFA_TECHNOLOGY_MASK tech_mask;
+} tNFA_CE_API_REG_LISTEN;
+
+/* data type for NFA_CE_API_DEREG_LISTEN_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE handle;
+ UINT32 listen_info;
+} tNFA_CE_API_DEREG_LISTEN;
+
+/* union of all data types */
+typedef union
+{
+ /* GKI event buffer header */
+ BT_HDR hdr;
+ tNFA_CE_API_CFG_LOCAL_TAG local_tag;
+ tNFA_CE_API_REG_LISTEN reg_listen;
+ tNFA_CE_API_DEREG_LISTEN dereg_listen;
+ tNFA_CE_ACTIVATE_NTF activate_ntf;
+} tNFA_CE_MSG;
+
+/****************************************************************************
+** LISTEN_INFO definitions
+*****************************************************************************/
+#define NFA_CE_LISTEN_INFO_IDX_NDEF 0 /* Entry 0 is reserved for local NDEF tag */
+#define NFA_CE_LISTEN_INFO_IDX_INVALID (NFA_CE_LISTEN_INFO_MAX)
+
+
+/* Flags for listen request */
+#define NFA_CE_LISTEN_INFO_IN_USE 0x00000001 /* LISTEN_INFO entry is in use */
+#define NFC_CE_LISTEN_INFO_READONLY_NDEF 0x00000010 /* NDEF is read-only */
+#define NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND 0x00000040 /* App has not been notified of ACTIVATE_EVT yet for this T4T AID */
+#define NFA_CE_LISTEN_INFO_T4T_AID 0x00000080 /* This is a listen_info for T4T AID */
+#define NFA_CE_LISTEN_INFO_START_NTF_PND 0x00000100 /* App has not been notified of LISTEN_START yet */
+#define NFA_CE_LISTEN_INFO_FELICA 0x00000200 /* This is a listen_info for non-NDEF Felica */
+#define NFA_CE_LISTEN_INFO_UICC 0x00000400 /* This is a listen_info for UICC */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define NFA_CE_LISTEN_INFO_ESE 0x00008000 /* This is a listen_info for ESE */
+#endif
+
+/* Structure for listen look up table */
+typedef struct
+{
+ UINT32 flags;
+ tNFA_CONN_CBACK *p_conn_cback; /* Callback for this listen request */
+ tNFA_PROTOCOL_MASK protocol_mask; /* Mask of protocols for this listen request */
+ tNFA_HANDLE rf_disc_handle; /* RF Discover handle */
+
+ /* For host tag emulation (NFA_CeRegisterVirtualT4tSE and NFA_CeRegisterT4tAidOnDH) */
+ UINT8 t3t_nfcid2[NCI_RF_F_UID_LEN];
+ UINT16 t3t_system_code; /* Type-3 system code */
+ UINT8 t4t_aid_handle; /* Type-4 aid callback handle (from CE_T4tRegisterAID) */
+
+ /* For UICC */
+ tNFA_HANDLE ee_handle;
+ tNFA_TECHNOLOGY_MASK tech_mask; /* listening technologies */
+ tNFA_DM_DISC_TECH_PROTO_MASK tech_proto_mask; /* listening technologies and protocols */
+} tNFA_CE_LISTEN_INFO;
+
+
+/****************************************************************************/
+
+/* Internal flags for nfa_ce */
+#define NFA_CE_FLAGS_APP_INIT_DEACTIVATION 0x00000001 /* Deactivation locally initiated by application */
+#define NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP 0x00000002 /* Tag is in listen active or sleep state */
+typedef UINT32 tNFA_CE_FLAGS;
+
+/* NFA_CE control block */
+typedef struct
+{
+ UINT8 *p_scratch_buf; /* Scratch buffer for write requests */
+ UINT32 scratch_buf_size;
+
+ tNFC_ACTIVATE_DEVT activation_params; /* Activation params */
+ tNFA_CE_FLAGS flags; /* internal flags */
+ tNFA_CONN_CBACK *p_active_conn_cback; /* Callback of activated CE */
+
+ /* listen_info table (table of listen paramters and app callbacks) */
+ tNFA_CE_LISTEN_INFO listen_info[NFA_CE_LISTEN_INFO_MAX];/* listen info table */
+ UINT8 idx_cur_active; /* listen_info index for currently activated CE */
+ UINT8 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 *p_ndef_data;
+ UINT16 ndef_cur_size;
+ UINT16 ndef_max_size;
+
+ tNFA_SYS_EVT_HDLR *p_vs_evt_hdlr; /* VS event handler */
+} tNFA_CE_CB;
+extern tNFA_CE_CB nfa_ce_cb;
+
+/* type definition for action functions */
+typedef BOOLEAN (*tNFA_CE_ACTION) (tNFA_CE_MSG *p_data);
+
+/* Action function prototypes */
+BOOLEAN nfa_ce_api_cfg_local_tag (tNFA_CE_MSG *p_ce_msg);
+BOOLEAN nfa_ce_api_reg_listen (tNFA_CE_MSG *p_ce_msg);
+BOOLEAN nfa_ce_api_dereg_listen (tNFA_CE_MSG *p_ce_msg);
+BOOLEAN nfa_ce_api_cfg_isodep_tech (tNFA_CE_MSG *p_ce_msg);
+BOOLEAN nfa_ce_activate_ntf (tNFA_CE_MSG *p_ce_msg);
+BOOLEAN nfa_ce_deactivate_ntf (tNFA_CE_MSG *p_ce_msg);
+
+/* Internal function prototypes */
+void nfa_ce_t3t_generate_rand_nfcid (UINT8 nfcid2[NCI_RF_F_UID_LEN]);
+BOOLEAN nfa_ce_hdl_event (BT_HDR *p_msg);
+tNFC_STATUS nfa_ce_set_content (void);
+tNFA_STATUS nfa_ce_start_listening (void);
+void nfa_ce_remove_listen_info_entry (UINT8 listen_info_idx, BOOLEAN notify_app);
+void nfa_ce_sys_disable (void);
+void nfa_ce_free_scratch_buf (void);
+BOOLEAN nfa_ce_restart_listen_check (void);
+#endif /* NFA_DM_INT_H */
diff --git a/src/nfa/int/nfa_cho_int.h b/src/nfa/int/nfa_cho_int.h
new file mode 100644
index 0000000..eaeebf5
--- /dev/null
+++ b/src/nfa/int/nfa_cho_int.h
@@ -0,0 +1,292 @@
+/******************************************************************************
+ *
+ * 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 Connection Handover.
+ *
+ ******************************************************************************/
+#ifndef NFA_CHO_INT_H
+#define NFA_CHO_INT_H
+
+#if (defined (NFA_CHO_INCLUDED) && (NFA_CHO_INCLUDED==TRUE))
+#include "llcp_api.h"
+#include "llcp_defs.h"
+#include "nfa_cho_api.h"
+
+/*****************************************************************************
+** Constants and data types
+*****************************************************************************/
+
+/* NFA Connection Handover state */
+enum
+{
+ NFA_CHO_ST_DISABLED, /* Application has not registered */
+ NFA_CHO_ST_IDLE, /* No data link connection */
+ NFA_CHO_ST_W4_CC, /* Waiting for connection confirm */
+ NFA_CHO_ST_CONNECTED, /* Data link connected */
+
+ NFA_CHO_ST_MAX
+};
+
+typedef UINT8 tNFA_CHO_STATE;
+
+/* NFA Connection Handover substate in NFA_CHO_ST_CONNECTED */
+enum
+{
+ NFA_CHO_SUBSTATE_W4_LOCAL_HR, /* Waiting for Hs record from local */
+ NFA_CHO_SUBSTATE_W4_LOCAL_HS, /* Waiting for Hs record from local */
+ NFA_CHO_SUBSTATE_W4_REMOTE_HR, /* Waiting for Hr record from remote */
+ NFA_CHO_SUBSTATE_W4_REMOTE_HS, /* Waiting for Hs record from remote */
+
+ NFA_CHO_SUBSTATE_MAX
+};
+
+typedef UINT8 tNFA_CHO_SUBSTATE;
+
+/* Handover Message receiving status for SAR */
+#define NFA_CHO_RX_NDEF_COMPLETE 0 /* received complete NDEF message */
+#define NFA_CHO_RX_NDEF_TEMP_MEM 1 /* Cannot process due to temporary memory constraint */
+#define NFA_CHO_RX_NDEF_PERM_MEM 2 /* Cannot process due to permanent memory constraint */
+#define NFA_CHO_RX_NDEF_INCOMPLTE 3 /* Need more date */
+#define NFA_CHO_RX_NDEF_INVALID 4 /* Invalid NDEF message */
+
+typedef UINT8 tNFA_CHO_RX_NDEF_STATUS;
+
+/* Handover Message Type */
+#define NFA_CHO_MSG_UNKNOWN 0 /* Unknown Message */
+#define NFA_CHO_MSG_HR 1 /* Handover Request Message */
+#define NFA_CHO_MSG_HS 2 /* Handover Select Message */
+#define NFA_CHO_MSG_BT_OOB 3 /* Simplified BT OOB message */
+#define NFA_CHO_MSG_WIFI 4 /* Simplified WIFI message */
+
+typedef UINT8 tNFA_CHO_MSG_TYPE;
+
+/* Timeout */
+#define NFA_CHO_TIMEOUT_FOR_HS 1000 /* ms, waiting for Hs record */
+#define NFA_CHO_TIMEOUT_FOR_RETRY 1000 /* ms, retry because of temp memory constrain */
+#define NFA_CHO_TIMEOUT_SEGMENTED_HR 500 /* ms, waiting for next segmented Hr */
+
+#define NFA_CHO_EXCLUDING_PAYLOAD_ID 0xFF /* don't include payload ID string */
+
+/* NFA Connection Handover internal events */
+enum
+{
+ NFA_CHO_API_REG_EVT = NFA_SYS_EVT_START (NFA_ID_CHO), /* NFA_ChoRegister () */
+ NFA_CHO_API_DEREG_EVT, /* NFA_ChoDeregister () */
+ NFA_CHO_API_CONNECT_EVT, /* NFA_ChoConnect () */
+ NFA_CHO_API_DISCONNECT_EVT, /* NFA_ChoDisconnect () */
+ NFA_CHO_API_SEND_HR_EVT, /* NFA_ChoSendHr () */
+ NFA_CHO_API_SEND_HS_EVT, /* NFA_ChoSendHs () */
+ NFA_CHO_API_SEL_ERR_EVT, /* NFA_ChoSendSelectError () */
+
+ NFA_CHO_RX_HANDOVER_MSG_EVT, /* Received Handover Message */
+
+ NFA_CHO_LLCP_CONNECT_IND_EVT, /* LLCP_SAP_EVT_CONNECT_IND */
+ NFA_CHO_LLCP_CONNECT_RESP_EVT, /* LLCP_SAP_EVT_CONNECT_RESP */
+ NFA_CHO_LLCP_DISCONNECT_IND_EVT, /* LLCP_SAP_EVT_DISCONNECT_IND */
+ NFA_CHO_LLCP_DISCONNECT_RESP_EVT, /* LLCP_SAP_EVT_DISCONNECT_RESP */
+ NFA_CHO_LLCP_CONGEST_EVT, /* LLCP_SAP_EVT_CONGEST */
+ NFA_CHO_LLCP_LINK_STATUS_EVT, /* LLCP_SAP_EVT_LINK_STATUS */
+
+ NFA_CHO_NDEF_TYPE_HANDLER_EVT, /* Callback event from NDEF Type handler */
+ NFA_CHO_TIMEOUT_EVT, /* Timeout event */
+
+ NFA_CHO_LAST_EVT
+};
+
+typedef UINT16 tNFA_CHO_INT_EVT;
+
+/* data type for NFA_CHO_API_REG_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ BOOLEAN enable_server;
+ tNFA_CHO_CBACK *p_cback;
+} tNFA_CHO_API_REG;
+
+/* data type for NFA_CHO_API_DEREG_EVT */
+typedef BT_HDR tNFA_CHO_API_DEREG;
+
+/* data type for NFA_CHO_API_CONNECT_EVT */
+typedef BT_HDR tNFA_CHO_API_CONNECT;
+
+/* data type for NFA_CHO_API_DISCONNECT_EVT */
+typedef BT_HDR tNFA_CHO_API_DISCONNECT;
+
+/* data type for NFA_CHO_API_SEND_HR_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ UINT8 num_ac_info;
+ tNFA_CHO_AC_INFO *p_ac_info;
+ UINT8 *p_ndef;
+ UINT32 max_ndef_size;
+ UINT32 cur_ndef_size;
+} tNFA_CHO_API_SEND_HR;
+
+/* data type for NFA_CHO_API_SEND_HS_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ UINT8 num_ac_info;
+ tNFA_CHO_AC_INFO *p_ac_info;
+ UINT8 *p_ndef;
+ UINT32 max_ndef_size;
+ UINT32 cur_ndef_size;
+} tNFA_CHO_API_SEND_HS;
+
+/* data type for NFA_CHO_API_STOP_EVT */
+typedef BT_HDR tNFA_CHO_API_STOP;
+
+/* data type for NFA_CHO_API_SEL_ERR_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ UINT8 error_reason;
+ UINT32 error_data;
+} tNFA_CHO_API_SEL_ERR;
+
+/* data type for NFA_CHO_NDEF_TYPE_HANDLER_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_NDEF_EVT event;
+ tNFA_NDEF_EVT_DATA data;
+} tNFA_CHO_NDEF_TYPE_HDLR_EVT;
+
+/* union of all event data types */
+typedef union
+{
+ BT_HDR hdr; /* NFA_CHO_TIMEOUT_EVT */
+ tNFA_CHO_API_REG api_reg; /* NFA_CHO_API_REG_EVT */
+ tNFA_CHO_API_DEREG api_dereg; /* NFA_CHO_API_DEREG_EVT */
+ tNFA_CHO_API_CONNECT api_connect; /* NFA_CHO_API_CONNECT_EVT */
+ tNFA_CHO_API_DISCONNECT api_disconnect; /* NFA_CHO_API_DISCONNECT_EVT */
+ tNFA_CHO_API_SEND_HR api_send_hr; /* NFA_CHO_API_SEND_HR_EVT */
+ tNFA_CHO_API_SEND_HS api_send_hs; /* NFA_CHO_API_SEND_HS_EVT */
+ tNFA_CHO_API_SEL_ERR api_sel_err; /* NFA_CHO_API_SEL_ERR_EVT */
+ tNFA_CHO_NDEF_TYPE_HDLR_EVT ndef_type_hdlr; /* NFA_CHO_NDEF_TYPE_HANDLER_EVT */
+ tLLCP_SAP_CBACK_DATA llcp_cback_data; /* LLCP callback data */
+} tNFA_CHO_INT_EVENT_DATA;
+
+/*****************************************************************************
+** control block
+*****************************************************************************/
+
+#define NFA_CHO_FLAGS_LLCP_ACTIVATED 0x01
+#define NFA_CHO_FLAGS_CLIENT_ONLY 0x02 /* Handover server is not enabled */
+#define NFA_CHO_FLAGS_CONN_COLLISION 0x04 /* collision when creating data link */
+
+/* NFA Connection Handover control block */
+typedef struct
+{
+ tNFA_CHO_STATE state; /* main state */
+ tNFA_CHO_SUBSTATE substate; /* substate in connected state */
+ TIMER_LIST_ENT timer; /* timer for rx handover message */
+
+ UINT8 server_sap; /* SAP for local handover server */
+ UINT8 client_sap; /* SAP for connection to remote handover server */
+ UINT8 local_sap; /* SSAP for connection, either server_sap or client_sap */
+ UINT8 remote_sap; /* DSAP for connection */
+
+ UINT8 flags; /* internal flags */
+ tNFA_CHO_DISC_REASON disc_reason; /* disconnection reason */
+
+ tNFA_HANDLE hs_ndef_type_handle; /* handle for HS NDEF Type handler */
+ tNFA_HANDLE bt_ndef_type_handle; /* handle for BT OOB NDEF Type handler */
+ tNFA_HANDLE wifi_ndef_type_handle; /* handle for WiFi NDEF Type handler */
+
+ UINT16 local_link_miu; /* MIU of local LLCP */
+ UINT16 remote_miu; /* peer's MIU of data link connection */
+ BOOLEAN congested; /* TRUE if data link is congested */
+
+ UINT8 collision_local_sap; /* SSAP for collision connection */
+ UINT8 collision_remote_sap; /* DSAP for collision connection */
+ UINT16 collision_remote_miu; /* peer's MIU of collision connection */
+ BOOLEAN collision_congested; /* TRUE if collision connection is congested */
+
+ UINT16 tx_random_number; /* it has been sent in Hr for collision */
+
+ UINT8 *p_tx_ndef_msg; /* allocate buffer for tx NDEF msg */
+ UINT32 tx_ndef_cur_size; /* current size of NDEF message */
+ UINT32 tx_ndef_sent_size; /* transmitted size of NDEF message */
+
+ UINT8 *p_rx_ndef_msg; /* allocate buffer for rx NDEF msg */
+ UINT32 rx_ndef_buf_size; /* allocate buffer size for rx NDEF msg */
+ UINT32 rx_ndef_cur_size; /* current rx size of NDEF message */
+
+ tNFA_CHO_CBACK *p_cback; /* callback registered by application */
+
+ UINT8 trace_level;
+
+#if (defined (NFA_CHO_TEST_INCLUDED) && (NFA_CHO_TEST_INCLUDED == TRUE))
+ UINT8 test_enabled;
+ UINT8 test_version;
+ UINT16 test_random_number;
+#endif
+} tNFA_CHO_CB;
+
+/*****************************************************************************
+** External variables
+*****************************************************************************/
+
+/* NFA Connection Handover control block */
+#if NFA_DYNAMIC_MEMORY == FALSE
+extern tNFA_CHO_CB nfa_cho_cb;
+#else
+extern tNFA_CHO_CB *nfa_cho_cb_ptr;
+#define nfa_cho_cb (*nfa_cho_cb_ptr)
+#endif
+
+/*****************************************************************************
+** External functions
+*****************************************************************************/
+/* nfa_cho_main.c */
+void nfa_cho_init (void);
+
+/* nfa_cho_sm.c */
+void nfa_cho_sm_llcp_cback (tLLCP_SAP_CBACK_DATA *p_data);
+void nfa_cho_sm_execute (tNFA_CHO_INT_EVT event, tNFA_CHO_INT_EVENT_DATA *p_evt_data);
+
+/* nfa_cho_util.c */
+void nfa_cho_proc_ndef_type_handler_evt (tNFA_CHO_INT_EVENT_DATA *p_evt_data);
+tNFA_STATUS nfa_cho_proc_api_reg (tNFA_CHO_INT_EVENT_DATA *p_evt_data);
+void nfa_cho_proc_api_dereg (void);
+tNFA_STATUS nfa_cho_create_connection (void);
+void nfa_cho_process_disconnection (tNFA_CHO_DISC_REASON disc_reason);
+void nfa_cho_notify_tx_fail_evt (tNFA_STATUS status);
+
+tNFA_STATUS nfa_cho_send_handover_msg (void);
+tNFA_CHO_RX_NDEF_STATUS nfa_cho_read_ndef_msg (UINT8 local_sap, UINT8 remote_sap);
+tNFA_CHO_RX_NDEF_STATUS nfa_cho_reassemble_ho_msg (UINT8 local_sap, UINT8 remote_sap);
+
+tNFA_STATUS nfa_cho_send_hr (tNFA_CHO_API_SEND_HR *p_api_send_hr);
+tNFA_STATUS nfa_cho_send_hs (tNFA_CHO_API_SEND_HS *p_api_select);
+tNFA_STATUS nfa_cho_send_hs_error (UINT8 error_reason, UINT32 error_data);
+
+void nfa_cho_proc_hr (UINT32 length, UINT8 *p_ndef_msg);
+void nfa_cho_proc_hs (UINT32 length, UINT8 *p_ndef_msg);
+void nfa_cho_proc_simplified_format (UINT32 length, UINT8 *p_ndef_msg);
+
+tNFA_CHO_MSG_TYPE nfa_cho_get_msg_type (UINT32 length, UINT8 *p_ndef_msg);
+tNFA_CHO_ROLE_TYPE nfa_cho_get_local_device_role (UINT32 length, UINT8 *p_ndef_msg);
+tNFA_STATUS nfa_cho_update_random_number (UINT8 *p_ndef_msg);
+#endif /* (defined (NFA_CHO_INCLUDED) && (NFA_CHO_INCLUDED==TRUE)) */
+#endif /* NFA_CHO_INT_H */
diff --git a/src/nfa/int/nfa_dm_int.h b/src/nfa/int/nfa_dm_int.h
new file mode 100644
index 0000000..0100098
--- /dev/null
+++ b/src/nfa/int/nfa_dm_int.h
@@ -0,0 +1,685 @@
+/******************************************************************************
+ *
+ * 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"
+
+
+/*****************************************************************************
+** 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,
+ 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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ NFA_DM_API_SEND_NXP_EVT,
+#endif
+ NFA_DM_MAX_EVT
+};
+
+
+/* data type for NFA_DM_API_ENABLE_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_DM_CBACK *p_dm_cback;
+ tNFA_CONN_CBACK *p_conn_cback;
+} tNFA_DM_API_ENABLE;
+
+/* data type for NFA_DM_API_DISABLE_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ BOOLEAN graceful;
+} tNFA_DM_API_DISABLE;
+
+/* data type for NFA_DM_API_SET_CONFIG_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_PMID param_id;
+ UINT8 length;
+ UINT8 *p_data;
+} tNFA_DM_API_SET_CONFIG;
+
+/* data type for NFA_DM_API_GET_CONFIG_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ UINT8 num_ids;
+ tNFA_PMID *p_pmids;
+} tNFA_DM_API_GET_CONFIG;
+
+/* data type for NFA_DM_API_REQ_EXCL_RF_CTRL_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_TECHNOLOGY_MASK poll_mask;
+ tNFA_LISTEN_CFG listen_cfg;
+ tNFA_CONN_CBACK *p_conn_cback;
+ tNFA_NDEF_CBACK *p_ndef_cback;
+} tNFA_DM_API_REQ_EXCL_RF_CTRL;
+
+/* data type for NFA_DM_API_ENABLE_POLLING_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_TECHNOLOGY_MASK poll_mask;
+} tNFA_DM_API_ENABLE_POLL;
+
+/* data type for NFA_DM_API_SET_P2P_LISTEN_TECH_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_TECHNOLOGY_MASK tech_mask;
+} tNFA_DM_API_SET_P2P_LISTEN_TECH;
+
+/* data type for NFA_DM_API_SELECT_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ UINT8 rf_disc_id;
+ tNFA_NFC_PROTOCOL protocol;
+ tNFA_INTF_TYPE rf_interface;
+} tNFA_DM_API_SELECT;
+
+/* data type for NFA_DM_API_UPDATE_RF_PARAMS_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_RF_COMM_PARAMS params;
+} tNFA_DM_API_UPDATE_RF_PARAMS;
+
+/* data type for NFA_DM_API_DEACTIVATE_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ BOOLEAN sleep_mode;
+} tNFA_DM_API_DEACTIVATE;
+
+/* data type for NFA_DM_API_SET_RF_DISC_DURATION_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ UINT16 rf_disc_dur_ms;
+} tNFA_DM_API_SET_RF_DISC_DUR;
+#define NFA_RF_DISC_DURATION_MAX 0xFFFF
+
+/* data type for NFA_DM_API_REG_NDEF_HDLR_EVT */
+#define NFA_NDEF_FLAGS_HANDLE_WHOLE_MESSAGE 0x01
+#define NFA_NDEF_FLAGS_WKT_URI 0x02
+#define NFA_NDEF_FLAGS_WHOLE_MESSAGE_NOTIFIED 0x04
+
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE ndef_type_handle;
+ UINT8 flags;
+ tNFA_NDEF_CBACK *p_ndef_cback;
+ tNFA_TNF tnf; /* Type-name field of record-type that was registered. */
+ tNFA_NDEF_URI_ID uri_id; /* URI prefix abrieviation (for NFA_RegisterNDefUriHandler) */
+ UINT8 name_len; /* Length of type name or absolute URI */
+ UINT8 name[1]; /* Type name or absolute URI of record-type that got was registered. */
+} tNFA_DM_API_REG_NDEF_HDLR;
+
+/* data type for NFA_DM_API_DEREG_NDEF_HDLR_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE ndef_type_handle;
+} tNFA_DM_API_DEREG_NDEF_HDLR;
+
+/* data type for NFA_DM_API_REG_VSC_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_VSC_CBACK *p_cback;
+ BOOLEAN is_register;
+} tNFA_DM_API_REG_VSC;
+
+/* data type for NFA_DM_API_SEND_VSC_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_VSC_CBACK *p_cback;
+ UINT8 oid;
+ UINT8 cmd_params_len;
+ UINT16 pad; /* add padding to ensure the size is big enough for offset=NCI_VSC_MSG_HDR_SIZE */
+ UINT8 *p_cmd_params;
+} tNFA_DM_API_SEND_VSC;
+
+
+/* union of all data types */
+typedef union
+{
+ /* GKI event buffer header */
+ BT_HDR hdr; /* NFA_DM_API_RAW_FRAME_EVT */
+ /* NFA_DM_API_MULTI_TECH_RSP_EVT */
+ /* NFA_DM_API_RELEASE_EXCL_RF_CTRL */
+ /* NFA_DM_API_DISABLE_POLLING_EVT */
+ /* NFA_DM_API_START_RF_DISCOVERY_EVT */
+ /* NFA_DM_API_STOP_RF_DISCOVERY_EVT */
+ tNFA_DM_API_ENABLE enable; /* NFA_DM_API_ENABLE_EVT */
+ tNFA_DM_API_DISABLE disable; /* NFA_DM_API_DISABLE_EVT */
+ tNFA_DM_API_SET_CONFIG setconfig; /* NFA_DM_API_SET_CONFIG_EVT */
+ tNFA_DM_API_GET_CONFIG getconfig; /* NFA_DM_API_GET_CONFIG_EVT */
+ tNFA_DM_API_SET_RF_DISC_DUR disc_duration; /* NFA_DM_API_SET_RF_DISC_DURATION_EVT */
+ tNFA_DM_API_REG_NDEF_HDLR reg_ndef_hdlr; /* NFA_DM_API_REG_NDEF_HDLR_EVT */
+ tNFA_DM_API_DEREG_NDEF_HDLR dereg_ndef_hdlr; /* NFA_DM_API_DEREG_NDEF_HDLR_EVT */
+ tNFA_DM_API_REQ_EXCL_RF_CTRL req_excl_rf_ctrl; /* NFA_DM_API_REQUEST_EXCL_RF_CTRL */
+ tNFA_DM_API_ENABLE_POLL enable_poll; /* NFA_DM_API_ENABLE_POLLING_EVT */
+ tNFA_DM_API_SET_P2P_LISTEN_TECH set_p2p_listen_tech;/* NFA_DM_API_SET_P2P_LISTEN_TECH_EVT */
+ tNFA_DM_API_SELECT select; /* NFA_DM_API_SELECT_EVT */
+ tNFA_DM_API_UPDATE_RF_PARAMS update_rf_params; /* NFA_DM_API_UPDATE_RF_PARAMS_EVT */
+ tNFA_DM_API_DEACTIVATE deactivate; /* NFA_DM_API_DEACTIVATE_EVT */
+ tNFA_DM_API_SEND_VSC send_vsc; /* NFA_DM_API_SEND_VSC_EVT */
+ tNFA_DM_API_REG_VSC reg_vsc; /* NFA_DM_API_REG_VSC_EVT */
+} tNFA_DM_MSG;
+
+/* DM RF discovery state */
+enum
+{
+ NFA_DM_RFST_IDLE, /* idle state */
+ NFA_DM_RFST_DISCOVERY, /* discovery state */
+ NFA_DM_RFST_W4_ALL_DISCOVERIES, /* wait for all discoveries state */
+ NFA_DM_RFST_W4_HOST_SELECT, /* wait for host selection state */
+ NFA_DM_RFST_POLL_ACTIVE, /* poll mode activated state */
+ NFA_DM_RFST_LISTEN_ACTIVE, /* listen mode activated state */
+ NFA_DM_RFST_LISTEN_SLEEP, /* listen mode sleep state */
+ NFA_DM_RFST_LP_LISTEN, /* Listening in Low Power mode */
+ NFA_DM_RFST_LP_ACTIVE /* Activated in Low Power mode */
+};
+typedef UINT8 tNFA_DM_RF_DISC_STATE;
+
+/* DM RF discovery state machine event */
+enum
+{
+ NFA_DM_RF_DISCOVER_CMD, /* start RF discovery */
+ NFA_DM_RF_DISCOVER_RSP, /* discover response from NFCC */
+ NFA_DM_RF_DISCOVER_NTF, /* RF discovery NTF from NFCC */
+ NFA_DM_RF_DISCOVER_SELECT_CMD, /* select discovered target */
+ NFA_DM_RF_DISCOVER_SELECT_RSP, /* select response from NFCC */
+ NFA_DM_RF_INTF_ACTIVATED_NTF, /* RF interface activation NTF from NFCC */
+ NFA_DM_RF_DEACTIVATE_CMD, /* deactivate RF interface */
+ NFA_DM_RF_DEACTIVATE_RSP, /* deactivate response from NFCC */
+ NFA_DM_RF_DEACTIVATE_NTF, /* deactivate RF interface NTF from NFCC */
+ NFA_DM_LP_LISTEN_CMD, /* NFCC is listening in low power mode */
+ NFA_DM_CORE_INTF_ERROR_NTF, /* RF interface error NTF from NFCC */
+ NFA_DM_DISC_SM_MAX_EVENT
+};
+typedef UINT8 tNFA_DM_RF_DISC_SM_EVENT;
+
+/* DM RF discovery state machine data */
+typedef struct
+{
+ UINT8 rf_disc_id;
+ tNFA_NFC_PROTOCOL protocol;
+ tNFA_INTF_TYPE rf_interface;
+} tNFA_DM_DISC_SELECT_PARAMS;
+
+typedef union
+{
+ tNFC_DISCOVER nfc_discover; /* discovery data from NFCC */
+ tNFC_DEACT_TYPE deactivate_type; /* deactivation type */
+ tNFA_DM_DISC_SELECT_PARAMS select; /* selected target information */
+} tNFA_DM_RF_DISC_DATA;
+
+/* Callback event from NFA DM RF Discovery to other NFA sub-modules */
+enum
+{
+ NFA_DM_RF_DISC_START_EVT, /* discovery started with protocol, technology and mode */
+ NFA_DM_RF_DISC_ACTIVATED_EVT, /* activated with configured protocol, technology and mode */
+ NFA_DM_RF_DISC_DEACTIVATED_EVT /* deactivated sleep or idle */
+};
+typedef UINT8 tNFA_DM_RF_DISC_EVT;
+
+/* Combined NFC Technology and protocol bit mask */
+#define NFA_DM_DISC_MASK_PA_T1T 0x00000001
+#define NFA_DM_DISC_MASK_PA_T2T 0x00000002
+#define NFA_DM_DISC_MASK_PA_ISO_DEP 0x00000004
+#define NFA_DM_DISC_MASK_PA_NFC_DEP 0x00000008
+#define NFA_DM_DISC_MASK_PB_ISO_DEP 0x00000010
+#define NFA_DM_DISC_MASK_PF_T3T 0x00000020
+#define NFA_DM_DISC_MASK_PF_NFC_DEP 0x00000040
+#define NFA_DM_DISC_MASK_P_ISO15693 0x00000100
+#define NFA_DM_DISC_MASK_P_B_PRIME 0x00000200
+#define NFA_DM_DISC_MASK_P_KOVIO 0x00000400
+#define NFA_DM_DISC_MASK_PAA_NFC_DEP 0x00000800
+#define NFA_DM_DISC_MASK_PFA_NFC_DEP 0x00001000
+#define NFA_DM_DISC_MASK_P_LEGACY 0x00002000 /* Legacy/proprietary/non-NFC Forum protocol (e.g Shanghai transit card) */
+#define NFA_DM_DISC_MASK_POLL 0x0000FFFF
+
+#define NFA_DM_DISC_MASK_LA_T1T 0x00010000
+#define NFA_DM_DISC_MASK_LA_T2T 0x00020000
+#define NFA_DM_DISC_MASK_LA_ISO_DEP 0x00040000
+#define NFA_DM_DISC_MASK_LA_NFC_DEP 0x00080000
+#define NFA_DM_DISC_MASK_LB_ISO_DEP 0x00100000
+#define NFA_DM_DISC_MASK_LF_T3T 0x00200000
+#define NFA_DM_DISC_MASK_LF_NFC_DEP 0x00400000
+#define NFA_DM_DISC_MASK_L_ISO15693 0x01000000
+#define NFA_DM_DISC_MASK_L_B_PRIME 0x02000000
+#define NFA_DM_DISC_MASK_LAA_NFC_DEP 0x04000000
+#define NFA_DM_DISC_MASK_LFA_NFC_DEP 0x08000000
+#define NFA_DM_DISC_MASK_L_LEGACY 0x10000000
+#define NFA_DM_DISC_MASK_LISTEN 0xFFFF0000
+
+#define NFA_DM_DISC_MASK_NFC_DEP 0x0C481848
+
+
+typedef UINT32 tNFA_DM_DISC_TECH_PROTO_MASK;
+
+
+/* DM RF discovery host ID */
+#define NFA_DM_DISC_HOST_ID_DH NFC_DH_ID
+typedef UINT8 tNFA_DM_DISC_HOST_ID;
+
+/* DM deactivation callback type */
+typedef void (tNFA_DISCOVER_CBACK) (tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER *p_data);
+
+/* DM RF discovery action flags */
+#define NFA_DM_DISC_FLAGS_ENABLED 0x0001 /* RF discovery process has been started */
+#define NFA_DM_DISC_FLAGS_STOPPING 0x0002 /* Stop RF discovery is pending */
+#define NFA_DM_DISC_FLAGS_DISABLING 0x0004 /* Disable NFA is pending */
+#define NFA_DM_DISC_FLAGS_CHECKING 0x0008 /* Sleep wakeup in progress */
+#define NFA_DM_DISC_FLAGS_NOTIFY 0x0010 /* Notify sub-module that discovery is starting */
+#define NFA_DM_DISC_FLAGS_W4_RSP 0x0020 /* command has been sent to NFCC in the state */
+#define NFA_DM_DISC_FLAGS_W4_NTF 0x0040 /* wait for NTF before changing discovery state */
+
+typedef UINT16 tNFA_DM_DISC_FLAGS;
+
+/* DM Discovery control block */
+typedef struct
+{
+ BOOLEAN in_use; /* TRUE if used */
+ tNFA_DISCOVER_CBACK *p_disc_cback; /* discovery callback */
+
+ tNFA_DM_DISC_FLAGS disc_flags; /* specific action flags */
+ tNFA_DM_DISC_HOST_ID host_id; /* DH or UICC1/UICC2 */
+ tNFA_DM_DISC_TECH_PROTO_MASK requested_disc_mask;/* technology and protocol requested */
+ tNFA_DM_DISC_TECH_PROTO_MASK selected_disc_mask; /* technology and protocol waiting for activation */
+} tNFA_DM_DISC_ENTRY;
+
+#define NFA_DM_DISC_NUM_ENTRIES 8 /* polling, raw listen, P2P listen, NDEF CE, 2xVSE, 2xUICC */
+
+#define NFA_DM_MAX_DISC_PARAMS 16 /* max discovery technology parameters */
+
+/* index of listen mode routing table for technologies */
+enum {
+ NFA_DM_DISC_LRT_NFC_A,
+ NFA_DM_DISC_LRT_NFC_B,
+ NFA_DM_DISC_LRT_NFC_F,
+ NFA_DM_DISC_LRT_NFC_BP
+};
+
+/* SLP_REQ (HLTA) command */
+#define SLP_REQ_CMD 0x5000
+#define NFA_DM_MAX_TECH_ROUTE 4 /* NFA_EE_MAX_TECH_ROUTE. only A, B, F, Bprime are supported by UICC now */
+
+/* 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 disc_duration; /* Disc duration */
+ tNFA_DM_DISC_FLAGS disc_flags; /* specific action flags */
+ tNFA_DM_RF_DISC_STATE disc_state; /* RF discovery state */
+
+ tNFC_RF_TECH_N_MODE activated_tech_mode; /* activated technology and mode */
+ UINT8 activated_rf_disc_id; /* activated RF discovery ID */
+ tNFA_INTF_TYPE activated_rf_interface; /* activated RF interface */
+ tNFA_NFC_PROTOCOL activated_protocol; /* activated protocol */
+ tNFA_HANDLE activated_handle; /* handle of activated sub-module */
+ UINT8 activated_sel_res; /* activated tag's SEL_RES response */
+
+ tNFA_DM_DISC_ENTRY entry[NFA_DM_DISC_NUM_ENTRIES];
+
+ tNFA_DM_DISC_ENTRY excl_disc_entry; /* exclusive RF discovery */
+ tNFA_LISTEN_CFG excl_listen_config; /* listen cfg for exclusive-rf mode */
+
+ UINT8 listen_RT[NFA_DM_MAX_TECH_ROUTE];/* Host ID for A, B, F, B' technology routing*/
+ tNFA_DM_DISC_TECH_PROTO_MASK dm_disc_mask; /* technology and protocol waiting for activation */
+
+ TIMER_LIST_ENT tle; /* timer for waiting deactivation NTF */
+ TIMER_LIST_ENT kovio_tle; /* timer for Kovio bar code tag presence check */
+
+ BOOLEAN deact_pending; /* TRUE if deactivate while checking presence */
+ BOOLEAN 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 */
+#define NFA_NDEF_DEFAULT_HANDLER_IDX 0 /* Default handler entry in ndef_handler table */
+
+#define NFA_PARAM_ID_INVALID 0xFF
+
+/* Maximum number of pending SetConfigs */
+#define NFA_DM_SETCONFIG_PENDING_MAX 32
+
+/* NFA_DM flags */
+#define NFA_DM_FLAGS_DM_IS_ACTIVE 0x00000001 /* DM is enabled */
+#define NFA_DM_FLAGS_EXCL_RF_ACTIVE 0x00000002 /* Exclusive RF mode is active */
+#define NFA_DM_FLAGS_POLLING_ENABLED 0x00000004 /* Polling is enabled (while not in exclusive RF mode */
+#define NFA_DM_FLAGS_SEND_POLL_STOP_EVT 0x00000008 /* send poll stop event */
+#define NFA_DM_FLAGS_AUTO_READING_NDEF 0x00000010 /* auto reading of NDEF in progress */
+#define NFA_DM_FLAGS_ENABLE_EVT_PEND 0x00000020 /* NFA_DM_ENABLE_EVT is not reported yet */
+#define NFA_DM_FLAGS_SEND_DEACTIVATED_EVT 0x00000040 /* Send NFA_DEACTIVATED_EVT when deactivated */
+#define NFA_DM_FLAGS_NFCC_IS_RESTORING 0x00000100 /* NFCC is restoring after back to full power mode */
+#define NFA_DM_FLAGS_SETTING_PWR_MODE 0x00000200 /* NFCC power mode is updating */
+#define NFA_DM_FLAGS_DM_DISABLING_NFC 0x00000400 /* NFA DM is disabling NFC */
+#define NFA_DM_FLAGS_RAW_FRAME 0x00000800 /* NFA_SendRawFrame() is called since RF activation */
+#define NFA_DM_FLAGS_LISTEN_DISABLED 0x00001000 /* NFA_DisableListening() is called and engaged */
+#define NFA_DM_FLAGS_P2P_PAUSED 0x00002000 /* NFA_PauseP2p() is called and engaged */
+#define NFA_DM_FLAGS_POWER_OFF_SLEEP 0x00008000 /* Power Off Sleep */
+/* stored parameters */
+typedef struct
+{
+ UINT8 total_duration[NCI_PARAM_LEN_TOTAL_DURATION];
+
+ UINT8 la_bit_frame_sdd[NCI_PARAM_LEN_LA_BIT_FRAME_SDD];
+ UINT8 la_bit_frame_sdd_len;
+ UINT8 la_platform_config[NCI_PARAM_LEN_LA_PLATFORM_CONFIG];
+ UINT8 la_platform_config_len;
+ UINT8 la_sel_info[NCI_PARAM_LEN_LA_SEL_INFO];
+ UINT8 la_sel_info_len;
+ UINT8 la_nfcid1[NCI_NFCID1_MAX_LEN];
+ UINT8 la_nfcid1_len;
+ UINT8 la_hist_by[NCI_MAX_HIS_BYTES_LEN];
+ UINT8 la_hist_by_len;
+
+ UINT8 lb_sensb_info[NCI_PARAM_LEN_LB_SENSB_INFO];
+ UINT8 lb_sensb_info_len;
+ UINT8 lb_nfcid0[NCI_PARAM_LEN_LB_NFCID0];
+ UINT8 lb_nfcid0_len;
+ UINT8 lb_appdata[NCI_PARAM_LEN_LB_APPDATA];
+ UINT8 lb_appdata_len;
+ UINT8 lb_adc_fo[NCI_PARAM_LEN_LB_ADC_FO];
+ UINT8 lb_adc_fo_len;
+ UINT8 lb_h_info[NCI_MAX_ATTRIB_LEN];
+ UINT8 lb_h_info_len;
+
+ UINT8 lf_protocol[NCI_PARAM_LEN_LF_PROTOCOL];
+ UINT8 lf_protocol_len;
+ UINT8 lf_t3t_flags2[NCI_PARAM_LEN_LF_T3T_FLAGS2];
+ UINT8 lf_t3t_flags2_len;
+ UINT8 lf_t3t_pmm[NCI_PARAM_LEN_LF_T3T_PMM];
+ UINT8 lf_t3t_id[NFA_CE_LISTEN_INFO_MAX][NCI_PARAM_LEN_LF_T3T_ID];
+
+ UINT8 fwi[NCI_PARAM_LEN_FWI];
+ UINT8 wt[NCI_PARAM_LEN_WT];
+ UINT8 atr_req_gen_bytes[NCI_MAX_GEN_BYTES_LEN];
+ UINT8 atr_req_gen_bytes_len;
+ UINT8 atr_res_gen_bytes[NCI_MAX_GEN_BYTES_LEN];
+ UINT8 atr_res_gen_bytes_len;
+} tNFA_DM_PARAMS;
+
+/*
+** NFA_NDEF CHO callback
+** It returns TRUE if NDEF is handled by connection handover module.
+*/
+typedef BOOLEAN (tNFA_NDEF_CHO_CBACK) (UINT32 ndef_len, UINT8 *p_ndef_data);
+
+/* DM control block */
+typedef struct
+{
+ UINT32 flags; /* NFA_DM flags (see definitions for NFA_DM_FLAGS_*) */
+ tNFA_DM_CBACK *p_dm_cback; /* NFA DM callback */
+ TIMER_LIST_ENT tle;
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ BOOLEAN 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 *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 activated_nfcid[NFC_KOVIO_MAX_LEN]; /* NFCID 0/1/2 or UID of ISO15694/Kovio */
+ UINT8 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 setcfg_pending_mask; /* Mask of to indicate whether pending SET_CONFIGs require NFA_DM_SET_CONFIG_EVT. LSB=oldest pending */
+ UINT8 setcfg_pending_num; /* Number of setconfigs pending */
+
+ /* NFCC power mode */
+ UINT8 nfcc_pwr_mode; /* NFA_DM_PWR_MODE_FULL or NFA_DM_PWR_MODE_OFF_SLEEP */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ UINT8 eDtaMode; /*For enable the DTA type modes. */
+#endif
+} tNFA_DM_CB;
+
+/* Internal function prototypes */
+void nfa_dm_ndef_register_cho (tNFA_NDEF_CHO_CBACK *p_cback);
+void nfa_dm_ndef_deregister_cho (void);
+void nfa_dm_ndef_handle_message (tNFA_STATUS status, UINT8 *p_msg_buf, UINT32 len);
+void nfa_dm_ndef_dereg_all (void);
+void nfa_dm_act_conn_cback_notify (UINT8 event, tNFA_CONN_EVT_DATA *p_data);
+void nfa_dm_notify_activation_status (tNFA_STATUS status, tNFA_TAG_PARAMS *p_params);
+void nfa_dm_disable_complete (void);
+
+/* Internal functions from nfa_rw */
+void nfa_rw_init (void);
+void nfa_rw_proc_disc_evt (tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER *p_data, BOOLEAN excl_rf_not_active);
+tNFA_STATUS nfa_rw_send_raw_frame (BT_HDR *p_data);
+
+/* Internal functions from nfa_ce */
+void nfa_ce_init (void);
+
+/* Pointer to compile-time configuration structure */
+extern tNFA_DM_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 *p_nfa_dm_ce_cfg;
+extern UINT8 *p_nfa_dm_gen_cfg;
+extern UINT8 nfa_ee_max_ee_cfg;
+extern tNCI_DISCOVER_MAPS *p_nfa_dm_interface_mapping;
+extern UINT8 nfa_dm_num_dm_interface_mapping;
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+void nfa_dm_poll_disc_cback_dta_wrapper(tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER *p_data);
+#endif
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+extern unsigned char appl_dta_mode_flag;
+#endif
+
+/* NFA device manager control block */
+#if NFA_DYNAMIC_MEMORY == FALSE
+extern tNFA_DM_CB nfa_dm_cb;
+#else
+extern tNFA_DM_CB *nfa_dm_cb_ptr;
+#define nfa_dm_cb (*nfa_dm_cb_ptr)
+#endif
+
+void nfa_dm_init (void);
+void nfa_p2p_init (void);
+#if (defined (NFA_CHO_INCLUDED) && (NFA_CHO_INCLUDED==TRUE))
+void nfa_cho_init (void);
+#else
+#define nfa_cho_init()
+#endif /* (defined (NFA_CHO_INCLUDED) && (NFA_CHO_INCLUDED==TRUE)) */
+#if (defined (NFA_SNEP_INCLUDED) && (NFA_SNEP_INCLUDED==TRUE))
+void nfa_snep_init (BOOLEAN 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 */
+BOOLEAN nfa_dm_enable (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_disable (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_set_config (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_get_config (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_request_excl_rf_ctrl (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_release_excl_rf_ctrl (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_enable_polling (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_disable_polling (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_enable_listening (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_disable_listening (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_pause_p2p (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_resume_p2p (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_send_raw_frame (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_set_p2p_listen_tech (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_start_rf_discovery (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_stop_rf_discovery (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_set_rf_disc_duration (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_select (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_update_rf_params (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_deactivate (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_power_off_sleep (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_ndef_reg_hdlr (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_ndef_dereg_hdlr (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_tout (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_reg_vsc (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_send_vsc (tNFA_DM_MSG *p_data);
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+BOOLEAN nfa_dm_act_send_nxp(tNFA_DM_MSG *p_data);
+UINT16 nfa_dm_act_get_rf_disc_duration ();
+#endif
+BOOLEAN nfa_dm_act_disable_timeout (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_nfc_cback_data (tNFA_DM_MSG *p_data);
+
+void nfa_dm_proc_nfcc_power_mode (UINT8 nfcc_power_mode);
+
+/* Main function prototypes */
+BOOLEAN nfa_dm_evt_hdlr (BT_HDR *p_msg);
+void nfa_dm_sys_enable (void);
+void nfa_dm_sys_disable (void);
+tNFA_STATUS nfa_dm_check_set_config (UINT8 tlv_list_len, UINT8 *p_tlv_list, BOOLEAN app_init);
+
+void nfa_dm_conn_cback_event_notify (UINT8 event, tNFA_CONN_EVT_DATA *p_data);
+
+/* Discovery function prototypes */
+void nfa_dm_disc_sm_execute (tNFA_DM_RF_DISC_SM_EVENT event, tNFA_DM_RF_DISC_DATA *p_data);
+tNFA_HANDLE nfa_dm_add_rf_discover (tNFA_DM_DISC_TECH_PROTO_MASK disc_mask, tNFA_DM_DISC_HOST_ID host_id, tNFA_DISCOVER_CBACK *p_disc_cback);
+void nfa_dm_delete_rf_discover (tNFA_HANDLE handle);
+void nfa_dm_start_excl_discovery (tNFA_TECHNOLOGY_MASK poll_tech_mask,
+ tNFA_LISTEN_CFG *p_listen_cfg,
+ tNFA_DISCOVER_CBACK *p_disc_cback);
+void nfa_dm_rel_excl_rf_control_and_notify (void);
+void nfa_dm_stop_excl_discovery (void);
+void nfa_dm_disc_new_state (tNFA_DM_RF_DISC_STATE new_state);
+
+void nfa_dm_start_rf_discover (void);
+void nfa_dm_rf_discover_select (UINT8 rf_disc_id, tNFA_NFC_PROTOCOL protocol, tNFA_INTF_TYPE rf_interface);
+tNFA_STATUS nfa_dm_rf_deactivate (tNFA_DEACTIVATE_TYPE deactivate_type);
+BOOLEAN nfa_dm_is_protocol_supported (tNFA_NFC_PROTOCOL protocol, UINT8 sel_res);
+BOOLEAN nfa_dm_is_active (void);
+tNFC_STATUS nfa_dm_disc_sleep_wakeup (void);
+tNFC_STATUS nfa_dm_disc_start_kovio_presence_check (void);
+BOOLEAN nfa_dm_is_raw_frame_session (void);
+BOOLEAN nfa_dm_is_p2p_paused (void);
+
+
+#if (NFC_NFCEE_INCLUDED == FALSE)
+#define nfa_ee_get_tech_route(ps, ha) memset(ha, NFC_DH_ID, NFA_DM_MAX_TECH_ROUTE);
+#endif
+
+#if (BT_TRACE_VERBOSE == TRUE)
+char *nfa_dm_nfc_revt_2_str (tNFC_RESPONSE_EVT event);
+#endif
+
+
+#endif /* NFA_DM_INT_H */
diff --git a/src/nfa/int/nfa_dta_int.h b/src/nfa/int/nfa_dta_int.h
new file mode 100644
index 0000000..da4af59
--- /dev/null
+++ b/src/nfa/int/nfa_dta_int.h
@@ -0,0 +1,458 @@
+/******************************************************************************
+ *
+ * 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
+
+#define NDEF_WKT_TEXT_HDR_LEN 7 /* Header length for long NDEF text message */
+#define NFA_DTA_T3T_WRITE_NDEF_SIZE 192 /* Size of NDEF message for T3T write-tests ([DTA] $5.5.6) */
+#define NFA_DTA_T3T_LISTEN_SYSTEMCODE 0xBABE /* System code to use for T3T Listen mode tests */
+
+#define NFA_PROTOCOL_RANK_INVALID 0xFF /* Maximum protocol preference rank */
+
+#define NFA_DTA_SCRATCH_BUF_SIZE T3T_MSG_BLOCKSIZE
+
+#ifndef NFA_DTA_DEFAULT_CO_OUT_DSAP
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define NFA_DTA_DEFAULT_CO_OUT_DSAP 0x10 /* Default SAP[LT,CO-OUT-DEST] if SDP was not performed to get SAP from the LT */
+#else
+#define NFA_DTA_DEFAULT_CO_OUT_DSAP 0x12 /* Default SAP[LT,CO-OUT-DEST] if SDP was not performed to get SAP from the LT */
+#endif
+#endif
+
+/*****************************************************************************
+* DTA state machine definitions
+*****************************************************************************/
+
+typedef struct {
+ BOOLEAN tp_continue; /* NFA_DTA_CFG_TP_CONTINUE */
+ tNFA_DTA_FL_POLL_LISTEN poll_listen; /* NFA_DTA_CFG_POLL_LISTEN */
+ BOOLEAN t4at_nfcdep_priority; /* NFA_DTA_CFG_T4AT_NFCDEP_PRIORITY */
+ BOOLEAN reactivation; /* NFA_DTA_CFG_REACTIVATION */
+ UINT16 total_duration; /* NFA_DTA_CFG_TOTAL_DURATION */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ BOOLEAN 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
+{
+ BT_HDR hdr;
+ BOOLEAN auto_start;
+ tNFA_DTA_CBACK *p_cback;
+} tNFA_DTA_API_ENABLE;
+
+/* data type for NFA_DTA_API_START_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ UINT16 pattern_number;
+ UINT8 tlv_len;
+ UINT8 *p_tlv_params;
+} tNFA_DTA_API_START;
+
+/* data type for NFA_DTA_API_CONFIG */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_DTA_CFG_ITEM item;
+ tNFA_DTA_CFG cfg_data;
+} tNFA_DTA_API_CONFIG;
+
+/* data type for NFA_DTA_DATA_CBACK_EVT */
+typedef struct
+{
+ UINT8 event;
+ tRW_DATA data;
+} tNFA_DTA_RW_DATA;
+
+typedef struct
+{
+ UINT8 event;
+ tCE_DATA data;
+} tNFA_DTA_CE_DATA;
+
+typedef struct
+{
+ tNFC_CONN_EVT event;
+ tNFC_CONN data;
+} tNFA_DTA_NFCDEP_DATA;
+
+
+enum
+{
+ NFA_DTA_LLCP_CONNECT_CO_ECHO_OUT,
+ NFA_DTA_LLCP_DISCONNECT_CO_ECHO_OUT
+};
+typedef UINT8 tNFA_DTA_LLCP_EVT;
+
+enum
+{
+ NFA_DTA_RW_DATA,
+ NFA_DTA_CE_DATA,
+ NFA_DTA_NFCDEP_DATA,
+ NFA_DTA_LLCP_DATA
+};
+
+typedef UINT8 tNFA_DTA_DATA_TYPE;
+
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_DTA_DATA_TYPE type;
+ union
+ {
+ tNFA_DTA_RW_DATA rw;
+ tNFA_DTA_CE_DATA ce;
+ tNFA_DTA_NFCDEP_DATA nfcdep;
+ tNFA_DTA_LLCP_EVT llcp_evt;
+ } data;
+} tNFA_DTA_DATA_CBACK;
+
+/* All API message type */
+typedef union
+{
+ BT_HDR hdr;
+ tNFA_DTA_API_ENABLE enable;
+ tNFA_DTA_API_CONFIG cfg;
+ tNFA_DTA_API_START start;
+ tNFA_DTA_DATA_CBACK data_cback;
+}tNFA_DTA_MSG;
+
+
+
+/* DTA states */
+enum
+{
+ NFA_DTA_ST_IDLE,
+ NFA_DTA_ST_DISCOVER, /* Polling/Listening */
+ NFA_DTA_ST_ACTIVATED /* Activated, listen mode */
+};
+typedef UINT8 tNFA_DTA_STATE;
+
+/* DTA Substates (while in ACTIVATED state) - substate enumerations are found in protocol-specific files (nfa_dta_XXX.c) */
+#define NFA_DTA_SST_IDLE 0
+typedef UINT8 tNFA_DTA_SUBSTATE;
+
+/* DTA discovery states */
+enum
+{
+ NFA_DTA_DISC_STATE_IDLE,
+ NFA_DTA_DISC_STATE_DISCOVERY,
+ NFA_DTA_DISC_STATE_POLL_ACTIVE,
+ NFA_DTA_DISC_STATE_W4_ALL_DISCOVERIES,
+ NFA_DTA_DISC_STATE_W4_HOST_SELECT,
+ NFA_DTA_DISC_STATE_LISTEN_ACTIVE,
+ NFA_DTA_DISC_STATE_LISTEN_SLEEP,
+ NFA_DTA_DISC_STATE_MAX
+};
+
+/*****************************************************************************
+* DTA control block definitions
+*****************************************************************************/
+
+/* NDEF buffer definitions */
+enum {
+ NFA_DTA_BUF_READ, /* Buffer for RW Read requests */
+ NFA_DTA_BUF_WRITE, /* Buffer for RW Write requests */
+ NFA_DTA_BUF_MAX
+};
+
+typedef struct {
+ UINT8 *p_data;
+ UINT32 max_size;
+ UINT32 cur_size;
+ UINT32 offset; /* current read/write offset */
+} tNFA_DTA_BUF_CB;
+
+
+/* T4T listen mode test application */
+enum {
+ NFA_DTA_T4T_CE_APP_NONE, /* Not selected */
+ NFA_DTA_T4T_CE_APP_LOOPBACK, /* loopback test applicaiton */
+ NFA_DTA_T4T_CE_APP_PROP /* propretary test application */
+};
+
+/* DTA test step command */
+typedef tNFC_STATUS (*tNFA_DTA_CMD_FCN) (void *);
+
+/* dta control block flags */
+#define NFA_DTA_FL_ENABLED 0x00000001 /* DTA is enabled */
+#define NFA_DTA_FL_AUTOSTART 0x00000002 /* Automatically start discovery when NFC is enabled */
+#define NFA_DTA_FL_STOPPING 0x00000004 /* DTA is stopping (NFA_DtaStop called) */
+#define NFA_DTA_FL_DISABLING 0x00000008 /* DTA is being disabled (NFA_DtaDisable called) */
+#define NFA_DTA_FL_T4T_DESELECT_DEACT 0x00000010 /* T4T/NFCDEP is deactivating to IDLE (need to DESELECT first) */
+
+/* DTA control block */
+typedef struct {
+ UINT32 dta_flags; /* dta_flags must be first item in structure (statically intialized to 0 on startup) */
+
+ /* Configuration */
+ tNFA_DTA_CONFIG cfg;
+
+ /* DTA State Machine */
+ tNFA_DTA_STATE state;
+ tNFA_DTA_SUBSTATE substate; /* Current protocol-specific sub-state */
+ tNFA_DTA_CBACK *p_cback; /* Applicatation for DTA event notification */
+
+ /* DTA test parameters */
+ UINT16 pattern_number;
+ UINT16 pattern_number_old;
+
+ /* Discovery Parameters */
+ UINT8 disc_state;
+ UINT8 disc_params_num;
+ tNFC_DISCOVER_PARAMS disc_params[NFA_DTA_DISCOVER_PARAMS_MAX];
+
+ /* Activation parameters */
+ tNFC_ACTIVATE_DEVT activate_params;
+ UINT8 cur_protocol_rank; /* perference ranking of currently discovered protocol */
+
+ tRW_CBACK *p_rw_cback;
+ tCE_CBACK *p_ce_cback;
+
+ TIMER_LIST_ENT protocol_timer; /* timer for the activated protocol if needed */
+
+ UINT8 t4t_ce_app; /* T4T listen mode test application */
+ tCE_T4T_AID_HANDLE t4t_dta_aid_hdl; /* T4T registration handle for proprietary dta aid */
+ tCE_T4T_AID_HANDLE t4t_prop_aid_hdl; /* T4T registration handle for proprietary aid */
+ UINT8 nfc_dep_wt;
+
+ BOOLEAN llcp_cl_more_to_read; /* TRUE if there is more to read in llcp cl link*/
+ BOOLEAN llcp_co_more_to_read; /* TRUE if there is more to read in llcp recieve window*/
+ BOOLEAN llcp_is_initiator; /* TURE if IUT is LLCP initiator */
+ UINT16 llcp_local_link_miu; /* link MIU of IUT */
+ UINT16 llcp_remote_link_miu; /* link MIU of LT */
+
+ UINT8 llcp_pattern_num_sap; /* SAP of pattern number exchange */
+
+ UINT8 llcp_cl_in_local_sap; /* SAP of IUT-CL-IN-DEST */
+ UINT8 llcp_cl_out_local_sap; /* SAP of IUT-CL-OUT-SRC */
+ UINT8 llcp_cl_out_remote_sap; /* SAP of LT-CL-OUT-DEST */
+
+ UINT8 llcp_co_in_local_sap; /* SAP of IUT-CO-IN-DEST */
+ UINT8 llcp_co_in_remote_sap; /* SAP of LT-CO-IN-SRC */
+ UINT8 llcp_co_out_local_sap; /* SAP of IUT-CO-OUT-SRC */
+ UINT8 llcp_co_out_remote_sap; /* SAP of LT-CO-OUT-DEST */
+
+ UINT16 llcp_co_out_remote_miu; /* MIU of LT-CO-OUT-DEST */
+ UINT8 llcp_co_out_remote_rw; /* RW of LT-CO-OUT-DEST */
+
+#define NFA_DTA_LLCP_FLAGS_CO_OUT_CONNECTING 0x01 /* establishing outbound on connection-oriented */
+#define NFA_DTA_LLCP_FLAGS_CO_OUT_CONNECTED 0x02 /* established outbound on connection-oriented */
+
+ UINT8 llcp_flags; /* internal flags for LLCP echo test */
+ UINT8 llcp_sdp_tid_cl; /* SDP transaction ID for outbound connectionless */
+ UINT8 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(NFC_NXP_NOT_OPEN_INCLUDED == 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 snep_client_test_flags;
+#endif
+ UINT8 *p_snep_short_ndef;
+ UINT32 snep_short_ndef_size;
+ UINT8 *p_snep_long_ndef;
+ UINT32 snep_long_ndef_size;
+
+ /* DTA buffer for NDEF read/write */
+ tNFA_DTA_BUF_CB buf_cb[NFA_DTA_BUF_MAX];
+ UINT32 ndef_size; /* Size of NDEF message from NDEF detection */
+
+ /* Scratch buffer for miscelaneous use */
+ UINT8 scratch_buf[NFA_DTA_SCRATCH_BUF_SIZE];
+
+ /* DTA Test command table */
+ tNFA_DTA_CMD_FCN *p_cur_cmd_tbl; /* Current table of commands for current test */
+ UINT8 cur_cmd_idx;
+} tNFA_DTA_CB;
+extern tNFA_DTA_CB nfa_dta_cb;
+
+/* NFA_SYS info for DTA */
+extern const tNFA_SYS_REG nfa_dta_sys_reg;
+
+/* DTA startup setconfig parameters */
+extern UINT8 *p_nfa_dta_start_up_cfg;
+extern UINT8 nfa_dta_start_up_cfg_len;
+
+/*****************************************************************************
+* DTA internal funciton protoytpes
+*****************************************************************************/
+/* Internal function prototypes */
+void nfa_dta_deactivate (UINT8 deactivate_type);
+void nfa_dta_shutdown (void);
+void nfa_dta_discover_start (void);
+
+/* nfa_sys handler for DTA */
+BOOLEAN nfa_dta_evt_hdlr (BT_HDR *p_msg);
+void nfa_dta_sys_disable (void);
+
+/* State machine action functions */
+BOOLEAN nfa_dta_enable (tNFA_DTA_MSG *p_data);
+BOOLEAN nfa_dta_disable (tNFA_DTA_MSG *p_data);
+BOOLEAN nfa_dta_config (tNFA_DTA_MSG *p_data);
+BOOLEAN nfa_dta_start (tNFA_DTA_MSG *p_data);
+BOOLEAN nfa_dta_handle_deact (tNFA_DTA_MSG *p_data);
+BOOLEAN nfa_dta_stop (tNFA_DTA_MSG *p_data);
+BOOLEAN nfa_dta_run_test (tNFA_DTA_MSG *p_data);
+BOOLEAN nfa_dta_proc_data (tNFA_DTA_MSG *p_msg_data);
+
+/* Utility functions */
+void nfa_dta_test_set_state (tNFA_DTA_STATE state);
+void nfa_dta_test_set_substate (tNFA_DTA_SUBSTATE substate);
+void nfa_dta_free_ndef_buf (UINT8 ndef_idx);
+UINT8 *nfa_dta_realloc_buf (UINT8 ndef_idx, UINT32 size);
+void nfa_dta_t3t_nfcid_rand (UINT8 nfcid2[NCI_RF_F_UID_LEN]);
+
+/* Test function entry points (in nfa_dta_XXX.c) */
+void nfa_dta_nfcdep_poll_test_start (void);
+void nfa_dta_nfcdep_proc_data (tNFC_CONN_EVT event, tNFC_CONN *p_data);
+void nfa_dta_t1t_poll_test_start (void);
+void nfa_dta_t2t_poll_test_start (void);
+void nfa_dta_t3t_poll_test_start (void);
+void nfa_dta_t4t_poll_test_start (void);
+
+void nfa_dta_nfcdep_listen_test_start (void);
+void nfa_dta_t3t_listen_test_start (void);
+void nfa_dta_t4t_listen_test_start (void);
+
+void nfa_dta_t1t_rw_cback (UINT8 event, tRW_DATA *p_data);
+void nfa_dta_t2t_rw_cback (UINT8 event, tRW_DATA *p_data);
+void nfa_dta_t3t_rw_cback (UINT8 event, tRW_DATA *p_data);
+void nfa_dta_t4t_rw_cback (UINT8 event, tRW_DATA *p_data);
+
+void nfa_dta_t3t_ce_cback (UINT8 event, tCE_DATA *p_data);
+void nfa_dta_t4t_ce_cback (UINT8 event, tCE_DATA *p_data);
+
+void nfa_dta_ce_cback (UINT8 event, tCE_DATA *p_ce_data);
+
+void nfa_dta_t4t_register_apps (void);
+void nfa_dta_t4t_deregister_apps (void);
+
+void nfa_dta_llcp_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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+void nfa_dta_snep_mode (tNFA_DTA_SNEP_MODE mode);
+#endif
+
+void nfa_dta_emvco_pcd_config_nfcc (BOOLEAN enable);
+void nfa_dta_emvco_pcd_start (void);
+void nfa_dta_emvco_pcd_cback (UINT8 event, tRW_DATA *p_data);
+
+extern UINT8 *p_nfa_dta_brcm_start_up_cfg;
+extern UINT8 nfa_dta_brcm_start_up_cfg_len;
+extern UINT8 *p_nfa_dta_start_up_vsc_cfg;
+
+#endif /* (NFA_DTA_INCLUDED == TRUE) */
+#endif /* NFA_DTA_INT_H */
diff --git a/src/nfa/int/nfa_ee_int.h b/src/nfa/int/nfa_ee_int.h
new file mode 100644
index 0000000..3c207f1
--- /dev/null
+++ b/src/nfa/int/nfa_ee_int.h
@@ -0,0 +1,575 @@
+/******************************************************************************
+ *
+ * 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
+#define NFA_EE_NUM_ECBS (NFA_EE_MAX_EE_SUPPORTED+1) /* the number of tNFA_EE_ECBs (for NFCEEs and DH) */
+#define NFA_EE_CB_4_DH NFA_EE_MAX_EE_SUPPORTED /* The index for DH in nfa_ee_cb.ee_cb[] */
+#define NFA_EE_INVALID 0xFF
+#define NFA_EE_MAX_TECH_ROUTE 4 /* only A, B, F, Bprime are supported by UICC now */
+
+#ifndef NFA_EE_AID_CFG_TAG_NAME
+#define NFA_EE_AID_CFG_TAG_NAME 0x4F /* AID */
+#endif
+
+/* NFA EE events */
+enum
+{
+ NFA_EE_API_DISCOVER_EVT = NFA_SYS_EVT_START(NFA_ID_EE),
+ NFA_EE_API_REGISTER_EVT,
+ NFA_EE_API_DEREGISTER_EVT,
+ NFA_EE_API_MODE_SET_EVT,
+ NFA_EE_API_SET_TECH_CFG_EVT,
+ NFA_EE_API_SET_PROTO_CFG_EVT,
+ NFA_EE_API_ADD_AID_EVT,
+ NFA_EE_API_REMOVE_AID_EVT,
+ NFA_EE_API_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,
+ 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_MAX_EVT
+
+};
+
+typedef UINT16 tNFA_EE_INT_EVT;
+#define NFA_EE_AE_ROUTE 0x80 /* for listen mode routing table*/
+#define NFA_EE_AE_VS 0x40
+
+
+/* NFA EE Management state */
+enum
+{
+ NFA_EE_EM_STATE_INIT = 0,
+ NFA_EE_EM_STATE_INIT_DONE,
+ NFA_EE_EM_STATE_RESTORING,
+ NFA_EE_EM_STATE_DISABLING,
+ NFA_EE_EM_STATE_DISABLED,
+
+ NFA_EE_EM_STATE_MAX
+};
+typedef UINT8 tNFA_EE_EM_STATE;
+
+/* NFA EE connection status */
+enum
+{
+ NFA_EE_CONN_ST_NONE, /* not connected */
+ NFA_EE_CONN_ST_WAIT, /* connection is initiated; waiting for ack */
+ NFA_EE_CONN_ST_CONN, /* connected; can send/receive data */
+ NFA_EE_CONN_ST_DISC, /* disconnecting; waiting for ack */
+ NFA_EE_CONN_ST_MAX
+};
+typedef UINT8 tNFA_EE_CONN_ST;
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+/**
+ * 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_MAX_AID_CFG_LEN (660)
+
+#else
+#define NFA_EE_MAX_AID_CFG_LEN (160)
+#endif
+#else
+#define NFA_EE_MAX_AID_CFG_LEN (510)
+#endif
+#define NFA_EE_7816_STATUS_LEN (2)
+
+/* NFA EE control block flags:
+ * use to indicate an API function has changed the configuration of the associated NFCEE
+ * The flags are cleared when the routing table/VS is updated */
+#define NFA_EE_ECB_FLAGS_TECH 0x02 /* technology routing changed */
+#define NFA_EE_ECB_FLAGS_PROTO 0x04 /* protocol routing changed */
+#define NFA_EE_ECB_FLAGS_AID 0x08 /* AID routing changed */
+#define NFA_EE_ECB_FLAGS_VS 0x10 /* VS changed */
+#define NFA_EE_ECB_FLAGS_RESTORE 0x20 /* Restore related */
+#define NFA_EE_ECB_FLAGS_ROUTING 0x0E /* routing flags changed */
+#define NFA_EE_ECB_FLAGS_DISC_REQ 0x40 /* NFCEE Discover Request NTF is set */
+#define NFA_EE_ECB_FLAGS_ORDER 0x80 /* DISC_REQ N reported before DISC N */
+typedef UINT8 tNFA_EE_ECB_FLAGS;
+
+/* part of tNFA_EE_STATUS; for internal use only */
+#define NFA_EE_STATUS_RESTORING 0x20 /* waiting for restore to full power mode to complete */
+#define NFA_EE_STATUS_INT_MASK 0x20 /* this bit is in ee_status for internal use only */
+
+/* NFA-EE information for a particular NFCEE Entity (including DH) */
+typedef struct
+{
+ tNFA_TECHNOLOGY_MASK tech_switch_on; /* default routing - technologies switch_on */
+ tNFA_TECHNOLOGY_MASK tech_switch_off; /* default routing - technologies switch_off */
+ tNFA_TECHNOLOGY_MASK tech_battery_off; /* default routing - technologies battery_off*/
+ tNFA_PROTOCOL_MASK proto_switch_on; /* default routing - protocols switch_on */
+ tNFA_PROTOCOL_MASK proto_switch_off; /* default routing - protocols switch_off */
+ tNFA_PROTOCOL_MASK proto_battery_off; /* default routing - protocols battery_off */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ tNFA_PROTOCOL_MASK proto_screen_lock; /* default routing - protocols screen_lock */
+ tNFA_PROTOCOL_MASK proto_screen_off; /* 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*/
+#endif
+ tNFA_EE_CONN_ST conn_st; /* connection status */
+ UINT8 conn_id; /* connection id */
+ tNFA_EE_CBACK *p_ee_cback; /* the callback function */
+
+ /* Each AID entry has an ssociated aid_len, aid_pwr_cfg, aid_rt_info.
+ * aid_cfg[] contains AID and maybe some other VS information in TLV format
+ * The first T is always NFA_EE_AID_CFG_TAG_NAME, the L is the actual AID length
+ * the aid_len is the total length of all the TLVs associated with this AID entry
+ */
+ UINT8 aid_len[NFA_EE_MAX_AID_ENTRIES];/* the actual lengths in aid_cfg */
+ UINT8 aid_pwr_cfg[NFA_EE_MAX_AID_ENTRIES];/* power configuration of this AID entry */
+ UINT8 aid_rt_info[NFA_EE_MAX_AID_ENTRIES];/* route/vs info for this AID entry */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ UINT8 aid_rt_loc[NFA_EE_MAX_AID_ENTRIES];/* route location info for this AID entry */
+#endif
+ UINT8 aid_cfg[NFA_EE_MAX_AID_CFG_LEN];/* routing entries based on AID */
+ UINT8 aid_entries; /* The number of AID entries in aid_cfg */
+ UINT8 nfcee_id; /* ID for this NFCEE */
+ UINT8 ee_status; /* The NFCEE status */
+ UINT8 ee_old_status; /* The NFCEE status before going to low power mode */
+ tNFA_EE_INTERFACE ee_interface[NFC_MAX_EE_INTERFACE];/* NFCEE supported interface */
+ tNFA_EE_TLV ee_tlv[NFC_MAX_EE_TLVS];/* the TLV */
+ UINT8 num_interface; /* number of Target interface */
+ UINT8 num_tlvs; /* number of TLVs */
+ tNFA_EE_ECB_FLAGS ecb_flags; /* the flags of this control block */
+ tNFA_EE_INTERFACE use_interface; /* NFCEE interface used for the connection */
+ tNFA_NFC_PROTOCOL la_protocol; /* Listen A protocol */
+ tNFA_NFC_PROTOCOL lb_protocol; /* Listen B protocol */
+ tNFA_NFC_PROTOCOL lf_protocol; /* Listen F protocol */
+ tNFA_NFC_PROTOCOL lbp_protocol; /* Listen B' protocol */
+ UINT8 size_mask; /* the size for technology and protocol routing */
+ UINT16 size_aid; /* the size for aid routing */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ tNFA_NFC_PROTOCOL pa_protocol; /* Passive poll A SWP Reader */
+ tNFA_NFC_PROTOCOL pb_protocol; /* Passive poll B SWP Reader */
+ UINT8 ee_req_op; /* add or remove req ntf*/
+#endif
+} tNFA_EE_ECB;
+
+/* data type for NFA_EE_API_DISCOVER_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_EE_CBACK *p_cback;
+} tNFA_EE_API_DISCOVER;
+
+/* data type for NFA_EE_API_REGISTER_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_EE_CBACK *p_cback;
+} tNFA_EE_API_REGISTER;
+
+/* data type for NFA_EE_API_DEREGISTER_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ int index;
+} tNFA_EE_API_DEREGISTER;
+
+/* data type for NFA_EE_API_MODE_SET_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_EE_ECB *p_cb;
+ UINT8 nfcee_id;
+ UINT8 mode;
+} tNFA_EE_API_MODE_SET;
+
+/* data type for NFA_EE_API_SET_TECH_CFG_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_EE_ECB *p_cb;
+ UINT8 nfcee_id;
+ tNFA_TECHNOLOGY_MASK technologies_switch_on;
+ tNFA_TECHNOLOGY_MASK technologies_switch_off;
+ tNFA_TECHNOLOGY_MASK technologies_battery_off;
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ tNFA_TECHNOLOGY_MASK technologies_screen_lock;
+ tNFA_TECHNOLOGY_MASK technologies_screen_off;
+#endif
+} tNFA_EE_API_SET_TECH_CFG;
+
+/* data type for NFA_EE_API_SET_PROTO_CFG_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_EE_ECB *p_cb;
+ UINT8 nfcee_id;
+ tNFA_PROTOCOL_MASK protocols_switch_on;
+ tNFA_PROTOCOL_MASK protocols_switch_off;
+ tNFA_PROTOCOL_MASK protocols_battery_off;
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ tNFA_PROTOCOL_MASK protocols_screen_lock;
+ tNFA_PROTOCOL_MASK protocols_screen_off;
+#endif
+
+} tNFA_EE_API_SET_PROTO_CFG;
+
+/* data type for NFA_EE_API_ADD_AID_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_EE_ECB *p_cb;
+ UINT8 nfcee_id;
+ UINT8 aid_len;
+ UINT8 *p_aid;
+ tNFA_EE_PWR_STATE power_state;
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ UINT8 vs_info;
+#endif
+} tNFA_EE_API_ADD_AID;
+
+/* data type for NFA_EE_API_REMOVE_AID_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ UINT8 aid_len;
+ UINT8 *p_aid;
+} tNFA_EE_API_REMOVE_AID;
+
+/* data type for NFA_EE_API_LMRT_SIZE_EVT */
+typedef BT_HDR tNFA_EE_API_LMRT_SIZE;
+
+/* data type for NFA_EE_API_CONNECT_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_EE_ECB *p_cb;
+ UINT8 nfcee_id;
+ UINT8 ee_interface;
+ tNFA_EE_CBACK *p_cback;
+} tNFA_EE_API_CONNECT;
+
+/* data type for NFA_EE_API_SEND_DATA_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_EE_ECB *p_cb;
+ UINT8 nfcee_id;
+ UINT16 data_len;
+ UINT8 *p_data;
+} tNFA_EE_API_SEND_DATA;
+
+/* data type for NFA_EE_API_DISCONNECT_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_EE_ECB *p_cb;
+ UINT8 nfcee_id;
+} tNFA_EE_API_DISCONNECT;
+
+
+typedef struct
+{
+ BT_HDR hdr;
+ tNFC_STATUS status; /* The event status. */
+} tNFA_EE_MSG_STATUS;
+
+/* common data type for internal events with nfa_ee_use_cfg_cb[] as TRUE */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_EE_ECB *p_cb;
+ UINT8 nfcee_id;
+} tNFA_EE_CFG_HDR;
+
+/* data type for tNFC_RESPONSE_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ void *p_data;
+} tNFA_EE_NCI_RESPONSE;
+
+/* data type for NFA_EE_NCI_DISC_RSP_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFC_NFCEE_DISCOVER_REVT *p_data;
+} tNFA_EE_NCI_DISC_RSP;
+
+/* data type for NFA_EE_NCI_DISC_NTF_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFC_NFCEE_INFO_REVT *p_data;
+} tNFA_EE_NCI_DISC_NTF;
+
+/* data type for NFA_EE_NCI_MODE_SET_RSP_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFC_NFCEE_MODE_SET_REVT *p_data;
+} tNFA_EE_NCI_MODE_SET;
+
+/* data type for NFA_EE_NCI_WAIT_RSP_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ void *p_data;
+ UINT8 opcode;
+} tNFA_EE_NCI_WAIT_RSP;
+
+/* data type for NFA_EE_NCI_CONN_EVT and NFA_EE_NCI_DATA_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ UINT8 conn_id;
+ tNFC_CONN_EVT event;
+ tNFC_CONN *p_data;
+} tNFA_EE_NCI_CONN;
+
+/* data type for NFA_EE_NCI_ACTION_NTF_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFC_EE_ACTION_REVT *p_data;
+} tNFA_EE_NCI_ACTION;
+
+/* data type for NFA_EE_NCI_DISC_REQ_NTF_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFC_EE_DISCOVER_REQ_REVT *p_data;
+} tNFA_EE_NCI_DISC_REQ;
+
+/* union of all event data types */
+typedef union
+{
+ BT_HDR hdr;
+ tNFA_EE_CFG_HDR cfg_hdr;
+ tNFA_EE_API_DISCOVER ee_discover;
+ tNFA_EE_API_REGISTER ee_register;
+ tNFA_EE_API_DEREGISTER deregister;
+ tNFA_EE_API_MODE_SET mode_set;
+ tNFA_EE_API_SET_TECH_CFG set_tech;
+ tNFA_EE_API_SET_PROTO_CFG set_proto;
+ tNFA_EE_API_ADD_AID add_aid;
+ tNFA_EE_API_REMOVE_AID rm_aid;
+ tNFA_EE_API_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;
+ 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_MSG;
+
+/* type for State Machine (SM) action functions */
+typedef void (*tNFA_EE_SM_ACT)(tNFA_EE_MSG *p_data);
+
+/*****************************************************************************
+** control block
+*****************************************************************************/
+#define NFA_EE_CFGED_UPDATE_NOW 0x80
+#define NFA_EE_CFGED_OFF_ROUTING 0x40 /* either switch off or battery off is configured */
+
+/* the following status are the definition used in ee_cfg_sts */
+#define NFA_EE_STS_CHANGED_ROUTING 0x01
+#define NFA_EE_STS_CHANGED_VS 0x02
+#define NFA_EE_STS_CHANGED 0x0f
+#define NFA_EE_STS_PREV_ROUTING 0x10
+#define NFA_EE_STS_PREV 0xf0
+
+
+#define NFA_EE_WAIT_UPDATE 0x10 /* need to report NFA_EE_UPDATED_EVT */
+#define NFA_EE_WAIT_UPDATE_RSP 0x20 /* waiting for the rsp of set routing commands */
+#define NFA_EE_WAIT_UPDATE_ALL 0xF0
+
+typedef UINT8 tNFA_EE_WAIT;
+
+#define NFA_EE_FLAG_WAIT_HCI 0x01 /* set this bit when waiting for HCI to finish the initialization process in NFA_EE_EM_STATE_RESTORING */
+#define NFA_EE_FLAG_NOTIFY_HCI 0x02 /* set this bit when EE needs to notify the p_enable_cback at the end of NFCEE discover process in NFA_EE_EM_STATE_RESTORING */
+#define NFA_EE_FLAG_WAIT_DISCONN 0x04 /* set this bit when gracefully disable with outstanding NCI connections */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define NFA_EE_FLAG_CFG_NFC_DEP 0x05 /* set this bit when NFC-DEP is configured in the routing table */
+#endif
+typedef UINT8 tNFA_EE_FLAGS;
+
+
+#define NFA_EE_DISC_STS_ON 0x00 /* NFCEE DISCOVER in progress */
+#define NFA_EE_DISC_STS_OFF 0x01 /* disable NFCEE DISCOVER */
+#define NFA_EE_DISC_STS_REQ 0x02 /* received NFCEE DISCOVER REQ NTF */
+typedef UINT8 tNFA_EE_DISC_STS;
+
+typedef void (tNFA_EE_ENABLE_DONE_CBACK)(tNFA_EE_DISC_STS status);
+
+/* NFA EE Management control block */
+typedef struct
+{
+ tNFA_EE_ECB ecb[NFA_EE_NUM_ECBS]; /* control block for DH and NFCEEs */
+ TIMER_LIST_ENT timer; /* timer to send info to NFCC */
+ TIMER_LIST_ENT discv_timer; /* timer to end NFCEE discovery */
+ tNFA_EE_CBACK *p_ee_cback[NFA_EE_MAX_CBACKS];/* to report EE events */
+ tNFA_EE_CBACK *p_ee_disc_cback; /* to report EE discovery result */
+ tNFA_EE_ENABLE_DONE_CBACK *p_enable_cback; /* callback to notify on enable done*/
+ tNFA_EE_EM_STATE em_state; /* NFA-EE state initialized or not */
+ UINT8 wait_rsp; /* num of NCI rsp expected (update) */
+ UINT8 num_ee_expecting; /* number of ee_info still expecting*/
+ UINT8 cur_ee; /* the number of ee_info in cb */
+ UINT8 ee_cfged; /* the bit mask of configured ECBs */
+ UINT8 ee_cfg_sts; /* configuration status */
+ tNFA_EE_WAIT ee_wait_evt; /* Pending event(s) to be reported */
+ tNFA_EE_FLAGS ee_flags; /* flags */
+} tNFA_EE_CB;
+
+/*****************************************************************************
+** External variables
+*****************************************************************************/
+
+/* NFA EE control block */
+#if NFA_DYNAMIC_MEMORY == FALSE
+extern tNFA_EE_CB nfa_ee_cb;
+#else
+extern tNFA_EE_CB *nfa_ee_cb_ptr;
+#define nfa_ee_cb (*nfa_ee_cb_ptr)
+#endif
+
+/*****************************************************************************
+** External functions
+*****************************************************************************/
+/* function prototypes - exported from nfa_ee_main.c */
+void nfa_ee_sys_enable (void);
+void nfa_ee_sys_disable (void);
+
+/* event handler function type */
+BOOLEAN nfa_ee_evt_hdlr (BT_HDR *p_msg);
+void nfa_ee_proc_nfcc_power_mode (UINT8 nfcc_power_mode);
+#if (NFC_NFCEE_INCLUDED == TRUE)
+void nfa_ee_get_tech_route (UINT8 power_state, UINT8 *p_handles);
+#endif
+void nfa_ee_proc_evt(tNFC_RESPONSE_EVT event, void *p_data);
+tNFA_EE_ECB * nfa_ee_find_ecb (UINT8 nfcee_id);
+tNFA_EE_ECB * nfa_ee_find_ecb_by_conn_id (UINT8 conn_id);
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+UINT16 nfa_ee_lmrt_size();
+UINT8 nfa_ee_get_supported_tech_list(UINT8 nfcee_id);
+#endif
+UINT8 nfa_ee_ecb_to_mask (tNFA_EE_ECB *p_cb);
+void nfa_ee_restore_one_ecb (tNFA_EE_ECB *p_cb);
+BOOLEAN nfa_ee_is_active (tNFA_HANDLE nfcee_id);
+
+/* Action function prototypes - nfa_ee_act.c */
+void nfa_ee_api_discover(tNFA_EE_MSG *p_data);
+void nfa_ee_api_register(tNFA_EE_MSG *p_data);
+void nfa_ee_api_deregister(tNFA_EE_MSG *p_data);
+void nfa_ee_api_mode_set(tNFA_EE_MSG *p_data);
+void nfa_ee_api_set_tech_cfg(tNFA_EE_MSG *p_data);
+void nfa_ee_api_set_proto_cfg(tNFA_EE_MSG *p_data);
+void nfa_ee_api_add_aid(tNFA_EE_MSG *p_data);
+void nfa_ee_api_remove_aid(tNFA_EE_MSG *p_data);
+void nfa_ee_api_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(BOOLEAN notify_sys);
+void nfa_ee_nci_disc_rsp(tNFA_EE_MSG *p_data);
+void nfa_ee_nci_disc_ntf(tNFA_EE_MSG *p_data);
+void nfa_ee_nci_mode_set_rsp(tNFA_EE_MSG *p_data);
+void nfa_ee_nci_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);
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+BOOLEAN nfa_ee_nfeeid_active(UINT8 nfee_id);
+#endif
+void nfa_ee_report_event(tNFA_EE_CBACK *p_cback, tNFA_EE_EVT event, tNFA_EE_CBACK_DATA *p_data);
+tNFA_EE_ECB * nfa_ee_find_aid_offset(UINT8 aid_len, UINT8 *p_aid, int *p_offset, int *p_entry);
+void nfa_ee_remove_labels(void);
+int nfa_ee_find_total_aid_len(tNFA_EE_ECB *p_cb, int start_entry);
+void nfa_ee_start_timer(void);
+void nfa_ee_reg_cback_enable_done (tNFA_EE_ENABLE_DONE_CBACK *p_cback);
+void nfa_ee_report_update_evt (void);
+
+extern void nfa_ee_proc_hci_info_cback (void);
+void nfa_ee_check_disable (void);
+BOOLEAN nfa_ee_restore_ntf_done(void);
+void nfa_ee_check_restore_complete(void);
+
+
+#endif /* NFA_P2P_INT_H */
diff --git a/src/nfa/int/nfa_hci_int.h b/src/nfa/int/nfa_hci_int.h
new file mode 100644
index 0000000..b9cdb94
--- /dev/null
+++ b/src/nfa/int/nfa_hci_int.h
@@ -0,0 +1,566 @@
+/******************************************************************************
+ *
+ * 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 HCI.
+ *
+ ******************************************************************************/
+#ifndef NFA_HCI_INT_H
+#define NFA_HCI_INT_H
+
+#include "nfa_hci_api.h"
+
+extern BOOLEAN HCI_LOOPBACK_DEBUG;
+
+/*****************************************************************************
+** Constants and data types
+*****************************************************************************/
+
+
+#define NFA_HCI_HOST_ID_UICC0 0x02 /* Host ID for UICC 0 */
+#define NFA_HCI_LAST_HOST_SPECIFIC_GATE 0xEF /* Lost host specific gate */
+
+#define NFA_HCI_SESSION_ID_LEN 8 /* HCI Session ID length */
+#define NFA_MAX_PIPES_IN_GENERIC_GATE 0x0F /* Maximum pipes that can be created on a generic pipe */
+
+#define NFA_HCI_VERSION_SW 0x090000 /* HCI SW Version number */
+#define NFA_HCI_VERSION_HW 0x000000 /* HCI HW Version number */
+#define NFA_HCI_VENDOR_NAME "HCI" /* Vendor Name */
+#define NFA_HCI_MODEL_ID 00 /* Model ID */
+#define NFA_HCI_VERSION 90 /* HCI Version */
+
+/* NFA HCI states */
+#define NFA_HCI_STATE_DISABLED 0x00 /* HCI is disabled */
+#define NFA_HCI_STATE_STARTUP 0x01 /* HCI performing Initialization sequence */
+#define NFA_HCI_STATE_WAIT_NETWK_ENABLE 0x02 /* HCI is waiting for initialization of other host in the network */
+#define NFA_HCI_STATE_IDLE 0x03 /* HCI is waiting to handle api commands */
+#define NFA_HCI_STATE_WAIT_RSP 0x04 /* HCI is waiting for response to command sent */
+#define NFA_HCI_STATE_REMOVE_GATE 0x05 /* Removing all pipes prior to removing the gate */
+#define NFA_HCI_STATE_APP_DEREGISTER 0x06 /* Removing all pipes and gates prior to deregistering the app */
+#define NFA_HCI_STATE_RESTORE 0x07 /* HCI restore */
+#define NFA_HCI_STATE_RESTORE_NETWK_ENABLE 0x08 /* HCI is waiting for initialization of other host in the network after restore */
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define NFA_HCI_MAX_RSP_WAIT_TIME 0x0C
+#define NFA_HCI_CHAIN_PKT_RSP_TIMEOUT 30000 /* After the reception of WTX, maximum response timeout value is 30 sec */
+#endif
+
+typedef UINT8 tNFA_HCI_STATE;
+
+/* NFA HCI PIPE states */
+#define NFA_HCI_PIPE_CLOSED 0x00 /* Pipe is closed */
+#define NFA_HCI_PIPE_OPENED 0x01 /* Pipe is opened */
+
+#define NFA_HCI_INVALID_INX 0xFF
+
+
+typedef UINT8 tNFA_HCI_COMMAND;
+typedef UINT8 tNFA_HCI_RESPONSE;
+
+
+/* NFA HCI Internal events */
+enum
+{
+ NFA_HCI_API_REGISTER_APP_EVT = NFA_SYS_EVT_START (NFA_ID_HCI),/* Register APP with HCI */
+ NFA_HCI_API_DEREGISTER_APP_EVT, /* Deregister an app from HCI */
+ NFA_HCI_API_GET_APP_GATE_PIPE_EVT, /* Get the list of gate and pipe associated to the application */
+ NFA_HCI_API_ALLOC_GATE_EVT, /* Allocate a dyanmic gate for the application */
+ NFA_HCI_API_DEALLOC_GATE_EVT, /* Deallocate a previously allocated gate to the application */
+ NFA_HCI_API_GET_HOST_LIST_EVT, /* Get the list of Host in the network */
+ NFA_HCI_API_GET_REGISTRY_EVT, /* Get a registry entry from a host */
+ NFA_HCI_API_SET_REGISTRY_EVT, /* Set a registry entry on a host */
+ NFA_HCI_API_CREATE_PIPE_EVT, /* Create a pipe between two gates */
+ NFA_HCI_API_OPEN_PIPE_EVT, /* Open a pipe */
+ NFA_HCI_API_CLOSE_PIPE_EVT, /* Close a pipe */
+ NFA_HCI_API_DELETE_PIPE_EVT, /* Delete a pipe */
+ NFA_HCI_API_ADD_STATIC_PIPE_EVT, /* Add a static pipe */
+ NFA_HCI_API_SEND_CMD_EVT, /* Send command via pipe */
+ NFA_HCI_API_SEND_RSP_EVT, /* Application Response to a command */
+ NFA_HCI_API_SEND_EVENT_EVT, /* Send event via pipe */
+
+ NFA_HCI_RSP_NV_READ_EVT, /* Non volatile read complete event */
+ NFA_HCI_RSP_NV_WRITE_EVT, /* Non volatile write complete event */
+ NFA_HCI_RSP_TIMEOUT_EVT, /* Timeout to response for the HCP Command packet */
+ NFA_HCI_CHECK_QUEUE_EVT
+};
+
+#define NFA_HCI_FIRST_API_EVENT NFA_HCI_API_REGISTER_APP_EVT
+#define NFA_HCI_LAST_API_EVENT NFA_HCI_API_SEND_EVENT_EVT
+
+typedef UINT16 tNFA_HCI_INT_EVT;
+
+/* Internal event structures.
+**
+** Note, every internal structure starts with a BT_HDR and an app handle
+*/
+
+/* data type for NFA_HCI_API_REGISTER_APP_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE hci_handle;
+ char app_name[NFA_MAX_HCI_APP_NAME_LEN + 1];
+ tNFA_HCI_CBACK *p_cback;
+ BOOLEAN b_send_conn_evts;
+} tNFA_HCI_API_REGISTER_APP;
+
+/* data type for NFA_HCI_API_DEREGISTER_APP_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE hci_handle;
+ char app_name[NFA_MAX_HCI_APP_NAME_LEN + 1];
+} tNFA_HCI_API_DEREGISTER_APP;
+
+/* data type for NFA_HCI_API_GET_APP_GATE_PIPE_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE hci_handle;
+} tNFA_HCI_API_GET_APP_GATE_PIPE;
+
+/* data type for NFA_HCI_API_ALLOC_GATE_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE hci_handle;
+ UINT8 gate;
+} tNFA_HCI_API_ALLOC_GATE;
+
+/* data type for NFA_HCI_API_DEALLOC_GATE_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE hci_handle;
+ UINT8 gate;
+} tNFA_HCI_API_DEALLOC_GATE;
+
+/* data type for NFA_HCI_API_GET_HOST_LIST_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE hci_handle;
+ tNFA_STATUS status;
+} tNFA_HCI_API_GET_HOST_LIST;
+
+/* data type for NFA_HCI_API_GET_REGISTRY_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE hci_handle;
+ UINT8 pipe;
+ UINT8 reg_inx;
+} tNFA_HCI_API_GET_REGISTRY;
+
+/* data type for NFA_HCI_API_SET_REGISTRY_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE hci_handle;
+ UINT8 pipe;
+ UINT8 reg_inx;
+ UINT8 size;
+ UINT8 data[NFA_MAX_HCI_CMD_LEN];
+} tNFA_HCI_API_SET_REGISTRY;
+
+/* data type for NFA_HCI_API_CREATE_PIPE_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE hci_handle;
+ tNFA_STATUS status;
+ UINT8 source_gate;
+ UINT8 dest_host;
+ UINT8 dest_gate;
+} tNFA_HCI_API_CREATE_PIPE_EVT;
+
+/* data type for NFA_HCI_API_OPEN_PIPE_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE hci_handle;
+ tNFA_STATUS status;
+ UINT8 pipe;
+} tNFA_HCI_API_OPEN_PIPE_EVT;
+
+/* data type for NFA_HCI_API_CLOSE_PIPE_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE hci_handle;
+ tNFA_STATUS status;
+ UINT8 pipe;
+} tNFA_HCI_API_CLOSE_PIPE_EVT;
+
+/* data type for NFA_HCI_API_DELETE_PIPE_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE hci_handle;
+ tNFA_STATUS status;
+ UINT8 pipe;
+} tNFA_HCI_API_DELETE_PIPE_EVT;
+
+/* data type for NFA_HCI_API_ADD_STATIC_PIPE_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE hci_handle;
+ tNFA_STATUS status;
+ UINT8 host;
+ UINT8 gate;
+ UINT8 pipe;
+} tNFA_HCI_API_ADD_STATIC_PIPE_EVT;
+
+/* data type for NFA_HCI_API_SEND_EVENT_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE hci_handle;
+ UINT8 pipe;
+ UINT8 evt_code;
+ UINT16 evt_len;
+ UINT8 *p_evt_buf;
+ UINT16 rsp_len;
+ UINT8 *p_rsp_buf;
+ UINT16 rsp_timeout;
+} tNFA_HCI_API_SEND_EVENT_EVT;
+
+/* data type for NFA_HCI_API_SEND_CMD_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE hci_handle;
+ UINT8 pipe;
+ UINT8 cmd_code;
+ UINT16 cmd_len;
+ UINT8 data[NFA_MAX_HCI_CMD_LEN];
+} tNFA_HCI_API_SEND_CMD_EVT;
+
+/* data type for NFA_HCI_RSP_NV_READ_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ UINT8 block;
+ UINT16 size;
+ tNFA_STATUS status;
+} tNFA_HCI_RSP_NV_READ_EVT;
+
+/* data type for NFA_HCI_RSP_NV_WRITE_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_STATUS status;
+} tNFA_HCI_RSP_NV_WRITE_EVT;
+
+/* data type for NFA_HCI_API_SEND_RSP_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE hci_handle;
+ UINT8 pipe;
+ UINT8 response;
+ UINT8 size;
+ UINT8 data[NFA_MAX_HCI_RSP_LEN];
+} tNFA_HCI_API_SEND_RSP_EVT;
+
+/* common data type for internal events */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE hci_handle;
+} tNFA_HCI_COMM_DATA;
+
+/* union of all event data types */
+typedef union
+{
+ BT_HDR hdr;
+ tNFA_HCI_COMM_DATA comm;
+
+ /* API events */
+ tNFA_HCI_API_REGISTER_APP app_info; /* Register/Deregister an application */
+ tNFA_HCI_API_GET_APP_GATE_PIPE get_gate_pipe_list; /* Get the list of gates and pipes created for the application */
+ tNFA_HCI_API_ALLOC_GATE gate_info; /* Allocate a dynamic gate to the application */
+ tNFA_HCI_API_DEALLOC_GATE gate_dealloc; /* Deallocate the gate allocated to the application */
+ tNFA_HCI_API_CREATE_PIPE_EVT create_pipe; /* Create a pipe */
+ tNFA_HCI_API_OPEN_PIPE_EVT open_pipe; /* Open a pipe */
+ tNFA_HCI_API_CLOSE_PIPE_EVT close_pipe; /* Close a pipe */
+ tNFA_HCI_API_DELETE_PIPE_EVT delete_pipe; /* Delete a pipe */
+ tNFA_HCI_API_ADD_STATIC_PIPE_EVT add_static_pipe; /* Add a static pipe */
+ tNFA_HCI_API_GET_HOST_LIST get_host_list; /* Get the list of Host in the network */
+ tNFA_HCI_API_GET_REGISTRY get_registry; /* Get a registry entry on a host */
+ tNFA_HCI_API_SET_REGISTRY set_registry; /* Set a registry entry on a host */
+ tNFA_HCI_API_SEND_CMD_EVT send_cmd; /* Send a event on a pipe to a host */
+ tNFA_HCI_API_SEND_RSP_EVT send_rsp; /* Response to a command sent on a pipe to a host */
+ tNFA_HCI_API_SEND_EVENT_EVT send_evt; /* Send a command on a pipe to a host */
+
+ /* Internal events */
+ tNFA_HCI_RSP_NV_READ_EVT nv_read; /* Read Non volatile data */
+ tNFA_HCI_RSP_NV_WRITE_EVT nv_write; /* Write Non volatile data */
+} tNFA_HCI_EVENT_DATA;
+
+/*****************************************************************************
+** control block
+*****************************************************************************/
+
+/* Dynamic pipe control block */
+typedef struct
+{
+ UINT8 pipe_id; /* Pipe ID */
+ tNFA_HCI_PIPE_STATE pipe_state; /* State of the Pipe */
+ UINT8 local_gate; /* local gate id */
+ UINT8 dest_host; /* Peer host to which this pipe is connected */
+ UINT8 dest_gate; /* Peer gate to which this pipe is connected */
+} tNFA_HCI_DYN_PIPE;
+
+/* Dynamic gate control block */
+typedef struct
+{
+ UINT8 gate_id; /* local gate id */
+ tNFA_HANDLE gate_owner; /* NFA-HCI handle assigned to the application which owns the gate */
+ UINT32 pipe_inx_mask; /* Bit 0 == pipe inx 0, etc */
+} tNFA_HCI_DYN_GATE;
+
+/* Admin gate control block */
+typedef struct
+{
+ tNFA_HCI_PIPE_STATE pipe01_state; /* State of Pipe '01' */
+ UINT8 session_id[NFA_HCI_SESSION_ID_LEN]; /* Session ID of the host network */
+} tNFA_ADMIN_GATE_INFO;
+
+/* Link management gate control block */
+typedef struct
+{
+ tNFA_HCI_PIPE_STATE pipe00_state; /* State of Pipe '00' */
+ UINT16 rec_errors; /* Receive errors */
+} tNFA_LINK_MGMT_GATE_INFO;
+
+/* Identity management gate control block */
+typedef struct
+{
+ UINT32 pipe_inx_mask; /* Bit 0 == pipe inx 0, etc */
+ UINT16 version_sw; /* Software version number */
+ UINT16 version_hw; /* Hardware version number */
+ UINT8 vendor_name[20]; /* Vendor name */
+ UINT8 model_id; /* Model ID */
+ UINT8 hci_version; /* HCI Version */
+} tNFA_ID_MGMT_GATE_INFO;
+
+/* Internal flags */
+#define NFA_HCI_FL_DISABLING 0x01 /* sub system is being disabled */
+#define NFA_HCI_FL_NV_CHANGED 0x02 /* NV Ram changed */
+#if (NFC_NXP_NOT_OPEN_INCLUDED == 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_ESE_PIPE 0x16
+#define NFA_HCI_CONN_UICC_PIPE 0x0A
+#define NFA_HCI_APDU_PIPE 0x19
+#endif
+/* NFA HCI control block */
+typedef struct
+{
+ tNFA_HCI_STATE hci_state; /* state of the HCI */
+ UINT8 num_nfcee; /* Number of NFCEE ID Discovered */
+ UINT8 num_ee_dis_req_ntf; /* Number of ee discovery request ntf received */
+ UINT8 num_hot_plug_evts; /* Number of Hot plug events received after ee discovery disable ntf */
+ UINT8 inactive_host[NFA_HCI_MAX_HOST_IN_NETWORK]; /* Inactive host in the host network */
+ UINT8 reset_host[NFA_HCI_MAX_HOST_IN_NETWORK]; /* List of host reseting */
+ BOOLEAN b_low_power_mode; /* Host controller in low power mode */
+ BOOLEAN b_hci_netwk_reset; /* Command sent to reset HCI Network */
+ BOOLEAN w4_hci_netwk_init; /* Wait for other host in network to initialize */
+ TIMER_LIST_ENT timer; /* Timer to avoid indefinitely waiting for response */
+ UINT8 conn_id; /* Connection ID */
+ UINT8 buff_size; /* Connection buffer size */
+ BOOLEAN nv_read_cmplt; /* NV Read completed */
+ BOOLEAN nv_write_needed; /* Something changed - NV write is needed */
+ BOOLEAN assembling; /* Set true if in process of assembling a message */
+ BOOLEAN assembly_failed; /* Set true if Insufficient buffer to Reassemble incoming message */
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ UINT8 assembling_flags; /* the flags to keep track of assembling status*/
+ UINT8 assembly_failed_flags; /* the flags to keep track of failed assembly*/
+#endif
+ BOOLEAN w4_rsp_evt; /* Application command sent on HCP Event */
+ tNFA_HANDLE app_in_use; /* Index of the application that is waiting for response */
+ UINT8 local_gate_in_use; /* Local gate currently working with */
+ UINT8 remote_gate_in_use; /* Remote gate currently working with */
+ UINT8 remote_host_in_use; /* The remote host to which a command is sent */
+ UINT8 pipe_in_use; /* The pipe currently working with */
+ UINT8 param_in_use; /* The registry parameter currently working with */
+ tNFA_HCI_COMMAND cmd_sent; /* The last command sent */
+ BOOLEAN ee_disc_cmplt; /* EE Discovery operation completed */
+ BOOLEAN ee_disable_disc; /* EE Discovery operation is disabled */
+ UINT16 msg_len; /* For segmentation - length of the combined message */
+ UINT16 max_msg_len; /* Maximum reassembled message size */
+ UINT8 msg_data[NFA_MAX_HCI_EVENT_LEN]; /* For segmentation - the combined message data */
+ UINT8 *p_msg_data; /* For segmentation - reassembled message */
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ UINT8 *p_evt_data; /* For segmentation - reassembled event data */
+ UINT16 evt_len; /* For segmentation - length of the combined event data */
+ UINT16 max_evt_len; /* Maximum reassembled message size */
+ UINT8 evt_data[NFA_MAX_HCI_EVENT_LEN]; /* For segmentation - the combined event data */
+ UINT8 type_evt; /* Instruction type of incoming message */
+ UINT8 inst_evt; /* Instruction of incoming message */
+ UINT8 type_msg; /* Instruction type of incoming message */
+ UINT8 inst_msg; /* Instruction of incoming message */
+
+#endif
+ UINT8 type; /* Instruction type of incoming message */
+ UINT8 inst; /* Instruction of incoming message */
+
+ BUFFER_Q hci_api_q; /* Buffer Q to hold incoming API commands */
+ BUFFER_Q hci_host_reset_api_q; /* Buffer Q to hold incoming API commands to a host that is reactivating */
+ tNFA_HCI_CBACK *p_app_cback[NFA_HCI_MAX_APP_CB]; /* Callback functions registered by the applications */
+ UINT16 rsp_buf_size; /* Maximum size of APDU buffer */
+ UINT8 *p_rsp_buf; /* Buffer to hold response to sent event */
+ struct /* 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];
+
+ BOOLEAN b_send_conn_evts[NFA_HCI_MAX_APP_CB];
+ tNFA_ADMIN_GATE_INFO admin_gate;
+ tNFA_LINK_MGMT_GATE_INFO link_mgmt_gate;
+ tNFA_ID_MGMT_GATE_INFO id_mgmt_gate;
+ } cfg;
+
+} tNFA_HCI_CB;
+
+
+/*****************************************************************************
+** External variables
+*****************************************************************************/
+
+/* NFA HCI control block */
+#if NFA_DYNAMIC_MEMORY == FALSE
+extern tNFA_HCI_CB nfa_hci_cb;
+#else
+extern tNFA_HCI_CB *nfa_hci_cb_ptr;
+#define nfa_hci_cb (*nfa_hci_cb_ptr)
+#endif
+
+
+/*****************************************************************************
+** External functions
+*****************************************************************************/
+
+/* Functions in nfa_hci_main.c
+*/
+extern void nfa_hci_init (void);
+extern void nfa_hci_proc_nfcc_power_mode (UINT8 nfcc_power_mode);
+extern void nfa_hci_dh_startup_complete (void);
+extern void nfa_hci_startup_complete (tNFA_STATUS status);
+extern void nfa_hci_startup (void);
+extern void nfa_hci_restore_default_config (UINT8 *p_session_id);
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+extern void nfa_hci_release_transcieve();
+extern void nfa_hci_network_enable();
+#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 *p_data);
+extern void nfa_hci_handle_admin_gate_rsp (UINT8 *p_data, UINT8 data_len);
+extern void nfa_hci_handle_admin_gate_evt (UINT8 *p_data);
+extern void nfa_hci_handle_link_mgm_gate_cmd (UINT8 *p_data);
+extern void nfa_hci_handle_dyn_pipe_pkt (UINT8 pipe, UINT8 *p_data, UINT16 data_len);
+extern void nfa_hci_handle_pipe_open_close_cmd (tNFA_HCI_DYN_PIPE *p_pipe);
+extern void nfa_hci_api_dealloc_gate (tNFA_HCI_EVENT_DATA *p_evt_data);
+extern void nfa_hci_api_deregister (tNFA_HCI_EVENT_DATA *p_evt_data);
+
+/* Utility functions in nfa_hci_utils.c
+*/
+extern tNFA_HCI_DYN_GATE *nfa_hciu_alloc_gate (UINT8 gate_id, tNFA_HANDLE app_handle);
+extern tNFA_HCI_DYN_GATE *nfa_hciu_find_gate_by_gid (UINT8 gate_id);
+extern tNFA_HCI_DYN_GATE *nfa_hciu_find_gate_by_owner (tNFA_HANDLE app_handle);
+extern tNFA_HCI_DYN_GATE *nfa_hciu_find_gate_with_nopipes_by_owner (tNFA_HANDLE app_handle);
+extern tNFA_HCI_DYN_PIPE *nfa_hciu_find_pipe_by_pid (UINT8 pipe_id);
+extern tNFA_HCI_DYN_PIPE *nfa_hciu_find_pipe_by_owner (tNFA_HANDLE app_handle);
+extern tNFA_HCI_DYN_PIPE *nfa_hciu_find_active_pipe_by_owner (tNFA_HANDLE app_handle);
+extern tNFA_HCI_DYN_PIPE *nfa_hciu_find_pipe_on_gate (UINT8 gate_id);
+extern tNFA_HANDLE nfa_hciu_get_gate_owner (UINT8 gate_id);
+extern BOOLEAN nfa_hciu_check_pipe_between_gates (UINT8 local_gate, UINT8 dest_host, UINT8 dest_gate);
+extern BOOLEAN nfa_hciu_is_active_host (UINT8 host_id);
+extern BOOLEAN nfa_hciu_is_host_reseting (UINT8 host_id);
+extern BOOLEAN nfa_hciu_is_no_host_resetting (void);
+extern tNFA_HCI_DYN_PIPE *nfa_hciu_find_active_pipe_on_gate (UINT8 gate_id);
+extern tNFA_HANDLE nfa_hciu_get_pipe_owner (UINT8 pipe_id);
+extern UINT8 nfa_hciu_count_open_pipes_on_gate (tNFA_HCI_DYN_GATE *p_gate);
+extern UINT8 nfa_hciu_count_pipes_on_gate (tNFA_HCI_DYN_GATE *p_gate);
+extern tNFA_STATUS nfa_hciu_asmbl_dyn_pipe_pkt (UINT8 *p_data, UINT8 data_len);
+
+extern tNFA_HCI_RESPONSE nfa_hciu_add_pipe_to_gate (UINT8 pipe, UINT8 local_gate, UINT8 dest_host, UINT8 dest_gate);
+extern tNFA_HCI_RESPONSE nfa_hciu_add_pipe_to_static_gate (UINT8 local_gate, UINT8 pipe_id, UINT8 dest_host, UINT8 dest_gate);
+
+extern tNFA_HCI_RESPONSE nfa_hciu_release_pipe (UINT8 pipe_id);
+extern void nfa_hciu_release_gate (UINT8 gate);
+extern void nfa_hciu_remove_all_pipes_from_host (UINT8 host);
+extern UINT8 nfa_hciu_get_allocated_gate_list (UINT8 *p_gate_list);
+
+extern void nfa_hciu_send_to_app (tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA *p_evt, tNFA_HANDLE app_handle);
+extern void nfa_hciu_send_to_all_apps (tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA *p_evt);
+extern void nfa_hciu_send_to_apps_handling_connectivity_evts (tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA *p_evt);
+
+extern tNFA_STATUS nfa_hciu_send_close_pipe_cmd (UINT8 pipe);
+extern tNFA_STATUS nfa_hciu_send_delete_pipe_cmd (UINT8 pipe);
+extern tNFA_STATUS nfa_hciu_send_clear_all_pipe_cmd (void);
+extern tNFA_STATUS nfa_hciu_send_open_pipe_cmd (UINT8 pipe);
+extern tNFA_STATUS nfa_hciu_send_get_param_cmd (UINT8 pipe, UINT8 index);
+extern tNFA_STATUS nfa_hciu_send_create_pipe_cmd (UINT8 source_gate, UINT8 dest_host, UINT8 dest_gate);
+extern tNFA_STATUS nfa_hciu_send_set_param_cmd (UINT8 pipe, UINT8 index, UINT8 length, UINT8 *p_data);
+extern tNFA_STATUS nfa_hciu_send_msg (UINT8 pipe_id, UINT8 type, UINT8 instruction, UINT16 pkt_len, UINT8 *p_pkt);
+
+
+
+#if (BT_TRACE_VERBOSE == TRUE)
+extern char *nfa_hciu_type_2_str (UINT8 type);
+extern char *nfa_hciu_instr_2_str (UINT8 type);
+extern char *nfa_hciu_get_event_name (UINT16 event);
+extern char *nfa_hciu_get_response_name (UINT8 rsp_code);
+extern char *nfa_hciu_get_state_name (UINT8 state);
+extern char *nfa_hciu_get_type_inst_names (UINT8 pipe, UINT8 type, UINT8 inst, char *p_buff);
+extern char *nfa_hciu_evt_2_str (UINT8 pipe_id, UINT8 evt);
+#endif
+
+
+#endif /* NFA_HCI_INT_H */
diff --git a/src/nfa/int/nfa_p2p_int.h b/src/nfa/int/nfa_p2p_int.h
new file mode 100644
index 0000000..0296ec5
--- /dev/null
+++ b/src/nfa/int/nfa_p2p_int.h
@@ -0,0 +1,339 @@
+/******************************************************************************
+ *
+ * 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 (defined (NFA_P2P_INCLUDED) && (NFA_P2P_INCLUDED==TRUE))
+#include "nfa_p2p_api.h"
+#include "nfa_dm_int.h"
+
+/*****************************************************************************
+** Constants and data types
+*****************************************************************************/
+#define NFA_P2P_DEBUG BT_TRACE_VERBOSE
+
+/* NFA P2P LLCP link state */
+enum
+{
+ NFA_P2P_LLCP_STATE_IDLE,
+ NFA_P2P_LLCP_STATE_LISTENING,
+ NFA_P2P_LLCP_STATE_ACTIVATED,
+
+ NFA_P2P_LLCP_STATE_MAX
+};
+
+typedef UINT8 tNFA_P2P_LLCP_STATE;
+
+/* NFA P2P events */
+enum
+{
+ NFA_P2P_API_REG_SERVER_EVT = NFA_SYS_EVT_START (NFA_ID_P2P),
+ NFA_P2P_API_REG_CLIENT_EVT,
+ NFA_P2P_API_DEREG_EVT,
+ NFA_P2P_API_ACCEPT_CONN_EVT,
+ NFA_P2P_API_REJECT_CONN_EVT,
+ NFA_P2P_API_DISCONNECT_EVT,
+ NFA_P2P_API_CONNECT_EVT,
+ NFA_P2P_API_SEND_UI_EVT,
+ NFA_P2P_API_SEND_DATA_EVT,
+ NFA_P2P_API_SET_LOCAL_BUSY_EVT,
+ NFA_P2P_API_GET_LINK_INFO_EVT,
+ NFA_P2P_API_GET_REMOTE_SAP_EVT,
+ NFA_P2P_API_SET_LLCP_CFG_EVT,
+ NFA_P2P_INT_RESTART_RF_DISC_EVT,
+
+ NFA_P2P_LAST_EVT
+};
+
+/* data type for NFA_P2P_API_REG_SERVER_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ UINT8 server_sap;
+ tNFA_P2P_LINK_TYPE link_type;
+ char service_name[LLCP_MAX_SN_LEN + 1];
+ tNFA_P2P_CBACK *p_cback;
+} tNFA_P2P_API_REG_SERVER;
+
+/* data type for NFA_P2P_API_REG_CLIENT_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_P2P_LINK_TYPE link_type;
+ tNFA_P2P_CBACK *p_cback;
+} tNFA_P2P_API_REG_CLIENT;
+
+/* data type for NFA_P2P_API_DEREG_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE handle;
+} tNFA_P2P_API_DEREG;
+
+/* data type for NFA_P2P_API_ACCEPT_CONN_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE conn_handle;
+ UINT16 miu;
+ UINT8 rw;
+} tNFA_P2P_API_ACCEPT_CONN;
+
+/* data type for NFA_P2P_API_REJECT_CONN_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE conn_handle;
+} tNFA_P2P_API_REJECT_CONN;
+
+/* data type for NFA_P2P_API_DISCONNECT_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE conn_handle;
+ BOOLEAN flush;
+} tNFA_P2P_API_DISCONNECT;
+
+/* data type for NFA_P2P_API_CONNECT_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE client_handle;
+ char service_name[LLCP_MAX_SN_LEN + 1];
+ UINT8 dsap;
+ UINT16 miu;
+ UINT8 rw;
+} tNFA_P2P_API_CONNECT;
+
+/* data type for NFA_P2P_API_SEND_UI_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE handle;
+ UINT8 dsap;
+ BT_HDR *p_msg;
+} tNFA_P2P_API_SEND_UI;
+
+/* data type for NFA_P2P_API_SEND_DATA_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE conn_handle;
+ BT_HDR *p_msg;
+} tNFA_P2P_API_SEND_DATA;
+
+/* data type for NFA_P2P_API_SET_LOCAL_BUSY_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE conn_handle;
+ BOOLEAN is_busy;
+} tNFA_P2P_API_SET_LOCAL_BUSY;
+
+/* data type for NFA_P2P_API_GET_LINK_INFO_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE handle;
+} tNFA_P2P_API_GET_LINK_INFO;
+
+/* data type for NFA_P2P_API_GET_REMOTE_SAP_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE handle;
+ char service_name[LLCP_MAX_SN_LEN + 1];
+} tNFA_P2P_API_GET_REMOTE_SAP;
+
+/* data type for NFA_P2P_API_SET_LLCP_CFG_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ UINT16 link_miu;
+ UINT8 opt;
+ UINT8 wt;
+ UINT16 link_timeout;
+ UINT16 inact_timeout_init;
+ UINT16 inact_timeout_target;
+ UINT16 symm_delay;
+ UINT16 data_link_timeout;
+ UINT16 delay_first_pdu_timeout;
+} tNFA_P2P_API_SET_LLCP_CFG;
+
+/* union of all event data types */
+typedef union
+{
+ BT_HDR hdr;
+ tNFA_P2P_API_REG_SERVER api_reg_server;
+ tNFA_P2P_API_REG_CLIENT api_reg_client;
+ tNFA_P2P_API_DEREG api_dereg;
+ tNFA_P2P_API_ACCEPT_CONN api_accept;
+ tNFA_P2P_API_REJECT_CONN api_reject;
+ tNFA_P2P_API_DISCONNECT api_disconnect;
+ tNFA_P2P_API_CONNECT api_connect;
+ tNFA_P2P_API_SEND_UI api_send_ui;
+ tNFA_P2P_API_SEND_DATA api_send_data;
+ tNFA_P2P_API_SET_LOCAL_BUSY api_local_busy;
+ tNFA_P2P_API_GET_LINK_INFO api_link_info;
+ tNFA_P2P_API_GET_REMOTE_SAP api_remote_sap;
+ tNFA_P2P_API_SET_LLCP_CFG api_set_llcp_cfg;
+} tNFA_P2P_MSG;
+
+/*****************************************************************************
+** control block
+*****************************************************************************/
+#define NFA_P2P_HANDLE_FLAG_CONN 0x80 /* Bit flag for connection handle */
+
+/* NFA P2P Connection block */
+#define NFA_P2P_CONN_FLAG_IN_USE 0x01 /* Connection control block is used */
+#define NFA_P2P_CONN_FLAG_REMOTE_RW_ZERO 0x02 /* Remote set RW to 0 (flow off) */
+#define NFA_P2P_CONN_FLAG_CONGESTED 0x04 /* data link connection is congested */
+
+typedef struct
+{
+ UINT8 flags; /* internal flags for data link connection */
+ UINT8 local_sap; /* local SAP of data link connection */
+ UINT8 remote_sap; /* remote SAP of data link connection */
+ UINT16 remote_miu; /* MIU of remote end point */
+ UINT8 num_pending_i_pdu; /* number of tx I PDU not processed by NFA */
+} tNFA_P2P_CONN_CB;
+
+/* NFA P2P SAP control block */
+#define NFA_P2P_SAP_FLAG_SERVER 0x01 /* registered server */
+#define NFA_P2P_SAP_FLAG_CLIENT 0x02 /* registered client */
+#define NFA_P2P_SAP_FLAG_LLINK_CONGESTED 0x04 /* logical link connection is congested */
+
+typedef struct
+{
+ UINT8 flags; /* internal flags for local SAP */
+ tNFA_P2P_CBACK *p_cback; /* callback function for local SAP */
+ UINT8 num_pending_ui_pdu; /* number of tx UI PDU not processed by NFA */
+} tNFA_P2P_SAP_CB;
+
+/* NFA P2P SDP control block */
+typedef struct
+{
+ UINT8 tid; /* transaction ID */
+ UINT8 local_sap;
+} tNFA_P2P_SDP_CB;
+
+#define NFA_P2P_NUM_SAP 64
+
+/* NFA P2P control block */
+typedef struct
+{
+ tNFA_HANDLE dm_disc_handle;
+
+ tNFA_DM_RF_DISC_STATE rf_disc_state;
+ tNFA_P2P_LLCP_STATE llcp_state;
+ BOOLEAN is_initiator;
+ BOOLEAN is_active_mode;
+ UINT16 local_link_miu;
+ UINT16 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 */
+ BOOLEAN is_p2p_listening;
+ BOOLEAN is_cho_listening;
+ BOOLEAN is_snep_listening;
+
+ tNFA_P2P_SAP_CB sap_cb[NFA_P2P_NUM_SAP];
+ tNFA_P2P_CONN_CB conn_cb[LLCP_MAX_DATA_LINK];
+ tNFA_P2P_SDP_CB sdp_cb[LLCP_MAX_SDP_TRANSAC];
+
+ UINT8 total_pending_ui_pdu; /* total number of tx UI PDU not processed by NFA */
+ UINT8 total_pending_i_pdu; /* total number of tx I PDU not processed by NFA */
+
+ UINT8 trace_level;
+} tNFA_P2P_CB;
+
+/*****************************************************************************
+** External variables
+*****************************************************************************/
+
+/* NFA P2P control block */
+#if NFA_DYNAMIC_MEMORY == FALSE
+extern tNFA_P2P_CB nfa_p2p_cb;
+#else
+extern tNFA_P2P_CB *nfa_p2p_cb_ptr;
+#define nfa_p2p_cb (*nfa_p2p_cb_ptr)
+#endif
+
+/*****************************************************************************
+** External functions
+*****************************************************************************/
+/*
+** nfa_p2p_main.c
+*/
+void nfa_p2p_init (void);
+void nfa_p2p_update_listen_tech (tNFA_TECHNOLOGY_MASK tech_mask);
+void nfa_p2p_enable_listening (tNFA_SYS_ID sys_id, BOOLEAN update_wks);
+void nfa_p2p_disable_listening (tNFA_SYS_ID sys_id, BOOLEAN update_wks);
+void nfa_p2p_activate_llcp (tNFC_DISCOVER *p_data);
+void nfa_p2p_deactivate_llcp (void);
+void nfa_p2p_set_config (tNFA_DM_DISC_TECH_PROTO_MASK disc_mask);
+
+/*
+** nfa_p2p_act.c
+*/
+void nfa_p2p_proc_llcp_data_ind (tLLCP_SAP_CBACK_DATA *p_data);
+void nfa_p2p_proc_llcp_connect_ind (tLLCP_SAP_CBACK_DATA *p_data);
+void nfa_p2p_proc_llcp_connect_resp (tLLCP_SAP_CBACK_DATA *p_data);
+void nfa_p2p_proc_llcp_disconnect_ind (tLLCP_SAP_CBACK_DATA *p_data);
+void nfa_p2p_proc_llcp_disconnect_resp (tLLCP_SAP_CBACK_DATA *p_data);
+void nfa_p2p_proc_llcp_congestion (tLLCP_SAP_CBACK_DATA *p_data);
+void nfa_p2p_proc_llcp_link_status (tLLCP_SAP_CBACK_DATA *p_data);
+
+BOOLEAN nfa_p2p_start_sdp (char *p_service_name, UINT8 local_sap);
+
+BOOLEAN nfa_p2p_reg_server (tNFA_P2P_MSG *p_msg);
+BOOLEAN nfa_p2p_reg_client (tNFA_P2P_MSG *p_msg);
+BOOLEAN nfa_p2p_dereg (tNFA_P2P_MSG *p_msg);
+BOOLEAN nfa_p2p_accept_connection (tNFA_P2P_MSG *p_msg);
+BOOLEAN nfa_p2p_reject_connection (tNFA_P2P_MSG *p_msg);
+BOOLEAN nfa_p2p_disconnect (tNFA_P2P_MSG *p_msg);
+BOOLEAN nfa_p2p_create_data_link_connection (tNFA_P2P_MSG *p_msg);
+BOOLEAN nfa_p2p_send_ui (tNFA_P2P_MSG *p_msg);
+BOOLEAN nfa_p2p_send_data (tNFA_P2P_MSG *p_msg);
+BOOLEAN nfa_p2p_set_local_busy (tNFA_P2P_MSG *p_msg);
+BOOLEAN nfa_p2p_get_link_info (tNFA_P2P_MSG *p_msg);
+BOOLEAN nfa_p2p_get_remote_sap (tNFA_P2P_MSG *p_msg);
+BOOLEAN nfa_p2p_set_llcp_cfg (tNFA_P2P_MSG *p_msg);
+BOOLEAN nfa_p2p_restart_rf_discovery (tNFA_P2P_MSG *p_msg);
+
+#if (BT_TRACE_VERBOSE == TRUE)
+char *nfa_p2p_evt_code (UINT16 evt_code);
+#endif
+
+#else
+
+#define nfa_p2p_init ()
+#define nfa_p2p_activate_llcp (a) {};
+#define nfa_p2p_deactivate_llcp ()
+#define nfa_p2p_set_config ()
+
+#endif /* (defined (NFA_P2P_INCLUDED) && (NFA_P2P_INCLUDED==TRUE)) */
+#endif /* NFA_P2P_INT_H */
diff --git a/src/nfa/int/nfa_rw_int.h b/src/nfa/int/nfa_rw_int.h
new file mode 100644
index 0000000..c5fde03
--- /dev/null
+++ b/src/nfa/int/nfa_rw_int.h
@@ -0,0 +1,380 @@
+/******************************************************************************
+ *
+ * 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 */
+#define NFA_RW_TLV_DETECT_ST_LOCK_TLV_OP_COMPLETE 0x01 /* Lock control tlv detected */
+#define NFA_RW_TLV_DETECT_ST_MEM_TLV_OP_COMPLETE 0x02 /* Memory control tlv detected */
+#define NFA_RW_TLV_DETECT_ST_COMPLETE 0x03 /* Both Lock and Memory control Tlvs are detected */
+
+typedef UINT8 tNFA_RW_TLV_ST;
+
+
+/* RW events */
+enum
+{
+ NFA_RW_OP_REQUEST_EVT = NFA_SYS_EVT_START (NFA_ID_RW),
+ NFA_RW_ACTIVATE_NTF_EVT,
+ NFA_RW_DEACTIVATE_NTF_EVT,
+ NFA_RW_PRESENCE_CHECK_TICK_EVT,
+ NFA_RW_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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ NFA_RW_OP_T3BT_PUPI,
+#endif
+
+ NFA_RW_OP_MAX
+};
+typedef UINT8 tNFA_RW_OP;
+
+/* Enumeration of parameter structios for nfa_rw operations */
+
+/* NFA_RW_OP_WRITE_NDEF params */
+typedef struct
+{
+ UINT32 len;
+ UINT8 *p_data;
+} tNFA_RW_OP_PARAMS_WRITE_NDEF;
+
+/* NFA_RW_OP_SEND_RAW_FRAME params */
+typedef struct
+{
+ BT_HDR *p_data;
+} tNFA_RW_OP_PARAMS_SEND_RAW_FRAME;
+
+/* NFA_RW_OP_SET_TAG_RO params */
+typedef struct
+{
+ BOOLEAN b_hard_lock;
+} tNFA_RW_OP_PARAMS_CONFIG_READ_ONLY;
+
+/* NFA_RW_OP_T1T_READ params */
+typedef struct
+{
+ UINT8 segment_number;
+ UINT8 block_number;
+ UINT8 index;
+} tNFA_RW_OP_PARAMS_T1T_READ;
+
+/* NFA_RW_OP_T1T_WRITE_E8,NFA_RW_OP_T1T_WRITE_NE8
+ NFA_RW_OP_T1T_WRITE_E, NFA_RW_OP_T1T_WRITE_NE params */
+typedef struct
+{
+ BOOLEAN b_erase;
+ UINT8 block_number;
+ UINT8 index;
+ UINT8 p_block_data[8];
+} tNFA_RW_OP_PARAMS_T1T_WRITE;
+
+/* NFA_RW_OP_T2T_READ params */
+typedef struct
+{
+ UINT8 block_number;
+} tNFA_RW_OP_PARAMS_T2T_READ;
+
+/* NFA_RW_OP_T2T_WRITE params */
+typedef struct
+{
+ UINT8 block_number;
+ UINT8 p_block_data[4];
+} tNFA_RW_OP_PARAMS_T2T_WRITE;
+
+/* NFA_RW_OP_T2T_SECTOR_SELECT params */
+typedef struct
+{
+ UINT8 sector_number;
+} tNFA_RW_OP_PARAMS_T2T_SECTOR_SELECT;
+
+/* NFA_RW_OP_T3T_READ params */
+typedef struct
+{
+ UINT8 num_blocks;
+ tNFA_T3T_BLOCK_DESC *p_block_desc;
+} tNFA_RW_OP_PARAMS_T3T_READ;
+
+/* NFA_RW_OP_T3T_WRITE params */
+typedef struct
+{
+ UINT8 num_blocks;
+ tNFA_T3T_BLOCK_DESC *p_block_desc;
+ UINT8 *p_block_data;
+} tNFA_RW_OP_PARAMS_T3T_WRITE;
+
+/* NFA_RW_OP_I93_XXX params */
+typedef struct
+{
+ BOOLEAN uid_present;
+ UINT8 uid[I93_UID_BYTE_LEN];
+ BOOLEAN afi_present;
+ UINT8 afi;
+ UINT8 dsfid;
+ UINT16 first_block_number;
+ UINT16 number_blocks;
+ UINT8 *p_data;
+} tNFA_RW_OP_PARAMS_I93_CMD;
+
+/* Union of params for all reader/writer operations */
+typedef union
+{
+ /* params for NFA_RW_OP_WRITE_NDEF */
+ tNFA_RW_OP_PARAMS_WRITE_NDEF write_ndef;
+
+ /* params for NFA_RW_OP_SEND_RAW_FRAME */
+ tNFA_RW_OP_PARAMS_SEND_RAW_FRAME send_raw_frame;
+
+ /* params for NFA_RW_OP_SET_TAG_RO */
+ tNFA_RW_OP_PARAMS_CONFIG_READ_ONLY set_readonly;
+
+ /* params for NFA_RW_OP_T2T_READ and NFA_RW_OP_T1T_WRITE */
+ tNFA_RW_OP_PARAMS_T1T_READ t1t_read;
+ tNFA_RW_OP_PARAMS_T1T_WRITE t1t_write;
+
+ /* params for NFA_RW_OP_T2T_READ,NFA_RW_OP_T2T_WRITE and NFA_RW_OP_T2T_SECTOR_SELECT */
+ tNFA_RW_OP_PARAMS_T2T_READ t2t_read;
+ tNFA_RW_OP_PARAMS_T2T_WRITE t2t_write;
+ tNFA_RW_OP_PARAMS_T2T_SECTOR_SELECT t2t_sector_select;
+
+ /* params for NFA_RW_OP_T3T_READ and NFA_RW_OP_T3T_WRITE */
+ tNFA_RW_OP_PARAMS_T3T_READ t3t_read;
+ tNFA_RW_OP_PARAMS_T3T_WRITE t3t_write;
+
+ /* params for 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
+{
+ BT_HDR hdr;
+ tNFA_RW_OP op; /* NFA RW operation */
+ tNFA_RW_OP_PARAMS params;
+} tNFA_RW_OPERATION;
+
+/* data type for NFA_RW_ACTIVATE_NTF */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFC_ACTIVATE_DEVT *p_activate_params; /* Data from NFC_ACTIVATE_DEVT */
+ BOOLEAN excl_rf_not_active; /* TRUE if not in exclusive RF mode */
+} tNFA_RW_ACTIVATE_NTF;
+
+/* union of all data types */
+typedef union
+{
+ /* GKI event buffer header */
+ BT_HDR hdr;
+ tNFA_RW_OPERATION op_req;
+ tNFA_RW_ACTIVATE_NTF activate_ntf;
+} tNFA_RW_MSG;
+
+/* NDEF detection status */
+enum
+{
+ NFA_RW_NDEF_ST_UNKNOWN =0, /* NDEF detection not performed yet */
+ NFA_RW_NDEF_ST_TRUE, /* Tag is NDEF */
+ NFA_RW_NDEF_ST_FALSE /* Tag is not NDEF */
+};
+typedef UINT8 tNFA_RW_NDEF_ST;
+
+/* flags for RW control block */
+#define NFA_RW_FL_NOT_EXCL_RF_MODE 0x01 /* Activation while not in exclusive RF mode */
+#define NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY 0x02 /* Waiting for response from tag for auto-presence check */
+#define NFA_RW_FL_TAG_IS_READONLY 0x04 /* Read only tag */
+#define NFA_RW_FL_ACTIVATION_NTF_PENDING 0x08 /* Busy retrieving additional tag information */
+#define NFA_RW_FL_API_BUSY 0x10 /* Tag operation is in progress */
+#define NFA_RW_FL_ACTIVATED 0x20 /* Tag is been activated */
+#define NFA_RW_FL_NDEF_OK 0x40 /* NDEF DETECTed OK */
+
+/* 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 pa_sel_res;
+ tNFC_RF_TECH_N_MODE activated_tech_mode; /* activated technology and mode */
+
+ BOOLEAN b_hard_lock;
+
+ tNFA_RW_MSG *p_buffer_rw_msg; /* Buffer to hold incoming cmd while reading tag id */
+
+ /* TLV info */
+ tNFA_RW_TLV_ST tlv_st; /* TLV detection status */
+
+ /* NDEF info */
+ tNFA_RW_NDEF_ST ndef_st; /* NDEF detection status */
+ UINT32 ndef_max_size; /* max number of bytes available for NDEF data */
+ UINT32 ndef_cur_size; /* current size of stored NDEF data (in bytes) */
+ UINT8 *p_ndef_buf;
+ UINT32 ndef_rd_offset; /* current read-offset of incoming NDEF data */
+
+ /* Current NDEF Write info */
+ UINT8 *p_ndef_wr_buf; /* Pointer to NDEF data being written */
+ UINT32 ndef_wr_len; /* Length of NDEF data being written */
+
+ /* 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 */
+ BOOLEAN skip_dyn_locks; /* To skip reading dynamic locks during NDEF Detect */
+
+ /* Flags (see defintions for NFA_RW_FL_* ) */
+ UINT8 flags;
+
+ /* ISO 15693 tag memory information */
+ UINT16 i93_afi_location;
+ UINT8 i93_dsfid;
+ UINT8 i93_block_size;
+ UINT16 i93_num_block;
+ UINT8 i93_uid[I93_UID_BYTE_LEN];
+} tNFA_RW_CB;
+extern tNFA_RW_CB nfa_rw_cb;
+
+
+
+/* type definition for action functions */
+typedef BOOLEAN (*tNFA_RW_ACTION) (tNFA_RW_MSG *p_data);
+
+/* Internal nfa_rw function prototypes */
+extern void nfa_rw_stop_presence_check_timer (void);
+
+/* Action function prototypes */
+extern BOOLEAN nfa_rw_handle_op_req (tNFA_RW_MSG *p_data);
+extern BOOLEAN nfa_rw_activate_ntf (tNFA_RW_MSG *p_data);
+extern BOOLEAN nfa_rw_deactivate_ntf (tNFA_RW_MSG *p_data);
+extern BOOLEAN nfa_rw_presence_check_tick (tNFA_RW_MSG *p_data);
+extern BOOLEAN 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 BOOLEAN nfa_rw_handle_event (BT_HDR *p_msg);
+
+extern void nfa_rw_free_ndef_rx_buf (void);
+extern void nfa_rw_sys_disable (void);
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+extern void nfa_rw_set_cback(tNFC_DISCOVER *p_data);
+extern void nfa_rw_update_pupi_id(UINT8 *p, UINT8 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..7ca5c54
--- /dev/null
+++ b/src/nfa/int/nfa_snep_int.h
@@ -0,0 +1,293 @@
+/******************************************************************************
+ *
+ * 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 (defined (NFA_SNEP_INCLUDED) && (NFA_SNEP_INCLUDED==TRUE))
+#include "llcp_api.h"
+#include "nfa_snep_api.h"
+
+/*****************************************************************************
+** Constants and data types
+*****************************************************************************/
+#define NFA_SNEP_DEFAULT_SERVER_SAP 0x04 /* SNEP default server SAP */
+#define NFA_SNEP_HEADER_SIZE 6 /* SNEP header size */
+#define NFA_SNEP_ACCEPT_LEN_SIZE 4 /* SNEP Acceptable Length size */
+#define NFA_SNEP_CLIENT_TIMEOUT 1000 /* ms, waiting for response */
+
+/* NFA SNEP events */
+enum
+{
+ NFA_SNEP_API_START_DEFAULT_SERVER_EVT = NFA_SYS_EVT_START (NFA_ID_SNEP),
+ NFA_SNEP_API_STOP_DEFAULT_SERVER_EVT,
+ NFA_SNEP_API_REG_SERVER_EVT,
+ NFA_SNEP_API_REG_CLIENT_EVT,
+ NFA_SNEP_API_DEREG_EVT,
+ NFA_SNEP_API_CONNECT_EVT,
+ NFA_SNEP_API_GET_REQ_EVT,
+ NFA_SNEP_API_PUT_REQ_EVT,
+ NFA_SNEP_API_GET_RESP_EVT,
+ NFA_SNEP_API_PUT_RESP_EVT,
+ NFA_SNEP_API_DISCONNECT_EVT,
+
+ NFA_SNEP_LAST_EVT
+};
+
+/* data type for NFA_SNEP_API_START_DEFAULT_SERVER_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_SNEP_CBACK *p_cback;
+} tNFA_SNEP_API_START_DEFAULT_SERVER;
+
+/* data type for NFA_SNEP_API_STOP_DEFAULT_SERVER_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_SNEP_CBACK *p_cback;
+} tNFA_SNEP_API_STOP_DEFAULT_SERVER;
+
+/* data type for NFA_SNEP_API_REG_SERVER_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ UINT8 server_sap;
+ char service_name[LLCP_MAX_SN_LEN + 1];
+ tNFA_SNEP_CBACK *p_cback;
+} tNFA_SNEP_API_REG_SERVER;
+
+/* data type for NFA_SNEP_API_REG_CLIENT_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_SNEP_CBACK *p_cback;
+} tNFA_SNEP_API_REG_CLIENT;
+
+/* data type for NFA_SNEP_API_DEREG_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE reg_handle; /* handle for registered server/client */
+} tNFA_SNEP_API_DEREG;
+
+/* data type for NFA_SNEP_API_CONNECT_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE client_handle; /* handle for client */
+ char service_name[LLCP_MAX_SN_LEN + 1];
+} tNFA_SNEP_API_CONNECT;
+
+/* data type for NFA_SNEP_API_GET_REQ_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE conn_handle; /* handle for data link connection */
+ UINT32 buff_length; /* length of buffer; acceptable length */
+ UINT32 ndef_length; /* length of current NDEF message */
+ UINT8 *p_ndef_buff; /* buffer for NDEF message */
+} tNFA_SNEP_API_GET_REQ;
+
+/* data type for NFA_SNEP_API_PUT_REQ_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE conn_handle; /* handle for data link connection */
+ UINT32 ndef_length; /* length of NDEF message */
+ UINT8 *p_ndef_buff; /* buffer for NDEF message */
+} tNFA_SNEP_API_PUT_REQ;
+
+/* data type for NFA_SNEP_API_GET_RESP_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE conn_handle; /* handle for data link connection */
+ tNFA_SNEP_RESP_CODE resp_code; /* response code */
+ UINT32 ndef_length; /* length of NDEF message */
+ UINT8 *p_ndef_buff; /* buffer for NDEF message */
+} tNFA_SNEP_API_GET_RESP;
+
+/* data type for NFA_SNEP_API_PUT_RESP_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE conn_handle; /* handle for data link connection */
+ tNFA_SNEP_RESP_CODE resp_code; /* response code */
+} tNFA_SNEP_API_PUT_RESP;
+
+/* data type for NFA_SNEP_API_DISCONNECT_EVT */
+typedef struct
+{
+ BT_HDR hdr;
+ tNFA_HANDLE conn_handle; /* response code */
+ BOOLEAN flush; /* TRUE if discard pending data */
+} tNFA_SNEP_API_DISCONNECT;
+
+/* union of all event data types */
+typedef union
+{
+ BT_HDR hdr;
+ tNFA_SNEP_API_START_DEFAULT_SERVER api_start_default_server; /* NFA_SNEP_API_START_DEFAULT_SERVER_EVT */
+ tNFA_SNEP_API_STOP_DEFAULT_SERVER api_stop_default_server; /* NFA_SNEP_API_STOP_DEFAULT_SERVER_EVT */
+ tNFA_SNEP_API_REG_SERVER api_reg_server; /* NFA_SNEP_API_REG_SERVER_EVT */
+ tNFA_SNEP_API_REG_CLIENT api_reg_client; /* NFA_SNEP_API_REG_CLIENT_EVT */
+ tNFA_SNEP_API_DEREG api_dereg; /* NFA_SNEP_API_DEREG_EVT */
+ tNFA_SNEP_API_CONNECT api_connect; /* NFA_SNEP_API_CONNECT_EVT */
+ tNFA_SNEP_API_GET_REQ api_get_req; /* NFA_SNEP_API_GET_REQ_EVT */
+ tNFA_SNEP_API_PUT_REQ api_put_req; /* NFA_SNEP_API_PUT_REQ_EVT */
+ tNFA_SNEP_API_GET_RESP api_get_resp; /* NFA_SNEP_API_GET_RESP_EVT */
+ tNFA_SNEP_API_PUT_RESP api_put_resp; /* NFA_SNEP_API_PUT_RESP_EVT */
+ tNFA_SNEP_API_DISCONNECT api_disc; /* NFA_SNEP_API_DISCONNECT_EVT */
+} tNFA_SNEP_MSG;
+
+/*****************************************************************************
+** control block
+*****************************************************************************/
+
+/* NFA SNEP service control block */
+#define NFA_SNEP_FLAG_ANY 0x00 /* ignore flags while searching */
+#define NFA_SNEP_FLAG_SERVER 0x01 /* server */
+#define NFA_SNEP_FLAG_CLIENT 0x02 /* client */
+#define NFA_SNEP_FLAG_CONNECTING 0x04 /* waiting for connection confirm */
+#define NFA_SNEP_FLAG_CONNECTED 0x08 /* data link connected */
+#define NFA_SNEP_FLAG_W4_RESP_CONTINUE 0x10 /* Waiting for continue response */
+#define NFA_SNEP_FLAG_W4_REQ_CONTINUE 0x20 /* Waiting for continue request */
+
+typedef struct
+{
+ UINT8 local_sap; /* local SAP of service */
+ UINT8 remote_sap; /* local SAP of service */
+ UINT8 flags; /* internal flags */
+ tNFA_SNEP_CBACK *p_cback; /* callback for event */
+ TIMER_LIST_ENT timer; /* timer for client */
+
+ UINT16 tx_miu; /* adjusted MIU for throughput */
+ BOOLEAN congest; /* TRUE if data link connection is congested */
+ BOOLEAN rx_fragments; /* TRUE if waiting more fragments */
+
+ UINT8 tx_code; /* transmitted code in request/response */
+ UINT8 rx_code; /* received code in request/response */
+
+ UINT32 acceptable_length;
+ UINT32 buff_length; /* size of buffer for NDEF message */
+ UINT32 ndef_length; /* length of NDEF message */
+ UINT32 cur_length; /* currently sent or received length */
+ UINT8 *p_ndef_buff; /* NDEF message buffer */
+} tNFA_SNEP_CONN;
+
+/*
+** NFA SNEP control block
+*/
+typedef struct
+{
+ tNFA_SNEP_CONN conn[NFA_SNEP_MAX_CONN];
+ BOOLEAN listen_enabled;
+ BOOLEAN is_dta_mode;
+ UINT8 trace_level;
+} tNFA_SNEP_CB;
+
+/*
+** NFA SNEP default server control block
+*/
+
+/* multiple data link connections for default server */
+typedef struct
+{
+ tNFA_HANDLE conn_handle; /* connection handle for default server */
+ UINT8 *p_rx_ndef; /* buffer to receive NDEF */
+} tNFA_SNEP_DEFAULT_CONN;
+
+#define NFA_SNEP_DEFAULT_MAX_CONN 3
+
+typedef struct
+{
+
+ tNFA_HANDLE server_handle; /* registered handle for default server */
+ tNFA_SNEP_DEFAULT_CONN conn[NFA_SNEP_DEFAULT_MAX_CONN];/* connections for default server */
+
+} tNFA_SNEP_DEFAULT_CB;
+
+/*****************************************************************************
+** External variables
+*****************************************************************************/
+
+/* NFA SNEP control block */
+#if NFA_DYNAMIC_MEMORY == FALSE
+extern tNFA_SNEP_CB nfa_snep_cb;
+#else
+extern tNFA_SNEP_CB *nfa_snep_cb_ptr;
+#define nfa_snep_cb (*nfa_snep_cb_ptr)
+#endif
+
+/* NFA SNEP default server control block */
+#if NFA_DYNAMIC_MEMORY == FALSE
+extern tNFA_SNEP_DEFAULT_CB nfa_snep_default_cb;
+#else
+extern tNFA_SNEP_DEFAULT_CB *nfa_snep_default_cb_ptr;
+#define nfa_snep_default_cb (*nfa_snep_default_cb_ptr)
+#endif
+
+/*****************************************************************************
+** External functions
+*****************************************************************************/
+/*
+** nfa_snep_main.c
+*/
+void nfa_snep_init (BOOLEAN is_dta_mode);
+/*
+** nfa_snep_default.c
+*/
+void nfa_snep_default_init (void);
+BOOLEAN nfa_snep_start_default_server (tNFA_SNEP_MSG *p_msg);
+BOOLEAN nfa_snep_stop_default_server (tNFA_SNEP_MSG *p_msg);
+/*
+** nfa_snep_srv.c
+*/
+UINT8 nfa_snep_allocate_cb (void);
+void nfa_snep_deallocate_cb (UINT8 xx);
+void nfa_snep_send_msg (UINT8 opcode, UINT8 dlink);
+
+void nfa_snep_llcp_cback (tLLCP_SAP_CBACK_DATA *p_data);
+void nfa_snep_proc_llcp_data_ind (tLLCP_SAP_CBACK_DATA *p_data);
+void nfa_snep_proc_llcp_connect_ind (tLLCP_SAP_CBACK_DATA *p_data);
+void nfa_snep_proc_llcp_connect_resp (tLLCP_SAP_CBACK_DATA *p_data);
+void nfa_snep_proc_llcp_disconnect_ind (tLLCP_SAP_CBACK_DATA *p_data);
+void nfa_snep_proc_llcp_disconnect_resp (tLLCP_SAP_CBACK_DATA *p_data);
+void nfa_snep_proc_llcp_congest (tLLCP_SAP_CBACK_DATA *p_data);
+void nfa_snep_proc_llcp_link_status (tLLCP_SAP_CBACK_DATA *p_data);
+void nfa_snep_proc_llcp_tx_complete (tLLCP_SAP_CBACK_DATA *p_data);
+
+BOOLEAN nfa_snep_reg_server (tNFA_SNEP_MSG *p_msg);
+BOOLEAN nfa_snep_reg_client (tNFA_SNEP_MSG *p_msg);
+BOOLEAN nfa_snep_dereg (tNFA_SNEP_MSG *p_msg);
+BOOLEAN nfa_snep_connect (tNFA_SNEP_MSG *p_msg);
+BOOLEAN nfa_snep_put_resp (tNFA_SNEP_MSG *p_msg);
+BOOLEAN nfa_snep_get_resp (tNFA_SNEP_MSG *p_msg);
+BOOLEAN nfa_snep_put_req (tNFA_SNEP_MSG *p_msg);
+BOOLEAN nfa_snep_get_req (tNFA_SNEP_MSG *p_msg);
+BOOLEAN nfa_snep_disconnect (tNFA_SNEP_MSG *p_msg);
+
+#endif /* (defined (NFA_SNEP_INCLUDED) && (NFA_SNEP_INCLUDED==TRUE)) */
+#endif /* NFA_SNEP_INT_H */
diff --git a/src/nfa/int/nfa_sys.h b/src/nfa/int/nfa_sys.h
new file mode 100644
index 0000000..3d2eeb9
--- /dev/null
+++ b/src/nfa/int/nfa_sys.h
@@ -0,0 +1,138 @@
+/******************************************************************************
+ *
+ * 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_CHO, /* Connection Handover sub-system */
+ NFA_ID_SNEP, /* SNEP sub-system */
+ NFA_ID_RW, /* Reader/writer sub-system */
+ NFA_ID_CE, /* Card-emulation sub-system */
+ NFA_ID_HCI, /* Host controller interface sub-system*/
+#if (NFA_DTA_INCLUDED == TRUE)
+ NFA_ID_DTA, /* Device Test Application sub-system */
+#endif
+ NFA_ID_MAX
+};
+typedef UINT8 tNFA_SYS_ID;
+
+/* enable function type */
+typedef void (tNFA_SYS_ENABLE) (void);
+
+/* event handler function type */
+typedef BOOLEAN (tNFA_SYS_EVT_HDLR) (BT_HDR *p_msg);
+
+/* disable function type */
+typedef void (tNFA_SYS_DISABLE) (void);
+
+/* function type for processing the change of NFCC power mode */
+typedef void (tNFA_SYS_PROC_NFCC_PWR_MODE) (UINT8 nfcc_power_mode);
+
+typedef void (tNFA_SYS_CBACK) (void);
+typedef void (tNFA_SYS_ENABLE_CBACK) (void);
+typedef void (tNFA_SYS_PROC_NFCC_PWR_MODE_CMPL) (void);
+
+/* registration structure */
+typedef struct
+{
+ tNFA_SYS_ENABLE *enable;
+ tNFA_SYS_EVT_HDLR *evt_hdlr;
+ tNFA_SYS_DISABLE *disable;
+ tNFA_SYS_PROC_NFCC_PWR_MODE *proc_nfcc_pwr_mode;
+} tNFA_SYS_REG;
+
+/* system manager configuration structure */
+typedef struct
+{
+ UINT16 mbox_evt; /* GKI mailbox event */
+ UINT8 mbox; /* GKI mailbox id */
+ UINT8 timer; /* GKI timer id */
+ UINT8 trace_level; /* initial trace level */
+} tNFA_SYS_CFG;
+
+
+/*****************************************************************************
+** Global data
+*****************************************************************************/
+
+/*****************************************************************************
+** Macros
+*****************************************************************************/
+
+/* Calculate start of event enumeration; id is top 8 bits of event */
+#define NFA_SYS_EVT_START(id) ((id) << 8)
+
+
+/*****************************************************************************
+** Function declarations
+*****************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+NFC_API extern void nfa_sys_init (void);
+NFC_API extern void nfa_sys_event (BT_HDR *p_msg);
+NFC_API extern void nfa_sys_timer_update (void);
+NFC_API extern void nfa_sys_disable_timers (void);
+NFC_API extern void nfa_sys_set_trace_level (UINT8 level);
+
+extern void nfa_sys_register (UINT8 id, const tNFA_SYS_REG *p_reg);
+extern void nfa_sys_deregister (UINT8 id);
+extern void nfa_sys_check_disabled (void);
+extern BOOLEAN nfa_sys_is_register (UINT8 id);
+extern void nfa_sys_disable_subsystems (BOOLEAN graceful);
+extern void nfa_sys_enable_subsystems (void);
+
+extern BOOLEAN nfa_sys_is_graceful_disable (void);
+extern void nfa_sys_sendmsg (void *p_msg);
+extern void nfa_sys_start_timer (TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout);
+extern void nfa_sys_stop_timer (TIMER_LIST_ENT *p_tle);
+
+extern void nfa_sys_cback_reg_enable_complete (tNFA_SYS_ENABLE_CBACK *p_cback);
+extern void nfa_sys_cback_notify_enable_complete (UINT8 id);
+
+extern void nfa_sys_notify_nfcc_power_mode (UINT8 nfcc_power_mode);
+extern void nfa_sys_cback_reg_nfcc_power_mode_proc_complete (tNFA_SYS_PROC_NFCC_PWR_MODE_CMPL *p_cback);
+extern void nfa_sys_cback_notify_nfcc_power_mode_proc_complete (UINT8 id);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFA_SYS_H */
diff --git a/src/nfa/int/nfa_sys_int.h b/src/nfa/int/nfa_sys_int.h
new file mode 100644
index 0000000..27d0539
--- /dev/null
+++ b/src/nfa/int/nfa_sys_int.h
@@ -0,0 +1,82 @@
+/******************************************************************************
+ *
+ * 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 flags; /* nfa_sys flags (must be first element of structure) */
+ tNFA_SYS_REG *reg[NFA_ID_MAX]; /* registration structures */
+ BOOLEAN is_reg[NFA_ID_MAX]; /* registration structures */
+ tPTIM_CB ptim_cb; /* protocol timer list */
+ tNFA_SYS_ENABLE_CBACK *p_enable_cback;
+ UINT16 enable_cplt_flags;
+ UINT16 enable_cplt_mask;
+
+ tNFA_SYS_PROC_NFCC_PWR_MODE_CMPL *p_proc_nfcc_pwr_mode_cmpl_cback;
+ UINT16 proc_nfcc_pwr_mode_cplt_flags;
+ UINT16 proc_nfcc_pwr_mode_cplt_mask;
+
+ BOOLEAN graceful_disable; /* TRUE if NFA_Disable () is called with TRUE */
+ BOOLEAN timers_disabled; /* TRUE if sys timers disabled */
+ UINT8 trace_level; /* Trace level */
+} tNFA_SYS_CB;
+
+
+
+/*****************************************************************************
+** Global variables
+*****************************************************************************/
+
+/* system manager control block */
+#if NFA_DYNAMIC_MEMORY == FALSE
+extern tNFA_SYS_CB nfa_sys_cb;
+#else
+extern tNFA_SYS_CB *nfa_sys_cb_ptr;
+#define nfa_sys_cb (*nfa_sys_cb_ptr)
+#endif
+
+
+/* system manager configuration structure */
+extern tNFA_SYS_CFG *p_nfa_sys_cfg;
+
+BOOLEAN nfa_sys_sm_execute (BT_HDR *p_msg);
+
+#endif /* NFA_SYS_INT_H */
diff --git a/src/nfa/int/nfa_sys_ptim.h b/src/nfa/int/nfa_sys_ptim.h
new file mode 100644
index 0000000..45484aa
--- /dev/null
+++ b/src/nfa/int/nfa_sys_ptim.h
@@ -0,0 +1,100 @@
+/******************************************************************************
+ *
+ * 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 period; /* Timer period in milliseconds */
+ UINT32 last_gki_ticks; /* GKI ticks since last time update called */
+ UINT8 timer_id; /* GKI timer id */
+} tPTIM_CB;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*****************************************************************************
+** Function Declarations
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function nfa_sys_ptim_init
+**
+** Description Initialize a protocol timer service control block.
+**
+** Returns void
+**
+*******************************************************************************/
+extern void nfa_sys_ptim_init (tPTIM_CB *p_cb, UINT16 period, UINT8 timer_id);
+
+/*******************************************************************************
+**
+** Function nfa_sys_ptim_timer_update
+**
+** Description Update the protocol timer list and handle expired timers.
+**
+** Returns void
+**
+*******************************************************************************/
+extern void nfa_sys_ptim_timer_update (tPTIM_CB *p_cb);
+
+/*******************************************************************************
+**
+** Function nfa_sys_ptim_start_timer
+**
+** Description Start a protocol timer for the specified amount
+** of time in milliseconds.
+**
+** Returns void
+**
+*******************************************************************************/
+extern void nfa_sys_ptim_start_timer (tPTIM_CB *p_cb, TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout);
+
+/*******************************************************************************
+**
+** Function nfa_sys_ptim_stop_timer
+**
+** Description Stop a protocol timer.
+**
+** Returns void
+**
+*******************************************************************************/
+extern void nfa_sys_ptim_stop_timer (tPTIM_CB *p_cb, TIMER_LIST_ENT *p_tle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFA_SYS_PTIM_H */
diff --git a/src/nfa/p2p/nfa_p2p_act.c b/src/nfa/p2p/nfa_p2p_act.c
new file mode 100644
index 0000000..f8817d3
--- /dev/null
+++ b/src/nfa/p2p/nfa_p2p_act.c
@@ -0,0 +1,1237 @@
+/******************************************************************************
+ *
+ * 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
+**
+*******************************************************************************/
+static UINT8 nfa_p2p_allocate_conn_cb (UINT8 local_sap)
+{
+ UINT8 xx;
+
+ for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++)
+ {
+ if (nfa_p2p_cb.conn_cb[xx].flags == 0)
+ {
+ nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_IN_USE;
+ nfa_p2p_cb.conn_cb[xx].local_sap = local_sap;
+
+ return (xx);
+ }
+ }
+
+ P2P_TRACE_ERROR0 ("nfa_p2p_allocate_conn_cb (): No resource");
+
+ return LLCP_MAX_DATA_LINK;
+}
+
+/*******************************************************************************
+**
+** Function nfa_p2p_deallocate_conn_cb
+**
+** Description Deallocate data link connection control block
+**
+**
+** Returns void
+**
+*******************************************************************************/
+static void nfa_p2p_deallocate_conn_cb (UINT8 xx)
+{
+ if (xx < LLCP_MAX_DATA_LINK)
+ {
+ nfa_p2p_cb.conn_cb[xx].flags = 0;
+ }
+ else
+ {
+ P2P_TRACE_ERROR1 ("nfa_p2p_deallocate_conn_cb (): Invalid index (%d)", xx);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_p2p_find_conn_cb
+**
+** Description Find data link connection control block by local/remote SAP
+**
+**
+** Returns UINT8
+**
+*******************************************************************************/
+static UINT8 nfa_p2p_find_conn_cb (UINT8 local_sap, UINT8 remote_sap)
+{
+ UINT8 xx;
+
+ for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++)
+ {
+ if ( (nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_IN_USE)
+ &&(nfa_p2p_cb.conn_cb[xx].local_sap == local_sap)
+ &&(nfa_p2p_cb.conn_cb[xx].remote_sap == remote_sap) )
+ {
+ return (xx);
+ }
+ }
+
+ return (LLCP_MAX_DATA_LINK);
+}
+
+/*******************************************************************************
+**
+** Function nfa_p2p_llcp_cback
+**
+** Description Processing SAP callback events from LLCP
+**
+**
+** Returns None
+**
+*******************************************************************************/
+static void nfa_p2p_llcp_cback (tLLCP_SAP_CBACK_DATA *p_data)
+{
+ P2P_TRACE_DEBUG2 ("nfa_p2p_llcp_cback (): event:0x%02X, local_sap:0x%02X", p_data->hdr.event, p_data->hdr.local_sap);
+
+ switch (p_data->hdr.event)
+ {
+ case LLCP_SAP_EVT_DATA_IND:
+ nfa_p2p_proc_llcp_data_ind (p_data);
+ break;
+
+ case LLCP_SAP_EVT_CONNECT_IND:
+ nfa_p2p_proc_llcp_connect_ind (p_data);
+ break;
+
+ case LLCP_SAP_EVT_CONNECT_RESP:
+ nfa_p2p_proc_llcp_connect_resp (p_data);
+ break;
+
+ case LLCP_SAP_EVT_DISCONNECT_IND:
+ nfa_p2p_proc_llcp_disconnect_ind (p_data);
+ break;
+
+ case LLCP_SAP_EVT_DISCONNECT_RESP:
+ nfa_p2p_proc_llcp_disconnect_resp (p_data);
+ break;
+
+ case LLCP_SAP_EVT_CONGEST:
+ nfa_p2p_proc_llcp_congestion (p_data);
+ break;
+
+ case LLCP_SAP_EVT_LINK_STATUS:
+ nfa_p2p_proc_llcp_link_status (p_data);
+ break;
+
+ default:
+ P2P_TRACE_ERROR1 ("nfa_p2p_llcp_cback (): Unknown event:0x%02X", p_data->hdr.event);
+ return;
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_p2p_sdp_cback
+**
+** Description Process SDP callback event from LLCP
+**
+**
+** Returns None
+**
+*******************************************************************************/
+void nfa_p2p_sdp_cback (UINT8 tid, UINT8 remote_sap)
+{
+ UINT8 local_sap;
+ UINT8 xx;
+ tNFA_P2P_EVT_DATA evt_data;
+
+ P2P_TRACE_DEBUG2 ("nfa_p2p_sdp_cback (): tid:0x%02X, remote_sap:0x%02X", tid, remote_sap);
+
+ /* search for callback function to process */
+ for (xx = 0; xx < LLCP_MAX_SDP_TRANSAC; xx++)
+ {
+ if ( (nfa_p2p_cb.sdp_cb[xx].local_sap != LLCP_INVALID_SAP)
+ &&(nfa_p2p_cb.sdp_cb[xx].tid == tid) )
+ {
+ local_sap = nfa_p2p_cb.sdp_cb[xx].local_sap;
+
+ evt_data.sdp.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+ evt_data.sdp.remote_sap = remote_sap;
+ nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_SDP_EVT, &evt_data);
+
+ nfa_p2p_cb.sdp_cb[xx].local_sap = LLCP_INVALID_SAP;
+ break;
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_p2p_start_sdp
+**
+** Description Initiate SDP
+**
+**
+** Returns TRUE if success
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_start_sdp (char *p_service_name, UINT8 local_sap)
+{
+ int xx;
+
+ P2P_TRACE_DEBUG1 ("nfa_p2p_start_sdp (): SN:<%s>", p_service_name);
+
+ /* search for empty slot */
+ for (xx = 0; xx < LLCP_MAX_SDP_TRANSAC; xx++)
+ {
+ if (nfa_p2p_cb.sdp_cb[xx].local_sap == LLCP_INVALID_SAP)
+ {
+ if (LLCP_DiscoverService (p_service_name,
+ nfa_p2p_sdp_cback,
+ &(nfa_p2p_cb.sdp_cb[xx].tid)) == LLCP_STATUS_SUCCESS)
+ {
+ nfa_p2p_cb.sdp_cb[xx].local_sap = local_sap;
+ return TRUE;
+ }
+ else
+ {
+ /* failure of SDP */
+ return FALSE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_p2p_proc_llcp_data_ind
+**
+** Description Processing incoming data event from LLCP
+**
+**
+** Returns None
+**
+*******************************************************************************/
+void nfa_p2p_proc_llcp_data_ind (tLLCP_SAP_CBACK_DATA *p_data)
+{
+ UINT8 local_sap, xx;
+ tNFA_P2P_EVT_DATA evt_data;
+
+ P2P_TRACE_DEBUG0 ("nfa_p2p_proc_llcp_data_ind ()");
+
+ local_sap = p_data->data_ind.local_sap;
+
+ if (nfa_p2p_cb.sap_cb[local_sap].p_cback)
+ {
+ evt_data.data.handle = 0;
+ /* if connectionless */
+ if (p_data->data_ind.link_type == NFA_P2P_LLINK_TYPE)
+ {
+ evt_data.data.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+ }
+ else
+ {
+ xx = nfa_p2p_find_conn_cb (p_data->data_ind.local_sap,
+ p_data->data_ind.remote_sap);
+
+ if (xx != LLCP_MAX_DATA_LINK)
+ {
+ evt_data.data.handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
+ }
+ }
+
+ evt_data.data.remote_sap = p_data->data_ind.remote_sap;
+ evt_data.data.link_type = p_data->data_ind.link_type;
+
+ /* notify upper layer that there are data at LLCP */
+ nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DATA_EVT, &evt_data);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_p2p_proc_llcp_connect_ind
+**
+** Description Processing connection request from peer
+**
+**
+** Returns None
+**
+*******************************************************************************/
+void nfa_p2p_proc_llcp_connect_ind (tLLCP_SAP_CBACK_DATA *p_data)
+{
+ UINT8 server_sap, local_sap;
+ tNFA_P2P_EVT_DATA evt_data;
+ UINT8 xx;
+
+ P2P_TRACE_DEBUG1 ("nfa_p2p_proc_llcp_connect_ind () server_sap:0x%x",
+ p_data->connect_ind.server_sap);
+
+ server_sap = p_data->connect_ind.server_sap;
+ local_sap = p_data->connect_ind.local_sap;
+
+ if (nfa_p2p_cb.sap_cb[server_sap].p_cback)
+ {
+ xx = nfa_p2p_allocate_conn_cb (server_sap);
+
+ if (xx != LLCP_MAX_DATA_LINK)
+ {
+ nfa_p2p_cb.conn_cb[xx].remote_sap = p_data->connect_ind.remote_sap;
+ nfa_p2p_cb.conn_cb[xx].remote_miu = p_data->connect_ind.miu;
+
+ /* peer will not receive any data */
+ if (p_data->connect_ind.rw == 0)
+ nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_REMOTE_RW_ZERO;
+
+ evt_data.conn_req.server_handle = (NFA_HANDLE_GROUP_P2P | server_sap);
+ evt_data.conn_req.conn_handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
+ evt_data.conn_req.remote_sap = p_data->connect_ind.remote_sap;
+ evt_data.conn_req.remote_miu = p_data->connect_ind.miu;
+ evt_data.conn_req.remote_rw = p_data->connect_ind.rw;
+
+ nfa_p2p_cb.sap_cb[server_sap].p_cback (NFA_P2P_CONN_REQ_EVT, &evt_data);
+ }
+ }
+ else
+ {
+ P2P_TRACE_ERROR0 ("nfa_p2p_proc_llcp_connect_ind (): Not registered");
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_p2p_proc_llcp_connect_resp
+**
+** Description Processing connection response from peer
+**
+**
+** Returns None
+**
+*******************************************************************************/
+void nfa_p2p_proc_llcp_connect_resp (tLLCP_SAP_CBACK_DATA *p_data)
+{
+ UINT8 local_sap, xx;
+ tNFA_P2P_EVT_DATA evt_data;
+
+ P2P_TRACE_DEBUG0 ("nfa_p2p_proc_llcp_connect_resp ()");
+
+ local_sap = p_data->connect_resp.local_sap;
+
+ if (nfa_p2p_cb.sap_cb[local_sap].p_cback)
+ {
+ xx = nfa_p2p_allocate_conn_cb (local_sap);
+
+ if (xx != LLCP_MAX_DATA_LINK)
+ {
+ nfa_p2p_cb.conn_cb[xx].remote_sap = p_data->connect_resp.remote_sap;
+ nfa_p2p_cb.conn_cb[xx].remote_miu = p_data->connect_resp.miu;
+
+ /* peer will not receive any data */
+ if (p_data->connect_resp.rw == 0)
+ nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_REMOTE_RW_ZERO;
+
+ evt_data.connected.client_handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+ evt_data.connected.conn_handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
+ evt_data.connected.remote_sap = p_data->connect_resp.remote_sap;
+ evt_data.connected.remote_miu = p_data->connect_resp.miu;
+ evt_data.connected.remote_rw = p_data->connect_resp.rw;
+
+ nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_CONNECTED_EVT, &evt_data);
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_p2p_proc_llcp_disconnect_ind
+**
+** Description Processing disconnection request from peer
+**
+**
+** Returns None
+**
+*******************************************************************************/
+void nfa_p2p_proc_llcp_disconnect_ind (tLLCP_SAP_CBACK_DATA *p_data)
+{
+ UINT8 local_sap, xx;
+ tNFA_P2P_EVT_DATA evt_data;
+
+ P2P_TRACE_DEBUG0 ("nfa_p2p_proc_llcp_disconnect_ind ()");
+
+ local_sap = p_data->disconnect_ind.local_sap;
+
+ if (nfa_p2p_cb.sap_cb[local_sap].p_cback)
+ {
+ xx = nfa_p2p_find_conn_cb (p_data->disconnect_ind.local_sap,
+ p_data->disconnect_ind.remote_sap);
+
+ if (xx != LLCP_MAX_DATA_LINK)
+ {
+ evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
+ evt_data.disc.reason = NFA_P2P_DISC_REASON_REMOTE_INITIATE;
+
+ nfa_p2p_deallocate_conn_cb (xx);
+
+ nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DISC_EVT, &evt_data);
+ }
+ else
+ {
+ /*
+ ** LLCP link has been deactivated before receiving CC or DM.
+ ** Return NFA_P2P_DISC_EVT to indicate failure of creating connection
+ */
+
+ evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+ evt_data.disc.reason = NFA_P2P_DISC_REASON_LLCP_DEACTIVATED;
+
+ nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DISC_EVT, &evt_data);
+
+ P2P_TRACE_ERROR0 ("nfa_p2p_proc_llcp_disconnect_ind (): Link deactivated");
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_p2p_proc_llcp_disconnect_resp
+**
+** Description Processing rejected connection from peer
+**
+**
+** Returns None
+**
+*******************************************************************************/
+void nfa_p2p_proc_llcp_disconnect_resp (tLLCP_SAP_CBACK_DATA *p_data)
+{
+ UINT8 local_sap, xx;
+ tNFA_P2P_EVT_DATA evt_data;
+
+ P2P_TRACE_DEBUG0 ("nfa_p2p_proc_llcp_disconnect_resp ()");
+
+ local_sap = p_data->disconnect_resp.local_sap;
+
+ if (nfa_p2p_cb.sap_cb[local_sap].p_cback)
+ {
+ if (p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_RESP_DISC)
+ {
+ evt_data.disc.reason = NFA_P2P_DISC_REASON_LOCAL_INITITATE;
+ }
+ else if ( (p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_APP_REJECTED)
+ ||(p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_PERM_REJECT_THIS)
+ ||(p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_PERM_REJECT_ANY)
+ ||(p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_TEMP_REJECT_THIS)
+ ||(p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_TEMP_REJECT_ANY) )
+ {
+ evt_data.disc.reason = NFA_P2P_DISC_REASON_REMOTE_REJECT;
+ }
+ else if (p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_NO_SERVICE)
+ {
+ evt_data.disc.reason = NFA_P2P_DISC_REASON_NO_SERVICE;
+ }
+ else if (p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_NO_ACTIVE_CONNECTION)
+ {
+ evt_data.disc.reason = NFA_P2P_DISC_REASON_LLCP_DEACTIVATED;
+ }
+ else
+ {
+ evt_data.disc.reason = NFA_P2P_DISC_REASON_NO_INFORMATION;
+ }
+
+ if (evt_data.disc.reason == NFA_P2P_DISC_REASON_LOCAL_INITITATE)
+ {
+ xx = nfa_p2p_find_conn_cb (p_data->disconnect_resp.local_sap,
+ p_data->disconnect_resp.remote_sap);
+
+ if (xx != LLCP_MAX_DATA_LINK)
+ {
+ evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
+
+ nfa_p2p_deallocate_conn_cb (xx);
+
+ nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DISC_EVT, &evt_data);
+ }
+ else
+ {
+ P2P_TRACE_ERROR0 ("nfa_p2p_proc_llcp_disconnect_resp (): No connection found");
+ }
+ }
+ else
+ {
+ evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+ nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DISC_EVT, &evt_data);
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_p2p_proc_llcp_congest
+**
+** Description Processing LLCP congestion event
+**
+**
+** Returns None
+**
+*******************************************************************************/
+void nfa_p2p_proc_llcp_congestion (tLLCP_SAP_CBACK_DATA *p_data)
+{
+ UINT8 local_sap, remote_sap, xx;
+ tNFA_P2P_EVT_DATA evt_data;
+
+ local_sap = p_data->congest.local_sap;
+ remote_sap = p_data->congest.remote_sap;
+
+ evt_data.congest.link_type = p_data->congest.link_type;
+ evt_data.congest.is_congested = p_data->congest.is_congested;
+
+ if (p_data->congest.is_congested)
+ {
+ P2P_TRACE_DEBUG2 ("nfa_p2p_proc_llcp_congestion () START SAP=(0x%x,0x%x)",
+ local_sap, remote_sap);
+
+ }
+ else
+ {
+ P2P_TRACE_DEBUG2 ("nfa_p2p_proc_llcp_congestion () END SAP=(0x%x,0x%x)",
+ local_sap, remote_sap);
+ }
+
+ if (nfa_p2p_cb.sap_cb[local_sap].p_cback)
+ {
+ if (evt_data.congest.link_type == NFA_P2P_LLINK_TYPE)
+ {
+ evt_data.congest.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+
+ if ( (evt_data.congest.is_congested == FALSE)
+ &&(nfa_p2p_cb.sap_cb[local_sap].flags & NFA_P2P_SAP_FLAG_LLINK_CONGESTED) )
+ {
+ nfa_p2p_cb.sap_cb[local_sap].flags &= ~NFA_P2P_SAP_FLAG_LLINK_CONGESTED;
+ nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_CONGEST_EVT, &evt_data);
+ }
+ else if ( (evt_data.congest.is_congested == TRUE)
+ &&(!(nfa_p2p_cb.sap_cb[local_sap].flags & NFA_P2P_SAP_FLAG_LLINK_CONGESTED)) )
+ {
+ /* this is overall congestion due to high usage of buffer pool */
+ nfa_p2p_cb.sap_cb[local_sap].flags |= NFA_P2P_SAP_FLAG_LLINK_CONGESTED;
+ nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_CONGEST_EVT, &evt_data);
+ }
+ }
+ else
+ {
+ xx = nfa_p2p_find_conn_cb (local_sap, remote_sap);
+
+ if (xx != LLCP_MAX_DATA_LINK)
+ {
+ evt_data.congest.handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
+
+ if ( (evt_data.congest.is_congested == FALSE)
+ &&(nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_CONGESTED) )
+ {
+ nfa_p2p_cb.conn_cb[xx].flags &= ~NFA_P2P_CONN_FLAG_CONGESTED;
+ nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_CONGEST_EVT, &evt_data);
+ }
+ else if ( (evt_data.congest.is_congested == TRUE)
+ &&(!(nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_CONGESTED)) )
+ {
+ /* this is overall congestion due to high usage of buffer pool */
+ nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_CONGESTED;
+ nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_CONGEST_EVT, &evt_data);
+ }
+ }
+ else
+ {
+ P2P_TRACE_ERROR0 ("nfa_p2p_proc_llcp_congestion (): No connection found");
+ }
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_p2p_proc_llcp_link_status
+**
+** Description Processing LLCP link status
+**
+**
+** Returns next state after processing this event
+**
+*******************************************************************************/
+void nfa_p2p_proc_llcp_link_status (tLLCP_SAP_CBACK_DATA *p_data)
+{
+ UINT8 local_sap, xx;
+ tNFA_P2P_EVT_DATA evt_data;
+
+ P2P_TRACE_DEBUG1 ("nfa_p2p_proc_llcp_link_status () is_activated:%d",
+ p_data->link_status.is_activated);
+
+ local_sap = p_data->link_status.local_sap;
+
+ if (nfa_p2p_cb.sap_cb[local_sap].p_cback)
+ {
+ if (p_data->link_status.is_activated)
+ {
+ /* only for server */
+ evt_data.activated.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+ evt_data.activated.local_link_miu = nfa_p2p_cb.local_link_miu;
+ evt_data.activated.remote_link_miu = nfa_p2p_cb.remote_link_miu;
+
+ nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_ACTIVATED_EVT, &evt_data);
+ }
+ else /* if LLCP link is deactivated */
+ {
+ for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++)
+ {
+ if ( (nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_IN_USE)
+ &&(nfa_p2p_cb.conn_cb[xx].local_sap == local_sap))
+ {
+ evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
+ evt_data.disc.reason = NFA_P2P_DISC_REASON_LLCP_DEACTIVATED;
+
+ nfa_p2p_deallocate_conn_cb (xx);
+ nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DISC_EVT, &evt_data);
+ }
+ }
+
+ /* notify deactivation and clear flags */
+ if (nfa_p2p_cb.sap_cb[local_sap].flags & NFA_P2P_SAP_FLAG_SERVER)
+ {
+ evt_data.deactivated.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+ nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DEACTIVATED_EVT, &evt_data);
+
+ nfa_p2p_cb.sap_cb[local_sap].flags = NFA_P2P_SAP_FLAG_SERVER;
+ }
+ else if (nfa_p2p_cb.sap_cb[local_sap].flags & NFA_P2P_SAP_FLAG_CLIENT)
+ {
+ evt_data.deactivated.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+ nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DEACTIVATED_EVT, &evt_data);
+
+ nfa_p2p_cb.sap_cb[local_sap].flags = NFA_P2P_SAP_FLAG_CLIENT;
+ }
+ else /* if this is not registered service */
+ {
+ nfa_p2p_cb.sap_cb[local_sap].p_cback = NULL;
+ }
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_p2p_reg_server
+**
+** Description Allocate a service as server and register to LLCP
+**
+**
+** Returns FALSE if need to keep buffer
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_reg_server (tNFA_P2P_MSG *p_msg)
+{
+ tNFA_P2P_EVT_DATA evt_data;
+ UINT8 server_sap;
+
+ P2P_TRACE_DEBUG0 ("nfa_p2p_reg_server ()");
+
+ server_sap = LLCP_RegisterServer (p_msg->api_reg_server.server_sap,
+ p_msg->api_reg_server.link_type,
+ p_msg->api_reg_server.service_name,
+ nfa_p2p_llcp_cback);
+
+ if (server_sap == LLCP_INVALID_SAP)
+ {
+ evt_data.reg_server.server_handle = NFA_HANDLE_INVALID;
+ evt_data.reg_server.server_sap = NFA_P2P_INVALID_SAP;
+ BCM_STRNCPY_S (evt_data.reg_server.service_name, sizeof (evt_data.reg_server.service_name),
+ p_msg->api_reg_server.service_name, LLCP_MAX_SN_LEN);
+ evt_data.reg_server.service_name[LLCP_MAX_SN_LEN] = 0;
+
+ p_msg->api_reg_server.p_cback (NFA_P2P_REG_SERVER_EVT, &evt_data);
+
+ return TRUE;
+ }
+
+ /* if need to update WKS in LLCP Gen bytes */
+ if (server_sap <= LLCP_UPPER_BOUND_WK_SAP)
+ {
+ nfa_p2p_enable_listening (NFA_ID_P2P, TRUE);
+ }
+ else if (!nfa_p2p_cb.is_p2p_listening)
+ {
+ nfa_p2p_enable_listening (NFA_ID_P2P, FALSE);
+ }
+
+ nfa_p2p_cb.sap_cb[server_sap].p_cback = p_msg->api_reg_server.p_cback;
+ nfa_p2p_cb.sap_cb[server_sap].flags = NFA_P2P_SAP_FLAG_SERVER;
+
+ evt_data.reg_server.server_handle = (NFA_HANDLE_GROUP_P2P | server_sap);
+ evt_data.reg_server.server_sap = server_sap;
+ BCM_STRNCPY_S (evt_data.reg_server.service_name, sizeof (evt_data.reg_server.service_name),
+ p_msg->api_reg_server.service_name, LLCP_MAX_SN_LEN);
+ evt_data.reg_server.service_name[LLCP_MAX_SN_LEN] = 0;
+
+ /* notify NFA_P2P_REG_SERVER_EVT to server */
+ nfa_p2p_cb.sap_cb[server_sap].p_cback (NFA_P2P_REG_SERVER_EVT, &evt_data);
+
+ /* if LLCP is already activated */
+ if (nfa_p2p_cb.llcp_state == NFA_P2P_LLCP_STATE_ACTIVATED)
+ {
+ evt_data.activated.handle = (NFA_HANDLE_GROUP_P2P | server_sap);
+ evt_data.activated.local_link_miu = nfa_p2p_cb.local_link_miu;
+ evt_data.activated.remote_link_miu = nfa_p2p_cb.remote_link_miu;
+
+ /* notify NFA_P2P_ACTIVATED_EVT to server */
+ nfa_p2p_cb.sap_cb[server_sap].p_cback (NFA_P2P_ACTIVATED_EVT, &evt_data);
+ }
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_p2p_reg_client
+**
+** Description Allocate a service as client and register to LLCP
+**
+**
+** Returns TRUE to deallocate buffer
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_reg_client (tNFA_P2P_MSG *p_msg)
+{
+ tNFA_P2P_EVT_DATA evt_data;
+ UINT8 local_sap;
+
+ P2P_TRACE_DEBUG0 ("nfa_p2p_reg_client ()");
+
+ local_sap = LLCP_RegisterClient (p_msg->api_reg_client.link_type,
+ nfa_p2p_llcp_cback);
+
+ if (local_sap == LLCP_INVALID_SAP)
+ {
+ evt_data.reg_client.client_handle = NFA_HANDLE_INVALID;
+ p_msg->api_reg_client.p_cback (NFA_P2P_REG_CLIENT_EVT, &evt_data);
+ return TRUE;
+ }
+
+ nfa_p2p_cb.sap_cb[local_sap].p_cback = p_msg->api_reg_client.p_cback;
+ nfa_p2p_cb.sap_cb[local_sap].flags = NFA_P2P_SAP_FLAG_CLIENT;
+
+ evt_data.reg_client.client_handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+ nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_REG_CLIENT_EVT, &evt_data);
+
+ /* if LLCP is already activated */
+ if (nfa_p2p_cb.llcp_state == NFA_P2P_LLCP_STATE_ACTIVATED)
+ {
+ evt_data.activated.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+ evt_data.activated.local_link_miu = nfa_p2p_cb.local_link_miu;
+ evt_data.activated.remote_link_miu = nfa_p2p_cb.remote_link_miu;
+
+ /* notify NFA_P2P_ACTIVATED_EVT to client */
+ nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_ACTIVATED_EVT, &evt_data);
+ }
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_p2p_dereg
+**
+** Description Deallocate a service as server or client and deregister to LLCP
+** LLCP will deallocate data link connection created by this server
+**
+** Returns TRUE to deallocate buffer
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_dereg (tNFA_P2P_MSG *p_msg)
+{
+ UINT8 local_sap, xx;
+
+ P2P_TRACE_DEBUG0 ("nfa_p2p_dereg ()");
+
+ local_sap = (UINT8) (p_msg->api_dereg.handle & NFA_HANDLE_MASK);
+
+ if (nfa_p2p_cb.sap_cb[local_sap].p_cback)
+ {
+ for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++)
+ {
+ if ( (nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_IN_USE)
+ &&(nfa_p2p_cb.conn_cb[xx].local_sap == local_sap) )
+ {
+ nfa_p2p_deallocate_conn_cb (xx);
+ }
+ }
+ }
+
+ LLCP_Deregister (local_sap);
+ nfa_p2p_cb.sap_cb[local_sap].p_cback = NULL;
+
+ if (nfa_p2p_cb.is_p2p_listening)
+ {
+ /* check if this is the last server on NFA P2P */
+ for (xx = 0; xx < NFA_P2P_NUM_SAP; xx++)
+ {
+ if ( (nfa_p2p_cb.sap_cb[xx].p_cback)
+ &&(nfa_p2p_cb.sap_cb[xx].flags & NFA_P2P_SAP_FLAG_SERVER) )
+ {
+ break;
+ }
+ }
+
+ if (xx >= NFA_P2P_NUM_SAP)
+ {
+ /* if need to update WKS in LLCP Gen bytes */
+ if (local_sap <= LLCP_UPPER_BOUND_WK_SAP)
+ nfa_p2p_disable_listening (NFA_ID_P2P, TRUE);
+ else
+ nfa_p2p_disable_listening (NFA_ID_P2P, FALSE);
+ }
+ /* if need to update WKS in LLCP Gen bytes */
+ else if (local_sap <= LLCP_UPPER_BOUND_WK_SAP)
+ {
+ nfa_p2p_enable_listening (NFA_ID_P2P, TRUE);
+ }
+ }
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_p2p_accept_connection
+**
+** Description Connection Confirm from local application
+**
+**
+** Returns TRUE to deallocate buffer
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_accept_connection (tNFA_P2P_MSG *p_msg)
+{
+ UINT8 xx;
+ tLLCP_CONNECTION_PARAMS params;
+
+ P2P_TRACE_DEBUG0 ("nfa_p2p_accept_connection ()");
+
+ xx = (UINT8) (p_msg->api_accept.conn_handle & NFA_HANDLE_MASK);
+ xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+
+ params.miu = p_msg->api_accept.miu;
+ params.rw = p_msg->api_accept.rw;
+ params.sn[0] = 0;
+
+ LLCP_ConnectCfm (nfa_p2p_cb.conn_cb[xx].local_sap, nfa_p2p_cb.conn_cb[xx].remote_sap, ¶ms);
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_p2p_reject_connection
+**
+** Description Reject connection by local application
+**
+**
+** Returns TRUE to deallocate buffer
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_reject_connection (tNFA_P2P_MSG *p_msg)
+{
+ UINT8 xx;
+
+ P2P_TRACE_DEBUG0 ("nfa_p2p_reject_connection ()");
+
+ xx = (UINT8) (p_msg->api_reject.conn_handle & NFA_HANDLE_MASK);
+ xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+
+ LLCP_ConnectReject (nfa_p2p_cb.conn_cb[xx].local_sap, nfa_p2p_cb.conn_cb[xx].remote_sap,
+ LLCP_SAP_DM_REASON_APP_REJECTED);
+
+ /* no need to deregister service on LLCP */
+ nfa_p2p_deallocate_conn_cb (xx);
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_p2p_disconnect
+**
+** Description Disconnect data link connection by local application
+**
+**
+** Returns TRUE to deallocate buffer
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_disconnect (tNFA_P2P_MSG *p_msg)
+{
+ UINT8 local_sap, xx;
+ tLLCP_STATUS status;
+ tNFA_P2P_EVT_DATA evt_data;
+
+ P2P_TRACE_DEBUG0 ("nfa_p2p_disconnect ()");
+
+ xx = (UINT8) (p_msg->api_disconnect.conn_handle & NFA_HANDLE_MASK);
+
+ /* if this is for data link connection */
+ if (xx & NFA_P2P_HANDLE_FLAG_CONN)
+ {
+ xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+
+ status = LLCP_DisconnectReq (nfa_p2p_cb.conn_cb[xx].local_sap, nfa_p2p_cb.conn_cb[xx].remote_sap,
+ p_msg->api_disconnect.flush);
+
+ if (status == LLCP_STATUS_SUCCESS)
+ {
+ /* wait for disconnect response if successful */
+ return TRUE;
+ }
+ else
+ {
+ /*
+ ** while we are waiting for connect confirm,
+ ** we cannot sent DISC because we don't know DSAP yet
+ */
+ local_sap = nfa_p2p_cb.conn_cb[xx].local_sap;
+
+ if (nfa_p2p_cb.sap_cb[local_sap].p_cback)
+ {
+ evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
+ evt_data.disc.reason = NFA_P2P_DISC_REASON_LOCAL_INITITATE;
+
+ nfa_p2p_deallocate_conn_cb (xx);
+ nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DISC_EVT, &evt_data);
+ }
+ }
+ }
+ else
+ {
+ P2P_TRACE_ERROR0 ("Handle is not for Data link connection");
+ }
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_p2p_create_data_link_connection
+**
+** Description Create data link connection
+**
+**
+** Returns TRUE to deallocate buffer
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_create_data_link_connection (tNFA_P2P_MSG *p_msg)
+{
+ UINT8 local_sap;
+ tNFA_P2P_EVT_DATA evt_data;
+ tLLCP_CONNECTION_PARAMS conn_params;
+ tLLCP_STATUS status;
+
+ P2P_TRACE_DEBUG0 ("nfa_p2p_create_data_link_connection ()");
+
+ local_sap = (UINT8) (p_msg->api_connect.client_handle & NFA_HANDLE_MASK);
+
+ conn_params.miu = p_msg->api_connect.miu;
+ conn_params.rw = p_msg->api_connect.rw;
+
+ /* NFA_P2pConnectBySap () */
+ if (p_msg->api_connect.dsap != LLCP_INVALID_SAP)
+ {
+ conn_params.sn[0] = 0;
+ status = LLCP_ConnectReq (local_sap, p_msg->api_connect.dsap, &conn_params);
+ }
+ /* NFA_P2pConnectByName () */
+ else
+ {
+ BCM_STRNCPY_S (conn_params.sn, sizeof (conn_params.sn),
+ p_msg->api_connect.service_name, LLCP_MAX_SN_LEN);
+ conn_params.sn[LLCP_MAX_SN_LEN] = 0;
+
+ status = LLCP_ConnectReq (local_sap, LLCP_SAP_SDP, &conn_params);
+ }
+
+ if (status != LLCP_STATUS_SUCCESS)
+ {
+ evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+ evt_data.disc.reason = NFA_P2P_DISC_REASON_NO_INFORMATION;
+
+ nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DISC_EVT, &evt_data);
+ }
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_p2p_send_ui
+**
+** Description Send UI PDU
+**
+**
+** Returns TRUE to deallocate buffer
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_send_ui (tNFA_P2P_MSG *p_msg)
+{
+ UINT8 local_sap;
+ tLLCP_STATUS status;
+ tNFA_P2P_EVT_DATA evt_data;
+
+ P2P_TRACE_DEBUG0 ("nfa_p2p_send_ui ()");
+
+ local_sap = (UINT8) (p_msg->api_send_ui.handle & NFA_HANDLE_MASK);
+
+ /* decrease number of tx UI PDU which is not processed by NFA for congestion control */
+ if (nfa_p2p_cb.sap_cb[local_sap].num_pending_ui_pdu)
+ nfa_p2p_cb.sap_cb[local_sap].num_pending_ui_pdu--;
+
+ if (nfa_p2p_cb.total_pending_ui_pdu)
+ nfa_p2p_cb.total_pending_ui_pdu--;
+
+ status = LLCP_SendUI (local_sap,
+ p_msg->api_send_ui.dsap,
+ p_msg->api_send_ui.p_msg);
+
+ if (status == LLCP_STATUS_CONGESTED)
+ {
+ if (!(nfa_p2p_cb.sap_cb[local_sap].flags & NFA_P2P_SAP_FLAG_LLINK_CONGESTED))
+ {
+ nfa_p2p_cb.sap_cb[local_sap].flags |= NFA_P2P_SAP_FLAG_LLINK_CONGESTED;
+
+ /* notify that this logical link is congested */
+ evt_data.congest.link_type = NFA_P2P_LLINK_TYPE;
+ evt_data.congest.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+ evt_data.congest.is_congested = TRUE;
+
+ nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_CONGEST_EVT, &evt_data);
+ }
+ }
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_p2p_send_data
+**
+** Description Send I PDU
+**
+**
+** Returns TRUE to deallocate buffer
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_send_data (tNFA_P2P_MSG *p_msg)
+{
+ tNFA_P2P_EVT_DATA evt_data;
+ tLLCP_STATUS status;
+ UINT8 xx;
+
+ P2P_TRACE_DEBUG0 ("nfa_p2p_send_data ()");
+
+ xx = (UINT8) (p_msg->api_send_data.conn_handle & NFA_HANDLE_MASK);
+ xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+
+ /* decrease number of tx I PDU which is not processed by NFA for congestion control */
+ if (nfa_p2p_cb.conn_cb[xx].num_pending_i_pdu)
+ nfa_p2p_cb.conn_cb[xx].num_pending_i_pdu--;
+
+ if (nfa_p2p_cb.total_pending_i_pdu)
+ nfa_p2p_cb.total_pending_i_pdu--;
+
+ status = LLCP_SendData (nfa_p2p_cb.conn_cb[xx].local_sap,
+ nfa_p2p_cb.conn_cb[xx].remote_sap,
+ p_msg->api_send_data.p_msg);
+
+ if (status == LLCP_STATUS_CONGESTED)
+ {
+ if (!(nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_CONGESTED))
+ {
+ nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_CONGESTED;
+
+ /* notify that this data link is congested */
+ evt_data.congest.link_type = NFA_P2P_DLINK_TYPE;
+ evt_data.congest.handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
+ evt_data.congest.is_congested = TRUE;
+
+ nfa_p2p_cb.sap_cb[nfa_p2p_cb.conn_cb[xx].local_sap].p_cback (NFA_P2P_CONGEST_EVT, &evt_data);
+ }
+ }
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_p2p_set_local_busy
+**
+** Description Set or reset local busy
+**
+**
+** Returns TRUE to deallocate buffer
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_set_local_busy (tNFA_P2P_MSG *p_msg)
+{
+ UINT8 xx;
+
+ P2P_TRACE_DEBUG0 ("nfa_p2p_set_local_busy ()");
+
+ xx = (UINT8) (p_msg->api_local_busy.conn_handle & NFA_HANDLE_MASK);
+ xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+
+ LLCP_SetLocalBusyStatus (nfa_p2p_cb.conn_cb[xx].local_sap,
+ nfa_p2p_cb.conn_cb[xx].remote_sap,
+ p_msg->api_local_busy.is_busy);
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_p2p_get_link_info
+**
+** Description Get WKS of remote and link MIU
+**
+**
+** Returns TRUE to deallocate buffer
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_get_link_info (tNFA_P2P_MSG *p_msg)
+{
+ tNFA_P2P_EVT_DATA evt_data;
+ UINT8 local_sap;
+
+ P2P_TRACE_DEBUG0 ("nfa_p2p_get_link_info ()");
+
+ evt_data.link_info.handle = p_msg->api_link_info.handle;
+ evt_data.link_info.wks = LLCP_GetRemoteWKS ();
+ evt_data.link_info.local_link_miu = nfa_p2p_cb.local_link_miu;
+ evt_data.link_info.remote_link_miu = nfa_p2p_cb.remote_link_miu;
+
+ local_sap = (UINT8) (p_msg->api_link_info.handle & NFA_HANDLE_MASK);
+ nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_LINK_INFO_EVT, &evt_data);
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_p2p_get_remote_sap
+**
+** Description Get remote SAP
+**
+**
+** Returns TRUE to deallocate buffer
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_get_remote_sap (tNFA_P2P_MSG *p_msg)
+{
+ tNFA_P2P_EVT_DATA evt_data;
+ UINT8 local_sap;
+
+ P2P_TRACE_DEBUG0 ("nfa_p2p_get_remote_sap ()");
+
+ local_sap = (UINT8) (p_msg->api_remote_sap.handle & NFA_HANDLE_MASK);
+
+ if (!nfa_p2p_start_sdp (p_msg->api_remote_sap.service_name,
+ local_sap))
+ {
+ evt_data.sdp.handle = p_msg->api_remote_sap.handle;
+ evt_data.sdp.remote_sap = 0x00;
+ nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_SDP_EVT, &evt_data);
+ }
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_p2p_set_llcp_cfg
+**
+** Description Set LLCP configuration
+**
+**
+** Returns TRUE to deallocate buffer
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_set_llcp_cfg (tNFA_P2P_MSG *p_msg)
+{
+ LLCP_SetConfig (p_msg->api_set_llcp_cfg.link_miu,
+ p_msg->api_set_llcp_cfg.opt,
+ p_msg->api_set_llcp_cfg.wt,
+ p_msg->api_set_llcp_cfg.link_timeout,
+ p_msg->api_set_llcp_cfg.inact_timeout_init,
+ p_msg->api_set_llcp_cfg.inact_timeout_target,
+ p_msg->api_set_llcp_cfg.symm_delay,
+ p_msg->api_set_llcp_cfg.data_link_timeout,
+ p_msg->api_set_llcp_cfg.delay_first_pdu_timeout);
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_p2p_restart_rf_discovery
+**
+** Description Restart RF discovery by deactivating to IDLE
+**
+**
+** Returns TRUE to deallocate buffer
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_restart_rf_discovery (tNFA_P2P_MSG *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..15a455b
--- /dev/null
+++ b/src/nfa/p2p/nfa_p2p_api.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.
+ *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ *
+ * NFA interface to LLCP
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_api.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "llcp_defs.h"
+#include "llcp_api.h"
+#include "nfa_p2p_api.h"
+#include "nfa_p2p_int.h"
+
+/*****************************************************************************
+** Constants
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function NFA_P2pRegisterServer
+**
+** Description This function is called to listen to a SAP as server on LLCP.
+**
+** NFA_P2P_REG_SERVER_EVT will be returned with status and handle.
+**
+** If server_sap is set to NFA_P2P_ANY_SAP, then NFA will allocate
+** a SAP between LLCP_LOWER_BOUND_SDP_SAP and LLCP_UPPER_BOUND_SDP_SAP
+** Otherwise, server_sap must be between (LLCP_SDP_SAP + 1) and
+** LLCP_UPPER_BOUND_SDP_SAP
+**
+** link_type : NFA_P2P_LLINK_TYPE and/or NFA_P2P_DLINK_TYPE
+**
+** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pRegisterServer (UINT8 server_sap,
+ tNFA_P2P_LINK_TYPE link_type,
+ char *p_service_name,
+ tNFA_P2P_CBACK *p_cback)
+{
+ tNFA_P2P_API_REG_SERVER *p_msg;
+
+ P2P_TRACE_API3 ("NFA_P2pRegisterServer (): server_sap:0x%02x, link_type:0x%x, SN:<%s>",
+ server_sap, link_type, p_service_name);
+
+ if ( (server_sap != NFA_P2P_ANY_SAP)
+ &&((server_sap <= LLCP_SAP_SDP) ||(server_sap > LLCP_UPPER_BOUND_SDP_SAP)) )
+ {
+ P2P_TRACE_ERROR2 ("NFA_P2pRegisterServer (): server_sap must be between %d and %d",
+ LLCP_SAP_SDP + 1, LLCP_UPPER_BOUND_SDP_SAP);
+ return (NFA_STATUS_FAILED);
+ }
+ else if ( ((link_type & NFA_P2P_LLINK_TYPE) == 0x00)
+ &&((link_type & NFA_P2P_DLINK_TYPE) == 0x00) )
+ {
+ P2P_TRACE_ERROR1 ("NFA_P2pRegisterServer(): link type (0x%x) must be specified", link_type);
+ return (NFA_STATUS_FAILED);
+ }
+
+ if ((p_msg = (tNFA_P2P_API_REG_SERVER *) GKI_getbuf (sizeof (tNFA_P2P_API_REG_SERVER))) != NULL)
+ {
+ p_msg->hdr.event = NFA_P2P_API_REG_SERVER_EVT;
+
+ p_msg->server_sap = server_sap;
+ p_msg->link_type = link_type;
+
+ BCM_STRNCPY_S (p_msg->service_name, sizeof (p_msg->service_name), p_service_name, LLCP_MAX_SN_LEN);
+ p_msg->service_name[LLCP_MAX_SN_LEN] = 0;
+
+ p_msg->p_cback = p_cback;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_P2pRegisterClient
+**
+** Description This function is called to register a client service on LLCP.
+**
+** NFA_P2P_REG_CLIENT_EVT will be returned with status and handle.
+**
+** link_type : NFA_P2P_LLINK_TYPE and/or NFA_P2P_DLINK_TYPE
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pRegisterClient (tNFA_P2P_LINK_TYPE link_type,
+ tNFA_P2P_CBACK *p_cback)
+{
+ tNFA_P2P_API_REG_CLIENT *p_msg;
+
+ P2P_TRACE_API1 ("NFA_P2pRegisterClient (): link_type:0x%x", link_type);
+
+ if ( ((link_type & NFA_P2P_LLINK_TYPE) == 0x00)
+ &&((link_type & NFA_P2P_DLINK_TYPE) == 0x00) )
+ {
+ P2P_TRACE_ERROR1 ("NFA_P2pRegisterClient (): link type (0x%x) must be specified", link_type);
+ return (NFA_STATUS_FAILED);
+ }
+
+ if ((p_msg = (tNFA_P2P_API_REG_CLIENT *) GKI_getbuf (sizeof (tNFA_P2P_API_REG_CLIENT))) != NULL)
+ {
+ p_msg->hdr.event = NFA_P2P_API_REG_CLIENT_EVT;
+
+ p_msg->p_cback = p_cback;
+ p_msg->link_type = link_type;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_P2pDeregister
+**
+** Description This function is called to stop listening to a SAP as server
+** or stop client service on LLCP.
+**
+** Note: If this function is called to de-register a server and RF discovery
+** is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+** should happen before calling this function
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pDeregister (tNFA_HANDLE handle)
+{
+ tNFA_P2P_API_DEREG *p_msg;
+ tNFA_HANDLE xx;
+
+ P2P_TRACE_API1 ("NFA_P2pDeregister (): handle:0x%02X", handle);
+
+ xx = handle & NFA_HANDLE_MASK;
+
+ if ( (xx >= NFA_P2P_NUM_SAP)
+ ||(nfa_p2p_cb.sap_cb[xx].p_cback == NULL) )
+ {
+ P2P_TRACE_ERROR0 ("NFA_P2pDeregister (): Handle is invalid or not registered");
+ return (NFA_STATUS_BAD_HANDLE);
+ }
+
+ if ((p_msg = (tNFA_P2P_API_DEREG *) GKI_getbuf (sizeof (tNFA_P2P_API_DEREG))) != NULL)
+ {
+ p_msg->hdr.event = NFA_P2P_API_DEREG_EVT;
+
+ p_msg->handle = handle;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_P2pAcceptConn
+**
+** Description This function is called to accept a request of data link
+** connection to a listening SAP on LLCP after receiving
+** NFA_P2P_CONN_REQ_EVT.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pAcceptConn (tNFA_HANDLE handle,
+ UINT16 miu,
+ UINT8 rw)
+{
+ tNFA_P2P_API_ACCEPT_CONN *p_msg;
+ tNFA_HANDLE xx;
+
+ P2P_TRACE_API3 ("NFA_P2pAcceptConn (): handle:0x%02X, MIU:%d, RW:%d", handle, miu, rw);
+
+ xx = handle & NFA_HANDLE_MASK;
+
+ if (!(xx & NFA_P2P_HANDLE_FLAG_CONN))
+ {
+ P2P_TRACE_ERROR0 ("NFA_P2pAcceptConn (): Connection Handle is not valid");
+ return (NFA_STATUS_BAD_HANDLE);
+ }
+ else
+ {
+ xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+ }
+
+ if ( (xx >= LLCP_MAX_DATA_LINK)
+ ||(nfa_p2p_cb.conn_cb[xx].flags == 0) )
+ {
+ P2P_TRACE_ERROR0 ("NFA_P2pAcceptConn (): Connection Handle is not valid");
+ return (NFA_STATUS_BAD_HANDLE);
+ }
+
+ if ((miu < LLCP_DEFAULT_MIU) || (nfa_p2p_cb.local_link_miu < miu))
+ {
+ P2P_TRACE_ERROR3 ("NFA_P2pAcceptConn (): MIU(%d) must be between %d and %d",
+ miu, LLCP_DEFAULT_MIU, nfa_p2p_cb.local_link_miu);
+ }
+ else if ((p_msg = (tNFA_P2P_API_ACCEPT_CONN *) GKI_getbuf (sizeof (tNFA_P2P_API_ACCEPT_CONN))) != NULL)
+ {
+ p_msg->hdr.event = NFA_P2P_API_ACCEPT_CONN_EVT;
+
+ p_msg->conn_handle = handle;
+ p_msg->miu = miu;
+ p_msg->rw = rw;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_P2pRejectConn
+**
+** Description This function is called to reject a request of data link
+** connection to a listening SAP on LLCP after receiving
+** NFA_P2P_CONN_REQ_EVT.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pRejectConn (tNFA_HANDLE handle)
+{
+ tNFA_P2P_API_REJECT_CONN *p_msg;
+ tNFA_HANDLE xx;
+
+ P2P_TRACE_API1 ("NFA_P2pRejectConn (): handle:0x%02X", handle);
+
+ xx = handle & NFA_HANDLE_MASK;
+
+ if (!(xx & NFA_P2P_HANDLE_FLAG_CONN))
+ {
+ P2P_TRACE_ERROR0 ("NFA_P2pRejectConn (): Connection Handle is not valid");
+ return (NFA_STATUS_BAD_HANDLE);
+ }
+ else
+ {
+ xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+ }
+
+ if ( (xx >= LLCP_MAX_DATA_LINK)
+ ||(nfa_p2p_cb.conn_cb[xx].flags == 0) )
+ {
+ P2P_TRACE_ERROR0 ("NFA_P2pRejectConn (): Connection Handle is not valid");
+ return (NFA_STATUS_BAD_HANDLE);
+ }
+
+ if ((p_msg = (tNFA_P2P_API_REJECT_CONN *) GKI_getbuf (sizeof (tNFA_P2P_API_REJECT_CONN))) != NULL)
+ {
+ p_msg->hdr.event = NFA_P2P_API_REJECT_CONN_EVT;
+
+ p_msg->conn_handle = handle;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_P2pDisconnect
+**
+** Description This function is called to disconnect an existing or
+** connecting data link connection.
+**
+** discard any pending data on data link connection if flush is set to TRUE
+**
+** NFA_P2P_DISC_EVT will be returned after data link connection is disconnected
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pDisconnect (tNFA_HANDLE handle, BOOLEAN flush)
+{
+ tNFA_P2P_API_DISCONNECT *p_msg;
+ tNFA_HANDLE xx;
+
+ P2P_TRACE_API2 ("NFA_P2pDisconnect (): handle:0x%02X, flush=%d", handle, flush);
+
+ xx = handle & NFA_HANDLE_MASK;
+
+ if (xx & NFA_P2P_HANDLE_FLAG_CONN)
+ {
+ xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+
+ if ( (xx >= LLCP_MAX_DATA_LINK)
+ ||(nfa_p2p_cb.conn_cb[xx].flags == 0) )
+ {
+ P2P_TRACE_ERROR0 ("NFA_P2pDisconnect (): Connection Handle is not valid");
+ return (NFA_STATUS_BAD_HANDLE);
+ }
+ }
+ else
+ {
+ P2P_TRACE_ERROR0 ("NFA_P2pDisconnect (): Handle is not valid");
+ return (NFA_STATUS_BAD_HANDLE);
+ }
+
+ if ((p_msg = (tNFA_P2P_API_DISCONNECT *) GKI_getbuf (sizeof (tNFA_P2P_API_DISCONNECT))) != NULL)
+ {
+ p_msg->hdr.event = NFA_P2P_API_DISCONNECT_EVT;
+
+ p_msg->conn_handle = handle;
+ p_msg->flush = flush;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_P2pConnectByName
+**
+** Description This function is called to create a connection-oriented transport
+** by a service name.
+** NFA_P2P_CONNECTED_EVT if success
+** NFA_P2P_DISC_EVT if failed
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if client is not registered
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pConnectByName (tNFA_HANDLE client_handle,
+ char *p_service_name,
+ UINT16 miu,
+ UINT8 rw)
+{
+ tNFA_P2P_API_CONNECT *p_msg;
+ tNFA_HANDLE xx;
+
+ P2P_TRACE_API4 ("NFA_P2pConnectByName (): client_handle:0x%x, SN:<%s>, MIU:%d, RW:%d",
+ client_handle, p_service_name, miu, rw);
+
+ xx = client_handle & NFA_HANDLE_MASK;
+
+ if ( (xx >= NFA_P2P_NUM_SAP)
+ ||(nfa_p2p_cb.sap_cb[xx].p_cback == NULL) )
+ {
+ P2P_TRACE_ERROR0 ("NFA_P2pConnectByName (): Client Handle is not valid");
+ return (NFA_STATUS_BAD_HANDLE);
+ }
+
+ if ( (miu < LLCP_DEFAULT_MIU)
+ ||(nfa_p2p_cb.llcp_state != NFA_P2P_LLCP_STATE_ACTIVATED)
+ ||(nfa_p2p_cb.local_link_miu < miu) )
+ {
+ P2P_TRACE_ERROR3 ("NFA_P2pConnectByName (): MIU(%d) must be between %d and %d or LLCP link is not activated",
+ miu, LLCP_DEFAULT_MIU, nfa_p2p_cb.local_link_miu);
+ }
+ else if ((p_msg = (tNFA_P2P_API_CONNECT *) GKI_getbuf (sizeof (tNFA_P2P_API_CONNECT))) != NULL)
+ {
+ p_msg->hdr.event = NFA_P2P_API_CONNECT_EVT;
+
+ BCM_STRNCPY_S (p_msg->service_name, sizeof (p_msg->service_name), p_service_name, LLCP_MAX_SN_LEN);
+ p_msg->service_name[LLCP_MAX_SN_LEN] = 0;
+
+ p_msg->dsap = LLCP_INVALID_SAP;
+ p_msg->miu = miu;
+ p_msg->rw = rw;
+ p_msg->client_handle = client_handle;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_P2pConnectBySap
+**
+** Description This function is called to create a connection-oriented transport
+** by a SAP.
+** NFA_P2P_CONNECTED_EVT if success
+** NFA_P2P_DISC_EVT if failed
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if client is not registered
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pConnectBySap (tNFA_HANDLE client_handle,
+ UINT8 dsap,
+ UINT16 miu,
+ UINT8 rw)
+{
+ tNFA_P2P_API_CONNECT *p_msg;
+ tNFA_HANDLE xx;
+
+ P2P_TRACE_API4 ("NFA_P2pConnectBySap (): client_handle:0x%x, DSAP:0x%02X, MIU:%d, RW:%d",
+ client_handle, dsap, miu, rw);
+
+ xx = client_handle & NFA_HANDLE_MASK;
+
+ if ( (xx >= NFA_P2P_NUM_SAP)
+ ||(nfa_p2p_cb.sap_cb[xx].p_cback == NULL) )
+ {
+ P2P_TRACE_ERROR0 ("NFA_P2pConnectBySap (): Client Handle is not valid");
+ return (NFA_STATUS_BAD_HANDLE);
+ }
+
+ if ( (miu < LLCP_DEFAULT_MIU)
+ ||(nfa_p2p_cb.llcp_state != NFA_P2P_LLCP_STATE_ACTIVATED)
+ ||(nfa_p2p_cb.local_link_miu < miu) )
+ {
+ P2P_TRACE_ERROR3 ("NFA_P2pConnectBySap (): MIU(%d) must be between %d and %d, or LLCP link is not activated",
+ miu, LLCP_DEFAULT_MIU, nfa_p2p_cb.local_link_miu);
+ }
+ else if ((p_msg = (tNFA_P2P_API_CONNECT *) GKI_getbuf (sizeof (tNFA_P2P_API_CONNECT))) != NULL)
+ {
+ p_msg->hdr.event = NFA_P2P_API_CONNECT_EVT;
+
+ p_msg->service_name[LLCP_MAX_SN_LEN] = 0;
+
+ p_msg->dsap = dsap;
+ p_msg->miu = miu;
+ p_msg->rw = rw;
+ p_msg->client_handle = client_handle;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_P2pSendUI
+**
+** Description This function is called to send data on connectionless
+** transport.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+** NFA_STATUS_BAD_LENGTH if data length is more than remote link MIU
+** NFA_STATUS_CONGESTED if congested
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pSendUI (tNFA_HANDLE handle,
+ UINT8 dsap,
+ UINT16 length,
+ UINT8 *p_data)
+{
+ tNFA_P2P_API_SEND_UI *p_msg;
+ tNFA_STATUS ret_status = NFA_STATUS_FAILED;
+ tNFA_HANDLE xx;
+
+ P2P_TRACE_API3 ("NFA_P2pSendUI (): handle:0x%X, DSAP:0x%02X, length:%d", handle, dsap, length);
+
+ GKI_sched_lock ();
+
+ xx = handle & NFA_HANDLE_MASK;
+
+ if ( (xx >= NFA_P2P_NUM_SAP)
+ ||(nfa_p2p_cb.sap_cb[xx].p_cback == NULL))
+ {
+ P2P_TRACE_ERROR1 ("NFA_P2pSendUI (): Handle (0x%X) is not valid", handle);
+ ret_status = NFA_STATUS_BAD_HANDLE;
+ }
+ else if (length > nfa_p2p_cb.remote_link_miu)
+ {
+ P2P_TRACE_ERROR3 ("NFA_P2pSendUI (): handle:0x%X, length(%d) must be less than remote link MIU(%d)",
+ handle, length, nfa_p2p_cb.remote_link_miu);
+ ret_status = NFA_STATUS_BAD_LENGTH;
+ }
+ else if (nfa_p2p_cb.sap_cb[xx].flags & NFA_P2P_SAP_FLAG_LLINK_CONGESTED)
+ {
+ P2P_TRACE_WARNING1 ("NFA_P2pSendUI (): handle:0x%X, logical data link is already congested",
+ handle);
+ ret_status = NFA_STATUS_CONGESTED;
+ }
+ else if (LLCP_IsLogicalLinkCongested ((UINT8)xx,
+ nfa_p2p_cb.sap_cb[xx].num_pending_ui_pdu,
+ nfa_p2p_cb.total_pending_ui_pdu,
+ nfa_p2p_cb.total_pending_i_pdu))
+ {
+ nfa_p2p_cb.sap_cb[xx].flags |= NFA_P2P_SAP_FLAG_LLINK_CONGESTED;
+
+ P2P_TRACE_WARNING1 ("NFA_P2pSendUI(): handle:0x%X, logical data link is congested",
+ handle);
+ ret_status = NFA_STATUS_CONGESTED;
+ }
+ else if ((p_msg = (tNFA_P2P_API_SEND_UI *) GKI_getbuf (sizeof(tNFA_P2P_API_SEND_UI))) != NULL)
+ {
+ p_msg->hdr.event = NFA_P2P_API_SEND_UI_EVT;
+
+ p_msg->handle = handle;
+ p_msg->dsap = dsap;
+
+ if ((p_msg->p_msg = (BT_HDR *) GKI_getpoolbuf (LLCP_POOL_ID)) != NULL)
+ {
+ p_msg->p_msg->len = length;
+ p_msg->p_msg->offset = LLCP_MIN_OFFSET;
+ memcpy (((UINT8*) (p_msg->p_msg + 1) + p_msg->p_msg->offset), p_data, length);
+
+ /* increase number of tx UI PDU which is not processed by NFA for congestion control */
+ nfa_p2p_cb.sap_cb[xx].num_pending_ui_pdu++;
+ nfa_p2p_cb.total_pending_ui_pdu++;
+ nfa_sys_sendmsg (p_msg);
+
+ ret_status = NFA_STATUS_OK;
+ }
+ else
+ {
+ GKI_freebuf (p_msg);
+
+ nfa_p2p_cb.sap_cb[xx].flags |= NFA_P2P_SAP_FLAG_LLINK_CONGESTED;
+ ret_status = NFA_STATUS_CONGESTED;
+ }
+ }
+
+ GKI_sched_unlock ();
+
+ return (ret_status);
+}
+
+/*******************************************************************************
+**
+** Function NFA_P2pReadUI
+**
+** Description This function is called to read data on connectionless
+** transport when receiving NFA_P2P_DATA_EVT with NFA_P2P_LLINK_TYPE.
+**
+** - Remote SAP who sent UI PDU is returned.
+** - Information of UI PDU up to max_data_len is copied into p_data.
+** - If more information of UI PDU or more UI PDU in queue then more
+** is returned to TRUE.
+** - Information of next UI PDU is not concatenated.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pReadUI (tNFA_HANDLE handle,
+ UINT32 max_data_len,
+ UINT8 *p_remote_sap,
+ UINT32 *p_data_len,
+ UINT8 *p_data,
+ BOOLEAN *p_more)
+{
+ tNFA_STATUS ret_status;
+ tNFA_HANDLE xx;
+
+ P2P_TRACE_API1 ("NFA_P2pReadUI (): handle:0x%X", handle);
+
+ GKI_sched_lock ();
+
+ xx = handle & NFA_HANDLE_MASK;
+
+ if ( (xx >= NFA_P2P_NUM_SAP)
+ ||(nfa_p2p_cb.sap_cb[xx].p_cback == NULL) )
+ {
+ P2P_TRACE_ERROR1 ("NFA_P2pReadUI (): Handle (0x%X) is not valid", handle);
+ ret_status = NFA_STATUS_BAD_HANDLE;
+ }
+ else
+ {
+ *p_more = LLCP_ReadLogicalLinkData ((UINT8)xx,
+ max_data_len,
+ p_remote_sap,
+ p_data_len,
+ p_data);
+ ret_status = NFA_STATUS_OK;
+ }
+
+ GKI_sched_unlock ();
+
+ return (ret_status);
+}
+
+/*******************************************************************************
+**
+** Function NFA_P2pFlushUI
+**
+** Description This function is called to flush data on connectionless
+** transport.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pFlushUI (tNFA_HANDLE handle,
+ UINT32 *p_length)
+{
+ tNFA_STATUS ret_status;
+ tNFA_HANDLE xx;
+
+ P2P_TRACE_API1 ("NFA_P2pReadUI (): handle:0x%X", handle);
+
+ GKI_sched_lock ();
+
+ xx = handle & NFA_HANDLE_MASK;
+
+ if ( (xx >= NFA_P2P_NUM_SAP)
+ ||(nfa_p2p_cb.sap_cb[xx].p_cback == NULL) )
+ {
+ P2P_TRACE_ERROR1 ("NFA_P2pFlushUI (): Handle (0x%X) is not valid", handle);
+ ret_status = NFA_STATUS_BAD_HANDLE;
+ *p_length = 0;
+ }
+ else
+ {
+ *p_length = LLCP_FlushLogicalLinkRxData ((UINT8)xx);
+ ret_status = NFA_STATUS_OK;
+ }
+
+ GKI_sched_unlock ();
+
+ return (ret_status);
+}
+
+/*******************************************************************************
+**
+** Function NFA_P2pSendData
+**
+** Description This function is called to send data on connection-oriented
+** transport.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+** NFA_STATUS_BAD_LENGTH if data length is more than remote MIU
+** NFA_STATUS_CONGESTED if congested
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pSendData (tNFA_HANDLE handle,
+ UINT16 length,
+ UINT8 *p_data)
+{
+ tNFA_P2P_API_SEND_DATA *p_msg;
+ tNFA_STATUS ret_status = NFA_STATUS_FAILED;
+ tNFA_HANDLE xx;
+
+ P2P_TRACE_API2 ("NFA_P2pSendData (): handle:0x%X, length:%d", handle, length);
+
+ GKI_sched_lock ();
+
+ xx = handle & NFA_HANDLE_MASK;
+ xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+
+ if ( (!(handle & NFA_P2P_HANDLE_FLAG_CONN))
+ ||(xx >= LLCP_MAX_DATA_LINK)
+ ||(nfa_p2p_cb.conn_cb[xx].flags == 0) )
+ {
+ P2P_TRACE_ERROR1 ("NFA_P2pSendData (): Handle(0x%X) is not valid", handle);
+ ret_status = NFA_STATUS_BAD_HANDLE;
+ }
+ else if (nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_REMOTE_RW_ZERO)
+ {
+ P2P_TRACE_ERROR1 ("NFA_P2pSendData (): handle:0x%X, Remote set RW to 0 (flow off)", handle);
+ ret_status = NFA_STATUS_FAILED;
+ }
+ else if (nfa_p2p_cb.conn_cb[xx].remote_miu < length)
+ {
+ P2P_TRACE_ERROR2 ("NFA_P2pSendData (): handle:0x%X, Data more than remote MIU(%d)",
+ handle, nfa_p2p_cb.conn_cb[xx].remote_miu);
+ ret_status = NFA_STATUS_BAD_LENGTH;
+ }
+ else if (nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_CONGESTED)
+ {
+ P2P_TRACE_WARNING1 ("NFA_P2pSendData (): handle:0x%X, data link connection is already congested",
+ handle);
+ ret_status = NFA_STATUS_CONGESTED;
+ }
+ else if (LLCP_IsDataLinkCongested (nfa_p2p_cb.conn_cb[xx].local_sap,
+ nfa_p2p_cb.conn_cb[xx].remote_sap,
+ nfa_p2p_cb.conn_cb[xx].num_pending_i_pdu,
+ nfa_p2p_cb.total_pending_ui_pdu,
+ nfa_p2p_cb.total_pending_i_pdu))
+ {
+ nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_CONGESTED;
+
+ P2P_TRACE_WARNING1 ("NFA_P2pSendData (): handle:0x%X, data link connection is congested",
+ handle);
+ ret_status = NFA_STATUS_CONGESTED;
+ }
+ else if ((p_msg = (tNFA_P2P_API_SEND_DATA *) GKI_getbuf (sizeof(tNFA_P2P_API_SEND_DATA))) != NULL)
+ {
+ p_msg->hdr.event = NFA_P2P_API_SEND_DATA_EVT;
+
+ p_msg->conn_handle = handle;
+
+ if ((p_msg->p_msg = (BT_HDR *) GKI_getpoolbuf (LLCP_POOL_ID)) != NULL)
+ {
+ p_msg->p_msg->len = length;
+ p_msg->p_msg->offset = LLCP_MIN_OFFSET;
+ memcpy (((UINT8*) (p_msg->p_msg + 1) + p_msg->p_msg->offset), p_data, length);
+
+ /* increase number of tx I PDU which is not processed by NFA for congestion control */
+ nfa_p2p_cb.conn_cb[xx].num_pending_i_pdu++;
+ nfa_p2p_cb.total_pending_i_pdu++;
+ nfa_sys_sendmsg (p_msg);
+
+ ret_status = NFA_STATUS_OK;
+ }
+ else
+ {
+ GKI_freebuf (p_msg);
+ nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_CONGESTED;
+ ret_status = NFA_STATUS_CONGESTED;
+ }
+ }
+
+ GKI_sched_unlock ();
+
+ return (ret_status);
+}
+
+/*******************************************************************************
+**
+** Function NFA_P2pReadData
+**
+** Description This function is called to read data on connection-oriented
+** transport when receiving NFA_P2P_DATA_EVT with NFA_P2P_DLINK_TYPE.
+**
+** - Information of I PDU is copied into p_data up to max_data_len.
+** - If more information of I PDU or more I PDU in queue, then more
+** is returned to TRUE.
+** - Information of next I PDU is not concatenated.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pReadData (tNFA_HANDLE handle,
+ UINT32 max_data_len,
+ UINT32 *p_data_len,
+ UINT8 *p_data,
+ BOOLEAN *p_more)
+{
+ tNFA_STATUS ret_status;
+ tNFA_HANDLE xx;
+
+ P2P_TRACE_API1 ("NFA_P2pReadData (): handle:0x%X", handle);
+
+ GKI_sched_lock ();
+
+ xx = handle & NFA_HANDLE_MASK;
+ xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+
+ if ( (!(handle & NFA_P2P_HANDLE_FLAG_CONN))
+ ||(xx >= LLCP_MAX_DATA_LINK)
+ ||(nfa_p2p_cb.conn_cb[xx].flags == 0) )
+ {
+ P2P_TRACE_ERROR1 ("NFA_P2pReadData (): Handle(0x%X) is not valid", handle);
+ ret_status = NFA_STATUS_BAD_HANDLE;
+ }
+ else
+ {
+ *p_more = LLCP_ReadDataLinkData (nfa_p2p_cb.conn_cb[xx].local_sap,
+ nfa_p2p_cb.conn_cb[xx].remote_sap,
+ max_data_len,
+ p_data_len,
+ p_data);
+ ret_status = NFA_STATUS_OK;
+ }
+
+ GKI_sched_unlock ();
+
+ return (ret_status);
+}
+
+/*******************************************************************************
+**
+** Function NFA_P2pFlushData
+**
+** Description This function is called to flush data on connection-oriented
+** transport.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pFlushData (tNFA_HANDLE handle,
+ UINT32 *p_length)
+{
+ tNFA_STATUS ret_status;
+ tNFA_HANDLE xx;
+
+ P2P_TRACE_API1 ("NFA_P2pFlushData (): handle:0x%X", handle);
+
+ GKI_sched_lock ();
+
+ xx = handle & NFA_HANDLE_MASK;
+ xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+
+ if ( (!(handle & NFA_P2P_HANDLE_FLAG_CONN))
+ ||(xx >= LLCP_MAX_DATA_LINK)
+ ||(nfa_p2p_cb.conn_cb[xx].flags == 0) )
+ {
+ P2P_TRACE_ERROR1 ("NFA_P2pFlushData (): Handle(0x%X) is not valid", handle);
+ ret_status = NFA_STATUS_BAD_HANDLE;
+ }
+ else
+ {
+ *p_length = LLCP_FlushDataLinkRxData (nfa_p2p_cb.conn_cb[xx].local_sap,
+ nfa_p2p_cb.conn_cb[xx].remote_sap);
+ ret_status = NFA_STATUS_OK;
+ }
+
+ GKI_sched_unlock ();
+
+ return (ret_status);
+}
+
+/*******************************************************************************
+**
+** Function NFA_P2pSetLocalBusy
+**
+** Description This function is called to stop or resume incoming data on
+** connection-oriented transport.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if handle is not valid
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pSetLocalBusy (tNFA_HANDLE conn_handle,
+ BOOLEAN is_busy)
+{
+ tNFA_P2P_API_SET_LOCAL_BUSY *p_msg;
+ tNFA_HANDLE xx;
+
+ P2P_TRACE_API2 ("NFA_P2pSetLocalBusy (): conn_handle:0x%02X, is_busy:%d", conn_handle, is_busy);
+
+ xx = conn_handle & NFA_HANDLE_MASK;
+
+ if (!(xx & NFA_P2P_HANDLE_FLAG_CONN))
+ {
+ P2P_TRACE_ERROR0 ("NFA_P2pSetLocalBusy (): Connection Handle is not valid");
+ return (NFA_STATUS_BAD_HANDLE);
+ }
+ else
+ {
+ xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+ }
+
+ if ( (xx >= LLCP_MAX_DATA_LINK)
+ ||(nfa_p2p_cb.conn_cb[xx].flags == 0) )
+ {
+ P2P_TRACE_ERROR0 ("NFA_P2pSetLocalBusy (): Connection Handle is not valid");
+ return (NFA_STATUS_BAD_HANDLE);
+ }
+
+ if ((p_msg = (tNFA_P2P_API_SET_LOCAL_BUSY *) GKI_getbuf (sizeof (tNFA_P2P_API_SET_LOCAL_BUSY))) != NULL)
+ {
+ p_msg->hdr.event = NFA_P2P_API_SET_LOCAL_BUSY_EVT;
+
+ p_msg->conn_handle = conn_handle;
+ p_msg->is_busy = is_busy;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_P2pGetLinkInfo
+**
+** Description This function is called to get local/remote link MIU and
+** Well-Known Service list encoded as a 16-bit field of connected LLCP.
+** NFA_P2P_LINK_INFO_EVT will be returned.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if server or client is not registered
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pGetLinkInfo (tNFA_HANDLE handle)
+{
+ tNFA_P2P_API_GET_LINK_INFO *p_msg;
+ tNFA_HANDLE xx;
+
+ P2P_TRACE_API1 ("NFA_P2pGetLinkInfo (): handle:0x%x", handle);
+
+ if (nfa_p2p_cb.llcp_state != NFA_P2P_LLCP_STATE_ACTIVATED)
+ {
+ P2P_TRACE_ERROR0 ("NFA_P2pGetLinkInfo (): LLCP link is not activated");
+ return (NFA_STATUS_FAILED);
+ }
+
+ xx = handle & NFA_HANDLE_MASK;
+
+ if ( (xx >= NFA_P2P_NUM_SAP)
+ ||(nfa_p2p_cb.sap_cb[xx].p_cback == NULL) )
+ {
+ P2P_TRACE_ERROR0 ("NFA_P2pGetLinkInfo (): Handle is invalid or not registered");
+ return (NFA_STATUS_BAD_HANDLE);
+ }
+
+ if ((p_msg = (tNFA_P2P_API_GET_LINK_INFO *) GKI_getbuf (sizeof (tNFA_P2P_API_GET_LINK_INFO))) != NULL)
+ {
+ p_msg->hdr.event = NFA_P2P_API_GET_LINK_INFO_EVT;
+
+ p_msg->handle = handle;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_P2pGetRemoteSap
+**
+** Description This function is called to get SAP associated by service name
+** on connected remote LLCP.
+** NFA_P2P_SDP_EVT will be returned.
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_BAD_HANDLE if server or client is not registered
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pGetRemoteSap (tNFA_HANDLE handle,
+ char *p_service_name)
+{
+ tNFA_P2P_API_GET_REMOTE_SAP *p_msg;
+ tNFA_HANDLE xx;
+
+ P2P_TRACE_API2 ("NFA_P2pGetRemoteSap(): handle:0x%x, SN:<%s>", handle, p_service_name);
+
+ if (nfa_p2p_cb.llcp_state != NFA_P2P_LLCP_STATE_ACTIVATED)
+ {
+ P2P_TRACE_ERROR0 ("NFA_P2pGetRemoteSap(): LLCP link is not activated");
+ return (NFA_STATUS_FAILED);
+ }
+
+ xx = handle & NFA_HANDLE_MASK;
+
+ if ( (xx >= NFA_P2P_NUM_SAP)
+ ||(nfa_p2p_cb.sap_cb[xx].p_cback == NULL) )
+ {
+ P2P_TRACE_ERROR0 ("NFA_P2pGetRemoteSap (): Handle is invalid or not registered");
+ return (NFA_STATUS_BAD_HANDLE);
+ }
+
+ if ((p_msg = (tNFA_P2P_API_GET_REMOTE_SAP *) GKI_getbuf (sizeof (tNFA_P2P_API_GET_REMOTE_SAP))) != NULL)
+ {
+ p_msg->hdr.event = NFA_P2P_API_GET_REMOTE_SAP_EVT;
+
+ p_msg->handle = handle;
+
+ BCM_STRNCPY_S (p_msg->service_name, sizeof (p_msg->service_name), p_service_name, LLCP_MAX_SN_LEN);
+ p_msg->service_name[LLCP_MAX_SN_LEN] = 0;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_P2pSetLLCPConfig
+**
+** Description This function is called to change LLCP config parameters.
+** Application must call while LLCP is not activated.
+**
+** Parameters descriptions (default value)
+** - Local Link MIU (LLCP_MIU)
+** - Option parameter (LLCP_OPT_VALUE)
+** - Response Waiting Time Index (LLCP_WAITING_TIME)
+** - Local Link Timeout (LLCP_LTO_VALUE)
+** - Inactivity Timeout as initiator role (LLCP_INIT_INACTIVITY_TIMEOUT)
+** - Inactivity Timeout as target role (LLCP_TARGET_INACTIVITY_TIMEOUT)
+** - Delay SYMM response (LLCP_DELAY_RESP_TIME)
+** - Data link connection timeout (LLCP_DATA_LINK_CONNECTION_TOUT)
+** - Delay timeout to send first PDU as initiator (LLCP_DELAY_TIME_TO_SEND_FIRST_PDU)
+**
+** Returns NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pSetLLCPConfig (UINT16 link_miu,
+ UINT8 opt,
+ UINT8 wt,
+ UINT16 link_timeout,
+ UINT16 inact_timeout_init,
+ UINT16 inact_timeout_target,
+ UINT16 symm_delay,
+ UINT16 data_link_timeout,
+ UINT16 delay_first_pdu_timeout)
+{
+ tNFA_P2P_API_SET_LLCP_CFG *p_msg;
+
+ P2P_TRACE_API4 ("NFA_P2pSetLLCPConfig ():link_miu:%d, opt:0x%02X, wt:%d, link_timeout:%d",
+ link_miu, opt, wt, link_timeout);
+ P2P_TRACE_API4 (" inact_timeout(init:%d, target:%d), symm_delay:%d, data_link_timeout:%d",
+ inact_timeout_init, inact_timeout_target, symm_delay, data_link_timeout);
+ P2P_TRACE_API1 (" delay_first_pdu_timeout:%d", delay_first_pdu_timeout);
+
+ if (nfa_p2p_cb.llcp_state == NFA_P2P_LLCP_STATE_ACTIVATED)
+ {
+ P2P_TRACE_ERROR0 ("NFA_P2pSetLLCPConfig (): LLCP link is activated");
+ return (NFA_STATUS_FAILED);
+ }
+
+ if ((p_msg = (tNFA_P2P_API_SET_LLCP_CFG *) GKI_getbuf (sizeof (tNFA_P2P_API_SET_LLCP_CFG))) != NULL)
+ {
+ p_msg->hdr.event = NFA_P2P_API_SET_LLCP_CFG_EVT;
+
+ p_msg->link_miu = link_miu;
+ p_msg->opt = opt;
+ p_msg->wt = wt;
+ p_msg->link_timeout = link_timeout;
+ p_msg->inact_timeout_init = inact_timeout_init;
+ p_msg->inact_timeout_target = inact_timeout_target;
+ p_msg->symm_delay = symm_delay;
+ p_msg->data_link_timeout = data_link_timeout;
+ p_msg->delay_first_pdu_timeout = delay_first_pdu_timeout;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_P2pGetLLCPConfig
+**
+** Description This function is called to read LLCP config parameters.
+**
+** Parameters descriptions
+** - Local Link MIU
+** - Option parameter
+** - Response Waiting Time Index
+** - Local Link Timeout
+** - Inactivity Timeout as initiator role
+** - Inactivity Timeout as target role
+** - Delay SYMM response
+** - Data link connection timeout
+** - Delay timeout to send first PDU as initiator
+**
+** Returns None
+**
+*******************************************************************************/
+void NFA_P2pGetLLCPConfig (UINT16 *p_link_miu,
+ UINT8 *p_opt,
+ UINT8 *p_wt,
+ UINT16 *p_link_timeout,
+ UINT16 *p_inact_timeout_init,
+ UINT16 *p_inact_timeout_target,
+ UINT16 *p_symm_delay,
+ UINT16 *p_data_link_timeout,
+ UINT16 *p_delay_first_pdu_timeout)
+{
+ LLCP_GetConfig (p_link_miu,
+ p_opt,
+ p_wt,
+ p_link_timeout,
+ p_inact_timeout_init,
+ p_inact_timeout_target,
+ p_symm_delay,
+ p_data_link_timeout,
+ p_delay_first_pdu_timeout);
+
+ P2P_TRACE_API4 ("NFA_P2pGetLLCPConfig () link_miu:%d, opt:0x%02X, wt:%d, link_timeout:%d",
+ *p_link_miu, *p_opt, *p_wt, *p_link_timeout);
+ P2P_TRACE_API4 (" inact_timeout(init:%d, target:%d), symm_delay:%d, data_link_timeout:%d",
+ *p_inact_timeout_init, *p_inact_timeout_target, *p_symm_delay, *p_data_link_timeout);
+ P2P_TRACE_API1 ("delay_first_pdu_timeout:%d",*p_delay_first_pdu_timeout);
+}
+
+/*******************************************************************************
+**
+** Function NFA_P2pSetTraceLevel
+**
+** Description This function sets the trace level for P2P. If called with
+** a value of 0xFF, it simply returns the current trace level.
+**
+** Returns The new or current trace level
+**
+*******************************************************************************/
+UINT8 NFA_P2pSetTraceLevel (UINT8 new_level)
+{
+ if (new_level != 0xFF)
+ nfa_p2p_cb.trace_level = new_level;
+
+ return (nfa_p2p_cb.trace_level);
+}
diff --git a/src/nfa/p2p/nfa_p2p_main.c b/src/nfa/p2p/nfa_p2p_main.c
new file mode 100644
index 0000000..0b78e8e
--- /dev/null
+++ b/src/nfa/p2p/nfa_p2p_main.c
@@ -0,0 +1,877 @@
+/******************************************************************************
+ *
+ * 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 */
+#if NFA_DYNAMIC_MEMORY == FALSE
+tNFA_P2P_CB nfa_p2p_cb;
+#endif
+
+/*****************************************************************************
+** Static Functions
+*****************************************************************************/
+
+/* event handler function type */
+static BOOLEAN nfa_p2p_evt_hdlr (BT_HDR *p_msg);
+
+/* disable function type */
+static void nfa_p2p_sys_disable (void);
+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 BOOLEAN (*tNFA_P2P_ACTION) (tNFA_P2P_MSG *p_data);
+
+/* action function list */
+const tNFA_P2P_ACTION nfa_p2p_action[] =
+{
+ nfa_p2p_reg_server, /* NFA_P2P_API_REG_SERVER_EVT */
+ nfa_p2p_reg_client, /* NFA_P2P_API_REG_CLIENT_EVT */
+ nfa_p2p_dereg, /* NFA_P2P_API_DEREG_EVT */
+ nfa_p2p_accept_connection, /* NFA_P2P_API_ACCEPT_CONN_EVT */
+ nfa_p2p_reject_connection, /* NFA_P2P_API_REJECT_CONN_EVT */
+ nfa_p2p_disconnect, /* NFA_P2P_API_DISCONNECT_EVT */
+ nfa_p2p_create_data_link_connection, /* NFA_P2P_API_CONNECT_EVT */
+ nfa_p2p_send_ui, /* NFA_P2P_API_SEND_UI_EVT */
+ nfa_p2p_send_data, /* NFA_P2P_API_SEND_DATA_EVT */
+ nfa_p2p_set_local_busy, /* NFA_P2P_API_SET_LOCAL_BUSY_EVT */
+ nfa_p2p_get_link_info, /* NFA_P2P_API_GET_LINK_INFO_EVT */
+ nfa_p2p_get_remote_sap, /* NFA_P2P_API_GET_REMOTE_SAP_EVT */
+ nfa_p2p_set_llcp_cfg, /* NFA_P2P_API_SET_LLCP_CFG_EVT */
+ 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)
+{
+ 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;
+ BT_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(NFC_NXP_NOT_OPEN_INCLUDED == 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 == 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 */
+ if ((p_msg = (BT_HDR *) GKI_getbuf (sizeof(BT_HDR))) != 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 event, UINT8 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 ();
+
+ nfa_dm_act_conn_cback_notify (NFA_LLCP_ACTIVATED_EVT, (tNFA_CONN_EVT_DATA *) &llcp_activated);
+
+ }
+ else if (event == LLCP_LINK_ACTIVATION_FAILED_EVT)
+ {
+ nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_IDLE;
+
+ if (nfa_p2p_cb.is_initiator)
+ {
+ /* notify NFA DM to send Activate Event to applicaiton with status */
+ nfa_dm_notify_activation_status (NFA_STATUS_FAILED, NULL);
+ }
+
+ nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_DISCOVERY);
+ }
+ else 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, (tNFA_CONN_EVT_DATA *)&llcp_deactivated);
+
+ if (reason != LLCP_LINK_RF_LINK_LOSS_ERR) /* if NFC link is still up */
+ {
+ if (nfa_p2p_cb.is_initiator)
+ {
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ /*For LLCP DTA test, Deactivate to Sleep is needed to send DSL_REQ*/
+ if((appl_dta_mode_flag == 1) && (nfa_dm_cb.eDtaMode == NFA_DTA_LLCP_MODE))
+ {
+ nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_SLEEP);
+ }
+ else
+ {
+#endif
+ nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_DISCOVERY);
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 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 wt, gen_bytes_len = LLCP_MAX_GEN_BYTES;
+ UINT8 params[LLCP_MAX_GEN_BYTES + 5], *p, length;
+
+ P2P_TRACE_DEBUG0 ("nfa_p2p_set_config ()");
+
+ LLCP_GetDiscoveryConfig (&wt, params + 2, &gen_bytes_len);
+ if (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, BOOLEAN update_wks)
+{
+ tNFA_DM_DISC_TECH_PROTO_MASK p2p_listen_mask = 0;
+
+ P2P_TRACE_DEBUG2 ("nfa_p2p_enable_listening () sys_id = %d, update_wks = %d",
+ sys_id, update_wks);
+
+ if (sys_id == NFA_ID_P2P)
+ nfa_p2p_cb.is_p2p_listening = TRUE;
+ else if (sys_id == NFA_ID_CHO)
+ nfa_p2p_cb.is_cho_listening = TRUE;
+ else if (sys_id == NFA_ID_SNEP)
+ nfa_p2p_cb.is_snep_listening = TRUE;
+
+ if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID)
+ {
+ /* if need to update WKS in LLCP Gen bytes */
+ if (update_wks)
+ {
+ /* update LLCP Gen Bytes */
+ nfa_p2p_set_config (NFA_DM_DISC_MASK_PA_NFC_DEP|NFA_DM_DISC_MASK_LA_NFC_DEP);
+ }
+ return;
+ }
+
+ /* collect listen technologies with NFC-DEP protocol */
+ if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_A)
+ p2p_listen_mask |= NFA_DM_DISC_MASK_LA_NFC_DEP;
+
+ if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_F)
+ p2p_listen_mask |= NFA_DM_DISC_MASK_LF_NFC_DEP;
+
+ if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_A_ACTIVE)
+ p2p_listen_mask |= NFA_DM_DISC_MASK_LAA_NFC_DEP;
+
+ if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_F_ACTIVE)
+ p2p_listen_mask |= NFA_DM_DISC_MASK_LFA_NFC_DEP;
+
+ if (p2p_listen_mask)
+ {
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 == 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, BOOLEAN update_wks)
+{
+
+ P2P_TRACE_DEBUG2 ("nfa_p2p_disable_listening () sys_id = %d, update_wks = %d",
+ sys_id, update_wks);
+
+ if (sys_id == NFA_ID_P2P)
+ nfa_p2p_cb.is_p2p_listening = FALSE;
+ else if (sys_id == NFA_ID_CHO)
+ nfa_p2p_cb.is_cho_listening = FALSE;
+ else if (sys_id == NFA_ID_SNEP)
+ nfa_p2p_cb.is_snep_listening = FALSE;
+
+ if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID)
+ {
+ if ( (nfa_p2p_cb.is_p2p_listening == FALSE)
+ &&(nfa_p2p_cb.is_cho_listening == FALSE)
+ &&(nfa_p2p_cb.is_snep_listening == FALSE) )
+ {
+ nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_IDLE;
+ nfa_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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ || appl_dta_mode_flag
+#endif
+ )
+ nfa_p2p_enable_listening (NFA_ID_P2P, FALSE);
+ else if (nfa_p2p_cb.is_cho_listening)
+ nfa_p2p_enable_listening (NFA_ID_CHO, FALSE);
+ else if (nfa_p2p_cb.is_snep_listening)
+ nfa_p2p_enable_listening (NFA_ID_SNEP, FALSE);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_p2p_evt_hdlr
+**
+** Description Processing event for NFA P2P
+**
+**
+** Returns TRUE if p_msg needs to be deallocated
+**
+*******************************************************************************/
+static BOOLEAN nfa_p2p_evt_hdlr (BT_HDR *p_hdr)
+{
+ BOOLEAN delete_msg = TRUE;
+ UINT16 event;
+
+ tNFA_P2P_MSG *p_msg = (tNFA_P2P_MSG *)p_hdr;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ P2P_TRACE_DEBUG2 ("nfa_p2p_evt_hdlr (): LLCP State [%s], Event [%s]",
+ nfa_p2p_llcp_state_code (nfa_p2p_cb.llcp_state),
+ nfa_p2p_evt_code (p_msg->hdr.event));
+#else
+ P2P_TRACE_DEBUG2 ("nfa_p2p_evt_hdlr (): State 0x%02x, Event 0x%02x",
+ nfa_p2p_cb.llcp_state, p_msg->hdr.event);
+#endif
+
+ event = p_msg->hdr.event & 0x00ff;
+
+ /* execute action functions */
+ if (event < NFA_P2P_NUM_ACTIONS)
+ {
+ delete_msg = (*nfa_p2p_action[event]) (p_msg);
+ }
+ else
+ {
+ P2P_TRACE_ERROR0 ("Unhandled event");
+ }
+
+ return delete_msg;
+}
+
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function nfa_p2p_llcp_state_code
+**
+** Description
+**
+** Returns string of state
+**
+*******************************************************************************/
+static char *nfa_p2p_llcp_state_code (tNFA_P2P_LLCP_STATE state_code)
+{
+ switch (state_code)
+ {
+ case NFA_P2P_LLCP_STATE_IDLE:
+ return "Link IDLE";
+ case NFA_P2P_LLCP_STATE_LISTENING:
+ return "Link LISTENING";
+ case NFA_P2P_LLCP_STATE_ACTIVATED:
+ return "Link ACTIVATED";
+ default:
+ return "Unknown state";
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_p2p_evt_code
+**
+** Description
+**
+** Returns string of event
+**
+*******************************************************************************/
+char *nfa_p2p_evt_code (UINT16 evt_code)
+{
+ switch (evt_code)
+ {
+ case NFA_P2P_API_REG_SERVER_EVT:
+ return "API_REG_SERVER";
+ case NFA_P2P_API_REG_CLIENT_EVT:
+ return "API_REG_CLIENT";
+ case NFA_P2P_API_DEREG_EVT:
+ return "API_DEREG";
+ case NFA_P2P_API_ACCEPT_CONN_EVT:
+ return "API_ACCEPT_CONN";
+ case NFA_P2P_API_REJECT_CONN_EVT:
+ return "API_REJECT_CONN";
+ case NFA_P2P_API_DISCONNECT_EVT:
+ return "API_DISCONNECT";
+ case NFA_P2P_API_CONNECT_EVT:
+ return "API_CONNECT";
+ case NFA_P2P_API_SEND_UI_EVT:
+ return "API_SEND_UI";
+ case NFA_P2P_API_SEND_DATA_EVT:
+ return "API_SEND_DATA";
+ case NFA_P2P_API_SET_LOCAL_BUSY_EVT:
+ return "API_SET_LOCAL_BUSY";
+ case NFA_P2P_API_GET_LINK_INFO_EVT:
+ return "API_GET_LINK_INFO";
+ case NFA_P2P_API_GET_REMOTE_SAP_EVT:
+ return "API_GET_REMOTE_SAP";
+ case NFA_P2P_API_SET_LLCP_CFG_EVT:
+ return "API_SET_LLCP_CFG_EVT";
+ 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..f171fcb
--- /dev/null
+++ b/src/nfa/rw/nfa_rw_act.c
@@ -0,0 +1,3310 @@
+/******************************************************************************
+ *
+ * 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(BOOLEAN b_hard_lock);
+static BOOLEAN nfa_rw_op_req_while_busy(tNFA_RW_MSG *p_data);
+static void nfa_rw_error_cleanup (UINT8 event);
+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 BOOLEAN 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 *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 *)(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 *)(p_rw_data->data.p_data + 1) + p_rw_data->data.p_data->offset;
+ conn_evt_data.data.len = p_rw_data->data.p_data->len;
+
+ nfa_dm_act_conn_cback_notify(NFA_DATA_EVT, &conn_evt_data);
+
+ GKI_freebuf(p_rw_data->data.p_data);
+ p_rw_data->data.p_data = NULL;
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_error_cleanup
+**
+** Description Handle failure - signal command complete and notify app
+**
+** Returns Nothing
+**
+*******************************************************************************/
+static void nfa_rw_error_cleanup (UINT8 event)
+{
+ tNFA_CONN_EVT_DATA conn_evt_data;
+
+ nfa_rw_command_complete();
+
+ conn_evt_data.status = NFA_STATUS_FAILED;
+
+ nfa_dm_act_conn_cback_notify (event, &conn_evt_data);
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_check_start_presence_check_timer
+**
+** Description Start timer to wait for specified time before presence check
+**
+** Returns Nothing
+**
+*******************************************************************************/
+static void nfa_rw_check_start_presence_check_timer (UINT16 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;
+
+ 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 */
+ if ((conn_evt_data.status = nfa_rw_start_ndef_read()) != NFA_STATUS_OK)
+ {
+ /* Failed to start NDEF Read */
+
+ /* Command complete - perform cleanup, notify app */
+ nfa_rw_command_complete();
+ nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+ }
+ }
+ else if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF)
+ {
+ /* if ndef detection was done as part of ndef-write operation, then perform ndef write now */
+ if ((conn_evt_data.status = nfa_rw_start_ndef_write()) != NFA_STATUS_OK)
+ {
+ /* Failed to start NDEF Write. */
+
+ /* Command complete - perform cleanup, notify app */
+ nfa_rw_command_complete();
+ nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
+ }
+ }
+ else
+ {
+ /* current op was stand-alone NFA_DetectNDef. Command complete - perform cleanup and notify app */
+ nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
+ nfa_rw_command_complete();
+
+ nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data);
+ }
+ }
+ else
+ {
+ /* NDEF detection failed... */
+
+ /* Command complete - perform cleanup, notify app */
+ nfa_rw_command_complete();
+ nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_FALSE;
+ 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;
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ conn_evt_data.ndef_detect.status = NFA_STATUS_TIMEOUT;
+#endif
+ }
+ else
+ {
+ /* NDEF Detection failed for other reasons */
+ conn_evt_data.ndef_detect.cur_size = nfa_rw_cb.ndef_cur_size = p_rw_data->ndef.cur_size;
+ conn_evt_data.ndef_detect.max_size = nfa_rw_cb.ndef_max_size = p_rw_data->ndef.max_size;
+ conn_evt_data.ndef_detect.flags = p_rw_data->ndef.flags;
+ }
+ nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data);
+ }
+
+ nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_handle_tlv_detect
+**
+** Description Handler for TLV detection reader/writer event
+**
+** Returns Nothing
+**
+*******************************************************************************/
+static void nfa_rw_handle_tlv_detect(tRW_EVENT event, tRW_DATA *p_rw_data)
+{
+ tNFA_CONN_EVT_DATA conn_evt_data;
+
+ /* Set TLV detection state */
+ if (nfa_rw_cb.cur_op == NFA_RW_OP_SET_TAG_RO)
+ {
+ if(nfa_rw_cb.tlv_st == NFA_RW_TLV_DETECT_ST_OP_NOT_STARTED)
+ {
+ nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_LOCK_TLV_OP_COMPLETE;
+ }
+ else
+ {
+ nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE;
+ }
+ }
+ else
+ {
+ if(nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_LOCK_TLV)
+ {
+ nfa_rw_cb.tlv_st |= NFA_RW_TLV_DETECT_ST_LOCK_TLV_OP_COMPLETE;
+ }
+ else if(nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_MEM_TLV)
+ {
+ nfa_rw_cb.tlv_st |= NFA_RW_TLV_DETECT_ST_MEM_TLV_OP_COMPLETE;
+ }
+ }
+
+ /* Check if TLV detection succeeded */
+ if (p_rw_data->tlv.status == NFC_STATUS_OK)
+ {
+ NFA_TRACE_DEBUG1("TLV Detection succeeded: num_bytes=%i",p_rw_data->tlv.num_bytes);
+
+ /* Store tlv properties */
+ conn_evt_data.tlv_detect.status = NFA_STATUS_OK;
+ conn_evt_data.tlv_detect.protocol = p_rw_data->tlv.protocol;
+ conn_evt_data.tlv_detect.num_bytes = p_rw_data->tlv.num_bytes;
+
+
+ /* Determine what operation triggered the TLV detection procedure */
+ if(nfa_rw_cb.cur_op == NFA_RW_OP_SET_TAG_RO)
+ {
+ if (nfa_rw_config_tag_ro(nfa_rw_cb.b_hard_lock) != NFC_STATUS_OK)
+ {
+ /* Failed to set tag read only */
+ conn_evt_data.tlv_detect.status = NFA_STATUS_FAILED;
+ nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
+ }
+ }
+ else
+ {
+ /* current op was stand-alone NFA_DetectTlv. Command complete - perform cleanup and notify app */
+ nfa_rw_command_complete();
+ nfa_dm_act_conn_cback_notify(NFA_TLV_DETECT_EVT, &conn_evt_data);
+ }
+ }
+
+ /* Handle failures */
+ if (p_rw_data->tlv.status != NFC_STATUS_OK)
+ {
+ /* Command complete - perform cleanup, notify the app */
+ nfa_rw_command_complete();
+
+ conn_evt_data.tlv_detect.status = NFA_STATUS_FAILED;
+ if( (nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_LOCK_TLV)
+ ||(nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_MEM_TLV) )
+ {
+ nfa_dm_act_conn_cback_notify(NFA_TLV_DETECT_EVT, &conn_evt_data);
+ }
+ else if(nfa_rw_cb.cur_op == NFA_RW_OP_SET_TAG_RO)
+ {
+ if (nfa_rw_config_tag_ro(nfa_rw_cb.b_hard_lock) != NFC_STATUS_OK)
+ {
+ /* Failed to set tag read only */
+ conn_evt_data.tlv_detect.status = NFA_STATUS_FAILED;
+ nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
+ }
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_handle_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)
+{
+ BT_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, (tNFA_CONN_EVT_DATA *)&status);
+ GKI_freebuf(nfa_rw_cb.p_pending_msg);
+ nfa_rw_cb.p_pending_msg = NULL;
+ }
+ /* For all other APIs called during auto-presence check, perform the command now (if tag is still present) */
+ else if (status == NFC_STATUS_OK)
+ {
+ NFA_TRACE_DEBUG0("Performing deferred operation after presence check...");
+ p_pending_msg = (BT_HDR *)nfa_rw_cb.p_pending_msg;
+ nfa_rw_cb.p_pending_msg = NULL;
+ nfa_rw_handle_event(p_pending_msg);
+ 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, (tNFA_CONN_EVT_DATA *)&status);
+
+ /* If in normal mode (not-exclusive RF mode) then deactivate the link if presence check failed */
+ if ((nfa_rw_cb.flags & NFA_RW_FL_NOT_EXCL_RF_MODE) && (status != NFC_STATUS_OK))
+ {
+ NFA_TRACE_DEBUG0("Presence check failed. Deactivating...");
+ nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_DISCOVERY);
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_handle_t1t_evt
+**
+** Description Handler for Type-1 tag reader/writer events
+**
+** Returns Nothing
+**
+*******************************************************************************/
+static void nfa_rw_handle_t1t_evt (tRW_EVENT event, tRW_DATA *p_rw_data)
+{
+ tNFA_CONN_EVT_DATA conn_evt_data;
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ tNFA_TAG_PARAMS tag_params;
+ UINT8 *p_rid_rsp;
+ tNFA_STATUS activation_status;
+#endif
+
+ conn_evt_data.status = p_rw_data->data.status;
+ switch (event)
+ {
+ case RW_T1T_RID_EVT:
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ if(p_rw_data->data.p_data != NULL)
+ {
+ /* Assume the data is just the response byte sequence */
+ p_rid_rsp = (UINT8 *) (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);
+ }
+ /* 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;
+#endif
+ 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) */
+ if ((p_rw_data->status = nfa_dm_disc_sleep_wakeup ()) == 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;
+ }
+
+ nfa_dm_notify_activation_status(NFA_STATUS_OK, &tag_params);
+ break;
+
+ case RW_T3T_FORMAT_CPLT_EVT: /* Format completed */
+ /* Command complete - perform cleanup, notify the app */
+ nfa_rw_command_complete();
+
+ /* Notify app */
+ conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED;
+
+ /* Notify app of ndef write complete status */
+ nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data);
+ break;
+
+
+ case RW_T3T_INTF_ERROR_EVT:
+ conn_evt_data.status = p_rw_data->status;
+ nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data);
+ break;
+
+ 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;
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ 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;
+
+ 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(NFC_NXP_NOT_OPEN_INCLUDED == 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 *)(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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+static void nfa_rw_handle_t3bt_evt (tRW_EVENT event, tRW_DATA *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(NFC_NXP_NOT_OPEN_INCLUDED == 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;
+
+ switch (protocol)
+ {
+ case NFC_PROTOCOL_T1T: /* Type1Tag - NFC-A */
+ status = RW_T1tDetectNDef();
+ break;
+
+ case NFC_PROTOCOL_T2T: /* Type2Tag - NFC-A */
+ if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
+ {
+ status = RW_T2tDetectNDef(nfa_rw_cb.skip_dyn_locks);
+ }
+ break;
+
+ case NFC_PROTOCOL_T3T: /* Type3Tag - NFC-F */
+ status = RW_T3tDetectNDef();
+ break;
+
+ case NFC_PROTOCOL_ISO_DEP: /* ISODEP/4A,4B- NFC-A or NFC-B */
+ status = RW_T4tDetectNDef();
+ break;
+
+ case NFC_PROTOCOL_15693: /* ISO 15693 */
+ status = RW_I93DetectNDef();
+ break;
+
+ default:
+ break;
+ }
+
+ return(status);
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_start_ndef_read
+**
+** Description Start NDEF read on activated tag
+**
+** Returns Nothing
+**
+*******************************************************************************/
+static tNFC_STATUS nfa_rw_start_ndef_read(void)
+{
+ tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ tNFA_CONN_EVT_DATA conn_evt_data;
+
+ /* Handle zero length NDEF message */
+ if (nfa_rw_cb.ndef_cur_size == 0)
+ {
+ NFA_TRACE_DEBUG0("NDEF message is zero-length");
+
+ /* Send zero-lengh NDEF message to ndef callback */
+ nfa_dm_ndef_handle_message(NFA_STATUS_OK, NULL, 0);
+
+ /* Command complete - perform cleanup, notify app */
+ nfa_rw_command_complete();
+ conn_evt_data.status = NFA_STATUS_OK;
+ nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+ return NFC_STATUS_OK;
+ }
+
+ /* Allocate buffer for incoming NDEF message (free previous NDEF rx buffer, if needed) */
+ nfa_rw_free_ndef_rx_buf ();
+ if ((nfa_rw_cb.p_ndef_buf = (UINT8 *)nfa_mem_co_alloc(nfa_rw_cb.ndef_cur_size)) == NULL)
+ {
+ NFA_TRACE_ERROR1("Unable to allocate a buffer for reading NDEF (size=%i)", nfa_rw_cb.ndef_cur_size);
+
+ /* Command complete - perform cleanup, notify app */
+ nfa_rw_command_complete();
+ conn_evt_data.status = NFA_STATUS_FAILED;
+ nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+ return NFC_STATUS_FAILED;
+ }
+ nfa_rw_cb.ndef_rd_offset = 0;
+
+ switch (protocol)
+ {
+ case NFC_PROTOCOL_T1T: /* Type1Tag - NFC-A */
+ status = RW_T1tReadNDef(nfa_rw_cb.p_ndef_buf,(UINT16)nfa_rw_cb.ndef_cur_size);
+ break;
+
+ case NFC_PROTOCOL_T2T: /* Type2Tag - NFC-A */
+ if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
+ {
+ status = RW_T2tReadNDef(nfa_rw_cb.p_ndef_buf,(UINT16)nfa_rw_cb.ndef_cur_size);
+ }
+ break;
+
+ case NFC_PROTOCOL_T3T: /* Type3Tag - NFC-F */
+ status = RW_T3tCheckNDef();
+ break;
+
+ case NFC_PROTOCOL_ISO_DEP: /* ISODEP/4A,4B- NFC-A or NFC-B */
+ status = RW_T4tReadNDef();
+ break;
+
+ case NFC_PROTOCOL_15693: /* ISO 15693 */
+ status = RW_I93ReadNDef();
+ break;
+
+ default:
+ break;
+ }
+ return(status);
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_detect_ndef
+**
+** Description Handler for NFA_RW_API_DETECT_NDEF_EVT
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_detect_ndef(tNFA_RW_MSG *p_data)
+{
+ tNFA_CONN_EVT_DATA conn_evt_data;
+ NFA_TRACE_DEBUG0("nfa_rw_detect_ndef");
+
+ if ((conn_evt_data.ndef_detect.status = nfa_rw_start_ndef_detection()) != NFC_STATUS_OK)
+ {
+ /* Command complete - perform cleanup, notify app */
+ nfa_rw_command_complete();
+ conn_evt_data.ndef_detect.cur_size = 0;
+ conn_evt_data.ndef_detect.max_size = 0;
+ conn_evt_data.ndef_detect.flags = RW_NDEF_FL_UNKNOWN;
+ nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data);
+ }
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_start_ndef_write
+**
+** Description Start NDEF write on activated tag
+**
+** Returns Nothing
+**
+*******************************************************************************/
+static tNFC_STATUS nfa_rw_start_ndef_write(void)
+{
+ tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+
+ if (nfa_rw_cb.flags & NFA_RW_FL_TAG_IS_READONLY)
+ {
+ /* error: ndef tag is read-only */
+ status = NFC_STATUS_FAILED;
+ NFA_TRACE_ERROR0("Unable to write NDEF. Tag is read-only")
+ }
+ else if (nfa_rw_cb.ndef_max_size < nfa_rw_cb.ndef_wr_len)
+ {
+ /* error: ndef tag size is too small */
+ status = NFC_STATUS_BUFFER_FULL;
+ NFA_TRACE_ERROR2("Unable to write NDEF. Tag maxsize=%i, request write size=%i", nfa_rw_cb.ndef_max_size, nfa_rw_cb.ndef_wr_len)
+ }
+ else
+ {
+ switch (protocol)
+ {
+ case NFC_PROTOCOL_T1T: /* Type1Tag - NFC-A */
+ status = RW_T1tWriteNDef((UINT16)nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf);
+ break;
+
+ case NFC_PROTOCOL_T2T: /* Type2Tag - NFC-A */
+
+ if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
+ {
+ status = RW_T2tWriteNDef((UINT16)nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf);
+ }
+ break;
+
+ case NFC_PROTOCOL_T3T: /* Type3Tag - NFC-F */
+ status = RW_T3tUpdateNDef(nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf);
+ break;
+
+ case NFC_PROTOCOL_ISO_DEP: /* ISODEP/4A,4B- NFC-A or NFC-B */
+ status = RW_T4tUpdateNDef((UINT16)nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf);
+ break;
+
+ case NFC_PROTOCOL_15693: /* ISO 15693 */
+ status = RW_I93UpdateNDef((UINT16)nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return(status);
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_read_ndef
+**
+** Description Handler for NFA_RW_API_READ_NDEF_EVT
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_read_ndef(tNFA_RW_MSG *p_data)
+{
+ tNFA_STATUS status = NFA_STATUS_OK;
+ tNFA_CONN_EVT_DATA conn_evt_data;
+
+ NFA_TRACE_DEBUG0("nfa_rw_read_ndef");
+
+ /* Check if ndef detection has been performed yet */
+ if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_UNKNOWN)
+ {
+ /* Perform ndef detection first */
+ status = nfa_rw_start_ndef_detection();
+ }
+ else if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_FALSE)
+ {
+ /* Tag is not NDEF */
+ status = NFA_STATUS_FAILED;
+ }
+ else
+ {
+ /* Perform the NDEF read operation */
+ status = nfa_rw_start_ndef_read();
+ }
+
+ /* Handle failure */
+ if (status != NFA_STATUS_OK)
+ {
+ /* Command complete - perform cleanup, notify app */
+ nfa_rw_command_complete();
+ conn_evt_data.status = status;
+ nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+ }
+
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_write_ndef
+**
+** Description Handler for NFA_RW_API_WRITE_NDEF_EVT
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_write_ndef(tNFA_RW_MSG *p_data)
+{
+ tNDEF_STATUS ndef_status;
+ tNFA_STATUS write_status = NFA_STATUS_OK;
+ tNFA_CONN_EVT_DATA conn_evt_data;
+ NFA_TRACE_DEBUG0("nfa_rw_write_ndef");
+
+ /* Validate NDEF message */
+ if ((ndef_status = NDEF_MsgValidate(p_data->op_req.params.write_ndef.p_data, p_data->op_req.params.write_ndef.len, FALSE)) != NDEF_OK)
+ {
+ NFA_TRACE_ERROR1("Invalid NDEF message. NDEF_MsgValidate returned %i", ndef_status);
+
+ /* Command complete - perform cleanup, notify app */
+ nfa_rw_command_complete();
+ conn_evt_data.status = NFA_STATUS_FAILED;
+ nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
+ return TRUE;
+ }
+
+ /* Store pointer to source NDEF */
+ nfa_rw_cb.p_ndef_wr_buf = p_data->op_req.params.write_ndef.p_data;
+ nfa_rw_cb.ndef_wr_len = p_data->op_req.params.write_ndef.len;
+
+ /* Check if ndef detection has been performed yet */
+ if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_UNKNOWN)
+ {
+ /* Perform ndef detection first */
+ write_status = nfa_rw_start_ndef_detection();
+ }
+ else if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_FALSE)
+ {
+ 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 sel_res = nfa_rw_cb.pa_sel_res;
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ BOOLEAN unsupported = FALSE;
+ UINT8 option = NFA_RW_OPTION_INVALID;
+ tNFA_RW_PRES_CHK_OPTION op_param = NFA_RW_PRES_CHK_DEFAULT;
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ UINT16 iso_15693_max_presence_check_timeout = NFA_DM_ISO_15693_MAX_PRESENCE_CHECK_TIMEOUT + RW_I93_MAX_RSP_TIMEOUT;
+#endif
+ switch (protocol)
+ {
+ case NFC_PROTOCOL_T1T: /* Type1Tag - NFC-A */
+ status = RW_T1tPresenceCheck();
+ break;
+
+ case NFC_PROTOCOL_T3T: /* Type3Tag - NFC-F */
+ status = RW_T3tPresenceCheck();
+ break;
+
+ case NFC_PROTOCOL_ISO_DEP: /* ISODEP/4A,4B- NFC-A or NFC-B */
+ 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;
+
+ 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;
+ }
+
+
+ break;
+
+ case NFC_PROTOCOL_15693: /* ISO 15693 */
+ status = RW_I93PresenceCheck();
+ break;
+
+ case NFC_PROTOCOL_T2T: /* Type2Tag - NFC-A */
+ /* If T2T NFC-Forum, then let RW handle presence check; otherwise fall through */
+ if (sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
+ {
+ /* Type 2 tag have not sent NACK after activation */
+ status = RW_T2tPresenceCheck();
+ break;
+ }
+
+ default:
+ /* Protocol unsupported by RW module... */
+ unsupported = TRUE;
+ break;
+ }
+
+ 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(NFC_NXP_NOT_OPEN_INCLUDED == 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)
+**
+*******************************************************************************/
+BOOLEAN nfa_rw_presence_check_tick(tNFA_RW_MSG *p_data)
+{
+ /* Store the current operation */
+ nfa_rw_cb.cur_op = NFA_RW_OP_PRESENCE_CHECK;
+ nfa_rw_cb.flags |= NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY;
+ NFA_TRACE_DEBUG0("Auto-presence check starting...");
+
+ /* Perform presence check */
+ nfa_rw_presence_check(NULL);
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_presence_check_timeout
+**
+** Description presence check timeout: report presence check failure
+**
+** Returns TRUE (caller frees message buffer)
+**
+*******************************************************************************/
+BOOLEAN nfa_rw_presence_check_timeout (tNFA_RW_MSG *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;
+
+ if (protocol == NFC_PROTOCOL_T1T)
+ {
+ status = RW_T1tFormatNDef();
+ }
+ else if ( (protocol == NFC_PROTOCOL_T2T)
+ &&(nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) )
+ {
+ status = RW_T2tFormatNDef();
+ }
+ else if (protocol == NFC_PROTOCOL_T3T)
+ {
+ status = RW_T3tFormatNDef();
+ }
+ else if (protocol == NFC_PROTOCOL_15693)
+ {
+ status = RW_I93FormatNDef();
+ }
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ else if (protocol == NFC_PROTOCOL_ISO_DEP)
+ {
+ status = RW_T4tFormatNDef();
+ }
+#endif
+ /* If unable to format NDEF, notify the app */
+ if (status != NFC_STATUS_OK)
+ nfa_rw_error_cleanup (NFA_FORMAT_CPLT_EVT);
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_detect_tlv
+**
+** Description Handler for NFA_RW_API_DETECT_NDEF_EVT
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_detect_tlv (tNFA_RW_MSG *p_data, UINT8 tlv)
+{
+ NFA_TRACE_DEBUG0("nfa_rw_detect_tlv");
+
+ switch (nfa_rw_cb.protocol)
+ {
+ case NFC_PROTOCOL_T1T:
+ if (RW_T1tLocateTlv(tlv) != NFC_STATUS_OK)
+ nfa_rw_error_cleanup (NFA_TLV_DETECT_EVT);
+ break;
+
+ case NFC_PROTOCOL_T2T:
+ if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
+ {
+ if (RW_T2tLocateTlv(tlv) != NFC_STATUS_OK)
+ nfa_rw_error_cleanup (NFA_TLV_DETECT_EVT);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_config_tag_ro
+**
+** Description Handler for NFA_RW_OP_SET_TAG_RO
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static tNFC_STATUS nfa_rw_config_tag_ro (BOOLEAN b_hard_lock)
+{
+ tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+
+ NFA_TRACE_DEBUG0 ("nfa_rw_config_tag_ro ()");
+
+ switch (protocol)
+ {
+ case NFC_PROTOCOL_T1T:
+ if( (nfa_rw_cb.tlv_st == NFA_RW_TLV_DETECT_ST_OP_NOT_STARTED)
+ ||(nfa_rw_cb.tlv_st == NFA_RW_TLV_DETECT_ST_MEM_TLV_OP_COMPLETE) )
+ {
+ status = RW_T1tLocateTlv(TAG_LOCK_CTRL_TLV);
+ return (status);
+ }
+ else
+ {
+ status = RW_T1tSetTagReadOnly(b_hard_lock);
+ }
+ break;
+
+ case NFC_PROTOCOL_T2T:
+ if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
+ {
+ status = RW_T2tSetTagReadOnly(b_hard_lock);
+ }
+ break;
+
+ case NFC_PROTOCOL_T3T:
+ status = RW_T3tSetReadOnly(b_hard_lock);
+ break;
+
+ case NFC_PROTOCOL_ISO_DEP:
+ status = RW_T4tSetNDefReadOnly();
+ break;
+
+ case NFC_PROTOCOL_15693:
+ status = RW_I93SetTagReadOnly();
+ break;
+
+ default:
+ break;
+
+ }
+
+ 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 BOOLEAN nfa_rw_t1t_rid(tNFA_RW_MSG *p_data)
+{
+ if (RW_T1tRid () != NFC_STATUS_OK)
+ nfa_rw_error_cleanup (NFA_READ_CPLT_EVT);
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_t1t_rall
+**
+** Description Handler for T1T_ReadAll API
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_t1t_rall(tNFA_RW_MSG *p_data)
+{
+ if (RW_T1tReadAll() != NFC_STATUS_OK)
+ nfa_rw_error_cleanup (NFA_READ_CPLT_EVT);
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_t1t_read
+**
+** Description Handler for T1T_Read API
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_t1t_read (tNFA_RW_MSG *p_data)
+{
+ tNFA_RW_OP_PARAMS_T1T_READ *p_t1t_read = (tNFA_RW_OP_PARAMS_T1T_READ *)&(p_data->op_req.params.t1t_read);
+
+ if (RW_T1tRead (p_t1t_read->block_number, p_t1t_read->index) != NFC_STATUS_OK)
+ nfa_rw_error_cleanup (NFA_READ_CPLT_EVT);
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_t1t_write
+**
+** Description Handler for T1T_WriteErase/T1T_WriteNoErase API
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_t1t_write (tNFA_RW_MSG *p_data)
+{
+ tNFA_RW_OP_PARAMS_T1T_WRITE *p_t1t_write = (tNFA_RW_OP_PARAMS_T1T_WRITE *)&(p_data->op_req.params.t1t_write);
+ tNFC_STATUS status;
+
+ if (p_t1t_write->b_erase)
+ {
+ status = RW_T1tWriteErase (p_t1t_write->block_number,p_t1t_write->index,p_t1t_write->p_block_data[0]);
+ }
+ else
+ {
+ status = RW_T1tWriteNoErase (p_t1t_write->block_number,p_t1t_write->index,p_t1t_write->p_block_data[0]);
+ }
+
+ if (status != NFC_STATUS_OK)
+ {
+ nfa_rw_error_cleanup (NFA_WRITE_CPLT_EVT);
+ }
+ else
+ {
+ if (p_t1t_write->block_number == 0x01)
+ nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
+ }
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_t1t_rseg
+**
+** Description Handler for T1t_ReadSeg API
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_t1t_rseg (tNFA_RW_MSG *p_data)
+{
+ tNFA_RW_OP_PARAMS_T1T_READ *p_t1t_read = (tNFA_RW_OP_PARAMS_T1T_READ *)&(p_data->op_req.params.t1t_read);
+
+ if (RW_T1tReadSeg (p_t1t_read->segment_number) != NFC_STATUS_OK)
+ nfa_rw_error_cleanup (NFA_READ_CPLT_EVT);
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_t1t_read8
+**
+** Description Handler for T1T_Read8 API
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_t1t_read8 (tNFA_RW_MSG *p_data)
+{
+ tNFA_RW_OP_PARAMS_T1T_READ *p_t1t_read = (tNFA_RW_OP_PARAMS_T1T_READ *)&(p_data->op_req.params.t1t_read);
+
+ if (RW_T1tRead8 (p_t1t_read->block_number) != NFC_STATUS_OK)
+ nfa_rw_error_cleanup (NFA_READ_CPLT_EVT);
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_t1t_write8
+**
+** Description Handler for T1T_WriteErase8/T1T_WriteNoErase8 API
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_t1t_write8 (tNFA_RW_MSG *p_data)
+{
+ tNFA_RW_OP_PARAMS_T1T_WRITE *p_t1t_write = (tNFA_RW_OP_PARAMS_T1T_WRITE *)&(p_data->op_req.params.t1t_write);
+ tNFC_STATUS status;
+
+ if (p_t1t_write->b_erase)
+ {
+ status = RW_T1tWriteErase8 (p_t1t_write->block_number,p_t1t_write->p_block_data);
+ }
+ else
+ {
+ status = RW_T1tWriteNoErase8 (p_t1t_write->block_number,p_t1t_write->p_block_data);
+ }
+
+ if (status != NFC_STATUS_OK)
+ {
+ nfa_rw_error_cleanup (NFA_WRITE_CPLT_EVT);
+ }
+ else
+ {
+ if (p_t1t_write->block_number == 0x01)
+ nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
+ }
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_t2t_read
+**
+** Description Handler for T2T_Read API
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_t2t_read (tNFA_RW_MSG *p_data)
+{
+ tNFA_RW_OP_PARAMS_T2T_READ *p_t2t_read = (tNFA_RW_OP_PARAMS_T2T_READ *)&(p_data->op_req.params.t2t_read);
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+
+ if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
+ status = RW_T2tRead (p_t2t_read->block_number);
+
+ if (status != NFC_STATUS_OK)
+ nfa_rw_error_cleanup (NFA_READ_CPLT_EVT);
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_t2t_write
+**
+** Description Handler for T2T_Write API
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_t2t_write (tNFA_RW_MSG *p_data)
+{
+ tNFA_RW_OP_PARAMS_T2T_WRITE *p_t2t_write = (tNFA_RW_OP_PARAMS_T2T_WRITE *)&(p_data->op_req.params.t2t_write);
+
+ if (RW_T2tWrite (p_t2t_write->block_number,p_t2t_write->p_block_data) != NFC_STATUS_OK)
+ {
+ nfa_rw_error_cleanup (NFA_WRITE_CPLT_EVT);
+ }
+ else
+ {
+ if (p_t2t_write->block_number == 0x03)
+ nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
+ }
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_t2t_sector_select
+**
+** Description Handler for T2T_Sector_Select API
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_t2t_sector_select(tNFA_RW_MSG *p_data)
+{
+ tNFA_RW_OP_PARAMS_T2T_SECTOR_SELECT *p_t2t_sector_select = (tNFA_RW_OP_PARAMS_T2T_SECTOR_SELECT *)&(p_data->op_req.params.t2t_sector_select);
+
+ if (RW_T2tSectorSelect (p_t2t_sector_select->sector_number) != NFC_STATUS_OK)
+ nfa_rw_error_cleanup (NFA_SELECT_CPLT_EVT);
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_t3t_read
+**
+** Description Handler for T3T_Read API
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_t3t_read (tNFA_RW_MSG *p_data)
+{
+ tNFA_RW_OP_PARAMS_T3T_READ *p_t3t_read = (tNFA_RW_OP_PARAMS_T3T_READ *)&(p_data->op_req.params.t3t_read);
+
+ if (RW_T3tCheck (p_t3t_read->num_blocks, (tT3T_BLOCK_DESC *)p_t3t_read->p_block_desc) != NFC_STATUS_OK)
+ nfa_rw_error_cleanup (NFA_READ_CPLT_EVT);
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_t3t_write
+**
+** Description Handler for T3T_Write API
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_t3t_write (tNFA_RW_MSG *p_data)
+{
+ tNFA_RW_OP_PARAMS_T3T_WRITE *p_t3t_write = (tNFA_RW_OP_PARAMS_T3T_WRITE *)&(p_data->op_req.params.t3t_write);
+
+ if (RW_T3tUpdate (p_t3t_write->num_blocks, (tT3T_BLOCK_DESC *)p_t3t_write->p_block_desc, p_t3t_write->p_block_data) != NFC_STATUS_OK)
+ nfa_rw_error_cleanup (NFA_WRITE_CPLT_EVT);
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_t3t_get_system_codes
+**
+** Description Get system codes (initiated by NFA after activation)
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_t3t_get_system_codes (tNFA_RW_MSG *p_data)
+{
+ tNFC_STATUS status;
+ tNFA_TAG_PARAMS tag_params;
+
+ status = RW_T3tGetSystemCodes();
+
+ if (status != NFC_STATUS_OK)
+ {
+ /* Command complete - perform cleanup, notify app */
+ nfa_rw_command_complete();
+ tag_params.t3t.num_system_codes = 0;
+ tag_params.t3t.p_system_codes = NULL;
+
+ nfa_dm_notify_activation_status (NFA_STATUS_OK, &tag_params);
+ }
+
+ return TRUE;
+}
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+static BOOLEAN nfa_rw_t3bt_get_pupi(tNFA_RW_MSG *p_data)
+{
+ tNFC_STATUS status;
+
+ 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 BOOLEAN nfa_rw_i93_command (tNFA_RW_MSG *p_data)
+{
+ tNFA_CONN_EVT_DATA conn_evt_data;
+ tNFC_STATUS status = NFC_STATUS_OK;
+ UINT8 i93_command = I93_CMD_STAY_QUIET;
+
+ switch (p_data->op_req.op)
+ {
+ case NFA_RW_OP_I93_INVENTORY:
+ i93_command = I93_CMD_INVENTORY;
+ if (p_data->op_req.params.i93_cmd.uid_present)
+ {
+ status = RW_I93Inventory (p_data->op_req.params.i93_cmd.afi_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)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)p_data->op_req.params.i93_cmd.first_block_number,
+ p_data->op_req.params.i93_cmd.number_blocks,
+ p_data->op_req.params.i93_cmd.p_data);
+ break;
+
+ case NFA_RW_OP_I93_SELECT:
+ i93_command = I93_CMD_SELECT;
+ status = RW_I93Select (p_data->op_req.params.i93_cmd.p_data);
+ break;
+
+ case NFA_RW_OP_I93_RESET_TO_READY:
+ i93_command = I93_CMD_RESET_TO_READY;
+ status = RW_I93ResetToReady ();
+ break;
+
+ case NFA_RW_OP_I93_WRITE_AFI:
+ i93_command = I93_CMD_WRITE_AFI;
+ status = RW_I93WriteAFI (p_data->op_req.params.i93_cmd.afi);
+ break;
+
+ case NFA_RW_OP_I93_LOCK_AFI:
+ i93_command = I93_CMD_LOCK_AFI;
+ status = RW_I93LockAFI ();
+ break;
+
+ case NFA_RW_OP_I93_WRITE_DSFID:
+ i93_command = I93_CMD_WRITE_DSFID;
+ status = RW_I93WriteDSFID (p_data->op_req.params.i93_cmd.dsfid);
+ break;
+
+ case NFA_RW_OP_I93_LOCK_DSFID:
+ i93_command = I93_CMD_LOCK_DSFID;
+ status = RW_I93LockDSFID ();
+ break;
+
+ case NFA_RW_OP_I93_GET_SYS_INFO:
+ i93_command = I93_CMD_GET_SYS_INFO;
+ if (p_data->op_req.params.i93_cmd.uid_present)
+ {
+ status = RW_I93GetSysInfo (p_data->op_req.params.i93_cmd.uid);
+ }
+ else
+ {
+ status = RW_I93GetSysInfo (NULL);
+ }
+ break;
+
+ case NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS:
+ i93_command = I93_CMD_GET_MULTI_BLK_SEC;
+ status = RW_I93GetMultiBlockSecurityStatus (p_data->op_req.params.i93_cmd.first_block_number,
+ p_data->op_req.params.i93_cmd.number_blocks);
+ break;
+
+ default:
+ break;
+ }
+
+ if (status != NFC_STATUS_OK)
+ {
+ /* Command complete - perform cleanup, notify app */
+ nfa_rw_command_complete();
+
+ conn_evt_data.i93_cmd_cplt.status = NFA_STATUS_FAILED;
+ conn_evt_data.i93_cmd_cplt.sent_command = i93_command;
+
+ nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data);
+ }
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_raw_mode_data_cback
+**
+** Description Handler for incoming tag data for unsupported tag protocols
+** (forward data to upper layer)
+**
+** Returns nothing
+**
+*******************************************************************************/
+static void nfa_rw_raw_mode_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
+{
+ BT_HDR *p_msg;
+ tNFA_CONN_EVT_DATA evt_data;
+
+ NFA_TRACE_DEBUG1 ("nfa_rw_raw_mode_data_cback(): event = 0x%X", event);
+
+ if ( (event == NFC_DATA_CEVT)
+ &&( (p_data->data.status == NFC_STATUS_OK)
+ ||(p_data->data.status == NFC_STATUS_CONTINUE) ) )
+ {
+ p_msg = (BT_HDR *)p_data->data.p_data;
+
+ if (p_msg)
+ {
+ evt_data.data.status = p_data->data.status;
+ evt_data.data.p_data = (UINT8 *)(p_msg + 1) + p_msg->offset;
+ evt_data.data.len = p_msg->len;
+
+ nfa_dm_conn_cback_event_notify (NFA_DATA_EVT, &evt_data);
+
+ GKI_freebuf (p_msg);
+ }
+ else
+ {
+ NFA_TRACE_ERROR0 ("nfa_rw_raw_mode_data_cback (): received NFC_DATA_CEVT with NULL data pointer");
+ }
+ }
+ else if (event == NFC_DEACTIVATE_CEVT)
+ {
+ NFC_SetStaticRfCback (NULL);
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function nfa_rw_activate_ntf
+**
+** Description Handler for NFA_RW_ACTIVATE_NTF
+**
+** Returns TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_rw_activate_ntf(tNFA_RW_MSG *p_data)
+{
+ tNFC_ACTIVATE_DEVT *p_activate_params = p_data->activate_ntf.p_activate_params;
+ tNFA_TAG_PARAMS tag_params;
+ tNFA_RW_OPERATION msg;
+ BOOLEAN activate_notify = TRUE;
+ UINT8 *p;
+
+ 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(NFC_NXP_NOT_OPEN_INCLUDED == 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 */
+ switch (nfa_rw_cb.protocol)
+ {
+ case NFC_PROTOCOL_T1T:
+ /* Retrieve HR and UID fields from activation notification */
+ memcpy (tag_params.t1t.hr, p_activate_params->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);
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ msg.op = NFA_RW_OP_T1T_RID;
+ nfa_rw_handle_op_req((tNFA_RW_MSG *)&msg);
+ activate_notify = FALSE; /* Delay notifying upper layer of NFA_ACTIVATED_EVT until HR0/HR1 is received */
+#endif
+ break;
+
+ case NFC_PROTOCOL_T2T:
+ /* Retrieve UID fields from activation notification */
+ memcpy (tag_params.t2t.uid, p_activate_params->rf_tech_param.param.pa.nfcid1, p_activate_params->rf_tech_param.param.pa.nfcid1_len);
+ break;
+
+ case NFC_PROTOCOL_T3T:
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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((tNFA_RW_MSG *)&msg);
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ }
+#endif
+ break;
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ case NFC_PROTOCOL_T3BT:
+ 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((tNFA_RW_MSG *)&msg);
+ break;
+#endif
+
+ case NFC_PROTOCOL_15693:
+ /* 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)(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;
+ }
+ }
+ break;
+
+
+ default:
+ /* No action needed for other protocols */
+ break;
+ }
+
+ /* Notify upper layer of NFA_ACTIVATED_EVT if needed, and start presence check timer */
+ if (activate_notify)
+ {
+ nfa_dm_notify_activation_status (NFA_STATUS_OK, &tag_params);
+ nfa_rw_check_start_presence_check_timer (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)
+**
+*******************************************************************************/
+BOOLEAN nfa_rw_deactivate_ntf(tNFA_RW_MSG *p_data)
+{
+ /* Clear the activated flag */
+ nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATED;
+
+ /* Free buffer for incoming NDEF message, in case we were in the middle of a read operation */
+ nfa_rw_free_ndef_rx_buf();
+
+ /* If there is a pending command message, then free it */
+ if (nfa_rw_cb.p_pending_msg)
+ {
+ 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
+**
+*******************************************************************************/
+BOOLEAN nfa_rw_handle_op_req (tNFA_RW_MSG *p_data)
+{
+ BOOLEAN freebuf = TRUE;
+ UINT16 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(NFC_NXP_NOT_OPEN_INCLUDED == 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 BOOLEAN nfa_rw_op_req_while_busy(tNFA_RW_MSG *p_data)
+{
+ BOOLEAN freebuf = TRUE;
+ tNFA_CONN_EVT_DATA conn_evt_data;
+ UINT8 event;
+
+ NFA_TRACE_ERROR0("nfa_rw_op_req_while_busy: unable to handle API");
+
+ /* Return appropriate event for requested API, with status=BUSY */
+ conn_evt_data.status = NFA_STATUS_BUSY;
+
+ switch (p_data->op_req.op)
+ {
+ case NFA_RW_OP_DETECT_NDEF:
+ conn_evt_data.ndef_detect.cur_size = 0;
+ conn_evt_data.ndef_detect.max_size = 0;
+ conn_evt_data.ndef_detect.flags = RW_NDEF_FL_UNKNOWN;
+ event = NFA_NDEF_DETECT_EVT;
+ break;
+ case NFA_RW_OP_READ_NDEF:
+ case NFA_RW_OP_T1T_RID:
+ case NFA_RW_OP_T1T_RALL:
+ case NFA_RW_OP_T1T_READ:
+ case NFA_RW_OP_T1T_RSEG:
+ case NFA_RW_OP_T1T_READ8:
+ case NFA_RW_OP_T2T_READ:
+ case NFA_RW_OP_T3T_READ:
+ event = NFA_READ_CPLT_EVT;
+ break;
+ case NFA_RW_OP_WRITE_NDEF:
+ case NFA_RW_OP_T1T_WRITE:
+ case NFA_RW_OP_T1T_WRITE8:
+ case NFA_RW_OP_T2T_WRITE:
+ case NFA_RW_OP_T3T_WRITE:
+ event = NFA_WRITE_CPLT_EVT;
+ break;
+ case NFA_RW_OP_FORMAT_TAG:
+ event = NFA_FORMAT_CPLT_EVT;
+ break;
+ case NFA_RW_OP_DETECT_LOCK_TLV:
+ case NFA_RW_OP_DETECT_MEM_TLV:
+ event = NFA_TLV_DETECT_EVT;
+ break;
+ case NFA_RW_OP_SET_TAG_RO:
+ event = NFA_SET_TAG_RO_EVT;
+ break;
+ case NFA_RW_OP_T2T_SECTOR_SELECT:
+ event = NFA_SELECT_CPLT_EVT;
+ break;
+ case NFA_RW_OP_I93_INVENTORY:
+ case NFA_RW_OP_I93_STAY_QUIET:
+ case NFA_RW_OP_I93_READ_SINGLE_BLOCK:
+ case NFA_RW_OP_I93_WRITE_SINGLE_BLOCK:
+ case NFA_RW_OP_I93_LOCK_BLOCK:
+ case NFA_RW_OP_I93_READ_MULTI_BLOCK:
+ case NFA_RW_OP_I93_WRITE_MULTI_BLOCK:
+ case NFA_RW_OP_I93_SELECT:
+ case NFA_RW_OP_I93_RESET_TO_READY:
+ case NFA_RW_OP_I93_WRITE_AFI:
+ case NFA_RW_OP_I93_LOCK_AFI:
+ case NFA_RW_OP_I93_WRITE_DSFID:
+ case NFA_RW_OP_I93_LOCK_DSFID:
+ case NFA_RW_OP_I93_GET_SYS_INFO:
+ case NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS:
+ event = NFA_I93_CMD_CPLT_EVT;
+ break;
+ default:
+ return (freebuf);
+ }
+ nfa_dm_act_conn_cback_notify(event, &conn_evt_data);
+
+ return (freebuf);
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_command_complete
+**
+** Description Handle command complete: clear the busy flag,
+** and start the presence check timer if applicable.
+**
+** Returns None
+**
+*******************************************************************************/
+void nfa_rw_command_complete(void)
+{
+ /* Clear the busy flag */
+ nfa_rw_cb.flags &= ~NFA_RW_FL_API_BUSY;
+
+ /* Restart presence_check timer */
+ nfa_rw_check_start_presence_check_timer (NFA_RW_PRESENCE_CHECK_INTERVAL);
+}
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 *p, UINT8 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..bdc689c
--- /dev/null
+++ b/src/nfa/rw/nfa_rw_api.c
@@ -0,0 +1,1505 @@
+/******************************************************************************
+ *
+ * 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");
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_DETECT_NDEF;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RwReadNDef
+**
+** Description Read NDEF message from tag. This function will internally
+** perform the NDEF detection procedure (if not performed
+** previously), and read the NDEF tag data using the
+** appropriate method for the currently activated tag.
+**
+** Upon successful completion of NDEF detection (if performed),
+** a NFA_NDEF_DETECT_EVT will be sent, to notify the application
+** of the NDEF attributes (NDEF total memory size, current size,
+** etc.).
+**
+** Upon receiving the NDEF message, the message will be sent to
+** the handler registered with NFA_RegisterNDefTypeHandler or
+** NFA_RequestExclusiveRfControl (if exclusive RF mode is active)
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFC_STATUS_REFUSED if tag does not support NDEF
+** NFC_STATUS_NOT_INITIALIZED if NULL NDEF was detected on the tag
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwReadNDef (void)
+{
+ tNFA_RW_OPERATION *p_msg;
+
+ NFA_TRACE_API0 ("NFA_RwReadNDef");
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_READ_NDEF;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+
+
+/*******************************************************************************
+**
+** Function NFA_RwWriteNDef
+**
+** Description Write NDEF data to the activated tag. This function will
+** internally perform NDEF detection if necessary, and write
+** the NDEF tag data using the appropriate method for the
+** currently activated tag.
+**
+** When the entire message has been written, or if an error
+** occurs, the app will be notified with NFA_WRITE_CPLT_EVT.
+**
+** p_data needs to be persistent until NFA_WRITE_CPLT_EVT
+**
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFC_STATUS_REFUSED if tag does not support NDEF/locked
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwWriteNDef (UINT8 *p_data, UINT32 len)
+{
+ tNFA_RW_OPERATION *p_msg;
+
+ NFA_TRACE_API2 ("NFA_RwWriteNDef (): ndef p_data=%08x, len: %i", p_data, len);
+
+ /* Validate parameters */
+ if (p_data == NULL)
+ return (NFA_STATUS_INVALID_PARAM);
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_WRITE_NDEF;
+ p_msg->params.write_ndef.len = len;
+ p_msg->params.write_ndef.p_data = p_data;
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*****************************************************************************
+**
+** Function NFA_RwPresenceCheck
+**
+** Description Check if the tag is still in the field.
+**
+** The NFA_RW_PRESENCE_CHECK_EVT w/ status is used to
+** indicate presence or non-presence.
+**
+** 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");
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_PRESENCE_CHECK;
+ 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");
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16)(sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_FORMAT_TAG;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RwSetTagReadOnly
+**
+** Description:
+** Sets tag as read only.
+**
+** When tag is set as read only, or if an error occurs, the app will be
+** notified with NFA_SET_TAG_RO_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_REJECTED if protocol is not T1/T2/ISO15693
+** (or) if hard lock is not requested for protocol ISO15693
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwSetTagReadOnly (BOOLEAN b_hard_lock)
+{
+ tNFA_RW_OPERATION *p_msg;
+ tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
+
+ if ((protocol != NFC_PROTOCOL_T1T) && (protocol != NFC_PROTOCOL_T2T) && (protocol != NFC_PROTOCOL_15693) && (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");
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ /* Fill in tNFA_RW_OPERATION struct */
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_SET_TAG_RO;
+ p_msg->params.set_readonly.b_hard_lock = b_hard_lock;
+
+ nfa_sys_sendmsg (p_msg);
+ return (NFA_STATUS_OK);
+ }
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+** Tag specific APIs
+** (note: for Type-4 tags, use NFA_SendRawFrame to exchange APDUs)
+*******************************************************************************/
+
+/*******************************************************************************
+**
+** Function NFA_RwLocateTlv
+**
+** Description:
+** Search for the Lock/Memory contril TLV on the activated Type1/Type2 tag
+**
+** Data is returned to the application using the NFA_TLV_DETECT_EVT. When
+** search operation has completed, or if an error occurs, the app will be
+** notified with NFA_TLV_DETECT_EVT.
+**
+** Description Perform the TLV detection procedure using the appropriate
+** method for the currently activated tag.
+**
+** Upon successful completion of TLV detection in T1/T2 tag, a
+** NFA_TLV_DETECT_EVT will be sent, to notify the application
+** of the TLV attributes (total lock/reserved bytes etc.).
+** However if the TLV type specified is NDEF then it is same as
+** calling NFA_RwDetectNDef and should expect to receive
+** NFA_NDEF_DETECT_EVT instead of NFA_TLV_DETECT_EVT
+**
+** It is not mandatory to call this function - NFA_RwDetectNDef,
+** NFA_RwReadNDef and NFA_RwWriteNDef will perform TLV detection
+** internally if not performed already. An application may call
+** this API to check the a tag/card-emulator's total Reserved/
+** Lock bytes before issuing a write-request.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFC_STATUS_REFUSED if tlv_type is NDEF & tag won't support NDEF
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwLocateTlv (UINT8 tlv_type)
+{
+ tNFA_RW_OPERATION *p_msg;
+
+ NFA_TRACE_API0 ("NFA_RwLocateTlv");
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+
+ if (tlv_type == TAG_LOCK_CTRL_TLV)
+ {
+ p_msg->op = NFA_RW_OP_DETECT_LOCK_TLV;
+ }
+ else if (tlv_type == TAG_MEM_CTRL_TLV)
+ {
+ p_msg->op = NFA_RW_OP_DETECT_MEM_TLV;
+ }
+ else if (tlv_type == TAG_NDEF_TLV)
+ {
+ p_msg->op = NFA_RW_OP_DETECT_NDEF;
+ }
+ else
+ return (NFA_STATUS_FAILED);
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RwT1tRid
+**
+** Description:
+** Send a RID command to the activated Type 1 tag.
+**
+** Data is returned to the application using the NFA_DATA_EVT. When the read
+** operation has completed, or if an error occurs, the app will be notified with
+** NFA_READ_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT1tRid (void)
+{
+ tNFA_RW_OPERATION *p_msg;
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ /* Fill in tNFA_RW_OPERATION struct */
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_T1T_RID;
+
+ nfa_sys_sendmsg (p_msg);
+ return (NFA_STATUS_OK);
+ }
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RwT1tReadAll
+**
+** Description:
+** Send a RALL command to the activated Type 1 tag.
+**
+** Data is returned to the application using the NFA_DATA_EVT. When the read
+** operation has completed, or if an error occurs, the app will be notified with
+** NFA_READ_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT1tReadAll (void)
+{
+ tNFA_RW_OPERATION *p_msg;
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ /* Fill in tNFA_RW_OPERATION struct */
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_T1T_RALL;
+
+ nfa_sys_sendmsg (p_msg);
+ return (NFA_STATUS_OK);
+ }
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RwT1tRead
+**
+** Description:
+** Send a READ command to the activated Type 1 tag.
+**
+** Data is returned to the application using the NFA_DATA_EVT. When the read
+** operation has completed, or if an error occurs, the app will be notified with
+** NFA_READ_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT1tRead (UINT8 block_number, UINT8 index)
+{
+ tNFA_RW_OPERATION *p_msg;
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ /* Fill in tNFA_RW_OPERATION struct */
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_T1T_READ;
+ p_msg->params.t1t_read.block_number = block_number;
+ p_msg->params.t1t_read.index = index;
+
+ nfa_sys_sendmsg (p_msg);
+ return (NFA_STATUS_OK);
+ }
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RwT1tWrite
+**
+** Description:
+** Send a WRITE command to the activated Type 1 tag.
+**
+** Data is returned to the application using the NFA_DATA_EVT. When the write
+** operation has completed, or if an error occurs, the app will be notified with
+** NFA_WRITE_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT1tWrite (UINT8 block_number, UINT8 index, UINT8 data, BOOLEAN b_erase)
+{
+ tNFA_RW_OPERATION *p_msg;
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ /* Fill in tNFA_RW_OPERATION struct */
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->params.t1t_write.b_erase = b_erase;
+ p_msg->op = NFA_RW_OP_T1T_WRITE;
+ p_msg->params.t1t_write.block_number = block_number;
+ p_msg->params.t1t_write.index = index;
+ p_msg->params.t1t_write.p_block_data[0] = data;
+
+ nfa_sys_sendmsg (p_msg);
+ return (NFA_STATUS_OK);
+ }
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RwT1tReadSeg
+**
+** Description:
+** Send a RSEG command to the activated Type 1 tag.
+**
+** Data is returned to the application using the NFA_DATA_EVT. When the read
+** operation has completed, or if an error occurs, the app will be notified with
+** NFA_READ_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT1tReadSeg (UINT8 segment_number)
+{
+ tNFA_RW_OPERATION *p_msg;
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ /* Fill in tNFA_RW_OPERATION struct */
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_T1T_RSEG;
+ p_msg->params.t1t_read.segment_number = segment_number;
+
+ nfa_sys_sendmsg (p_msg);
+ return (NFA_STATUS_OK);
+ }
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RwT1tRead8
+**
+** Description:
+** Send a READ8 command to the activated Type 1 tag.
+**
+** Data is returned to the application using the NFA_DATA_EVT. When the read
+** operation has completed, or if an error occurs, the app will be notified with
+** NFA_READ_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT1tRead8 (UINT8 block_number)
+{
+ tNFA_RW_OPERATION *p_msg;
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ /* Fill in tNFA_RW_OPERATION struct */
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_T1T_READ8;
+ p_msg->params.t1t_write.block_number = block_number;
+
+ nfa_sys_sendmsg (p_msg);
+ return (NFA_STATUS_OK);
+ }
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RwT1tWrite8
+**
+** Description:
+** Send a WRITE8_E / WRITE8_NE command to the activated Type 1 tag.
+**
+** Data is returned to the application using the NFA_DATA_EVT. When the read
+** operation has completed, or if an error occurs, the app will be notified with
+** NFA_READ_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT1tWrite8 (UINT8 block_number, UINT8 *p_data, BOOLEAN b_erase)
+{
+ tNFA_RW_OPERATION *p_msg;
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ /* Fill in tNFA_RW_OPERATION struct */
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->params.t1t_write.b_erase = b_erase;
+ p_msg->op = NFA_RW_OP_T1T_WRITE8;
+ p_msg->params.t1t_write.block_number = block_number;
+
+ memcpy (p_msg->params.t1t_write.p_block_data,p_data,8);
+
+ nfa_sys_sendmsg (p_msg);
+ return (NFA_STATUS_OK);
+ }
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RwT2tRead
+**
+** Description:
+** Send a READ command to the activated Type 2 tag.
+**
+** Data is returned to the application using the NFA_DATA_EVT. When the read
+** operation has completed, or if an error occurs, the app will be notified with
+** NFA_READ_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT2tRead (UINT8 block_number)
+{
+ tNFA_RW_OPERATION *p_msg;
+
+ NFA_TRACE_API1 ("NFA_RwT2tRead (): Block to read: %d", block_number);
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ /* Fill in tNFA_RW_OPERATION struct */
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_T2T_READ;
+ p_msg->params.t2t_read.block_number = block_number;
+
+ nfa_sys_sendmsg (p_msg);
+ return (NFA_STATUS_OK);
+ }
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RwT2tWrite
+**
+** Description:
+** Send an WRITE command to the activated Type 2 tag.
+**
+** When the write operation has completed (or if an error occurs), the
+** app will be notified with NFA_WRITE_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT2tWrite (UINT8 block_number, UINT8 *p_data)
+{
+ tNFA_RW_OPERATION *p_msg;
+
+ NFA_TRACE_API1 ("NFA_RwT2tWrite (): Block to write: %d", block_number);
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ /* Fill in tNFA_RW_OPERATION struct */
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_T2T_WRITE;
+
+ p_msg->params.t2t_write.block_number = block_number;
+
+ memcpy (p_msg->params.t2t_write.p_block_data,p_data,4);
+
+ nfa_sys_sendmsg (p_msg);
+ return (NFA_STATUS_OK);
+ }
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RwT2tSectorSelect
+**
+** Description:
+** Send SECTOR SELECT command to the activated Type 2 tag.
+**
+** When the sector select operation has completed (or if an error occurs), the
+** app will be notified with NFA_SECTOR_SELECT_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT2tSectorSelect (UINT8 sector_number)
+{
+ tNFA_RW_OPERATION *p_msg;
+
+ NFA_TRACE_API1 ("NFA_RwT2tRead (): sector to select: %d", sector_number);
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ /* Fill in tNFA_RW_OPERATION struct */
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_T2T_SECTOR_SELECT;
+
+ p_msg->params.t2t_sector_select.sector_number = sector_number;
+
+ nfa_sys_sendmsg (p_msg);
+ return (NFA_STATUS_OK);
+ }
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RwT3tRead
+**
+** Description:
+** Send a CHECK (read) command to the activated Type 3 tag.
+**
+** Data is returned to the application using the NFA_DATA_EVT. When the read
+** operation has completed, or if an error occurs, the app will be notified with
+** NFA_READ_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT3tRead (UINT8 num_blocks, tNFA_T3T_BLOCK_DESC *t3t_blocks)
+{
+ tNFA_RW_OPERATION *p_msg;
+ UINT8 *p_block_desc;
+
+ NFA_TRACE_API1 ("NFA_RwT3tRead (): num_blocks to read: %i", num_blocks);
+
+ /* Validate parameters */
+ if ((num_blocks == 0) || (t3t_blocks == NULL))
+ return (NFA_STATUS_INVALID_PARAM);
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION) + (num_blocks * sizeof (tNFA_T3T_BLOCK_DESC))))) != NULL)
+ {
+ /* point to area after tNFA_RW_OPERATION */
+ p_block_desc = (UINT8 *) (p_msg+1);
+
+ /* Fill in tNFA_RW_OPERATION struct */
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_T3T_READ;
+
+ p_msg->params.t3t_read.num_blocks = num_blocks;
+ p_msg->params.t3t_read.p_block_desc = (tNFA_T3T_BLOCK_DESC *) p_block_desc;
+
+ /* Copy block descriptor list */
+ memcpy (p_block_desc, t3t_blocks, (num_blocks * sizeof (tNFA_T3T_BLOCK_DESC)));
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RwT3tWrite
+**
+** Description:
+** Send an UPDATE (write) command to the activated Type 3 tag.
+**
+** When the write operation has completed (or if an error occurs), the
+** app will be notified with NFA_WRITE_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT3tWrite (UINT8 num_blocks, tNFA_T3T_BLOCK_DESC *t3t_blocks, UINT8 *p_data)
+{
+ tNFA_RW_OPERATION *p_msg;
+ UINT8 *p_block_desc, *p_data_area;
+
+ NFA_TRACE_API1 ("NFA_RwT3tWrite (): num_blocks to write: %i", num_blocks);
+
+ /* Validate parameters */
+ if ((num_blocks == 0) || (t3t_blocks == NULL) | (p_data == NULL))
+ return (NFA_STATUS_INVALID_PARAM);
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION) + (num_blocks * (sizeof (tNFA_T3T_BLOCK_DESC) + 16))))) != NULL)
+ {
+ /* point to block descriptor and data areas after tNFA_RW_OPERATION */
+ p_block_desc = (UINT8 *) (p_msg+1);
+ p_data_area = p_block_desc + (num_blocks * (sizeof (tNFA_T3T_BLOCK_DESC)));
+
+ /* Fill in tNFA_RW_OPERATION struct */
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_T3T_WRITE;
+
+ p_msg->params.t3t_write.num_blocks = num_blocks;
+ p_msg->params.t3t_write.p_block_desc = (tNFA_T3T_BLOCK_DESC *) p_block_desc;
+ p_msg->params.t3t_write.p_block_data = p_data_area;
+
+ /* Copy block descriptor list */
+ memcpy (p_block_desc, t3t_blocks, (num_blocks * sizeof (tNFA_T3T_BLOCK_DESC)));
+
+ /* Copy data */
+ memcpy (p_data_area, p_data, (num_blocks * 16));
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RwI93Inventory
+**
+** Description:
+** Send Inventory command to the activated ISO 15693 tag 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 (BOOLEAN afi_present, UINT8 afi, UINT8 *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);
+ }
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ /* Fill in tNFA_RW_OPERATION struct */
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_I93_INVENTORY;
+
+ p_msg->params.i93_cmd.afi_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);
+ }
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ /* Fill in tNFA_RW_OPERATION struct */
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_I93_STAY_QUIET;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RwI93ReadSingleBlock
+**
+** Description:
+** Send Read Single Block command to the activated ISO 15693 tag.
+**
+** Data is returned to the application using the NFA_DATA_EVT. When the read
+** operation has completed, or if an error occurs, the app will be notified with
+** NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93ReadSingleBlock (UINT8 block_number)
+{
+ tNFA_RW_OPERATION *p_msg;
+
+ NFA_TRACE_API1 ("NFA_RwI93ReadSingleBlock (): block_number: 0x%02X", block_number);
+
+ if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693)
+ {
+ return (NFA_STATUS_WRONG_PROTOCOL);
+ }
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ /* Fill in tNFA_RW_OPERATION struct */
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_I93_READ_SINGLE_BLOCK;
+
+ p_msg->params.i93_cmd.first_block_number = block_number;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RwI93WriteSingleBlock
+**
+** Description:
+** Send Write Single Block command to the activated ISO 15693 tag.
+**
+** When the write operation has completed (or if an error occurs), the
+** app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93WriteSingleBlock (UINT8 block_number,
+ UINT8 *p_data)
+{
+ tNFA_RW_OPERATION *p_msg;
+
+ NFA_TRACE_API1 ("NFA_RwI93WriteSingleBlock (): block_number: 0x%02X", block_number);
+
+ if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693)
+ {
+ return (NFA_STATUS_WRONG_PROTOCOL);
+ }
+
+ /* we don't know block size of tag */
+ if ( (nfa_rw_cb.i93_block_size == 0)
+ ||(nfa_rw_cb.i93_num_block == 0) )
+ {
+ return (NFA_STATUS_FAILED);
+ }
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION) + nfa_rw_cb.i93_block_size))) != NULL)
+ {
+ /* Fill in tNFA_RW_OPERATION struct */
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_I93_WRITE_SINGLE_BLOCK;
+
+ p_msg->params.i93_cmd.first_block_number = block_number;
+ p_msg->params.i93_cmd.p_data = (UINT8*) (p_msg + 1);
+
+ memcpy (p_msg->params.i93_cmd.p_data, p_data, nfa_rw_cb.i93_block_size);
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RwI93LockBlock
+**
+** Description:
+** Send Lock block command to the activated ISO 15693 tag.
+**
+** When the operation has completed (or if an error occurs), the
+** app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93LockBlock (UINT8 block_number)
+{
+ tNFA_RW_OPERATION *p_msg;
+
+ NFA_TRACE_API1 ("NFA_RwI93LockBlock (): block_number: 0x%02X", block_number);
+
+ if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693)
+ {
+ return (NFA_STATUS_WRONG_PROTOCOL);
+ }
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ /* Fill in tNFA_RW_OPERATION struct */
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_I93_LOCK_BLOCK;
+
+ p_msg->params.i93_cmd.first_block_number = block_number;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RwI93ReadMultipleBlocks
+**
+** Description:
+** Send Read Multiple Block command to the activated ISO 15693 tag.
+**
+** Data is returned to the application using the NFA_DATA_EVT. When the read
+** operation has completed, or if an error occurs, the app will be notified with
+** NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93ReadMultipleBlocks (UINT8 first_block_number,
+ UINT16 number_blocks)
+{
+ tNFA_RW_OPERATION *p_msg;
+
+ NFA_TRACE_API2 ("NFA_RwI93ReadMultipleBlocks(): %d, %d", first_block_number, number_blocks);
+
+ if ( nfa_rw_cb.protocol != NFC_PROTOCOL_15693)
+ {
+ return (NFA_STATUS_WRONG_PROTOCOL);
+ }
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ /* Fill in tNFA_RW_OPERATION struct */
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_I93_READ_MULTI_BLOCK;
+
+ p_msg->params.i93_cmd.first_block_number = first_block_number;
+ p_msg->params.i93_cmd.number_blocks = number_blocks;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RwI93WriteMultipleBlocks
+**
+** Description:
+** Send Write Multiple Block command to the activated ISO 15693 tag.
+**
+** When the write operation has completed (or if an error occurs), the
+** app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93WriteMultipleBlocks (UINT8 first_block_number,
+ UINT16 number_blocks,
+ UINT8 *p_data)
+{
+ tNFA_RW_OPERATION *p_msg;
+ UINT16 data_length;
+
+ NFA_TRACE_API2 ("NFA_RwI93WriteMultipleBlocks (): %d, %d", first_block_number, number_blocks);
+
+ if ( nfa_rw_cb.protocol != NFC_PROTOCOL_15693)
+ {
+ return (NFA_STATUS_WRONG_PROTOCOL);
+ }
+
+ /* we don't know block size of tag */
+ if ((nfa_rw_cb.i93_block_size == 0) || (nfa_rw_cb.i93_num_block == 0))
+ {
+ return (NFA_STATUS_FAILED);
+ }
+
+ data_length = nfa_rw_cb.i93_block_size * number_blocks;
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION) + data_length))) != NULL)
+ {
+ /* Fill in tNFA_RW_OPERATION struct */
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_I93_WRITE_MULTI_BLOCK;
+
+ p_msg->params.i93_cmd.first_block_number = first_block_number;
+ p_msg->params.i93_cmd.number_blocks = number_blocks;
+ p_msg->params.i93_cmd.p_data = (UINT8*) (p_msg + 1);
+
+ memcpy (p_msg->params.i93_cmd.p_data, p_data, data_length);
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RwI93Select
+**
+** Description:
+** Send Select command to the activated ISO 15693 tag.
+**
+** UID[0]: 0xE0, MSB
+** UID[1]: IC Mfg Code
+** ...
+** UID[7]: LSB
+**
+** When the operation has completed (or if an error occurs), the
+** app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93Select (UINT8 *p_uid)
+{
+ tNFA_RW_OPERATION *p_msg;
+
+ NFA_TRACE_API3 ("NFA_RwI93Select (): UID: [%02X%02X%02X...]", *(p_uid), *(p_uid+1), *(p_uid+2));
+
+ if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693)
+ {
+ return (NFA_STATUS_WRONG_PROTOCOL);
+ }
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION) + I93_UID_BYTE_LEN))) != NULL)
+ {
+ /* Fill in tNFA_RW_OPERATION struct */
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_I93_SELECT;
+
+ p_msg->params.i93_cmd.p_data = (UINT8 *) (p_msg + 1);
+ memcpy (p_msg->params.i93_cmd.p_data, p_uid, I93_UID_BYTE_LEN);
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RwI93ResetToReady
+**
+** Description:
+** Send Reset to ready command to the activated ISO 15693 tag.
+**
+** When the operation has completed (or if an error occurs), the
+** app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93ResetToReady (void)
+{
+ tNFA_RW_OPERATION *p_msg;
+
+ NFA_TRACE_API0 ("NFA_RwI93ResetToReady ()");
+
+ if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693)
+ {
+ return (NFA_STATUS_WRONG_PROTOCOL);
+ }
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ /* Fill in tNFA_RW_OPERATION struct */
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_I93_RESET_TO_READY;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RwI93WriteAFI
+**
+** Description:
+** Send Write AFI command to the activated ISO 15693 tag.
+**
+** When the operation has completed (or if an error occurs), the
+** app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93WriteAFI (UINT8 afi)
+{
+ tNFA_RW_OPERATION *p_msg;
+
+ NFA_TRACE_API1 ("NFA_RwI93WriteAFI (): AFI: 0x%02X", afi);
+
+ if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693)
+ {
+ return (NFA_STATUS_WRONG_PROTOCOL);
+ }
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ /* Fill in tNFA_RW_OPERATION struct */
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_I93_WRITE_AFI;
+
+ p_msg->params.i93_cmd.afi = afi;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RwI93LockAFI
+**
+** Description:
+** Send Lock AFI command to the activated ISO 15693 tag.
+**
+** When the operation has completed (or if an error occurs), the
+** app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93LockAFI (void)
+{
+ tNFA_RW_OPERATION *p_msg;
+
+ NFA_TRACE_API0 ("NFA_RwI93LockAFI ()");
+
+ if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693)
+ {
+ return (NFA_STATUS_WRONG_PROTOCOL);
+ }
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ /* Fill in tNFA_RW_OPERATION struct */
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_I93_LOCK_AFI;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RwI93WriteDSFID
+**
+** Description:
+** Send Write DSFID command to the activated ISO 15693 tag.
+**
+** When the operation has completed (or if an error occurs), the
+** app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93WriteDSFID (UINT8 dsfid)
+{
+ tNFA_RW_OPERATION *p_msg;
+
+ NFA_TRACE_API1 ("NFA_RwI93WriteDSFID (): DSFID: 0x%02X", dsfid);
+
+ if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693)
+ {
+ return (NFA_STATUS_WRONG_PROTOCOL);
+ }
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ /* Fill in tNFA_RW_OPERATION struct */
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_I93_WRITE_DSFID;
+
+ p_msg->params.i93_cmd.dsfid = dsfid;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RwI93LockDSFID
+**
+** Description:
+** Send Lock DSFID command to the activated ISO 15693 tag.
+**
+** When the operation has completed (or if an error occurs), the
+** app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93LockDSFID (void)
+{
+ tNFA_RW_OPERATION *p_msg;
+
+ NFA_TRACE_API0 ("NFA_RwI93LockDSFID ()");
+
+ if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693)
+ {
+ return (NFA_STATUS_WRONG_PROTOCOL);
+ }
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ /* Fill in tNFA_RW_OPERATION struct */
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_I93_LOCK_DSFID;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RwI93GetSysInfo
+**
+** Description:
+** Send Get system information command to the activated ISO 15693 tag.
+** If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
+**
+** When the operation has completed (or if an error occurs), the
+** app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93GetSysInfo (UINT8 *p_uid)
+{
+ tNFA_RW_OPERATION *p_msg;
+
+ NFA_TRACE_API0 ("NFA_RwI93GetSysInfo ()");
+
+ if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693)
+ {
+ return (NFA_STATUS_WRONG_PROTOCOL);
+ }
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ /* Fill in tNFA_RW_OPERATION struct */
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_I93_GET_SYS_INFO;
+
+ if (p_uid)
+ {
+ p_msg->params.i93_cmd.uid_present = TRUE;
+ memcpy (p_msg->params.i93_cmd.uid, p_uid, I93_UID_BYTE_LEN);
+ }
+ else
+ {
+ p_msg->params.i93_cmd.uid_present = FALSE;
+ }
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function NFA_RwI93GetMultiBlockSecurityStatus
+**
+** Description:
+** Send Get Multiple block security status command to the activated ISO 15693 tag.
+**
+** Data is returned to the application using the NFA_DATA_EVT. When the read
+** operation has completed, or if an error occurs, the app will be notified with
+** NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+** NFA_STATUS_OK if successfully initiated
+** NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+** NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93GetMultiBlockSecurityStatus (UINT8 first_block_number,
+ UINT16 number_blocks)
+{
+ tNFA_RW_OPERATION *p_msg;
+
+ NFA_TRACE_API2 ("NFA_RwI93GetMultiBlockSecurityStatus(): %d, %d", first_block_number, number_blocks);
+
+ if ( nfa_rw_cb.protocol != NFC_PROTOCOL_15693)
+ {
+ return (NFA_STATUS_WRONG_PROTOCOL);
+ }
+
+ if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+ {
+ /* Fill in tNFA_RW_OPERATION struct */
+ p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+ p_msg->op = NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS;
+
+ p_msg->params.i93_cmd.first_block_number = first_block_number;
+ p_msg->params.i93_cmd.number_blocks = number_blocks;
+
+ nfa_sys_sendmsg (p_msg);
+
+ return (NFA_STATUS_OK);
+ }
+
+ return (NFA_STATUS_FAILED);
+}
diff --git a/src/nfa/rw/nfa_rw_main.c b/src/nfa/rw/nfa_rw_main.c
new file mode 100644
index 0000000..2176c08
--- /dev/null
+++ b/src/nfa/rw/nfa_rw_main.c
@@ -0,0 +1,240 @@
+/******************************************************************************
+ *
+ * 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 event);
+#endif
+
+/*******************************************************************************
+**
+** Function nfa_rw_init
+**
+** Description Initialize NFA RW
+**
+** Returns None
+**
+*******************************************************************************/
+void nfa_rw_init (void)
+{
+ NFA_TRACE_DEBUG0 ("nfa_rw_init ()");
+
+ /* initialize control block */
+ memset (&nfa_rw_cb, 0, sizeof (tNFA_RW_CB));
+
+ /* register message handler on NFA SYS */
+ nfa_sys_register (NFA_ID_RW, &nfa_rw_sys_reg);
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_sys_disable
+**
+** Description Clean up rw sub-system
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_rw_sys_disable (void)
+{
+ /* Return to idle */
+ NFC_SetStaticRfCback (NULL);
+
+ /* Stop presence check timer (if started) */
+ nfa_rw_stop_presence_check_timer ();
+
+ /* Free scratch buffer if any */
+ nfa_rw_free_ndef_rx_buf ();
+
+ /* Free pending command if any */
+ if (nfa_rw_cb.p_pending_msg)
+ {
+ GKI_freebuf (nfa_rw_cb.p_pending_msg);
+ nfa_rw_cb.p_pending_msg = NULL;
+ }
+
+ nfa_sys_deregister (NFA_ID_RW);
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_proc_disc_evt
+**
+** Description Called by nfa_dm to handle ACTIVATED/DEACTIVATED events
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_rw_proc_disc_evt (tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER *p_data, BOOLEAN excl_rf_not_active)
+{
+ tNFA_RW_MSG msg;
+
+ switch (event)
+ {
+ case NFA_DM_RF_DISC_ACTIVATED_EVT:
+ msg.hdr.event = NFA_RW_ACTIVATE_NTF_EVT;
+ msg.activate_ntf.p_activate_params = &p_data->activate;
+ msg.activate_ntf.excl_rf_not_active = excl_rf_not_active;
+
+ nfa_rw_handle_event ((BT_HDR *) &msg);
+ break;
+
+ case NFA_DM_RF_DISC_DEACTIVATED_EVT:
+ msg.hdr.event = NFA_RW_DEACTIVATE_NTF_EVT;
+
+ nfa_rw_handle_event ((BT_HDR *) &msg);
+ break;
+
+ default:
+ break;
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_rw_send_raw_frame
+**
+** Description Called by nfa_dm to send raw frame
+**
+** Returns tNFA_STATUS
+**
+*******************************************************************************/
+tNFA_STATUS nfa_rw_send_raw_frame (BT_HDR *p_data)
+{
+ tNFA_RW_MSG *p_msg;
+
+ if ((p_msg = (tNFA_RW_MSG *) GKI_getbuf ((UINT16) sizeof(tNFA_RW_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 ((BT_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
+**
+*******************************************************************************/
+BOOLEAN nfa_rw_handle_event(BT_HDR *p_msg)
+{
+ UINT16 act_idx;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ NFA_TRACE_EVENT3 ("nfa_rw_handle_event event: %s (0x%02x), flags: %08x", nfa_rw_evt_2_str (p_msg->event), p_msg->event, nfa_rw_cb.flags);
+#else
+ NFA_TRACE_EVENT2 ("nfa_rw_handle_event event: 0x%x, flags: %08x",p_msg->event, nfa_rw_cb.flags);
+#endif
+
+ /* Get NFA_RW sub-event */
+ if ((act_idx = (p_msg->event & 0x00FF)) < (NFA_RW_MAX_EVT & 0xFF))
+ {
+ return (*nfa_rw_action_tbl[act_idx]) ( (tNFA_RW_MSG*) p_msg);
+ }
+ else
+ {
+ NFA_TRACE_ERROR1 ("nfa_rw_handle_event: unhandled event 0x%02X", p_msg->event);
+ return TRUE;
+ }
+}
+
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function nfa_rw_evt_2_str
+**
+** Description convert nfa_rw evt to string
+**
+*******************************************************************************/
+static char *nfa_rw_evt_2_str (UINT16 event)
+{
+ switch (event)
+ {
+ case NFA_RW_OP_REQUEST_EVT:
+ return "NFA_RW_OP_REQUEST_EVT";
+
+ case NFA_RW_ACTIVATE_NTF_EVT:
+ return "NFA_RW_ACTIVATE_NTF_EVT";
+
+ case NFA_RW_DEACTIVATE_NTF_EVT:
+ return "NFA_RW_DEACTIVATE_NTF_EVT";
+
+ case NFA_RW_PRESENCE_CHECK_TICK_EVT:
+ return "NFA_RW_PRESENCE_CHECK_TICK_EVT";
+
+ 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..275c39a
--- /dev/null
+++ b/src/nfa/sys/nfa_sys_cback.c
@@ -0,0 +1,111 @@
+/******************************************************************************
+ *
+ * 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 id)
+{
+ nfa_sys_cb.enable_cplt_flags |= (0x0001 << id);
+
+ NFA_TRACE_DEBUG2 ("nfa_sys_cback_notify_enable_complete () enable_cplt_flags=0x%x, enable_cplt_mask=0x%x",
+ nfa_sys_cb.enable_cplt_flags, nfa_sys_cb.enable_cplt_mask);
+
+ if ( (nfa_sys_cb.enable_cplt_flags == nfa_sys_cb.enable_cplt_mask)
+ &&(nfa_sys_cb.p_enable_cback) )
+ {
+ nfa_sys_cb.p_enable_cback ();
+ nfa_sys_cb.p_enable_cback = NULL;
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_sys_cback_reg_nfcc_power_mode_proc_complete
+**
+** Description Called to register a callback function for complete of processing
+** NFCC power mode change from NFA sub-systems
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_sys_cback_reg_nfcc_power_mode_proc_complete (tNFA_SYS_PROC_NFCC_PWR_MODE_CMPL *p_cback)
+{
+ nfa_sys_cb.p_proc_nfcc_pwr_mode_cmpl_cback = p_cback;
+ nfa_sys_cb.proc_nfcc_pwr_mode_cplt_flags = 0;
+}
+
+/*******************************************************************************
+**
+** Function nfa_sys_cback_notify_nfcc_power_mode_proc_complete
+**
+** Description Called by other NFA subsystems to notify processing NFCC power
+** mode is complete
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_sys_cback_notify_nfcc_power_mode_proc_complete (UINT8 id)
+{
+ nfa_sys_cb.proc_nfcc_pwr_mode_cplt_flags |= (0x0001 << id);
+
+ NFA_TRACE_DEBUG2 ("nfa_sys_cback_notify_nfcc_power_mode_proc_complete () flags=0x%x, mask=0x%x",
+ nfa_sys_cb.proc_nfcc_pwr_mode_cplt_flags,
+ nfa_sys_cb.proc_nfcc_pwr_mode_cplt_mask);
+
+ if ( (nfa_sys_cb.proc_nfcc_pwr_mode_cplt_flags == nfa_sys_cb.proc_nfcc_pwr_mode_cplt_mask) /* except SYS */
+ &&(nfa_sys_cb.p_proc_nfcc_pwr_mode_cmpl_cback) )
+ {
+ nfa_sys_cb.p_proc_nfcc_pwr_mode_cmpl_cback ();
+ nfa_sys_cb.p_proc_nfcc_pwr_mode_cmpl_cback = NULL;
+ }
+}
diff --git a/src/nfa/sys/nfa_sys_cfg.c b/src/nfa/sys/nfa_sys_cfg.c
new file mode 100644
index 0000000..481dbdc
--- /dev/null
+++ b/src/nfa/sys/nfa_sys_cfg.c
@@ -0,0 +1,39 @@
+/******************************************************************************
+ *
+ * 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..efbf7ff
--- /dev/null
+++ b/src/nfa/sys/nfa_sys_main.c
@@ -0,0 +1,419 @@
+/******************************************************************************
+ *
+ * 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 */
+#if NFA_DYNAMIC_MEMORY == FALSE
+tNFA_SYS_CB nfa_sys_cb = {0}; /* nfa_sys control block. statically initialize 'flags' field to 0 */
+#endif
+
+/*******************************************************************************
+**
+** Function nfa_sys_init
+**
+** Description NFA initialization; called from task initialization.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_sys_init (void)
+{
+ memset (&nfa_sys_cb, 0, sizeof (tNFA_SYS_CB));
+ nfa_sys_cb.flags |= NFA_SYS_FL_INITIALIZED;
+ nfa_sys_ptim_init (&nfa_sys_cb.ptim_cb, NFA_SYS_TIMER_PERIOD, p_nfa_sys_cfg->timer);
+ nfa_sys_cb.trace_level = p_nfa_sys_cfg->trace_level;
+}
+
+
+
+
+/*******************************************************************************
+**
+** Function nfa_sys_event
+**
+** Description BTA event handler; called from task event handler.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_sys_event (BT_HDR *p_msg)
+{
+ UINT8 id;
+ BOOLEAN freebuf = TRUE;
+
+ NFA_TRACE_EVENT1 ("NFA got event 0x%04X", p_msg->event);
+
+ /* get subsystem id from event */
+ id = (UINT8) (p_msg->event >> 8);
+
+ /* verify id and call subsystem event handler */
+ if ((id < NFA_ID_MAX) && (nfa_sys_cb.is_reg[id]))
+ {
+ freebuf = (*nfa_sys_cb.reg[id]->evt_hdlr) (p_msg);
+ }
+ else
+ {
+ NFA_TRACE_WARNING1 ("NFA got unregistered event id %d", id);
+ }
+
+ if (freebuf)
+ {
+ GKI_freebuf (p_msg);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_sys_timer_update
+**
+** Description Update the BTA timer list and handle expired timers.
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_sys_timer_update (void)
+{
+ if (!nfa_sys_cb.timers_disabled)
+ {
+ nfa_sys_ptim_timer_update (&nfa_sys_cb.ptim_cb);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_sys_register
+**
+** Description Called by other BTA subsystems to register their event
+** handler.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_sys_register (UINT8 id, const tNFA_SYS_REG *p_reg)
+{
+ nfa_sys_cb.reg[id] = (tNFA_SYS_REG *) p_reg;
+ nfa_sys_cb.is_reg[id] = TRUE;
+
+ if ((id != NFA_ID_DM) && (id != NFA_ID_SYS))
+ nfa_sys_cb.enable_cplt_mask |= (0x0001 << id);
+
+ if (id != NFA_ID_SYS)
+ {
+ if (p_reg->proc_nfcc_pwr_mode)
+ nfa_sys_cb.proc_nfcc_pwr_mode_cplt_mask |= (0x0001 << id);
+ }
+
+ NFA_TRACE_DEBUG2 ("nfa_sys_register () id=%i, enable_cplt_mask=0x%x",
+ id, nfa_sys_cb.enable_cplt_mask);
+}
+
+
+/*******************************************************************************
+**
+** Function nfa_sys_check_disabled
+**
+** Description If all subsystems above DM have been disabled, then
+** disable DM. Called during NFA shutdown
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_sys_check_disabled (void)
+{
+ UINT8 id;
+ UINT8 done = TRUE;
+
+ /* Check if all subsystems above DM have been disabled. */
+ for (id = (NFA_ID_DM+1); id < NFA_ID_MAX; id++)
+ {
+ if (nfa_sys_cb.is_reg[id])
+ {
+ /* as long as one subsystem is not done */
+ done = FALSE;
+ break;
+ }
+ }
+
+ /* All subsystems disabled. disable DM */
+ if ((done) && (nfa_sys_cb.is_reg[NFA_ID_DM]))
+ {
+ (*nfa_sys_cb.reg[NFA_ID_DM]->disable) ();
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function nfa_sys_deregister
+**
+** Description Called by other BTA subsystems to de-register
+** handler.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_sys_deregister (UINT8 id)
+{
+ NFA_TRACE_DEBUG1 ("nfa_sys: deregistering subsystem %i", id);
+
+ nfa_sys_cb.is_reg[id] = FALSE;
+
+ /* If not deregistering DM, then check if any other subsystems above DM are still */
+ /* registered. */
+ if (id != NFA_ID_DM)
+ {
+ /* If all subsystems above NFA_DM have been disabled, then okay to disable DM */
+ nfa_sys_check_disabled ();
+ }
+ else
+ {
+ /* DM (the final sub-system) is deregistering. Clear pending timer events in nfa_sys. */
+ nfa_sys_ptim_init (&nfa_sys_cb.ptim_cb, NFA_SYS_TIMER_PERIOD, p_nfa_sys_cfg->timer);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_sys_is_register
+**
+** Description Called by other BTA subsystems to get registeration
+** status.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+BOOLEAN nfa_sys_is_register (UINT8 id)
+{
+ return nfa_sys_cb.is_reg[id];
+}
+
+/*******************************************************************************
+**
+** Function nfa_sys_is_graceful_disable
+**
+** Description Called by other BTA subsystems to get disable
+** parameter.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+BOOLEAN nfa_sys_is_graceful_disable (void)
+{
+ return nfa_sys_cb.graceful_disable;
+}
+
+/*******************************************************************************
+**
+** Function nfa_sys_enable_subsystems
+**
+** Description Call on NFA Start up
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_sys_enable_subsystems (void)
+{
+ UINT8 id;
+
+ NFA_TRACE_DEBUG0 ("nfa_sys: enabling subsystems");
+
+ /* Enable all subsystems except SYS */
+ for (id = NFA_ID_DM; id < NFA_ID_MAX; id++)
+ {
+ if (nfa_sys_cb.is_reg[id])
+ {
+ if (nfa_sys_cb.reg[id]->enable != NULL)
+ {
+ /* Subsytem has a Disable funciton. Call it now */
+ (*nfa_sys_cb.reg[id]->enable) ();
+ }
+ else
+ {
+ /* Subsytem does not have a Enable function. Report Enable on behalf of subsystem */
+ nfa_sys_cback_notify_enable_complete (id);
+ }
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_sys_disable_subsystems
+**
+** Description Call on NFA shutdown. Disable all subsystems above NFA_DM
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_sys_disable_subsystems (BOOLEAN graceful)
+{
+ UINT8 id;
+ BOOLEAN done = TRUE;
+
+ NFA_TRACE_DEBUG1 ("nfa_sys: disabling subsystems:%d", graceful);
+ nfa_sys_cb.graceful_disable = graceful;
+
+ /* Disable all subsystems above NFA_DM. (NFA_DM and NFA_SYS will be disabled last) */
+ for (id = (NFA_ID_DM+1); id < NFA_ID_MAX; id++)
+ {
+ if (nfa_sys_cb.is_reg[id])
+ {
+ done = FALSE;
+ if (nfa_sys_cb.reg[id]->disable != NULL)
+ {
+ /* Subsytem has a Disable funciton. Call it now */
+ (*nfa_sys_cb.reg[id]->disable) ();
+ }
+ else
+ {
+ /* Subsytem does not have a Disable function. Deregister on behalf of subsystem */
+ nfa_sys_deregister (id);
+ }
+ }
+ }
+
+ /* If All subsystems disabled. disable DM */
+ if ((done) && (nfa_sys_cb.is_reg[NFA_ID_DM]))
+ {
+ (*nfa_sys_cb.reg[NFA_ID_DM]->disable) ();
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_sys_notify_nfcc_power_mode
+**
+** Description Call to notify NFCC power mode to NFA sub-modules
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_sys_notify_nfcc_power_mode (UINT8 nfcc_power_mode)
+{
+ UINT8 id;
+
+ NFA_TRACE_DEBUG1 ("nfa_sys: notify NFCC power mode(%d) to subsystems", nfcc_power_mode);
+
+ /* Notify NFCC power state to all subsystems except NFA_SYS */
+ for (id = NFA_ID_DM; id < NFA_ID_MAX; id++)
+ {
+ if ((nfa_sys_cb.is_reg[id]) && (nfa_sys_cb.reg[id]->proc_nfcc_pwr_mode))
+ {
+ /* Subsytem has a funciton for processing NFCC power mode. Call it now */
+ (*nfa_sys_cb.reg[id]->proc_nfcc_pwr_mode) (nfcc_power_mode);
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_sys_sendmsg
+**
+** Description Send a GKI message to BTA. This function is designed to
+** optimize sending of messages to BTA. It is called by BTA
+** API functions and call-in functions.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_sys_sendmsg (void *p_msg)
+{
+ GKI_send_msg (NFC_TASK, p_nfa_sys_cfg->mbox, p_msg);
+}
+
+/*******************************************************************************
+**
+** Function nfa_sys_start_timer
+**
+** Description Start a protocol timer for the specified amount
+** of time in milliseconds.
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_sys_start_timer (TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout)
+{
+ nfa_sys_ptim_start_timer (&nfa_sys_cb.ptim_cb, p_tle, type, timeout);
+}
+
+/*******************************************************************************
+**
+** Function nfa_sys_stop_timer
+**
+** Description Stop a BTA timer.
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_sys_stop_timer (TIMER_LIST_ENT *p_tle)
+{
+ nfa_sys_ptim_stop_timer (&nfa_sys_cb.ptim_cb, p_tle);
+}
+
+
+/*******************************************************************************
+**
+** Function nfa_sys_disable_timers
+**
+** Description Disable sys timer event handling
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_sys_disable_timers (void)
+{
+ nfa_sys_cb.timers_disabled = TRUE;
+}
+
+/*******************************************************************************
+**
+** Function nfa_sys_set_trace_level
+**
+** Description Set trace level for BTA
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_sys_set_trace_level (UINT8 level)
+{
+ nfa_sys_cb.trace_level = level;
+}
diff --git a/src/nfa/sys/nfa_sys_ptim.c b/src/nfa/sys/nfa_sys_ptim.c
new file mode 100644
index 0000000..62916e6
--- /dev/null
+++ b/src/nfa/sys/nfa_sys_ptim.c
@@ -0,0 +1,172 @@
+/******************************************************************************
+ *
+ * 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 period, UINT8 timer_id)
+{
+ GKI_init_timer_list (&p_cb->timer_queue);
+ p_cb->period = period;
+ p_cb->timer_id = timer_id;
+}
+
+/*******************************************************************************
+**
+** Function nfa_sys_ptim_timer_update
+**
+** Description Update the protocol timer list and handle expired timers.
+** This function is called from the task running the protocol
+** timers when the periodic GKI timer expires.
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_sys_ptim_timer_update (tPTIM_CB *p_cb)
+{
+ TIMER_LIST_ENT *p_tle;
+ BT_HDR *p_msg;
+ UINT32 new_ticks_count;
+ INT32 period_in_ticks;
+
+ /* To handle the case when the function is called less frequently than the period
+ we must convert determine the number of ticks since the last update, then
+ convert back to milliseconds before updating timer list */
+ new_ticks_count = GKI_get_tick_count ();
+
+ /* Check for wrapped condition */
+ if (new_ticks_count >= p_cb->last_gki_ticks)
+ {
+ period_in_ticks = (INT32) (new_ticks_count - p_cb->last_gki_ticks);
+ }
+ else
+ {
+ period_in_ticks = (INT32) (((UINT32) 0xffffffff - p_cb->last_gki_ticks)
+ + new_ticks_count + 1);
+ }
+
+ /* update timer list */
+ GKI_update_timer_list (&p_cb->timer_queue, GKI_TICKS_TO_MS (period_in_ticks));
+
+ p_cb->last_gki_ticks = new_ticks_count;
+
+ /* while there are expired timers */
+ while ((p_cb->timer_queue.p_first) && (p_cb->timer_queue.p_first->ticks <= 0))
+ {
+ /* removed expired timer from list */
+ p_tle = p_cb->timer_queue.p_first;
+ NFA_TRACE_DEBUG1 ("nfa_sys_ptim_timer_update expired: %08x", p_tle);
+ GKI_remove_from_timer_list (&p_cb->timer_queue, p_tle);
+
+ /* call timer callback */
+ if (p_tle->p_cback)
+ {
+ (*p_tle->p_cback) (p_tle);
+ }
+ else if (p_tle->event)
+ {
+ if ((p_msg = (BT_HDR *) GKI_getbuf (sizeof (BT_HDR))) != NULL)
+ {
+ p_msg->event = p_tle->event;
+ p_msg->layer_specific = 0;
+ nfa_sys_sendmsg (p_msg);
+ }
+ }
+ }
+
+ /* if timer list is empty stop periodic GKI timer */
+ if (p_cb->timer_queue.p_first == NULL)
+ {
+ NFA_TRACE_DEBUG0 ("ptim timer stop");
+ GKI_stop_timer (p_cb->timer_id);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_sys_ptim_start_timer
+**
+** Description Start a protocol timer for the specified amount
+** of time in seconds.
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_sys_ptim_start_timer (tPTIM_CB *p_cb, TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout)
+{
+ NFA_TRACE_DEBUG1 ("nfa_sys_ptim_start_timer %08x", p_tle);
+
+ /* if timer list is currently empty, start periodic GKI timer */
+ if (p_cb->timer_queue.p_first == NULL)
+ {
+ NFA_TRACE_DEBUG0 ("ptim timer start");
+ p_cb->last_gki_ticks = GKI_get_tick_count ();
+ GKI_start_timer (p_cb->timer_id, GKI_MS_TO_TICKS (p_cb->period), TRUE);
+ }
+
+ GKI_remove_from_timer_list (&p_cb->timer_queue, p_tle);
+
+ p_tle->event = type;
+ p_tle->ticks = timeout;
+
+ GKI_add_to_timer_list (&p_cb->timer_queue, p_tle);
+}
+
+/*******************************************************************************
+**
+** Function nfa_sys_ptim_stop_timer
+**
+** Description Stop a protocol timer.
+**
+** Returns void
+**
+*******************************************************************************/
+void nfa_sys_ptim_stop_timer (tPTIM_CB *p_cb, TIMER_LIST_ENT *p_tle)
+{
+ NFA_TRACE_DEBUG1 ("nfa_sys_ptim_stop_timer %08x", p_tle);
+
+ GKI_remove_from_timer_list (&p_cb->timer_queue, p_tle);
+
+ /* if timer list is empty stop periodic GKI timer */
+ if (p_cb->timer_queue.p_first == NULL)
+ {
+ NFA_TRACE_DEBUG0 ("ptim timer stop");
+ GKI_stop_timer (p_cb->timer_id);
+ }
+}
diff --git a/src/nfc/include/ce_api.h b/src/nfc/include/ce_api.h
new file mode 100644
index 0000000..052b1e4
--- /dev/null
+++ b/src/nfc/include/ce_api.h
@@ -0,0 +1,265 @@
+/******************************************************************************
+ *
+ * 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 "tags_defs.h"
+
+#define CE_T3T_FIRST_EVT 0x60
+#define CE_T4T_FIRST_EVT 0x80
+
+enum
+{
+ CE_T3T_NDEF_UPDATE_START_EVT = CE_T3T_FIRST_EVT,
+ CE_T3T_NDEF_UPDATE_CPLT_EVT,
+ CE_T3T_UPDATE_EVT,
+ CE_T3T_CHECK_EVT,
+ CE_T3T_RAW_FRAME_EVT,
+ CE_T3T_MAX_EVT,
+
+ CE_T4T_NDEF_UPDATE_START_EVT = CE_T4T_FIRST_EVT,
+ CE_T4T_NDEF_UPDATE_CPLT_EVT,
+ CE_T4T_NDEF_UPDATE_ABORT_EVT,
+ CE_T4T_RAW_FRAME_EVT,
+ CE_T4T_MAX_EVT
+};
+
+
+#define CE_RAW_FRAME_EVT 0xFF
+
+typedef UINT8 tCE_EVENT;
+
+typedef struct
+{
+ tNFC_STATUS status;
+ BT_HDR *p_data;
+} tCE_T2T_DATA;
+
+typedef struct
+{
+ tNFC_STATUS status;
+ UINT8 *p_data;
+ BOOLEAN b_updated;
+ UINT32 length;
+} tCE_UPDATE_INFO;
+
+typedef struct
+{
+ tNFC_STATUS status;
+ UINT8 aid_handle;
+ BT_HDR *p_data;
+} tCE_RAW_FRAME;
+
+typedef union
+{
+ tNFC_STATUS status;
+ tCE_UPDATE_INFO update_info;
+ tCE_RAW_FRAME raw_frame;
+} tCE_DATA;
+
+typedef void (tCE_CBACK) (tCE_EVENT event, tCE_DATA *p_data);
+
+
+/* T4T definitions */
+typedef UINT8 tCE_T4T_AID_HANDLE; /* Handle for AID registration */
+#define CE_T4T_AID_HANDLE_INVALID 0xFF /* Invalid tCE_T4T_AID_HANDLE */
+#define CE_T4T_WILDCARD_AID_HANDLE (CE_T4T_MAX_REG_AID) /* reserved handle for wildcard aid */
+
+/*******************************************************************************
+**
+** Function CE_T3tSetLocalNDEFMsg
+**
+** Description Initialise CE Type 3 Tag with mandatory NDEF message
+**
+** Returns NFC_STATUS_OK if success
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS CE_T3tSetLocalNDEFMsg (BOOLEAN read_only,
+ UINT32 size_max,
+ UINT32 size_current,
+ UINT8 *p_buf,
+ UINT8 *p_scratch_buf);
+
+/*******************************************************************************
+**
+** Function CE_T3tSetLocalNDefParams
+**
+** Description Sets T3T-specific NDEF parameters. (Optional - if not
+** called, then CE will use default parameters)
+**
+** Returns NFC_STATUS_OK if success
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS CE_T3tSetLocalNDefParams (UINT8 nbr, UINT8 nbw);
+
+/*******************************************************************************
+**
+** Function CE_T3tSendCheckRsp
+**
+** Description Send CHECK response message
+**
+** Returns NFC_STATUS_OK if success
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS CE_T3tSendCheckRsp (UINT8 status1, UINT8 status2, UINT8 num_blocks, UINT8 *p_block_data);
+
+/*******************************************************************************
+**
+** Function CE_T3tSendUpdateRsp
+**
+** Description Send UPDATE response message
+**
+** Returns NFC_STATUS_OK if success
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS CE_T3tSendUpdateRsp (UINT8 status1, UINT8 status2);
+
+/*******************************************************************************
+**
+** Function CE_T4tSetLocalNDEFMsg
+**
+** Description Initialise CE Type 4 Tag with mandatory NDEF message
+**
+** The following event may be returned
+** CE_T4T_UPDATE_START_EVT for starting update
+** CE_T4T_UPDATE_CPLT_EVT for complete update
+** CE_T4T_UPDATE_ABORT_EVT for failure of update
+** CE_T4T_RAW_FRAME_EVT for raw frame
+**
+** read_only: TRUE if read only
+** ndef_msg_max: Max NDEF message size
+** ndef_msg_len: NDEF message size
+** p_ndef_msg: NDEF message (excluding NLEN)
+** p_scratch_buf: temp storage for update
+**
+** Returns NFC_STATUS_OK if success
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS CE_T4tSetLocalNDEFMsg (BOOLEAN read_only,
+ UINT16 ndef_msg_max,
+ UINT16 ndef_msg_len,
+ UINT8 *p_ndef_msg,
+ UINT8 *p_scratch_buf);
+
+/*******************************************************************************
+**
+** Function CE_T4tRegisterAID
+**
+** Description Register AID in CE T4T
+**
+** aid_len: length of AID (up to NFC_MAX_AID_LEN)
+** p_aid: AID
+** p_cback: Raw frame will be forwarded with CE_RAW_FRAME_EVT
+**
+** Returns tCE_T4T_AID_HANDLE if successful,
+** CE_T4T_AID_HANDLE_INVALID otherwisse
+**
+*******************************************************************************/
+NFC_API extern tCE_T4T_AID_HANDLE CE_T4tRegisterAID (UINT8 aid_len,
+ UINT8 *p_aid,
+ tCE_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function CE_T4tDeregisterAID
+**
+** Description Deregister AID in CE T4T
+**
+** aid_len: length of AID (up to NFC_MAX_AID_LEN)
+** p_aid: AID
+**
+** Returns NFC_STATUS_OK if success
+**
+*******************************************************************************/
+NFC_API extern void CE_T4tDeregisterAID (tCE_T4T_AID_HANDLE aid_handle);
+
+/*******************************************************************************
+**
+** Function CE_T4TTestSetCC
+**
+** Description Set fields in Capability Container File for testing
+**
+** Returns NFC_STATUS_OK if success
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS CE_T4TTestSetCC (UINT16 cc_len,
+ UINT8 version,
+ UINT16 max_le,
+ UINT16 max_lc);
+
+/*******************************************************************************
+**
+** Function CE_T4TTestSetNDEFCtrlTLV
+**
+** Description Set fields in NDEF File Control TLV for testing
+**
+** Returns NFC_STATUS_OK if success
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS CE_T4TTestSetNDEFCtrlTLV (UINT8 type,
+ UINT8 length,
+ UINT16 file_id,
+ UINT16 max_file_size,
+ UINT8 read_access,
+ UINT8 write_access);
+
+/*******************************************************************************
+**
+** Function CE_SendRawFrame
+**
+** Description This function sends a raw frame to the peer device.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS CE_SendRawFrame (UINT8 *p_raw_data, UINT16 data_len);
+
+/*******************************************************************************
+**
+** Function CE_SetActivatedTagType
+**
+** Description This function selects the tag type for Reader/Writer mode.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS CE_SetActivatedTagType (tNFC_ACTIVATE_DEVT *p_activate_params, UINT16 t3t_system_code, tCE_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function CE_SetTraceLevel
+**
+** Description This function sets the trace level for Card Emulation mode.
+** If called with a value of 0xFF,
+** it simply returns the current trace level.
+**
+** Returns The new or current trace level
+**
+*******************************************************************************/
+NFC_API extern UINT8 CE_SetTraceLevel (UINT8 new_level);
+
+#endif /* CE_API_H */
diff --git a/src/nfc/include/llcp_api.h b/src/nfc/include/llcp_api.h
new file mode 100644
index 0000000..eb20ec1
--- /dev/null
+++ b/src/nfc/include/llcp_api.h
@@ -0,0 +1,711 @@
+/******************************************************************************
+ *
+ * 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
+*****************************************************************************/
+#define LLCP_STATUS_SUCCESS 0 /* Successfully done */
+#define LLCP_STATUS_FAIL 1 /* Failed without specific reason */
+#define LLCP_STATUS_CONGESTED 2 /* Data link is congested */
+
+typedef UINT8 tLLCP_STATUS;
+
+#define LLCP_MIN_OFFSET (NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE)
+
+#define LLCP_INVALID_SAP 0xFF /* indication of failure to allocate data link resource */
+
+/*****************************************************************************
+** Type Definitions
+*****************************************************************************/
+typedef struct
+{
+ BOOLEAN is_initiator; /* TRUE if we are POLL mode */
+ UINT8 max_payload_size; /* 64, 128, 192 or 254 */
+ UINT8 waiting_time;
+ UINT8 *p_gen_bytes;
+ UINT8 gen_bytes_len;
+} tLLCP_ACTIVATE_CONFIG;
+
+typedef struct
+{
+ UINT16 miu; /* Local receiving MIU */
+ UINT8 rw; /* Local receiving window */
+ char sn[LLCP_MAX_SN_LEN + 1]; /* Service name to connect */
+} tLLCP_CONNECTION_PARAMS;
+
+/*********************************
+** Callback Functions Prototypes
+**********************************/
+
+/* Link Management Callback Events */
+
+#define LLCP_LINK_ACTIVATION_FAILED_EVT 0x00 /* Fail to activate link */
+#define LLCP_LINK_ACTIVATION_COMPLETE_EVT 0x01 /* LLCP Link is activated */
+#define LLCP_LINK_DEACTIVATED_EVT 0x02 /* LLCP Link is deactivated */
+#define LLCP_LINK_FIRST_PACKET_RECEIVED_EVT 0x03 /* First LLCP packet received from remote */
+
+/* Link Management Callback Reasons */
+
+#define LLCP_LINK_SUCCESS 0x00 /* Success */
+#define LLCP_LINK_VERSION_FAILED 0x01 /* Failed to agree version */
+#define LLCP_LINK_BAD_GEN_BYTES 0x02 /* Failed to parse received general bytes */
+#define LLCP_LINK_INTERNAL_ERROR 0x03 /* internal error */
+#define LLCP_LINK_LOCAL_INITIATED 0x04 /* Link has been deactivated by local */
+#define LLCP_LINK_REMOTE_INITIATED 0x05 /* Link has been deactivated by remote */
+#define LLCP_LINK_TIMEOUT 0x06 /* Link has been deactivated by timeout */
+#define LLCP_LINK_FRAME_ERROR 0x07 /* Link has been deactivated by frame error */
+#define LLCP_LINK_RF_LINK_LOSS_NO_RX_LLC 0x08 /* RF link loss without any rx LLC PDU */
+
+
+#define LLCP_LINK_RF_TRANSMISSION_ERR NFC_STATUS_RF_TRANSMISSION_ERR
+#define LLCP_LINK_RF_PROTOCOL_ERR NFC_STATUS_RF_PROTOCOL_ERR
+#define LLCP_LINK_RF_TIMEOUT NFC_STATUS_TIMEOUT
+#define LLCP_LINK_RF_LINK_LOSS_ERR NFC_STATUS_LINK_LOSS
+
+typedef void (tLLCP_LINK_CBACK) (UINT8 event, UINT8 reason);
+
+/* Minimum length of Gen Bytes for LLCP */
+/* In CE4 low power mode, NFCC can store up to 21 bytes */
+#define LLCP_MIN_GEN_BYTES 20
+
+/* Service Access Point (SAP) Callback Events */
+
+#define LLCP_SAP_EVT_DATA_IND 0x00 /* Received data on SAP */
+#define LLCP_SAP_EVT_CONNECT_IND 0x01 /* Connection request from peer */
+#define LLCP_SAP_EVT_CONNECT_RESP 0x02 /* Connection accepted by peer */
+#define LLCP_SAP_EVT_DISCONNECT_IND 0x03 /* Received disconnect request */
+#define LLCP_SAP_EVT_DISCONNECT_RESP 0x04 /* Received disconnect response */
+#define LLCP_SAP_EVT_CONGEST 0x05 /* congested status is changed */
+#define LLCP_SAP_EVT_LINK_STATUS 0x06 /* Change of LLCP Link status */
+#define LLCP_SAP_EVT_TX_COMPLETE 0x07 /* tx queue is empty and all PDU is acked */
+
+#define LLCP_LINK_TYPE_LOGICAL_DATA_LINK 0x01
+#define LLCP_LINK_TYPE_DATA_LINK_CONNECTION 0x02
+
+typedef struct
+{
+ UINT8 event; /* LLCP_SAP_EVT_DATA_IND */
+ UINT8 local_sap; /* SAP of local device */
+ UINT8 remote_sap; /* SAP of remote device */
+ UINT8 link_type; /* link type */
+} tLLCP_SAP_DATA_IND;
+
+typedef struct
+{
+ UINT8 event; /* LLCP_SAP_EVT_CONNECT_IND */
+ UINT8 server_sap; /* SAP of local server */
+ UINT8 local_sap; /* SAP of local device */
+ UINT8 remote_sap; /* SAP of remote device */
+ UINT16 miu; /* MIU of peer device */
+ UINT8 rw; /* RW of peer device */
+ char *p_service_name; /* Service name (only for SDP) */
+} tLLCP_SAP_CONNECT_IND;
+
+typedef struct
+{
+ UINT8 event; /* LLCP_SAP_EVT_CONNECT_RESP */
+ UINT8 local_sap; /* SAP of local device */
+ UINT8 remote_sap; /* SAP of remote device */
+ UINT16 miu; /* MIU of peer device */
+ UINT8 rw; /* RW of peer device */
+} tLLCP_SAP_CONNECT_RESP;
+
+#define LLCP_SAP_DISCONNECT_REASON_TIMEOUT 0x80
+typedef struct
+{
+ UINT8 event; /* LLCP_SAP_EVT_DISCONNECT_IND */
+ UINT8 local_sap; /* SAP of local device */
+ UINT8 remote_sap; /* SAP of remote device */
+} tLLCP_SAP_DISCONNECT_IND;
+
+typedef struct
+{
+ UINT8 event; /* LLCP_SAP_EVT_DISCONNECT_RESP */
+ UINT8 local_sap; /* SAP of local device */
+ UINT8 remote_sap; /* SAP of remote device */
+ UINT8 reason; /* Reason of DM PDU if not timeout */
+} tLLCP_SAP_DISCONNECT_RESP;
+
+typedef struct
+{
+ UINT8 event; /* LLCP_SAP_EVT_CONGEST */
+ UINT8 local_sap; /* SAP of local device */
+ UINT8 remote_sap; /* SAP of remote device */
+ BOOLEAN is_congested; /* TRUE if congested */
+ UINT8 link_type; /* congested link type */
+} tLLCP_SAP_CONGEST;
+
+typedef struct
+{
+ UINT8 event; /* LLCP_SAP_EVT_LINK_STATUS */
+ UINT8 local_sap; /* SAP of local device */
+ BOOLEAN is_activated; /* TRUE if LLCP link is activated */
+ BOOLEAN is_initiator; /* TRUE if local LLCP is initiator */
+} tLLCP_SAP_LINK_STATUS;
+
+typedef struct
+{
+ UINT8 event; /* LLCP_SAP_EVT_TX_COMPLETE */
+ UINT8 local_sap; /* SAP of local device */
+ UINT8 remote_sap; /* SAP of remote device */
+} tLLCP_SAP_TX_COMPLETE;
+
+typedef struct
+{
+ UINT8 event; /* event */
+ UINT8 local_sap; /* SAP of local device */
+} tLLCP_SAP_HEADER;
+
+typedef union
+{
+ tLLCP_SAP_HEADER hdr; /* common header */
+ tLLCP_SAP_DATA_IND data_ind; /* LLCP_SAP_EVT_DATA_IND */
+ tLLCP_SAP_CONNECT_IND connect_ind; /* LLCP_SAP_EVT_CONNECT_IND */
+ tLLCP_SAP_CONNECT_RESP connect_resp; /* LLCP_SAP_EVT_CONNECT_RESP */
+ tLLCP_SAP_DISCONNECT_IND disconnect_ind; /* LLCP_SAP_EVT_DISCONNECT_IND */
+ tLLCP_SAP_DISCONNECT_RESP disconnect_resp; /* LLCP_SAP_EVT_DISCONNECT_RESP */
+ tLLCP_SAP_CONGEST congest; /* LLCP_SAP_EVT_CONGEST */
+ tLLCP_SAP_LINK_STATUS link_status; /* LLCP_SAP_EVT_LINK_STATUS */
+ tLLCP_SAP_TX_COMPLETE tx_complete; /* LLCP_SAP_EVT_TX_COMPLETE */
+} tLLCP_SAP_CBACK_DATA;
+
+typedef void (tLLCP_APP_CBACK) (tLLCP_SAP_CBACK_DATA *p_data);
+
+/* Service Discovery Callback */
+
+typedef void (tLLCP_SDP_CBACK) (UINT8 tid, UINT8 remote_sap);
+
+/* LLCP DTA Callback - notify DTA responded SNL for connectionless echo service */
+
+typedef void (tLLCP_DTA_CBACK) (void);
+
+/*****************************************************************************
+** External Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*******************************************************************************
+**
+** Function LLCP_SetConfig
+**
+** Description Set configuration parameters for LLCP
+** - Local Link MIU
+** - Option parameter
+** - Waiting Time Index
+** - Local Link Timeout
+** - Inactivity Timeout as initiator role
+** - Inactivity Timeout as target role
+** - Delay SYMM response
+** - Data link connection timeout
+** - Delay timeout to send first PDU as initiator
+** - Firmware start symmetry
+** Returns void
+**
+*******************************************************************************/
+LLCP_API extern void LLCP_SetConfig (UINT16 link_miu,
+ UINT8 opt,
+ UINT8 wt,
+ UINT16 link_timeout,
+ UINT16 inact_timeout_init,
+ UINT16 inact_timeout_target,
+ UINT16 symm_delay,
+ UINT16 data_link_timeout,
+ UINT16 delay_first_pdu_timeout);
+
+/*******************************************************************************
+**
+** Function LLCP_GetConfig
+**
+** Description Get configuration parameters for LLCP
+** - Local Link MIU
+** - Option parameter
+** - Response Waiting Time Index
+** - Local Link Timeout
+** - Inactivity Timeout as initiator role
+** - Inactivity Timeout as target role
+** - Delay SYMM response
+** - Data link connection timeout
+** - Delay timeout to send first PDU as initiator
+** - Firmware start symmetry
+** Returns void
+**
+*******************************************************************************/
+LLCP_API extern void LLCP_GetConfig (UINT16 *p_link_miu,
+ UINT8 *p_opt,
+ UINT8 *p_wt,
+ UINT16 *p_link_timeout,
+ UINT16 *p_inact_timeout_init,
+ UINT16 *p_inact_timeout_target,
+ UINT16 *p_symm_delay,
+ UINT16 *p_data_link_timeout,
+ UINT16 *p_delay_first_pdu_timeout);
+
+/*******************************************************************************
+**
+** Function LLCP_GetDiscoveryConfig
+**
+** Description Returns discovery config for LLCP MAC link activation
+** This function is called to get general bytes for NFC_PMID_ATR_REQ_GEN_BYTES
+** or NFC_PMID_ATR_RES_GEN_BYTES before starting discovery.
+**
+** wt:Waiting time 0 - 8, only for listen
+** p_gen_bytes: pointer to store LLCP magic number and paramters
+** p_gen_bytes_len: length of buffer for gen bytes as input
+** (NOTE:it must be bigger than LLCP_MIN_GEN_BYTES)
+** actual gen bytes size as output
+**
+** Restrictions on the use of ISO 18092
+** 1. The DID features shall not be used.
+** 2. the NAD features shall not be used.
+** 3. Frame waiting time extentions (WTX) shall not be used.
+**
+** Returns None
+**
+*******************************************************************************/
+LLCP_API extern void LLCP_GetDiscoveryConfig (UINT8 *p_wt,
+ UINT8 *p_gen_bytes,
+ UINT8 *p_gen_bytes_len);
+
+/*******************************************************************************
+**
+** Function LLCP_ActivateLink
+**
+** Description This function will activate LLCP link with LR, WT and Gen Bytes
+** in activation NTF from NFCC.
+**
+** LLCP_LINK_ACTIVATION_COMPLETE_EVT will be returned through
+** callback function if successful.
+** Otherwise, LLCP_LINK_ACTIVATION_FAILED_EVT will be returned.
+**
+** Returns LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+LLCP_API extern tLLCP_STATUS LLCP_ActivateLink (tLLCP_ACTIVATE_CONFIG config,
+ tLLCP_LINK_CBACK *p_link_cback);
+
+/*******************************************************************************
+**
+** Function LLCP_DeactivateLink
+**
+** Description Deactivate LLCP link
+**
+** LLCP_LINK_DEACTIVATED_EVT will be returned through callback
+** when LLCP link is deactivated. Then NFC link may be deactivated.
+**
+** Returns LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+LLCP_API extern tLLCP_STATUS LLCP_DeactivateLink (void);
+
+/*******************************************************************************
+**
+** Function LLCP_RegisterServer
+**
+** Description Register server and callback function
+**
+** reg_sap : Well-Known SAP except LM and SDP (0x02 - 0x0F)
+** Advertized by SDP (0x10 - 0x1F)
+** LLCP_INVALID_SAP, LLCP will allocate between 0x10 and 0x1F
+** link_type : LLCP_LINK_TYPE_LOGICAL_DATA_LINK
+** and/or LLCP_LINK_TYPE_DATA_LINK_CONNECTION
+** p_service_name : Null-terminated string up to LLCP_MAX_SN_LEN
+**
+** Returns SAP between 0x02 and 0x1F, if success
+** LLCP_INVALID_SAP, otherwise
+**
+*******************************************************************************/
+LLCP_API extern UINT8 LLCP_RegisterServer (UINT8 reg_sap,
+ UINT8 link_type,
+ char *p_service_name,
+ tLLCP_APP_CBACK *p_sap_cback);
+
+/*******************************************************************************
+**
+** Function LLCP_RegisterClient
+**
+** Description Register client and callback function
+**
+** link_type : LLCP_LINK_TYPE_LOGICAL_DATA_LINK
+** and/or LLCP_LINK_TYPE_DATA_LINK_CONNECTION
+**
+** Returns SAP between 0x20 and 0x3F, if success
+** LLCP_INVALID_SAP, otherwise
+**
+*******************************************************************************/
+LLCP_API extern UINT8 LLCP_RegisterClient (UINT8 link_type,
+ tLLCP_APP_CBACK *p_sap_cback);
+
+/*******************************************************************************
+**
+** Function LLCP_Deregister
+**
+** Description Deregister server or client
+**
+**
+** Returns LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+LLCP_API extern tLLCP_STATUS LLCP_Deregister (UINT8 sap);
+
+/*******************************************************************************
+**
+** Function LLCP_IsLogicalLinkCongested
+**
+** Description Check if logical link is congested
+**
+**
+** Returns TRUE if congested
+**
+*******************************************************************************/
+LLCP_API extern BOOLEAN LLCP_IsLogicalLinkCongested (UINT8 local_sap,
+ UINT8 num_pending_ui_pdu,
+ UINT8 total_pending_ui_pdu,
+ UINT8 total_pending_i_pdu);
+
+/*******************************************************************************
+**
+** Function LLCP_SendUI
+**
+** Description Send connnectionless data to DSAP
+**
+**
+** Returns LLCP_STATUS_SUCCESS if success
+** LLCP_STATUS_CONGESTED if logical link is congested
+** LLCP_STATUS_FAIL, otherwise
+**
+*******************************************************************************/
+LLCP_API extern tLLCP_STATUS LLCP_SendUI (UINT8 ssap, UINT8 dsap, BT_HDR *p_buf);
+
+/*******************************************************************************
+**
+** Function LLCP_ReadLogicalLinkData
+**
+** Description Read information of UI PDU for local SAP
+**
+** - Remote SAP who sent UI PDU is returned.
+** - Information of UI PDU up to max_data_len is copied into p_data.
+** - Information of next UI PDU is not concatenated.
+** - Recommended max_data_len is link MIU of local device
+**
+** Returns TRUE if more information of UI PDU or more UI PDU in queue
+**
+*******************************************************************************/
+LLCP_API extern BOOLEAN LLCP_ReadLogicalLinkData (UINT8 local_sap,
+ UINT32 max_data_len,
+ UINT8 *p_remote_sap,
+ UINT32 *p_data_len,
+ UINT8 *p_data);
+
+/*******************************************************************************
+**
+** Function LLCP_FlushLogicalLinkRxData
+**
+** Description Discard received data in logical data link of local SAP
+**
+**
+** Returns length of data flushed
+**
+*******************************************************************************/
+LLCP_API extern UINT32 LLCP_FlushLogicalLinkRxData (UINT8 local_sap);
+
+/*******************************************************************************
+**
+** Function LLCP_ConnectReq
+**
+** Description Create data link connection between registered SAP and DSAP
+** in peer LLCP,
+**
+**
+** Returns LLCP_STATUS_SUCCESS if success
+** LLCP_STATUS_FAIL, otherwise
+**
+*******************************************************************************/
+LLCP_API extern tLLCP_STATUS LLCP_ConnectReq (UINT8 reg_sap, UINT8 dsap,
+ tLLCP_CONNECTION_PARAMS *p_params);
+
+/*******************************************************************************
+**
+** Function LLCP_ConnectCfm
+**
+** Description Accept connection request from peer LLCP
+**
+**
+** Returns LLCP_STATUS_SUCCESS if success
+** LLCP_STATUS_FAIL, otherwise
+**
+*******************************************************************************/
+LLCP_API extern tLLCP_STATUS LLCP_ConnectCfm (UINT8 local_sap,
+ UINT8 remote_sap,
+ tLLCP_CONNECTION_PARAMS *p_params);
+
+/*******************************************************************************
+**
+** Function LLCP_ConnectReject
+**
+** Description Reject connection request from peer LLCP
+**
+** reason : LLCP_SAP_DM_REASON_APP_REJECTED
+** LLCP_SAP_DM_REASON_PERM_REJECT_THIS
+** LLCP_SAP_DM_REASON_PERM_REJECT_ANY
+** LLCP_SAP_DM_REASON_TEMP_REJECT_THIS
+** LLCP_SAP_DM_REASON_TEMP_REJECT_ANY
+**
+** Returns LLCP_STATUS_SUCCESS if success
+** LLCP_STATUS_FAIL, otherwise
+**
+*******************************************************************************/
+LLCP_API extern tLLCP_STATUS LLCP_ConnectReject (UINT8 local_sap,
+ UINT8 remote_sap,
+ UINT8 reason);
+
+/*******************************************************************************
+**
+** Function LLCP_IsDataLinkCongested
+**
+** Description Check if data link is congested
+**
+**
+** Returns TRUE if congested
+**
+*******************************************************************************/
+LLCP_API extern BOOLEAN LLCP_IsDataLinkCongested (UINT8 local_sap,
+ UINT8 remote_sap,
+ UINT8 num_pending_i_pdu,
+ UINT8 total_pending_ui_pdu,
+ UINT8 total_pending_i_pdu);
+
+/*******************************************************************************
+**
+** Function LLCP_SendData
+**
+** Description Send connection-oriented data
+**
+**
+** Returns LLCP_STATUS_SUCCESS if success
+** LLCP_STATUS_CONGESTED if data link is congested
+**
+*******************************************************************************/
+LLCP_API extern tLLCP_STATUS LLCP_SendData (UINT8 local_sap,
+ UINT8 remote_sap,
+ BT_HDR *p_buf);
+
+/*******************************************************************************
+**
+** Function LLCP_ReadDataLinkData
+**
+** Description Read information of I PDU for data link connection
+**
+** - Information of I PDU up to max_data_len is copied into p_data.
+** - Information of next I PDU is not concatenated.
+** - Recommended max_data_len is data link connection MIU of local
+** end point
+**
+** Returns TRUE if more data in queue
+**
+*******************************************************************************/
+LLCP_API extern BOOLEAN LLCP_ReadDataLinkData (UINT8 local_sap,
+ UINT8 remote_sap,
+ UINT32 max_data_len,
+ UINT32 *p_data_len,
+ UINT8 *p_data);
+
+/*******************************************************************************
+**
+** Function LLCP_FlushDataLinkRxData
+**
+** Description Discard received data in data link connection
+**
+**
+** Returns length of rx data flushed
+**
+*******************************************************************************/
+LLCP_API extern UINT32 LLCP_FlushDataLinkRxData (UINT8 local_sap,
+ UINT8 remote_sap);
+
+/*******************************************************************************
+**
+** Function LLCP_DisconnectReq
+**
+** Description Disconnect data link
+** discard any pending data if flush is set to TRUE
+**
+** Returns LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+LLCP_API extern tLLCP_STATUS LLCP_DisconnectReq (UINT8 local_sap,
+ UINT8 remote_sap,
+ BOOLEAN flush);
+
+/*******************************************************************************
+**
+** Function LLCP_SetTxCompleteNtf
+**
+** Description This function is called to get LLCP_SAP_EVT_TX_COMPLETE
+** when Tx queue is empty and all PDU is acked.
+** This is one time event, so upper layer shall call this function
+** again to get next LLCP_SAP_EVT_TX_COMPLETE.
+**
+** Returns LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+LLCP_API extern tLLCP_STATUS LLCP_SetTxCompleteNtf (UINT8 local_sap,
+ UINT8 remote_sap);
+
+/*******************************************************************************
+**
+** Function LLCP_SetLocalBusyStatus
+**
+** Description Set local busy status
+**
+**
+** Returns LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+LLCP_API extern tLLCP_STATUS LLCP_SetLocalBusyStatus (UINT8 local_sap,
+ UINT8 remote_sap,
+ BOOLEAN is_busy);
+
+/*******************************************************************************
+**
+** Function LLCP_GetRemoteWKS
+**
+** Description Return well-known service bitmap of connected device
+**
+**
+** Returns WKS bitmap if success
+**
+*******************************************************************************/
+LLCP_API extern UINT16 LLCP_GetRemoteWKS (void);
+
+/*******************************************************************************
+**
+** Function LLCP_GetRemoteLSC
+**
+** Description Return link service class of connected device
+**
+**
+** Returns link service class
+**
+*******************************************************************************/
+LLCP_API extern UINT8 LLCP_GetRemoteLSC (void);
+
+/*******************************************************************************
+**
+** Function LLCP_GetLinkMIU
+**
+** Description Return local and remote link MIU
+**
+**
+** Returns None
+**
+*******************************************************************************/
+LLCP_API extern void LLCP_GetLinkMIU (UINT16 *p_local_link_miu, UINT16 *p_remote_link_miu);
+
+/*******************************************************************************
+**
+** Function LLCP_DiscoverService
+**
+** Description Return SAP of service name in connected device through callback
+**
+**
+** Returns LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+LLCP_API extern tLLCP_STATUS LLCP_DiscoverService (char *p_name,
+ tLLCP_SDP_CBACK *p_cback,
+ UINT8 *p_tid);
+
+/*******************************************************************************
+**
+** Function LLCP_SetTraceLevel
+**
+** Description This function sets the trace level for LLCP. If called with
+** a value of 0xFF, it simply returns the current trace level.
+**
+** Returns The new or current trace level
+**
+*******************************************************************************/
+LLCP_API extern UINT8 LLCP_SetTraceLevel (UINT8 new_level);
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+/*******************************************************************************
+**
+** Function LLCP_RegisterDtaCback
+**
+** Description Register callback function for LLCP DTA testing
+**
+**
+** Returns void
+**
+*******************************************************************************/
+LLCP_API extern void LLCP_RegisterDtaCback (tLLCP_DTA_CBACK *p_dta_cback);
+#endif
+
+#if (LLCP_TEST_INCLUDED == TRUE)
+/*******************************************************************************
+**
+** Function LLCP_SetTestParams
+**
+** Description Set test parameters for LLCP
+**
+**
+** Returns void
+**
+*******************************************************************************/
+LLCP_API extern void LLCP_SetTestParams (UINT8 version, UINT16 wks);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LLCP_API_H */
diff --git a/src/nfc/include/llcp_defs.h b/src/nfc/include/llcp_defs.h
new file mode 100644
index 0000000..c944042
--- /dev/null
+++ b/src/nfc/include/llcp_defs.h
@@ -0,0 +1,193 @@
+/******************************************************************************
+ *
+ * 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) (dsap) << 10) | ((UINT16) (ptype) << 6) | (UINT16) (ssap))
+
+#define LLCP_GET_NS(u8) ((UINT8)(u8) >> 4)
+#define LLCP_GET_NR(u8) ((UINT8)(u8) & 0x0F)
+#define LLCP_GET_SEQUENCE(NS, NR) (((UINT8) (NS) << 4) | (UINT8) (NR))
+#define LLCP_SEQUENCE_SIZE 1
+
+#define LLCP_PDU_SYMM_TYPE 0
+#define LLCP_PDU_PAX_TYPE 1
+#define LLCP_PDU_AGF_TYPE 2
+#define LLCP_PDU_UI_TYPE 3
+#define LLCP_PDU_CONNECT_TYPE 4
+#define LLCP_PDU_DISC_TYPE 5
+#define LLCP_PDU_CC_TYPE 6
+#define LLCP_PDU_DM_TYPE 7
+#define LLCP_PDU_FRMR_TYPE 8
+#define LLCP_PDU_SNL_TYPE 9
+#define LLCP_PDU_RESERVED_1010 10
+#define LLCP_PDU_RESERVED_1011 11
+#define LLCP_PDU_I_TYPE 12
+#define LLCP_PDU_RR_TYPE 13
+#define LLCP_PDU_RNR_TYPE 14
+#define LLCP_PDU_RESERVED_1111 15
+
+#define LLCP_PDU_SYMM_SIZE 2
+#define LLCP_PDU_DISC_SIZE 2
+#define LLCP_PDU_DM_SIZE 3
+#define LLCP_PDU_FRMR_SIZE 6
+#define LLCP_PDU_RR_SIZE 3
+#define LLCP_PDU_RNR_SIZE 3
+#define LLCP_PDU_AGF_LEN_SIZE 2 /* 2 bytes of length in AGF PDU */
+
+#define LLCP_SAP_DM_REASON_RESP_DISC 0x00
+#define LLCP_SAP_DM_REASON_NO_ACTIVE_CONNECTION 0x01
+#define LLCP_SAP_DM_REASON_NO_SERVICE 0x02
+#define LLCP_SAP_DM_REASON_APP_REJECTED 0x03
+#define LLCP_SAP_DM_REASON_PERM_REJECT_THIS 0x10
+#define LLCP_SAP_DM_REASON_PERM_REJECT_ANY 0x11
+#define LLCP_SAP_DM_REASON_TEMP_REJECT_THIS 0x20
+#define LLCP_SAP_DM_REASON_TEMP_REJECT_ANY 0x21
+
+#define LLCP_FRMR_W_ERROR_FLAG 0x08 /* Well-formedness Error */
+#define LLCP_FRMR_I_ERROR_FLAG 0x04 /* Information Field Error */
+#define LLCP_FRMR_R_ERROR_FLAG 0x02 /* Receive Sequence Error */
+#define LLCP_FRMR_S_ERROR_FLAG 0x01 /* Send Sequence Error */
+
+#define LLCP_GET_FRMR_W_ERROR_FLAG(u8) (((UINT8) (u8) >> 7) & 0x01)
+#define LLCP_GET_FRMR_I_ERROR_FLAG(u8) (((UINT8) (u8) >> 6) & 0x01)
+#define LLCP_GET_FRMR_R_ERROR_FLAG(u8) (((UINT8) (u8) >> 5) & 0x01)
+#define LLCP_GET_FRMR_S_ERROR_FLAG(u8) (((UINT8) (u8) >> 4) & 0x01)
+#define LLCP_GET_FRMR_PTYPE(u8) ((UINT8) (u8) & 0x0F)
+#define LLCP_GET_FRMR_VS(u16) (((UINT16) (u16) >> 12) & 0x000F)
+#define LLCP_GET_FRMR_VR(u16) (((UINT16) (u16) >> 8) & 0x000F)
+#define LLCP_GET_FRMR_VSA(u16) (((UINT16) (u16) >> 4) & 0x000F)
+#define LLCP_GET_FRMR_VRA(u16) (((UINT16) (u16) >> 0) & 0x000F)
+
+/*
+** LLCP Parameter Descriptions
+*/
+
+/* Version */
+#define LLCP_VERSION_TYPE 0x01
+#define LLCP_VERSION_LEN 0x01
+#define LLCP_GET_MAJOR_VERSION(u8) (((UINT8) (u8) >> 4) & 0x0F)
+#define LLCP_GET_MINOR_VERSION(u8) ((UINT8) (u8) & 0x0F)
+#define LLCP_MIN_MAJOR_VERSION 0x01
+#define LLCP_MIN_SNL_MAJOR_VERSION 0x01
+#define LLCP_MIN_SNL_MINOR_VERSION 0x01
+
+/* LLCP Version 1.1 */
+#define LLCP_VERSION_MAJOR 0x01
+#define LLCP_VERSION_MINOR 0x01
+#define LLCP_VERSION_VALUE ((LLCP_VERSION_MAJOR << 4) | LLCP_VERSION_MINOR)
+
+/* Maximum Information Unit Extension */
+#define LLCP_MIUX_TYPE 0x02
+#define LLCP_MIUX_LEN 0x02
+#define LLCP_MIUX_MASK 0x07FF /* MIUX bit 10:0 */
+#define LLCP_DEFAULT_MIU 128 /* if local LLC doesn't receive MIUX */
+#define LLCP_MAX_MIU 2175 /* 2047 (11bits) + 128 */
+
+/* Well-Known Service */
+#define LLCP_WKS_TYPE 0x03
+#define LLCP_WKS_LEN 0x02
+
+/* Well-Known Service Bitmap */
+#define LLCP_WKS_MASK_LM 0x0001 /* Link Management */
+#define LLCP_WKS_MASK_SDP 0x0002 /* Service Discovery "urn:nfc:sn:sdp" */
+#define LLCP_WKS_MASK_IP 0x0004 /* IP over LLCP Binding "urn:nfc:sn:ip" */
+#define LLCP_WKS_MASK_OBEX 0x0008 /* OBEX over LLCP Binding "urn:nfc:sn:obex" */
+#define LLCP_WKS_MASK_SNEP 0x0010 /* Simple NDEP Exchange Protocol "urn:nfc:sn:snep" */
+
+/* Well-Known Service Access Points */
+#define LLCP_SAP_LM 0x00 /* Link Management */
+#define LLCP_SAP_SDP 0x01 /* Service Discovery "urn:nfc:sn:sdp" */
+#define LLCP_SAP_IP 0x02 /* IP over LLCP Binding "urn:nfc:sn:ip" */
+#define LLCP_SAP_OBEX 0x03 /* OBEX over LLCP Binding "urn:nfc:sn:obex" */
+#define LLCP_SAP_SNEP 0x04 /* Simple NDEP Exchange Protocol "urn:nfc:sn:snep" */
+
+/* Link Timeout, LTO */
+#define LLCP_LTO_TYPE 0x04
+#define LLCP_LTO_LEN 0x01
+#define LLCP_DEFAULT_LTO_IN_MS 100 /* default 100ms. It should be sufficiently larget than RWT */
+#define LLCP_LTO_UNIT 10 /* 10 ms */
+#define LLCP_MAX_LTO_IN_MS 2550 /* 2550 ms; 8bits * 10ms */
+
+/* Receive Window Size, RW */
+#define LLCP_RW_TYPE 0x05
+#define LLCP_RW_LEN 0x01
+#define LLCP_DEFAULT_RW 1 /* if local LLC doesn't receive RW */
+
+/* Service Name, SN */
+#define LLCP_SN_TYPE 0x06
+
+/* Option, OPT */
+#define LLCP_OPT_TYPE 0x07
+#define LLCP_OPT_LEN 0x01
+#define LLCP_GET_OPT_LSC(u8) ((UINT8) (u8) & 0x03)
+
+/* Service Discovery Request, SDREQ */
+#define LLCP_SDREQ_TYPE 0x08
+#define LLCP_SDREQ_MIN_LEN 0x03 /* type(1 byte), length(1 byte), TID(1 byte) */
+
+/* Service Discovery Response, SDRES */
+#define LLCP_SDRES_TYPE 0x09
+#define LLCP_SDRES_LEN 0x02
+
+/* Link Service Class */
+#define LLCP_LSC_UNKNOWN 0x00
+#define LLCP_LSC_1 0x01
+#define LLCP_LSC_2 0x02
+#define LLCP_LSC_3 0x03
+
+#define LLCP_MAGIC_NUMBER_LEN 3
+#define LLCP_MAGIC_NUMBER_BYTE0 0x46
+#define LLCP_MAGIC_NUMBER_BYTE1 0x66
+#define LLCP_MAGIC_NUMBER_BYTE2 0x6D
+
+#define LLCP_SEQ_MODULO 16
+
+#define LLCP_NUM_SAPS 64
+#define LLCP_LOWER_BOUND_WK_SAP 0x00
+#define LLCP_UPPER_BOUND_WK_SAP 0x0F
+#define LLCP_LOWER_BOUND_SDP_SAP 0x10
+#define LLCP_UPPER_BOUND_SDP_SAP 0x1F
+#define LLCP_LOWER_BOUND_LOCAL_SAP 0x20
+#define LLCP_UPPER_BOUND_LOCAL_SAP 0x3F
+
+/* Max Payload */
+#define LLCP_NCI_MAX_PAYL_SIZE 254 /* Maximum Payload size, Length Reduction LRi/LRt */
+#define LLCP_NFC_DEP_HEADER_SIZE 3 /* Data exchange protocol header, 3 bytes */
+#define LLCP_MAX_PAYLOAD_SIZE (LLCP_NCI_MAX_PAYL_SIZE - LLCP_NFC_DEP_HEADER_SIZE)
+
+#define LLCP_MAX_GEN_BYTES 48
+
+#endif /* LLCP_DEFS_H */
diff --git a/src/nfc/include/nci_hmsgs.h b/src/nfc/include/nci_hmsgs.h
new file mode 100644
index 0000000..da5c1b8
--- /dev/null
+++ b/src/nfc/include/nci_hmsgs.h
@@ -0,0 +1,97 @@
+/******************************************************************************
+ *
+ * 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 "nci_defs.h"
+
+
+BOOLEAN nci_proc_core_rsp (BT_HDR *p_msg);
+void nci_proc_rf_management_rsp (BT_HDR *p_msg);
+void nci_proc_ee_management_rsp (BT_HDR *p_msg);
+void nci_proc_core_ntf (BT_HDR *p_msg);
+void nci_proc_rf_management_ntf (BT_HDR *p_msg);
+void nci_proc_ee_management_ntf (BT_HDR *p_msg);
+void nci_proc_prop_rsp (BT_HDR *p_msg);
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+void nci_proc_prop_nxp_rsp (BT_HDR *p_msg);
+#endif
+void nci_proc_prop_ntf (BT_HDR *p_msg);
+
+
+UINT8 nci_snd_core_reset (UINT8 reset_type);
+UINT8 nci_snd_core_init (void);
+UINT8 nci_snd_core_get_config (UINT8 *param_ids, UINT8 num_ids);
+UINT8 nci_snd_core_set_config (UINT8 *p_param_tlvs, UINT8 tlv_size);
+
+UINT8 nci_snd_core_conn_create (UINT8 dest_type, UINT8 num_tlv, UINT8 tlv_size, UINT8 *p_param_tlvs);
+UINT8 nci_snd_core_conn_close (UINT8 conn_id);
+
+
+
+UINT8 nci_snd_discover_cmd (UINT8 num, tNCI_DISCOVER_PARAMS *p_param);
+
+UINT8 nci_snd_discover_select_cmd (UINT8 rf_disc_id, UINT8 protocol, UINT8 rf_interface);
+UINT8 nci_snd_deactivate_cmd (UINT8 de_act_type );
+UINT8 nci_snd_discover_map_cmd (UINT8 num, tNCI_DISCOVER_MAPS *p_maps);
+UINT8 nci_snd_t3t_polling (UINT16 system_code, UINT8 rc, UINT8 tsn);
+UINT8 nci_snd_parameter_update_cmd (UINT8 *p_param_tlvs, UINT8 tlv_size);
+
+
+#if ((NFC_NFCEE_INCLUDED == TRUE) && (NFC_RW_ONLY == FALSE))
+UINT8 nci_snd_nfcee_discover (UINT8 discover_action);
+UINT8 nci_snd_nfcee_mode_set (UINT8 nfcee_id, UINT8 nfcee_mode);
+UINT8 nci_snd_set_routing_cmd (BOOLEAN more, UINT8 num_tlv, UINT8 tlv_size, UINT8 *p_param_tlvs);
+UINT8 nci_snd_get_routing_cmd (void);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_NCI_MSGS_H */
diff --git a/src/nfc/include/ndef_utils.h b/src/nfc/include/ndef_utils.h
new file mode 100644
index 0000000..e97d6f0
--- /dev/null
+++ b/src/nfc/include/ndef_utils.h
@@ -0,0 +1,540 @@
+/******************************************************************************
+ *
+ * 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 */
+
+/* NDEF Type Name Format */
+#define NDEF_TNF_EMPTY 0 /* Empty (type/id/payload len =0) */
+#define NDEF_TNF_WKT 1 /* NFC Forum well-known type/RTD */
+#define NDEF_TNF_MEDIA 2 /* Media-type as defined in RFC 2046 */
+#define NDEF_TNF_URI 3 /* Absolute URI as defined in RFC 3986 */
+#define NDEF_TNF_EXT 4 /* NFC Forum external type/RTD */
+#define NDEF_TNF_UNKNOWN 5 /* Unknown (type len =0) */
+#define NDEF_TNF_UNCHANGED 6 /* Unchanged (type len =0) */
+#define NDEF_TNF_RESERVED 7 /* Reserved */
+
+/* Define the status code returned from the Validate, Parse or Build functions
+*/
+enum
+{
+ NDEF_OK, /* 0 - OK */
+
+ NDEF_REC_NOT_FOUND, /* 1 - No record matching the find criteria */
+ NDEF_MSG_TOO_SHORT, /* 2 - Message was too short (< 3 bytes) */
+ NDEF_MSG_NO_MSG_BEGIN, /* 3 - No 'begin' flag at start of message */
+ NDEF_MSG_NO_MSG_END, /* 4 - No 'end' flag at end of message */
+ NDEF_MSG_EXTRA_MSG_BEGIN, /* 5 - 'begin' flag after start of message */
+ NDEF_MSG_UNEXPECTED_CHUNK, /* 6 - Unexpected chunk found */
+ NDEF_MSG_INVALID_EMPTY_REC, /* 7 - Empty record with non-zero contents */
+ NDEF_MSG_INVALID_CHUNK, /* 8 - Invalid chunk found */
+ NDEF_MSG_LENGTH_MISMATCH, /* 9 - Overall message length doesn't match */
+ NDEF_MSG_INSUFFICIENT_MEM /* 10 - Insuffiecient memory to add record */
+};
+typedef UINT8 tNDEF_STATUS;
+
+
+#define HR_REC_TYPE_LEN 2 /* Handover Request Record Type */
+#define HS_REC_TYPE_LEN 2 /* Handover Select Record Type */
+#define HC_REC_TYPE_LEN 2 /* Handover Carrier recrod Type */
+#define CR_REC_TYPE_LEN 2 /* Collision Resolution Record Type */
+#define AC_REC_TYPE_LEN 2 /* Alternative Carrier Record Type */
+#define ERR_REC_TYPE_LEN 3 /* Error Record Type */
+#define BT_OOB_REC_TYPE_LEN 32 /* Bluetooth OOB Data Type */
+#define WIFI_WSC_REC_TYPE_LEN 23 /* Wifi WSC Data Type */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Define prefix for exporting APIs from libraries */
+#ifdef NFC_DLL
+#define EXPORT_NDEF_API __declspec(dllexport) /* Windows DLL export prefix */
+#else
+#define EXPORT_NDEF_API
+#endif
+
+/* Functions to parse a received NDEF Message
+*/
+/*******************************************************************************
+**
+** Function NDEF_MsgValidate
+**
+** Description This function validates an NDEF message.
+**
+** Returns TRUE if all OK, or FALSE if the message is invalid.
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgValidate (UINT8 *p_msg, UINT32 msg_len, BOOLEAN b_allow_chunks);
+
+/*******************************************************************************
+**
+** Function NDEF_MsgGetNumRecs
+**
+** Description This function gets the number of records in the given NDEF
+** message.
+**
+** Returns The record count, or 0 if the message is invalid.
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern INT32 NDEF_MsgGetNumRecs (UINT8 *p_msg);
+
+/*******************************************************************************
+**
+** Function NDEF_MsgGetRecLength
+**
+** Description This function returns length of the current record in the given
+** NDEF message.
+**
+** Returns Length of record
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern UINT32 NDEF_MsgGetRecLength (UINT8 *p_cur_rec);
+
+/*******************************************************************************
+**
+** Function NDEF_MsgGetNextRec
+**
+** Description This function gets a pointer to the next record after the
+** current one.
+**
+** Returns Pointer to the start of the record, or NULL if no more
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern UINT8 *NDEF_MsgGetNextRec (UINT8 *p_cur_rec);
+
+/*******************************************************************************
+**
+** Function NDEF_MsgGetRecByIndex
+**
+** Description This function gets a pointer to the record with the given
+** index (0-based index) in the given NDEF message.
+**
+** Returns Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern UINT8 *NDEF_MsgGetRecByIndex (UINT8 *p_msg, INT32 index);
+
+/*******************************************************************************
+**
+** Function NDEF_MsgGetLastRecInMsg
+**
+** Description This function gets a pointer to the last record in the
+** given NDEF message.
+**
+** Returns Pointer to the start of the last record, or NULL if some problem
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern UINT8 *NDEF_MsgGetLastRecInMsg (UINT8 *p_msg);
+
+/*******************************************************************************
+**
+** Function NDEF_MsgGetFirstRecByType
+**
+** Description This function gets a pointer to the first record with the given
+** record type in the given NDEF message.
+**
+** Returns Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern UINT8 *NDEF_MsgGetFirstRecByType (UINT8 *p_msg, UINT8 tnf, UINT8 *p_type, UINT8 tlen);
+
+/*******************************************************************************
+**
+** Function NDEF_MsgGetNextRecByType
+**
+** Description This function gets a pointer to the next record with the given
+** record type in the given NDEF message.
+**
+** Returns Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern UINT8 *NDEF_MsgGetNextRecByType (UINT8 *p_cur_rec, UINT8 tnf, UINT8 *p_type, UINT8 tlen);
+
+/*******************************************************************************
+**
+** Function NDEF_MsgGetFirstRecById
+**
+** Description This function gets a pointer to the first record with the given
+** record id in the given NDEF message.
+**
+** Returns Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern UINT8 *NDEF_MsgGetFirstRecById (UINT8 *p_msg, UINT8 *p_id, UINT8 ilen);
+
+/*******************************************************************************
+**
+** Function NDEF_MsgGetNextRecById
+**
+** Description This function gets a pointer to the next record with the given
+** record id in the given NDEF message.
+**
+** Returns Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern UINT8 *NDEF_MsgGetNextRecById (UINT8 *p_cur_rec, UINT8 *p_id, UINT8 ilen);
+
+/*******************************************************************************
+**
+** Function NDEF_RecGetType
+**
+** Description This function gets a pointer to the record type for the given NDEF record.
+**
+** Returns Pointer to Type (NULL if none). TNF and len are filled in.
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern UINT8 *NDEF_RecGetType (UINT8 *p_rec, UINT8 *p_tnf, UINT8 *p_type_len);
+
+/*******************************************************************************
+**
+** Function NDEF_RecGetId
+**
+** Description This function gets a pointer to the record id for the given NDEF record.
+**
+** Returns Pointer to Id (NULL if none). ID Len is filled in.
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern UINT8 *NDEF_RecGetId (UINT8 *p_rec, UINT8 *p_id_len);
+
+/*******************************************************************************
+**
+** Function NDEF_RecGetPayload
+**
+** Description This function gets a pointer to the payload for the given NDEF record.
+**
+** Returns a pointer to the payload (NULL if none). Payload len filled in.
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern UINT8 *NDEF_RecGetPayload (UINT8 *p_rec, UINT32 *p_payload_len);
+
+
+/* Functions to build an NDEF Message
+*/
+/*******************************************************************************
+**
+** Function NDEF_MsgInit
+**
+** Description This function initializes an NDEF message.
+**
+** Returns void
+** *p_cur_size is initialized to 0
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern void NDEF_MsgInit (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size);
+
+/*******************************************************************************
+**
+** Function NDEF_MsgAddRec
+**
+** Description This function adds an NDEF record to the end of an NDEF message.
+**
+** Returns OK, or error if the record did not fit
+** *p_cur_size is updated
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgAddRec (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ UINT8 tnf, UINT8 *p_type, UINT8 type_len,
+ UINT8 *p_id, UINT8 id_len,
+ UINT8 *p_payload, UINT32 payload_len);
+
+/*******************************************************************************
+**
+** Function NDEF_MsgInsertRec
+**
+** Description This function inserts a record at a specific index into the
+** given NDEF message
+**
+** Returns OK, or error if the record did not fit
+** *p_cur_size is updated
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgInsertRec (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size, INT32 index,
+ UINT8 tnf, UINT8 *p_type, UINT8 type_len,
+ UINT8 *p_id, UINT8 id_len,
+ UINT8 *p_payload, UINT32 payload_len);
+
+/*******************************************************************************
+**
+** Function NDEF_MsgAppendRec
+**
+** Description This function adds NDEF records to the end of an NDEF message.
+**
+** Returns OK, or error if the record did not fit
+** *p_cur_size is updated
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgAppendRec (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ UINT8 *p_new_rec, UINT32 new_rec_len);
+
+/*******************************************************************************
+**
+** Function NDEF_MsgAppendPayload
+**
+** Description This function appends extra payload to a specific record in the
+** given NDEF message
+**
+** Returns OK, or error if the extra payload did not fit
+** *p_cur_size is updated
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgAppendPayload (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ UINT8 *p_rec, UINT8 *p_add_pl, UINT32 add_pl_len);
+
+/*******************************************************************************
+**
+** Function NDEF_MsgReplacePayload
+**
+** Description This function replaces the payload of a specific record in the
+** given NDEF message
+**
+** Returns OK, or error if the new payload did not fit
+** *p_cur_size is updated
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgReplacePayload (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ UINT8 *p_rec, UINT8 *p_new_pl, UINT32 new_pl_len);
+
+/*******************************************************************************
+**
+** Function NDEF_MsgReplaceType
+**
+** Description This function replaces the type field of a specific record in the
+** given NDEF message
+**
+** Returns OK, or error if the new type field did not fit
+** *p_cur_size is updated
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgReplaceType (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ UINT8 *p_rec, UINT8 *p_new_type, UINT8 new_type_len);
+
+/*******************************************************************************
+**
+** Function NDEF_MsgReplaceId
+**
+** Description This function replaces the ID field of a specific record in the
+** given NDEF message
+**
+** Returns OK, or error if the new ID field did not fit
+** *p_cur_size is updated
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgReplaceId (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ UINT8 *p_rec, UINT8 *p_new_id, UINT8 new_id_len);
+
+/*******************************************************************************
+**
+** Function NDEF_MsgRemoveRec
+**
+** Description This function removes the record at the given
+** index in the given NDEF message.
+**
+** Returns OK, or error if the index was invalid
+** *p_cur_size is updated
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgRemoveRec (UINT8 *p_msg, UINT32 *p_cur_size, INT32 index);
+
+/*******************************************************************************
+**
+** Function NDEF_MsgCopyAndDechunk
+**
+** Description This function copies and de-chunks an NDEF message.
+** It is assumed that the destination is at least as large
+** as the source, since the source may not actually contain
+** any chunks.
+**
+** Returns The output byte count
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgCopyAndDechunk (UINT8 *p_src, UINT32 src_len, UINT8 *p_dest, UINT32 *p_out_len);
+
+/*******************************************************************************
+**
+** Function NDEF_MsgCreateWktHr
+**
+** Description This function creates Handover Request Record with version.
+**
+** Returns NDEF_OK if all OK
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgCreateWktHr (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ UINT8 version );
+
+/*******************************************************************************
+**
+** Function NDEF_MsgCreateWktHs
+**
+** Description This function creates Handover Select Record with version.
+**
+** Returns NDEF_OK if all OK
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgCreateWktHs (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ UINT8 version );
+
+/*******************************************************************************
+**
+** Function NDEF_MsgAddWktHc
+**
+** Description This function adds Handover Carrier Record.
+**
+** Returns NDEF_OK if all OK
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgAddWktHc (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ char *p_id_str, UINT8 ctf,
+ UINT8 carrier_type_len, UINT8 *p_carrier_type,
+ UINT8 carrier_data_len, UINT8 *p_carrier_data);
+
+/*******************************************************************************
+**
+** Function NDEF_MsgAddWktAc
+**
+** Description This function adds Alternative Carrier Record.
+**
+** Returns NDEF_OK if all OK
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgAddWktAc (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ UINT8 cps, char *p_carrier_data_ref_str,
+ UINT8 aux_data_ref_count, char *p_aux_data_ref_str[]);
+
+/*******************************************************************************
+**
+** Function NDEF_MsgAddWktCr
+**
+** Description This function adds Collision Resolution Record.
+**
+** Returns NDEF_OK if all OK
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgAddWktCr (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ UINT16 random_number );
+
+/*******************************************************************************
+**
+** Function NDEF_MsgAddWktErr
+**
+** Description This function adds Error Record.
+**
+** Returns NDEF_OK if all OK
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgAddWktErr (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ UINT8 error_reason, UINT32 error_data );
+
+/*******************************************************************************
+**
+** Function NDEF_MsgAddMediaBtOob
+**
+** Description This function adds BT OOB Record.
+**
+** Returns NDEF_OK if all OK
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgAddMediaBtOob (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ char *p_id_str, BD_ADDR bd_addr);
+
+/*******************************************************************************
+**
+** Function NDEF_MsgAppendMediaBtOobCod
+**
+** Description This function appends COD EIR data at the end of BT OOB Record.
+**
+** Returns NDEF_OK if all OK
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgAppendMediaBtOobCod (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ char *p_id_str, DEV_CLASS cod);
+
+/*******************************************************************************
+**
+** Function NDEF_MsgAppendMediaBtOobName
+**
+** Description This function appends Bluetooth Local Name EIR data
+** at the end of BT OOB Record.
+**
+** Returns NDEF_OK if all OK
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgAppendMediaBtOobName (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ char *p_id_str, BOOLEAN is_complete,
+ UINT8 name_len, UINT8 *p_name);
+
+/*******************************************************************************
+**
+** Function NDEF_MsgAppendMediaBtOobHashCRandR
+**
+** Description This function appends Hash C and Rand R at the end of BT OOB Record.
+**
+** Returns NDEF_OK if all OK
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgAppendMediaBtOobHashCRandR (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ char *p_id_str, UINT8 *p_hash_c, UINT8 *p_rand_r);
+
+/*******************************************************************************
+**
+** Function NDEF_MsgAppendMediaBtOobEirData
+**
+** Description This function appends EIR Data at the end of BT OOB Record.
+**
+** Returns NDEF_OK if all OK
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgAppendMediaBtOobEirData (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ char *p_id_str,
+ UINT8 eir_type, UINT8 data_len, UINT8 *p_data);
+
+/*******************************************************************************
+**
+** Function NDEF_MsgAddMediaWifiWsc
+**
+** Description This function adds Wifi Wsc Record header.
+**
+** Returns NDEF_OK if all OK
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgAddMediaWifiWsc (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ char *p_id_str, UINT8 *p_payload, UINT32 payload_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..5678d3d
--- /dev/null
+++ b/src/nfc/include/nfc_api.h
@@ -0,0 +1,1437 @@
+/******************************************************************************
+ *
+ * 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"
+
+/* NFC application return status codes */
+#define NFC_STATUS_OK NCI_STATUS_OK /* Command succeeded */
+#define NFC_STATUS_REJECTED NCI_STATUS_REJECTED /* Command is rejected. */
+#define NFC_STATUS_MSG_CORRUPTED NCI_STATUS_MESSAGE_CORRUPTED /* Message is corrupted */
+#define NFC_STATUS_BUFFER_FULL NCI_STATUS_BUFFER_FULL /* buffer full */
+#define NFC_STATUS_FAILED NCI_STATUS_FAILED /* failed */
+#define NFC_STATUS_NOT_INITIALIZED NCI_STATUS_NOT_INITIALIZED /* not initialized */
+#define NFC_STATUS_SYNTAX_ERROR NCI_STATUS_SYNTAX_ERROR /* Syntax error */
+#define NFC_STATUS_SEMANTIC_ERROR NCI_STATUS_SEMANTIC_ERROR /* Semantic error */
+#define NFC_STATUS_UNKNOWN_GID NCI_STATUS_UNKNOWN_GID /* Unknown NCI Group ID */
+#define NFC_STATUS_UNKNOWN_OID NCI_STATUS_UNKNOWN_OID /* Unknown NCI Opcode */
+#define NFC_STATUS_INVALID_PARAM NCI_STATUS_INVALID_PARAM /* Invalid Parameter */
+#define NFC_STATUS_MSG_SIZE_TOO_BIG NCI_STATUS_MSG_SIZE_TOO_BIG /* Message size too big */
+#define NFC_STATUS_ALREADY_STARTED NCI_STATUS_ALREADY_STARTED /* Already started */
+#define NFC_STATUS_ACTIVATION_FAILED NCI_STATUS_ACTIVATION_FAILED /* Activation Failed */
+#define NFC_STATUS_TEAR_DOWN NCI_STATUS_TEAR_DOWN /* Tear Down Error */
+#define NFC_STATUS_RF_TRANSMISSION_ERR NCI_STATUS_RF_TRANSMISSION_ERR /* RF transmission error*/
+#define NFC_STATUS_RF_PROTOCOL_ERR NCI_STATUS_RF_PROTOCOL_ERR /* RF protocol error */
+#define NFC_STATUS_TIMEOUT NCI_STATUS_TIMEOUT /* RF Timeout */
+#define NFC_STATUS_EE_INTF_ACTIVE_FAIL NCI_STATUS_EE_INTF_ACTIVE_FAIL /* EE Intf activate err */
+#define NFC_STATUS_EE_TRANSMISSION_ERR NCI_STATUS_EE_TRANSMISSION_ERR /* EE transmission error*/
+#define NFC_STATUS_EE_PROTOCOL_ERR NCI_STATUS_EE_PROTOCOL_ERR /* EE protocol error */
+#define NFC_STATUS_EE_TIMEOUT NCI_STATUS_EE_TIMEOUT /* EE Timeout */
+
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+//DTA API for MW Version need to change according to release
+#define NXP_EN_PN547C2 1
+#define NXP_EN_PN65T 1
+#define NXP_EN_PN548AD 1
+#define NXP_EN_PN66T 1
+#define NXP_ANDROID_VER (3U) /* NXP android version */
+#define NFC_NXP_MW_VERSION_MAJ (5U) /* MW Major Version */
+#define NFC_NXP_MW_VERSION_MIN (0U) /* MW Minor Version */
+#endif
+/* 0xE0 ~0xFF are proprietary status codes */
+#define NFC_STATUS_CMD_STARTED 0xE3/* Command started successfully */
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define NFC_STATUS_HW_TIMEOUT 0xEC/* changed from 0xE4 (as 0xE4 is defined for STATUS_EMVCO_PCD_COLLISOIN
+ NFCC Timeout in responding to an NCI command */
+#else
+#define NFC_STATUS_HW_TIMEOUT 0xE4/* NFCC Timeout in responding to an NCI command */
+#endif
+#define NFC_STATUS_CONTINUE 0xE5/* More (same) event to follow */
+#define NFC_STATUS_REFUSED 0xE6/* API is called to perform illegal function */
+#define NFC_STATUS_BAD_RESP 0xE7/* Wrong format of R-APDU, CC file or NDEF file */
+#define NFC_STATUS_CMD_NOT_CMPLTD 0xE8/* 7816 Status Word is not command complete(0x9000) */
+#define NFC_STATUS_NO_BUFFERS 0xE9/* Out of GKI buffers */
+#define NFC_STATUS_WRONG_PROTOCOL 0xEA/* Protocol mismatch between API and activated one */
+#define NFC_STATUS_BUSY 0xEB/* Another Tag command is already in progress */
+
+#define NFC_STATUS_LINK_LOSS 0xFC /* Link Loss */
+#define NFC_STATUS_BAD_LENGTH 0xFD /* data len exceeds MIU */
+#define NFC_STATUS_BAD_HANDLE 0xFE /* invalid handle */
+#define NFC_STATUS_CONGESTED 0xFF /* congested */
+typedef UINT8 tNFC_STATUS;
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define NFC_NFCC_INIT_MAX_RETRY 2
+#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_PB_AFI NCI_PARAM_ID_PB_AFI
+#define NFC_PMID_PB_BAILOUT NCI_PARAM_ID_PB_BAILOUT
+#define NFC_PMID_PB_ATTRIB_PARAM1 NCI_PARAM_ID_PB_ATTRIB_PARAM1
+#define NFC_PMID_PF_BIT_RATE NCI_PARAM_ID_PF_BIT_RATE
+#define NFC_PMID_PB_H_INFO NCI_PARAM_ID_PB_H_INFO
+#define NFC_PMID_BITR_NFC_DEP NCI_PARAM_ID_BITR_NFC_DEP
+#define NFC_PMID_ATR_REQ_GEN_BYTES NCI_PARAM_ID_ATR_REQ_GEN_BYTES
+#define NFC_PMID_ATR_REQ_CONFIG NCI_PARAM_ID_ATR_REQ_CONFIG
+#define NFC_PMID_LA_HIST_BY NCI_PARAM_ID_LA_HIST_BY
+#define NFC_PMID_LA_NFCID1 NCI_PARAM_ID_LA_NFCID1
+#define NFC_PMID_PI_BIT_RATE NCI_PARAM_ID_PI_BIT_RATE
+#define NFC_PMID_LA_BIT_FRAME_SDD NCI_PARAM_ID_LA_BIT_FRAME_SDD
+#define NFC_PMID_LA_PLATFORM_CONFIG NCI_PARAM_ID_LA_PLATFORM_CONFIG
+#define NFC_PMID_LA_SEL_INFO NCI_PARAM_ID_LA_SEL_INFO
+#define NFC_PMID_LI_BIT_RATE NCI_PARAM_ID_LI_BIT_RATE
+#define NFC_PMID_LB_SENSB_INFO NCI_PARAM_ID_LB_SENSB_INFO
+#define NFC_PMID_LB_PROTOCOL NCI_PARAM_ID_LB_PROTOCOL
+#define NFC_PMID_LB_H_INFO NCI_PARAM_ID_LB_H_INFO_RSP
+#define NFC_PMID_LB_NFCID0 NCI_PARAM_ID_LB_NFCID0
+#define NFC_PMID_LB_APPDATA NCI_PARAM_ID_LB_APPDATA
+#define NFC_PMID_LB_SFGI NCI_PARAM_ID_LB_SFGI
+#define NFC_PMID_LB_ADC_FO NCI_PARAM_ID_LB_ADC_FO
+#define NFC_PMID_LF_T3T_ID1 NCI_PARAM_ID_LF_T3T_ID1
+#define NFC_PMID_LF_T3T_ID2 NCI_PARAM_ID_LF_T3T_ID2
+#define NFC_PMID_LF_T3T_ID3 NCI_PARAM_ID_LF_T3T_ID3
+#define NFC_PMID_LF_T3T_ID4 NCI_PARAM_ID_LF_T3T_ID4
+#define NFC_PMID_LF_T3T_ID5 NCI_PARAM_ID_LF_T3T_ID5
+#define NFC_PMID_LF_T3T_ID6 NCI_PARAM_ID_LF_T3T_ID6
+#define NFC_PMID_LF_T3T_ID7 NCI_PARAM_ID_LF_T3T_ID7
+#define NFC_PMID_LF_T3T_ID8 NCI_PARAM_ID_LF_T3T_ID8
+#define NFC_PMID_LF_T3T_ID9 NCI_PARAM_ID_LF_T3T_ID9
+#define NFC_PMID_LF_T3T_ID10 NCI_PARAM_ID_LF_T3T_ID10
+#define NFC_PMID_LF_T3T_ID11 NCI_PARAM_ID_LF_T3T_ID11
+#define NFC_PMID_LF_T3T_ID12 NCI_PARAM_ID_LF_T3T_ID12
+#define NFC_PMID_LF_T3T_ID13 NCI_PARAM_ID_LF_T3T_ID13
+#define NFC_PMID_LF_T3T_ID14 NCI_PARAM_ID_LF_T3T_ID14
+#define NFC_PMID_LF_T3T_ID15 NCI_PARAM_ID_LF_T3T_ID15
+#define NFC_PMID_LF_T3T_ID16 NCI_PARAM_ID_LF_T3T_ID16
+#define NFC_PMID_LF_PROTOCOL NCI_PARAM_ID_LF_PROTOCOL
+#define NFC_PMID_LF_T3T_PMM NCI_PARAM_ID_LF_T3T_PMM
+#define NFC_PMID_LF_T3T_MAX NCI_PARAM_ID_LF_T3T_MAX
+#define NFC_PMID_LF_T3T_FLAGS2 NCI_PARAM_ID_LF_T3T_FLAGS2
+#define NFC_PMID_FWI NCI_PARAM_ID_FWI
+#define NFC_PMID_LF_CON_BITR_F NCI_PARAM_ID_LF_CON_BITR_F
+#define NFC_PMID_WT NCI_PARAM_ID_WT
+#define NFC_PMID_ATR_RES_GEN_BYTES NCI_PARAM_ID_ATR_RES_GEN_BYTES
+#define NFC_PMID_ATR_RSP_CONFIG NCI_PARAM_ID_ATR_RSP_CONFIG
+#define NFC_PMID_RF_FIELD_INFO NCI_PARAM_ID_RF_FIELD_INFO
+#define NFC_PMID_NFC_DEP_OP NCI_PARAM_ID_NFC_DEP_OP
+#define NFC_PARAM_ID_RF_EE_ACTION NCI_PARAM_ID_RF_EE_ACTION
+#define NFC_PARAM_ID_ISO_DEP_OP NCI_PARAM_ID_ISO_DEP_OP
+
+#define NFC_ROUTE_TAG_TECH NCI_ROUTE_TAG_TECH /* Technology based routing */
+#define NFC_ROUTE_TAG_PROTO NCI_ROUTE_TAG_PROTO /* Protocol based routing */
+#define NFC_ROUTE_TAG_AID NCI_ROUTE_TAG_AID /* AID routing */
+#define NFC_ROUTE_TLV_ENTRY_SIZE 4 /* tag, len, 2 byte value for technology/protocol based routing */
+
+/* For routing */
+#define NFC_DH_ID NCI_DH_ID /* for DH */
+/* To identify the loopback test */
+#define NFC_TEST_ID NCI_TEST_ID /* use a proprietary range */
+
+typedef UINT8 tNFC_PMID;
+#define NFC_TL_SIZE 2
+#define NFC_SAVED_CMD_SIZE 2
+
+typedef tNCI_DISCOVER_MAPS tNFC_DISCOVER_MAPS;
+typedef tNCI_DISCOVER_PARAMS tNFC_DISCOVER_PARAMS;
+
+/* all NFC Manager Callback functions have prototype like void (cback) (UINT8 event, void *p_data)
+ * tNFC_DATA_CBACK uses connection id as the first parameter; range 0x00-0x0F.
+ * tNFC_DISCOVER_CBACK uses tNFC_DISCOVER_EVT; range 0x4000 ~
+ * tNFC_RESPONSE_CBACK uses tNFC_RESPONSE_EVT; range 0x5000 ~
+ */
+
+#define NFC_FIRST_DEVT 0x4000
+#define NFC_FIRST_REVT 0x5000
+#define NFC_FIRST_CEVT 0x6000
+#define NFC_FIRST_TEVT 0x8000
+
+/* the events reported on tNFC_RESPONSE_CBACK */
+enum
+{
+ NFC_ENABLE_REVT = NFC_FIRST_REVT, /* 0 Enable event */
+ NFC_DISABLE_REVT, /* 1 Disable event */
+ NFC_SET_CONFIG_REVT, /* 2 Set Config Response */
+ NFC_GET_CONFIG_REVT, /* 3 Get Config Response */
+ NFC_NFCEE_DISCOVER_REVT, /* 4 Discover NFCEE response */
+ NFC_NFCEE_INFO_REVT, /* 5 Discover NFCEE Notification */
+ NFC_NFCEE_MODE_SET_REVT, /* 6 NFCEE Mode Set response */
+ NFC_RF_FIELD_REVT, /* 7 RF Field information */
+ NFC_EE_ACTION_REVT, /* 8 EE Action notification */
+ NFC_EE_DISCOVER_REQ_REVT, /* 9 EE Discover Req notification */
+ NFC_SET_ROUTING_REVT, /* 10 Configure Routing response */
+ NFC_GET_ROUTING_REVT, /* 11 Retrieve Routing response */
+ NFC_RF_COMM_PARAMS_UPDATE_REVT, /* 12 RF Communication Param Update */
+ NFC_GEN_ERROR_REVT, /* 13 generic error notification */
+ NFC_NFCC_RESTART_REVT, /* 14 NFCC has been re-initialized */
+ NFC_NFCC_TIMEOUT_REVT, /* 15 NFCC is not responding */
+ NFC_NFCC_TRANSPORT_ERR_REVT, /* 16 NCI Tranport error */
+ NFC_NFCC_POWER_OFF_REVT, /* 17 NFCC turned off */
+
+ NFC_FIRST_VS_REVT /* First vendor-specific rsp event */
+};
+typedef UINT16 tNFC_RESPONSE_EVT;
+
+enum
+{
+ NFC_CONN_CREATE_CEVT = NFC_FIRST_CEVT, /* 0 Conn Create Response */
+ NFC_CONN_CLOSE_CEVT, /* 1 Conn Close Response */
+ NFC_DEACTIVATE_CEVT, /* 2 Deactivate response/notificatn*/
+ NFC_DATA_CEVT, /* 3 Data */
+ NFC_ERROR_CEVT, /* 4 generic or interface error */
+ NFC_DATA_START_CEVT, /* 5 received the first fragment on RF link */
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ NFC_RF_WTX_CEVT /* 6 received rf wtx */
+#endif
+};
+typedef UINT16 tNFC_CONN_EVT;
+
+#define NFC_NFCC_INFO_LEN 4
+#ifndef NFC_NFCC_MAX_NUM_VS_INTERFACE
+#define NFC_NFCC_MAX_NUM_VS_INTERFACE 4
+#endif
+typedef struct
+{
+ tNFC_STATUS status; /* The event status. */
+ UINT8 nci_version; /* the NCI version of NFCC */
+ UINT8 max_conn; /* max number of connections by NFCC*/
+ UINT32 nci_features; /* the NCI features of NFCC */
+ UINT16 nci_interfaces; /* the NCI interfaces of NFCC */
+ UINT16 max_ce_table; /* the max routing table size */
+ UINT16 max_param_size; /* Max Size for Large Parameters */
+ UINT8 manufacture_id; /* the Manufacture ID for NFCC */
+ UINT8 nfcc_info[NFC_NFCC_INFO_LEN];/* the Manufacture Info for NFCC */
+ UINT8 vs_interface[NFC_NFCC_MAX_NUM_VS_INTERFACE]; /* the NCI VS interfaces of NFCC */
+} tNFC_ENABLE_REVT;
+
+#define NFC_MAX_NUM_IDS 125
+/* the data type associated with NFC_SET_CONFIG_REVT */
+typedef struct
+{
+ tNFC_STATUS status; /* The event status. */
+ UINT8 num_param_id; /* Number of rejected NCI Param ID */
+ UINT8 param_ids[NFC_MAX_NUM_IDS];/* NCI Param ID */
+} tNFC_SET_CONFIG_REVT;
+
+/* the data type associated with NFC_GET_CONFIG_REVT */
+typedef struct
+{
+ tNFC_STATUS status; /* The event status. */
+ UINT16 tlv_size; /* The length of TLV */
+ UINT8 *p_param_tlvs; /* TLV */
+} tNFC_GET_CONFIG_REVT;
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+/* This data type is for FW Version */
+typedef struct
+{
+ UINT8 rom_code_version; /* ROM code Version */
+ UINT8 major_version; /* Major Version */
+ UINT8 minor_version; /* Minor Version */
+} tNFC_FW_VERSION;
+#endif
+
+
+/* the data type associated with NFC_NFCEE_DISCOVER_REVT */
+typedef struct
+{
+ tNFC_STATUS status; /* The event status. */
+ UINT8 num_nfcee; /* The number of NFCEE */
+} tNFC_NFCEE_DISCOVER_REVT;
+
+#define NFC_NFCEE_INTERFACE_APDU NCI_NFCEE_INTERFACE_APDU
+#define NFC_NFCEE_INTERFACE_HCI_ACCESS NCI_NFCEE_INTERFACE_HCI_ACCESS
+#define NFC_NFCEE_INTERFACE_T3T NCI_NFCEE_INTERFACE_T3T
+#define NFC_NFCEE_INTERFACE_TRANSPARENT NCI_NFCEE_INTERFACE_TRANSPARENT
+#define NFC_NFCEE_INTERFACE_PROPRIETARY NCI_NFCEE_INTERFACE_PROPRIETARY
+typedef UINT8 tNFC_NFCEE_INTERFACE;
+
+#define NFC_NFCEE_TAG_HW_ID NCI_NFCEE_TAG_HW_ID
+#define NFC_NFCEE_TAG_ATR_BYTES NCI_NFCEE_TAG_ATR_BYTES
+#define NFC_NFCEE_TAG_T3T_INFO NCI_NFCEE_TAG_T3T_INFO
+#define NFC_NFCEE_TAG_HCI_HOST_ID NCI_NFCEE_TAG_HCI_HOST_ID
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+typedef UINT16 tNFC_NFCEE_TAG;
+#else
+typedef UINT8 tNFC_NFCEE_TAG;
+#endif
+/* additional NFCEE Info */
+typedef struct
+{
+ tNFC_NFCEE_TAG tag;
+ UINT8 len;
+ UINT8 info[NFC_MAX_EE_INFO];
+} tNFC_NFCEE_TLV;
+
+#define NFC_NFCEE_STATUS_INACTIVE NCI_NFCEE_STS_CONN_INACTIVE/* NFCEE connected and inactive */
+#define NFC_NFCEE_STATUS_ACTIVE NCI_NFCEE_STS_CONN_ACTIVE /* NFCEE connected and active */
+#define NFC_NFCEE_STATUS_REMOVED NCI_NFCEE_STS_REMOVED /* NFCEE removed */
+/* the data type associated with NFC_NFCEE_INFO_REVT */
+typedef struct
+{
+ tNFC_STATUS status; /* The event status - place holder */
+ UINT8 nfcee_id; /* NFCEE ID */
+ UINT8 ee_status; /* The NFCEE status. */
+ UINT8 num_interface; /* number of NFCEE interfaces */
+ UINT8 ee_interface[NFC_MAX_EE_INTERFACE];/* NFCEE interface */
+ UINT8 num_tlvs; /* number of TLVs */
+ tNFC_NFCEE_TLV ee_tlv[NFC_MAX_EE_TLVS];/* The TLVs associated with NFCEE */
+} tNFC_NFCEE_INFO_REVT;
+
+#define NFC_MODE_ACTIVATE NCI_NFCEE_MD_ACTIVATE
+#define NFC_MODE_DEACTIVATE NCI_NFCEE_MD_DEACTIVATE
+typedef UINT8 tNFC_NFCEE_MODE;
+/* the data type associated with NFC_NFCEE_MODE_SET_REVT */
+typedef struct
+{
+ tNFC_STATUS status; /* The event status.*/
+ UINT8 nfcee_id; /* NFCEE ID */
+ tNFC_NFCEE_MODE mode; /* NFCEE mode */
+} tNFC_NFCEE_MODE_SET_REVT;
+
+#define NFC_MAX_AID_LEN NCI_MAX_AID_LEN /* 16 */
+
+/* the data type associated with NFC_CE_GET_ROUTING_REVT */
+
+/* Max payload size */
+#define NFC_MAX_GET_ROUTING_PLD_SIZE 255
+
+typedef struct
+{
+ tNFC_STATUS status; /* The event status */
+ UINT8 nfcee_id; /* NFCEE ID */
+ UINT8 num_tlvs; /* number of TLVs */
+ UINT8 tlv_size; /* the total len of all TLVs */
+ UINT8 param_tlvs[NFC_MAX_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 dest_type; /* the destination type */
+ UINT8 id; /* NFCEE ID or RF Discovery ID */
+ UINT8 buff_size; /* The max buffer size */
+ UINT8 num_buffs; /* The number of buffers */
+} tNFC_CONN_CREATE_CEVT;
+
+/* the data type associated with NFC_CONN_CLOSE_CEVT */
+typedef struct
+{
+ tNFC_STATUS status; /* The event status */
+} tNFC_CONN_CLOSE_CEVT;
+
+/* the data type associated with NFC_DATA_CEVT */
+typedef struct
+{
+ tNFC_STATUS status; /* The event status */
+ BT_HDR *p_data; /* The received Data */
+} tNFC_DATA_CEVT;
+
+/* RF Field Status */
+#define NFC_RF_STS_NO_REMOTE NCI_RF_STS_NO_REMOTE /* No field generated by remote device */
+#define NFC_RF_STS_REMOTE NCI_RF_STS_REMOTE /* field generated by remote device */
+typedef UINT8 tNFC_RF_STS;
+
+/* RF Field Technologies */
+#define NFC_RF_TECHNOLOGY_A NCI_RF_TECHNOLOGY_A
+#define NFC_RF_TECHNOLOGY_B NCI_RF_TECHNOLOGY_B
+#define NFC_RF_TECHNOLOGY_F NCI_RF_TECHNOLOGY_F
+#define NFC_RF_TECHNOLOGY_15693 NCI_RF_TECHNOLOGY_15693
+typedef UINT8 tNFC_RF_TECH;
+
+
+/* Supported Protocols */
+#define NFC_PROTOCOL_UNKNOWN NCI_PROTOCOL_UNKNOWN /* Unknown */
+#define NFC_PROTOCOL_T1T NCI_PROTOCOL_T1T /* Type1Tag - NFC-A */
+#define NFC_PROTOCOL_T2T NCI_PROTOCOL_T2T /* Type2Tag - NFC-A */
+#define NFC_PROTOCOL_T3T NCI_PROTOCOL_T3T /* Type3Tag - NFC-F */
+#define NFC_PROTOCOL_ISO_DEP NCI_PROTOCOL_ISO_DEP /* Type 4A,4B - NFC-A or NFC-B */
+#define NFC_PROTOCOL_NFC_DEP NCI_PROTOCOL_NFC_DEP /* NFCDEP/LLCP - NFC-A or NFC-F */
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define NFC_PROTOCOL_ISO7816 NCI_PROTOCOL_ISO7816 /*ISO7816 -AID default Routing */
+#define NFC_PROTOCOL_MIFARE NCI_PROTOCOL_MIFARE
+#define NFC_PROTOCOL_ISO7816 NCI_PROTOCOL_ISO7816
+#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 tNFC_PROTOCOL;
+
+/* Discovery Types/Detected Technology and Mode */
+#define NFC_DISCOVERY_TYPE_POLL_A NCI_DISCOVERY_TYPE_POLL_A
+#define NFC_DISCOVERY_TYPE_POLL_B NCI_DISCOVERY_TYPE_POLL_B
+#define NFC_DISCOVERY_TYPE_POLL_F NCI_DISCOVERY_TYPE_POLL_F
+#define NFC_DISCOVERY_TYPE_POLL_A_ACTIVE NCI_DISCOVERY_TYPE_POLL_A_ACTIVE
+#define NFC_DISCOVERY_TYPE_POLL_F_ACTIVE NCI_DISCOVERY_TYPE_POLL_F_ACTIVE
+#define NFC_DISCOVERY_TYPE_POLL_ISO15693 NCI_DISCOVERY_TYPE_POLL_ISO15693
+#define NFC_DISCOVERY_TYPE_POLL_B_PRIME NCI_DISCOVERY_TYPE_POLL_B_PRIME
+#define NFC_DISCOVERY_TYPE_POLL_KOVIO NCI_DISCOVERY_TYPE_POLL_KOVIO
+#define NFC_DISCOVERY_TYPE_LISTEN_A NCI_DISCOVERY_TYPE_LISTEN_A
+#define NFC_DISCOVERY_TYPE_LISTEN_B NCI_DISCOVERY_TYPE_LISTEN_B
+#define NFC_DISCOVERY_TYPE_LISTEN_F NCI_DISCOVERY_TYPE_LISTEN_F
+#define NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE NCI_DISCOVERY_TYPE_LISTEN_A_ACTIVE
+#define NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE
+#define NFC_DISCOVERY_TYPE_LISTEN_ISO15693 NCI_DISCOVERY_TYPE_LISTEN_ISO15693
+#define NFC_DISCOVERY_TYPE_LISTEN_B_PRIME NCI_DISCOVERY_TYPE_LISTEN_B_PRIME
+typedef UINT8 tNFC_DISCOVERY_TYPE;
+typedef UINT8 tNFC_RF_TECH_N_MODE;
+
+/* Select Response codes */
+#define NFC_SEL_RES_NFC_FORUM_T2T 0x00
+#define NFC_SEL_RES_MF_CLASSIC 0x08
+
+/* Bit Rates */
+#define NFC_BIT_RATE_106 NCI_BIT_RATE_106 /* 106 kbit/s */
+#define NFC_BIT_RATE_212 NCI_BIT_RATE_212 /* 212 kbit/s */
+#define NFC_BIT_RATE_424 NCI_BIT_RATE_424 /* 424 kbit/s */
+#define NFC_BIT_RATE_848 NCI_BIT_RATE_848 /* 848 Kbit/s */
+#define NFC_BIT_RATE_1696 NCI_BIT_RATE_1696 /* 1696 Kbit/s*/
+#define NFC_BIT_RATE_3392 NCI_BIT_RATE_3392 /* 3392 Kbit/s*/
+#define NFC_BIT_RATE_6784 NCI_BIT_RATE_6784 /* 6784 Kbit/s*/
+typedef UINT8 tNFC_BIT_RATE;
+
+/**********************************************
+ * Interface Types
+ **********************************************/
+#define NFC_INTERFACE_EE_DIRECT_RF NCI_INTERFACE_EE_DIRECT_RF
+#define NFC_INTERFACE_FRAME NCI_INTERFACE_FRAME
+#define NFC_INTERFACE_ISO_DEP NCI_INTERFACE_ISO_DEP
+#define NFC_INTERFACE_NDEF NCI_INTERFACE_NDEF
+#define NFC_INTERFACE_NFC_DEP NCI_INTERFACE_NFC_DEP
+#define NFC_INTERFACE_LLCP_LOW NCI_INTERFACE_LLCP_LOW
+#define NFC_INTERFACE_LLCP_HIGH NCI_INTERFACE_LLCP_HIGH
+#define NFC_INTERFACE_VS_T2T_CE NCI_INTERFACE_VS_T2T_CE
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define NFC_INTERFACE_MIFARE NCI_INTERFACE_MIFARE
+#endif
+typedef tNCI_INTF_TYPE tNFC_INTF_TYPE;
+
+/**********************************************
+ * Deactivation Type
+ **********************************************/
+#define NFC_DEACTIVATE_TYPE_IDLE NCI_DEACTIVATE_TYPE_IDLE
+#define NFC_DEACTIVATE_TYPE_SLEEP NCI_DEACTIVATE_TYPE_SLEEP
+#define NFC_DEACTIVATE_TYPE_SLEEP_AF NCI_DEACTIVATE_TYPE_SLEEP_AF
+#define NFC_DEACTIVATE_TYPE_DISCOVERY NCI_DEACTIVATE_TYPE_DISCOVERY
+typedef UINT8 tNFC_DEACT_TYPE;
+
+/**********************************************
+ * Deactivation Reasons
+ **********************************************/
+#define NFC_DEACTIVATE_REASON_DH_REQ NCI_DEACTIVATE_REASON_DH_REQ
+#define NFC_DEACTIVATE_REASON_ENDPOINT_REQ NCI_DEACTIVATE_REASON_ENDPOINT_REQ
+#define NFC_DEACTIVATE_REASON_RF_LINK_LOSS NCI_DEACTIVATE_REASON_RF_LINK_LOSS
+#define NFC_DEACTIVATE_REASON_NFCB_BAD_AFI NCI_DEACTIVATE_REASON_NFCB_BAD_AFI
+typedef UINT8 tNFC_DEACT_REASON;
+
+/* the data type associated with NFC_RF_FIELD_REVT */
+typedef struct
+{
+ tNFC_STATUS status; /* The event status - place holder. */
+ tNFC_RF_STS rf_field; /* RF Field Status */
+} tNFC_RF_FIELD_REVT;
+
+#define NFC_MAX_APP_DATA_LEN 40
+typedef struct
+{
+ UINT8 len_aid; /* length of application id */
+ UINT8 aid[NFC_MAX_AID_LEN]; /* application id */
+} tNFC_AID;
+typedef struct
+{
+ UINT8 len_aid; /* length of application id */
+ UINT8 aid[NFC_MAX_AID_LEN]; /* application id */
+ UINT8 len_data; /* len of application data */
+ UINT8 data[NFC_MAX_APP_DATA_LEN]; /* application data */
+} tNFC_APP_INIT;
+
+#define NFC_EE_TRIG_SELECT NCI_EE_TRIG_7816_SELECT /* ISO 7816-4 SELECT command */
+#define NFC_EE_TRIG_RF_PROTOCOL NCI_EE_TRIG_RF_PROTOCOL /* RF Protocol changed */
+#define NFC_EE_TRIG_RF_TECHNOLOGY NCI_EE_TRIG_RF_TECHNOLOGY/* RF Technology changed */
+#define NFC_EE_TRIG_APP_INIT NCI_EE_TRIG_APP_INIT /* Application initiation */
+typedef UINT8 tNFC_EE_TRIGGER;
+typedef struct
+{
+ tNFC_EE_TRIGGER trigger; /* the trigger of this event */
+ union
+ {
+ tNFC_PROTOCOL protocol;
+ tNFC_RF_TECH technology;
+ tNFC_AID aid;
+ tNFC_APP_INIT app_init;
+ } param; /* Discovery Type specific parameters */
+} tNFC_ACTION_DATA;
+
+/* the data type associated with NFC_EE_ACTION_REVT */
+typedef struct
+{
+ tNFC_STATUS status; /* The event status - place holder */
+ UINT8 nfcee_id; /* NFCEE ID */
+ tNFC_ACTION_DATA act_data; /* data associated /w the action */
+} tNFC_EE_ACTION_REVT;
+
+#define NFC_EE_DISC_OP_ADD 0
+#define NFC_EE_DISC_OP_REMOVE 1
+typedef UINT8 tNFC_EE_DISC_OP;
+typedef struct
+{
+ tNFC_EE_DISC_OP op; /* add or remove this entry */
+ UINT8 nfcee_id; /* NFCEE ID */
+ tNFC_RF_TECH_N_MODE tech_n_mode; /* Discovery Technology and Mode */
+ tNFC_PROTOCOL protocol; /* NFC protocol */
+} tNFC_EE_DISCOVER_INFO;
+
+#ifndef NFC_MAX_EE_DISC_ENTRIES
+#define NFC_MAX_EE_DISC_ENTRIES 6
+#endif
+#define NFC_EE_DISCOVER_ENTRY_LEN 5 /* T, L, V(NFCEE ID, TechnMode, Protocol) */
+#define NFC_EE_DISCOVER_INFO_LEN 3 /* NFCEE ID, TechnMode, Protocol */
+/* the data type associated with NFC_EE_DISCOVER_REQ_REVT */
+typedef struct
+{
+ tNFC_STATUS status; /* The event status - place holder */
+ UINT8 num_info; /* number of entries in info[] */
+ tNFC_EE_DISCOVER_INFO info[NFC_MAX_EE_DISC_ENTRIES]; /* discovery request from NFCEE */
+} tNFC_EE_DISCOVER_REQ_REVT;
+
+typedef union
+{
+ tNFC_STATUS status; /* The event status. */
+ tNFC_ENABLE_REVT enable;
+ tNFC_SET_CONFIG_REVT set_config;
+ tNFC_GET_CONFIG_REVT get_config;
+ tNFC_NFCEE_DISCOVER_REVT nfcee_discover;
+ tNFC_NFCEE_INFO_REVT nfcee_info;
+ tNFC_NFCEE_MODE_SET_REVT mode_set;
+ tNFC_RF_FIELD_REVT rf_field;
+ tNFC_STATUS cfg_routing;
+ tNFC_GET_ROUTING_REVT get_routing;
+ tNFC_EE_ACTION_REVT ee_action;
+ tNFC_EE_DISCOVER_REQ_REVT ee_discover_req;
+ void *p_vs_evt_data;
+} tNFC_RESPONSE;
+
+/*************************************
+** RESPONSE Callback Functions
+**************************************/
+typedef void (tNFC_RESPONSE_CBACK) (tNFC_RESPONSE_EVT event, tNFC_RESPONSE *p_data);
+
+/* The events reported on tNFC_VS_CBACK */
+/* The event is (NCI_RSP_BIT|oid) for response and (NCI_NTF_BIT|oid) for notification*/
+
+typedef UINT8 tNFC_VS_EVT;
+
+/*************************************
+** Proprietary (Vendor Specific) Callback Functions
+**************************************/
+typedef void (tNFC_VS_CBACK) (tNFC_VS_EVT event, UINT16 data_len, UINT8 *p_data);
+
+/* the events reported on tNFC_DISCOVER_CBACK */
+enum
+{
+ NFC_START_DEVT = NFC_FIRST_DEVT, /* Status of NFC_DiscoveryStart */
+ NFC_MAP_DEVT, /* Status of NFC_DiscoveryMap */
+ NFC_RESULT_DEVT, /* The responses from remote device */
+ NFC_SELECT_DEVT, /* Status of NFC_DiscoverySelect */
+ NFC_ACTIVATE_DEVT, /* RF interface is activated */
+ NFC_DEACTIVATE_DEVT /* Status of RF deactivation */
+};
+typedef UINT16 tNFC_DISCOVER_EVT;
+
+/* the data type associated with NFC_START_DEVT */
+typedef tNFC_STATUS tNFC_START_DEVT;
+
+typedef tNCI_RF_PA_PARAMS tNFC_RF_PA_PARAMS;
+#define NFC_MAX_SENSB_RES_LEN NCI_MAX_SENSB_RES_LEN
+#define NFC_NFCID0_MAX_LEN 4
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define NFC_PUPIID_MAX_LEN 8
+#endif
+typedef struct
+{
+ UINT8 sensb_res_len;/* Length of SENSB_RES Response (Byte 2 - Byte 12 or 13) Available after Technology Detection */
+ UINT8 sensb_res[NFC_MAX_SENSB_RES_LEN]; /* SENSB_RES Response (ATQ) */
+ UINT8 nfcid0[NFC_NFCID0_MAX_LEN];
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ UINT8 pupiid_len;
+ UINT8 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 bit_rate;/* NFC_BIT_RATE_212 or NFC_BIT_RATE_424 */
+ UINT8 sensf_res_len;/* Length of SENSF_RES Response (Byte 2 - Byte 17 or 19) Available after Technology Detection */
+ UINT8 sensf_res[NFC_MAX_SENSF_RES_LEN]; /* SENSB_RES Response */
+ UINT8 nfcid2[NFC_NFCID2_LEN]; /* NFCID2 generated by the Local NFCC for NFC-DEP Protocol.Available for Frame Interface */
+ UINT8 mrti_check;
+ UINT8 mrti_update;
+} tNFC_RF_PF_PARAMS;
+
+typedef tNCI_RF_LF_PARAMS tNFC_RF_LF_PARAMS;
+
+#define NFC_ISO15693_UID_LEN 8
+typedef struct
+{
+ UINT8 flag;
+ UINT8 dsfid;
+ UINT8 uid[NFC_ISO15693_UID_LEN];
+} tNFC_RF_PISO15693_PARAMS;
+
+#ifndef NFC_KOVIO_MAX_LEN
+#define NFC_KOVIO_MAX_LEN 32
+#endif
+typedef struct
+{
+ UINT8 uid_len;
+ UINT8 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 rf_disc_id; /* RF Discovery ID */
+ UINT8 protocol; /* supported protocol */
+ tNFC_RF_TECH_PARAMS rf_tech_param; /* RF technology parameters */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ UINT8 more; /* 0: last notification */
+#else
+ BOOLEAN more; /* 0: last notification */
+#endif
+} tNFC_RESULT_DEVT;
+
+/* the data type associated with NFC_SELECT_DEVT */
+typedef tNFC_STATUS tNFC_SELECT_DEVT;
+
+/* the data type associated with NFC_STOP_DEVT */
+typedef tNFC_STATUS tNFC_STOP_DEVT;
+
+#define NFC_MAX_ATS_LEN NCI_MAX_ATS_LEN
+#define NFC_MAX_HIS_BYTES_LEN NCI_MAX_HIS_BYTES_LEN
+#define NFC_MAX_GEN_BYTES_LEN NCI_MAX_GEN_BYTES_LEN
+
+
+typedef struct
+{
+ UINT8 ats_res_len; /* Length of ATS RES */
+ UINT8 ats_res[NFC_MAX_ATS_LEN]; /* ATS RES */
+ BOOLEAN nad_used; /* NAD is used or not */
+ UINT8 fwi; /* Frame Waiting time Integer */
+ UINT8 sfgi; /* Start-up Frame Guard time Integer*/
+ UINT8 his_byte_len; /* len of historical bytes */
+ UINT8 his_byte[NFC_MAX_HIS_BYTES_LEN];/* historical bytes */
+} tNFC_INTF_PA_ISO_DEP;
+
+typedef struct
+{
+ UINT8 rats; /* RATS */
+} tNFC_INTF_LA_ISO_DEP;
+
+
+typedef struct
+{
+ UINT8 atr_res_len; /* Length of ATR_RES */
+ UINT8 atr_res[NFC_MAX_ATS_LEN]; /* ATR_RES (Byte 3 - Byte 17+n) */
+ UINT8 max_payload_size; /* 64, 128, 192 or 254 */
+ UINT8 gen_bytes_len; /* len of general bytes */
+ UINT8 gen_bytes[NFC_MAX_GEN_BYTES_LEN];/* general bytes */
+ UINT8 waiting_time; /* WT -> Response Waiting Time RWT = (256 x 16/fC) x 2WT */
+} tNFC_INTF_PA_NFC_DEP;
+
+/* Note: keep tNFC_INTF_PA_NFC_DEP data member in the same order as tNFC_INTF_LA_NFC_DEP */
+typedef struct
+{
+ UINT8 atr_req_len; /* Length of ATR_REQ */
+ UINT8 atr_req[NFC_MAX_ATS_LEN]; /* ATR_REQ (Byte 3 - Byte 18+n) */
+ UINT8 max_payload_size; /* 64, 128, 192 or 254 */
+ UINT8 gen_bytes_len; /* len of general bytes */
+ UINT8 gen_bytes[NFC_MAX_GEN_BYTES_LEN];/* general bytes */
+} tNFC_INTF_LA_NFC_DEP;
+typedef tNFC_INTF_LA_NFC_DEP tNFC_INTF_LF_NFC_DEP;
+typedef tNFC_INTF_PA_NFC_DEP tNFC_INTF_PF_NFC_DEP;
+
+#define NFC_MAX_ATTRIB_LEN NCI_MAX_ATTRIB_LEN
+
+typedef struct
+{
+ UINT8 attrib_res_len; /* Length of ATTRIB RES */
+ UINT8 attrib_res[NFC_MAX_ATTRIB_LEN];/* ATTRIB RES */
+ UINT8 hi_info_len; /* len of Higher layer Info */
+ UINT8 hi_info[NFC_MAX_GEN_BYTES_LEN];/* Higher layer Info */
+ UINT8 mbli; /* Maximum buffer length. */
+} tNFC_INTF_PB_ISO_DEP;
+
+typedef struct
+{
+ UINT8 attrib_req_len; /* Length of ATTRIB REQ */
+ UINT8 attrib_req[NFC_MAX_ATTRIB_LEN];/* ATTRIB REQ (Byte 2 - 10+k)*/
+ UINT8 hi_info_len; /* len of Higher layer Info */
+ UINT8 hi_info[NFC_MAX_GEN_BYTES_LEN];/* Higher layer Info */
+ UINT8 nfcid0[NFC_NFCID0_MAX_LEN]; /* NFCID0 */
+} tNFC_INTF_LB_ISO_DEP;
+
+
+#ifndef NFC_MAX_RAW_PARAMS
+#define NFC_MAX_RAW_PARAMS 16
+#endif
+#define NFC_MAX_RAW_PARAMS 16
+typedef struct
+{
+ UINT8 param_len;
+ UINT8 param[NFC_MAX_RAW_PARAMS];
+} tNFC_INTF_FRAME;
+
+typedef struct
+{
+ tNFC_INTF_TYPE type; /* Interface Type 1 Byte See Table 67 */
+ union
+ {
+ tNFC_INTF_LA_ISO_DEP la_iso;
+ tNFC_INTF_PA_ISO_DEP pa_iso;
+ tNFC_INTF_LB_ISO_DEP lb_iso;
+ tNFC_INTF_PB_ISO_DEP pb_iso;
+ tNFC_INTF_LA_NFC_DEP la_nfc;
+ tNFC_INTF_PA_NFC_DEP pa_nfc;
+ tNFC_INTF_LF_NFC_DEP lf_nfc;
+ tNFC_INTF_PF_NFC_DEP pf_nfc;
+ tNFC_INTF_FRAME frame;
+ } intf_param; /* Activation Parameters 0 - n Bytes */
+} tNFC_INTF_PARAMS;
+
+/* the data type associated with NFC_ACTIVATE_DEVT */
+typedef struct
+{
+ UINT8 rf_disc_id; /* RF Discovery ID */
+ tNFC_PROTOCOL protocol; /* supported protocol */
+ tNFC_RF_TECH_PARAMS rf_tech_param; /* RF technology parameters */
+ tNFC_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 */
+ BOOLEAN is_ntf; /* TRUE, if deactivate notif*/
+} tNFC_DEACTIVATE_DEVT;
+
+typedef union
+{
+ tNFC_STATUS status; /* The event status. */
+ tNFC_START_DEVT start;
+ tNFC_RESULT_DEVT result;
+ tNFC_SELECT_DEVT select;
+ tNFC_STOP_DEVT stop;
+ tNFC_ACTIVATE_DEVT activate;
+ tNFC_DEACTIVATE_DEVT deactivate;
+} tNFC_DISCOVER;
+
+/* Min TR0 indicates to tag the min delay before responding after the end of command */
+#define NFC_RF_PARAM_MIN_TR0_DEFAULT 0x00
+#define NFC_RF_PARAM_MIN_TR0_48X 0x01 /* 48 x 16/fc */
+#define NFC_RF_PARAM_MIN_TR0_16X 0x02 /* 16 x 16/fc */
+
+/* Min TR1 indicates to tag the min delay between subcarrier modulation and data transmission */
+#define NFC_RF_PARAM_MIN_TR1_DEFAULT 0x00
+#define NFC_RF_PARAM_MIN_TR1_64X 0x01 /* 64 x 16/fc */
+#define NFC_RF_PARAM_MIN_TR1_16X 0x02 /* 16 x 16/fc */
+
+/* Min TR2 indicates to RW the min delay between EoS of tag and SoS of RW */
+#define NFC_RF_PARAM_MIN_TR2_1792 0x00 /* 1792/fc (10etu + 32/fc) */
+#define NFC_RF_PARAM_MIN_TR2_3328 0x01 /* 3328/fc (10etu + 128/fc) */
+#define NFC_RF_PARAM_MIN_TR2_5376 0x02 /* 5376/fc (10etu + 256/fc) */
+#define NFC_RF_PARAM_MIN_TR2_9472 0x03 /* 9472/fc (10etu + 512/fc) */
+
+#define NFC_RF_PARAM_EOS_REQUIRED 0x00 /* EoS required */
+#define NFC_RF_PARAM_EOS_NOT_REQUIRED 0x01 /* EoS not required */
+
+#define NFC_RF_PARAM_SOS_REQUIRED 0x00 /* SoS required */
+#define NFC_RF_PARAM_SOS_NOT_REQUIRED 0x01 /* SoS not required */
+
+typedef struct
+{
+ BOOLEAN include_rf_tech_mode; /* TRUE if including RF Tech and Mode update */
+ tNFC_RF_TECH_N_MODE rf_tech_n_mode; /* RF tech and mode */
+ BOOLEAN include_tx_bit_rate; /* TRUE if including Tx bit rate update */
+ tNFC_BIT_RATE tx_bit_rate; /* Transmit Bit Rate */
+ BOOLEAN include_rx_bit_rate; /* TRUE if including Rx bit rate update */
+ tNFC_BIT_RATE rx_bit_rate; /* Receive Bit Rate */
+ BOOLEAN include_nfc_b_config; /* TRUE if including NFC-B data exchange config */
+ UINT8 min_tr0; /* Minimun TR0 */
+ UINT8 min_tr1; /* Minimun TR1 */
+ UINT8 suppression_eos; /* Suppression of EoS */
+ UINT8 suppression_sos; /* Suppression of SoS */
+ UINT8 min_tr2; /* Minimun TR1 */
+} tNFC_RF_COMM_PARAMS;
+
+/*************************************
+** DISCOVER Callback Functions
+**************************************/
+typedef void (tNFC_DISCOVER_CBACK) (tNFC_DISCOVER_EVT event, tNFC_DISCOVER *p_data);
+
+/* the events reported on tNFC_TEST_CBACK */
+enum
+{
+ NFC_LOOPBACK_TEVT = NFC_FIRST_TEVT, /* 0 Loopback test */
+ NFC_RF_CONTROL_TEVT, /* 1 RF control Test response */
+ NFC_RF_FIELD_DONE_TEVT /* 1 RF control Test notificatn*/
+};
+typedef UINT16 tNFC_TEST_EVT;
+
+/* the data type associated with NFC_LOOPBACK_TEVT */
+typedef struct
+{
+ tNFC_STATUS status; /* The event status. */
+ BT_HDR *p_data; /* The loop back data from NFCC */
+} tNFC_LOOPBACK_TEVT;
+
+/* the data type associated with NFC_RF_CONTROL_TEVT */
+typedef tNFC_STATUS tNFC_RF_CONTROL_TEVT;
+
+typedef union
+{
+ tNFC_STATUS status; /* The event status. */
+ tNFC_LOOPBACK_TEVT loop_back;
+ tNFC_RF_CONTROL_TEVT rf_control;
+} tNFC_TEST;
+
+/*************************************
+** TEST Callback Functions
+**************************************/
+typedef void (tNFC_TEST_CBACK) (tNFC_TEST_EVT event, tNFC_TEST *p_data);
+
+
+typedef tNFC_DEACTIVATE_DEVT tNFC_DEACTIVATE_CEVT;
+typedef union
+{
+ tNFC_STATUS status; /* The event status. */
+ tNFC_CONN_CREATE_CEVT conn_create;
+ tNFC_CONN_CLOSE_CEVT conn_close;
+ tNFC_DEACTIVATE_CEVT deactivate;
+ tNFC_DATA_CEVT data;
+} tNFC_CONN;
+
+/*************************************
+** Data Callback Functions
+**************************************/
+typedef void (tNFC_CONN_CBACK) (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data);
+#define NFC_MAX_CONN_ID 15
+#define NFC_ILLEGAL_CONN_ID 0xFF
+#define NFC_RF_CONN_ID 0 /* the static connection ID for RF traffic */
+
+
+
+/*************************************
+** Status callback function
+**************************************/
+typedef void (tNFC_STATUS_CBACK) (tNFC_STATUS status);
+
+/*****************************************************************************
+** EXTERNAL FUNCTION DECLARATIONS
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+**
+** Function NFC_Enable
+**
+** Description This function enables NFC. Prior to calling NFC_Enable:
+** - the NFCC must be powered up, and ready to receive commands.
+** - GKI must be enabled
+** - NFC_TASK must be started
+** - NCIT_TASK must be started (if using dedicated NCI transport)
+**
+** This function opens the NCI transport (if applicable),
+** resets the NFC controller, and initializes the NFC subsystems.
+**
+** When the NFC startup procedure is completed, an
+** NFC_ENABLE_REVT is returned to the application using the
+** tNFC_RESPONSE_CBACK.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_Enable (tNFC_RESPONSE_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function NFC_Disable
+**
+** Description This function performs clean up routines for shutting down
+** NFC and closes the NCI transport (if using dedicated NCI
+** transport).
+**
+** When the NFC shutdown procedure is completed, an
+** NFC_DISABLED_REVT is returned to the application using the
+** tNFC_RESPONSE_CBACK.
+**
+** Returns nothing
+**
+*******************************************************************************/
+NFC_API extern void NFC_Disable (void);
+
+/*******************************************************************************
+**
+** Function NFC_Init
+**
+** Description This function initializes control blocks for NFC
+**
+** Returns nothing
+**
+*******************************************************************************/
+NFC_API extern void NFC_Init(tHAL_NFC_ENTRY *p_hal_entry_tbl);
+
+/*******************************************************************************
+**
+** Function NFC_GetLmrtSize
+**
+** Description Called by application wto query the Listen Mode Routing
+** Table size supported by NFCC
+**
+** Returns Listen Mode Routing Table size
+**
+*******************************************************************************/
+NFC_API extern UINT16 NFC_GetLmrtSize(void);
+
+/*******************************************************************************
+**
+** Function NFC_SetConfig
+**
+** Description This function is called to send the configuration parameter
+** TLV to NFCC. The response from NFCC is reported by
+** tNFC_RESPONSE_CBACK as NFC_SET_CONFIG_REVT.
+**
+** Parameters tlv_size - the length of p_param_tlvs.
+** p_param_tlvs - the parameter ID/Len/Value list
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_SetConfig (UINT8 tlv_size,
+ UINT8 *p_param_tlvs);
+
+/*******************************************************************************
+**
+** Function NFC_GetConfig
+**
+** Description This function is called to retrieve the parameter TLV from NFCC.
+** The response from NFCC is reported by tNFC_RESPONSE_CBACK
+** as NFC_GET_CONFIG_REVT.
+**
+** Parameters num_ids - the number of parameter IDs
+** p_param_ids - the parameter ID list.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_GetConfig (UINT8 num_ids,
+ UINT8 *p_param_ids);
+
+/*******************************************************************************
+**
+** Function NFC_NfceeDiscover
+**
+** Description This function is called to enable or disable NFCEE Discovery.
+** The response from NFCC is reported by tNFC_RESPONSE_CBACK
+** as NFC_NFCEE_DISCOVER_REVT.
+** The notification from NFCC is reported by tNFC_RESPONSE_CBACK
+** as NFC_NFCEE_INFO_REVT.
+**
+** Parameters discover - 1 to enable discover, 0 to disable.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_NfceeDiscover (BOOLEAN discover);
+
+/*******************************************************************************
+**
+** Function NFC_NfceeModeSet
+**
+** Description This function is called to activate or de-activate an NFCEE
+** connected to the NFCC.
+** The response from NFCC is reported by tNFC_RESPONSE_CBACK
+** as NFC_NFCEE_MODE_SET_REVT.
+**
+** Parameters nfcee_id - the NFCEE to activate or de-activate.
+** mode - 0 to activate NFCEE, 1 to de-activate.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_NfceeModeSet (UINT8 nfcee_id,
+ tNFC_NFCEE_MODE mode);
+/*******************************************************************************
+**
+** Function NFC_DiscoveryMap
+**
+** Description This function is called to set the discovery interface mapping.
+** The response from NFCC is reported by tNFC_DISCOVER_CBACK as.
+** NFC_MAP_DEVT.
+**
+** Parameters num - the number of items in p_params.
+** p_maps - the discovery interface mappings
+** p_cback - the discovery callback function
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_DiscoveryMap(UINT8 num, tNFC_DISCOVER_MAPS *p_maps,
+ tNFC_DISCOVER_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function NFC_DiscoveryStart
+**
+** Description This function is called to start Polling and/or Listening.
+** The response from NFCC is reported by tNFC_DISCOVER_CBACK as.
+** NFC_START_DEVT. The notification from NFCC is reported by
+** tNFC_DISCOVER_CBACK as NFC_RESULT_DEVT.
+**
+** Parameters num_params - the number of items in p_params.
+** p_params - the discovery parameters
+** p_cback - the discovery callback function
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_DiscoveryStart(UINT8 num_params,
+ tNFC_DISCOVER_PARAMS *p_params,
+ tNFC_DISCOVER_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function NFC_DiscoverySelect
+**
+** Description If tNFC_DISCOVER_CBACK reports status=NFC_MULTIPLE_PROT,
+** the application needs to use this function to select the
+** the logical endpoint to continue. The response from NFCC is
+** reported by tNFC_DISCOVER_CBACK as NFC_SELECT_DEVT.
+**
+** Parameters rf_disc_id - The ID identifies the remote device.
+** protocol - the logical endpoint on the remote devide
+** rf_interface - the RF interface to communicate with NFCC
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_DiscoverySelect (UINT8 rf_disc_id,
+ UINT8 protocol,
+ UINT8 rf_interface);
+
+/*******************************************************************************
+**
+** Function NFC_ConnCreate
+**
+** Description This function is called to create a logical connection with
+** NFCC for data exchange.
+** The response from NFCC is reported in tNFC_CONN_CBACK
+** as NFC_CONN_CREATE_CEVT.
+**
+** Parameters dest_type - the destination type
+** id - the NFCEE ID or RF Discovery ID .
+** protocol - the protocol
+** p_cback - the data callback function to receive data fron NFCC
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_ConnCreate(UINT8 dest_type,
+ UINT8 id,
+ UINT8 protocol,
+ tNFC_CONN_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function NFC_ConnClose
+**
+** Description This function is called to close a logical connection with
+** NFCC.
+** The response from NFCC is reported in tNFC_CONN_CBACK
+** as NFC_CONN_CLOSE_CEVT.
+**
+** Parameters conn_id - the connection id.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_ConnClose(UINT8 conn_id);
+
+/*******************************************************************************
+**
+** Function NFC_SetStaticRfCback
+**
+** Description This function is called to update the data callback function
+** to receive the data for the given connection id.
+**
+** Parameters p_cback - the connection callback function
+**
+** Returns Nothing
+**
+*******************************************************************************/
+NFC_API extern void NFC_SetStaticRfCback(tNFC_CONN_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function NFC_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
+**
+*******************************************************************************/
+NFC_API extern void NFC_SetReassemblyFlag (BOOLEAN 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
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_SendData(UINT8 conn_id,
+ BT_HDR *p_data);
+
+/*******************************************************************************
+**
+** Function NFC_FlushData
+**
+** Description This function is called to discard the tx data queue of
+** the given connection id.
+**
+** Parameters conn_id - the connection id.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_FlushData (UINT8 conn_id);
+
+/*******************************************************************************
+**
+** Function NFC_Deactivate
+**
+** Description This function is called to stop the discovery process or
+** put the listen device in sleep mode or terminate the NFC link.
+**
+** The response from NFCC is reported by tNFC_DISCOVER_CBACK
+** as NFC_DEACTIVATE_DEVT.
+**
+** Parameters deactivate_type - NFC_DEACTIVATE_TYPE_IDLE, to IDLE mode.
+** NFC_DEACTIVATE_TYPE_SLEEP to SLEEP mode.
+** NFC_DEACTIVATE_TYPE_SLEEP_AF to SLEEP_AF mode.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_Deactivate(tNFC_DEACT_TYPE deactivate_type);
+
+/*******************************************************************************
+**
+** Function NFC_UpdateRFCommParams
+**
+** Description This function is called to update RF Communication parameters
+** once the Frame RF Interface has been activated.
+**
+** The response from NFCC is reported by tNFC_RESPONSE_CBACK
+** as NFC_RF_COMM_PARAMS_UPDATE_REVT.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_UpdateRFCommParams (tNFC_RF_COMM_PARAMS *p_params);
+
+/*******************************************************************************
+**
+** Function NFC_SetPowerOffSleep
+**
+** Description This function closes/opens transport and turns off/on NFCC.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_SetPowerOffSleep (BOOLEAN enable);
+
+/*******************************************************************************
+**
+** Function NFC_PowerCycleNFCC
+**
+** Description This function turns off and then on NFCC.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_PowerCycleNFCC (void);
+
+/*******************************************************************************
+**
+** Function NFC_SetRouting
+**
+** Description This function is called to configure the CE routing table.
+** The response from NFCC is reported by tNFC_RESPONSE_CBACK
+** as NFC_SET_ROUTING_REVT.
+**
+** Parameters
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_SetRouting(BOOLEAN more,
+ UINT8 num_tlv,
+ UINT8 tlv_size,
+ UINT8 *p_param_tlvs);
+
+/*******************************************************************************
+**
+** Function NFC_GetRouting
+**
+** Description This function is called to retrieve the CE routing table from
+** NFCC. The response from NFCC is reported by tNFC_RESPONSE_CBACK
+** as NFC_GET_ROUTING_REVT.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_GetRouting(void);
+
+/*******************************************************************************
+**
+** Function NFC_RegVSCback
+**
+** Description This function is called to register or de-register a callback
+** function to receive Proprietary NCI response and notification
+** events.
+** The maximum number of callback functions allowed is NFC_NUM_VS_CBACKS
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_RegVSCback (BOOLEAN is_register,
+ tNFC_VS_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function NFC_SendVsCommand
+**
+** Description This function is called to send the given vendor specific
+** command to NFCC. The response from NFCC is reported to the
+** given tNFC_VS_CBACK as (oid).
+**
+** Parameters oid - The opcode of the VS command.
+** p_data - The parameters for the VS command
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_SendVsCommand(UINT8 oid,
+ BT_HDR *p_data,
+ tNFC_VS_CBACK *p_cback);
+
+#if (NFC_NXP_NOT_OPEN_INCLUDED == 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
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_SendNxpNciCommand (BT_HDR *p_data,
+ tNFC_VS_CBACK *p_cback);
+#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
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_TestLoopback(BT_HDR *p_data);
+
+
+/*******************************************************************************
+**
+** Function NFC_SetTraceLevel
+**
+** Description This function sets the trace level for NFC. If called with
+** a value of 0xFF, it simply returns the current trace level.
+**
+** Returns The new or current trace level
+**
+*******************************************************************************/
+NFC_API extern UINT8 NFC_SetTraceLevel (UINT8 new_level);
+
+#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
+**
+*******************************************************************************/
+NFC_API extern char * NFC_GetStatusName (tNFC_STATUS status);
+#endif
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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
+**
+*******************************************************************************/
+NFC_API extern tNFC_FW_VERSION nfc_ncif_getFWVersion();
+#if(ESE_NFC_POWER_MANAGEMENT == 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 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 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 NFC_GetP61Status (void *pdata);
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_API_H */
diff --git a/src/nfc/include/rw_api.h b/src/nfc/include/rw_api.h
new file mode 100644
index 0000000..ccbbaf1
--- /dev/null
+++ b/src/nfc/include/rw_api.h
@@ -0,0 +1,1365 @@
+/******************************************************************************
+ *
+ * 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(NFC_NXP_NOT_OPEN_INCLUDED == 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 */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ RW_T4T_NDEF_FORMAT_CPLT_EVT, /* Format operation completed */
+ 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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ RW_I93_MAX_EVT,
+ RW_T3BT_RAW_READ_CPLT_EVT,
+ RW_T3BT_MAX_EVT
+#else
+ RW_I93_MAX_EVT
+#endif
+};
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define RW_I93_MAX_RSP_TIMEOUT 1000
+#endif
+#define RW_RAW_FRAME_EVT 0xFF
+
+typedef UINT8 tRW_EVENT;
+
+#define RW_NDEF_FL_READ_ONLY 0x01 /* Tag is read only */
+#define RW_NDEF_FL_FORMATED 0x02 /* Tag formated for NDEF */
+#define RW_NDEF_FL_SUPPORTED 0x04 /* NDEF supported by the tag */
+#define RW_NDEF_FL_UNKNOWN 0x08 /* Unable to find if tag is ndef capable/formated/read only */
+#define RW_NDEF_FL_FORMATABLE 0x10 /* Tag supports format operation */
+#define RW_NDEF_FL_SOFT_LOCKABLE 0x20 /* Tag can be soft locked */
+#define RW_NDEF_FL_HARD_LOCKABLE 0x40 /* Tag can be hard locked */
+#define RW_NDEF_FL_OTP 0x80 /* Tag is one time programmable */
+
+typedef UINT8 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 hr[T1T_HR_LEN];
+ UINT8 uid[T1T_CMD_UID_LEN];
+} tRW_T1T_RID_EVT;
+
+typedef struct
+{
+ tNFC_STATUS status;
+ UINT16 msg_len; /* Length of the NDEF message */
+} tRW_T2T_DETECT;
+
+typedef struct
+{
+ tNFC_STATUS status; /* Status of the POLL request */
+ UINT8 rc; /* RC (request code) used in the POLL request */
+ UINT8 response_num; /* Number of SENSF_RES responses */
+ UINT8 response_bufsize; /* Size of SENSF_RES responses */
+ UINT8 *response_buf; /* Buffer of responses (length + SENSF_RES) see $8.1.2.2 of NCI specs */
+} tRW_T3T_POLL;
+
+typedef struct
+{
+ tNFC_STATUS status; /* Status of the Get System Codes request */
+ UINT8 num_system_codes; /* Number of system codes */
+ UINT16 *p_system_codes; /* Table of system codes */
+} tRW_T3T_SYSTEM_CODES;
+
+typedef struct
+{
+ tNFC_STATUS status; /* status of NDEF detection */
+ tNFC_PROTOCOL protocol; /* protocol used to detect NDEF */
+ UINT32 max_size; /* max number of bytes available for NDEF data */
+ UINT32 cur_size; /* current size of stored NDEF data (in bytes) */
+ 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 num_bytes; /* number of reserved/lock bytes based on the type of tlv */
+} tRW_DETECT_TLV_DATA;
+
+typedef struct
+{
+ tNFC_STATUS status;
+ BT_HDR *p_data;
+} tRW_READ_DATA;
+
+typedef struct
+{
+ tNFC_STATUS status;
+ UINT8 sw1;
+ UINT8 sw2;
+} tRW_T4T_SW;
+
+typedef struct /* RW_I93_INVENTORY_EVT */
+{
+ tNFC_STATUS status; /* status of Inventory command */
+ UINT8 dsfid; /* DSFID */
+ UINT8 uid[I93_UID_BYTE_LEN]; /* UID[0]:MSB, ... UID[7]:LSB */
+} tRW_I93_INVENTORY;
+
+typedef struct /* RW_I93_DATA_EVT */
+{
+ tNFC_STATUS status; /* status of Read/Get security status command */
+ UINT8 command; /* sent command */
+ BT_HDR *p_data; /* block data of security status */
+} tRW_I93_DATA;
+
+typedef struct /* RW_I93_SYS_INFO_EVT */
+{
+ tNFC_STATUS status; /* status of Get Sys Info command */
+ UINT8 info_flags; /* information flags */
+ UINT8 uid[I93_UID_BYTE_LEN]; /* UID[0]:MSB, ... UID[7]:LSB */
+ UINT8 dsfid; /* DSFID if I93_INFO_FLAG_DSFID */
+ UINT8 afi; /* AFI if I93_INFO_FLAG_AFI */
+ UINT16 num_block; /* number of blocks if I93_INFO_FLAG_MEM_SIZE */
+ UINT8 block_size; /* block size in byte if I93_INFO_FLAG_MEM_SIZE */
+ UINT8 IC_reference; /* IC Reference if I93_INFO_FLAG_IC_REF */
+} tRW_I93_SYS_INFO;
+
+typedef struct /* RW_I93_CMD_CMPL_EVT */
+{
+ tNFC_STATUS status; /* status of sent command */
+ UINT8 command; /* sent command */
+ UINT8 error_code; /* error code; I93_ERROR_CODE_XXX */
+} tRW_I93_CMD_CMPL;
+
+typedef struct
+{
+ tNFC_STATUS status;
+ BT_HDR *p_data;
+} tRW_RAW_FRAME;
+
+typedef union
+{
+ tNFC_STATUS status;
+ tRW_T3T_POLL t3t_poll; /* Response to t3t poll command */
+ tRW_T3T_SYSTEM_CODES t3t_sc; /* Received system codes from t3 tag */
+ tRW_DETECT_TLV_DATA tlv; /* The information of detected TLV data */
+ tRW_DETECT_NDEF_DATA ndef; /* The information of detected NDEF data */
+ tRW_READ_DATA data; /* The received data from a tag */
+ tRW_RAW_FRAME raw_frame; /* Response of raw frame sent */
+ tRW_T4T_SW t4t_sw; /* Received status words from a tag */
+ tRW_I93_INVENTORY i93_inventory; /* ISO 15693 Inventory response */
+ tRW_I93_DATA i93_data; /* ISO 15693 Data response */
+ tRW_I93_SYS_INFO i93_sys_info; /* ISO 15693 System Information */
+ tRW_I93_CMD_CMPL i93_cmd_cmpl; /* ISO 15693 Command complete */
+} tRW_DATA;
+
+
+typedef void (tRW_CBACK) (tRW_EVENT event, tRW_DATA *p_data);
+
+/*******************************************************************************
+**
+** Function RW_T1tRid
+**
+** Description This function send a RID command for Reader/Writer mode.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tRid (void);
+
+/*******************************************************************************
+**
+** Function RW_T1tReadAll
+**
+** Description This function send a RALL command for Reader/Writer mode.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tReadAll (void);
+
+/*******************************************************************************
+**
+** Function RW_T1tRead
+**
+** Description This function send a READ command for Reader/Writer mode.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tRead (UINT8 block, UINT8 byte);
+
+/*******************************************************************************
+**
+** Function RW_T1tWriteErase
+**
+** Description This function send a WRITE-E command for Reader/Writer mode.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tWriteErase (UINT8 block, UINT8 byte, UINT8 new_byte);
+
+/*******************************************************************************
+**
+** Function RW_T1tWriteNoErase
+**
+** Description This function send a WRITE-NE command for Reader/Writer mode.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tWriteNoErase (UINT8 block, UINT8 byte, UINT8 new_byte);
+
+/*******************************************************************************
+**
+** Function RW_T1tReadSeg
+**
+** Description This function send a RSEG command for Reader/Writer mode.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tReadSeg (UINT8 segment);
+
+/*******************************************************************************
+**
+** Function RW_T1tRead8
+**
+** Description This function send a READ8 command for Reader/Writer mode.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tRead8 (UINT8 block);
+
+/*******************************************************************************
+**
+** Function RW_T1tWriteErase8
+**
+** Description This function send a WRITE-E8 command for Reader/Writer mode.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tWriteErase8 (UINT8 block, UINT8 *p_new_dat);
+
+/*******************************************************************************
+**
+** Function RW_T1tWriteNoErase8
+**
+** Description This function send a WRITE-NE8 command for Reader/Writer mode.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tWriteNoErase8 (UINT8 block, UINT8 *p_new_dat);
+
+/*******************************************************************************
+**
+** Function RW_T1tLocateTlv
+**
+** Description This function is called to find the start of the given TLV
+**
+** Parameters: void
+**
+** Returns NCI_STATUS_OK, if detection was started. Otherwise, error status.
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tLocateTlv (UINT8 tlv_type);
+
+/*******************************************************************************
+**
+** Function RW_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.
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tDetectNDef (void);
+
+/*******************************************************************************
+**
+** Function RW_T1tReadNDef
+**
+** Description This function can be called to read the NDEF message on the tag.
+**
+** Parameters: p_buffer: The buffer into which to read the NDEF message
+** buf_len: The length of the buffer
+**
+** Returns NCI_STATUS_OK, if read was started. Otherwise, error status.
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tReadNDef (UINT8 *p_buffer, UINT16 buf_len);
+
+/*******************************************************************************
+**
+** Function RW_T1tWriteNDef
+**
+** Description This function can be called to write an NDEF message to the tag.
+**
+** Parameters: msg_len: The length of the buffer
+** p_msg: The NDEF message to write
+**
+** Returns NCI_STATUS_OK, if write was started. Otherwise, error status.
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tWriteNDef (UINT16 msg_len, UINT8 *p_msg);
+
+/*******************************************************************************
+**
+** Function RW_T1tSetTagReadOnly
+**
+** Description This function can be called to set the tag in to read only
+** state
+**
+** Parameters: b_hard_lock: To hard lock or just soft lock the tag
+**
+** Returns NCI_STATUS_OK, if set readonly operation started.
+** Otherwise, error status.
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tSetTagReadOnly (BOOLEAN b_hard_lock);
+
+/*****************************************************************************
+**
+** Function RW_T1tPresenceCheck
+**
+** Description
+** Check if the tag is still in the field.
+**
+** The RW_T1T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
+** or non-presence.
+**
+** Returns
+** NFC_STATUS_OK, if raw data frame sent
+** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+** NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tPresenceCheck (void);
+
+/*****************************************************************************
+**
+** Function RW_T1tFormatNDef
+**
+** Description
+** Format Tag content
+**
+** Returns
+** NFC_STATUS_OK, Command sent to format Tag
+** NFC_STATUS_REJECTED: Invalid HR0 and cannot format the tag
+** NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T1tFormatNDef (void);
+
+/*******************************************************************************
+**
+** Function RW_T2tLocateTlv
+**
+** Description This function is called to find the start of the given TLV
+**
+** Returns Pointer to the TLV, if successful. Otherwise, NULL.
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T2tLocateTlv(UINT8 tlv_type);
+
+/*******************************************************************************
+**
+** Function RW_T2tRead
+**
+** Description This function issues the Type 2 Tag READ command. When the
+** operation is complete the callback function will be called
+** with a RW_T2T_READ_EVT.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T2tRead (UINT16 block);
+
+/*******************************************************************************
+**
+** Function RW_T2tWrite
+**
+** Description This function issues the Type 2 Tag WRITE command. When the
+** operation is complete the callback function will be called
+** with a RW_T2T_WRITE_EVT.
+**
+** p_write_data points to the array of 4 bytes to be written
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T2tWrite (UINT16 block, UINT8 *p_write_data);
+
+/*******************************************************************************
+**
+** Function RW_T2tSectorSelect
+**
+** Description This function issues the Type 2 Tag SECTOR-SELECT command
+** packet 1. If a NACK is received as the response, the callback
+** function will be called with a RW_T2T_SECTOR_SELECT_EVT. If
+** an ACK is received as the response, the command packet 2 with
+** the given sector number is sent to the peer device. When the
+** response for packet 2 is received, the callback function will
+** be called with a RW_T2T_SECTOR_SELECT_EVT.
+**
+** A sector is 256 contiguous blocks (1024 bytes).
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T2tSectorSelect (UINT8 sector);
+
+/*******************************************************************************
+**
+** Function RW_T2tDetectNDef
+**
+** Description This function will find NDEF message if any in the Tag
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T2tDetectNDef (BOOLEAN 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.
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T2tReadNDef (UINT8 *p_buffer, UINT16 buf_len);
+
+/*******************************************************************************
+**
+** Function RW_T2tWriteNDef
+**
+** Description This function can be called to write an NDEF message to the tag.
+**
+** Parameters: msg_len: The length of the buffer
+** p_msg: The NDEF message to write
+**
+** Returns NCI_STATUS_OK, if write was started. Otherwise, error status.
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T2tWriteNDef (UINT16 msg_len, UINT8 *p_msg );
+
+/*******************************************************************************
+**
+** Function RW_T2tSetTagReadOnly
+**
+** Description This function can be called to set the tag in to read only
+** state
+**
+** Parameters: b_hard_lock: To indicate hard lock the tag or not
+**
+** Returns NCI_STATUS_OK, if set readonly operation started.
+** Otherwise, error status.
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T2tSetTagReadOnly (BOOLEAN b_hard_lock);
+
+/*****************************************************************************
+**
+** Function RW_T2tPresenceCheck
+**
+** Description
+** Check if the tag is still in the field.
+**
+** The RW_T2T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
+** or non-presence.
+**
+** Returns
+** NFC_STATUS_OK, if raw data frame sent
+** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+** NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_T2tPresenceCheck (void);
+
+/*****************************************************************************
+**
+** Function RW_T2tFormatNDef
+**
+** Description
+** Format Tag content
+**
+** Returns
+** NFC_STATUS_OK, Command sent to format Tag
+** NFC_STATUS_FAILED: otherwise
+**
+*****************************************************************************/
+tNFC_STATUS RW_T2tFormatNDef (void);
+
+/*****************************************************************************
+**
+** Function RW_T3tDetectNDef
+**
+** Description
+** This function is used to perform NDEF detection on a Type 3 tag, and
+** retrieve the tag's NDEF attribute information (block 0).
+**
+** Before using this API, the application must call RW_SelectTagType to
+** indicate that a Type 3 tag has been activated, and to provide the
+** tag's Manufacture ID (IDm) .
+**
+** Returns
+** NFC_STATUS_OK: ndef detection procedure started
+** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+** NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_T3tDetectNDef (void);
+
+/*****************************************************************************
+**
+** Function RW_T3tFormatNDef
+**
+** Description
+** Format a type-3 tag for NDEF.
+**
+** Only Felica-Lite tags are supported by this API. The
+** RW_T3T_FORMAT_CPLT_EVT is used to notify the status of the operation.
+**
+** Returns
+** NFC_STATUS_OK: ndef detection procedure started
+** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+** NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_T3tFormatNDef (void);
+
+/*****************************************************************************
+**
+** Function RW_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
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_T3tSetReadOnly (BOOLEAN 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
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_T3tCheckNDef (void);
+
+/*****************************************************************************
+**
+** Function RW_T3tUpdateNDef
+**
+** Description
+** Write NDEF contents to a Type3 tag.
+**
+** The RW_T3T_UPDATE_CPLT_EVT callback event will be used to notify the
+** application of the response.
+**
+** Before using this API, the RW_T3tDetectNDef function must be called to
+** verify that the tag contains NDEF data, and to retrieve the NDEF
+** attributes.
+**
+** Internally, this command will be separated into multiple Tag 3 Update
+** commands (if necessary) - depending on the tag's Nbw (max number of
+** blocks per write) attribute.
+**
+** Returns
+** NFC_STATUS_OK: check command started
+** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+** NFC_STATUS_REFUSED: tag is read-only
+** NFC_STATUS_BUFFER_FULL: len exceeds tag's maximum size
+** NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_T3tUpdateNDef (UINT32 len, UINT8 *p_data);
+
+/*****************************************************************************
+**
+** Function RW_T3tCheck
+**
+** Description
+** Read (non-NDEF) contents from a Type3 tag.
+**
+** The RW_READ_EVT event is used to notify the application for each
+** segment of NDEF data received. The RW_READ_CPLT_EVT event is used to
+** notify the application all segments have been received.
+**
+** Before using this API, the application must call RW_SelectTagType to
+** indicate that a Type 3 tag has been activated, and to provide the
+** tag's Manufacture ID (IDm) .
+**
+** Returns
+** NFC_STATUS_OK: check command started
+** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+** NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_T3tCheck (UINT8 num_blocks, tT3T_BLOCK_DESC *t3t_blocks);
+
+/*****************************************************************************
+**
+** Function RW_T3tUpdate
+**
+** Description
+** Write (non-NDEF) contents to a Type3 tag.
+**
+** The RW_WRITE_CPLT_EVT event is used to notify the application all
+** segments have been received.
+**
+** Before using this API, the application must call RW_SelectTagType to
+** indicate that a Type 3 tag has been activated, and to provide the tag's
+** Manufacture ID (IDm) .
+**
+** Returns
+** NFC_STATUS_OK: check command started
+** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+** NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_T3tUpdate (UINT8 num_blocks, tT3T_BLOCK_DESC *t3t_blocks, UINT8 *p_data);
+
+/*****************************************************************************
+**
+** Function RW_T3tSendRawFrame
+**
+** Description
+** This function is called to send a raw data frame to the peer device.
+** When type 3 tag receives response from peer, the callback function
+** will be called with a RW_T3T_RAW_FRAME_EVT [Table 6].
+**
+** Before using this API, the application must call RW_SelectTagType to
+** indicate that a Type 3 tag has been activated.
+**
+** The raw frame should be a properly formatted Type 3 tag message.
+**
+** Returns
+** NFC_STATUS_OK, if raw data frame sent
+** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+** NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_T3tSendRawFrame (UINT16 len, UINT8 *p_data);
+
+/*****************************************************************************
+**
+** Function RW_T3tPoll
+**
+** Description
+** Send POLL command
+**
+** Returns
+** NFC_STATUS_OK, if raw data frame sent
+** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+** NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_T3tPoll (UINT16 system_code, tT3T_POLL_RC rc, UINT8 tsn);
+
+/*****************************************************************************
+**
+** Function RW_T3tPresenceCheck
+**
+** Description
+** Check if the tag is still in the field.
+**
+** The RW_T3T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
+** or non-presence.
+**
+** Returns
+** NFC_STATUS_OK, if raw data frame sent
+** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+** NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_T3tPresenceCheck (void);
+
+/*****************************************************************************
+**
+** Function RW_T3tGetSystemCodes
+**
+** Description
+** Get systems codes supported by the activated tag:
+** Poll for wildcard (FFFF):
+** - If felica-lite code then poll for ndef (12fc)
+** - Otherwise send RequestSystmCode command to get
+** system codes.
+**
+** Before using this API, the application must call RW_SelectTagType to
+** indicate that a Type 3 tag has been activated.
+**
+** Returns
+** NFC_STATUS_OK, if raw data frame sent
+** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+** NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_T3tGetSystemCodes (void);
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+/*****************************************************************************
+**
+** 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
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_T4tFormatNDef (void);
+#endif
+
+/*******************************************************************************
+**
+** Function RW_T4tDetectNDef
+**
+** Description This function performs NDEF detection procedure
+**
+** RW_T4T_NDEF_DETECT_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_FAILED if T4T is busy or other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T4tDetectNDef (void);
+
+/*******************************************************************************
+**
+** Function RW_T4tReadNDef
+**
+** Description This function performs NDEF read procedure
+** Note: RW_T4tDetectNDef() must be called before using this
+**
+** The following event will be returned
+** RW_T4T_NDEF_READ_EVT for each segmented NDEF message
+** RW_T4T_NDEF_READ_CPLT_EVT for the last segment or complete NDEF
+** RW_T4T_NDEF_READ_FAIL_EVT for failure
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_FAILED if T4T is busy or other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T4tReadNDef (void);
+
+/*******************************************************************************
+**
+** Function RW_T4tUpdateNDef
+**
+** Description This function performs NDEF update procedure
+** Note: RW_T4tDetectNDef() must be called before using this
+** Updating data must not be removed until returning event
+**
+** The following event will be returned
+** RW_T4T_NDEF_UPDATE_CPLT_EVT for complete
+** RW_T4T_NDEF_UPDATE_FAIL_EVT for failure
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_FAILED if T4T is busy or other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T4tUpdateNDef (UINT16 length, UINT8 *p_data);
+
+/*****************************************************************************
+**
+** Function RW_T4tPresenceCheck
+**
+** Description
+** Check if the tag is still in the field.
+**
+** The RW_T4T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
+** or non-presence.
+** 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
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_T4tPresenceCheck (UINT8 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
+**
+*****************************************************************************/
+NFC_API 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
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93Inventory (BOOLEAN including_afi, UINT8 afi, UINT8 *p_uid);
+
+/*******************************************************************************
+**
+** Function RW_I93StayQuiet
+**
+** Description This function send Inventory command
+**
+** RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_NO_BUFFERS if out of buffer
+** NFC_STATUS_BUSY if busy
+** NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93StayQuiet (void);
+
+/*******************************************************************************
+**
+** Function RW_I93ReadSingleBlock
+**
+** Description This function send Read Single Block command
+**
+** RW_I93_RESPONSE_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_NO_BUFFERS if out of buffer
+** NFC_STATUS_BUSY if busy
+** NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93ReadSingleBlock (UINT16 block_number);
+
+/*******************************************************************************
+**
+** Function RW_I93WriteSingleBlock
+**
+** Description This function send Write Single Block command
+** Application must get block size first by calling RW_I93GetSysInfo().
+**
+** RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_NO_BUFFERS if out of buffer
+** NFC_STATUS_BUSY if busy
+** NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93WriteSingleBlock (UINT16 block_number,
+ UINT8 *p_data);
+
+/*******************************************************************************
+**
+** Function RW_I93LockBlock
+**
+** Description This function send Lock Block command
+**
+** RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_NO_BUFFERS if out of buffer
+** NFC_STATUS_BUSY if busy
+** NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93LockBlock (UINT8 block_number);
+
+/*******************************************************************************
+**
+** Function RW_I93ReadMultipleBlocks
+**
+** Description This function send Read Multiple Blocks command
+**
+** RW_I93_RESPONSE_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_NO_BUFFERS if out of buffer
+** NFC_STATUS_BUSY if busy
+** NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93ReadMultipleBlocks (UINT16 first_block_number,
+ UINT16 number_blocks);
+
+/*******************************************************************************
+**
+** Function RW_I93WriteMultipleBlocks
+**
+** Description This function send Write Multiple Blocks command
+**
+** RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_NO_BUFFERS if out of buffer
+** NFC_STATUS_BUSY if busy
+** NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93WriteMultipleBlocks (UINT8 first_block_number,
+ UINT16 number_blocks,
+ UINT8 *p_data);
+
+/*******************************************************************************
+**
+** Function RW_I93Select
+**
+** Description This function send Select command
+**
+** UID[0]: 0xE0, MSB
+** UID[1]: IC Mfg Code
+** ...
+** UID[7]: LSB
+**
+** RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_NO_BUFFERS if out of buffer
+** NFC_STATUS_BUSY if busy
+** NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93Select (UINT8 *p_uid);
+
+/*******************************************************************************
+**
+** Function RW_I93ResetToReady
+**
+** Description This function send Reset To Ready command
+**
+** RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_NO_BUFFERS if out of buffer
+** NFC_STATUS_BUSY if busy
+** NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93ResetToReady (void);
+
+/*******************************************************************************
+**
+** Function RW_I93WriteAFI
+**
+** Description This function send Write AFI command
+**
+** RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_NO_BUFFERS if out of buffer
+** NFC_STATUS_BUSY if busy
+** NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93WriteAFI (UINT8 afi);
+
+/*******************************************************************************
+**
+** Function RW_I93LockAFI
+**
+** Description This function send Lock AFI command
+**
+** RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_NO_BUFFERS if out of buffer
+** NFC_STATUS_BUSY if busy
+** NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93LockAFI (void);
+
+/*******************************************************************************
+**
+** Function RW_I93WriteDSFID
+**
+** Description This function send Write DSFID command
+**
+** RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_NO_BUFFERS if out of buffer
+** NFC_STATUS_BUSY if busy
+** NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93WriteDSFID (UINT8 dsfid);
+
+/*******************************************************************************
+**
+** Function RW_I93LockDSFID
+**
+** Description This function send Lock DSFID command
+**
+** RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_NO_BUFFERS if out of buffer
+** NFC_STATUS_BUSY if busy
+** NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93LockDSFID (void);
+
+/*******************************************************************************
+**
+** Function RW_I93GetSysInfo
+**
+** Description This function send Get System Information command
+** If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
+**
+** RW_I93_RESPONSE_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_NO_BUFFERS if out of buffer
+** NFC_STATUS_BUSY if busy
+** NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93GetSysInfo (UINT8 *p_uid);
+
+/*******************************************************************************
+**
+** Function RW_I93GetMultiBlockSecurityStatus
+**
+** Description This function send Get Multiple Block Security Status command
+**
+** RW_I93_RESPONSE_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_NO_BUFFERS if out of buffer
+** NFC_STATUS_BUSY if busy
+** NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93GetMultiBlockSecurityStatus (UINT16 first_block_number,
+ UINT16 number_blocks);
+
+/*******************************************************************************
+**
+** Function RW_I93DetectNDef
+**
+** Description This function performs NDEF detection procedure
+**
+** RW_I93_NDEF_DETECT_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_FAILED if busy or other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93DetectNDef (void);
+
+/*******************************************************************************
+**
+** Function RW_I93ReadNDef
+**
+** Description This function performs NDEF read procedure
+** Note: RW_I93DetectNDef() must be called before using this
+**
+** The following event will be returned
+** RW_I93_NDEF_READ_EVT for each segmented NDEF message
+** RW_I93_NDEF_READ_CPLT_EVT for the last segment or complete NDEF
+** RW_I93_NDEF_READ_FAIL_EVT for failure
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_FAILED if I93 is busy or other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93ReadNDef (void);
+
+/*******************************************************************************
+**
+** Function RW_I93UpdateNDef
+**
+** Description This function performs NDEF update procedure
+** Note: RW_I93DetectNDef() must be called before using this
+** Updating data must not be removed until returning event
+**
+** The following event will be returned
+** RW_I93_NDEF_UPDATE_CPLT_EVT for complete
+** RW_I93_NDEF_UPDATE_FAIL_EVT for failure
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_FAILED if I93 is busy or other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93UpdateNDef (UINT16 length, UINT8 *p_data);
+
+/*******************************************************************************
+**
+** Function RW_I93FormatNDef
+**
+** Description This function performs formatting procedure
+**
+** RW_I93_FORMAT_CPLT_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_FAILED if busy or other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93FormatNDef (void);
+
+/*******************************************************************************
+**
+** Function RW_I93SetTagReadOnly
+**
+** Description This function performs NDEF read-only procedure
+** Note: RW_I93DetectNDef() must be called before using this
+** Updating data must not be removed until returning event
+**
+** The RW_I93_SET_TAG_RO_EVT event will be returned.
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_FAILED if I93 is busy or other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93SetTagReadOnly (void);
+
+/*****************************************************************************
+**
+** Function RW_I93PresenceCheck
+**
+** Description Check if the tag is still in the field.
+**
+** The RW_I93_PRESENCE_CHECK_EVT w/ status is used to indicate
+** presence or non-presence.
+**
+** Returns NFC_STATUS_OK, if raw data frame sent
+** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+** NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93PresenceCheck (void);
+
+/*******************************************************************************
+**
+** Function RW_SendRawFrame
+**
+** Description This function sends a raw frame to the peer device.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_SendRawFrame (UINT8 *p_raw_data, UINT16 data_len);
+
+/*******************************************************************************
+**
+** Function RW_SetActivatedTagType
+**
+** Description This function sets tag type for Reader/Writer mode.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_SetActivatedTagType (tNFC_ACTIVATE_DEVT *p_activate_params, tRW_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function RW_SetTraceLevel
+**
+** Description This function sets the trace level for Reader/Writer mode.
+** If called with a value of 0xFF,
+** it simply returns the current trace level.
+**
+** Returns The new or current trace level
+**
+*******************************************************************************/
+NFC_API extern UINT8 RW_SetTraceLevel (UINT8 new_level);
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+NFC_API 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..ad4d07c
--- /dev/null
+++ b/src/nfc/include/tags_defs.h
@@ -0,0 +1,586 @@
+/******************************************************************************
+ *
+ * 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 */
+#define TAG_BRCM_MID 0x2E /* BROADCOM CORPORATION */
+#define TAG_MIFARE_MID 0x04 /* MIFARE */
+#define TAG_KOVIO_MID 0x37 /* KOVIO */
+#define TAG_INFINEON_MID 0x05 /* Infineon Technologies */
+
+/* TLV types present in Type1 and Type 2 Tags */
+#define TAG_NULL_TLV 0 /* May be used for padding. SHALL ignore this */
+#define TAG_LOCK_CTRL_TLV 1 /* Defines details of the lock bytes */
+#define TAG_MEM_CTRL_TLV 2 /* Identifies reserved memory areas */
+#define TAG_NDEF_TLV 3 /* Contains the NDEF message */
+#define TAG_PROPRIETARY_TLV 0xFD /* Tag proprietary information */
+#define TAG_TERMINATOR_TLV 0xFE /* Last TLV block in the data area */
+#define TAG_BITS_PER_BYTE 0x08 /* Number of bits in every tag byte */
+#define TAG_MAX_UID_LEN 0x0A /* Max UID Len of type 1 and type 2 tag */
+
+#define TAG_LONG_NDEF_LEN_FIELD_BYTE0 0xFF /* Byte 0 Length field to indicate LNDEF */
+#define TAG_DEFAULT_TLV_LEN 3 /* Tlv len for LOCK_CTRL/MEM TLV per spec */
+
+/* Type 1 Tag related definitions */
+
+#define T1T_STATIC_BLOCKS 0x0F /* block 0 to Block E */
+#define T1T_BLOCK_SIZE 0x08 /* T1T Block size in bytes */
+
+#define T1T_STATIC_SIZE T1T_STATIC_BLOCKS * T1T_BLOCK_SIZE /* Static Tag size */
+
+#define T1T_SEGMENT_SIZE 0x80 /* Size of Type 1 Tag segment in bytes */
+#define T1T_MAX_SEGMENTS 0x10 /* Maximum segment supported by Type 1 Tag */
+#define T1T_BLOCKS_PER_SEGMENT 0x10 /* Number of blocks present in a segment */
+#define T1T_OTP_LOCK_RES_BYTES 0x10 /* No.of default OTP,staticlocks,res bytes in tag */
+
+#define T1T_STATIC_HR0 0x11 /* HRO value to indicate static Tag */
+#define T1T_DYNAMIC_HR0 0x12 /* 0x1y, as long as (y!=1) */
+#define T1T_NDEF_SUPPORTED 0x10 /* HR0 value is 0x1y, indicates NDEF supported */
+#define T1T_HR1 0x00 /* should be ignored */
+#define T1T_UID_BLOCK 0x00 /* UID block */
+#define T1T_RES_BLOCK 0x0D /* Reserved block */
+#define T1T_LOCK_BLOCK 0x0E /* Static lock block */
+#define T1T_MID_OFFSET 0x06 /* Manufacturer ID offset */
+#define T1T_STATIC_RES_OFFSET 0x68 /* Reserved bytes offset */
+#define T1T_LOCK_0_OFFSET 0x70 /* Static lock offset */
+#define T1T_LOCK_1_OFFSET 0x71 /* Static lock offset */
+#define T1T_DYNAMIC_LOCK_OFFSET 0x78 /* Block F - typically used for dynamic locks */
+#define T1T_DYNAMIC_LOCK_BYTES 0x08
+
+#define T1T_RES_BYTE_LEN 1 /* the len of reserved byte in T1T block 0 */
+
+/* Capability Container definitions */
+#define T1T_CC_BLOCK 1 /* Capability container block */
+#define T1T_CC_LEN 4 /* the len of CC used in T1T tag */
+/* CC offset */
+#define T1T_CC_NMN_OFFSET 0x00 /* Offset for NDEF magic number in CC */
+#define T1T_CC_VNO_OFFSET 0x01 /* Offset for Version number in CC */
+#define T1T_CC_TMS_OFFSET 0x02 /* Offset for Tag memory size in CC */
+#define T1T_CC_RWA_OFFSET 0x03 /* Offset for Read/Write access in CC */
+#define T1T_CC_NMN_BYTE 0x08 /* NDEF Magic Number byte number */
+#define T1T_CC_VNO_BYTE 0x09 /* Version Number byte number */
+#define T1T_CC_TMS_BYTE 0x0A /* Tag Memory Size byte number */
+#define T1T_CC_RWA_BYTE 0x0B /* Read Write Access byte number */
+#define T1T_CC_NMN 0xE1 /* NDEF Magic Number */
+#define T1T_CC_LEGACY_VNO 0x10 /* Supported Legacy Version */
+#define T1T_CC_VNO 0x11 /* Version Number */
+#define T1T_CC_TMS_STATIC 0x0E /* TMS static memory - (8 * (n+1)). */
+#define T1T_CC_RWA_RW 0x00 /* RWA - Read/write allowed */
+#define T1T_CC_RWA_RO 0x0F /* RWA - Read only */
+
+#define T1T_TAG_NULL 0 /* May be used for padding. SHALL ignore this */
+#define T1T_TAG_LOCK_CTRL 1 /* Defines details of the lock bytes */
+#define T1T_TAG_MEM_CTRL 2 /* Identifies reserved memory areas */
+#define T1T_TAG_NDEF 3 /* Contains the NDEF message */
+#define T1T_TAG_PROPRIETARY 0xFD /* Tag proprietary information */
+#define T1T_TAG_TERMINATOR 0xFE /* Last TLV block in the data area */
+
+#define T1T_DEFAULT_TLV_LEN 3 /* Tlv len for LOCK_CTRL/MEM TLV per spec */
+#define T1T_TLV_TYPE_LEN 1 /* Tlv type identifier len */
+#define T1T_DEFAULT_TLV_LEN_FIELD_LEN 1 /* Length field size of lock/mem tlv */
+
+#define T1T_HR_LEN 2 /* the len of HR used in Type 1 Tag */
+#define T1T_CMD_UID_LEN 4 /* the len of UID used in Type 1 Tag Commands */
+#define T1T_UID_LEN 7 /* the len of UID used in Type 1 Tag */
+#define T1T_ADD_LEN 1
+
+#define T1T_SHORT_NDEF_LEN_FIELD_LEN 1 /* Length Field size of short NDEF Message */
+#define T1T_LONG_NDEF_LEN_FIELD_LEN 3 /* Length Field size of Long NDEF Message */
+#define T1T_LONG_NDEF_LEN_FIELD_BYTE0 0xFF /* Byte 0 in Length field to indicate LNDEF*/
+#define T1T_LONG_NDEF_MIN_LEN 0x00FF /* Min. len of NDEF to qualify as LNDEF */
+
+/* Type 1 Tag Commands (7 bits) */
+#define T1T_CMD_RID 0x78 /* read id */
+#define T1T_CMD_RALL 0x00 /* read all bytes */
+#define T1T_CMD_READ 0x01 /* read (1 byte) */
+#define T1T_CMD_WRITE_E 0x53 /* write with erase (1 byte) */
+#define T1T_CMD_WRITE_NE 0x1A /* write no erase (1 byte) */
+/* dynamic memory only */
+#define T1T_CMD_RSEG 0x10 /* read segment */
+#define T1T_CMD_READ8 0x02 /* read (8 byte) */
+#define T1T_CMD_WRITE_E8 0x54 /* write with erase (8 byte) */
+#define T1T_CMD_WRITE_NE8 0x1B /* write no erase (8 byte) */
+
+/* Lock */
+#define T1T_NUM_STATIC_LOCK_BYTES 2 /* Number of static lock bytes in tag */
+#define T1T_BYTES_LOCKED_BY_STATIC_LOCK_BIT 4 /* Bytes locked by one static lock bit */
+
+
+/* Type 2 Tag related definitions */
+#define T2T_STATIC_MEM_STR 0
+#define T2T_DYNAMIC_MEM_STR 1
+#define T2T_STATIC_SIZE 64
+#define T2T_STATIC_BLOCKS 16 /* block 0 to Block 15 */
+#define T2T_BLOCK_SIZE 4
+#define T2T_HEADER_BLOCKS 4
+#define T2T_HEADER_SIZE 16
+#define T2T_SECTOR_SIZE 1024
+#define T2T_BLOCKS_PER_SECTOR 0x100
+
+#define T2T_UID_LEN 4 /* the len of UID used in T2T tag */
+#define T2T_BLOCK0_UID_LEN 3 /* the len of UID in Block 0 of T2T tag */
+#define T2T_BCC0_LEN 1 /* the len of BCC0 of T2T tag */
+#define T2T_BLOCK1_UID_LEN 4 /* the len of UID in Block 1 of T2T tag */
+#define T2T_BCC1_LEN 1 /* the len of BCC0 of T2T tag */
+#define T2T_SNO_LEN 4 /* the len of Serial number used in T2T tag */
+#define T2T_INTERNAL_BYTES_LEN 2 /* the len of internal used in T2T tag */
+#define T2T_STATIC_LOCK_LEN 2 /* the len of static lock used in T2T tag */
+/* Static Lock Bytes */
+#define T2T_STATIC_LOCK0 0x0A /* Static Lock 0 offset */
+#define T2T_STATIC_LOCK1 0x0B /* Static Lock 1 offset */
+
+#define T2T_CC_LEN 4 /* the len of CC used in T2T tag */
+
+/* Capability Container definitions */
+#define T2T_CC_BLOCK 0x03 /* Capability container block */
+#define T2T_CC0_NMN_BYTE 0x0C /* NDEF Magic Number byte number */
+#define T2T_CC1_VNO_BYTE 0x0D /* Version Number byte number*/
+#define T2T_CC2_TMS_BYTE 0x0E /* Tag Memory Size byte number */
+#define T2T_CC3_RWA_BYTE 0x0F /* Read Write Access byte number */
+#define T2T_DATA_MEM 0x10 /* Data Memory */
+
+#define T2T_CC0_NMN 0xE1 /* NDEF Magic Number */
+#define T2T_CC1_VNO 0x11 /* Version Number */
+#define T2T_CC1_LEGACY_VNO 0x10 /* Legacy Version Number */
+#define T2T_CC1_NEW_VNO 0x12 /* Another supported Version Number */
+#define T2T_CC2_TMS_STATIC 0x06 /* TMS static memory - (4 * (n+1)). */
+#define T2T_CC3_RWA_RW 0x00 /* RWA - Read/write allowed */
+#define T2T_CC3_RWA_RO 0x0F /* RWA - Read only */
+
+#define T2T_TMS_TAG_FACTOR 0x08 /* Factor to multiply to get tag data size from TMS */
+#define T2T_DEFAULT_LOCK_BLPB 0x08 /* Bytes locked per lock bit of default locks */
+
+/* Type 2 Tag Commands */
+#define T2T_CMD_READ 0x30 /* read 4 blocks (16 bytes) */
+#define T2T_CMD_WRITE 0xA2 /* write 1 block (4 bytes) */
+#define T2T_CMD_SEC_SEL 0xC2 /* Sector select */
+#define T2T_RSP_ACK 0xA
+#define T2T_RSP_NACK5 0x5
+#define T2T_RSP_NACK1 0x1 /* Nack can be either 1 */
+
+#define T2T_FIRST_DATA_BLOCK 4
+#define T2T_READ_BLOCKS 4
+#define T2T_BLOCK_LEN 4
+#define T2T_READ_DATA_LEN (T2T_BLOCK_LEN * T2T_READ_BLOCKS)
+#define T2T_WRITE_DATA_LEN 4
+
+
+/* Type 2 TLV definitions */
+#define T2T_TLV_TYPE_NULL 0 /* May be used for padding. SHALL ignore this */
+#define T2T_TLV_TYPE_LOCK_CTRL 1 /* Defines details of the lock bytes */
+#define T2T_TLV_TYPE_MEM_CTRL 2 /* Identifies reserved memory areas */
+#define T2T_TLV_TYPE_NDEF 3 /* Contains the NDEF message */
+#define T2T_TLV_TYPE_PROPRIETARY 0xFD /* Tag proprietary information */
+#define T2T_TLV_TYPE_TERMINATOR 0xFE /* Last TLV block in the data area */
+
+
+#define T2T_TLEN_LOCK_CTRL_TLV 3 /* Tag len for LOCK_CTRL TLV per spec */
+#define T2T_TLEN_MEM_CTRL_TLV 3 /* Tag len for MEM_CTRL TLV per spec */
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define T2T_MAX_SECTOR 3 /* Maximum number of sectors supported */
+#else
+#define T2T_MAX_SECTOR 2 /* Maximum number of sectors supported */
+#endif
+
+#define T2T_TLV_TYPE_LEN 1 /* Tlv type identifier len */
+
+#define T2T_DEFAULT_TLV_LEN 3 /* Tlv len for LOCK_CTRL/MEM TLV per spec */
+#define T2T_SHORT_NDEF_LEN_FIELD_LEN 1 /* Length Field size of short NDEF Message */
+#define T2T_LONG_NDEF_LEN_FIELD_LEN 3 /* Length Field size of Long NDEF Message */
+#define T2T_LONG_NDEF_LEN_FIELD_BYTE0 0xFF /* Byte 0 in Length field to indicate LNDEF*/
+#define T2T_LONG_NDEF_MIN_LEN 0x00FF /* Min. len of NDEF to qualify as LNDEF */
+
+/* Lock */
+#define T2T_NUM_STATIC_LOCK_BYTES 2 /* Number of static lock bytes in tag */
+#define T2T_BYTES_LOCKED_BY_STATIC_LOCK_BIT 4 /* Bytes locked by one static lock bit */
+
+#define T2T_CC2_TMS_MUL 0x06
+#define T2T_CC2_TMS_MULC 0x12
+/*
+**
+** Type 3 Tag Definitions
+**
+*/
+
+#define T3T_SYSTEM_CODE_NDEF 0x12FC /* System Code for NDEF tags */
+#define T3T_SYSTEM_CODE_FELICA_LITE 0x88B4 /* System Code for felica-lite tags */
+#define T3T_MAX_SYSTEM_CODES 16
+#define T3T_FELICALITE_NMAXB 13 /* Maximum number of blocks for NDEF message for Felica Lite tags */
+
+/* Block descriptor, used to describe a block to check/update */
+typedef struct
+{
+ UINT16 service_code; /* Block service code. Set to T3T_SERVICE_CODE_NDEF (0x000B) for NDEF data */
+ UINT16 block_number; /* Block number */
+} tT3T_BLOCK_DESC;
+
+/* Poll RC (request code) definitions */
+#define T3T_POLL_RC_NONE 0 /* No RD requested in SENSF_RES */
+#define T3T_POLL_RC_SC 1 /* System code requested in SENSF_RES */
+#define T3T_POLL_RC_COMM 2 /* Avanced protocol features requested in SENSF_RES */
+typedef UINT8 tT3T_POLL_RC;
+
+/* Definitions for constructing t3t command messages */
+
+/* NFC Forum / Felica commands */
+#define T3T_MSG_OPC_CHECK_CMD 0x06
+#define T3T_MSG_OPC_CHECK_RSP 0x07
+#define T3T_MSG_OPC_UPDATE_CMD 0x08
+#define T3T_MSG_OPC_UPDATE_RSP 0x09
+
+/* Felica commands (not specified in NFC-Forum Type 3 tag specifications) */
+#define T3T_MSG_OPC_POLL_CMD 0x00
+#define T3T_MSG_OPC_POLL_RSP 0x01
+#define T3T_MSG_OPC_REQ_SERVICE_CMD 0x02
+#define T3T_MSG_OPC_REQ_SERVICE_RSP 0x03
+#define T3T_MSG_OPC_REQ_RESPONSE_CMD 0x04
+#define T3T_MSG_OPC_REQ_RESPONSE_RSP 0x05
+#define T3T_MSG_OPC_REQ_SYSTEMCODE_CMD 0x0C
+#define T3T_MSG_OPC_REQ_SYSTEMCODE_RSP 0x0D
+
+#define T3T_MSG_NDEF_SC_RO 0x000B /* Service code: read-only NDEF */
+#define T3T_MSG_NDEF_SC_RW 0x0009 /* Service code: read/write NDEF */
+#define T3T_MSG_NDEF_VERSION 0x10 /* NDEF Mapping Version 1.0 */
+#define T3T_MSG_NDEF_WRITEF_OFF 0x00
+#define T3T_MSG_NDEF_WRITEF_ON 0x0F
+#define T3T_MSG_NDEF_RWFLAG_RO 0x00
+#define T3T_MSG_NDEF_RWFLAG_RW 0x01
+#define T3T_MSG_NDEF_ATTR_INFO_SIZE 14 /* Size of NDEF attribute info block (minus checksum) */
+
+#define T3T_MSG_OFFSET_IDM 1 /* offset of Manufacturer ID in UPDATE/CHECK messages */
+#define T3T_MSG_OFFSET_NUM_SERVICES 9 /* offset of Number of Services parameter in UPDATE/CHECK messages */
+#define T3T_MSG_OFFSET_SERVICE_CODE_LIST 10 /* offset of Service Code List parameter in UPDATE/CHECK messages */
+#define T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT 0x80 /* len flag for Block List Element */
+#define T3T_MSG_SERVICE_LIST_MASK 0x0F /* service code list mask */
+#define T3T_MSG_SERVICE_LIST_MAX 16
+
+#define T3T_MSG_NUM_SERVICES_UPDATE_MAX 12 /* Max Number of Services per UPDATE command */
+#define T3T_MSG_NUM_SERVICES_CHECK_MAX 15 /* Max Number of Services per CHECK command */
+#define T3T_MSG_NUM_BLOCKS_UPDATE_MAX 13 /* Max Number of Blocks per UPDATE command */
+#define T3T_MSG_NUM_BLOCKS_CHECK_MAX 15 /* Max Number of Blocks per CHECK command */
+
+#define T3T_MSG_BLOCKSIZE 16 /* Data block size for UPDATE and CHECK commands */
+
+/* Common header definitions for T3t commands */
+#define T3T_MSG_CMD_COMMON_HDR_LEN 11 /* Common header: SoD + cmdcode + NFCID2 + num_services */
+
+/* Common header definition for T3t responses */
+#define T3T_MSG_RSP_COMMON_HDR_LEN 11 /* Common header: rspcode + NFCID2 + StatusFlag1 + StatusFlag2 */
+#define T3T_MSG_RSP_CHECK_HDR_LEN (T3T_MSG_RSP_COMMON_HDR_LEN + 1) /* Common header + NumBlocks */
+#define T3T_MSG_RSP_OFFSET_RSPCODE 0 /* Offset for Response code */
+#define T3T_MSG_RSP_OFFSET_IDM 1 /* Offset for Manufacturer ID */
+#define T3T_MSG_RSP_OFFSET_STATUS1 9 /* Offset for Status Flag1 */
+#define T3T_MSG_RSP_OFFSET_NUMBLOCKS 11 /* Offset for NumberOfBlocks (in CHECK response) */
+#define T3T_MSG_RSP_OFFSET_CHECK_DATA 12 /* Offset for Block Data (in CHECK response) */
+#define T3T_MSG_RSP_OFFSET_POLL_PMM 9 /* Offset for PMm (in POLL response) */
+#define T3T_MSG_RSP_OFFSET_POLL_RD 17 /* Offset for RD (in POLL response) */
+#define T3T_MSG_RSP_OFFSET_NUMSYS 9 /* Offset for Number of Systems */
+
+#define T3T_MSG_RSP_STATUS_OK 0x00
+#define T3T_MSG_RSP_STATUS_ERROR 0x01
+
+#define T3T_MSG_RSP_STATUS2_ERROR_MEMORY 0x70
+#define T3T_MSG_RSP_STATUS2_ERROR_EXCESSIVE_WRITES 0x71
+#define T3T_MSG_RSP_STATUS2_ERROR_PROCESSING 0xFF
+
+#define T3T_NFC_F_MAX_PAYLOAD_LEN 0xFE /* Maximum payload lenght for NFC-F messages (including SoD) */
+
+/* Felica Lite defintions */
+#define T3T_MSG_FELICALITE_BLOCK_ID_MC 0x88 /* Block ID for MC (memory configuration) */
+
+#define T3T_MSG_FELICALITE_MC_OFFSET_MC_SP 0x00 /* Memory Configuration Block offset: MC_SP (Memory Configuration for scratch pad) */
+#define T3T_MSG_FELICALITE_MC_OFFSET_MC_ALL 0x02 /* Memory Configuration Block offset: MC_ALL (Memory Configuration for system block) */
+#define T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP 0x03 /* Memory Configuration Block offset: SYS_OP (System Option) */
+#define T3T_MSG_FELICALITE_MC_OFFSET_RF_PRM 0x04 /* Memory Configuration Block offset: RF_PRM (Memory Configuration for RF Parameter) */
+
+
+
+/*
+**
+** 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
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#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
+#endif
+#define T4T_CMD_P1_SELECT_BY_NAME 0x04
+#define T4T_CMD_P1_SELECT_BY_FILE_ID 0x00
+#define T4T_CMD_P2_FIRST_OR_ONLY_00H 0x00
+#define T4T_CMD_P2_FIRST_OR_ONLY_0CH 0x0C
+
+#define T4T_MAX_LENGTH_LE 0xFF /* Max number of bytes to be read from file in ReadBinary Command */
+#define T4T_MAX_LENGTH_LC 0xFF /* Max number of bytes written to NDEF file in UpdateBinary Command */
+
+#define T4T_RSP_STATUS_WORDS_SIZE 0x02
+
+#define T4T_RSP_CMD_CMPLTED 0x9000
+#define T4T_RSP_NOT_FOUND 0x6A82
+#define T4T_RSP_WRONG_PARAMS 0x6B00
+#define T4T_RSP_CLASS_NOT_SUPPORTED 0x6E00
+#define T4T_RSP_WRONG_LENGTH 0x6700
+#define T4T_RSP_INSTR_NOT_SUPPORTED 0x6D00
+#define T4T_RSP_CMD_NOT_ALLOWED 0x6986
+
+#define T4T_V10_NDEF_TAG_AID_LEN 0x07 /* V1.0 Type 4 Tag Applicaiton ID length */
+#define T4T_V20_NDEF_TAG_AID_LEN 0x07 /* V2.0 Type 4 Tag Applicaiton ID length */
+
+#define T4T_MIN_MLE 0x000F /* Min of Max R-APDU data size */
+
+#define T4T_FILE_ID_SIZE 0x02
+#define T4T_CC_FILE_ID 0xE103
+#define T4T_CC_FILE_MIN_LEN 0x000F
+
+#define T4T_VERSION_OFFSET_IN_CC 0x02
+#define T4T_FC_TLV_OFFSET_IN_CC 0x07
+#define T4T_FC_WRITE_ACCESS_OFFSET_IN_TLV 0x07 /* Offset of Write access byte from type field in CC */
+
+#define T4T_NDEF_FILE_CONTROL_TYPE 0x04 /* NDEF File Control Type */
+#define T4T_PROP_FILE_CONTROL_TYPE 0x05 /* Proprietary File Control Type */
+
+#define T4T_FILE_CONTROL_TLV_SIZE 0x08 /* size of T(1),L(1),V(6) for file control */
+#define T4T_FILE_CONTROL_LENGTH 0x06 /* size of V(6) for file control */
+
+#define T4T_FC_READ_ACCESS 0x00 /* read access granted without any security */
+#define T4T_FC_WRITE_ACCESS 0x00 /* write access granted without any security */
+#define T4T_FC_NO_WRITE_ACCESS 0xFF /* no write access granted at all (read-only) */
+
+#define T4T_FILE_LENGTH_SIZE 0x02
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#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
+#endif
+
+/*
+**
+** ISO 15693 Tag Definitions
+**
+*/
+
+/* Request flags 1 to 4 definition */
+#define I93_FLAG_SUB_CARRIER_MASK 0x01 /* Sub_carrier_flag */
+#define I93_FLAG_SUB_CARRIER_SINGLE 0x00 /* A single sub-carrier frequency shall be used by VICC */
+#define I93_FLAG_SUB_CARRIER_DOUBLE 0x01 /* Two sub-carriers shall be used by VICC */
+
+#define I93_FLAG_DATA_RATE_MASK 0x02 /* Data_rate_flag */
+#define I93_FLAG_DATA_RATE_LOW 0x00 /* Low data rate shall be used */
+#define I93_FLAG_DATA_RATE_HIGH 0x02 /* High data rate shall be used */
+
+#define I93_FLAG_INVENTORY_MASK 0x04 /* Inventory_flag */
+#define I93_FLAG_INVENTORY_UNSET 0x00 /* Flags 5 to 8 meaning is according to table 4 */
+#define I93_FLAG_INVENTORY_SET 0x04 /* Flags 5 to 8 meaning is according to table 5 */
+
+#define I93_FLAG_PROT_EXT_MASK 0x08 /* Protocol_Extension_flag */
+#define I93_FLAG_PROT_EXT_NO 0x00 /* No protocol format extension */
+#define I93_FLAG_PROT_EXT_YES 0x08 /* Protocol format is extended. Reserved for future use */
+
+/* Request flags 5 to 6 definition when inventory flag is not set */
+#define I93_FLAG_SELECT_MASK 0x10 /* Select_flag */
+#define I93_FLAG_SELECT_UNSET 0x00 /* Request shall be executed by any VICC according to the setting of Address_flag */
+#define I93_FLAG_SELECT_SET 0x10 /* Request shall be executed only by VICC in selected state */
+ /* The Address_flag shall be set to 0 and the UID field shall bot be included in the request */
+
+#define I93_FLAG_ADDRESS_MASK 0x20 /* Address_flag */
+#define I93_FLAG_ADDRESS_UNSET 0x00 /* Request is not addressed. UID field is not included. It shall be executed by any VICC */
+#define I93_FLAG_ADDRESS_SET 0x20 /* Request is addressed. UID field is included. It shall be executed only by VICC */
+ /* whose UID matches the UID specified in the request */
+
+/* Request flags 5 to 6 definition when inventory flag is set */
+#define I93_FLAG_AFI_MASK 0x10 /* AFI_flag */
+#define I93_FLAG_AFI_NOT_PRESENT 0x00 /* AFI field is not present */
+#define I93_FLAG_AFI_PRESENT 0x10 /* AFI field is present */
+
+#define I93_FLAG_SLOT_MASK 0x20 /* Nb_slots_flag */
+#define I93_FLAG_SLOT_16 0x00 /* 16 slots */
+#define I93_FLAG_SLOT_ONE 0x20 /* 1 slot */
+
+/* Request flags 6 to 8 definition when inventory flag is set or not set */
+
+#define I93_FLAG_OPTION_MASK 0x40 /* Option_flag */
+#define I93_FLAG_OPTION_UNSET 0x00 /* Meaning is defined by the command description. */
+ /* It shall be set to 0 if not otherwise defined by command */
+#define I93_FLAG_OPTION_SET 0x40 /* Meaning is defined by the command description. */
+
+/* Response flags */
+#define I93_FLAG_ERROR_MASK 0x01 /* Error_flag */
+#define I93_FLAG_ERORR_NOT_DETECTED 0x00 /* No error */
+#define I93_FLAG_ERROR_DETECTED 0x01 /* Error detected, Error code is in the "Error" field */
+
+/* Response error code */
+#define I93_ERROR_CODE_NOT_SUPPORTED 0x01 /* The command is not supported, i.e. the request code is not recognized */
+#define I93_ERROR_CODE_NOT_RECOGNIZED 0x02 /* The command is not recognized, for example: a format error occured */
+#define I93_ERROR_CODE_OPTION_NOT_SUPPORTED 0x03 /* The command option is not supported */
+#define I93_ERROR_CODE_NO_INFO 0x0F /* Error with no information given or a specific error code is not supported */
+#define I93_ERROR_CODE_BLOCK_NOT_AVAILABLE 0x10 /* The specific block is not available (doesn't exist) */
+#define I93_ERROR_CODE_BLOCK_ALREADY_LOCKED 0x11 /* The specific block is already locked and thus cannot be locked again */
+#define I93_ERROR_CODE_BLOCK_LOCKED 0x12 /* The specific block is locked and its content cannot be changed */
+#define I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE 0x13 /* The specific block is was not successfully programmed */
+#define I93_ERROR_CODE_BLOCK_FAIL_TO_LOCK 0x14 /* The specific block is was not successfully locked */
+
+#define I93_UID_BYTE_LEN 8 /* UID length in bytes */
+#define I93_DFS_UNSUPPORTED 0x00 /* Data Storage Format is not supported */
+#define I93_BLOCK_UNLOCKED 0x00 /* Block is not locked */
+#define I93_BLOCK_LOCKED 0x01 /* Block is locked */
+
+/* ISO 15693 Mandatory commands */
+#define I93_CMD_INVENTORY 0x01 /* Inventory */
+#define I93_CMD_STAY_QUIET 0x02 /* Stay Quiet */
+
+/* ISO 15693 Optional commands */
+#define I93_CMD_READ_SINGLE_BLOCK 0x20 /* Read single block */
+#define I93_CMD_WRITE_SINGLE_BLOCK 0x21 /* Write single block */
+#define I93_CMD_LOCK_BLOCK 0x22 /* Lock block */
+#define I93_CMD_READ_MULTI_BLOCK 0x23 /* Read multiple blocks */
+#define I93_CMD_WRITE_MULTI_BLOCK 0x24 /* Write multiple blocks */
+#define I93_CMD_SELECT 0x25 /* Select */
+#define I93_CMD_RESET_TO_READY 0x26 /* Reset to ready */
+#define I93_CMD_WRITE_AFI 0x27 /* Wreite AFI */
+#define I93_CMD_LOCK_AFI 0x28 /* Lock AFI */
+#define I93_CMD_WRITE_DSFID 0x29 /* Write DSFID */
+#define I93_CMD_LOCK_DSFID 0x2A /* Lock DSFID */
+#define I93_CMD_GET_SYS_INFO 0x2B /* Get system information */
+#define I93_CMD_GET_MULTI_BLK_SEC 0x2C /* Get multiple block security status */
+
+/* Information flags definition */
+#define I93_INFO_FLAG_DSFID 0x01 /* DSFID is supported and DSFID field is present */
+#define I93_INFO_FLAG_AFI 0x02 /* AFI is supported and AFI field is present */
+#define I93_INFO_FLAG_MEM_SIZE 0x04 /* VICC memory size field is present */
+#define I93_INFO_FLAG_IC_REF 0x08 /* IC reference field is present */
+
+#define I93_MAX_BLOCK_LENGH 32 /* Max block size in bytes */
+#define I93_MAX_NUM_BLOCK 256 /* Max number of blocks */
+
+/* ICODE Capability Container(CC) definition */
+#define I93_ICODE_CC_MAGIC_NUMER 0xE1 /* magic number in CC[0] */
+#define I93_ICODE_CC_MAJOR_VER_MASK 0xC0 /* major version in CC[1] */
+#define I93_ICODE_CC_MINOR_VER_MASK 0x30 /* minor version in CC[1] */
+#define I93_ICODE_CC_READ_ACCESS_MASK 0x0C /* read access condition in CC[1] */
+#define I93_ICODE_CC_READ_ACCESS_GRANTED 0x00 /* read access granted without security */
+#define I93_ICODE_CC_WRITE_ACCESS_MASK 0x03 /* write access condition in CC[1] */
+#define I93_ICODE_CC_WRITE_ACCESS_GRANTED 0x00 /* write access granted without security */
+#define I93_ICODE_CC_READ_ONLY 0x03 /* write access not granted at all */
+#define I93_ICODE_CC_MBREAD_MASK 0x01 /* read multi block supported in CC[3] */
+#define I93_ICODE_CC_IPREAD_MASK 0x02 /* inventory page read supported in CC[3] */
+#define I93_STM_CC_OVERFLOW_MASK 0x04 /* More than 2040 bytes are supported in CC[3] */
+
+/* ICODE TLV type */
+#define I93_ICODE_TLV_TYPE_NULL 0x00 /* NULL TLV */
+#define I93_ICODE_TLV_TYPE_NDEF 0x03 /* NDEF message TLV */
+#define I93_ICODE_TLV_TYPE_PROP 0xFD /* Proprietary TLV */
+#define I93_ICODE_TLV_TYPE_TERM 0xFE /* Terminator TLV */
+
+/* UID Coding (UID Bit 64-57), First byte of ISO 15693 UID */
+#define I93_UID_FIRST_BYTE 0xE0
+
+/* UID Coding (UID Bit 56-49), IC manufacturer code */
+#define I93_UID_IC_MFG_CODE_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) */
+#define I93_UID_ICODE_SLI 0x01 /* ICODE SLI, SLIX */
+#define I93_UID_ICODE_SLI_S 0x02 /* ICODE SLI-S, SLIX-S */
+#define I93_UID_ICODE_SLI_L 0x03 /* ICODE SLI-L, SLIX-L */
+
+#define I93_IC_REF_ICODE_SLI_L 0x03 /* IC Reference for ICODE SLI-L */
+#define I93_ICODE_IC_REF_MBREAD_MASK 0x02 /* read multi block supported check bit */
+
+/* TI, UID Coding of product version (UID Bit 48-42) */
+#define I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK 0xFE /* upper 7 bits */
+#define I93_UID_TAG_IT_HF_I_PLUS_INLAY 0x00 /* Tag-it HF-I Plus Inlay */
+#define I93_UID_TAG_IT_HF_I_PLUS_CHIP 0x80 /* Tag-it HF-I Plus Chip */
+#define I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY 0xC0 /* Tag-it HF-I Standard Chip/Inlyas */
+#define I93_UID_TAG_IT_HF_I_PRO_CHIP_INLAY 0xC4 /* Tag-it HF-I Pro Chip/Inlyas */
+
+#define I93_TAG_IT_HF_I_STD_CHIP_INLAY_NUM_TOTAL_BLK 11
+#define I93_TAG_IT_HF_I_PRO_CHIP_INLAY_NUM_TOTAL_BLK 12
+
+#define I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_BLK_SIZE 4
+#define I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_NUM_USER_BLK 8
+#define I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION 40 /* LSB in Block 0x0A */
+
+/* STM, product version (IC manufacturer code) */
+#define I93_IC_REF_STM_MASK 0xFC /* IC Reference mask for STM */
+#define I93_IC_REF_STM_LRI1K 0x40 /* IC Reference for LRI1K: 010000xx(b), blockSize: 4, numberBlocks: 0x20 */
+#define I93_IC_REF_STM_LRI2K 0x20 /* IC Reference for LRI2K: 001000xx(b), blockSize: 4, numberBlocks: 0x40 */
+#define I93_IC_REF_STM_LRIS2K 0x28 /* IC Reference for LRIS2K: 001010xx(b), blockSize: 4, numberBlocks: 0x40 */
+#define I93_IC_REF_STM_LRIS64K 0x44 /* IC Reference for LRIS64K: 010001xx(b), blockSize: 4, numberBlocks: 0x800 */
+#define I93_IC_REF_STM_M24LR64_R 0x2C /* IC Reference for M24LR64-R: 001011xx(b), blockSize: 4, numberBlocks: 0x800 */
+#define I93_IC_REF_STM_M24LR04E_R 0x5A /* IC Reference for M24LR04E-R: 01011010(b), blockSize: 4, numberBlocks: 0x80 */
+#define I93_IC_REF_STM_M24LR16E_R 0x4E /* IC Reference for M24LR16E-R: 01001110(b), blockSize: 4, numberBlocks: 0x200 */
+#define I93_IC_REF_STM_M24LR64E_R 0x5E /* IC Reference for M24LR64E-R: 01011110(b), blockSize: 4, numberBlocks: 0x800 */
+
+#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..9f4efe2
--- /dev/null
+++ b/src/nfc/int/ce_int.h
@@ -0,0 +1,174 @@
+/******************************************************************************
+ *
+ * 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
+
+#define CE_MAX_BYTE_PER_PAGE 7 /* 2^8=256. CB use UINT8 for BytesPerPage, so max is 7 */
+
+/* CE Type 3 Tag structures */
+
+/* Type 3 Tag NDEF card-emulation */
+typedef struct {
+ BOOLEAN initialized;
+ UINT8 version; /* Ver: peer version */
+ UINT8 nbr; /* NBr: number of blocks that can be read using one Check command */
+ UINT8 nbw; /* Nbw: number of blocks that can be written using one Update command */
+ UINT16 nmaxb; /* Nmaxb: maximum number of blocks available for NDEF data */
+ UINT8 writef; /* WriteFlag: 00h if writing data finished; 0Fh if writing data in progress */
+ UINT8 rwflag; /* RWFlag: 00h NDEF is read-only; 01h if read/write available */
+ UINT32 ln;
+ UINT8 *p_buf; /* Current contents for READs */
+
+ /* Scratch NDEF buffer (for update NDEF commands) */
+ UINT8 scratch_writef;
+ UINT32 scratch_ln;
+ UINT8 *p_scratch_buf; /* Scratch buffer for WRITE/readback */
+} tCE_T3T_NDEF_INFO;
+
+/* Type 3 Tag current command processing */
+typedef struct {
+ UINT16 service_code_list[T3T_MSG_SERVICE_LIST_MAX];
+ UINT8 *p_block_list_start;
+ UINT8 *p_block_data_start;
+ UINT8 num_services;
+ UINT8 num_blocks;
+} tCE_T3T_CUR_CMD;
+
+/* Type 3 Tag control blcok */
+typedef struct
+{
+ UINT8 state;
+ UINT16 system_code;
+ UINT8 local_nfcid2[NCI_RF_F_UID_LEN];
+ UINT8 local_pmm[NCI_T3T_PMM_LEN];
+ tCE_T3T_NDEF_INFO ndef_info;
+ tCE_T3T_CUR_CMD cur_cmd;
+} tCE_T3T_MEM;
+
+/* CE Type 4 Tag control blocks */
+typedef struct
+{
+ UINT8 aid_len;
+ UINT8 aid[NFC_MAX_AID_LEN];
+ tCE_CBACK *p_cback;
+} tCE_T4T_REG_AID; /* registered AID table */
+
+typedef struct
+{
+ TIMER_LIST_ENT timer; /* timeout for update file */
+ UINT8 cc_file[T4T_FC_TLV_OFFSET_IN_CC + T4T_FILE_CONTROL_TLV_SIZE];
+ UINT8 *p_ndef_msg; /* storage of NDEF message */
+ UINT16 nlen; /* current size of NDEF message */
+ UINT16 max_file_size; /* size of storage + 2 bytes for NLEN */
+ UINT8 *p_scratch_buf; /* temp storage of NDEF message for update */
+
+#define CE_T4T_STATUS_T4T_APP_SELECTED 0x01 /* T4T CE App is selected */
+#define CE_T4T_STATUS_REG_AID_SELECTED 0x02 /* Registered AID is selected */
+#define CE_T4T_STATUS_CC_FILE_SELECTED 0x04 /* CC file is selected */
+#define CE_T4T_STATUS_NDEF_SELECTED 0x08 /* NDEF file is selected */
+#define CE_T4T_STATUS_NDEF_FILE_READ_ONLY 0x10 /* NDEF is read-only */
+#define CE_T4T_STATUS_NDEF_FILE_UPDATING 0x20 /* NDEF is updating */
+#define CE_T4T_STATUS_WILDCARD_AID_SELECTED 0x40 /* Wildcard AID selected */
+
+ UINT8 status;
+
+ tCE_CBACK *p_wildcard_aid_cback; /* registered wildcard AID callback */
+ tCE_T4T_REG_AID reg_aid[CE_T4T_MAX_REG_AID]; /* registered AID table */
+ UINT8 selected_aid_idx;
+} tCE_T4T_MEM;
+
+
+/* CE memory control blocks */
+typedef struct
+{
+ tCE_T3T_MEM t3t;
+ tCE_T4T_MEM t4t;
+} tCE_MEM;
+
+/* CE control blocks */
+typedef struct
+{
+ tCE_MEM mem;
+ tCE_CBACK *p_cback;
+ UINT8 *p_ndef; /* the memory starting from NDEF */
+ UINT16 ndef_max; /* max size of p_ndef */
+ UINT16 ndef_cur; /* current size of p_ndef */
+ tNFC_RF_TECH tech;
+ UINT8 trace_level;
+
+} tCE_CB;
+
+/*
+** CE Type 4 Tag Definition
+*/
+
+/* Max data size using a single ReadBinary. 2 bytes are for status bytes */
+#define CE_T4T_MAX_LE (NFC_CE_POOL_BUF_SIZE - BT_HDR_SIZE - NCI_MSG_OFFSET_SIZE - NCI_DATA_HDR_SIZE - T4T_RSP_STATUS_WORDS_SIZE)
+
+/* Max data size using a single UpdateBinary. 6 bytes are for CLA, INS, P1, P2, Lc */
+#define CE_T4T_MAX_LC (NFC_CE_POOL_BUF_SIZE - BT_HDR_SIZE - NCI_DATA_HDR_SIZE - T4T_CMD_MAX_HDR_SIZE)
+
+/*****************************************************************************
+** EXTERNAL FUNCTION DECLARATIONS
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Global NFC data */
+#if NFC_DYNAMIC_MEMORY == FALSE
+NFC_API extern tCE_CB ce_cb;
+#else
+NFC_API extern tCE_CB *ce_cb_ptr;
+#define ce_cb (*ce_cb_ptr)
+#endif
+
+extern void ce_init (void);
+
+/* ce_t3t internal functions */
+void ce_t3t_init (void);
+tNFC_STATUS ce_select_t3t (UINT16 system_code, UINT8 nfcid2[NCI_RF_F_UID_LEN]);
+
+/* ce_t4t internal functions */
+extern tNFC_STATUS ce_select_t4t (void);
+extern void ce_t4t_process_timeout (TIMER_LIST_ENT *p_tle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CE_INT_H_ */
diff --git a/src/nfc/int/llcp_int.h b/src/nfc/int/llcp_int.h
new file mode 100644
index 0000000..f511084
--- /dev/null
+++ b/src/nfc/int/llcp_int.h
@@ -0,0 +1,381 @@
+/******************************************************************************
+ *
+ * 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 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
+*/
+#define LLCP_LINK_FLAGS_RX_ANY_LLC_PDU 0x01 /* Received any LLC PDU in activated state */
+
+/*
+** LLCP link control block
+*/
+typedef struct
+{
+ tLLCP_LINK_STATE link_state; /* llcp link state */
+ tLLCP_LINK_CBACK *p_link_cback; /* callback function to report llcp link status */
+ UINT16 wks; /* well-known service bit-map */
+
+ BOOLEAN is_initiator; /* TRUE if initiator role */
+ BOOLEAN is_sending_data; /* TRUE if llcp_link_check_send_data() is excuting */
+ UINT8 flags; /* LLCP internal flags */
+ BOOLEAN received_first_packet; /* TRUE if a packet has been received from remote */
+ UINT8 agreed_major_version; /* llcp major version used in activated state */
+ UINT8 agreed_minor_version; /* llcp minor version used in activated state */
+
+ UINT8 peer_version; /* llcp version of peer device */
+ UINT16 peer_miu; /* link MIU of peer device */
+ UINT16 peer_wks; /* WKS of peer device */
+ UINT16 peer_lto; /* link timeout of peer device in ms */
+ UINT8 peer_opt; /* Option field of peer device */
+ UINT16 effective_miu; /* MIU to send PDU in activated state */
+
+ TIMER_LIST_ENT timer; /* link timer for LTO and SYMM response */
+ UINT8 symm_state; /* state of symmectric procedure */
+ BOOLEAN ll_served; /* TRUE if last transmisstion was for UI */
+ UINT8 ll_idx; /* for scheduler of logical link connection */
+ UINT8 dl_idx; /* for scheduler of data link connection */
+
+ TIMER_LIST_ENT inact_timer; /* inactivity timer */
+ UINT16 inact_timeout; /* inactivity timeout in ms */
+
+ UINT8 link_deact_reason; /* reason of LLCP link deactivated */
+
+ BUFFER_Q sig_xmit_q; /* tx signaling PDU queue */
+
+ /* runtime configuration parameters */
+ UINT16 local_link_miu; /* Maximum Information Unit */
+ UINT8 local_opt; /* Option parameter */
+ UINT8 local_wt; /* Response Waiting Time Index */
+ UINT16 local_lto; /* Local Link Timeout */
+ UINT16 inact_timeout_init; /* Inactivity Timeout as initiator role */
+ UINT16 inact_timeout_target; /* Inactivity Timeout as target role */
+ UINT16 symm_delay; /* Delay SYMM response */
+ UINT16 data_link_timeout; /* data link conneciton timeout */
+ UINT16 delay_first_pdu_timeout;/* delay timeout to send first PDU as initiator */
+} tLLCP_LCB;
+
+/*
+** LLCP Application's registration control block on service access point (SAP)
+*/
+
+typedef struct
+{
+ UINT8 link_type; /* logical link and/or data link */
+ UINT8 *p_service_name; /* GKI buffer containing service name */
+ tLLCP_APP_CBACK *p_app_cback; /* application's callback pointer */
+
+ BUFFER_Q ui_xmit_q; /* UI PDU queue for transmitting */
+ BUFFER_Q ui_rx_q; /* UI PDU queue for receiving */
+ BOOLEAN is_ui_tx_congested; /* TRUE if transmitting UI PDU is congested */
+
+} tLLCP_APP_CB;
+
+/*
+** LLCP data link connection states
+*/
+enum
+{
+ LLCP_DLC_STATE_IDLE, /* initial state */
+ LLCP_DLC_STATE_W4_REMOTE_RESP, /* waiting for connection confirm from peer */
+ LLCP_DLC_STATE_W4_LOCAL_RESP, /* waiting for connection confirm from upper layer */
+ LLCP_DLC_STATE_CONNECTED, /* data link connection has been established */
+ LLCP_DLC_STATE_W4_REMOTE_DM, /* waiting for disconnection confirm from peer */
+ LLCP_DLC_STATE_MAX
+};
+typedef UINT8 tLLCP_DLC_STATE;
+
+/*
+** LLCP data link connection events
+*/
+enum
+{
+ LLCP_DLC_EVENT_API_CONNECT_REQ, /* connection request from upper layer */
+ LLCP_DLC_EVENT_API_CONNECT_CFM, /* connection confirm from upper layer */
+ LLCP_DLC_EVENT_API_CONNECT_REJECT, /* connection reject from upper layer */
+ LLCP_DLC_EVENT_PEER_CONNECT_IND, /* connection request from peer */
+ LLCP_DLC_EVENT_PEER_CONNECT_CFM, /* connection confirm from peer */
+
+ LLCP_DLC_EVENT_API_DATA_REQ, /* data packet from upper layer */
+ LLCP_DLC_EVENT_PEER_DATA_IND, /* data packet from peer */
+
+ LLCP_DLC_EVENT_API_DISCONNECT_REQ, /* disconnect request from upper layer */
+ LLCP_DLC_EVENT_PEER_DISCONNECT_IND, /* disconnect request from peer */
+ LLCP_DLC_EVENT_PEER_DISCONNECT_RESP, /* disconnect response from peer */
+
+ LLCP_DLC_EVENT_FRAME_ERROR, /* received erroneous frame from peer */
+ LLCP_DLC_EVENT_LINK_ERROR, /* llcp link has been deactivated */
+
+ LLCP_DLC_EVENT_TIMEOUT /* timeout event */
+};
+typedef UINT8 tLLCP_DLC_EVENT;
+
+/*
+** LLCP data link connection control block
+*/
+
+#define LLCP_DATA_LINK_FLAG_PENDING_DISC 0x01 /* send DISC when tx queue is empty */
+#define LLCP_DATA_LINK_FLAG_PENDING_RR_RNR 0x02 /* send RR/RNR with valid sequence */
+#define LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE 0x04 /* notify upper later when tx complete */
+
+
+typedef struct
+{
+ tLLCP_DLC_STATE state; /* data link connection state */
+ UINT8 flags; /* specific action flags */
+ tLLCP_APP_CB *p_app_cb; /* pointer of application registration */
+ TIMER_LIST_ENT timer; /* timer for connection complete */
+
+ UINT8 local_sap; /* SAP of local end point */
+ UINT16 local_miu; /* MIU of local SAP */
+ UINT8 local_rw; /* RW of local SAP */
+ BOOLEAN local_busy; /* TRUE if local SAP is busy */
+
+ UINT8 remote_sap; /* SAP of remote end point */
+ UINT16 remote_miu; /* MIU of remote SAP */
+ UINT8 remote_rw; /* RW of remote SAP */
+ BOOLEAN remote_busy; /* TRUE if remote SAP is busy */
+
+ UINT8 next_tx_seq; /* V(S), send state variable */
+ UINT8 rcvd_ack_seq; /* V(SA), send ack state variable */
+ UINT8 next_rx_seq; /* V(R), receive state variable */
+ UINT8 sent_ack_seq; /* V(RA), receive ack state variable */
+
+ BUFFER_Q i_xmit_q; /* tx queue of I PDU */
+ BOOLEAN is_tx_congested; /* TRUE if tx I PDU is congested */
+
+ BUFFER_Q i_rx_q; /* rx queue of I PDU */
+ BOOLEAN is_rx_congested; /* TRUE if rx I PDU is congested */
+ UINT8 num_rx_i_pdu; /* number of I PDU in rx queue */
+ UINT8 rx_congest_threshold; /* dynamic congest threshold for rx I PDU */
+
+} tLLCP_DLCB;
+
+/*
+** LLCP service discovery control block
+*/
+
+typedef struct
+{
+ UINT8 tid; /* transaction ID */
+ tLLCP_SDP_CBACK *p_cback; /* callback function for service discovery */
+} tLLCP_SDP_TRANSAC;
+
+typedef struct
+{
+ UINT8 next_tid; /* next TID to use */
+ tLLCP_SDP_TRANSAC transac[LLCP_MAX_SDP_TRANSAC]; /* active SDP transactions */
+ BT_HDR *p_snl; /* buffer for SNL PDU */
+} tLLCP_SDP_CB;
+
+
+/*
+** LLCP control block
+*/
+
+typedef struct
+{
+ UINT8 trace_level; /* LLCP trace level */
+
+ tLLCP_SDP_CB sdp_cb; /* SDP control block */
+ tLLCP_LCB lcb; /* LLCP link control block */
+ tLLCP_APP_CB wks_cb[LLCP_MAX_WKS]; /* Application's registration for well-known services */
+ tLLCP_APP_CB server_cb[LLCP_MAX_SERVER]; /* Application's registration for SDP services */
+ tLLCP_APP_CB client_cb[LLCP_MAX_CLIENT]; /* Application's registration for client */
+ tLLCP_DLCB dlcb[LLCP_MAX_DATA_LINK]; /* Data link connection control block */
+
+ UINT8 max_num_ll_tx_buff; /* max number of tx UI PDU in queue */
+ UINT8 max_num_tx_buff; /* max number of tx UI/I PDU in queue */
+
+ UINT8 num_logical_data_link; /* number of logical data link */
+ UINT8 num_data_link_connection; /* number of established data link connection */
+
+ /* these two thresholds (number of tx UI PDU) are dynamically adjusted based on number of logical links */
+ UINT8 ll_tx_congest_start; /* congest start threshold for each logical link*/
+ UINT8 ll_tx_congest_end; /* congest end threshold for each logical link */
+
+ UINT8 total_tx_ui_pdu; /* total number of tx UI PDU in all of ui_xmit_q*/
+ UINT8 total_tx_i_pdu; /* total number of tx I PDU in all of i_xmit_q */
+ BOOLEAN overall_tx_congested; /* TRUE if tx link is congested */
+
+ /* start point of uncongested status notification is in round robin */
+ UINT8 ll_tx_uncongest_ntf_start_sap; /* next start of logical data link */
+ UINT8 dl_tx_uncongest_ntf_start_idx; /* next start of data link connection */
+
+ /*
+ ** when overall rx link congestion starts, RNR is sent to remote end point of data link connection
+ ** while rx link is congested, UI PDU is discarded.
+ */
+ UINT8 num_rx_buff; /* reserved number of rx UI/I PDU in queue */
+ UINT8 overall_rx_congest_start; /* threshold of overall rx congestion start */
+ UINT8 overall_rx_congest_end; /* threshold of overall rx congestion end */
+ UINT8 max_num_ll_rx_buff; /* max number of rx UI PDU in queue */
+
+ /*
+ ** threshold (number of rx UI PDU) is dynamically adjusted based on number of logical links
+ ** when number of rx UI PDU is more than ll_rx_congest_start, the oldest UI PDU is discarded
+ */
+ UINT8 ll_rx_congest_start; /* rx congest start threshold for each logical link */
+
+ UINT8 total_rx_ui_pdu; /* total number of rx UI PDU in all of ui_rx_q */
+ UINT8 total_rx_i_pdu; /* total number of rx I PDU in all of i_rx_q */
+ BOOLEAN overall_rx_congested; /* TRUE if overall rx link is congested */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ tLLCP_DTA_CBACK *p_dta_cback; /* callback to notify DTA when respoding SNL */
+ BOOLEAN dta_snl_resp; /* TRUE if need to notify DTA when respoding SNL*/
+#endif
+} tLLCP_CB;
+
+#if (LLCP_TEST_INCLUDED == TRUE) /* this is for LLCP testing */
+
+typedef struct {
+ UINT8 version;
+ UINT16 wks;
+} tLLCP_TEST_PARAMS;
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+** LLCP global data
+*/
+
+#if (!defined LLCP_DYNAMIC_MEMORY) || (LLCP_DYNAMIC_MEMORY == FALSE)
+LLCP_API extern tLLCP_CB llcp_cb;
+#else
+LLCP_API extern tLLCP_CB *llcp_cb_ptr;
+#define llcp_cb (*llcp_cb_ptr)
+#endif
+
+/*
+** Functions provided by llcp_main.c
+*/
+void llcp_init (void);
+void llcp_cleanup (void);
+void llcp_process_timeout (TIMER_LIST_ENT *p_tle);
+
+/*
+** Functions provided by llcp_link.c
+*/
+tLLCP_STATUS llcp_link_activate (tLLCP_ACTIVATE_CONFIG *p_config);
+void llcp_link_process_link_timeout (void);
+void llcp_link_deactivate (UINT8 reason);
+
+void llcp_link_check_send_data (void);
+void llcp_link_connection_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data);
+
+/*
+** Functions provided by llcp_util.c
+*/
+void llcp_util_adjust_ll_congestion (void);
+void llcp_util_adjust_dl_rx_congestion (void);
+void llcp_util_check_rx_congested_status (void);
+BOOLEAN llcp_util_parse_link_params (UINT16 length, UINT8 *p_bytes);
+tLLCP_STATUS llcp_util_send_ui (UINT8 ssap, UINT8 dsap, tLLCP_APP_CB *p_app_cb, BT_HDR *p_msg);
+void llcp_util_send_disc (UINT8 dsap, UINT8 ssap);
+tLLCP_DLCB *llcp_util_allocate_data_link (UINT8 reg_sap, UINT8 remote_sap);
+void llcp_util_deallocate_data_link (tLLCP_DLCB *p_dlcb);
+tLLCP_STATUS llcp_util_send_connect (tLLCP_DLCB *p_dlcb, tLLCP_CONNECTION_PARAMS *p_params);
+tLLCP_STATUS llcp_util_parse_connect (UINT8 *p_bytes, UINT16 length, tLLCP_CONNECTION_PARAMS *p_params);
+tLLCP_STATUS llcp_util_send_cc (tLLCP_DLCB *p_dlcb, tLLCP_CONNECTION_PARAMS *p_params);
+tLLCP_STATUS llcp_util_parse_cc (UINT8 *p_bytes, UINT16 length, UINT16 *p_miu, UINT8 *p_rw);
+void llcp_util_send_dm (UINT8 dsap, UINT8 ssap, UINT8 reason);
+void llcp_util_build_info_pdu (tLLCP_DLCB *p_dlcb, BT_HDR *p_msg);
+tLLCP_STATUS llcp_util_send_frmr (tLLCP_DLCB *p_dlcb, UINT8 flags, UINT8 ptype, UINT8 sequence);
+void llcp_util_send_rr_rnr (tLLCP_DLCB *p_dlcb);
+tLLCP_APP_CB *llcp_util_get_app_cb (UINT8 sap);
+/*
+** Functions provided by llcp_dlc.c
+*/
+tLLCP_STATUS llcp_dlsm_execute (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data);
+tLLCP_DLCB *llcp_dlc_find_dlcb_by_sap (UINT8 local_sap, UINT8 remote_sap);
+void llcp_dlc_flush_q (tLLCP_DLCB *p_dlcb);
+void llcp_dlc_proc_i_pdu (UINT8 dsap, UINT8 ssap, UINT16 i_pdu_length, UINT8 *p_i_pdu, BT_HDR *p_msg);
+void llcp_dlc_proc_rx_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, UINT16 length, UINT8 *p_data);
+void llcp_dlc_check_to_send_rr_rnr (void);
+BOOLEAN llcp_dlc_is_rw_open (tLLCP_DLCB *p_dlcb);
+BT_HDR *llcp_dlc_get_next_pdu (tLLCP_DLCB *p_dlcb);
+UINT16 llcp_dlc_get_next_pdu_length (tLLCP_DLCB *p_dlcb);
+
+/*
+** Functions provided by llcp_sdp.c
+*/
+void llcp_sdp_proc_data (tLLCP_SAP_CBACK_DATA *p_data);
+tLLCP_STATUS llcp_sdp_send_sdreq (UINT8 tid, char *p_name);
+UINT8 llcp_sdp_get_sap_by_name (char *p_name, UINT8 length);
+tLLCP_STATUS llcp_sdp_proc_snl (UINT16 sdu_length, UINT8 *p);
+void llcp_sdp_check_send_snl (void);
+void llcp_sdp_proc_deactivation (void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/nfc/int/nfc_int.h b/src/nfc/int/nfc_int.h
new file mode 100644
index 0000000..8dabe9b
--- /dev/null
+++ b/src/nfc/int/nfc_int.h
@@ -0,0 +1,355 @@
+/******************************************************************************
+ *
+ * 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"
+#include "btu_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/****************************************************************************
+** Internal NFC constants and definitions
+****************************************************************************/
+
+/****************************************************************************
+** NFC_TASK definitions
+****************************************************************************/
+
+/* NFC_TASK event masks */
+#define NFC_TASK_EVT_TRANSPORT_READY EVENT_MASK (APPL_EVT_0)
+
+/* NFC Timer events */
+#define NFC_TTYPE_NCI_WAIT_RSP 0
+#define NFC_TTYPE_WAIT_2_DEACTIVATE 1
+#define NFC_TTYPE_NCI_WAIT_DATA_NTF 2
+#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
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define NFC_TTYPE_P2P_PRIO_RESPONSE 110 /* added for p2p prio logic timer */
+#define NFC_TTYPE_LISTEN_ACTIVATION 111 /* added for listen activation timer */
+#define NFC_TTYPE_P2P_PRIO_LOGIC_CLEANUP 112 /* added for p2p prio logic clenaup */
+#endif
+#define NFC_TTYPE_VS_BASE 200
+
+
+/* NFC Task event messages */
+
+enum
+{
+ NFC_STATE_NONE, /* not start up yet */
+ NFC_STATE_W4_HAL_OPEN, /* waiting for HAL_NFC_OPEN_CPLT_EVT */
+ NFC_STATE_CORE_INIT, /* sending CORE_RESET and CORE_INIT */
+ NFC_STATE_W4_POST_INIT_CPLT, /* waiting for HAL_NFC_POST_INIT_CPLT_EVT */
+ NFC_STATE_IDLE, /* normal operation (discovery state) */
+ NFC_STATE_OPEN, /* NFC link is activated */
+ NFC_STATE_CLOSING, /* de-activating */
+ NFC_STATE_W4_HAL_CLOSE, /* waiting for HAL_NFC_POST_INIT_CPLT_EVT */
+ NFC_STATE_NFCC_POWER_OFF_SLEEP /* NFCC is power-off sleep mode */
+};
+typedef UINT8 tNFC_STATE;
+enum
+{
+ I2C_FRAGMENATATION_ENABLED, /*i2c fragmentation_enabled */
+ I2C_FRAGMENTATION_DISABLED /*i2c_fragmentation_disabled */
+};
+/* NFC control block flags */
+#define NFC_FL_DEACTIVATING 0x0001 /* NFC_Deactivate () is called and the NCI cmd is not sent */
+#define NFC_FL_RESTARTING 0x0002 /* restarting NFCC after PowerOffSleep */
+#define NFC_FL_POWER_OFF_SLEEP 0x0004 /* enterning power off sleep mode */
+#define NFC_FL_POWER_CYCLE_NFCC 0x0008 /* Power cycle NFCC */
+#define NFC_FL_CONTROL_REQUESTED 0x0010 /* HAL requested control on NCI command window */
+#define NFC_FL_CONTROL_GRANTED 0x0020 /* NCI command window is on the HAL side */
+#define NFC_FL_DISCOVER_PENDING 0x0040 /* NCI command window is on the HAL side */
+#define NFC_FL_HAL_REQUESTED 0x0080 /* NFC_FL_CONTROL_REQUESTED on HAL request */
+
+#define NFC_PEND_CONN_ID 0xFE
+#define NFC_CONN_ID_INT_MASK 0xF0
+#define NFC_CONN_ID_ID_MASK NCI_CID_MASK
+#define NFC_CONN_NO_FC 0xFF /* set num_buff to this for no flow control */
+#define NFC_NCI_CONN_NO_FC 0xFF
+
+#if (NFC_RW_ONLY == FALSE)
+/* only allow the entries that the NFCC can support */
+#define NFC_CHECK_MAX_CONN() {if (max > nfc_cb.max_conn) max = nfc_cb.max_conn;}
+#else
+#define NFC_CHECK_MAX_CONN()
+#endif
+
+typedef struct
+{
+ tNFC_CONN_CBACK *p_cback; /* the callback function to receive the data */
+ BUFFER_Q tx_q; /* transmit queue */
+ BUFFER_Q rx_q; /* receive queue */
+ UINT8 id; /* NFCEE ID or RF Discovery ID or NFC_TEST_ID */
+ UINT8 act_protocol; /* the active protocol on this logical connection */
+ UINT8 conn_id; /* the connection id assigned by NFCC for this conn */
+ UINT8 buff_size; /* the max buffer size for this connection. . */
+ UINT8 num_buff; /* num of buffers left to send on this connection */
+ UINT8 init_credits; /* initial num of buffer credits */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ UINT8 act_interface; /* the active interface on this logical i=connetion */
+ UINT8 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
+{
+ BT_HDR bt_hdr; /* the NCI command */
+ tNFC_VS_CBACK *p_cback; /* the callback function to receive RSP */
+} tNFC_NCI_VS_MSG;
+
+/* This data type is for HAL event */
+typedef struct
+{
+ BT_HDR hdr;
+ UINT8 hal_evt; /* HAL event code */
+ UINT8 status; /* tHAL_NFC_STATUS */
+} tNFC_HAL_EVT_MSG;
+
+#define NFC_RECEIVE_MSGS_OFFSET (10) /* callback function pointer(8; use 8 to be safe + NFC_SAVED_CMD_SIZE(2) */
+
+/* NFCC power state change pending callback */
+typedef void (tNFC_PWR_ST_CBACK) (void);
+#define NFC_SAVED_HDR_SIZE (2)
+/* data Reassembly error (in BT_HDR.layer_specific) */
+#define NFC_RAS_TOO_BIG 0x08
+#define NFC_RAS_FRAGMENTED 0x01
+
+/* NCI command buffer contains a VSC (in BT_HDR.layer_specific) */
+#define NFC_WAIT_RSP_VSC 0x01
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define NFC_WAIT_RSP_NXP 0x02
+#endif
+
+typedef struct
+{
+ UINT8 data_ntf_timeout; /* indicates credit ntf timeout occured */
+ UINT8 nci_cmd_channel_busy; /* indicates to the data queue that cmd is sent */
+ UINT8 data_stored; /* indicates data is stored to be sent later */
+ UINT8 conn_id; /* stores the conn_id of the data stored */
+}i2c_data;
+
+/* NFC control blocks */
+typedef struct
+{
+ UINT16 flags; /* NFC control block flags - NFC_FL_* */
+ tNFC_CONN_CB conn_cb[NCI_MAX_CONN_CBS];
+ UINT8 conn_id[NFC_MAX_CONN_ID+1]; /* index: conn_id; conn_id[]: index(1 based) to conn_cb[] */
+ tNFC_DISCOVER_CBACK *p_discv_cback;
+ tNFC_RESPONSE_CBACK *p_resp_cback;
+ tNFC_TEST_CBACK *p_test_cback;
+ tNFC_VS_CBACK *p_vs_cb[NFC_NUM_VS_CBACKS];/* Register for vendor specific events */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ UINT8 nxpCbflag;
+#endif
+
+#if (NFC_RW_ONLY == FALSE)
+ /* NFCC information at init rsp */
+ UINT32 nci_features; /* the NCI features supported by NFCC */
+ UINT16 max_ce_table; /* the max routing table size */
+ UINT8 max_conn; /* the num of connections supported by NFCC */
+#endif
+ UINT8 nci_ctrl_size; /* Max Control Packet Payload Size */
+
+ const tNCI_DISCOVER_MAPS *p_disc_maps; /* NCI RF Discovery interface mapping */
+ UINT8 vs_interface[NFC_NFCC_MAX_NUM_VS_INTERFACE]; /* the NCI VS interfaces of NFCC */
+ UINT16 nci_interfaces; /* the NCI interfaces of NFCC */
+ UINT8 num_disc_maps; /* number of RF Discovery interface mappings */
+ void *p_disc_pending; /* the parameters associated with pending NFC_DiscoveryStart */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 */
+
+ tNFC_STATE nfc_state;
+ BOOLEAN reassembly; /* Reassemble fragmented data pkt */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ tNFC_STATE old_nfc_state;
+#endif
+ UINT8 trace_level;
+ UINT8 last_hdr[NFC_SAVED_HDR_SIZE];/* part of last NCI command header */
+ UINT8 last_cmd[NFC_SAVED_CMD_SIZE];/* part of last NCI command payload */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ UINT8 *last_cmd_buf;
+ UINT8 cmd_size;
+#endif
+ void *p_vsc_cback; /* the callback function for last VSC command */
+ BUFFER_Q nci_cmd_xmit_q; /* NCI command queue */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ BUFFER_Q nci_cmd_recov_xmit_q; /* NCI recovery command queue */
+ TIMER_LIST_ENT listen_activation_timer_list; /* Timer for monitoring listen activation */
+#endif
+ TIMER_LIST_ENT nci_wait_rsp_timer; /* Timer for waiting for nci command response */
+ TIMER_LIST_ENT nci_wait_data_ntf_timer; /* Timer for waiting for core credit ntf*/
+ UINT16 nci_wait_rsp_tout; /* NCI command timeout (in ms) */
+ UINT8 nci_wait_rsp; /* layer_specific for last NCI message */
+
+ UINT8 nci_cmd_window; /* Number of commands the controller can accecpt without waiting for response */
+
+ BT_HDR *p_nci_init_rsp; /* holding INIT_RSP until receiving HAL_NFC_POST_INIT_CPLT_EVT */
+ tHAL_NFC_ENTRY *p_hal;
+ i2c_data i2c_data_t; /* holding i2c fragmentation data */
+} tNFC_CB;
+
+
+/*****************************************************************************
+** EXTERNAL FUNCTION DECLARATIONS
+*****************************************************************************/
+
+/* Global NFC data */
+#if NFC_DYNAMIC_MEMORY == FALSE
+NFC_API extern tNFC_CB nfc_cb;
+#else
+NFC_API extern tNFC_CB *nfc_cb_ptr;
+#define nfc_cb (*nfc_cb_ptr)
+#endif
+
+/****************************************************************************
+** Internal nfc functions
+****************************************************************************/
+
+NFC_API extern void nfc_init(void);
+
+/* from nfc_utils.c */
+NFC_API extern tNFC_CONN_CB * nfc_alloc_conn_cb ( tNFC_CONN_CBACK *p_cback);
+NFC_API extern tNFC_CONN_CB * nfc_find_conn_cb_by_conn_id (UINT8 conn_id);
+NFC_API extern tNFC_CONN_CB * nfc_find_conn_cb_by_handle (UINT8 target_handle);
+NFC_API extern void nfc_set_conn_id (tNFC_CONN_CB * p_cb, UINT8 conn_id);
+NFC_API extern void nfc_free_conn_cb (tNFC_CONN_CB *p_cb);
+NFC_API extern void nfc_reset_all_conn_cbs (void);
+NFC_API extern void nfc_data_event (tNFC_CONN_CB * p_cb);
+
+void nfc_ncif_send (BT_HDR *p_buf, BOOLEAN is_cmd);
+extern UINT8 nfc_ncif_send_data (tNFC_CONN_CB *p_cb, BT_HDR *p_data);
+NFC_API extern void nfc_ncif_cmd_timeout (void);
+NFC_API extern void nfc_wait_2_deactivate_timeout (void);
+NFC_API extern void nfc_ncif_credit_ntf_timeout (void);
+NFC_API extern BOOLEAN nfc_ncif_process_event (BT_HDR *p_msg);
+NFC_API extern void nfc_ncif_check_cmd_queue (BT_HDR *p_buf);
+NFC_API extern void nfc_ncif_send_cmd (BT_HDR *p_buf);
+NFC_API extern void nfc_ncif_proc_discover_ntf (UINT8 *p, UINT16 plen);
+NFC_API extern void nfc_ncif_rf_management_status (tNFC_DISCOVER_EVT event, UINT8 status);
+NFC_API extern void nfc_ncif_set_config_status (UINT8 *p, UINT8 len);
+NFC_API extern void nfc_ncif_event_status (tNFC_RESPONSE_EVT event, UINT8 status);
+NFC_API extern void nfc_ncif_error_status (UINT8 conn_id, UINT8 status);
+NFC_API extern void nfc_ncif_proc_credits(UINT8 *p, UINT16 plen);
+NFC_API extern void nfc_ncif_proc_activate (UINT8 *p, UINT8 len);
+NFC_API extern void nfc_ncif_proc_deactivate (UINT8 status, UINT8 deact_type, BOOLEAN is_ntf);
+#if ((NFC_NFCEE_INCLUDED == TRUE) && (NFC_RW_ONLY == FALSE))
+NFC_API extern void nfc_ncif_proc_ee_action (UINT8 *p, UINT16 plen);
+NFC_API extern void nfc_ncif_proc_ee_discover_req (UINT8 *p, UINT16 plen);
+NFC_API extern void nfc_ncif_proc_get_routing (UINT8 *p, UINT8 len);
+#endif
+NFC_API extern void nfc_ncif_proc_conn_create_rsp (UINT8 *p, UINT16 plen, UINT8 dest_type);
+NFC_API extern void nfc_ncif_report_conn_close_evt (UINT8 conn_id, tNFC_STATUS status);
+NFC_API extern void nfc_ncif_proc_t3t_polling_ntf (UINT8 *p, UINT16 plen);
+NFC_API extern void nfc_ncif_proc_reset_rsp (UINT8 *p, BOOLEAN is_ntf);
+NFC_API extern void nfc_ncif_proc_init_rsp (BT_HDR *p_msg);
+NFC_API extern void nfc_ncif_proc_get_config_rsp (BT_HDR *p_msg);
+NFC_API extern void nfc_ncif_proc_data (BT_HDR *p_msg);
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+NFC_API extern tNFC_STATUS nfc_ncif_store_FWVersion(UINT8 * p_buf);
+NFC_API extern BOOLEAN nfa_dm_p2p_prio_logic(UINT8 event, UINT8 *p, UINT8 ntf_rsp);
+NFC_API extern void nfc_ncif_update_window (void);
+NFC_API extern void nfa_dm_p2p_timer_event ();
+NFC_API extern void nfc_ncif_empty_cmd_queue ();
+NFC_API extern BOOLEAN nfc_ncif_proc_proprietary_rsp (UINT8 mt, UINT8 gid, UINT8 oid);
+NFC_API extern void nfc_ncif_proc_rf_wtx_ntf (UINT8 *p, UINT16 plen);
+#endif
+
+#if (NFC_RW_ONLY == FALSE)
+NFC_API extern void nfc_ncif_proc_rf_field_ntf (UINT8 rf_status);
+#else
+#define nfc_ncif_proc_rf_field_ntf(rf_status)
+#endif
+
+/* From nfc_task.c */
+NFC_API extern UINT32 nfc_task (UINT32 param);
+void nfc_task_shutdown_nfcc (void);
+
+/* From nfc_main.c */
+void nfc_enabled (tNFC_STATUS nfc_status, BT_HDR *p_init_rsp_msg);
+void nfc_set_state (tNFC_STATE nfc_state);
+void nfc_main_flush_cmd_queue (void);
+void nfc_gen_cleanup (void);
+void nfc_main_handle_hal_evt (tNFC_HAL_EVT_MSG *p_msg);
+
+/* Timer functions */
+void nfc_start_timer (TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout);
+UINT32 nfc_remaining_time (TIMER_LIST_ENT *p_tle);
+void nfc_stop_timer (TIMER_LIST_ENT *p_tle);
+
+void nfc_start_quick_timer (TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout);
+void nfc_stop_quick_timer (TIMER_LIST_ENT *p_tle);
+void nfc_process_quick_timer_evt (void);
+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..40335ea
--- /dev/null
+++ b/src/nfc/int/rw_int.h
@@ -0,0 +1,682 @@
+/******************************************************************************
+ *
+ * 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 */
+#define RW_T1T_HR0_HI_NIB 0xF0 /* HI NIB Tag */
+#define RW_T1T_IS_JEWEL64 0x20 /* Jewel 64 Tag */
+#define RW_T1T_IS_JEWEL 0x00 /* Jewel Tag */
+#define RW_T1T_IS_TOPAZ 0x10 /* TOPAZ Tag */
+#define RW_T1T_IS_TOPAZ96 0x11 /* TOPAZ96 Tag */
+#define RW_T1T_IS_TOPAZ512 0x12 /* TOPAZ512 Tag */
+#define RW_T1T_HR1_MIN 0x49 /* Supports dynamic commands on static tag if HR1 > 0x49 */
+
+#define RW_T1T_MAX_MEM_TLVS 0x05 /* Maximum supported Memory control TLVS in the tag */
+#define RW_T1T_MAX_LOCK_TLVS 0x05 /* Maximum supported Lock control TLVS in the tag */
+#define RW_T1T_MAX_LOCK_BYTES 0x1E /* Maximum supported dynamic lock bytes */
+
+/* State of the Tag as interpreted by RW */
+#define RW_T1_TAG_ATTRB_UNKNOWN 0x00 /* TAG State is unknown to RW */
+#define RW_T1_TAG_ATTRB_INITIALIZED 0x01 /* TAG is in INITIALIZED state */
+#define RW_T1_TAG_ATTRB_INITIALIZED_NDEF 0x02 /* TAG is in INITIALIZED state and has NDEF tlv with len=0 */
+#define RW_T1_TAG_ATTRB_READ_ONLY 0x03 /* TAG is in READ ONLY state */
+#define RW_T1_TAG_ATTRB_READ_WRITE 0x04 /* TAG is in READ WRITE state */
+
+#define RW_T1T_LOCK_NOT_UPDATED 0x00 /* Lock not yet set as part of SET TAG RO op */
+#define RW_T1T_LOCK_UPDATE_INITIATED 0x01 /* Sent command to set the Lock bytes */
+#define RW_T1T_LOCK_UPDATED 0x02 /* Lock bytes are set */
+typedef UINT8 tRW_T1T_LOCK_STATUS;
+
+/* States */
+#define RW_T1T_STATE_NOT_ACTIVATED 0x00 /* Tag not activated and or response not received for RID */
+#define RW_T1T_STATE_IDLE 0x01 /* T1 Tag activated and ready to perform rw operation on Tag*/
+#define RW_T1T_STATE_READ 0x02 /* waiting rsp for read command sent to tag */
+#define RW_T1T_STATE_WRITE 0x03 /* waiting rsp for write command sent to tag */
+#define RW_T1T_STATE_TLV_DETECT 0x04 /* performing TLV detection procedure */
+#define RW_T1T_STATE_READ_NDEF 0x05 /* performing read NDEF procedure */
+#define RW_T1T_STATE_WRITE_NDEF 0x06 /* performing update NDEF procedure */
+#define RW_T1T_STATE_SET_TAG_RO 0x07 /* Setting Tag as read only tag */
+#define RW_T1T_STATE_CHECK_PRESENCE 0x08 /* Check if Tag is still present */
+#define RW_T1T_STATE_FORMAT_TAG 0x09 /* Format T1 Tag */
+
+/* Sub states */
+#define RW_T1T_SUBSTATE_NONE 0x00 /* Default substate */
+
+/* Sub states in RW_T1T_STATE_TLV_DETECT state */
+#define RW_T1T_SUBSTATE_WAIT_TLV_DETECT 0x01 /* waiting for the detection of a tlv in a tag */
+#define RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN 0x02 /* waiting for finding the len field is 1 or 3 bytes long */
+#define RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0 0x03 /* waiting for extracting len field value */
+#define RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN1 0x04 /* waiting for extracting len field value */
+#define RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE 0x05 /* waiting for extracting value field in the TLV */
+#define RW_T1T_SUBSTATE_WAIT_READ_LOCKS 0x06 /* waiting for reading dynamic locks in the TLV */
+
+/* Sub states in RW_T1T_STATE_WRITE_NDEF state */
+#define RW_T1T_SUBSTATE_WAIT_READ_NDEF_BLOCK 0x07 /* waiting for response of reading a block that will be partially updated */
+#define RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF 0x08 /* waiting for response of invalidating NDEF Msg */
+#define RW_T1T_SUBSTATE_WAIT_NDEF_WRITE 0x09 /* waiting for response of writing a part of NDEF Msg */
+#define RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED 0x0A /* waiting for response of writing last part of NDEF Msg */
+#define RW_T1T_SUBSTATE_WAIT_VALIDATE_NDEF 0x0B /* waiting for response of validating NDEF Msg */
+
+/* Sub states in RW_T1T_STATE_SET_TAG_RO state */
+#define RW_T1T_SUBSTATE_WAIT_SET_CC_RWA_RO 0x0C /* waiting for response of setting CC-RWA to read only */
+#define RW_T1T_SUBSTATE_WAIT_SET_ST_LOCK_BITS 0x0D /* waiting for response of setting all static lock bits */
+#define RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS 0x0E /* waiting for response of setting all dynamic lock bits */
+
+/* Sub states in RW_T1T_STATE_FORMAT_TAG state */
+#define RW_T1T_SUBSTATE_WAIT_SET_CC 0x0F /* waiting for response to format/set capability container */
+#define RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF 0x10 /* waiting for response to format/set NULL NDEF */
+
+
+typedef struct
+{
+ UINT16 offset; /* Offset of the lock byte in the Tag */
+ UINT8 num_bits; /* Number of lock bits in the lock byte */
+ UINT8 bytes_locked_per_bit; /* No. of tag bytes gets locked by a bit in this byte */
+} tRW_T1T_LOCK_INFO;
+
+typedef struct
+{
+ UINT16 offset; /* Reserved bytes offset taken from Memory control TLV */
+ UINT8 num_bytes; /* Number of reserved bytes as per the TLV */
+}tRW_T1T_RES_INFO;
+
+typedef struct
+{
+ UINT8 tlv_index; /* Index of Lock control tlv that points to this address*/
+ UINT8 byte_index; /* Index of Lock byte pointed by the TLV */
+ UINT8 lock_byte; /* Value in the lock byte */
+ tRW_T1T_LOCK_STATUS lock_status; /* Indicates if it is modifed to set tag as Read only */
+ BOOLEAN b_lock_read; /* Is the lock byte is already read from tag */
+} tRW_T1T_LOCK;
+
+typedef struct
+{
+ UINT8 addr; /* ADD/ADD8/ADDS field value */
+ UINT8 op_code; /* Command sent */
+ UINT8 rsp_len; /* expected length of the response */
+ UINT8 pend_retx_rsp; /* Number of pending rsps to retransmission on prev cmd */
+} tRW_T1T_PREV_CMD_RSP_INFO;
+
+#if (defined (RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE))
+#define T1T_BUFFER_SIZE T1T_STATIC_SIZE /* Buffer 0-E block, for easier tlv operation */
+#else
+#define T1T_BUFFER_SIZE T1T_UID_LEN /* Buffer UID */
+#endif
+
+/* RW Type 1 Tag control blocks */
+typedef struct
+{
+ UINT8 hr[T1T_HR_LEN]; /* Header ROM byte 0 - 0x1y,Header ROM byte 1 - 0x00 */
+ UINT8 mem[T1T_SEGMENT_SIZE]; /* Tag contents of block 0 or from block 0-E */
+ tT1T_CMD_RSP_INFO *p_cmd_rsp_info; /* Pointer to Command rsp info of last sent command */
+ UINT8 state; /* Current state of RW module */
+ UINT8 tag_attribute; /* Present state of the Tag as interpreted by RW */
+ BT_HDR *p_cur_cmd_buf; /* Buffer to hold cur sent command for retransmission */
+ UINT8 addr; /* ADD/ADD8/ADDS value */
+ tRW_T1T_PREV_CMD_RSP_INFO prev_cmd_rsp_info; /* Information about previous sent command if retx */
+ TIMER_LIST_ENT timer; /* timer to set timelimit for the response to command */
+ BOOLEAN b_update; /* Tag header updated */
+ BOOLEAN b_rseg; /* Segment 0 read from tag */
+ BOOLEAN b_hard_lock; /* Hard lock the tag as part of config tag to Read only */
+#if (defined (RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE))
+ UINT8 segment; /* Current Tag segment */
+ UINT8 substate; /* Current substate of RW module */
+ UINT16 work_offset; /* Working byte offset */
+ UINT8 ndef_first_block[T1T_BLOCK_SIZE]; /* Buffer for ndef first block */
+ UINT8 ndef_final_block[T1T_BLOCK_SIZE]; /* Buffer for ndef last block */
+ UINT8 *p_ndef_buffer; /* Buffer to store ndef message */
+ UINT16 new_ndef_msg_len; /* Lenght of new updating NDEF Message */
+ UINT8 block_read; /* Last read Block */
+ UINT8 write_byte; /* Index of last written byte */
+ UINT8 tlv_detect; /* TLV type under detection */
+ UINT16 ndef_msg_offset; /* The offset on Tag where first NDEF message is present*/
+ UINT16 ndef_msg_len; /* Lenght of NDEF Message */
+ UINT16 max_ndef_msg_len; /* Maximum size of NDEF that can be written on the tag */
+ UINT16 ndef_header_offset; /* The offset on Tag where first NDEF tlv is present */
+ UINT8 ndef_block_written; /* Last block where NDEF bytes are written */
+ UINT8 num_ndef_finalblock; /* Block number where NDEF's last byte will be present */
+ UINT8 num_lock_tlvs; /* Number of lcok tlvs detected in the tag */
+ tRW_T1T_LOCK_INFO lock_tlv[RW_T1T_MAX_LOCK_TLVS]; /* Information retrieved from lock control tlv */
+ UINT8 num_lockbytes; /* Number of dynamic lock bytes present in the tag */
+ tRW_T1T_LOCK lockbyte[RW_T1T_MAX_LOCK_BYTES]; /* Dynamic Lock byte information */
+ UINT8 num_mem_tlvs; /* Number of memory tlvs detected in the tag */
+ tRW_T1T_RES_INFO mem_tlv[RW_T1T_MAX_MEM_TLVS]; /* Information retrieved from mem tlv */
+ UINT8 attr_seg; /* Tag segment for which attributes are prepared */
+ UINT8 lock_attr_seg; /* Tag segment for which lock attributes are prepared */
+ UINT8 attr[T1T_BLOCKS_PER_SEGMENT]; /* byte information - Reserved/lock/otp or data */
+ UINT8 lock_attr[T1T_BLOCKS_PER_SEGMENT]; /* byte information - read only or read write */
+#endif
+} tRW_T1T_CB;
+
+/* Mifare Ultalight/ Ultralight Family blank tag version block settings */
+#define T2T_MIFARE_VERSION_BLOCK 0x04 /* Block where version number of the tag is stored */
+#define T2T_MIFARE_ULTRALIGHT_VER_NO 0xFFFF /* Blank Ultralight tag - Block 4 (byte 0, byte 1) */
+#define T2T_MIFARE_ULTRALIGHT_FAMILY_VER_NO 0x0200 /* Blank Ultralight family tag - Block 4 (byte 0, byte 1) */
+
+/* Infineon my-d move / my-d blank tag uid block settings */
+#define T2T_INFINEON_VERSION_BLOCK 0x00
+#define T2T_INFINEON_MYD_MOVE_LEAN 0x0570
+#define T2T_INFINEON_MYD_MOVE 0x0530
+
+#define T2T_BRCM_VERSION_BLOCK 0x00
+#define T2T_BRCM_STATIC_MEM 0x2E01
+#define T2T_BRCM_DYNAMIC_MEM 0x2E02
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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
+
+#define T2T_MAX_NDEF_OFFSET 128 /* Max offset of an NDEF message in a T2 tag */
+#define T2T_MAX_RESERVED_BYTES_IN_TAG 0x64
+#define T2T_MAX_LOCK_BYTES_IN_TAG 0x64
+
+#define RW_T2T_MAX_MEM_TLVS 0x05 /* Maximum supported Memory control TLVS in the tag */
+#define RW_T2T_MAX_LOCK_TLVS 0x05 /* Maximum supported Lock control TLVS in the tag */
+#define RW_T2T_MAX_LOCK_BYTES 0x1E /* Maximum supported dynamic lock bytes */
+#define RW_T2T_SEGMENT_BYTES 128
+#define RW_T2T_SEGMENT_SIZE 16
+
+#define RW_T2T_LOCK_NOT_UPDATED 0x00 /* Lock not yet set as part of SET TAG RO op */
+#define RW_T2T_LOCK_UPDATE_INITIATED 0x01 /* Sent command to set the Lock bytes */
+#define RW_T2T_LOCK_UPDATED 0x02 /* Lock bytes are set */
+typedef UINT8 tRW_T2T_LOCK_STATUS;
+
+
+/* States */
+#define RW_T2T_STATE_NOT_ACTIVATED 0x00 /* Tag not activated */
+#define RW_T2T_STATE_IDLE 0x01 /* T1 Tag activated and ready to perform rw operation on Tag*/
+#define RW_T2T_STATE_READ 0x02 /* waiting response for read command sent to tag */
+#define RW_T2T_STATE_WRITE 0x03 /* waiting response for write command sent to tag */
+#define RW_T2T_STATE_SELECT_SECTOR 0x04 /* Waiting response for sector select command */
+#define RW_T2T_STATE_DETECT_TLV 0x05 /* Detecting Lock/Memory/NDEF/Proprietary TLV in the Tag */
+#define RW_T2T_STATE_READ_NDEF 0x06 /* Performing NDEF Read procedure */
+#define RW_T2T_STATE_WRITE_NDEF 0x07 /* Performing NDEF Write procedure */
+#define RW_T2T_STATE_SET_TAG_RO 0x08 /* Setting Tag as Read only tag */
+#define RW_T2T_STATE_CHECK_PRESENCE 0x09 /* Check if Tag is still present */
+#define RW_T2T_STATE_FORMAT_TAG 0x0A /* Format the tag */
+#define RW_T2T_STATE_HALT 0x0B /* Tag is in HALT State */
+
+/* rw_t2t_read/rw_t2t_write takes care of sector change if the block to read/write is in a different sector
+ * Next Substate should be assigned to control variable 'substate' before calling these function for State Machine to
+ * move back to the particular substate after Sector change is completed and read/write command is sent on new sector */
+
+/* Sub states */
+#define RW_T2T_SUBSTATE_NONE 0x00
+
+/* Sub states in RW_T2T_STATE_SELECT_SECTOR state */
+#define RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT 0x01 /* waiting for response of sector select CMD 1 */
+#define RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR 0x02 /* waiting for response of sector select CMD 2 */
+
+/* Sub states in RW_T1T_STATE_DETECT_XXX state */
+#define RW_T2T_SUBSTATE_WAIT_READ_CC 0x03 /* waiting for the detection of a tlv in a tag */
+#define RW_T2T_SUBSTATE_WAIT_TLV_DETECT 0x04 /* waiting for the detection of a tlv in a tag */
+#define RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN 0x05 /* waiting for finding the len field is 1 or 3 bytes long */
+#define RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0 0x06 /* waiting for extracting len field value */
+#define RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1 0x07 /* waiting for extracting len field value */
+#define RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE 0x08 /* waiting for extracting value field in the TLV */
+#define RW_T2T_SUBSTATE_WAIT_READ_LOCKS 0x09 /* waiting for reading dynamic locks in the TLV */
+
+/* Sub states in RW_T2T_STATE_WRITE_NDEF state */
+#define RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK 0x0A /* waiting for rsp to reading the block where NDEF starts */
+#define RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK 0x0B /* waiting for rsp to reading block where new NDEF Msg ends */
+#define RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK 0x0C /* waiting for rsp to reading block where Trm tlv gets added*/
+#define RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK 0x0D /* waiting for rsp to reading block where nxt NDEF write */
+#define RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK 0x0E /* waiting for rsp to writting NDEF block */
+#define RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK 0x0F /* waiting for rsp to last NDEF block write cmd */
+#define RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK 0x10 /* waiting for rsp to reading NDEF len field block */
+#define RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK 0x11 /* waiting for rsp of updating first NDEF len field block */
+#define RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK 0x12 /* waiting for rsp of updating next NDEF len field block */
+#define RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT 0x13 /* waiting for rsp to writing to Terminator tlv */
+
+/* Sub states in RW_T2T_STATE_FORMAT_TAG state */
+#define RW_T2T_SUBSTATE_WAIT_READ_VERSION_INFO 0x14
+#define RW_T2T_SUBSTATE_WAIT_SET_CC 0x15 /* waiting for response to format/set capability container */
+#define RW_T2T_SUBSTATE_WAIT_SET_LOCK_TLV 0x16
+#define RW_T2T_SUBSTATE_WAIT_SET_NULL_NDEF 0x17 /* waiting for response to format/set NULL NDEF */
+
+/* Sub states in RW_T2T_STATE_SET_TAG_RO state */
+#define RW_T2T_SUBSTATE_WAIT_SET_CC_RO 0x19 /* waiting for response to set CC3 to RO */
+#define RW_T2T_SUBSTATE_WAIT_READ_DYN_LOCK_BYTE_BLOCK 0x1A /* waiting for response to read dynamic lock bytes block */
+#define RW_T2T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS 0x1B /* waiting for response to set dynamic lock bits */
+#define RW_T2T_SUBSTATE_WAIT_SET_ST_LOCK_BITS 0x1C /* waiting for response to set static lock bits */
+
+typedef struct
+{
+ UINT16 offset; /* Offset of the lock byte in the Tag */
+ UINT8 num_bits; /* Number of lock bits in the lock byte */
+ UINT8 bytes_locked_per_bit; /* No. of tag bytes gets locked by a bit in this byte */
+} tRW_T2T_LOCK_INFO;
+
+typedef struct
+{
+ UINT16 offset; /* Reserved bytes offset taken from Memory control TLV */
+ UINT8 num_bytes; /* Number of reserved bytes as per the TLV */
+}tRW_T2T_RES_INFO;
+
+typedef struct
+{
+ UINT8 tlv_index; /* Index of Lock control tlv that points to this address */
+ UINT8 byte_index; /* Index of Lock byte pointed by the TLV */
+ UINT8 lock_byte; /* Value in the lock byte */
+ tRW_T2T_LOCK_STATUS lock_status; /* Indicates if it is modifed to set tag as Read only */
+ BOOLEAN b_lock_read; /* Is the lock byte is already read from tag */
+} tRW_T2T_LOCK;
+
+/* RW Type 2 Tag control block */
+typedef struct
+{
+ UINT8 state; /* Reader/writer state */
+ UINT8 substate; /* Reader/write substate in NDEF write state */
+ UINT8 prev_substate; /* Substate of the tag before moving to different sector */
+ UINT8 sector; /* Sector number that is selected */
+ UINT8 select_sector; /* Sector number that is expected to get selected */
+ UINT8 tag_hdr[T2T_READ_DATA_LEN]; /* T2T Header blocks */
+ UINT8 tag_data[T2T_READ_DATA_LEN]; /* T2T Block 4 - 7 data */
+ UINT8 ndef_status; /* The current status of NDEF Write operation */
+ UINT16 block_read; /* Read block */
+ UINT16 block_written; /* Written block */
+ tT2T_CMD_RSP_INFO *p_cmd_rsp_info; /* Pointer to Command rsp info of last sent command */
+ BT_HDR *p_cur_cmd_buf; /* Copy of current command, for retx/send after sector change */
+ BT_HDR *p_sec_cmd_buf; /* Copy of command, to send after sector change */
+ TIMER_LIST_ENT t2_timer; /* timeout for each API call */
+ BOOLEAN b_read_hdr; /* Tag header read from tag */
+ BOOLEAN b_read_data; /* Tag data block read from tag */
+ BOOLEAN b_hard_lock; /* Hard lock the tag as part of config tag to Read only */
+ BOOLEAN check_tag_halt; /* Resent command after NACK rsp to find tag is in HALT State */
+#if (defined (RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE))
+ BOOLEAN skip_dyn_locks; /* Skip reading dynamic lock bytes from the tag */
+ UINT8 found_tlv; /* The Tlv found while searching a particular TLV */
+ UINT8 tlv_detect; /* TLV type under detection */
+ UINT8 num_lock_tlvs; /* Number of lcok tlvs detected in the tag */
+ UINT8 attr_seg; /* Tag segment for which attributes are prepared */
+ UINT8 lock_attr_seg; /* Tag segment for which lock attributes are prepared */
+ UINT8 segment; /* Current operating segment */
+ UINT8 ndef_final_block[T2T_BLOCK_SIZE]; /* Buffer for ndef last block */
+ UINT8 num_mem_tlvs; /* Number of memory tlvs detected in the tag */
+ UINT8 num_lockbytes; /* Number of dynamic lock bytes present in the tag */
+ UINT8 attr[RW_T2T_SEGMENT_SIZE]; /* byte information - Reserved/lock/otp or data */
+ UINT8 lock_attr[RW_T2T_SEGMENT_SIZE]; /* byte information - read only or read write */
+ UINT8 tlv_value[3]; /* Read value field of TLV */
+ UINT8 ndef_first_block[T2T_BLOCK_LEN]; /* NDEF TLV Header block */
+ UINT8 ndef_read_block[T2T_BLOCK_LEN]; /* Buffer to hold read before write block */
+ UINT8 ndef_last_block[T2T_BLOCK_LEN]; /* Terminator TLV block after NDEF Write operation */
+ UINT8 terminator_tlv_block[T2T_BLOCK_LEN];/* Terminator TLV Block */
+ UINT16 ndef_last_block_num; /* Block where last byte of updating ndef message will exist */
+ UINT16 ndef_read_block_num; /* Block read during NDEF Write to avoid overwritting res bytes */
+ UINT16 bytes_count; /* No. of bytes remaining to collect during tlv detect */
+ UINT16 terminator_byte_index; /* The offset of the tag where terminator tlv may be added */
+ UINT16 work_offset; /* Working byte offset */
+ UINT16 ndef_header_offset;
+ UINT16 ndef_msg_offset; /* Offset on Tag where first NDEF message is present */
+ UINT16 ndef_msg_len; /* Lenght of NDEF Message */
+ UINT16 max_ndef_msg_len; /* Maximum size of NDEF that can be written on the tag */
+ UINT16 new_ndef_msg_len; /* Lenght of new updating NDEF Message */
+ UINT16 ndef_write_block;
+ UINT16 prop_msg_len; /* Proprietary tlv length */
+ UINT8 *p_new_ndef_buffer; /* Pointer to updating NDEF Message */
+ UINT8 *p_ndef_buffer; /* Pointer to NDEF Message */
+ tRW_T2T_LOCK_INFO lock_tlv[RW_T2T_MAX_LOCK_TLVS]; /* Information retrieved from lock control tlv */
+ tRW_T2T_LOCK lockbyte[RW_T2T_MAX_LOCK_BYTES]; /* Dynamic Lock byte information */
+ tRW_T2T_RES_INFO mem_tlv[RW_T2T_MAX_MEM_TLVS]; /* Information retrieved from mem tlv */
+#endif
+} tRW_T2T_CB;
+
+/* Type 3 Tag control block */
+typedef UINT8 tRW_T3T_RW_STATE;
+
+typedef struct
+{
+ tNFC_STATUS status;
+ UINT8 version; /* Ver: peer version */
+ UINT8 nbr; /* NBr: number of blocks that can be read using one Check command */
+ UINT8 nbw; /* Nbw: number of blocks that can be written using one Update command */
+ UINT16 nmaxb; /* Nmaxb: maximum number of blocks available for NDEF data */
+ UINT8 writef; /* WriteFlag: 00h if writing data finished; 0Fh if writing data in progress */
+ UINT8 rwflag; /* RWFlag: 00h NDEF is read-only; 01h if read/write available */
+ UINT32 ln; /* Ln: actual size of stored NDEF data (in bytes) */
+} tRW_T3T_DETECT;
+
+/* RW_T3T control block flags */
+#define RW_T3T_FL_IS_FINAL_NDEF_SEGMENT 0x01 /* The final command for completing the NDEF read/write */
+#define RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP 0x02 /* Waiting for POLL response for presence check */
+#define RW_T3T_FL_W4_GET_SC_POLL_RSP 0x04 /* Waiting for POLL response for RW_T3tGetSystemCodes */
+#define RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP 0x08 /* Waiting for POLL response for RW_T3tDetectNDef */
+#define RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP 0x10 /* Waiting for POLL response for RW_T3tFormat */
+#define RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP 0x20 /* Waiting for POLL response for RW_T3tSetReadOnly */
+
+typedef struct
+{
+ UINT32 cur_tout; /* Current command timeout */
+ /* check timeout is check_tout_a + n * check_tout_b; X is T/t3t * 4^E */
+ UINT32 check_tout_a; /* Check command timeout (A+1)*X */
+ UINT32 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 update_tout_a; /* Update command timeout (A+1)*X */
+ UINT32 update_tout_b; /* Update command timeout (B+1)*X */
+ tRW_T3T_RW_STATE rw_state; /* Reader/writer state */
+ UINT8 rw_substate;
+ UINT8 cur_cmd; /* Current command being executed */
+ BT_HDR *p_cur_cmd_buf; /* Copy of current command, for retransmission */
+ TIMER_LIST_ENT timer; /* timeout for waiting for response */
+ TIMER_LIST_ENT poll_timer; /* timeout for waiting for response */
+
+ tRW_T3T_DETECT ndef_attrib; /* T3T NDEF attribute information */
+
+ UINT32 ndef_msg_len; /* Length of ndef message to send */
+ UINT32 ndef_msg_bytes_sent; /* Length of ndef message sent so far */
+ UINT8 *ndef_msg; /* Buffer for outgoing NDEF message */
+ UINT32 ndef_rx_readlen; /* Number of bytes read in current CHECK command */
+ UINT32 ndef_rx_offset; /* Length of ndef message read so far */
+
+ UINT8 num_system_codes; /* System codes detected */
+ UINT16 system_codes[T3T_MAX_SYSTEM_CODES];
+
+ UINT8 peer_nfcid2[NCI_NFCID2_LEN];
+ UINT8 cur_poll_rc; /* RC used in current POLL command */
+
+ UINT8 flags; /* Flags see RW_T3T_FL_* */
+} tRW_T3T_CB;
+
+
+/*
+** Type 4 Tag
+*/
+
+/* Max data size using a single ReadBinary. 2 bytes are for status bytes */
+#define RW_T4T_MAX_DATA_PER_READ (NFC_RW_POOL_BUF_SIZE - BT_HDR_SIZE - NCI_DATA_HDR_SIZE - T4T_RSP_STATUS_WORDS_SIZE)
+
+/* Max data size using a single UpdateBinary. 6 bytes are for CLA, INS, P1, P2, Lc */
+#define RW_T4T_MAX_DATA_PER_WRITE (NFC_RW_POOL_BUF_SIZE - BT_HDR_SIZE - NCI_MSG_OFFSET_SIZE - NCI_DATA_HDR_SIZE - T4T_CMD_MAX_HDR_SIZE)
+
+
+
+/* Mandatory NDEF file control */
+typedef struct
+{
+ UINT16 file_id; /* File Identifier */
+ UINT16 max_file_size; /* Max NDEF file size */
+ UINT8 read_access; /* read access condition */
+ UINT8 write_access; /* write access condition */
+} tRW_T4T_NDEF_FC;
+
+/* Capability Container */
+typedef struct
+{
+ UINT16 cclen; /* the size of this capability container */
+ UINT8 version; /* the mapping specification version */
+ UINT16 max_le; /* the max data size by a single ReadBinary */
+ UINT16 max_lc; /* the max data size by a single UpdateBinary */
+ tRW_T4T_NDEF_FC ndef_fc; /* Mandatory NDEF file control */
+} tRW_T4T_CC;
+
+typedef UINT8 tRW_T4T_RW_STATE;
+typedef UINT8 tRW_T4T_RW_SUBSTATE;
+
+/* Type 4 Tag Control Block */
+typedef struct
+{
+ tRW_T4T_RW_STATE state; /* main state */
+ tRW_T4T_RW_SUBSTATE sub_state; /* sub state */
+ UINT8 version; /* currently effective version */
+ TIMER_LIST_ENT timer; /* timeout for each API call */
+
+ UINT16 ndef_length; /* length of NDEF data */
+ UINT8 *p_update_data; /* pointer of data to update */
+ UINT16 rw_length; /* remaining bytes to read/write */
+ UINT16 rw_offset; /* remaining offset to read/write */
+ BT_HDR *p_data_to_free; /* GKI buffet to delete after done */
+
+ tRW_T4T_CC cc_file; /* Capability Container File */
+
+#define RW_T4T_NDEF_STATUS_NDEF_DETECTED 0x01 /* NDEF has been detected */
+#define RW_T4T_NDEF_STATUS_NDEF_READ_ONLY 0x02 /* NDEF file is read-only */
+
+ UINT8 ndef_status; /* bitmap for NDEF status */
+ UINT8 channel; /* channel id: used for read-binary */
+
+ UINT16 max_read_size; /* max reading size per a command */
+ UINT16 max_update_size; /* max updating size per a command */
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ UINT16 card_size;
+ UINT8 card_type;
+#endif
+} tRW_T4T_CB;
+
+/* RW retransmission statistics */
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+typedef struct
+{
+ UINT32 start_tick; /* System tick count at activation */
+ UINT32 bytes_sent; /* Total bytes sent since activation */
+ UINT32 bytes_received; /* Total bytes received since activation */
+ UINT32 num_ops; /* Number of operations since activation */
+ UINT32 num_retries; /* Number of retranmissions since activation */
+ UINT32 num_crc; /* Number of crc failures */
+ UINT32 num_trans_err; /* Number of transmission error notifications */
+ UINT32 num_fail; /* Number of aborts (failures after retries) */
+} tRW_STATS;
+#endif /* RW_STATS_INCLUDED */
+
+/* ISO 15693 RW Control Block */
+typedef UINT8 tRW_I93_RW_STATE;
+typedef UINT8 tRW_I93_RW_SUBSTATE;
+
+#define RW_I93_FLAG_READ_ONLY 0x01 /* tag is read-only */
+#define RW_I93_FLAG_READ_MULTI_BLOCK 0x02 /* tag supports read multi block */
+#define RW_I93_FLAG_RESET_DSFID 0x04 /* need to reset DSFID for formatting */
+#define RW_I93_FLAG_RESET_AFI 0x08 /* need to reset AFI for formatting */
+#define RW_I93_FLAG_16BIT_NUM_BLOCK 0x10 /* use 2 bytes for number of blocks */
+
+#define RW_I93_TLV_DETECT_STATE_TYPE 0x01 /* searching for type */
+#define RW_I93_TLV_DETECT_STATE_LENGTH_1 0x02 /* searching for the first byte of length */
+#define RW_I93_TLV_DETECT_STATE_LENGTH_2 0x03 /* searching for the second byte of length */
+#define RW_I93_TLV_DETECT_STATE_LENGTH_3 0x04 /* searching for the third byte of length */
+#define RW_I93_TLV_DETECT_STATE_VALUE 0x05 /* reading value field */
+
+enum
+{
+ RW_I93_ICODE_SLI, /* ICODE SLI, SLIX */
+ RW_I93_ICODE_SLI_S, /* ICODE SLI-S, SLIX-S */
+ RW_I93_ICODE_SLI_L, /* ICODE SLI-L, SLIX-L */
+ RW_I93_TAG_IT_HF_I_PLUS_INLAY, /* Tag-it HF-I Plus Inlay */
+ RW_I93_TAG_IT_HF_I_PLUS_CHIP, /* Tag-it HF-I Plus Chip */
+ RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY, /* Tag-it HF-I Standard Chip/Inlyas */
+ RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY, /* Tag-it HF-I Pro Chip/Inlyas */
+ RW_I93_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 sent_cmd; /* last sent command */
+ UINT8 retry_count; /* number of retry */
+ BT_HDR *p_retry_cmd; /* buffer to store cmd sent last */
+
+ UINT8 info_flags; /* information flags */
+ UINT8 uid[I93_UID_BYTE_LEN]; /* UID of currently activated */
+ UINT8 dsfid; /* DSFID if I93_INFO_FLAG_DSFID */
+ UINT8 afi; /* AFI if I93_INFO_FLAG_AFI */
+ UINT8 block_size; /* block size of tag, in bytes */
+ UINT16 num_block; /* number of blocks in tag */
+ UINT8 ic_reference; /* IC Reference of tag */
+ UINT8 product_version; /* tag product version */
+
+ UINT8 intl_flags; /* flags for internal information */
+
+ UINT8 tlv_detect_state; /* TLV detecting state */
+ UINT8 tlv_type; /* currently detected type */
+ UINT16 tlv_length; /* currently detected length */
+
+ UINT16 ndef_tlv_start_offset; /* offset of first byte of NDEF TLV */
+ UINT16 ndef_tlv_last_offset; /* offset of last byte of NDEF TLV */
+ UINT16 max_ndef_length; /* max NDEF length the tag contains */
+ UINT16 ndef_length; /* length of NDEF data */
+
+ UINT8 *p_update_data; /* pointer of data to update */
+ UINT16 rw_length; /* bytes to read/write */
+ UINT16 rw_offset; /* offset to read/write */
+} tRW_I93_CB;
+
+/* RW memory control blocks */
+typedef union
+{
+ tRW_T1T_CB t1t;
+ tRW_T2T_CB t2t;
+ tRW_T3T_CB t3t;
+ tRW_T4T_CB t4t;
+ tRW_I93_CB i93;
+} tRW_TCB;
+
+/* RW control blocks */
+typedef struct
+{
+ tRW_TCB tcb;
+ tRW_CBACK *p_cback;
+ UINT32 cur_retry; /* Retry count for the current operation */
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+ tRW_STATS stats;
+#endif /* RW_STATS_INCLUDED */
+ UINT8 trace_level;
+} tRW_CB;
+
+
+/*****************************************************************************
+** EXTERNAL FUNCTION DECLARATIONS
+*****************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Global NFC data */
+#if NFC_DYNAMIC_MEMORY == FALSE
+NFC_API extern tRW_CB rw_cb;
+#else
+NFC_API extern tRW_CB *rw_cb_ptr;
+#define rw_cb (*rw_cb_ptr)
+#endif
+
+/* from .c */
+
+#if (defined (RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE))
+extern tRW_EVENT rw_t1t_handle_rsp (const tT1T_CMD_RSP_INFO * p_info, BOOLEAN *p_notify, UINT8 *p_data, tNFC_STATUS *p_status);
+extern tRW_EVENT rw_t1t_info_to_event (const tT1T_CMD_RSP_INFO * p_info);
+#else
+#define rw_t1t_handle_rsp(p, a, b, c) t1t_info_to_evt (p)
+#define rw_t1t_info_to_event(p) t1t_info_to_evt (p)
+#endif
+
+extern void rw_init (void);
+extern tNFC_STATUS rw_t1t_select (UINT8 hr[T1T_HR_LEN], UINT8 uid[T1T_CMD_UID_LEN]);
+extern tNFC_STATUS rw_t1t_send_dyn_cmd (UINT8 opcode, UINT8 add, UINT8 *p_dat);
+extern tNFC_STATUS rw_t1t_send_static_cmd (UINT8 opcode, UINT8 add, UINT8 dat);
+extern void rw_t1t_process_timeout (TIMER_LIST_ENT *p_tle);
+extern void rw_t1t_handle_op_complete (void);
+
+#if (defined (RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE))
+extern tRW_EVENT rw_t2t_info_to_event (const tT2T_CMD_RSP_INFO *p_info);
+extern void rw_t2t_handle_rsp (UINT8 *p_data);
+#else
+#define rw_t2t_info_to_event(p) t2t_info_to_evt (p)
+#define rw_t2t_handle_rsp(p)
+#endif
+
+extern tNFC_STATUS rw_t2t_sector_change (UINT8 sector);
+extern tNFC_STATUS rw_t2t_read (UINT16 block);
+extern tNFC_STATUS rw_t2t_write (UINT16 block, UINT8 *p_write_data);
+extern void rw_t2t_process_timeout (TIMER_LIST_ENT *p_tle);
+extern tNFC_STATUS rw_t2t_select (void);
+void rw_t2t_handle_op_complete (void);
+
+extern void rw_t3t_process_timeout (TIMER_LIST_ENT *p_tle);
+extern tNFC_STATUS rw_t3t_select (UINT8 peer_nfcid2[NCI_RF_F_UID_LEN], UINT8 mrti_check, UINT8 mrti_update);
+void rw_t3t_handle_nci_poll_ntf (UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf);
+
+extern tNFC_STATUS rw_t4t_select (void);
+extern void rw_t4t_process_timeout (TIMER_LIST_ENT *p_tle);
+
+extern tNFC_STATUS rw_i93_select (UINT8 *p_uid);
+extern void rw_i93_process_timeout (TIMER_LIST_ENT *p_tle);
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+/* Internal fcns for statistics (from rw_main.c) */
+void rw_main_reset_stats (void);
+void rw_main_update_tx_stats (UINT32 bytes_tx, BOOLEAN is_retry);
+void rw_main_update_rx_stats (UINT32 bytes_rx);
+void rw_main_update_crc_error_stats (void);
+void rw_main_update_trans_error_stats (void);
+void rw_main_update_fail_stats (void);
+void rw_main_log_stats (void);
+#endif /* RW_STATS_INCLUDED */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RW_INT_H_ */
diff --git a/src/nfc/int/tags_int.h b/src/nfc/int/tags_int.h
new file mode 100644
index 0000000..3267251
--- /dev/null
+++ b/src/nfc/int/tags_int.h
@@ -0,0 +1,98 @@
+/******************************************************************************
+ *
+ * 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 opcode;
+ UINT8 cmd_len;
+ UINT8 uid_offset;
+ UINT8 rsp_len;
+} tT1T_CMD_RSP_INFO;
+
+typedef struct
+{
+ UINT8 tag_model;
+ UINT8 tms;
+ UINT8 b_dynamic;
+ UINT8 lock_tlv[3];
+ UINT8 mem_tlv[3];
+} tT1T_INIT_TAG;
+
+typedef struct
+{
+ UINT8 manufacturer_id;
+ BOOLEAN b_multi_version;
+ UINT8 version_block;
+ UINT16 version_no;
+ UINT16 version_bmask;
+ UINT8 b_calc_cc;
+ UINT8 tms;
+ BOOLEAN b_otp;
+ UINT8 default_lock_blpb;
+} tT2T_INIT_TAG;
+
+typedef struct
+{
+ UINT8 opcode;
+ UINT8 cmd_len;
+ UINT8 rsp_len;
+ UINT8 nack_rsp_len;
+} tT2T_CMD_RSP_INFO;
+
+extern const UINT8 t4t_v10_ndef_tag_aid[]; /* V1.0 Type 4 Tag Applicaiton ID */
+extern const UINT8 t4t_v20_ndef_tag_aid[]; /* V2.0 Type 4 Tag Applicaiton ID */
+
+extern const tT1T_CMD_RSP_INFO t1t_cmd_rsp_infos[];
+extern const tT1T_INIT_TAG t1t_init_content[];
+extern const tT1T_CMD_RSP_INFO * t1t_cmd_to_rsp_info (UINT8 opcode);
+extern const tT1T_INIT_TAG * t1t_tag_init_data (UINT8 tag_model);
+extern UINT8 t1t_info_to_evt (const tT1T_CMD_RSP_INFO * p_info);
+
+extern const tT2T_INIT_TAG * t2t_tag_init_data (UINT8 manufacturer_id, BOOLEAN b_valid_ver, UINT16 version_no);
+extern const tT2T_CMD_RSP_INFO t2t_cmd_rsp_infos[];
+extern const tT2T_CMD_RSP_INFO * t2t_cmd_to_rsp_info (UINT8 opcode);
+extern UINT8 t2t_info_to_evt (const tT2T_CMD_RSP_INFO * p_info);
+
+
+#if (BT_TRACE_PROTOCOL == TRUE)
+extern const char * t1t_info_to_str (const tT1T_CMD_RSP_INFO * p_info);
+extern const char * t2t_info_to_str (const tT2T_CMD_RSP_INFO * p_info);
+#else
+#define t1t_info_to_str(x) ""
+#define t2t_info_to_str(x) ""
+#endif
+extern int tags_pow (int x, int y);
+extern unsigned int tags_log2 (register unsigned int x);
+
+
+#endif /* TAGS_INT_H */
diff --git a/src/nfc/llcp/llcp_api.c b/src/nfc/llcp/llcp_api.c
new file mode 100644
index 0000000..ab69a49
--- /dev/null
+++ b/src/nfc/llcp/llcp_api.c
@@ -0,0 +1,1664 @@
+/******************************************************************************
+ *
+ * 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 code
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include "gki.h"
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "llcp_api.h"
+#include "llcp_int.h"
+#include "llcp_defs.h"
+
+#if (LLCP_TEST_INCLUDED == TRUE) /* this is for LLCP testing */
+
+tLLCP_TEST_PARAMS llcp_test_params =
+{
+ LLCP_VERSION_VALUE,
+ 0, /* not override */
+};
+
+/*******************************************************************************
+**
+** Function LLCP_SetTestParams
+**
+** Description Set test parameters for LLCP
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void LLCP_SetTestParams (UINT8 version, UINT16 wks)
+{
+ LLCP_TRACE_API2 ("LLCP_SetTestParams () version:0x%02X, wks:0x%04X",
+ version, wks);
+
+ if (version != 0xFF)
+ llcp_test_params.version = version;
+
+ if (wks != 0xFFFF)
+ llcp_test_params.wks = wks;
+}
+#endif
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 link_miu,
+ UINT8 opt,
+ UINT8 wt,
+ UINT16 link_timeout,
+ UINT16 inact_timeout_init,
+ UINT16 inact_timeout_target,
+ UINT16 symm_delay,
+ UINT16 data_link_timeout,
+ UINT16 delay_first_pdu_timeout)
+{
+ LLCP_TRACE_API4 ("LLCP_SetConfig () link_miu:%d, opt:0x%02X, wt:%d, link_timeout:%d",
+ link_miu, opt, wt, link_timeout);
+ LLCP_TRACE_API4 (" inact_timeout (init:%d,target:%d), symm_delay:%d, data_link_timeout:%d",
+ inact_timeout_init, inact_timeout_target, symm_delay, data_link_timeout);
+ LLCP_TRACE_API1 (" delay_first_pdu_timeout:%d", delay_first_pdu_timeout);
+
+ if (link_miu < LLCP_DEFAULT_MIU)
+ {
+ LLCP_TRACE_ERROR1 ("LLCP_SetConfig (): link_miu shall not be smaller than LLCP_DEFAULT_MIU (%d)",
+ LLCP_DEFAULT_MIU);
+ link_miu = LLCP_DEFAULT_MIU;
+ }
+ else if (link_miu > LLCP_MAX_MIU)
+ {
+ LLCP_TRACE_ERROR1 ("LLCP_SetConfig (): link_miu shall not be bigger than LLCP_MAX_MIU (%d)",
+ LLCP_MAX_MIU);
+ link_miu = LLCP_MAX_MIU;
+ }
+
+ /* if Link MIU is bigger than GKI buffer */
+ if (link_miu > LLCP_MIU)
+ {
+ LLCP_TRACE_ERROR1 ("LLCP_SetConfig (): link_miu shall not be bigger than LLCP_MIU (%d)",
+ LLCP_MIU);
+ llcp_cb.lcb.local_link_miu = LLCP_MIU;
+ }
+ else
+ llcp_cb.lcb.local_link_miu = link_miu;
+
+ llcp_cb.lcb.local_opt = opt;
+ llcp_cb.lcb.local_wt = wt;
+
+ if (link_timeout < LLCP_LTO_UNIT)
+ {
+ LLCP_TRACE_ERROR1 ("LLCP_SetConfig (): link_timeout shall not be smaller than LLCP_LTO_UNIT (%d ms)",
+ LLCP_LTO_UNIT);
+ llcp_cb.lcb.local_lto = LLCP_DEFAULT_LTO_IN_MS;
+ }
+ else if (link_timeout > LLCP_MAX_LTO_IN_MS)
+ {
+ LLCP_TRACE_ERROR1 ("LLCP_SetConfig (): link_timeout shall not be bigger than LLCP_MAX_LTO_IN_MS (%d ms)",
+ LLCP_MAX_LTO_IN_MS);
+ llcp_cb.lcb.local_lto = LLCP_MAX_LTO_IN_MS;
+ }
+ else
+ llcp_cb.lcb.local_lto = link_timeout;
+
+ llcp_cb.lcb.inact_timeout_init = inact_timeout_init;
+ llcp_cb.lcb.inact_timeout_target = inact_timeout_target;
+ llcp_cb.lcb.symm_delay = symm_delay;
+ llcp_cb.lcb.data_link_timeout = data_link_timeout;
+ llcp_cb.lcb.delay_first_pdu_timeout = delay_first_pdu_timeout;
+}
+
+/*******************************************************************************
+**
+** Function LLCP_GetConfig
+**
+** Description Get configuration parameters for LLCP
+** - Local Link MIU
+** - Option parameter
+** - Response Waiting Time Index
+** - Local Link Timeout
+** - Inactivity Timeout as initiator role
+** - Inactivity Timeout as target role
+** - Delay SYMM response
+** - Data link connection timeout
+** - Delay timeout to send first PDU as initiator
+** - Firmware start symmetry
+** Returns void
+**
+*******************************************************************************/
+void LLCP_GetConfig (UINT16 *p_link_miu,
+ UINT8 *p_opt,
+ UINT8 *p_wt,
+ UINT16 *p_link_timeout,
+ UINT16 *p_inact_timeout_init,
+ UINT16 *p_inact_timeout_target,
+ UINT16 *p_symm_delay,
+ UINT16 *p_data_link_timeout,
+ UINT16 *p_delay_first_pdu_timeout)
+{
+ *p_link_miu = llcp_cb.lcb.local_link_miu;
+ *p_opt = llcp_cb.lcb.local_opt;
+ *p_wt = llcp_cb.lcb.local_wt;
+ *p_link_timeout = llcp_cb.lcb.local_lto;
+ *p_inact_timeout_init = llcp_cb.lcb.inact_timeout_init;
+ *p_inact_timeout_target = llcp_cb.lcb.inact_timeout_target;
+ *p_symm_delay = llcp_cb.lcb.symm_delay;
+ *p_data_link_timeout = llcp_cb.lcb.data_link_timeout;
+ *p_delay_first_pdu_timeout = llcp_cb.lcb.delay_first_pdu_timeout;
+
+ LLCP_TRACE_API4 ("LLCP_GetConfig () link_miu:%d, opt:0x%02X, wt:%d, link_timeout:%d",
+ *p_link_miu, *p_opt, *p_wt, *p_link_timeout);
+ LLCP_TRACE_API4 (" inact_timeout (init:%d, target:%d), symm_delay:%d, data_link_timeout:%d",
+ *p_inact_timeout_init, *p_inact_timeout_target, *p_symm_delay, *p_data_link_timeout);
+ LLCP_TRACE_API1 (" delay_first_pdu_timeout:%d", *p_delay_first_pdu_timeout);
+}
+
+/*******************************************************************************
+**
+** Function LLCP_GetDiscoveryConfig
+**
+** Description Returns discovery config for ISO 18092 MAC link activation
+** This function is called to get general bytes for NFC_PMID_ATR_REQ_GEN_BYTES
+** or NFC_PMID_ATR_RES_GEN_BYTES before starting discovery.
+**
+** wt:Waiting time 0 - 8, only for listen
+** p_gen_bytes: pointer to store LLCP magic number and paramters
+** p_gen_bytes_len: length of buffer for gen bytes as input
+** (NOTE:it must be bigger than LLCP_MIN_GEN_BYTES)
+** actual gen bytes size as output
+**
+** Restrictions on the use of ISO 18092
+** 1. The DID features shall not be used.
+** 2. the NAD features shall not be used.
+** 3. Frame waiting time extentions (WTX) shall not be used.
+**
+** Returns None
+**
+*******************************************************************************/
+void LLCP_GetDiscoveryConfig (UINT8 *p_wt,
+ UINT8 *p_gen_bytes,
+ UINT8 *p_gen_bytes_len)
+{
+ UINT8 *p = p_gen_bytes;
+
+ LLCP_TRACE_API0 ("LLCP_GetDiscoveryConfig ()");
+
+ if (*p_gen_bytes_len < LLCP_MIN_GEN_BYTES)
+ {
+ LLCP_TRACE_ERROR1 ("LLCP_GetDiscoveryConfig (): GenBytes length shall not be smaller than LLCP_MIN_GEN_BYTES (%d)",
+ LLCP_MIN_GEN_BYTES);
+ *p_gen_bytes_len = 0;
+ return;
+ }
+
+ *p_wt = llcp_cb.lcb.local_wt;
+
+ UINT8_TO_BE_STREAM (p, LLCP_MAGIC_NUMBER_BYTE0);
+ UINT8_TO_BE_STREAM (p, LLCP_MAGIC_NUMBER_BYTE1);
+ UINT8_TO_BE_STREAM (p, LLCP_MAGIC_NUMBER_BYTE2);
+
+#if (LLCP_TEST_INCLUDED == TRUE) /* this is for LLCP testing */
+ UINT8_TO_BE_STREAM (p, LLCP_VERSION_TYPE);
+ UINT8_TO_BE_STREAM (p, LLCP_VERSION_LEN);
+ UINT8_TO_BE_STREAM (p, llcp_test_params.version);
+
+ UINT8_TO_BE_STREAM (p, LLCP_MIUX_TYPE);
+ UINT8_TO_BE_STREAM (p, LLCP_MIUX_LEN);
+ UINT16_TO_BE_STREAM (p, (llcp_cb.lcb.local_link_miu - LLCP_DEFAULT_MIU));
+
+ UINT8_TO_BE_STREAM (p, LLCP_WKS_TYPE);
+ UINT8_TO_BE_STREAM (p, LLCP_WKS_LEN);
+ if (llcp_test_params.wks == 0) /* not override */
+ {
+ UINT16_TO_BE_STREAM (p, llcp_cb.lcb.wks);
+ }
+ else
+ {
+ UINT16_TO_BE_STREAM (p, llcp_test_params.wks);
+ }
+#else
+ UINT8_TO_BE_STREAM (p, LLCP_VERSION_TYPE);
+ UINT8_TO_BE_STREAM (p, LLCP_VERSION_LEN);
+ UINT8_TO_BE_STREAM (p, LLCP_VERSION_VALUE);
+
+ UINT8_TO_BE_STREAM (p, LLCP_MIUX_TYPE);
+ UINT8_TO_BE_STREAM (p, LLCP_MIUX_LEN);
+ UINT16_TO_BE_STREAM (p, (llcp_cb.lcb.local_link_miu - LLCP_DEFAULT_MIU));
+
+ UINT8_TO_BE_STREAM (p, LLCP_WKS_TYPE);
+ UINT8_TO_BE_STREAM (p, LLCP_WKS_LEN);
+ UINT16_TO_BE_STREAM (p, llcp_cb.lcb.wks);
+#endif
+
+ UINT8_TO_BE_STREAM (p, LLCP_LTO_TYPE);
+ UINT8_TO_BE_STREAM (p, LLCP_LTO_LEN);
+ UINT8_TO_BE_STREAM (p, (llcp_cb.lcb.local_lto/LLCP_LTO_UNIT));
+
+ UINT8_TO_BE_STREAM (p, LLCP_OPT_TYPE);
+ UINT8_TO_BE_STREAM (p, LLCP_OPT_LEN);
+ UINT8_TO_BE_STREAM (p, llcp_cb.lcb.local_opt);
+
+ *p_gen_bytes_len = (UINT8) (p - p_gen_bytes);
+}
+
+/*******************************************************************************
+**
+** Function LLCP_ActivateLink
+**
+** Description This function will activate LLCP link with LR, WT and Gen Bytes
+** in activation NTF from NFCC.
+**
+** LLCP_LINK_ACTIVATION_COMPLETE_EVT will be returned through
+** callback function if successful.
+** Otherwise, LLCP_LINK_ACTIVATION_FAILED_EVT will be returned.
+**
+** Returns LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_ActivateLink (tLLCP_ACTIVATE_CONFIG config,
+ tLLCP_LINK_CBACK *p_link_cback)
+{
+ LLCP_TRACE_API1 ("LLCP_ActivateLink () link_state = %d", llcp_cb.lcb.link_state);
+
+ if ( (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATED)
+ &&(p_link_cback) )
+ {
+ llcp_cb.lcb.p_link_cback = p_link_cback;
+ return (llcp_link_activate (&config));
+ }
+ else
+ return LLCP_STATUS_FAIL;
+}
+
+/*******************************************************************************
+**
+** Function LLCP_DeactivateLink
+**
+** Description Deactivate LLCP link
+**
+** LLCP_LINK_DEACTIVATED_EVT will be returned through callback
+** when LLCP link is deactivated. Then NFC link may be deactivated.
+**
+** Returns LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_DeactivateLink (void)
+{
+ LLCP_TRACE_API1 ("LLCP_DeactivateLink () link_state = %d", llcp_cb.lcb.link_state);
+
+ if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_DEACTIVATED)
+ {
+ llcp_link_deactivate (LLCP_LINK_LOCAL_INITIATED);
+ return LLCP_STATUS_SUCCESS;
+ }
+ else
+ return LLCP_STATUS_FAIL;
+}
+
+/*******************************************************************************
+**
+** Function LLCP_RegisterServer
+**
+** Description Register server and callback function
+**
+** reg_sap : Well-Known SAP except LM and SDP (0x02 - 0x0F)
+** Advertized by SDP (0x10 - 0x1F)
+** LLCP_INVALID_SAP, LLCP will allocate between 0x10 and 0x1F
+** link_type : LLCP_LINK_TYPE_LOGICAL_DATA_LINK
+** and/or LLCP_LINK_TYPE_DATA_LINK_CONNECTION
+** p_service_name : Null-terminated string up to LLCP_MAX_SN_LEN
+**
+** Returns SAP between 0x02 and 0x1F, if success
+** LLCP_INVALID_SAP, otherwise
+**
+*******************************************************************************/
+UINT8 LLCP_RegisterServer (UINT8 reg_sap,
+ UINT8 link_type,
+ char *p_service_name,
+ tLLCP_APP_CBACK *p_app_cback)
+{
+ UINT8 sap;
+ UINT16 length;
+ tLLCP_APP_CB *p_app_cb;
+
+ LLCP_TRACE_API3 ("LLCP_RegisterServer (): SAP:0x%x, link_type:0x%x, ServiceName:<%s>",
+ reg_sap, link_type, ((p_service_name == NULL) ? "" : p_service_name));
+
+ if (!p_app_cback)
+ {
+ LLCP_TRACE_ERROR0 ("LLCP_RegisterServer (): Callback must be provided");
+ return LLCP_INVALID_SAP;
+ }
+ else if ( ((link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0x00)
+ &&((link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0x00) )
+ {
+ LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): link type (0x%x) must be specified", link_type);
+ return LLCP_INVALID_SAP;
+ }
+
+ if (reg_sap == LLCP_INVALID_SAP)
+ {
+ /* allocate a SAP between 0x10 and 0x1F */
+ for (sap = 0; sap < LLCP_MAX_SERVER; sap++)
+ {
+ if (llcp_cb.server_cb[sap].p_app_cback == NULL)
+ {
+ p_app_cb = &llcp_cb.server_cb[sap];
+ reg_sap = LLCP_LOWER_BOUND_SDP_SAP + sap;
+ break;
+ }
+ }
+
+ if (reg_sap == LLCP_INVALID_SAP)
+ {
+ LLCP_TRACE_ERROR0 ("LLCP_RegisterServer (): out of resource");
+ return LLCP_INVALID_SAP;
+ }
+ }
+ else if (reg_sap == LLCP_SAP_LM)
+ {
+ LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): SAP (0x%x) is for link manager", reg_sap);
+ return LLCP_INVALID_SAP;
+ }
+ else if (reg_sap <= LLCP_UPPER_BOUND_WK_SAP)
+ {
+ if (reg_sap >= LLCP_MAX_WKS)
+ {
+ LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): out of resource for SAP (0x%x)", reg_sap);
+ return LLCP_INVALID_SAP;
+ }
+ else if (llcp_cb.wks_cb[reg_sap].p_app_cback)
+ {
+ LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): SAP (0x%x) is already registered", reg_sap);
+ return LLCP_INVALID_SAP;
+ }
+ else
+ {
+ p_app_cb = &llcp_cb.wks_cb[reg_sap];
+ }
+ }
+ else if (reg_sap <= LLCP_UPPER_BOUND_SDP_SAP)
+ {
+ if (reg_sap - LLCP_LOWER_BOUND_SDP_SAP >= LLCP_MAX_SERVER)
+ {
+ LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): out of resource for SAP (0x%x)", reg_sap);
+ return LLCP_INVALID_SAP;
+ }
+ else if (llcp_cb.server_cb[reg_sap - LLCP_LOWER_BOUND_SDP_SAP].p_app_cback)
+ {
+ LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): SAP (0x%x) is already registered", reg_sap);
+ return LLCP_INVALID_SAP;
+ }
+ else
+ {
+ p_app_cb = &llcp_cb.server_cb[reg_sap - LLCP_LOWER_BOUND_SDP_SAP];
+ }
+ }
+ else if (reg_sap >= LLCP_LOWER_BOUND_LOCAL_SAP)
+ {
+ LLCP_TRACE_ERROR2 ("LLCP_RegisterServer (): SAP (0x%x) must be less than 0x%x",
+ reg_sap, LLCP_LOWER_BOUND_LOCAL_SAP);
+ return LLCP_INVALID_SAP;
+ }
+
+ memset (p_app_cb, 0x00, sizeof (tLLCP_APP_CB));
+
+ if (p_service_name)
+ {
+ length = (UINT8) strlen (p_service_name);
+ if (length > LLCP_MAX_SN_LEN)
+ {
+ LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): Service Name (%d bytes) is too long", length);
+ return LLCP_INVALID_SAP;
+ }
+
+ p_app_cb->p_service_name = (UINT8 *) GKI_getbuf ((UINT16) (length + 1));
+ if (p_app_cb->p_service_name == NULL)
+ {
+ LLCP_TRACE_ERROR0 ("LLCP_RegisterServer (): Out of resource");
+ return LLCP_INVALID_SAP;
+ }
+
+ BCM_STRNCPY_S ((char *) p_app_cb->p_service_name, length + 1, (char *) p_service_name, length + 1);
+ p_app_cb->p_service_name[length] = 0;
+ }
+ else
+ p_app_cb->p_service_name = NULL;
+
+ p_app_cb->p_app_cback = p_app_cback;
+ p_app_cb->link_type = link_type;
+
+ if (reg_sap <= LLCP_UPPER_BOUND_WK_SAP)
+ {
+ llcp_cb.lcb.wks |= (1 << reg_sap);
+ }
+
+ LLCP_TRACE_DEBUG1 ("LLCP_RegisterServer (): Registered SAP = 0x%02X", reg_sap);
+
+ if (link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)
+ {
+ llcp_cb.num_logical_data_link++;
+ llcp_util_adjust_ll_congestion ();
+ }
+
+ return reg_sap;
+}
+
+/*******************************************************************************
+**
+** Function LLCP_RegisterClient
+**
+** Description Register client and callback function
+**
+** link_type : LLCP_LINK_TYPE_LOGICAL_DATA_LINK
+** and/or LLCP_LINK_TYPE_DATA_LINK_CONNECTION
+**
+** Returns SAP between 0x20 and 0x3F, if success
+** LLCP_INVALID_SAP, otherwise
+**
+*******************************************************************************/
+UINT8 LLCP_RegisterClient (UINT8 link_type,
+ tLLCP_APP_CBACK *p_app_cback)
+{
+ UINT8 reg_sap = LLCP_INVALID_SAP;
+ UINT8 sap;
+ tLLCP_APP_CB *p_app_cb;
+
+ LLCP_TRACE_API1 ("LLCP_RegisterClient (): link_type = 0x%x", link_type);
+
+ if (!p_app_cback)
+ {
+ LLCP_TRACE_ERROR0 ("LLCP_RegisterClient (): Callback must be provided");
+ return LLCP_INVALID_SAP;
+ }
+ else if ( ((link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0x00)
+ &&((link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0x00) )
+ {
+ LLCP_TRACE_ERROR1 ("LLCP_RegisterClient (): link type (0x%x) must be specified", link_type);
+ return LLCP_INVALID_SAP;
+ }
+
+ /* allocate a SAP between 0x20 and 0x3F */
+ for (sap = 0; sap < LLCP_MAX_CLIENT; sap++)
+ {
+ if (llcp_cb.client_cb[sap].p_app_cback == NULL)
+ {
+ p_app_cb = &llcp_cb.client_cb[sap];
+ memset (p_app_cb, 0x00, sizeof (tLLCP_APP_CB));
+ reg_sap = LLCP_LOWER_BOUND_LOCAL_SAP + sap;
+ break;
+ }
+ }
+
+ if (reg_sap == LLCP_INVALID_SAP)
+ {
+ LLCP_TRACE_ERROR0 ("LLCP_RegisterClient (): out of resource");
+ return LLCP_INVALID_SAP;
+ }
+
+ p_app_cb->p_app_cback = p_app_cback;
+ p_app_cb->p_service_name = NULL;
+ p_app_cb->link_type = link_type;
+
+ LLCP_TRACE_DEBUG1 ("LLCP_RegisterClient (): Registered SAP = 0x%02X", reg_sap);
+
+ if (link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)
+ {
+ llcp_cb.num_logical_data_link++;
+ llcp_util_adjust_ll_congestion ();
+ }
+
+ return reg_sap;
+}
+
+/*******************************************************************************
+**
+** Function LLCP_Deregister
+**
+** Description Deregister server or client
+**
+**
+** Returns LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_Deregister (UINT8 local_sap)
+{
+ UINT8 idx;
+ tLLCP_APP_CB *p_app_cb;
+
+ LLCP_TRACE_API1 ("LLCP_Deregister () SAP:0x%x", local_sap);
+
+ p_app_cb = llcp_util_get_app_cb (local_sap);
+
+ if ((!p_app_cb) || (p_app_cb->p_app_cback == NULL))
+ {
+ LLCP_TRACE_ERROR1 ("LLCP_Deregister (): SAP (0x%x) is not registered", local_sap);
+ return LLCP_STATUS_FAIL;
+ }
+
+ if (p_app_cb->p_service_name)
+ GKI_freebuf (p_app_cb->p_service_name);
+
+ /* update WKS bit map */
+ if (local_sap <= LLCP_UPPER_BOUND_WK_SAP)
+ {
+ llcp_cb.lcb.wks &= ~ (1 << local_sap);
+ }
+
+ /* discard any received UI PDU on this SAP */
+ LLCP_FlushLogicalLinkRxData (local_sap);
+ llcp_cb.total_rx_ui_pdu = 0;
+
+ /* deallocate any data link connection on this SAP */
+ for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++)
+ {
+ if ( (llcp_cb.dlcb[idx].state != LLCP_DLC_STATE_IDLE)
+ &&(llcp_cb.dlcb[idx].local_sap == local_sap) )
+ {
+ llcp_util_deallocate_data_link (&llcp_cb.dlcb[idx]);
+ }
+ }
+
+ p_app_cb->p_app_cback = NULL;
+
+ /* discard any pending tx UI PDU from this SAP */
+ while (p_app_cb->ui_xmit_q.p_first)
+ {
+ GKI_freebuf (GKI_dequeue (&p_app_cb->ui_xmit_q));
+ llcp_cb.total_tx_ui_pdu--;
+ }
+
+ if (p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)
+ {
+ llcp_cb.num_logical_data_link--;
+ llcp_util_adjust_ll_congestion ();
+ }
+
+ /* check rx congestion status */
+ llcp_util_check_rx_congested_status ();
+
+ return LLCP_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function LLCP_IsLogicalLinkCongested
+**
+** Description Check if logical link is congested
+**
+**
+** Returns TRUE if congested
+**
+*******************************************************************************/
+BOOLEAN LLCP_IsLogicalLinkCongested (UINT8 local_sap,
+ UINT8 num_pending_ui_pdu,
+ UINT8 total_pending_ui_pdu,
+ UINT8 total_pending_i_pdu)
+{
+ tLLCP_APP_CB *p_app_cb;
+
+ LLCP_TRACE_API4 ("LLCP_IsLogicalLinkCongested () Local SAP:0x%x, pending = (%d, %d, %d)",
+ local_sap, num_pending_ui_pdu, total_pending_ui_pdu, total_pending_i_pdu);
+
+ p_app_cb = llcp_util_get_app_cb (local_sap);
+
+ if ( (llcp_cb.lcb.link_state != LLCP_LINK_STATE_ACTIVATED)
+ ||(p_app_cb == NULL)
+ ||(p_app_cb->p_app_cback == NULL)
+ ||((p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0)
+ ||(p_app_cb->is_ui_tx_congested) )
+ {
+ return (TRUE);
+ }
+ else if ( (num_pending_ui_pdu + p_app_cb->ui_xmit_q.count >= llcp_cb.ll_tx_congest_start)
+ ||(total_pending_ui_pdu + llcp_cb.total_tx_ui_pdu >= llcp_cb.max_num_ll_tx_buff)
+ ||(total_pending_ui_pdu + total_pending_i_pdu + llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu >= llcp_cb.max_num_tx_buff) )
+ {
+ /* set flag so LLCP can notify uncongested status later */
+ p_app_cb->is_ui_tx_congested = TRUE;
+
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+/*******************************************************************************
+**
+** Function LLCP_SendUI
+**
+** Description Send connnectionless data to DSAP
+**
+**
+** Returns LLCP_STATUS_SUCCESS if success
+** LLCP_STATUS_CONGESTED if logical link is congested
+** LLCP_STATUS_FAIL, otherwise
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_SendUI (UINT8 ssap,
+ UINT8 dsap,
+ BT_HDR *p_buf)
+{
+ tLLCP_STATUS status = LLCP_STATUS_FAIL;
+ tLLCP_APP_CB *p_app_cb;
+
+ LLCP_TRACE_API2 ("LLCP_SendUI () SSAP=0x%x, DSAP=0x%x", ssap, dsap);
+
+ p_app_cb = llcp_util_get_app_cb (ssap);
+
+ if ( (p_app_cb == NULL)
+ ||(p_app_cb->p_app_cback == NULL) )
+ {
+ LLCP_TRACE_ERROR1 ("LLCP_SendUI (): SSAP (0x%x) is not registered", ssap);
+ }
+ else if ((p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0)
+ {
+ LLCP_TRACE_ERROR1 ("LLCP_SendUI (): Logical link on SSAP (0x%x) is not enabled", ssap);
+ }
+ else if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_ACTIVATED)
+ {
+ LLCP_TRACE_ERROR0 ("LLCP_SendUI (): LLCP link is not activated");
+ }
+ else if ( (llcp_cb.lcb.peer_opt == LLCP_LSC_UNKNOWN)
+ ||(llcp_cb.lcb.peer_opt & LLCP_LSC_1) )
+ {
+ if (p_buf->len <= llcp_cb.lcb.peer_miu)
+ {
+ if (p_buf->offset >= LLCP_MIN_OFFSET)
+ {
+ status = llcp_util_send_ui (ssap, dsap, p_app_cb, p_buf);
+ }
+ else
+ {
+ LLCP_TRACE_ERROR2 ("LLCP_SendUI (): offset (%d) must be %d at least",
+ p_buf->offset, LLCP_MIN_OFFSET );
+ }
+ }
+ else
+ {
+ LLCP_TRACE_ERROR0 ("LLCP_SendUI (): Data length shall not be bigger than peer's link MIU");
+ }
+ }
+ else
+ {
+ LLCP_TRACE_ERROR0 ("LLCP_SendUI (): Peer doesn't support connectionless link");
+ }
+
+ if (status == LLCP_STATUS_FAIL)
+ {
+ GKI_freebuf (p_buf);
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function LLCP_ReadLogicalLinkData
+**
+** Description Read information of UI PDU for local SAP
+**
+** - Remote SAP who sent UI PDU is returned.
+** - Information of UI PDU up to max_data_len is copied into p_data.
+** - Information of next UI PDU is not concatenated.
+** - Recommended max_data_len is link MIU of local device
+**
+** Returns TRUE if more information of UI PDU or more UI PDU in queue
+**
+*******************************************************************************/
+BOOLEAN LLCP_ReadLogicalLinkData (UINT8 local_sap,
+ UINT32 max_data_len,
+ UINT8 *p_remote_sap,
+ UINT32 *p_data_len,
+ UINT8 *p_data)
+{
+ tLLCP_APP_CB *p_app_cb;
+ BT_HDR *p_buf;
+ UINT8 *p_ui_pdu;
+ UINT16 pdu_hdr, ui_pdu_length;
+
+ LLCP_TRACE_API1 ("LLCP_ReadLogicalLinkData () Local SAP:0x%x", local_sap);
+
+ *p_data_len = 0;
+
+ p_app_cb = llcp_util_get_app_cb (local_sap);
+
+ /* if application is registered */
+ if ((p_app_cb) && (p_app_cb->p_app_cback))
+ {
+ /* if any UI PDU in rx queue */
+ if (p_app_cb->ui_rx_q.p_first)
+ {
+ p_buf = (BT_HDR *) p_app_cb->ui_rx_q.p_first;
+ p_ui_pdu = (UINT8*) (p_buf + 1) + p_buf->offset;
+
+ /* get length of UI PDU */
+ BE_STREAM_TO_UINT16 (ui_pdu_length, p_ui_pdu);
+
+ /* get remote SAP from LLCP header */
+ BE_STREAM_TO_UINT16 (pdu_hdr, p_ui_pdu);
+ *p_remote_sap = LLCP_GET_SSAP (pdu_hdr);
+
+ /* layer_specific has the offset to read within UI PDU */
+ p_ui_pdu += p_buf->layer_specific;
+
+ /* copy data up to max_data_len */
+ if (max_data_len >= (UINT32) (ui_pdu_length - LLCP_PDU_HEADER_SIZE - p_buf->layer_specific))
+ {
+ /* copy information without LLCP header */
+ *p_data_len = (UINT32) (ui_pdu_length - LLCP_PDU_HEADER_SIZE - p_buf->layer_specific);
+
+ /* move to next UI PDU if any */
+ p_buf->layer_specific = 0; /* reset offset to read from the first byte of next UI PDU */
+ p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
+ p_buf->len -= LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
+ }
+ else
+ {
+ *p_data_len = max_data_len;
+
+ /* update offset to read from remaining UI PDU next time */
+ p_buf->layer_specific += max_data_len;
+ }
+
+ memcpy (p_data, p_ui_pdu, *p_data_len);
+
+ /* if read all of UI PDU */
+ if (p_buf->len == 0)
+ {
+ GKI_dequeue (&p_app_cb->ui_rx_q);
+ GKI_freebuf (p_buf);
+
+ /* decrease number of received UI PDU in in all of ui_rx_q and check rx congestion status */
+ llcp_cb.total_rx_ui_pdu--;
+ llcp_util_check_rx_congested_status ();
+ }
+ }
+
+ /* if there is more UI PDU in rx queue */
+ if (p_app_cb->ui_rx_q.p_first)
+ {
+ return (TRUE);
+ }
+ else
+ {
+ return (FALSE);
+ }
+ }
+ else
+ {
+ LLCP_TRACE_ERROR1 ("LLCP_ReadLogicalLinkData (): Unregistered SAP:0x%x", local_sap);
+
+ return (FALSE);
+ }
+}
+
+/*******************************************************************************
+**
+** Function LLCP_FlushLogicalLinkRxData
+**
+** Description Discard received data in logical data link of local SAP
+**
+**
+** Returns length of data flushed
+**
+*******************************************************************************/
+UINT32 LLCP_FlushLogicalLinkRxData (UINT8 local_sap)
+{
+ BT_HDR *p_buf;
+ UINT32 flushed_length = 0;
+ tLLCP_APP_CB *p_app_cb;
+ UINT8 *p_ui_pdu;
+ UINT16 ui_pdu_length;
+
+ LLCP_TRACE_API1 ("LLCP_FlushLogicalLinkRxData () Local SAP:0x%x", local_sap);
+
+ p_app_cb = llcp_util_get_app_cb (local_sap);
+
+ /* if application is registered */
+ if ((p_app_cb) && (p_app_cb->p_app_cback))
+ {
+ /* if any UI PDU in rx queue */
+ while (p_app_cb->ui_rx_q.p_first)
+ {
+ p_buf = (BT_HDR *) p_app_cb->ui_rx_q.p_first;
+ p_ui_pdu = (UINT8*) (p_buf + 1) + p_buf->offset;
+
+ /* get length of UI PDU */
+ BE_STREAM_TO_UINT16 (ui_pdu_length, p_ui_pdu);
+
+ flushed_length += (UINT32) (ui_pdu_length - LLCP_PDU_HEADER_SIZE - p_buf->layer_specific);
+
+ /* move to next UI PDU if any */
+ p_buf->layer_specific = 0; /* offset */
+ p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
+ p_buf->len -= LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
+
+ /* if read all of UI PDU */
+ if (p_buf->len == 0)
+ {
+ GKI_dequeue (&p_app_cb->ui_rx_q);
+ GKI_freebuf (p_buf);
+ llcp_cb.total_rx_ui_pdu--;
+ }
+ }
+
+ /* number of received UI PDU is decreased so check rx congestion status */
+ llcp_util_check_rx_congested_status ();
+ }
+ else
+ {
+ LLCP_TRACE_ERROR1 ("LLCP_FlushLogicalLinkRxData (): Unregistered SAP:0x%x", local_sap);
+ }
+
+ return (flushed_length);
+}
+
+/*******************************************************************************
+**
+** Function LLCP_ConnectReq
+**
+** Description Create data link connection between registered SAP and DSAP
+** in peer LLCP,
+**
+**
+** Returns LLCP_STATUS_SUCCESS if success
+** LLCP_STATUS_FAIL, otherwise
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_ConnectReq (UINT8 reg_sap,
+ UINT8 dsap,
+ tLLCP_CONNECTION_PARAMS *p_params)
+{
+ tLLCP_DLCB *p_dlcb;
+ tLLCP_STATUS status;
+ tLLCP_APP_CB *p_app_cb;
+ 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 = ¶ms;
+ }
+
+ p_app_cb = llcp_util_get_app_cb (reg_sap);
+
+ /* if application is registered */
+ if ( (p_app_cb == NULL)
+ ||(p_app_cb->p_app_cback == NULL) )
+ {
+ LLCP_TRACE_ERROR1 ("LLCP_ConnectReq (): SSAP (0x%x) is not registered", reg_sap);
+ return LLCP_STATUS_FAIL;
+ }
+
+ if (dsap == LLCP_SAP_LM)
+ {
+ LLCP_TRACE_ERROR1 ("LLCP_ConnectReq (): DSAP (0x%x) must not be link manager SAP", dsap);
+ return LLCP_STATUS_FAIL;
+ }
+
+ if (dsap == LLCP_SAP_SDP)
+ {
+ if (strlen (p_params->sn) > LLCP_MAX_SN_LEN)
+ {
+ LLCP_TRACE_ERROR1 ("LLCP_ConnectReq (): Service Name (%d bytes) is too long",
+ strlen (p_params->sn));
+ return LLCP_STATUS_FAIL;
+ }
+ }
+
+ if ((p_params) && (p_params->miu > llcp_cb.lcb.local_link_miu))
+ {
+ LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): Data link MIU shall not be bigger than local link MIU");
+ return LLCP_STATUS_FAIL;
+ }
+
+ /* check if any pending connection request on this reg_sap */
+ p_dlcb = llcp_dlc_find_dlcb_by_sap (reg_sap, LLCP_INVALID_SAP);
+ if (p_dlcb)
+ {
+ /*
+ ** Accepting LLCP may change SAP in CC, so we cannot find right data link connection
+ ** if there is multiple pending connection request on the same local SAP.
+ */
+ LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): There is pending connect request on this reg_sap");
+ return LLCP_STATUS_FAIL;
+ }
+
+ p_dlcb = llcp_util_allocate_data_link (reg_sap, dsap);
+
+ if (p_dlcb)
+ {
+ status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_CONNECT_REQ, p_params);
+ if (status != LLCP_STATUS_SUCCESS)
+ {
+ LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): Error in state machine");
+ llcp_util_deallocate_data_link (p_dlcb);
+ return LLCP_STATUS_FAIL;
+ }
+ }
+ else
+ {
+ return LLCP_STATUS_FAIL;
+ }
+
+ return LLCP_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function LLCP_ConnectCfm
+**
+** Description Accept connection request from peer LLCP
+**
+**
+** Returns LLCP_STATUS_SUCCESS if success
+** LLCP_STATUS_FAIL, otherwise
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_ConnectCfm (UINT8 local_sap,
+ UINT8 remote_sap,
+ tLLCP_CONNECTION_PARAMS *p_params)
+{
+ tLLCP_STATUS status;
+ tLLCP_DLCB *p_dlcb;
+ 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 = ¶ms;
+ }
+ 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 local_sap,
+ UINT8 remote_sap,
+ UINT8 reason)
+{
+ tLLCP_STATUS status;
+ tLLCP_DLCB *p_dlcb;
+
+ LLCP_TRACE_API3 ("LLCP_ConnectReject () Local SAP:0x%x, Remote SAP:0x%x, reason:0x%x",
+ local_sap, remote_sap, reason);
+
+ p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
+
+ if (p_dlcb)
+ {
+ status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_CONNECT_REJECT, &reason);
+ llcp_util_deallocate_data_link (p_dlcb);
+ }
+ else
+ {
+ LLCP_TRACE_ERROR0 ("LLCP_ConnectReject (): No data link");
+ status = LLCP_STATUS_FAIL;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function LLCP_IsDataLinkCongested
+**
+** Description Check if data link connection is congested
+**
+**
+** Returns TRUE if congested
+**
+*******************************************************************************/
+BOOLEAN LLCP_IsDataLinkCongested (UINT8 local_sap,
+ UINT8 remote_sap,
+ UINT8 num_pending_i_pdu,
+ UINT8 total_pending_ui_pdu,
+ UINT8 total_pending_i_pdu)
+{
+ tLLCP_DLCB *p_dlcb;
+
+ LLCP_TRACE_API5 ("LLCP_IsDataLinkCongested () Local SAP:0x%x, Remote SAP:0x%x, pending = (%d, %d, %d)",
+ local_sap, remote_sap, num_pending_i_pdu, total_pending_ui_pdu, total_pending_i_pdu);
+
+ p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
+
+ if (p_dlcb)
+ {
+ if ( (p_dlcb->is_tx_congested)
+ ||(p_dlcb->remote_busy) )
+ {
+ return (TRUE);
+ }
+ else if ( (num_pending_i_pdu + p_dlcb->i_xmit_q.count >= p_dlcb->remote_rw)
+ ||(total_pending_ui_pdu + total_pending_i_pdu + llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu >= llcp_cb.max_num_tx_buff) )
+ {
+ /* set flag so LLCP can notify uncongested status later */
+ p_dlcb->is_tx_congested = TRUE;
+ return (TRUE);
+ }
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function LLCP_SendData
+**
+** Description Send connection-oriented data
+**
+**
+** Returns LLCP_STATUS_SUCCESS if success
+** LLCP_STATUS_CONGESTED if data link is congested
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_SendData (UINT8 local_sap,
+ UINT8 remote_sap,
+ BT_HDR *p_buf)
+{
+ tLLCP_STATUS status = LLCP_STATUS_FAIL;
+ tLLCP_DLCB *p_dlcb;
+
+ LLCP_TRACE_API2 ("LLCP_SendData () Local SAP:0x%x, Remote SAP:0x%x",
+ local_sap, remote_sap);
+
+ p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
+
+ if (p_dlcb)
+ {
+ if (p_dlcb->remote_miu >= p_buf->len)
+ {
+ if (p_buf->offset >= LLCP_MIN_OFFSET)
+ {
+ status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DATA_REQ, p_buf);
+ }
+ else
+ {
+ LLCP_TRACE_ERROR2 ("LLCP_SendData (): offset (%d) must be %d at least",
+ p_buf->offset, LLCP_MIN_OFFSET );
+ }
+ }
+ else
+ {
+ LLCP_TRACE_ERROR2 ("LLCP_SendData (): Information (%d bytes) cannot be more than peer MIU (%d bytes)",
+ p_buf->len, p_dlcb->remote_miu);
+ }
+ }
+ else
+ {
+ LLCP_TRACE_ERROR0 ("LLCP_SendData (): No data link");
+ }
+
+ if (status == LLCP_STATUS_FAIL)
+ {
+ GKI_freebuf (p_buf);
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function LLCP_ReadDataLinkData
+**
+** Description Read information of I PDU for data link connection
+**
+** - Information of I PDU up to max_data_len is copied into p_data.
+** - Information of next I PDU is not concatenated.
+** - Recommended max_data_len is data link connection MIU of local
+** end point
+**
+** Returns TRUE if more data in queue
+**
+*******************************************************************************/
+BOOLEAN LLCP_ReadDataLinkData (UINT8 local_sap,
+ UINT8 remote_sap,
+ UINT32 max_data_len,
+ UINT32 *p_data_len,
+ UINT8 *p_data)
+{
+ tLLCP_DLCB *p_dlcb;
+ BT_HDR *p_buf;
+ UINT8 *p_i_pdu;
+ UINT16 i_pdu_length;
+
+ LLCP_TRACE_API2 ("LLCP_ReadDataLinkData () Local SAP:0x%x, Remote SAP:0x%x",
+ local_sap, remote_sap);
+
+ p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
+
+ *p_data_len = 0;
+ if (p_dlcb)
+ {
+ /* if any I PDU in rx queue */
+ if (p_dlcb->i_rx_q.p_first)
+ {
+ p_buf = (BT_HDR *) p_dlcb->i_rx_q.p_first;
+ p_i_pdu = (UINT8*) (p_buf + 1) + p_buf->offset;
+
+ /* get length of I PDU */
+ BE_STREAM_TO_UINT16 (i_pdu_length, p_i_pdu);
+
+ /* layer_specific has the offset to read within I PDU */
+ p_i_pdu += p_buf->layer_specific;
+
+ /* copy data up to max_data_len */
+ if (max_data_len >= (UINT32) (i_pdu_length - p_buf->layer_specific))
+ {
+ /* copy information */
+ *p_data_len = (UINT32) (i_pdu_length - p_buf->layer_specific);
+
+ /* move to next I PDU if any */
+ p_buf->layer_specific = 0; /* reset offset to read from the first byte of next I PDU */
+ p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
+ p_buf->len -= LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
+ }
+ else
+ {
+ *p_data_len = max_data_len;
+
+ /* update offset to read from remaining I PDU next time */
+ p_buf->layer_specific += max_data_len;
+ }
+
+ memcpy (p_data, p_i_pdu, *p_data_len);
+
+ if (p_buf->layer_specific == 0)
+ {
+ p_dlcb->num_rx_i_pdu--;
+ }
+
+ /* if read all of I PDU */
+ if (p_buf->len == 0)
+ {
+ GKI_dequeue (&p_dlcb->i_rx_q);
+ GKI_freebuf (p_buf);
+
+ /* decrease number of received I PDU in in all of ui_rx_q and check rx congestion status */
+ llcp_cb.total_rx_i_pdu--;
+ llcp_util_check_rx_congested_status ();
+ }
+ }
+
+ /* if getting out of rx congestion */
+ if ( (!p_dlcb->local_busy)
+ &&(p_dlcb->is_rx_congested)
+ &&(p_dlcb->num_rx_i_pdu <= p_dlcb->rx_congest_threshold / 2) )
+ {
+ /* send RR */
+ p_dlcb->is_rx_congested = FALSE;
+ p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
+ }
+
+ /* if there is more I PDU in rx queue */
+ if (p_dlcb->i_rx_q.p_first)
+ {
+ return (TRUE);
+ }
+ else
+ {
+ return (FALSE);
+ }
+ }
+ else
+ {
+ LLCP_TRACE_ERROR0 ("LLCP_ReadDataLinkData (): No data link connection");
+
+ return (FALSE);
+ }
+}
+
+/*******************************************************************************
+**
+** Function LLCP_FlushDataLinkRxData
+**
+** Description Discard received data in data link connection
+**
+**
+** Returns length of rx data flushed
+**
+*******************************************************************************/
+UINT32 LLCP_FlushDataLinkRxData (UINT8 local_sap,
+ UINT8 remote_sap)
+{
+ tLLCP_DLCB *p_dlcb;
+ BT_HDR *p_buf;
+ UINT32 flushed_length = 0;
+ UINT8 *p_i_pdu;
+ UINT16 i_pdu_length;
+
+ LLCP_TRACE_API2 ("LLCP_FlushDataLinkRxData () Local SAP:0x%x, Remote SAP:0x%x",
+ local_sap, remote_sap);
+
+ p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
+
+ if (p_dlcb)
+ {
+ /* if any I PDU in rx queue */
+ while (p_dlcb->i_rx_q.p_first)
+ {
+ p_buf = (BT_HDR *) p_dlcb->i_rx_q.p_first;
+ p_i_pdu = (UINT8*) (p_buf + 1) + p_buf->offset;
+
+ /* get length of I PDU */
+ BE_STREAM_TO_UINT16 (i_pdu_length, p_i_pdu);
+
+ flushed_length += (UINT32) (i_pdu_length - p_buf->layer_specific);
+
+ /* move to next I PDU if any */
+ p_buf->layer_specific = 0; /* offset */
+ p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
+ p_buf->len -= LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
+
+ /* if read all of I PDU */
+ if (p_buf->len == 0)
+ {
+ GKI_dequeue (&p_dlcb->i_rx_q);
+ GKI_freebuf (p_buf);
+ llcp_cb.total_rx_i_pdu--;
+ }
+ }
+
+ p_dlcb->num_rx_i_pdu = 0;
+
+ /* if getting out of rx congestion */
+ if ( (!p_dlcb->local_busy)
+ &&(p_dlcb->is_rx_congested) )
+ {
+ /* send RR */
+ p_dlcb->is_rx_congested = FALSE;
+ p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
+ }
+
+ /* number of received I PDU is decreased so check rx congestion status */
+ llcp_util_check_rx_congested_status ();
+ }
+ else
+ {
+ LLCP_TRACE_ERROR0 ("LLCP_FlushDataLinkRxData (): No data link connection");
+ }
+
+ return (flushed_length);
+}
+
+/*******************************************************************************
+**
+** Function LLCP_DisconnectReq
+**
+** Description Disconnect data link
+** discard any pending data if flush is set to TRUE
+**
+** Returns LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_DisconnectReq (UINT8 local_sap,
+ UINT8 remote_sap,
+ BOOLEAN flush)
+{
+ tLLCP_STATUS status;
+ tLLCP_DLCB *p_dlcb;
+
+ LLCP_TRACE_API3 ("LLCP_DisconnectReq () Local SAP:0x%x, Remote SAP:0x%x, flush=%d",
+ local_sap, remote_sap, flush);
+
+ p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
+
+ if (p_dlcb)
+ {
+ status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
+ }
+ else
+ {
+ LLCP_TRACE_ERROR0 ("LLCP_DisconnectReq (): No data link");
+ status = LLCP_STATUS_FAIL;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function LLCP_SetTxCompleteNtf
+**
+** Description This function is called to get LLCP_SERVICE_TX_COMPLETE
+** when Tx queue is empty and all PDU is acked.
+** This is one time event, so upper layer shall call this function
+** again to get next LLCP_SERVICE_TX_COMPLETE.
+**
+** Returns LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_SetTxCompleteNtf (UINT8 local_sap,
+ UINT8 remote_sap)
+{
+ tLLCP_STATUS status;
+ tLLCP_DLCB *p_dlcb;
+
+ LLCP_TRACE_API2 ("LLCP_SetTxCompleteNtf () Local SAP:0x%x, Remote SAP:0x%x",
+ local_sap, remote_sap);
+
+ p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
+
+ if (p_dlcb)
+ {
+ /* set flag to notify upper later when tx complete */
+ p_dlcb->flags |= LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE;
+ status = LLCP_STATUS_SUCCESS;
+ }
+ else
+ {
+ LLCP_TRACE_ERROR0 ("LLCP_SetTxCompleteNtf (): No data link");
+ status = LLCP_STATUS_FAIL;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function LLCP_SetLocalBusyStatus
+**
+** Description Set local busy status
+**
+**
+** Returns LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_SetLocalBusyStatus (UINT8 local_sap,
+ UINT8 remote_sap,
+ BOOLEAN is_busy)
+{
+ tLLCP_STATUS status;
+ tLLCP_DLCB *p_dlcb;
+
+ LLCP_TRACE_API2 ("LLCP_SetLocalBusyStatus () Local SAP:0x%x, is_busy=%d",
+ local_sap, is_busy);
+
+ p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
+
+ if (p_dlcb)
+ {
+ if (p_dlcb->local_busy != is_busy)
+ {
+ p_dlcb->local_busy = is_busy;
+
+ /* send RR or RNR with valid sequence */
+ p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
+
+ if (is_busy == FALSE)
+ {
+ if (p_dlcb->i_rx_q.count)
+ {
+ llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DATA_IND, NULL);
+ }
+ }
+ }
+ status = LLCP_STATUS_SUCCESS;
+ }
+ else
+ {
+ LLCP_TRACE_ERROR0 ("LLCP_SetLocalBusyStatus (): No data link");
+ status = LLCP_STATUS_FAIL;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function LLCP_GetRemoteWKS
+**
+** Description Return well-known service bitmap of connected device
+**
+**
+** Returns WKS bitmap if success
+**
+*******************************************************************************/
+UINT16 LLCP_GetRemoteWKS (void)
+{
+ LLCP_TRACE_API1 ("LLCP_GetRemoteWKS () WKS:0x%04x",
+ (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED) ? llcp_cb.lcb.peer_wks :0);
+
+ if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
+ return (llcp_cb.lcb.peer_wks);
+ else
+ return (0);
+}
+
+/*******************************************************************************
+**
+** Function LLCP_GetRemoteLSC
+**
+** Description Return link service class of connected device
+**
+**
+** Returns link service class
+**
+*******************************************************************************/
+UINT8 LLCP_GetRemoteLSC (void)
+{
+ LLCP_TRACE_API1 ("LLCP_GetRemoteLSC () LSC:0x%x",
+ (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
+ ? llcp_cb.lcb.peer_opt & (LLCP_LSC_1 | LLCP_LSC_2) :0);
+
+ if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
+ return (llcp_cb.lcb.peer_opt & (LLCP_LSC_1 | LLCP_LSC_2));
+ else
+ return (LLCP_LSC_UNKNOWN);
+}
+
+/*******************************************************************************
+**
+** Function LLCP_GetLinkMIU
+**
+** Description Return local and remote link MIU
+**
+**
+** Returns None
+**
+*******************************************************************************/
+LLCP_API void LLCP_GetLinkMIU (UINT16 *p_local_link_miu,
+ UINT16 *p_remote_link_miu)
+{
+ LLCP_TRACE_API0 ("LLCP_GetLinkMIU ()");
+
+ if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
+ {
+ *p_local_link_miu = llcp_cb.lcb.local_link_miu;
+ *p_remote_link_miu = llcp_cb.lcb.effective_miu;
+ }
+ else
+ {
+ *p_local_link_miu = 0;
+ *p_remote_link_miu = 0;
+ }
+
+ LLCP_TRACE_DEBUG2 ("LLCP_GetLinkMIU (): local_link_miu = %d, remote_link_miu = %d",
+ *p_local_link_miu, *p_remote_link_miu);
+}
+
+/*******************************************************************************
+**
+** Function LLCP_DiscoverService
+**
+** Description Return SAP of service name in connected device through callback
+**
+**
+** Returns LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_DiscoverService (char *p_name,
+ tLLCP_SDP_CBACK *p_cback,
+ UINT8 *p_tid)
+{
+ tLLCP_STATUS status;
+ UINT8 i;
+
+ LLCP_TRACE_API1 ("LLCP_DiscoverService () Service Name:%s",
+ p_name);
+
+ if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_ACTIVATED)
+ {
+ LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Link is not activated");
+ return LLCP_STATUS_FAIL;
+ }
+
+ if (!p_cback)
+ {
+ LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Callback must be provided.");
+ return LLCP_STATUS_FAIL;
+ }
+
+ /* if peer version is less than V1.1 then SNL is not supported */
+ if ((llcp_cb.lcb.agreed_major_version == 0x01) && (llcp_cb.lcb.agreed_minor_version < 0x01))
+ {
+ LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Peer doesn't support SNL");
+ return LLCP_STATUS_FAIL;
+ }
+
+ for (i = 0; i < LLCP_MAX_SDP_TRANSAC; i++)
+ {
+ if (!llcp_cb.sdp_cb.transac[i].p_cback)
+ {
+ llcp_cb.sdp_cb.transac[i].tid = llcp_cb.sdp_cb.next_tid;
+ llcp_cb.sdp_cb.next_tid++;
+ llcp_cb.sdp_cb.transac[i].p_cback = p_cback;
+
+ status = llcp_sdp_send_sdreq (llcp_cb.sdp_cb.transac[i].tid, p_name);
+
+ if (status == LLCP_STATUS_FAIL)
+ {
+ llcp_cb.sdp_cb.transac[i].p_cback = NULL;
+ }
+
+ *p_tid = llcp_cb.sdp_cb.transac[i].tid;
+ return (status);
+ }
+ }
+
+ LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Out of resource");
+
+ return LLCP_STATUS_FAIL;
+}
diff --git a/src/nfc/llcp/llcp_dlc.c b/src/nfc/llcp/llcp_dlc.c
new file mode 100644
index 0000000..9afdc98
--- /dev/null
+++ b/src/nfc/llcp/llcp_dlc.c
@@ -0,0 +1,1524 @@
+/******************************************************************************
+ *
+ * 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 Data Link Connection Management
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include "gki.h"
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "llcp_int.h"
+#include "llcp_defs.h"
+#include "nfc_int.h"
+
+static tLLCP_STATUS llcp_dlsm_idle (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data);
+static tLLCP_STATUS llcp_dlsm_w4_remote_resp (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data);
+static tLLCP_STATUS llcp_dlsm_w4_local_resp (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data);
+static tLLCP_STATUS llcp_dlsm_connected (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data);
+static tLLCP_STATUS llcp_dlsm_w4_remote_dm (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data);
+
+#if (BT_TRACE_VERBOSE == TRUE)
+static char *llcp_dlsm_get_state_name (tLLCP_DLC_STATE state);
+static char *llcp_dlsm_get_event_name (tLLCP_DLC_EVENT event);
+#endif
+
+/*******************************************************************************
+**
+** Function llcp_dlsm_execute
+**
+** Description This function executes the state machine for data link connection.
+**
+** Returns tLLCP_STATUS
+**
+*******************************************************************************/
+tLLCP_STATUS llcp_dlsm_execute (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
+{
+ tLLCP_STATUS status;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ LLCP_TRACE_EVENT3 ("DLC (0x%02X) - state: %s, evt: %s",
+ p_dlcb->local_sap,
+ llcp_dlsm_get_state_name (p_dlcb->state),
+ llcp_dlsm_get_event_name (event));
+#else
+ LLCP_TRACE_EVENT3 ("DLC (0x%02X) - state: %d, evt: %d", p_dlcb->local_sap, p_dlcb->state, event);
+#endif
+
+ switch (p_dlcb->state)
+ {
+ case LLCP_DLC_STATE_IDLE:
+ status = llcp_dlsm_idle (p_dlcb, event, p_data);
+ break;
+
+ case LLCP_DLC_STATE_W4_REMOTE_RESP:
+ status = llcp_dlsm_w4_remote_resp (p_dlcb, event, p_data);
+ break;
+
+ case LLCP_DLC_STATE_W4_LOCAL_RESP:
+ status = llcp_dlsm_w4_local_resp (p_dlcb, event, p_data);
+ break;
+
+ case LLCP_DLC_STATE_CONNECTED:
+ status = llcp_dlsm_connected (p_dlcb, event, p_data);
+ break;
+
+ case LLCP_DLC_STATE_W4_REMOTE_DM:
+ status = llcp_dlsm_w4_remote_dm (p_dlcb, event, p_data);
+ break;
+
+ default:
+ status = LLCP_STATUS_FAIL;
+ break;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function llcp_dlsm_idle
+**
+** Description Data link connection is in idle state
+**
+** Returns tLLCP_STATUS
+**
+*******************************************************************************/
+static tLLCP_STATUS llcp_dlsm_idle (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
+{
+ tLLCP_STATUS status = LLCP_STATUS_SUCCESS;
+ tLLCP_SAP_CBACK_DATA data;
+ tLLCP_CONNECTION_PARAMS *p_params;
+
+ switch (event)
+ {
+ case LLCP_DLC_EVENT_API_CONNECT_REQ:
+
+ /* upper layer requests to create data link connection */
+ p_params = (tLLCP_CONNECTION_PARAMS *)p_data;
+
+ status = llcp_util_send_connect (p_dlcb, p_params);
+
+ if (status == LLCP_STATUS_SUCCESS)
+ {
+ p_dlcb->local_miu = p_params->miu;
+ p_dlcb->local_rw = p_params->rw;
+
+ /* wait for response from peer device */
+ p_dlcb->state = LLCP_DLC_STATE_W4_REMOTE_RESP;
+
+ nfc_start_quick_timer (&p_dlcb->timer, NFC_TTYPE_LLCP_DATA_LINK,
+ (UINT32) (llcp_cb.lcb.data_link_timeout * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+ }
+ break;
+
+ case LLCP_DLC_EVENT_PEER_CONNECT_IND:
+
+ /* peer device requests to create data link connection */
+ p_params = (tLLCP_CONNECTION_PARAMS *) p_data;
+
+ if (p_params->miu > llcp_cb.lcb.peer_miu)
+ {
+ LLCP_TRACE_WARNING0 ("llcp_dlsm_idle (): Peer sent data link MIU bigger than peer's link MIU");
+ p_params->miu = llcp_cb.lcb.peer_miu;
+ }
+
+ data.connect_ind.event = LLCP_SAP_EVT_CONNECT_IND;
+ data.connect_ind.remote_sap = p_dlcb->remote_sap;
+ data.connect_ind.local_sap = p_dlcb->local_sap;
+ data.connect_ind.miu = p_params->miu;
+ data.connect_ind.rw = p_params->rw;
+ data.connect_ind.p_service_name = p_params->sn;
+ data.connect_ind.server_sap = p_dlcb->local_sap;
+
+ p_dlcb->remote_miu = p_params->miu;
+ p_dlcb->remote_rw = p_params->rw;
+
+ LLCP_TRACE_DEBUG2 ("llcp_dlsm_idle (): Remote MIU:%d, RW:%d", p_dlcb->remote_miu, p_dlcb->remote_rw);
+
+ /* wait for response from upper layer */
+ p_dlcb->state = LLCP_DLC_STATE_W4_LOCAL_RESP;
+
+ nfc_start_quick_timer (&p_dlcb->timer, NFC_TTYPE_LLCP_DATA_LINK,
+ (UINT32) (llcp_cb.lcb.data_link_timeout * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+
+ (*p_dlcb->p_app_cb->p_app_cback) (&data);
+
+ break;
+
+ default:
+ LLCP_TRACE_ERROR0 ("llcp_dlsm_idle (): Unexpected event");
+ status = LLCP_STATUS_FAIL;
+ break;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function llcp_dlsm_w4_remote_resp
+**
+** Description data link connection is waiting for connection confirm from peer
+**
+** Returns tLLCP_STATUS
+**
+*******************************************************************************/
+static tLLCP_STATUS llcp_dlsm_w4_remote_resp (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
+{
+ tLLCP_STATUS status = LLCP_STATUS_SUCCESS;
+ tLLCP_SAP_CBACK_DATA data;
+ tLLCP_CONNECTION_PARAMS *p_params;
+
+ switch (event)
+ {
+ case LLCP_DLC_EVENT_PEER_CONNECT_CFM:
+
+ /* peer device accepted data link connection */
+ nfc_stop_quick_timer (&p_dlcb->timer);
+
+ p_params = (tLLCP_CONNECTION_PARAMS *) p_data;
+
+ /* data link MIU must be up to link MIU */
+ if (p_params->miu > llcp_cb.lcb.peer_miu)
+ {
+ LLCP_TRACE_WARNING0 ("llcp_dlsm_w4_remote_resp (): Peer sent data link MIU bigger than peer's link MIU");
+ p_params->miu = llcp_cb.lcb.peer_miu;
+ }
+
+ p_dlcb->remote_miu = p_params->miu;
+ p_dlcb->remote_rw = p_params->rw;
+
+ LLCP_TRACE_DEBUG2 ("llcp_dlsm_w4_remote_resp (): Remote MIU:%d, RW:%d", p_dlcb->remote_miu, p_dlcb->remote_rw);
+
+ p_dlcb->state = LLCP_DLC_STATE_CONNECTED;
+ llcp_util_adjust_dl_rx_congestion ();
+
+ data.connect_resp.event = LLCP_SAP_EVT_CONNECT_RESP;
+ data.connect_resp.remote_sap = p_dlcb->remote_sap;
+ data.connect_resp.local_sap = p_dlcb->local_sap;
+ data.connect_resp.miu = p_params->miu;
+ data.connect_resp.rw = p_params->rw;
+
+ (*p_dlcb->p_app_cb->p_app_cback) (&data);
+
+ if (llcp_cb.overall_rx_congested)
+ {
+ p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
+ }
+ break;
+
+ case LLCP_DLC_EVENT_PEER_DISCONNECT_RESP:
+ case LLCP_DLC_EVENT_TIMEOUT:
+
+ /* peer device rejected connection or didn't respond */
+ data.disconnect_resp.event = LLCP_SAP_EVT_DISCONNECT_RESP;
+ data.disconnect_resp.local_sap = p_dlcb->local_sap;
+ data.disconnect_resp.remote_sap = p_dlcb->remote_sap;
+ data.disconnect_resp.reason = *((UINT8*) p_data);
+ (*p_dlcb->p_app_cb->p_app_cback) (&data);
+
+ /* stop timer, flush any pending data in queue and deallocate control block */
+ llcp_util_deallocate_data_link (p_dlcb);
+
+ llcp_util_adjust_dl_rx_congestion ();
+ break;
+
+ case LLCP_DLC_EVENT_FRAME_ERROR:
+ case LLCP_DLC_EVENT_LINK_ERROR:
+
+ /* received bad frame or link is deactivated */
+ data.disconnect_ind.event = LLCP_SAP_EVT_DISCONNECT_IND;
+ data.disconnect_ind.local_sap = p_dlcb->local_sap;
+ data.disconnect_ind.remote_sap = p_dlcb->remote_sap;
+ (*p_dlcb->p_app_cb->p_app_cback) (&data);
+
+ llcp_util_deallocate_data_link (p_dlcb);
+ llcp_util_adjust_dl_rx_congestion ();
+ break;
+
+ default:
+ LLCP_TRACE_ERROR0 ("llcp_dlsm_w4_remote_resp (): Unexpected event");
+ status = LLCP_STATUS_FAIL;
+ break;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function llcp_dlsm_w4_local_resp
+**
+** Description data link connection is waiting for connection confirm from application
+**
+** Returns tLLCP_STATUS
+**
+*******************************************************************************/
+static tLLCP_STATUS llcp_dlsm_w4_local_resp (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
+{
+ tLLCP_STATUS status = LLCP_STATUS_SUCCESS;
+ tLLCP_CONNECTION_PARAMS *p_params;
+ tLLCP_SAP_CBACK_DATA data;
+ UINT8 reason;
+
+ switch (event)
+ {
+ case LLCP_DLC_EVENT_API_CONNECT_CFM:
+
+ /* upper layer accepted data link connection */
+ nfc_stop_quick_timer (&p_dlcb->timer);
+
+ p_params = (tLLCP_CONNECTION_PARAMS *) p_data;
+
+ p_dlcb->local_miu = p_params->miu;
+ p_dlcb->local_rw = p_params->rw;
+
+ p_dlcb->state = LLCP_DLC_STATE_CONNECTED;
+
+ if (llcp_cb.overall_rx_congested)
+ {
+ p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
+ }
+
+ status = llcp_util_send_cc (p_dlcb, p_params);
+
+ if (status == LLCP_STATUS_SUCCESS)
+ {
+ llcp_util_adjust_dl_rx_congestion ();
+ }
+ else
+ {
+ data.disconnect_ind.event = LLCP_SAP_EVT_DISCONNECT_IND;
+ data.disconnect_ind.local_sap = p_dlcb->local_sap;
+ data.disconnect_ind.remote_sap = p_dlcb->remote_sap;
+ (*p_dlcb->p_app_cb->p_app_cback) (&data);
+
+ llcp_util_deallocate_data_link (p_dlcb);
+ }
+ break;
+
+ case LLCP_DLC_EVENT_API_CONNECT_REJECT:
+ case LLCP_DLC_EVENT_TIMEOUT:
+
+ if (event == LLCP_DLC_EVENT_TIMEOUT)
+ reason = LLCP_SAP_DM_REASON_TEMP_REJECT_THIS;
+ else
+ reason = *((UINT8*) p_data);
+
+ /* upper layer rejected connection or didn't respond */
+ llcp_util_send_dm (p_dlcb->remote_sap, p_dlcb->local_sap, reason);
+
+ /* stop timer, flush any pending data in queue and deallocate control block */
+ llcp_util_deallocate_data_link (p_dlcb);
+ llcp_util_adjust_dl_rx_congestion ();
+ break;
+
+ case LLCP_DLC_EVENT_FRAME_ERROR:
+ case LLCP_DLC_EVENT_LINK_ERROR:
+
+ /* received bad frame or link is deactivated */
+ data.disconnect_ind.event = LLCP_SAP_EVT_DISCONNECT_IND;
+ data.disconnect_ind.local_sap = p_dlcb->local_sap;
+ data.disconnect_ind.remote_sap = p_dlcb->remote_sap;
+ (*p_dlcb->p_app_cb->p_app_cback) (&data);
+
+ llcp_util_deallocate_data_link (p_dlcb);
+ llcp_util_adjust_dl_rx_congestion ();
+ break;
+
+ default:
+ LLCP_TRACE_ERROR0 ("llcp_dlsm_w4_local_resp (): Unexpected event");
+ status = LLCP_STATUS_FAIL;
+ break;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function llcp_dlsm_connected
+**
+** Description data link connection is connected
+**
+** Returns tLLCP_STATUS
+**
+*******************************************************************************/
+static tLLCP_STATUS llcp_dlsm_connected (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
+{
+ BOOLEAN flush;
+ tLLCP_STATUS status = LLCP_STATUS_SUCCESS;
+ tLLCP_SAP_CBACK_DATA data;
+
+ switch (event)
+ {
+ case LLCP_DLC_EVENT_API_DISCONNECT_REQ:
+
+ /* upper layer requests to disconnect */
+ flush = *(BOOLEAN*) (p_data);
+
+ /*
+ ** if upper layer asks to discard any pending data
+ ** or there is no pending data/ack to send and it is not waiting for ack
+ */
+ if ( (flush)
+ ||( (p_dlcb->i_xmit_q.count == 0)
+ &&(p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq)
+ &&(p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq) ) )
+ {
+ /* wait for disconnect response */
+ p_dlcb->state = LLCP_DLC_STATE_W4_REMOTE_DM;
+
+ llcp_util_send_disc (p_dlcb->remote_sap, p_dlcb->local_sap );
+
+ nfc_start_quick_timer (&p_dlcb->timer, NFC_TTYPE_LLCP_DATA_LINK,
+ (UINT32) (llcp_cb.lcb.data_link_timeout * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+ }
+ else
+ {
+ /* set flag to send DISC when tx queue is empty */
+ p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_DISC;
+ }
+ break;
+
+ case LLCP_DLC_EVENT_PEER_DISCONNECT_IND:
+
+ /* peer device requests to disconnect */
+
+ /* send disconnect response and notify upper layer */
+ llcp_util_send_dm (p_dlcb->remote_sap, p_dlcb->local_sap, LLCP_SAP_DM_REASON_RESP_DISC );
+
+ data.disconnect_ind.event = LLCP_SAP_EVT_DISCONNECT_IND;
+ data.disconnect_ind.local_sap = p_dlcb->local_sap;
+ data.disconnect_ind.remote_sap = p_dlcb->remote_sap;
+ (*p_dlcb->p_app_cb->p_app_cback) (&data);
+
+ llcp_util_deallocate_data_link (p_dlcb);
+ llcp_util_adjust_dl_rx_congestion ();
+ break;
+
+ case LLCP_DLC_EVENT_API_DATA_REQ:
+
+ /* upper layer requests to send data */
+
+ /* if peer device can receive data */
+ if (p_dlcb->remote_rw)
+ {
+ /* enqueue data and check if data can be sent */
+ GKI_enqueue (&p_dlcb->i_xmit_q, p_data);
+ llcp_cb.total_tx_i_pdu++;
+
+ llcp_link_check_send_data ();
+
+ if ( (p_dlcb->is_tx_congested)
+ ||(llcp_cb.overall_tx_congested)
+ ||(p_dlcb->remote_busy)
+ ||(p_dlcb->i_xmit_q.count >= p_dlcb->remote_rw) ) /*if enough data to send next round */
+ {
+ LLCP_TRACE_DEBUG3 ("llcp_dlsm_connected (): Data link (SSAP:DSAP=0x%X:0x%X) congested: xmit_q.count=%d",
+ p_dlcb->local_sap, p_dlcb->remote_sap, p_dlcb->i_xmit_q.count);
+
+ /* set congested here so overall congestion check routine will not report event again */
+ p_dlcb->is_tx_congested = TRUE;
+ status = LLCP_STATUS_CONGESTED;
+ }
+ }
+ else
+ {
+ LLCP_TRACE_ERROR0 ("llcp_dlsm_connected (): Remote RW is zero: discard data");
+ /* buffer will be freed when returned to API function */
+ status = LLCP_STATUS_FAIL;
+ }
+ break;
+
+ case LLCP_DLC_EVENT_PEER_DATA_IND:
+ /* peer device sends data so notify upper layer to read data from data link connection */
+
+ data.data_ind.event = LLCP_SAP_EVT_DATA_IND;
+ data.data_ind.local_sap = p_dlcb->local_sap;
+ data.data_ind.link_type = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
+ data.data_ind.remote_sap = p_dlcb->remote_sap;
+
+ (*p_dlcb->p_app_cb->p_app_cback) (&data);
+ break;
+
+ case LLCP_DLC_EVENT_FRAME_ERROR:
+ case LLCP_DLC_EVENT_LINK_ERROR:
+
+ /* received bad frame or link is deactivated */
+ data.disconnect_ind.event = LLCP_SAP_EVT_DISCONNECT_IND;
+ data.disconnect_ind.local_sap = p_dlcb->local_sap;
+ data.disconnect_ind.remote_sap = p_dlcb->remote_sap;
+ (*p_dlcb->p_app_cb->p_app_cback) (&data);
+
+ llcp_util_deallocate_data_link (p_dlcb);
+ llcp_util_adjust_dl_rx_congestion ();
+ break;
+
+ default:
+ LLCP_TRACE_ERROR0 ("llcp_dlsm_connected (): Unexpected event");
+ status = LLCP_STATUS_FAIL;
+ break;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function llcp_dlsm_w4_remote_dm
+**
+** Description data link connection is waiting for disconnection confirm from peer
+**
+** Returns tLLCP_STATUS
+**
+*******************************************************************************/
+static tLLCP_STATUS llcp_dlsm_w4_remote_dm (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
+{
+ tLLCP_STATUS status = LLCP_STATUS_SUCCESS;
+ tLLCP_SAP_CBACK_DATA data;
+
+ switch (event)
+ {
+ case LLCP_DLC_EVENT_PEER_DISCONNECT_RESP:
+ case LLCP_DLC_EVENT_TIMEOUT:
+
+ /* peer device sends disconnect response or didn't responde */
+ data.disconnect_resp.event = LLCP_SAP_EVT_DISCONNECT_RESP;
+ data.disconnect_resp.local_sap = p_dlcb->local_sap;
+ data.disconnect_resp.remote_sap = p_dlcb->remote_sap;
+ data.disconnect_resp.reason = LLCP_SAP_DM_REASON_RESP_DISC;
+ (*p_dlcb->p_app_cb->p_app_cback) (&data);
+
+ llcp_util_deallocate_data_link (p_dlcb);
+ llcp_util_adjust_dl_rx_congestion ();
+ break;
+
+ case LLCP_DLC_EVENT_FRAME_ERROR:
+ case LLCP_DLC_EVENT_LINK_ERROR:
+
+ /* received bad frame or link is deactivated */
+ data.disconnect_ind.event = LLCP_SAP_EVT_DISCONNECT_IND;
+ data.disconnect_ind.local_sap = p_dlcb->local_sap;
+ data.disconnect_ind.remote_sap = p_dlcb->remote_sap;
+ (*p_dlcb->p_app_cb->p_app_cback) (&data);
+
+ llcp_util_deallocate_data_link (p_dlcb);
+ llcp_util_adjust_dl_rx_congestion ();
+ break;
+
+ case LLCP_DLC_EVENT_PEER_DATA_IND:
+ break;
+
+ case LLCP_DLC_EVENT_PEER_DISCONNECT_IND:
+ /* it's race condition, send disconnect response and wait for DM */
+ llcp_util_send_dm (p_dlcb->remote_sap, p_dlcb->local_sap, LLCP_SAP_DM_REASON_RESP_DISC );
+ break;
+
+ default:
+ LLCP_TRACE_ERROR0 ("llcp_dlsm_w4_remote_dm (): Unexpected event");
+ status = LLCP_STATUS_FAIL;
+ break;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function llcp_dlc_find_dlcb_by_local_sap
+**
+** Description Find tLLCP_DLCB by local SAP and remote SAP
+** if remote_sap is LLCP_INVALID_SAP, it will return a DLCB which
+** is waiting for CC from peer.
+**
+** Returns tLLCP_DLCB *
+**
+*******************************************************************************/
+tLLCP_DLCB *llcp_dlc_find_dlcb_by_sap (UINT8 local_sap, UINT8 remote_sap)
+{
+ int i;
+
+ for (i = 0; i < LLCP_MAX_DATA_LINK; i++)
+ {
+ if ( (llcp_cb.dlcb[i].state != LLCP_DLC_STATE_IDLE)
+ &&(llcp_cb.dlcb[i].local_sap == local_sap) )
+ {
+ if ((remote_sap == LLCP_INVALID_SAP) && (llcp_cb.dlcb[i].state == LLCP_DLC_STATE_W4_REMOTE_RESP))
+ {
+ /* Remote SAP has not been finalized because we are watiing for CC */
+ return (&llcp_cb.dlcb[i]);
+ }
+ else if (llcp_cb.dlcb[i].remote_sap == remote_sap)
+ {
+ return (&llcp_cb.dlcb[i]);
+ }
+ }
+ }
+ return NULL;
+}
+
+/*******************************************************************************
+**
+** Function llcp_dlc_flush_q
+**
+** Description Free buffers in tx and rx queue in data link
+**
+** Returns void
+**
+*******************************************************************************/
+void llcp_dlc_flush_q (tLLCP_DLCB *p_dlcb)
+{
+ if (p_dlcb)
+ {
+ LLCP_TRACE_DEBUG1 ("llcp_dlc_flush_q (): local SAP:0x%02X", p_dlcb->local_sap);
+
+ /* Release any held buffers */
+ while (p_dlcb->i_xmit_q.p_first)
+ {
+ GKI_freebuf (GKI_dequeue (&p_dlcb->i_xmit_q));
+ llcp_cb.total_tx_i_pdu--;
+ }
+
+ /* discard any received I PDU on data link including in AGF */
+ LLCP_FlushDataLinkRxData (p_dlcb->local_sap, p_dlcb->remote_sap);
+ }
+ else
+ {
+ LLCP_TRACE_ERROR0 ("llcp_dlc_flush_q (): p_dlcb is NULL");
+ }
+}
+
+/*******************************************************************************
+**
+** Function llcp_dlc_proc_connect_pdu
+**
+** Description Process CONNECT PDU
+**
+** Returns void
+**
+*******************************************************************************/
+static void llcp_dlc_proc_connect_pdu (UINT8 dsap, UINT8 ssap, UINT16 length, UINT8 *p_data)
+{
+ tLLCP_DLCB *p_dlcb;
+ tLLCP_STATUS status;
+ tLLCP_APP_CB *p_app_cb;
+
+ tLLCP_CONNECTION_PARAMS params;
+
+ LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_connect_pdu ()");
+
+ p_app_cb = llcp_util_get_app_cb (dsap);
+
+ if ( (p_app_cb == NULL)
+ ||(p_app_cb->p_app_cback == NULL)
+ ||((p_app_cb->link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0) )
+ {
+ LLCP_TRACE_ERROR1 ("llcp_dlc_proc_connect_pdu (): Unregistered SAP:0x%x", dsap);
+ llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_NO_SERVICE );
+ return;
+ }
+
+ /* parse CONNECT PDU and get connection parameters */
+ if (llcp_util_parse_connect (p_data, length, ¶ms) != LLCP_STATUS_SUCCESS)
+ {
+ LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): Bad format CONNECT");
+ 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) 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, ¶ms);
+ if (status != LLCP_STATUS_SUCCESS)
+ {
+ LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): Error in state machine");
+ llcp_util_deallocate_data_link (p_dlcb);
+ }
+ }
+ else
+ {
+ LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): Out of resource");
+ llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_TEMP_REJECT_ANY );
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function llcp_dlc_proc_disc_pdu
+**
+** Description Process DISC PDU
+**
+** Returns void
+**
+*******************************************************************************/
+static void llcp_dlc_proc_disc_pdu (UINT8 dsap, UINT8 ssap, UINT16 length, UINT8 *p_data)
+{
+ tLLCP_DLCB *p_dlcb;
+
+ LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_disc_pdu ()");
+
+ p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
+ if (p_dlcb)
+ {
+ if (length > 0)
+ {
+ LLCP_TRACE_ERROR1 ("llcp_dlc_proc_disc_pdu (): Received extra data (%d bytes) in DISC PDU", length);
+
+ llcp_util_send_frmr (p_dlcb, LLCP_FRMR_W_ERROR_FLAG|LLCP_FRMR_I_ERROR_FLAG, LLCP_PDU_DISC_TYPE, 0);
+ llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
+ }
+ else
+ {
+ llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DISCONNECT_IND, NULL);
+ }
+ }
+ else
+ {
+ LLCP_TRACE_ERROR2 ("llcp_dlc_proc_disc_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
+ }
+}
+
+/*******************************************************************************
+**
+** Function llcp_dlc_proc_cc_pdu
+**
+** Description Process CC PDU
+**
+** Returns void
+**
+*******************************************************************************/
+static void llcp_dlc_proc_cc_pdu (UINT8 dsap, UINT8 ssap, UINT16 length, UINT8 *p_data)
+{
+ tLLCP_DLCB *p_dlcb;
+ tLLCP_CONNECTION_PARAMS params;
+ tLLCP_STATUS status;
+
+ LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_cc_pdu ()");
+
+ /* find a DLCB waiting for CC on this local SAP */
+ p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, LLCP_INVALID_SAP);
+ if (p_dlcb)
+ {
+ /* The CC may contain a SSAP that is different from the DSAP in the CONNECT */
+ p_dlcb->remote_sap = ssap;
+
+ if (llcp_util_parse_cc (p_data, length, &(params.miu), &(params.rw)) == LLCP_STATUS_SUCCESS)
+ {
+ status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_CONNECT_CFM, ¶ms);
+ if (status != LLCP_STATUS_SUCCESS)
+ {
+ LLCP_TRACE_ERROR0 ("llcp_dlc_proc_cc_pdu (): Error in state machine");
+ llcp_util_deallocate_data_link (p_dlcb);
+ }
+ }
+ else
+ {
+ llcp_util_send_frmr (p_dlcb, LLCP_FRMR_W_ERROR_FLAG|LLCP_FRMR_I_ERROR_FLAG, LLCP_PDU_DISC_TYPE, 0);
+ llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
+ }
+ }
+ else
+ {
+ LLCP_TRACE_ERROR2 ("llcp_dlc_proc_cc_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
+ }
+}
+
+/*******************************************************************************
+**
+** Function llcp_dlc_proc_dm_pdu
+**
+** Description Process DM PDU
+**
+** Returns void
+**
+*******************************************************************************/
+static void llcp_dlc_proc_dm_pdu (UINT8 dsap, UINT8 ssap, UINT16 length, UINT8 *p_data)
+{
+ tLLCP_DLCB *p_dlcb;
+
+ LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_dm_pdu ()");
+
+ if (length != LLCP_PDU_DM_SIZE - LLCP_PDU_HEADER_SIZE)
+ {
+ LLCP_TRACE_ERROR0 ("llcp_dlc_proc_dm_pdu (): Received invalid DM PDU");
+ }
+ else
+ {
+ if (*p_data == LLCP_SAP_DM_REASON_RESP_DISC)
+ {
+ /* local device initiated disconnecting */
+ p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
+ }
+ else
+ {
+ /* peer device rejected connection with any reason */
+ /* find a DLCB waiting for CC on this local SAP */
+ p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, LLCP_INVALID_SAP);
+ }
+
+ if (p_dlcb)
+ {
+ llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DISCONNECT_RESP, p_data); /* passing reason */
+ }
+ else
+ {
+ LLCP_TRACE_ERROR2 ("llcp_dlc_proc_dm_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function llcp_dlc_proc_i_pdu
+**
+** Description Process I PDU
+**
+** Returns void
+**
+*******************************************************************************/
+void llcp_dlc_proc_i_pdu (UINT8 dsap, UINT8 ssap, UINT16 i_pdu_length, UINT8 *p_i_pdu, BT_HDR *p_msg)
+{
+ UINT8 *p, *p_dst, send_seq, rcv_seq, error_flags;
+ UINT16 info_len, available_bytes;
+ tLLCP_DLCB *p_dlcb;
+ BOOLEAN appended;
+ BT_HDR *p_last_buf;
+
+ LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_i_pdu ()");
+
+ p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
+
+ if ((p_dlcb)&&(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 *) (p_msg + 1) + p_msg->offset;
+ }
+
+ info_len = i_pdu_length - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE;
+
+ if (info_len > p_dlcb->local_miu)
+ {
+ LLCP_TRACE_ERROR2 ("llcp_dlc_proc_i_pdu (): exceeding local MIU (%d bytes): got %d bytes SDU",
+ p_dlcb->local_miu, info_len);
+
+ error_flags |= LLCP_FRMR_I_ERROR_FLAG;
+ }
+
+ /* get sequence numbers */
+ p = p_i_pdu + LLCP_PDU_HEADER_SIZE;
+
+ send_seq = LLCP_GET_NS (*p);
+ rcv_seq = LLCP_GET_NR (*p);
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ LLCP_TRACE_DEBUG6 ("LLCP RX I PDU - N(S,R):(%d,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
+ send_seq, rcv_seq,
+ p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
+ p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
+#endif
+
+ /* if send sequence number, N(S) is not expected one, V(R) */
+ if (p_dlcb->next_rx_seq != send_seq)
+ {
+ LLCP_TRACE_ERROR2 ("llcp_dlc_proc_i_pdu (): Bad N(S) got:%d, expected:%d",
+ send_seq, p_dlcb->next_rx_seq);
+
+ error_flags |= LLCP_FRMR_S_ERROR_FLAG;
+ }
+ else
+ {
+ /* if peer device sends more than our receiving window size */
+ if ((UINT8) (send_seq - p_dlcb->sent_ack_seq) % LLCP_SEQ_MODULO >= p_dlcb->local_rw)
+ {
+ LLCP_TRACE_ERROR3 ("llcp_dlc_proc_i_pdu (): Bad N(S):%d >= V(RA):%d + RW(L):%d",
+ send_seq, p_dlcb->sent_ack_seq, p_dlcb->local_rw);
+
+ error_flags |= LLCP_FRMR_S_ERROR_FLAG;
+ }
+ }
+
+ /* check N(R) is in valid range; V(SA) <= N(R) <= V(S) */
+ if ((UINT8) (rcv_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO + (UINT8) (p_dlcb->next_tx_seq - rcv_seq) % LLCP_SEQ_MODULO
+ != (UINT8) (p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO)
+ {
+ error_flags |= LLCP_FRMR_R_ERROR_FLAG;
+ LLCP_TRACE_ERROR3 ("llcp_dlc_proc_i_pdu (): Bad N(R):%d valid range [V(SA):%d, V(S):%d]",
+ rcv_seq, p_dlcb->rcvd_ack_seq, p_dlcb->next_tx_seq);
+ }
+
+ /* if any error is found */
+ if (error_flags)
+ {
+ llcp_util_send_frmr (p_dlcb, error_flags, LLCP_PDU_I_TYPE, *p);
+ llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
+ }
+ else
+ {
+ /* update local sequence variables */
+ p_dlcb->next_rx_seq = (p_dlcb->next_rx_seq + 1) % LLCP_SEQ_MODULO;
+ p_dlcb->rcvd_ack_seq = rcv_seq;
+
+ appended = FALSE;
+
+ /* get last buffer in rx queue */
+ p_last_buf = (BT_HDR *) GKI_getlast (&p_dlcb->i_rx_q);
+
+ if (p_last_buf)
+ {
+ /* get max length to append at the end of buffer */
+ available_bytes = GKI_get_buf_size (p_last_buf) - BT_HDR_SIZE - p_last_buf->offset - p_last_buf->len;
+
+ /* if new UI PDU with length can be attached at the end of buffer */
+ if (available_bytes >= LLCP_PDU_AGF_LEN_SIZE + info_len)
+ {
+ p_dst = (UINT8*) (p_last_buf + 1) + p_last_buf->offset + p_last_buf->len;
+
+ /* add length of information in I PDU */
+ UINT16_TO_BE_STREAM (p_dst, info_len);
+
+ /* copy information of I PDU */
+ p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
+
+ memcpy (p_dst, p, info_len);
+
+ p_last_buf->len += LLCP_PDU_AGF_LEN_SIZE + info_len;
+
+ if (p_msg)
+ {
+ GKI_freebuf (p_msg);
+ p_msg = NULL;
+ }
+
+ appended = TRUE;
+ }
+ }
+
+ /* if it is not available to append */
+ if (!appended)
+ {
+ /* if it's not from AGF PDU */
+ if (p_msg)
+ {
+ /* add length of information in front of information */
+ p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
+ UINT16_TO_BE_STREAM (p, info_len);
+
+ p_msg->offset += LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
+ p_msg->len -= LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
+ p_msg->layer_specific = 0;
+ }
+ else
+ {
+ p_msg = (BT_HDR *) GKI_getpoolbuf (LLCP_POOL_ID);
+
+ if (p_msg)
+ {
+ p_dst = (UINT8*) (p_msg + 1);
+
+ /* add length of information in front of information */
+ UINT16_TO_BE_STREAM (p_dst, info_len);
+
+ p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
+ memcpy (p_dst, p, info_len);
+
+ p_msg->offset = 0;
+ p_msg->len = LLCP_PDU_AGF_LEN_SIZE + info_len;
+ p_msg->layer_specific = 0;
+ }
+ else
+ {
+ LLCP_TRACE_ERROR0 ("llcp_dlc_proc_i_pdu (): out of buffer");
+ }
+ }
+
+ /* insert I PDU in rx queue */
+ if (p_msg)
+ {
+ GKI_enqueue (&p_dlcb->i_rx_q, p_msg);
+ p_msg = NULL;
+ llcp_cb.total_rx_i_pdu++;
+
+ llcp_util_check_rx_congested_status ();
+ }
+ }
+
+ p_dlcb->num_rx_i_pdu++;
+
+ if ( (!p_dlcb->local_busy)
+ &&(p_dlcb->num_rx_i_pdu == 1) )
+ {
+ /* notify rx data is available so upper layer reads data until queue is empty */
+ llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DATA_IND, NULL);
+ }
+
+ if ( (!p_dlcb->is_rx_congested)
+ &&(p_dlcb->num_rx_i_pdu >= p_dlcb->rx_congest_threshold) )
+ {
+ LLCP_TRACE_DEBUG2 ("llcp_dlc_proc_i_pdu (): congested num_rx_i_pdu=%d, rx_congest_threshold=%d",
+ p_dlcb->num_rx_i_pdu, p_dlcb->rx_congest_threshold);
+
+ /* send RNR */
+ p_dlcb->is_rx_congested = TRUE;
+ p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
+ }
+ }
+ }
+ else
+ {
+ LLCP_TRACE_ERROR2 ("llcp_dlc_proc_i_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
+ llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_NO_ACTIVE_CONNECTION );
+ }
+
+ if (p_msg)
+ {
+ GKI_freebuf (p_msg);
+ }
+}
+
+/*******************************************************************************
+**
+** Function llcp_dlc_proc_rr_rnr_pdu
+**
+** Description Process RR or RNR PDU
+**
+** Returns void
+**
+*******************************************************************************/
+static void llcp_dlc_proc_rr_rnr_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, UINT16 length, UINT8 *p_data)
+{
+ UINT8 rcv_seq, error_flags;
+ tLLCP_DLCB *p_dlcb;
+ BOOLEAN flush = TRUE;
+ tLLCP_SAP_CBACK_DATA cback_data;
+ BOOLEAN 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) (rcv_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO + (UINT8) (p_dlcb->next_tx_seq - rcv_seq) % LLCP_SEQ_MODULO
+ != (UINT8) (p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO )
+ {
+ error_flags |= LLCP_FRMR_R_ERROR_FLAG;
+ LLCP_TRACE_ERROR3 ("llcp_dlc_proc_rr_rnr_pdu (): Bad N(R):%d valid range [V(SA):%d, V(S):%d]",
+ rcv_seq, p_dlcb->rcvd_ack_seq, p_dlcb->next_tx_seq);
+ }
+
+ if (error_flags)
+ {
+ llcp_util_send_frmr (p_dlcb, error_flags, ptype, *p_data);
+ llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
+ }
+ else
+ {
+ p_dlcb->rcvd_ack_seq = rcv_seq;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ LLCP_TRACE_DEBUG5 ("LLCP RX - N(S,R):(NA,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
+ rcv_seq,
+ p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
+ p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
+#endif
+ 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 dsap, UINT8 ptype, UINT8 ssap, UINT16 length, UINT8 *p_data)
+{
+ tLLCP_DLCB *p_dlcb;
+
+ LLCP_TRACE_DEBUG3 ("llcp_dlc_proc_rx_pdu (): DSAP:0x%x, PTYPE:0x%x, SSAP:0x%x",
+ dsap, ptype, ssap);
+
+ if (dsap == LLCP_SAP_LM)
+ {
+ LLCP_TRACE_ERROR2 ("llcp_dlc_proc_rx_pdu (): Invalid SAP:0x%x for PTYPE:0x%x", dsap, ptype);
+ return;
+ }
+
+ switch (ptype)
+ {
+ case LLCP_PDU_CONNECT_TYPE:
+ llcp_dlc_proc_connect_pdu (dsap, ssap, length, p_data);
+ break;
+
+ case LLCP_PDU_DISC_TYPE:
+ llcp_dlc_proc_disc_pdu (dsap, ssap, length, p_data);
+ break;
+
+ case LLCP_PDU_CC_TYPE:
+ llcp_dlc_proc_cc_pdu (dsap, ssap, length, p_data);
+ break;
+
+ case LLCP_PDU_DM_TYPE:
+ llcp_dlc_proc_dm_pdu (dsap, ssap, length, p_data);
+ break;
+
+ case LLCP_PDU_FRMR_TYPE:
+ p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
+ if (p_dlcb)
+ {
+ llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
+ }
+ break;
+
+ case LLCP_PDU_RR_TYPE:
+ case LLCP_PDU_RNR_TYPE:
+ llcp_dlc_proc_rr_rnr_pdu (dsap, ptype, ssap, length, p_data);
+ break;
+
+ default:
+ LLCP_TRACE_ERROR1 ("llcp_dlc_proc_rx_pdu (): Unexpected PDU type (0x%x)", ptype);
+
+ p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
+ if (p_dlcb)
+ {
+ llcp_util_send_frmr (p_dlcb, LLCP_FRMR_W_ERROR_FLAG, ptype, 0);
+ llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
+ }
+ break;
+ }
+}
+
+/*******************************************************************************
+**
+** Function llcp_dlc_check_to_send_rr_rnr
+**
+** Description Send RR or RNR if necessary
+**
+** Returns void
+**
+*******************************************************************************/
+void llcp_dlc_check_to_send_rr_rnr (void)
+{
+ UINT8 idx;
+ BOOLEAN flush = TRUE;
+
+ LLCP_TRACE_DEBUG0 ("llcp_dlc_check_to_send_rr_rnr ()");
+
+ /*
+ ** DLC doesn't send RR PDU for each received I PDU because multiple I PDUs can be aggregated
+ ** in a received AGF PDU. In this case, this is post processing of AGF PDU to send single RR
+ ** or RNR after processing all I PDUs in received AGF if there was no I-PDU to carry N(R).
+ **
+ ** Send RR or RNR if any change of local busy condition or rx congestion status, or V(RA) is not
+ ** V(R).
+ */
+ for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++)
+ {
+ if (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED)
+ {
+ llcp_util_send_rr_rnr (&(llcp_cb.dlcb[idx]));
+
+ /* check flag to send DISC when tx queue is empty */
+ if (llcp_cb.dlcb[idx].flags & LLCP_DATA_LINK_FLAG_PENDING_DISC)
+ {
+ /* if no pending data and all PDU is acked */
+ if ( (llcp_cb.dlcb[idx].i_xmit_q.count == 0)
+ &&(llcp_cb.dlcb[idx].next_rx_seq == llcp_cb.dlcb[idx].sent_ack_seq)
+ &&(llcp_cb.dlcb[idx].next_tx_seq == llcp_cb.dlcb[idx].rcvd_ack_seq) )
+ {
+ llcp_cb.dlcb[idx].flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
+ llcp_dlsm_execute (&(llcp_cb.dlcb[idx]), LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
+ }
+ }
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function llcp_dlc_is_rw_open
+**
+** Description check if receive window is open in remote
+**
+** Returns TRUE if remote can receive more data
+**
+*******************************************************************************/
+BOOLEAN llcp_dlc_is_rw_open (tLLCP_DLCB *p_dlcb)
+{
+ if ((UINT8) (p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO < p_dlcb->remote_rw)
+ {
+ return TRUE;
+ }
+ else
+ {
+ LLCP_TRACE_DEBUG3 ("llcp_dlc_is_rw_open ():Flow Off, V(S):%d, V(SA):%d, RW(R):%d",
+ p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq, p_dlcb->remote_rw);
+ return FALSE;
+ }
+}
+
+/*******************************************************************************
+**
+** Function llcp_dlc_get_next_pdu
+**
+** Description Get a PDU from tx queue of data link
+**
+** Returns BT_HDR*
+**
+*******************************************************************************/
+BT_HDR* llcp_dlc_get_next_pdu (tLLCP_DLCB *p_dlcb)
+{
+ BT_HDR *p_msg = NULL;
+ BOOLEAN flush = TRUE;
+ tLLCP_SAP_CBACK_DATA data;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ UINT8 send_seq = p_dlcb->next_tx_seq;
+#endif
+
+ /* if there is data to send and remote device can receive it */
+ if ( (p_dlcb->i_xmit_q.count)
+ &&(!p_dlcb->remote_busy)
+ &&(llcp_dlc_is_rw_open (p_dlcb)) )
+ {
+ p_msg = (BT_HDR *) GKI_dequeue (&p_dlcb->i_xmit_q);
+ llcp_cb.total_tx_i_pdu--;
+
+ if (p_msg->offset >= LLCP_MIN_OFFSET)
+ {
+ /* add LLCP header, DSAP, PTYPE, SSAP, N(S), N(R) and update sent_ack_seq, V(RA) */
+ llcp_util_build_info_pdu (p_dlcb, p_msg);
+
+ p_dlcb->next_tx_seq = (p_dlcb->next_tx_seq + 1) % LLCP_SEQ_MODULO;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ LLCP_TRACE_DEBUG6 ("LLCP TX - N(S,R):(%d,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
+ send_seq, p_dlcb->next_rx_seq,
+ p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
+ p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
+#endif
+ }
+ else
+ {
+ LLCP_TRACE_ERROR2 ("LLCP - llcp_dlc_get_next_pdu (): offset (%d) must be %d at least",
+ p_msg->offset, LLCP_MIN_OFFSET );
+ GKI_freebuf (p_msg);
+ p_msg = NULL;
+ }
+ }
+
+ /* if tx queue is empty and all PDU is acknowledged */
+ if ( (p_dlcb->i_xmit_q.count == 0)
+ &&(p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq)
+ &&(p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq) )
+ {
+ /* check flag to send DISC */
+ if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_PENDING_DISC)
+ {
+ p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
+ llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
+ }
+
+ /* check flag to notify upper layer */
+ if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE)
+ {
+ p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE;
+
+ data.tx_complete.event = LLCP_SAP_EVT_TX_COMPLETE;
+ data.tx_complete.local_sap = p_dlcb->local_sap;
+ data.tx_complete.remote_sap = p_dlcb->remote_sap;
+
+ (*p_dlcb->p_app_cb->p_app_cback) (&data);
+ }
+ }
+
+ return p_msg;
+}
+
+/*******************************************************************************
+**
+** Function llcp_dlc_get_next_pdu_length
+**
+** Description return length of PDU which is top in tx queue of data link
+**
+** Returns length of PDU
+**
+*******************************************************************************/
+UINT16 llcp_dlc_get_next_pdu_length (tLLCP_DLCB *p_dlcb)
+{
+ BT_HDR *p_msg;
+
+ /* if there is data to send and remote device can receive it */
+ if ( (p_dlcb->i_xmit_q.count)
+ &&(!p_dlcb->remote_busy)
+ &&(llcp_dlc_is_rw_open (p_dlcb)) )
+ {
+ p_msg = (BT_HDR *) p_dlcb->i_xmit_q.p_first;
+
+ return (p_msg->len + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE);
+ }
+ return 0;
+}
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function llcp_dlsm_get_state_name
+**
+** Description This function returns the state name.
+**
+** Returns pointer to the name
+**
+*******************************************************************************/
+static char *llcp_dlsm_get_state_name (tLLCP_DLC_STATE state)
+{
+ switch (state)
+ {
+ case LLCP_DLC_STATE_IDLE:
+ return ("IDLE");
+ case LLCP_DLC_STATE_W4_REMOTE_RESP:
+ return ("W4_REMOTE_RESP");
+ case LLCP_DLC_STATE_W4_LOCAL_RESP:
+ return ("W4_LOCAL_RESP");
+ case LLCP_DLC_STATE_CONNECTED:
+ return ("CONNECTED");
+ case LLCP_DLC_STATE_W4_REMOTE_DM:
+ return ("W4_REMOTE_DM");
+ default:
+ return ("???? UNKNOWN STATE");
+ }
+}
+
+/*******************************************************************************
+**
+** Function llcp_dlsm_get_event_name
+**
+** Description This function returns the event name.
+**
+** Returns pointer to the name
+**
+*******************************************************************************/
+static char *llcp_dlsm_get_event_name (tLLCP_DLC_EVENT event)
+{
+ switch (event)
+ {
+ case LLCP_DLC_EVENT_API_CONNECT_REQ:
+ return ("API_CONNECT_REQ");
+ case LLCP_DLC_EVENT_API_CONNECT_CFM:
+ return ("API_CONNECT_CFM");
+ case LLCP_DLC_EVENT_API_CONNECT_REJECT:
+ return ("API_CONNECT_REJECT");
+ case LLCP_DLC_EVENT_PEER_CONNECT_IND:
+ return ("PEER_CONNECT_IND");
+ case LLCP_DLC_EVENT_PEER_CONNECT_CFM:
+ return ("PEER_CONNECT_CFM");
+
+ case LLCP_DLC_EVENT_API_DATA_REQ:
+ return ("API_DATA_REQ");
+ case LLCP_DLC_EVENT_PEER_DATA_IND:
+ return ("PEER_DATA_IND");
+
+ case LLCP_DLC_EVENT_API_DISCONNECT_REQ:
+ return ("API_DISCONNECT_REQ");
+ case LLCP_DLC_EVENT_PEER_DISCONNECT_IND:
+ return ("PEER_DISCONNECT_IND");
+ case LLCP_DLC_EVENT_PEER_DISCONNECT_RESP:
+ return ("PEER_DISCONNECT_RESP");
+
+ case LLCP_DLC_EVENT_FRAME_ERROR:
+ return ("FRAME_ERROR");
+ case LLCP_DLC_EVENT_LINK_ERROR:
+ return ("LINK_ERROR");
+
+ case LLCP_DLC_EVENT_TIMEOUT:
+ return ("TIMEOUT");
+
+ default:
+ return ("???? UNKNOWN EVENT");
+ }
+}
+#endif /* (BT_TRACE_VERBOSE == TRUE) */
diff --git a/src/nfc/llcp/llcp_link.c b/src/nfc/llcp/llcp_link.c
new file mode 100644
index 0000000..47f9d61
--- /dev/null
+++ b/src/nfc/llcp/llcp_link.c
@@ -0,0 +1,1853 @@
+/******************************************************************************
+ *
+ * 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 Link Management
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include "gki.h"
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "trace_api.h"
+#include "llcp_int.h"
+#include "llcp_defs.h"
+#include "nfc_int.h"
+
+
+const UINT16 llcp_link_rwt[15] = /* RWT = (302us)*2**WT; 302us = 256*16/fc; fc = 13.56MHz */
+{
+ 1, /* WT=0, 302us */
+ 1, /* WT=1, 604us */
+ 2, /* WT=2, 1208us */
+ 3, /* WT=3, 2.4ms */
+ 5, /* WT=4, 4.8ms */
+ 10, /* WT=5, 9.7ms */
+ 20, /* WT=6, 19.3ms */
+ 39, /* WT=7, 38.7ms */
+ 78, /* WT=8, 77.3ms */
+ 155, /* WT=9, 154.6ms */
+ 310, /* WT=10, 309.2ms */
+ 619, /* WT=11, 618.5ms */
+ 1237, /* WT=12, 1237.0ms */
+ 2474, /* WT=13, 2474.0ms */
+ 4948, /* WT=14, 4948.0ms */
+};
+
+static BOOLEAN llcp_link_parse_gen_bytes (UINT8 gen_bytes_len, UINT8 *p_gen_bytes);
+static BOOLEAN llcp_link_version_agreement (void);
+
+static void llcp_link_send_SYMM (void);
+static void llcp_link_update_status (BOOLEAN is_activated);
+static void llcp_link_check_congestion (void);
+static void llcp_link_check_uncongested (void);
+static void llcp_link_proc_ui_pdu (UINT8 local_sap, UINT8 remote_sap, UINT16 ui_pdu_length, UINT8 *p_ui_pdu, BT_HDR *p_msg);
+static void llcp_link_proc_agf_pdu (BT_HDR *p_msg);
+static void llcp_link_proc_rx_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, BT_HDR *p_msg);
+static void llcp_link_proc_rx_data (BT_HDR *p_msg);
+
+static BT_HDR *llcp_link_get_next_pdu (BOOLEAN length_only, UINT16 *p_next_pdu_length);
+static BT_HDR *llcp_link_build_next_pdu (BT_HDR *p_agf);
+static void llcp_link_send_to_lower (BT_HDR *p_msg);
+
+#if (LLCP_TEST_INCLUDED == TRUE) /* this is for LLCP testing */
+extern tLLCP_TEST_PARAMS llcp_test_params;
+#endif
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+extern unsigned char appl_dta_mode_flag;
+#endif
+
+/* debug functions type */
+#if (BT_TRACE_VERBOSE == TRUE)
+static char *llcp_pdu_type (UINT8 ptype);
+#endif
+
+/*******************************************************************************
+**
+** Function llcp_link_start_inactivity_timer
+**
+** Description This function start LLCP link inactivity timer.
+**
+** Returns void
+**
+*******************************************************************************/
+static void llcp_link_start_inactivity_timer (void)
+{
+ if ( (llcp_cb.lcb.inact_timer.in_use == FALSE)
+ &&(llcp_cb.lcb.inact_timeout > 0) )
+ {
+ LLCP_TRACE_DEBUG1 ("Start inactivity_timer: %d ms", llcp_cb.lcb.inact_timeout);
+
+ nfc_start_quick_timer (&llcp_cb.lcb.inact_timer, NFC_TTYPE_LLCP_LINK_INACT,
+ ((UINT32) llcp_cb.lcb.inact_timeout) * QUICK_TIMER_TICKS_PER_SEC / 1000);
+ }
+}
+
+/*******************************************************************************
+**
+** Function llcp_link_stop_inactivity_timer
+**
+** Description This function stop LLCP link inactivity timer.
+**
+** Returns void
+**
+*******************************************************************************/
+static void llcp_link_stop_inactivity_timer (void)
+{
+ if (llcp_cb.lcb.inact_timer.in_use)
+ {
+ LLCP_TRACE_DEBUG0 ("Stop inactivity_timer");
+
+ nfc_stop_quick_timer (&llcp_cb.lcb.inact_timer);
+ }
+}
+
+/*******************************************************************************
+**
+** Function llcp_link_start_link_timer
+**
+** Description This function starts LLCP link timer (LTO or delay response).
+**
+** Returns void
+**
+*******************************************************************************/
+static void llcp_link_start_link_timer (void)
+{
+ if (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT)
+ {
+ /* wait for application layer sending data */
+ nfc_start_quick_timer (&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER,
+ (((UINT32) llcp_cb.lcb.symm_delay) * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+ }
+ else
+ {
+ /* wait for data to receive from remote */
+ nfc_start_quick_timer (&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER,
+ ((UINT32) llcp_cb.lcb.peer_lto) * QUICK_TIMER_TICKS_PER_SEC / 1000);
+ }
+}
+
+/*******************************************************************************
+**
+** Function llcp_link_stop_link_timer
+**
+** Description This function stop LLCP link timer (LTO or delay response).
+**
+** Returns void
+**
+*******************************************************************************/
+static void llcp_link_stop_link_timer (void)
+{
+ nfc_stop_quick_timer (&llcp_cb.lcb.timer);
+}
+
+/*******************************************************************************
+**
+** Function llcp_link_activate
+**
+** Description Activate LLCP link
+**
+** Returns tLLCP_STATUS
+**
+*******************************************************************************/
+tLLCP_STATUS llcp_link_activate (tLLCP_ACTIVATE_CONFIG *p_config)
+{
+ LLCP_TRACE_DEBUG0 ("llcp_link_activate ()");
+
+ /* At this point, MAC link activation procedure has been successfully completed */
+
+ /* The Length Reduction values LRi and LRt MUST be 11b. (254bytes) */
+ if (p_config->max_payload_size != LLCP_NCI_MAX_PAYL_SIZE)
+ {
+ LLCP_TRACE_WARNING2 ("llcp_link_activate (): max payload size (%d) must be %d bytes",
+ p_config->max_payload_size, LLCP_NCI_MAX_PAYL_SIZE);
+ }
+
+ /* Processing the parametes that have been received with the MAC link activation */
+ if (llcp_link_parse_gen_bytes (p_config->gen_bytes_len,
+ p_config->p_gen_bytes ) == FALSE)
+ {
+ LLCP_TRACE_ERROR0 ("llcp_link_activate (): Failed to parse general bytes");
+ (*llcp_cb.lcb.p_link_cback) (LLCP_LINK_ACTIVATION_FAILED_EVT, LLCP_LINK_BAD_GEN_BYTES);
+
+ 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(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED == 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) llcp_cb.lcb.delay_first_pdu_timeout) * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+ }
+ else
+ {
+ llcp_link_send_SYMM ();
+ }
+ }
+ else
+ {
+ LLCP_TRACE_DEBUG0 ("llcp_link_activate (): Connected as Target");
+ llcp_cb.lcb.inact_timeout = llcp_cb.lcb.inact_timeout_target;
+ llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_REMOTE_XMIT_NEXT;
+
+ /* wait for data to receive from remote */
+ llcp_link_start_link_timer ();
+
+ }
+
+
+ /*
+ ** Set state to LLCP_LINK_STATE_ACTIVATED and notify activation before set data callback
+ ** because LLCP PDU could be in NCI queue.
+ */
+ llcp_cb.lcb.link_state = LLCP_LINK_STATE_ACTIVATED;
+
+ /* LLCP Link Activation completed */
+ (*llcp_cb.lcb.p_link_cback) (LLCP_LINK_ACTIVATION_COMPLETE_EVT, LLCP_LINK_SUCCESS);
+
+ /* Update link status to service layer */
+ llcp_link_update_status (TRUE);
+
+ NFC_SetStaticRfCback (llcp_link_connection_cback);
+
+ return (LLCP_STATUS_SUCCESS);
+}
+
+/*******************************************************************************
+**
+** Function llcp_deactivate_cleanup
+**
+** Description Clean up for link deactivation
+**
+** Returns void
+**
+*******************************************************************************/
+static void llcp_deactivate_cleanup (UINT8 reason)
+{
+ /* report SDP failure for any pending request */
+ llcp_sdp_proc_deactivation ();
+
+ /* Update link status to service layer */
+ llcp_link_update_status (FALSE);
+
+ /* We had sent out DISC */
+ llcp_cb.lcb.link_state = LLCP_LINK_STATE_DEACTIVATED;
+
+ llcp_link_stop_link_timer ();
+
+ /* stop inactivity timer */
+ llcp_link_stop_inactivity_timer ();
+
+ /* Let upper layer deactivate local link */
+ (*llcp_cb.lcb.p_link_cback) (LLCP_LINK_DEACTIVATED_EVT, reason);
+}
+
+/*******************************************************************************
+**
+** Function llcp_link_process_link_timeout
+**
+** Description Process timeout events for LTO, SYMM and deactivating
+**
+** Returns void
+**
+*******************************************************************************/
+void llcp_link_process_link_timeout (void)
+{
+ if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
+ {
+ if ((llcp_cb.lcb.symm_delay > 0) && (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT))
+ {
+ /* upper layer doesn't have anything to send */
+ LLCP_TRACE_DEBUG0 ("llcp_link_process_link_timeout (): LEVT_TIMEOUT in state of LLCP_LINK_SYMM_LOCAL_XMIT_NEXT");
+ llcp_link_send_SYMM ();
+
+ /* wait for data to receive from remote */
+ llcp_link_start_link_timer ();
+
+ /* start inactivity timer */
+ if (llcp_cb.num_data_link_connection == 0)
+ {
+ llcp_link_start_inactivity_timer ();
+ }
+ }
+ else
+ {
+ LLCP_TRACE_ERROR0 ("llcp_link_process_link_timeout (): LEVT_TIMEOUT in state of LLCP_LINK_SYMM_REMOTE_XMIT_NEXT");
+ llcp_link_deactivate (LLCP_LINK_TIMEOUT);
+ }
+ }
+ else if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING)
+ {
+ llcp_deactivate_cleanup (llcp_cb.lcb.link_deact_reason);
+
+ NFC_SetStaticRfCback (NULL);
+ }
+}
+
+/*******************************************************************************
+**
+** Function llcp_link_deactivate
+**
+** Description Deactivate LLCP link
+**
+** Returns void
+**
+*******************************************************************************/
+void llcp_link_deactivate (UINT8 reason)
+{
+ UINT8 local_sap, idx;
+ tLLCP_DLCB *p_dlcb;
+ tLLCP_APP_CB *p_app_cb;
+
+ LLCP_TRACE_DEBUG1 ("llcp_link_deactivate () reason = 0x%x", reason);
+
+ /* Release any held buffers in signaling PDU queue */
+ while (llcp_cb.lcb.sig_xmit_q.p_first)
+ GKI_freebuf (GKI_dequeue (&llcp_cb.lcb.sig_xmit_q));
+
+ /* Release any held buffers in UI PDU queue */
+ for (local_sap = LLCP_SAP_SDP + 1; local_sap < LLCP_NUM_SAPS; local_sap++)
+ {
+ p_app_cb = llcp_util_get_app_cb (local_sap);
+
+ if ( (p_app_cb)
+ &&(p_app_cb->p_app_cback) )
+ {
+ while (p_app_cb->ui_xmit_q.p_first)
+ GKI_freebuf (GKI_dequeue (&p_app_cb->ui_xmit_q));
+
+ p_app_cb->is_ui_tx_congested = FALSE;
+
+ while (p_app_cb->ui_rx_q.p_first)
+ GKI_freebuf (GKI_dequeue (&p_app_cb->ui_rx_q));
+ }
+ }
+
+ llcp_cb.total_tx_ui_pdu = 0;
+ llcp_cb.total_rx_ui_pdu = 0;
+
+ /* Notify all of data link */
+ for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++)
+ {
+ if (llcp_cb.dlcb[idx].state != LLCP_DLC_STATE_IDLE)
+ {
+ p_dlcb = &(llcp_cb.dlcb[idx]);
+
+ llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_LINK_ERROR, NULL);
+ }
+ }
+ llcp_cb.total_tx_i_pdu = 0;
+ llcp_cb.total_rx_i_pdu = 0;
+
+ llcp_cb.overall_tx_congested = FALSE;
+ llcp_cb.overall_rx_congested = FALSE;
+
+ if ( (reason == LLCP_LINK_FRAME_ERROR)
+ ||(reason == LLCP_LINK_LOCAL_INITIATED) )
+ {
+ /* get rid of the data pending in NFC tx queue, so DISC PDU can be sent ASAP */
+ NFC_FlushData (NFC_RF_CONN_ID);
+
+ llcp_util_send_disc (LLCP_SAP_LM, LLCP_SAP_LM);
+
+ /* Wait until DISC is sent to peer */
+ LLCP_TRACE_DEBUG0 ("llcp_link_deactivate (): Wait until DISC is sent to peer");
+
+ llcp_cb.lcb.link_state = LLCP_LINK_STATE_DEACTIVATING;
+
+ if (llcp_cb.lcb.sig_xmit_q.count == 0)
+ {
+ /* if DISC is sent to NFCC, wait for short period for NFCC to send it to peer */
+ nfc_start_quick_timer (&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER,
+ ((UINT32) 50) * QUICK_TIMER_TICKS_PER_SEC / 1000);
+ }
+
+ llcp_cb.lcb.link_deact_reason = reason;
+ return;
+ }
+ else if ( (reason == LLCP_LINK_REMOTE_INITIATED)
+ &&(!llcp_cb.lcb.is_initiator) )
+ {
+ /* if received DISC to deactivate LLCP link as target role, send SYMM PDU */
+ llcp_link_send_SYMM ();
+ }
+ else /* for link timeout and interface error */
+ {
+ /* 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 BOOLEAN llcp_link_parse_gen_bytes (UINT8 gen_bytes_len, UINT8 *p_gen_bytes)
+{
+ UINT8 *p = p_gen_bytes + LLCP_MAGIC_NUMBER_LEN;
+ UINT8 length = gen_bytes_len - LLCP_MAGIC_NUMBER_LEN;
+
+ if ( (gen_bytes_len >= LLCP_MAGIC_NUMBER_LEN)
+ &&(*(p_gen_bytes) == LLCP_MAGIC_NUMBER_BYTE0)
+ &&(*(p_gen_bytes + 1) == LLCP_MAGIC_NUMBER_BYTE1)
+ &&(*(p_gen_bytes + 2) == LLCP_MAGIC_NUMBER_BYTE2) )
+ {
+ /* in case peer didn't include these */
+ llcp_cb.lcb.peer_miu = LLCP_DEFAULT_MIU;
+ llcp_cb.lcb.peer_lto = LLCP_DEFAULT_LTO_IN_MS;
+
+ return (llcp_util_parse_link_params (length, p));
+ }
+ else /* if this is not LLCP */
+ {
+ return (FALSE);
+ }
+
+ return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function llcp_link_version_agreement
+**
+** Description LLCP version number agreement
+**
+** Returns TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN llcp_link_version_agreement (void)
+{
+ UINT8 peer_major_version, peer_minor_version;
+
+ peer_major_version = LLCP_GET_MAJOR_VERSION (llcp_cb.lcb.peer_version);
+ peer_minor_version = LLCP_GET_MINOR_VERSION (llcp_cb.lcb.peer_version);
+
+ if (peer_major_version < LLCP_MIN_MAJOR_VERSION)
+ {
+ LLCP_TRACE_ERROR1("llcp_link_version_agreement(): unsupported peer version number. Peer Major Version:%d", peer_major_version);
+ return FALSE;
+ }
+ else
+ {
+ if (peer_major_version == LLCP_VERSION_MAJOR)
+ {
+ llcp_cb.lcb.agreed_major_version = LLCP_VERSION_MAJOR;
+ if (peer_minor_version >= LLCP_VERSION_MINOR)
+ {
+ llcp_cb.lcb.agreed_minor_version = LLCP_VERSION_MINOR;
+ }
+ else
+ {
+ llcp_cb.lcb.agreed_minor_version = peer_minor_version;
+ }
+ }
+ else if (peer_major_version < LLCP_VERSION_MAJOR)
+ {
+ /* so far we can support backward compatibility */
+ llcp_cb.lcb.agreed_major_version = peer_major_version;
+ llcp_cb.lcb.agreed_minor_version = peer_minor_version;
+ }
+ else
+ {
+ /* let peer (higher major version) decide it */
+ llcp_cb.lcb.agreed_major_version = LLCP_VERSION_MAJOR;
+ llcp_cb.lcb.agreed_minor_version = LLCP_VERSION_MINOR;
+ }
+
+ LLCP_TRACE_DEBUG6 ("local version:%d.%d, remote version:%d.%d, agreed version:%d.%d",
+ LLCP_VERSION_MAJOR, LLCP_VERSION_MINOR,
+ peer_major_version, peer_minor_version,
+ llcp_cb.lcb.agreed_major_version, llcp_cb.lcb.agreed_minor_version);
+
+ return (TRUE);
+ }
+}
+
+/*******************************************************************************
+**
+** Function llcp_link_update_status
+**
+** Description Notify all of service layer client link status change
+**
+** Returns void
+**
+*******************************************************************************/
+static void llcp_link_update_status (BOOLEAN is_activated)
+{
+ tLLCP_SAP_CBACK_DATA data;
+ tLLCP_APP_CB *p_app_cb;
+ UINT8 sap;
+
+ data.link_status.event = LLCP_SAP_EVT_LINK_STATUS;
+ data.link_status.is_activated = is_activated;
+ data.link_status.is_initiator = llcp_cb.lcb.is_initiator;
+
+ /* notify all SAP so they can create connection while link is activated */
+ for (sap = LLCP_SAP_SDP + 1; sap < LLCP_NUM_SAPS; sap++)
+ {
+ p_app_cb = llcp_util_get_app_cb (sap);
+
+ if ( (p_app_cb)
+ &&(p_app_cb->p_app_cback) )
+ {
+ data.link_status.local_sap = sap;
+ p_app_cb->p_app_cback (&data);
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function llcp_link_check_congestion
+**
+** Description Check overall congestion status
+** Notify to all of upper layer if congested
+**
+** Returns void
+**
+*******************************************************************************/
+static void llcp_link_check_congestion (void)
+{
+ tLLCP_SAP_CBACK_DATA data;
+ tLLCP_APP_CB *p_app_cb;
+ UINT8 sap, idx;
+
+ if (llcp_cb.overall_tx_congested)
+ {
+ /* already congested so no need to check again */
+ return;
+ }
+
+ if (llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu >= llcp_cb.max_num_tx_buff)
+ {
+ /* overall buffer usage is high */
+ llcp_cb.overall_tx_congested = TRUE;
+
+ LLCP_TRACE_WARNING2 ("overall tx congestion start: total_tx_ui_pdu=%d, total_tx_i_pdu=%d",
+ llcp_cb.total_tx_ui_pdu, llcp_cb.total_tx_i_pdu);
+
+ data.congest.event = LLCP_SAP_EVT_CONGEST;
+ data.congest.is_congested = TRUE;
+
+ /* notify logical data link congestion status */
+ data.congest.remote_sap = LLCP_INVALID_SAP;
+ data.congest.link_type = LLCP_LINK_TYPE_LOGICAL_DATA_LINK;
+
+ for (sap = LLCP_SAP_SDP + 1; sap < LLCP_NUM_SAPS; sap++)
+ {
+ p_app_cb = llcp_util_get_app_cb (sap);
+
+ if ( (p_app_cb)
+ &&(p_app_cb->p_app_cback)
+ &&(p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) )
+ {
+ /* if already congested then no need to notify again */
+ if (!p_app_cb->is_ui_tx_congested)
+ {
+ p_app_cb->is_ui_tx_congested = TRUE;
+
+ LLCP_TRACE_WARNING2 ("Logical link (SAP=0x%X) congestion start: count=%d",
+ sap, p_app_cb->ui_xmit_q.count);
+
+ data.congest.local_sap = sap;
+ p_app_cb->p_app_cback (&data);
+ }
+ }
+ }
+
+ /* notify data link connection congestion status */
+ data.congest.link_type = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
+
+ for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++ )
+ {
+ if ( (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED)
+ &&(llcp_cb.dlcb[idx].remote_busy == FALSE)
+ &&(llcp_cb.dlcb[idx].is_tx_congested == FALSE) )
+ {
+ llcp_cb.dlcb[idx].is_tx_congested = TRUE;
+
+ LLCP_TRACE_WARNING3 ("Data link (SSAP:DSAP=0x%X:0x%X) congestion start: count=%d",
+ llcp_cb.dlcb[idx].local_sap, llcp_cb.dlcb[idx].remote_sap,
+ llcp_cb.dlcb[idx].i_xmit_q.count);
+
+ data.congest.local_sap = llcp_cb.dlcb[idx].local_sap;
+ data.congest.remote_sap = llcp_cb.dlcb[idx].remote_sap;
+
+ (*llcp_cb.dlcb[idx].p_app_cb->p_app_cback) (&data);
+ }
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function llcp_link_check_uncongested
+**
+** Description Check overall congestion status, logical data link and
+** data link connection congestion status
+** Notify to each upper layer if uncongested
+**
+** Returns void
+**
+*******************************************************************************/
+static void llcp_link_check_uncongested (void)
+{
+ tLLCP_SAP_CBACK_DATA data;
+ tLLCP_APP_CB *p_app_cb;
+ UINT8 xx, sap, idx;
+
+ if (llcp_cb.overall_tx_congested)
+ {
+ if (llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu <= llcp_cb.max_num_tx_buff / 2)
+ {
+ /* overall congestion is cleared */
+ llcp_cb.overall_tx_congested = FALSE;
+
+ LLCP_TRACE_WARNING2 ("overall tx congestion end: total_tx_ui_pdu=%d, total_tx_i_pdu=%d",
+ llcp_cb.total_tx_ui_pdu, llcp_cb.total_tx_i_pdu);
+ }
+ else
+ {
+ /* wait until more data packets are sent out */
+ return;
+ }
+ }
+
+ data.congest.event = LLCP_SAP_EVT_CONGEST;
+ data.congest.is_congested = FALSE;
+
+ /* if total number of UI PDU is below threshold */
+ if (llcp_cb.total_tx_ui_pdu < llcp_cb.max_num_ll_tx_buff)
+ {
+ /* check and notify logical data link congestion status */
+ data.congest.remote_sap = LLCP_INVALID_SAP;
+ data.congest.link_type = LLCP_LINK_TYPE_LOGICAL_DATA_LINK;
+
+ /*
+ ** start point of uncongested status notification is in round robin
+ ** so each logical data link has equal chance of transmitting.
+ */
+ sap = llcp_cb.ll_tx_uncongest_ntf_start_sap;
+
+ for (xx = LLCP_SAP_SDP + 1; xx < LLCP_NUM_SAPS; xx++)
+ {
+ /* no logical data link on LM and SDP */
+ if (sap > LLCP_SAP_SDP)
+ {
+ p_app_cb = llcp_util_get_app_cb (sap);
+
+ if ( (p_app_cb)
+ &&(p_app_cb->p_app_cback)
+ &&(p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)
+ &&(p_app_cb->is_ui_tx_congested)
+ &&(p_app_cb->ui_xmit_q.count <= llcp_cb.ll_tx_congest_end) )
+ {
+ /* if it was congested but now tx queue count is below threshold */
+ p_app_cb->is_ui_tx_congested = FALSE;
+
+ LLCP_TRACE_DEBUG2 ("Logical link (SAP=0x%X) congestion end: count=%d",
+ sap, p_app_cb->ui_xmit_q.count);
+
+ data.congest.local_sap = sap;
+ p_app_cb->p_app_cback (&data);
+ }
+ }
+
+ sap = (sap + 1) % LLCP_NUM_SAPS;
+ }
+
+ /* move start point for next logical data link */
+ for (xx = 0; xx < LLCP_NUM_SAPS; xx++)
+ {
+ sap = (llcp_cb.ll_tx_uncongest_ntf_start_sap + 1) % LLCP_NUM_SAPS;
+
+ if (sap > LLCP_SAP_SDP)
+ {
+ p_app_cb = llcp_util_get_app_cb (sap);
+
+ if ( (p_app_cb)
+ &&(p_app_cb->p_app_cback)
+ &&(p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) )
+ {
+ llcp_cb.ll_tx_uncongest_ntf_start_sap = sap;
+ break;
+ }
+ }
+ }
+ }
+
+ /* notify data link connection congestion status */
+ data.congest.link_type = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
+
+ /*
+ ** start point of uncongested status notification is in round robin
+ ** so each data link connection has equal chance of transmitting.
+ */
+ idx = llcp_cb.dl_tx_uncongest_ntf_start_idx;
+
+ for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++ )
+ {
+ /* if it was congested but now tx queue is below threshold (receiving window) */
+ if ( (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED)
+ &&(llcp_cb.dlcb[idx].is_tx_congested)
+ &&(llcp_cb.dlcb[idx].i_xmit_q.count <= llcp_cb.dlcb[idx].remote_rw / 2) )
+ {
+ llcp_cb.dlcb[idx].is_tx_congested = FALSE;
+
+ if (llcp_cb.dlcb[idx].remote_busy == FALSE)
+ {
+ LLCP_TRACE_DEBUG3 ("Data link (SSAP:DSAP=0x%X:0x%X) congestion end: count=%d",
+ llcp_cb.dlcb[idx].local_sap, llcp_cb.dlcb[idx].remote_sap,
+ llcp_cb.dlcb[idx].i_xmit_q.count);
+
+ data.congest.local_sap = llcp_cb.dlcb[idx].local_sap;
+ data.congest.remote_sap = llcp_cb.dlcb[idx].remote_sap;
+
+ (*llcp_cb.dlcb[idx].p_app_cb->p_app_cback) (&data);
+ }
+ }
+ idx = (idx + 1) % LLCP_MAX_DATA_LINK;
+ }
+
+ /* move start point for next data link connection */
+ for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++ )
+ {
+ idx = (llcp_cb.dl_tx_uncongest_ntf_start_idx + 1) % LLCP_MAX_DATA_LINK;
+ if (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED)
+ {
+ llcp_cb.dl_tx_uncongest_ntf_start_idx = idx;
+ break;
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function llcp_link_send_SYMM
+**
+** Description Send SYMM PDU
+**
+** Returns void
+**
+*******************************************************************************/
+static void llcp_link_send_SYMM (void)
+{
+ BT_HDR *p_msg;
+ UINT8 *p;
+ p_msg = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);
+
+ if (p_msg)
+ {
+ p_msg->len = LLCP_PDU_SYMM_SIZE;
+ p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+ UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (LLCP_SAP_LM, LLCP_PDU_SYMM_TYPE, LLCP_SAP_LM ));
+
+ llcp_link_send_to_lower (p_msg);
+ }
+}
+
+/*******************************************************************************
+**
+** Function llcp_link_send_invalid_pdu
+**
+** Description Send invalid LLC PDU in LLCP_LINK_STATE_ACTIVATION_FAILED
+**
+** Returns void
+**
+*******************************************************************************/
+static void llcp_link_send_invalid_pdu (void)
+{
+ BT_HDR *p_msg;
+ UINT8 *p;
+
+ p_msg = (BT_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 *) (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)
+{
+ BT_HDR *p_pdu;
+ /* don't re-enter while processing to prevent out of sequence */
+ if (llcp_cb.lcb.is_sending_data)
+ return;
+ else
+ llcp_cb.lcb.is_sending_data = TRUE;
+
+ /*
+ ** check overall congestion due to high usage of buffer pool
+ ** if congested then notify all of upper layers not to send any more data
+ */
+ llcp_link_check_congestion ();
+
+ if(llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT)
+ {
+ LLCP_TRACE_DEBUG0 ("llcp_link_check_send_data () in state of LLCP_LINK_SYMM_LOCAL_XMIT_NEXT");
+
+ p_pdu = llcp_link_build_next_pdu (NULL);
+
+ /*
+ ** For data link connection,
+ ** V(RA) was updated and N(R) was set to V(RA), if I PDU was added in this transmission.
+ ** If there was no I PDU to carry V(RA) and V(RA) is not V(R) and it's not congested,
+ ** then RR PDU will be sent.
+ ** If there was no I PDU to carry V(RA) and V(RA) is not V(R) and it's congested,
+ ** then RNR PDU will be sent.
+ ** If local busy state has been changed then RR or RNR PDU may be sent.
+ */
+ llcp_dlc_check_to_send_rr_rnr ();
+
+ /* add RR/RNR PDU to be sent if any */
+ p_pdu = llcp_link_build_next_pdu (p_pdu);
+
+ if (p_pdu != NULL)
+ {
+ llcp_link_send_to_lower (p_pdu);
+
+ /* stop inactivity timer */
+ llcp_link_stop_inactivity_timer ();
+
+ /* check congestion status after sending out some data */
+ llcp_link_check_uncongested ();
+ }
+ else
+ {
+ /* There is no data to send, so send SYMM */
+ if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
+ {
+ if (llcp_cb.lcb.symm_delay > 0)
+ {
+ /* wait for application layer sending data */
+ llcp_link_start_link_timer ();
+ llcp_cb.lcb.is_sending_data = FALSE;
+ return;
+ }
+ else
+ {
+ llcp_link_send_SYMM ();
+
+ /* start inactivity timer */
+ if (llcp_cb.num_data_link_connection == 0)
+ {
+ llcp_link_start_inactivity_timer ();
+ }
+ }
+ }
+ else
+ {
+ llcp_cb.lcb.is_sending_data = FALSE;
+ return;
+ }
+ }
+
+ if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING)
+ {
+ /* wait for short period for NFCC to send DISC */
+ nfc_start_quick_timer (&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER,
+ ((UINT32) 50) * QUICK_TIMER_TICKS_PER_SEC / 1000);
+ }
+ else
+ {
+ /* wait for data to receive from remote */
+ llcp_link_start_link_timer ();
+ }
+ }
+
+ llcp_cb.lcb.is_sending_data = FALSE;
+}
+
+/*******************************************************************************
+**
+** Function llcp_link_proc_ui_pdu
+**
+** Description Process UI PDU from peer device
+**
+** Returns None
+**
+*******************************************************************************/
+static void llcp_link_proc_ui_pdu (UINT8 local_sap,
+ UINT8 remote_sap,
+ UINT16 ui_pdu_length,
+ UINT8 *p_ui_pdu,
+ BT_HDR *p_msg)
+{
+ BOOLEAN appended;
+ BT_HDR *p_last_buf;
+ UINT16 available_bytes;
+ UINT8 *p_dst;
+ tLLCP_APP_CB *p_app_cb;
+ tLLCP_SAP_CBACK_DATA data;
+ tLLCP_DLCB *p_dlcb;
+
+ p_app_cb = llcp_util_get_app_cb (local_sap);
+ /*if UI PDU sent to SAP with data link connection*/
+ if ((p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap)))
+ {
+ llcp_util_send_frmr (p_dlcb, LLCP_FRMR_W_ERROR_FLAG, LLCP_PDU_UI_TYPE, 0);
+ llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
+ if (p_msg)
+ {
+ GKI_freebuf (p_msg);
+ }
+ return;
+ }
+
+ /* if application is registered and expecting UI PDU on logical data link */
+ if ( (p_app_cb)
+ &&(p_app_cb->p_app_cback)
+ &&(p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) )
+ {
+ LLCP_TRACE_DEBUG2 ("llcp_link_proc_ui_pdu () Local SAP:0x%x, Remote SAP:0x%x", local_sap, remote_sap);
+
+ /* if this is not from AGF PDU */
+ if (p_msg)
+ {
+ ui_pdu_length = p_msg->len; /* including LLCP header */
+ p_ui_pdu = (UINT8*) (p_msg + 1) + p_msg->offset;
+ }
+
+ appended = FALSE;
+
+ /* get last buffer in rx queue */
+ p_last_buf = (BT_HDR *) GKI_getlast (&p_app_cb->ui_rx_q);
+
+ if (p_last_buf)
+ {
+ /* get max length to append at the end of buffer */
+ available_bytes = GKI_get_buf_size (p_last_buf) - BT_HDR_SIZE - p_last_buf->offset - p_last_buf->len;
+
+ /* if new UI PDU with length can be attached at the end of buffer */
+ if (available_bytes >= LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length)
+ {
+ p_dst = (UINT8*) (p_last_buf + 1) + p_last_buf->offset + p_last_buf->len;
+
+ /* add length of UI PDU */
+ UINT16_TO_BE_STREAM (p_dst, ui_pdu_length);
+
+ /* copy UI PDU with LLCP header */
+ memcpy (p_dst, p_ui_pdu, ui_pdu_length);
+
+ p_last_buf->len += LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
+
+ if (p_msg)
+ GKI_freebuf (p_msg);
+
+ appended = TRUE;
+ }
+ }
+
+ /* if it is not available to append */
+ if (!appended)
+ {
+ /* if it's not from AGF PDU */
+ if (p_msg)
+ {
+ /* add length of PDU in front of UI PDU (reuse room for NCI header) */
+ p_ui_pdu -= LLCP_PDU_AGF_LEN_SIZE;
+ UINT16_TO_BE_STREAM (p_ui_pdu, ui_pdu_length);
+
+ p_msg->offset -= LLCP_PDU_AGF_LEN_SIZE;
+ p_msg->len += LLCP_PDU_AGF_LEN_SIZE;
+ p_msg->layer_specific = 0;
+ }
+ else
+ {
+ p_msg = (BT_HDR *) GKI_getpoolbuf (LLCP_POOL_ID);
+
+ if (p_msg)
+ {
+ p_dst = (UINT8*) (p_msg + 1);
+
+ /* add length of PDU in front of UI PDU */
+ UINT16_TO_BE_STREAM (p_dst, ui_pdu_length);
+
+ memcpy (p_dst, p_ui_pdu, ui_pdu_length);
+
+ p_msg->offset = 0;
+ p_msg->len = LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
+ p_msg->layer_specific = 0;
+ }
+ else
+ {
+ LLCP_TRACE_ERROR0 ("llcp_link_proc_ui_pdu (): out of buffer");
+ }
+ }
+
+ /* insert UI PDU in rx queue */
+ if (p_msg)
+ {
+ GKI_enqueue (&p_app_cb->ui_rx_q, p_msg);
+ llcp_cb.total_rx_ui_pdu++;
+ }
+ }
+
+ if (p_app_cb->ui_rx_q.count > llcp_cb.ll_rx_congest_start)
+ {
+ LLCP_TRACE_WARNING2 ("llcp_link_proc_ui_pdu (): SAP:0x%x, rx link is congested (%d), discard oldest UI PDU",
+ local_sap, p_app_cb->ui_rx_q.count);
+
+ GKI_freebuf (GKI_dequeue (&p_app_cb->ui_rx_q));
+ llcp_cb.total_rx_ui_pdu--;
+ }
+
+ if ((p_app_cb->ui_rx_q.count == 1) && (appended == FALSE))
+ {
+ data.data_ind.event = LLCP_SAP_EVT_DATA_IND;
+ data.data_ind.local_sap = local_sap;
+ data.data_ind.remote_sap = remote_sap;
+ data.data_ind.link_type = LLCP_LINK_TYPE_LOGICAL_DATA_LINK;
+ (*p_app_cb->p_app_cback) (&data);
+ }
+ }
+ else
+ {
+ LLCP_TRACE_ERROR1 ("llcp_link_proc_ui_pdu (): Unregistered SAP:0x%x", local_sap);
+
+ if (p_msg)
+ {
+ GKI_freebuf (p_msg);
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function llcp_link_proc_agf_pdu
+**
+** Description Process AGF PDU from peer device
+**
+** Returns void
+**
+*******************************************************************************/
+static void llcp_link_proc_agf_pdu (BT_HDR *p_agf)
+{
+ UINT16 agf_length;
+ UINT8 *p, *p_info, *p_pdu_length;
+ UINT16 pdu_hdr, pdu_length;
+ UINT8 dsap, ptype, ssap;
+
+ p_agf->len -= LLCP_PDU_HEADER_SIZE;
+ p_agf->offset += LLCP_PDU_HEADER_SIZE;
+
+ /*
+ ** check integrity of AGF PDU and get number of PDUs in AGF PDU
+ */
+ agf_length = p_agf->len;
+ p = (UINT8 *) (p_agf + 1) + p_agf->offset;
+
+ while (agf_length > 0)
+ {
+ if (agf_length > LLCP_PDU_AGF_LEN_SIZE)
+ {
+ BE_STREAM_TO_UINT16 (pdu_length, p);
+ agf_length -= LLCP_PDU_AGF_LEN_SIZE;
+ }
+ else
+ {
+ break;
+ }
+
+ if (pdu_length <= agf_length)
+ {
+ p += pdu_length;
+ agf_length -= pdu_length;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if (agf_length != 0)
+ {
+ LLCP_TRACE_ERROR0 ("llcp_link_proc_agf_pdu (): Received invalid AGF PDU");
+ GKI_freebuf (p_agf);
+ return;
+ }
+
+ /*
+ ** Process PDUs in AGF
+ */
+ agf_length = p_agf->len;
+ p = (UINT8 *) (p_agf + 1) + p_agf->offset;
+
+ while (agf_length > 0)
+ {
+ /* get length of PDU */
+ p_pdu_length = p;
+ BE_STREAM_TO_UINT16 (pdu_length, p);
+ agf_length -= LLCP_PDU_AGF_LEN_SIZE;
+
+ /* get DSAP/PTYPE/SSAP */
+ p_info = p;
+ BE_STREAM_TO_UINT16 (pdu_hdr, p_info );
+
+ dsap = LLCP_GET_DSAP (pdu_hdr);
+ ptype = (UINT8) (LLCP_GET_PTYPE (pdu_hdr));
+ ssap = LLCP_GET_SSAP (pdu_hdr);
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ LLCP_TRACE_DEBUG4 ("llcp_link_proc_agf_pdu (): Rx DSAP:0x%x, PTYPE:%s (0x%x), SSAP:0x%x in AGF",
+ dsap, llcp_pdu_type (ptype), ptype, ssap);
+#endif
+
+ if ( (ptype == LLCP_PDU_DISC_TYPE)
+ &&(dsap == LLCP_SAP_LM)
+ &&(ssap == LLCP_SAP_LM) )
+ {
+ GKI_freebuf (p_agf);
+ llcp_link_deactivate (LLCP_LINK_REMOTE_INITIATED);
+ return;
+ }
+ else if (ptype == LLCP_PDU_SYMM_TYPE)
+ {
+ LLCP_TRACE_ERROR0 ("llcp_link_proc_agf_pdu (): SYMM PDU exchange shall not be in AGF");
+ }
+ else if (ptype == LLCP_PDU_PAX_TYPE)
+ {
+ LLCP_TRACE_ERROR0 ("llcp_link_proc_agf_pdu (): PAX PDU exchange shall not be used");
+ }
+ else if (ptype == LLCP_PDU_SNL_TYPE)
+ {
+ llcp_sdp_proc_snl ((UINT16) (pdu_length - LLCP_PDU_HEADER_SIZE), p_info);
+ }
+ else if ((ptype == LLCP_PDU_UI_TYPE) && (pdu_length > LLCP_PDU_HEADER_SIZE))
+ {
+ llcp_link_proc_ui_pdu (dsap, ssap, pdu_length, p, NULL);
+ }
+ else if (ptype == LLCP_PDU_I_TYPE)
+ {
+ llcp_dlc_proc_i_pdu (dsap, ssap, pdu_length, p, NULL);
+ }
+ else /* let data link connection handle PDU */
+ {
+ llcp_dlc_proc_rx_pdu (dsap, ptype, ssap, (UINT16) (pdu_length - LLCP_PDU_HEADER_SIZE), p_info);
+ }
+
+ p += pdu_length;
+ agf_length -= pdu_length;
+ }
+
+ GKI_freebuf (p_agf);
+}
+
+/*******************************************************************************
+**
+** Function llcp_link_proc_rx_pdu
+**
+** Description Process received PDU from peer device
+**
+** Returns void
+**
+*******************************************************************************/
+static void llcp_link_proc_rx_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, BT_HDR *p_msg)
+{
+ BOOLEAN free_buffer = TRUE;
+ UINT8 *p_data;
+
+ switch (ptype)
+ {
+ case LLCP_PDU_PAX_TYPE:
+ LLCP_TRACE_ERROR0 ("llcp_link_proc_rx_pdu (); PAX PDU exchange shall not be used");
+ break;
+
+ case LLCP_PDU_DISC_TYPE:
+ if ((dsap == LLCP_SAP_LM) && (ssap == LLCP_SAP_LM))
+ {
+ llcp_link_deactivate (LLCP_LINK_REMOTE_INITIATED);
+ }
+ else
+ {
+ p_data = (UINT8 *) (p_msg + 1) + p_msg->offset + LLCP_PDU_HEADER_SIZE;
+ llcp_dlc_proc_rx_pdu (dsap, ptype, ssap, (UINT16) (p_msg->len - LLCP_PDU_HEADER_SIZE), p_data);
+ }
+ break;
+
+ case LLCP_PDU_SNL_TYPE:
+ p_data = (UINT8 *) (p_msg + 1) + p_msg->offset + LLCP_PDU_HEADER_SIZE;
+ llcp_sdp_proc_snl ((UINT16) (p_msg->len - LLCP_PDU_HEADER_SIZE), p_data);
+ break;
+
+ case LLCP_PDU_AGF_TYPE:
+ llcp_link_proc_agf_pdu (p_msg);
+ free_buffer = FALSE;
+ break;
+
+ case LLCP_PDU_UI_TYPE:
+ llcp_link_proc_ui_pdu (dsap, ssap, 0, NULL, p_msg);
+ free_buffer = FALSE;
+ break;
+
+ case LLCP_PDU_I_TYPE:
+ llcp_dlc_proc_i_pdu (dsap, ssap, 0, NULL, p_msg);
+ free_buffer = FALSE;
+ break;
+
+ default:
+ p_data = (UINT8 *) (p_msg + 1) + p_msg->offset + LLCP_PDU_HEADER_SIZE;
+ llcp_dlc_proc_rx_pdu (dsap, ptype, ssap, (UINT16) (p_msg->len - LLCP_PDU_HEADER_SIZE), p_data);
+ break;
+ }
+
+ if (free_buffer)
+ GKI_freebuf (p_msg);
+}
+
+/*******************************************************************************
+**
+** Function llcp_link_proc_rx_data
+**
+** Description Process received data from NFCC and maintain symmetry state
+**
+** Returns void
+**
+*******************************************************************************/
+static void llcp_link_proc_rx_data (BT_HDR *p_msg)
+{
+ UINT8 *p;
+ UINT16 pdu_hdr, info_length = 0;
+ UINT8 dsap, ptype, ssap;
+ BOOLEAN free_buffer = TRUE;
+ BOOLEAN frame_error = FALSE;
+
+ if(llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_REMOTE_XMIT_NEXT)
+ {
+ llcp_link_stop_link_timer ();
+
+ if (llcp_cb.lcb.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 */
+ llcp_link_process_link_timeout ();
+ }
+ else
+ {
+ if (p_msg->len < LLCP_PDU_HEADER_SIZE)
+ {
+ LLCP_TRACE_ERROR1 ("Received too small PDU: got %d bytes", p_msg->len);
+ frame_error = TRUE;
+ }
+ else
+ {
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+ BE_STREAM_TO_UINT16 (pdu_hdr, p );
+
+ dsap = LLCP_GET_DSAP (pdu_hdr);
+ ptype = (UINT8) (LLCP_GET_PTYPE (pdu_hdr));
+ ssap = LLCP_GET_SSAP (pdu_hdr);
+
+ /* get length of information per PDU type */
+ if ( (ptype == LLCP_PDU_I_TYPE)
+ ||(ptype == LLCP_PDU_RR_TYPE)
+ ||(ptype == LLCP_PDU_RNR_TYPE) )
+ {
+ if (p_msg->len >= LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE)
+ {
+ info_length = p_msg->len - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE;
+ }
+ else
+ {
+ LLCP_TRACE_ERROR0 ("Received I/RR/RNR PDU without sequence");
+ frame_error = TRUE;
+ }
+ }
+ else
+ {
+ info_length = p_msg->len - LLCP_PDU_HEADER_SIZE;
+ }
+
+ /* check if length of information is bigger than link MIU */
+ if ((!frame_error) && (info_length > llcp_cb.lcb.local_link_miu))
+ {
+ LLCP_TRACE_ERROR2 ("Received exceeding MIU (%d): got %d bytes SDU",
+ llcp_cb.lcb.local_link_miu, info_length);
+
+ frame_error = TRUE;
+ }
+ else
+ {
+#if (BT_TRACE_VERBOSE == TRUE)
+ LLCP_TRACE_DEBUG4 ("llcp_link_proc_rx_data (): DSAP:0x%x, PTYPE:%s (0x%x), SSAP:0x%x",
+ dsap, llcp_pdu_type (ptype), ptype, ssap);
+#endif
+
+ if (ptype == LLCP_PDU_SYMM_TYPE)
+ {
+ if (info_length > 0)
+ {
+ LLCP_TRACE_ERROR1 ("Received extra data (%d bytes) in SYMM PDU", info_length);
+ frame_error = TRUE;
+ }
+ }
+ else
+ {
+ /* received other than SYMM */
+ llcp_link_stop_inactivity_timer ();
+
+ llcp_link_proc_rx_pdu (dsap, ptype, ssap, p_msg);
+ free_buffer = FALSE;
+ }
+ }
+ }
+ llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_LOCAL_XMIT_NEXT;
+
+ /* check if any pending packet */
+ llcp_link_check_send_data ();
+ }
+ }
+ else
+ {
+ LLCP_TRACE_ERROR0 ("Received PDU in state of SYMM_MUST_XMIT_NEXT");
+ }
+
+ if (free_buffer)
+ GKI_freebuf (p_msg);
+}
+
+/*******************************************************************************
+**
+** Function llcp_link_get_next_pdu
+**
+** Description Get next PDU from link manager or data links w/wo dequeue
+**
+** Returns pointer of a PDU to send if length_only is FALSE
+** NULL otherwise
+**
+*******************************************************************************/
+static BT_HDR *llcp_link_get_next_pdu (BOOLEAN length_only, UINT16 *p_next_pdu_length)
+{
+ BT_HDR *p_msg;
+ int count, xx;
+ tLLCP_APP_CB *p_app_cb;
+
+ /* processing signalling PDU first */
+ if (llcp_cb.lcb.sig_xmit_q.p_first)
+ {
+ if (length_only)
+ {
+ p_msg = (BT_HDR*) llcp_cb.lcb.sig_xmit_q.p_first;
+ *p_next_pdu_length = p_msg->len;
+ return NULL;
+ }
+ else
+ p_msg = (BT_HDR*) GKI_dequeue (&llcp_cb.lcb.sig_xmit_q);
+
+ return p_msg;
+ }
+ else
+ {
+ /* transmitting logical data link and data link connection equaly */
+ for (xx = 0; xx < 2; xx++)
+ {
+ if (!llcp_cb.lcb.ll_served)
+ {
+ /* Get one from logical link connection */
+ for (count = 0; count < LLCP_NUM_SAPS; count++)
+ {
+ /* round robin schedule without priority */
+ p_app_cb = llcp_util_get_app_cb (llcp_cb.lcb.ll_idx);
+
+ if ( (p_app_cb)
+ &&(p_app_cb->p_app_cback)
+ &&(p_app_cb->ui_xmit_q.count) )
+ {
+ if (length_only)
+ {
+ /* don't alternate next data link to return the same length of PDU */
+ p_msg = (BT_HDR *) p_app_cb->ui_xmit_q.p_first;
+ *p_next_pdu_length = p_msg->len;
+ return NULL;
+ }
+ else
+ {
+ /* check data link connection first in next time */
+ llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
+
+ p_msg = (BT_HDR*) GKI_dequeue (&p_app_cb->ui_xmit_q);
+ llcp_cb.total_tx_ui_pdu--;
+
+ /* this logical link has been served, so start from next logical link next time */
+ llcp_cb.lcb.ll_idx = (llcp_cb.lcb.ll_idx + 1) % LLCP_NUM_SAPS;
+
+ return p_msg;
+ }
+ }
+ else
+ {
+ /* check next logical link connection */
+ llcp_cb.lcb.ll_idx = (llcp_cb.lcb.ll_idx + 1) % LLCP_NUM_SAPS;
+ }
+ }
+
+ /* no data, so check data link connection if not checked yet */
+ llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
+ }
+ else
+ {
+ /* Get one from data link connection */
+ for (count = 0; count < LLCP_MAX_DATA_LINK; count++)
+ {
+ /* round robin schedule without priority */
+ if (llcp_cb.dlcb[llcp_cb.lcb.dl_idx].state != LLCP_DLC_STATE_IDLE)
+ {
+ if (length_only)
+ {
+ *p_next_pdu_length = llcp_dlc_get_next_pdu_length (&llcp_cb.dlcb[llcp_cb.lcb.dl_idx]);
+
+ if (*p_next_pdu_length > 0 )
+ {
+ /* don't change data link connection to return the same length of PDU */
+ return NULL;
+ }
+ else
+ {
+ /* no data, so check next data link connection */
+ llcp_cb.lcb.dl_idx = (llcp_cb.lcb.dl_idx + 1) % LLCP_MAX_DATA_LINK;
+ }
+ }
+ else
+ {
+ p_msg = llcp_dlc_get_next_pdu (&llcp_cb.dlcb[llcp_cb.lcb.dl_idx]);
+
+ /* this data link has been served, so start from next data link next time */
+ llcp_cb.lcb.dl_idx = (llcp_cb.lcb.dl_idx + 1) % LLCP_MAX_DATA_LINK;
+
+ if (p_msg)
+ {
+ /* serve logical data link next time */
+ llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
+ return p_msg;
+ }
+ }
+ }
+ else
+ {
+ /* check next data link connection */
+ llcp_cb.lcb.dl_idx = (llcp_cb.lcb.dl_idx + 1) % LLCP_MAX_DATA_LINK;
+ }
+ }
+
+ /* if all of data link connection doesn't have data to send */
+ if (count >= LLCP_MAX_DATA_LINK)
+ {
+ llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
+ }
+ }
+ }
+ }
+
+ /* nothing to send */
+ *p_next_pdu_length = 0;
+ return NULL;
+}
+
+/*******************************************************************************
+**
+** Function llcp_link_build_next_pdu
+**
+** Description Build a PDU from Link Manager and Data Link
+** Perform aggregation procedure if necessary
+**
+** Returns BT_HDR* if sent any PDU
+**
+*******************************************************************************/
+static BT_HDR *llcp_link_build_next_pdu (BT_HDR *p_pdu)
+{
+ BT_HDR *p_agf = NULL, *p_msg = NULL, *p_next_pdu;
+ UINT8 *p, ptype;
+ UINT16 next_pdu_length, pdu_hdr;
+
+ LLCP_TRACE_DEBUG0 ("llcp_link_build_next_pdu ()");
+
+ /* add any pending SNL PDU into sig_xmit_q for transmitting */
+ llcp_sdp_check_send_snl ();
+
+ if (p_pdu)
+ {
+ /* get PDU type */
+ p = (UINT8 *) (p_pdu + 1) + p_pdu->offset;
+ BE_STREAM_TO_UINT16 (pdu_hdr, p);
+
+ ptype = (UINT8) (LLCP_GET_PTYPE (pdu_hdr));
+
+ if (ptype == LLCP_PDU_AGF_TYPE)
+ {
+ /* add more PDU into this AGF PDU */
+ p_agf = p_pdu;
+ }
+ else
+ {
+ p_msg = p_pdu;
+ }
+ }
+ else
+ {
+ /* Get a PDU from link manager or data links */
+ p_msg = llcp_link_get_next_pdu (FALSE, &next_pdu_length);
+
+ if (!p_msg)
+ {
+ return NULL;
+ }
+ }
+
+ /* Get length of next PDU from link manager or data links without dequeue */
+ llcp_link_get_next_pdu (TRUE, &next_pdu_length);
+ while (next_pdu_length > 0)
+ {
+ /* if it's first visit */
+ if (!p_agf)
+ {
+ /* if next PDU fits into MIU, allocate AGF PDU and copy the first PDU */
+ if (2 + p_msg->len + 2 + next_pdu_length <= llcp_cb.lcb.effective_miu)
+ {
+ p_agf = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);
+ if (p_agf)
+ {
+ p_agf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+ p = (UINT8 *) (p_agf + 1) + p_agf->offset;
+
+ UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (LLCP_SAP_LM, LLCP_PDU_AGF_TYPE, LLCP_SAP_LM ));
+ UINT16_TO_BE_STREAM (p, p_msg->len);
+ memcpy(p, (UINT8 *) (p_msg + 1) + p_msg->offset, p_msg->len);
+
+ p_agf->len = LLCP_PDU_HEADER_SIZE + 2 + p_msg->len;
+
+ GKI_freebuf (p_msg);
+ p_msg = p_agf;
+ }
+ else
+ {
+ LLCP_TRACE_ERROR0 ("llcp_link_build_next_pdu (): Out of buffer");
+ return p_msg;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ /* if next PDU fits into MIU, copy the next PDU into AGF */
+ if (p_agf->len - LLCP_PDU_HEADER_SIZE + 2 + next_pdu_length <= llcp_cb.lcb.effective_miu)
+ {
+ /* Get a next PDU from link manager or data links */
+ p_next_pdu = llcp_link_get_next_pdu (FALSE, &next_pdu_length);
+ if(p_next_pdu != NULL )
+ {
+ p = (UINT8 *) (p_agf + 1) + p_agf->offset + p_agf->len;
+
+ UINT16_TO_BE_STREAM (p, p_next_pdu->len);
+ memcpy (p, (UINT8 *) (p_next_pdu + 1) + p_next_pdu->offset, p_next_pdu->len);
+
+ p_agf->len += 2 + p_next_pdu->len;
+
+ GKI_freebuf (p_next_pdu);
+
+ /* Get next PDU length from link manager or data links without dequeue */
+ llcp_link_get_next_pdu (TRUE, &next_pdu_length);
+ }
+ else
+ {
+ 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 (BT_HDR *p_pdu)
+{
+#if (BT_TRACE_PROTOCOL == TRUE)
+ DispLLCP (p_pdu, FALSE);
+#endif
+ llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_REMOTE_XMIT_NEXT;
+ NFC_SendData (NFC_RF_CONN_ID, p_pdu);
+}
+
+/*******************************************************************************
+**
+** Function llcp_link_connection_cback
+**
+** Description processing incoming data
+**
+** Returns void
+**
+*******************************************************************************/
+void llcp_link_connection_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
+{
+ if (event == NFC_DATA_CEVT)
+ {
+#if (BT_TRACE_PROTOCOL == TRUE)
+ DispLLCP ((BT_HDR *)p_data->data.p_data, TRUE);
+#endif
+ if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATED)
+ {
+ /* respoding SYMM while LLCP is deactivated but RF link is not deactivated yet */
+ llcp_link_send_SYMM ();
+ GKI_freebuf ((BT_HDR *) p_data->data.p_data);
+ }
+ else 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 ((BT_HDR *) p_data->data.p_data);
+ }
+ else
+ {
+ llcp_cb.lcb.flags |= LLCP_LINK_FLAGS_RX_ANY_LLC_PDU;
+ llcp_link_proc_rx_data ((BT_HDR *) p_data->data.p_data);
+ }
+ }
+ else if (event == NFC_ERROR_CEVT)
+ {
+ /* RF interface specific status code */
+ llcp_link_deactivate (*(UINT8*) p_data);
+ }
+ else if (event == NFC_DEACTIVATE_CEVT)
+ {
+ if ( (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING)
+ &&(!llcp_cb.lcb.is_initiator) )
+ {
+ /* peer initiates NFC link deactivation before timeout */
+ llcp_link_stop_link_timer ();
+ llcp_link_process_link_timeout ();
+ }
+ else if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_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 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..1e0b397
--- /dev/null
+++ b/src/nfc/llcp/llcp_main.c
@@ -0,0 +1,191 @@
+/******************************************************************************
+ *
+ * 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"
+
+#if (LLCP_DYNAMIC_MEMORY == FALSE)
+tLLCP_CB llcp_cb;
+#endif
+
+/*******************************************************************************
+**
+** Function llcp_init
+**
+** Description This function is called once at startup to initialize
+** all the LLCP structures
+**
+** Returns void
+**
+*******************************************************************************/
+void llcp_init (void)
+{
+ UINT32 pool_count;
+
+ memset (&llcp_cb, 0, sizeof (tLLCP_CB));
+
+ llcp_cb.trace_level = LLCP_INITIAL_TRACE_LEVEL;
+
+ LLCP_TRACE_DEBUG0 ("LLCP - llcp_init ()");
+
+ llcp_cb.lcb.local_link_miu = (LLCP_MIU <= LLCP_MAX_MIU ? LLCP_MIU : LLCP_MAX_MIU);
+ llcp_cb.lcb.local_opt = LLCP_OPT_VALUE;
+ llcp_cb.lcb.local_wt = LLCP_WAITING_TIME;
+ llcp_cb.lcb.local_lto = LLCP_LTO_VALUE;
+
+ llcp_cb.lcb.inact_timeout_init = LLCP_INIT_INACTIVITY_TIMEOUT;
+ llcp_cb.lcb.inact_timeout_target = LLCP_TARGET_INACTIVITY_TIMEOUT;
+ llcp_cb.lcb.symm_delay = LLCP_DELAY_RESP_TIME;
+ llcp_cb.lcb.data_link_timeout = LLCP_DATA_LINK_CONNECTION_TOUT;
+ llcp_cb.lcb.delay_first_pdu_timeout = LLCP_DELAY_TIME_TO_SEND_FIRST_PDU;
+
+ llcp_cb.lcb.wks = LLCP_WKS_MASK_LM;
+
+ /* total number of buffers for LLCP */
+ pool_count = GKI_poolcount (LLCP_POOL_ID);
+
+ /* number of buffers for receiving data */
+ llcp_cb.num_rx_buff = (pool_count * LLCP_RX_BUFF_RATIO) / 100;
+
+ /* rx congestion start/end threshold */
+ llcp_cb.overall_rx_congest_start = (UINT8) ((llcp_cb.num_rx_buff * LLCP_RX_CONGEST_START) / 100);
+ llcp_cb.overall_rx_congest_end = (UINT8) ((llcp_cb.num_rx_buff * LLCP_RX_CONGEST_END) / 100);
+
+ /* max number of buffers for receiving data on logical data link */
+ llcp_cb.max_num_ll_rx_buff = (UINT8) ((llcp_cb.num_rx_buff * LLCP_LL_RX_BUFF_LIMIT) / 100);
+
+ LLCP_TRACE_DEBUG4 ("num_rx_buff = %d, rx_congest_start = %d, rx_congest_end = %d, max_num_ll_rx_buff = %d",
+ llcp_cb.num_rx_buff, llcp_cb.overall_rx_congest_start,
+ llcp_cb.overall_rx_congest_end, llcp_cb.max_num_ll_rx_buff);
+
+ /* max number of buffers for transmitting data */
+ llcp_cb.max_num_tx_buff = (UINT8) (pool_count - llcp_cb.num_rx_buff);
+
+ /* max number of buffers for transmitting data on logical data link */
+ llcp_cb.max_num_ll_tx_buff = (UINT8) ((llcp_cb.max_num_tx_buff * LLCP_LL_TX_BUFF_LIMIT) / 100);
+
+ LLCP_TRACE_DEBUG2 ("max_num_tx_buff = %d, max_num_ll_tx_buff = %d",
+ llcp_cb.max_num_tx_buff, llcp_cb.max_num_ll_tx_buff);
+
+ llcp_cb.ll_tx_uncongest_ntf_start_sap = LLCP_SAP_SDP + 1;
+
+ LLCP_RegisterServer (LLCP_SAP_SDP, LLCP_LINK_TYPE_DATA_LINK_CONNECTION, "urn:nfc:sn:sdp", llcp_sdp_proc_data);
+}
+
+/*******************************************************************************
+**
+** Function llcp_cleanup
+**
+** Description This function is called once at closing to clean up
+**
+** Returns void
+**
+*******************************************************************************/
+void llcp_cleanup (void)
+{
+ UINT8 sap;
+ tLLCP_APP_CB *p_app_cb;
+
+ LLCP_TRACE_DEBUG0 ("LLCP - llcp_cleanup ()");
+
+ for (sap = LLCP_SAP_SDP; sap < LLCP_NUM_SAPS; sap++)
+ {
+ p_app_cb = llcp_util_get_app_cb (sap);
+
+ if ( (p_app_cb)
+ &&(p_app_cb->p_app_cback) )
+ {
+ LLCP_Deregister (sap);
+ }
+ }
+
+ nfc_stop_quick_timer (&llcp_cb.lcb.inact_timer);
+ nfc_stop_quick_timer (&llcp_cb.lcb.timer);
+}
+
+/*******************************************************************************
+**
+** Function llcp_process_timeout
+**
+** Description This function is called when an LLCP-related timeout occurs
+**
+** Returns void
+**
+*******************************************************************************/
+void llcp_process_timeout (TIMER_LIST_ENT *p_tle)
+{
+ UINT8 reason;
+
+ LLCP_TRACE_DEBUG1 ("llcp_process_timeout: event=%d", p_tle->event);
+
+ switch (p_tle->event)
+ {
+ case NFC_TTYPE_LLCP_LINK_MANAGER:
+ /* Link timeout or Symm timeout */
+ llcp_link_process_link_timeout ();
+ break;
+
+ case NFC_TTYPE_LLCP_LINK_INACT:
+ /* inactivity timeout */
+ llcp_link_deactivate (LLCP_LINK_LOCAL_INITIATED);
+ break;
+
+ case NFC_TTYPE_LLCP_DATA_LINK:
+ reason = LLCP_SAP_DISCONNECT_REASON_TIMEOUT;
+ llcp_dlsm_execute ((tLLCP_DLCB *) (p_tle->param), LLCP_DLC_EVENT_TIMEOUT, &reason);
+ break;
+
+ case NFC_TTYPE_LLCP_DELAY_FIRST_PDU:
+ llcp_link_check_send_data ();
+ break;
+
+ default:
+ break;
+ }
+}
+
+/*******************************************************************************
+**
+** Function LLCP_SetTraceLevel
+**
+** Description This function sets the trace level for LLCP. If called with
+** a value of 0xFF, it simply returns the current trace level.
+**
+** Returns The new or current trace level
+**
+*******************************************************************************/
+UINT8 LLCP_SetTraceLevel (UINT8 new_level)
+{
+ if (new_level != 0xFF)
+ llcp_cb.trace_level = new_level;
+
+ return (llcp_cb.trace_level);
+}
diff --git a/src/nfc/llcp/llcp_sdp.c b/src/nfc/llcp/llcp_sdp.c
new file mode 100644
index 0000000..71a97b4
--- /dev/null
+++ b/src/nfc/llcp/llcp_sdp.c
@@ -0,0 +1,521 @@
+/******************************************************************************
+ *
+ * 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(NFC_NXP_NOT_OPEN_INCLUDED == 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)
+{
+ /*
+ ** Do nothing
+ ** llcp_sdp_proc_SNL () is called by link layer
+ */
+}
+
+/*******************************************************************************
+**
+** Function llcp_sdp_check_send_snl
+**
+** Description Enqueue Service Name Lookup PDU into sig_xmit_q for transmitting
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void llcp_sdp_check_send_snl (void)
+{
+ UINT8 *p;
+
+ if (llcp_cb.sdp_cb.p_snl)
+ {
+ LLCP_TRACE_DEBUG0 ("SDP: llcp_sdp_check_send_snl ()");
+
+ llcp_cb.sdp_cb.p_snl->len += LLCP_PDU_HEADER_SIZE;
+ llcp_cb.sdp_cb.p_snl->offset -= LLCP_PDU_HEADER_SIZE;
+
+ p = (UINT8 *) (llcp_cb.sdp_cb.p_snl + 1) + llcp_cb.sdp_cb.p_snl->offset;
+ UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (LLCP_SAP_SDP, LLCP_PDU_SNL_TYPE, LLCP_SAP_SDP ));
+
+ GKI_enqueue (&llcp_cb.lcb.sig_xmit_q, llcp_cb.sdp_cb.p_snl);
+ llcp_cb.sdp_cb.p_snl = NULL;
+ }
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 tid, char *p_name)
+{
+ UINT8 *p;
+ UINT16 name_len = (UINT16) strlen (p_name);
+
+ p = (UINT8 *) (llcp_cb.sdp_cb.p_snl + 1) + llcp_cb.sdp_cb.p_snl->offset + llcp_cb.sdp_cb.p_snl->len;
+
+ UINT8_TO_BE_STREAM (p, LLCP_SDREQ_TYPE);
+ UINT8_TO_BE_STREAM (p, (1 + name_len));
+ UINT8_TO_BE_STREAM (p, tid);
+ ARRAY_TO_BE_STREAM (p, p_name, name_len);
+
+ llcp_cb.sdp_cb.p_snl->len += LLCP_SDREQ_MIN_LEN + name_len;
+}
+
+/*******************************************************************************
+**
+** Function llcp_sdp_send_sdreq
+**
+** Description Send Service Discovery Request
+**
+**
+** Returns LLCP_STATUS
+**
+*******************************************************************************/
+tLLCP_STATUS llcp_sdp_send_sdreq (UINT8 tid, char *p_name)
+{
+ tLLCP_STATUS status;
+ UINT16 name_len;
+ UINT16 available_bytes;
+
+ LLCP_TRACE_DEBUG2 ("llcp_sdp_send_sdreq (): tid=0x%x, ServiceName=%s", tid, p_name);
+
+ /* if there is no pending SNL */
+ if (!llcp_cb.sdp_cb.p_snl)
+ {
+ llcp_cb.sdp_cb.p_snl = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);
+
+ if (llcp_cb.sdp_cb.p_snl)
+ {
+ llcp_cb.sdp_cb.p_snl->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + LLCP_PDU_HEADER_SIZE;
+ llcp_cb.sdp_cb.p_snl->len = 0;
+ }
+ }
+
+ if (llcp_cb.sdp_cb.p_snl)
+ {
+ available_bytes = GKI_get_buf_size (llcp_cb.sdp_cb.p_snl)
+ - BT_HDR_SIZE - llcp_cb.sdp_cb.p_snl->offset
+ - llcp_cb.sdp_cb.p_snl->len;
+
+ name_len = (UINT16) strlen (p_name);
+
+ /* if SDREQ parameter can be added in SNL */
+ if ( (available_bytes >= LLCP_SDREQ_MIN_LEN + name_len)
+ &&(llcp_cb.sdp_cb.p_snl->len + LLCP_SDREQ_MIN_LEN + name_len <= llcp_cb.lcb.effective_miu) )
+ {
+ llcp_sdp_add_sdreq (tid, p_name);
+ status = LLCP_STATUS_SUCCESS;
+ }
+ else
+ {
+ /* send pending SNL PDU to LM */
+ llcp_sdp_check_send_snl ();
+
+ llcp_cb.sdp_cb.p_snl = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);
+
+ if (llcp_cb.sdp_cb.p_snl)
+ {
+ llcp_cb.sdp_cb.p_snl->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + LLCP_PDU_HEADER_SIZE;
+ llcp_cb.sdp_cb.p_snl->len = 0;
+
+ llcp_sdp_add_sdreq (tid, p_name);
+
+ status = LLCP_STATUS_SUCCESS;
+ }
+ else
+ {
+ status = LLCP_STATUS_FAIL;
+ }
+ }
+ }
+ else
+ {
+ status = LLCP_STATUS_FAIL;
+ }
+ /* if LM is waiting for PDUs from upper layer */
+ if ( (status == LLCP_STATUS_SUCCESS)
+ &&(llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT) )
+ {
+ llcp_link_check_send_data ();
+ }
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function llcp_sdp_add_sdres
+**
+** Description Add Service Discovery Response into SNL PDU
+**
+**
+** Returns void
+**
+*******************************************************************************/
+static void llcp_sdp_add_sdres (UINT8 tid, UINT8 sap)
+{
+ UINT8 *p;
+
+ p = (UINT8 *) (llcp_cb.sdp_cb.p_snl + 1) + llcp_cb.sdp_cb.p_snl->offset + llcp_cb.sdp_cb.p_snl->len;
+
+ UINT8_TO_BE_STREAM (p, LLCP_SDRES_TYPE);
+ UINT8_TO_BE_STREAM (p, LLCP_SDRES_LEN);
+ UINT8_TO_BE_STREAM (p, tid);
+ UINT8_TO_BE_STREAM (p, sap);
+
+ llcp_cb.sdp_cb.p_snl->len += 2 + LLCP_SDRES_LEN; /* type and length */
+}
+
+/*******************************************************************************
+**
+** Function llcp_sdp_send_sdres
+**
+** Description Send Service Discovery Response
+**
+**
+** Returns LLCP_STATUS
+**
+*******************************************************************************/
+static tLLCP_STATUS llcp_sdp_send_sdres (UINT8 tid, UINT8 sap)
+{
+ tLLCP_STATUS status;
+ UINT16 available_bytes;
+
+ LLCP_TRACE_DEBUG2 ("llcp_sdp_send_sdres (): tid=0x%x, SAP=0x%x", tid, sap);
+
+ /* if there is no pending SNL */
+ if (!llcp_cb.sdp_cb.p_snl)
+ {
+ llcp_cb.sdp_cb.p_snl = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);
+
+ if (llcp_cb.sdp_cb.p_snl)
+ {
+ llcp_cb.sdp_cb.p_snl->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + LLCP_PDU_HEADER_SIZE;
+ llcp_cb.sdp_cb.p_snl->len = 0;
+ }
+ }
+
+ if (llcp_cb.sdp_cb.p_snl)
+ {
+ available_bytes = GKI_get_buf_size (llcp_cb.sdp_cb.p_snl)
+ - BT_HDR_SIZE - llcp_cb.sdp_cb.p_snl->offset
+ - llcp_cb.sdp_cb.p_snl->len;
+
+ /* if SDRES parameter can be added in SNL */
+ if ( (available_bytes >= 2 + LLCP_SDRES_LEN)
+ &&(llcp_cb.sdp_cb.p_snl->len + 2 + LLCP_SDRES_LEN <= llcp_cb.lcb.effective_miu) )
+ {
+ llcp_sdp_add_sdres (tid, sap);
+ status = LLCP_STATUS_SUCCESS;
+ }
+ else
+ {
+ /* send pending SNL PDU to LM */
+ llcp_sdp_check_send_snl ();
+
+ llcp_cb.sdp_cb.p_snl = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);
+
+ if (llcp_cb.sdp_cb.p_snl)
+ {
+ llcp_cb.sdp_cb.p_snl->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + LLCP_PDU_HEADER_SIZE;
+ llcp_cb.sdp_cb.p_snl->len = 0;
+
+ llcp_sdp_add_sdres (tid, sap);
+
+ status = LLCP_STATUS_SUCCESS;
+ }
+ else
+ {
+ status = LLCP_STATUS_FAIL;
+ }
+ }
+ }
+ else
+ {
+ status = LLCP_STATUS_FAIL;
+ }
+ /* if LM is waiting for PDUs from upper layer */
+ if ( (status == LLCP_STATUS_SUCCESS)
+ &&(llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT) )
+ {
+ llcp_link_check_send_data ();
+ }
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function llcp_sdp_get_sap_by_name
+**
+** Description Search SAP by service name
+**
+**
+** Returns SAP if success
+**
+*******************************************************************************/
+UINT8 llcp_sdp_get_sap_by_name (char *p_name, UINT8 length)
+{
+ UINT8 sap;
+ tLLCP_APP_CB *p_app_cb;
+
+ for (sap = LLCP_SAP_SDP; sap <= LLCP_UPPER_BOUND_SDP_SAP; sap++)
+ {
+ p_app_cb = llcp_util_get_app_cb (sap);
+
+ if ( (p_app_cb)
+ &&(p_app_cb->p_app_cback)
+ &&(strlen((char*)p_app_cb->p_service_name) == length)
+ &&(!strncmp((char*)p_app_cb->p_service_name, p_name, length)) )
+ {
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 tid, UINT8 sap)
+{
+ UINT8 i;
+
+ LLCP_TRACE_DEBUG2 ("llcp_sdp_return_sap (): tid=0x%x, SAP=0x%x", tid, sap);
+
+ for (i = 0; i < LLCP_MAX_SDP_TRANSAC; i++)
+ {
+ if ( (llcp_cb.sdp_cb.transac[i].p_cback)
+ &&(llcp_cb.sdp_cb.transac[i].tid == tid) )
+ {
+ (*llcp_cb.sdp_cb.transac[i].p_cback) (tid, sap);
+
+ llcp_cb.sdp_cb.transac[i].p_cback = NULL;
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function llcp_sdp_proc_deactivation
+**
+** Description Report SDP failure for any pending request because of deactivation
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void llcp_sdp_proc_deactivation (void)
+{
+ UINT8 i;
+
+ LLCP_TRACE_DEBUG0 ("llcp_sdp_proc_deactivation ()");
+
+ for (i = 0; i < LLCP_MAX_SDP_TRANSAC; i++)
+ {
+ if (llcp_cb.sdp_cb.transac[i].p_cback)
+ {
+ (*llcp_cb.sdp_cb.transac[i].p_cback) (llcp_cb.sdp_cb.transac[i].tid, 0x00);
+
+ llcp_cb.sdp_cb.transac[i].p_cback = NULL;
+ }
+ }
+
+ /* free any pending SNL PDU */
+ if (llcp_cb.sdp_cb.p_snl)
+ {
+ GKI_freebuf (llcp_cb.sdp_cb.p_snl);
+ llcp_cb.sdp_cb.p_snl = NULL;
+ }
+
+ llcp_cb.sdp_cb.next_tid = 0;
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 sdu_length, UINT8 *p)
+{
+ UINT8 type, length, tid, sap, *p_value;
+
+ LLCP_TRACE_DEBUG0 ("llcp_sdp_proc_snl ()");
+
+ if ((llcp_cb.lcb.agreed_major_version < LLCP_MIN_SNL_MAJOR_VERSION)||
+ ((llcp_cb.lcb.agreed_major_version == LLCP_MIN_SNL_MAJOR_VERSION)&&(llcp_cb.lcb.agreed_minor_version < LLCP_MIN_SNL_MINOR_VERSION)))
+ {
+ LLCP_TRACE_DEBUG0 ("llcp_sdp_proc_snl(): version number less than 1.1, SNL not supported.");
+ return LLCP_STATUS_FAIL;
+ }
+ while (sdu_length >= 2) /* at least type and length */
+ {
+ BE_STREAM_TO_UINT8 (type, p);
+ BE_STREAM_TO_UINT8 (length, p);
+
+ switch (type)
+ {
+ case LLCP_SDREQ_TYPE:
+ if ( (length > 1) /* TID and sevice name */
+ &&(sdu_length >= 2 + length) ) /* type, length, TID and service name */
+ {
+ p_value = p;
+ BE_STREAM_TO_UINT8 (tid, p_value);
+ sap = llcp_sdp_get_sap_by_name ((char*) p_value, (UINT8) (length - 1));
+ llcp_sdp_send_sdres (tid, sap);
+ }
+ else
+ {
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 == NFA_DTA_LLCP_MODE))
+ {
+ LLCP_TRACE_ERROR0 ("DEBUG> 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..2f4420c
--- /dev/null
+++ b/src/nfc/llcp/llcp_util.c
@@ -0,0 +1,919 @@
+/******************************************************************************
+ *
+ * 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
+**
+*******************************************************************************/
+BOOLEAN llcp_util_parse_link_params (UINT16 length, UINT8 *p_bytes)
+{
+ UINT8 param_type, param_len, *p = p_bytes;
+
+ while (length)
+ {
+ BE_STREAM_TO_UINT8 (param_type, p);
+ length--;
+
+ switch (param_type)
+ {
+ case LLCP_VERSION_TYPE:
+ BE_STREAM_TO_UINT8 (param_len, p);
+ BE_STREAM_TO_UINT8 (llcp_cb.lcb.peer_version, p);
+ LLCP_TRACE_DEBUG1 ("Peer Version - 0x%02X", llcp_cb.lcb.peer_version);
+ break;
+
+ case LLCP_MIUX_TYPE:
+ BE_STREAM_TO_UINT8 (param_len, p);
+ BE_STREAM_TO_UINT16 (llcp_cb.lcb.peer_miu, p);
+ llcp_cb.lcb.peer_miu &= LLCP_MIUX_MASK;
+ llcp_cb.lcb.peer_miu += LLCP_DEFAULT_MIU;
+ LLCP_TRACE_DEBUG1 ("Peer MIU - %d bytes", llcp_cb.lcb.peer_miu);
+ break;
+
+ case LLCP_WKS_TYPE:
+ BE_STREAM_TO_UINT8 (param_len, p);
+ BE_STREAM_TO_UINT16 (llcp_cb.lcb.peer_wks, p);
+ LLCP_TRACE_DEBUG1 ("Peer WKS - 0x%04X", llcp_cb.lcb.peer_wks);
+ break;
+
+ case LLCP_LTO_TYPE:
+ BE_STREAM_TO_UINT8 (param_len, p);
+ BE_STREAM_TO_UINT8 (llcp_cb.lcb.peer_lto, p);
+ llcp_cb.lcb.peer_lto *= LLCP_LTO_UNIT; /* 10ms unit */
+ LLCP_TRACE_DEBUG1 ("Peer LTO - %d ms", llcp_cb.lcb.peer_lto);
+ break;
+
+ case LLCP_OPT_TYPE:
+ BE_STREAM_TO_UINT8 (param_len, p);
+ BE_STREAM_TO_UINT8 (llcp_cb.lcb.peer_opt, p);
+ LLCP_TRACE_DEBUG1 ("Peer OPT - 0x%02X", llcp_cb.lcb.peer_opt);
+ break;
+
+ default:
+ LLCP_TRACE_ERROR1 ("llcp_util_parse_link_params (): Unexpected type 0x%x", param_type);
+ BE_STREAM_TO_UINT8 (param_len, p);
+ p += param_len;
+ break;
+ }
+
+ if (length >= param_len + 1)
+ length -= param_len + 1;
+ else
+ {
+ LLCP_TRACE_ERROR0 ("llcp_util_parse_link_params (): Bad LTV's");
+ return (FALSE);
+ }
+ }
+ return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function llcp_util_adjust_ll_congestion
+**
+** Description adjust tx/rx congestion thresholds on logical link
+**
+** Returns void
+**
+*******************************************************************************/
+void llcp_util_adjust_ll_congestion (void)
+{
+ /* buffer quota is allocated equally for each logical data link */
+ if (llcp_cb.num_logical_data_link)
+ {
+ llcp_cb.ll_tx_congest_start = llcp_cb.max_num_ll_tx_buff / llcp_cb.num_logical_data_link;
+ llcp_cb.ll_rx_congest_start = llcp_cb.max_num_ll_rx_buff / llcp_cb.num_logical_data_link;
+ }
+ else
+ {
+ llcp_cb.ll_tx_congest_start = llcp_cb.max_num_ll_tx_buff;
+ llcp_cb.ll_rx_congest_start = llcp_cb.max_num_ll_rx_buff;
+ }
+
+ /* at least one for each logical data link */
+ if (llcp_cb.ll_tx_congest_start == 0)
+ {
+ llcp_cb.ll_tx_congest_start = 1;
+ }
+ if (llcp_cb.ll_rx_congest_start == 0)
+ {
+ llcp_cb.ll_rx_congest_start = 1;
+ }
+
+ if (llcp_cb.ll_tx_congest_start > 1)
+ {
+ llcp_cb.ll_tx_congest_end = 1;
+ }
+ else
+ {
+ llcp_cb.ll_tx_congest_end = 0;
+ }
+
+ LLCP_TRACE_DEBUG4 ("num_logical_data_link=%d, ll_tx_congest_start=%d, ll_tx_congest_end=%d, ll_rx_congest_start=%d",
+ llcp_cb.num_logical_data_link,
+ llcp_cb.ll_tx_congest_start,
+ llcp_cb.ll_tx_congest_end,
+ llcp_cb.ll_rx_congest_start);
+}
+
+/*******************************************************************************
+**
+** Function llcp_util_adjust_dl_rx_congestion
+**
+** Description adjust rx congestion thresholds on data link
+**
+** Returns void
+**
+*******************************************************************************/
+void llcp_util_adjust_dl_rx_congestion (void)
+{
+ UINT8 idx, rx_congest_start;
+
+ if (llcp_cb.num_data_link_connection)
+ {
+ rx_congest_start = llcp_cb.num_rx_buff / llcp_cb.num_data_link_connection;
+
+ for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++)
+ {
+ if (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED)
+ {
+ if (rx_congest_start > llcp_cb.dlcb[idx].local_rw)
+ {
+ /*
+ ** set rx congestion threshold LLCP_DL_MIN_RX_CONGEST at least
+ ** so, we don't need to flow off too often.
+ */
+ if (llcp_cb.dlcb[idx].local_rw + 1 > LLCP_DL_MIN_RX_CONGEST)
+ llcp_cb.dlcb[idx].rx_congest_threshold = llcp_cb.dlcb[idx].local_rw + 1;
+ else
+ llcp_cb.dlcb[idx].rx_congest_threshold = LLCP_DL_MIN_RX_CONGEST;
+ }
+ else
+ {
+ llcp_cb.dlcb[idx].rx_congest_threshold = LLCP_DL_MIN_RX_CONGEST;
+ }
+
+ LLCP_TRACE_DEBUG3 ("DLC[%d], local_rw=%d, rx_congest_threshold=%d",
+ idx,
+ llcp_cb.dlcb[idx].local_rw,
+ llcp_cb.dlcb[idx].rx_congest_threshold);
+ }
+ }
+ }
+
+}
+
+/*******************************************************************************
+**
+** Function llcp_util_check_rx_congested_status
+**
+** Description Update rx congested status
+**
+** Returns void
+**
+*******************************************************************************/
+void llcp_util_check_rx_congested_status (void)
+{
+ UINT8 idx;
+
+ if (llcp_cb.overall_rx_congested)
+ {
+ /* check if rx congestion clear */
+ if (llcp_cb.total_rx_ui_pdu + llcp_cb.total_rx_i_pdu <= llcp_cb.overall_rx_congest_end)
+ {
+ LLCP_TRACE_DEBUG3 ("llcp_util_check_rx_congested_status (): rx link is uncongested, %d+%d <= %d",
+ llcp_cb.total_rx_ui_pdu, llcp_cb.total_rx_i_pdu,
+ llcp_cb.overall_rx_congest_end);
+
+ llcp_cb.overall_rx_congested = FALSE;
+
+ for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++)
+ {
+ /* set flag to clear local busy status on data link connections */
+ if ( (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED)
+ &&(llcp_cb.dlcb[idx].is_rx_congested == FALSE) )
+ {
+ llcp_cb.dlcb[idx].flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* check if rx link is congested */
+ if (llcp_cb.total_rx_ui_pdu + llcp_cb.total_rx_i_pdu >= llcp_cb.overall_rx_congest_start)
+ {
+ LLCP_TRACE_WARNING3 ("llcp_util_check_rx_congested_status (): rx link is congested, %d+%d >= %d",
+ llcp_cb.total_rx_ui_pdu, llcp_cb.total_rx_i_pdu,
+ llcp_cb.overall_rx_congest_start);
+
+ llcp_cb.overall_rx_congested = TRUE;
+
+ /* rx link congestion is started, send RNR to remote end point */
+ for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++)
+ {
+ if ( (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED)
+ &&(llcp_cb.dlcb[idx].is_rx_congested == FALSE) )
+ {
+ llcp_cb.dlcb[idx].flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
+ }
+ }
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function llcp_util_send_ui
+**
+** Description Send UI PDU
+**
+** Returns tLLCP_STATUS
+**
+*******************************************************************************/
+tLLCP_STATUS llcp_util_send_ui (UINT8 ssap, UINT8 dsap, tLLCP_APP_CB *p_app_cb, BT_HDR *p_msg)
+{
+ UINT8 *p;
+ tLLCP_STATUS status = LLCP_STATUS_SUCCESS;
+
+ p_msg->offset -= LLCP_PDU_HEADER_SIZE;
+ p_msg->len += LLCP_PDU_HEADER_SIZE;
+
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+ UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (dsap, LLCP_PDU_UI_TYPE, ssap));
+
+ GKI_enqueue (&p_app_cb->ui_xmit_q, p_msg);
+ llcp_cb.total_tx_ui_pdu++;
+
+ llcp_link_check_send_data ();
+
+ if ( (p_app_cb->is_ui_tx_congested)
+ ||(p_app_cb->ui_xmit_q.count >= llcp_cb.ll_tx_congest_start)
+ ||(llcp_cb.overall_tx_congested)
+ ||(llcp_cb.total_tx_ui_pdu >= llcp_cb.max_num_ll_tx_buff) )
+ {
+ /* set congested here so overall congestion check routine will not report event again, */
+ /* or notify uncongestion later */
+ p_app_cb->is_ui_tx_congested = TRUE;
+
+ LLCP_TRACE_WARNING2 ("Logical link (SAP=0x%X) congested: ui_xmit_q.count=%d",
+ ssap, p_app_cb->ui_xmit_q.count);
+
+ status = LLCP_STATUS_CONGESTED;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function llcp_util_send_disc
+**
+** Description Send DISC PDU
+**
+** Returns void
+**
+*******************************************************************************/
+void llcp_util_send_disc (UINT8 dsap, UINT8 ssap)
+{
+ BT_HDR *p_msg;
+ UINT8 *p;
+
+ p_msg = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);
+
+ if (p_msg)
+ {
+ p_msg->len = LLCP_PDU_DISC_SIZE;
+ p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+ UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (dsap, LLCP_PDU_DISC_TYPE, ssap));
+
+ GKI_enqueue (&llcp_cb.lcb.sig_xmit_q, p_msg);
+ llcp_link_check_send_data ();
+ }
+}
+
+/*******************************************************************************
+**
+** Function llcp_util_allocate_data_link
+**
+** Description Allocate tLLCP_DLCB for data link connection
+**
+** Returns tLLCP_DLCB *
+**
+******************************************************************************/
+tLLCP_DLCB *llcp_util_allocate_data_link (UINT8 reg_sap, UINT8 remote_sap)
+{
+ tLLCP_DLCB *p_dlcb = NULL;
+ int idx;
+
+ LLCP_TRACE_DEBUG2 ("llcp_util_allocate_data_link (): reg_sap = 0x%x, remote_sap = 0x%x",
+ reg_sap, remote_sap);
+
+ for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++)
+ {
+ if (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_IDLE)
+ {
+ p_dlcb = &(llcp_cb.dlcb[idx]);
+
+ memset (p_dlcb, 0, sizeof (tLLCP_DLCB));
+ break;
+ }
+ }
+
+ if (!p_dlcb)
+ {
+ LLCP_TRACE_ERROR0 ("llcp_util_allocate_data_link (): Out of DLCB");
+ }
+ else
+ {
+ p_dlcb->p_app_cb = llcp_util_get_app_cb (reg_sap);
+ p_dlcb->local_sap = reg_sap;
+ p_dlcb->remote_sap = remote_sap;
+ p_dlcb->timer.param = (TIMER_PARAM_TYPE) p_dlcb;
+
+ /* this is for inactivity timer and congestion control. */
+ llcp_cb.num_data_link_connection++;
+
+ LLCP_TRACE_DEBUG3 ("llcp_util_allocate_data_link (): local_sap = 0x%x, remote_sap = 0x%x, num_data_link_connection = %d",
+ p_dlcb->local_sap, p_dlcb->remote_sap, llcp_cb.num_data_link_connection);
+ }
+ return p_dlcb;
+}
+
+/*******************************************************************************
+**
+** Function llcp_util_deallocate_data_link
+**
+** Description Deallocate tLLCP_DLCB
+**
+** Returns void
+**
+******************************************************************************/
+void llcp_util_deallocate_data_link (tLLCP_DLCB *p_dlcb)
+{
+ if (p_dlcb)
+ {
+ LLCP_TRACE_DEBUG1 ("llcp_util_deallocate_data_link (): local_sap = 0x%x", p_dlcb->local_sap);
+
+ if (p_dlcb->state != LLCP_DLC_STATE_IDLE)
+ {
+ nfc_stop_quick_timer (&p_dlcb->timer);
+ llcp_dlc_flush_q (p_dlcb);
+
+ p_dlcb->state = LLCP_DLC_STATE_IDLE;
+
+ if (llcp_cb.num_data_link_connection > 0)
+ {
+ llcp_cb.num_data_link_connection--;
+ }
+
+ LLCP_TRACE_DEBUG1 ("llcp_util_deallocate_data_link (): num_data_link_connection = %d", llcp_cb.num_data_link_connection);
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function llcp_util_send_connect
+**
+** Description Send CONNECT PDU
+**
+** Returns tLLCP_STATUS
+**
+******************************************************************************/
+tLLCP_STATUS llcp_util_send_connect (tLLCP_DLCB *p_dlcb, tLLCP_CONNECTION_PARAMS *p_params)
+{
+ BT_HDR *p_msg;
+ UINT8 *p;
+ UINT16 miu_len = 0, rw_len = 0, sn_len = 0;
+
+ if (p_params->miu != LLCP_DEFAULT_MIU)
+ {
+ miu_len = 4; /* TYPE, LEN, 2 bytes MIU */
+ }
+ if (p_params->rw != LLCP_DEFAULT_RW)
+ {
+ rw_len = 3; /* TYPE, LEN, 1 byte RW */
+ p_params->rw &= 0x0F; /* only 4 bits */
+ }
+ if ((strlen (p_params->sn)) && (p_dlcb->remote_sap == LLCP_SAP_SDP))
+ {
+ sn_len = (UINT16) (2 + strlen (p_params->sn)); /* TYPE, LEN, SN */
+ }
+
+ p_msg = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);
+
+ if (p_msg)
+ {
+ p_msg->len = LLCP_PDU_HEADER_SIZE + miu_len + rw_len + sn_len;
+ p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+
+ UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (p_dlcb->remote_sap, LLCP_PDU_CONNECT_TYPE, p_dlcb->local_sap));
+
+ if (miu_len)
+ {
+ UINT8_TO_BE_STREAM (p, LLCP_MIUX_TYPE);
+ UINT8_TO_BE_STREAM (p, LLCP_MIUX_LEN);
+ UINT16_TO_BE_STREAM (p, p_params->miu - LLCP_DEFAULT_MIU);
+ }
+
+ if (rw_len)
+ {
+ UINT8_TO_BE_STREAM (p, LLCP_RW_TYPE);
+ UINT8_TO_BE_STREAM (p, LLCP_RW_LEN);
+ UINT8_TO_BE_STREAM (p, p_params->rw);
+ }
+
+ if (sn_len)
+ {
+ UINT8_TO_BE_STREAM (p, LLCP_SN_TYPE);
+ UINT8_TO_BE_STREAM (p, sn_len - 2);
+ memcpy (p, p_params->sn, sn_len - 2);
+ }
+
+ GKI_enqueue (&llcp_cb.lcb.sig_xmit_q, p_msg);
+ llcp_link_check_send_data ();
+
+ return LLCP_STATUS_SUCCESS;
+ }
+
+ return LLCP_STATUS_FAIL;
+}
+
+/*******************************************************************************
+**
+** Function llcp_util_parse_connect
+**
+** Description Parse CONNECT PDU
+**
+** Returns tLLCP_STATUS
+**
+*******************************************************************************/
+tLLCP_STATUS llcp_util_parse_connect (UINT8 *p_bytes, UINT16 length, tLLCP_CONNECTION_PARAMS *p_params)
+{
+ UINT8 param_type, param_len, *p = p_bytes;
+
+ p_params->miu = LLCP_DEFAULT_MIU;
+ p_params->rw = LLCP_DEFAULT_RW;
+ p_params->sn[0] = 0;
+ 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)
+{
+ BT_HDR *p_msg;
+ UINT8 *p;
+ UINT16 miu_len = 0, rw_len = 0;
+
+ if (p_params->miu != LLCP_DEFAULT_MIU)
+ {
+ miu_len = 4;
+ }
+ if (p_params->rw != LLCP_DEFAULT_RW)
+ {
+ rw_len = 3;
+ p_params->rw &= 0x0F;
+ }
+
+ p_msg = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);
+
+ if (p_msg)
+ {
+ p_msg->len = LLCP_PDU_HEADER_SIZE + miu_len + rw_len;
+ p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+
+ UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (p_dlcb->remote_sap, LLCP_PDU_CC_TYPE, p_dlcb->local_sap));
+
+ if (miu_len)
+ {
+ UINT8_TO_BE_STREAM (p, LLCP_MIUX_TYPE);
+ UINT8_TO_BE_STREAM (p, LLCP_MIUX_LEN);
+ UINT16_TO_BE_STREAM (p, p_params->miu - LLCP_DEFAULT_MIU);
+ }
+
+ if (rw_len)
+ {
+ UINT8_TO_BE_STREAM (p, LLCP_RW_TYPE);
+ UINT8_TO_BE_STREAM (p, LLCP_RW_LEN);
+ UINT8_TO_BE_STREAM (p, p_params->rw);
+ }
+
+ GKI_enqueue (&llcp_cb.lcb.sig_xmit_q, p_msg);
+ llcp_link_check_send_data ();
+
+ return LLCP_STATUS_SUCCESS;
+ }
+
+ return LLCP_STATUS_FAIL;
+}
+
+/*******************************************************************************
+**
+** Function llcp_util_parse_cc
+**
+** Description Parse CC PDU
+**
+** Returns tLLCP_STATUS
+**
+*******************************************************************************/
+tLLCP_STATUS llcp_util_parse_cc (UINT8 *p_bytes, UINT16 length, UINT16 *p_miu, UINT8 *p_rw)
+{
+ UINT8 param_type, param_len, *p = p_bytes;
+
+ *p_miu = LLCP_DEFAULT_MIU;
+ *p_rw = LLCP_DEFAULT_RW;
+
+ while (length)
+ {
+ BE_STREAM_TO_UINT8 (param_type, p);
+ length--;
+
+ switch (param_type)
+ {
+ case LLCP_MIUX_TYPE:
+ BE_STREAM_TO_UINT8 (param_len, p);
+ BE_STREAM_TO_UINT16 ((*p_miu), p);
+ (*p_miu) &= LLCP_MIUX_MASK;
+ (*p_miu) += LLCP_DEFAULT_MIU;
+
+ LLCP_TRACE_DEBUG1 ("llcp_util_parse_cc (): LLCP_MIUX_TYPE:%d", *p_miu);
+ break;
+
+ case LLCP_RW_TYPE:
+ BE_STREAM_TO_UINT8 (param_len, p);
+ BE_STREAM_TO_UINT8 ((*p_rw), p);
+ (*p_rw) &= 0x0F;
+
+ LLCP_TRACE_DEBUG1 ("llcp_util_parse_cc (): LLCP_RW_TYPE:%d", *p_rw);
+ break;
+
+ default:
+ LLCP_TRACE_ERROR1 ("llcp_util_parse_cc (): Unexpected type 0x%x", param_type);
+ BE_STREAM_TO_UINT8 (param_len, p);
+ p += param_len;
+ break;
+ }
+
+ if (length >= param_len + 1)
+ length -= param_len + 1;
+ else
+ {
+ LLCP_TRACE_ERROR0 ("llcp_util_parse_cc (): Bad LTV's");
+ return LLCP_STATUS_FAIL;
+ }
+ }
+ return LLCP_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function llcp_util_send_dm
+**
+** Description Send DM PDU
+**
+** Returns void
+**
+*******************************************************************************/
+void llcp_util_send_dm (UINT8 dsap, UINT8 ssap, UINT8 reason)
+{
+ BT_HDR *p_msg;
+ UINT8 *p;
+
+ p_msg = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);
+
+ if (p_msg)
+ {
+ p_msg->len = LLCP_PDU_DM_SIZE;
+ p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+ UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (dsap, LLCP_PDU_DM_TYPE, ssap));
+ UINT8_TO_BE_STREAM (p, reason);
+
+ GKI_enqueue (&llcp_cb.lcb.sig_xmit_q, p_msg);
+ llcp_link_check_send_data ();
+ }
+}
+
+/*******************************************************************************
+**
+** Function llcp_util_build_info_pdu
+**
+** Description Add DSAP, PTYPE, SSAP and sequence numbers and update local ack
+** sequence
+**
+** Returns void
+**
+*******************************************************************************/
+void llcp_util_build_info_pdu (tLLCP_DLCB *p_dlcb, BT_HDR *p_msg)
+{
+ UINT8 *p;
+ UINT8 rcv_seq;
+
+ p_msg->offset -= LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
+ p_msg->len += LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+
+ UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (p_dlcb->remote_sap, LLCP_PDU_I_TYPE, p_dlcb->local_sap));
+
+ /* if local_busy or rx congested then do not update receive sequence number to flow off */
+ if ( (p_dlcb->local_busy)
+ ||(p_dlcb->is_rx_congested)
+ ||(llcp_cb.overall_rx_congested) )
+ {
+ rcv_seq = p_dlcb->sent_ack_seq;
+ }
+ else
+ {
+ p_dlcb->sent_ack_seq = p_dlcb->next_rx_seq;
+ rcv_seq = p_dlcb->sent_ack_seq;
+ }
+ UINT8_TO_BE_STREAM (p, LLCP_GET_SEQUENCE (p_dlcb->next_tx_seq, rcv_seq));
+}
+
+/*******************************************************************************
+**
+** Function llcp_util_send_frmr
+**
+** Description Send FRMR PDU
+**
+** Returns tLLCP_STATUS
+**
+*******************************************************************************/
+tLLCP_STATUS llcp_util_send_frmr (tLLCP_DLCB *p_dlcb, UINT8 flags, UINT8 ptype, UINT8 sequence)
+{
+ BT_HDR *p_msg;
+ UINT8 *p;
+
+ p_msg = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);
+
+ if (p_msg)
+ {
+ p_msg->len = LLCP_PDU_FRMR_SIZE;
+ p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+
+ UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (p_dlcb->remote_sap, LLCP_PDU_FRMR_TYPE, p_dlcb->local_sap));
+ UINT8_TO_BE_STREAM (p, (flags << 4) | ptype);
+ UINT8_TO_BE_STREAM (p, sequence);
+ UINT8_TO_BE_STREAM (p, (p_dlcb->next_tx_seq << 4) | p_dlcb->next_rx_seq);
+ UINT8_TO_BE_STREAM (p, (p_dlcb->rcvd_ack_seq << 4) | p_dlcb->sent_ack_seq);
+
+ GKI_enqueue (&llcp_cb.lcb.sig_xmit_q, p_msg);
+ llcp_link_check_send_data ();
+
+ return LLCP_STATUS_SUCCESS;
+ }
+ else
+ {
+ LLCP_TRACE_ERROR0 ("llcp_util_send_frmr (): Out of resource");
+ return LLCP_STATUS_FAIL;
+ }
+}
+
+/*******************************************************************************
+**
+** Function llcp_util_send_rr_rnr
+**
+** Description Send RR or RNR PDU
+**
+** Returns void
+**
+*******************************************************************************/
+void llcp_util_send_rr_rnr (tLLCP_DLCB *p_dlcb)
+{
+ BT_HDR *p_msg;
+ UINT8 *p;
+ UINT8 pdu_type;
+ UINT8 pdu_size;
+ UINT8 rcv_seq;
+
+ /* if no indication of change in local busy or rx congestion */
+ if ((p_dlcb->flags & LLCP_DATA_LINK_FLAG_PENDING_RR_RNR) == 0)
+ {
+ /* if all ack is sent */
+ if (p_dlcb->sent_ack_seq == p_dlcb->next_rx_seq)
+ {
+ /* we don't need to send RR/RNR */
+ return;
+ }
+ else
+ {
+ /* if rx flow off because of local busy or congestion */
+ if ( (p_dlcb->local_busy)
+ ||(p_dlcb->is_rx_congested)
+ ||(llcp_cb.overall_rx_congested) )
+ {
+ /* don't send RR/RNR */
+ return;
+ }
+ }
+ }
+
+ if ( (p_dlcb->local_busy)
+ ||(p_dlcb->is_rx_congested)
+ ||(llcp_cb.overall_rx_congested) )
+ {
+ LLCP_TRACE_DEBUG3 ("llcp_util_send_rr_rnr (): local_busy=%d,is_rx_congested=%d,overall_rx_congested=%d",
+ p_dlcb->local_busy, p_dlcb->is_rx_congested, llcp_cb.overall_rx_congested);
+
+ /* if local_busy or rx congested then do not update receive sequence number to flow off */
+ pdu_type = LLCP_PDU_RNR_TYPE;
+ pdu_size = LLCP_PDU_RNR_SIZE;
+ rcv_seq = p_dlcb->sent_ack_seq;
+ }
+ else
+ {
+ pdu_type = LLCP_PDU_RR_TYPE;
+ pdu_size = LLCP_PDU_RR_SIZE;
+
+ p_dlcb->sent_ack_seq = p_dlcb->next_rx_seq;
+ rcv_seq = p_dlcb->sent_ack_seq;
+ }
+
+ p_msg = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);
+
+ if (p_msg)
+ {
+ p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
+
+ p_msg->len = pdu_size;
+ p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+
+ UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (p_dlcb->remote_sap, pdu_type, p_dlcb->local_sap));
+
+ UINT8_TO_BE_STREAM (p, rcv_seq);
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ LLCP_TRACE_DEBUG5 ("LLCP TX - N(S,R):(NA,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
+ p_dlcb->next_rx_seq,
+ p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
+ p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
+#endif
+ GKI_enqueue (&llcp_cb.lcb.sig_xmit_q, p_msg);
+ llcp_link_check_send_data ();
+ }
+ else
+ {
+ LLCP_TRACE_ERROR0 ("llcp_util_send_rr_rnr (): Out of resource");
+ }
+}
+
+/*******************************************************************************
+**
+** Function llcp_util_get_app_cb
+**
+** Description get pointer of application registered control block by SAP
+**
+** Returns tLLCP_APP_CB *
+**
+*******************************************************************************/
+tLLCP_APP_CB *llcp_util_get_app_cb (UINT8 local_sap)
+{
+ tLLCP_APP_CB *p_app_cb = NULL;
+
+ if (local_sap <= LLCP_UPPER_BOUND_WK_SAP)
+ {
+ if ((local_sap != LLCP_SAP_LM) && (local_sap < LLCP_MAX_WKS))
+ {
+ p_app_cb = &llcp_cb.wks_cb[local_sap];
+ }
+ }
+ else if (local_sap <= LLCP_UPPER_BOUND_SDP_SAP)
+ {
+ if (local_sap - LLCP_LOWER_BOUND_SDP_SAP < LLCP_MAX_SERVER)
+ {
+ p_app_cb = &llcp_cb.server_cb[local_sap - LLCP_LOWER_BOUND_SDP_SAP];
+ }
+ }
+ else if (local_sap <= LLCP_UPPER_BOUND_LOCAL_SAP)
+ {
+ if (local_sap - LLCP_LOWER_BOUND_LOCAL_SAP < LLCP_MAX_CLIENT)
+ {
+ p_app_cb = &llcp_cb.client_cb[local_sap - LLCP_LOWER_BOUND_LOCAL_SAP];
+ }
+ }
+
+ return (p_app_cb);
+}
diff --git a/src/nfc/nci/nci_hmsgs.c b/src/nfc/nci/nci_hmsgs.c
new file mode 100644
index 0000000..7918e7c
--- /dev/null
+++ b/src/nfc/nci/nci_hmsgs.c
@@ -0,0 +1,718 @@
+/******************************************************************************
+ *
+ * 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"
+
+#if NFC_INCLUDED == TRUE
+#include "nci_defs.h"
+#include "nci_hmsgs.h"
+#include "nfc_api.h"
+#include "nfc_int.h"
+/*******************************************************************************
+**
+** Function nci_snd_core_reset
+**
+** Description compose and send CORE RESET command to command queue
+**
+** Returns status
+**
+*******************************************************************************/
+UINT8 nci_snd_core_reset (UINT8 reset_type)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ if ((p = NCI_GET_CMD_BUF (NCI_CORE_PARAM_SIZE_RESET)) == NULL)
+ return (NCI_STATUS_FAILED);
+
+ p->event = BT_EVT_TO_NFC_NCI;
+ p->len = NCI_MSG_HDR_SIZE + NCI_CORE_PARAM_SIZE_RESET;
+ p->offset = NCI_MSG_OFFSET_SIZE;
+ p->layer_specific = 0;
+ pp = (UINT8 *) (p + 1) + p->offset;
+
+ NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_CORE);
+ NCI_MSG_BLD_HDR1 (pp, NCI_MSG_CORE_RESET);
+ UINT8_TO_STREAM (pp, NCI_CORE_PARAM_SIZE_RESET);
+ UINT8_TO_STREAM (pp, reset_type);
+
+ nfc_ncif_send_cmd (p);
+ return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function nci_snd_core_init
+**
+** Description compose and send CORE INIT command to command queue
+**
+** Returns status
+**
+*******************************************************************************/
+UINT8 nci_snd_core_init (void)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+ if ((p = NCI_GET_CMD_BUF (NCI_CORE_PARAM_SIZE_INIT)) == NULL)
+ return (NCI_STATUS_FAILED);
+
+ p->event = BT_EVT_TO_NFC_NCI;
+ p->len = NCI_MSG_HDR_SIZE + NCI_CORE_PARAM_SIZE_INIT;
+ p->offset = NCI_MSG_OFFSET_SIZE;
+ p->layer_specific = 0;
+ pp = (UINT8 *) (p + 1) + p->offset;
+
+ NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_CORE);
+ NCI_MSG_BLD_HDR1 (pp, NCI_MSG_CORE_INIT);
+ UINT8_TO_STREAM (pp, NCI_CORE_PARAM_SIZE_INIT);
+ nfc_ncif_send_cmd (p);
+ return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function nci_snd_core_get_config
+**
+** Description compose and send CORE GET_CONFIG command to command queue
+**
+** Returns status
+**
+*******************************************************************************/
+UINT8 nci_snd_core_get_config (UINT8 *param_ids, UINT8 num_ids)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ UINT8 bytes;
+ UINT8 propConfigCnt;
+#endif
+
+ if ((p = NCI_GET_CMD_BUF (num_ids)) == NULL)
+ return (NCI_STATUS_FAILED);
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ UINT32 idx = 0;
+ UINT8 *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(NFC_NXP_NOT_OPEN_INCLUDED == 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 *) (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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ UINT8_TO_STREAM (pp, (UINT8) (bytes + 1));
+#else
+ UINT8_TO_STREAM (pp, (UINT8) (num_ids + 1));
+#endif
+ UINT8_TO_STREAM (pp, num_ids);
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 nci_snd_core_set_config (UINT8 *p_param_tlvs, UINT8 tlv_size)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+ UINT8 num = 0, ulen, len, *pt;
+
+ if ((p = NCI_GET_CMD_BUF (tlv_size + 1)) == NULL)
+ return (NCI_STATUS_FAILED);
+
+ p->event = BT_EVT_TO_NFC_NCI;
+ p->len = NCI_MSG_HDR_SIZE + tlv_size + 1;
+ p->offset = NCI_MSG_OFFSET_SIZE;
+ pp = (UINT8 *) (p + 1) + p->offset;
+
+ NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_CORE);
+ NCI_MSG_BLD_HDR1 (pp, NCI_MSG_CORE_SET_CONFIG);
+ UINT8_TO_STREAM (pp, (UINT8) (tlv_size + 1));
+ len = tlv_size;
+ pt = p_param_tlvs;
+ while (len > 1)
+ {
+ len -= 2;
+ pt++;
+ num++;
+ ulen = *pt++;
+ pt += ulen;
+ if (len >= ulen)
+ {
+ len -= ulen;
+ }
+ else
+ {
+ GKI_freebuf (p);
+ return NCI_STATUS_FAILED;
+ }
+ }
+
+ UINT8_TO_STREAM (pp, num);
+ ARRAY_TO_STREAM (pp, p_param_tlvs, tlv_size);
+ nfc_ncif_send_cmd (p);
+
+ return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function nci_snd_core_conn_create
+**
+** Description compose and send CORE CONN_CREATE command to command queue
+**
+** Returns status
+**
+*******************************************************************************/
+UINT8 nci_snd_core_conn_create (UINT8 dest_type, UINT8 num_tlv, UINT8 tlv_size, UINT8 *p_param_tlvs)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+ UINT8 size = NCI_CORE_PARAM_SIZE_CON_CREATE+tlv_size;
+
+ if ((p = NCI_GET_CMD_BUF (size)) == NULL)
+ return (NCI_STATUS_FAILED);
+
+ p->event = BT_EVT_TO_NFC_NCI;
+ p->len = NCI_MSG_HDR_SIZE + NCI_CORE_PARAM_SIZE_CON_CREATE;
+ p->offset = NCI_MSG_OFFSET_SIZE;
+ p->layer_specific = 0;
+ pp = (UINT8 *) (p + 1) + p->offset;
+
+ NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_CORE);
+ NCI_MSG_BLD_HDR1 (pp, NCI_MSG_CORE_CONN_CREATE);
+ UINT8_TO_STREAM (pp, size);
+ UINT8_TO_STREAM (pp, dest_type);
+ UINT8_TO_STREAM (pp, num_tlv);
+ if (tlv_size)
+ {
+ ARRAY_TO_STREAM (pp, p_param_tlvs, tlv_size);
+ p->len += tlv_size;
+ }
+
+ nfc_ncif_send_cmd (p);
+ return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function nci_snd_core_conn_close
+**
+** Description compose and send CORE CONN_CLOSE command to command queue
+**
+** Returns status
+**
+*******************************************************************************/
+UINT8 nci_snd_core_conn_close (UINT8 conn_id)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ if ((p = NCI_GET_CMD_BUF (NCI_CORE_PARAM_SIZE_CON_CLOSE)) == NULL)
+ return (NCI_STATUS_FAILED);
+
+ p->event = BT_EVT_TO_NFC_NCI;
+ p->len = NCI_MSG_HDR_SIZE + NCI_CORE_PARAM_SIZE_CON_CLOSE;
+ p->offset = NCI_MSG_OFFSET_SIZE;
+ p->layer_specific = 0;
+ pp = (UINT8 *) (p + 1) + p->offset;
+
+ NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_CORE);
+ NCI_MSG_BLD_HDR1 (pp, NCI_MSG_CORE_CONN_CLOSE);
+ UINT8_TO_STREAM (pp, NCI_CORE_PARAM_SIZE_CON_CLOSE);
+ UINT8_TO_STREAM (pp, conn_id);
+
+ nfc_ncif_send_cmd (p);
+ return (NCI_STATUS_OK);
+}
+
+
+#if (NFC_NFCEE_INCLUDED == TRUE)
+#if (NFC_RW_ONLY == FALSE)
+/*******************************************************************************
+**
+** Function nci_snd_nfcee_discover
+**
+** Description compose and send NFCEE Management NFCEE_DISCOVER command
+** to command queue
+**
+** Returns status
+**
+*******************************************************************************/
+UINT8 nci_snd_nfcee_discover (UINT8 discover_action)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ if ((p = NCI_GET_CMD_BUF (NCI_PARAM_SIZE_DISCOVER_NFCEE)) == NULL)
+ return (NCI_STATUS_FAILED);
+
+ p->event = BT_EVT_TO_NFC_NCI;
+ p->len = NCI_MSG_HDR_SIZE + NCI_PARAM_SIZE_DISCOVER_NFCEE;
+ p->offset = NCI_MSG_OFFSET_SIZE;
+ p->layer_specific = 0;
+ pp = (UINT8 *) (p + 1) + p->offset;
+
+ NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_EE_MANAGE);
+ NCI_MSG_BLD_HDR1 (pp, NCI_MSG_NFCEE_DISCOVER);
+ UINT8_TO_STREAM (pp, NCI_PARAM_SIZE_DISCOVER_NFCEE);
+ UINT8_TO_STREAM (pp, discover_action);
+
+ nfc_ncif_send_cmd (p);
+ return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function nci_snd_nfcee_mode_set
+**
+** Description compose and send NFCEE Management NFCEE MODE SET command
+** to command queue
+**
+** Returns status
+**
+*******************************************************************************/
+UINT8 nci_snd_nfcee_mode_set (UINT8 nfcee_id, UINT8 nfcee_mode)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ if ((p = NCI_GET_CMD_BUF (NCI_CORE_PARAM_SIZE_NFCEE_MODE_SET)) == NULL)
+ return (NCI_STATUS_FAILED);
+
+ p->event = BT_EVT_TO_NFC_NCI;
+ p->len = NCI_MSG_HDR_SIZE + NCI_CORE_PARAM_SIZE_NFCEE_MODE_SET;
+ p->offset = NCI_MSG_OFFSET_SIZE;
+ p->layer_specific = 0;
+ pp = (UINT8 *) (p + 1) + p->offset;
+
+ NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_EE_MANAGE);
+ NCI_MSG_BLD_HDR1 (pp, NCI_MSG_NFCEE_MODE_SET);
+ UINT8_TO_STREAM (pp, NCI_CORE_PARAM_SIZE_NFCEE_MODE_SET);
+ UINT8_TO_STREAM (pp, nfcee_id);
+ UINT8_TO_STREAM (pp, nfcee_mode);
+
+ nfc_ncif_send_cmd (p);
+ return (NCI_STATUS_OK);
+}
+#endif
+#endif
+
+/*******************************************************************************
+**
+** Function nci_snd_discover_cmd
+**
+** Description compose and send RF Management DISCOVER command to command queue
+**
+** Returns status
+**
+*******************************************************************************/
+UINT8 nci_snd_discover_cmd (UINT8 num, tNCI_DISCOVER_PARAMS *p_param)
+{
+ BT_HDR *p;
+ UINT8 *pp, *p_size, *p_start;
+ int xx;
+ int size;
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ if(NULL == p_param)
+ {
+ return NCI_STATUS_FAILED;
+ }
+#endif
+
+ size = num * sizeof (tNCI_DISCOVER_PARAMS) + 1;
+ if ((p = NCI_GET_CMD_BUF (size)) == NULL)
+ return (NCI_STATUS_FAILED);
+
+ p->event = BT_EVT_TO_NFC_NCI;
+ p->offset = NCI_MSG_OFFSET_SIZE;
+ p->layer_specific = 0;
+ pp = (UINT8 *) (p + 1) + p->offset;
+
+ NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_RF_MANAGE);
+ NCI_MSG_BLD_HDR1 (pp, NCI_MSG_RF_DISCOVER);
+ p_size = pp;
+ pp++;
+ p_start = pp;
+ UINT8_TO_STREAM (pp, num);
+ for (xx=0; xx<num; xx++)
+ {
+ UINT8_TO_STREAM (pp, p_param[xx].type);
+ UINT8_TO_STREAM (pp, p_param[xx].frequency);
+ }
+ *p_size = (UINT8) (pp - p_start);
+ p->len = NCI_MSG_HDR_SIZE + *p_size;
+
+ nfc_ncif_send_cmd (p);
+ return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function nci_snd_discover_select_cmd
+**
+** Description compose and send RF Management DISCOVER SELECT command
+** to command queue
+**
+** Returns status
+**
+*******************************************************************************/
+UINT8 nci_snd_discover_select_cmd (UINT8 rf_disc_id, UINT8 protocol, UINT8 rf_interface)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ if ((p = NCI_GET_CMD_BUF (NCI_DISCOVER_PARAM_SIZE_SELECT)) == NULL)
+ return (NCI_STATUS_FAILED);
+
+ p->event = BT_EVT_TO_NFC_NCI;
+ p->len = NCI_MSG_HDR_SIZE + NCI_DISCOVER_PARAM_SIZE_SELECT;
+ p->offset = NCI_MSG_OFFSET_SIZE;
+ p->layer_specific = 0;
+ pp = (UINT8 *) (p + 1) + p->offset;
+
+ NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_RF_MANAGE);
+ NCI_MSG_BLD_HDR1 (pp, NCI_MSG_RF_DISCOVER_SELECT);
+ UINT8_TO_STREAM (pp, NCI_DISCOVER_PARAM_SIZE_SELECT);
+ UINT8_TO_STREAM (pp, rf_disc_id);
+ UINT8_TO_STREAM (pp, protocol);
+ UINT8_TO_STREAM (pp, rf_interface);
+
+ nfc_ncif_send_cmd (p);
+ return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function nci_snd_deactivate_cmd
+**
+** Description compose and send RF Management DEACTIVATE command
+** to command queue
+**
+** Returns status
+**
+*******************************************************************************/
+UINT8 nci_snd_deactivate_cmd (UINT8 de_act_type )
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ nfc_cb.reassembly = TRUE;
+
+ if ((p = NCI_GET_CMD_BUF (NCI_DISCOVER_PARAM_SIZE_DEACT)) == NULL)
+ return (NCI_STATUS_FAILED);
+
+ p->event = BT_EVT_TO_NFC_NCI;
+ p->len = NCI_MSG_HDR_SIZE + NCI_DISCOVER_PARAM_SIZE_DEACT;
+ p->offset = NCI_MSG_OFFSET_SIZE;
+ p->layer_specific = 0;
+ pp = (UINT8 *) (p + 1) + p->offset;
+
+ NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_RF_MANAGE);
+ NCI_MSG_BLD_HDR1 (pp, NCI_MSG_RF_DEACTIVATE);
+ UINT8_TO_STREAM (pp, NCI_DISCOVER_PARAM_SIZE_DEACT);
+ UINT8_TO_STREAM (pp, de_act_type);
+
+ nfc_ncif_send_cmd (p);
+ return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function nci_snd_discover_map_cmd
+**
+** Description compose and send RF Management DISCOVER MAP command
+** to command queue
+**
+** Returns status
+**
+*******************************************************************************/
+UINT8 nci_snd_discover_map_cmd (UINT8 num, tNCI_DISCOVER_MAPS *p_maps)
+{
+ BT_HDR *p;
+ UINT8 *pp, *p_size, *p_start;
+ int xx;
+ int size;
+
+ size = num * sizeof (tNCI_DISCOVER_MAPS) + 1;
+
+ if ((p = NCI_GET_CMD_BUF (size)) == NULL)
+ return (NCI_STATUS_FAILED);
+
+ p->event = BT_EVT_TO_NFC_NCI;
+ p->offset = NCI_MSG_OFFSET_SIZE;
+ p->layer_specific = 0;
+ pp = (UINT8 *) (p + 1) + p->offset;
+
+ NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_RF_MANAGE);
+ NCI_MSG_BLD_HDR1 (pp, NCI_MSG_RF_DISCOVER_MAP);
+ p_size = pp;
+ pp++;
+ p_start = pp;
+ UINT8_TO_STREAM (pp, num);
+ for (xx = 0; xx < num; xx++)
+ {
+ UINT8_TO_STREAM (pp, p_maps[xx].protocol);
+ UINT8_TO_STREAM (pp, p_maps[xx].mode);
+ UINT8_TO_STREAM (pp, p_maps[xx].intf_type);
+ }
+ *p_size = (UINT8) (pp - p_start);
+ p->len = NCI_MSG_HDR_SIZE + *p_size;
+ nfc_ncif_send_cmd (p);
+ return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function nci_snd_t3t_polling
+**
+** Description compose and send RF Management T3T POLLING command
+** to command queue
+**
+** Returns status
+**
+*******************************************************************************/
+UINT8 nci_snd_t3t_polling (UINT16 system_code, UINT8 rc, UINT8 tsn)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+
+ if ((p = NCI_GET_CMD_BUF (NCI_RF_PARAM_SIZE_T3T_POLLING)) == NULL)
+ return (NCI_STATUS_FAILED);
+
+ p->event = BT_EVT_TO_NFC_NCI;
+ p->len = NCI_MSG_HDR_SIZE + NCI_RF_PARAM_SIZE_T3T_POLLING;
+ p->offset = NCI_MSG_OFFSET_SIZE;
+ p->layer_specific = 0;
+ pp = (UINT8 *) (p + 1) + p->offset;
+
+ NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_RF_MANAGE);
+ NCI_MSG_BLD_HDR1 (pp, NCI_MSG_RF_T3T_POLLING);
+ UINT8_TO_STREAM (pp, NCI_RF_PARAM_SIZE_T3T_POLLING);
+ UINT16_TO_BE_STREAM (pp, system_code);
+ UINT8_TO_STREAM (pp, rc);
+ UINT8_TO_STREAM (pp, tsn);
+
+ nfc_ncif_send_cmd (p);
+ return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function nci_snd_parameter_update_cmd
+**
+** Description compose and send RF Management RF Communication Parameter
+** Update commandto command queue
+**
+** Returns status
+**
+*******************************************************************************/
+UINT8 nci_snd_parameter_update_cmd (UINT8 *p_param_tlvs, UINT8 tlv_size)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+ UINT8 num = 0, ulen, len, *pt;
+
+ if ((p = NCI_GET_CMD_BUF (tlv_size + 1)) == NULL)
+ return (NCI_STATUS_FAILED);
+
+ p->event = BT_EVT_TO_NFC_NCI;
+ p->len = NCI_MSG_HDR_SIZE + tlv_size + 1;
+ p->offset = NCI_MSG_OFFSET_SIZE;
+ pp = (UINT8 *) (p + 1) + p->offset;
+
+ NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_RF_MANAGE);
+ NCI_MSG_BLD_HDR1 (pp, NCI_MSG_RF_PARAMETER_UPDATE);
+ UINT8_TO_STREAM (pp, (UINT8) (tlv_size + 1));
+ len = tlv_size;
+ pt = p_param_tlvs;
+ while (len > 1)
+ {
+ len -= 2;
+ pt++;
+ num++;
+ ulen = *pt++;
+ pt += ulen;
+ if (len >= ulen)
+ {
+ len -= ulen;
+ }
+ else
+ {
+ GKI_freebuf (p);
+ return NCI_STATUS_FAILED;
+ }
+ }
+
+ UINT8_TO_STREAM (pp, num);
+ ARRAY_TO_STREAM (pp, p_param_tlvs, tlv_size);
+ nfc_ncif_send_cmd (p);
+
+ return (NCI_STATUS_OK);
+}
+
+#if (NFC_NFCEE_INCLUDED == TRUE)
+#if (NFC_RW_ONLY == FALSE)
+/*******************************************************************************
+**
+** Function nci_snd_set_routing_cmd
+**
+** Description compose and send RF Management SET_LISTEN_MODE_ROUTING command
+** to command queue
+**
+** Returns status
+**
+*******************************************************************************/
+UINT8 nci_snd_set_routing_cmd (BOOLEAN more, UINT8 num_tlv, UINT8 tlv_size, UINT8 *p_param_tlvs)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+ UINT8 size = tlv_size + 2;
+
+ if (tlv_size == 0)
+ {
+ /* just to terminate routing table
+ * 2 bytes (more=FALSE and num routing entries=0) */
+ size = 2;
+ }
+
+ if ((p = NCI_GET_CMD_BUF(size)) == NULL)
+ return (NCI_STATUS_FAILED);
+
+ p->event = BT_EVT_TO_NFC_NCI;
+ p->offset = NCI_MSG_OFFSET_SIZE;
+ p->len = NCI_MSG_HDR_SIZE + size;
+ p->layer_specific = 0;
+ pp = (UINT8 *) (p + 1) + p->offset;
+
+ NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_RF_MANAGE);
+ NCI_MSG_BLD_HDR1 (pp, NCI_MSG_RF_SET_ROUTING);
+ UINT8_TO_STREAM (pp, size);
+ UINT8_TO_STREAM (pp, more);
+ if (size == 2)
+ {
+ UINT8_TO_STREAM (pp, 0);
+ }
+ else
+ {
+ UINT8_TO_STREAM (pp, num_tlv);
+ ARRAY_TO_STREAM (pp, p_param_tlvs, tlv_size);
+ }
+ nfc_ncif_send_cmd (p);
+
+ return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function nci_snd_get_routing_cmd
+**
+** Description compose and send RF Management GET_LISTEN_MODE_ROUTING command
+** to command queue
+**
+** Returns status
+**
+*******************************************************************************/
+UINT8 nci_snd_get_routing_cmd (void)
+{
+ BT_HDR *p;
+ UINT8 *pp;
+ UINT8 param_size = 0;
+
+ if ((p = NCI_GET_CMD_BUF (param_size)) == NULL)
+ return (NCI_STATUS_FAILED);
+
+ p->event = BT_EVT_TO_NFC_NCI;
+ p->len = NCI_MSG_HDR_SIZE + param_size;
+ p->offset = NCI_MSG_OFFSET_SIZE;
+ p->layer_specific = 0;
+ pp = (UINT8 *) (p + 1) + p->offset;
+
+ NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_RF_MANAGE);
+ NCI_MSG_BLD_HDR1 (pp, NCI_MSG_RF_GET_ROUTING);
+ UINT8_TO_STREAM (pp, param_size);
+
+ nfc_ncif_send_cmd (p);
+ return (NCI_STATUS_OK);
+}
+#endif
+#endif
+
+
+#endif /* NFC_INCLUDED == TRUE*/
diff --git a/src/nfc/nci/nci_hrcv.c b/src/nfc/nci/nci_hrcv.c
new file mode 100644
index 0000000..5e24e09
--- /dev/null
+++ b/src/nfc/nci/nci_hrcv.c
@@ -0,0 +1,582 @@
+/******************************************************************************
+ *
+ * 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"
+
+#if NFC_INCLUDED == TRUE
+#include "nci_defs.h"
+#include "nci_hmsgs.h"
+#include "nfc_api.h"
+#include "nfc_int.h"
+
+/*******************************************************************************
+**
+** Function nci_proc_core_rsp
+**
+** Description Process NCI responses in the CORE group
+**
+** Returns TRUE-caller of this function to free the GKI buffer p_msg
+**
+*******************************************************************************/
+BOOLEAN nci_proc_core_rsp (BT_HDR *p_msg)
+{
+ UINT8 *p;
+ UINT8 *pp, len, op_code;
+ BOOLEAN free = TRUE;
+ UINT8 *p_old = nfc_cb.last_cmd;
+
+ /* find the start of the NCI message and parse the NCI header */
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+ pp = p+1;
+ NCI_MSG_PRS_HDR1 (pp, op_code);
+ NFC_TRACE_DEBUG1 ("nci_proc_core_rsp opcode:0x%x", op_code);
+ len = *pp++;
+
+ /* process the message based on the opcode and message type */
+ switch (op_code)
+ {
+ case NCI_MSG_CORE_RESET:
+ nfc_ncif_proc_reset_rsp (pp, FALSE);
+ break;
+
+ case NCI_MSG_CORE_INIT:
+ nfc_ncif_proc_init_rsp (p_msg);
+ free = FALSE;
+ break;
+
+ case NCI_MSG_CORE_GET_CONFIG:
+ nfc_ncif_proc_get_config_rsp (p_msg);
+ break;
+
+ case NCI_MSG_CORE_SET_CONFIG:
+ nfc_ncif_set_config_status (pp, len);
+ break;
+
+ case NCI_MSG_CORE_CONN_CREATE:
+ nfc_ncif_proc_conn_create_rsp (p, p_msg->len, *p_old);
+ break;
+
+ case NCI_MSG_CORE_CONN_CLOSE:
+ nfc_ncif_report_conn_close_evt (*p_old, *pp);
+ break;
+
+ default:
+ NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
+ break;
+ }
+
+ return free;
+}
+
+/*******************************************************************************
+**
+** Function nci_proc_core_ntf
+**
+** Description Process NCI notifications in the CORE group
+**
+** Returns void
+**
+*******************************************************************************/
+void nci_proc_core_ntf (BT_HDR *p_msg)
+{
+ UINT8 *p;
+ UINT8 *pp, len, op_code;
+ UINT8 conn_id;
+
+ /* find the start of the NCI message and parse the NCI header */
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+ pp = p+1;
+ NCI_MSG_PRS_HDR1 (pp, op_code);
+ NFC_TRACE_DEBUG1 ("nci_proc_core_ntf opcode:0x%x", op_code);
+ len = *pp++;
+
+ /* process the message based on the opcode and message type */
+ switch (op_code)
+ {
+ case NCI_MSG_CORE_RESET:
+ nfc_ncif_proc_reset_rsp (pp, TRUE);
+ break;
+
+ case NCI_MSG_CORE_GEN_ERR_STATUS:
+ /* process the error ntf */
+ /* in case of timeout: notify the static connection callback */
+ nfc_ncif_event_status (NFC_GEN_ERROR_REVT, *pp);
+ nfc_ncif_error_status (NFC_RF_CONN_ID, *pp);
+ break;
+
+ case NCI_MSG_CORE_INTF_ERR_STATUS:
+ conn_id = *(pp+1);
+ nfc_ncif_error_status (conn_id, *pp);
+ break;
+
+ case NCI_MSG_CORE_CONN_CREDITS:
+ nfc_ncif_proc_credits(pp, len);
+ break;
+
+ default:
+ NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
+ break;
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function nci_proc_rf_management_rsp
+**
+** Description Process NCI responses in the RF Management group
+**
+** Returns void
+**
+*******************************************************************************/
+void nci_proc_rf_management_rsp (BT_HDR *p_msg)
+{
+ UINT8 *p;
+ UINT8 *pp, len, op_code;
+ UINT8 *p_old = nfc_cb.last_cmd;
+
+ /* find the start of the NCI message and parse the NCI header */
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+ pp = p+1;
+ NCI_MSG_PRS_HDR1 (pp, op_code);
+ len = *pp++;
+
+ switch (op_code)
+ {
+ case NCI_MSG_RF_DISCOVER:
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ nfa_dm_p2p_prio_logic(op_code, pp, 1);
+#endif
+ 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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ if (FALSE == nfa_dm_p2p_prio_logic(op_code, pp, 1))
+ {
+ NFC_TRACE_ERROR0("Dont process the Response");
+ return;
+ }
+#endif
+ nfc_ncif_proc_deactivate (*pp, *p_old, FALSE);
+ break;
+
+#if (NFC_NFCEE_INCLUDED == TRUE)
+#if (NFC_RW_ONLY == FALSE)
+
+ case NCI_MSG_RF_SET_ROUTING:
+ nfc_ncif_event_status (NFC_SET_ROUTING_REVT, *pp);
+ break;
+
+ case NCI_MSG_RF_GET_ROUTING:
+ if (*pp != NFC_STATUS_OK)
+ nfc_ncif_event_status (NFC_GET_ROUTING_REVT, *pp);
+ break;
+#endif
+#endif
+
+ case NCI_MSG_RF_PARAMETER_UPDATE:
+ nfc_ncif_event_status (NFC_RF_COMM_PARAMS_UPDATE_REVT, *pp);
+ break;
+
+ default:
+ NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
+ break;
+ }
+}
+
+/*******************************************************************************
+**
+** Function nci_proc_rf_management_ntf
+**
+** Description Process NCI notifications in the RF Management group
+**
+** Returns void
+**
+*******************************************************************************/
+void nci_proc_rf_management_ntf (BT_HDR *p_msg)
+{
+ UINT8 *p;
+ UINT8 *pp, len, op_code;
+
+ /* find the start of the NCI message and parse the NCI header */
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+ pp = p+1;
+ NCI_MSG_PRS_HDR1 (pp, op_code);
+ len = *pp++;
+
+ switch (op_code)
+ {
+ case NCI_MSG_RF_DISCOVER :
+ nfc_ncif_proc_discover_ntf (p, p_msg->len);
+ break;
+
+ case NCI_MSG_RF_DEACTIVATE:
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ if (FALSE == nfa_dm_p2p_prio_logic(op_code, pp, 2))
+ {
+ NFC_TRACE_ERROR0("Dont process the Event");
+ return;
+ }
+#endif
+ nfc_ncif_proc_deactivate (NFC_STATUS_OK, *pp, TRUE);
+ break;
+
+ case NCI_MSG_RF_INTF_ACTIVATED:
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ if (FALSE == nfa_dm_p2p_prio_logic(op_code, pp, 2))
+ {
+ NFC_TRACE_ERROR0("Dont process the Event");
+ return;
+ }
+#endif
+ nfc_ncif_proc_activate (pp, len);
+ break;
+
+ case NCI_MSG_RF_FIELD:
+ nfc_ncif_proc_rf_field_ntf (*pp);
+ break;
+
+ case NCI_MSG_RF_T3T_POLLING:
+ nfc_ncif_proc_t3t_polling_ntf (pp, len);
+ break;
+
+#if (NFC_NFCEE_INCLUDED == TRUE)
+#if (NFC_RW_ONLY == FALSE)
+
+ case NCI_MSG_RF_GET_ROUTING:
+ nfc_ncif_proc_get_routing (pp, len);
+ break;
+
+ case NCI_MSG_RF_EE_ACTION:
+ nfc_ncif_proc_ee_action (pp, len);
+ break;
+
+ case NCI_MSG_RF_EE_DISCOVERY_REQ:
+ nfc_ncif_proc_ee_discover_req (pp, len);
+ break;
+#endif
+#endif
+
+ default:
+ NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
+ break;
+ }
+}
+
+#if (NFC_NFCEE_INCLUDED == TRUE)
+#if (NFC_RW_ONLY == FALSE)
+
+/*******************************************************************************
+**
+** Function nci_proc_ee_management_rsp
+**
+** Description Process NCI responses in the NFCEE Management group
+**
+** Returns void
+**
+*******************************************************************************/
+void nci_proc_ee_management_rsp (BT_HDR *p_msg)
+{
+ UINT8 *p;
+ UINT8 *pp, len, op_code;
+ tNFC_RESPONSE_CBACK *p_cback = nfc_cb.p_resp_cback;
+ tNFC_NFCEE_DISCOVER_REVT nfcee_discover;
+ tNFC_NFCEE_INFO_REVT nfcee_info;
+ tNFC_NFCEE_MODE_SET_REVT mode_set;
+ tNFC_RESPONSE *p_evt = (tNFC_RESPONSE *) &nfcee_info;
+ tNFC_RESPONSE_EVT event = NFC_NFCEE_INFO_REVT;
+ UINT8 *p_old = nfc_cb.last_cmd;
+
+ /* find the start of the NCI message and parse the NCI header */
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+ pp = p+1;
+ NCI_MSG_PRS_HDR1 (pp, op_code);
+ NFC_TRACE_DEBUG1 ("nci_proc_ee_management_rsp opcode:0x%x", op_code);
+ len = *pp++;
+
+ switch (op_code)
+ {
+ case NCI_MSG_NFCEE_DISCOVER:
+ p_evt = (tNFC_RESPONSE *) &nfcee_discover;
+ nfcee_discover.status = *pp++;
+ nfcee_discover.num_nfcee = *pp++;
+
+ if (nfcee_discover.status != NFC_STATUS_OK)
+ nfcee_discover.num_nfcee = 0;
+
+ event = NFC_NFCEE_DISCOVER_REVT;
+ break;
+
+ case NCI_MSG_NFCEE_MODE_SET:
+ p_evt = (tNFC_RESPONSE *) &mode_set;
+ mode_set.status = *pp;
+ mode_set.nfcee_id = 0;
+ event = NFC_NFCEE_MODE_SET_REVT;
+ mode_set.nfcee_id = *p_old++;
+ mode_set.mode = *p_old++;
+ break;
+
+ default:
+ p_cback = NULL;
+ NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
+ break;
+ }
+
+ if (p_cback)
+ (*p_cback) (event, p_evt);
+}
+
+/*******************************************************************************
+**
+** Function nci_proc_ee_management_ntf
+**
+** Description Process NCI notifications in the NFCEE Management group
+**
+** Returns void
+**
+*******************************************************************************/
+void nci_proc_ee_management_ntf (BT_HDR *p_msg)
+{
+ UINT8 *p;
+ UINT8 *pp, len, op_code;
+ tNFC_RESPONSE_CBACK *p_cback = nfc_cb.p_resp_cback;
+ tNFC_NFCEE_INFO_REVT nfcee_info;
+ tNFC_RESPONSE *p_evt = (tNFC_RESPONSE *) &nfcee_info;
+ tNFC_RESPONSE_EVT event = NFC_NFCEE_INFO_REVT;
+ UINT8 xx;
+ UINT8 yy;
+ UINT8 ee_status;
+ tNFC_NFCEE_TLV *p_tlv;
+
+ /* find the start of the NCI message and parse the NCI header */
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+ pp = p+1;
+ NCI_MSG_PRS_HDR1 (pp, op_code);
+ NFC_TRACE_DEBUG1 ("nci_proc_ee_management_ntf opcode:0x%x", op_code);
+ len = *pp++;
+
+ if (op_code == NCI_MSG_NFCEE_DISCOVER)
+ {
+ nfcee_info.nfcee_id = *pp++;
+ ee_status = *pp++;
+
+ nfcee_info.ee_status = ee_status;
+ yy = *pp;
+ nfcee_info.num_interface = *pp++;
+ p = pp;
+
+ if (nfcee_info.num_interface > NFC_MAX_EE_INTERFACE)
+ nfcee_info.num_interface = NFC_MAX_EE_INTERFACE;
+
+ for (xx = 0; xx < nfcee_info.num_interface; xx++)
+ {
+ nfcee_info.ee_interface[xx] = *pp++;
+ }
+
+ pp = p + yy;
+ nfcee_info.num_tlvs = *pp++;
+ NFC_TRACE_DEBUG4 ("nfcee_id: 0x%x num_interface:0x%x/0x%x, num_tlvs:0x%x",
+ nfcee_info.nfcee_id, nfcee_info.num_interface, yy, nfcee_info.num_tlvs);
+
+ if (nfcee_info.num_tlvs > NFC_MAX_EE_TLVS)
+ nfcee_info.num_tlvs = NFC_MAX_EE_TLVS;
+
+ p_tlv = &nfcee_info.ee_tlv[0];
+
+ for (xx = 0; xx < nfcee_info.num_tlvs; xx++, p_tlv++)
+ {
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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;
+ }
+ }
+ else
+ {
+ p_cback = NULL;
+ NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
+ }
+
+ if (p_cback)
+ (*p_cback) (event, p_evt);
+}
+
+#endif
+#endif
+
+/*******************************************************************************
+**
+** Function nci_proc_prop_rsp
+**
+** Description Process NCI responses in the Proprietary group
+**
+** Returns void
+**
+*******************************************************************************/
+void nci_proc_prop_rsp (BT_HDR *p_msg)
+{
+ UINT8 *p;
+ UINT8 *p_evt;
+ UINT8 *pp, len, op_code;
+ tNFC_VS_CBACK *p_cback = (tNFC_VS_CBACK *)nfc_cb.p_vsc_cback;
+
+ /* find the start of the NCI message and parse the NCI header */
+ p = p_evt = (UINT8 *) (p_msg + 1) + p_msg->offset;
+ pp = p+1;
+ NCI_MSG_PRS_HDR1 (pp, op_code);
+ len = *pp++;
+
+ /*If there's a pending/stored command, restore the associated address of the callback function */
+ if (p_cback)
+ (*p_cback) ((tNFC_VS_EVT) (NCI_RSP_BIT|op_code), p_msg->len, p_evt);
+}
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+/*******************************************************************************
+**
+** Function nci_proc_prop_nxp_rsp
+**
+** Description Process NXP NCI responses
+**
+** Returns void
+**
+*******************************************************************************/
+void nci_proc_prop_nxp_rsp (BT_HDR *p_msg)
+{
+ UINT8 *p;
+ UINT8 *p_evt;
+ UINT8 *pp, len, op_code;
+ tNFC_VS_CBACK *p_cback = (tNFC_VS_CBACK *)nfc_cb.p_vsc_cback;
+
+ /* find the start of the NCI message and parse the NCI header */
+ p = p_evt = (UINT8 *) (p_msg + 1) + p_msg->offset;
+ pp = p+1;
+ NCI_MSG_PRS_HDR1 (pp, op_code);
+ len = *pp++;
+
+ /*If there's a pending/stored command, restore the associated address of the callback function */
+ if (p_cback)
+ {
+ (*p_cback) ((tNFC_VS_EVT) (NCI_RSP_BIT|op_code), p_msg->len, p_evt);
+ nfc_cb.p_vsc_cback = NULL;
+ }
+ 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 (BT_HDR *p_msg)
+{
+ UINT8 *p;
+ UINT8 *p_evt;
+ UINT8 *pp, len, op_code;
+ int i;
+
+ /* find the start of the NCI message and parse the NCI header */
+ p = p_evt = (UINT8 *) (p_msg + 1) + p_msg->offset;
+ pp = p+1;
+ NCI_MSG_PRS_HDR1 (pp, op_code);
+ len = *pp++;
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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);
+ }
+ }
+}
+
+#endif /* NFC_INCLUDED == TRUE*/
diff --git a/src/nfc/ndef/ndef_cho_utils.c b/src/nfc/ndef/ndef_cho_utils.c
new file mode 100644
index 0000000..7dd8f42
--- /dev/null
+++ b/src/nfc/ndef/ndef_cho_utils.c
@@ -0,0 +1,589 @@
+/******************************************************************************
+ *
+ * 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 for Connection
+ * Handover
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include "ndef_utils.h"
+
+/*******************************************************************************
+**
+** Static Local Functions
+*/
+static UINT8 *ndef_get_bt_oob_record (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ char *p_id_str);
+
+/*******************************************************************************
+**
+** Static data
+*/
+
+/* Handover Request Record Type */
+static UINT8 hr_rec_type[HR_REC_TYPE_LEN] = { 0x48, 0x72 }; /* "Hr" */
+
+/* Handover Select Record Type */
+static UINT8 hs_rec_type[HS_REC_TYPE_LEN] = { 0x48, 0x73 }; /* "Hs" */
+
+/* Handover Carrier recrod Type */
+static UINT8 hc_rec_type[HC_REC_TYPE_LEN] = { 0x48, 0x63 }; /* "Hc" */
+
+/* Collision Resolution Record Type */
+static UINT8 cr_rec_type[CR_REC_TYPE_LEN] = { 0x63, 0x72 }; /* "cr" */
+
+/* Alternative Carrier Record Type */
+static UINT8 ac_rec_type[AC_REC_TYPE_LEN] = { 0x61, 0x63 }; /* "ac" */
+
+/* Error Record Type */
+static UINT8 err_rec_type[ERR_REC_TYPE_LEN] = { 0x65, 0x72, 0x72 }; /* "err" */
+
+/* Bluetooth OOB Data Type */
+static UINT8 *p_bt_oob_rec_type = (UINT8 *)"application/vnd.bluetooth.ep.oob";
+
+/* Wifi WSC Data Type */
+static UINT8 *p_wifi_wsc_rec_type = (UINT8 *)"application/vnd.wfa.wsc";
+
+/*******************************************************************************
+**
+** Function NDEF_MsgCreateWktHr
+**
+** Description This function creates Handover Request Record with version.
+**
+** Returns NDEF_OK if all OK
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgCreateWktHr (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ UINT8 version )
+{
+ tNDEF_STATUS status;
+
+ NDEF_MsgInit (p_msg, max_size, p_cur_size);
+
+ /* Add record with version */
+ status = NDEF_MsgAddRec (p_msg, max_size, p_cur_size,
+ NDEF_TNF_WKT, hr_rec_type, HR_REC_TYPE_LEN,
+ NULL, 0, &version, 1);
+
+ return (status);
+}
+
+/*******************************************************************************
+**
+** Function NDEF_MsgCreateWktHs
+**
+** Description This function creates Handover Select Record with version.
+**
+** Returns NDEF_OK if all OK
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgCreateWktHs (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ UINT8 version )
+{
+ tNDEF_STATUS status;
+
+ NDEF_MsgInit (p_msg, max_size, p_cur_size);
+
+ /* Add record with version */
+ status = NDEF_MsgAddRec (p_msg, max_size, p_cur_size,
+ NDEF_TNF_WKT, hs_rec_type, HS_REC_TYPE_LEN,
+ NULL, 0, &version, 1);
+
+ return (status);
+}
+
+/*******************************************************************************
+**
+** Function NDEF_MsgAddWktHc
+**
+** Description This function adds Handover Carrier Record.
+**
+** Returns NDEF_OK if all OK
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgAddWktHc (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ char *p_id_str, UINT8 ctf,
+ UINT8 carrier_type_len, UINT8 *p_carrier_type,
+ UINT8 carrier_data_len, UINT8 *p_carrier_data)
+{
+ tNDEF_STATUS status;
+ UINT8 payload[256], *p, id_len;
+ UINT32 payload_len;
+
+ if (carrier_type_len + carrier_data_len + 2 > 256)
+ {
+ return (NDEF_MSG_INSUFFICIENT_MEM);
+ }
+
+ p = payload;
+
+ UINT8_TO_STREAM (p, (ctf & 0x07));
+ UINT8_TO_STREAM (p, carrier_type_len);
+ ARRAY_TO_STREAM (p, p_carrier_type, carrier_type_len);
+ ARRAY_TO_STREAM (p, p_carrier_data, carrier_data_len);
+
+ payload_len = (UINT32)carrier_type_len + carrier_data_len + 2;
+
+ id_len = (UINT8)strlen (p_id_str);
+
+ status = NDEF_MsgAddRec (p_msg, max_size, p_cur_size,
+ NDEF_TNF_WKT, hc_rec_type, HC_REC_TYPE_LEN,
+ (UINT8*)p_id_str, id_len, payload, payload_len);
+ return (status);
+}
+
+/*******************************************************************************
+**
+** Function NDEF_MsgAddWktAc
+**
+** Description This function adds Alternative Carrier Record.
+**
+** Returns NDEF_OK if all OK
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgAddWktAc (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ UINT8 cps, char *p_carrier_data_ref_str,
+ UINT8 aux_data_ref_count, char *p_aux_data_ref_str[])
+{
+ tNDEF_STATUS status;
+ UINT32 payload_len;
+ UINT8 ref_str_len, xx;
+ UINT8 *p_rec, *p;
+
+ /* get payload length first */
+
+ /* CPS, length of carrier data ref, carrier data ref, Aux data reference count */
+ payload_len = 3 + (UINT8)strlen (p_carrier_data_ref_str);
+ for (xx = 0; xx < aux_data_ref_count; xx++)
+ {
+ /* Aux Data Reference length (1 byte) */
+ payload_len += 1 + (UINT8)strlen (p_aux_data_ref_str[xx]);
+ }
+
+ /* reserve memory for payload */
+ status = NDEF_MsgAddRec (p_msg, max_size, p_cur_size,
+ NDEF_TNF_WKT, ac_rec_type, AC_REC_TYPE_LEN,
+ NULL, 0, NULL, payload_len);
+
+ if (status == NDEF_OK)
+ {
+ /* get AC record added at the end */
+ p_rec = NDEF_MsgGetLastRecInMsg (p_msg);
+
+ /* get start pointer of reserved payload */
+ p = NDEF_RecGetPayload (p_rec, &payload_len);
+
+ /* Add Carrier Power State */
+ UINT8_TO_BE_STREAM (p, cps);
+
+ /* Carrier Data Reference length */
+ ref_str_len = (UINT8)strlen (p_carrier_data_ref_str);
+
+ UINT8_TO_BE_STREAM (p, ref_str_len);
+
+ /* Carrier Data Reference */
+ ARRAY_TO_BE_STREAM (p, p_carrier_data_ref_str, ref_str_len);
+
+ /* Aux Data Reference Count */
+ UINT8_TO_BE_STREAM (p, aux_data_ref_count);
+
+ for (xx = 0; xx < aux_data_ref_count; xx++)
+ {
+ /* Aux Data Reference length (1 byte) */
+ ref_str_len = (UINT8)strlen (p_aux_data_ref_str[xx]);
+
+ UINT8_TO_BE_STREAM (p, ref_str_len);
+
+ /* Aux Data Reference */
+ ARRAY_TO_BE_STREAM (p, p_aux_data_ref_str[xx], ref_str_len);
+ }
+ }
+
+ return (status);
+}
+
+/*******************************************************************************
+**
+** Function NDEF_MsgAddWktCr
+**
+** Description This function adds Collision Resolution Record.
+**
+** Returns NDEF_OK if all OK
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgAddWktCr (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ UINT16 random_number )
+{
+ tNDEF_STATUS status;
+ UINT8 data[2], *p;
+
+ p = data;
+ UINT16_TO_BE_STREAM (p, random_number);
+
+ status = NDEF_MsgAddRec (p_msg, max_size, p_cur_size,
+ NDEF_TNF_WKT, cr_rec_type, CR_REC_TYPE_LEN,
+ NULL, 0, data, 2);
+ return (status);
+}
+
+/*******************************************************************************
+**
+** Function NDEF_MsgAddWktErr
+**
+** Description This function adds Error Record.
+**
+** Returns NDEF_OK if all OK
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgAddWktErr (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ UINT8 error_reason, UINT32 error_data )
+{
+ tNDEF_STATUS status;
+ UINT8 payload[5], *p;
+ UINT32 payload_len;
+
+ p = payload;
+
+ UINT8_TO_BE_STREAM (p, error_reason);
+
+ if (error_reason == 0x02)
+ {
+ UINT32_TO_BE_STREAM (p, error_data);
+ payload_len = 5;
+ }
+ else
+ {
+ UINT8_TO_BE_STREAM (p, error_data);
+ payload_len = 2;
+ }
+
+ status = NDEF_MsgAddRec (p_msg, max_size, p_cur_size,
+ NDEF_TNF_WKT, err_rec_type, ERR_REC_TYPE_LEN,
+ NULL, 0, payload, payload_len);
+ return (status);
+}
+
+/*******************************************************************************
+**
+** Function NDEF_MsgAddMediaBtOob
+**
+** Description This function adds BT OOB Record.
+**
+** Returns NDEF_OK if all OK
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgAddMediaBtOob (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ char *p_id_str, BD_ADDR bd_addr)
+{
+ tNDEF_STATUS status;
+ UINT8 payload[BD_ADDR_LEN + 2];
+ UINT8 *p;
+ UINT8 payload_len, id_len;
+
+ p = payload;
+
+ /* length including itself */
+ UINT16_TO_STREAM (p, BD_ADDR_LEN + 2);
+
+ /* BD Addr */
+ BDADDR_TO_STREAM (p, bd_addr);
+
+ payload_len = BD_ADDR_LEN + 2;
+ id_len = (UINT8)strlen (p_id_str);
+
+ status = NDEF_MsgAddRec (p_msg, max_size, p_cur_size,
+ NDEF_TNF_MEDIA, p_bt_oob_rec_type, BT_OOB_REC_TYPE_LEN,
+ (UINT8*)p_id_str, id_len, payload, payload_len);
+ return (status);
+}
+
+/*******************************************************************************
+**
+** Function NDEF_MsgAppendMediaBtOobCod
+**
+** Description This function appends COD EIR data at the end of BT OOB Record.
+**
+** Returns NDEF_OK if all OK
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgAppendMediaBtOobCod (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ char *p_id_str, DEV_CLASS cod)
+{
+ tNDEF_STATUS status;
+ UINT8 *p_rec;
+ UINT8 eir_data[BT_OOB_COD_SIZE + 2];
+ UINT8 *p;
+ UINT8 eir_data_len;
+ UINT32 oob_data_len;
+
+ /* find record by Payload ID */
+ p_rec = ndef_get_bt_oob_record (p_msg, max_size, p_cur_size, p_id_str);
+
+ if (!p_rec)
+ return (NDEF_REC_NOT_FOUND);
+
+ /* create EIR data format for COD */
+ p = eir_data;
+ UINT8_TO_STREAM (p, BT_OOB_COD_SIZE + 1);
+ UINT8_TO_STREAM (p, BT_EIR_OOB_COD_TYPE);
+ DEVCLASS_TO_STREAM (p, cod);
+ eir_data_len = BT_OOB_COD_SIZE + 2;
+
+ /* append EIR data at the end of record */
+ status = NDEF_MsgAppendPayload(p_msg, max_size, p_cur_size,
+ p_rec, eir_data, eir_data_len);
+
+ /* update BT OOB data length, if success */
+ if (status == NDEF_OK)
+ {
+ /* payload length is the same as BT OOB data length */
+ p = NDEF_RecGetPayload (p_rec, &oob_data_len);
+ UINT16_TO_STREAM (p, oob_data_len);
+ }
+
+ return (status);
+}
+
+/*******************************************************************************
+**
+** Function NDEF_MsgAppendMediaBtOobName
+**
+** Description This function appends Bluetooth Local Name EIR data
+** at the end of BT OOB Record.
+**
+** Returns NDEF_OK if all OK
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgAppendMediaBtOobName (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ char *p_id_str, BOOLEAN is_complete,
+ UINT8 name_len, UINT8 *p_name)
+{
+ tNDEF_STATUS status;
+ UINT8 *p_rec;
+ UINT8 eir_data[256];
+ UINT8 *p;
+ UINT8 eir_data_len;
+ UINT32 oob_data_len;
+
+ /* find record by Payload ID */
+ p_rec = ndef_get_bt_oob_record (p_msg, max_size, p_cur_size, p_id_str);
+
+ if (!p_rec)
+ return (NDEF_REC_NOT_FOUND);
+
+ /* create EIR data format for COD */
+ p = eir_data;
+ UINT8_TO_STREAM (p, name_len + 1);
+
+ if (is_complete)
+ {
+ UINT8_TO_STREAM (p, BT_EIR_COMPLETE_LOCAL_NAME_TYPE);
+ }
+ else
+ {
+ UINT8_TO_STREAM (p, BT_EIR_SHORTENED_LOCAL_NAME_TYPE);
+ }
+
+ ARRAY_TO_STREAM (p, p_name, name_len);
+ eir_data_len = name_len + 2;
+
+ /* append EIR data at the end of record */
+ status = NDEF_MsgAppendPayload(p_msg, max_size, p_cur_size,
+ p_rec, eir_data, eir_data_len);
+
+ /* update BT OOB data length, if success */
+ if (status == NDEF_OK)
+ {
+ /* payload length is the same as BT OOB data length */
+ p = NDEF_RecGetPayload (p_rec, &oob_data_len);
+ UINT16_TO_STREAM (p, oob_data_len);
+ }
+
+ return (status);
+}
+
+/*******************************************************************************
+**
+** Function NDEF_MsgAppendMediaBtOobHashCRandR
+**
+** Description This function appends Hash C and Rand R at the end of BT OOB Record.
+**
+** Returns NDEF_OK if all OK
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgAppendMediaBtOobHashCRandR (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ char *p_id_str, UINT8 *p_hash_c, UINT8 *p_rand_r)
+{
+ tNDEF_STATUS status;
+ UINT8 *p_rec;
+ UINT8 eir_data[BT_OOB_HASH_C_SIZE + BT_OOB_RAND_R_SIZE + 4];
+ UINT8 *p;
+ UINT8 eir_data_len;
+ UINT32 oob_data_len;
+
+ /* find record by Payload ID */
+ p_rec = ndef_get_bt_oob_record (p_msg, max_size, p_cur_size, p_id_str);
+
+ if (!p_rec)
+ return (NDEF_REC_NOT_FOUND);
+
+ /* create EIR data format */
+ p = eir_data;
+
+ UINT8_TO_STREAM (p, BT_OOB_HASH_C_SIZE + 1);
+ UINT8_TO_STREAM (p, BT_EIR_OOB_SSP_HASH_C_TYPE);
+ ARRAY16_TO_STREAM (p, p_hash_c);
+
+ UINT8_TO_STREAM (p, BT_OOB_RAND_R_SIZE + 1);
+ UINT8_TO_STREAM (p, BT_EIR_OOB_SSP_RAND_R_TYPE);
+ ARRAY16_TO_STREAM (p, p_rand_r);
+
+ eir_data_len = BT_OOB_HASH_C_SIZE + BT_OOB_RAND_R_SIZE + 4;
+
+ /* append EIR data at the end of record */
+ status = NDEF_MsgAppendPayload(p_msg, max_size, p_cur_size,
+ p_rec, eir_data, eir_data_len);
+
+ /* update BT OOB data length, if success */
+ if (status == NDEF_OK)
+ {
+ /* payload length is the same as BT OOB data length */
+ p = NDEF_RecGetPayload (p_rec, &oob_data_len);
+ UINT16_TO_STREAM (p, oob_data_len);
+ }
+
+ return (status);
+}
+
+/*******************************************************************************
+**
+** Function NDEF_MsgAppendMediaBtOobEirData
+**
+** Description This function appends EIR Data at the end of BT OOB Record.
+**
+** Returns NDEF_OK if all OK
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgAppendMediaBtOobEirData (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ char *p_id_str,
+ UINT8 eir_type, UINT8 data_len, UINT8 *p_data)
+{
+ tNDEF_STATUS status;
+ UINT8 *p_rec;
+ UINT8 eir_data[256];
+ UINT8 *p;
+ UINT8 eir_data_len;
+ UINT32 oob_data_len;
+
+ /* find record by Payload ID */
+ p_rec = ndef_get_bt_oob_record (p_msg, max_size, p_cur_size, p_id_str);
+
+ if (!p_rec)
+ return (NDEF_REC_NOT_FOUND);
+
+ /* create EIR data format */
+ p = eir_data;
+ UINT8_TO_STREAM (p, data_len + 1);
+ UINT8_TO_STREAM (p, eir_type);
+ ARRAY_TO_STREAM (p, p_data, data_len);
+ eir_data_len = data_len + 2;
+
+ /* append EIR data at the end of record */
+ status = NDEF_MsgAppendPayload(p_msg, max_size, p_cur_size,
+ p_rec, eir_data, eir_data_len);
+
+ /* update BT OOB data length, if success */
+ if (status == NDEF_OK)
+ {
+ /* payload length is the same as BT OOB data length */
+ p = NDEF_RecGetPayload (p_rec, &oob_data_len);
+ UINT16_TO_STREAM (p, oob_data_len);
+ }
+
+ return (status);
+}
+
+/*******************************************************************************
+**
+** Function NDEF_MsgAddMediaWifiWsc
+**
+** Description This function adds Wifi Wsc Record header.
+**
+** Returns NDEF_OK if all OK
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgAddMediaWifiWsc (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ char *p_id_str, UINT8 *p_payload, UINT32 payload_len)
+{
+ tNDEF_STATUS status;
+ UINT8 id_len = 0;
+
+ if (p_id_str)
+ id_len = (UINT8)strlen (p_id_str);
+
+ status = NDEF_MsgAddRec (p_msg, max_size, p_cur_size,
+ NDEF_TNF_MEDIA, p_wifi_wsc_rec_type, WIFI_WSC_REC_TYPE_LEN,
+ (UINT8*)p_id_str, id_len, p_payload, payload_len);
+ return (status);
+}
+
+/*******************************************************************************
+**
+** Static Local Functions
+**
+*******************************************************************************/
+/*******************************************************************************
+**
+** Function ndef_get_bt_oob_record
+**
+** Description This function returns BT OOB record which has matched payload ID
+**
+** Returns pointer of record if found, otherwise NULL
+**
+*******************************************************************************/
+static UINT8 *ndef_get_bt_oob_record (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ char *p_id_str)
+{
+ UINT8 *p_rec, *p_type;
+ UINT8 id_len, tnf, type_len;
+
+ /* find record by Payload ID */
+ id_len = (UINT8)strlen (p_id_str);
+ p_rec = NDEF_MsgGetFirstRecById (p_msg, (UINT8*)p_id_str, id_len);
+
+ if (!p_rec)
+ return (NULL);
+
+ p_type = NDEF_RecGetType (p_rec, &tnf, &type_len);
+
+ /* check type if this is BT OOB record */
+ if ((!p_rec)
+ ||(tnf != NDEF_TNF_MEDIA)
+ ||(type_len != BT_OOB_REC_TYPE_LEN)
+ ||(memcmp (p_type, p_bt_oob_rec_type, BT_OOB_REC_TYPE_LEN)))
+ {
+ return (NULL);
+ }
+
+ return (p_rec);
+}
diff --git a/src/nfc/ndef/ndef_utils.c b/src/nfc/ndef/ndef_utils.c
new file mode 100644
index 0000000..f6eea76
--- /dev/null
+++ b/src/nfc/ndef/ndef_utils.c
@@ -0,0 +1,1569 @@
+/******************************************************************************
+ *
+ * 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 *p_mem, UINT32 len, UINT32 shift_amount)
+{
+ register UINT8 *ps = p_mem + len - 1;
+ register UINT8 *pd = ps + shift_amount;
+ register UINT32 xx;
+
+ for (xx = 0; xx < len; xx++)
+ *pd-- = *ps--;
+}
+
+/*******************************************************************************
+**
+** Function shiftup
+**
+** Description shift memory up (to delete a record)
+**
+*******************************************************************************/
+static void shiftup (UINT8 *p_dest, UINT8 *p_src, UINT32 len)
+{
+ register UINT8 *ps = p_src;
+ register UINT8 *pd = p_dest;
+ register UINT32 xx;
+
+ for (xx = 0; xx < len; xx++)
+ *pd++ = *ps++;
+}
+
+/*******************************************************************************
+**
+** Function NDEF_MsgValidate
+**
+** Description This function validates an NDEF message.
+**
+** Returns TRUE if all OK, or FALSE if the message is invalid.
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgValidate (UINT8 *p_msg, UINT32 msg_len, BOOLEAN b_allow_chunks)
+{
+ UINT8 *p_rec = p_msg;
+ UINT8 *p_end = p_msg + msg_len;
+ UINT8 rec_hdr=0, type_len, id_len;
+ int count;
+ UINT32 payload_len;
+ BOOLEAN bInChunk = FALSE;
+
+ if ( (p_msg == NULL) || (msg_len < 3) )
+ return (NDEF_MSG_TOO_SHORT);
+
+ /* The first record must have the MB bit set */
+ if ((*p_msg & NDEF_MB_MASK) == 0)
+ return (NDEF_MSG_NO_MSG_BEGIN);
+
+ /* The first record cannot be a chunk */
+ if ((*p_msg & NDEF_TNF_MASK) == NDEF_TNF_UNCHANGED)
+ return (NDEF_MSG_UNEXPECTED_CHUNK);
+
+ for (count = 0; p_rec < p_end; count++)
+ {
+ /* if less than short record header */
+ if (p_rec + 3 > p_end)
+ return (NDEF_MSG_TOO_SHORT);
+
+ rec_hdr = *p_rec++;
+
+ /* The second and all subsequent records must NOT have the MB bit set */
+ if ( (count > 0) && (rec_hdr & NDEF_MB_MASK) )
+ return (NDEF_MSG_EXTRA_MSG_BEGIN);
+
+ /* Type field length */
+ type_len = *p_rec++;
+
+ /* Payload length - can be 1 or 4 bytes */
+ if (rec_hdr & NDEF_SR_MASK)
+ payload_len = *p_rec++;
+ else
+ {
+ /* if less than 4 bytes payload length */
+ if (p_rec + 4 > p_end)
+ return (NDEF_MSG_TOO_SHORT);
+
+ BE_STREAM_TO_UINT32 (payload_len, p_rec);
+ }
+
+ /* ID field Length */
+ if (rec_hdr & NDEF_IL_MASK)
+ {
+ /* if less than 1 byte ID field length */
+ if (p_rec + 1 > p_end)
+ return (NDEF_MSG_TOO_SHORT);
+
+ id_len = *p_rec++;
+ }
+ else
+ id_len = 0;
+
+ /* A chunk must have type "unchanged", and no type or ID fields */
+ if (rec_hdr & NDEF_CF_MASK)
+ {
+ if (!b_allow_chunks)
+ return (NDEF_MSG_UNEXPECTED_CHUNK);
+
+ /* Inside a chunk, the type must be unchanged and no type or ID field i sallowed */
+ if (bInChunk)
+ {
+ if ( (type_len != 0) || (id_len != 0) || ((rec_hdr & NDEF_TNF_MASK) != NDEF_TNF_UNCHANGED) )
+ return (NDEF_MSG_INVALID_CHUNK);
+ }
+ else
+ {
+ /* First record of a chunk must NOT have type "unchanged" */
+ if ((rec_hdr & NDEF_TNF_MASK) == NDEF_TNF_UNCHANGED)
+ return (NDEF_MSG_INVALID_CHUNK);
+
+ bInChunk = TRUE;
+ }
+ }
+ else
+ {
+ /* This may be the last guy in a chunk. */
+ if (bInChunk)
+ {
+ if ( (type_len != 0) || (id_len != 0) || ((rec_hdr & NDEF_TNF_MASK) != NDEF_TNF_UNCHANGED) )
+ return (NDEF_MSG_INVALID_CHUNK);
+
+ bInChunk = FALSE;
+ }
+ else
+ {
+ /* If not in a chunk, the record must NOT have type "unchanged" */
+ if ((rec_hdr & NDEF_TNF_MASK) == NDEF_TNF_UNCHANGED)
+ return (NDEF_MSG_INVALID_CHUNK);
+ }
+ }
+
+ /* An empty record must NOT have a type, ID or payload */
+ if ((rec_hdr & NDEF_TNF_MASK) == NDEF_TNF_EMPTY)
+ {
+ if ( (type_len != 0) || (id_len != 0) || (payload_len != 0) )
+ return (NDEF_MSG_INVALID_EMPTY_REC);
+ }
+
+ if ((rec_hdr & NDEF_TNF_MASK) == NDEF_TNF_UNKNOWN)
+ {
+ if (type_len != 0)
+ return (NDEF_MSG_LENGTH_MISMATCH);
+ }
+
+ /* Point to next record */
+ p_rec += (payload_len + type_len + id_len);
+
+ if (rec_hdr & NDEF_ME_MASK)
+ break;
+
+ rec_hdr = 0;
+ }
+
+ /* The last record should have the ME bit set */
+ if ((rec_hdr & NDEF_ME_MASK) == 0)
+ return (NDEF_MSG_NO_MSG_END);
+
+ /* p_rec should equal p_end if all the length fields were correct */
+ if (p_rec != p_end)
+ return (NDEF_MSG_LENGTH_MISMATCH);
+
+ return (NDEF_OK);
+}
+
+/*******************************************************************************
+**
+** Function NDEF_MsgGetNumRecs
+**
+** Description This function gets the number of records in the given NDEF
+** message.
+**
+** Returns The record count, or 0 if the message is invalid.
+**
+*******************************************************************************/
+INT32 NDEF_MsgGetNumRecs (UINT8 *p_msg)
+{
+ UINT8 *p_rec = p_msg;
+ UINT8 rec_hdr, type_len, id_len;
+ int count;
+ UINT32 payload_len;
+
+ for (count = 0; ; )
+ {
+ count++;
+
+ rec_hdr = *p_rec++;
+
+ if (rec_hdr & NDEF_ME_MASK)
+ break;
+
+ /* Type field length */
+ type_len = *p_rec++;
+
+ /* Payload length - can be 1 or 4 bytes */
+ if (rec_hdr & NDEF_SR_MASK)
+ payload_len = *p_rec++;
+ else
+ BE_STREAM_TO_UINT32 (payload_len, p_rec);
+
+ /* ID field Length */
+ if (rec_hdr & NDEF_IL_MASK)
+ id_len = *p_rec++;
+ else
+ id_len = 0;
+
+ /* Point to next record */
+ p_rec += (payload_len + type_len + id_len);
+ }
+
+ /* Return the number of records found */
+ return (count);
+}
+
+/*******************************************************************************
+**
+** Function NDEF_MsgGetRecLength
+**
+** Description This function returns length of the current record in the given
+** NDEF message.
+**
+** Returns Length of record
+**
+*******************************************************************************/
+UINT32 NDEF_MsgGetRecLength (UINT8 *p_cur_rec)
+{
+ UINT8 rec_hdr, type_len, id_len;
+ UINT32 rec_len = 0;
+ UINT32 payload_len;
+
+ /* Get the current record's header */
+ rec_hdr = *p_cur_rec++;
+ rec_len++;
+
+ /* Type field length */
+ type_len = *p_cur_rec++;
+ rec_len++;
+
+ /* Payload length - can be 1 or 4 bytes */
+ if (rec_hdr & NDEF_SR_MASK)
+ {
+ payload_len = *p_cur_rec++;
+ rec_len++;
+ }
+ else
+ {
+ BE_STREAM_TO_UINT32 (payload_len, p_cur_rec);
+ rec_len += 4;
+ }
+
+ /* ID field Length */
+ if (rec_hdr & NDEF_IL_MASK)
+ {
+ id_len = *p_cur_rec++;
+ rec_len++;
+ }
+ else
+ id_len = 0;
+
+ /* Total length of record */
+ rec_len += (payload_len + type_len + id_len);
+
+ return (rec_len);
+}
+
+/*******************************************************************************
+**
+** Function NDEF_MsgGetNextRec
+**
+** Description This function gets a pointer to the next record in the given
+** NDEF message. If the current record pointer is NULL, a pointer
+** to the first record is returned.
+**
+** Returns Pointer to the start of the record, or NULL if no more
+**
+*******************************************************************************/
+UINT8 *NDEF_MsgGetNextRec (UINT8 *p_cur_rec)
+{
+ UINT8 rec_hdr, type_len, id_len;
+ UINT32 payload_len;
+
+ /* Get the current record's header */
+ rec_hdr = *p_cur_rec++;
+
+ /* If this is the last record, return NULL */
+ if (rec_hdr & NDEF_ME_MASK)
+ return (NULL);
+
+ /* Type field length */
+ type_len = *p_cur_rec++;
+
+ /* Payload length - can be 1 or 4 bytes */
+ if (rec_hdr & NDEF_SR_MASK)
+ payload_len = *p_cur_rec++;
+ else
+ BE_STREAM_TO_UINT32 (payload_len, p_cur_rec);
+
+ /* ID field Length */
+ if (rec_hdr & NDEF_IL_MASK)
+ id_len = *p_cur_rec++;
+ else
+ id_len = 0;
+
+ /* Point to next record */
+ p_cur_rec += (payload_len + type_len + id_len);
+
+ return (p_cur_rec);
+}
+
+/*******************************************************************************
+**
+** Function NDEF_MsgGetRecByIndex
+**
+** Description This function gets a pointer to the record with the given
+** index (0-based index) in the given NDEF message.
+**
+** Returns Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+UINT8 *NDEF_MsgGetRecByIndex (UINT8 *p_msg, INT32 index)
+{
+ UINT8 *p_rec = p_msg;
+ UINT8 rec_hdr, type_len, id_len;
+ INT32 count;
+ UINT32 payload_len;
+
+ for (count = 0; ; count++)
+ {
+ if (count == index)
+ return (p_rec);
+
+ rec_hdr = *p_rec++;
+
+ if (rec_hdr & NDEF_ME_MASK)
+ return (NULL);
+
+ /* Type field length */
+ type_len = *p_rec++;
+
+ /* Payload length - can be 1 or 4 bytes */
+ if (rec_hdr & NDEF_SR_MASK)
+ payload_len = *p_rec++;
+ else
+ BE_STREAM_TO_UINT32 (payload_len, p_rec);
+
+ /* ID field Length */
+ if (rec_hdr & NDEF_IL_MASK)
+ id_len = *p_rec++;
+ else
+ id_len = 0;
+
+ /* Point to next record */
+ p_rec += (payload_len + type_len + id_len);
+ }
+
+ /* If here, there is no record of that index */
+ return (NULL);
+}
+
+
+/*******************************************************************************
+**
+** Function NDEF_MsgGetLastRecInMsg
+**
+** Description This function gets a pointer to the last record in the
+** given NDEF message.
+**
+** Returns Pointer to the start of the last record, or NULL if some problem
+**
+*******************************************************************************/
+UINT8 *NDEF_MsgGetLastRecInMsg (UINT8 *p_msg)
+{
+ UINT8 *p_rec = p_msg;
+ UINT8 *pRecStart;
+ UINT8 rec_hdr, type_len, id_len;
+ UINT32 payload_len;
+
+ for ( ; ; )
+ {
+ pRecStart = p_rec;
+ rec_hdr = *p_rec++;
+
+ if (rec_hdr & NDEF_ME_MASK)
+ break;
+
+ /* Type field length */
+ type_len = *p_rec++;
+
+ /* Payload length - can be 1 or 4 bytes */
+ if (rec_hdr & NDEF_SR_MASK)
+ payload_len = *p_rec++;
+ else
+ BE_STREAM_TO_UINT32 (payload_len, p_rec);
+
+ /* ID field Length */
+ if (rec_hdr & NDEF_IL_MASK)
+ id_len = *p_rec++;
+ else
+ id_len = 0;
+
+ /* Point to next record */
+ p_rec += (payload_len + type_len + id_len);
+ }
+
+ return (pRecStart);
+}
+
+
+/*******************************************************************************
+**
+** Function NDEF_MsgGetFirstRecByType
+**
+** Description This function gets a pointer to the first record with the given
+** record type in the given NDEF message.
+**
+** Returns Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+UINT8 *NDEF_MsgGetFirstRecByType (UINT8 *p_msg, UINT8 tnf, UINT8 *p_type, UINT8 tlen)
+{
+ UINT8 *p_rec = p_msg;
+ UINT8 *pRecStart;
+ UINT8 rec_hdr, type_len, id_len;
+ UINT32 payload_len;
+
+ for ( ; ; )
+ {
+ pRecStart = p_rec;
+
+ rec_hdr = *p_rec++;
+
+ /* Type field length */
+ type_len = *p_rec++;
+
+ /* Payload length - can be 1 or 4 bytes */
+ if (rec_hdr & NDEF_SR_MASK)
+ payload_len = *p_rec++;
+ else
+ BE_STREAM_TO_UINT32 (payload_len, p_rec);
+
+ /* ID field Length */
+ if (rec_hdr & NDEF_IL_MASK)
+ id_len = *p_rec++;
+ else
+ id_len = 0;
+
+ /* At this point, p_rec points to the start of the type field. We need to */
+ /* compare the type of the type, the length of the type and the data */
+ if ( ((rec_hdr & NDEF_TNF_MASK) == tnf)
+ && (type_len == tlen)
+ && (!memcmp (p_rec, p_type, tlen)) )
+ return (pRecStart);
+
+ /* If this was the last record, return NULL */
+ if (rec_hdr & NDEF_ME_MASK)
+ return (NULL);
+
+ /* Point to next record */
+ p_rec += (payload_len + type_len + id_len);
+ }
+
+ /* If here, there is no record of that type */
+ return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function NDEF_MsgGetNextRecByType
+**
+** Description This function gets a pointer to the next record with the given
+** record type in the given NDEF message.
+**
+** Returns Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+UINT8 *NDEF_MsgGetNextRecByType (UINT8 *p_cur_rec, UINT8 tnf, UINT8 *p_type, UINT8 tlen)
+{
+ UINT8 *p_rec;
+ UINT8 *pRecStart;
+ UINT8 rec_hdr, type_len, id_len;
+ UINT32 payload_len;
+
+ /* If this is the last record in the message, return NULL */
+ if ((p_rec = NDEF_MsgGetNextRec (p_cur_rec)) == NULL)
+ return (NULL);
+
+ for ( ; ; )
+ {
+ pRecStart = p_rec;
+
+ rec_hdr = *p_rec++;
+
+ /* Type field length */
+ type_len = *p_rec++;
+
+ /* Payload length - can be 1 or 4 bytes */
+ if (rec_hdr & NDEF_SR_MASK)
+ payload_len = *p_rec++;
+ else
+ BE_STREAM_TO_UINT32 (payload_len, p_rec);
+
+ /* ID field Length */
+ if (rec_hdr & NDEF_IL_MASK)
+ id_len = *p_rec++;
+ else
+ id_len = 0;
+
+ /* At this point, p_rec points to the start of the type field. We need to */
+ /* compare the type of the type, the length of the type and the data */
+ if ( ((rec_hdr & NDEF_TNF_MASK) == tnf)
+ && (type_len == tlen)
+ && (!memcmp (p_rec, p_type, tlen)) )
+ return (pRecStart);
+
+ /* If this was the last record, return NULL */
+ if (rec_hdr & NDEF_ME_MASK)
+ break;
+
+ /* Point to next record */
+ p_rec += (payload_len + type_len + id_len);
+ }
+
+ /* If here, there is no record of that type */
+ return (NULL);
+}
+
+
+/*******************************************************************************
+**
+** Function NDEF_MsgGetFirstRecById
+**
+** Description This function gets a pointer to the first record with the given
+** record id in the given NDEF message.
+**
+** Returns Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+UINT8 *NDEF_MsgGetFirstRecById (UINT8 *p_msg, UINT8 *p_id, UINT8 ilen)
+{
+ UINT8 *p_rec = p_msg;
+ UINT8 *pRecStart;
+ UINT8 rec_hdr, type_len, id_len;
+ UINT32 payload_len;
+
+ for ( ; ; )
+ {
+ pRecStart = p_rec;
+
+ rec_hdr = *p_rec++;
+
+ /* Type field length */
+ type_len = *p_rec++;
+
+ /* Payload length - can be 1 or 4 bytes */
+ if (rec_hdr & NDEF_SR_MASK)
+ payload_len = *p_rec++;
+ else
+ BE_STREAM_TO_UINT32 (payload_len, p_rec);
+
+ /* ID field Length */
+ if (rec_hdr & NDEF_IL_MASK)
+ id_len = *p_rec++;
+ else
+ id_len = 0;
+
+ /* At this point, p_rec points to the start of the type field. Skip it */
+ p_rec += type_len;
+
+ /* At this point, p_rec points to the start of the ID field. Compare length and data */
+ if ( (id_len == ilen) && (!memcmp (p_rec, p_id, ilen)) )
+ return (pRecStart);
+
+ /* If this was the last record, return NULL */
+ if (rec_hdr & NDEF_ME_MASK)
+ return (NULL);
+
+ /* Point to next record */
+ p_rec += (id_len + payload_len);
+ }
+
+ /* If here, there is no record of that ID */
+ return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function NDEF_MsgGetNextRecById
+**
+** Description This function gets a pointer to the next record with the given
+** record id in the given NDEF message.
+**
+** Returns Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+UINT8 *NDEF_MsgGetNextRecById (UINT8 *p_cur_rec, UINT8 *p_id, UINT8 ilen)
+{
+ UINT8 *p_rec;
+ UINT8 *pRecStart;
+ UINT8 rec_hdr, type_len, id_len;
+ UINT32 payload_len;
+
+ /* If this is the last record in the message, return NULL */
+ if ((p_rec = NDEF_MsgGetNextRec (p_cur_rec)) == NULL)
+ return (NULL);
+
+ for ( ; ; )
+ {
+ pRecStart = p_rec;
+
+ rec_hdr = *p_rec++;
+
+ /* Type field length */
+ type_len = *p_rec++;
+
+ /* Payload length - can be 1 or 4 bytes */
+ if (rec_hdr & NDEF_SR_MASK)
+ payload_len = *p_rec++;
+ else
+ BE_STREAM_TO_UINT32 (payload_len, p_rec);
+
+ /* ID field Length */
+ if (rec_hdr & NDEF_IL_MASK)
+ id_len = *p_rec++;
+ else
+ id_len = 0;
+
+ /* At this point, p_rec points to the start of the type field. Skip it */
+ p_rec += type_len;
+
+ /* At this point, p_rec points to the start of the ID field. Compare length and data */
+ if ( (id_len == ilen) && (!memcmp (p_rec, p_id, ilen)) )
+ return (pRecStart);
+
+ /* If this was the last record, return NULL */
+ if (rec_hdr & NDEF_ME_MASK)
+ break;
+
+ /* Point to next record */
+ p_rec += (id_len + payload_len);
+ }
+
+ /* If here, there is no record of that ID */
+ return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function NDEF_RecGetType
+**
+** Description This function gets a pointer to the record type for the given NDEF record.
+**
+** Returns Pointer to Type (NULL if none). TNF and len are filled in.
+**
+*******************************************************************************/
+UINT8 *NDEF_RecGetType (UINT8 *p_rec, UINT8 *p_tnf, UINT8 *p_type_len)
+{
+ UINT8 rec_hdr, type_len;
+
+ /* First byte is the record header */
+ rec_hdr = *p_rec++;
+
+ /* Next byte is the type field length */
+ type_len = *p_rec++;
+
+ /* Skip the payload length */
+ if (rec_hdr & NDEF_SR_MASK)
+ p_rec += 1;
+ else
+ p_rec += 4;
+
+ /* Skip ID field Length, if present */
+ if (rec_hdr & NDEF_IL_MASK)
+ p_rec++;
+
+ /* At this point, p_rec points to the start of the type field. */
+ *p_type_len = type_len;
+ *p_tnf = rec_hdr & NDEF_TNF_MASK;
+
+ if (type_len == 0)
+ return (NULL);
+ else
+ return (p_rec);
+}
+
+/*******************************************************************************
+**
+** Function NDEF_RecGetId
+**
+** Description This function gets a pointer to the record id for the given NDEF record.
+**
+** Returns Pointer to Id (NULL if none). ID Len is filled in.
+**
+*******************************************************************************/
+UINT8 *NDEF_RecGetId (UINT8 *p_rec, UINT8 *p_id_len)
+{
+ UINT8 rec_hdr, type_len;
+
+ /* First byte is the record header */
+ rec_hdr = *p_rec++;
+
+ /* Next byte is the type field length */
+ type_len = *p_rec++;
+
+ /* Skip the payload length */
+ if (rec_hdr & NDEF_SR_MASK)
+ p_rec++;
+ else
+ p_rec += 4;
+
+ /* ID field Length */
+ if (rec_hdr & NDEF_IL_MASK)
+ *p_id_len = *p_rec++;
+ else
+ *p_id_len = 0;
+
+ /* p_rec now points to the start of the type field. The ID field follows it */
+ if (*p_id_len == 0)
+ return (NULL);
+ else
+ return (p_rec + type_len);
+}
+
+
+/*******************************************************************************
+**
+** Function NDEF_RecGetPayload
+**
+** Description This function gets a pointer to the payload for the given NDEF record.
+**
+** Returns a pointer to the payload (or NULL none). Payload len filled in.
+**
+*******************************************************************************/
+UINT8 *NDEF_RecGetPayload (UINT8 *p_rec, UINT32 *p_payload_len)
+{
+ UINT8 rec_hdr, type_len, id_len;
+ UINT32 payload_len;
+
+ /* First byte is the record header */
+ rec_hdr = *p_rec++;
+
+ /* Next byte is the type field length */
+ type_len = *p_rec++;
+
+ /* Next is the payload length (1 or 4 bytes) */
+ if (rec_hdr & NDEF_SR_MASK)
+ payload_len = *p_rec++;
+ else
+ BE_STREAM_TO_UINT32 (payload_len, p_rec);
+
+ *p_payload_len = payload_len;
+
+ /* ID field Length */
+ if (rec_hdr & NDEF_IL_MASK)
+ id_len = *p_rec++;
+ else
+ id_len = 0;
+
+ /* p_rec now points to the start of the type field. The ID field follows it, then the payload */
+ if (payload_len == 0)
+ return (NULL);
+ else
+ return (p_rec + type_len + id_len);
+}
+
+
+/*******************************************************************************
+**
+** Function NDEF_MsgInit
+**
+** Description This function initializes an NDEF message.
+**
+** Returns void
+** *p_cur_size is initialized to 0
+**
+*******************************************************************************/
+void NDEF_MsgInit (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size)
+{
+ *p_cur_size = 0;
+ memset (p_msg, 0, max_size);
+}
+
+/*******************************************************************************
+**
+** Function NDEF_MsgAddRec
+**
+** Description This function adds an NDEF record to the end of an NDEF message.
+**
+** Returns OK, or error if the record did not fit
+** *p_cur_size is updated
+**
+*******************************************************************************/
+extern tNDEF_STATUS NDEF_MsgAddRec (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ UINT8 tnf, UINT8 *p_type, UINT8 type_len,
+ UINT8 *p_id, UINT8 id_len,
+ UINT8 *p_payload, UINT32 payload_len)
+{
+ UINT8 *p_rec = p_msg + *p_cur_size;
+ UINT32 recSize;
+ int plen = (payload_len < 256) ? 1 : 4;
+ int ilen = (id_len == 0) ? 0 : 1;
+
+ if (tnf > NDEF_TNF_RESERVED)
+ {
+ tnf = NDEF_TNF_UNKNOWN;
+ type_len = 0;
+ }
+
+ /* First, make sure the record will fit. we need at least 2 bytes for header and type length */
+ recSize = payload_len + 2 + type_len + plen + ilen + id_len;
+
+ if ((*p_cur_size + recSize) > max_size)
+ return (NDEF_MSG_INSUFFICIENT_MEM);
+
+ /* Construct the record header. For the first record, set both begin and end bits */
+ if (*p_cur_size == 0)
+ *p_rec = tnf | NDEF_MB_MASK | NDEF_ME_MASK;
+ else
+ {
+ /* Find the previous last and clear his 'Message End' bit */
+ UINT8 *pLast = NDEF_MsgGetLastRecInMsg (p_msg);
+
+ if (!pLast)
+ return (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)payload_len;
+ else
+ UINT32_TO_BE_STREAM (p_rec, payload_len);
+
+ /* ID field Length (optional) */
+ if (ilen > 0)
+ *p_rec++ = id_len;
+
+ /* Next comes the type */
+ if (type_len)
+ {
+ if (p_type)
+ memcpy (p_rec, p_type, type_len);
+
+ p_rec += type_len;
+ }
+
+ /* Next comes the ID */
+ if (id_len)
+ {
+ if (p_id)
+ memcpy (p_rec, p_id, id_len);
+
+ p_rec += id_len;
+ }
+
+ /* And lastly the payload. If NULL, the app just wants to reserve memory */
+ if (p_payload)
+ memcpy (p_rec, p_payload, payload_len);
+
+ *p_cur_size += recSize;
+
+ return (NDEF_OK);
+}
+
+/*******************************************************************************
+**
+** Function NDEF_MsgInsertRec
+**
+** Description This function inserts a record at a specific index into the
+** given NDEF message
+**
+** Returns OK, or error if the record did not fit
+** *p_cur_size is updated
+**
+*******************************************************************************/
+extern tNDEF_STATUS NDEF_MsgInsertRec (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size, INT32 index,
+ UINT8 tnf, UINT8 *p_type, UINT8 type_len,
+ UINT8 *p_id, UINT8 id_len,
+ UINT8 *p_payload, UINT32 payload_len)
+{
+ UINT8 *p_rec;
+ UINT32 recSize;
+ INT32 plen = (payload_len < 256) ? 1 : 4;
+ INT32 ilen = (id_len == 0) ? 0 : 1;
+
+ /* First, make sure the record will fit. we need at least 2 bytes for header and type length */
+ recSize = payload_len + 2 + type_len + plen + ilen + id_len;
+
+ if ((*p_cur_size + recSize) > max_size)
+ return (NDEF_MSG_INSUFFICIENT_MEM);
+
+ /* See where the new record goes. If at the end, call the 'AddRec' function */
+ if ( (index >= NDEF_MsgGetNumRecs (p_msg))
+ || ((p_rec = NDEF_MsgGetRecByIndex(p_msg, index)) == NULL) )
+ {
+ return NDEF_MsgAddRec (p_msg, max_size, p_cur_size, tnf, p_type, type_len,
+ p_id, id_len, p_payload, payload_len);
+ }
+
+ /* If we are inserting at the beginning, remove the MB bit from the current first */
+ if (index == 0)
+ *p_msg &= ~NDEF_MB_MASK;
+
+ /* Make space for the new record */
+ shiftdown (p_rec, (UINT32)(*p_cur_size - (p_rec - p_msg)), recSize);
+
+ /* If adding at the beginning, set begin bit */
+ if (index == 0)
+ *p_rec = tnf | NDEF_MB_MASK;
+ else
+ *p_rec = tnf;
+
+ if (plen == 1)
+ *p_rec |= NDEF_SR_MASK;
+
+ if (ilen != 0)
+ *p_rec |= NDEF_IL_MASK;
+
+ p_rec++;
+
+ /* The next byte is the type field length */
+ *p_rec++ = type_len;
+
+ /* Payload length - can be 1 or 4 bytes */
+ if (plen == 1)
+ *p_rec++ = (UINT8)payload_len;
+ else
+ UINT32_TO_BE_STREAM (p_rec, payload_len);
+
+ /* ID field Length (optional) */
+ if (ilen != 0)
+ *p_rec++ = id_len;
+
+ /* Next comes the type */
+ if (type_len)
+ {
+ if (p_type)
+ memcpy (p_rec, p_type, type_len);
+
+ p_rec += type_len;
+ }
+
+ /* Next comes the ID */
+ if (ilen != 0)
+ {
+ if (p_id)
+ memcpy (p_rec, p_id, id_len);
+
+ p_rec += id_len;
+ }
+
+ /* And lastly the payload. If NULL, the app just wants to reserve memory */
+ if (p_payload)
+ memcpy (p_rec, p_payload, payload_len);
+
+ *p_cur_size += recSize;
+
+ return (NDEF_OK);
+}
+
+/*******************************************************************************
+**
+** Function NDEF_MsgAppendRec
+**
+** Description This function adds NDEF records to the end of an NDEF message.
+**
+** Returns OK, or error if the record did not fit
+** *p_cur_size is updated
+**
+*******************************************************************************/
+extern tNDEF_STATUS NDEF_MsgAppendRec (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ UINT8 *p_new_rec, UINT32 new_rec_len)
+{
+ UINT8 *p_rec;
+ tNDEF_STATUS status;
+
+ /* First, validate new records */
+ if ((status = NDEF_MsgValidate(p_new_rec, new_rec_len, FALSE)) != NDEF_OK)
+ return (status);
+
+ /* First, make sure the record will fit */
+ if ((*p_cur_size + new_rec_len) > max_size)
+ return (NDEF_MSG_INSUFFICIENT_MEM);
+
+ /* Find where to copy new record */
+ if (*p_cur_size == 0)
+ p_rec = p_msg;
+ else
+ {
+ /* Find the previous last and clear his 'Message End' bit */
+ UINT8 *pLast = NDEF_MsgGetLastRecInMsg (p_msg);
+
+ if (!pLast)
+ return (NDEF_MSG_NO_MSG_END);
+
+ *pLast &= ~NDEF_ME_MASK;
+ p_rec = p_msg + *p_cur_size;
+
+ /* clear 'Message Begin' bit of new record */
+ *p_new_rec &= ~NDEF_MB_MASK;
+ }
+
+ /* append new records */
+ memcpy (p_rec, p_new_rec, new_rec_len);
+
+ *p_cur_size += new_rec_len;
+
+ return (NDEF_OK);
+}
+
+/*******************************************************************************
+**
+** Function NDEF_MsgAppendPayload
+**
+** Description This function appends extra payload to a specific record in the
+** given NDEF message
+**
+** Returns OK, or error if the extra payload did not fit
+** *p_cur_size is updated
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgAppendPayload (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ UINT8 *p_rec, UINT8 *p_add_pl, UINT32 add_pl_len)
+{
+ UINT32 prev_paylen, new_paylen;
+ UINT8 *p_prev_pl, *pp;
+ UINT8 incr_lenfld = 0;
+ UINT8 type_len, id_len;
+
+ /* Skip header */
+ pp = p_rec + 1;
+
+ /* Next byte is the type field length */
+ type_len = *pp++;
+
+ /* Next is the payload length (1 or 4 bytes) */
+ if (*p_rec & NDEF_SR_MASK)
+ prev_paylen = *pp++;
+ else
+ BE_STREAM_TO_UINT32 (prev_paylen, pp);
+
+ /* ID field Length */
+ if (*p_rec & NDEF_IL_MASK)
+ id_len = *pp++;
+ else
+ id_len = 0;
+
+ p_prev_pl = pp + type_len + id_len;
+
+ new_paylen = prev_paylen + add_pl_len;
+
+ /* Previous payload may be < 256, and this addition may make it larger than 256 */
+ /* If that were to happen, the payload length field goes from 1 byte to 4 bytes */
+ if ( (prev_paylen < 256) && (new_paylen > 255) )
+ incr_lenfld = 3;
+
+ /* Check that it all fits */
+ if ((*p_cur_size + add_pl_len + incr_lenfld) > max_size)
+ return (NDEF_MSG_INSUFFICIENT_MEM);
+
+ /* Point to payload length field */
+ pp = p_rec + 2;
+
+ /* If we need to increase the length field from 1 to 4 bytes, do it first */
+ if (incr_lenfld)
+ {
+ shiftdown (pp + 1, (UINT32)(*p_cur_size - (pp - p_msg) - 1), 3);
+ p_prev_pl += 3;
+ }
+
+ /* Store in the new length */
+ if (new_paylen > 255)
+ {
+ *p_rec &= ~NDEF_SR_MASK;
+ UINT32_TO_BE_STREAM (pp, new_paylen);
+ }
+ else
+ *pp = (UINT8)new_paylen;
+
+ /* Point to the end of the previous payload */
+ pp = p_prev_pl + prev_paylen;
+
+ /* If we are not the last record, make space for the extra payload */
+ if ((*p_rec & NDEF_ME_MASK) == 0)
+ shiftdown (pp, (UINT32)(*p_cur_size - (pp - p_msg)), add_pl_len);
+
+ /* Now copy in the additional payload data */
+ memcpy (pp, p_add_pl, add_pl_len);
+
+ *p_cur_size += add_pl_len + incr_lenfld;
+
+ return (NDEF_OK);
+}
+
+/*******************************************************************************
+**
+** Function NDEF_MsgReplacePayload
+**
+** Description This function replaces the payload of a specific record in the
+** given NDEF message
+**
+** Returns OK, or error if the new payload did not fit
+** *p_cur_size is updated
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgReplacePayload (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ UINT8 *p_rec, UINT8 *p_new_pl, UINT32 new_pl_len)
+{
+ UINT32 prev_paylen;
+ UINT8 *p_prev_pl, *pp;
+ UINT32 paylen_delta;
+ UINT8 type_len, id_len;
+
+ /* Skip header */
+ pp = p_rec + 1;
+
+ /* Next byte is the type field length */
+ type_len = *pp++;
+
+ /* Next is the payload length (1 or 4 bytes) */
+ if (*p_rec & NDEF_SR_MASK)
+ prev_paylen = *pp++;
+ else
+ BE_STREAM_TO_UINT32 (prev_paylen, pp);
+
+ /* ID field Length */
+ if (*p_rec & NDEF_IL_MASK)
+ id_len = *pp++;
+ else
+ id_len = 0;
+
+ p_prev_pl = pp + type_len + id_len;
+
+ /* Point to payload length field again */
+ pp = p_rec + 2;
+
+ if (new_pl_len > prev_paylen)
+ {
+ /* New payload is larger than the previous */
+ paylen_delta = new_pl_len - prev_paylen;
+
+ /* If the previous payload length was < 256, and new is > 255 */
+ /* the payload length field goes from 1 byte to 4 bytes */
+ if ( (prev_paylen < 256) && (new_pl_len > 255) )
+ {
+ if ((*p_cur_size + paylen_delta + 3) > max_size)
+ return (NDEF_MSG_INSUFFICIENT_MEM);
+
+ shiftdown (pp + 1, (UINT32)(*p_cur_size - (pp - p_msg) - 1), 3);
+ p_prev_pl += 3;
+ *p_cur_size += 3;
+ *p_rec &= ~NDEF_SR_MASK;
+ }
+ else if ((*p_cur_size + paylen_delta) > max_size)
+ return (NDEF_MSG_INSUFFICIENT_MEM);
+
+ /* Store in the new length */
+ if (new_pl_len > 255)
+ {
+ UINT32_TO_BE_STREAM (pp, new_pl_len);
+ }
+ else
+ *pp = (UINT8)new_pl_len;
+
+ /* Point to the end of the previous payload */
+ pp = p_prev_pl + prev_paylen;
+
+ /* If we are not the last record, make space for the extra payload */
+ if ((*p_rec & NDEF_ME_MASK) == 0)
+ shiftdown (pp, (UINT32)(*p_cur_size - (pp - p_msg)), paylen_delta);
+
+ *p_cur_size += paylen_delta;
+ }
+ else if (new_pl_len < prev_paylen)
+ {
+ /* New payload is smaller than the previous */
+ paylen_delta = prev_paylen - new_pl_len;
+
+ /* If the previous payload was > 256, and new is less than 256 */
+ /* the payload length field goes from 4 bytes to 1 byte */
+ if ( (prev_paylen > 255) && (new_pl_len < 256) )
+ {
+ shiftup (pp + 1, pp + 4, (UINT32)(*p_cur_size - (pp - p_msg) - 3));
+ p_prev_pl -= 3;
+ *p_cur_size -= 3;
+ *p_rec |= NDEF_SR_MASK;
+ }
+
+ /* Store in the new length */
+ if (new_pl_len > 255)
+ {
+ UINT32_TO_BE_STREAM (pp, new_pl_len);
+ }
+ else
+ *pp = (UINT8)new_pl_len;
+
+ /* Point to the end of the previous payload */
+ pp = p_prev_pl + prev_paylen;
+
+ /* If we are not the last record, remove the extra space from the previous payload */
+ if ((*p_rec & NDEF_ME_MASK) == 0)
+ shiftup (pp - paylen_delta, pp, (UINT32)(*p_cur_size - (pp - p_msg)));
+
+ *p_cur_size -= paylen_delta;
+ }
+
+ /* Now copy in the new payload data */
+ if (p_new_pl)
+ memcpy (p_prev_pl, p_new_pl, new_pl_len);
+
+ return (NDEF_OK);
+}
+
+/*******************************************************************************
+**
+** Function NDEF_MsgReplaceType
+**
+** Description This function replaces the type field of a specific record in the
+** given NDEF message
+**
+** Returns OK, or error if the new type field did not fit
+** *p_cur_size is updated
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgReplaceType (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ UINT8 *p_rec, UINT8 *p_new_type, UINT8 new_type_len)
+{
+ UINT8 typelen_delta;
+ UINT8 *p_prev_type, prev_type_len;
+ UINT8 *pp;
+
+ /* Skip header */
+ pp = p_rec + 1;
+
+ /* Next byte is the type field length */
+ prev_type_len = *pp++;
+
+ /* Skip the payload length */
+ if (*p_rec & NDEF_SR_MASK)
+ pp += 1;
+ else
+ pp += 4;
+
+ if (*p_rec & NDEF_IL_MASK)
+ pp++;
+
+ /* Save pointer to the start of the type field */
+ p_prev_type = pp;
+
+ if (new_type_len > prev_type_len)
+ {
+ /* New type is larger than the previous */
+ typelen_delta = new_type_len - prev_type_len;
+
+ if ((*p_cur_size + typelen_delta) > max_size)
+ return (NDEF_MSG_INSUFFICIENT_MEM);
+
+ /* Point to the end of the previous type, and make space for the extra data */
+ pp = p_prev_type + prev_type_len;
+ shiftdown (pp, (UINT32)(*p_cur_size - (pp - p_msg)), typelen_delta);
+
+ *p_cur_size += typelen_delta;
+ }
+ else if (new_type_len < prev_type_len)
+ {
+ /* New type field is smaller than the previous */
+ typelen_delta = prev_type_len - new_type_len;
+
+ /* Point to the end of the previous type, and shift up to fill the the unused space */
+ pp = p_prev_type + prev_type_len;
+ shiftup (pp - typelen_delta, pp, (UINT32)(*p_cur_size - (pp - p_msg)));
+
+ *p_cur_size -= typelen_delta;
+ }
+
+ /* Save in new type length */
+ p_rec[1] = new_type_len;
+
+ /* Now copy in the new type field data */
+ if (p_new_type)
+ memcpy (p_prev_type, p_new_type, new_type_len);
+
+ return (NDEF_OK);
+}
+
+/*******************************************************************************
+**
+** Function NDEF_MsgReplaceId
+**
+** Description This function replaces the ID field of a specific record in the
+** given NDEF message
+**
+** Returns OK, or error if the new ID field did not fit
+** *p_cur_size is updated
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgReplaceId (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+ UINT8 *p_rec, UINT8 *p_new_id, UINT8 new_id_len)
+{
+ UINT8 idlen_delta;
+ UINT8 *p_prev_id, *p_idlen_field;
+ UINT8 prev_id_len, type_len;
+ UINT8 *pp;
+
+ /* Skip header */
+ pp = p_rec + 1;
+
+ /* Next byte is the type field length */
+ type_len = *pp++;
+
+ /* Skip the payload length */
+ if (*p_rec & NDEF_SR_MASK)
+ pp += 1;
+ else
+ pp += 4;
+
+ p_idlen_field = pp;
+
+ if (*p_rec & NDEF_IL_MASK)
+ prev_id_len = *pp++;
+ else
+ prev_id_len = 0;
+
+ /* Save pointer to the start of the ID field (right after the type field) */
+ p_prev_id = pp + type_len;
+
+ if (new_id_len > prev_id_len)
+ {
+ /* New ID field is larger than the previous */
+ idlen_delta = new_id_len - prev_id_len;
+
+ /* If the previous ID length was 0, we need to add a 1-byte ID length */
+ if (prev_id_len == 0)
+ {
+ if ((*p_cur_size + idlen_delta + 1) > max_size)
+ return (NDEF_MSG_INSUFFICIENT_MEM);
+
+ shiftdown (p_idlen_field, (UINT32)(*p_cur_size - (p_idlen_field - p_msg)), 1);
+ p_prev_id += 1;
+ *p_cur_size += 1;
+ *p_rec |= NDEF_IL_MASK;
+ }
+ else if ((*p_cur_size + idlen_delta) > max_size)
+ return (NDEF_MSG_INSUFFICIENT_MEM);
+
+ /* Point to the end of the previous ID field, and make space for the extra data */
+ pp = p_prev_id + prev_id_len;
+ shiftdown (pp, (UINT32)(*p_cur_size - (pp - p_msg)), idlen_delta);
+
+ *p_cur_size += idlen_delta;
+ }
+ else if (new_id_len < prev_id_len)
+ {
+ /* New ID field is smaller than the previous */
+ idlen_delta = prev_id_len - new_id_len;
+
+ /* Point to the end of the previous ID, and shift up to fill the the unused space */
+ pp = p_prev_id + prev_id_len;
+ shiftup (pp - idlen_delta, pp, (UINT32)(*p_cur_size - (pp - p_msg)));
+
+ *p_cur_size -= idlen_delta;
+
+ /* If removing the ID, make sure that length field is also removed */
+ if (new_id_len == 0)
+ {
+ shiftup (p_idlen_field, p_idlen_field + 1, (UINT32)(*p_cur_size - (p_idlen_field - p_msg - (UINT32)1)));
+ *p_rec &= ~NDEF_IL_MASK;
+ *p_cur_size -= 1;
+ }
+ }
+
+ /* Save in new ID length and data */
+ if (new_id_len)
+ {
+ *p_idlen_field = new_id_len;
+
+ if (p_new_id)
+ memcpy (p_prev_id, p_new_id, new_id_len);
+ }
+
+ return (NDEF_OK);
+}
+
+/*******************************************************************************
+**
+** Function NDEF_MsgRemoveRec
+**
+** Description This function removes the record at the given
+** index in the given NDEF message.
+**
+** Returns TRUE if OK, FALSE if the index was invalid
+** *p_cur_size is updated
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgRemoveRec (UINT8 *p_msg, UINT32 *p_cur_size, INT32 index)
+{
+ UINT8 *p_rec = NDEF_MsgGetRecByIndex (p_msg, index);
+ UINT8 *pNext, *pPrev;
+
+ if (!p_rec)
+ return (NDEF_REC_NOT_FOUND);
+
+ /* If this is the first record in the message... */
+ if (*p_rec & NDEF_MB_MASK)
+ {
+ /* Find the second record (if any) and set his 'Message Begin' bit */
+ if ((pNext = NDEF_MsgGetRecByIndex(p_msg, 1)) != NULL)
+ {
+ *pNext |= NDEF_MB_MASK;
+
+ *p_cur_size -= (UINT32)(pNext - p_msg);
+
+ shiftup (p_msg, pNext, *p_cur_size);
+ }
+ else
+ *p_cur_size = 0; /* No more records, lenght must be zero */
+
+ return (NDEF_OK);
+ }
+
+ /* If this is the last record in the message... */
+ if (*p_rec & NDEF_ME_MASK)
+ {
+ if (index > 0)
+ {
+ /* Find the previous record and set his 'Message End' bit */
+ if ((pPrev = NDEF_MsgGetRecByIndex(p_msg, index - 1)) == NULL)
+ return (FALSE);
+
+ *pPrev |= NDEF_ME_MASK;
+ }
+ *p_cur_size = (UINT32)(p_rec - p_msg);
+
+ return (NDEF_OK);
+ }
+
+ /* Not the first or the last... get the address of the next record */
+ if ((pNext = NDEF_MsgGetNextRec (p_rec)) == NULL)
+ return (FALSE);
+
+ /* We are removing p_rec, so shift from pNext to the end */
+ shiftup (p_rec, pNext, (UINT32)(*p_cur_size - (pNext - p_msg)));
+
+ *p_cur_size -= (UINT32)(pNext - p_rec);
+
+ return (NDEF_OK);
+}
+
+
+/*******************************************************************************
+**
+** Function NDEF_MsgCopyAndDechunk
+**
+** Description This function copies and de-chunks an NDEF message.
+** It is assumed that the destination is at least as large
+** as the source, since the source may not actually contain
+** any chunks.
+**
+** Returns The output byte count
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgCopyAndDechunk (UINT8 *p_src, UINT32 src_len, UINT8 *p_dest, UINT32 *p_out_len)
+{
+ UINT32 out_len, max_out_len;
+ UINT8 *p_rec;
+ UINT8 *p_prev_rec = p_dest;
+ UINT8 *p_type, *p_id, *p_pay;
+ UINT8 type_len, id_len, tnf;
+ UINT32 pay_len;
+ tNDEF_STATUS status;
+
+ /* First, validate the source */
+ if ((status = NDEF_MsgValidate(p_src, src_len, TRUE)) != NDEF_OK)
+ return (status);
+
+ /* The output buffer must be at least as large as the input buffer */
+ max_out_len = src_len;
+
+ /* Initialize output */
+ NDEF_MsgInit (p_dest, max_out_len, &out_len);
+
+ p_rec = p_src;
+
+ /* Now, copy record by record */
+ while ((p_rec != NULL) && (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..50294a9
--- /dev/null
+++ b/src/nfc/nfc/nfc_ee.c
@@ -0,0 +1,125 @@
+/******************************************************************************
+ *
+ * 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"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_api.h"
+#include "nfc_int.h"
+#include "nci_hmsgs.h"
+
+
+/*******************************************************************************
+**
+** Function NFC_NfceeDiscover
+**
+** Description This function is called to enable or disable NFCEE Discovery.
+** The response from NFCC is reported by tNFC_RESPONSE_CBACK
+** as NFC_NFCEE_DISCOVER_REVT.
+** The notification from NFCC is reported by tNFC_RESPONSE_CBACK
+** as NFC_NFCEE_INFO_REVT.
+**
+** Parameters discover - 1 to enable discover, 0 to disable.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_NfceeDiscover (BOOLEAN discover)
+{
+ return nci_snd_nfcee_discover ((UINT8) (discover ? NCI_DISCOVER_ACTION_ENABLE : NCI_DISCOVER_ACTION_DISABLE));
+}
+
+/*******************************************************************************
+**
+** Function NFC_NfceeModeSet
+**
+** Description This function is called to activate or de-activate an NFCEE
+** connected to the NFCC.
+** The response from NFCC is reported by tNFC_RESPONSE_CBACK
+** as NFC_NFCEE_MODE_SET_REVT.
+**
+** Parameters nfcee_id - the NFCEE to activate or de-activate.
+** mode - NFC_MODE_ACTIVATE to activate NFCEE,
+** NFC_MODE_DEACTIVATE to de-activate.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_NfceeModeSet (UINT8 nfcee_id,
+ tNFC_NFCEE_MODE mode)
+{
+ if (mode >= NCI_NUM_NFCEE_MODE)
+ {
+ NFC_TRACE_ERROR1 ("NFC_NfceeModeSet bad mode:%d", mode);
+ return NFC_STATUS_FAILED;
+ }
+
+ return nci_snd_nfcee_mode_set (nfcee_id, mode);
+}
+
+
+
+
+/*******************************************************************************
+**
+** Function NFC_SetRouting
+**
+** Description This function is called to configure the CE routing table.
+** The response from NFCC is reported by tNFC_RESPONSE_CBACK
+** as NFC_SET_ROUTING_REVT.
+**
+** Parameters
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_SetRouting (BOOLEAN more,
+ UINT8 num_tlv,
+ UINT8 tlv_size,
+ UINT8 *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 ();
+}
+
+
+#endif /* NFC_INCLUDED == TRUE */
diff --git a/src/nfc/nfc/nfc_main.c b/src/nfc/nfc/nfc_main.c
new file mode 100644
index 0000000..049534d
--- /dev/null
+++ b/src/nfc/nfc/nfc_main.c
@@ -0,0 +1,1594 @@
+/******************************************************************************
+ *
+ * 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 interface with the NFC NCI transport.
+ * On the receive side, it routes events to the appropriate handler
+ * (callback). On the transmit side, it manages the command transmission.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "gki.h"
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "hcidefs.h"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_hal_api.h"
+#include "nfc_api.h"
+#include "nfc_int.h"
+#include "nci_hmsgs.h"
+#include "rw_int.h"
+#include "ce_int.h"
+
+
+#if (NFC_RW_ONLY == FALSE)
+#include "ce_api.h"
+#include "ce_int.h"
+#include "llcp_int.h"
+
+/* NFC mandates support for at least one logical connection;
+ * Update max_conn to the NFCC capability on InitRsp */
+#define NFC_SET_MAX_CONN_DEFAULT() {nfc_cb.max_conn = 1;}
+
+#else /* NFC_RW_ONLY */
+#define ce_init()
+#define llcp_init()
+
+#define NFC_SET_MAX_CONN_DEFAULT()
+
+#endif /* NFC_RW_ONLY */
+/****************************************************************************
+** Declarations
+****************************************************************************/
+#if NFC_DYNAMIC_MEMORY == FALSE
+tNFC_CB nfc_cb;
+#endif
+UINT8 i2c_fragmentation_enabled = 0xff;
+#if (NFC_RW_ONLY == FALSE)
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+#define NFC_NUM_INTERFACE_MAP 4
+#else
+#define NFC_NUM_INTERFACE_MAP 3
+#endif
+#else
+#define NFC_NUM_INTERFACE_MAP 3
+#endif
+#else
+#define NFC_NUM_INTERFACE_MAP 1
+#endif
+
+static const tNCI_DISCOVER_MAPS nfc_interface_mapping[NFC_NUM_INTERFACE_MAP] =
+{
+ /* Protocols that use Frame Interface do not need to be included in the interface mapping */
+ {
+ NCI_PROTOCOL_ISO_DEP,
+ NCI_INTERFACE_MODE_POLL_N_LISTEN,
+ NCI_INTERFACE_ISO_DEP
+ }
+#if (NFC_RW_ONLY == FALSE)
+ ,
+ /* this can not be set here due to 2079xB0 NFCC issues */
+ {
+ NCI_PROTOCOL_NFC_DEP,
+ NCI_INTERFACE_MODE_POLL_N_LISTEN,
+ NCI_INTERFACE_NFC_DEP
+ }
+#endif
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ ,
+ {
+ NCI_PROTOCOL_MIFARE,
+ NCI_INTERFACE_MODE_POLL,
+ NCI_INTERFACE_MIFARE
+ }
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+ ,
+ /* This mapping is for Felica on DH */
+ {
+ NCI_PROTOCOL_T3T,
+ NCI_INTERFACE_MODE_LISTEN,
+ NCI_INTERFACE_FRAME
+ }
+#endif
+#endif
+};
+
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function nfc_state_name
+**
+** Description This function returns the state name.
+**
+** NOTE conditionally compiled to save memory.
+**
+** Returns pointer to the name
+**
+*******************************************************************************/
+static char *nfc_state_name (UINT8 state)
+{
+ switch (state)
+ {
+ case NFC_STATE_NONE:
+ return ("NONE");
+ case NFC_STATE_W4_HAL_OPEN:
+ return ("W4_HAL_OPEN");
+ case NFC_STATE_CORE_INIT:
+ return ("CORE_INIT");
+ case NFC_STATE_W4_POST_INIT_CPLT:
+ return ("W4_POST_INIT_CPLT");
+ case NFC_STATE_IDLE:
+ return ("IDLE");
+ case NFC_STATE_OPEN:
+ return ("OPEN");
+ case NFC_STATE_CLOSING:
+ return ("CLOSING");
+ case NFC_STATE_W4_HAL_CLOSE:
+ return ("W4_HAL_CLOSE");
+ case NFC_STATE_NFCC_POWER_OFF_SLEEP:
+ return ("NFCC_POWER_OFF_SLEEP");
+ default:
+ return ("???? UNKNOWN STATE");
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_event_name
+**
+** Description This function returns the HAL event name.
+**
+** NOTE conditionally compiled to save memory.
+**
+** Returns pointer to the name
+**
+*******************************************************************************/
+static char *nfc_hal_event_name (UINT8 event)
+{
+ switch (event)
+ {
+ case HAL_NFC_OPEN_CPLT_EVT:
+ return ("HAL_NFC_OPEN_CPLT_EVT");
+
+ case HAL_NFC_CLOSE_CPLT_EVT:
+ return ("HAL_NFC_CLOSE_CPLT_EVT");
+
+ case HAL_NFC_POST_INIT_CPLT_EVT:
+ return ("HAL_NFC_POST_INIT_CPLT_EVT");
+
+ case HAL_NFC_PRE_DISCOVER_CPLT_EVT:
+ return ("HAL_NFC_PRE_DISCOVER_CPLT_EVT");
+
+ case HAL_NFC_REQUEST_CONTROL_EVT:
+ return ("HAL_NFC_REQUEST_CONTROL_EVT");
+
+ case HAL_NFC_RELEASE_CONTROL_EVT:
+ return ("HAL_NFC_RELEASE_CONTROL_EVT");
+
+ case HAL_NFC_ERROR_EVT:
+ return ("HAL_NFC_ERROR_EVT");
+
+ 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, BT_HDR *p_init_rsp_msg)
+{
+ tNFC_RESPONSE evt_data;
+ tNFC_CONN_CB *p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+ UINT8 *p;
+ UINT8 num_interfaces = 0, xx;
+ int yy = 0;
+
+ memset (&evt_data, 0, sizeof (tNFC_RESPONSE));
+
+ if (nfc_status == NCI_STATUS_OK)
+ {
+ nfc_set_state (NFC_STATE_IDLE);
+
+ p = (UINT8 *) (p_init_rsp_msg + 1) + p_init_rsp_msg->offset + NCI_MSG_HDR_SIZE + 1;
+ /* we currently only support NCI of the same version.
+ * We may need to change this, when we support multiple version of NFCC */
+ evt_data.enable.nci_version = NCI_VERSION;
+ STREAM_TO_UINT32 (evt_data.enable.nci_features, p);
+ STREAM_TO_UINT8 (num_interfaces, p);
+
+ evt_data.enable.nci_interfaces = 0;
+ for (xx = 0; xx < num_interfaces; xx++)
+ {
+ if ((*p) <= NCI_INTERFACE_MAX)
+ evt_data.enable.nci_interfaces |= (1 << (*p));
+ #if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ else if (((*p) >= NCI_INTERFACE_FIRST_VS) && (yy < NFC_NFCC_MAX_NUM_VS_INTERFACE))
+ #else
+ else if (((*p) > NCI_INTERFACE_FIRST_VS) && (yy < NFC_NFCC_MAX_NUM_VS_INTERFACE))
+ #endif
+ {
+ /* save the VS RF interface in control block, if there's still room */
+ nfc_cb.vs_interface[yy++] = *p;
+ }
+ p++;
+ }
+ nfc_cb.nci_interfaces = evt_data.enable.nci_interfaces;
+ memcpy (evt_data.enable.vs_interface, nfc_cb.vs_interface, NFC_NFCC_MAX_NUM_VS_INTERFACE);
+ evt_data.enable.max_conn = *p++;
+ STREAM_TO_UINT16 (evt_data.enable.max_ce_table, p);
+#if (NFC_RW_ONLY == FALSE)
+ nfc_cb.max_ce_table = evt_data.enable.max_ce_table;
+ nfc_cb.nci_features = evt_data.enable.nci_features;
+ nfc_cb.max_conn = evt_data.enable.max_conn;
+#endif
+ nfc_cb.nci_ctrl_size = *p++; /* Max Control Packet Payload Length */
+ p_cb->init_credits = p_cb->num_buff = 0;
+ STREAM_TO_UINT16 (evt_data.enable.max_param_size, p);
+ nfc_set_conn_id (p_cb, NFC_RF_CONN_ID);
+ evt_data.enable.manufacture_id = *p++;
+ STREAM_TO_ARRAY (evt_data.enable.nfcc_info, p, NFC_NFCC_INFO_LEN);
+ NFC_DiscoveryMap (nfc_cb.num_disc_maps, (tNCI_DISCOVER_MAPS *) nfc_cb.p_disc_maps, NULL);
+ }
+ /* else not successful. the buffers will be freed in nfc_free_conn_cb () */
+ else
+ {
+ if (nfc_cb.flags & NFC_FL_RESTARTING)
+ {
+ nfc_set_state (NFC_STATE_NFCC_POWER_OFF_SLEEP);
+ }
+ else
+ {
+ nfc_free_conn_cb (p_cb);
+
+ /* if NFCC didn't respond to CORE_RESET or CORE_INIT */
+ if (nfc_cb.nfc_state == NFC_STATE_CORE_INIT)
+ {
+ /* report status after closing HAL */
+ nfc_cb.p_hal->close ();
+ return;
+ }
+ else
+ nfc_set_state (NFC_STATE_NONE);
+ }
+ }
+
+ nfc_main_notify_enable_status (nfc_status);
+}
+
+/*******************************************************************************
+**
+** Function nfc_set_state
+**
+** Description Set the state of NFC stack
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_set_state (tNFC_STATE nfc_state)
+{
+#if (BT_TRACE_VERBOSE == TRUE)
+ NFC_TRACE_DEBUG4 ("nfc_set_state %d (%s)->%d (%s)", nfc_cb.nfc_state, nfc_state_name (nfc_cb.nfc_state), nfc_state, nfc_state_name (nfc_state));
+#else
+ NFC_TRACE_DEBUG2 ("nfc_set_state %d->%d", nfc_cb.nfc_state, nfc_state);
+#endif
+ nfc_cb.nfc_state = nfc_state;
+}
+
+/*******************************************************************************
+**
+** Function nfc_gen_cleanup
+**
+** Description Clean up for both going into low power mode and disabling NFC
+**
+*******************************************************************************/
+void nfc_gen_cleanup (void)
+{
+ nfc_cb.flags &= ~NFC_FL_DEACTIVATING;
+
+ /* the HAL pre-discover is still active - clear the pending flag/free the buffer */
+ if (nfc_cb.flags & NFC_FL_DISCOVER_PENDING)
+ {
+ nfc_cb.flags &= ~NFC_FL_DISCOVER_PENDING;
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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;
+ }
+
+ /* clear any pending CMD/RSP */
+ nfc_main_flush_cmd_queue ();
+}
+
+/*******************************************************************************
+**
+** Function nfc_main_handle_hal_evt
+**
+** Description Handle BT_EVT_TO_NFC_MSGS
+**
+*******************************************************************************/
+void nfc_main_handle_hal_evt (tNFC_HAL_EVT_MSG *p_msg)
+{
+ UINT8 *ps;
+
+ NFC_TRACE_DEBUG1 ("nfc_main_handle_hal_evt(): HAL event=0x%x", p_msg->hal_evt);
+
+ switch (p_msg->hal_evt)
+ {
+ case HAL_NFC_OPEN_CPLT_EVT: /* only for failure case */
+ nfc_enabled (NFC_STATUS_FAILED, NULL);
+ break;
+
+ case HAL_NFC_CLOSE_CPLT_EVT:
+ if (nfc_cb.p_resp_cback)
+ {
+ if (nfc_cb.nfc_state == NFC_STATE_W4_HAL_CLOSE)
+ {
+ if (nfc_cb.flags & NFC_FL_POWER_OFF_SLEEP)
+ {
+ nfc_cb.flags &= ~NFC_FL_POWER_OFF_SLEEP;
+ nfc_set_state (NFC_STATE_NFCC_POWER_OFF_SLEEP);
+ (*nfc_cb.p_resp_cback) (NFC_NFCC_POWER_OFF_REVT, NULL);
+ }
+ else
+ {
+ nfc_set_state (NFC_STATE_NONE);
+ (*nfc_cb.p_resp_cback) (NFC_DISABLE_REVT, NULL);
+ nfc_cb.p_resp_cback = NULL;
+ }
+ }
+ else
+ {
+ /* found error during initialization */
+ nfc_set_state (NFC_STATE_NONE);
+ nfc_main_notify_enable_status (NFC_STATUS_FAILED);
+ }
+ }
+ break;
+
+ case HAL_NFC_POST_INIT_CPLT_EVT:
+ if (nfc_cb.p_nci_init_rsp)
+ {
+ /*
+ ** if NFC_Disable() is called before receiving HAL_NFC_POST_INIT_CPLT_EVT,
+ ** then wait for HAL_NFC_CLOSE_CPLT_EVT.
+ */
+ if (nfc_cb.nfc_state == NFC_STATE_W4_POST_INIT_CPLT)
+ {
+ if (p_msg->status == HAL_NFC_STATUS_OK)
+ {
+ nfc_enabled (NCI_STATUS_OK, nfc_cb.p_nci_init_rsp);
+ }
+ else /* if post initailization failed */
+ {
+ nfc_enabled (NCI_STATUS_FAILED, NULL);
+ }
+ }
+
+ GKI_freebuf (nfc_cb.p_nci_init_rsp);
+ nfc_cb.p_nci_init_rsp = NULL;
+ }
+ break;
+
+ case HAL_NFC_PRE_DISCOVER_CPLT_EVT:
+ /* restore the command window, no matter if the discover command is still pending */
+ nfc_cb.nci_cmd_window = NCI_MAX_CMD_WINDOW;
+ nfc_cb.flags &= ~NFC_FL_CONTROL_GRANTED;
+ if (nfc_cb.flags & NFC_FL_DISCOVER_PENDING)
+ {
+ /* issue the discovery command now, if it is still pending */
+ nfc_cb.flags &= ~NFC_FL_DISCOVER_PENDING;
+ ps = (UINT8 *)nfc_cb.p_disc_pending;
+ nci_snd_discover_cmd (*ps, (tNFC_DISCOVER_PARAMS *)(ps + 1));
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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;
+
+ default:
+ NFC_TRACE_ERROR1 ("nfc_main_handle_hal_evt (): unhandled event (0x%x).", p_msg->hal_evt);
+ break;
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function nfc_main_flush_cmd_queue
+**
+** Description This function is called when setting power off sleep state.
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_main_flush_cmd_queue (void)
+{
+ BT_HDR *p_msg;
+
+ NFC_TRACE_DEBUG0 ("nfc_main_flush_cmd_queue ()");
+
+ /* initialize command window */
+ nfc_cb.nci_cmd_window = NCI_MAX_CMD_WINDOW;
+
+ /* Stop command-pending timer */
+ nfc_stop_timer(&nfc_cb.nci_wait_rsp_timer);
+
+ /* dequeue and free buffer */
+ while ((p_msg = (BT_HDR *)GKI_dequeue (&nfc_cb.nci_cmd_xmit_q)) != NULL)
+ {
+ GKI_freebuf (p_msg);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_main_post_hal_evt
+**
+** Description This function posts HAL event to NFC_TASK
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_main_post_hal_evt (UINT8 hal_evt, tHAL_NFC_STATUS status)
+{
+ tNFC_HAL_EVT_MSG *p_msg;
+
+ if ((p_msg = (tNFC_HAL_EVT_MSG *) GKI_getbuf (sizeof(tNFC_HAL_EVT_MSG))) != NULL)
+ {
+ /* Initialize BT_HDR */
+ p_msg->hdr.len = 0;
+ p_msg->hdr.event = BT_EVT_TO_NFC_MSGS;
+ p_msg->hdr.offset = 0;
+ p_msg->hdr.layer_specific = 0;
+ p_msg->hal_evt = hal_evt;
+ p_msg->status = status;
+ GKI_send_msg (NFC_TASK, NFC_MBOX_ID, p_msg);
+ }
+ else
+ {
+ NFC_TRACE_ERROR0 ("nfc_main_post_hal_evt (): No buffer");
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function nfc_main_hal_cback
+**
+** Description HAL event handler
+**
+** Returns void
+**
+*******************************************************************************/
+static void nfc_main_hal_cback(UINT8 event, tHAL_NFC_STATUS status)
+{
+#if (BT_TRACE_VERBOSE == TRUE)
+ NFC_TRACE_DEBUG3 ("nfc_main_hal_cback event: %s(0x%x), status=%d",
+ nfc_hal_event_name (event), event, status);
+#else
+ NFC_TRACE_DEBUG2 ("nfc_main_hal_cback event: 0x%x, status=%d", event, status);
+#endif
+
+ switch (event)
+ {
+ case HAL_NFC_OPEN_CPLT_EVT:
+ /*
+ ** if NFC_Disable() is called before receiving HAL_NFC_OPEN_CPLT_EVT,
+ ** then wait for HAL_NFC_CLOSE_CPLT_EVT.
+ */
+ if (nfc_cb.nfc_state == NFC_STATE_W4_HAL_OPEN)
+ {
+ if (status == HAL_NFC_STATUS_OK)
+ {
+ /* Notify NFC_TASK that NCI tranport is initialized */
+ GKI_send_event (NFC_TASK, NFC_TASK_EVT_TRANSPORT_READY);
+ }
+ else
+ {
+ nfc_main_post_hal_evt (event, status);
+ }
+ }
+ break;
+
+ case HAL_NFC_CLOSE_CPLT_EVT:
+ case HAL_NFC_POST_INIT_CPLT_EVT:
+ case HAL_NFC_PRE_DISCOVER_CPLT_EVT:
+ case HAL_NFC_REQUEST_CONTROL_EVT:
+ case HAL_NFC_RELEASE_CONTROL_EVT:
+ case HAL_NFC_ERROR_EVT:
+ nfc_main_post_hal_evt (event, status);
+ break;
+ 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 data_len, UINT8 *p_data)
+{
+ BT_HDR *p_msg;
+
+ /* ignore all data while shutting down NFCC */
+ if (nfc_cb.nfc_state == NFC_STATE_W4_HAL_CLOSE)
+ {
+ return;
+ }
+
+ if (p_data)
+ {
+ if ((p_msg = (BT_HDR *) GKI_getpoolbuf (NFC_NCI_POOL_ID)) != NULL)
+ {
+ /* Initialize BT_HDR */
+ p_msg->len = data_len;
+ p_msg->event = BT_EVT_TO_NFC_NCI;
+ p_msg->offset = NFC_RECEIVE_MSGS_OFFSET;
+
+ /* no need to check length, it always less than pool size */
+ memcpy ((UINT8 *)(p_msg + 1) + p_msg->offset, p_data, p_msg->len);
+
+ GKI_send_msg (NFC_TASK, NFC_MBOX_ID, p_msg);
+ }
+ else
+ {
+ NFC_TRACE_ERROR0 ("nfc_main_hal_data_cback (): No buffer");
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function NFC_Enable
+**
+** Description This function enables NFC. Prior to calling NFC_Enable:
+** - the NFCC must be powered up, and ready to receive commands.
+** - GKI must be enabled
+** - NFC_TASK must be started
+** - NCIT_TASK must be started (if using dedicated NCI transport)
+**
+** This function opens the NCI transport (if applicable),
+** resets the NFC controller, and initializes the NFC subsystems.
+**
+** When the NFC startup procedure is completed, an
+** NFC_ENABLE_REVT is returned to the application using the
+** tNFC_RESPONSE_CBACK.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_Enable (tNFC_RESPONSE_CBACK *p_cback)
+{
+ NFC_TRACE_API0 ("NFC_Enable ()");
+
+ /* Validate callback */
+ if (!p_cback)
+ {
+ return (NFC_STATUS_INVALID_PARAM);
+ }
+ nfc_cb.p_resp_cback = p_cback;
+
+ /* Open HAL transport. */
+ nfc_set_state (NFC_STATE_W4_HAL_OPEN);
+ nfc_cb.p_hal->open (nfc_main_hal_cback, nfc_main_hal_data_cback);
+
+ return (NFC_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function NFC_Disable
+**
+** Description This function performs clean up routines for shutting down
+** NFC and closes the NCI transport (if using dedicated NCI
+** transport).
+**
+** When the NFC shutdown procedure is completed, an
+** NFC_DISABLED_REVT is returned to the application using the
+** tNFC_RESPONSE_CBACK.
+**
+** Returns nothing
+**
+*******************************************************************************/
+void NFC_Disable (void)
+{
+ NFC_TRACE_API1 ("NFC_Disable (): nfc_state = %d", nfc_cb.nfc_state);
+
+ if ((nfc_cb.nfc_state == NFC_STATE_NONE) || (nfc_cb.nfc_state == NFC_STATE_NFCC_POWER_OFF_SLEEP))
+ {
+ nfc_set_state (NFC_STATE_NONE);
+ if (nfc_cb.p_resp_cback)
+ {
+ (*nfc_cb.p_resp_cback) (NFC_DISABLE_REVT, NULL);
+ nfc_cb.p_resp_cback = NULL;
+ }
+ return;
+ }
+
+ /* Close transport and clean up */
+ nfc_task_shutdown_nfcc ();
+}
+
+/*******************************************************************************
+**
+** Function NFC_Init
+**
+** Description This function initializes control block for NFC
+**
+** Returns nothing
+**
+*******************************************************************************/
+void NFC_Init (tHAL_NFC_ENTRY *p_hal_entry_tbl)
+{
+ int xx;
+
+ /* Clear nfc control block */
+ memset (&nfc_cb, 0, sizeof (tNFC_CB));
+
+ /* Reset the nfc control block */
+ for (xx = 0; xx < NCI_MAX_CONN_CBS; xx++)
+ {
+ nfc_cb.conn_cb[xx].conn_id = NFC_ILLEGAL_CONN_ID;
+ }
+
+ /* NCI init */
+ nfc_cb.p_hal = p_hal_entry_tbl;
+ nfc_cb.nfc_state = NFC_STATE_NONE;
+ nfc_cb.nci_cmd_window = NCI_MAX_CMD_WINDOW;
+ nfc_cb.nci_wait_rsp_tout= NFC_CMD_CMPL_TIMEOUT;
+ nfc_cb.p_disc_maps = nfc_interface_mapping;
+ nfc_cb.num_disc_maps = NFC_NUM_INTERFACE_MAP;
+ nfc_cb.trace_level = NFC_INITIAL_TRACE_LEVEL;
+ nfc_cb.nci_ctrl_size = NCI_CTRL_INIT_SIZE;
+ nfc_cb.reassembly = TRUE;
+
+ rw_init ();
+ ce_init ();
+ llcp_init ();
+ NFC_SET_MAX_CONN_DEFAULT ();
+}
+
+/*******************************************************************************
+**
+** Function NFC_GetLmrtSize
+**
+** Description Called by application wto query the Listen Mode Routing
+** Table size supported by NFCC
+**
+** Returns Listen Mode Routing Table size
+**
+*******************************************************************************/
+UINT16 NFC_GetLmrtSize (void)
+{
+ UINT16 size = 0;
+#if (NFC_RW_ONLY == FALSE)
+ size = nfc_cb.max_ce_table;
+#endif
+ return size;
+}
+
+
+/*******************************************************************************
+**
+** Function NFC_SetConfig
+**
+** Description This function is called to send the configuration parameter
+** TLV to NFCC. The response from NFCC is reported by
+** tNFC_RESPONSE_CBACK as NFC_SET_CONFIG_REVT.
+**
+** Parameters tlv_size - the length of p_param_tlvs.
+** p_param_tlvs - the parameter ID/Len/Value list
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_SetConfig (UINT8 tlv_size,
+ UINT8 *p_param_tlvs)
+{
+ return nci_snd_core_set_config (p_param_tlvs, tlv_size);
+}
+
+/*******************************************************************************
+**
+** Function NFC_GetConfig
+**
+** Description This function is called to retrieve the parameter TLV from NFCC.
+** The response from NFCC is reported by tNFC_RESPONSE_CBACK
+** as NFC_GET_CONFIG_REVT.
+**
+** Parameters num_ids - the number of parameter IDs
+** p_param_ids - the parameter ID list.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_GetConfig (UINT8 num_ids,
+ UINT8 *p_param_ids)
+{
+ return nci_snd_core_get_config (p_param_ids, num_ids);
+}
+
+/*******************************************************************************
+**
+** Function NFC_DiscoveryMap
+**
+** Description This function is called to set the discovery interface mapping.
+** The response from NFCC is reported by tNFC_DISCOVER_CBACK as.
+** NFC_MAP_DEVT.
+**
+** Parameters num - the number of items in p_params.
+** p_maps - the discovery interface mappings
+** p_cback - the discovery callback function
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_DiscoveryMap (UINT8 num, tNFC_DISCOVER_MAPS *p_maps,
+ tNFC_DISCOVER_CBACK *p_cback)
+{
+ UINT8 num_disc_maps = num;
+ UINT8 xx, yy, num_intf, intf_mask;
+ tNFC_DISCOVER_MAPS max_maps[NFC_NFCC_MAX_NUM_VS_INTERFACE + NCI_INTERFACE_MAX];
+ BOOLEAN is_supported;
+ #if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ nfc_cb.num_disc_maps = num;
+ #endif
+ nfc_cb.p_discv_cback = p_cback;
+ num_intf = 0;
+ NFC_TRACE_DEBUG1 ("nci_interfaces supported by NFCC: 0x%x", nfc_cb.nci_interfaces);
+
+ for(xx = 0; xx < 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 (nfc_cb.vs_interface[yy] == p_maps[xx].intf_type)
+ is_supported = TRUE;
+ }
+ NFC_TRACE_DEBUG3 ("[%d]: vs intf_type:0x%x is_supported:%d", xx, p_maps[xx].intf_type, is_supported);
+ }
+ else
+ {
+ intf_mask = (1 << (p_maps[xx].intf_type));
+ if (intf_mask & nfc_cb.nci_interfaces)
+ {
+ is_supported = TRUE;
+ }
+ NFC_TRACE_DEBUG4 ("[%d]: intf_type:%d intf_mask: 0x%x is_supported:%d", xx, p_maps[xx].intf_type, intf_mask, is_supported);
+ }
+ if (is_supported)
+ memcpy (&max_maps[num_intf++], &p_maps[xx], sizeof (tNFC_DISCOVER_MAPS));
+ else
+ {
+ NFC_TRACE_WARNING1 ("NFC_DiscoveryMap interface=0x%x is not supported by NFCC", p_maps[xx].intf_type);
+ }
+ }
+
+ 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 num_params,
+ tNFC_DISCOVER_PARAMS *p_params,
+ tNFC_DISCOVER_CBACK *p_cback)
+{
+ UINT8 *p;
+ int params_size;
+ tNFC_STATUS status = NFC_STATUS_NO_BUFFERS;
+
+ NFC_TRACE_API0 ("NFC_DiscoveryStart");
+ if (nfc_cb.p_disc_pending)
+ {
+ NFC_TRACE_ERROR0 ("There's pending NFC_DiscoveryStart");
+ status = NFC_STATUS_BUSY;
+ }
+ else
+ {
+ nfc_cb.p_discv_cback = p_cback;
+ nfc_cb.flags |= NFC_FL_DISCOVER_PENDING;
+ nfc_cb.flags |= NFC_FL_CONTROL_REQUESTED;
+ params_size = sizeof (tNFC_DISCOVER_PARAMS) * num_params;
+ nfc_cb.p_disc_pending = GKI_getbuf ((UINT16)(BT_HDR_SIZE + 1 + params_size));
+ if (nfc_cb.p_disc_pending)
+ {
+ p = (UINT8 *)nfc_cb.p_disc_pending;
+ *p++ = num_params;
+ memcpy (p, p_params, params_size);
+ status = NFC_STATUS_CMD_STARTED;
+ nfc_ncif_check_cmd_queue (NULL);
+ }
+ }
+
+ NFC_TRACE_API1 ("NFC_DiscoveryStart status: 0x%x", status);
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function NFC_DiscoverySelect
+**
+** Description If tNFC_DISCOVER_CBACK reports status=NFC_MULTIPLE_PROT,
+** the application needs to use this function to select the
+** the logical endpoint to continue. The response from NFCC is
+** reported by tNFC_DISCOVER_CBACK as NFC_SELECT_DEVT.
+**
+** Parameters rf_disc_id - The ID identifies the remote device.
+** protocol - the logical endpoint on the remote devide
+** rf_interface - the RF interface to communicate with NFCC
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_DiscoverySelect (UINT8 rf_disc_id,
+ UINT8 protocol,
+ UINT8 rf_interface)
+{
+ return nci_snd_discover_select_cmd (rf_disc_id, protocol, rf_interface);
+}
+
+/*******************************************************************************
+**
+** Function NFC_ConnCreate
+**
+** Description This function is called to create a logical connection with
+** NFCC for data exchange.
+**
+** Parameters dest_type - the destination type
+** id - the NFCEE ID or RF Discovery ID .
+** protocol - the protocol.
+** p_cback - the connection callback function
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_ConnCreate (UINT8 dest_type,
+ UINT8 id,
+ UINT8 protocol,
+ tNFC_CONN_CBACK *p_cback)
+{
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ tNFC_CONN_CB *p_cb;
+ UINT8 num_tlv=0, tlv_size=0;
+ UINT8 param_tlvs[4], *pp;
+
+ p_cb = nfc_alloc_conn_cb (p_cback);
+ if (p_cb)
+ {
+ p_cb->id = id;
+ pp = param_tlvs;
+ if (dest_type == NCI_DEST_TYPE_NFCEE)
+ {
+ num_tlv = 1;
+ UINT8_TO_STREAM (pp, NCI_CON_CREATE_TAG_NFCEE_VAL);
+ UINT8_TO_STREAM (pp, 2);
+ UINT8_TO_STREAM (pp, id);
+ UINT8_TO_STREAM (pp, protocol);
+ tlv_size = 4;
+ }
+ else if (dest_type == NCI_DEST_TYPE_REMOTE)
+ {
+ num_tlv = 1;
+ UINT8_TO_STREAM (pp, NCI_CON_CREATE_TAG_RF_DISC_ID);
+ UINT8_TO_STREAM (pp, 1);
+ UINT8_TO_STREAM (pp, id);
+ tlv_size = 3;
+ }
+ else if (dest_type == NCI_DEST_TYPE_NFCC)
+ {
+ p_cb->id = NFC_TEST_ID;
+ }
+ /* Add handling of NCI_DEST_TYPE_REMOTE when more RF interface definitions are added */
+ p_cb->act_protocol = protocol;
+ p_cb->p_cback = p_cback;
+ status = nci_snd_core_conn_create (dest_type, num_tlv, tlv_size, param_tlvs);
+ if (status == NFC_STATUS_FAILED)
+ nfc_free_conn_cb (p_cb);
+ }
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function NFC_ConnClose
+**
+** Description This function is called to close a logical connection with
+** NFCC.
+**
+** Parameters conn_id - the connection id.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_ConnClose (UINT8 conn_id)
+{
+ tNFC_CONN_CB *p_cb = nfc_find_conn_cb_by_conn_id (conn_id);
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+
+ if (p_cb)
+ {
+ status = nci_snd_core_conn_close (conn_id);
+ }
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function NFC_SetStaticRfCback
+**
+** Description This function is called to update the data callback function
+** to receive the data for the given connection id.
+**
+** Parameters p_cback - the connection callback function
+**
+** Returns Nothing
+**
+*******************************************************************************/
+void NFC_SetStaticRfCback (tNFC_CONN_CBACK *p_cback)
+{
+ tNFC_CONN_CB * p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+
+ p_cb->p_cback = p_cback;
+ /* just in case DH has received NCI data before the data callback is set
+ * check if there's any data event to report on this connection id */
+ nfc_data_event (p_cb);
+}
+
+/*******************************************************************************
+**
+** Function NFC_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 (BOOLEAN 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 *) (p_data + 1) + p_data->offset)
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_SendData (UINT8 conn_id,
+ BT_HDR *p_data)
+{
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ tNFC_CONN_CB *p_cb = nfc_find_conn_cb_by_conn_id (conn_id);
+
+ if (p_cb && p_data && p_data->offset >= NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE)
+ {
+ status = nfc_ncif_send_data (p_cb, p_data);
+ }
+
+ if (status != NFC_STATUS_OK)
+ GKI_freebuf (p_data);
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function NFC_FlushData
+**
+** Description This function is called to discard the tx data queue of
+** the given connection id.
+**
+** Parameters conn_id - the connection id.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_FlushData (UINT8 conn_id)
+{
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ tNFC_CONN_CB *p_cb = nfc_find_conn_cb_by_conn_id (conn_id);
+ void *p_buf;
+
+ if (p_cb)
+ {
+ status = NFC_STATUS_OK;
+ while ((p_buf = GKI_dequeue (&p_cb->tx_q)) != NULL)
+ GKI_freebuf (p_buf);
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function NFC_Deactivate
+**
+** Description This function is called to stop the discovery process or
+** put the listen device in sleep mode or terminate the NFC link.
+**
+** The response from NFCC is reported by tNFC_DISCOVER_CBACK
+** as NFC_DEACTIVATE_DEVT.
+**
+** Parameters deactivate_type - NFC_DEACTIVATE_TYPE_IDLE, to IDLE mode.
+** NFC_DEACTIVATE_TYPE_SLEEP to SLEEP mode.
+** NFC_DEACTIVATE_TYPE_SLEEP_AF to SLEEP_AF mode.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_Deactivate (tNFC_DEACT_TYPE deactivate_type)
+{
+ tNFC_CONN_CB * p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+ tNFC_STATUS status = NFC_STATUS_OK;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ NFC_TRACE_API3 ("NFC_Deactivate %d (%s) deactivate_type:%d", nfc_cb.nfc_state, nfc_state_name (nfc_cb.nfc_state), deactivate_type);
+#else
+ NFC_TRACE_API2 ("NFC_Deactivate %d deactivate_type:%d", nfc_cb.nfc_state, deactivate_type);
+#endif
+
+ if (nfc_cb.flags & NFC_FL_DISCOVER_PENDING)
+ {
+ /* the HAL pre-discover is still active - clear the pending flag */
+ nfc_cb.flags &= ~NFC_FL_DISCOVER_PENDING;
+ 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(NFC_NXP_NOT_OPEN_INCLUDED == 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 = (TIMER_PARAM_TYPE) deactivate_type;
+ nfc_start_timer (&nfc_cb.deactivate_timer , (UINT16) (NFC_TTYPE_WAIT_2_DEACTIVATE), NFC_DEACTIVATE_TIMEOUT);
+ return status;
+ }
+ }
+
+ status = nci_snd_deactivate_cmd (deactivate_type);
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function NFC_UpdateRFCommParams
+**
+** Description This function is called to update RF Communication parameters
+** once the Frame RF Interface has been activated.
+**
+** The response from NFCC is reported by tNFC_RESPONSE_CBACK
+** as NFC_RF_COMM_PARAMS_UPDATE_REVT.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_UpdateRFCommParams (tNFC_RF_COMM_PARAMS *p_params)
+{
+ UINT8 tlvs[12];
+ UINT8 *p = tlvs;
+ UINT8 data_exch_config;
+
+ /* RF Technology and Mode */
+ if (p_params->include_rf_tech_mode)
+ {
+ UINT8_TO_STREAM (p, NCI_RF_PARAM_ID_TECH_N_MODE);
+ UINT8_TO_STREAM (p, 1);
+ UINT8_TO_STREAM (p, p_params->rf_tech_n_mode);
+ }
+
+ /* Transmit Bit Rate */
+ if (p_params->include_tx_bit_rate)
+ {
+ UINT8_TO_STREAM (p, NCI_RF_PARAM_ID_TX_BIT_RATE);
+ UINT8_TO_STREAM (p, 1);
+ UINT8_TO_STREAM (p, p_params->tx_bit_rate);
+ }
+
+ /* Receive Bit Rate */
+ if (p_params->include_tx_bit_rate)
+ {
+ UINT8_TO_STREAM (p, NCI_RF_PARAM_ID_RX_BIT_RATE);
+ UINT8_TO_STREAM (p, 1);
+ UINT8_TO_STREAM (p, p_params->rx_bit_rate);
+ }
+
+ /* NFC-B Data Exchange Configuration */
+ if (p_params->include_nfc_b_config)
+ {
+ UINT8_TO_STREAM (p, NCI_RF_PARAM_ID_B_DATA_EX_PARAM);
+ UINT8_TO_STREAM (p, 1);
+
+ data_exch_config = (p_params->min_tr0 & 0x03) << 6; /* b7b6 : Mininum TR0 */
+ data_exch_config |= (p_params->min_tr1 & 0x03) << 4; /* b5b4 : Mininum TR1 */
+ data_exch_config |= (p_params->suppression_eos & 0x01) << 3; /* b3 : Suppression of EoS */
+ data_exch_config |= (p_params->suppression_sos & 0x01) << 2; /* b2 : Suppression of SoS */
+ data_exch_config |= (p_params->min_tr2 & 0x03); /* b1b0 : Mininum TR2 */
+
+ UINT8_TO_STREAM (p, data_exch_config);
+ }
+
+ return nci_snd_parameter_update_cmd (tlvs, (UINT8) (p - tlvs));
+}
+
+/*******************************************************************************
+**
+** Function NFC_SetPowerOffSleep
+**
+** Description This function closes/opens transport and turns off/on NFCC.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_SetPowerOffSleep (BOOLEAN enable)
+{
+ NFC_TRACE_API1 ("NFC_SetPowerOffSleep () enable = %d", enable);
+
+ if ( (enable == FALSE)
+ &&(nfc_cb.nfc_state == NFC_STATE_NFCC_POWER_OFF_SLEEP) )
+ {
+ nfc_cb.flags |= NFC_FL_RESTARTING;
+
+ /* open transport */
+ nfc_set_state (NFC_STATE_W4_HAL_OPEN);
+ nfc_cb.p_hal->open (nfc_main_hal_cback, nfc_main_hal_data_cback);
+
+ return NFC_STATUS_OK;
+ }
+ else if ( (enable == TRUE)
+ &&(nfc_cb.nfc_state == NFC_STATE_IDLE) )
+ {
+ /* close transport to turn off NFCC and clean up */
+ nfc_cb.flags |= NFC_FL_POWER_OFF_SLEEP;
+ nfc_task_shutdown_nfcc ();
+
+ return NFC_STATUS_OK;
+ }
+
+ NFC_TRACE_ERROR1 ("NFC_SetPowerOffSleep () invalid state = %d", nfc_cb.nfc_state);
+ return NFC_STATUS_FAILED;
+}
+
+/*******************************************************************************
+**
+** Function NFC_PowerCycleNFCC
+**
+** Description This function turns off and then on NFCC.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_PowerCycleNFCC (void)
+{
+ NFC_TRACE_API0 ("NFC_PowerCycleNFCC ()");
+
+ if (nfc_cb.nfc_state == NFC_STATE_IDLE)
+ {
+ /* power cycle NFCC */
+ nfc_cb.flags |= NFC_FL_POWER_CYCLE_NFCC;
+ nfc_task_shutdown_nfcc ();
+
+ return NFC_STATUS_OK;
+ }
+
+ NFC_TRACE_ERROR1 ("NFC_PowerCycleNFCC () invalid state = %d", nfc_cb.nfc_state);
+ return NFC_STATUS_FAILED;
+}
+
+
+/*******************************************************************************
+**
+** Function NFC_SetTraceLevel
+**
+** Description This function sets the trace level for NFC. If called with
+** a value of 0xFF, it simply returns the current trace level.
+**
+** Returns The new or current trace level
+**
+*******************************************************************************/
+UINT8 NFC_SetTraceLevel (UINT8 new_level)
+{
+ NFC_TRACE_API1 ("NFC_SetTraceLevel () new_level = %d", new_level);
+
+ if (new_level != 0xFF)
+ nfc_cb.trace_level = new_level;
+
+ return (nfc_cb.trace_level);
+}
+void set_i2c_fragmentation_enabled(int value)
+{
+ i2c_fragmentation_enabled = value;
+}
+
+int get_i2c_fragmentation_enabled()
+{
+ return i2c_fragmentation_enabled;
+}
+
+#if((ESE_NFC_POWER_MANAGEMENT == TRUE)&&(NFC_NXP_NOT_OPEN_INCLUDED == 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 NFC_ReqWiredAccess (void *pdata)
+{
+ return (nfc_cb.p_hal->ioctl(1, 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 NFC_RelWiredAccess (void *pdata)
+{
+ return (nfc_cb.p_hal->ioctl(0, pdata));
+}
+/*******************************************************************************
+**
+** 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 NFC_GetP61Status (void *pdata)
+{
+ return (nfc_cb.p_hal->ioctl(2, pdata));
+}
+#endif
+
+
+#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
+
+#endif /* NFC_INCLUDED == TRUE */
diff --git a/src/nfc/nfc/nfc_ncif.c b/src/nfc/nfc/nfc_ncif.c
new file mode 100644
index 0000000..eec6447
--- /dev/null
+++ b/src/nfc/nfc/nfc_ncif.c
@@ -0,0 +1,2290 @@
+/******************************************************************************
+ *
+ * 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 functions that interface with the NFC NCI transport.
+ * On the receive side, it routes events to the appropriate handler
+ * (callback). On the transmit side, it manages the command transmission.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+
+#if NFC_INCLUDED == TRUE
+#include "nfc_hal_api.h"
+#include "nfc_api.h"
+#include "nci_defs.h"
+#include "nci_hmsgs.h"
+#include "nfc_int.h"
+#include "rw_api.h"
+#include "rw_int.h"
+#include "hcidefs.h"
+#include "nfc_hal_api.h"
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#include "nfa_ce_int.h"
+#include "nfa_sys.h"
+#include "nfa_dm_int.h"
+#include "nfa_hci_int.h"
+#endif
+tNFC_CONN_CB *p_cb_stored = NULL;
+#if (NFC_RW_ONLY == FALSE)
+static const UINT8 nfc_mpl_code_to_size[] =
+{64, 128, 192, 254};
+
+#endif /* NFC_RW_ONLY */
+
+#define NFC_NCI_WAIT_DATA_NTF_TOUT 2
+#define NFC_PB_ATTRIB_REQ_FIXED_BYTES 1
+#define NFC_LB_ATTRIB_REQ_FIXED_BYTES 8
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+// Global Structure varibale for FW Version
+static tNFC_FW_VERSION nfc_fw_version;
+uint8_t sListenActivated;
+extern tNFA_CE_CB nfa_ce_cb;
+BOOLEAN core_reset_init_num_buff = FALSE;
+UINT8 nfcc_dh_conn_id;
+extern void nfa_hci_rsp_timeout (tNFA_HCI_EVENT_DATA *p_evt_data);
+#endif
+
+#if(NFC_NXP_ESE == TRUE && NFC_NXP_CHIP_TYPE == PN548C2)
+extern etsi_reader_in_progress;
+#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_ERROR0 ("nfc_ncif_cmd_timeout");
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+
+ NFC_TRACE_ERROR0 ("Recovery Start!");
+ {
+ // 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] = Used by recovery. 0 or 1.
+ buffer[1] = Last RF State, 0:Idle State 1:Discovery State
+ buffer[2] = Length of discovery packet.
+ buffer[3~34] = Last Discovery command(including phase data).(32 byte)
+ buffer[35] = Length of last command packet.
+ buffer[36~255] = Last Command /or Last Command & Data.
+ */
+ UINT8 *buffer = NULL;
+ UINT8 bufflen = 0xFF;
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ tNFC_CONN_CB * p_cb = NULL;
+ nfc_stop_timer (&nfc_cb.nci_wait_rsp_timer);
+
+ buffer = (UINT8 *) malloc(bufflen*sizeof(UINT8));
+ if(NULL == buffer)
+ {
+ NFC_TRACE_ERROR0 ("Recovery MEM Allocation is failed!!");
+ return;
+ }
+ memset(buffer, 0x00, (bufflen*sizeof(UINT8)));
+ buffer[0] = 1; //Sending reset/init command as raw packet in HAL layer.
+
+ NFC_TRACE_ERROR1 ("Last State nfa_dm_cb.disc_cb.disc_flags 0x%x", nfa_dm_cb.disc_cb.disc_flags);
+ NFC_TRACE_ERROR1 ("Last State nfa_dm_cb.disc_cb.disc_state 0x%x", nfa_dm_cb.disc_cb.disc_state);
+
+ if(!(nfa_dm_cb.disc_cb.disc_state > NFA_DM_RFST_IDLE))
+ {
+ NFC_TRACE_ERROR0 ("Last State is Idle!!");
+ buffer[1] = 0; //Idle State.
+ }
+ else
+ {
+ UINT8 *ps = (UINT8 *)nfc_cb.p_last_disc;
+ NFC_TRACE_ERROR0 ("Last State is Discovery!!");
+ buffer[1] = 1; //Discovery State.
+ nfa_dm_cb.disc_cb.disc_state = 0x01; //RF State is initialized to discovery.
+ nfa_ce_cb.flags = 0x00; // Listen Flag is initialized to 0x00.
+ if(ps[0])
+ {
+ buffer[2] = 2 + 1 + 1 + (ps[0] * 2); // HDR(2) + Length(1) + Entry(1) + Data(Tech(2) * 2)
+ memcpy((UINT8 *)&buffer[3], "\x21\x03", 2);
+ buffer[5] = 1 + (ps[0] * 2); // Entity(1) + Data(Tech(2) * 2)
+ memcpy((UINT8 *)&buffer[6], ps, buffer[5]);
+ }
+ else
+ {
+ buffer[2] = 26; //Length of packet
+ memcpy((UINT8 *)&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);
+ }
+ }
+
+ if((nfc_cb.last_hdr[0] == 0x20 && nfc_cb.last_hdr[1] == 0x02)
+ || (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))
+ {
+ buffer[35] = nfc_cb.cmd_size + 3; //HDR(2) + Lengh(1) + Cmd data(n)
+ memcpy(&buffer[36], nfc_cb.last_hdr, 2);
+ memcpy(&buffer[38], nfc_cb.last_cmd_buf, nfc_cb.cmd_size + 1);
+ }
+ else
+ {
+ buffer[35] = 2 + 1 + nfc_cb.cmd_size; //HDR(2) + Lengh(1) + Command Size(2)
+ memcpy(&buffer[36], nfc_cb.last_hdr, NFC_SAVED_HDR_SIZE);
+ buffer[38] = nfc_cb.cmd_size; // Length of Command.(2)
+ if(nfc_cb.cmd_size > 0)
+ memcpy(&buffer[39], nfc_cb.last_cmd, NFC_SAVED_CMD_SIZE);
+ if(nfc_cb.last_hdr[0] == 0x20 && nfc_cb.last_hdr[1] == 0x00) buffer[0] = 2; //last packet is CORE_RESET.
+ else if (nfc_cb.last_hdr[0] == 0x20 && nfc_cb.last_hdr[1] == 0x01) buffer[0] = 3; //last packet is CORE_INIT.
+ }
+ /* if HCI state is in wait 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)
+ {
+ BT_HDR *p_msg;
+ nfa_sys_stop_timer(&nfa_hci_cb.timer);
+ if ((p_msg = (BT_HDR *) GKI_getbuf (sizeof (BT_HDR))) != NULL)
+ {
+ NFC_TRACE_ERROR0("GKI Get Buffer Successful...Sending response timeout to upper layer");
+ p_msg->event = NFA_HCI_RSP_TIMEOUT_EVT;
+ p_msg->layer_specific = 0;
+ nfa_sys_sendmsg (p_msg);
+ }
+ }
+ /* Flush the data if any before proceeding further with the recovery */
+ p_cb = nfc_find_conn_cb_by_conn_id(nfcc_dh_conn_id);
+ NFC_TRACE_ERROR1("connection id %d", nfcc_dh_conn_id);
+ if(NULL != p_cb)
+ {
+ status = NFC_FlushData(p_cb->conn_id);
+ if(status != NFC_STATUS_OK)
+ {
+ NFC_TRACE_ERROR0 ("NFC data flush failed");
+ }
+ }
+ nfc_cb.p_hal->core_initialized (buffer);
+
+ if(buffer != NULL) free(buffer);
+ }
+#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) ((TIMER_PARAM_TYPE) nfc_cb.deactivate_timer.param));
+}
+
+
+/*******************************************************************************
+**
+** Function nfc_ncif_send_data
+**
+** Description This function is called to add the NCI data header
+** and send it to NCIT task for sending it to transport
+** as credits are available.
+**
+** Returns void
+**
+*******************************************************************************/
+UINT8 nfc_ncif_send_data (tNFC_CONN_CB *p_cb, BT_HDR *p_data)
+{
+ UINT8 *pp;
+ UINT8 *ps;
+ UINT8 ulen = NCI_MAX_PAYLOAD_SIZE;
+ BT_HDR *p;
+ UINT8 pbf = 1;
+ UINT8 buffer_size = p_cb->buff_size;
+ UINT8 hdr0 = p_cb->conn_id;
+ BOOLEAN fragmented = FALSE;
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ if(core_reset_init_num_buff == TRUE)
+ {
+ NFC_TRACE_ERROR0("Reinitializing the 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)((TIMER_PARAM_TYPE)nfc_cb.deactivate_timer.param));
+ }
+ }
+ }
+ return NCI_STATUS_FAILED;
+ }
+ }
+
+ if (p_data)
+ {
+ /* always enqueue the data to the tx queue */
+ GKI_enqueue (&p_cb->tx_q, p_data);
+ }
+
+ /* try to send the first data packet in the tx queue */
+ p_data = (BT_HDR *)GKI_getfirst (&p_cb->tx_q);
+
+ /* post data fragment to NCIT task as credits are available */
+ while (p_data && (p_data->len >= 0) && (p_cb->num_buff > 0))
+ {
+ if (p_data->len <= buffer_size)
+ {
+ pbf = 0; /* last fragment */
+ ulen = (UINT8)(p_data->len);
+ fragmented = FALSE;
+ }
+ else
+ {
+ fragmented = TRUE;
+ ulen = buffer_size;
+ }
+
+ if (!fragmented)
+ {
+ /* if data packet is not fragmented, use the original buffer */
+ p = p_data;
+ p_data = (BT_HDR *)GKI_dequeue (&p_cb->tx_q);
+ }
+ else
+ {
+ /* the data packet is too big and need to be fragmented
+ * prepare a new GKI buffer
+ * (even the last fragment to avoid issues) */
+ if ((p = NCI_GET_CMD_BUF(ulen)) == NULL)
+ return (NCI_STATUS_BUFFER_FULL);
+ p->len = ulen;
+ p->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + 1;
+ if (p->len)
+ {
+ pp = (UINT8 *)(p + 1) + p->offset;
+ ps = (UINT8 *)(p_data + 1) + p_data->offset;
+ memcpy (pp, ps, ulen);
+ }
+ /* adjust the BT_HDR on the old fragment */
+ p_data->len -= ulen;
+ p_data->offset += ulen;
+ }
+
+ p->event = BT_EVT_TO_NFC_NCI;
+ p->layer_specific = pbf;
+ p->len += NCI_DATA_HDR_SIZE;
+ p->offset -= NCI_DATA_HDR_SIZE;
+ pp = (UINT8 *)(p + 1) + p->offset;
+ /* build NCI Data packet header */
+ NCI_DATA_PBLD_HDR(pp, pbf, hdr0, ulen);
+ if (p_cb->num_buff != NFC_CONN_NO_FC)
+ p_cb->num_buff--;
+
+ /* send to HAL */
+ HAL_WRITE(p);
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ /* start NFC data ntf timeout timer */
+ if( get_i2c_fragmentation_enabled () == I2C_FRAGMENATATION_ENABLED)
+ {
+ nfc_cb.nci_cmd_window--;
+ }
+ nfc_start_timer (&nfc_cb.nci_wait_data_ntf_timer, (UINT16)(NFC_TTYPE_NCI_WAIT_DATA_NTF), NFC_NCI_WAIT_DATA_NTF_TOUT);
+ if (!fragmented)
+ {
+ /* check if there are more data to send */
+ p_data = (BT_HDR *)GKI_getfirst (&p_cb->tx_q);
+ }
+#endif
+ }
+
+ return (NCI_STATUS_OK);
+}
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+/*Function to empty cmd queue.*/
+void nfc_ncif_empty_cmd_queue ()
+{
+ BT_HDR *p_buf = (BT_HDR *)GKI_dequeue (&nfc_cb.nci_cmd_xmit_q);
+
+ while(p_buf)
+ {
+ GKI_freebuf (p_buf);
+ p_buf = (BT_HDR *)GKI_dequeue (&nfc_cb.nci_cmd_xmit_q);
+ }
+}
+#endif
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+/*Function to empty data queue.*/
+void nfc_ncif_empty_data_queue ()
+{
+ BT_HDR * p_data = (BT_HDR *)GKI_dequeue (&p_cb_stored->tx_q);
+
+ while(p_data)
+ {
+ GKI_freebuf (p_data);
+ p_data = (BT_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 (BT_HDR *p_buf)
+{
+ UINT8 *ps;
+ /* If there are commands waiting in the xmit queue, or if the controller cannot accept any more commands, */
+ /* then enqueue this command */
+ if (p_buf)
+ {
+ if ((nfc_cb.nci_cmd_xmit_q.count) || (nfc_cb.nci_cmd_window == 0))
+ {
+ GKI_enqueue (&nfc_cb.nci_cmd_xmit_q, p_buf);
+#if (NFC_NXP_NOT_OPEN_INCLUDED == 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 = (BT_HDR *)GKI_dequeue (&nfc_cb.nci_cmd_xmit_q);
+
+ if (p_buf)
+ {
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+
+ /* save the message header to double check the response */
+ ps = (UINT8 *)(p_buf + 1) + p_buf->offset;
+ memcpy(nfc_cb.last_hdr, ps, NFC_SAVED_HDR_SIZE);
+
+ if((nfc_cb.last_hdr[0] == 0x20 && nfc_cb.last_hdr[1] == 0x02)
+ || (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))
+ {
+ nfc_cb.cmd_size = *(ps + NFC_SAVED_HDR_SIZE);
+ if (nfc_cb.last_cmd_buf != NULL)
+ {
+ GKI_freebuf(nfc_cb.last_cmd_buf); // ======> Free before allocation
+ }
+ nfc_cb.last_cmd_buf = (UINT8 *) GKI_getbuf(nfc_cb.cmd_size +1 );
+ 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_cb.cmd_size = *(ps + NFC_SAVED_HDR_SIZE);
+ 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 *)(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(NFC_NXP_NOT_OPEN_INCLUDED == 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;
+ }
+#endif
+
+ /* send to HAL */
+ HAL_WRITE(p_buf);
+ 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");
+ }
+ /* Indicate command is pending */
+ nfc_cb.nci_cmd_window--;
+
+ /* start NFC command-timeout timer */
+ nfc_start_timer (&nfc_cb.nci_wait_rsp_timer, (UINT16)(NFC_TTYPE_NCI_WAIT_RSP), nfc_cb.nci_wait_rsp_tout);
+ }
+ }
+
+ if (nfc_cb.nci_cmd_window == NCI_MAX_CMD_WINDOW)
+ {
+ /* the command queue must be empty now */
+ if (nfc_cb.flags & NFC_FL_CONTROL_REQUESTED)
+ {
+ /* HAL requested control or stack needs to handle pre-discover */
+ nfc_cb.flags &= ~NFC_FL_CONTROL_REQUESTED;
+ if (nfc_cb.flags & NFC_FL_DISCOVER_PENDING)
+ {
+ if (nfc_cb.p_hal->prediscover ())
+ {
+ /* HAL has the command window now */
+ nfc_cb.flags |= NFC_FL_CONTROL_GRANTED;
+ nfc_cb.nci_cmd_window = 0;
+ }
+ else
+ {
+ /* HAL does not need to send command,
+ * - restore the command window and issue the discovery command now */
+ nfc_cb.flags &= ~NFC_FL_DISCOVER_PENDING;
+ ps = (UINT8 *)nfc_cb.p_disc_pending;
+ nci_snd_discover_cmd (*ps, (tNFC_DISCOVER_PARAMS *)(ps + 1));
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 (BT_HDR *p_buf)
+{
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ NFC_TRACE_DEBUG0 ("nfc_ncif_send_cmd.");
+ if(p_buf == NULL)
+ {
+ NFC_TRACE_DEBUG0 ("p_buf is NULL.");
+ return;
+ }
+ UINT8 *cmd = NULL;
+ cmd = (UINT8 *)(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
+**
+*******************************************************************************/
+BOOLEAN nfc_ncif_process_event (BT_HDR *p_msg)
+{
+ UINT8 mt, pbf, gid, *p, *pp;
+ BOOLEAN free = TRUE;
+ UINT8 oid;
+ UINT8 *p_old, old_gid, old_oid, old_mt;
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+
+ pp = p;
+ NCI_MSG_PRS_HDR0 (pp, mt, pbf, gid);
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_ESE == TRUE && NFC_NXP_CHIP_TYPE == PN548C2)
+ if(((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
+ {
+#endif
+ /*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;
+ }
+#if(NFC_NXP_ESE == TRUE && NFC_NXP_CHIP_TYPE == PN548C2)
+ }
+#endif
+ }
+
+ 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(get_i2c_fragmentation_enabled() == I2C_FRAGMENATATION_ENABLED)
+ {
+ nfc_cb.i2c_data_t.nci_cmd_channel_busy = 0;
+ NFC_TRACE_DEBUG1("%s,updating window" , __FUNCTION__);
+ 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 status)
+{
+ tNFC_DISCOVER evt_data;
+ if (nfc_cb.p_discv_cback)
+ {
+ evt_data.status = (tNFC_STATUS) status;
+ (*nfc_cb.p_discv_cback) (event, &evt_data);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_ncif_set_config_status
+**
+** Description This function is called to report NFC_SET_CONFIG_REVT
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_ncif_set_config_status (UINT8 *p, UINT8 len)
+{
+ tNFC_RESPONSE evt_data;
+ if (nfc_cb.p_resp_cback)
+ {
+ evt_data.set_config.status = (tNFC_STATUS) *p++;
+ evt_data.set_config.num_param_id = NFC_STATUS_OK;
+ if (evt_data.set_config.status != NFC_STATUS_OK)
+ {
+ evt_data.set_config.num_param_id = *p++;
+ STREAM_TO_ARRAY (evt_data.set_config.param_ids, p, evt_data.set_config.num_param_id);
+ }
+
+ (*nfc_cb.p_resp_cback) (NFC_SET_CONFIG_REVT, &evt_data);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_ncif_event_status
+**
+** Description This function is called to report an event
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_ncif_event_status (tNFC_RESPONSE_EVT event, UINT8 status)
+{
+ tNFC_RESPONSE evt_data;
+ if (nfc_cb.p_resp_cback)
+ {
+ evt_data.status = (tNFC_STATUS) status;
+ (*nfc_cb.p_resp_cback) (event, &evt_data);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_ncif_error_status
+**
+** Description This function is called to report an error event to data cback
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_ncif_error_status (UINT8 conn_id, UINT8 status)
+{
+ tNFC_CONN_CB * p_cb;
+ p_cb = nfc_find_conn_cb_by_conn_id (conn_id);
+ if (p_cb && p_cb->p_cback)
+ {
+ (*p_cb->p_cback) (conn_id, NFC_ERROR_CEVT, (tNFC_CONN *) &status);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_ncif_proc_rf_field_ntf
+**
+** Description This function is called to process RF field notification
+**
+** Returns void
+**
+*******************************************************************************/
+#if (NFC_RW_ONLY == FALSE)
+void nfc_ncif_proc_rf_field_ntf (UINT8 rf_status)
+{
+ tNFC_RESPONSE evt_data;
+ if (nfc_cb.p_resp_cback)
+ {
+ evt_data.status = (tNFC_STATUS) NFC_STATUS_OK;
+ evt_data.rf_field.rf_field = rf_status;
+ (*nfc_cb.p_resp_cback) (NFC_RF_FIELD_REVT, &evt_data);
+ }
+}
+#endif
+
+/*******************************************************************************
+**
+** Function nfc_ncif_proc_credits
+**
+** Description This function is called to process data credits
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_ncif_proc_credits(UINT8 *p, UINT16 plen)
+{
+ UINT8 num, xx;
+ tNFC_CONN_CB * p_cb;
+
+ num = *p++;
+ for (xx = 0; xx < num; xx++)
+ {
+ p_cb = nfc_find_conn_cb_by_conn_id(*p++);
+ if (p_cb && p_cb->num_buff != NFC_CONN_NO_FC)
+ {
+ p_cb->num_buff += (*p);
+#if (BT_USE_TRACES == TRUE)
+ if (p_cb->num_buff > p_cb->init_credits)
+ {
+ if (nfc_cb.nfc_state == NFC_STATE_OPEN)
+ {
+ /* if this happens in activated state, it's very likely that our NFCC has issues */
+ /* However, credit may be returned after deactivation */
+ NFC_TRACE_ERROR2( "num_buff:0x%x, init_credits:0x%x", p_cb->num_buff, p_cb->init_credits);
+ }
+ p_cb->num_buff = p_cb->init_credits;
+ }
+#endif
+ nfc_stop_timer (&nfc_cb.nci_wait_data_ntf_timer);
+ 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 * nfc_ncif_decode_rf_params (tNFC_RF_TECH_PARAMS *p_param, UINT8 *p)
+{
+ tNFC_RF_PA_PARAMS *p_pa;
+ UINT8 len, *p_start, u8;
+ tNFC_RF_PB_PARAMS *p_pb;
+ tNFC_RF_LF_PARAMS *p_lf;
+ tNFC_RF_PF_PARAMS *p_pf;
+ tNFC_RF_PISO15693_PARAMS *p_i93;
+
+ len = *p++;
+ p_start = p;
+ memset ( &p_param->param, 0, sizeof (tNFC_RF_TECH_PARAMU));
+ switch (p_param->mode)
+ {
+ case NCI_DISCOVERY_TYPE_POLL_A:
+ case NCI_DISCOVERY_TYPE_POLL_A_ACTIVE:
+ p_pa = &p_param->param.pa;
+ /*
+SENS_RES Response 2 bytes Defined in [DIGPROT] Available after Technology Detection
+NFCID1 length 1 byte Length of NFCID1 Available after Collision Resolution
+NFCID1 4, 7, or 10 bytes Defined in [DIGPROT]Available after Collision Resolution
+SEL_RES Response 1 byte Defined in [DIGPROT]Available after Collision Resolution
+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;
+ }
+ }
+ break;
+
+ case NCI_DISCOVERY_TYPE_POLL_B:
+ /*
+SENSB_RES Response length (n) 1 byte Length of SENSB_RES Response (Byte 2 - Byte 12 or 13)Available after Technology Detection
+SENSB_RES Response Byte 2 - Byte 12 or 13 11 or 12 bytes Defined in [DIGPROT] Available after Technology Detection
+ */
+ p_pb = &p_param->param.pb;
+ p_pb->sensb_res_len = *p++;
+ if (p_pb->sensb_res_len > NCI_MAX_SENSB_RES_LEN)
+ p_pb->sensb_res_len = NCI_MAX_SENSB_RES_LEN;
+ STREAM_TO_ARRAY (p_pb->sensb_res, p, p_pb->sensb_res_len);
+ memcpy (p_pb->nfcid0, p_pb->sensb_res, NFC_NFCID0_MAX_LEN);
+ break;
+
+ case NCI_DISCOVERY_TYPE_POLL_F:
+ case NCI_DISCOVERY_TYPE_POLL_F_ACTIVE:
+ /*
+Bit Rate 1 byte 1 212 kbps/2 424 kbps/0 and 3 to 255 RFU
+SENSF_RES Response length.(n) 1 byte Length of SENSF_RES (Byte 2 - Byte 17 or 19).Available after Technology Detection
+SENSF_RES Response Byte 2 - Byte 17 or 19 n bytes Defined in [DIGPROT] Available after Technology Detection
+ */
+ p_pf = &p_param->param.pf;
+ p_pf->bit_rate = *p++;
+ p_pf->sensf_res_len = *p++;
+ if (p_pf->sensf_res_len > NCI_MAX_SENSF_RES_LEN)
+ p_pf->sensf_res_len = NCI_MAX_SENSF_RES_LEN;
+ STREAM_TO_ARRAY (p_pf->sensf_res, p, p_pf->sensf_res_len);
+ memcpy (p_pf->nfcid2, p_pf->sensf_res, NCI_NFCID2_LEN);
+ p_pf->mrti_check = p_pf->sensf_res[NCI_MRTI_CHECK_INDEX];
+ p_pf->mrti_update = p_pf->sensf_res[NCI_MRTI_UPDATE_INDEX];
+ break;
+
+ case NCI_DISCOVERY_TYPE_LISTEN_F:
+ case NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE:
+ p_lf = &p_param->param.lf;
+ u8 = *p++;
+ if (u8)
+ {
+ STREAM_TO_ARRAY (p_lf->nfcid2, p, NCI_NFCID2_LEN);
+ }
+ break;
+
+ case NCI_DISCOVERY_TYPE_POLL_ISO15693:
+ p_i93 = &p_param->param.pi93;
+ p_i93->flag = *p++;
+ p_i93->dsfid = *p++;
+ STREAM_TO_ARRAY (p_i93->uid, p, NFC_ISO15693_UID_LEN);
+ break;
+
+ case NCI_DISCOVERY_TYPE_POLL_KOVIO:
+ p_param->param.pk.uid_len = *p++;
+ 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);
+ break;
+ }
+
+ return (p_start + len);
+}
+
+/*******************************************************************************
+**
+** Function nfc_ncif_proc_discover_ntf
+**
+** Description This function is called to process discover notification
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_ncif_proc_discover_ntf (UINT8 *p, UINT16 plen)
+{
+ tNFC_DISCOVER evt_data;
+
+ if (nfc_cb.p_discv_cback)
+ {
+ p += NCI_MSG_HDR_SIZE;
+ evt_data.status = NCI_STATUS_OK;
+ evt_data.result.rf_disc_id = *p++;
+ evt_data.result.protocol = *p++;
+
+ /* fill in tNFC_RESULT_DEVT */
+ evt_data.result.rf_tech_param.mode = *p++;
+ p = nfc_ncif_decode_rf_params (&evt_data.result.rf_tech_param, p);
+
+ evt_data.result.more = *p++;
+ (*nfc_cb.p_discv_cback) (NFC_RESULT_DEVT, &evt_data);
+ }
+}
+
+#if (NFC_NXP_NOT_OPEN_INCLUDED == 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 *p, UINT16 plen)
+{
+ tNFC_CONN_CB *p_cb = NULL;
+ (void)p;
+ 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 *p, UINT8 len)
+{
+ tNFC_DISCOVER evt_data;
+ tNFC_INTF_PARAMS *p_intf = &evt_data.activate.intf_param;
+ tNFC_INTF_PA_ISO_DEP *p_pa_iso;
+ tNFC_INTF_LB_ISO_DEP *p_lb_iso;
+ tNFC_INTF_PB_ISO_DEP *p_pb_iso;
+#if (NFC_RW_ONLY == FALSE)
+ tNFC_INTF_PA_NFC_DEP *p_pa_nfc;
+ int mpl_idx = 0;
+ UINT8 gb_idx = 0, mpl;
+#endif
+ UINT8 t0;
+ tNCI_DISCOVERY_TYPE mode;
+ tNFC_CONN_CB * p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+ UINT8 *pp, len_act;
+ UINT8 buff_size, num_buff;
+ 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 (NFC_NXP_NOT_OPEN_INCLUDED == 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 (NFC_NXP_NOT_OPEN_INCLUDED == 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)(NFC_TTYPE_LISTEN_ACTIVATION), 2);
+ }
+#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) (p_pa_iso->ats_res_len - (pp - p_pa_iso->ats_res));
+ memcpy (p_pa_iso->his_byte, pp, p_pa_iso->his_byte_len);
+ break;
+
+ case NCI_DISCOVERY_TYPE_LISTEN_A:
+ p_intf->intf_param.la_iso.rats = *p++;
+ break;
+
+ case NCI_DISCOVERY_TYPE_POLL_B:
+ /* ATTRIB RSP
+ Byte 1 Byte 2 ~ 2+n-1
+ MBLI/DID Higher layer - Response
+ */
+ p_pb_iso = &p_intf->intf_param.pb_iso;
+ p_pb_iso->attrib_res_len = *p++;
+
+ if (p_pb_iso->attrib_res_len == 0)
+ break;
+
+ if (p_pb_iso->attrib_res_len > NFC_MAX_ATTRIB_LEN)
+ p_pb_iso->attrib_res_len = NFC_MAX_ATTRIB_LEN;
+ STREAM_TO_ARRAY (p_pb_iso->attrib_res, p, p_pb_iso->attrib_res_len);
+ p_pb_iso->mbli = (p_pb_iso->attrib_res[0]) >> 4;
+ if (p_pb_iso->attrib_res_len > NFC_PB_ATTRIB_REQ_FIXED_BYTES)
+ {
+ p_pb_iso->hi_info_len = p_pb_iso->attrib_res_len - NFC_PB_ATTRIB_REQ_FIXED_BYTES;
+ if (p_pb_iso->hi_info_len > NFC_MAX_GEN_BYTES_LEN)
+ p_pb_iso->hi_info_len = NFC_MAX_GEN_BYTES_LEN;
+ memcpy (p_pb_iso->hi_info, &p_pb_iso->attrib_res[NFC_PB_ATTRIB_REQ_FIXED_BYTES], p_pb_iso->hi_info_len);
+ }
+ break;
+
+ case NCI_DISCOVERY_TYPE_LISTEN_B:
+ /* ATTRIB CMD
+ Byte 2~5 Byte 6 Byte 7 Byte 8 Byte 9 Byte 10 ~ 10+k-1
+ NFCID0 Param 1 Param 2 Param 3 Param 4 Higher layer - INF
+ */
+ p_lb_iso = &p_intf->intf_param.lb_iso;
+ p_lb_iso->attrib_req_len = *p++;
+
+ if (p_lb_iso->attrib_req_len == 0)
+ break;
+
+ if (p_lb_iso->attrib_req_len > NFC_MAX_ATTRIB_LEN)
+ p_lb_iso->attrib_req_len = NFC_MAX_ATTRIB_LEN;
+ STREAM_TO_ARRAY (p_lb_iso->attrib_req, p, p_lb_iso->attrib_req_len);
+ memcpy (p_lb_iso->nfcid0, p_lb_iso->attrib_req, NFC_NFCID0_MAX_LEN);
+ if (p_lb_iso->attrib_req_len > NFC_LB_ATTRIB_REQ_FIXED_BYTES)
+ {
+ p_lb_iso->hi_info_len = p_lb_iso->attrib_req_len - NFC_LB_ATTRIB_REQ_FIXED_BYTES;
+ if (p_lb_iso->hi_info_len > NFC_MAX_GEN_BYTES_LEN)
+ p_lb_iso->hi_info_len = NFC_MAX_GEN_BYTES_LEN;
+ memcpy (p_lb_iso->hi_info, &p_lb_iso->attrib_req[NFC_LB_ATTRIB_REQ_FIXED_BYTES], p_lb_iso->hi_info_len);
+ }
+ break;
+ }
+
+ }
+#if (NFC_RW_ONLY == FALSE)
+ else if(evt_data.activate.intf_param.type == NCI_INTERFACE_NFC_DEP)
+ {
+ /* Make max payload of NCI aligned to max payload of NFC-DEP for better performance */
+ if (buff_size > NCI_NFC_DEP_MAX_DATA)
+ buff_size = NCI_NFC_DEP_MAX_DATA;
+
+ p_pa_nfc = &p_intf->intf_param.pa_nfc;
+ p_pa_nfc->atr_res_len = *p++;
+
+ if (p_pa_nfc->atr_res_len > 0)
+ {
+ if (p_pa_nfc->atr_res_len > NFC_MAX_ATS_LEN)
+ p_pa_nfc->atr_res_len = NFC_MAX_ATS_LEN;
+ STREAM_TO_ARRAY (p_pa_nfc->atr_res, p, p_pa_nfc->atr_res_len);
+ if ( (mode == NCI_DISCOVERY_TYPE_POLL_A)
+ ||(mode == NCI_DISCOVERY_TYPE_POLL_F)
+ ||(mode == NCI_DISCOVERY_TYPE_POLL_A_ACTIVE)
+ ||(mode == NCI_DISCOVERY_TYPE_POLL_F_ACTIVE) )
+ {
+ /* ATR_RES
+ Byte 3~12 Byte 13 Byte 14 Byte 15 Byte 16 Byte 17 Byte 18~18+n
+ NFCID3T DIDT BST BRT TO PPT [GT0 ... GTn] */
+ mpl_idx = 14;
+ gb_idx = NCI_P_GEN_BYTE_INDEX;
+ p_pa_nfc->waiting_time = p_pa_nfc->atr_res[NCI_L_NFC_DEP_TO_INDEX] & 0x0F;
+ }
+ else if ( (mode == NCI_DISCOVERY_TYPE_LISTEN_A)
+ ||(mode == NCI_DISCOVERY_TYPE_LISTEN_F)
+ ||(mode == NCI_DISCOVERY_TYPE_LISTEN_A_ACTIVE)
+ ||(mode == NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE) )
+ {
+ /* ATR_REQ
+ Byte 3~12 Byte 13 Byte 14 Byte 15 Byte 16 Byte 17~17+n
+ NFCID3I DIDI BSI BRI PPI [GI0 ... GIn] */
+ mpl_idx = 13;
+ gb_idx = NCI_L_GEN_BYTE_INDEX;
+ }
+
+ mpl = ((p_pa_nfc->atr_res[mpl_idx]) >> 4) & 0x03;
+ p_pa_nfc->max_payload_size = nfc_mpl_code_to_size[mpl];
+ if (p_pa_nfc->atr_res_len > gb_idx)
+ {
+ p_pa_nfc->gen_bytes_len = p_pa_nfc->atr_res_len - gb_idx;
+ if (p_pa_nfc->gen_bytes_len > NFC_MAX_GEN_BYTES_LEN)
+ p_pa_nfc->gen_bytes_len = NFC_MAX_GEN_BYTES_LEN;
+ memcpy (p_pa_nfc->gen_bytes, &p_pa_nfc->atr_res[gb_idx], p_pa_nfc->gen_bytes_len);
+ }
+ }
+ }
+#endif
+ 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(NFC_NXP_NOT_OPEN_INCLUDED == 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 == NCI_INTERFACE_UICC_DIRECT || evt_data.activate.intf_param.type == 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(NFC_NXP_NOT_OPEN_INCLUDED == 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 status, UINT8 deact_type, BOOLEAN is_ntf)
+{
+ tNFC_DISCOVER evt_data;
+ tNFC_DEACTIVATE_DEVT *p_deact;
+ tNFC_CONN_CB * p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+ void *p_data;
+
+ nfc_set_state (NFC_STATE_IDLE);
+ p_deact = &evt_data.deactivate;
+ p_deact->status = status;
+ p_deact->type = deact_type;
+ p_deact->is_ntf = is_ntf;
+
+ while ((p_data = GKI_dequeue (&p_cb->rx_q)) != NULL)
+ {
+ GKI_freebuf (p_data);
+ }
+
+ while ((p_data = GKI_dequeue (&p_cb->tx_q)) != NULL)
+ {
+ GKI_freebuf (p_data);
+ }
+
+ if (p_cb->p_cback)
+ (*p_cb->p_cback) (NFC_RF_CONN_ID, NFC_DEACTIVATE_CEVT, (tNFC_CONN *) p_deact);
+
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ 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 *p, UINT16 plen)
+{
+ tNFC_EE_ACTION_REVT evt_data;
+ tNFC_RESPONSE_CBACK *p_cback = nfc_cb.p_resp_cback;
+ UINT8 data_len, ulen, tag, *p_data;
+ UINT8 max_len;
+
+ if (p_cback)
+ {
+ memset (&evt_data.act_data, 0, sizeof (tNFC_ACTION_DATA));
+ evt_data.status = NFC_STATUS_OK;
+ evt_data.nfcee_id = *p++;
+ evt_data.act_data.trigger = *p++;
+ data_len = *p++;
+ if (plen >= 3)
+ plen -= 3;
+ if (data_len > plen)
+ data_len = (UINT8) plen;
+
+ switch (evt_data.act_data.trigger)
+ {
+ case NCI_EE_TRIG_7816_SELECT:
+ if (data_len > NFC_MAX_AID_LEN)
+ data_len = NFC_MAX_AID_LEN;
+ evt_data.act_data.param.aid.len_aid = data_len;
+ STREAM_TO_ARRAY (evt_data.act_data.param.aid.aid, p, data_len);
+ break;
+ case NCI_EE_TRIG_RF_PROTOCOL:
+ evt_data.act_data.param.protocol = *p++;
+ break;
+ case NCI_EE_TRIG_RF_TECHNOLOGY:
+ evt_data.act_data.param.technology = *p++;
+ break;
+ case NCI_EE_TRIG_APP_INIT:
+ while (data_len > NFC_TL_SIZE)
+ {
+ data_len -= NFC_TL_SIZE;
+ tag = *p++;
+ ulen = *p++;
+ if (ulen > data_len)
+ ulen = data_len;
+ p_data = NULL;
+ max_len = ulen;
+ switch (tag)
+ {
+ case NCI_EE_ACT_TAG_AID: /* AID */
+ if (max_len > NFC_MAX_AID_LEN)
+ max_len = NFC_MAX_AID_LEN;
+ evt_data.act_data.param.app_init.len_aid = max_len;
+ p_data = evt_data.act_data.param.app_init.aid;
+ break;
+ case NCI_EE_ACT_TAG_DATA: /* hex data for app */
+ if (max_len > NFC_MAX_APP_DATA_LEN)
+ max_len = NFC_MAX_APP_DATA_LEN;
+ evt_data.act_data.param.app_init.len_data = max_len;
+ p_data = evt_data.act_data.param.app_init.data;
+ break;
+ }
+ if (p_data)
+ {
+ STREAM_TO_ARRAY (p_data, p, max_len);
+ }
+ data_len -= ulen;
+ }
+ break;
+ }
+ (*p_cback) (NFC_EE_ACTION_REVT, (tNFC_RESPONSE *) &evt_data);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_ncif_proc_ee_discover_req
+**
+** Description This function is called to process NFCEE DISCOVER REQ NTF
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_ncif_proc_ee_discover_req (UINT8 *p, UINT16 plen)
+{
+ tNFC_RESPONSE_CBACK *p_cback = nfc_cb.p_resp_cback;
+ tNFC_EE_DISCOVER_REQ_REVT ee_disc_req;
+ tNFC_EE_DISCOVER_INFO *p_info;
+ UINT8 u8;
+
+ NFC_TRACE_DEBUG2 ("nfc_ncif_proc_ee_discover_req %d len:%d", *p, plen);
+ if (p_cback)
+ {
+ u8 = *p;
+ ee_disc_req.status = NFC_STATUS_OK;
+ ee_disc_req.num_info = *p++;
+ p_info = ee_disc_req.info;
+ if (plen)
+ plen--;
+ while ((u8 > 0) && (plen >= NFC_EE_DISCOVER_ENTRY_LEN))
+ {
+ p_info->op = *p++; /* T */
+ if (*p != NFC_EE_DISCOVER_INFO_LEN)/* L */
+ {
+ NFC_TRACE_DEBUG1 ("bad entry len:%d", *p );
+ return;
+ }
+ p++;
+ /* V */
+ p_info->nfcee_id = *p++;
+ p_info->tech_n_mode = *p++;
+ p_info->protocol = *p++;
+ u8--;
+ plen -=NFC_EE_DISCOVER_ENTRY_LEN;
+ p_info++;
+ }
+ (*p_cback) (NFC_EE_DISCOVER_REQ_REVT, (tNFC_RESPONSE *) &ee_disc_req);
+ }
+
+}
+
+/*******************************************************************************
+**
+** Function nfc_ncif_proc_get_routing
+**
+** Description This function is called to process get routing notification
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_ncif_proc_get_routing (UINT8 *p, UINT8 len)
+{
+ tNFC_GET_ROUTING_REVT evt_data;
+ UINT8 more, num_entries, xx, yy, *pn, tl;
+ tNFC_STATUS status = NFC_STATUS_CONTINUE;
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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);
+ }
+ }
+#endif
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ 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 *p, UINT16 plen, UINT8 dest_type)
+{
+ tNFC_CONN_CB * p_cb;
+ tNFC_STATUS status;
+ tNFC_CONN_CBACK *p_cback;
+ tNFC_CONN evt_data;
+ UINT8 conn_id;
+
+ /* find the pending connection control block */
+ p_cb = nfc_find_conn_cb_by_conn_id (NFC_PEND_CONN_ID);
+ if (p_cb)
+ {
+ p += NCI_MSG_HDR_SIZE;
+ status = *p++;
+ p_cb->buff_size = *p++;
+ p_cb->num_buff = p_cb->init_credits = *p++;
+ conn_id = *p++;
+ evt_data.conn_create.status = status;
+ evt_data.conn_create.dest_type = dest_type;
+ evt_data.conn_create.id = p_cb->id;
+ evt_data.conn_create.buff_size = p_cb->buff_size;
+ evt_data.conn_create.num_buffs = p_cb->num_buff;
+ p_cback = p_cb->p_cback;
+ if (status == NCI_STATUS_OK)
+ {
+ nfc_set_conn_id (p_cb, conn_id);
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 conn_id, tNFC_STATUS status)
+{
+ tNFC_CONN evt_data;
+ tNFC_CONN_CBACK *p_cback;
+ tNFC_CONN_CB *p_cb;
+
+ p_cb = nfc_find_conn_cb_by_conn_id (conn_id);
+ if (p_cb)
+ {
+ p_cback = p_cb->p_cback;
+ nfc_free_conn_cb (p_cb);
+ evt_data.status = status;
+ if (p_cback)
+ (*p_cback) (conn_id, NFC_CONN_CLOSE_CEVT, &evt_data);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_ncif_proc_reset_rsp
+**
+** Description This function is called to process reset response/notification
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_ncif_proc_reset_rsp (UINT8 *p, BOOLEAN is_ntf)
+{
+ UINT8 status = *p++;
+
+ if (is_ntf)
+ {
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ NFC_TRACE_ERROR1 ("reset notification nfc_state :0x%x ", nfc_cb.nfc_state);
+ NFC_TRACE_ERROR1 ("reset notification!!:0x%x ", status);
+ core_reset_init_num_buff = TRUE;
+ nfc_ncif_cmd_timeout();
+ }
+ else
+ {
+ NFC_TRACE_ERROR0 ("reset notification nfc_state : #### 1");
+
+ if (nfc_cb.flags & (NFC_FL_RESTARTING|NFC_FL_POWER_CYCLE_NFCC))
+ {
+ nfc_reset_all_conn_cbs ();
+ }
+
+ /*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;
+ }
+ }
+ }
+#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)
+ {
+ 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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ NFC_TRACE_ERROR0 ("reset notification sending core init");
+#endif
+ nci_snd_core_init ();
+ }
+ else
+ {
+ NFC_TRACE_ERROR0 ("Failed to reset NFCC");
+ nfc_enabled (status, NULL);
+ }
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ }
+#endif
+}
+
+/*******************************************************************************
+**
+** Function nfc_ncif_proc_init_rsp
+**
+** Description This function is called to process init response
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_ncif_proc_init_rsp (BT_HDR *p_msg)
+{
+ UINT8 *p, status;
+ tNFC_CONN_CB * p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+#if (NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ static UINT8 retry_cnt = 0;
+ UINT8 fw_status;
+#endif
+
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+
+ /* handle init params in nfc_enabled */
+ status = *(p + NCI_MSG_HDR_SIZE);
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ fw_status = nfc_ncif_store_FWVersion(p);
+#endif
+
+ if (status == NCI_STATUS_OK
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ &&
+ fw_status == NCI_STATUS_OK
+#endif
+ )
+ {
+ p_cb->id = NFC_RF_CONN_ID;
+ p_cb->act_protocol = NCI_PROTOCOL_UNKNOWN;
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ retry_cnt = 0;
+#endif
+ nfc_set_state (NFC_STATE_W4_POST_INIT_CPLT);
+
+ nfc_cb.p_nci_init_rsp = p_msg;
+ nfc_cb.p_hal->core_initialized (p);
+ }
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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)
+ {
+ GKI_send_event (NFC_TASK, NFC_TASK_EVT_TRANSPORT_READY);
+ GKI_freebuf (p_msg);
+ }
+#endif
+ else
+ {
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ status = NCI_STATUS_FAILED;
+ retry_cnt = 0;
+#endif
+ nfc_enabled (status, NULL);
+ GKI_freebuf (p_msg);
+ }
+}
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 * p_buf)
+{
+ UINT8 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_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;
+}
+#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 (BT_HDR *p_evt)
+{
+ UINT8 *p;
+ tNFC_RESPONSE_CBACK *p_cback = nfc_cb.p_resp_cback;
+ tNFC_RESPONSE evt_data;
+
+ p_evt->offset += NCI_MSG_HDR_SIZE;
+ p_evt->len -= NCI_MSG_HDR_SIZE;
+ if (p_cback)
+ {
+ p = (UINT8 *) (p_evt + 1) + p_evt->offset;
+ evt_data.get_config.status = *p++;
+ evt_data.get_config.tlv_size = p_evt->len;
+ evt_data.get_config.p_param_tlvs = p;
+ (*p_cback) (NFC_GET_CONFIG_REVT, &evt_data);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_ncif_proc_t3t_polling_ntf
+**
+** Description Handle NCI_MSG_RF_T3T_POLLING NTF
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_ncif_proc_t3t_polling_ntf (UINT8 *p, UINT16 plen)
+{
+ UINT8 status;
+ UINT8 num_responses;
+
+ /* Pass result to RW_T3T for processing */
+ STREAM_TO_UINT8 (status, p);
+ STREAM_TO_UINT8 (num_responses, p);
+ plen-=NFC_TL_SIZE;
+ rw_t3t_handle_nci_poll_ntf (status, num_responses, (UINT8) plen, p);
+}
+
+/*******************************************************************************
+**
+** Function nfc_data_event
+**
+** Description Report Data event on the given connection control block
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_data_event (tNFC_CONN_CB * p_cb)
+{
+ BT_HDR *p_evt;
+ tNFC_DATA_CEVT data_cevt;
+ UINT8 *p;
+
+ if (p_cb->p_cback)
+ {
+ while ((p_evt = (BT_HDR *)GKI_getfirst (&p_cb->rx_q)) != NULL)
+ {
+ if (p_evt->layer_specific & NFC_RAS_FRAGMENTED)
+ {
+ /* 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 = (BT_HDR *) GKI_dequeue (&p_cb->rx_q);
+ /* report data event */
+ p_evt->offset += NCI_MSG_HDR_SIZE;
+ p_evt->len -= NCI_MSG_HDR_SIZE;
+
+ if (p_evt->layer_specific)
+ data_cevt.status = NFC_STATUS_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(NFC_NXP_NOT_OPEN_INCLUDED == 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 *) (p_evt + 1);
+ data_cevt.status = *(p + p_evt->offset + p_evt->len);
+ }
+ }
+ }
+ (*p_cb->p_cback) (p_cb->conn_id, NFC_DATA_CEVT, (tNFC_CONN *) &data_cevt);
+ p_evt = NULL;
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_ncif_proc_data
+**
+** Description Find the connection control block associated with the data
+** packet. Assemble the data packet, if needed.
+** Report the Data event.
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_ncif_proc_data (BT_HDR *p_msg)
+{
+ UINT8 *pp, cid;
+ tNFC_CONN_CB * p_cb;
+ UINT8 pbf;
+ BT_HDR *p_last;
+ UINT8 *ps, *pd;
+ UINT16 size;
+ BT_HDR *p_max = NULL;
+ UINT16 len;
+
+ pp = (UINT8 *) (p_msg+1) + p_msg->offset;
+ NFC_TRACE_DEBUG3 ("nfc_ncif_proc_data 0x%02x%02x%02x", pp[0], pp[1], pp[2]);
+ NCI_DATA_PRS_HDR (pp, pbf, cid, len);
+ p_cb = nfc_find_conn_cb_by_conn_id (cid);
+ if (p_cb && (p_msg->len >= NCI_DATA_HDR_SIZE))
+ {
+ NFC_TRACE_DEBUG1 ("nfc_ncif_proc_data len:%d", len);
+
+ p_msg->layer_specific = 0;
+ if (pbf)
+ {
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 = (BT_HDR *)GKI_getlast (&p_cb->rx_q);
+ if (p_last && (p_last->layer_specific & NFC_RAS_FRAGMENTED))
+ {
+ /* last data buffer is not last fragment, append this new packet to the last */
+ size = GKI_get_buf_size(p_last);
+ if (size < (BT_HDR_SIZE + p_last->len + p_last->offset + len))
+ {
+ /* the current size of p_last is not big enough to hold the new fragment, p_msg */
+ if (size != GKI_MAX_BUF_SIZE)
+ {
+ /* try the biggest GKI pool */
+ p_max = (BT_HDR *)GKI_getpoolbuf (GKI_MAX_BUF_SIZE_POOL_ID);
+ if (p_max)
+ {
+ /* copy the content of last buffer to the new buffer */
+ memcpy(p_max, p_last, BT_HDR_SIZE);
+ pd = (UINT8 *)(p_max + 1) + p_max->offset;
+ ps = (UINT8 *)(p_last + 1) + p_last->offset;
+ memcpy(pd, ps, p_last->len);
+
+ /* place the new buffer in the queue instead */
+ GKI_remove_from_queue (&p_cb->rx_q, p_last);
+ GKI_freebuf (p_last);
+ GKI_enqueue (&p_cb->rx_q, p_max);
+ p_last = p_max;
+ }
+ }
+ if (p_max == NULL)
+ {
+ /* 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 *)(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 *)(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 *)(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_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( get_i2c_fragmentation_enabled () == I2C_FRAGMENATATION_ENABLED)
+ {
+ nfc_cb.i2c_data_t.data_ntf_timeout = 1;
+ }
+ else
+ {
+ nfa_sys_stop_timer (&nfa_hci_cb.timer);
+ nfa_hci_rsp_timeout (NULL);
+ }
+
+ 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);
+}
+#if(NFC_NXP_ESE == TRUE && NFC_NXP_CHIP_TYPE == PN548C2)
+void disc_deact_ntf_timeout_handler(tNFC_RESPONSE_EVT event)
+{
+ 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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+/*******************************************************************************
+**
+** Function nfc_ncif_process_proprietary_rsp
+**
+** Description Process the response to avoid collision
+** while nxpCbflag is set
+**
+** Returns TRUE if proprietary response else FALSE
+**
+*******************************************************************************/
+
+BOOLEAN nfc_ncif_proc_proprietary_rsp (UINT8 mt, UINT8 gid, UINT8 oid)
+{
+ BOOLEAN stat = FALSE;
+ 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 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 0x07: /*RF FIELD INFO EVENT*/
+ stat = FALSE;
+ break;
+ case 0x09: /*NFA_EE_ACTION_NTF*/
+ stat = FALSE;
+ break;
+ default:
+ stat = TRUE;
+ break;
+ }
+ default:
+ stat = TRUE;
+ break;
+ }
+ break;
+
+ default:
+ stat = TRUE;
+ break;
+
+ }
+ return stat;
+}
+#endif
+
+#endif /* NFC_INCLUDED == TRUE*/
diff --git a/src/nfc/nfc/nfc_task.c b/src/nfc/nfc/nfc_task.c
new file mode 100644
index 0000000..a7d6486
--- /dev/null
+++ b/src/nfc/nfc/nfc_task.c
@@ -0,0 +1,507 @@
+/******************************************************************************
+ *
+ * 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"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_api.h"
+#include "nfc_hal_api.h"
+#include "nfc_int.h"
+#include "nci_hmsgs.h"
+#include "rw_int.h"
+#include "ce_int.h"
+#if (NFC_RW_ONLY == FALSE)
+#include "llcp_int.h"
+#else
+#define llcp_cleanup()
+#endif
+
+#if (defined (NFA_INCLUDED) && NFA_INCLUDED == TRUE)
+#include "nfa_sys.h"
+#include "nfa_dm_int.h"
+#endif
+
+/*******************************************************************************
+**
+** Function nfc_start_timer
+**
+** Description Start a timer for the specified amount of time.
+** NOTE: The timeout resolution is in SECONDS! (Even
+** though the timer structure field is ticks)
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_start_timer (TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout)
+{
+ BT_HDR *p_msg;
+
+ /* if timer list is currently empty, start periodic GKI timer */
+ if (nfc_cb.timer_queue.p_first == NULL)
+ {
+ /* if timer starts on other than NFC task (scritp wrapper) */
+ if (GKI_get_taskid () != NFC_TASK)
+ {
+ /* post event to start timer in NFC task */
+ if ((p_msg = (BT_HDR *) GKI_getbuf (BT_HDR_SIZE)) != NULL)
+ {
+ p_msg->event = BT_EVT_TO_START_TIMER;
+ GKI_send_msg (NFC_TASK, NFC_MBOX_ID, p_msg);
+ }
+ }
+ else
+ {
+ /* Start nfc_task 1-sec resolution timer */
+ GKI_start_timer (NFC_TIMER_ID, GKI_SECS_TO_TICKS (1), TRUE);
+ }
+ }
+
+ GKI_remove_from_timer_list (&nfc_cb.timer_queue, p_tle);
+
+ p_tle->event = type;
+ p_tle->ticks = timeout; /* Save the number of seconds for the timer */
+
+ GKI_add_to_timer_list (&nfc_cb.timer_queue, p_tle);
+}
+
+/*******************************************************************************
+**
+** Function nfc_remaining_time
+**
+** Description Return amount of time to expire
+**
+** Returns time in second
+**
+*******************************************************************************/
+UINT32 nfc_remaining_time (TIMER_LIST_ENT *p_tle)
+{
+ return (GKI_get_remaining_ticks (&nfc_cb.timer_queue, p_tle));
+}
+
+/*******************************************************************************
+**
+** Function nfc_process_timer_evt
+**
+** Description Process nfc GKI timer event
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_process_timer_evt (void)
+{
+ TIMER_LIST_ENT *p_tle;
+
+ GKI_update_timer_list (&nfc_cb.timer_queue, 1);
+
+ while ((nfc_cb.timer_queue.p_first) && (!nfc_cb.timer_queue.p_first->ticks))
+ {
+ p_tle = nfc_cb.timer_queue.p_first;
+ GKI_remove_from_timer_list (&nfc_cb.timer_queue, p_tle);
+
+ switch (p_tle->event)
+ {
+ case NFC_TTYPE_NCI_WAIT_RSP:
+ nfc_ncif_cmd_timeout();
+ break;
+
+ case NFC_TTYPE_WAIT_2_DEACTIVATE:
+ nfc_wait_2_deactivate_timeout ();
+ break;
+ case NFC_TTYPE_NCI_WAIT_DATA_NTF:
+ {
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ 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();
+#endif
+ break;
+ }
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ 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 type, UINT32 timeout)
+{
+ BT_HDR *p_msg;
+
+ /* if timer list is currently empty, start periodic GKI timer */
+ if (nfc_cb.quick_timer_queue.p_first == NULL)
+ {
+ /* if timer starts on other than NFC task (scritp wrapper) */
+ if (GKI_get_taskid () != NFC_TASK)
+ {
+ /* post event to start timer in NFC task */
+ if ((p_msg = (BT_HDR *) GKI_getbuf (BT_HDR_SIZE)) != NULL)
+ {
+ p_msg->event = BT_EVT_TO_START_QUICK_TIMER;
+ GKI_send_msg (NFC_TASK, NFC_MBOX_ID, p_msg);
+ }
+ }
+ else
+ {
+ /* Quick-timer is required for LLCP */
+ GKI_start_timer (NFC_QUICK_TIMER_ID, ((GKI_SECS_TO_TICKS (1) / QUICK_TIMER_TICKS_PER_SEC)), TRUE);
+ }
+ }
+
+ GKI_remove_from_timer_list (&nfc_cb.quick_timer_queue, p_tle);
+
+ p_tle->event = type;
+ p_tle->ticks = timeout; /* Save the number of ticks for the timer */
+
+ GKI_add_to_timer_list (&nfc_cb.quick_timer_queue, p_tle);
+}
+
+
+
+
+/*******************************************************************************
+**
+** Function nfc_stop_quick_timer
+**
+** Description Stop a timer.
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_stop_quick_timer (TIMER_LIST_ENT *p_tle)
+{
+ GKI_remove_from_timer_list (&nfc_cb.quick_timer_queue, p_tle);
+
+ /* if timer list is empty stop periodic GKI timer */
+ if (nfc_cb.quick_timer_queue.p_first == NULL)
+ {
+ GKI_stop_timer (NFC_QUICK_TIMER_ID);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_process_quick_timer_evt
+**
+** Description Process quick timer event
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_process_quick_timer_evt (void)
+{
+ TIMER_LIST_ENT *p_tle;
+
+ GKI_update_timer_list (&nfc_cb.quick_timer_queue, 1);
+
+ while ((nfc_cb.quick_timer_queue.p_first) && (!nfc_cb.quick_timer_queue.p_first->ticks))
+ {
+ p_tle = nfc_cb.quick_timer_queue.p_first;
+ GKI_remove_from_timer_list (&nfc_cb.quick_timer_queue, p_tle);
+
+ switch (p_tle->event)
+ {
+#if (NFC_RW_ONLY == FALSE)
+ case NFC_TTYPE_LLCP_LINK_MANAGER:
+ case NFC_TTYPE_LLCP_LINK_INACT:
+ case NFC_TTYPE_LLCP_DATA_LINK:
+ case NFC_TTYPE_LLCP_DELAY_FIRST_PDU:
+ llcp_process_timeout (p_tle);
+ break;
+#endif
+ case NFC_TTYPE_RW_T1T_RESPONSE:
+ rw_t1t_process_timeout (p_tle);
+ break;
+ case NFC_TTYPE_RW_T2T_RESPONSE:
+ rw_t2t_process_timeout (p_tle);
+ break;
+ case NFC_TTYPE_RW_T3T_RESPONSE:
+ rw_t3t_process_timeout (p_tle);
+ break;
+ case NFC_TTYPE_RW_T4T_RESPONSE:
+ rw_t4t_process_timeout (p_tle);
+ break;
+ case NFC_TTYPE_RW_I93_RESPONSE:
+ rw_i93_process_timeout (p_tle);
+ break;
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ 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;
+#endif
+#if (NFC_RW_ONLY == FALSE)
+ case NFC_TTYPE_CE_T4T_UPDATE:
+ ce_t4t_process_timeout (p_tle);
+ 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)
+{
+ BT_HDR *p_msg;
+
+ /* Free any messages still in the mbox */
+ while ((p_msg = (BT_HDR *) GKI_read_mbox (NFC_MBOX_ID)) != NULL)
+ {
+ GKI_freebuf (p_msg);
+ }
+
+ nfc_gen_cleanup ();
+
+ if (nfc_cb.flags & NFC_FL_POWER_OFF_SLEEP)
+ {
+ nfc_set_state (NFC_STATE_W4_HAL_CLOSE);
+ nfc_cb.p_hal->close();
+ }
+ else if (nfc_cb.flags & NFC_FL_POWER_CYCLE_NFCC)
+ {
+ nfc_set_state (NFC_STATE_W4_HAL_OPEN);
+ nfc_cb.p_hal->power_cycle();
+ }
+ else
+ {
+ nfc_set_state (NFC_STATE_W4_HAL_CLOSE);
+ nfc_cb.p_hal->close();
+
+ /* Perform final clean up */
+ llcp_cleanup ();
+
+ /* Stop the timers */
+ GKI_stop_timer (NFC_TIMER_ID);
+ GKI_stop_timer (NFC_QUICK_TIMER_ID);
+#if (defined (NFA_INCLUDED) && NFA_INCLUDED == TRUE)
+ GKI_stop_timer (NFA_TIMER_ID);
+#endif
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_task
+**
+** Description NFC event processing task
+**
+** Returns nothing
+**
+*******************************************************************************/
+UINT32 nfc_task (UINT32 param)
+{
+ UINT16 event;
+ BT_HDR *p_msg;
+ BOOLEAN free_buf;
+
+ /* Initialize the nfc control block */
+ memset (&nfc_cb, 0, sizeof (tNFC_CB));
+ nfc_cb.trace_level = NFC_INITIAL_TRACE_LEVEL;
+
+ NFC_TRACE_DEBUG0 ("NFC_TASK started.");
+
+ /* main loop */
+ while (TRUE)
+ {
+ event = GKI_wait (0xFFFF, 0);
+
+ /* Handle NFC_TASK_EVT_TRANSPORT_READY from NFC HAL */
+ if (event & NFC_TASK_EVT_TRANSPORT_READY)
+ {
+ NFC_TRACE_DEBUG0 ("NFC_TASK got NFC_TASK_EVT_TRANSPORT_READY.");
+
+ /* Reset the NFC controller. */
+ nfc_set_state (NFC_STATE_CORE_INIT);
+ nci_snd_core_reset (NCI_RESET_TYPE_RESET_CFG);
+ }
+
+ if (event & NFC_MBOX_EVT_MASK)
+ {
+ /* Process all incoming NCI messages */
+ while ((p_msg = (BT_HDR *) GKI_read_mbox (NFC_MBOX_ID)) != NULL)
+ {
+ free_buf = TRUE;
+
+ /* Determine the input message type. */
+ switch (p_msg->event & BT_EVT_MASK)
+ {
+ case BT_EVT_TO_NFC_NCI:
+ free_buf = nfc_ncif_process_event (p_msg);
+ break;
+
+ case BT_EVT_TO_START_TIMER :
+ /* Start nfc_task 1-sec resolution timer */
+ GKI_start_timer (NFC_TIMER_ID, GKI_SECS_TO_TICKS (1), TRUE);
+ break;
+
+ case BT_EVT_TO_START_QUICK_TIMER :
+ /* Quick-timer is required for LLCP */
+ GKI_start_timer (NFC_QUICK_TIMER_ID, ((GKI_SECS_TO_TICKS (1) / QUICK_TIMER_TICKS_PER_SEC)), TRUE);
+ break;
+
+ case BT_EVT_TO_NFC_MSGS:
+ nfc_main_handle_hal_evt ((tNFC_HAL_EVT_MSG*)p_msg);
+ break;
+
+ default:
+ NFC_TRACE_DEBUG1 ("nfc_task: unhandle mbox message, event=%04x", p_msg->event);
+ break;
+ }
+
+ if (free_buf)
+ {
+ GKI_freebuf (p_msg);
+ }
+ }
+ }
+
+ /* Process gki timer tick */
+ if (event & NFC_TIMER_EVT_MASK)
+ {
+ nfc_process_timer_evt ();
+ }
+
+ /* Process quick timer tick */
+ if (event & NFC_QUICK_TIMER_EVT_MASK)
+ {
+ nfc_process_quick_timer_evt ();
+ }
+
+#if (defined (NFA_INCLUDED) && NFA_INCLUDED == TRUE)
+ if (event & NFA_MBOX_EVT_MASK)
+ {
+ while ((p_msg = (BT_HDR *) GKI_read_mbox (NFA_MBOX_ID)) != NULL)
+ {
+ nfa_sys_event (p_msg);
+ }
+ }
+
+ if (event & NFA_TIMER_EVT_MASK)
+ {
+ nfa_sys_timer_update ();
+ }
+#endif
+
+ }
+
+
+ NFC_TRACE_DEBUG0 ("nfc_task terminated");
+
+ GKI_exit_task (GKI_get_taskid ());
+ return 0;
+}
+
+#endif /* NFC_INCLUDED == TRUE */
diff --git a/src/nfc/nfc/nfc_test.c b/src/nfc/nfc/nfc_test.c
new file mode 100644
index 0000000..dc97ef6
--- /dev/null
+++ b/src/nfc/nfc/nfc_test.c
@@ -0,0 +1,73 @@
+/******************************************************************************
+ *
+ * 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"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_int.h"
+#include "nci_hmsgs.h"
+
+/****************************************************************************
+** Declarations
+****************************************************************************/
+
+/*******************************************************************************
+**
+** Function NFC_TestLoopback
+**
+** Description This function is called to send the given data packet
+** to NFCC for loopback test.
+** When loopback data is received from NFCC, tNFC_TEST_CBACK .
+** reports a NFC_LOOPBACK_TEVT.
+**
+** Parameters p_data - the data packet
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_TestLoopback (BT_HDR *p_data)
+{
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ tNFC_CONN_CB *p_cb = nfc_find_conn_cb_by_handle (NCI_TEST_ID);
+
+ if (p_data && p_cb && (p_data->offset >= (NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE)))
+ {
+ status = nfc_ncif_send_data (p_cb, p_data);
+ }
+
+ if (status != NFC_STATUS_OK)
+ GKI_freebuf (p_data);
+
+ return status;
+}
+
+
+
+
+#endif /* NFC_INCLUDED == TRUE */
diff --git a/src/nfc/nfc/nfc_utils.c b/src/nfc/nfc/nfc_utils.c
new file mode 100644
index 0000000..b413d46
--- /dev/null
+++ b/src/nfc/nfc/nfc_utils.c
@@ -0,0 +1,214 @@
+/******************************************************************************
+ *
+ * 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"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_int.h"
+
+
+/*******************************************************************************
+**
+** Function nfc_alloc_conn_cb
+**
+** Description This function is called to allocation a control block for
+** NCI logical connection
+**
+** Returns The allocated control block or NULL
+**
+*******************************************************************************/
+tNFC_CONN_CB * nfc_alloc_conn_cb (tNFC_CONN_CBACK *p_cback)
+{
+ int xx, max = NCI_MAX_CONN_CBS;
+ tNFC_CONN_CB *p_conn_cb = NULL;
+
+ NFC_CHECK_MAX_CONN ();
+ for (xx = 0; xx < max; xx++)
+ {
+ if (nfc_cb.conn_cb[xx].conn_id == NFC_ILLEGAL_CONN_ID)
+ {
+ nfc_cb.conn_cb[xx].conn_id = NFC_PEND_CONN_ID; /* to indicate this cb is used */
+ p_conn_cb = &nfc_cb.conn_cb[xx];
+ p_conn_cb->p_cback = p_cback;
+ break;
+ }
+ }
+ return p_conn_cb;
+}
+
+/*******************************************************************************
+**
+** Function nfc_set_conn_id
+**
+** Description This function is called to set the connection id to the
+** connection control block and the id mapping table
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_set_conn_id (tNFC_CONN_CB * p_cb, UINT8 conn_id)
+{
+ UINT8 handle;
+
+ if (p_cb == NULL)
+ return;
+
+ p_cb->conn_id = conn_id;
+ handle = (UINT8) (p_cb - nfc_cb.conn_cb + 1);
+ nfc_cb.conn_id[conn_id] = handle;
+ NFC_TRACE_DEBUG2 ("nfc_set_conn_id conn_id:%d, handle:%d", conn_id, handle);
+}
+
+/*******************************************************************************
+**
+** Function nfc_find_conn_cb_by_handle
+**
+** Description This function is called to locate the control block for
+** loopback test.
+**
+** Returns The loopback test control block or NULL
+**
+*******************************************************************************/
+tNFC_CONN_CB * nfc_find_conn_cb_by_handle (UINT8 id)
+{
+ int xx;
+ tNFC_CONN_CB *p_conn_cb = NULL;
+
+ for (xx = 0; xx < NCI_MAX_CONN_CBS; xx++)
+ {
+ if (nfc_cb.conn_cb[xx].id == id)
+ {
+ p_conn_cb = &nfc_cb.conn_cb[xx];
+ break;
+ }
+ }
+ return p_conn_cb;
+}
+
+/*******************************************************************************
+**
+** Function nfc_find_conn_cb_by_conn_id
+**
+** Description This function is called to locate the control block for
+** the given connection id
+**
+** Returns The control block or NULL
+**
+*******************************************************************************/
+tNFC_CONN_CB * nfc_find_conn_cb_by_conn_id (UINT8 conn_id)
+{
+ tNFC_CONN_CB *p_conn_cb = NULL;
+ UINT8 handle;
+ UINT8 id;
+ int xx;
+
+ if (conn_id == NFC_PEND_CONN_ID)
+ {
+ for (xx = 0; xx < NCI_MAX_CONN_CBS; xx++)
+ {
+ if (nfc_cb.conn_cb[xx].conn_id == NFC_PEND_CONN_ID)
+ {
+ p_conn_cb = &nfc_cb.conn_cb[xx];
+ break;
+ }
+ }
+ }
+ else
+ {
+ id = conn_id & NFC_CONN_ID_ID_MASK;
+ if (id < NFC_MAX_CONN_ID)
+ {
+ handle = nfc_cb.conn_id[id];
+ if (handle > 0)
+ p_conn_cb = &nfc_cb.conn_cb[handle - 1];
+ }
+ }
+
+ return p_conn_cb;
+}
+
+/*******************************************************************************
+**
+** Function nfc_free_conn_cb
+**
+** Description This function is called to free the control block and
+** resources and id mapping table
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_free_conn_cb (tNFC_CONN_CB *p_cb)
+{
+ void *p_buf;
+
+ if (p_cb == NULL)
+ return;
+
+ while ((p_buf = GKI_dequeue (&p_cb->rx_q)) != NULL)
+ GKI_freebuf (p_buf);
+
+ while ((p_buf = GKI_dequeue (&p_cb->tx_q)) != NULL)
+ GKI_freebuf (p_buf);
+
+ nfc_cb.conn_id[p_cb->conn_id] = 0;
+ p_cb->p_cback = NULL;
+ p_cb->conn_id = NFC_ILLEGAL_CONN_ID;
+}
+
+/*******************************************************************************
+**
+** Function nfc_reset_all_conn_cbs
+**
+** Description This function is called to free all the control blocks and
+** resources and id mapping table
+**
+** Returns void
+**
+*******************************************************************************/
+NFC_API extern void nfc_reset_all_conn_cbs (void)
+{
+ int xx;
+ tNFC_CONN_CB *p_conn_cb = &nfc_cb.conn_cb[0];
+ tNFC_DEACTIVATE_DEVT deact;
+
+ deact.status = NFC_STATUS_NOT_INITIALIZED;
+ deact.type = NFC_DEACTIVATE_TYPE_IDLE;
+ deact.is_ntf = TRUE;
+ for (xx = 0; xx < NCI_MAX_CONN_CBS; xx++, p_conn_cb++)
+ {
+ if (p_conn_cb->conn_id != NFC_ILLEGAL_CONN_ID)
+ {
+ if (p_conn_cb->p_cback)
+ (*p_conn_cb->p_cback) (p_conn_cb->conn_id, NFC_DEACTIVATE_CEVT, (tNFC_CONN *) &deact);
+ nfc_free_conn_cb (p_conn_cb);
+ }
+ }
+}
+
+
+#endif /* NFC_INCLUDED == TRUE */
diff --git a/src/nfc/nfc/nfc_vs.c b/src/nfc/nfc/nfc_vs.c
new file mode 100644
index 0000000..3fa0c2e
--- /dev/null
+++ b/src/nfc/nfc/nfc_vs.c
@@ -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.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ * 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"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_int.h"
+
+/****************************************************************************
+** Declarations
+****************************************************************************/
+
+
+
+/*******************************************************************************
+**
+** Function NFC_RegVSCback
+**
+** Description This function is called to register or de-register a callback
+** function to receive Proprietary NCI response and notification
+** events.
+** The maximum number of callback functions allowed is NFC_NUM_VS_CBACKS
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_RegVSCback (BOOLEAN is_register,
+ tNFC_VS_CBACK *p_cback)
+{
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ int i;
+
+ if (is_register)
+ {
+ for (i = 0; i < NFC_NUM_VS_CBACKS; i++)
+ {
+ /* find an empty spot to hold the callback function */
+ if (nfc_cb.p_vs_cb[i] == NULL)
+ {
+ nfc_cb.p_vs_cb[i] = p_cback;
+ status = NFC_STATUS_OK;
+ break;
+ }
+ }
+ }
+ else
+ {
+ for (i = 0; i < NFC_NUM_VS_CBACKS; i++)
+ {
+ /* find the callback to de-register */
+ if (nfc_cb.p_vs_cb[i] == p_cback)
+ {
+ nfc_cb.p_vs_cb[i] = NULL;
+ status = NFC_STATUS_OK;
+ break;
+ }
+ }
+ }
+ return status;
+}
+
+
+/*******************************************************************************
+**
+** Function NFC_SendVsCommand
+**
+** Description This function is called to send the given vendor specific
+** command to NFCC. The response from NFCC is reported to the
+** given tNFC_VS_CBACK as (oid).
+**
+** Parameters oid - The opcode of the VS command.
+** p_data - The parameters for the VS command
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_SendVsCommand (UINT8 oid,
+ BT_HDR *p_data,
+ tNFC_VS_CBACK *p_cback)
+{
+ tNFC_STATUS status = NFC_STATUS_OK;
+ UINT8 *pp;
+
+ /* Allow VSC with 0-length payload */
+ if (p_data == NULL)
+ {
+ p_data = NCI_GET_CMD_BUF (0);
+ if (p_data)
+ {
+ p_data->offset = NCI_VSC_MSG_HDR_SIZE;
+ p_data->len = 0;
+ }
+ }
+
+ /* Validate parameters */
+ if ((p_data == NULL) || (p_data->offset < NCI_VSC_MSG_HDR_SIZE) || (p_data->len > NCI_MAX_VSC_SIZE))
+ {
+ NFC_TRACE_ERROR1 ("buffer offset must be >= %d", NCI_VSC_MSG_HDR_SIZE);
+ if (p_data)
+ GKI_freebuf (p_data);
+ return NFC_STATUS_INVALID_PARAM;
+ }
+
+ p_data->event = BT_EVT_TO_NFC_NCI;
+ p_data->layer_specific = NFC_WAIT_RSP_VSC;
+ /* save the callback function in the BT_HDR, to receive the response */
+ ((tNFC_NCI_VS_MSG *) p_data)->p_cback = p_cback;
+
+ p_data->offset -= NCI_MSG_HDR_SIZE;
+ pp = (UINT8 *) (p_data + 1) + p_data->offset;
+ NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_PROP);
+ NCI_MSG_BLD_HDR1 (pp, oid);
+ *pp = (UINT8) p_data->len;
+ p_data->len += NCI_MSG_HDR_SIZE;
+ nfc_ncif_check_cmd_queue (p_data);
+ return status;
+}
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 (BT_HDR *p_data,
+ tNFC_VS_CBACK *p_cback)
+{
+ tNFC_STATUS status = NFC_STATUS_OK;
+ UINT8 *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 BT_HDR, to receive the response */
+ ((tNFC_NCI_VS_MSG *) p_data)->p_cback = p_cback;
+ pp = (UINT8 *) (p_data + 1) + p_data->offset;
+
+ nfc_ncif_check_cmd_queue (p_data);
+ return status;
+}
+#endif
+
+#endif /* NFC_INCLUDED == TRUE */
diff --git a/src/nfc/tags/ce_main.c b/src/nfc/tags/ce_main.c
new file mode 100644
index 0000000..d56015c
--- /dev/null
+++ b/src/nfc/tags/ce_main.c
@@ -0,0 +1,150 @@
+/******************************************************************************
+ *
+ * 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"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_api.h"
+#include "nci_hmsgs.h"
+#include "ce_api.h"
+#include "ce_int.h"
+#include "gki.h"
+
+tCE_CB ce_cb;
+
+/*******************************************************************************
+*******************************************************************************/
+void ce_init (void)
+{
+ memset (&ce_cb, 0, sizeof (tCE_CB));
+ ce_cb.trace_level = NFC_INITIAL_TRACE_LEVEL;
+
+ /* Initialize tag-specific fields of ce control block */
+ ce_t3t_init ();
+}
+
+/*******************************************************************************
+**
+** Function CE_SendRawFrame
+**
+** Description This function sends a raw frame to the peer device.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS CE_SendRawFrame (UINT8 *p_raw_data, UINT16 data_len)
+{
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ BT_HDR *p_data;
+ UINT8 *p;
+
+ if (ce_cb.p_cback)
+ {
+ /* a valid opcode for RW */
+ p_data = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+ if (p_data)
+ {
+ p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p = (UINT8 *) (p_data + 1) + p_data->offset;
+ memcpy (p, p_raw_data, data_len);
+ p_data->len = data_len;
+ CE_TRACE_EVENT1 ("CE SENT raw frame (0x%x)", data_len);
+ status = NFC_SendData (NFC_RF_CONN_ID, p_data);
+ }
+
+ }
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function CE_SetActivatedTagType
+**
+** Description This function selects the tag type for CE mode.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS CE_SetActivatedTagType (tNFC_ACTIVATE_DEVT *p_activate_params, UINT16 t3t_system_code, tCE_CBACK *p_cback)
+{
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ tNFC_PROTOCOL protocol = p_activate_params->protocol;
+
+ CE_TRACE_API1 ("CE_SetActivatedTagType protocol:%d", protocol);
+
+ switch (protocol)
+ {
+ case NFC_PROTOCOL_T1T:
+ case NFC_PROTOCOL_T2T:
+ return NFC_STATUS_FAILED;
+
+ case NFC_PROTOCOL_T3T: /* Type3Tag - NFC-F */
+ /* store callback function before NFC_SetStaticRfCback () */
+ ce_cb.p_cback = p_cback;
+ status = ce_select_t3t (t3t_system_code, p_activate_params->rf_tech_param.param.lf.nfcid2);
+ break;
+
+ case NFC_PROTOCOL_ISO_DEP: /* ISODEP/4A,4B- NFC-A or NFC-B */
+ /* store callback function before NFC_SetStaticRfCback () */
+ ce_cb.p_cback = p_cback;
+ status = ce_select_t4t ();
+ break;
+
+ default:
+ CE_TRACE_ERROR0 ("CE_SetActivatedTagType Invalid protocol");
+ return NFC_STATUS_FAILED;
+ }
+
+ if (status != NFC_STATUS_OK)
+ {
+ NFC_SetStaticRfCback (NULL);
+ ce_cb.p_cback = NULL;
+ }
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function CE_SetTraceLevel
+**
+** Description This function sets the trace level for Card Emulation mode.
+** If called with a value of 0xFF,
+** it simply returns the current trace level.
+**
+** Returns The new or current trace level
+**
+*******************************************************************************/
+UINT8 CE_SetTraceLevel (UINT8 new_level)
+{
+ if (new_level != 0xFF)
+ ce_cb.trace_level = new_level;
+
+ return (ce_cb.trace_level);
+}
+
+#endif /* NFC_INCLUDED == TRUE */
diff --git a/src/nfc/tags/ce_t3t.c b/src/nfc/tags/ce_t3t.c
new file mode 100644
index 0000000..97de9ac
--- /dev/null
+++ b/src/nfc/tags/ce_t3t.c
@@ -0,0 +1,1062 @@
+/******************************************************************************
+ *
+ * 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"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_api.h"
+#include "nfc_int.h"
+#include "ce_api.h"
+#include "ce_int.h"
+#include "tags_int.h"
+#include "gki.h"
+
+enum {
+ CE_T3T_COMMAND_INVALID,
+ CE_T3T_COMMAND_NFC_FORUM,
+ CE_T3T_COMMAND_FELICA
+};
+
+/* T3T CE states */
+enum {
+ CE_T3T_STATE_NOT_ACTIVATED,
+ CE_T3T_STATE_IDLE,
+ CE_T3T_STATE_UPDATING
+};
+
+/* Bitmasks to indicate type of UPDATE */
+#define CE_T3T_UPDATE_FL_NDEF_UPDATE_START 0x01
+#define CE_T3T_UPDATE_FL_NDEF_UPDATE_CPLT 0x02
+#define CE_T3T_UPDATE_FL_UPDATE 0x04
+
+/*******************************************************************************
+* Static constant definitions
+*******************************************************************************/
+static const UINT8 CE_DEFAULT_LF_PMM[NCI_T3T_PMM_LEN] = {0x20, 0x79, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; /* Default PMm param */
+
+/*******************************************************************************
+**
+** Function ce_t3t_init
+**
+** Description Initialize tag-specific fields of ce control block
+**
+** Returns none
+**
+*******************************************************************************/
+void ce_t3t_init (void)
+{
+ memcpy (ce_cb.mem.t3t.local_pmm, CE_DEFAULT_LF_PMM, NCI_T3T_PMM_LEN);
+ ce_cb.mem.t3t.ndef_info.nbr = CE_T3T_DEFAULT_CHECK_MAXBLOCKS;
+ ce_cb.mem.t3t.ndef_info.nbw = CE_T3T_DEFAULT_UPDATE_MAXBLOCKS;
+}
+
+/*******************************************************************************
+**
+** Function ce_t3t_send_to_lower
+**
+** Description Send C-APDU to lower layer
+**
+** Returns none
+**
+*******************************************************************************/
+void ce_t3t_send_to_lower (BT_HDR *p_msg)
+{
+ UINT8 *p;
+
+ /* Set NFC-F SoD field (payload len + 1) */
+ p_msg->offset -= 1; /* Point to SoD field */
+ p = (UINT8 *) (p_msg+1) + p_msg->offset;
+ UINT8_TO_STREAM (p, (p_msg->len+1));
+ p_msg->len += 1; /* Increment len to include SoD */
+
+#if (BT_TRACE_PROTOCOL == TRUE)
+ DispT3TagMessage (p_msg, FALSE);
+#endif
+
+ if (NFC_SendData (NFC_RF_CONN_ID, p_msg) != NFC_STATUS_OK)
+ {
+ CE_TRACE_ERROR0 ("ce_t3t_send_to_lower (): NFC_SendData () failed");
+ }
+}
+
+/*******************************************************************************
+**
+** Function ce_t3t_is_valid_opcode
+**
+** Description Valid opcode
+**
+** Returns Type of command
+**
+*******************************************************************************/
+UINT8 ce_t3t_is_valid_opcode (UINT8 cmd_id)
+{
+ UINT8 retval = CE_T3T_COMMAND_INVALID;
+
+ if ( (cmd_id == T3T_MSG_OPC_CHECK_CMD)
+ ||(cmd_id == T3T_MSG_OPC_UPDATE_CMD) )
+ {
+ retval = CE_T3T_COMMAND_NFC_FORUM;
+ }
+ else if ( (cmd_id == T3T_MSG_OPC_POLL_CMD)
+ ||(cmd_id == T3T_MSG_OPC_REQ_SERVICE_CMD)
+ ||(cmd_id == T3T_MSG_OPC_REQ_RESPONSE_CMD)
+ ||(cmd_id == T3T_MSG_OPC_REQ_SYSTEMCODE_CMD) )
+ {
+ retval = CE_T3T_COMMAND_FELICA;
+ }
+
+ return (retval);
+}
+
+/*****************************************************************************
+**
+** Function ce_t3t_get_rsp_buf
+**
+** Description Get a buffer for sending T3T messages
+**
+** Returns BT_HDR *
+**
+*****************************************************************************/
+BT_HDR *ce_t3t_get_rsp_buf (void)
+{
+ BT_HDR *p_cmd_buf;
+
+ if ((p_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_CE_POOL_ID)) != NULL)
+ {
+ /* Reserve offset for NCI_DATA_HDR and NFC-F Sod (LEN) field */
+ p_cmd_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + 1;
+ p_cmd_buf->len = 0;
+ }
+
+ return (p_cmd_buf);
+}
+
+/*******************************************************************************
+**
+** Function ce_t3t_send_rsp
+**
+** Description Send response to reader/writer
+**
+** Returns none
+**
+*******************************************************************************/
+void ce_t3t_send_rsp (tCE_CB *p_ce_cb, UINT8 *p_nfcid2, UINT8 opcode, UINT8 status1, UINT8 status2)
+{
+ tCE_T3T_MEM *p_cb = &p_ce_cb->mem.t3t;
+ BT_HDR *p_rsp_msg;
+ UINT8 *p_dst, *p_rsp_start;
+
+ /* If p_nfcid2 is NULL, then used activated NFCID2 */
+ if (p_nfcid2 == NULL)
+ {
+ p_nfcid2 = p_cb->local_nfcid2;
+ }
+
+ if ((p_rsp_msg = ce_t3t_get_rsp_buf ()) != NULL)
+ {
+ p_dst = p_rsp_start = (UINT8 *) (p_rsp_msg+1) + p_rsp_msg->offset;
+
+ /* Response Code */
+ UINT8_TO_STREAM (p_dst, opcode);
+
+ /* Manufacturer ID */
+ ARRAY_TO_STREAM (p_dst, p_nfcid2, NCI_RF_F_UID_LEN);
+
+ /* Status1 and Status2 */
+ UINT8_TO_STREAM (p_dst, status1);
+ UINT8_TO_STREAM (p_dst, status2);
+
+ p_rsp_msg->len = (UINT16) (p_dst - p_rsp_start);
+ ce_t3t_send_to_lower (p_rsp_msg);
+ }
+ else
+ {
+ CE_TRACE_ERROR0 ("CE: Unable to allocat buffer for response message");
+ }
+}
+
+/*******************************************************************************
+**
+** Function ce_t3t_handle_update_cmd
+**
+** Description Handle UPDATE command from reader/writer
+**
+** Returns none
+**
+*******************************************************************************/
+void ce_t3t_handle_update_cmd (tCE_CB *p_ce_cb, BT_HDR *p_cmd_msg)
+{
+ tCE_T3T_MEM *p_cb = &p_ce_cb->mem.t3t;
+ UINT8 *p_temp;
+ UINT8 *p_block_list = p_cb->cur_cmd.p_block_list_start;
+ UINT8 *p_block_data = p_cb->cur_cmd.p_block_data_start;
+ UINT8 i, j, bl0;
+ UINT16 block_number, service_code, checksum, checksum_rx;
+ UINT32 newlen_hiword;
+ tCE_T3T_NDEF_INFO ndef_info;
+ tNFC_STATUS nfc_status = NFC_STATUS_OK;
+ UINT8 update_flags = 0;
+ tCE_UPDATE_INFO update_info;
+
+ /* If in idle state, notify app that update is starting */
+ if (p_cb->state == CE_T3T_STATE_IDLE)
+ {
+ p_cb->state = CE_T3T_STATE_UPDATING;
+ }
+
+ for (i = 0; i < p_cb->cur_cmd.num_blocks; i++)
+ {
+ /* Read byte0 of block list */
+ STREAM_TO_UINT8 (bl0, p_block_list);
+
+ if (bl0 & T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT)
+ {
+ STREAM_TO_UINT8 (block_number, p_block_list);
+ }
+ else
+ {
+ STREAM_TO_UINT16 (block_number, p_block_list);
+ }
+
+ /* Read the block from memory */
+ service_code = p_cb->cur_cmd.service_code_list[bl0 & T3T_MSG_SERVICE_LIST_MASK];
+
+ /* Reject UPDATE command if service code=T3T_MSG_NDEF_SC_RO */
+ if (service_code == T3T_MSG_NDEF_SC_RO)
+ {
+ /* Error: invalid block number to update */
+ CE_TRACE_ERROR0 ("CE: UPDATE request using read-only service");
+ nfc_status = NFC_STATUS_FAILED;
+ break;
+ }
+
+ /* Check for NDEF */
+ if (service_code == T3T_MSG_NDEF_SC_RW)
+ {
+ if (p_cb->cur_cmd.num_blocks > p_cb->ndef_info.nbw)
+ {
+ CE_TRACE_ERROR2 ("CE: Requested too many blocks to update (requested: %i, max: %i)", p_cb->cur_cmd.num_blocks, p_cb->ndef_info.nbw);
+ nfc_status = NFC_STATUS_FAILED;
+ break;
+ }
+ else if (p_cb->ndef_info.rwflag == T3T_MSG_NDEF_RWFLAG_RO)
+ {
+ CE_TRACE_ERROR0 ("CE: error: write-request to read-only NDEF message.");
+ nfc_status = NFC_STATUS_FAILED;
+ break;
+ }
+ else if (block_number == 0)
+ {
+ CE_TRACE_DEBUG2 ("CE: Update sc 0x%04x block %i.", service_code, block_number);
+
+ /* Special caes: NDEF block0 is the ndef attribute block */
+ p_temp = p_block_data;
+ STREAM_TO_UINT8 (ndef_info.version, p_block_data);
+ p_block_data+=8; /* Ignore nbr,nbw,maxb,and reserved (reader/writer not allowed to update this) */
+ STREAM_TO_UINT8 (ndef_info.writef, p_block_data);
+ p_block_data++; /* Ignore rwflag (reader/writer not allowed to update this) */
+ STREAM_TO_UINT8 (newlen_hiword, p_block_data);
+ BE_STREAM_TO_UINT16 (ndef_info.ln, p_block_data);
+ ndef_info.ln += (newlen_hiword<<16);
+ BE_STREAM_TO_UINT16 (checksum_rx, p_block_data);
+
+ checksum=0;
+ for (j=0; j<T3T_MSG_NDEF_ATTR_INFO_SIZE; j++)
+ {
+ checksum+=p_temp[j];
+ }
+
+ /* Compare calcuated checksum with received checksum */
+ if (checksum != checksum_rx)
+ {
+ CE_TRACE_ERROR0 ("CE: Checksum failed for NDEF attribute block.");
+ nfc_status = NFC_STATUS_FAILED;
+ }
+ else
+ {
+ /* Update NDEF attribute block (only allowed to update current length and writef fields) */
+ p_cb->ndef_info.scratch_ln = ndef_info.ln;
+ p_cb->ndef_info.scratch_writef = ndef_info.writef;
+
+ /* If writef=0 indicates completion of NDEF update */
+ if (ndef_info.writef == 0)
+ {
+ update_flags |= CE_T3T_UPDATE_FL_NDEF_UPDATE_CPLT;
+ }
+ /* writef=1 indicates start of NDEF update */
+ else
+ {
+ update_flags |= CE_T3T_UPDATE_FL_NDEF_UPDATE_START;
+ }
+ }
+ }
+ else
+ {
+ CE_TRACE_DEBUG2 ("CE: Udpate sc 0x%04x block %i.", service_code, block_number);
+
+ /* Verify that block_number is within NDEF memory */
+ if (block_number > p_cb->ndef_info.nmaxb)
+ {
+ /* Error: invalid block number to update */
+ CE_TRACE_ERROR2 ("CE: Requested invalid NDEF block number to update %i (max is %i).", block_number, p_cb->ndef_info.nmaxb);
+ nfc_status = NFC_STATUS_FAILED;
+ break;
+ }
+ else
+ {
+ /* Update NDEF memory block */
+ STREAM_TO_ARRAY ((&p_cb->ndef_info.p_scratch_buf[(block_number-1) * T3T_MSG_BLOCKSIZE]), p_block_data, T3T_MSG_BLOCKSIZE);
+ }
+
+ /* Set flag to indicate that this UPDATE contained at least one block */
+ update_flags |= CE_T3T_UPDATE_FL_UPDATE;
+ }
+ }
+ else
+ {
+ /* Error: invalid service code */
+ CE_TRACE_ERROR1 ("CE: Requested invalid service code: 0x%04x.", service_code);
+ nfc_status = NFC_STATUS_FAILED;
+ break;
+ }
+ }
+
+ /* Send appropriate response to reader/writer */
+ if (nfc_status == NFC_STATUS_OK)
+ {
+ ce_t3t_send_rsp (p_ce_cb, NULL, T3T_MSG_OPC_UPDATE_RSP, T3T_MSG_RSP_STATUS_OK, T3T_MSG_RSP_STATUS_OK);
+ }
+ else
+ {
+ ce_t3t_send_rsp (p_ce_cb, NULL, T3T_MSG_OPC_UPDATE_RSP, T3T_MSG_RSP_STATUS_ERROR, T3T_MSG_RSP_STATUS2_ERROR_MEMORY);
+ p_cb->state = CE_T3T_STATE_IDLE;
+ }
+
+
+ /* Notify the app of what got updated */
+ if (update_flags & CE_T3T_UPDATE_FL_NDEF_UPDATE_START)
+ {
+ /* NDEF attribute got updated with WriteF=TRUE */
+ p_ce_cb->p_cback (CE_T3T_NDEF_UPDATE_START_EVT, NULL);
+ }
+
+ if (update_flags & CE_T3T_UPDATE_FL_UPDATE)
+ {
+ /* UPDATE message contained at least one non-NDEF block */
+ p_ce_cb->p_cback (CE_T3T_UPDATE_EVT, NULL);
+ }
+
+
+ if (update_flags & CE_T3T_UPDATE_FL_NDEF_UPDATE_CPLT)
+ {
+ /* NDEF attribute got updated with WriteF=FALSE */
+ update_info.status = nfc_status;
+ update_info.p_data = p_cb->ndef_info.p_scratch_buf;
+ update_info.length = p_cb->ndef_info.scratch_ln;
+ p_cb->state = CE_T3T_STATE_IDLE;
+ p_ce_cb->p_cback (CE_T3T_NDEF_UPDATE_CPLT_EVT, (tCE_DATA *) &update_info);
+ }
+
+ GKI_freebuf (p_cmd_msg);
+}
+
+/*******************************************************************************
+**
+** Function ce_t3t_handle_check_cmd
+**
+** Description Handle CHECK command from reader/writer
+**
+** Returns Nothing
+**
+*******************************************************************************/
+void ce_t3t_handle_check_cmd (tCE_CB *p_ce_cb, BT_HDR *p_cmd_msg)
+{
+ tCE_T3T_MEM *p_cb = &p_ce_cb->mem.t3t;
+ BT_HDR *p_rsp_msg;
+ UINT8 *p_rsp_start;
+ UINT8 *p_dst, *p_temp, *p_status;
+ UINT8 *p_src = p_cb->cur_cmd.p_block_list_start;
+ UINT8 i, bl0;
+ UINT8 ndef_writef;
+ UINT32 ndef_len;
+ UINT16 block_number, service_code, checksum;
+
+ if ((p_rsp_msg = ce_t3t_get_rsp_buf ()) != NULL)
+ {
+ p_dst = p_rsp_start = (UINT8 *) (p_rsp_msg+1) + p_rsp_msg->offset;
+
+ /* Response Code */
+ UINT8_TO_STREAM (p_dst, T3T_MSG_OPC_CHECK_RSP);
+
+ /* Manufacturer ID */
+ ARRAY_TO_STREAM (p_dst, p_cb->local_nfcid2, NCI_RF_F_UID_LEN);
+
+ /* Save pointer to start of status field */
+ p_status = p_dst;
+
+ /* Status1 and Status2 (assume success initially */
+ UINT8_TO_STREAM (p_dst, T3T_MSG_RSP_STATUS_OK);
+ UINT8_TO_STREAM (p_dst, T3T_MSG_RSP_STATUS_OK);
+ UINT8_TO_STREAM (p_dst, p_cb->cur_cmd.num_blocks);
+
+ for (i = 0; i < p_cb->cur_cmd.num_blocks; i++)
+ {
+ /* Read byte0 of block list */
+ STREAM_TO_UINT8 (bl0, p_src);
+
+ if (bl0 & T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT)
+ {
+ STREAM_TO_UINT8 (block_number, p_src);
+ }
+ else
+ {
+ STREAM_TO_UINT16 (block_number, p_src);
+ }
+
+ /* Read the block from memory */
+ service_code = p_cb->cur_cmd.service_code_list[bl0 & T3T_MSG_SERVICE_LIST_MASK];
+
+ /* Check for NDEF */
+ if ((service_code == T3T_MSG_NDEF_SC_RO) || (service_code == T3T_MSG_NDEF_SC_RW))
+ {
+ /* Verify Nbr (NDEF only) */
+ if (p_cb->cur_cmd.num_blocks > p_cb->ndef_info.nbr)
+ {
+ /* Error: invalid number of blocks to check */
+ CE_TRACE_ERROR2 ("CE: Requested too many blocks to check (requested: %i, max: %i)", p_cb->cur_cmd.num_blocks, p_cb->ndef_info.nbr);
+
+ p_dst = p_status;
+ UINT8_TO_STREAM (p_dst, T3T_MSG_RSP_STATUS_ERROR);
+ UINT8_TO_STREAM (p_dst, T3T_MSG_RSP_STATUS2_ERROR_MEMORY);
+ break;
+ }
+ else if (block_number == 0)
+ {
+ /* Special caes: NDEF block0 is the ndef attribute block */
+ p_temp = p_dst;
+
+ /* For rw ndef, use scratch buffer's attributes (in case reader/writer had previously updated NDEF) */
+ if ((p_cb->ndef_info.rwflag == T3T_MSG_NDEF_RWFLAG_RW) && (p_cb->ndef_info.p_scratch_buf))
+ {
+ ndef_writef = p_cb->ndef_info.scratch_writef;
+ ndef_len = p_cb->ndef_info.scratch_ln;
+ }
+ else
+ {
+ ndef_writef = p_cb->ndef_info.writef;
+ ndef_len = p_cb->ndef_info.ln;
+ }
+
+ UINT8_TO_STREAM (p_dst, p_cb->ndef_info.version);
+ UINT8_TO_STREAM (p_dst, p_cb->ndef_info.nbr);
+ UINT8_TO_STREAM (p_dst, p_cb->ndef_info.nbw);
+ UINT16_TO_BE_STREAM (p_dst, p_cb->ndef_info.nmaxb);
+ UINT32_TO_STREAM (p_dst, 0);
+ UINT8_TO_STREAM (p_dst, ndef_writef);
+ UINT8_TO_STREAM (p_dst, p_cb->ndef_info.rwflag);
+ UINT8_TO_STREAM (p_dst, (ndef_len >> 16 & 0xFF));
+ UINT16_TO_BE_STREAM (p_dst, (ndef_len & 0xFFFF));
+
+ checksum = 0;
+ for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++)
+ {
+ checksum+=p_temp[i];
+ }
+ UINT16_TO_BE_STREAM (p_dst, checksum);
+ }
+ else
+ {
+ /* Verify that block_number is within NDEF memory */
+ if (block_number > p_cb->ndef_info.nmaxb)
+ {
+ /* Invalid block number */
+ p_dst = p_status;
+
+ CE_TRACE_ERROR1 ("CE: Requested block number to check %i.", block_number);
+
+ /* Error: invalid number of blocks to check */
+ UINT8_TO_STREAM (p_dst, T3T_MSG_RSP_STATUS_ERROR);
+ UINT8_TO_STREAM (p_dst, T3T_MSG_RSP_STATUS2_ERROR_MEMORY);
+ break;
+ }
+ else
+ {
+ /* If card is RW, then read from the scratch buffer (so reader/write can read back what it had just written */
+ if ((p_cb->ndef_info.rwflag == T3T_MSG_NDEF_RWFLAG_RW) && (p_cb->ndef_info.p_scratch_buf))
+ {
+ ARRAY_TO_STREAM (p_dst, (&p_cb->ndef_info.p_scratch_buf[(block_number-1) * T3T_MSG_BLOCKSIZE]), T3T_MSG_BLOCKSIZE);
+ }
+ else
+ {
+ ARRAY_TO_STREAM (p_dst, (&p_cb->ndef_info.p_buf[(block_number-1) * T3T_MSG_BLOCKSIZE]), T3T_MSG_BLOCKSIZE);
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Error: invalid service code */
+ CE_TRACE_ERROR1 ("CE: Requested invalid service code: 0x%04x.", service_code);
+
+ p_dst = p_status;
+ UINT8_TO_STREAM (p_dst, T3T_MSG_RSP_STATUS_ERROR);
+ UINT8_TO_STREAM (p_dst, T3T_MSG_RSP_STATUS2_ERROR_MEMORY);
+ break;
+ }
+ }
+
+ p_rsp_msg->len = (UINT16) (p_dst - p_rsp_start);
+ ce_t3t_send_to_lower (p_rsp_msg);
+ }
+ else
+ {
+ CE_TRACE_ERROR0 ("CE: Unable to allocat buffer for response message");
+ }
+
+ GKI_freebuf (p_cmd_msg);
+}
+
+
+/*******************************************************************************
+**
+** Function ce_t3t_handle_non_nfc_forum_cmd
+**
+** Description Handle POLL command from reader/writer
+**
+** Returns Nothing
+**
+*******************************************************************************/
+void ce_t3t_handle_non_nfc_forum_cmd (tCE_CB *p_mem_cb, UINT8 cmd_id, BT_HDR *p_cmd_msg)
+{
+ tCE_T3T_MEM *p_cb = &p_mem_cb->mem.t3t;
+ BT_HDR *p_rsp_msg;
+ UINT8 *p_rsp_start;
+ UINT8 *p_dst;
+ UINT8 *p = (UINT8 *) (p_cmd_msg +1) + p_cmd_msg->offset;
+ UINT16 sc;
+ UINT8 rc;
+ BOOLEAN send_response = TRUE;
+
+ if ((p_rsp_msg = ce_t3t_get_rsp_buf ()) != NULL)
+ {
+ p_dst = p_rsp_start = (UINT8 *) (p_rsp_msg+1) + p_rsp_msg->offset;
+
+ switch (cmd_id)
+ {
+ case T3T_MSG_OPC_POLL_CMD:
+ /* Get system code and RC */
+ /* Skip over sod and cmd_id */
+ p+=2;
+ BE_STREAM_TO_UINT16 (sc, p);
+ STREAM_TO_UINT8 (rc, p);
+
+ /* If requesting wildcard system code, or specifically our system code, then send POLL response */
+ if ((sc == 0xFFFF) || (sc == p_cb->system_code))
+ {
+ /* Response Code */
+ UINT8_TO_STREAM (p_dst, T3T_MSG_OPC_POLL_RSP);
+
+ /* Manufacturer ID */
+ ARRAY_TO_STREAM (p_dst, p_cb->local_nfcid2, NCI_RF_F_UID_LEN);
+
+ /* Manufacturer Parameter PMm */
+ ARRAY_TO_STREAM (p_dst, p_cb->local_pmm, NCI_T3T_PMM_LEN);
+
+ /* If requesting system code */
+ if (rc == T3T_POLL_RC_SC)
+ {
+ UINT16_TO_BE_STREAM (p_dst, p_cb->system_code);
+ }
+ }
+ else
+ {
+ send_response = FALSE;
+ }
+ break;
+
+
+ case T3T_MSG_OPC_REQ_RESPONSE_CMD:
+ /* Response Code */
+ UINT8_TO_STREAM (p_dst, T3T_MSG_OPC_REQ_RESPONSE_RSP);
+
+ /* Manufacturer ID */
+ ARRAY_TO_STREAM (p_dst, p_cb->local_nfcid2, NCI_RF_F_UID_LEN);
+
+ /* Mode */
+ UINT8_TO_STREAM (p_dst, 0);
+ break;
+
+ case T3T_MSG_OPC_REQ_SYSTEMCODE_CMD:
+ /* Response Code */
+ UINT8_TO_STREAM (p_dst, T3T_MSG_OPC_REQ_SYSTEMCODE_RSP);
+
+ /* Manufacturer ID */
+ ARRAY_TO_STREAM (p_dst, p_cb->local_nfcid2, NCI_RF_F_UID_LEN);
+
+ /* Number of system codes */
+ UINT8_TO_STREAM (p_dst, 1);
+
+ /* system codes */
+ UINT16_TO_BE_STREAM (p_dst, T3T_SYSTEM_CODE_NDEF);
+ break;
+
+
+ case T3T_MSG_OPC_REQ_SERVICE_CMD:
+ default:
+ /* Unhandled command */
+ CE_TRACE_ERROR1 ("Unhandled CE opcode: %02x", cmd_id);
+ send_response = FALSE;
+ break;
+ }
+
+ if (send_response)
+ {
+ p_rsp_msg->len = (UINT16) (p_dst - p_rsp_start);
+ ce_t3t_send_to_lower (p_rsp_msg);
+ }
+ else
+ {
+ GKI_freebuf (p_rsp_msg);
+ }
+ }
+ else
+ {
+ CE_TRACE_ERROR0 ("CE: Unable to allocat buffer for response message");
+ }
+ GKI_freebuf (p_cmd_msg);
+}
+
+/*******************************************************************************
+**
+** Function ce_t3t_data_cback
+**
+** Description This callback function receives the data from NFCC.
+**
+** Returns none
+**
+*******************************************************************************/
+void ce_t3t_data_cback (UINT8 conn_id, tNFC_DATA_CEVT *p_data)
+{
+ tCE_CB *p_ce_cb = &ce_cb;
+ tCE_T3T_MEM *p_cb = &p_ce_cb->mem.t3t;
+ BT_HDR *p_msg = p_data->p_data;
+ tCE_DATA ce_data;
+ UINT8 cmd_id, bl0, entry_len, i;
+ UINT8 *p_nfcid2 = NULL;
+ UINT8 *p = (UINT8 *) (p_msg +1) + p_msg->offset;
+ UINT8 cmd_nfcid2[NCI_RF_F_UID_LEN];
+ UINT16 block_list_start_offset, remaining;
+ BOOLEAN msg_processed = FALSE;
+ BOOLEAN block_list_ok;
+ UINT8 sod;
+ UINT8 cmd_type;
+
+#if (BT_TRACE_PROTOCOL == TRUE)
+ DispT3TagMessage (p_msg, TRUE);
+#endif
+
+ /* If activate system code is not NDEF, or if no local NDEF contents was set, then pass data up to the app */
+ if ((p_cb->system_code != T3T_SYSTEM_CODE_NDEF) || (!p_cb->ndef_info.initialized))
+ {
+ ce_data.raw_frame.status = 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 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 system_code, UINT8 nfcid2[NCI_RF_F_UID_LEN])
+{
+ tCE_T3T_MEM *p_cb = &ce_cb.mem.t3t;
+
+ CE_TRACE_DEBUG0 ("ce_select_t3t ()");
+
+ p_cb->state = CE_T3T_STATE_IDLE;
+ p_cb->system_code = system_code;
+ memcpy (p_cb->local_nfcid2, nfcid2, NCI_RF_F_UID_LEN);
+
+ NFC_SetStaticRfCback (ce_t3t_conn_cback);
+ return NFC_STATUS_OK;
+}
+
+
+/*******************************************************************************
+**
+** Function CE_T3tSetLocalNDEFMsg
+**
+** Description Initialise CE Type 3 Tag with mandatory NDEF message
+**
+** Returns NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS CE_T3tSetLocalNDEFMsg (BOOLEAN read_only,
+ UINT32 size_max,
+ UINT32 size_current,
+ UINT8 *p_buf,
+ UINT8 *p_scratch_buf)
+{
+ tCE_T3T_MEM *p_cb = &ce_cb.mem.t3t;
+
+ CE_TRACE_API3 ("CE_T3tSetContent: ro=%i, size_max=%i, size_current=%i", read_only, size_max, size_current);
+
+ /* Verify scratch buffer was provided if NDEF message is read/write */
+ if ((!read_only) && (!p_scratch_buf))
+ {
+ CE_TRACE_ERROR0 ("CE_T3tSetLocalNDEFMsg (): p_scratch_buf cannot be NULL if not read-only");
+ return NFC_STATUS_FAILED;
+ }
+
+ /* Check if disabling the local NDEF */
+ if (!p_buf)
+ {
+ p_cb->ndef_info.initialized = FALSE;
+ }
+ /* Save ndef attributes */
+ else
+ {
+ p_cb->ndef_info.initialized = TRUE;
+ p_cb->ndef_info.ln = size_current; /* Current length */
+ p_cb->ndef_info.nmaxb = (UINT16) ((size_max + 15) / T3T_MSG_BLOCKSIZE); /* Max length (in blocks) */
+ p_cb->ndef_info.rwflag = (read_only) ? T3T_MSG_NDEF_RWFLAG_RO : T3T_MSG_NDEF_RWFLAG_RW;
+ p_cb->ndef_info.writef = T3T_MSG_NDEF_WRITEF_OFF;
+ p_cb->ndef_info.version = 0x10;
+ p_cb->ndef_info.p_buf = p_buf;
+ p_cb->ndef_info.p_scratch_buf = p_scratch_buf;
+
+ /* Initiate scratch buffer with same contents as read-buffer */
+ if (p_scratch_buf)
+ {
+ p_cb->ndef_info.scratch_ln = p_cb->ndef_info.ln;
+ p_cb->ndef_info.scratch_writef = T3T_MSG_NDEF_WRITEF_OFF;
+ memcpy (p_scratch_buf, p_buf, p_cb->ndef_info.ln);
+ }
+ }
+
+ return (NFC_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function CE_T3tSetLocalNDefParams
+**
+** Description Sets T3T-specific NDEF parameters. (Optional - if not
+** called, then CE will use default parameters)
+**
+** Returns NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS CE_T3tSetLocalNDefParams (UINT8 nbr, UINT8 nbw)
+{
+ tCE_T3T_MEM *p_cb = &ce_cb.mem.t3t;
+
+ CE_TRACE_API2 ("CE_T3tSetLocalNDefParams: nbr=%i, nbw=%i", nbr, nbw);
+
+ /* Validate */
+ if ((nbr > T3T_MSG_NUM_BLOCKS_CHECK_MAX) || (nbw>T3T_MSG_NUM_BLOCKS_UPDATE_MAX) || (nbr < 1) || (nbw < 1))
+ {
+ CE_TRACE_ERROR0 ("CE_T3tSetLocalNDefParams: invalid params");
+ return NFC_STATUS_FAILED;
+ }
+
+ p_cb->ndef_info.nbr = nbr;
+ p_cb->ndef_info.nbw = nbw;
+
+ return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function CE_T3tSendCheckRsp
+**
+** Description Send CHECK response message
+**
+** Returns NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS CE_T3tSendCheckRsp (UINT8 status1, UINT8 status2, UINT8 num_blocks, UINT8 *p_block_data)
+{
+ tCE_T3T_MEM *p_cb = &ce_cb.mem.t3t;
+ tNFC_STATUS retval = NFC_STATUS_OK;
+ BT_HDR *p_rsp_msg;
+ UINT8 *p_dst, *p_rsp_start;
+
+ CE_TRACE_API3 ("CE_T3tCheckRsp: status1=0x%02X, status2=0x%02X, num_blocks=%i", status1, status2, num_blocks);
+
+ /* Validate num_blocks */
+ if (num_blocks > T3T_MSG_NUM_BLOCKS_CHECK_MAX)
+ {
+ CE_TRACE_ERROR2 ("CE_T3tCheckRsp num_blocks (%i) exceeds maximum (%i)", num_blocks, T3T_MSG_NUM_BLOCKS_CHECK_MAX);
+ return (NFC_STATUS_FAILED);
+ }
+
+ if ((p_rsp_msg = ce_t3t_get_rsp_buf ()) != NULL)
+ {
+ p_dst = p_rsp_start = (UINT8 *) (p_rsp_msg+1) + p_rsp_msg->offset;
+
+ /* Response Code */
+ UINT8_TO_STREAM (p_dst, T3T_MSG_OPC_CHECK_RSP);
+
+ /* Manufacturer ID */
+ ARRAY_TO_STREAM (p_dst, p_cb->local_nfcid2, NCI_RF_F_UID_LEN);
+
+ /* Status1 and Status2 */
+ UINT8_TO_STREAM (p_dst, status1);
+ UINT8_TO_STREAM (p_dst, status2);
+
+ if (status1 == T3T_MSG_RSP_STATUS_OK)
+ {
+ UINT8_TO_STREAM (p_dst, num_blocks);
+ ARRAY_TO_STREAM (p_dst, p_block_data, (num_blocks * T3T_MSG_BLOCKSIZE));
+ }
+
+ p_rsp_msg->len = (UINT16) (p_dst - p_rsp_start);
+ ce_t3t_send_to_lower (p_rsp_msg);
+ }
+ else
+ {
+ CE_TRACE_ERROR0 ("CE: Unable to allocate buffer for response message");
+ }
+
+ return (retval);
+}
+
+/*******************************************************************************
+**
+** Function CE_T3tSendUpdateRsp
+**
+** Description Send UPDATE response message
+**
+** Returns NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS CE_T3tSendUpdateRsp (UINT8 status1, UINT8 status2)
+{
+ tNFC_STATUS retval = NFC_STATUS_OK;
+ tCE_CB *p_ce_cb = &ce_cb;
+
+ CE_TRACE_API2 ("CE_T3tUpdateRsp: status1=0x%02X, status2=0x%02X", status1, status2);
+ ce_t3t_send_rsp (p_ce_cb, NULL, T3T_MSG_OPC_UPDATE_RSP, status1, status2);
+
+ return (retval);
+}
+
+#endif /* NFC_INCLUDED == TRUE */
diff --git a/src/nfc/tags/ce_t4t.c b/src/nfc/tags/ce_t4t.c
new file mode 100644
index 0000000..b812cff
--- /dev/null
+++ b/src/nfc/tags/ce_t4t.c
@@ -0,0 +1,1201 @@
+/******************************************************************************
+ *
+ * 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"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_api.h"
+#include "nfc_int.h"
+#include "ce_api.h"
+#include "ce_int.h"
+#include "tags_int.h"
+#include "gki.h"
+
+#if (CE_TEST_INCLUDED == TRUE) /* test only */
+BOOLEAN mapping_aid_test_enabled = FALSE;
+UINT8 ce_test_tag_app_id[T4T_V20_NDEF_TAG_AID_LEN] = {0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01};
+#endif
+
+/*******************************************************************************
+**
+** Function ce_t4t_send_to_lower
+**
+** Description Send packet to lower layer
+**
+** Returns TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN ce_t4t_send_to_lower (BT_HDR *p_r_apdu)
+{
+#if (BT_TRACE_PROTOCOL == TRUE)
+ DispCET4Tags (p_r_apdu, FALSE);
+#endif
+
+ if (NFC_SendData (NFC_RF_CONN_ID, p_r_apdu) != NFC_STATUS_OK)
+ {
+ CE_TRACE_ERROR0 ("ce_t4t_send_to_lower (): NFC_SendData () failed");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function ce_t4t_send_status
+**
+** Description Send status on R-APDU to peer
+**
+** Returns TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN ce_t4t_send_status (UINT16 status)
+{
+ BT_HDR *p_r_apdu;
+ UINT8 *p;
+
+ CE_TRACE_DEBUG1 ("ce_t4t_send_status (): Status:0x%04X", status);
+
+ p_r_apdu = (BT_HDR *) GKI_getpoolbuf (NFC_CE_POOL_ID);
+
+ if (!p_r_apdu)
+ {
+ CE_TRACE_ERROR0 ("ce_t4t_send_status (): Cannot allocate buffer");
+ return FALSE;
+ }
+
+ p_r_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p = (UINT8 *) (p_r_apdu + 1) + p_r_apdu->offset;
+
+ UINT16_TO_BE_STREAM (p, status);
+
+ p_r_apdu->len = T4T_RSP_STATUS_WORDS_SIZE;
+
+ if (!ce_t4t_send_to_lower (p_r_apdu))
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function ce_t4t_select_file
+**
+** Description Select a file
+**
+** Returns TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN ce_t4t_select_file (UINT16 file_id)
+{
+ tCE_T4T_MEM *p_t4t = &ce_cb.mem.t4t;
+
+ CE_TRACE_DEBUG1 ("ce_t4t_select_file (): FileID:0x%04X", file_id);
+
+ if (file_id == T4T_CC_FILE_ID)
+ {
+ CE_TRACE_DEBUG0 ("ce_t4t_select_file (): Select CC file");
+
+ p_t4t->status |= CE_T4T_STATUS_CC_FILE_SELECTED;
+ p_t4t->status &= ~ (CE_T4T_STATUS_NDEF_SELECTED);
+
+ return TRUE;
+ }
+
+ if (file_id == CE_T4T_MANDATORY_NDEF_FILE_ID)
+ {
+ CE_TRACE_DEBUG3 ("ce_t4t_select_file (): NLEN:0x%04X, MaxFileSize:0x%04X, WriteAccess:%s",
+ p_t4t->nlen,
+ p_t4t->max_file_size,
+ (p_t4t->status & CE_T4T_STATUS_NDEF_FILE_READ_ONLY ? "RW" : "RO"));
+
+ p_t4t->status |= CE_T4T_STATUS_NDEF_SELECTED;
+ p_t4t->status &= ~ (CE_T4T_STATUS_CC_FILE_SELECTED);
+
+ return TRUE;
+ }
+ else
+ {
+ CE_TRACE_ERROR1 ("ce_t4t_select_file (): Cannot find file ID (0x%04X)", file_id);
+
+ p_t4t->status &= ~ (CE_T4T_STATUS_CC_FILE_SELECTED);
+ p_t4t->status &= ~ (CE_T4T_STATUS_NDEF_SELECTED);
+
+ return FALSE;
+ }
+}
+
+/*******************************************************************************
+**
+** Function ce_t4t_read_binary
+**
+** Description Read data from selected file and send R-APDU to peer
+**
+** Returns TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN ce_t4t_read_binary (UINT16 offset, UINT8 length)
+{
+ tCE_T4T_MEM *p_t4t = &ce_cb.mem.t4t;
+ UINT8 *p_src = NULL, *p_dst;
+ BT_HDR *p_r_apdu;
+
+ CE_TRACE_DEBUG3 ("ce_t4t_read_binary (): Offset:0x%04X, Length:0x%04X, selected status = 0x%02X",
+ offset, length, p_t4t->status);
+
+ if (p_t4t->status & CE_T4T_STATUS_CC_FILE_SELECTED)
+ {
+ p_src = p_t4t->cc_file;
+ }
+ else if (p_t4t->status & CE_T4T_STATUS_NDEF_SELECTED)
+ {
+ if (p_t4t->p_scratch_buf)
+ p_src = p_t4t->p_scratch_buf;
+ else
+ p_src = p_t4t->p_ndef_msg;
+ }
+
+ if (p_src)
+ {
+ p_r_apdu = (BT_HDR *) GKI_getpoolbuf (NFC_CE_POOL_ID);
+
+ if (!p_r_apdu)
+ {
+ CE_TRACE_ERROR0 ("ce_t4t_read_binary (): Cannot allocate buffer");
+ return FALSE;
+ }
+
+ p_r_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p_dst = (UINT8 *) (p_r_apdu + 1) + p_r_apdu->offset;
+
+ p_r_apdu->len = length;
+
+ /* add NLEN before NDEF message and adjust offset */
+ /* if NDEF file is selected and offset < T4T_FILE_LENGTH_SIZE */
+ if ((p_t4t->status & CE_T4T_STATUS_NDEF_SELECTED) && (length > 0))
+ {
+ if (offset == 0)
+ {
+ UINT16_TO_BE_STREAM (p_dst, p_t4t->nlen);
+
+ if (length == 1)
+ {
+ length = 0;
+ p_dst--;
+ }
+ else /* length >= 2 */
+ length -= T4T_FILE_LENGTH_SIZE;
+ }
+ else if (offset == 1)
+ {
+ UINT8_TO_BE_STREAM (p_dst, (UINT8) (p_t4t->nlen));
+
+ offset = 0;
+ length--;
+ }
+ else
+ {
+ offset -= T4T_FILE_LENGTH_SIZE;
+ }
+ }
+
+ if (length > 0)
+ {
+ memcpy (p_dst, p_src + offset, length);
+ p_dst += length;
+ }
+
+ UINT16_TO_BE_STREAM (p_dst, T4T_RSP_CMD_CMPLTED);
+ p_r_apdu->len += T4T_RSP_STATUS_WORDS_SIZE;
+
+ if (!ce_t4t_send_to_lower (p_r_apdu))
+ {
+ return FALSE;
+ }
+ return TRUE;
+ }
+ else
+ {
+ CE_TRACE_ERROR0 ("ce_t4t_read_binary (): No selected file");
+
+ if (!ce_t4t_send_status (T4T_RSP_CMD_NOT_ALLOWED))
+ {
+ return FALSE;
+ }
+ return TRUE;
+ }
+}
+
+/*******************************************************************************
+**
+** Function ce_t4t_update_binary
+**
+** Description Update file and send R-APDU to peer
+**
+** Returns TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN ce_t4t_update_binary (UINT16 offset, UINT8 length, UINT8 *p_data)
+{
+ tCE_T4T_MEM *p_t4t = &ce_cb.mem.t4t;
+ UINT8 *p;
+ UINT8 file_length[2];
+ UINT16 starting_offset;
+ 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 version)
+{
+ tCE_T4T_MEM *p_t4t = &ce_cb.mem.t4t;
+ UINT8 *p;
+
+ CE_TRACE_DEBUG1 ("ce_t4t_set_version_in_cc (): version = 0x%02X", version);
+
+ p = p_t4t->cc_file + T4T_VERSION_OFFSET_IN_CC;
+
+ UINT8_TO_BE_STREAM (p, version);
+}
+
+/*******************************************************************************
+**
+** Function ce_t4t_process_select_file_cmd
+**
+** Description This function processes Select Command by file ID.
+**
+** Returns TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN ce_t4t_process_select_file_cmd (UINT8 *p_cmd)
+{
+ UINT8 data_len;
+ UINT16 file_id, status_words;
+
+ CE_TRACE_DEBUG0 ("ce_t4t_process_select_file_cmd ()");
+
+ p_cmd++; /* skip P2 */
+
+ /* Lc Byte */
+ BE_STREAM_TO_UINT8 (data_len, p_cmd);
+
+ if (data_len == T4T_FILE_ID_SIZE)
+ {
+ /* File ID */
+ BE_STREAM_TO_UINT16 (file_id, p_cmd);
+
+ if (ce_t4t_select_file (file_id))
+ {
+ status_words = T4T_RSP_CMD_CMPLTED;
+ }
+ else
+ {
+ status_words = T4T_RSP_NOT_FOUND;
+ }
+ }
+ else
+ {
+ status_words = T4T_RSP_WRONG_LENGTH;
+ }
+
+ if (!ce_t4t_send_status (status_words))
+ {
+ return FALSE;
+ }
+
+ if (status_words == T4T_RSP_CMD_CMPLTED)
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*******************************************************************************
+**
+** Function ce_t4t_process_select_app_cmd
+**
+** Description This function processes Select Command by AID.
+**
+** Returns none
+**
+*******************************************************************************/
+static void ce_t4t_process_select_app_cmd (UINT8 *p_cmd, BT_HDR *p_c_apdu)
+{
+ UINT8 data_len;
+ UINT16 status_words = 0x0000; /* invalid status words */
+ tCE_DATA ce_data;
+ UINT8 xx;
+
+ CE_TRACE_DEBUG0 ("ce_t4t_process_select_app_cmd ()");
+
+ p_cmd++; /* skip P2 */
+
+ /* Lc Byte */
+ BE_STREAM_TO_UINT8 (data_len, p_cmd);
+
+#if (CE_TEST_INCLUDED == TRUE)
+ if (mapping_aid_test_enabled)
+ {
+ if ( (data_len == T4T_V20_NDEF_TAG_AID_LEN)
+ &&(!memcmp(p_cmd, ce_test_tag_app_id, data_len))
+ &&(ce_cb.mem.t4t.p_ndef_msg) )
+ {
+ GKI_freebuf (p_c_apdu);
+ ce_t4t_send_status ((UINT16) T4T_RSP_CMD_CMPLTED);
+ return;
+ }
+ }
+#endif
+
+ /*
+ ** Compare AIDs registered by applications
+ ** if found, use callback of the application
+ ** otherwise, return error and maintain the same status
+ */
+ ce_cb.mem.t4t.selected_aid_idx = CE_T4T_MAX_REG_AID;
+ for (xx = 0; xx < CE_T4T_MAX_REG_AID; xx++)
+ {
+ if ( (ce_cb.mem.t4t.reg_aid[xx].aid_len > 0)
+ &&(ce_cb.mem.t4t.reg_aid[xx].aid_len == data_len)
+ &&(!(memcmp(ce_cb.mem.t4t.reg_aid[xx].aid, p_cmd, data_len))) )
+ {
+ ce_cb.mem.t4t.selected_aid_idx = xx;
+ break;
+ }
+ }
+
+ /* if found matched AID */
+ if (ce_cb.mem.t4t.selected_aid_idx < CE_T4T_MAX_REG_AID)
+ {
+ ce_cb.mem.t4t.status &= ~ (CE_T4T_STATUS_CC_FILE_SELECTED);
+ ce_cb.mem.t4t.status &= ~ (CE_T4T_STATUS_NDEF_SELECTED);
+ ce_cb.mem.t4t.status &= ~ (CE_T4T_STATUS_T4T_APP_SELECTED);
+ ce_cb.mem.t4t.status &= ~ (CE_T4T_STATUS_WILDCARD_AID_SELECTED);
+ ce_cb.mem.t4t.status |= CE_T4T_STATUS_REG_AID_SELECTED;
+
+ CE_TRACE_DEBUG4 ("ce_t4t_process_select_app_cmd (): Registered AID[%02X%02X%02X%02X...] is selected",
+ ce_cb.mem.t4t.reg_aid[ce_cb.mem.t4t.selected_aid_idx].aid[0],
+ ce_cb.mem.t4t.reg_aid[ce_cb.mem.t4t.selected_aid_idx].aid[1],
+ ce_cb.mem.t4t.reg_aid[ce_cb.mem.t4t.selected_aid_idx].aid[2],
+ ce_cb.mem.t4t.reg_aid[ce_cb.mem.t4t.selected_aid_idx].aid[3]);
+
+ ce_data.raw_frame.status = NFC_STATUS_OK;
+ ce_data.raw_frame.p_data = p_c_apdu;
+ ce_data.raw_frame.aid_handle = ce_cb.mem.t4t.selected_aid_idx;
+
+ p_c_apdu = NULL;
+
+ (*(ce_cb.mem.t4t.reg_aid[ce_cb.mem.t4t.selected_aid_idx].p_cback)) (CE_T4T_RAW_FRAME_EVT, &ce_data);
+ }
+ else if ( (data_len == T4T_V20_NDEF_TAG_AID_LEN)
+ &&(!memcmp(p_cmd, t4t_v20_ndef_tag_aid, data_len - 1))
+ &&(ce_cb.mem.t4t.p_ndef_msg) )
+ {
+ p_cmd += data_len - 1;
+
+ /* adjust version if possible */
+ if ((*p_cmd) == 0x00)
+ {
+ ce_t4t_set_version_in_cc (T4T_VERSION_1_0);
+ status_words = T4T_RSP_CMD_CMPLTED;
+ }
+ else if ((*p_cmd) == 0x01)
+ {
+ ce_t4t_set_version_in_cc (T4T_VERSION_2_0);
+ status_words = T4T_RSP_CMD_CMPLTED;
+ }
+ else
+ {
+ CE_TRACE_DEBUG0 ("ce_t4t_process_select_app_cmd (): Not found matched AID");
+ status_words = T4T_RSP_NOT_FOUND;
+ }
+ }
+ else if (ce_cb.mem.t4t.p_wildcard_aid_cback)
+ {
+ ce_cb.mem.t4t.status &= ~ (CE_T4T_STATUS_CC_FILE_SELECTED);
+ ce_cb.mem.t4t.status &= ~ (CE_T4T_STATUS_NDEF_SELECTED);
+ ce_cb.mem.t4t.status &= ~ (CE_T4T_STATUS_T4T_APP_SELECTED);
+ ce_cb.mem.t4t.status &= ~ (CE_T4T_STATUS_REG_AID_SELECTED);
+ ce_cb.mem.t4t.status |= CE_T4T_STATUS_WILDCARD_AID_SELECTED;
+
+ ce_data.raw_frame.status = NFC_STATUS_OK;
+ ce_data.raw_frame.p_data = p_c_apdu;
+ ce_data.raw_frame.aid_handle = CE_T4T_WILDCARD_AID_HANDLE;
+ p_c_apdu = NULL;
+
+ CE_TRACE_DEBUG0 ("CET4T: Forward raw frame (SELECT APP) to wildcard AID handler");
+ (*(ce_cb.mem.t4t.p_wildcard_aid_cback)) (CE_T4T_RAW_FRAME_EVT, &ce_data);
+ }
+ else
+ {
+ CE_TRACE_DEBUG0 ("ce_t4t_process_select_app_cmd (): Not found matched AID or not listening T4T NDEF");
+ status_words = T4T_RSP_NOT_FOUND;
+ }
+
+ if (status_words)
+ {
+ /* if T4T CE can support */
+ if (status_words == T4T_RSP_CMD_CMPLTED)
+ {
+ ce_cb.mem.t4t.status &= ~ (CE_T4T_STATUS_CC_FILE_SELECTED);
+ ce_cb.mem.t4t.status &= ~ (CE_T4T_STATUS_NDEF_SELECTED);
+ ce_cb.mem.t4t.status &= ~ (CE_T4T_STATUS_REG_AID_SELECTED);
+ ce_cb.mem.t4t.status &= ~ (CE_T4T_STATUS_WILDCARD_AID_SELECTED);
+ ce_cb.mem.t4t.status |= CE_T4T_STATUS_T4T_APP_SELECTED;
+
+ CE_TRACE_DEBUG0 ("ce_t4t_process_select_app_cmd (): T4T CE App selected");
+ }
+
+ ce_t4t_send_status (status_words);
+ GKI_freebuf (p_c_apdu);
+ }
+ /* if status_words is not set then upper layer will send R-APDU */
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function ce_t4t_process_timeout
+**
+** Description process timeout event
+**
+** Returns none
+**
+*******************************************************************************/
+void ce_t4t_process_timeout (TIMER_LIST_ENT *p_tle)
+{
+ tCE_T4T_MEM *p_t4t = &ce_cb.mem.t4t;
+ tCE_DATA ce_data;
+
+ CE_TRACE_DEBUG1 ("ce_t4t_process_timeout () event=%d", p_tle->event);
+
+ if (p_tle->event == NFC_TTYPE_CE_T4T_UPDATE)
+ {
+ if (p_t4t->status & CE_T4T_STATUS_NDEF_FILE_UPDATING)
+ {
+ ce_data.status = NFC_STATUS_TIMEOUT;
+
+ if (ce_cb.p_cback)
+ (*ce_cb.p_cback) (CE_T4T_NDEF_UPDATE_ABORT_EVT, &ce_data);
+
+ p_t4t->status &= ~ (CE_T4T_STATUS_NDEF_FILE_UPDATING);
+ }
+ }
+ else
+ {
+ CE_TRACE_ERROR1 ("ce_t4t_process_timeout () unknown event=%d", p_tle->event);
+ }
+}
+
+/*******************************************************************************
+**
+** Function ce_t4t_data_cback
+**
+** Description This callback function receives the data from NFCC.
+**
+** Returns none
+**
+*******************************************************************************/
+static void ce_t4t_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
+{
+ BT_HDR *p_c_apdu;
+ UINT8 *p_cmd;
+ UINT8 cla, instruct, select_type = 0, length;
+ UINT16 offset, max_file_size;
+ tCE_DATA ce_data;
+
+ if (event == NFC_DEACTIVATE_CEVT)
+ {
+ NFC_SetStaticRfCback (NULL);
+ return;
+ }
+ if (event != NFC_DATA_CEVT)
+ {
+ return;
+ }
+
+ p_c_apdu = (BT_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 *) (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 (length <= CE_T4T_MAX_LE)
+ {
+ /* CE allows to read more than current file size but not max file size */
+ if (length + offset > max_file_size)
+ {
+ if (offset < max_file_size)
+ {
+ length = (UINT8) (max_file_size - offset);
+
+ CE_TRACE_DEBUG2 ("CET4T: length is reduced to %d by max_file_size (%d)",
+ length, max_file_size);
+ }
+ else
+ {
+ CE_TRACE_ERROR2 ("CET4T: offset (%d) must be less than max_file_size (%d)",
+ offset, max_file_size);
+ length = 0;
+ }
+ }
+ }
+ else
+ {
+ CE_TRACE_ERROR2 ("CET4T: length (%d) must be less than MLe (%d)",
+ length, CE_T4T_MAX_LE);
+ length = 0;
+ }
+
+ if (length > 0)
+ ce_t4t_read_binary (offset, length);
+ else
+ ce_t4t_send_status (T4T_RSP_WRONG_PARAMS);
+ }
+ else
+ {
+ CE_TRACE_ERROR0 ("CET4T: File has not been selected");
+ ce_t4t_send_status (T4T_RSP_CMD_NOT_ALLOWED);
+ }
+ }
+ else if (instruct == T4T_CMD_INS_UPDATE_BINARY)
+ {
+ if (ce_cb.mem.t4t.status & CE_T4T_STATUS_NDEF_FILE_READ_ONLY)
+ {
+ CE_TRACE_ERROR0 ("CET4T: No access right");
+ ce_t4t_send_status (T4T_RSP_CMD_NOT_ALLOWED);
+ }
+ else if (ce_cb.mem.t4t.status & CE_T4T_STATUS_NDEF_SELECTED)
+ {
+ BE_STREAM_TO_UINT16 (offset, p_cmd); /* Offset */
+ BE_STREAM_TO_UINT8 (length, p_cmd); /* Lc */
+
+ /* check if valid parameters */
+ if (length <= CE_T4T_MAX_LC)
+ {
+ if (length + offset > ce_cb.mem.t4t.max_file_size)
+ {
+ CE_TRACE_ERROR3 ("CET4T: length (%d) + offset (%d) must be less than max_file_size (%d)",
+ length, offset, ce_cb.mem.t4t.max_file_size);
+ length = 0;
+ }
+ }
+ else
+ {
+ CE_TRACE_ERROR2 ("CET4T: length (%d) must be less than MLc (%d)",
+ length, CE_T4T_MAX_LC);
+ length = 0;
+ }
+
+ if (length > 0)
+ ce_t4t_update_binary (offset, length, p_cmd);
+ else
+ ce_t4t_send_status (T4T_RSP_WRONG_PARAMS);
+ }
+ else
+ {
+ CE_TRACE_ERROR0 ("CET4T: NDEF File has not been selected");
+ ce_t4t_send_status (T4T_RSP_CMD_NOT_ALLOWED);
+ }
+ }
+ else
+ {
+ CE_TRACE_ERROR1 ("CET4T: Unsupported Instruction byte (0x%02X)", instruct);
+ ce_t4t_send_status (T4T_RSP_INSTR_NOT_SUPPORTED);
+ }
+ }
+ else
+ {
+ CE_TRACE_ERROR0 ("CET4T: Application has not been selected");
+ ce_t4t_send_status (T4T_RSP_CMD_NOT_ALLOWED);
+ }
+
+ if (p_c_apdu)
+ GKI_freebuf (p_c_apdu);
+}
+
+/*******************************************************************************
+**
+** Function ce_select_t4t
+**
+** Description Select Type 4 Tag
+**
+** Returns NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS ce_select_t4t (void)
+{
+ tCE_T4T_MEM *p_t4t = &ce_cb.mem.t4t;
+
+ CE_TRACE_DEBUG0 ("ce_select_t4t ()");
+
+ nfc_stop_quick_timer (&p_t4t->timer);
+
+ /* clear other than read-only flag */
+ p_t4t->status &= CE_T4T_STATUS_NDEF_FILE_READ_ONLY;
+
+ NFC_SetStaticRfCback (ce_t4t_data_cback);
+
+ return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function CE_T4tSetLocalNDEFMsg
+**
+** Description Initialise CE Type 4 Tag with mandatory NDEF message
+**
+** The following event may be returned
+** CE_T4T_UPDATE_START_EVT for starting update
+** CE_T4T_UPDATE_CPLT_EVT for complete update
+** CE_T4T_UPDATE_ABORT_EVT for failure of update
+** CE_T4T_RAW_FRAME_EVT for raw frame
+**
+** read_only: TRUE if read only
+** ndef_msg_max: Max NDEF message size
+** ndef_msg_len: NDEF message size
+** p_ndef_msg: NDEF message (excluding NLEN)
+** p_scratch_buf: temp storage for update
+**
+** Returns NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS CE_T4tSetLocalNDEFMsg (BOOLEAN read_only,
+ UINT16 ndef_msg_max,
+ UINT16 ndef_msg_len,
+ UINT8 *p_ndef_msg,
+ UINT8 *p_scratch_buf)
+{
+ tCE_T4T_MEM *p_t4t = &ce_cb.mem.t4t;
+ UINT8 *p;
+
+ CE_TRACE_API3 ("CE_T4tSetLocalNDEFMsg () read_only=%d, ndef_msg_max=%d, ndef_msg_len=%d",
+ read_only, ndef_msg_max, ndef_msg_len);
+
+ if (!p_ndef_msg)
+ {
+ p_t4t->p_ndef_msg = NULL;
+
+ CE_TRACE_DEBUG0 ("CE_T4tSetLocalNDEFMsg (): T4T is disabled");
+ return NFC_STATUS_OK;
+ }
+
+ if ((!read_only) && (!p_scratch_buf))
+ {
+ CE_TRACE_ERROR0 ("CE_T4tSetLocalNDEFMsg (): p_scratch_buf cannot be NULL if not read-only");
+ return NFC_STATUS_FAILED;
+ }
+
+#if (CE_TEST_INCLUDED == TRUE)
+ mapping_aid_test_enabled = FALSE;
+#endif
+
+ /* Initialise CC file */
+ p = p_t4t->cc_file;
+
+ UINT16_TO_BE_STREAM (p, T4T_CC_FILE_MIN_LEN);
+ UINT8_TO_BE_STREAM (p, T4T_MY_VERSION);
+ UINT16_TO_BE_STREAM (p, CE_T4T_MAX_LE);
+ UINT16_TO_BE_STREAM (p, CE_T4T_MAX_LC);
+
+ /* Mandatory NDEF File Control TLV */
+ UINT8_TO_BE_STREAM (p, T4T_NDEF_FILE_CONTROL_TYPE); /* type */
+ UINT8_TO_BE_STREAM (p, T4T_FILE_CONTROL_LENGTH); /* length */
+ UINT16_TO_BE_STREAM (p, CE_T4T_MANDATORY_NDEF_FILE_ID); /* file ID */
+ UINT16_TO_BE_STREAM (p, ndef_msg_max + T4T_FILE_LENGTH_SIZE); /* max NDEF file size */
+ UINT8_TO_BE_STREAM (p, T4T_FC_READ_ACCESS); /* read access */
+
+ if (read_only)
+ {
+ UINT8_TO_BE_STREAM (p, T4T_FC_NO_WRITE_ACCESS); /* read only */
+ p_t4t->status |= CE_T4T_STATUS_NDEF_FILE_READ_ONLY;
+ }
+ else
+ {
+ UINT8_TO_BE_STREAM (p, T4T_FC_WRITE_ACCESS); /* write access */
+ p_t4t->status &= ~ (CE_T4T_STATUS_NDEF_FILE_READ_ONLY);
+ }
+
+ /* set mandatory NDEF file */
+ p_t4t->p_ndef_msg = p_ndef_msg;
+ p_t4t->nlen = ndef_msg_len;
+ p_t4t->max_file_size = ndef_msg_max + T4T_FILE_LENGTH_SIZE;
+
+ /* Initialize scratch buffer */
+ p_t4t->p_scratch_buf = p_scratch_buf;
+
+ if (p_scratch_buf)
+ {
+ memcpy (p_scratch_buf, p_ndef_msg, ndef_msg_len);
+ }
+
+ return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function CE_T4tRegisterAID
+**
+** Description Register AID in CE T4T
+**
+** aid_len: length of AID (up to NFC_MAX_AID_LEN)
+** p_aid: AID
+** p_cback: Raw frame will be forwarded with CE_RAW_FRAME_EVT
+**
+** Returns tCE_T4T_AID_HANDLE if successful,
+** CE_T4T_AID_HANDLE_INVALID otherwisse
+**
+*******************************************************************************/
+tCE_T4T_AID_HANDLE CE_T4tRegisterAID (UINT8 aid_len, UINT8 *p_aid, tCE_CBACK *p_cback)
+{
+ tCE_T4T_MEM *p_t4t = &ce_cb.mem.t4t;
+ UINT8 xx;
+
+ /* Handle registering callback for wildcard AID (all AIDs) */
+ if (aid_len == 0)
+ {
+ CE_TRACE_API0 ("CE_T4tRegisterAID (): registering callback for wildcard AID ");
+
+ /* Check if a wildcard callback is already registered (only one is allowed) */
+ if (p_t4t->p_wildcard_aid_cback != NULL)
+ {
+ CE_TRACE_ERROR0 ("CE_T4tRegisterAID (): only one wildcard AID can be registered at time.");
+ return CE_T4T_AID_HANDLE_INVALID;
+ }
+
+ CE_TRACE_DEBUG1 ("CE_T4tRegisterAID (): handle 0x%02x registered (for wildcard AID)", CE_T4T_WILDCARD_AID_HANDLE);
+ p_t4t->p_wildcard_aid_cback = p_cback;
+ return CE_T4T_WILDCARD_AID_HANDLE;
+ }
+
+
+ CE_TRACE_API5 ("CE_T4tRegisterAID () AID [%02X%02X%02X%02X...], %d bytes",
+ *p_aid, *(p_aid+1), *(p_aid+2), *(p_aid+3), aid_len);
+
+ if (aid_len > NFC_MAX_AID_LEN)
+ {
+ CE_TRACE_ERROR1 ("CE_T4tRegisterAID (): AID is up to %d bytes", NFC_MAX_AID_LEN);
+ return CE_T4T_AID_HANDLE_INVALID;
+ }
+
+ if (p_cback == NULL)
+ {
+ CE_TRACE_ERROR0 ("CE_T4tRegisterAID (): callback must be provided");
+ return CE_T4T_AID_HANDLE_INVALID;
+ }
+
+ for (xx = 0; xx < CE_T4T_MAX_REG_AID; xx++)
+ {
+ if ( (p_t4t->reg_aid[xx].aid_len == aid_len)
+ &&(!(memcmp(p_t4t->reg_aid[xx].aid, p_aid, aid_len))) )
+ {
+ CE_TRACE_ERROR0 ("CE_T4tRegisterAID (): already registered");
+ return CE_T4T_AID_HANDLE_INVALID;
+ }
+ }
+
+ for (xx = 0; xx < CE_T4T_MAX_REG_AID; xx++)
+ {
+ if (p_t4t->reg_aid[xx].aid_len == 0)
+ {
+ p_t4t->reg_aid[xx].aid_len = aid_len;
+ p_t4t->reg_aid[xx].p_cback = p_cback;
+ memcpy (p_t4t->reg_aid[xx].aid, p_aid, aid_len);
+ break;
+ }
+ }
+
+ if (xx >= CE_T4T_MAX_REG_AID)
+ {
+ CE_TRACE_ERROR0 ("CE_T4tRegisterAID (): No resource");
+ return CE_T4T_AID_HANDLE_INVALID;
+ }
+ else
+ {
+ CE_TRACE_DEBUG1 ("CE_T4tRegisterAID (): handle 0x%02x registered", xx);
+ }
+
+ return (xx);
+}
+
+/*******************************************************************************
+**
+** Function CE_T4tDeregisterAID
+**
+** Description Deregister AID in CE T4T
+**
+** Returns NFC_STATUS_OK if success
+**
+*******************************************************************************/
+NFC_API extern void CE_T4tDeregisterAID (tCE_T4T_AID_HANDLE aid_handle)
+{
+ tCE_T4T_MEM *p_t4t = &ce_cb.mem.t4t;
+
+ CE_TRACE_API1 ("CE_T4tDeregisterAID () handle 0x%02x", aid_handle);
+
+ /* Check if deregistering wildcard AID */
+ if (aid_handle == CE_T4T_WILDCARD_AID_HANDLE)
+ {
+ if (p_t4t->p_wildcard_aid_cback != NULL)
+ {
+ p_t4t->p_wildcard_aid_cback = NULL;
+ }
+ else
+ {
+ CE_TRACE_ERROR0 ("CE_T4tDeregisterAID (): Invalid handle");
+ }
+ return;
+ }
+
+ /* Deregister AID */
+ if ((aid_handle >= CE_T4T_MAX_REG_AID) || (p_t4t->reg_aid[aid_handle].aid_len==0))
+ {
+ CE_TRACE_ERROR0 ("CE_T4tDeregisterAID (): Invalid handle");
+ }
+ else
+ {
+ p_t4t->reg_aid[aid_handle].aid_len = 0;
+ p_t4t->reg_aid[aid_handle].p_cback = NULL;
+ }
+}
+
+/*******************************************************************************
+**
+** Function CE_T4TTestSetCC
+**
+** Description Set fields in Capability Container File for testing
+**
+** Returns NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS CE_T4TTestSetCC (UINT16 cc_len,
+ UINT8 version,
+ UINT16 max_le,
+ UINT16 max_lc)
+{
+#if (CE_TEST_INCLUDED == TRUE)
+ tCE_T4T_MEM *p_t4t = &ce_cb.mem.t4t;
+ UINT8 *p;
+
+ CE_TRACE_DEBUG4 ("CE_T4TTestSetCC (): CCLen:0x%04X, Ver:0x%02X, MaxLe:0x%04X, MaxLc:0x%04X",
+ cc_len, version, max_le, max_lc);
+
+ /* CC file */
+ p = p_t4t->cc_file;
+
+ if (cc_len != 0xFFFF)
+ {
+ UINT16_TO_BE_STREAM (p, cc_len);
+ }
+ else
+ p += 2;
+
+ if (version != 0xFF)
+ {
+ mapping_aid_test_enabled = TRUE;
+ if (version == T4T_VERSION_1_0)
+ ce_test_tag_app_id[T4T_V20_NDEF_TAG_AID_LEN - 1] = 0x00;
+ else if (version == T4T_VERSION_2_0)
+ ce_test_tag_app_id[T4T_V20_NDEF_TAG_AID_LEN - 1] = 0x01;
+ else /* Undefined version */
+ ce_test_tag_app_id[T4T_V20_NDEF_TAG_AID_LEN - 1] = 0xFF;
+
+ UINT8_TO_BE_STREAM (p, version);
+ }
+ else
+ {
+ mapping_aid_test_enabled = FALSE;
+ p += 1;
+ }
+
+ if (max_le != 0xFFFF)
+ {
+ UINT16_TO_BE_STREAM (p, max_le);
+ }
+ else
+ p += 2;
+
+ if (max_lc != 0xFFFF)
+ {
+ UINT16_TO_BE_STREAM (p, max_lc);
+ }
+ else
+ p += 2;
+
+ return NFC_STATUS_OK;
+#else
+ return NFC_STATUS_FAILED;
+#endif
+}
+
+/*******************************************************************************
+**
+** Function CE_T4TTestSetNDEFCtrlTLV
+**
+** Description Set fields in NDEF File Control TLV for testing
+**
+** Returns NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS CE_T4TTestSetNDEFCtrlTLV (UINT8 type,
+ UINT8 length,
+ UINT16 file_id,
+ UINT16 max_file_size,
+ UINT8 read_access,
+ UINT8 write_access)
+{
+#if (CE_TEST_INCLUDED == TRUE)
+ tCE_T4T_MEM *p_t4t = &ce_cb.mem.t4t;
+ UINT8 *p;
+
+ CE_TRACE_DEBUG6 ("CE_T4TTestSetNDEFCtrlTLV (): type:0x%02X, len:0x%02X, FileID:0x%04X, MaxFile:0x%04X, RdAcc:0x%02X, WrAcc:0x%02X",
+ type, length, file_id, max_file_size, read_access, write_access);
+
+ /* NDEF File control TLV */
+ p = p_t4t->cc_file + T4T_FC_TLV_OFFSET_IN_CC;
+
+ if (type != 0xFF)
+ {
+ UINT8_TO_BE_STREAM (p, type);
+ }
+ else
+ p += 1;
+
+ if (length != 0xFF)
+ {
+ UINT8_TO_BE_STREAM (p, length);
+ }
+ else
+ p += 1;
+
+ if (file_id != 0xFFFF)
+ {
+ UINT16_TO_BE_STREAM (p, file_id);
+ }
+ else
+ p += 2;
+
+ if (max_file_size != 0xFFFF)
+ {
+ UINT16_TO_BE_STREAM (p, max_file_size);
+ }
+ else
+ p += 2;
+
+ if (read_access != 0xFF)
+ {
+ UINT8_TO_BE_STREAM (p, read_access);
+ }
+ else
+ p += 1;
+
+ if (write_access != 0xFF)
+ {
+ UINT8_TO_BE_STREAM (p, write_access);
+ }
+ else
+ p += 1;
+
+ return NFC_STATUS_OK;
+#else
+ return NFC_STATUS_FAILED;
+#endif
+}
+#endif /* NFC_INCLUDED == TRUE */
diff --git a/src/nfc/tags/rw_i93.c b/src/nfc/tags/rw_i93.c
new file mode 100644
index 0000000..a7e9d5c
--- /dev/null
+++ b/src/nfc/tags/rw_i93.c
@@ -0,0 +1,4328 @@
+/******************************************************************************
+ *
+ * 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"
+
+#if (NFC_INCLUDED == TRUE)
+
+#include "nfc_api.h"
+#include "nfc_int.h"
+#include "rw_api.h"
+#include "rw_int.h"
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define RW_I93_TOUT_RESP RW_I93_MAX_RSP_TIMEOUT /* Response timeout */
+#endif
+#define RW_I93_TOUT_STAY_QUIET 200 /* stay quiet timeout */
+#define RW_I93_READ_MULTI_BLOCK_SIZE 128 /* max reading data if read multi block is supported */
+#define RW_I93_FORMAT_DATA_LEN 8 /* CC, zero length NDEF, Terminator TLV */
+#define RW_I93_GET_MULTI_BLOCK_SEC_SIZE 512 /* max getting lock status if get multi block sec is supported */
+
+/* main state */
+enum
+{
+ RW_I93_STATE_NOT_ACTIVATED, /* ISO15693 is not activated */
+ RW_I93_STATE_IDLE, /* waiting for upper layer API */
+ RW_I93_STATE_BUSY, /* waiting for response from tag */
+
+ RW_I93_STATE_DETECT_NDEF, /* performing NDEF detection precedure */
+ RW_I93_STATE_READ_NDEF, /* performing read NDEF procedure */
+ RW_I93_STATE_UPDATE_NDEF, /* performing update NDEF procedure */
+ RW_I93_STATE_FORMAT, /* performing format procedure */
+ RW_I93_STATE_SET_READ_ONLY, /* performing set read-only procedure */
+
+ RW_I93_STATE_PRESENCE_CHECK /* checking presence of tag */
+};
+
+/* sub state */
+enum
+{
+ RW_I93_SUBSTATE_WAIT_UID, /* waiting for response of inventory */
+ RW_I93_SUBSTATE_WAIT_SYS_INFO, /* waiting for response of get sys info */
+ RW_I93_SUBSTATE_WAIT_CC, /* waiting for reading CC */
+ RW_I93_SUBSTATE_SEARCH_NDEF_TLV, /* searching NDEF TLV */
+ RW_I93_SUBSTATE_CHECK_LOCK_STATUS, /* check if any NDEF TLV is locked */
+
+ RW_I93_SUBSTATE_RESET_LEN, /* set length to 0 to update NDEF TLV */
+ RW_I93_SUBSTATE_WRITE_NDEF, /* writing NDEF and Terminator TLV */
+ RW_I93_SUBSTATE_UPDATE_LEN, /* set length into NDEF TLV */
+
+ RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI, /* reset DSFID and AFI */
+ RW_I93_SUBSTATE_CHECK_READ_ONLY, /* check if any block is locked */
+ RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV, /* write CC and empty NDEF/Terminator TLV */
+
+ RW_I93_SUBSTATE_WAIT_UPDATE_CC, /* updating CC as read-only */
+ RW_I93_SUBSTATE_LOCK_NDEF_TLV, /* lock blocks of NDEF TLV */
+ RW_I93_SUBSTATE_WAIT_LOCK_CC /* lock block of CC */
+};
+
+#if (BT_TRACE_VERBOSE == TRUE)
+static char *rw_i93_get_state_name (UINT8 state);
+static char *rw_i93_get_sub_state_name (UINT8 sub_state);
+static char *rw_i93_get_tag_name (UINT8 product_version);
+#endif
+
+static void rw_i93_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data);
+void rw_i93_handle_error (tNFC_STATUS status);
+tNFC_STATUS rw_i93_send_cmd_get_sys_info (UINT8 *p_uid, UINT8 extra_flag);
+
+/*******************************************************************************
+**
+** Function rw_i93_get_product_version
+**
+** Description Get product version from UID
+**
+** Returns void
+**
+*******************************************************************************/
+void rw_i93_get_product_version (UINT8 *p_uid)
+{
+ tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
+
+ if (!memcmp (p_i93->uid, p_uid, I93_UID_BYTE_LEN))
+ {
+ return;
+ }
+
+ RW_TRACE_DEBUG0 ("rw_i93_get_product_version ()");
+
+ memcpy (p_i93->uid, p_uid, I93_UID_BYTE_LEN);
+
+ if (p_uid[1] == I93_UID_IC_MFG_CODE_NXP)
+ {
+ if (p_uid[2] == I93_UID_ICODE_SLI)
+ p_i93->product_version = RW_I93_ICODE_SLI;
+ else if (p_uid[2] == I93_UID_ICODE_SLI_S)
+ p_i93->product_version = RW_I93_ICODE_SLI_S;
+ else if (p_uid[2] == I93_UID_ICODE_SLI_L)
+ p_i93->product_version = RW_I93_ICODE_SLI_L;
+ else
+ p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
+ }
+ else if (p_uid[1] == I93_UID_IC_MFG_CODE_TI)
+ {
+ if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_PLUS_INLAY)
+ p_i93->product_version = RW_I93_TAG_IT_HF_I_PLUS_INLAY;
+ else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_PLUS_CHIP)
+ p_i93->product_version = RW_I93_TAG_IT_HF_I_PLUS_CHIP;
+ else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY)
+ p_i93->product_version = RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY;
+ else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_PRO_CHIP_INLAY)
+ p_i93->product_version = RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY;
+ else
+ p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
+ }
+ else 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
+**
+*******************************************************************************/
+BOOLEAN rw_i93_process_sys_info (UINT8* p_data)
+{
+ UINT8 *p = p_data;
+ tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
+ UINT8 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
+**
+*******************************************************************************/
+BOOLEAN rw_i93_check_sys_info_prot_ext (UINT8 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 (BT_HDR *p_resp)
+{
+ UINT8 *p = (UINT8 *) (p_resp + 1) + p_resp->offset, *p_uid;
+ UINT16 length = p_resp->len;
+ tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
+ tRW_DATA rw_data;
+ UINT8 event = RW_I93_MAX_EVT;
+ UINT8 flags;
+ BT_HDR *p_buff;
+
+ RW_TRACE_DEBUG0 ("rw_i93_send_to_upper ()");
+
+ STREAM_TO_UINT8 (flags, p);
+ length--;
+
+ if (flags & I93_FLAG_ERROR_DETECTED)
+ {
+ 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 = (BT_HDR*) GKI_getbuf ((UINT16) (length + BT_HDR_SIZE));
+
+ if (p_buff)
+ {
+ p_buff->offset = 0;
+ p_buff->len = length;
+
+ memcpy ((p_buff + 1), p, length);
+
+ rw_data.i93_data.status = NFC_STATUS_OK;
+ rw_data.i93_data.command = p_i93->sent_cmd;
+ rw_data.i93_data.p_data = p_buff;
+
+ event = RW_I93_DATA_EVT;
+ }
+ else
+ {
+ rw_data.i93_cmd_cmpl.status = NFC_STATUS_NO_BUFFERS;
+ rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
+ rw_data.i93_cmd_cmpl.error_code = 0;
+
+ event = RW_I93_CMD_CMPL_EVT;
+ }
+ break;
+
+ case I93_CMD_WRITE_SINGLE_BLOCK:
+ case I93_CMD_LOCK_BLOCK:
+ case I93_CMD_WRITE_MULTI_BLOCK:
+ case I93_CMD_SELECT:
+ case I93_CMD_RESET_TO_READY:
+ case I93_CMD_WRITE_AFI:
+ case I93_CMD_LOCK_AFI:
+ case I93_CMD_WRITE_DSFID:
+ case I93_CMD_LOCK_DSFID:
+
+ /* notify the complete of command */
+ rw_data.i93_cmd_cmpl.status = NFC_STATUS_OK;
+ rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
+ rw_data.i93_cmd_cmpl.error_code = 0;
+
+ event = RW_I93_CMD_CMPL_EVT;
+ break;
+
+ case I93_CMD_GET_SYS_INFO:
+
+ 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
+**
+*******************************************************************************/
+BOOLEAN rw_i93_send_to_lower (BT_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 = (BT_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 (BT_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 *p_uid, BOOLEAN including_afi, UINT8 afi)
+{
+ BT_HDR *p_cmd;
+ UINT8 *p, flags;
+
+ RW_TRACE_DEBUG2 ("rw_i93_send_cmd_inventory () including_afi:%d, AFI:0x%02X", including_afi, afi);
+
+ p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+ if (!p_cmd)
+ {
+ RW_TRACE_ERROR0 ("rw_i93_send_cmd_inventory (): Cannot allocate buffer");
+ return NFC_STATUS_NO_BUFFERS;
+ }
+
+ p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p_cmd->len = 3;
+ p = (UINT8 *) (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)
+{
+ BT_HDR *p_cmd;
+ UINT8 *p;
+
+ RW_TRACE_DEBUG0 ("rw_i93_send_cmd_stay_quiet ()");
+
+ p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+ if (!p_cmd)
+ {
+ RW_TRACE_ERROR0 ("rw_i93_send_cmd_stay_quiet (): Cannot allocate buffer");
+ return NFC_STATUS_NO_BUFFERS;
+ }
+
+ p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p_cmd->len = 10;
+ p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+ /* Flags */
+ UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+
+ /* Command Code */
+ UINT8_TO_STREAM (p, I93_CMD_STAY_QUIET);
+
+ /* Parameters */
+ ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
+
+ if (rw_i93_send_to_lower (p_cmd))
+ {
+ rw_cb.tcb.i93.sent_cmd = I93_CMD_STAY_QUIET;
+
+ /* restart timer for stay quiet */
+ nfc_start_quick_timer (&rw_cb.tcb.i93.timer, NFC_TTYPE_RW_I93_RESPONSE,
+ (RW_I93_TOUT_STAY_QUIET * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+ return NFC_STATUS_OK;
+ }
+ else
+ {
+ return NFC_STATUS_FAILED;
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_i93_send_cmd_read_single_block
+**
+** Description Send Read Single Block Request to VICC
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_read_single_block (UINT16 block_number, BOOLEAN read_security)
+{
+ BT_HDR *p_cmd;
+ UINT8 *p, flags;
+
+ RW_TRACE_DEBUG0 ("rw_i93_send_cmd_read_single_block ()");
+
+ p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+ if (!p_cmd)
+ {
+ RW_TRACE_ERROR0 ("rw_i93_send_cmd_read_single_block (): Cannot allocate buffer");
+ return NFC_STATUS_NO_BUFFERS;
+ }
+
+ p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p_cmd->len = 11;
+ p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+ /* Flags */
+ 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 block_number, UINT8 *p_data)
+{
+ BT_HDR *p_cmd;
+ UINT8 *p, flags;
+
+ RW_TRACE_DEBUG0 ("rw_i93_send_cmd_write_single_block ()");
+
+ p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+ if (!p_cmd)
+ {
+ RW_TRACE_ERROR0 ("rw_i93_send_cmd_write_single_block (): Cannot allocate buffer");
+ return NFC_STATUS_NO_BUFFERS;
+ }
+
+ p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p_cmd->len = 11 + rw_cb.tcb.i93.block_size;
+ p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+ /* Flags */
+ if ( (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY)
+ ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)
+ ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
+ ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) )
+ {
+ /* Option must be set for TI tag */
+ 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 block_number)
+{
+ BT_HDR *p_cmd;
+ UINT8 *p;
+
+ RW_TRACE_DEBUG0 ("rw_i93_send_cmd_lock_block ()");
+
+ p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+ if (!p_cmd)
+ {
+ RW_TRACE_ERROR0 ("rw_i93_send_cmd_lock_block (): Cannot allocate buffer");
+ return NFC_STATUS_NO_BUFFERS;
+ }
+
+ p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p_cmd->len = 11;
+ p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+ /* Flags */
+ if ( (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY)
+ ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)
+ ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
+ ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) )
+ {
+ /* Option must be set for TI tag */
+ UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | I93_FLAG_OPTION_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+ }
+ else
+ {
+ UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+ }
+
+ /* Command Code */
+ UINT8_TO_STREAM (p, I93_CMD_LOCK_BLOCK);
+
+ /* Parameters */
+ ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
+ UINT8_TO_STREAM (p, block_number); /* Block number */
+
+ if (rw_i93_send_to_lower (p_cmd))
+ {
+ rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_BLOCK;
+ return NFC_STATUS_OK;
+ }
+ else
+ {
+ return NFC_STATUS_FAILED;
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_i93_send_cmd_read_multi_blocks
+**
+** Description Send Read Multiple Blocks Request to VICC
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_read_multi_blocks (UINT16 first_block_number, UINT16 number_blocks)
+{
+ BT_HDR *p_cmd;
+ UINT8 *p, flags;
+
+ RW_TRACE_DEBUG0 ("rw_i93_send_cmd_read_multi_blocks ()");
+
+ p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+ if (!p_cmd)
+ {
+ RW_TRACE_ERROR0 ("rw_i93_send_cmd_read_multi_blocks (): Cannot allocate buffer");
+ return NFC_STATUS_NO_BUFFERS;
+ }
+
+ p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p_cmd->len = 12;
+ p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+ /* Flags */
+ 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 first_block_number,
+ UINT16 number_blocks,
+ UINT8 *p_data)
+{
+ BT_HDR *p_cmd;
+ UINT8 *p;
+
+ RW_TRACE_DEBUG0 ("rw_i93_send_cmd_write_multi_blocks ()");
+
+ p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+ if (!p_cmd)
+ {
+ RW_TRACE_ERROR0 ("rw_i93_send_cmd_write_multi_blocks (): Cannot allocate buffer");
+ return NFC_STATUS_NO_BUFFERS;
+ }
+
+ p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p_cmd->len = 12 + number_blocks * rw_cb.tcb.i93.block_size;
+ p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+ /* Flags */
+ UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+
+ /* Command Code */
+ UINT8_TO_STREAM (p, I93_CMD_WRITE_MULTI_BLOCK);
+
+ /* Parameters */
+ ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
+ UINT8_TO_STREAM (p, first_block_number); /* First block number */
+ UINT8_TO_STREAM (p, number_blocks - 1); /* Number of blocks, 0x00 to read one block */
+
+ /* Data */
+ ARRAY_TO_STREAM (p, p_data, number_blocks * rw_cb.tcb.i93.block_size);
+
+ if (rw_i93_send_to_lower (p_cmd))
+ {
+ rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_MULTI_BLOCK;
+ return NFC_STATUS_OK;
+ }
+ else
+ {
+ return NFC_STATUS_FAILED;
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_i93_send_cmd_select
+**
+** Description Send Select Request to VICC
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_select (UINT8 *p_uid)
+{
+ BT_HDR *p_cmd;
+ UINT8 *p;
+
+ RW_TRACE_DEBUG0 ("rw_i93_send_cmd_select ()");
+
+ p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+ if (!p_cmd)
+ {
+ RW_TRACE_ERROR0 ("rw_i93_send_cmd_select (): Cannot allocate buffer");
+ return NFC_STATUS_NO_BUFFERS;
+ }
+
+ p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p_cmd->len = 10 ;
+ p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+ /* Flags */
+ UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+
+ /* Command Code */
+ UINT8_TO_STREAM (p, I93_CMD_SELECT);
+
+ /* Parameters */
+ ARRAY8_TO_STREAM (p, p_uid); /* UID */
+
+ if (rw_i93_send_to_lower (p_cmd))
+ {
+ rw_cb.tcb.i93.sent_cmd = I93_CMD_SELECT;
+ return NFC_STATUS_OK;
+ }
+ else
+ {
+ return NFC_STATUS_FAILED;
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_i93_send_cmd_reset_to_ready
+**
+** Description Send Reset to Ready Request to VICC
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_reset_to_ready (void)
+{
+ BT_HDR *p_cmd;
+ UINT8 *p;
+
+ RW_TRACE_DEBUG0 ("rw_i93_send_cmd_reset_to_ready ()");
+
+ p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+ if (!p_cmd)
+ {
+ RW_TRACE_ERROR0 ("rw_i93_send_cmd_reset_to_ready (): Cannot allocate buffer");
+ return NFC_STATUS_NO_BUFFERS;
+ }
+
+ p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p_cmd->len = 10 ;
+ p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+ /* Flags */
+ UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+
+ /* Command Code */
+ UINT8_TO_STREAM (p, I93_CMD_RESET_TO_READY);
+
+ /* Parameters */
+ ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
+
+ if (rw_i93_send_to_lower (p_cmd))
+ {
+ rw_cb.tcb.i93.sent_cmd = I93_CMD_RESET_TO_READY;
+ return NFC_STATUS_OK;
+ }
+ else
+ {
+ return NFC_STATUS_FAILED;
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_i93_send_cmd_write_afi
+**
+** Description Send Write AFI Request to VICC
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_write_afi (UINT8 afi)
+{
+ BT_HDR *p_cmd;
+ UINT8 *p;
+
+ RW_TRACE_DEBUG0 ("rw_i93_send_cmd_write_afi ()");
+
+ p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+ if (!p_cmd)
+ {
+ RW_TRACE_ERROR0 ("rw_i93_send_cmd_write_afi (): Cannot allocate buffer");
+ return NFC_STATUS_NO_BUFFERS;
+ }
+
+ p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p_cmd->len = 11;
+ p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+ /* Flags */
+ UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+
+ /* Command Code */
+ UINT8_TO_STREAM (p, I93_CMD_WRITE_AFI);
+
+ /* Parameters */
+ ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
+ UINT8_TO_STREAM (p, afi); /* AFI */
+
+ if (rw_i93_send_to_lower (p_cmd))
+ {
+ rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_AFI;
+ return NFC_STATUS_OK;
+ }
+ else
+ {
+ return NFC_STATUS_FAILED;
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_i93_send_cmd_lock_afi
+**
+** Description Send Lock AFI Request to VICC
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_lock_afi (void)
+{
+ BT_HDR *p_cmd;
+ UINT8 *p;
+
+ RW_TRACE_DEBUG0 ("rw_i93_send_cmd_lock_afi ()");
+
+ p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+ if (!p_cmd)
+ {
+ RW_TRACE_ERROR0 ("rw_i93_send_cmd_lock_afi (): Cannot allocate buffer");
+ return NFC_STATUS_NO_BUFFERS;
+ }
+
+ p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p_cmd->len = 10;
+ p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+ /* Flags */
+ UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+
+ /* Command Code */
+ UINT8_TO_STREAM (p, I93_CMD_LOCK_AFI);
+
+ /* Parameters */
+ ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
+
+ if (rw_i93_send_to_lower (p_cmd))
+ {
+ rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_AFI;
+ return NFC_STATUS_OK;
+ }
+ else
+ {
+ return NFC_STATUS_FAILED;
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_i93_send_cmd_write_dsfid
+**
+** Description Send Write DSFID Request to VICC
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_write_dsfid (UINT8 dsfid)
+{
+ BT_HDR *p_cmd;
+ UINT8 *p;
+
+ RW_TRACE_DEBUG0 ("rw_i93_send_cmd_write_dsfid ()");
+
+ p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+ if (!p_cmd)
+ {
+ RW_TRACE_ERROR0 ("rw_i93_send_cmd_write_dsfid (): Cannot allocate buffer");
+ return NFC_STATUS_NO_BUFFERS;
+ }
+
+ p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p_cmd->len = 11;
+ p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+ /* Flags */
+ UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+
+ /* Command Code */
+ UINT8_TO_STREAM (p, I93_CMD_WRITE_DSFID);
+
+ /* Parameters */
+ ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
+ UINT8_TO_STREAM (p, dsfid); /* DSFID */
+
+ if (rw_i93_send_to_lower (p_cmd))
+ {
+ rw_cb.tcb.i93.sent_cmd = I93_CMD_WRITE_DSFID;
+ return NFC_STATUS_OK;
+ }
+ else
+ {
+ return NFC_STATUS_FAILED;
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_i93_send_cmd_lock_dsfid
+**
+** Description Send Lock DSFID Request to VICC
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_lock_dsfid (void)
+{
+ BT_HDR *p_cmd;
+ UINT8 *p;
+
+ RW_TRACE_DEBUG0 ("rw_i93_send_cmd_lock_dsfid ()");
+
+ p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+ if (!p_cmd)
+ {
+ RW_TRACE_ERROR0 ("rw_i93_send_cmd_lock_dsfid (): Cannot allocate buffer");
+ return NFC_STATUS_NO_BUFFERS;
+ }
+
+ p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p_cmd->len = 10;
+ p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+ /* Flags */
+ UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+
+ /* Command Code */
+ UINT8_TO_STREAM (p, I93_CMD_LOCK_DSFID);
+
+ /* Parameters */
+ ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid); /* UID */
+
+ if (rw_i93_send_to_lower (p_cmd))
+ {
+ rw_cb.tcb.i93.sent_cmd = I93_CMD_LOCK_DSFID;
+ return NFC_STATUS_OK;
+ }
+ else
+ {
+ return NFC_STATUS_FAILED;
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_i93_send_cmd_get_sys_info
+**
+** Description Send Get System Information Request to VICC
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_get_sys_info (UINT8 *p_uid, UINT8 extra_flags)
+{
+ BT_HDR *p_cmd;
+ UINT8 *p;
+
+ RW_TRACE_DEBUG0 ("rw_i93_send_cmd_get_sys_info ()");
+
+ p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+ if (!p_cmd)
+ {
+ RW_TRACE_ERROR0 ("rw_i93_send_cmd_get_sys_info (): Cannot allocate buffer");
+ return NFC_STATUS_NO_BUFFERS;
+ }
+
+ p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p_cmd->len = 10;
+ p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+ /* Flags */
+ UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE | 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 first_block_number,
+ UINT16 number_blocks)
+{
+ BT_HDR *p_cmd;
+ UINT8 *p, flags;
+
+ RW_TRACE_DEBUG0 ("rw_i93_send_cmd_get_multi_block_sec ()");
+
+ p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+ if (!p_cmd)
+ {
+ RW_TRACE_ERROR0 ("rw_i93_send_cmd_get_multi_block_sec (): Cannot allocate buffer");
+ return NFC_STATUS_NO_BUFFERS;
+ }
+
+ p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p_cmd->len = 12;
+ p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+ /* Flags */
+ 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 offset)
+{
+ tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
+ UINT16 first_block;
+ UINT16 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 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 (BT_HDR *p_resp)
+{
+ UINT8 *p = (UINT8 *) (p_resp + 1) + p_resp->offset, *p_uid;
+ UINT8 flags, u8 = 0, cc[4];
+ UINT16 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 */
+ p_i93->rw_offset = 4;
+
+ if (rw_i93_get_next_blocks (p_i93->rw_offset) == NFC_STATUS_OK)
+ {
+ p_i93->sub_state = RW_I93_SUBSTATE_SEARCH_NDEF_TLV;
+ p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_TYPE;
+ }
+ else
+ {
+ rw_i93_handle_error (NFC_STATUS_FAILED);
+ }
+ }
+ else
+ {
+ rw_i93_handle_error (NFC_STATUS_FAILED);
+ }
+ break;
+
+ case RW_I93_SUBSTATE_SEARCH_NDEF_TLV:
+
+ /* search TLV within read blocks */
+ for (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)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)(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 (BT_HDR *p_resp)
+{
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ UINT8 *p;
+ UINT16 offset = 0, length = 0;
+#else
+ UINT8 *p = (UINT8 *) (p_resp + 1) + p_resp->offset;
+ UINT16 offset, length = p_resp->len;
+#endif
+
+ UINT8 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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ p = (UINT8 *) (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;
+ }
+
+ /* if read all of NDEF data */
+ if (p_i93->rw_length >= p_i93->ndef_length)
+ {
+ /* remove extra btyes in the last block */
+ p_resp->len -= (p_i93->rw_length - p_i93->ndef_length);
+
+ p_i93->state = RW_I93_STATE_IDLE;
+ p_i93->sent_cmd = 0;
+
+ RW_TRACE_DEBUG2 ("NDEF read complete read (%d)/total (%d)",
+ p_resp->len,
+ p_i93->ndef_length);
+
+ (*(rw_cb.p_cback)) (RW_I93_NDEF_READ_CPLT_EVT, &rw_data);
+ }
+ else
+ {
+ RW_TRACE_DEBUG2 ("NDEF read segment read (%d)/total (%d)",
+ p_resp->len,
+ p_i93->ndef_length);
+
+ (*(rw_cb.p_cback)) (RW_I93_NDEF_READ_EVT, &rw_data);
+
+ /* this will make read data from next block */
+ p_i93->rw_offset += length;
+
+ if (rw_i93_get_next_blocks (p_i93->rw_offset) != NFC_STATUS_OK)
+ {
+ rw_i93_handle_error (NFC_STATUS_FAILED);
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_i93_sm_update_ndef
+**
+** Description Process NDEF update procedure
+**
+** 1. Set length field to zero
+** 2. Write NDEF and Terminator TLV
+** 3. Set length field to NDEF length
+**
+** Returns void
+**
+*******************************************************************************/
+void rw_i93_sm_update_ndef (BT_HDR *p_resp)
+{
+ UINT8 *p = (UINT8 *) (p_resp + 1) + p_resp->offset;
+ UINT8 flags, xx, length_offset, buff[I93_MAX_BLOCK_LENGH];
+ UINT16 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) (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) ((p_i93->ndef_length >> 8) & 0xFF);
+ else if (p_i93->rw_length == 1)
+ *(p + xx) = (UINT8) (p_i93->ndef_length & 0xFF);
+
+ p_i93->rw_length--;
+ if (p_i93->rw_length == 0)
+ break;
+ }
+
+ block_number = (p_i93->rw_offset / p_i93->block_size);
+
+ if (rw_i93_send_cmd_write_single_block (block_number, p) == NFC_STATUS_OK)
+ {
+ /* set offset to the beginning of next block */
+ p_i93->rw_offset += p_i93->block_size - (p_i93->rw_offset % p_i93->block_size);
+ }
+ else
+ {
+ rw_i93_handle_error (NFC_STATUS_FAILED);
+ }
+ }
+ }
+ else
+ {
+ RW_TRACE_DEBUG3 ("NDEF update complete, %d bytes, (%d-%d)",
+ p_i93->ndef_length,
+ p_i93->ndef_tlv_start_offset,
+ p_i93->ndef_tlv_last_offset);
+
+ p_i93->state = RW_I93_STATE_IDLE;
+ p_i93->sent_cmd = 0;
+ p_i93->p_update_data = NULL;
+
+ rw_data.status = NFC_STATUS_OK;
+ (*(rw_cb.p_cback)) (RW_I93_NDEF_UPDATE_CPLT_EVT, &rw_data);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_i93_sm_format
+**
+** Description Process format procedure
+**
+** 1. Get UID
+** 2. Get sys info for memory size (reset AFI/DSFID)
+** 3. Get block status to get read-only status
+** 4. Write CC and empty NDEF
+**
+** Returns void
+**
+*******************************************************************************/
+void rw_i93_sm_format (BT_HDR *p_resp)
+{
+ UINT8 *p = (UINT8 *) (p_resp + 1) + p_resp->offset, *p_uid;
+ UINT8 flags;
+ UINT16 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)(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)(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*) 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) ((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 (BT_HDR *p_resp)
+{
+ UINT8 *p = (UINT8 *) (p_resp + 1) + p_resp->offset;
+ UINT8 flags, block_number;
+ UINT16 length = p_resp->len;
+ tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
+ tRW_DATA rw_data;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ RW_TRACE_DEBUG2 ("rw_i93_sm_set_read_only () sub_state:%s (0x%x)",
+ rw_i93_get_sub_state_name (p_i93->sub_state), p_i93->sub_state);
+#else
+ RW_TRACE_DEBUG1 ("rw_i93_sm_set_read_only () sub_state:0x%x", p_i93->sub_state);
+#endif
+
+ STREAM_TO_UINT8 (flags, p);
+ length--;
+
+ if (flags & I93_FLAG_ERROR_DETECTED)
+ {
+ if ( ( (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY)
+ ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)
+ ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
+ ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY) )
+ &&
+ (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE) )
+ {
+ /* ignore error */
+ }
+ else
+ {
+ RW_TRACE_DEBUG1 ("Got error flags (0x%02x)", flags);
+ rw_i93_handle_error (NFC_STATUS_FAILED);
+ return;
+ }
+ }
+
+ switch (p_i93->sub_state)
+ {
+ case RW_I93_SUBSTATE_WAIT_CC:
+
+ /* mark CC as read-only */
+ *(p+1) |= I93_ICODE_CC_READ_ONLY;
+
+ if (rw_i93_send_cmd_write_single_block (0, p) == NFC_STATUS_OK)
+ {
+ p_i93->sub_state = RW_I93_SUBSTATE_WAIT_UPDATE_CC;
+ }
+ else
+ {
+ rw_i93_handle_error (NFC_STATUS_FAILED);
+ }
+ break;
+
+ case RW_I93_SUBSTATE_WAIT_UPDATE_CC:
+
+ /* successfully write CC then lock all blocks of NDEF TLV */
+ p_i93->rw_offset = p_i93->ndef_tlv_start_offset;
+ block_number = (UINT8) (p_i93->rw_offset / p_i93->block_size);
+
+ if (rw_i93_send_cmd_lock_block (block_number) == NFC_STATUS_OK)
+ {
+ p_i93->rw_offset += p_i93->block_size;
+ p_i93->sub_state = RW_I93_SUBSTATE_LOCK_NDEF_TLV;
+ }
+ else
+ {
+ rw_i93_handle_error (NFC_STATUS_FAILED);
+ }
+ break;
+
+ case RW_I93_SUBSTATE_LOCK_NDEF_TLV:
+
+ /* if we need to lock more blocks */
+ if (p_i93->rw_offset < p_i93->ndef_tlv_last_offset)
+ {
+ /* get the next block of NDEF TLV */
+ block_number = (UINT8) (p_i93->rw_offset / p_i93->block_size);
+
+ if (rw_i93_send_cmd_lock_block (block_number) == NFC_STATUS_OK)
+ {
+ p_i93->rw_offset += p_i93->block_size;
+ }
+ else
+ {
+ rw_i93_handle_error (NFC_STATUS_FAILED);
+ }
+ }
+ /* if the first block of NDEF TLV is different from block of CC */
+ else if (p_i93->ndef_tlv_start_offset / p_i93->block_size != 0)
+ {
+ /* lock block of CC */
+ if (rw_i93_send_cmd_lock_block (0) == NFC_STATUS_OK)
+ {
+ p_i93->sub_state = RW_I93_SUBSTATE_WAIT_LOCK_CC;
+ }
+ else
+ {
+ rw_i93_handle_error (NFC_STATUS_FAILED);
+ }
+ }
+ else
+ {
+ p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
+ p_i93->state = RW_I93_STATE_IDLE;
+ p_i93->sent_cmd = 0;
+
+ rw_data.status = NFC_STATUS_OK;
+ (*(rw_cb.p_cback)) (RW_I93_SET_TAG_RO_EVT, &rw_data);
+ }
+ break;
+
+ case RW_I93_SUBSTATE_WAIT_LOCK_CC:
+
+ p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
+ p_i93->state = RW_I93_STATE_IDLE;
+ p_i93->sent_cmd = 0;
+
+ rw_data.status = NFC_STATUS_OK;
+ (*(rw_cb.p_cback)) (RW_I93_SET_TAG_RO_EVT, &rw_data);
+ break;
+
+ default:
+ break;
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_i93_handle_error
+**
+** Description notify error to application and clean up
+**
+** Returns none
+**
+*******************************************************************************/
+void rw_i93_handle_error (tNFC_STATUS status)
+{
+ tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
+ tRW_DATA rw_data;
+ tRW_EVENT event;
+
+ RW_TRACE_DEBUG2 ("rw_i93_handle_error (): status:0x%02X, state:0x%X",
+ status, p_i93->state);
+
+ nfc_stop_quick_timer (&p_i93->timer);
+
+ if (rw_cb.p_cback)
+ {
+ rw_data.status = status;
+
+ switch (p_i93->state)
+ {
+ case RW_I93_STATE_IDLE: /* in case of RawFrame */
+ event = RW_I93_INTF_ERROR_EVT;
+ break;
+
+ case RW_I93_STATE_BUSY:
+ if (p_i93->sent_cmd == I93_CMD_STAY_QUIET)
+ {
+ /* There is no response to Stay Quiet command */
+ rw_data.i93_cmd_cmpl.status = NFC_STATUS_OK;
+ rw_data.i93_cmd_cmpl.command = I93_CMD_STAY_QUIET;
+ rw_data.i93_cmd_cmpl.error_code = 0;
+ event = RW_I93_CMD_CMPL_EVT;
+ }
+ else
+ {
+ event = RW_I93_INTF_ERROR_EVT;
+ }
+ break;
+
+ case RW_I93_STATE_DETECT_NDEF:
+ rw_data.ndef.protocol = NFC_PROTOCOL_15693;
+ rw_data.ndef.cur_size = 0;
+ rw_data.ndef.max_size = 0;
+ rw_data.ndef.flags = 0;
+ rw_data.ndef.flags |= RW_NDEF_FL_FORMATABLE;
+ rw_data.ndef.flags |= RW_NDEF_FL_UNKNOWN;
+ event = RW_I93_NDEF_DETECT_EVT;
+ break;
+
+ case RW_I93_STATE_READ_NDEF:
+ event = RW_I93_NDEF_READ_FAIL_EVT;
+ break;
+
+ case RW_I93_STATE_UPDATE_NDEF:
+ p_i93->p_update_data = NULL;
+ event = RW_I93_NDEF_UPDATE_FAIL_EVT;
+ break;
+
+ case RW_I93_STATE_FORMAT:
+ if (p_i93->p_update_data)
+ {
+ GKI_freebuf (p_i93->p_update_data);
+ p_i93->p_update_data = NULL;
+ }
+ event = RW_I93_FORMAT_CPLT_EVT;
+ break;
+
+ case RW_I93_STATE_SET_READ_ONLY:
+ event = RW_I93_SET_TAG_RO_EVT;
+ break;
+
+ case RW_I93_STATE_PRESENCE_CHECK:
+ event = RW_I93_PRESENCE_CHECK_EVT;
+ break;
+
+ default:
+ event = RW_I93_MAX_EVT;
+ break;
+ }
+
+ p_i93->state = RW_I93_STATE_IDLE;
+ p_i93->sent_cmd = 0;
+
+ if (event != RW_I93_MAX_EVT)
+ {
+ (*(rw_cb.p_cback)) (event, &rw_data);
+ }
+ }
+ else
+ {
+ p_i93->state = RW_I93_STATE_IDLE;
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_i93_process_timeout
+**
+** Description process timeout event
+**
+** Returns none
+**
+*******************************************************************************/
+void rw_i93_process_timeout (TIMER_LIST_ENT *p_tle)
+{
+ BT_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 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
+{
+ tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
+ BT_HDR *p_resp;
+ tRW_DATA rw_data;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ UINT8 begin_state = p_i93->state;
+#endif
+
+ RW_TRACE_DEBUG1 ("rw_i93_data_cback () event = 0x%X", event);
+
+ if ( (event == NFC_DEACTIVATE_CEVT)
+ ||(event == NFC_ERROR_CEVT) )
+ {
+ nfc_stop_quick_timer (&p_i93->timer);
+
+ if (event == NFC_ERROR_CEVT)
+ {
+ 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*) p_data));
+ }
+ else
+ {
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ /* free retry buffer */
+ if ((event == NFC_DEACTIVATE_CEVT )&& p_i93->p_retry_cmd)
+ {
+ GKI_freebuf (p_i93->p_retry_cmd);
+ p_i93->p_retry_cmd = NULL;
+ p_i93->retry_count = 0;
+ }
+#endif
+ NFC_SetStaticRfCback (NULL);
+ p_i93->state = RW_I93_STATE_NOT_ACTIVATED;
+ }
+ return;
+ }
+
+ if (event != NFC_DATA_CEVT)
+ {
+ return;
+ }
+
+ p_resp = (BT_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 *p_uid)
+{
+ tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
+ UINT8 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 (BOOLEAN including_afi, UINT8 afi, UINT8 *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 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 block_number,
+ UINT8 *p_data)
+{
+ tNFC_STATUS status;
+
+ RW_TRACE_API0 ("RW_I93WriteSingleBlock ()");
+
+ if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("RW_I93WriteSingleBlock ():Unable to start command at state (0x%X)",
+ rw_cb.tcb.i93.state);
+ return NFC_STATUS_BUSY;
+ }
+
+ if (rw_cb.tcb.i93.block_size == 0)
+ {
+ RW_TRACE_ERROR0 ("RW_I93WriteSingleBlock ():Block size is unknown");
+ return NFC_STATUS_FAILED;
+ }
+
+ status = rw_i93_send_cmd_write_single_block (block_number, p_data);
+ if (status == NFC_STATUS_OK)
+ {
+ rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function RW_I93LockBlock
+**
+** Description This function send Lock Block command
+**
+** RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_NO_BUFFERS if out of buffer
+** NFC_STATUS_BUSY if busy
+** NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93LockBlock (UINT8 block_number)
+{
+ tNFC_STATUS status;
+
+ RW_TRACE_API0 ("RW_I93LockBlock ()");
+
+ if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("RW_I93LockBlock ():Unable to start command at state (0x%X)",
+ rw_cb.tcb.i93.state);
+ return NFC_STATUS_BUSY;
+ }
+
+ status = rw_i93_send_cmd_lock_block (block_number);
+ if (status == NFC_STATUS_OK)
+ {
+ rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function RW_I93ReadMultipleBlocks
+**
+** Description This function send Read Multiple Blocks command
+**
+** RW_I93_RESPONSE_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_NO_BUFFERS if out of buffer
+** NFC_STATUS_BUSY if busy
+** NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93ReadMultipleBlocks (UINT16 first_block_number,
+ UINT16 number_blocks)
+{
+ tNFC_STATUS status;
+
+ RW_TRACE_API0 ("RW_I93ReadMultipleBlocks ()");
+
+ if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("RW_I93ReadMultipleBlocks ():Unable to start command at state (0x%X)",
+ rw_cb.tcb.i93.state);
+ return NFC_STATUS_BUSY;
+ }
+
+ status = rw_i93_send_cmd_read_multi_blocks (first_block_number, number_blocks);
+ if (status == NFC_STATUS_OK)
+ {
+ rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function RW_I93WriteMultipleBlocks
+**
+** Description This function send Write Multiple Blocks command
+**
+** RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_NO_BUFFERS if out of buffer
+** NFC_STATUS_BUSY if busy
+** NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93WriteMultipleBlocks (UINT8 first_block_number,
+ UINT16 number_blocks,
+ UINT8 *p_data)
+{
+ tNFC_STATUS status;
+
+ RW_TRACE_API0 ("RW_I93WriteMultipleBlocks ()");
+
+ if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("RW_I93WriteMultipleBlocks ():Unable to start command at state (0x%X)",
+ rw_cb.tcb.i93.state);
+ return NFC_STATUS_BUSY;
+ }
+
+ if (rw_cb.tcb.i93.block_size == 0)
+ {
+ RW_TRACE_ERROR0 ("RW_I93WriteSingleBlock ():Block size is unknown");
+ return NFC_STATUS_FAILED;
+ }
+
+ status = rw_i93_send_cmd_write_multi_blocks (first_block_number, number_blocks, p_data);
+ if (status == NFC_STATUS_OK)
+ {
+ rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function RW_I93Select
+**
+** Description This function send Select command
+**
+** UID[0]: 0xE0, MSB
+** UID[1]: IC Mfg Code
+** ...
+** UID[7]: LSB
+**
+** RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_NO_BUFFERS if out of buffer
+** NFC_STATUS_BUSY if busy
+** NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93Select (UINT8 *p_uid)
+{
+ tNFC_STATUS status;
+
+ RW_TRACE_API0 ("RW_I93Select ()");
+
+ if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("RW_I93Select ():Unable to start command at state (0x%X)",
+ rw_cb.tcb.i93.state);
+ return NFC_STATUS_BUSY;
+ }
+
+ if (p_uid)
+ {
+ status = rw_i93_send_cmd_select (p_uid);
+ if (status == NFC_STATUS_OK)
+ {
+ rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+ }
+ }
+ else
+ {
+ RW_TRACE_ERROR0 ("RW_I93Select ():UID shall be provided");
+ status = NFC_STATUS_FAILED;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function RW_I93ResetToReady
+**
+** Description This function send Reset To Ready command
+**
+** RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_NO_BUFFERS if out of buffer
+** NFC_STATUS_BUSY if busy
+** NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93ResetToReady (void)
+{
+ tNFC_STATUS status;
+
+ RW_TRACE_API0 ("RW_I93ResetToReady ()");
+
+ if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("RW_I93ResetToReady ():Unable to start command at state (0x%X)",
+ rw_cb.tcb.i93.state);
+ return NFC_STATUS_BUSY;
+ }
+
+ status = rw_i93_send_cmd_reset_to_ready ();
+ if (status == NFC_STATUS_OK)
+ {
+ rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function RW_I93WriteAFI
+**
+** Description This function send Write AFI command
+**
+** RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_NO_BUFFERS if out of buffer
+** NFC_STATUS_BUSY if busy
+** NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93WriteAFI (UINT8 afi)
+{
+ tNFC_STATUS status;
+
+ RW_TRACE_API0 ("RW_I93WriteAFI ()");
+
+ if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("RW_I93WriteAFI ():Unable to start command at state (0x%X)",
+ rw_cb.tcb.i93.state);
+ return NFC_STATUS_BUSY;
+ }
+
+ status = rw_i93_send_cmd_write_afi (afi);
+ if (status == NFC_STATUS_OK)
+ {
+ rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function RW_I93LockAFI
+**
+** Description This function send Lock AFI command
+**
+** RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_NO_BUFFERS if out of buffer
+** NFC_STATUS_BUSY if busy
+** NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93LockAFI (void)
+{
+ tNFC_STATUS status;
+
+ RW_TRACE_API0 ("RW_I93LockAFI ()");
+
+ if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("RW_I93LockAFI ():Unable to start command at state (0x%X)",
+ rw_cb.tcb.i93.state);
+ return NFC_STATUS_BUSY;
+ }
+
+ status = rw_i93_send_cmd_lock_afi ();
+ if (status == NFC_STATUS_OK)
+ {
+ rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function RW_I93WriteDSFID
+**
+** Description This function send Write DSFID command
+**
+** RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_NO_BUFFERS if out of buffer
+** NFC_STATUS_BUSY if busy
+** NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93WriteDSFID (UINT8 dsfid)
+{
+ tNFC_STATUS status;
+
+ RW_TRACE_API0 ("RW_I93WriteDSFID ()");
+
+ if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("RW_I93WriteDSFID ():Unable to start command at state (0x%X)",
+ rw_cb.tcb.i93.state);
+ return NFC_STATUS_BUSY;
+ }
+
+ status = rw_i93_send_cmd_write_dsfid (dsfid);
+ if (status == NFC_STATUS_OK)
+ {
+ rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function RW_I93LockDSFID
+**
+** Description This function send Lock DSFID command
+**
+** RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_NO_BUFFERS if out of buffer
+** NFC_STATUS_BUSY if busy
+** NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93LockDSFID (void)
+{
+ tNFC_STATUS status;
+
+ RW_TRACE_API0 ("RW_I93LockDSFID ()");
+
+ if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("RW_I93LockDSFID ():Unable to start command at state (0x%X)",
+ rw_cb.tcb.i93.state);
+ return NFC_STATUS_BUSY;
+ }
+
+ status = rw_i93_send_cmd_lock_dsfid ();
+ if (status == NFC_STATUS_OK)
+ {
+ rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function RW_I93GetSysInfo
+**
+** Description This function send Get System Information command
+**
+** RW_I93_RESPONSE_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_NO_BUFFERS if out of buffer
+** NFC_STATUS_BUSY if busy
+** NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93GetSysInfo (UINT8 *p_uid)
+{
+ tNFC_STATUS status;
+
+ RW_TRACE_API0 ("RW_I93GetSysInfo ()");
+
+ if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("RW_I93GetSysInfo ():Unable to start command at state (0x%X)",
+ rw_cb.tcb.i93.state);
+ return NFC_STATUS_BUSY;
+ }
+
+ if (p_uid)
+ {
+ status = rw_i93_send_cmd_get_sys_info (p_uid, 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 first_block_number,
+ UINT16 number_blocks)
+{
+ tNFC_STATUS status;
+
+ RW_TRACE_API0 ("RW_I93GetMultiBlockSecurityStatus ()");
+
+ if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("RW_I93GetMultiBlockSecurityStatus ():Unable to start command at state (0x%X)",
+ rw_cb.tcb.i93.state);
+ return NFC_STATUS_BUSY;
+ }
+
+ status = rw_i93_send_cmd_get_multi_block_sec (first_block_number, number_blocks);
+ if (status == NFC_STATUS_OK)
+ {
+ rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function RW_I93DetectNDef
+**
+** Description This function performs NDEF detection procedure
+**
+** RW_I93_NDEF_DETECT_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_FAILED if busy or other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93DetectNDef (void)
+{
+ tNFC_STATUS status;
+ tRW_I93_RW_SUBSTATE sub_state;
+
+ RW_TRACE_API0 ("RW_I93DetectNDef ()");
+
+ if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("RW_I93DetectNDef ():Unable to start command at state (0x%X)",
+ rw_cb.tcb.i93.state);
+ return NFC_STATUS_FAILED;
+ }
+
+ if (rw_cb.tcb.i93.uid[0] != I93_UID_FIRST_BYTE)
+ {
+ status = rw_i93_send_cmd_inventory (NULL, 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 length, UINT8 *p_data)
+{
+ UINT16 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 state)
+{
+ switch (state)
+ {
+ case RW_I93_STATE_NOT_ACTIVATED:
+ return ("NOT_ACTIVATED");
+ case RW_I93_STATE_IDLE:
+ return ("IDLE");
+ case RW_I93_STATE_BUSY:
+ return ("BUSY");
+
+ case RW_I93_STATE_DETECT_NDEF:
+ return ("NDEF_DETECTION");
+ case RW_I93_STATE_READ_NDEF:
+ return ("READ_NDEF");
+ case RW_I93_STATE_UPDATE_NDEF:
+ return ("UPDATE_NDEF");
+ case RW_I93_STATE_FORMAT:
+ return ("FORMAT");
+ case RW_I93_STATE_SET_READ_ONLY:
+ return ("SET_READ_ONLY");
+
+ case RW_I93_STATE_PRESENCE_CHECK:
+ return ("PRESENCE_CHECK");
+ default:
+ return ("???? UNKNOWN STATE");
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_i93_get_sub_state_name
+**
+** Description This function returns the sub_state name.
+**
+** NOTE conditionally compiled to save memory.
+**
+** Returns pointer to the name
+**
+*******************************************************************************/
+static char *rw_i93_get_sub_state_name (UINT8 sub_state)
+{
+ switch (sub_state)
+ {
+ case RW_I93_SUBSTATE_WAIT_UID:
+ return ("WAIT_UID");
+ case RW_I93_SUBSTATE_WAIT_SYS_INFO:
+ return ("WAIT_SYS_INFO");
+ case RW_I93_SUBSTATE_WAIT_CC:
+ return ("WAIT_CC");
+ case RW_I93_SUBSTATE_SEARCH_NDEF_TLV:
+ return ("SEARCH_NDEF_TLV");
+ case RW_I93_SUBSTATE_CHECK_LOCK_STATUS:
+ return ("CHECK_LOCK_STATUS");
+ case RW_I93_SUBSTATE_RESET_LEN:
+ return ("RESET_LEN");
+ case RW_I93_SUBSTATE_WRITE_NDEF:
+ return ("WRITE_NDEF");
+ case RW_I93_SUBSTATE_UPDATE_LEN:
+ return ("UPDATE_LEN");
+ case RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI:
+ return ("WAIT_RESET_DSFID_AFI");
+ case RW_I93_SUBSTATE_CHECK_READ_ONLY:
+ return ("CHECK_READ_ONLY");
+ case RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV:
+ return ("WRITE_CC_NDEF_TLV");
+ case RW_I93_SUBSTATE_WAIT_UPDATE_CC:
+ return ("WAIT_UPDATE_CC");
+ case RW_I93_SUBSTATE_LOCK_NDEF_TLV:
+ return ("LOCK_NDEF_TLV");
+ case RW_I93_SUBSTATE_WAIT_LOCK_CC:
+ return ("WAIT_LOCK_CC");
+ default:
+ return ("???? UNKNOWN SUBSTATE");
+ }
+}
+
+/*******************************************************************************
+**
+** 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 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
+
+#endif /* (NFC_INCLUDED == TRUE) */
diff --git a/src/nfc/tags/rw_main.c b/src/nfc/tags/rw_main.c
new file mode 100644
index 0000000..7af85a2
--- /dev/null
+++ b/src/nfc/tags/rw_main.c
@@ -0,0 +1,323 @@
+/******************************************************************************
+ *
+ * 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"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_api.h"
+#include "nci_hmsgs.h"
+#include "rw_api.h"
+#include "rw_int.h"
+
+tRW_CB rw_cb;
+/*******************************************************************************
+*******************************************************************************/
+void rw_init (void)
+{
+ memset (&rw_cb, 0, sizeof (tRW_CB));
+ rw_cb.trace_level = NFC_INITIAL_TRACE_LEVEL;
+
+}
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+/*******************************************************************************
+* Internal functions for statistics
+*******************************************************************************/
+/*******************************************************************************
+**
+** Function rw_main_reset_stats
+**
+** Description Reset counters for statistics
+**
+** Returns void
+**
+*******************************************************************************/
+void rw_main_reset_stats (void)
+{
+ memset (&rw_cb.stats, 0, sizeof (tRW_STATS));
+
+ /* Get current tick count */
+ rw_cb.stats.start_tick = GKI_get_tick_count ();
+}
+
+/*******************************************************************************
+**
+** Function rw_main_update_tx_stats
+**
+** Description Update stats for tx
+**
+** Returns void
+**
+*******************************************************************************/
+void rw_main_update_tx_stats (UINT32 num_bytes, BOOLEAN is_retry)
+{
+ rw_cb.stats.bytes_sent+=num_bytes;
+ rw_cb.stats.num_ops++;
+
+ if (is_retry)
+ rw_cb.stats.num_retries++;
+}
+
+/*******************************************************************************
+**
+** Function rw_main_update_fail_stats
+**
+** Description Increment failure count
+**
+** Returns void
+**
+*******************************************************************************/
+void rw_main_update_fail_stats (void)
+{
+ rw_cb.stats.num_fail++;
+}
+
+/*******************************************************************************
+**
+** Function rw_main_update_crc_error_stats
+**
+** Description Increment crc error count
+**
+** Returns void
+**
+*******************************************************************************/
+void rw_main_update_crc_error_stats (void)
+{
+ rw_cb.stats.num_crc++;
+}
+
+/*******************************************************************************
+**
+** Function rw_main_update_trans_error_stats
+**
+** Description Increment trans error count
+**
+** Returns void
+**
+*******************************************************************************/
+void rw_main_update_trans_error_stats (void)
+{
+ rw_cb.stats.num_trans_err++;
+}
+
+/*******************************************************************************
+**
+** Function rw_main_update_rx_stats
+**
+** Description Update stats for rx
+**
+** Returns void
+**
+*******************************************************************************/
+void rw_main_update_rx_stats (UINT32 num_bytes)
+{
+ rw_cb.stats.bytes_received+=num_bytes;
+}
+
+/*******************************************************************************
+**
+** Function rw_main_log_stats
+**
+** Description Dump stats
+**
+** Returns void
+**
+*******************************************************************************/
+void rw_main_log_stats (void)
+{
+ UINT32 ticks, elapsed_ms;
+
+ ticks = GKI_get_tick_count () - rw_cb.stats.start_tick;
+ elapsed_ms = GKI_TICKS_TO_MS (ticks);
+
+ RW_TRACE_DEBUG5 ("NFC tx stats: cmds:%i, retries:%i, aborted: %i, tx_errs: %i, bytes sent:%i", rw_cb.stats.num_ops, rw_cb.stats.num_retries, rw_cb.stats.num_fail, rw_cb.stats.num_trans_err, rw_cb.stats.bytes_sent);
+ RW_TRACE_DEBUG2 (" rx stats: rx-crc errors %i, bytes received: %i", rw_cb.stats.num_crc, rw_cb.stats.bytes_received);
+ RW_TRACE_DEBUG1 (" time activated %i ms", elapsed_ms);
+}
+#endif /* RW_STATS_INCLUDED */
+
+
+/*******************************************************************************
+**
+** Function RW_SendRawFrame
+**
+** Description This function sends a raw frame to the peer device.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_SendRawFrame (UINT8 *p_raw_data, UINT16 data_len)
+{
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ BT_HDR *p_data;
+ UINT8 *p;
+
+ if (rw_cb.p_cback)
+ {
+ /* a valid opcode for RW - remove */
+ p_data = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+ if (p_data)
+ {
+ p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p = (UINT8 *) (p_data + 1) + p_data->offset;
+ memcpy (p, p_raw_data, data_len);
+ p_data->len = data_len;
+
+ RW_TRACE_EVENT1 ("RW SENT raw frame (0x%x)", data_len);
+ status = NFC_SendData (NFC_RF_CONN_ID, p_data);
+ }
+
+ }
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function RW_SetActivatedTagType
+**
+** Description This function selects the tag type for Reader/Writer mode.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_SetActivatedTagType (tNFC_ACTIVATE_DEVT *p_activate_params, tRW_CBACK *p_cback)
+{
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+
+ /* check for null cback here / remove checks from rw_t?t */
+ RW_TRACE_DEBUG3 ("RW_SetActivatedTagType protocol:%d, technology:%d, SAK:%d", p_activate_params->protocol, p_activate_params->rf_tech_param.mode, p_activate_params->rf_tech_param.param.pa.sel_rsp);
+
+ if (p_cback == NULL)
+ {
+ RW_TRACE_ERROR0 ("RW_SetActivatedTagType called with NULL callback");
+ return (NFC_STATUS_FAILED);
+ }
+
+ /* Reset tag-specific area of control block */
+ memset (&rw_cb.tcb, 0, sizeof (tRW_TCB));
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+ /* Reset RW stats */
+ rw_main_reset_stats ();
+#endif /* RW_STATS_INCLUDED */
+
+ rw_cb.p_cback = p_cback;
+ switch (p_activate_params->protocol)
+ {
+ /* not a tag NFC_PROTOCOL_NFCIP1: NFCDEP/LLCP - NFC-A or NFC-F */
+ case NFC_PROTOCOL_T1T: /* Type1Tag - NFC-A */
+ if (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A)
+ {
+ status = rw_t1t_select (p_activate_params->rf_tech_param.param.pa.hr,
+ p_activate_params->rf_tech_param.param.pa.nfcid1);
+ }
+ break;
+
+ case NFC_PROTOCOL_T2T: /* Type2Tag - NFC-A */
+ if (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A)
+ {
+ if (p_activate_params->rf_tech_param.param.pa.sel_rsp == NFC_SEL_RES_NFC_FORUM_T2T)
+ status = rw_t2t_select ();
+ }
+ break;
+
+ case NFC_PROTOCOL_T3T: /* Type3Tag - NFC-F */
+ if (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_F)
+ {
+ status = rw_t3t_select (p_activate_params->rf_tech_param.param.pf.nfcid2,
+ p_activate_params->rf_tech_param.param.pf.mrti_check,
+ p_activate_params->rf_tech_param.param.pf.mrti_update);
+ }
+ break;
+
+ case NFC_PROTOCOL_ISO_DEP: /* ISODEP/4A,4B- NFC-A or NFC-B */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ case NFC_PROTOCOL_T3BT:
+#endif
+ if ( (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_B)
+ ||(p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A) )
+ {
+ status = rw_t4t_select ();
+ }
+ break;
+
+ case NFC_PROTOCOL_15693: /* ISO 15693 */
+ if (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_ISO15693)
+ {
+ status = rw_i93_select (p_activate_params->rf_tech_param.param.pi93.uid);
+ }
+ break;
+ /* TODO set up callback for proprietary protocol */
+
+ default:
+ RW_TRACE_ERROR0 ("RW_SetActivatedTagType Invalid protocol");
+ }
+
+ if (status != NFC_STATUS_OK)
+ rw_cb.p_cback = NULL;
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function RW_SetTraceLevel
+**
+** Description This function sets the trace level for Reader/Writer mode.
+** If called with a value of 0xFF,
+** it simply returns the current trace level.
+**
+** Returns The new or current trace level
+**
+*******************************************************************************/
+UINT8 RW_SetTraceLevel (UINT8 new_level)
+{
+ if (new_level != 0xFF)
+ rw_cb.trace_level = new_level;
+
+ return (rw_cb.trace_level);
+}
+
+#endif /* NFC_INCLUDED == TRUE */
diff --git a/src/nfc/tags/rw_t1t.c b/src/nfc/tags/rw_t1t.c
new file mode 100644
index 0000000..9d3076f
--- /dev/null
+++ b/src/nfc/tags/rw_t1t.c
@@ -0,0 +1,1203 @@
+/******************************************************************************
+ *
+ * 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"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_api.h"
+#include "nci_hmsgs.h"
+#include "rw_api.h"
+#include "rw_int.h"
+#include "nfc_int.h"
+#include "gki.h"
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+extern unsigned char appl_dta_mode_flag;
+#endif
+/* Local Functions */
+static tRW_EVENT rw_t1t_handle_rid_rsp (BT_HDR *p_pkt);
+static void rw_t1t_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data);
+static void rw_t1t_process_frame_error (void);
+static void rw_t1t_process_error (void);
+static void rw_t1t_handle_presence_check_rsp (tNFC_STATUS status);
+#if (BT_TRACE_VERBOSE == TRUE)
+static char *rw_t1t_get_state_name (UINT8 state);
+static char *rw_t1t_get_sub_state_name (UINT8 sub_state);
+static char *rw_t1t_get_event_name (UINT8 event);
+#endif
+
+/*******************************************************************************
+**
+** Function rw_t1t_data_cback
+**
+** Description This callback function handles data from NFCC.
+**
+** Returns none
+**
+*******************************************************************************/
+static void rw_t1t_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
+{
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ tRW_EVENT rw_event = RW_RAW_FRAME_EVT;
+ BOOLEAN b_notify = TRUE;
+ tRW_DATA evt_data;
+ BT_HDR *p_pkt;
+ UINT8 *p;
+ tT1T_CMD_RSP_INFO *p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *) rw_cb.tcb.t1t.p_cmd_rsp_info;
+#if (BT_TRACE_VERBOSE == TRUE)
+ UINT8 begin_state = p_t1t->state;
+#endif
+
+ p_pkt = (BT_HDR *) (p_data->data.p_data);
+ if (p_pkt == NULL)
+ return;
+ /* Assume the data is just the response byte sequence */
+ p = (UINT8 *) (p_pkt + 1) + p_pkt->offset;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ RW_TRACE_DEBUG2 ("rw_t1t_data_cback (): state:%s (%d)", rw_t1t_get_state_name (p_t1t->state), p_t1t->state);
+#else
+ RW_TRACE_DEBUG1 ("rw_t1t_data_cback (): state=%d", p_t1t->state);
+#endif
+
+ evt_data.status = NFC_STATUS_OK;
+
+ if( (p_t1t->state == RW_T1T_STATE_IDLE)
+ ||(!p_cmd_rsp_info) )
+ {
+ /* If previous command was retransmitted and if response is pending to previous command retransmission,
+ * check if lenght and ADD/ADD8/ADDS field matches the expected value of previous
+ * retransmited command response. However, ignore ADD field if the command was RALL/RID
+ */
+ if ( (p_t1t->prev_cmd_rsp_info.pend_retx_rsp)
+ &&(p_t1t->prev_cmd_rsp_info.rsp_len == p_pkt->len)
+ &&((p_t1t->prev_cmd_rsp_info.op_code == T1T_CMD_RID) || (p_t1t->prev_cmd_rsp_info.op_code == T1T_CMD_RALL) || (p_t1t->prev_cmd_rsp_info.addr == *p)) )
+ {
+ /* Response to previous command retransmission */
+ RW_TRACE_ERROR2 ("T1T Response to previous command in Idle state. command=0x%02x, Remaining max retx rsp:0x%02x ", p_t1t->prev_cmd_rsp_info.op_code, p_t1t->prev_cmd_rsp_info.pend_retx_rsp - 1);
+ p_t1t->prev_cmd_rsp_info.pend_retx_rsp--;
+ GKI_freebuf (p_pkt);
+ }
+ else
+ {
+ /* Raw frame event */
+ evt_data.data.p_data = p_pkt;
+ (*rw_cb.p_cback) (RW_T1T_RAW_FRAME_EVT, (tRW_DATA *) &evt_data);
+ }
+ return;
+ }
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+ /* Update rx stats */
+ rw_main_update_rx_stats (p_pkt->len);
+#endif /* RW_STATS_INCLUDED */
+
+
+ if ( (p_pkt->len != p_cmd_rsp_info->rsp_len)
+ ||((p_cmd_rsp_info->opcode != T1T_CMD_RALL) && (p_cmd_rsp_info->opcode != T1T_CMD_RID) && (*p != p_t1t->addr)) )
+
+ {
+ /* If previous command was retransmitted and if response is pending to previous command retransmission,
+ * then check if lenght and ADD/ADD8/ADDS field matches the expected value of previous
+ * retransmited command response. However, ignore ADD field if the command was RALL/RID
+ */
+ if ( (p_t1t->prev_cmd_rsp_info.pend_retx_rsp)
+ &&(p_t1t->prev_cmd_rsp_info.rsp_len == p_pkt->len)
+ &&((p_t1t->prev_cmd_rsp_info.op_code == T1T_CMD_RID) || (p_t1t->prev_cmd_rsp_info.op_code == T1T_CMD_RALL) || (p_t1t->prev_cmd_rsp_info.addr == *p)) )
+ {
+ RW_TRACE_ERROR2 ("T1T Response to previous command. command=0x%02x, Remaining max retx rsp:0x%02x", p_t1t->prev_cmd_rsp_info.op_code, p_t1t->prev_cmd_rsp_info.pend_retx_rsp - 1);
+ p_t1t->prev_cmd_rsp_info.pend_retx_rsp--;
+ }
+ else
+ {
+ /* Stop timer as some response to current command is received */
+ nfc_stop_quick_timer (&p_t1t->timer);
+ /* Retrasmit the last sent command if retry-count < max retry */
+#if (BT_TRACE_VERBOSE == TRUE)
+ RW_TRACE_ERROR2 ("T1T Frame error. state=%s command (opcode) = 0x%02x", rw_t1t_get_state_name (p_t1t->state), p_cmd_rsp_info->opcode);
+#else
+ RW_TRACE_ERROR2 ("T1T Frame error. state=0x%02x command = 0x%02x ", p_t1t->state, p_cmd_rsp_info->opcode);
+#endif
+ rw_t1t_process_frame_error ();
+ }
+ GKI_freebuf (p_pkt);
+ return;
+ }
+
+ /* Stop timer as response to current command is received */
+ nfc_stop_quick_timer (&p_t1t->timer);
+
+ RW_TRACE_EVENT2 ("RW RECV [%s]:0x%x RSP", t1t_info_to_str (p_cmd_rsp_info), p_cmd_rsp_info->opcode);
+
+ /* If we did not receive response to all retransmitted previous command,
+ * dont expect that as response have come for the current command itself.
+ */
+ if (p_t1t->prev_cmd_rsp_info.pend_retx_rsp)
+ memset (&(p_t1t->prev_cmd_rsp_info), 0, sizeof (tRW_T1T_PREV_CMD_RSP_INFO));
+
+ if (rw_cb.cur_retry)
+ {
+ /* If the current command was retransmitted to get this response, we might get
+ response later to all or some of the retrasnmission of the current command
+ */
+ p_t1t->prev_cmd_rsp_info.addr = ((p_cmd_rsp_info->opcode != T1T_CMD_RALL) && (p_cmd_rsp_info->opcode != T1T_CMD_RID))? p_t1t->addr:0;
+ p_t1t->prev_cmd_rsp_info.rsp_len = p_cmd_rsp_info->rsp_len;
+ p_t1t->prev_cmd_rsp_info.op_code = p_cmd_rsp_info->opcode;
+ p_t1t->prev_cmd_rsp_info.pend_retx_rsp = (UINT8) rw_cb.cur_retry;
+ }
+
+ rw_cb.cur_retry = 0;
+
+ if (p_cmd_rsp_info->opcode == T1T_CMD_RID)
+ {
+ rw_event = rw_t1t_handle_rid_rsp (p_pkt);
+ }
+ else
+ {
+ rw_event = rw_t1t_handle_rsp (p_cmd_rsp_info, &b_notify, p, &evt_data.status);
+ }
+
+ if (b_notify)
+ {
+ if( (p_t1t->state != RW_T1T_STATE_READ)
+ &&(p_t1t->state != RW_T1T_STATE_WRITE) )
+ {
+ GKI_freebuf (p_pkt);
+ evt_data.data.p_data = NULL;
+ }
+ else
+ {
+ evt_data.data.p_data = p_pkt;
+ }
+ rw_t1t_handle_op_complete ();
+ (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &evt_data);
+ }
+ else
+ GKI_freebuf (p_pkt);
+
+#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 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
+{
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ tRW_READ_DATA evt_data;
+
+ RW_TRACE_DEBUG2 ("rw_t1t_conn_cback: conn_id=%i, evt=0x%x", conn_id, event);
+ /* Only handle static conn_id */
+ if (conn_id != NFC_RF_CONN_ID)
+ {
+ RW_TRACE_WARNING1 ("rw_t1t_conn_cback - Not static connection id: =%i", conn_id);
+ return;
+ }
+
+ switch (event)
+ {
+ case NFC_CONN_CREATE_CEVT:
+ case NFC_CONN_CLOSE_CEVT:
+ break;
+
+ case NFC_DEACTIVATE_CEVT:
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+ /* Display stats */
+ rw_main_log_stats ();
+#endif /* RW_STATS_INCLUDED */
+
+ /* Stop t1t timer (if started) */
+ nfc_stop_quick_timer (&p_t1t->timer);
+
+ /* Free cmd buf for retransmissions */
+ if (p_t1t->p_cur_cmd_buf)
+ {
+ GKI_freebuf (p_t1t->p_cur_cmd_buf);
+ p_t1t->p_cur_cmd_buf = NULL;
+ }
+
+ p_t1t->state = RW_T1T_STATE_NOT_ACTIVATED;
+ NFC_SetStaticRfCback (NULL);
+ break;
+
+ case NFC_DATA_CEVT:
+ if ( (p_data != NULL)
+ &&(p_data->data.status == NFC_STATUS_OK) )
+ {
+ rw_t1t_data_cback (conn_id, event, p_data);
+ break;
+ }
+ /* Data event with error status...fall through to NFC_ERROR_CEVT case */
+
+ case NFC_ERROR_CEVT:
+ if ( (p_t1t->state == RW_T1T_STATE_NOT_ACTIVATED)
+ ||(p_t1t->state == RW_T1T_STATE_IDLE) )
+ {
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+ rw_main_update_trans_error_stats ();
+#endif /* RW_STATS_INCLUDED */
+
+ if (event == NFC_ERROR_CEVT)
+ evt_data.status = (tNFC_STATUS) (*(UINT8*) p_data);
+ else if (p_data)
+ evt_data.status = p_data->status;
+ else
+ evt_data.status = NFC_STATUS_FAILED;
+
+ evt_data.p_data = NULL;
+ (*rw_cb.p_cback) (RW_T1T_INTF_ERROR_EVT, (tRW_DATA *) &evt_data);
+ break;
+ }
+ nfc_stop_quick_timer (&p_t1t->timer);
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+ rw_main_update_trans_error_stats ();
+#endif /* RW_STATS_INCLUDED */
+
+ if (p_t1t->state == RW_T1T_STATE_CHECK_PRESENCE)
+ {
+ rw_t1t_handle_presence_check_rsp (NFC_STATUS_FAILED);
+ }
+ else
+ {
+ rw_t1t_process_error ();
+ }
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ if((p_data != NULL) && (p_data->data.p_data != NULL))
+ {
+ /* Free the response buffer in case of invalid response*/
+ GKI_freebuf((BT_HDR *) (p_data->data.p_data));
+ p_data->data.p_data = NULL;
+ }
+#endif
+ break;
+
+ default:
+ break;
+
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_t1t_send_static_cmd
+**
+** Description This function composes a Type 1 Tag command for static
+** memory and send through NCI to NFCC.
+**
+** Returns NFC_STATUS_OK if the command is successfuly sent to NCI
+** otherwise, error status
+**
+*******************************************************************************/
+tNFC_STATUS rw_t1t_send_static_cmd (UINT8 opcode, UINT8 add, UINT8 dat)
+{
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ const tT1T_CMD_RSP_INFO *p_cmd_rsp_info = t1t_cmd_to_rsp_info (opcode);
+ BT_HDR *p_data;
+ UINT8 *p;
+
+ if (p_cmd_rsp_info)
+ {
+ /* a valid opcode for RW */
+ p_data = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+ if (p_data)
+ {
+ p_t1t->p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *) p_cmd_rsp_info;
+ p_t1t->addr = add;
+ p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p = (UINT8 *) (p_data + 1) + p_data->offset;
+ UINT8_TO_BE_STREAM (p, opcode);
+ UINT8_TO_BE_STREAM (p, add);
+ UINT8_TO_BE_STREAM (p, dat);
+
+ ARRAY_TO_STREAM (p, p_t1t->mem, T1T_CMD_UID_LEN);
+ p_data->len = p_cmd_rsp_info->cmd_len;
+
+ /* Indicate first attempt to send command, back up cmd buffer in case needed for retransmission */
+ rw_cb.cur_retry = 0;
+ memcpy (p_t1t->p_cur_cmd_buf, p_data, sizeof (BT_HDR) + p_data->offset + p_data->len);
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+ /* Update stats */
+ rw_main_update_tx_stats (p_data->len, FALSE);
+#endif /* RW_STATS_INCLUDED */
+
+ RW_TRACE_EVENT2 ("RW SENT [%s]:0x%x CMD", t1t_info_to_str (p_cmd_rsp_info), p_cmd_rsp_info->opcode);
+ if ((status = NFC_SendData (NFC_RF_CONN_ID, p_data)) == NFC_STATUS_OK)
+ {
+ nfc_start_quick_timer (&p_t1t->timer, NFC_TTYPE_RW_T1T_RESPONSE,
+ (RW_T1T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+ }
+ }
+ else
+ {
+ status = NFC_STATUS_NO_BUFFERS;
+ }
+ }
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function rw_t1t_send_dyn_cmd
+**
+** Description This function composes a Type 1 Tag command for dynamic memory
+** and send through NCI to NFCC.
+**
+** Returns NFC_STATUS_OK if the command is successfuly sent to NCI
+** otherwise, error status
+**
+*******************************************************************************/
+tNFC_STATUS rw_t1t_send_dyn_cmd (UINT8 opcode, UINT8 add, UINT8 *p_dat)
+{
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ const tT1T_CMD_RSP_INFO *p_cmd_rsp_info = t1t_cmd_to_rsp_info (opcode);
+ BT_HDR *p_data;
+ UINT8 *p;
+
+ if (p_cmd_rsp_info)
+ {
+ /* a valid opcode for RW */
+ p_data = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+ if (p_data)
+ {
+ p_t1t->p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *) p_cmd_rsp_info;
+ p_t1t->addr = add;
+ p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p = (UINT8 *) (p_data + 1) + p_data->offset;
+ UINT8_TO_BE_STREAM (p, opcode);
+ UINT8_TO_BE_STREAM (p, add);
+
+ if (p_dat)
+ {
+ ARRAY_TO_STREAM (p, p_dat, 8);
+ }
+ else
+ {
+ memset (p, 0, 8);
+ p += 8;
+ }
+ ARRAY_TO_STREAM (p, p_t1t->mem, T1T_CMD_UID_LEN);
+ p_data->len = p_cmd_rsp_info->cmd_len;
+
+ /* Indicate first attempt to send command, back up cmd buffer in case needed for retransmission */
+ rw_cb.cur_retry = 0;
+ memcpy (p_t1t->p_cur_cmd_buf, p_data, sizeof (BT_HDR) + p_data->offset + p_data->len);
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+ /* Update stats */
+ rw_main_update_tx_stats (p_data->len, FALSE);
+#endif /* RW_STATS_INCLUDED */
+
+ RW_TRACE_EVENT2 ("RW SENT [%s]:0x%x CMD", t1t_info_to_str (p_cmd_rsp_info), p_cmd_rsp_info->opcode);
+
+ if ((status = NFC_SendData (NFC_RF_CONN_ID, p_data)) == NFC_STATUS_OK)
+ {
+ nfc_start_quick_timer (&p_t1t->timer, NFC_TTYPE_RW_T1T_RESPONSE,
+ (RW_T1T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+ }
+ }
+ else
+ {
+ status = NFC_STATUS_NO_BUFFERS;
+ }
+ }
+ return status;
+}
+
+/*****************************************************************************
+**
+** Function rw_t1t_handle_rid_rsp
+**
+** Description Handles response to RID: Collects HR, UID, notify up the
+** stack
+**
+** Returns event to notify application
+**
+*****************************************************************************/
+static tRW_EVENT rw_t1t_handle_rid_rsp (BT_HDR *p_pkt)
+{
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ tRW_DATA evt_data;
+ UINT8 *p_rid_rsp;
+
+ evt_data.status = NFC_STATUS_OK;
+ evt_data.data.p_data = p_pkt;
+
+ /* Assume the data is just the response byte sequence */
+ p_rid_rsp = (UINT8 *) (p_pkt + 1) + p_pkt->offset;
+
+ /* Response indicates tag is present */
+ if (p_t1t->state == RW_T1T_STATE_CHECK_PRESENCE)
+ {
+ /* If checking for the presence of the tag then just notify */
+ return RW_T1T_PRESENCE_CHECK_EVT;
+ }
+
+ /* Extract HR and UID from response */
+ STREAM_TO_ARRAY (p_t1t->hr, p_rid_rsp, T1T_HR_LEN);
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ RW_TRACE_DEBUG2 ("hr0:0x%x, hr1:0x%x", p_t1t->hr[0], p_t1t->hr[1]);
+ RW_TRACE_DEBUG4 ("rw_t1t_handle_rid_rsp (): UID0-3=%02x%02x%02x%02x", p_rid_rsp[0], p_rid_rsp[1], p_rid_rsp[2], p_rid_rsp[3]);
+#else
+ RW_TRACE_DEBUG0 ("rw_t1t_handle_rid_rsp ()");
+#endif
+
+ /* Fetch UID0-3 from RID response message */
+ STREAM_TO_ARRAY (p_t1t->mem, p_rid_rsp, T1T_CMD_UID_LEN);
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ /* Free the RID response buffer */
+ GKI_freebuf (p_pkt);
+#endif
+
+ /* Notify RID response Event */
+ return RW_T1T_RID_EVT;
+}
+
+/*******************************************************************************
+**
+** Function rw_t1t_select
+**
+** Description This function will set the callback function to
+** receive data from lower layers and also send rid command
+**
+** Returns none
+**
+*******************************************************************************/
+tNFC_STATUS rw_t1t_select (UINT8 hr[T1T_HR_LEN], UINT8 uid[T1T_CMD_UID_LEN])
+{
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+
+ p_t1t->state = RW_T1T_STATE_NOT_ACTIVATED;
+
+ /* Alloc cmd buf for retransmissions */
+ if (p_t1t->p_cur_cmd_buf == NULL)
+ {
+ if ((p_t1t->p_cur_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) == NULL)
+ {
+ RW_TRACE_ERROR0 ("rw_t1t_select: unable to allocate buffer for retransmission");
+ return status;
+ }
+ }
+
+ memcpy (p_t1t->hr, hr, T1T_HR_LEN);
+ memcpy (p_t1t->mem, uid, T1T_CMD_UID_LEN);
+
+ NFC_SetStaticRfCback (rw_t1t_conn_cback);
+
+ p_t1t->state = RW_T1T_STATE_IDLE;
+
+ return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function rw_t1t_process_timeout
+**
+** Description process timeout event
+**
+** Returns none
+**
+*******************************************************************************/
+void rw_t1t_process_timeout (TIMER_LIST_ENT *p_tle)
+{
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ RW_TRACE_ERROR2 ("T1T timeout. state=%s command (opcode)=0x%02x ", rw_t1t_get_state_name (p_t1t->state), (rw_cb.tcb.t1t.p_cmd_rsp_info)->opcode);
+#else
+ RW_TRACE_ERROR2 ("T1T timeout. state=0x%02x command=0x%02x ", p_t1t->state, (rw_cb.tcb.t1t.p_cmd_rsp_info)->opcode);
+#endif
+
+ if (p_t1t->state == RW_T1T_STATE_CHECK_PRESENCE)
+ {
+ /* Tag has moved from range */
+ rw_t1t_handle_presence_check_rsp (NFC_STATUS_FAILED);
+ }
+ else if (p_t1t->state != RW_T1T_STATE_IDLE)
+ {
+ rw_t1t_process_error ();
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function rw_t1t_process_frame_error
+**
+** Description Process frame crc error
+**
+** Returns none
+**
+*******************************************************************************/
+static void rw_t1t_process_frame_error (void)
+{
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+ /* Update stats */
+ rw_main_update_crc_error_stats ();
+#endif /* RW_STATS_INCLUDED */
+
+ /* Process the error */
+ rw_t1t_process_error ();
+}
+
+/*******************************************************************************
+**
+** Function rw_t1t_process_error
+**
+** Description process timeout event
+**
+** Returns none
+**
+*******************************************************************************/
+static void rw_t1t_process_error (void)
+{
+ tRW_READ_DATA evt_data;
+ tRW_EVENT rw_event;
+ BT_HDR *p_cmd_buf;
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ tT1T_CMD_RSP_INFO *p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *) rw_cb.tcb.t1t.p_cmd_rsp_info;
+ tRW_DETECT_NDEF_DATA ndef_data;
+
+ RW_TRACE_DEBUG1 ("rw_t1t_process_error () State: %u", p_t1t->state);
+
+ /* Retry sending command if retry-count < max */
+ if (rw_cb.cur_retry < RW_MAX_RETRIES)
+ {
+ /* retry sending the command */
+ rw_cb.cur_retry++;
+
+ RW_TRACE_DEBUG2 ("T1T retransmission attempt %i of %i", rw_cb.cur_retry, RW_MAX_RETRIES);
+
+ /* allocate a new buffer for message */
+ if ((p_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL)
+ {
+ memcpy (p_cmd_buf, p_t1t->p_cur_cmd_buf, sizeof (BT_HDR) + p_t1t->p_cur_cmd_buf->offset + p_t1t->p_cur_cmd_buf->len);
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+ /* Update stats */
+ rw_main_update_tx_stats (p_cmd_buf->len, TRUE);
+#endif /* RW_STATS_INCLUDED */
+
+ if (NFC_SendData (NFC_RF_CONN_ID, p_cmd_buf) == NFC_STATUS_OK)
+ {
+ /* Start timer for waiting for response */
+ nfc_start_quick_timer (&p_t1t->timer, NFC_TTYPE_RW_T1T_RESPONSE,
+ (RW_T1T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC)/1000);
+
+ return;
+ }
+ }
+ }
+ else
+ {
+ /* we might get response later to all or some of the retrasnmission
+ * of the current command, update previous command response information */
+ RW_TRACE_DEBUG1 ("T1T maximum retransmission attempts reached (%i)", RW_MAX_RETRIES);
+ p_t1t->prev_cmd_rsp_info.addr = ((p_cmd_rsp_info->opcode != T1T_CMD_RALL) && (p_cmd_rsp_info->opcode != T1T_CMD_RID))? p_t1t->addr:0;
+ p_t1t->prev_cmd_rsp_info.rsp_len = p_cmd_rsp_info->rsp_len;
+ p_t1t->prev_cmd_rsp_info.op_code = p_cmd_rsp_info->opcode;
+ p_t1t->prev_cmd_rsp_info.pend_retx_rsp = RW_MAX_RETRIES;
+ }
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+ /* update failure count */
+ rw_main_update_fail_stats ();
+#endif /* RW_STATS_INCLUDED */
+
+ rw_event = rw_t1t_info_to_event (p_cmd_rsp_info);
+ if (p_t1t->state != RW_T1T_STATE_NOT_ACTIVATED)
+ rw_t1t_handle_op_complete ();
+
+ evt_data.status = NFC_STATUS_TIMEOUT;
+ if (rw_event == RW_T2T_NDEF_DETECT_EVT)
+ {
+ ndef_data.status = evt_data.status;
+ ndef_data.protocol = NFC_PROTOCOL_T1T;
+ ndef_data.flags = RW_NDEF_FL_UNKNOWN;
+ ndef_data.max_size = 0;
+ ndef_data.cur_size = 0;
+ (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &ndef_data);
+ }
+ else
+ {
+ evt_data.p_data = NULL;
+ (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &evt_data);
+ }
+}
+
+/*****************************************************************************
+**
+** Function rw_t1t_handle_presence_check_rsp
+**
+** Description Handle response to presence check
+**
+** Returns Nothing
+**
+*****************************************************************************/
+void rw_t1t_handle_presence_check_rsp (tNFC_STATUS status)
+{
+ tRW_READ_DATA evt_data;
+
+ /* Notify, Tag is present or not */
+ evt_data.status = status;
+ rw_t1t_handle_op_complete ();
+
+ (*(rw_cb.p_cback)) (RW_T1T_PRESENCE_CHECK_EVT, (tRW_DATA *) &evt_data);
+}
+
+/*****************************************************************************
+**
+** Function rw_t1t_handle_op_complete
+**
+** Description Reset to IDLE state
+**
+** Returns Nothing
+**
+*****************************************************************************/
+void rw_t1t_handle_op_complete (void)
+{
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+
+ p_t1t->state = RW_T1T_STATE_IDLE;
+#if (defined (RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE))
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 */
+ if((retval = rw_t1t_send_static_cmd (T1T_CMD_RID, 0, 0))== NFC_STATUS_OK)
+ {
+ p_rw_cb->tcb.t1t.state = RW_T1T_STATE_CHECK_PRESENCE;
+ }
+ }
+
+ return (retval);
+}
+
+/*****************************************************************************
+**
+** Function RW_T1tRid
+**
+** Description
+** This function sends a RID command for Reader/Writer mode.
+**
+** Returns
+** NFC_STATUS_OK, if raw data frame sent
+** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+** NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T1tRid (void)
+{
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+
+ RW_TRACE_API0 ("RW_T1tRid");
+
+ if (p_t1t->state != RW_T1T_STATE_IDLE)
+ {
+ RW_TRACE_WARNING1 ("RW_T1tRid - Busy - State: %u", p_t1t->state);
+ return (NFC_STATUS_BUSY);
+ }
+
+ /* send a RID command */
+ if((status = rw_t1t_send_static_cmd (T1T_CMD_RID, 0, 0))== NFC_STATUS_OK)
+ {
+ p_t1t->state = RW_T1T_STATE_READ;
+ }
+
+ return (status);
+}
+
+/*******************************************************************************
+**
+** Function RW_T1tReadAll
+**
+** Description This function sends a RALL command for Reader/Writer mode.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tReadAll (void)
+{
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+
+ RW_TRACE_API0 ("RW_T1tReadAll");
+
+ if (p_t1t->state != RW_T1T_STATE_IDLE)
+ {
+ RW_TRACE_WARNING1 ("RW_T1tReadAll - Busy - State: %u", p_t1t->state);
+ return (NFC_STATUS_BUSY);
+ }
+
+ /* send RALL command */
+ if ((status = rw_t1t_send_static_cmd (T1T_CMD_RALL, 0, 0)) == NFC_STATUS_OK)
+ {
+ p_t1t->state = RW_T1T_STATE_READ;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function RW_T1tRead
+**
+** Description This function sends a READ command for Reader/Writer mode.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tRead (UINT8 block, UINT8 byte)
+{
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ UINT8 addr;
+
+ if (p_t1t->state != RW_T1T_STATE_IDLE)
+ {
+ RW_TRACE_WARNING1 ("RW_T1tRead - Busy - State: %u", p_t1t->state);
+ return (NFC_STATUS_BUSY);
+ }
+
+ /* send READ command */
+ RW_T1T_BLD_ADD ((addr), (block), (byte));
+ if ((status = rw_t1t_send_static_cmd (T1T_CMD_READ, addr, 0)) == NFC_STATUS_OK)
+ {
+ p_t1t->state = RW_T1T_STATE_READ;
+ }
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function RW_T1tWriteErase
+**
+** Description This function sends a WRITE-E command for Reader/Writer mode.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tWriteErase (UINT8 block, UINT8 byte, UINT8 new_byte)
+{
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ UINT8 addr;
+
+ if (p_t1t->state != RW_T1T_STATE_IDLE)
+ {
+ RW_TRACE_WARNING1 ("RW_T1tWriteErase - Busy - State: %u", p_t1t->state);
+ return (NFC_STATUS_BUSY);
+ }
+ if ( (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_ONLY)
+ &&(block != T1T_CC_BLOCK)
+ &&(byte != T1T_CC_RWA_OFFSET) )
+ {
+ RW_TRACE_ERROR0 ("RW_T1tWriteErase - Tag is in Read only state");
+ return (NFC_STATUS_REFUSED);
+ }
+ if ( (block >= T1T_STATIC_BLOCKS)
+ ||(byte >= T1T_BLOCK_SIZE ) )
+ {
+ RW_TRACE_ERROR2 ("RW_T1tWriteErase - Invalid Block/byte: %u / %u", block, byte);
+ return (NFC_STATUS_REFUSED);
+ }
+ if( (block == T1T_UID_BLOCK)
+ ||(block == T1T_RES_BLOCK) )
+ {
+ RW_TRACE_WARNING1 ("RW_T1tWriteErase - Cannot write to Locked block: %u", block);
+ return (NFC_STATUS_REFUSED);
+ }
+ /* send WRITE-E command */
+ RW_T1T_BLD_ADD ((addr), (block), (byte));
+ if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, new_byte)) == NFC_STATUS_OK)
+ {
+ p_t1t->state = RW_T1T_STATE_WRITE;
+ if (block < T1T_BLOCKS_PER_SEGMENT)
+ {
+ p_t1t->b_update = FALSE;
+ p_t1t->b_rseg = FALSE;
+ }
+ }
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function RW_T1tWriteNoErase
+**
+** Description This function sends a WRITE-NE command for Reader/Writer mode.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tWriteNoErase (UINT8 block, UINT8 byte, UINT8 new_byte)
+{
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ UINT8 addr;
+
+ if (p_t1t->state != RW_T1T_STATE_IDLE)
+ {
+ RW_TRACE_WARNING1 ("RW_T1tWriteNoErase - Busy - State: %u", p_t1t->state);
+ return (NFC_STATUS_BUSY);
+ }
+ if ( (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_ONLY)
+ &&(block != T1T_CC_BLOCK)
+ &&(byte != T1T_CC_RWA_OFFSET) )
+ {
+ RW_TRACE_ERROR0 ("RW_T1tWriteErase - Tag is in Read only state");
+ return (NFC_STATUS_REFUSED);
+ }
+ if ( (block >= T1T_STATIC_BLOCKS)
+ ||(byte >= T1T_BLOCK_SIZE ) )
+ {
+ RW_TRACE_ERROR2 ("RW_T1tWriteErase - Invalid Block/byte: %u / %u", block, byte);
+ return (NFC_STATUS_REFUSED);
+ }
+ if( (block == T1T_UID_BLOCK)
+ ||(block == T1T_RES_BLOCK) )
+ {
+ RW_TRACE_WARNING1 ("RW_T1tWriteNoErase - Cannot write to Locked block: %u", block);
+ return (NFC_STATUS_REFUSED);
+ }
+ /* send WRITE-NE command */
+ RW_T1T_BLD_ADD ((addr), (block), (byte));
+ if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_NE, addr, new_byte)) == NFC_STATUS_OK)
+ {
+ p_t1t->state = RW_T1T_STATE_WRITE;
+ if (block < T1T_BLOCKS_PER_SEGMENT)
+ {
+ p_t1t->b_update = FALSE;
+ p_t1t->b_rseg = FALSE;
+ }
+ }
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function RW_T1tReadSeg
+**
+** Description This function sends a RSEG command for Reader/Writer mode.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tReadSeg (UINT8 segment)
+{
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ UINT8 adds;
+
+ if (p_t1t->state != RW_T1T_STATE_IDLE)
+ {
+ RW_TRACE_WARNING1 ("RW_T1tReadSeg - Busy - State: %u", p_t1t->state);
+ return (NFC_STATUS_BUSY);
+ }
+ if (segment >= T1T_MAX_SEGMENTS)
+ {
+ RW_TRACE_ERROR1 ("RW_T1tReadSeg - Invalid Segment: %u", segment);
+ return (NFC_STATUS_REFUSED);
+ }
+ if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0)
+ {
+ /* send RSEG command */
+ RW_T1T_BLD_ADDS ((adds), (segment));
+ if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_RSEG, adds, NULL)) == NFC_STATUS_OK)
+ {
+ p_t1t->state = RW_T1T_STATE_READ;
+ }
+ }
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function RW_T1tRead8
+**
+** Description This function sends a READ8 command for Reader/Writer mode.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tRead8 (UINT8 block)
+{
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ tRW_T1T_CB *p_t1t= &rw_cb.tcb.t1t;
+
+ if (p_t1t->state != RW_T1T_STATE_IDLE)
+ {
+ RW_TRACE_WARNING1 ("RW_T1tRead8 - Busy - State: %u", p_t1t->state);
+ return (NFC_STATUS_BUSY);
+ }
+
+ if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 || rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN)
+ {
+ /* send READ8 command */
+ if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_READ8, block, NULL)) == NFC_STATUS_OK)
+ {
+ p_t1t->state = RW_T1T_STATE_READ;
+ }
+ }
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function RW_T1tWriteErase8
+**
+** Description This function sends a WRITE-E8 command for Reader/Writer mode.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tWriteErase8 (UINT8 block, UINT8 *p_new_dat)
+{
+ tRW_T1T_CB *p_t1t= &rw_cb.tcb.t1t;
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+
+ if (p_t1t->state != RW_T1T_STATE_IDLE)
+ {
+ RW_TRACE_WARNING1 ("RW_T1tWriteErase8 - Busy - State: %u", p_t1t->state);
+ return (NFC_STATUS_BUSY);
+ }
+
+ if ( (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_ONLY)
+ &&(block != T1T_CC_BLOCK) )
+ {
+ RW_TRACE_ERROR0 ("RW_T1tWriteErase8 - Tag is in Read only state");
+ return (NFC_STATUS_REFUSED);
+ }
+
+ if( (block == T1T_UID_BLOCK)
+ ||(block == T1T_RES_BLOCK) )
+ {
+ RW_TRACE_WARNING1 ("RW_T1tWriteErase8 - Cannot write to Locked block: %u", block);
+ return (NFC_STATUS_REFUSED);
+ }
+
+ if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 || rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN)
+ {
+ /* send WRITE-E8 command */
+ if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_E8, block, p_new_dat)) == NFC_STATUS_OK)
+ {
+ p_t1t->state = RW_T1T_STATE_WRITE;
+ if (block < T1T_BLOCKS_PER_SEGMENT)
+ {
+ p_t1t->b_update = FALSE;
+ p_t1t->b_rseg = FALSE;
+ }
+ }
+ }
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function RW_T1tWriteNoErase8
+**
+** Description This function sends a WRITE-NE8 command for Reader/Writer mode.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tWriteNoErase8 (UINT8 block, UINT8 *p_new_dat)
+{
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ tRW_T1T_CB *p_t1t= &rw_cb.tcb.t1t;
+
+ if (p_t1t->state != RW_T1T_STATE_IDLE)
+ {
+ RW_TRACE_WARNING1 ("RW_T1tWriteNoErase8 - Busy - State: %u", p_t1t->state);
+ return (NFC_STATUS_BUSY);
+ }
+
+ if ( (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_ONLY)
+ &&(block != T1T_CC_BLOCK) )
+ {
+ RW_TRACE_ERROR0 ("RW_T1tWriteNoErase8 - Tag is in Read only state");
+ return (NFC_STATUS_REFUSED);
+ }
+
+ if( (block == T1T_UID_BLOCK)
+ ||(block == T1T_RES_BLOCK) )
+ {
+ RW_TRACE_WARNING1 ("RW_T1tWriteNoErase8 - Cannot write to Locked block: %u", block);
+ return (NFC_STATUS_REFUSED);
+ }
+
+ if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 || rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN)
+ {
+ /* send WRITE-NE command */
+ if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_NE8, block, p_new_dat)) == NFC_STATUS_OK)
+ {
+ p_t1t->state = RW_T1T_STATE_WRITE;
+ if (block < T1T_BLOCKS_PER_SEGMENT)
+ {
+ p_t1t->b_update = FALSE;
+ p_t1t->b_rseg = FALSE;
+ }
+ }
+ }
+ return status;
+}
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function rw_t1t_get_state_name
+**
+** Description This function returns the state name.
+**
+** NOTE conditionally compiled to save memory.
+**
+** Returns pointer to the name
+**
+*******************************************************************************/
+static char *rw_t1t_get_state_name (UINT8 state)
+{
+ switch (state)
+ {
+ case RW_T1T_STATE_IDLE:
+ return ("IDLE");
+ case RW_T1T_STATE_NOT_ACTIVATED:
+ return ("NOT_ACTIVATED");
+ case RW_T1T_STATE_READ:
+ return ("APP_READ");
+ case RW_T1T_STATE_WRITE:
+ return ("APP_WRITE");
+ case RW_T1T_STATE_TLV_DETECT:
+ return ("TLV_DETECTION");
+ case RW_T1T_STATE_READ_NDEF:
+ return ("READING_NDEF");
+ case RW_T1T_STATE_WRITE_NDEF:
+ return ("WRITING_NDEF");
+ case RW_T1T_STATE_SET_TAG_RO:
+ return ("SET_TAG_RO");
+ case RW_T1T_STATE_CHECK_PRESENCE:
+ return ("CHECK_PRESENCE");
+ case RW_T1T_STATE_FORMAT_TAG:
+ return ("FORMAT_TAG");
+ default:
+ return ("???? UNKNOWN STATE");
+ }
+}
+
+#endif /* (BT_TRACE_VERBOSE == TRUE) */
+
+#endif /* (NFC_INCLUDED == TRUE) */
diff --git a/src/nfc/tags/rw_t1t_ndef.c b/src/nfc/tags/rw_t1t_ndef.c
new file mode 100644
index 0000000..39783cc
--- /dev/null
+++ b/src/nfc/tags/rw_t1t_ndef.c
@@ -0,0 +1,2823 @@
+/******************************************************************************
+ *
+ * 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"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_api.h"
+#include "nci_hmsgs.h"
+#include "rw_api.h"
+#include "rw_int.h"
+#include "nfc_int.h"
+#include "gki.h"
+
+#if (defined (RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE))
+
+/* Local Functions */
+static tNFC_STATUS rw_t1t_handle_rall_rsp (BOOLEAN *p_notify,UINT8 *p_data);
+static tNFC_STATUS rw_t1t_handle_dyn_read_rsp (BOOLEAN *p_notify, UINT8 *p_data);
+static tNFC_STATUS rw_t1t_handle_write_rsp (BOOLEAN *p_notify, UINT8 *p_data);
+static tNFC_STATUS rw_t1t_handle_read_rsp (BOOLEAN *p_callback, UINT8 *p_data);
+static tNFC_STATUS rw_t1t_handle_tlv_detect_rsp (UINT8 *p_data);
+static tNFC_STATUS rw_t1t_handle_ndef_read_rsp (UINT8 *p_data);
+static tNFC_STATUS rw_t1t_handle_ndef_write_rsp (UINT8 *p_data);
+static tNFC_STATUS rw_t1t_handle_ndef_rall_rsp (void);
+static tNFC_STATUS rw_t1t_ndef_write_first_block (void);
+static tNFC_STATUS rw_t1t_next_ndef_write_block (void);
+static tNFC_STATUS rw_t1t_send_ndef_byte (UINT8 data, UINT8 block, UINT8 index, UINT8 msg_len);
+static tNFC_STATUS rw_t1t_send_ndef_block (UINT8 *p_data, UINT8 block);
+static UINT8 rw_t1t_prepare_ndef_bytes (UINT8 *p_data, UINT8 *p_length_field, UINT8 *p_index, BOOLEAN b_one_byte, UINT8 block, UINT8 lengthfield_len);
+static UINT8 rw_t1t_get_ndef_flags (void);
+static UINT16 rw_t1t_get_ndef_max_size (void);
+static BOOLEAN rw_t1t_is_lock_reserved_otp_byte (UINT16 index);
+static BOOLEAN rw_t1t_is_read_only_byte (UINT16 index);
+static UINT8 rw_t1t_get_lock_bits_for_segment (UINT8 segment,UINT8 *p_start_byte, UINT8 *p_start_bit,UINT8 *p_end_byte);
+static void rw_t1t_update_attributes (void);
+static void rw_t1t_update_lock_attributes (void);
+static void rw_t1t_extract_lock_bytes (UINT8 *p_data);
+static void rw_t1t_update_tag_state (void);
+
+const UINT8 rw_t1t_mask_bits[8] =
+{0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
+
+/*******************************************************************************
+**
+** Function rw_t1t_handle_rsp
+**
+** Description This function handles the response received for all commands
+** sent to tag
+**
+** Returns event to be sent to application
+**
+*******************************************************************************/
+tRW_EVENT rw_t1t_handle_rsp (const tT1T_CMD_RSP_INFO * p_info, BOOLEAN *p_notify, UINT8 *p_data, tNFC_STATUS *p_status)
+{
+ tRW_EVENT rw_event;
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ UINT8 adds;
+
+ if( (p_t1t->state == RW_T1T_STATE_READ)
+ ||(p_t1t->state == RW_T1T_STATE_WRITE) )
+ {
+ return t1t_info_to_evt (p_info);
+ }
+
+ rw_event = rw_t1t_info_to_event (p_info);
+
+ if (p_info->opcode == T1T_CMD_RALL)
+ {
+ *p_status = rw_t1t_handle_rall_rsp (p_notify,p_data);
+ }
+ else if (p_info->opcode == T1T_CMD_RSEG)
+ {
+ adds = *p_data;
+ if (adds == 0)
+ {
+ p_t1t->b_rseg = TRUE;
+ rw_t1t_update_tag_state ();
+ rw_t1t_update_attributes ();
+ rw_t1t_update_lock_attributes ();
+ memcpy (p_t1t->mem, (UINT8 *) (p_data + 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 *p_data)
+{
+ UINT16 end;
+ UINT16 start;
+ UINT8 num_locks;
+ UINT16 lock_offset = 0;
+ UINT16 offset;
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ tT1T_CMD_RSP_INFO *p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *) rw_cb.tcb.t1t.p_cmd_rsp_info;
+
+ num_locks = 0;
+ /* Based on the Command used to read Tag, calculate the offset of the tag read */
+ if (p_cmd_rsp_info->opcode == T1T_CMD_RSEG)
+ {
+ start = p_t1t->segment * T1T_SEGMENT_SIZE;
+ end = 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 num_locks = 0;
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ tNFC_STATUS status = NFC_STATUS_CONTINUE;
+ UINT16 offset;
+
+ while (num_locks < p_t1t->num_lockbytes)
+ {
+ if (p_t1t->lockbyte[num_locks].b_lock_read == FALSE)
+ {
+ offset = p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].offset + p_t1t->lockbyte[num_locks].byte_index;
+ if (offset < T1T_STATIC_SIZE)
+ {
+ p_t1t->lockbyte[num_locks].lock_byte = p_t1t->mem[offset];
+ p_t1t->lockbyte[num_locks].b_lock_read = TRUE;
+ }
+ else if (offset < (p_t1t->mem[T1T_CC_TMS_BYTE] + 1) * T1T_BLOCK_SIZE)
+ {
+ /* send READ8 command */
+ p_t1t->block_read = (UINT8) (offset/T1T_BLOCK_SIZE);
+ if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_READ8, p_t1t->block_read, NULL)) == NFC_STATUS_OK)
+ {
+ /* Reading Locks */
+ status = NFC_STATUS_CONTINUE;
+ p_t1t->substate = RW_T1T_SUBSTATE_WAIT_READ_LOCKS;
+ }
+ break;
+ }
+ else
+ {
+ /* Read locks failed */
+ status = NFC_STATUS_FAILED;
+ break;
+ }
+ }
+ num_locks++;
+ }
+ if (num_locks == p_t1t->num_lockbytes)
+ {
+ /* All locks are read */
+ status = NFC_STATUS_OK;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function rw_t1t_handle_write_rsp
+**
+** Description This function handles response received for WRITE_E8,
+** WRITE_NE8, WRITE_E, WRITE_NE commands
+**
+** Returns status of the current NDEF/TLV Operation
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_handle_write_rsp (BOOLEAN *p_notify, UINT8 *p_data)
+{
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ tNFC_STATUS status = NFC_STATUS_OK;
+ UINT8 num_locks;
+ UINT8 lock_count;
+ UINT8 value;
+ UINT8 addr;
+ UINT8 write_block[T1T_BLOCK_SIZE];
+ UINT16 offset;
+ UINT16 next_offset;
+ UINT8 num_bits;
+ UINT8 next_num_bits;
+
+ *p_notify = FALSE;
+
+ switch (p_t1t->state)
+ {
+ case RW_T1T_STATE_WRITE:
+ *p_notify = TRUE;
+ break;
+
+ case RW_T1T_STATE_FORMAT_TAG:
+ if (p_t1t->substate == RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF)
+ {
+ if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 || rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN)
+ *p_notify = TRUE;
+ else
+ {
+ if (p_t1t->work_offset < (T1T_BLOCK_SIZE - 1))
+ {
+ p_t1t->work_offset++;
+ /* send WRITE-E command */
+ RW_T1T_BLD_ADD ((addr), 1, (UINT8) p_t1t->work_offset);
+
+ if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, p_t1t->ndef_first_block[(UINT8) p_t1t->work_offset])) != NFC_STATUS_OK)
+ *p_notify = TRUE;
+ }
+ else
+ *p_notify = TRUE;
+ }
+
+ }
+ else
+ {
+ /* send WRITE-E8 command */
+ if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_E8, 2, p_t1t->ndef_final_block)) != NFC_STATUS_OK)
+ *p_notify = TRUE;
+ else
+ p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF;
+ }
+ break;
+
+ case RW_T1T_STATE_SET_TAG_RO:
+ switch (p_t1t->substate)
+ {
+ case RW_T1T_SUBSTATE_WAIT_SET_CC_RWA_RO:
+
+ if (!p_t1t->b_hard_lock)
+ {
+ status = NFC_STATUS_OK;
+ *p_notify = TRUE;
+ break;
+ }
+
+ if ((p_t1t->hr[0] & 0x0F) != 1)
+ {
+ memset (write_block,0,T1T_BLOCK_SIZE);
+ write_block[0] = 0xFF;
+ write_block[1] = 0xFF;
+
+ /* send WRITE-NE8 command */
+ if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_NE8, T1T_LOCK_BLOCK, write_block)) != NFC_STATUS_OK)
+ *p_notify = TRUE;
+ else
+ p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
+ }
+ else
+ {
+ /* send WRITE-NE command */
+ RW_T1T_BLD_ADD ((addr), (T1T_LOCK_BLOCK), (0));
+ if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_NE, addr, 0xFF)) != NFC_STATUS_OK)
+ *p_notify = TRUE;
+ else
+ p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_ST_LOCK_BITS;
+ }
+ break;
+
+ case RW_T1T_SUBSTATE_WAIT_SET_ST_LOCK_BITS:
+
+ /* send WRITE-NE command */
+ RW_T1T_BLD_ADD ((addr), (T1T_LOCK_BLOCK), (1));
+ if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_NE, addr, 0xFF)) != NFC_STATUS_OK)
+ *p_notify = TRUE;
+ else
+ p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
+
+ break;
+
+ case RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS:
+ num_locks = 0;
+ while (num_locks < p_t1t->num_lockbytes)
+ {
+ if (p_t1t->lockbyte[num_locks].lock_status == RW_T1T_LOCK_UPDATE_INITIATED)
+ {
+ p_t1t->lockbyte[num_locks].lock_status = RW_T1T_LOCK_UPDATED;
+ }
+ num_locks++;
+ }
+
+ num_locks = 0;
+ while (num_locks < p_t1t->num_lockbytes)
+ {
+ if (p_t1t->lockbyte[num_locks].lock_status == RW_T1T_LOCK_NOT_UPDATED)
+ {
+ offset = p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].offset + p_t1t->lockbyte[num_locks].byte_index;
+ num_bits = ((p_t1t->lockbyte[num_locks].byte_index + 1)* 8 <= p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].num_bits) ? 8 : p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].num_bits % 8;
+
+ if ((p_t1t->hr[0] & 0x0F) != 1)
+ {
+ memset (write_block,0,T1T_BLOCK_SIZE);
+
+ write_block[(UINT8) (offset%T1T_BLOCK_SIZE)] |= tags_pow (2,num_bits) - 1;
+ lock_count = num_locks + 1;
+ while (lock_count < p_t1t->num_lockbytes)
+ {
+ next_offset = p_t1t->lock_tlv[p_t1t->lockbyte[lock_count].tlv_index].offset + p_t1t->lockbyte[lock_count].byte_index;
+ next_num_bits = ((p_t1t->lockbyte[lock_count].byte_index + 1)* 8 <= p_t1t->lock_tlv[p_t1t->lockbyte[lock_count].tlv_index].num_bits) ? 8 : p_t1t->lock_tlv[p_t1t->lockbyte[lock_count].tlv_index].num_bits % 8;
+
+ if (next_offset/T1T_BLOCK_SIZE == offset/T1T_BLOCK_SIZE)
+ {
+ write_block[(UINT8) (next_offset%T1T_BLOCK_SIZE)] |= tags_pow (2,next_num_bits) - 1;
+ }
+ else
+ break;
+ lock_count ++;
+ }
+
+ /* send WRITE-NE8 command */
+ if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_NE8, (UINT8) (offset/T1T_BLOCK_SIZE), write_block)) == NFC_STATUS_OK)
+ {
+ p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
+ while (lock_count > num_locks)
+ {
+ p_t1t->lockbyte[lock_count - 1].lock_status = RW_T1T_LOCK_UPDATE_INITIATED;
+ lock_count --;
+ }
+ }
+ else
+ *p_notify = TRUE;
+ }
+ else
+ {
+ /* send WRITE-NE command */
+ RW_T1T_BLD_ADD ((addr), ((UINT8) (offset/T1T_BLOCK_SIZE)), ((UINT8) (offset%T1T_BLOCK_SIZE)));
+ value = (UINT8) (tags_pow (2,num_bits) - 1);
+ if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_NE, addr, value)) == NFC_STATUS_OK)
+ {
+ p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
+ p_t1t->lockbyte[num_locks].lock_status = RW_T1T_LOCK_UPDATE_INITIATED;
+ }
+ else
+ *p_notify = TRUE;
+ }
+ break;
+ }
+ num_locks++;
+ }
+ if (num_locks == p_t1t->num_lockbytes)
+ {
+ rw_t1t_update_lock_attributes ();
+ status = NFC_STATUS_OK;
+ *p_notify = TRUE;
+ }
+ break;
+ }
+ break;
+
+ case RW_T1T_STATE_WRITE_NDEF:
+ switch (p_t1t->substate)
+ {
+ case RW_T1T_SUBSTATE_WAIT_VALIDATE_NDEF:
+ p_t1t->ndef_msg_len = p_t1t->new_ndef_msg_len;
+ p_t1t->tag_attribute = RW_T1_TAG_ATTRB_READ_WRITE;
+ *p_notify = TRUE;
+ break;
+
+ case RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED:
+ status = rw_t1t_handle_ndef_write_rsp (p_data);
+ if (status == NFC_STATUS_OK)
+ {
+ p_t1t->substate = RW_T1T_SUBSTATE_WAIT_VALIDATE_NDEF;
+ }
+ else if (status == NFC_STATUS_FAILED)
+ {
+ /* Send Negative response to upper layer */
+ *p_notify = TRUE;
+ }
+ break;
+
+ case RW_T1T_SUBSTATE_WAIT_NDEF_WRITE:
+ status = rw_t1t_handle_ndef_write_rsp (p_data);
+
+ if (status == NFC_STATUS_FAILED)
+ {
+ /* Send Negative response to upper layer */
+ *p_notify = TRUE;
+ }
+ else if (status == NFC_STATUS_OK)
+ {
+ p_t1t->substate = RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED;
+ }
+ break;
+
+ case RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF:
+ status = rw_t1t_handle_ndef_write_rsp (p_data);
+ if (status == NFC_STATUS_FAILED)
+ {
+ /* Send Negative response to upper layer */
+ *p_notify = TRUE;
+ }
+ else if (status == NFC_STATUS_CONTINUE)
+ {
+ p_t1t->substate = RW_T1T_SUBSTATE_WAIT_NDEF_WRITE;
+ }
+ else
+ {
+ p_t1t->substate = RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED;
+ }
+ break;
+ }
+ break;
+ }
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function rw_t1t_handle_read_rsp
+**
+** Description This function handle the 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 (BOOLEAN *p_notify, UINT8 *p_data)
+{
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ tNFC_STATUS status = NFC_STATUS_OK;
+ tRW_DETECT_NDEF_DATA ndef_data;
+ tRW_DETECT_TLV_DATA tlv_data;
+ UINT8 count;
+ tRW_READ_DATA evt_data;
+
+ *p_notify = FALSE;
+ /* Handle the response based on the current state */
+ switch (p_t1t->state)
+ {
+ case RW_T1T_STATE_READ:
+ *p_notify = TRUE;
+ break;
+
+ case RW_T1T_STATE_READ_NDEF:
+ status = rw_t1t_handle_ndef_rall_rsp ();
+ if (status != NFC_STATUS_CONTINUE)
+ {
+ evt_data.status = status;
+ evt_data.p_data = NULL;
+ rw_t1t_handle_op_complete ();
+ (*rw_cb.p_cback) (RW_T1T_NDEF_READ_EVT, (tRW_DATA *) &evt_data);
+ }
+ break;
+
+ case RW_T1T_STATE_TLV_DETECT:
+ switch (p_t1t->substate)
+ {
+ case RW_T1T_SUBSTATE_WAIT_READ_LOCKS:
+ status = rw_t1t_read_locks ();
+ if (status != NFC_STATUS_CONTINUE)
+ {
+ rw_t1t_update_lock_attributes ();
+ /* Send positive response to upper layer */
+ if (p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV)
+ {
+ tlv_data.protocol = NFC_PROTOCOL_T1T;
+ tlv_data.num_bytes = p_t1t->num_lockbytes;
+ tlv_data.status = status;
+ rw_t1t_handle_op_complete ();
+ (*rw_cb.p_cback) (RW_T1T_TLV_DETECT_EVT, (tRW_DATA *) &tlv_data);
+ }
+ else if (p_t1t->tlv_detect == TAG_NDEF_TLV)
+ {
+ ndef_data.protocol = NFC_PROTOCOL_T1T;
+ ndef_data.flags = rw_t1t_get_ndef_flags ();
+ ndef_data.flags |= RW_NDEF_FL_FORMATED;
+ ndef_data.max_size = (UINT32) rw_t1t_get_ndef_max_size ();
+ ndef_data.cur_size = p_t1t->ndef_msg_len;
+
+ if (ndef_data.max_size < ndef_data.cur_size)
+ {
+ ndef_data.flags |= RW_NDEF_FL_READ_ONLY;
+ ndef_data.max_size = ndef_data.cur_size;
+ }
+
+ if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY))
+ {
+ ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE;
+ if (status == NFC_STATUS_OK)
+ ndef_data.flags |= RW_NDEF_FL_HARD_LOCKABLE;
+ }
+ ndef_data.status = status;
+ rw_t1t_handle_op_complete ();
+ (*rw_cb.p_cback) (RW_T1T_NDEF_DETECT_EVT, (tRW_DATA *)&ndef_data);
+ }
+ }
+ break;
+
+ case RW_T1T_SUBSTATE_NONE:
+ if (p_t1t->tlv_detect == TAG_MEM_CTRL_TLV)
+ {
+ tlv_data.status = rw_t1t_handle_tlv_detect_rsp (p_t1t->mem);
+ tlv_data.protocol = NFC_PROTOCOL_T1T;
+ tlv_data.num_bytes = 0;
+ count = 0;
+ while (count < p_t1t->num_mem_tlvs)
+ {
+ tlv_data.num_bytes += p_t1t->mem_tlv[p_t1t->num_mem_tlvs].num_bytes;
+ count++;
+ }
+ rw_t1t_handle_op_complete ();
+ /* Send response to upper layer */
+ (*rw_cb.p_cback) (RW_T1T_TLV_DETECT_EVT, (tRW_DATA *) &tlv_data);
+ }
+ else if (p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV)
+ {
+ tlv_data.status = rw_t1t_handle_tlv_detect_rsp (p_t1t->mem);
+ tlv_data.protocol = NFC_PROTOCOL_T1T;
+ tlv_data.num_bytes = p_t1t->num_lockbytes;
+
+ if (tlv_data.status == NFC_STATUS_FAILED)
+ {
+ rw_t1t_handle_op_complete ();
+
+ /* Send Negative response to upper layer */
+ (*rw_cb.p_cback) (RW_T1T_TLV_DETECT_EVT, (tRW_DATA *)&tlv_data);
+ }
+ else
+ {
+ rw_t1t_extract_lock_bytes (p_data);
+ status = rw_t1t_read_locks ();
+ if (status != NFC_STATUS_CONTINUE)
+ {
+ /* Send positive response to upper layer */
+ tlv_data.status = status;
+ rw_t1t_handle_op_complete ();
+
+ (*rw_cb.p_cback) (RW_T1T_TLV_DETECT_EVT, (tRW_DATA *) &tlv_data);
+ }
+ }
+ }
+ else if (p_t1t->tlv_detect == TAG_NDEF_TLV)
+ {
+ ndef_data.protocol = NFC_PROTOCOL_T1T;
+ ndef_data.flags = rw_t1t_get_ndef_flags ();
+
+ if (p_t1t->mem[T1T_CC_NMN_BYTE] == T1T_CC_NMN)
+ {
+ ndef_data.status = rw_t1t_handle_tlv_detect_rsp (p_t1t->mem);
+
+ ndef_data.cur_size = p_t1t->ndef_msg_len;
+ if (ndef_data.status == NFC_STATUS_FAILED)
+ {
+ ndef_data.max_size = (UINT32) rw_t1t_get_ndef_max_size ();
+ if (ndef_data.max_size < ndef_data.cur_size)
+ {
+ ndef_data.flags |= RW_NDEF_FL_READ_ONLY;
+ ndef_data.max_size = ndef_data.cur_size;
+ }
+ if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY))
+ {
+ ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE;
+ }
+ /* Send Negative response to upper layer */
+ rw_t1t_handle_op_complete ();
+
+ (*rw_cb.p_cback) (RW_T1T_NDEF_DETECT_EVT, (tRW_DATA *) &ndef_data);
+ }
+ else
+ {
+ ndef_data.flags |= RW_NDEF_FL_FORMATED;
+ rw_t1t_extract_lock_bytes (p_data);
+ status = rw_t1t_read_locks ();
+ if (status != NFC_STATUS_CONTINUE)
+ {
+ ndef_data.max_size = (UINT32) rw_t1t_get_ndef_max_size ();
+ if (ndef_data.max_size < ndef_data.cur_size)
+ {
+ ndef_data.flags |= RW_NDEF_FL_READ_ONLY;
+ ndef_data.max_size = ndef_data.cur_size;
+ }
+
+ if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY))
+ {
+ ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE;
+ if (status == NFC_STATUS_OK)
+ ndef_data.flags |= RW_NDEF_FL_HARD_LOCKABLE;
+ }
+ /* Send positive response to upper layer */
+ ndef_data.status = status;
+ rw_t1t_handle_op_complete ();
+
+ (*rw_cb.p_cback) (RW_T1T_NDEF_DETECT_EVT, (tRW_DATA *)&ndef_data);
+ }
+ }
+ }
+ else
+ {
+ /* Send Negative response to upper layer */
+ ndef_data.status = NFC_STATUS_FAILED;
+ ndef_data.max_size = (UINT32) rw_t1t_get_ndef_max_size ();
+ ndef_data.cur_size = p_t1t->ndef_msg_len;
+ if (ndef_data.max_size < ndef_data.cur_size)
+ {
+ ndef_data.flags |= RW_NDEF_FL_READ_ONLY;
+ ndef_data.max_size = ndef_data.cur_size;
+ }
+ if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY))
+ {
+ ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE;
+ ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE;
+ }
+ rw_t1t_handle_op_complete ();
+
+ (*rw_cb.p_cback) (RW_T1T_NDEF_DETECT_EVT, (tRW_DATA *) &ndef_data);
+ }
+ }
+ break;
+ }
+ break;
+ }
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function rw_t1t_handle_dyn_read_rsp
+**
+** Description This function handles response received for READ8, RSEG
+** commands based on the current state
+**
+** Returns status of the current NDEF/TLV Operation
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_handle_dyn_read_rsp (BOOLEAN *p_notify, UINT8 *p_data)
+{
+ tNFC_STATUS status = NFC_STATUS_OK;
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+
+ *p_notify = FALSE;
+
+ 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 (BOOLEAN *p_notify,UINT8 *p_data)
+{
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+
+ p_data += T1T_HR_LEN; /* skip HR */
+ memcpy (p_t1t->mem, (UINT8 *) p_data, T1T_STATIC_SIZE);
+ p_t1t->segment = 0;
+ rw_t1t_extract_lock_bytes (p_data);
+
+ p_data += T1T_UID_LEN + T1T_RES_BYTE_LEN; /* skip Block 0, UID and Reserved byte */
+
+ RW_TRACE_DEBUG0 ("rw_t1t_handle_rall_rsp ()");
+
+ rw_t1t_update_tag_state ();
+ rw_t1t_update_attributes ();
+ rw_t1t_update_lock_attributes ();
+ p_t1t->b_update = TRUE;
+ return (rw_t1t_handle_read_rsp (p_notify, p_t1t->mem));
+}
+
+/*******************************************************************************
+**
+** Function rw_t1t_handle_tlv_detect_rsp
+**
+** Description Handle response to the last command sent while
+** detecting tlv
+**
+** Returns NFC_STATUS_OK, if tlv detect is complete & success
+** NFC_STATUS_FAILED,if tlv detect failed
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_handle_tlv_detect_rsp (UINT8 *p_data)
+{
+ UINT16 offset;
+ UINT16 len;
+ UINT8 xx;
+ UINT8 *p_readbytes;
+ UINT8 index;
+ UINT8 tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
+ UINT8 found_tlv = TAG_NULL_TLV;
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ BOOLEAN failed = FALSE;
+ BOOLEAN found = FALSE;
+ UINT8 count = 0;
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ UINT8 start_offset = T1T_UID_LEN + T1T_CC_LEN + T1T_RES_BYTE_LEN;
+ UINT8 end_offset = T1T_STATIC_SIZE - (2*T1T_BLOCK_SIZE);
+ UINT8 bytes_read = T1T_STATIC_SIZE;
+ UINT8 tlv_value[T1T_DEFAULT_TLV_LEN];
+ UINT16 bytes_count = 0;
+
+ p_readbytes = p_data;
+
+ for (offset = start_offset; offset < end_offset && !failed && !found;)
+ {
+ if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) (offset)) == TRUE)
+ {
+ offset++;
+ continue;
+ }
+ switch (tlv_detect_state)
+ {
+ case RW_T1T_SUBSTATE_WAIT_TLV_DETECT:
+ /* Search for the tag */
+ found_tlv = p_readbytes[offset++];
+ switch (found_tlv)
+ {
+ case TAG_NULL_TLV: /* May be used for padding. SHALL ignore this */
+ break;
+
+ case TAG_NDEF_TLV:
+ if (p_t1t->tlv_detect == TAG_NDEF_TLV)
+ {
+ index = (offset % T1T_BLOCK_SIZE);
+ /* Backup ndef first block */
+ memcpy (&p_t1t->ndef_first_block[0],&p_readbytes[offset-index],index);
+ memcpy (&p_t1t->ndef_first_block[index],&p_readbytes[offset],T1T_BLOCK_SIZE - index);
+ tlv_detect_state = RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
+ }
+ else if (p_t1t->tlv_detect == TAG_PROPRIETARY_TLV)
+ {
+ tlv_detect_state = RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
+ }
+ else if ( ((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) && (p_t1t->num_lockbytes > 0))
+ ||((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) && (p_t1t->num_mem_tlvs > 0)) )
+ {
+ found = TRUE;
+ }
+ else
+ {
+ failed = TRUE;
+ }
+ break;
+
+ case TAG_LOCK_CTRL_TLV:
+ case TAG_MEM_CTRL_TLV:
+ tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0;
+ break;
+
+ case TAG_PROPRIETARY_TLV:
+ if (p_t1t->tlv_detect == TAG_PROPRIETARY_TLV)
+ {
+ index = (offset % T1T_BLOCK_SIZE);
+ /* Backup ndef first block */
+ tlv_detect_state = RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
+ }
+ else
+ {
+ /* 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) p_readbytes[offset];
+ tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN1;
+ break;
+ }
+ offset++;
+ break;
+
+ case RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN1:
+ bytes_count = (bytes_count << 8) + p_readbytes[offset];
+ if (found_tlv == TAG_NDEF_TLV)
+ {
+ p_t1t->ndef_msg_len = bytes_count;
+ }
+ tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE;
+ offset++;
+ break;
+
+ case RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE:
+ switch (found_tlv)
+ {
+ case TAG_NDEF_TLV:
+ if ((bytes_count == p_t1t->ndef_msg_len) && (p_t1t->tlv_detect == TAG_NDEF_TLV))
+ {
+ /* The first byte offset after length field */
+ p_t1t->ndef_msg_offset = offset + p_t1t->work_offset;
+ }
+ if (bytes_count > 0)
+ bytes_count--;
+
+ if (p_t1t->tlv_detect == TAG_NDEF_TLV)
+ {
+ if (p_t1t->ndef_msg_len > 0)
+ {
+ rw_t1t_update_tag_state ();
+ }
+ else
+ {
+ p_t1t->tag_attribute = RW_T1_TAG_ATTRB_INITIALIZED_NDEF;
+ }
+ found = TRUE;
+ }
+ else if (bytes_count == 0)
+ {
+ tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
+ }
+ break;
+
+ case TAG_LOCK_CTRL_TLV:
+ bytes_count--;
+ if ( (p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV)
+ ||(p_t1t->tlv_detect == TAG_NDEF_TLV) )
+ {
+ tlv_value[2 - bytes_count] = p_readbytes[offset];
+ if (bytes_count == 0)
+ {
+ if (p_t1t->num_lock_tlvs < RW_T1T_MAX_LOCK_TLVS)
+ {
+ p_t1t->lock_tlv[p_t1t->num_lock_tlvs].offset = (tlv_value[0] >> 4) & 0x0F;
+ p_t1t->lock_tlv[p_t1t->num_lock_tlvs].offset *= (UINT8) tags_pow (2, tlv_value[2] & 0x0F);
+ p_t1t->lock_tlv[p_t1t->num_lock_tlvs].offset += tlv_value[0] & 0x0F;
+ p_t1t->lock_tlv[p_t1t->num_lock_tlvs].bytes_locked_per_bit = (UINT8) tags_pow (2, ((tlv_value[2] & 0xF0) >> 4));
+ p_t1t->lock_tlv[p_t1t->num_lock_tlvs].num_bits = tlv_value[1];
+ count = tlv_value[1] / 8 + ((tlv_value[1] % 8 != 0)? 1:0);
+ xx = 0;
+ while (xx < count)
+ {
+ if (p_t1t->num_lockbytes < RW_T1T_MAX_LOCK_BYTES)
+ {
+ p_t1t->lockbyte[p_t1t->num_lockbytes].tlv_index = p_t1t->num_lock_tlvs;
+ p_t1t->lockbyte[p_t1t->num_lockbytes].byte_index = xx;
+ p_t1t->lockbyte[p_t1t->num_lockbytes].b_lock_read = FALSE;
+ p_t1t->num_lockbytes++;
+ }
+ else
+ RW_TRACE_ERROR1 ("T1T Buffer overflow error. Max supported lock bytes=0x%02X", RW_T1T_MAX_LOCK_BYTES);
+ xx++;
+ }
+ p_t1t->num_lock_tlvs++;
+ rw_t1t_update_attributes ();
+ }
+ else
+ RW_TRACE_ERROR1 ("T1T Buffer overflow error. Max supported lock tlvs=0x%02X", RW_T1T_MAX_LOCK_TLVS);
+
+ tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
+ }
+ }
+ else
+ {
+ if (bytes_count == 0)
+ {
+ tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
+ }
+ }
+ break;
+
+ case TAG_MEM_CTRL_TLV:
+ bytes_count--;
+ if ( (p_t1t->tlv_detect == TAG_MEM_CTRL_TLV)
+ ||(p_t1t->tlv_detect == TAG_NDEF_TLV) )
+ {
+ tlv_value[2 - bytes_count] = p_readbytes[offset];
+ if (bytes_count == 0)
+ {
+ if (p_t1t->num_mem_tlvs >= RW_T1T_MAX_MEM_TLVS)
+ {
+ RW_TRACE_ERROR0 ("rw_t1t_handle_tlv_detect_rsp - Maximum buffer allocated for Memory tlv has reached");
+ failed = TRUE;
+ }
+ else
+ {
+ /* Extract dynamic reserved bytes */
+ p_t1t->mem_tlv[p_t1t->num_mem_tlvs].offset = (tlv_value[0] >> 4) & 0x0F;
+ p_t1t->mem_tlv[p_t1t->num_mem_tlvs].offset *= (UINT8) tags_pow (2, tlv_value[2] & 0x0F);
+ p_t1t->mem_tlv[p_t1t->num_mem_tlvs].offset += tlv_value[0] & 0x0F;
+ p_t1t->mem_tlv[p_t1t->num_mem_tlvs].num_bytes = tlv_value[1];
+ p_t1t->num_mem_tlvs++;
+ rw_t1t_update_attributes ();
+ tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
+ }
+ }
+ }
+ else
+ {
+ if (bytes_count == 0)
+ {
+ tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
+ }
+ }
+ break;
+
+ case TAG_PROPRIETARY_TLV:
+ bytes_count--;
+ if (p_t1t->tlv_detect == TAG_PROPRIETARY_TLV)
+ found = TRUE;
+ else
+ {
+ if (bytes_count == 0)
+ {
+ tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
+ }
+ }
+ break;
+ }
+ offset++;
+ break;
+ }
+ }
+
+ p_t1t->work_offset += bytes_read;
+
+ /* 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 count;
+ UINT8 adds;
+
+ count = (UINT8) p_t1t->ndef_msg_offset;
+ p_t1t->work_offset = 0;
+ p_t1t->segment = 0;
+
+ while (count < T1T_STATIC_SIZE && p_t1t->work_offset < p_t1t->ndef_msg_len)
+ {
+ if (rw_t1t_is_lock_reserved_otp_byte (count) == FALSE)
+ {
+ p_t1t->p_ndef_buffer[p_t1t->work_offset] = p_t1t->mem[count];
+ p_t1t->work_offset++;
+ }
+ count++;
+ }
+ if (p_t1t->work_offset != p_t1t->ndef_msg_len)
+ {
+ if ((p_t1t->hr[0] & 0x0F) != 1)
+ {
+ if (p_t1t->work_offset == 0)
+ return NFC_STATUS_FAILED;
+
+ else
+ {
+ p_t1t->block_read = T1T_STATIC_BLOCKS + 1;
+ p_t1t->segment++;
+ }
+ if (p_t1t->ndef_msg_len - p_t1t->work_offset <= 8)
+ {
+ if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_READ8, p_t1t->block_read, NULL)) == NFC_STATUS_OK)
+ {
+ p_t1t->tlv_detect = TAG_NDEF_TLV;
+ p_t1t->state = RW_T1T_STATE_READ_NDEF;
+ status = NFC_STATUS_CONTINUE;
+ }
+ }
+ else
+ {
+ /* send RSEG command */
+ RW_T1T_BLD_ADDS ((adds), (p_t1t->segment));
+ if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_RSEG, adds, NULL)) == NFC_STATUS_OK)
+ {
+ p_t1t->state = RW_T1T_STATE_READ_NDEF;
+ status = NFC_STATUS_CONTINUE;
+ }
+ }
+ }
+ else
+ {
+ RW_TRACE_ERROR1 ("RW_T1tReadNDef - Invalid NDEF len: %u or NDEF corrupted", p_t1t->ndef_msg_len);
+ status = NFC_STATUS_FAILED;
+ }
+ }
+ else
+ {
+ status = NFC_STATUS_OK;
+ }
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function rw_t1t_handle_ndef_read_rsp
+**
+** Description Handle response to commands sent while reading an
+** NDEF message
+**
+** Returns NFC_STATUS_CONTINUE, if tlv read is not yet complete
+** NFC_STATUS_OK, if tlv read is complete & success
+** NFC_STATUS_FAILED,if tlv read failed
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_handle_ndef_read_rsp (UINT8 *p_data)
+{
+ tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ UINT8 index;
+ UINT8 adds;
+ 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) ((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) (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++;
+ if ((ndef_status = rw_t1t_send_dyn_cmd (T1T_CMD_READ8, (UINT8) (p_t1t->block_read), NULL)) == NFC_STATUS_OK)
+ {
+ ndef_status = NFC_STATUS_CONTINUE;
+ }
+ }
+ else
+ {
+ p_t1t->segment++;
+ /* send RSEG command */
+ RW_T1T_BLD_ADDS ((adds), (p_t1t->segment));
+ if ((ndef_status = rw_t1t_send_dyn_cmd (T1T_CMD_RSEG, adds, NULL)) == NFC_STATUS_OK)
+ {
+ ndef_status = NFC_STATUS_CONTINUE;
+ }
+ }
+ }
+ }
+ else
+ {
+ ndef_status = NFC_STATUS_OK;
+ }
+ return ndef_status;
+}
+
+/*******************************************************************************
+**
+** Function rw_t1t_next_ndef_write_block
+**
+** Description This function prepare and writes ndef blocks
+**
+** Returns NFC_STATUS_CONTINUE, if tlv write is not yet complete
+** NFC_STATUS_OK, if tlv write is complete & success
+** NFC_STATUS_FAILED,if tlv write failed
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_next_ndef_write_block (void)
+{
+ BOOLEAN b_block_write_cmd = FALSE;
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
+ UINT8 write_block[8];
+ UINT8 block;
+ UINT8 index;
+ UINT8 new_lengthfield_len;
+ UINT8 length_field[3];
+ UINT16 initial_offset;
+ UINT8 count;
+ /* Write NDEF Message */
+ new_lengthfield_len = p_t1t->new_ndef_msg_len > 254 ? 3:1;
+
+ /* Identify the command to use for NDEF write operation */
+ if ((p_t1t->hr[0] & 0x0F) != 1)
+ {
+ /* Dynamic memory structure */
+ b_block_write_cmd = FALSE;
+ block = p_t1t->ndef_block_written + 1;
+ p_t1t->segment = (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE;
+
+ count = 0;
+ while (block <= p_t1t->mem[T1T_CC_TMS_BYTE])
+ {
+ index = 0;
+ if (block == p_t1t->num_ndef_finalblock)
+ {
+ /* T1T_CMD_WRITE_E8 Command */
+ b_block_write_cmd = TRUE;
+ break;
+ }
+ while (index < T1T_BLOCK_SIZE && p_t1t->work_offset < (p_t1t->new_ndef_msg_len + new_lengthfield_len))
+ {
+ if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) ((block * T1T_BLOCK_SIZE) + index)) == FALSE)
+ {
+ count++;
+ }
+ index++;
+ }
+ if (count == T1T_BLOCK_SIZE)
+ {
+ /* T1T_CMD_WRITE_E8 Command */
+ b_block_write_cmd = TRUE;
+ break;
+ }
+ else if (count == 0)
+ {
+ index = 0;
+ block++;
+ if (p_t1t->segment != (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE)
+ {
+ p_t1t->segment = (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE;
+ }
+ }
+ else
+ {
+ /* T1T_CMD_WRITE_E Command */
+ b_block_write_cmd = FALSE;
+ break;
+ }
+ }
+ }
+ else
+ {
+ /* Static memory structure */
+ block = p_t1t->ndef_block_written;
+ b_block_write_cmd = FALSE;
+ }
+
+ new_lengthfield_len = p_t1t->new_ndef_msg_len > 254 ? 3:1;
+ if (new_lengthfield_len == 3)
+ {
+ length_field[0] = T1T_LONG_NDEF_LEN_FIELD_BYTE0;
+ length_field[1] = (UINT8) (p_t1t->new_ndef_msg_len >> 8);
+ length_field[2] = (UINT8) (p_t1t->new_ndef_msg_len);
+ }
+ else
+ {
+ length_field[0] = (UINT8) (p_t1t->new_ndef_msg_len);
+ }
+
+ if (b_block_write_cmd)
+ {
+ /* Dynamic memory structure */
+ index = 0;
+ p_t1t->segment = (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE;
+
+ initial_offset = p_t1t->work_offset;
+ block = rw_t1t_prepare_ndef_bytes (write_block, length_field, &index, FALSE, block, new_lengthfield_len);
+ if (p_t1t->work_offset == initial_offset)
+ {
+ ndef_status = NFC_STATUS_FAILED;
+ }
+ else
+ {
+ /* Send WRITE_E8 command */
+ ndef_status = rw_t1t_send_ndef_block (write_block, block);
+ }
+ }
+ else
+ {
+ /* Static memory structure */
+ if (p_t1t->write_byte + 1 >= T1T_BLOCK_SIZE)
+ {
+ index = 0;
+ block++;
+ }
+ else
+ {
+ index = p_t1t->write_byte + 1;
+ }
+ initial_offset = p_t1t->work_offset;
+ block = rw_t1t_prepare_ndef_bytes (write_block, length_field, &index, TRUE, block, new_lengthfield_len);
+ if (p_t1t->work_offset == initial_offset)
+ {
+ ndef_status = NFC_STATUS_FAILED;
+ }
+ else
+ {
+ /* send WRITE-E command */
+ ndef_status = rw_t1t_send_ndef_byte (write_block[index], block, index, new_lengthfield_len);
+ }
+ }
+ return ndef_status;
+
+}
+
+/*******************************************************************************
+**
+** Function rw_t1t_ndef_write_first_block
+**
+** Description This function writes ndef first block
+**
+** Returns NFC_STATUS_CONTINUE, if tlv write is not yet complete
+** NFC_STATUS_OK, if tlv write is complete & success
+** NFC_STATUS_FAILED,if tlv write failed
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_ndef_write_first_block (void)
+{
+ tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ UINT8 block;
+ UINT8 index;
+ UINT8 new_lengthfield_len;
+ UINT8 length_field[3];
+ UINT8 write_block[8];
+
+ /* handle positive response to invalidating existing NDEF Message */
+ p_t1t->work_offset = 0;
+ new_lengthfield_len = p_t1t->new_ndef_msg_len > 254 ? 3:1;
+ if (new_lengthfield_len == 3)
+ {
+ length_field[0] = T1T_LONG_NDEF_LEN_FIELD_BYTE0;
+ length_field[1] = (UINT8) (p_t1t->new_ndef_msg_len >> 8);
+ length_field[2] = (UINT8) (p_t1t->new_ndef_msg_len);
+ }
+ else
+ {
+ length_field[0] = (UINT8) (p_t1t->new_ndef_msg_len);
+ }
+ /* updating ndef_first_block with new ndef message */
+ memcpy(write_block,p_t1t->ndef_first_block,T1T_BLOCK_SIZE);
+ index = p_t1t->ndef_header_offset % T1T_BLOCK_SIZE;
+ block = (UINT8) (p_t1t->ndef_header_offset / T1T_BLOCK_SIZE);
+ p_t1t->segment = (UINT8) (p_t1t->ndef_header_offset/T1T_SEGMENT_SIZE);
+
+ if ((p_t1t->hr[0] & 0x0F) != 1)
+ {
+ /* Dynamic Memory structure */
+ block = rw_t1t_prepare_ndef_bytes (write_block, length_field, &index, FALSE, block, new_lengthfield_len);
+
+ if (p_t1t->work_offset == 0)
+ {
+ ndef_status = NFC_STATUS_FAILED;
+ }
+ else
+ {
+ /* Send WRITE-E8 command based on the prepared write_block */
+ ndef_status = rw_t1t_send_ndef_block (write_block, block);
+ }
+ }
+ else
+ {
+ /* Static Memory structure */
+ block = rw_t1t_prepare_ndef_bytes (write_block, length_field, &index, TRUE, block, new_lengthfield_len);
+ if (p_t1t->work_offset == 0)
+ {
+ ndef_status = NFC_STATUS_FAILED;
+ }
+ else
+ {
+ /* send WRITE-E command */
+ ndef_status = rw_t1t_send_ndef_byte (write_block[index], block, index, new_lengthfield_len);
+ }
+ }
+
+ return ndef_status;
+}
+
+/*******************************************************************************
+**
+** Function rw_t1t_send_ndef_byte
+**
+** Description Sends ndef message or length field byte and update
+** status
+**
+** Returns NFC_STATUS_CONTINUE, if tlv write is not yet complete
+** NFC_STATUS_OK, if tlv write is complete & success
+** NFC_STATUS_FAILED,if tlv write failed
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_send_ndef_byte (UINT8 data, UINT8 block, UINT8 index, UINT8 msg_len)
+{
+ tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ UINT8 addr;
+
+ /* send WRITE-E command */
+ RW_T1T_BLD_ADD ((addr), (block), (index));
+ if (NFC_STATUS_OK == rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, data))
+ {
+ p_t1t->write_byte = index;
+ p_t1t->ndef_block_written = block;
+ if (p_t1t->work_offset == p_t1t->new_ndef_msg_len + msg_len)
+ {
+ ndef_status = NFC_STATUS_OK;
+ }
+ else
+ {
+ ndef_status = NFC_STATUS_CONTINUE;
+ }
+ }
+ else
+ {
+ ndef_status = NFC_STATUS_FAILED;
+ }
+ return ndef_status;
+}
+
+/*******************************************************************************
+**
+** Function rw_t1t_prepare_ndef_bytes
+**
+** Description prepares ndef block to write
+**
+** Returns block number where to write
+**
+*******************************************************************************/
+static UINT8 rw_t1t_prepare_ndef_bytes (UINT8 *p_data, UINT8 *p_length_field, UINT8 *p_index, BOOLEAN b_one_byte, UINT8 block, UINT8 lengthfield_len)
+{
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ UINT8 first_block = (UINT8) (p_t1t->ndef_header_offset / T1T_BLOCK_SIZE);
+ UINT16 initial_offset = p_t1t->work_offset;
+
+ while (p_t1t->work_offset == initial_offset && block <= p_t1t->mem[T1T_CC_TMS_BYTE])
+ {
+ if ( (block == p_t1t->num_ndef_finalblock)
+ &&(block != first_block) )
+ {
+ memcpy (p_data,p_t1t->ndef_final_block,T1T_BLOCK_SIZE);
+ }
+ /* Update length field */
+ while ( (*p_index < T1T_BLOCK_SIZE)
+ &&(p_t1t->work_offset < lengthfield_len) )
+ {
+ if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) ((block * T1T_BLOCK_SIZE) + *p_index)) == FALSE)
+ {
+ p_data[*p_index] = p_length_field[p_t1t->work_offset];
+ p_t1t->work_offset++;
+ if (b_one_byte)
+ return block;
+ }
+ (*p_index)++;
+ if (p_t1t->work_offset == lengthfield_len)
+ {
+ break;
+ }
+ }
+ /* Update ndef message field */
+ while (*p_index < T1T_BLOCK_SIZE && p_t1t->work_offset < (p_t1t->new_ndef_msg_len + lengthfield_len))
+ {
+ if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) ((block * T1T_BLOCK_SIZE) + *p_index)) == FALSE)
+ {
+ p_data[*p_index] = p_t1t->p_ndef_buffer[p_t1t->work_offset - lengthfield_len];
+ p_t1t->work_offset++;
+ if (b_one_byte)
+ return block;
+ }
+ (*p_index)++;
+ }
+ if (p_t1t->work_offset == initial_offset)
+ {
+ *p_index = 0;
+ block++;
+ if (p_t1t->segment != (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE)
+ {
+ p_t1t->segment = (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE;
+ }
+ }
+ }
+ return block;
+}
+
+/*******************************************************************************
+**
+** Function rw_t1t_send_ndef_block
+**
+** Description Sends ndef block and update status
+**
+** Returns NFC_STATUS_CONTINUE, if tlv write is not yet complete
+** NFC_STATUS_OK, if tlv write is complete & success
+** NFC_STATUS_FAILED,if tlv write failed
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_send_ndef_block (UINT8 *p_data, UINT8 block)
+{
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
+
+ if (NFC_STATUS_OK == rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_E8, block, p_data))
+ {
+ p_t1t->ndef_block_written = block;
+ if (p_t1t->ndef_block_written == p_t1t->num_ndef_finalblock)
+ {
+ ndef_status = NFC_STATUS_OK;
+ }
+ else
+ {
+ ndef_status = NFC_STATUS_CONTINUE;
+ }
+ }
+ else
+ {
+ ndef_status = NFC_STATUS_FAILED;
+ }
+ return ndef_status;
+}
+
+/*******************************************************************************
+**
+** Function rw_t1t_get_ndef_flags
+**
+** Description Prepare NDEF Flags
+**
+** Returns NDEF Flag value
+**
+*******************************************************************************/
+static UINT8 rw_t1t_get_ndef_flags (void)
+{
+ UINT8 flags = 0;
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+
+ if ((p_t1t->hr[0] & 0xF0) == T1T_NDEF_SUPPORTED)
+ flags |= RW_NDEF_FL_SUPPORTED;
+
+ if (t1t_tag_init_data (p_t1t->hr[0]) != NULL)
+ flags |= RW_NDEF_FL_FORMATABLE;
+
+ if ((p_t1t->mem[T1T_CC_RWA_BYTE] & 0x0F) == T1T_CC_RWA_RO)
+ flags |=RW_NDEF_FL_READ_ONLY;
+
+ return flags;
+}
+
+/*******************************************************************************
+**
+** Function rw_t1t_get_ndef_max_size
+**
+** Description Calculate maximum size of NDEF message that can be written
+** on to the tag
+**
+** Returns Maximum size of NDEF Message
+**
+*******************************************************************************/
+static UINT16 rw_t1t_get_ndef_max_size (void)
+{
+ UINT16 offset;
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ UINT16 tag_size = (p_t1t->mem[T1T_CC_TMS_BYTE] +1)* T1T_BLOCK_SIZE;
+ const tT1T_INIT_TAG *p_ret;
+ UINT8 init_segment = p_t1t->segment;
+
+ p_t1t->max_ndef_msg_len = 0;
+ offset = p_t1t->ndef_msg_offset;
+ p_t1t->segment = (UINT8) (p_t1t->ndef_msg_offset/T1T_SEGMENT_SIZE);
+
+ if ( (tag_size < T1T_STATIC_SIZE)
+ ||(tag_size > (T1T_SEGMENT_SIZE * T1T_MAX_SEGMENTS))
+ ||((p_t1t->mem[T1T_CC_NMN_BYTE] != T1T_CC_NMN) && (p_t1t->mem[T1T_CC_NMN_BYTE] != 0)) )
+ {
+ /* Tag not formated, determine maximum NDEF size from HR */
+ if ( ((p_t1t->hr[0] & 0xF0) == T1T_NDEF_SUPPORTED)
+ &&((p_ret = t1t_tag_init_data (p_t1t->hr[0])) != NULL) )
+ {
+ p_t1t->max_ndef_msg_len = ((p_ret->tms +1)* T1T_BLOCK_SIZE) - T1T_OTP_LOCK_RES_BYTES - T1T_UID_LEN - T1T_ADD_LEN - T1T_CC_LEN - T1T_TLV_TYPE_LEN - T1T_SHORT_NDEF_LEN_FIELD_LEN;
+ if (p_ret->b_dynamic)
+ {
+ p_t1t->max_ndef_msg_len -= (T1T_TLV_TYPE_LEN + T1T_DEFAULT_TLV_LEN_FIELD_LEN + T1T_DEFAULT_TLV_LEN + T1T_TLV_TYPE_LEN + T1T_DEFAULT_TLV_LEN_FIELD_LEN + T1T_DEFAULT_TLV_LEN);
+ p_t1t->max_ndef_msg_len -= T1T_DYNAMIC_LOCK_BYTES;
+ }
+ offset = tag_size;
+ }
+ else
+ {
+ p_t1t->segment = init_segment;
+ return p_t1t->max_ndef_msg_len;
+ }
+ }
+
+ /* Starting from NDEF Message offset find the first locked data byte */
+ while (offset < tag_size)
+ {
+ if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) (offset)) == FALSE)
+ {
+ if (rw_t1t_is_read_only_byte ((UINT16) offset) == TRUE)
+ break;
+ p_t1t->max_ndef_msg_len++;
+ }
+ offset++;
+ if (offset % T1T_SEGMENT_SIZE == 0)
+ {
+ p_t1t->segment = (UINT8) (offset / T1T_SEGMENT_SIZE);
+ }
+ }
+ /* NDEF Length field length changes based on NDEF size */
+ if ( (p_t1t->max_ndef_msg_len >= T1T_LONG_NDEF_LEN_FIELD_BYTE0)
+ &&((p_t1t->ndef_msg_offset - p_t1t->ndef_header_offset) == T1T_SHORT_NDEF_LEN_FIELD_LEN) )
+ {
+ p_t1t->max_ndef_msg_len -= (p_t1t->max_ndef_msg_len == T1T_LONG_NDEF_LEN_FIELD_BYTE0)? 1 : (T1T_LONG_NDEF_LEN_FIELD_LEN - T1T_SHORT_NDEF_LEN_FIELD_LEN);
+ }
+
+ p_t1t->segment = init_segment;
+ return p_t1t->max_ndef_msg_len;
+}
+
+/*******************************************************************************
+**
+** Function rw_t1t_handle_ndef_write_rsp
+**
+** Description Handle response to commands sent while writing an
+** NDEF message
+**
+** Returns NFC_STATUS_CONTINUE, if tlv write is not yet complete
+** NFC_STATUS_OK, if tlv write is complete & success
+** NFC_STATUS_FAILED,if tlv write failed
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_handle_ndef_write_rsp (UINT8 *p_data)
+{
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
+ UINT8 addr;
+
+ switch (p_t1t->substate)
+ {
+ case RW_T1T_SUBSTATE_WAIT_READ_NDEF_BLOCK:
+ /* Backup ndef_final_block */
+ memcpy (p_t1t->ndef_final_block, p_data, T1T_BLOCK_SIZE);
+ /* Invalidate existing NDEF Message */
+ RW_T1T_BLD_ADD ((addr), (T1T_CC_BLOCK), (T1T_CC_NMN_OFFSET));
+ if (NFC_STATUS_OK == rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, 0))
+ {
+ ndef_status = NFC_STATUS_CONTINUE;
+ p_t1t->state = RW_T1T_STATE_WRITE_NDEF;
+ p_t1t->substate = RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF;
+ }
+ else
+ {
+ ndef_status = NFC_STATUS_FAILED;
+ }
+ break;
+
+ case RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF:
+ ndef_status = rw_t1t_ndef_write_first_block ();
+ break;
+
+ case RW_T1T_SUBSTATE_WAIT_NDEF_WRITE:
+ ndef_status = rw_t1t_next_ndef_write_block ();
+ break;
+
+ case RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED:
+ /* Validate new NDEF Message */
+ RW_T1T_BLD_ADD ((addr), (T1T_CC_BLOCK), (T1T_CC_NMN_OFFSET));
+ if (NFC_STATUS_OK == rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, T1T_CC_NMN))
+ {
+ ndef_status = NFC_STATUS_OK;
+ }
+ else
+ {
+ ndef_status = NFC_STATUS_FAILED;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return ndef_status;
+}
+
+/*******************************************************************************
+**
+** Function rw_t1t_update_attributes
+**
+** Description This function will prepare attributes for the current
+** segment. Every bit in the attribute refers to one byte of
+** tag content.The bit corresponding to a tag byte will be set
+** to '1' when the Tag byte is read only,otherwise will be set
+** to '0'
+**
+** Returns None
+**
+*******************************************************************************/
+static void rw_t1t_update_attributes (void)
+{
+ UINT8 count = 0;
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ UINT16 lower_offset;
+ UINT16 upper_offset;
+ UINT8 num_bytes;
+ UINT16 offset;
+ UINT8 bits_per_byte = 8;
+
+ count = 0;
+ while (count < T1T_BLOCKS_PER_SEGMENT)
+ {
+ p_t1t->attr[count] = 0x00;
+ count++;
+ }
+
+ lower_offset = p_t1t->segment * T1T_SEGMENT_SIZE;
+ upper_offset = (p_t1t->segment + 1)* T1T_SEGMENT_SIZE;
+
+ if (p_t1t->segment == 0)
+ {
+ /* UID/Lock/Reserved/OTP bytes */
+ p_t1t->attr[0x00] = 0xFF; /* Uid bytes */
+ p_t1t->attr[0x0D] = 0xFF; /* Reserved bytes */
+ p_t1t->attr[0x0E] = 0xFF; /* lock/otp bytes */
+ p_t1t->attr[0x0F] = 0xFF; /* lock/otp bytes */
+ }
+
+ /* update attr based on lock control and mem control tlvs */
+ count = 0;
+ while (count < p_t1t->num_lockbytes)
+ {
+ offset = p_t1t->lock_tlv[p_t1t->lockbyte[count].tlv_index].offset + p_t1t->lockbyte[count].byte_index;
+ if (offset >= lower_offset && offset < upper_offset)
+ {
+ /* Set the corresponding bit in attr to indicate - lock byte */
+ p_t1t->attr[(offset % T1T_SEGMENT_SIZE) / bits_per_byte] |= rw_t1t_mask_bits[(offset % T1T_SEGMENT_SIZE) % bits_per_byte];
+ }
+ count++;
+ }
+ count = 0;
+ while (count < p_t1t->num_mem_tlvs)
+ {
+ num_bytes = 0;
+ while (num_bytes < p_t1t->mem_tlv[count].num_bytes)
+ {
+ offset = p_t1t->mem_tlv[count].offset + num_bytes;
+ if (offset >= lower_offset && offset < upper_offset)
+ {
+ /* Set the corresponding bit in attr to indicate - reserved byte */
+ p_t1t->attr[(offset % T1T_SEGMENT_SIZE) / bits_per_byte] |= rw_t1t_mask_bits[(offset % T1T_SEGMENT_SIZE) % bits_per_byte];
+ }
+ num_bytes++;
+ }
+ count++;
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_t1t_get_lock_bits_for_segment
+**
+** Description This function will identify the index of the dynamic lock
+** byte that covers the current segment
+**
+** Parameters: segment, segment number
+** p_start_byte, pointer to hold the first lock byte index
+** p_start_bit, pointer to hold the first lock bit index
+** p_end_byte, pointer to hold the last lock byte index
+**
+** Returns Total lock bits that covers the specified segment
+**
+*******************************************************************************/
+static UINT8 rw_t1t_get_lock_bits_for_segment (UINT8 segment,UINT8 *p_start_byte, UINT8 *p_start_bit,UINT8 *p_end_byte)
+{
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ UINT16 byte_count = T1T_SEGMENT_SIZE;
+ UINT8 total_bits = 0;
+ UINT8 num_dynamic_locks = 0;
+ UINT8 bit_count = 0;
+ UINT16 tag_size = (p_t1t->mem[T1T_CC_TMS_BYTE] +1) * T1T_BLOCK_SIZE;
+ UINT16 lower_offset;
+ UINT16 upper_offset;
+ BOOLEAN b_all_bits_are_locks = TRUE;
+ UINT8 bytes_locked_per_bit;
+ UINT8 num_bits;
+
+ upper_offset = (segment + 1) * T1T_SEGMENT_SIZE;
+
+ if (upper_offset > tag_size)
+ upper_offset = tag_size;
+
+ lower_offset = segment * T1T_SEGMENT_SIZE;
+ *p_start_byte = num_dynamic_locks;
+ *p_start_bit = 0;
+
+ while ( (byte_count <= lower_offset)
+ &&(num_dynamic_locks < p_t1t->num_lockbytes) )
+ {
+ bytes_locked_per_bit = p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].bytes_locked_per_bit;
+ /* Number of bits in the current lock byte */
+ b_all_bits_are_locks = ((p_t1t->lockbyte[num_dynamic_locks].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].num_bits);
+ num_bits = b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].num_bits % TAG_BITS_PER_BYTE;
+
+ /* Skip lock bits that covers all previous segments */
+ if (bytes_locked_per_bit * num_bits + byte_count <= lower_offset)
+ {
+ byte_count += bytes_locked_per_bit * num_bits;
+ num_dynamic_locks++;
+ }
+ else
+ {
+ /* The first lock bit that covers this segment is present in this segment */
+ bit_count = 0;
+ while (bit_count < num_bits)
+ {
+ byte_count += bytes_locked_per_bit;
+ if (byte_count > lower_offset)
+ {
+ *p_start_byte = num_dynamic_locks;
+ *p_end_byte = num_dynamic_locks;
+ *p_start_bit = bit_count;
+ bit_count++;
+ total_bits = 1;
+ break;
+ }
+ bit_count++;
+ }
+ }
+ }
+ if (num_dynamic_locks == p_t1t->num_lockbytes)
+ {
+ return 0;
+ }
+ while ( (byte_count < upper_offset)
+ &&(num_dynamic_locks < p_t1t->num_lockbytes) )
+ {
+ bytes_locked_per_bit = p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].bytes_locked_per_bit;
+
+ /* Number of bits in the current lock byte */
+ b_all_bits_are_locks = ((p_t1t->lockbyte[num_dynamic_locks].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].num_bits);
+ num_bits = b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].num_bits % TAG_BITS_PER_BYTE;
+
+ /* Collect all lock bits that covers the current segment */
+ if ((bytes_locked_per_bit * (num_bits - bit_count)) + byte_count < upper_offset)
+ {
+ byte_count += bytes_locked_per_bit * (num_bits - bit_count);
+ total_bits += num_bits - bit_count;
+ bit_count = 0;
+ *p_end_byte = num_dynamic_locks;
+ num_dynamic_locks++;
+ }
+ else
+ {
+ /* The last lock byte that covers the current segment */
+ bit_count = 0;
+ while (bit_count < num_bits)
+ {
+ byte_count += bytes_locked_per_bit;
+ if (byte_count >= upper_offset)
+ {
+ *p_end_byte = num_dynamic_locks;
+ total_bits += (bit_count + 1);
+ break;
+ }
+ bit_count++;
+ }
+ }
+ }
+ return total_bits;
+}
+
+/*******************************************************************************
+**
+** Function rw_t1t_update_lock_attributes
+**
+** Description This function will check if the tag index passed as
+** argument is a locked byte and return
+** TRUE or FALSE
+**
+** Parameters: index, the index of the byte in the tag
+**
+**
+** Returns TRUE, if the specified index in the tag is a locked or
+** reserved or otp byte
+** FALSE, otherwise
+**
+*******************************************************************************/
+static void rw_t1t_update_lock_attributes (void)
+{
+ UINT8 xx = 0;
+ UINT8 bytes_locked_per_lock_bit;
+ UINT8 num_static_lock_bytes = 0;
+ UINT8 num_dynamic_lock_bytes = 0;
+ UINT8 bits_covered = 0;
+ UINT8 bytes_covered = 0;
+ UINT8 block_count = 0;
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ UINT8 start_lock_byte;
+ UINT8 start_lock_bit;
+ UINT8 end_lock_byte;
+ UINT8 num_lock_bits;
+ UINT8 total_bits;
+
+
+ block_count = 0;
+ while (block_count < T1T_BLOCKS_PER_SEGMENT)
+ {
+ p_t1t->lock_attr[block_count] = 0x00;
+ block_count++;
+ }
+
+ /* update lock_attr based on static lock bytes */
+ if (p_t1t->segment == 0)
+ {
+ xx = 0;
+ num_static_lock_bytes = 0;
+ block_count = 0;
+ num_lock_bits = 8;
+
+ while (num_static_lock_bytes < T1T_NUM_STATIC_LOCK_BYTES)
+ {
+ /* Update lock attribute based on 2 static locks */
+ while (xx < num_lock_bits)
+ {
+ p_t1t->lock_attr[block_count] = 0x00;
+
+ if (p_t1t->mem[T1T_LOCK_0_OFFSET + num_static_lock_bytes] & rw_t1t_mask_bits[xx++])
+ {
+ /* If the bit is set then 1 block is locked */
+ p_t1t->lock_attr[block_count] = 0xFF;
+ }
+
+ block_count++;
+ }
+ num_static_lock_bytes++;
+ xx = 0;
+ }
+ /* Locked bytes */
+ p_t1t->lock_attr[0x00] = 0xFF;
+ p_t1t->lock_attr[0x0D] = 0xFF;
+ }
+ else
+ {
+ /* update lock_attr based on segment and using dynamic lock bytes */
+ if ((total_bits = rw_t1t_get_lock_bits_for_segment (p_t1t->segment,&start_lock_byte, &start_lock_bit,&end_lock_byte)) != 0)
+ {
+ xx = start_lock_bit;
+ num_dynamic_lock_bytes = start_lock_byte;
+ bits_covered = 0;
+ bytes_covered = 0;
+ block_count = 0;
+ num_lock_bits = 8;
+
+ p_t1t->lock_attr[block_count] = 0;
+
+ while (num_dynamic_lock_bytes <= end_lock_byte)
+ {
+ bytes_locked_per_lock_bit = p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_lock_bytes].tlv_index].bytes_locked_per_bit;
+ if (num_dynamic_lock_bytes == end_lock_byte)
+ {
+ num_lock_bits = (total_bits % 8 == 0)? 8:total_bits % 8;
+ }
+ while (xx < num_lock_bits)
+ {
+ bytes_covered = 0;
+ while (bytes_covered < bytes_locked_per_lock_bit)
+ {
+ /* Set/clear lock_attr byte bits based on whether a particular lock bit is set or not
+ * each bit in lock_attr represents one byte in Tag read only attribute */
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ if ((p_t1t->lockbyte[num_dynamic_lock_bytes].lock_byte & rw_t1t_mask_bits[xx]) && (block_count < T1T_BLOCKS_PER_SEGMENT))
+#else
+ if (p_t1t->lockbyte[num_dynamic_lock_bytes].lock_byte & rw_t1t_mask_bits[xx])
+#endif
+ {
+ p_t1t->lock_attr[block_count] |= 0x01 << bits_covered;
+ }
+ bytes_covered++;
+ bits_covered++;
+ if (bits_covered == 8)
+ {
+ bits_covered = 0;
+ block_count++;
+ if (block_count < T1T_BLOCKS_PER_SEGMENT)
+ p_t1t->lock_attr[block_count] = 0;
+ }
+ }
+ xx++;
+ }
+ num_dynamic_lock_bytes++;
+ xx = 0;
+ }
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_t1t_is_lock_reserved_otp_byte
+**
+** Description This function will check if the tag index passed as
+** argument is a lock or reserved or otp byte
+**
+** Parameters: index, the index of the byte in the tag's current segment
+**
+**
+** Returns TRUE, if the specified index in the tag is a locked or
+** reserved or otp byte
+** FALSE, otherwise
+**
+*******************************************************************************/
+static BOOLEAN rw_t1t_is_lock_reserved_otp_byte (UINT16 index)
+{
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+
+ if (p_t1t->attr_seg != p_t1t->segment)
+ {
+ /* Update p_t1t->attr to reflect the current segment */
+ rw_t1t_update_attributes ();
+ p_t1t->attr_seg = p_t1t->segment;
+ }
+ index = index % T1T_SEGMENT_SIZE;
+
+ /* Every bit in p_t1t->attr indicates one specific byte of the tag is either a lock/reserved/otp byte or not
+ * So, each array element in p_t1t->attr covers one block in the tag as T1 block size and array element size is 8
+ * Find the block and offset for the index (passed as argument) and Check if the offset bit in the
+ * p_t1t->attr[block] is set or not. If the bit is set then it is a lock/reserved/otp byte, otherwise not */
+
+ return ((p_t1t->attr[index /8] & rw_t1t_mask_bits[index % 8]) == 0) ? FALSE:TRUE;
+}
+
+/*******************************************************************************
+**
+** Function rw_t1t_is_read_only_byte
+**
+** Description This function will check if the tag index passed as
+** argument is a read only byte
+**
+** Parameters: index, the index of the byte in the tag's current segment
+**
+**
+** Returns TRUE, if the specified index in the tag is a locked or
+** reserved or otp byte
+** FALSE, otherwise
+**
+*******************************************************************************/
+static BOOLEAN rw_t1t_is_read_only_byte (UINT16 index)
+{
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+
+ if (p_t1t->lock_attr_seg != p_t1t->segment)
+ {
+ /* Update p_t1t->lock_attr to reflect the current segment */
+ rw_t1t_update_lock_attributes ();
+ p_t1t->lock_attr_seg = p_t1t->segment;
+ }
+
+ index = index % T1T_SEGMENT_SIZE;
+ /* Every bit in p_t1t->lock_attr indicates one specific byte of the tag is a read only byte or read write byte
+ * So, each array element in p_t1t->lock_attr covers one block in the tag as T1 block size and array element size is 8
+ * Find the block and offset for the index (passed as argument) and Check if the offset bit in the
+ * p_t1t->lock_attr[block] is set or not. If the bit is set then it is a read only byte, otherwise read write byte */
+
+ return ((p_t1t->lock_attr[index /8] & rw_t1t_mask_bits[index % 8]) == 0) ? FALSE:TRUE;
+}
+
+/*****************************************************************************
+**
+** Function RW_T1tFormatNDef
+**
+** Description
+** Format Tag content
+**
+** Returns
+** NFC_STATUS_OK, Command sent to format Tag
+** NFC_STATUS_REJECTED: Invalid HR0 and cannot format the tag
+** NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T1tFormatNDef (void)
+{
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ const tT1T_INIT_TAG *p_ret;
+ UINT8 addr;
+ UINT8 *p;
+
+ if (p_t1t->state != RW_T1T_STATE_IDLE)
+ {
+ RW_TRACE_WARNING1 ("RW_T1tFormatNDef - Tag not initialized/ Busy! State: %u", p_t1t->state);
+ return (NFC_STATUS_FAILED);
+ }
+
+ if ((p_t1t->hr[0] & 0xF0) != T1T_NDEF_SUPPORTED)
+ {
+ RW_TRACE_WARNING1 ("RW_T1tFormatNDef - Cannot format tag as NDEF not supported. HR0: %u", p_t1t->hr[0]);
+ return (NFC_STATUS_REJECTED);
+ }
+
+ if ((p_ret = t1t_tag_init_data (p_t1t->hr[0])) == NULL)
+ {
+ RW_TRACE_WARNING2 ("RW_T1tFormatNDef - Invalid HR - HR0: %u, HR1: %u", p_t1t->hr[0], p_t1t->hr[1]);
+ return (NFC_STATUS_REJECTED);
+ }
+
+ memset (p_t1t->ndef_first_block, 0, T1T_BLOCK_SIZE);
+ memset (p_t1t->ndef_final_block, 0, T1T_BLOCK_SIZE);
+ p = p_t1t->ndef_first_block;
+
+ /* Prepare Capability Container */
+ UINT8_TO_BE_STREAM (p, T1T_CC_NMN);
+ UINT8_TO_BE_STREAM (p, T1T_CC_VNO);
+ UINT8_TO_BE_STREAM (p, p_ret->tms);
+ UINT8_TO_BE_STREAM (p, T1T_CC_RWA_RW);
+ if (p_ret->b_dynamic)
+ {
+ /* Prepare Lock and Memory TLV */
+ UINT8_TO_BE_STREAM (p, TAG_LOCK_CTRL_TLV);
+ UINT8_TO_BE_STREAM (p, T1T_DEFAULT_TLV_LEN);
+ UINT8_TO_BE_STREAM (p, p_ret->lock_tlv[0]);
+ UINT8_TO_BE_STREAM (p, p_ret->lock_tlv[1]);
+ p = p_t1t->ndef_final_block;
+ UINT8_TO_BE_STREAM (p, p_ret->lock_tlv[2]);
+ UINT8_TO_BE_STREAM (p, TAG_MEM_CTRL_TLV);
+ UINT8_TO_BE_STREAM (p, T1T_DEFAULT_TLV_LEN);
+ UINT8_TO_BE_STREAM (p, p_ret->mem_tlv[0]);
+ UINT8_TO_BE_STREAM (p, p_ret->mem_tlv[1]);
+ UINT8_TO_BE_STREAM (p, p_ret->mem_tlv[2]);
+ }
+ /* Prepare NULL NDEF TLV */
+ UINT8_TO_BE_STREAM (p, TAG_NDEF_TLV);
+ UINT8_TO_BE_STREAM (p, 0);
+
+ if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 || rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN)
+ {
+ /* send WRITE-E8 command */
+ if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_E8, 1, p_t1t->ndef_first_block)) == NFC_STATUS_OK)
+ {
+ p_t1t->state = RW_T1T_STATE_FORMAT_TAG;
+ p_t1t->b_update = FALSE;
+ p_t1t->b_rseg = FALSE;
+ if (p_ret->b_dynamic)
+ p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_CC;
+ else
+ p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF;
+ }
+ }
+ else
+ {
+ /* send WRITE-E command */
+ RW_T1T_BLD_ADD ((addr), 1, 0);
+
+ if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, p_t1t->ndef_first_block[0])) == NFC_STATUS_OK)
+ {
+ p_t1t->work_offset = 0;
+ p_t1t->state = RW_T1T_STATE_FORMAT_TAG;
+ p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF;
+ p_t1t->b_update = FALSE;
+ p_t1t->b_rseg = FALSE;
+ }
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function RW_T1tLocateTlv
+**
+** Description This function is called to find the start of the given TLV
+**
+** Parameters: tlv_type, Type of TLV to find
+**
+** Returns NCI_STATUS_OK, if detection was started. Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tLocateTlv (UINT8 tlv_type)
+{
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ tRW_T1T_CB *p_t1t= &rw_cb.tcb.t1t;
+ UINT8 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 *p_buffer, UINT16 buf_len)
+{
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ BOOLEAN b_notify;
+ UINT8 adds;
+ const tT1T_CMD_RSP_INFO *p_cmd_rsp_info_rall = t1t_cmd_to_rsp_info (T1T_CMD_RALL);
+ const tT1T_CMD_RSP_INFO *p_cmd_rsp_info_rseg = t1t_cmd_to_rsp_info (T1T_CMD_RSEG);
+
+
+
+ if (p_t1t->state != RW_T1T_STATE_IDLE)
+ {
+ RW_TRACE_WARNING1 ("RW_T1tReadNDef - Busy - State: %u", p_t1t->state);
+ return (NFC_STATUS_FAILED);
+ }
+
+ /* Check HR0 if NDEF supported by the tag */
+ if (((p_t1t->hr[0]) & 0xF0) != T1T_NDEF_SUPPORTED)
+ {
+ RW_TRACE_ERROR0 ("RW_T1tReadNDef - Error: NDEF not supported by the tag");
+ return (NFC_STATUS_REFUSED);
+ }
+
+ if (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_INITIALIZED_NDEF)
+ {
+ RW_TRACE_WARNING1 ("RW_T1tReadNDef - NDEF Message length is zero, NDEF Length : %u ", p_t1t->ndef_msg_len);
+ return (NFC_STATUS_NOT_INITIALIZED);
+ }
+
+ if ( (p_t1t->tag_attribute != RW_T1_TAG_ATTRB_READ_WRITE)
+ &&(p_t1t->tag_attribute != RW_T1_TAG_ATTRB_READ_ONLY) )
+ {
+ RW_TRACE_ERROR0 ("RW_T1tReadNDef - Error: NDEF detection not performed yet/ Tag is in Initialized state");
+ return (NFC_STATUS_FAILED);
+ }
+
+ if (buf_len < p_t1t->ndef_msg_len)
+ {
+ RW_TRACE_WARNING2 ("RW_T1tReadNDef - buffer size: %u less than NDEF msg sise: %u", buf_len, p_t1t->ndef_msg_len);
+ return (NFC_STATUS_FAILED);
+ }
+ p_t1t->p_ndef_buffer = p_buffer;
+
+ if (p_t1t->b_rseg == TRUE)
+ {
+ /* If already got response to RSEG 0 */
+ p_t1t->state = RW_T1T_STATE_READ_NDEF;
+ p_t1t->p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *)p_cmd_rsp_info_rseg;
+
+ rw_t1t_handle_read_rsp (&b_notify,p_t1t->mem);
+ status = NFC_STATUS_OK;
+ }
+ else if (p_t1t->b_update == TRUE)
+ {
+ /* If already got response to RALL */
+ p_t1t->state = RW_T1T_STATE_READ_NDEF;
+ p_t1t->p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *) p_cmd_rsp_info_rall;
+
+ rw_t1t_handle_read_rsp (&b_notify,p_t1t->mem);
+ status = NFC_STATUS_OK;
+
+ }
+ else
+ {
+ p_t1t->segment = 0;
+ p_t1t->work_offset = 0;
+ if ((p_t1t->hr[0] & 0x0F) != 1)
+ {
+ /* send RSEG command */
+ RW_T1T_BLD_ADDS ((adds), (p_t1t->segment));
+ status = rw_t1t_send_dyn_cmd (T1T_CMD_RSEG, adds, NULL);
+ }
+ else
+ {
+ status = rw_t1t_send_static_cmd (T1T_CMD_RALL, 0, 0);
+ }
+ if (status == NFC_STATUS_OK)
+ p_t1t->state = RW_T1T_STATE_READ_NDEF;
+
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function RW_T1tWriteNDef
+**
+** Description This function can be called to write an NDEF message to the tag.
+**
+** Parameters: msg_len: The length of the buffer
+** p_msg: The NDEF message to write
+**
+** Returns NCI_STATUS_OK, if write was started. Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tWriteNDef (UINT16 msg_len, UINT8 *p_msg)
+{
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ UINT16 num_ndef_bytes;
+ UINT16 offset;
+ UINT8 addr;
+ UINT8 init_lengthfield_len;
+ UINT8 new_lengthfield_len;
+ UINT16 init_ndef_msg_offset;
+
+ if (p_t1t->state != RW_T1T_STATE_IDLE)
+ {
+ RW_TRACE_WARNING1 ("RW_T1tWriteNDef - Busy - State: %u", p_t1t->state);
+ return (NFC_STATUS_FAILED);
+ }
+
+ /* Check HR0 if NDEF supported by the tag */
+ if (((p_t1t->hr[0]) & 0xF0) != T1T_NDEF_SUPPORTED)
+ {
+ RW_TRACE_ERROR0 ("RW_T1tWriteNDef - Error: NDEF not supported by the tag");
+ return (NFC_STATUS_REFUSED);
+ }
+
+ if ( (p_t1t->tag_attribute != RW_T1_TAG_ATTRB_READ_WRITE)
+ &&(p_t1t->tag_attribute != RW_T1_TAG_ATTRB_INITIALIZED_NDEF) )
+ {
+ RW_TRACE_ERROR0 ("RW_T1tWriteNDef - Tag cannot update NDEF");
+ return (NFC_STATUS_REFUSED);
+ }
+
+ if (msg_len > p_t1t->max_ndef_msg_len)
+ {
+ RW_TRACE_ERROR1 ("RW_T1tWriteNDef - Cannot write NDEF of size greater than %u bytes", p_t1t->max_ndef_msg_len);
+ return (NFC_STATUS_REFUSED);
+ }
+
+ p_t1t->p_ndef_buffer = p_msg;
+ p_t1t->new_ndef_msg_len = msg_len;
+ new_lengthfield_len = p_t1t->new_ndef_msg_len > 254 ? 3:1;
+ init_lengthfield_len = (UINT8) (p_t1t->ndef_msg_offset - p_t1t->ndef_header_offset);
+ init_ndef_msg_offset = p_t1t->ndef_msg_offset;
+
+ /* ndef_msg_offset should reflect the new ndef message offset */
+ if (init_lengthfield_len > new_lengthfield_len)
+ {
+ p_t1t->ndef_msg_offset = init_ndef_msg_offset - (T1T_LONG_NDEF_LEN_FIELD_LEN - T1T_SHORT_NDEF_LEN_FIELD_LEN);
+ }
+ else if (init_lengthfield_len < new_lengthfield_len)
+ {
+ p_t1t->ndef_msg_offset = init_ndef_msg_offset + (T1T_LONG_NDEF_LEN_FIELD_LEN - T1T_SHORT_NDEF_LEN_FIELD_LEN);
+ }
+
+ num_ndef_bytes = 0;
+ offset = p_t1t->ndef_msg_offset;
+ p_t1t->segment = (UINT8) (p_t1t->ndef_msg_offset/T1T_SEGMENT_SIZE);
+
+ /* Locate NDEF final block based on the size of new NDEF Message */
+ while (num_ndef_bytes < p_t1t->new_ndef_msg_len)
+ {
+ if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) offset) == FALSE)
+ num_ndef_bytes++;
+
+ offset++;
+ if (offset % T1T_SEGMENT_SIZE == 0)
+ {
+ p_t1t->segment = (UINT8) (offset / T1T_SEGMENT_SIZE);
+ }
+ }
+
+ p_t1t->b_update = FALSE;
+ p_t1t->b_rseg = FALSE;
+
+ if ((p_t1t->hr[0] & 0x0F) != 1)
+ {
+ /* Dynamic data structure */
+ p_t1t->block_read = (UINT8) ((offset - 1)/T1T_BLOCK_SIZE);
+ /* Read NDEF final block before updating */
+ if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_READ8, p_t1t->block_read, NULL)) == 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));
+ if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, 0)) == NFC_STATUS_OK)
+ {
+ p_t1t->state = RW_T1T_STATE_WRITE_NDEF;
+ p_t1t->substate = RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF;
+ }
+
+ }
+
+ if (status != NFC_STATUS_OK)
+ {
+ /* if status failed, reset ndef_msg_offset to initial message */
+ p_t1t->ndef_msg_offset = init_ndef_msg_offset;
+ }
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function RW_T1tSetTagReadOnly
+**
+** Description This function can be called to set t1 tag as read only.
+**
+** Parameters: None
+**
+** Returns NCI_STATUS_OK, if setting tag as read only was started.
+** Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tSetTagReadOnly (BOOLEAN b_hard_lock)
+{
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t;
+ UINT8 addr;
+ UINT8 num_locks;
+
+ if (p_t1t->state != RW_T1T_STATE_IDLE)
+ {
+ RW_TRACE_WARNING1 ("RW_T1tSetTagReadOnly - Busy - State: %u", p_t1t->state);
+ return (NFC_STATUS_BUSY);
+ }
+
+ p_t1t->b_hard_lock = b_hard_lock;
+
+ if ( (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_WRITE)
+ ||(p_t1t->tag_attribute == RW_T1_TAG_ATTRB_INITIALIZED)
+ ||(p_t1t->tag_attribute == RW_T1_TAG_ATTRB_INITIALIZED_NDEF) )
+ {
+ /* send WRITE-NE command */
+ RW_T1T_BLD_ADD ((addr), (T1T_CC_BLOCK), (T1T_CC_RWA_OFFSET));
+ if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_NE, addr, 0x0F)) == NFC_STATUS_OK)
+ {
+ p_t1t->b_update = FALSE;
+ p_t1t->b_rseg = FALSE;
+
+ if (p_t1t->b_hard_lock)
+ {
+ num_locks = 0;
+ while (num_locks < p_t1t->num_lockbytes)
+ {
+ p_t1t->lockbyte[num_locks].lock_status = RW_T1T_LOCK_NOT_UPDATED;
+ num_locks++;
+ }
+ }
+ p_t1t->state = RW_T1T_STATE_SET_TAG_RO;
+ p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_CC_RWA_RO;
+ }
+ }
+
+ return status;
+}
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function rw_t1t_get_sub_state_name
+**
+** Description This function returns the sub_state name.
+**
+** NOTE conditionally compiled to save memory.
+**
+** Returns pointer to the name
+**
+*******************************************************************************/
+static char *rw_t1t_get_sub_state_name (UINT8 sub_state)
+{
+ switch (sub_state)
+ {
+ case RW_T1T_SUBSTATE_NONE:
+ return ("NONE");
+ case RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE:
+ return ("EXTRACT_TLV_VALUE");
+ case RW_T1T_SUBSTATE_WAIT_READ_LOCKS:
+ return ("READING_LOCKS");
+ case RW_T1T_SUBSTATE_WAIT_READ_NDEF_BLOCK:
+ return ("READ_NDEF_FINAL_BLOCK");
+ case RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF:
+ return ("INVALIDATING_NDEF");
+ case RW_T1T_SUBSTATE_WAIT_NDEF_WRITE:
+ return ("WRITE_NDEF_TLV_MESSAGE");
+ case RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED:
+ return ("WAITING_RSP_FOR_LAST_NDEF_WRITE");
+ case RW_T1T_SUBSTATE_WAIT_VALIDATE_NDEF:
+ return ("VALIDATING_NDEF");
+ case RW_T1T_SUBSTATE_WAIT_SET_CC_RWA_RO:
+ return ("SET_RWA_RO");
+ case RW_T1T_SUBSTATE_WAIT_SET_ST_LOCK_BITS:
+ return ("SET_STATIC_LOCK_BITS");
+ case RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS:
+ return ("SET_DYNAMIC_LOCK_BITS");
+
+ default:
+ return ("???? UNKNOWN SUBSTATE");
+ }
+}
+#endif /* (BT_TRACE_VERBOSE == TRUE) */
+
+#endif /* (defined ((RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE)) */
+
+#endif /* (NFC_INCLUDED == TRUE) */
diff --git a/src/nfc/tags/rw_t2t.c b/src/nfc/tags/rw_t2t.c
new file mode 100644
index 0000000..1d17034
--- /dev/null
+++ b/src/nfc/tags/rw_t2t.c
@@ -0,0 +1,1222 @@
+/******************************************************************************
+ *
+ * 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"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_api.h"
+#include "nci_hmsgs.h"
+#include "rw_api.h"
+#include "rw_int.h"
+#include "nfc_int.h"
+#include "gki.h"
+
+/* Static local functions */
+static void rw_t2t_proc_data (UINT8 conn_id, tNFC_DATA_CEVT *p_data);
+static tNFC_STATUS rw_t2t_send_cmd (UINT8 opcode, UINT8 *p_dat);
+static void rw_t2t_process_error (void);
+static void rw_t2t_process_frame_error (void);
+static void rw_t2t_handle_presence_check_rsp (tNFC_STATUS status);
+static void rw_t2t_resume_op (void);
+
+#if (BT_TRACE_VERBOSE == TRUE)
+static char *rw_t2t_get_state_name (UINT8 state);
+static char *rw_t2t_get_substate_name (UINT8 substate);
+#endif
+
+/*******************************************************************************
+**
+** Function rw_t2t_proc_data
+**
+** Description This function handles data evt received from NFC Controller.
+**
+** Returns none
+**
+*******************************************************************************/
+static void rw_t2t_proc_data (UINT8 conn_id, tNFC_DATA_CEVT *p_data)
+{
+ tRW_EVENT rw_event = RW_RAW_FRAME_EVT;
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ BT_HDR *p_pkt = p_data->p_data;
+ BOOLEAN b_notify = TRUE;
+ BOOLEAN b_release = TRUE;
+ UINT8 *p;
+ tRW_READ_DATA evt_data = {0};
+ tT2T_CMD_RSP_INFO *p_cmd_rsp_info = (tT2T_CMD_RSP_INFO *) rw_cb.tcb.t2t.p_cmd_rsp_info;
+ tRW_DETECT_NDEF_DATA ndef_data;
+#if (BT_TRACE_VERBOSE == TRUE)
+ UINT8 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, (tRW_DATA *)&evt_data);
+ return;
+ }
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+ /* Update rx stats */
+ rw_main_update_rx_stats (p_pkt->len);
+#endif
+ /* Stop timer as response is received */
+ nfc_stop_quick_timer (&p_t2t->t2_timer);
+
+ RW_TRACE_EVENT2 ("RW RECV [%s]:0x%x RSP", t2t_info_to_str (p_cmd_rsp_info), p_cmd_rsp_info->opcode);
+
+ if ( ( (p_pkt->len != p_cmd_rsp_info->rsp_len)
+ &&(p_pkt->len != p_cmd_rsp_info->nack_rsp_len)
+ &&(p_t2t->substate != RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR) )
+ ||(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 *) (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(NFC_NXP_NOT_OPEN_INCLUDED == 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, (tRW_DATA *) &ndef_data);
+ }
+ else
+ {
+ /* Move back to idle state */
+ rw_t2t_handle_op_complete ();
+ (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &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 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ tRW_READ_DATA evt_data;
+
+ RW_TRACE_DEBUG2 ("rw_t2t_conn_cback: conn_id=%i, evt=%i", conn_id, event);
+ /* Only handle static conn_id */
+ if (conn_id != NFC_RF_CONN_ID)
+ {
+ return;
+ }
+
+ switch (event)
+ {
+ case NFC_CONN_CREATE_CEVT:
+ case NFC_CONN_CLOSE_CEVT:
+ break;
+
+ case NFC_DEACTIVATE_CEVT:
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+ /* Display stats */
+ rw_main_log_stats ();
+#endif
+ /* Stop t2t timer (if started) */
+ nfc_stop_quick_timer (&p_t2t->t2_timer);
+
+ /* Free cmd buf for retransmissions */
+ if (p_t2t->p_cur_cmd_buf)
+ {
+ GKI_freebuf (p_t2t->p_cur_cmd_buf);
+ p_t2t->p_cur_cmd_buf = NULL;
+ }
+ /* Free cmd buf used to hold command before sector change */
+ if (p_t2t->p_sec_cmd_buf)
+ {
+ GKI_freebuf (p_t2t->p_sec_cmd_buf);
+ p_t2t->p_sec_cmd_buf = NULL;
+ }
+
+ p_t2t->state = RW_T2T_STATE_NOT_ACTIVATED;
+ NFC_SetStaticRfCback (NULL);
+ break;
+
+ case NFC_DATA_CEVT:
+ if ( (p_data != NULL)
+ &&( (p_data->data.status == NFC_STATUS_OK)
+ ||(p_data->data.status == NFC_STATUS_CONTINUE) ) )
+ {
+ rw_t2t_proc_data (conn_id, &(p_data->data));
+ break;
+ }
+ /* Data event with error status...fall through to NFC_ERROR_CEVT case */
+
+ case NFC_ERROR_CEVT:
+ if ( (p_t2t->state == RW_T2T_STATE_NOT_ACTIVATED)
+ ||(p_t2t->state == RW_T2T_STATE_IDLE)
+ ||(p_t2t->state == RW_T2T_STATE_HALT) )
+ {
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+ rw_main_update_trans_error_stats ();
+#endif /* RW_STATS_INCLUDED */
+ if (event == NFC_ERROR_CEVT)
+ evt_data.status = (tNFC_STATUS) (*(UINT8*) p_data);
+ else if (p_data)
+ evt_data.status = p_data->status;
+ else
+ evt_data.status = NFC_STATUS_FAILED;
+
+ evt_data.p_data = NULL;
+ (*rw_cb.p_cback) (RW_T2T_INTF_ERROR_EVT, (tRW_DATA *) &evt_data);
+ break;
+ }
+ nfc_stop_quick_timer (&p_t2t->t2_timer);
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+ rw_main_update_trans_error_stats ();
+#endif
+ if (p_t2t->state == RW_T2T_STATE_CHECK_PRESENCE)
+ {
+ 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 ();
+ }
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ /* Free the response buffer in case of invalid response*/
+ if (p_data != NULL) {
+ GKI_freebuf((BT_HDR *) (p_data->data.p_data));
+ }
+#endif
+ break;
+
+ default:
+ break;
+
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_send_cmd
+**
+** Description This function composes a Type 2 Tag command and send it via
+** NCI to NFCC.
+**
+** Returns NFC_STATUS_OK if the command is successfuly sent to NCI
+** otherwise, error status
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_send_cmd (UINT8 opcode, UINT8 *p_dat)
+{
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ const tT2T_CMD_RSP_INFO *p_cmd_rsp_info = t2t_cmd_to_rsp_info (opcode);
+ BT_HDR *p_data;
+ UINT8 *p;
+
+ if (p_cmd_rsp_info)
+ {
+ /* a valid opcode for RW */
+ p_data = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+ if (p_data)
+ {
+ p_t2t->p_cmd_rsp_info = (tT2T_CMD_RSP_INFO *) p_cmd_rsp_info;
+ p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p = (UINT8 *) (p_data + 1) + p_data->offset;
+
+ UINT8_TO_STREAM (p, opcode);
+
+ if (p_dat)
+ {
+ ARRAY_TO_STREAM (p, p_dat, (p_cmd_rsp_info->cmd_len - 1));
+ }
+
+ p_data->len = p_cmd_rsp_info->cmd_len;
+
+ /* Indicate first attempt to send command, back up cmd buffer in case needed for retransmission */
+ rw_cb.cur_retry = 0;
+ memcpy (p_t2t->p_cur_cmd_buf, p_data, sizeof (BT_HDR) + p_data->offset + p_data->len);
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+ /* Update stats */
+ rw_main_update_tx_stats (p_data->len, FALSE);
+#endif
+ RW_TRACE_EVENT2 ("RW SENT [%s]:0x%x CMD", t2t_info_to_str (p_cmd_rsp_info), p_cmd_rsp_info->opcode);
+
+ if ((status = NFC_SendData (NFC_RF_CONN_ID, p_data)) == NFC_STATUS_OK)
+ {
+ nfc_start_quick_timer (&p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE,
+ (RW_T2T_TOUT_RESP*QUICK_TIMER_TICKS_PER_SEC) / 1000);
+ }
+ else
+ {
+#if (BT_TRACE_VERBOSE == TRUE)
+ RW_TRACE_ERROR2 ("T2T NFC Send data failed. state=%s substate=%s ", rw_t2t_get_state_name (p_t2t->state), rw_t2t_get_substate_name (p_t2t->substate));
+#else
+ RW_TRACE_ERROR2 ("T2T NFC Send data failed. state=0x%02X substate=0x%02X ", p_t2t->state, p_t2t->substate);
+#endif
+ }
+ }
+ else
+ {
+ status = NFC_STATUS_NO_BUFFERS;
+ }
+ }
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_process_timeout
+**
+** Description handles timeout event
+**
+** Returns none
+**
+*******************************************************************************/
+void rw_t2t_process_timeout (TIMER_LIST_ENT *p_tle)
+{
+ tRW_READ_DATA evt_data;
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+
+ if (p_t2t->state == RW_T2T_STATE_CHECK_PRESENCE)
+ {
+ 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, (tRW_DATA *) &evt_data);
+ }
+ else
+ {
+ /* Resume operation from where we stopped before sector change */
+ rw_t2t_resume_op ();
+ }
+ }
+ else if (p_t2t->state != RW_T2T_STATE_IDLE)
+ {
+#if (BT_TRACE_VERBOSE == TRUE)
+ RW_TRACE_ERROR1 ("T2T timeout. state=%s ", rw_t2t_get_state_name (p_t2t->state));
+#else
+ RW_TRACE_ERROR1 ("T2T timeout. state=0x%02X ", p_t2t->state);
+#endif
+ /* Handle timeout error as no response to the command sent */
+ rw_t2t_process_error ();
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_process_frame_error
+**
+** Description handles frame crc error
+**
+** Returns none
+**
+*******************************************************************************/
+static void rw_t2t_process_frame_error (void)
+{
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+ /* Update stats */
+ rw_main_update_crc_error_stats ();
+#endif
+ /* Process the error */
+ rw_t2t_process_error ();
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_process_error
+**
+** Description Process error including Timeout, Frame error. This function
+** will retry atleast till RW_MAX_RETRIES before give up and
+** sending negative notification to upper layer
+**
+** Returns none
+**
+*******************************************************************************/
+static void rw_t2t_process_error (void)
+{
+ tRW_READ_DATA evt_data;
+ tRW_EVENT rw_event;
+ BT_HDR *p_cmd_buf;
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ tT2T_CMD_RSP_INFO *p_cmd_rsp_info = (tT2T_CMD_RSP_INFO *) rw_cb.tcb.t2t.p_cmd_rsp_info;
+ tRW_DETECT_NDEF_DATA ndef_data;
+
+ RW_TRACE_DEBUG1 ("rw_t2t_process_error () State: %u", p_t2t->state);
+
+ /* Retry sending command if retry-count < max */
+ if ( (!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 */
+ if ((p_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL)
+ {
+ memcpy (p_cmd_buf, p_t2t->p_cur_cmd_buf, sizeof (BT_HDR) + p_t2t->p_cur_cmd_buf->offset + p_t2t->p_cur_cmd_buf->len);
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+ /* Update stats */
+ rw_main_update_tx_stats (p_cmd_buf->len, TRUE);
+#endif
+ if (NFC_SendData (NFC_RF_CONN_ID, p_cmd_buf) == NFC_STATUS_OK)
+ {
+ /* Start timer for waiting for response */
+ nfc_start_quick_timer (&p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE,
+ (RW_T2T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+
+ return;
+ }
+ }
+ }
+ else
+ {
+ 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 (defined (RW_STATS_INCLUDED) && (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, (tRW_DATA *) &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, (tRW_DATA *) &evt_data);
+ }
+}
+
+/*****************************************************************************
+**
+** Function rw_t2t_handle_presence_check_rsp
+**
+** Description Handle response to presence check
+**
+** Returns Nothing
+**
+*****************************************************************************/
+void rw_t2t_handle_presence_check_rsp (tNFC_STATUS status)
+{
+ tRW_READ_DATA evt_data;
+
+ /* Notify, Tag is present or not */
+ evt_data.status = status;
+ rw_t2t_handle_op_complete ();
+
+ (*rw_cb.p_cback) (RW_T2T_PRESENCE_CHECK_EVT, (tRW_DATA *) &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_resume_op
+**
+** Description This function will continue operation after moving to new
+** sector
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+static void rw_t2t_resume_op (void)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ tRW_READ_DATA evt_data;
+ BT_HDR *p_cmd_buf;
+ tRW_EVENT event;
+ const tT2T_CMD_RSP_INFO *p_cmd_rsp_info = (tT2T_CMD_RSP_INFO *) rw_cb.tcb.t2t.p_cmd_rsp_info;
+ UINT8 *p;
+
+ /* Move back to the substate where we were before changing sector */
+ p_t2t->substate = p_t2t->prev_substate;
+
+ p = (UINT8 *) (p_t2t->p_sec_cmd_buf + 1) + p_t2t->p_sec_cmd_buf->offset;
+ p_cmd_rsp_info = t2t_cmd_to_rsp_info ((UINT8) *p);
+ p_t2t->p_cmd_rsp_info = (tT2T_CMD_RSP_INFO *) p_cmd_rsp_info;
+
+ /* allocate a new buffer for message */
+ if ((p_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL)
+ {
+ memcpy (p_cmd_buf, p_t2t->p_sec_cmd_buf, sizeof (BT_HDR) + p_t2t->p_sec_cmd_buf->offset + p_t2t->p_sec_cmd_buf->len);
+ memcpy (p_t2t->p_cur_cmd_buf, p_t2t->p_sec_cmd_buf, sizeof (BT_HDR) + p_t2t->p_sec_cmd_buf->offset + p_t2t->p_sec_cmd_buf->len);
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+ /* Update stats */
+ rw_main_update_tx_stats (p_cmd_buf->len, TRUE);
+#endif
+ if (NFC_SendData (NFC_RF_CONN_ID, p_cmd_buf) == NFC_STATUS_OK)
+ {
+ /* Start timer for waiting for response */
+ nfc_start_quick_timer (&p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE,
+ (RW_T2T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+ }
+ else
+ {
+ /* failure - could not send buffer */
+ evt_data.p_data = NULL;
+ evt_data.status = NFC_STATUS_FAILED;
+ event = rw_t2t_info_to_event (p_cmd_rsp_info);
+ rw_t2t_handle_op_complete ();
+ (*rw_cb.p_cback) (event, (tRW_DATA *) &evt_data);
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_sector_change
+**
+** Description This function issues Type 2 Tag SECTOR-SELECT command
+** packet 1.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_sector_change (UINT8 sector)
+{
+ tNFC_STATUS status;
+ BT_HDR *p_data;
+ UINT8 *p;
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+
+ if ((p_data = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) == NULL)
+ {
+ RW_TRACE_ERROR0 ("rw_t2t_sector_change - No buffer");
+ return (NFC_STATUS_NO_BUFFERS);
+ }
+
+ p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p = (UINT8 *) (p_data + 1) + p_data->offset;
+
+ UINT8_TO_BE_STREAM (p, sector);
+ UINT8_TO_BE_STREAM (p, 0x00);
+ UINT8_TO_BE_STREAM (p, 0x00);
+ UINT8_TO_BE_STREAM (p, 0x00);
+
+ p_data->len = 4;
+
+ if ((status = NFC_SendData (NFC_RF_CONN_ID , p_data)) == NFC_STATUS_OK)
+ {
+ /* Passive rsp command and suppose not to get response to this command */
+ p_t2t->p_cmd_rsp_info = NULL;
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR;
+
+ RW_TRACE_EVENT0 ("rw_t2t_sector_change Sent Second Command");
+ nfc_start_quick_timer (&p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE,
+ (RW_T2T_SEC_SEL_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+ }
+ else
+ {
+ RW_TRACE_ERROR1 ("rw_t2t_sector_change Send failed at rw_t2t_send_cmd, error: %u", status);
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_read
+**
+** Description This function issues Type 2 Tag READ command for the
+** specified block. If the specified block is in different
+** sector then it first sends command to move to new sector
+** and after the tag moves to new sector it issues the read
+** command for the block.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_read (UINT16 block)
+{
+ tNFC_STATUS status;
+ UINT8 *p;
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ UINT8 sector_byte2[1];
+ UINT8 read_cmd[1];
+
+
+ read_cmd[0] = block % T2T_BLOCKS_PER_SECTOR;
+ if (p_t2t->sector != block/T2T_BLOCKS_PER_SECTOR)
+ {
+ sector_byte2[0] = 0xFF;
+ /* First Move to new sector before sending Read command */
+ if ((status = rw_t2t_send_cmd (T2T_CMD_SEC_SEL,sector_byte2)) == NFC_STATUS_OK)
+ {
+ /* Prepare command that needs to be sent after sector change op is completed */
+ p_t2t->select_sector = (UINT8) (block/T2T_BLOCKS_PER_SECTOR);
+ p_t2t->p_sec_cmd_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+ p = (UINT8 *) (p_t2t->p_sec_cmd_buf + 1) + p_t2t->p_sec_cmd_buf->offset;
+ UINT8_TO_BE_STREAM (p, T2T_CMD_READ);
+ UINT8_TO_BE_STREAM (p, read_cmd[0]);
+ p_t2t->p_sec_cmd_buf->len = 2;
+ p_t2t->block_read = block;
+
+ /* Backup the current substate to move back to this substate after changing sector */
+ p_t2t->prev_substate = p_t2t->substate;
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT;
+ return NFC_STATUS_OK;
+ }
+ return NFC_STATUS_FAILED;
+ }
+
+ /* Send Read command as sector change is not needed */
+ if ((status = rw_t2t_send_cmd (T2T_CMD_READ, (UINT8 *) read_cmd)) == NFC_STATUS_OK)
+ {
+ p_t2t->block_read = block;
+ RW_TRACE_EVENT1 ("rw_t2t_read Sent Command for Block: %u", block);
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_write
+**
+** Description This function issues Type 2 Tag WRITE command for the
+** specified block. If the specified block is in different
+** sector then it first sends command to move to new sector
+** and after the tag moves to new sector it issues the write
+** command for the block.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_write (UINT16 block, UINT8 *p_write_data)
+{
+ tNFC_STATUS status;
+ UINT8 *p;
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ UINT8 write_cmd[T2T_WRITE_DATA_LEN + 1];
+ UINT8 sector_byte2[1];
+
+ p_t2t->block_written = block;
+ write_cmd[0] = (UINT8) (block%T2T_BLOCKS_PER_SECTOR);
+ memcpy (&write_cmd[1], p_write_data, T2T_WRITE_DATA_LEN);
+
+ if (p_t2t->sector != block/T2T_BLOCKS_PER_SECTOR)
+ {
+ sector_byte2[0] = 0xFF;
+ /* First Move to new sector before sending Write command */
+ if ((status = rw_t2t_send_cmd (T2T_CMD_SEC_SEL, sector_byte2)) == NFC_STATUS_OK)
+ {
+ /* Prepare command that needs to be sent after sector change op is completed */
+ p_t2t->select_sector = (UINT8) (block/T2T_BLOCKS_PER_SECTOR);
+ p_t2t->p_sec_cmd_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p = (UINT8 *) (p_t2t->p_sec_cmd_buf + 1) + p_t2t->p_sec_cmd_buf->offset;
+ UINT8_TO_BE_STREAM (p, T2T_CMD_WRITE);
+ memcpy (p, write_cmd, T2T_WRITE_DATA_LEN + 1);
+ p_t2t->p_sec_cmd_buf->len = 2 + T2T_WRITE_DATA_LEN;
+ p_t2t->block_written = block;
+
+ /* Backup the current substate to move back to this substate after changing sector */
+ p_t2t->prev_substate = p_t2t->substate;
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT;
+ return NFC_STATUS_OK;
+ }
+ return NFC_STATUS_FAILED;
+ }
+
+ /* Send Write command as sector change is not needed */
+ if ((status = rw_t2t_send_cmd (T2T_CMD_WRITE, write_cmd)) == NFC_STATUS_OK)
+ {
+ RW_TRACE_EVENT1 ("rw_t2t_write Sent Command for Block: %u", block);
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_select
+**
+** Description This function selects type 2 tag.
+**
+** Returns Tag selection status
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_select (void)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+
+ p_t2t->state = RW_T2T_STATE_IDLE;
+ p_t2t->ndef_status = T2T_NDEF_NOT_DETECTED;
+
+
+ /* Alloc cmd buf for retransmissions */
+ if (p_t2t->p_cur_cmd_buf == NULL)
+ {
+ if ((p_t2t->p_cur_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) == NULL)
+ {
+ RW_TRACE_ERROR0 ("rw_t2t_select: unable to allocate buffer for retransmission");
+ return (NFC_STATUS_FAILED);
+ }
+ }
+ /* Alloc cmd buf for holding a command untill sector changes */
+ if (p_t2t->p_sec_cmd_buf == NULL)
+ {
+ if ((p_t2t->p_sec_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) == NULL)
+ {
+ RW_TRACE_ERROR0 ("rw_t2t_select: unable to allocate buffer used during sector change");
+ return (NFC_STATUS_FAILED);
+ }
+ }
+
+ NFC_SetStaticRfCback (rw_t2t_conn_cback);
+ rw_t2t_handle_op_complete ();
+ 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 sector_blk = 0; /* block 0 of current sector */
+
+ RW_TRACE_API0 ("RW_T2tPresenceCheck");
+
+ /* If RW_SelectTagType was not called (no conn_callback) return failure */
+ if (!p_rw_cb->p_cback)
+ {
+ retval = NFC_STATUS_FAILED;
+ }
+ /* If we are not activated, then RW_T2T_PRESENCE_CHECK_EVT status=FAIL */
+ else if (p_rw_cb->tcb.t2t.state == RW_T2T_STATE_NOT_ACTIVATED)
+ {
+ evt_data.status = NFC_STATUS_FAILED;
+ (*p_rw_cb->p_cback) (RW_T2T_PRESENCE_CHECK_EVT, &evt_data);
+ }
+ /* If command is pending, assume tag is still present */
+ else if (p_rw_cb->tcb.t2t.state != RW_T2T_STATE_IDLE)
+ {
+ evt_data.status = NFC_STATUS_OK;
+ (*p_rw_cb->p_cback) (RW_T2T_PRESENCE_CHECK_EVT, &evt_data);
+ }
+ else
+ {
+ /* IDLE state: send a READ command to block 0 of the current sector */
+ if((retval = rw_t2t_send_cmd (T2T_CMD_READ, §or_blk))== NFC_STATUS_OK)
+ {
+ p_rw_cb->tcb.t2t.state = RW_T2T_STATE_CHECK_PRESENCE;
+ }
+ }
+
+ return (retval);
+}
+
+/*******************************************************************************
+**
+** Function RW_T2tRead
+**
+** Description This function issues the Type 2 Tag READ command. When the
+** operation is complete the callback function will be called
+** with a RW_T2T_READ_EVT.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T2tRead (UINT16 block)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ tNFC_STATUS status;
+
+ if (p_t2t->state != RW_T2T_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
+ return (NFC_STATUS_FAILED);
+ }
+
+ if ((status = rw_t2t_read (block)) == NFC_STATUS_OK)
+ {
+ p_t2t->state = RW_T2T_STATE_READ;
+ RW_TRACE_EVENT0 ("RW_T2tRead Sent Read command");
+ }
+
+ return status;
+
+}
+
+/*******************************************************************************
+**
+** Function RW_T2tWrite
+**
+** Description This function issues the Type 2 Tag WRITE command. When the
+** operation is complete the callback function will be called
+** with a RW_T2T_WRITE_EVT.
+**
+** p_new_bytes points to the array of 4 bytes to be written
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T2tWrite (UINT16 block, UINT8 *p_write_data)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ tNFC_STATUS status;
+
+ if (p_t2t->state != RW_T2T_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
+ return (NFC_STATUS_FAILED);
+ }
+
+ if ((status = rw_t2t_write (block, p_write_data)) == NFC_STATUS_OK)
+ {
+ p_t2t->state = RW_T2T_STATE_WRITE;
+ if (block < T2T_FIRST_DATA_BLOCK)
+ p_t2t->b_read_hdr = FALSE;
+ else if (block < (T2T_FIRST_DATA_BLOCK + T2T_READ_BLOCKS))
+ p_t2t->b_read_data = FALSE;
+ RW_TRACE_EVENT0 ("RW_T2tWrite Sent Write command");
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function RW_T2tSectorSelect
+**
+** Description This function issues the Type 2 Tag SECTOR-SELECT command
+** packet 1. If a NACK is received as the response, the callback
+** function will be called with a RW_T2T_SECTOR_SELECT_EVT. If
+** an ACK is received as the response, the command packet 2 with
+** the given sector number is sent to the peer device. When the
+** response for packet 2 is received, the callback function will
+** be called with a RW_T2T_SECTOR_SELECT_EVT.
+**
+** A sector is 256 contiguous blocks (1024 bytes).
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T2tSectorSelect (UINT8 sector)
+{
+ tNFC_STATUS status;
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ UINT8 sector_byte2[1];
+
+ if (p_t2t->state != RW_T2T_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
+ return (NFC_STATUS_FAILED);
+ }
+
+ if (sector >= T2T_MAX_SECTOR)
+ {
+ RW_TRACE_ERROR2 ("RW_T2tSectorSelect - Invalid sector: %u, T2 Max supported sector value: %u", sector, T2T_MAX_SECTOR - 1);
+ return (NFC_STATUS_FAILED);
+ }
+
+ sector_byte2[0] = 0xFF;
+
+ if ((status = rw_t2t_send_cmd (T2T_CMD_SEC_SEL, sector_byte2)) == NFC_STATUS_OK)
+ {
+ p_t2t->state = RW_T2T_STATE_SELECT_SECTOR;
+ p_t2t->select_sector = sector;
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT;
+
+ RW_TRACE_EVENT0 ("RW_T2tSectorSelect Sent Sector select first command");
+ }
+
+ return status;
+}
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function rw_t2t_get_state_name
+**
+** Description This function returns the state name.
+**
+** NOTE conditionally compiled to save memory.
+**
+** Returns pointer to the name
+**
+*******************************************************************************/
+static char *rw_t2t_get_state_name (UINT8 state)
+{
+ switch (state)
+ {
+ case RW_T2T_STATE_NOT_ACTIVATED:
+ return ("NOT_ACTIVATED");
+ case RW_T2T_STATE_IDLE:
+ return ("IDLE");
+ case RW_T2T_STATE_READ:
+ return ("APP_READ");
+ case RW_T2T_STATE_WRITE:
+ return ("APP_WRITE");
+ case RW_T2T_STATE_SELECT_SECTOR:
+ return ("SECTOR_SELECT");
+ case RW_T2T_STATE_DETECT_TLV:
+ return ("TLV_DETECT");
+ case RW_T2T_STATE_READ_NDEF:
+ return ("READ_NDEF");
+ case RW_T2T_STATE_WRITE_NDEF:
+ return ("WRITE_NDEF");
+ case RW_T2T_STATE_SET_TAG_RO:
+ return ("SET_TAG_RO");
+ case RW_T2T_STATE_CHECK_PRESENCE:
+ return ("CHECK_PRESENCE");
+ default:
+ return ("???? UNKNOWN STATE");
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_get_substate_name
+**
+** Description This function returns the substate name.
+**
+** NOTE conditionally compiled to save memory.
+**
+** Returns pointer to the name
+**
+*******************************************************************************/
+static char *rw_t2t_get_substate_name (UINT8 substate)
+{
+ switch (substate)
+ {
+ case RW_T2T_SUBSTATE_NONE:
+ return ("RW_T2T_SUBSTATE_NONE");
+ case RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT:
+ return ("RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT");
+ case RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR:
+ return ("RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR");
+ case RW_T2T_SUBSTATE_WAIT_READ_CC:
+ return ("RW_T2T_SUBSTATE_WAIT_READ_CC");
+ case RW_T2T_SUBSTATE_WAIT_TLV_DETECT:
+ return ("RW_T2T_SUBSTATE_WAIT_TLV_DETECT");
+ case RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN:
+ return ("RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN");
+ case RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0:
+ return ("RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0");
+ case RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1:
+ return ("RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1");
+ case RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE:
+ return ("RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE");
+ case RW_T2T_SUBSTATE_WAIT_READ_LOCKS:
+ return ("RW_T2T_SUBSTATE_WAIT_READ_LOCKS");
+ case RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK:
+ return ("RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK");
+ case RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK:
+ return ("RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK");
+ case RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK:
+ return ("RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK");
+ case RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK:
+ return ("RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK");
+ case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK:
+ return ("RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK");
+ case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK:
+ return ("RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK");
+ case RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK:
+ return ("RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK");
+ case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK:
+ return ("RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK");
+ case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK:
+ return ("RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK");
+ case RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT:
+ return ("RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT");
+ default:
+ return ("???? UNKNOWN SUBSTATE");
+ }
+}
+
+#endif /* (BT_TRACE_VERBOSE == TRUE) */
+
+#endif /* NFC_INCLUDED == TRUE*/
diff --git a/src/nfc/tags/rw_t2t_ndef.c b/src/nfc/tags/rw_t2t_ndef.c
new file mode 100644
index 0000000..c802f2a
--- /dev/null
+++ b/src/nfc/tags/rw_t2t_ndef.c
@@ -0,0 +1,3215 @@
+/******************************************************************************
+ *
+ * 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 NDEF operation in
+ * Reader/Writer mode.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_api.h"
+#include "nci_hmsgs.h"
+#include "rw_api.h"
+#include "rw_int.h"
+#include "nfc_int.h"
+#include "gki.h"
+
+#if (defined (RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE))
+
+/* Local static functions */
+static void rw_t2t_handle_cc_read_rsp (void);
+static void rw_t2t_handle_lock_read_rsp (UINT8 *p_data);
+static void rw_t2t_handle_tlv_detect_rsp (UINT8 *p_data);
+static void rw_t2t_handle_ndef_read_rsp (UINT8 *p_data);
+static void rw_t2t_handle_ndef_write_rsp (UINT8 *p_data);
+static void rw_t2t_handle_format_tag_rsp (UINT8 *p_data);
+static void rw_t2t_handle_config_tag_readonly (UINT8 *p_data);
+static UINT8 rw_t2t_get_tag_size (UINT8 *p_data);
+static void rw_t2t_extract_default_locks_info (void);
+static void rw_t2t_update_cb (UINT16 block, UINT8 *p_write_block, BOOLEAN b_update_len);
+static UINT8 rw_t2t_get_ndef_flags (void);
+static UINT16 rw_t2t_get_ndef_max_size (void);
+static tNFC_STATUS rw_t2t_read_locks (void);
+static tNFC_STATUS rw_t2t_read_ndef_last_block (void);
+static void rw_t2t_update_attributes (void);
+static void rw_t2t_update_lock_attributes (void);
+static BOOLEAN rw_t2t_is_lock_res_byte (UINT16 index);
+static BOOLEAN rw_t2t_is_read_only_byte (UINT16 index);
+static tNFC_STATUS rw_t2t_write_ndef_first_block (UINT16 msg_len, BOOLEAN b_update_len);
+static tNFC_STATUS rw_t2t_write_ndef_next_block (UINT16 block, UINT16 msg_len, BOOLEAN b_update_len);
+static tNFC_STATUS rw_t2t_read_ndef_next_block (UINT16 block);
+static tNFC_STATUS rw_t2t_add_terminator_tlv (void);
+static BOOLEAN rw_t2t_is_read_before_write_block (UINT16 block, UINT16 *p_block_to_read);
+static tNFC_STATUS rw_t2t_set_cc (UINT8 tms);
+static tNFC_STATUS rw_t2t_set_lock_tlv (UINT16 addr, UINT8 num_dyn_lock_bits, UINT16 locked_area_size);
+static tNFC_STATUS rw_t2t_format_tag (void);
+static tNFC_STATUS rw_t2t_soft_lock_tag (void);
+static tNFC_STATUS rw_t2t_set_dynamic_lock_bits (UINT8 *p_data);
+static void rw_t2t_ntf_tlv_detect_complete (tNFC_STATUS status);
+
+const UINT8 rw_t2t_mask_bits[8] =
+{0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
+
+/*******************************************************************************
+**
+** Function rw_t2t_handle_rsp
+**
+** Description This function handles response to command sent during
+** NDEF and other tlv operation
+**
+** Returns None
+**
+*******************************************************************************/
+void rw_t2t_handle_rsp (UINT8 *p_data)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+
+ if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_CC)
+ {
+ p_t2t->b_read_hdr = TRUE;
+ memcpy (p_t2t->tag_hdr, p_data, T2T_READ_DATA_LEN);
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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) T2T_FIRST_DATA_BLOCK) != NFC_STATUS_OK)
+ {
+ rw_t2t_ntf_tlv_detect_complete (NFC_STATUS_FAILED);
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_ntf_tlv_detect_complete
+**
+** Description Notify TLV detection complete to upper layer
+**
+** Returns none
+**
+*******************************************************************************/
+static void rw_t2t_ntf_tlv_detect_complete (tNFC_STATUS status)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ tRW_DETECT_NDEF_DATA ndef_data = {0};
+ tRW_DETECT_TLV_DATA tlv_data;
+ tRW_T2T_DETECT evt_data;
+ UINT8 xx;
+
+ if (p_t2t->tlv_detect == TAG_NDEF_TLV)
+ {
+ /* Notify upper layer the result of NDEF detect op */
+ ndef_data.status = status;
+ ndef_data.protocol = NFC_PROTOCOL_T2T;
+ ndef_data.flags = rw_t2t_get_ndef_flags ();
+ ndef_data.cur_size = p_t2t->ndef_msg_len;
+
+ if (status == NFC_STATUS_OK)
+ ndef_data.flags |= RW_NDEF_FL_FORMATED;
+
+ if (p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] == T2T_CC3_RWA_RW)
+ ndef_data.max_size = (UINT32) rw_t2t_get_ndef_max_size ();
+ else
+ ndef_data.max_size = ndef_data.cur_size;
+
+ if (ndef_data.max_size < ndef_data.cur_size)
+ {
+ ndef_data.flags |= RW_NDEF_FL_READ_ONLY;
+ ndef_data.max_size = ndef_data.cur_size;
+ }
+
+ if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY))
+ {
+ ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE;
+ if (status == NFC_STATUS_OK)
+ ndef_data.flags |= RW_NDEF_FL_HARD_LOCKABLE;
+ }
+
+ rw_t2t_handle_op_complete ();
+ (*rw_cb.p_cback) (RW_T2T_NDEF_DETECT_EVT, (tRW_DATA *) &ndef_data);
+ }
+ else if (p_t2t->tlv_detect == TAG_PROPRIETARY_TLV)
+ {
+ evt_data.msg_len = p_t2t->prop_msg_len;
+ evt_data.status = status;
+ rw_t2t_handle_op_complete ();
+ (*rw_cb.p_cback) (RW_T2T_TLV_DETECT_EVT, (tRW_DATA *) &evt_data);
+ }
+ else
+ {
+ /* Notify upper layer the result of Lock/Mem TLV detect op */
+ tlv_data.protocol = NFC_PROTOCOL_T2T;
+ if (p_t2t->tlv_detect == TAG_LOCK_CTRL_TLV)
+ {
+ tlv_data.num_bytes = p_t2t->num_lockbytes;
+ }
+ else
+ {
+ tlv_data.num_bytes = 0;
+ for (xx = 0; xx < p_t2t->num_mem_tlvs; xx++)
+ {
+ tlv_data.num_bytes += p_t2t->mem_tlv[p_t2t->num_mem_tlvs].num_bytes;
+ }
+ }
+ tlv_data.status = status;
+ rw_t2t_handle_op_complete ();
+ (*rw_cb.p_cback) (RW_T2T_TLV_DETECT_EVT, (tRW_DATA *) &tlv_data);
+ }
+
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_handle_lock_read_rsp
+**
+** Description Handle response to reading lock bytes
+**
+** Returns none
+**
+*******************************************************************************/
+static void rw_t2t_handle_lock_read_rsp (UINT8 *p_data)
+{
+ UINT8 updated_lock_byte;
+ UINT8 num_locks;
+ UINT8 offset = 0;
+ UINT16 lock_offset;
+ UINT16 base_lock_offset = 0;
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ UINT16 block;
+
+ /* Prepare NDEF/TLV attributes (based on current op) for sending response to upper layer */
+
+ num_locks = 0;
+ updated_lock_byte = 0;
+
+ /* Extract all lock bytes present in the read 16 bytes
+ * but atleast one lock byte (base lock) should be present in the read 16 bytes */
+
+ while (num_locks < p_t2t->num_lockbytes)
+ {
+ if (p_t2t->lockbyte[num_locks].b_lock_read == FALSE)
+ {
+ lock_offset = p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].offset + p_t2t->lockbyte[num_locks].byte_index;
+ if (updated_lock_byte == 0)
+ {
+ /* The offset of the first lock byte present in the 16 bytes read using READ command */
+ base_lock_offset = lock_offset;
+ /* Block number used to read may not be the block where lock offset is present */
+ offset = (UINT8) (lock_offset - (p_t2t->block_read * T2T_BLOCK_SIZE));
+ /* Update the lock byte value in the control block */
+ p_t2t->lockbyte[num_locks].lock_byte = p_data[offset];
+ p_t2t->lockbyte[num_locks].b_lock_read = TRUE;
+ updated_lock_byte++;
+ }
+ else if (lock_offset > base_lock_offset)
+ {
+ /* Atleast one lock byte will get updated in the control block */
+ if ((lock_offset - base_lock_offset + offset) < T2T_READ_DATA_LEN)
+ {
+ /* And this lock byte is also present in the read data */
+ p_t2t->lockbyte[num_locks].lock_byte = p_data[lock_offset - base_lock_offset + offset];
+ p_t2t->lockbyte[num_locks].b_lock_read = TRUE;
+ updated_lock_byte++;
+ }
+ else
+ {
+ /* This lock byte is not present in the read data */
+ block = (UINT16) (lock_offset / T2T_BLOCK_LEN);
+ block -= block % T2T_READ_BLOCKS;
+ /* send READ command to read this lock byte */
+ if (NFC_STATUS_OK != rw_t2t_read ((UINT16) block))
+ {
+ /* Unable to send Read command, notify failure status to upper layer */
+ rw_t2t_ntf_tlv_detect_complete (NFC_STATUS_FAILED);
+ }
+ break;
+ }
+ }
+ else
+ {
+ /* This Lock byte is not present in the read 16 bytes
+ * send READ command to read the lock byte */
+ if (NFC_STATUS_OK != rw_t2t_read ((UINT16) (lock_offset / T2T_BLOCK_LEN)))
+ {
+ /* Unable to send Read command, notify failure status to upper layer */
+ rw_t2t_ntf_tlv_detect_complete (NFC_STATUS_FAILED);
+ }
+ break;
+ }
+ }
+ num_locks++;
+ }
+ if (num_locks == p_t2t->num_lockbytes)
+ {
+ /* All locks are read, notify upper layer */
+ rw_t2t_update_lock_attributes ();
+ rw_t2t_ntf_tlv_detect_complete (NFC_STATUS_OK);
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_handle_tlv_detect_rsp
+**
+** Description Handle TLV detection.
+**
+** Returns none
+**
+*******************************************************************************/
+static void rw_t2t_handle_tlv_detect_rsp (UINT8 *p_data)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ UINT16 offset;
+ UINT16 len = 0;
+ BOOLEAN failed = FALSE;
+ BOOLEAN found = FALSE;
+ tRW_EVENT event;
+ UINT8 index;
+ UINT8 count = 0;
+ UINT8 xx;
+ tNFC_STATUS status;
+ tT2T_CMD_RSP_INFO *p_cmd_rsp_info = (tT2T_CMD_RSP_INFO *) rw_cb.tcb.t2t.p_cmd_rsp_info;
+ UINT8 tlvtype = p_t2t->tlv_detect;
+
+ if (p_t2t->work_offset == 0)
+ {
+ /* Skip UID,Static Lock block,CC*/
+ p_t2t->work_offset = T2T_FIRST_DATA_BLOCK * T2T_BLOCK_LEN;
+ p_t2t->b_read_data = TRUE;
+ memcpy (p_t2t->tag_data, p_data, T2T_READ_DATA_LEN);
+ }
+
+ p_t2t->segment = 0;
+
+ for (offset = 0; offset < T2T_READ_DATA_LEN && !failed && !found;)
+ {
+ if (rw_t2t_is_lock_res_byte ((UINT16) (p_t2t->work_offset + offset)) == TRUE)
+ {
+ /* Skip locks, reserved bytes while searching for TLV */
+ offset++;
+ continue;
+ }
+ switch (p_t2t->substate)
+ {
+ case RW_T2T_SUBSTATE_WAIT_TLV_DETECT:
+ /* Search for the tlv */
+ p_t2t->found_tlv = p_data[offset++];
+ switch (p_t2t->found_tlv)
+ {
+ case TAG_NULL_TLV: /* May be used for padding. SHALL ignore this */
+ break;
+
+ case TAG_NDEF_TLV:
+ if (tlvtype == TAG_NDEF_TLV)
+ {
+ /* NDEF Detected, now collect NDEF Attributes including NDEF Length */
+ index = (offset % T2T_BLOCK_SIZE);
+ /* Backup ndef first block */
+ memcpy (p_t2t->ndef_first_block,&p_data[offset-index],index);
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
+ }
+ else if (tlvtype == TAG_PROPRIETARY_TLV)
+ {
+ /* Proprietary TLV can exist after NDEF Tlv so we continue searching */
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
+ }
+ else if ( ((tlvtype == TAG_LOCK_CTRL_TLV) && (p_t2t->num_lockbytes > 0))
+ ||((tlvtype == TAG_MEM_CTRL_TLV) && (p_t2t->num_mem_tlvs > 0)) )
+ {
+ /* Lock / Memory control tlv cannot exist after NDEF TLV
+ * So when NDEF is found, we stop searching for Lock and Memory control tlv */
+ found = TRUE;
+ }
+ else
+ {
+ /* While searching for Lock / Memory control tlv, if NDEF TLV is found
+ * first then our search for Lock /Memory control tlv failed and we stop here */
+ failed = TRUE;
+ }
+ break;
+
+ case TAG_LOCK_CTRL_TLV:
+ case TAG_MEM_CTRL_TLV:
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0;
+ break;
+
+ case TAG_PROPRIETARY_TLV:
+ if (tlvtype == TAG_PROPRIETARY_TLV)
+ {
+ index = (offset % T2T_BLOCK_SIZE);
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
+ }
+ else
+ {
+ /* 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) p_data[offset];
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1;
+ break;
+ }
+ offset++;
+ break;
+
+ case RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1:
+ /* Prepare NDEF Message length */
+ p_t2t->bytes_count = (p_t2t->bytes_count << 8) + p_data[offset];
+ if (p_t2t->found_tlv == TAG_NDEF_TLV)
+ {
+ p_t2t->ndef_msg_len = p_t2t->bytes_count;
+ }
+ else if (p_t2t->found_tlv == TAG_PROPRIETARY_TLV)
+ {
+ p_t2t->prop_msg_len = p_t2t->bytes_count;
+ }
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
+ offset++;
+ break;
+
+ case RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE:
+ switch (p_t2t->found_tlv)
+ {
+ case TAG_NDEF_TLV:
+ if ( (p_t2t->bytes_count == p_t2t->ndef_msg_len)
+ &&(tlvtype == TAG_NDEF_TLV) )
+ {
+ /* The first byte offset after length field */
+ p_t2t->ndef_msg_offset = offset + p_t2t->work_offset;
+ }
+ /* Reduce number of NDEF bytes remaining to pass over NDEF TLV */
+ if (p_t2t->bytes_count > 0)
+ p_t2t->bytes_count--;
+
+ if (tlvtype == TAG_NDEF_TLV)
+ {
+ found = TRUE;
+ p_t2t->ndef_status = T2T_NDEF_DETECTED;
+ }
+ else if (p_t2t->bytes_count == 0)
+ {
+ /* Next byte could be a different TLV */
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
+ }
+ break;
+
+ case TAG_LOCK_CTRL_TLV:
+ p_t2t->bytes_count--;
+ if ( (tlvtype == TAG_LOCK_CTRL_TLV)
+ ||(tlvtype == TAG_NDEF_TLV) )
+ {
+ /* Collect Lock TLV */
+ p_t2t->tlv_value[2 - p_t2t->bytes_count] = p_data[offset];
+ if (p_t2t->bytes_count == 0)
+ {
+ /* Lock TLV is collected and buffered in tlv_value, now decode it */
+ p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset = (p_t2t->tlv_value[0] >> 4) & 0x0F;
+ p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset *= (UINT8) tags_pow (2, p_t2t->tlv_value[2] & 0x0F);
+ p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset += p_t2t->tlv_value[0] & 0x0F;
+ p_t2t->lock_tlv[p_t2t->num_lock_tlvs].bytes_locked_per_bit = (UINT8) tags_pow (2, ((p_t2t->tlv_value[2] & 0xF0) >> 4));
+ p_t2t->lock_tlv[p_t2t->num_lock_tlvs].num_bits = p_t2t->tlv_value[1];
+ count = p_t2t->tlv_value[1] / 8 + ((p_t2t->tlv_value[1]%8 != 0)? 1:0);
+
+ /* Extract lockbytes info addressed by this Lock TLV */
+ xx = 0;
+ while (xx < count)
+ {
+ p_t2t->lockbyte[p_t2t->num_lockbytes].tlv_index = p_t2t->num_lock_tlvs;
+ p_t2t->lockbyte[p_t2t->num_lockbytes].byte_index = xx;
+ p_t2t->lockbyte[p_t2t->num_lockbytes].b_lock_read = FALSE;
+ xx++;
+ p_t2t->num_lockbytes++;
+ }
+ p_t2t->num_lock_tlvs++;
+ rw_t2t_update_attributes ();
+ /* Next byte could be a different TLV */
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
+ }
+ }
+ else
+ {
+ /* If not looking for lock/ndef tlv, just skip this Lock TLV */
+ if (p_t2t->bytes_count == 0)
+ {
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
+ }
+ }
+ break;
+
+ case TAG_MEM_CTRL_TLV:
+ p_t2t->bytes_count--;
+ if ( (tlvtype == TAG_MEM_CTRL_TLV)
+ ||(tlvtype == TAG_NDEF_TLV) )
+ {
+ p_t2t->tlv_value[2 - p_t2t->bytes_count] = p_data[offset];
+ if (p_t2t->bytes_count == 0)
+ {
+ if (p_t2t->num_mem_tlvs >= RW_T2T_MAX_MEM_TLVS)
+ {
+ RW_TRACE_ERROR0 ("rw_t2t_handle_tlv_detect_rsp - Maximum buffer allocated for Memory tlv has reached");
+ failed = TRUE;
+ }
+ else
+ {
+ /* Extract memory control tlv */
+ p_t2t->mem_tlv[p_t2t->num_mem_tlvs].offset = (p_t2t->tlv_value[0] >> 4) & 0x0F;
+ p_t2t->mem_tlv[p_t2t->num_mem_tlvs].offset *= (UINT8) tags_pow (2, p_t2t->tlv_value[2] & 0x0F);
+ p_t2t->mem_tlv[p_t2t->num_mem_tlvs].offset += p_t2t->tlv_value[0] & 0x0F;
+ p_t2t->mem_tlv[p_t2t->num_mem_tlvs].num_bytes = p_t2t->tlv_value[1];
+ p_t2t->num_mem_tlvs++;
+ rw_t2t_update_attributes ();
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
+ }
+ }
+ }
+ else
+ {
+ if (p_t2t->bytes_count == 0)
+ {
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
+ }
+ }
+ break;
+
+ case TAG_PROPRIETARY_TLV:
+ p_t2t->bytes_count--;
+ if (tlvtype == TAG_PROPRIETARY_TLV)
+ {
+ found = TRUE;
+ p_t2t->prop_msg_len = len;
+ }
+ else
+ {
+ if (p_t2t->bytes_count == 0)
+ {
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
+ }
+ }
+ break;
+ }
+ offset++;
+ break;
+ }
+ }
+
+
+ p_t2t->work_offset += T2T_READ_DATA_LEN;
+
+ event = rw_t2t_info_to_event (p_cmd_rsp_info);
+
+ /* If not found and not failed, read next block and search tlv */
+ if (!found && !failed)
+ {
+
+ if (p_t2t->work_offset >= (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR))
+ {
+ if ( ((tlvtype == TAG_LOCK_CTRL_TLV) && (p_t2t->num_lockbytes > 0))
+ ||((tlvtype == TAG_MEM_CTRL_TLV) && (p_t2t->num_mem_tlvs > 0)) )
+ {
+ found = TRUE;
+ }
+ else
+ {
+ failed = TRUE;
+ }
+ }
+ else
+ {
+ if (rw_t2t_read ((UINT16) ((p_t2t->work_offset / T2T_BLOCK_LEN) + T2T_FIRST_DATA_BLOCK)) != NFC_STATUS_OK)
+ failed = TRUE;
+ }
+ }
+
+ if (failed || found)
+ {
+ if (tlvtype == TAG_LOCK_CTRL_TLV)
+ {
+ /* Incase no Lock control tlv is present then look for default dynamic lock bytes */
+ rw_t2t_extract_default_locks_info ();
+
+ /* Send command to read the dynamic lock bytes */
+ status = rw_t2t_read_locks ();
+
+ if (status != NFC_STATUS_CONTINUE)
+ {
+ /* If unable to read a lock/all locks read, notify upper layer */
+ rw_t2t_update_lock_attributes ();
+ rw_t2t_ntf_tlv_detect_complete (status);
+ }
+ }
+ else if (tlvtype == TAG_NDEF_TLV)
+ {
+ rw_t2t_extract_default_locks_info ();
+
+ if (failed)
+ {
+ rw_t2t_ntf_tlv_detect_complete (NFC_STATUS_FAILED);
+ }
+ else
+ {
+ /* NDEF present,Send command to read the dynamic lock bytes */
+ status = rw_t2t_read_locks ();
+ if (status != NFC_STATUS_CONTINUE)
+ {
+ /* If unable to read a lock/all locks read, notify upper layer */
+ rw_t2t_update_lock_attributes ();
+ rw_t2t_ntf_tlv_detect_complete (status);
+ }
+ }
+ }
+ else
+ {
+ /* Notify Memory/ Proprietary tlv detect result */
+ status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK;
+ rw_t2t_ntf_tlv_detect_complete (status);
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_read_locks
+**
+** Description This function will send command to read next unread locks
+**
+** Returns NFC_STATUS_OK, if all locks are read successfully
+** NFC_STATUS_FAILED, if reading locks failed
+** NFC_STATUS_CONTINUE, if reading locks is in progress
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_read_locks (void)
+{
+ UINT8 num_locks = 0;
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ tNFC_STATUS status = NFC_STATUS_CONTINUE;
+ UINT16 offset;
+ UINT16 block;
+
+ if ( (p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] != T2T_CC3_RWA_RW)
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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(NFC_NXP_NOT_OPEN_INCLUDED == 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) (offset / T2T_BLOCK_LEN);
+ block -= block % T2T_READ_BLOCKS;
+
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_LOCKS;
+ /* send READ8 command */
+ if ((status = rw_t2t_read ((UINT16) block)) == NFC_STATUS_OK)
+ {
+ /* Reading Locks */
+ status = NFC_STATUS_CONTINUE;
+ }
+ else
+ {
+ status = NFC_STATUS_FAILED;
+ }
+ break;
+ }
+ num_locks++;
+ }
+ if (num_locks == p_t2t->num_lockbytes)
+ {
+ /* All locks are read */
+ status = NFC_STATUS_OK;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_extract_default_locks_info
+**
+** Description This function will prepare lockbytes information for default
+** locks present in the tag in the absence of lock control tlv.
+** Adding a virtual lock control tlv for these lock bytes for
+** easier manipulation.
+**
+** Returns None
+**
+*******************************************************************************/
+void rw_t2t_extract_default_locks_info (void)
+{
+ UINT8 num_dynamic_lock_bits;
+ UINT8 num_dynamic_lock_bytes;
+ UINT8 xx;
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ const tT2T_INIT_TAG *p_ret;
+ UINT8 bytes_locked_per_lock_bit = T2T_DEFAULT_LOCK_BLPB;
+
+
+ if ( (p_t2t->num_lock_tlvs == 0)
+ &&(p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] > T2T_CC2_TMS_STATIC) )
+ {
+ /* No Lock control tlv is detected. Indicates lock bytes are present in default location */
+ /* Add a virtual Lock tlv to map this default lock location */
+ if ((p_ret = t2t_tag_init_data (p_t2t->tag_hdr[0], FALSE, 0)) != NULL)
+ bytes_locked_per_lock_bit = p_ret->default_lock_blpb;
+
+ num_dynamic_lock_bits = ((p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) - (T2T_STATIC_SIZE - T2T_HEADER_SIZE)) / bytes_locked_per_lock_bit;
+ num_dynamic_lock_bytes = num_dynamic_lock_bits / 8;
+ num_dynamic_lock_bytes += (num_dynamic_lock_bits % 8 == 0) ? 0:1;
+
+ p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset = (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) + (T2T_FIRST_DATA_BLOCK * T2T_BLOCK_LEN);
+ p_t2t->lock_tlv[p_t2t->num_lock_tlvs].bytes_locked_per_bit = bytes_locked_per_lock_bit;
+ p_t2t->lock_tlv[p_t2t->num_lock_tlvs].num_bits = num_dynamic_lock_bits;
+
+ /* Based on tag data size the number of locks present in the default location changes */
+ for (xx = 0; xx < num_dynamic_lock_bytes; xx++)
+ {
+ p_t2t->lockbyte[xx].tlv_index = p_t2t->num_lock_tlvs;
+ p_t2t->lockbyte[xx].byte_index = xx;
+ p_t2t->lockbyte[xx].b_lock_read = FALSE;
+ }
+ p_t2t->num_lockbytes = num_dynamic_lock_bytes;
+ p_t2t->num_lock_tlvs = 1;
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_read_ndef_last_block
+**
+** Description This function will locate and read the last ndef block.
+** The last ndef block refers to the tag block where last byte
+** of new ndef message will reside. Also this function will
+** locate the offset of Terminator TLV based on the size of
+** new NDEF Message
+**
+** Returns NCI_STATUS_OK,if able to locate last ndef block & read started
+** Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_read_ndef_last_block (void)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ UINT16 header_len = (p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN) ? T2T_LONG_NDEF_LEN_FIELD_LEN : T2T_SHORT_NDEF_LEN_FIELD_LEN;
+ UINT16 num_ndef_bytes;
+ UINT16 total_ndef_bytes;
+ UINT16 last_ndef_byte_offset;
+ UINT16 terminator_tlv_byte_index;
+ tNFC_STATUS status;
+ UINT16 block;
+
+
+ total_ndef_bytes = header_len + p_t2t->new_ndef_msg_len;
+ num_ndef_bytes = 0;
+ last_ndef_byte_offset = p_t2t->ndef_header_offset;
+
+ /* Locate NDEF final block based on the size of new NDEF Message */
+ while (num_ndef_bytes < total_ndef_bytes)
+ {
+ if (rw_t2t_is_lock_res_byte ((UINT16) (last_ndef_byte_offset)) == FALSE)
+ num_ndef_bytes++;
+
+ last_ndef_byte_offset++;
+ }
+ p_t2t->ndef_last_block_num = (UINT16) ((last_ndef_byte_offset - 1) / T2T_BLOCK_SIZE);
+ block = p_t2t->ndef_last_block_num;
+
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK;
+ /* Read NDEF last block before updating */
+ if ((status = rw_t2t_read (block))== NFC_STATUS_OK)
+ {
+ if ((p_t2t->new_ndef_msg_len + 1) <= p_t2t->max_ndef_msg_len)
+ {
+ /* Locate Terminator TLV Block */
+ total_ndef_bytes++;
+ terminator_tlv_byte_index = last_ndef_byte_offset;
+
+ while (num_ndef_bytes < total_ndef_bytes)
+ {
+ if (rw_t2t_is_lock_res_byte ((UINT16) terminator_tlv_byte_index) == FALSE)
+ num_ndef_bytes++;
+
+ terminator_tlv_byte_index++;
+ }
+
+ p_t2t->terminator_byte_index = terminator_tlv_byte_index - 1;
+ }
+ else
+ {
+ /* No space for Terminator TLV */
+ p_t2t->terminator_byte_index = 0x00;
+ }
+ }
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_read_terminator_tlv_block
+**
+** Description This function will read the block where terminator tlv will
+** be added later
+**
+** Returns NCI_STATUS_OK, if read was started. Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_read_terminator_tlv_block (void)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ tNFC_STATUS status;
+ UINT16 block;
+
+ /* Send read command to read base block (Block % 4==0) where this block is also read as part of 16 bytes */
+ block = p_t2t->terminator_byte_index / T2T_BLOCK_SIZE;
+ block -= block % T2T_READ_BLOCKS;
+
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK;
+ /* Read the block where Terminator TLV may be added later during NDEF Write operation */
+ status = rw_t2t_read (block);
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_read_ndef_next_block
+**
+** Description This function will read the tag block passed as argument
+**
+** Returns NCI_STATUS_OK, if read was started. Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_read_ndef_next_block (UINT16 block)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ tNFC_STATUS status;
+
+ /* Send read command to read base block (Block % 4==0) where this block is also read as part of 16 bytes */
+ block -= block % T2T_READ_BLOCKS;
+
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK;
+ /* Read the block */
+ status = rw_t2t_read (block);
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_is_read_before_write_block
+**
+** Description This function will check if the block has to be read before
+** writting to avoid over writting in to lock/reserved bytes
+** present in the block.
+** If no bytes in the block can be overwritten it moves in to
+** next block and check. Finally it finds a block where part of
+** ndef bytes can exist and check if the whole block can be
+** updated or only part of block can be modified.
+**
+** Returns TRUE, if the block returned should be read before writting
+** FALSE, if the block need not be read as it was already
+** read or during NDEF write we may completely overwrite
+** the block and there is no reserved or locked bytes in
+** that block
+**
+*******************************************************************************/
+static BOOLEAN rw_t2t_is_read_before_write_block (UINT16 block, UINT16 *p_block_to_read)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ UINT8 *p_cc = &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE];
+ UINT8 count;
+ UINT8 index;
+ UINT16 tag_size = p_cc[2] * 2 + T2T_FIRST_DATA_BLOCK;
+ BOOLEAN read_before_write = TRUE;
+
+
+ if (block == p_t2t->ndef_header_offset / T2T_BLOCK_SIZE)
+ {
+ /* First NDEF block is already read */
+ read_before_write = FALSE;
+ memcpy (p_t2t->ndef_read_block,p_t2t->ndef_first_block,T2T_BLOCK_SIZE);
+ }
+ else if (block == p_t2t->ndef_last_block_num)
+ {
+ /* Last NDEF block is already read */
+ read_before_write = FALSE;
+ memcpy (p_t2t->ndef_read_block,p_t2t->ndef_last_block,T2T_BLOCK_SIZE);
+ }
+ else if (block == p_t2t->terminator_byte_index / T2T_BLOCK_SIZE)
+ {
+ /* Terminator tlv block is already read */
+ read_before_write = FALSE;
+ memcpy (p_t2t->ndef_read_block,p_t2t->terminator_tlv_block,T2T_BLOCK_SIZE);
+ }
+ else
+ {
+ count = 0;
+ while (block < tag_size)
+ {
+ index = 0;
+
+ while (index < T2T_BLOCK_SIZE)
+ {
+ /* check if it is a reserved or locked byte */
+ if (rw_t2t_is_lock_res_byte ((UINT16) ((block * T2T_BLOCK_SIZE) + index)) == FALSE)
+ {
+ count++;
+ }
+ index++;
+ }
+ if (count == T2T_BLOCK_SIZE)
+ {
+ /* All the bytes in the block are free to NDEF write */
+ read_before_write = FALSE;
+ break;
+ }
+ else if (count == 0)
+ {
+ /* The complete block is not free for NDEF write */
+ index = 0;
+ block++;
+ }
+ else
+ {
+ /* The block has reseved byte (s) or locked byte (s) or both */
+ read_before_write = TRUE;
+ break;
+ }
+ }
+ }
+ /* Return the block to read next before NDEF write */
+ *p_block_to_read = block;
+ return read_before_write;
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_write_ndef_first_block
+**
+** Description This function will write the first NDEF block with Length
+** field reset to zero.
+** Also after writting NDEF this function may be called to
+** update new NDEF length
+**
+** Returns NCI_STATUS_OK, if write was started. Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_write_ndef_first_block (UINT16 msg_len, BOOLEAN b_update_len)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ UINT8 new_lengthfield_len;
+ UINT8 write_block[4];
+ UINT8 block;
+ UINT8 *p_cc = &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE];
+ UINT16 total_blocks = p_cc[2] * 2 + T2T_FIRST_DATA_BLOCK;
+ tNFC_STATUS status;
+ UINT8 length_field[3];
+ UINT8 index;
+
+ p_t2t->work_offset = 0;
+ new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN ? T2T_LONG_NDEF_LEN_FIELD_LEN : T2T_SHORT_NDEF_LEN_FIELD_LEN;
+ if (new_lengthfield_len == 3)
+ {
+ /* New NDEF is Long NDEF */
+ if (msg_len == 0)
+ {
+ /* Clear NDEF length field */
+ length_field[0] = 0x00;
+ length_field[1] = 0x00;
+ length_field[2] = 0x00;
+ }
+ else
+ {
+ /* Update NDEF length field with new NDEF Msg len */
+ length_field[0] = T2T_LONG_NDEF_LEN_FIELD_BYTE0;
+ length_field[1] = (UINT8) (msg_len >> 8);
+ length_field[2] = (UINT8) (msg_len);
+ }
+ }
+ else
+ {
+ /* New NDEF is Short NDEF */
+ length_field[0] = (UINT8) (msg_len);
+ }
+
+ /* updating ndef_first_block with new ndef message */
+ memcpy (write_block, p_t2t->ndef_first_block, T2T_BLOCK_SIZE);
+
+ index = p_t2t->ndef_header_offset % T2T_BLOCK_SIZE;
+ block = (UINT8) (p_t2t->ndef_header_offset / T2T_BLOCK_SIZE);
+
+ while (p_t2t->work_offset == 0 && block < total_blocks)
+ {
+ /* update length field */
+ while (index < T2T_BLOCK_SIZE && p_t2t->work_offset < p_t2t->new_ndef_msg_len)
+ {
+ if (rw_t2t_is_lock_res_byte ((UINT16) ((block * T2T_BLOCK_SIZE) + index)) == FALSE)
+ {
+ write_block[index] = length_field[p_t2t->work_offset];
+ p_t2t->work_offset++;
+ }
+ index++;
+ if (p_t2t->work_offset == new_lengthfield_len)
+ {
+ break;
+ }
+ }
+ /* If more space in this block then add ndef message */
+ while (index < T2T_BLOCK_SIZE && p_t2t->work_offset < (p_t2t->new_ndef_msg_len + new_lengthfield_len))
+ {
+ if (rw_t2t_is_lock_res_byte ((UINT16) ((block * T2T_BLOCK_SIZE) + index)) == FALSE)
+ {
+ write_block[index] = p_t2t->p_new_ndef_buffer[p_t2t->work_offset - new_lengthfield_len];
+ p_t2t->work_offset++;
+ }
+ index++;
+ }
+ if (p_t2t->work_offset == 0)
+ {
+ /* If no bytes are written move to next block */
+ index = 0;
+ block++;
+ if (block == p_t2t->ndef_last_block_num)
+ {
+ memcpy (write_block, p_t2t->ndef_last_block, T2T_BLOCK_SIZE);
+ }
+ }
+ }
+ if (p_t2t->work_offset == 0)
+ {
+ status = NFC_STATUS_FAILED;
+ }
+ else
+ {
+ rw_t2t_update_cb (block, write_block, b_update_len);
+ /* Update the identified block with newly prepared data */
+ if ((status = rw_t2t_write (block, write_block)) == NFC_STATUS_OK)
+ {
+ p_t2t->b_read_data = FALSE;
+ }
+ }
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_write_ndef_next_block
+**
+** Description This function can be called to write an NDEF message block
+**
+** Returns NCI_STATUS_OK, if write was started. Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_write_ndef_next_block (UINT16 block, UINT16 msg_len, BOOLEAN b_update_len)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ UINT8 new_lengthfield_len;
+ UINT8 write_block[4];
+ UINT8 *p_cc = &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE];
+ UINT16 total_blocks = p_cc[2] * 2 + T2T_FIRST_DATA_BLOCK;
+ UINT16 initial_offset;
+ UINT8 length_field[3];
+ UINT8 index;
+ tNFC_STATUS status;
+
+ /* Write NDEF Message */
+ new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN ? T2T_LONG_NDEF_LEN_FIELD_LEN : T2T_SHORT_NDEF_LEN_FIELD_LEN;
+
+ index = 0;
+
+ memcpy (write_block, p_t2t->ndef_read_block, T2T_BLOCK_SIZE);
+
+ if (p_t2t->work_offset >= new_lengthfield_len)
+ {
+ /* Length field is updated, write ndef message field */
+ initial_offset = p_t2t->work_offset;
+ while (p_t2t->work_offset == initial_offset && block < total_blocks)
+ {
+ while (index < T2T_BLOCK_SIZE && p_t2t->work_offset < (p_t2t->new_ndef_msg_len + new_lengthfield_len))
+ {
+ if (rw_t2t_is_lock_res_byte ((UINT16) ((block * T2T_BLOCK_SIZE) + index)) == FALSE)
+ {
+ write_block[index] = p_t2t->p_new_ndef_buffer[p_t2t->work_offset - new_lengthfield_len];
+ p_t2t->work_offset++;
+ }
+ index++;
+ }
+ if (p_t2t->work_offset == initial_offset)
+ {
+ index = 0;
+ block++;
+ }
+ }
+ }
+ else
+ {
+ /* Complete writting Length field and then write ndef message */
+ new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN ? T2T_LONG_NDEF_LEN_FIELD_LEN : T2T_SHORT_NDEF_LEN_FIELD_LEN;
+ if (new_lengthfield_len == 3)
+ {
+ /* New NDEF is Long NDEF */
+ if (msg_len == 0)
+ {
+ length_field[0] = 0x00;
+ length_field[1] = 0x00;
+ length_field[2] = 0x00;
+ }
+ else
+ {
+ length_field[0] = T2T_LONG_NDEF_LEN_FIELD_BYTE0;
+ length_field[1] = (UINT8) (msg_len >> 8);
+ length_field[2] = (UINT8) (msg_len);
+ }
+ }
+ else
+ {
+ /* New NDEF is short NDEF */
+ length_field[0] = (UINT8) (msg_len);
+ }
+ initial_offset = p_t2t->work_offset;
+ while (p_t2t->work_offset == initial_offset && block < total_blocks)
+ {
+ /* Update length field */
+ while (index < T2T_BLOCK_SIZE && p_t2t->work_offset < p_t2t->new_ndef_msg_len)
+ {
+ if (rw_t2t_is_lock_res_byte ((UINT16) ((block * T2T_BLOCK_SIZE) + index)) == FALSE)
+ {
+ write_block[index] = length_field[p_t2t->work_offset];
+ p_t2t->work_offset++;
+ }
+ index++;
+ if (p_t2t->work_offset == new_lengthfield_len)
+ {
+ break;
+ }
+ }
+ /* Update ndef message field */
+ while (index < T2T_BLOCK_SIZE && p_t2t->work_offset < (p_t2t->new_ndef_msg_len + new_lengthfield_len))
+ {
+ if (rw_t2t_is_lock_res_byte ((UINT16) ((block * T2T_BLOCK_SIZE) + index)) == FALSE)
+ {
+ write_block[index] = p_t2t->p_new_ndef_buffer[p_t2t->work_offset - new_lengthfield_len];
+ p_t2t->work_offset++;
+ }
+ index++;
+ }
+ if (p_t2t->work_offset == initial_offset)
+ {
+ index = 0;
+ block++;
+ }
+ }
+ }
+ if (p_t2t->work_offset == initial_offset)
+ {
+ status = NFC_STATUS_FAILED;
+ }
+ else
+ {
+ rw_t2t_update_cb (block, write_block, b_update_len);
+ /* Write the NDEF Block */
+ status = rw_t2t_write (block, write_block);
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_update_cb
+**
+** Description This function can be called to write an NDEF message block
+**
+** Returns NCI_STATUS_OK, if write was started. Otherwise, error status.
+**
+*******************************************************************************/
+static void rw_t2t_update_cb (UINT16 block, UINT8 *p_write_block, BOOLEAN b_update_len)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ UINT8 new_lengthfield_len;
+
+ /* Write NDEF Message */
+ new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN ? T2T_LONG_NDEF_LEN_FIELD_LEN : T2T_SHORT_NDEF_LEN_FIELD_LEN;
+
+ if (block == p_t2t->ndef_header_offset / T2T_BLOCK_SIZE)
+ {
+ /* Update ndef first block if the 'block' points to ndef first block */
+ memcpy (p_t2t->ndef_first_block,p_write_block,T2T_BLOCK_SIZE);
+ }
+ if (p_t2t->terminator_byte_index/T2T_BLOCK_SIZE == block)
+ {
+ /* Update terminator block if the 'block' points to terminator tlv block */
+ memcpy (p_t2t->terminator_tlv_block, p_write_block, T2T_BLOCK_LEN);
+ }
+ if (b_update_len == FALSE)
+ {
+ if (block == p_t2t->ndef_last_block_num)
+ {
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK;
+ p_t2t->work_offset = 0;
+ /* Update ndef final block if the 'block' points to ndef final block */
+ memcpy (p_t2t->ndef_last_block,p_write_block,T2T_BLOCK_SIZE);
+ }
+ else
+ {
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK;
+ }
+ }
+ else
+ {
+ if (block == p_t2t->ndef_last_block_num)
+ {
+ /* Update the backup of Ndef final block TLV block */
+ memcpy (p_t2t->ndef_last_block,p_write_block,T2T_BLOCK_SIZE);
+ }
+
+ if (p_t2t->work_offset >= new_lengthfield_len)
+ {
+ if (p_t2t->terminator_byte_index != 0)
+ {
+ /* Add Terminator TLV as part of NDEF Write operation */
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK;
+ }
+ else
+ {
+ /* Skip adding Terminator TLV */
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT;
+ }
+ }
+ else
+ {
+ /* Part of NDEF Message Len should be added in the next block */
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK;
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_get_ndef_flags
+**
+** Description Prepare NDEF Flags
+**
+** Returns NDEF Flag value
+**
+*******************************************************************************/
+static UINT8 rw_t2t_get_ndef_flags (void)
+{
+ UINT8 flags = 0;
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ const tT2T_INIT_TAG *p_ret;
+
+ flags |= RW_NDEF_FL_SUPPORTED;
+
+ if ((p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] == T2T_CC2_TMS_STATIC) || (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] == 0))
+ flags |= RW_NDEF_FL_FORMATABLE;
+
+ if ((p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] & T2T_CC3_RWA_RO) == T2T_CC3_RWA_RO)
+ flags |=RW_NDEF_FL_READ_ONLY;
+
+ if ( ((p_ret = t2t_tag_init_data (p_t2t->tag_hdr[0], FALSE, 0)) != NULL)
+ &&(p_ret->b_otp) )
+ {
+ /* Set otp flag */
+ flags |= RW_NDEF_FL_OTP;
+
+ /* Set Read only flag if otp tag already has NDEF Message */
+ if (p_t2t->ndef_msg_len)
+ flags |= RW_NDEF_FL_READ_ONLY;
+ }
+ return flags;
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_get_ndef_max_size
+**
+** Description Calculate maximum size of NDEF message that can be written
+** on to the tag
+**
+** Returns Maximum size of NDEF Message
+**
+*******************************************************************************/
+static UINT16 rw_t2t_get_ndef_max_size (void)
+{
+ UINT16 offset;
+ UINT8 xx;
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ UINT16 tag_size = (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) + (T2T_FIRST_DATA_BLOCK * T2T_BLOCK_LEN) + p_t2t->num_lockbytes;
+
+ for (xx = 0; xx < p_t2t->num_mem_tlvs; xx++)
+ tag_size += p_t2t->mem_tlv[xx].num_bytes;
+
+ offset = p_t2t->ndef_msg_offset;
+ p_t2t->max_ndef_msg_len = 0;
+
+ if ( (tag_size < T2T_STATIC_SIZE)
+ ||(tag_size > (T2T_SECTOR_SIZE * T2T_MAX_SECTOR))
+ ||((p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != T2T_CC0_NMN) && (p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != 0)) )
+ {
+ /* Tag not formated, assume static tag */
+ p_t2t->max_ndef_msg_len = T2T_STATIC_SIZE - T2T_HEADER_SIZE - T2T_TLV_TYPE_LEN - T2T_SHORT_NDEF_LEN_FIELD_LEN;
+ return p_t2t->max_ndef_msg_len;
+ }
+
+ /* Starting from NDEF Message offset find the first locked data byte */
+ while (offset < tag_size)
+ {
+ if (rw_t2t_is_lock_res_byte ((UINT16) offset) == FALSE)
+ {
+ if (rw_t2t_is_read_only_byte ((UINT16) offset) == TRUE)
+ break;
+ p_t2t->max_ndef_msg_len++;
+ }
+ offset++;
+ }
+ /* NDEF Length field length changes based on NDEF size */
+ if ( (p_t2t->max_ndef_msg_len >= T2T_LONG_NDEF_LEN_FIELD_BYTE0)
+ &&((p_t2t->ndef_msg_offset - p_t2t->ndef_header_offset) == T2T_SHORT_NDEF_LEN_FIELD_LEN) )
+ {
+ p_t2t->max_ndef_msg_len -= (p_t2t->max_ndef_msg_len == T2T_LONG_NDEF_LEN_FIELD_BYTE0) ? 1: (T2T_LONG_NDEF_LEN_FIELD_LEN - T2T_SHORT_NDEF_LEN_FIELD_LEN);
+ }
+ return p_t2t->max_ndef_msg_len;
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_add_terminator_tlv
+**
+** Description This function will add terminator TLV after NDEF Message
+**
+** Returns NCI_STATUS_OK, if write was started. Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_add_terminator_tlv (void)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ tNFC_STATUS status;
+ UINT16 block;
+
+ /* Add Terminator TLV after NDEF Message */
+ p_t2t->terminator_tlv_block[p_t2t->terminator_byte_index%T2T_BLOCK_LEN] = TAG_TERMINATOR_TLV;
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT;
+
+ block = p_t2t->terminator_byte_index/T2T_BLOCK_LEN;
+ status = rw_t2t_write (block, p_t2t->terminator_tlv_block);
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_handle_ndef_read_rsp
+**
+** Description This function handles reading an NDEF message.
+**
+** Returns none
+**
+*******************************************************************************/
+static void rw_t2t_handle_ndef_read_rsp (UINT8 *p_data)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ tRW_READ_DATA evt_data;
+ UINT16 len;
+ UINT16 offset;
+ BOOLEAN failed = FALSE;
+ BOOLEAN done = FALSE;
+
+ /* On the first read, adjust for any partial block offset */
+ offset = 0;
+ len = T2T_READ_DATA_LEN;
+
+ if (p_t2t->work_offset == 0)
+ {
+ /* The Ndef Message offset may be present in the read 16 bytes */
+ offset = (p_t2t->ndef_msg_offset - (p_t2t->block_read * T2T_BLOCK_SIZE));
+ }
+
+ /* Skip all reserved and lock bytes */
+ while ( (offset < len)
+ &&(p_t2t->work_offset<p_t2t->ndef_msg_len) )
+
+ {
+ if (rw_t2t_is_lock_res_byte ((UINT16) (offset + p_t2t->block_read * T2T_BLOCK_LEN)) == FALSE)
+ {
+ /* Collect the NDEF Message */
+ p_t2t->p_ndef_buffer[p_t2t->work_offset] = p_data[offset];
+ p_t2t->work_offset++;
+ }
+ offset++;
+ }
+
+ if (p_t2t->work_offset >= p_t2t->ndef_msg_len)
+ {
+ done = TRUE;
+ p_t2t->ndef_status = T2T_NDEF_READ;
+ }
+ else
+ {
+ /* Read next 4 blocks */
+ if (rw_t2t_read ((UINT16) (p_t2t->block_read + T2T_READ_BLOCKS)) != NFC_STATUS_OK)
+ failed = TRUE;
+ }
+
+ if (failed || done)
+ {
+ evt_data.status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK;
+ evt_data.p_data = NULL;
+ rw_t2t_handle_op_complete ();
+ (*rw_cb.p_cback) (RW_T2T_NDEF_READ_EVT, (tRW_DATA *) &evt_data);
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_handle_ndef_write_rsp
+**
+** Description Handle response received to reading (or part of) NDEF message.
+**
+** Returns none
+**
+*******************************************************************************/
+static void rw_t2t_handle_ndef_write_rsp (UINT8 *p_data)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ tRW_READ_DATA evt_data;
+ BOOLEAN failed = FALSE;
+ BOOLEAN done = FALSE;
+ UINT16 block;
+ UINT8 offset;
+
+ switch (p_t2t->substate)
+ {
+ case RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK:
+
+ /* Backup the read NDEF first block */
+ memcpy (p_t2t->ndef_first_block, p_data, T2T_BLOCK_LEN);
+ /* Read ndef final block */
+ if (rw_t2t_read_ndef_last_block () != NFC_STATUS_OK)
+ failed = TRUE;
+ break;
+
+ case RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK:
+
+ offset = (UINT8) (p_t2t->ndef_last_block_num - p_t2t->block_read) * T2T_BLOCK_SIZE;
+ /* Backup the read NDEF final block */
+ memcpy (p_t2t->ndef_last_block, &p_data[offset], T2T_BLOCK_LEN);
+ if ((p_t2t->terminator_byte_index / T2T_BLOCK_SIZE) == p_t2t->ndef_last_block_num)
+ {
+ /* If Terminator TLV will reside on the NDEF Final block */
+ memcpy (p_t2t->terminator_tlv_block, p_t2t->ndef_last_block, T2T_BLOCK_LEN);
+ if (rw_t2t_write_ndef_first_block (0x0000, FALSE)!= NFC_STATUS_OK)
+ failed = TRUE;
+ }
+ else if (p_t2t->terminator_byte_index != 0)
+ {
+ /* If there is space for Terminator TLV and if it will reside outside NDEF Final block */
+ if (rw_t2t_read_terminator_tlv_block ()!= NFC_STATUS_OK)
+ failed = TRUE;
+ }
+ else
+ {
+ if (rw_t2t_write_ndef_first_block (0x0000, FALSE)!= NFC_STATUS_OK)
+ failed = TRUE;
+ }
+ break;
+
+ case RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK:
+
+ offset = (UINT8) (((p_t2t->terminator_byte_index / T2T_BLOCK_SIZE) - p_t2t->block_read) * T2T_BLOCK_SIZE);
+ /* Backup the read Terminator TLV block */
+ memcpy (p_t2t->terminator_tlv_block, &p_data[offset], T2T_BLOCK_LEN);
+
+ /* Write the first block for new NDEF Message */
+ if (rw_t2t_write_ndef_first_block (0x0000, FALSE)!= NFC_STATUS_OK)
+ failed = TRUE;
+ break;
+
+ case RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK:
+
+ offset = (UINT8) (p_t2t->ndef_read_block_num - p_t2t->block_read) * T2T_BLOCK_SIZE;
+ /* Backup read block */
+ memcpy (p_t2t->ndef_read_block, &p_data[offset], T2T_BLOCK_LEN);
+
+ /* Update the block with new NDEF Message */
+ if (rw_t2t_write_ndef_next_block (p_t2t->ndef_read_block_num, 0x0000, FALSE) != NFC_STATUS_OK)
+ failed = TRUE;
+ break;
+
+ case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK:
+ case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK:
+ if (rw_t2t_is_read_before_write_block ((UINT16) (p_t2t->block_written + 1), &block) == TRUE)
+ {
+ p_t2t->ndef_read_block_num = block;
+ /* If only part of the block is going to be updated read the block to retain previous data for
+ unchanged part of the block */
+ if (rw_t2t_read_ndef_next_block (block) != NFC_STATUS_OK)
+ failed = TRUE;
+ }
+ else
+ {
+ if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK)
+ {
+ /* Directly write the block with new NDEF contents as whole block is going to be updated */
+ if (rw_t2t_write_ndef_next_block (block, p_t2t->new_ndef_msg_len, TRUE)!= NFC_STATUS_OK)
+ failed = TRUE;
+ }
+ else
+ {
+ /* Directly write the block with new NDEF contents as whole block is going to be updated */
+ if (rw_t2t_write_ndef_next_block (block, 0x0000, FALSE)!= NFC_STATUS_OK)
+ failed = TRUE;
+ }
+ }
+ break;
+
+ case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK:
+ /* Write the next block for new NDEF Message */
+ p_t2t->ndef_write_block = p_t2t->ndef_header_offset / T2T_BLOCK_SIZE;
+ if (rw_t2t_is_read_before_write_block ((UINT16) (p_t2t->ndef_write_block), &block) == TRUE)
+ {
+ /* If only part of the block is going to be updated read the block to retain previous data for
+ part of the block thats not going to be changed */
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK;
+ if (rw_t2t_read (block) != NFC_STATUS_OK)
+ failed = TRUE;
+
+ }
+ else
+ {
+ /* Update NDEF Message Length in the Tag */
+ if (rw_t2t_write_ndef_first_block (p_t2t->new_ndef_msg_len, TRUE)!= NFC_STATUS_OK)
+ failed = TRUE;
+ }
+ break;
+
+ case RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK:
+ /* Backup read block */
+ memcpy (p_t2t->ndef_read_block, p_data, T2T_BLOCK_LEN);
+
+ /* Update the block with new NDEF Message */
+ if (rw_t2t_write_ndef_next_block (p_t2t->block_read, p_t2t->new_ndef_msg_len, TRUE) == NFC_STATUS_OK)
+ p_t2t->ndef_write_block = p_t2t->block_read + 1;
+ else
+ failed = TRUE;
+
+ break;
+
+ case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK:
+ if (rw_t2t_add_terminator_tlv ()!= NFC_STATUS_OK)
+ failed = TRUE;
+ break;
+
+ case RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT:
+ done = TRUE;
+ break;
+
+ default:
+ break;
+ }
+
+ if (failed || done)
+ {
+ evt_data.p_data = NULL;
+ /* NDEF WRITE Operation is done, inform up the stack */
+ evt_data.status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK;
+ if (done)
+ {
+ if ( (p_t2t->ndef_msg_len >= 0x00FF)
+ &&(p_t2t->new_ndef_msg_len < 0x00FF) )
+ {
+ p_t2t->ndef_msg_offset -= 2;
+ }
+ else if ( (p_t2t->new_ndef_msg_len >= 0x00FF)
+ &&(p_t2t->ndef_msg_len < 0x00FF) )
+ {
+ p_t2t->ndef_msg_offset += 2;
+ }
+ p_t2t->ndef_msg_len = p_t2t->new_ndef_msg_len;
+ }
+ rw_t2t_handle_op_complete ();
+ (*rw_cb.p_cback) (RW_T2T_NDEF_WRITE_EVT, (tRW_DATA *) &evt_data);
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_get_tag_size
+**
+** Description This function calculates tag data area size from data read
+** from block with version number
+**
+** Returns TMS of the tag
+**
+*******************************************************************************/
+static UINT8 rw_t2t_get_tag_size (UINT8 *p_data)
+{
+ UINT16 LchunkSize = 0;
+ UINT16 Num_LChuncks = 0;
+ UINT16 tms = 0;
+
+ LchunkSize = (UINT16) p_data[2] << 8 | p_data[3];
+ Num_LChuncks = (UINT16) p_data[4] << 8 | p_data[5];
+
+ tms = (UINT16) (LchunkSize * Num_LChuncks);
+
+ tms += (T2T_STATIC_SIZE - T2T_HEADER_SIZE);
+
+ tms /= 0x08;
+
+ return (UINT8) tms;
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_handle_config_tag_readonly
+**
+** Description This function handles configure type 2 tag as read only
+**
+** Returns none
+**
+*******************************************************************************/
+static void rw_t2t_handle_config_tag_readonly (UINT8 *p_data)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ BOOLEAN b_notify = FALSE;
+ UINT8 write_block[T2T_BLOCK_SIZE];
+ tRW_DATA evt;
+ BOOLEAN b_pending = FALSE;
+ UINT8 read_lock = 0;
+ UINT8 num_locks = 0;
+ UINT16 offset;
+
+ switch (p_t2t->substate)
+ {
+ case RW_T2T_SUBSTATE_WAIT_READ_CC:
+
+ /* First soft lock the tag */
+ rw_t2t_soft_lock_tag ();
+
+ break;
+
+ case RW_T2T_SUBSTATE_WAIT_SET_CC_RO:
+
+ /* Successfully soft locked! Update Tag header for future reference */
+ p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] = T2T_CC3_RWA_RO;
+ if (!p_t2t->b_hard_lock)
+ {
+ /* Tag configuration complete */
+ status = NFC_STATUS_OK;
+ b_notify = TRUE;
+ break;
+ }
+
+ /* Coverity: [FALSE-POSITIVE error] intended fall through */
+ /* Missing break statement between cases in switch statement */
+ /* fall through */
+ case RW_T2T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS:
+
+ num_locks = 0;
+
+ while (num_locks < p_t2t->num_lockbytes)
+ {
+ if (p_t2t->lockbyte[num_locks].lock_status == RW_T2T_LOCK_UPDATE_INITIATED)
+ {
+ /* Update control block as one or more dynamic lock byte (s) are set */
+ p_t2t->lockbyte[num_locks].lock_status = RW_T2T_LOCK_UPDATED;
+ }
+ if (!b_pending && p_t2t->lockbyte[num_locks].lock_status == RW_T2T_LOCK_NOT_UPDATED)
+ {
+ /* One or more dynamic lock bits are not set */
+ b_pending = TRUE;
+ read_lock = num_locks;
+ }
+ num_locks++;
+ }
+
+ if (b_pending)
+ {
+ /* Read the block where dynamic lock bits are present to avoid writing to NDEF bytes in the same block */
+ offset = p_t2t->lock_tlv[p_t2t->lockbyte[read_lock].tlv_index].offset + p_t2t->lockbyte[read_lock].byte_index;
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_DYN_LOCK_BYTE_BLOCK;
+ status = rw_t2t_read ((UINT16) (offset / T2T_BLOCK_LEN));
+ }
+ else
+ {
+ /* Now set Static lock bits as no more dynamic lock bits to set */
+
+ /* Copy the internal bytes */
+ memcpy (write_block, &p_t2t->tag_hdr[T2T_STATIC_LOCK0 - T2T_INTERNAL_BYTES_LEN], T2T_INTERNAL_BYTES_LEN);
+ /* Set all Static lock bits */
+ write_block [T2T_STATIC_LOCK0 % T2T_BLOCK_SIZE] = 0xFF;
+ write_block [T2T_STATIC_LOCK1 % T2T_BLOCK_SIZE] = 0xFF;
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_ST_LOCK_BITS;
+ status = rw_t2t_write ((T2T_STATIC_LOCK0 / T2T_BLOCK_SIZE), write_block);
+ }
+ break;
+
+ case RW_T2T_SUBSTATE_WAIT_READ_DYN_LOCK_BYTE_BLOCK:
+ /* Now set the dynamic lock bits present in the block read now */
+ status = rw_t2t_set_dynamic_lock_bits (p_data);
+ break;
+
+ case RW_T2T_SUBSTATE_WAIT_SET_ST_LOCK_BITS:
+ /* Tag configuration complete */
+ status = NFC_STATUS_OK;
+ b_notify = TRUE;
+ break;
+
+ }
+
+ if (status != NFC_STATUS_OK || b_notify)
+ {
+ /* Notify upper layer the result of Configuring Tag as Read only */
+ evt.status = status;
+ rw_t2t_handle_op_complete ();
+ (*rw_cb.p_cback) (RW_T2T_SET_TAG_RO_EVT, (tRW_DATA *) &evt);
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_handle_format_tag_rsp
+**
+** Description This function handles formating a type 2 tag
+**
+** Returns none
+**
+*******************************************************************************/
+static void rw_t2t_handle_format_tag_rsp (UINT8 *p_data)
+{
+ tRW_DATA evt;
+ UINT8 *p;
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ UINT16 version_no;
+ const tT2T_INIT_TAG *p_ret;
+ UINT8 tms;
+ UINT8 next_block = T2T_FIRST_DATA_BLOCK + 1;
+ UINT16 addr, locked_area;
+ BOOLEAN b_notify = FALSE;
+
+
+ p = p_t2t->ndef_final_block;
+ UINT8_TO_BE_STREAM (p, p_t2t->tlv_value[2]);
+
+ switch (p_t2t->substate)
+ {
+ case RW_T2T_SUBSTATE_WAIT_READ_CC:
+ /* Start format operation */
+ status = rw_t2t_format_tag ();
+ break;
+
+ case RW_T2T_SUBSTATE_WAIT_READ_VERSION_INFO:
+
+ memcpy (p_t2t->tag_data, p_data, T2T_READ_DATA_LEN);
+ p_t2t->b_read_data = TRUE;
+ version_no = (UINT16) p_data[0] << 8 | p_data[1];
+ if ((p_ret = t2t_tag_init_data (p_t2t->tag_hdr[0], TRUE, version_no)) != NULL)
+ {
+ /* Valid Version Number */
+ if (p_ret->b_calc_cc)
+ /* Calculate tag size from Version Information */
+ tms = rw_t2t_get_tag_size (p_data);
+
+ else
+ /* Tag size from Look up table */
+ tms = p_ret->tms;
+
+ /* Set CC with the Tag size from look up table or from calculated value */
+ status = rw_t2t_set_cc (tms);
+ }
+ break;
+
+ case RW_T2T_SUBSTATE_WAIT_SET_CC:
+
+ version_no = (UINT16) p_t2t->tag_data[0] << 8 | p_t2t->tag_data[1];
+ if ( (version_no == 0)
+ ||((p_ret = t2t_tag_init_data (p_t2t->tag_hdr[0], TRUE, version_no)) == NULL)
+ ||(!p_ret->b_multi_version)
+ ||(!p_ret->b_calc_cc) )
+ {
+ /* Currently Formating a non blank tag or a blank tag with manufacturer
+ * has only one variant of tag. Set Null NDEF TLV and complete Format Operation */
+ next_block = T2T_FIRST_DATA_BLOCK;
+ p = p_t2t->ndef_final_block;
+ }
+ else
+ {
+ addr = (UINT16) (((UINT16) p_t2t->tag_data[2] << 8 | p_t2t->tag_data[3]) * ((UINT16) p_t2t->tag_data[4] << 8 | p_t2t->tag_data[5]) + T2T_STATIC_SIZE);
+ locked_area = ((UINT16) p_t2t->tag_data[2] << 8 | p_t2t->tag_data[3]) * ((UINT16) p_t2t->tag_data[6]);
+
+ if ((status = rw_t2t_set_lock_tlv (addr, p_t2t->tag_data[7], locked_area)) == NFC_STATUS_REJECTED)
+ {
+ /* Cannot calculate Lock TLV. Set Null NDEF TLV and complete Format Operation */
+ next_block = T2T_FIRST_DATA_BLOCK;
+ p = p_t2t->ndef_final_block;
+ }
+ else
+ break;
+ }
+
+ /* falls through */
+ case RW_T2T_SUBSTATE_WAIT_SET_LOCK_TLV:
+
+ /* Prepare NULL NDEF TLV, TERMINATOR_TLV */
+ UINT8_TO_BE_STREAM (p, TAG_NDEF_TLV);
+ UINT8_TO_BE_STREAM (p, 0);
+
+ if ( ((p_ret = t2t_tag_init_data (p_t2t->tag_hdr[0], FALSE, 0)) != NULL)
+ &&(!p_ret->b_otp) )
+ {
+ UINT8_TO_BE_STREAM (p, TAG_TERMINATOR_TLV);
+ }
+ else
+ UINT8_TO_BE_STREAM (p, 0);
+
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_NULL_NDEF;
+ /* send WRITE-E8 command */
+ if ((status = rw_t2t_write (next_block, p_t2t->ndef_final_block)) == NFC_STATUS_OK)
+ p_t2t->b_read_data = FALSE;
+ break;
+
+ case RW_T2T_SUBSTATE_WAIT_SET_NULL_NDEF:
+ /* Tag Formated successfully */
+ status = NFC_STATUS_OK;
+ b_notify = TRUE;
+ break;
+
+ default:
+ break;
+
+ }
+
+ if (status != NFC_STATUS_OK || b_notify)
+ {
+ /* Notify upper layer the result of Format op */
+ evt.status = status;
+ rw_t2t_handle_op_complete ();
+ (*rw_cb.p_cback) (RW_T2T_FORMAT_CPLT_EVT, (tRW_DATA *) &evt);
+ }
+
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_update_attributes
+**
+** Description This function will update attribute for the current segment
+** based on lock and reserved bytes
+**
+** Returns None
+**
+*******************************************************************************/
+static void rw_t2t_update_attributes (void)
+{
+ UINT8 count = 0;
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ UINT16 lower_offset;
+ UINT16 upper_offset;
+ UINT16 offset;
+ UINT8 num_bytes;
+
+ /* Prepare attr for the current segment */
+ memset (p_t2t->attr, 0, RW_T2T_SEGMENT_SIZE * sizeof (UINT8));
+
+ /* calculate offset where the current segment starts in the tag */
+ lower_offset = p_t2t->segment * RW_T2T_SEGMENT_BYTES;
+ /* calculate offset where the current segment ends in the tag */
+ upper_offset = (p_t2t->segment + 1) * RW_T2T_SEGMENT_BYTES;
+
+
+ /* check offset of lock bytes in the tag and update p_t2t->attr
+ * for every lock byte that is present in the current segment */
+ count = 0;
+ while (count < p_t2t->num_lockbytes)
+ {
+ offset = p_t2t->lock_tlv[p_t2t->lockbyte[count].tlv_index].offset + p_t2t->lockbyte[count].byte_index;
+ if (offset >= lower_offset && offset < upper_offset)
+ {
+ /* Calculate offset in the current segment as p_t2t->attr is prepared for one segment only */
+ offset %= RW_T2T_SEGMENT_BYTES;
+ /* Every bit in p_t2t->attr indicates one byte of the tag is either a lock/reserved byte or not
+ * So, each array element in p_t2t->attr covers two blocks in the tag as T2 block size is 4 and array element size is 8
+ * Set the corresponding bit in attr to indicate - reserved byte */
+ p_t2t->attr[offset / TAG_BITS_PER_BYTE] |= rw_t2t_mask_bits[offset % TAG_BITS_PER_BYTE];
+ }
+ count++;
+ }
+
+
+ /* Search reserved bytes identified by all memory tlvs present in the tag */
+ count = 0;
+ while (count < p_t2t->num_mem_tlvs)
+ {
+ /* check the offset of reserved bytes in the tag and update p_t2t->attr
+ * for every reserved byte that is present in the current segment */
+ num_bytes = 0;
+ while (num_bytes < p_t2t->mem_tlv[count].num_bytes)
+ {
+ offset = p_t2t->mem_tlv[count].offset + num_bytes;
+ if (offset >= lower_offset && offset < upper_offset)
+ {
+ /* Let offset represents offset in the current segment as p_t2t->attr is prepared for one segment only */
+ offset %= RW_T2T_SEGMENT_BYTES;
+ /* Every bit in p_t2t->attr indicates one byte of the tag is either a lock/reserved byte or not
+ * So, each array element in p_t2t->attr covers two blocks in the tag as T2 block size is 4 and array element size is 8
+ * Set the corresponding bit in attr to indicate - reserved byte */
+ p_t2t->attr[offset /TAG_BITS_PER_BYTE] |= rw_t2t_mask_bits[offset % TAG_BITS_PER_BYTE];
+ }
+ num_bytes++;
+ }
+ count++;
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_get_lock_bits_for_segment
+**
+** Description This function returns the offset of lock bits associated for
+** the specified segment
+**
+** Parameters: segment: The segment number to which lock bits are associated
+** p_start_byte: The offset of lock byte that contains the first
+** lock bit for the segment
+** p_start_bit: The offset of the lock bit in the lock byte
+**
+** p_end_byte: The offset of the last bit associcated to the
+** segment
+**
+** Returns Total number of lock bits assigned to the specified segment
+**
+*******************************************************************************/
+static UINT8 rw_t2t_get_lock_bits_for_segment (UINT8 segment, UINT8 *p_start_byte, UINT8 *p_start_bit, UINT8 *p_end_byte)
+{
+ UINT8 total_bits = 0;
+ UINT16 byte_count = 0;
+ UINT16 lower_offset, upper_offset;
+ UINT8 num_dynamic_locks = 0;
+ UINT8 bit_count = 0;
+ UINT8 bytes_locked_per_bit;
+ UINT8 num_bits;
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ BOOLEAN b_all_bits_are_locks = TRUE;
+ UINT16 tag_size;
+ UINT8 xx;
+
+ tag_size = (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) + (T2T_FIRST_DATA_BLOCK * T2T_BLOCK_SIZE) + p_t2t->num_lockbytes;
+
+ for (xx = 0; xx < p_t2t->num_mem_tlvs; xx++)
+ tag_size += p_t2t->mem_tlv[xx].num_bytes;
+
+ lower_offset = segment * RW_T2T_SEGMENT_BYTES;
+ if (segment == 0)
+ {
+ lower_offset += T2T_STATIC_SIZE;
+ }
+ upper_offset = (segment + 1) * RW_T2T_SEGMENT_BYTES;
+
+ byte_count = T2T_STATIC_SIZE;
+ if (tag_size < upper_offset)
+ {
+ upper_offset = tag_size;
+ }
+
+ *p_start_byte = num_dynamic_locks;
+ *p_start_bit = 0;
+
+ while ( (byte_count <= lower_offset)
+ &&(num_dynamic_locks < p_t2t->num_lockbytes) )
+ {
+ bytes_locked_per_bit = p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index].bytes_locked_per_bit;
+ /* Number of bits in the current lock byte */
+ b_all_bits_are_locks = ((p_t2t->lockbyte[num_dynamic_locks].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index].num_bits);
+ num_bits = b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index].num_bits % TAG_BITS_PER_BYTE;
+
+ if (((bytes_locked_per_bit * num_bits) + byte_count) <= lower_offset)
+ {
+ /* Skip this lock byte as it covers different segment */
+ byte_count += bytes_locked_per_bit * num_bits;
+ num_dynamic_locks++;
+ }
+ else
+ {
+ bit_count = 0;
+ while (bit_count < num_bits)
+ {
+ byte_count += bytes_locked_per_bit;
+ if (byte_count > lower_offset)
+ {
+ /* First lock bit that is used to lock this segment */
+ *p_start_byte = num_dynamic_locks;
+ *p_end_byte = num_dynamic_locks;
+ *p_start_bit = bit_count;
+ bit_count++;
+ total_bits = 1;
+ break;
+ }
+ bit_count++;
+ }
+ }
+ }
+ if (num_dynamic_locks == p_t2t->num_lockbytes)
+ {
+ return 0;
+ }
+ while ( (byte_count < upper_offset)
+ &&(num_dynamic_locks < p_t2t->num_lockbytes) )
+ {
+ bytes_locked_per_bit = p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index].bytes_locked_per_bit;
+ /* Number of bits in the current lock byte */
+ b_all_bits_are_locks = ((p_t2t->lockbyte[num_dynamic_locks].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index].num_bits);
+ num_bits = b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index].num_bits % TAG_BITS_PER_BYTE;
+
+ if ((bytes_locked_per_bit * (num_bits - bit_count)) + byte_count < upper_offset)
+ {
+ /* Collect all lock bits that covers the current segment */
+ byte_count += bytes_locked_per_bit * (num_bits - bit_count);
+ total_bits += num_bits - bit_count;
+ bit_count = 0;
+ *p_end_byte = num_dynamic_locks;
+ num_dynamic_locks++;
+ }
+ else
+ {
+ /* The last lock byte that covers the current segment */
+ bit_count = 0;
+ while (bit_count < num_bits)
+ {
+ /* The last lock bit that is used to lock this segment */
+ byte_count += bytes_locked_per_bit;
+ if (byte_count >= upper_offset)
+ {
+ *p_end_byte = num_dynamic_locks;
+ total_bits += (bit_count + 1);
+ break;
+ }
+ bit_count++;
+ }
+ }
+ }
+ return total_bits;
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_update_lock_attributes
+**
+** Description This function will check if the tag index passed as
+** argument is a locked byte and return TRUE or FALSE
+**
+** Parameters: index, the index of the byte in the tag
+**
+**
+** Returns TRUE, if the specified index in the tag is a locked or
+** reserved or otp byte
+** FALSE, otherwise
+**
+*******************************************************************************/
+static void rw_t2t_update_lock_attributes (void)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ UINT8 xx = 0;
+ UINT8 num_static_lock_bytes = 0;
+ UINT8 num_dyn_lock_bytes = 0;
+ UINT8 bits_covered = 0;
+ UINT8 bytes_covered = 0;
+ UINT8 block_count = 0;
+ BOOLEAN b_all_bits_are_locks = TRUE;
+ UINT8 bytes_locked_per_lock_bit;
+ UINT8 start_lock_byte;
+ UINT8 start_lock_bit;
+ UINT8 end_lock_byte;
+ UINT8 num_lock_bits;
+ UINT8 total_bits;
+
+
+ /* Prepare lock_attr for the current segment */
+ memset (p_t2t->lock_attr, 0, RW_T2T_SEGMENT_SIZE * sizeof (UINT8));
+
+ block_count = 0;
+ if (p_t2t->segment == 0)
+ {
+ /* Update lock_attributes based on static lock bytes */
+ xx = 0;
+ num_static_lock_bytes = 0;
+ block_count = 0;
+ num_lock_bits = TAG_BITS_PER_BYTE - 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 */
+ if ((total_bits = rw_t2t_get_lock_bits_for_segment (p_t2t->segment,&start_lock_byte, &start_lock_bit, &end_lock_byte)) != 0)
+ {
+ /* update lock_attributes based on current segment using dynamic lock bytes */
+ xx = start_lock_bit;
+ num_dyn_lock_bytes = start_lock_byte;
+ bits_covered = 0;
+ bytes_covered = 0;
+ num_lock_bits = TAG_BITS_PER_BYTE;
+ p_t2t->lock_attr[block_count] = 0;
+
+ while (num_dyn_lock_bytes <= end_lock_byte)
+ {
+ bytes_locked_per_lock_bit = p_t2t->lock_tlv[p_t2t->lockbyte[num_dyn_lock_bytes].tlv_index].bytes_locked_per_bit;
+ /* Find number of bits in the byte are lock bits */
+ b_all_bits_are_locks = ((p_t2t->lockbyte[num_dyn_lock_bytes].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t2t->lock_tlv[p_t2t->lockbyte[num_dyn_lock_bytes].tlv_index].num_bits);
+ num_lock_bits = b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t2t->lock_tlv[p_t2t->lockbyte[num_dyn_lock_bytes].tlv_index].num_bits % TAG_BITS_PER_BYTE;
+
+ while (xx < num_lock_bits)
+ {
+ bytes_covered = 0;
+ while (bytes_covered < bytes_locked_per_lock_bit)
+ {
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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 BOOLEAN rw_t2t_is_lock_res_byte (UINT16 index)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+
+ p_t2t->segment = (UINT8) (index / RW_T2T_SEGMENT_BYTES);
+
+ if (p_t2t->attr_seg != p_t2t->segment)
+ {
+ /* Update attributes for the current segment */
+ rw_t2t_update_attributes ();
+ p_t2t->attr_seg = p_t2t->segment;
+ }
+
+ index = index % RW_T2T_SEGMENT_BYTES;
+ /* Every bit in p_t2t->attr indicates one specific byte of the tag is either a lock/reserved byte or not
+ * So, each array element in p_t2t->attr covers two blocks in the tag as T2 block size is 4 and array element size is 8
+ * Find the block and offset for the index (passed as argument) and Check if the offset bit in the
+ * p_t2t->attr[block/2] is set or not. If the bit is set then it is a lock/reserved byte, otherwise not */
+
+ return ((p_t2t->attr[index /8] & rw_t2t_mask_bits[index % 8]) == 0) ? FALSE:TRUE;
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_is_read_only_byte
+**
+** Description This function will check if the tag index passed as
+** argument is a locked and return
+** TRUE or FALSE
+**
+** Parameters: index, the index of the byte in the tag
+**
+**
+** Returns TRUE, if the specified index in the tag is a locked or
+** reserved or otp byte
+** FALSE, otherwise
+**
+*******************************************************************************/
+static BOOLEAN rw_t2t_is_read_only_byte (UINT16 index)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+
+ p_t2t->segment = (UINT8) (index / RW_T2T_SEGMENT_BYTES);
+
+ if (p_t2t->lock_attr_seg != p_t2t->segment)
+ {
+ /* Update lock attributes for the current segment */
+ rw_t2t_update_lock_attributes ();
+ p_t2t->lock_attr_seg = p_t2t->segment;
+ }
+
+ index = index % RW_T2T_SEGMENT_BYTES;
+ /* Every bit in p_t2t->lock_attr indicates one specific byte of the tag is a read only byte or read write byte
+ * So, each array element in p_t2t->lock_attr covers two blocks of the tag as T2 block size is 4 and array element size is 8
+ * Find the block and offset for the index (passed as argument) and Check if the offset bit in
+ * p_t2t->lock_attr[block/2] is set or not. If the bit is set then it is a read only byte, otherwise read write byte */
+
+ return ((p_t2t->lock_attr[index /8] & rw_t2t_mask_bits[index % 8]) == 0) ? FALSE:TRUE;
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_set_dynamic_lock_bits
+**
+** Description This function will set dynamic lock bits as part of
+** configuring tag as read only
+**
+** Returns
+** NFC_STATUS_OK, Command sent to set dynamic lock bits
+** NFC_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_set_dynamic_lock_bits (UINT8 *p_data)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ UINT8 write_block[T2T_BLOCK_SIZE];
+ UINT16 offset;
+ UINT16 next_offset;
+ UINT8 num_bits;
+ UINT8 next_num_bits;
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ UINT8 num_locks;
+ UINT8 lock_count;
+ BOOLEAN b_all_bits_are_locks = TRUE;
+
+ num_locks = 0;
+
+ memcpy (write_block, p_data, T2T_BLOCK_SIZE);
+ while (num_locks < p_t2t->num_lockbytes)
+ {
+ if (p_t2t->lockbyte[num_locks].lock_status == RW_T2T_LOCK_NOT_UPDATED)
+ {
+ offset = p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].offset + p_t2t->lockbyte[num_locks].byte_index;
+
+ /* Check if all bits are lock bits in the byte */
+ b_all_bits_are_locks = ((p_t2t->lockbyte[num_locks].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].num_bits);
+ num_bits = b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].num_bits % TAG_BITS_PER_BYTE;
+
+ write_block[(UINT8) (offset%T2T_BLOCK_SIZE)] |= tags_pow (2,num_bits) - 1;
+ lock_count = num_locks + 1;
+
+ /* Set all the lock bits in the block using a sing block write command */
+ while (lock_count < p_t2t->num_lockbytes)
+ {
+ next_offset = p_t2t->lock_tlv[p_t2t->lockbyte[lock_count].tlv_index].offset + p_t2t->lockbyte[lock_count].byte_index;
+
+ /* Check if all bits are lock bits in the byte */
+ b_all_bits_are_locks = ((p_t2t->lockbyte[lock_count].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t2t->lock_tlv[p_t2t->lockbyte[lock_count].tlv_index].num_bits);
+ next_num_bits = b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t2t->lock_tlv[p_t2t->lockbyte[lock_count].tlv_index].num_bits % TAG_BITS_PER_BYTE;
+
+ if (next_offset / T2T_BLOCK_SIZE == offset / T2T_BLOCK_SIZE)
+ {
+ write_block[(UINT8) (next_offset % T2T_BLOCK_SIZE)] |= tags_pow (2, next_num_bits) - 1;
+ }
+ else
+ break;
+ lock_count ++;
+ }
+
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
+ /* send WRITE command to set dynamic lock bits */
+ if ((status = rw_t2t_write ((UINT16) (offset / T2T_BLOCK_SIZE), write_block)) == NFC_STATUS_OK)
+ {
+ while (lock_count > num_locks)
+ {
+ /* Set update initiated flag to indicate a write command is sent to set dynamic lock bits of the block */
+ p_t2t->lockbyte[lock_count - 1].lock_status = RW_T2T_LOCK_UPDATE_INITIATED;
+ lock_count --;
+ }
+ }
+ else
+ status = NFC_STATUS_FAILED;
+
+ break;
+
+ }
+ num_locks++;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_set_lock_tlv
+**
+** Description This function will set lock control tlv on the blank
+** activated type 2 tag based on values read from version block
+**
+** Parameters: TAG data memory size
+**
+** Returns
+** NFC_STATUS_OK, Command sent to set Lock TLV
+** NFC_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_set_lock_tlv (UINT16 addr, UINT8 num_dyn_lock_bits, UINT16 locked_area_size)
+{
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ INT8 PageAddr = 0;
+ INT8 BytePerPage = 0;
+ INT8 ByteOffset = 0;
+ UINT8 a;
+ UINT8 data_block[T2T_BLOCK_SIZE];
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ UINT8 *p;
+ UINT8 xx;
+
+ for (xx = 15; xx >0; xx--)
+ {
+ a = (UINT8) (addr / xx);
+ a += (addr % xx) ? 1:0;
+
+ BytePerPage = (INT8) tags_log2 (a);
+ ByteOffset = (INT8) (addr - xx * tags_pow (2, BytePerPage));
+
+ if (ByteOffset < 16)
+ {
+ PageAddr = xx;
+ break;
+ }
+ }
+
+ if ((ByteOffset < 16) && (BytePerPage < 16) && (PageAddr < 16))
+ {
+ memset (data_block, 0, T2T_BLOCK_SIZE);
+ p = data_block;
+ UINT8_TO_BE_STREAM (p, T2T_TLV_TYPE_LOCK_CTRL);
+ UINT8_TO_BE_STREAM (p, T2T_TLEN_LOCK_CTRL_TLV);
+ UINT8_TO_BE_STREAM (p, (PageAddr << 4 | ByteOffset));
+ UINT8_TO_BE_STREAM (p, num_dyn_lock_bits);
+
+ p_t2t->tlv_value[0] = PageAddr << 4 | ByteOffset;
+ p_t2t->tlv_value[1] = num_dyn_lock_bits;
+ p_t2t->tlv_value[2] = (UINT8) (BytePerPage << 4 | tags_log2 (locked_area_size));
+
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_LOCK_TLV;
+
+ /* send WRITE-E8 command */
+ if ((status = rw_t2t_write (T2T_FIRST_DATA_BLOCK, data_block)) == NFC_STATUS_OK)
+ {
+ p_t2t->b_read_data = FALSE;
+ }
+ else
+ p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+ }
+ else
+ status = NFC_STATUS_REJECTED;
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_set_cc
+**
+** Description This function will set Capability Container on the activated
+** type 2 tag with default values of CC0, CC1, CC4 and specified
+** CC3 value
+**
+** Parameters: CC3 value of the tag
+**
+** Returns
+** NFC_STATUS_OK, Command sent to set CC
+** NFC_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_set_cc (UINT8 tms)
+{
+ UINT8 cc_block[T2T_BLOCK_SIZE];
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ UINT8 *p;
+
+ memset (cc_block, 0, T2T_BLOCK_SIZE);
+ memset (p_t2t->ndef_final_block, 0, T2T_BLOCK_SIZE);
+ p = cc_block;
+
+ /* Prepare Capability Container */
+ UINT8_TO_BE_STREAM (p, T2T_CC0_NMN);
+ UINT8_TO_BE_STREAM (p, T2T_CC1_VNO);
+ UINT8_TO_BE_STREAM (p, tms);
+ UINT8_TO_BE_STREAM (p, T2T_CC3_RWA_RW);
+
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_CC;
+
+ /* send WRITE-E8 command */
+ if ((status = rw_t2t_write (T2T_CC_BLOCK, cc_block)) == NFC_STATUS_OK)
+ {
+ p_t2t->state = RW_T2T_STATE_FORMAT_TAG;
+ p_t2t->b_read_hdr = FALSE;
+ }
+ else
+ p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_format_tag
+**
+** Description This function will format tag based on Manufacturer ID
+**
+** Returns
+** NFC_STATUS_OK, Command sent to format Tag
+** NFC_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_format_tag (void)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ const tT2T_INIT_TAG *p_ret;
+ UINT8 tms;
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ BOOLEAN b_blank_tag = TRUE;
+
+ if ((p_ret = t2t_tag_init_data (p_t2t->tag_hdr[0], FALSE, 0)) == NULL)
+ {
+ RW_TRACE_WARNING1 ("rw_t2t_format_tag - Unknown Manufacturer ID: %u, Cannot Format the tag!", p_t2t->tag_hdr[0]);
+ return (NFC_STATUS_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, T2T_READ_DATA_LEN);
+
+ if (!b_blank_tag || !p_ret->b_multi_version)
+ {
+ status = rw_t2t_set_cc (tms);
+ }
+ else if (p_ret->version_block != 0)
+ {
+ /* If Version number is not read, READ it now */
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_VERSION_INFO;
+
+ if ((status = rw_t2t_read (p_ret->version_block)) == NFC_STATUS_OK)
+ p_t2t->state = RW_T2T_STATE_FORMAT_TAG;
+ else
+ p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+ }
+ else
+ {
+ /* UID block is the version block */
+ p_t2t->state = RW_T2T_STATE_FORMAT_TAG;
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_VERSION_INFO;
+ rw_t2t_handle_format_tag_rsp (p_t2t->tag_hdr);
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function rw_t2t_soft_lock_tag
+**
+** Description This function will soft lock the tag after validating CC.
+**
+** Returns
+** NFC_STATUS_OK, Command sent to soft lock the tag
+** NFC_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_soft_lock_tag (void)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ UINT8 write_block[T2T_BLOCK_SIZE];
+ UINT8 num_locks;
+
+ /* If CC block is read and cc3 is soft locked, reject the command */
+ if ((p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] & T2T_CC3_RWA_RO) == T2T_CC3_RWA_RO)
+ {
+ RW_TRACE_ERROR1 ("rw_t2t_soft_lock_tag: Error: Type 2 tag is in Read only state, CC3: %u", p_t2t->tag_hdr[T2T_CC3_RWA_BYTE]);
+ return (NFC_STATUS_FAILED);
+ }
+
+ if (p_t2t->b_hard_lock)
+ {
+ /* Should have performed NDEF Detection on dynamic memory structure tag, before permanently converting to Read only
+ * Even when no lock control tlv is present, default lock bytes should be present */
+
+ if ((p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] != T2T_CC2_TMS_STATIC) && (p_t2t->num_lockbytes == 0))
+ {
+ RW_TRACE_ERROR0 ("rw_t2t_soft_lock_tag: Error: Lock TLV not detected! Cannot hard lock the tag");
+ return (NFC_STATUS_FAILED);
+ }
+
+ /* On dynamic memory structure tag, reset all lock bytes status to 'Not Updated' if not in Updated status */
+ num_locks = 0;
+ while (num_locks < p_t2t->num_lockbytes)
+ {
+ if (p_t2t->lockbyte[num_locks].lock_status != RW_T2T_LOCK_UPDATED)
+ p_t2t->lockbyte[num_locks].lock_status = RW_T2T_LOCK_NOT_UPDATED;
+ num_locks++;
+ }
+ }
+
+ memcpy (write_block, &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE], T2T_BLOCK_SIZE);
+ write_block[(T2T_CC3_RWA_BYTE % T2T_BLOCK_SIZE)] = T2T_CC3_RWA_RO;
+
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_CC_RO;
+ /* First Soft lock the tag */
+ if ((status = rw_t2t_write (T2T_CC_BLOCK, write_block)) == NFC_STATUS_OK)
+ {
+ p_t2t->state = RW_T2T_STATE_SET_TAG_RO;
+ p_t2t->b_read_hdr = FALSE;
+ }
+ else
+ {
+ p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+ }
+ return status;
+}
+
+/*****************************************************************************
+**
+** Function RW_T2tFormatNDef
+**
+** Description
+** Format Tag content
+**
+** Returns
+** NFC_STATUS_OK, Command sent to format Tag
+** NFC_STATUS_FAILED: otherwise
+**
+*****************************************************************************/
+tNFC_STATUS RW_T2tFormatNDef (void)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+
+ if (p_t2t->state != RW_T2T_STATE_IDLE)
+ {
+ RW_TRACE_WARNING1 ("RW_T2tFormatNDef - Tag not initialized/ Busy! State: %u", p_t2t->state);
+ return (NFC_STATUS_FAILED);
+ }
+
+ if (!p_t2t->b_read_hdr)
+ {
+ /* If UID is not read, READ it now */
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_CC;
+
+ if ((status = rw_t2t_read (0)) == NFC_STATUS_OK)
+ p_t2t->state = RW_T2T_STATE_FORMAT_TAG;
+ else
+ p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+ }
+ else
+ {
+ if ((status = rw_t2t_format_tag ()) != 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 tlv_type)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ tNFC_STATUS status;
+ UINT16 block;
+
+ if (p_t2t->state != RW_T2T_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
+ return (NFC_STATUS_BUSY);
+ }
+
+ if ((tlv_type != TAG_LOCK_CTRL_TLV) && (tlv_type != TAG_MEM_CTRL_TLV) && (tlv_type != TAG_NDEF_TLV) && (tlv_type != TAG_PROPRIETARY_TLV))
+ {
+ RW_TRACE_API1 ("RW_T2tLocateTlv - Cannot search TLV: 0x%02x", tlv_type);
+ return (NFC_STATUS_FAILED);
+ }
+
+ if ( (tlv_type == TAG_LOCK_CTRL_TLV)
+ &&(p_t2t->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 */
+ if ((status = rw_t2t_read ((UINT16) block)) == NFC_STATUS_OK)
+ {
+ p_t2t->state = RW_T2T_STATE_DETECT_TLV;
+ }
+ else
+ {
+ p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+ }
+ return (status);
+}
+
+/*******************************************************************************
+**
+** Function RW_T2tDetectNDef
+**
+** Description This function is used to perform NDEF detection on a Type 2
+** tag, and retrieve the tag's NDEF attribute information.
+**
+** Before using this API, the application must call
+** RW_SelectTagType to indicate that a Type 2 tag has been
+** activated.
+**
+** Parameters: none
+**
+** Returns NCI_STATUS_OK,if detect op started.Otherwise,error status.
+**
+*******************************************************************************/
+tNFC_STATUS RW_T2tDetectNDef (BOOLEAN 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 *p_buffer, UINT16 buf_len)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ tNFC_STATUS status = NFC_STATUS_OK;
+ UINT16 block;
+
+ if (p_t2t->state != RW_T2T_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
+ return (NFC_STATUS_FAILED);
+ }
+
+ if (p_t2t->ndef_status == T2T_NDEF_NOT_DETECTED)
+ {
+ RW_TRACE_ERROR0 ("RW_T2tReadNDef - Error: NDEF detection not performed yet");
+ return (NFC_STATUS_FAILED);
+ }
+
+ if (buf_len < p_t2t->ndef_msg_len)
+ {
+ RW_TRACE_WARNING2 ("RW_T2tReadNDef - buffer size: %u less than NDEF msg sise: %u", buf_len, p_t2t->ndef_msg_len);
+ return (NFC_STATUS_FAILED);
+ }
+
+ if (!p_t2t->ndef_msg_len)
+ {
+ RW_TRACE_WARNING1 ("RW_T2tReadNDef - NDEF Message length is zero ", p_t2t->ndef_msg_len);
+ return (NFC_STATUS_NOT_INITIALIZED);
+ }
+
+ p_t2t->p_ndef_buffer = p_buffer;
+ p_t2t->work_offset = 0;
+
+ block = (UINT16) (p_t2t->ndef_msg_offset / T2T_BLOCK_LEN);
+ block -= block % T2T_READ_BLOCKS;
+
+ p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+
+ if ( (block == T2T_FIRST_DATA_BLOCK)
+ &&(p_t2t->b_read_data) )
+ {
+ p_t2t->state = RW_T2T_STATE_READ_NDEF;
+ p_t2t->block_read = T2T_FIRST_DATA_BLOCK;
+ rw_t2t_handle_ndef_read_rsp (p_t2t->tag_data);
+ }
+ else
+ {
+ /* Start reading NDEF Message */
+ if ((status = rw_t2t_read (block)) == NFC_STATUS_OK)
+ {
+ p_t2t->state = RW_T2T_STATE_READ_NDEF;
+ }
+ }
+
+ return (status);
+}
+
+/*******************************************************************************
+**
+** Function RW_T2tWriteNDef
+**
+** Description Write NDEF contents to a Type2 tag.
+**
+** Before using this API, the RW_T2tDetectNDef
+** function must be called to verify that the tag contains
+** NDEF data, and to retrieve the NDEF attributes.
+**
+** The RW_T2T_NDEF_WRITE_EVT callback event will be used to
+** notify the application of the response.
+**
+** Internally, this command will be separated into multiple Tag2
+** Write commands (if necessary) - depending on the NDEF Msg size
+**
+** Parameters: msg_len: The length of the buffer
+** p_msg: The NDEF message to write
+**
+** Returns NCI_STATUS_OK,if write was started. Otherwise, error status
+**
+*******************************************************************************/
+tNFC_STATUS RW_T2tWriteNDef (UINT16 msg_len, UINT8 *p_msg)
+{
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+ UINT16 block;
+ const tT2T_INIT_TAG *p_ret;
+
+ tNFC_STATUS status = NFC_STATUS_OK;
+
+ if (p_t2t->state != RW_T2T_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
+ return (NFC_STATUS_FAILED);
+ }
+
+ if (p_t2t->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) (p_t2t->ndef_header_offset / T2T_BLOCK_LEN);
+
+ if ( (block < (T2T_FIRST_DATA_BLOCK + T2T_READ_BLOCKS))
+ &&(p_t2t->b_read_data) )
+ {
+ p_t2t->state = RW_T2T_STATE_WRITE_NDEF;
+ p_t2t->block_read = block;
+ rw_t2t_handle_ndef_write_rsp (&p_t2t->tag_data[(block - T2T_FIRST_DATA_BLOCK) * T2T_BLOCK_LEN]);
+ }
+ else
+ {
+ if ((status = rw_t2t_read (block)) == NFC_STATUS_OK)
+ p_t2t->state = RW_T2T_STATE_WRITE_NDEF;
+ else
+ p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function RW_T2tSetTagReadOnly
+**
+** Description This function can be called to set T2 tag as read only.
+**
+** Parameters: b_hard_lock: To indicate hard lock the tag or not
+**
+** Returns NCI_STATUS_OK, if setting tag as read only was started.
+** Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS RW_T2tSetTagReadOnly (BOOLEAN b_hard_lock)
+{
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+ tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
+
+ if (p_t2t->state != RW_T2T_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("RW_T2tSetTagReadOnly: Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
+ return (NFC_STATUS_FAILED);
+ }
+
+ p_t2t->b_hard_lock = b_hard_lock;
+
+ if (!p_t2t->b_read_hdr)
+ {
+ /* Read CC block before configuring tag as Read only */
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_CC;
+ if ((status = rw_t2t_read ((UINT16) 0)) == NFC_STATUS_OK)
+ {
+ p_t2t->state = RW_T2T_STATE_SET_TAG_RO;
+ }
+ else
+ p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+ }
+ else
+ {
+ if ((status = rw_t2t_soft_lock_tag ()) != NFC_STATUS_OK)
+ p_t2t->b_read_hdr = FALSE;
+ }
+
+ return status;
+}
+
+#endif /* (defined ((RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE)) */
+
+#endif /* (NFC_INCLUDED == TRUE) */
diff --git a/src/nfc/tags/rw_t3t.c b/src/nfc/tags/rw_t3t.c
new file mode 100644
index 0000000..d19a1b8
--- /dev/null
+++ b/src/nfc/tags/rw_t3t.c
@@ -0,0 +1,3185 @@
+/******************************************************************************
+ *
+ * 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 */
+#define RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT (13) /* Maximum number of NDEF blocks updates that can fit into one command (when all block-numbers are < 256) */
+#define RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_2_BYTE_FORMAT (12) /* Maximum number of NDEF blocks updates that can fit into one command (when all block-numbers are >= 256) */
+
+/* Definitions for SENSF_RES */
+#define RW_T3T_SENSF_RES_RD_OFFSET 17 /* Offset of RD in SENSF_RES from NCI_POLL NTF (includes 1 byte SENSF_RES length) */
+#define RW_T3T_SENSF_RES_RD_LEN 2 /* Size of RD in SENSF_RES */
+
+/* Timeout definitions for commands */
+#define RW_T3T_POLL_CMD_TIMEOUT_TICKS ((RW_T3T_TOUT_RESP*2*QUICK_TIMER_TICKS_PER_SEC) / 1000)
+#define RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS ((RW_T3T_TOUT_RESP*QUICK_TIMER_TICKS_PER_SEC) / 1000)
+#define RW_T3T_RAW_FRAME_CMD_TIMEOUT_TICKS (RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS * 4)
+#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 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 getting system codes */
+ RW_T3T_GET_SC_SST_POLL_WILDCARD, /* Waiting for wilcard poll response */
+ RW_T3T_GET_SC_SST_POLL_NDEF, /* Waiting for NDEF poll response */
+ RW_T3T_GET_SC_SST_REQUEST_SC, /* Waiting for REQUEST_SYSTEM_CODE response */
+
+ /* Sub states for formatting Felica-Lite */
+ RW_T3T_FMT_SST_POLL_FELICA_LITE, /* Waiting for POLL Felica-Lite response (for formatting) */
+ RW_T3T_FMT_SST_CHECK_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl) block-read to complete */
+ RW_T3T_FMT_SST_UPDATE_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl) block-write to complete */
+ RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB, /* Waiting for NDEF attribute block-write to complete */
+
+ /* 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 cmd_id);
+static char *rw_t3t_state_str (UINT8 state_id);
+#endif
+
+
+/* Local static functions */
+static void rw_t3t_update_ndef_flag (UINT8 *p_flag);
+static tNFC_STATUS rw_t3t_unselect (UINT8 peer_nfcid2[]);
+static BT_HDR *rw_t3t_get_cmd_buf (void);
+static tNFC_STATUS rw_t3t_send_to_lower (BT_HDR *p_msg);
+static void rw_t3t_handle_get_system_codes_cplt (void);
+static void rw_t3t_handle_get_sc_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf);
+static void rw_t3t_handle_ndef_detect_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf);
+static void rw_t3t_handle_fmt_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf);
+static void rw_t3t_handle_sro_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf);
+
+
+/* Default NDEF attribute information block (used when formatting Felica-Lite tags) */
+#define RW_T3T_DEFAULT_FELICALITE_NBR 4 /* NBr (max block reads per cmd)*/
+#define RW_T3T_DEFAULT_FELICALITE_NBW 1 /* NBw (max block write per cmd)*/
+#define RW_T3T_DEFAULT_FELICALITE_NMAXB (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 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 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 rw_t3t_check_timeout (UINT16 num_blocks)
+{
+ tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+ UINT32 timeout;
+ UINT32 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 rw_t3t_update_timeout (UINT16 num_blocks)
+{
+ tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+ UINT32 timeout;
+ UINT32 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 evt;
+ tRW_DATA evt_data;
+ BT_HDR *p_cmd_buf;
+
+ if (p_cb->rw_state == RW_T3T_STATE_COMMAND_PENDING)
+ {
+ if (p_cb->cur_cmd == RW_T3T_CMD_GET_SYSTEM_CODES)
+ {
+ /* For GetSystemCode: either tag did not respond to requested POLL, or REQUEST_SYSTEM_CODE command */
+ rw_t3t_handle_get_system_codes_cplt ();
+ return;
+ }
+ /* Retry sending command if retry-count < max */
+ else if (rw_cb.cur_retry < RW_MAX_RETRIES)
+ {
+ /* retry sending the command */
+ rw_cb.cur_retry++;
+
+ RW_TRACE_DEBUG2 ("T3T retransmission attempt %i of %i", rw_cb.cur_retry, RW_MAX_RETRIES);
+
+ /* allocate a new buffer for message */
+ if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
+ {
+ memcpy (p_cmd_buf, p_cb->p_cur_cmd_buf, sizeof (BT_HDR) + p_cb->p_cur_cmd_buf->offset + p_cb->p_cur_cmd_buf->len);
+
+ if (rw_t3t_send_to_lower (p_cmd_buf) == NFC_STATUS_OK)
+ {
+ /* Start timer for waiting for response */
+ nfc_start_quick_timer (&p_cb->timer, NFC_TTYPE_RW_T3T_RESPONSE, p_cb->cur_tout);
+ return;
+ }
+ else
+ {
+ /* failure - could not send buffer */
+ GKI_freebuf (p_cmd_buf);
+ }
+ }
+ }
+ else
+ {
+ RW_TRACE_DEBUG1 ("T3T maximum retransmission attempts reached (%i)", RW_MAX_RETRIES);
+ }
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+ /* update failure count */
+ rw_main_update_fail_stats ();
+#endif /* RW_STATS_INCLUDED */
+
+ p_cb->rw_state = RW_T3T_STATE_IDLE;
+
+ /* Notify app of result (if there was a pending command) */
+ if (p_cb->cur_cmd < RW_T3T_CMD_MAX)
+ {
+ /* If doing presence check, use status=NFC_STATUS_FAILED, otherwise NFC_STATUS_TIMEOUT */
+ evt_data.status = status;
+ evt = rw_t3t_api_res_evt[p_cb->cur_cmd];
+
+ /* Set additional flags for RW_T3T_NDEF_DETECT_EVT */
+ if (evt == RW_T3T_NDEF_DETECT_EVT)
+ {
+ evt_data.ndef.flags = RW_NDEF_FL_UNKNOWN;
+ rw_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)
+{
+ nfc_start_quick_timer (&p_cb->poll_timer, NFC_TTYPE_RW_T3T_RESPONSE, RW_T3T_POLL_CMD_TIMEOUT_TICKS);
+}
+
+/*******************************************************************************
+**
+** Function rw_t3t_handle_nci_poll_ntf
+**
+** Description Handle NCI_T3T_POLLING_NTF
+**
+** Returns none
+**
+*******************************************************************************/
+void rw_t3t_handle_nci_poll_ntf (UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf)
+{
+ tRW_DATA evt_data;
+ tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+
+ /* stop timer for poll response */
+ nfc_stop_quick_timer (&p_cb->poll_timer);
+
+ /* Stop t3t timer (if started) */
+ if (p_cb->flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP)
+ {
+ p_cb->flags &= ~RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
+ evt_data.status = nci_status;
+ p_cb->rw_state = RW_T3T_STATE_IDLE;
+ (*(rw_cb.p_cback)) (RW_T3T_PRESENCE_CHECK_EVT, (tRW_DATA *) &evt_data);
+ }
+ else if (p_cb->flags & RW_T3T_FL_W4_GET_SC_POLL_RSP)
+ {
+ /* Handle POLL ntf in response to get system codes */
+ p_cb->flags &= ~RW_T3T_FL_W4_GET_SC_POLL_RSP;
+ rw_t3t_handle_get_sc_poll_rsp (p_cb, nci_status, num_responses, sensf_res_buf_size, p_sensf_res_buf);
+ }
+ else if (p_cb->flags & RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP)
+ {
+ /* Handle POLL ntf in response to get system codes */
+ p_cb->flags &= ~RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
+ rw_t3t_handle_fmt_poll_rsp (p_cb, nci_status, num_responses, sensf_res_buf_size, p_sensf_res_buf);
+ }
+ else if (p_cb->flags & RW_T3T_FL_W4_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 */
+ if ((evt_data.t3t_poll.status = nci_status) == NCI_STATUS_OK)
+ {
+ evt_data.t3t_poll.rc = p_cb->cur_poll_rc;
+ evt_data.t3t_poll.response_num = num_responses;
+ evt_data.t3t_poll.response_bufsize = sensf_res_buf_size;
+ evt_data.t3t_poll.response_buf = p_sensf_res_buf;
+ }
+
+ p_cb->rw_state = RW_T3T_STATE_IDLE;
+ (*(rw_cb.p_cback)) (RW_T3T_POLL_EVT, &evt_data);
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function rw_t3t_handle_get_system_codes_cplt
+**
+** Description Notify upper layer of system codes
+**
+** Returns none
+**
+*******************************************************************************/
+void rw_t3t_handle_get_system_codes_cplt (void)
+{
+ tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+ tRW_DATA evt_data;
+ UINT8 i;
+
+ evt_data.t3t_sc.status = NFC_STATUS_OK;
+ evt_data.t3t_sc.num_system_codes = p_cb->num_system_codes;
+ evt_data.t3t_sc.p_system_codes = p_cb->system_codes;
+
+ RW_TRACE_DEBUG1 ("rw_t3t_handle_get_system_codes_cplt, number of systems: %i", evt_data.t3t_sc.num_system_codes);
+ for (i = 0; i < evt_data.t3t_sc.num_system_codes; i++)
+ {
+ RW_TRACE_DEBUG2 (" system %i: %04X", i, evt_data.t3t_sc.p_system_codes[i]);
+ }
+
+ p_cb->rw_state = RW_T3T_STATE_IDLE;
+ (*(rw_cb.p_cback)) (RW_T3T_GET_SYSTEM_CODES_EVT, &evt_data);
+
+
+}
+
+/*******************************************************************************
+**
+** Function rw_t3t_format_cplt
+**
+** Description Notify upper layer of format complete
+**
+** Returns none
+**
+*******************************************************************************/
+void rw_t3t_format_cplt (tNFC_STATUS status)
+{
+ tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+ tRW_DATA evt_data;
+
+ p_cb->rw_state = RW_T3T_STATE_IDLE;
+
+ /* 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 (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+ /* Update stats */
+ rw_main_update_crc_error_stats ();
+#endif /* RW_STATS_INCLUDED */
+
+ /* Process the error */
+ rw_t3t_process_error (NFC_STATUS_MSG_CORRUPTED);
+}
+
+/*******************************************************************************
+**
+** Function rw_t3t_send_to_lower
+**
+** Description Send command to lower layer
+**
+** Returns status of the send
+**
+*******************************************************************************/
+tNFC_STATUS rw_t3t_send_to_lower (BT_HDR *p_msg)
+{
+ UINT8 *p;
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+ BOOLEAN is_retry;
+ /* Update stats */
+ rw_main_update_tx_stats (p_msg->len, ((rw_cb.cur_retry==0) ? FALSE : TRUE));
+#endif /* RW_STATS_INCLUDED */
+
+ /* Set NFC-F SoD field (payload len + 1) */
+ p_msg->offset -= 1; /* Point to SoD field */
+ p = (UINT8 *) (p_msg+1) + p_msg->offset;
+ UINT8_TO_STREAM (p, (p_msg->len+1));
+ p_msg->len += 1; /* Increment len to include SoD */
+
+#if (BT_TRACE_PROTOCOL == TRUE)
+ DispT3TagMessage (p_msg, FALSE);
+#endif
+
+ return (NFC_SendData (NFC_RF_CONN_ID, p_msg));
+}
+
+/*****************************************************************************
+**
+** Function rw_t3t_get_cmd_buf
+**
+** Description Get a buffer for sending T3T messages
+**
+** Returns BT_HDR *
+**
+*****************************************************************************/
+BT_HDR *rw_t3t_get_cmd_buf (void)
+{
+ BT_HDR *p_cmd_buf;
+
+ if ((p_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL)
+ {
+ /* Reserve offset for NCI_DATA_HDR and NFC-F Sod (LEN) field */
+ p_cmd_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + 1;
+ p_cmd_buf->len = 0;
+ }
+
+ return (p_cmd_buf);
+}
+
+/*****************************************************************************
+**
+** Function rw_t3t_send_cmd
+**
+** Description Send command to tag, and start timer for response
+**
+** Returns tNFC_STATUS
+**
+*****************************************************************************/
+tNFC_STATUS rw_t3t_send_cmd (tRW_T3T_CB *p_cb, UINT8 rw_t3t_cmd, BT_HDR *p_cmd_buf, UINT32 timeout_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 (BT_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;
+
+ if ((retval = rw_t3t_send_to_lower (p_cmd_buf)) == NFC_STATUS_OK)
+ {
+ /* Start timer for waiting for response */
+ nfc_start_quick_timer (&p_cb->timer, NFC_TTYPE_RW_T3T_RESPONSE, timeout_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, BOOLEAN write_in_progress)
+{
+ tNFC_STATUS retval = NFC_STATUS_OK;
+ BT_HDR *p_cmd_buf;
+ UINT8 *p_cmd_start, *p;
+ UINT16 checksum, i;
+ UINT8 write_f;
+ UINT32 ln;
+ UINT8 *p_ndef_attr_info_start;
+
+ if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
+ {
+ /* Construct T3T message */
+ p = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
+
+ /* Add UPDATE opcode to message */
+ UINT8_TO_STREAM (p, T3T_MSG_OPC_UPDATE_CMD);
+
+ /* Add IDm to message */
+ ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
+
+ /* Add Service code list */
+ UINT8_TO_STREAM (p, 1); /* Number of services (only 1 service: NDEF) */
+ UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */
+
+ /* Add number of blocks in this UPDATE command */
+ UINT8_TO_STREAM (p, 1); /* Number of blocks to write in this command */
+
+ /* Block List element: the NDEF attribute information block (block 0) */
+ UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
+ UINT8_TO_STREAM (p, 0);
+
+ /* Add payload (Attribute information block) */
+ p_ndef_attr_info_start = p; /* Save start of a NDEF attribute info block for checksum */
+ UINT8_TO_STREAM (p, T3T_MSG_NDEF_VERSION);
+ UINT8_TO_STREAM (p, p_cb->ndef_attrib.nbr);
+ UINT8_TO_STREAM (p, p_cb->ndef_attrib.nbw);
+ UINT16_TO_BE_STREAM (p, p_cb->ndef_attrib.nmaxb);
+ UINT32_TO_STREAM (p, 0);
+
+ /* If starting NDEF write: set WriteF=ON, and ln=current ndef length */
+ if (write_in_progress)
+ {
+ write_f = T3T_MSG_NDEF_WRITEF_ON;
+ ln = p_cb->ndef_attrib.ln;
+ }
+ /* If finishing NDEF write: set WriteF=OFF, and ln=new ndef len */
+ else
+ {
+ write_f = T3T_MSG_NDEF_WRITEF_OFF;
+ ln = p_cb->ndef_msg_len;
+ }
+ UINT8_TO_STREAM (p, write_f);
+ UINT8_TO_STREAM (p, p_cb->ndef_attrib.rwflag);
+ UINT8_TO_STREAM (p, (ln>>16) & 0xFF); /* High byte (of 3) of Ln */
+ UINT8_TO_STREAM (p, (ln>>8) & 0xFF); /* Middle byte (of 3) of Ln */
+ UINT8_TO_STREAM (p, (ln) & 0xFF); /* Low byte (of 3) of Ln */
+
+ /* Calculate and append Checksum */
+ checksum = 0;
+ for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++)
+ {
+ checksum+=p_ndef_attr_info_start[i];
+ }
+ UINT16_TO_BE_STREAM (p, checksum);
+
+
+ /* Calculate length of message */
+ p_cmd_buf->len = (UINT16) (p - p_cmd_start);
+
+ /* Send the T3T message */
+ retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_UPDATE_NDEF, p_cmd_buf, rw_t3t_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 block_id;
+ UINT16 first_block_to_write;
+ UINT16 ndef_blocks_to_write, ndef_blocks_remaining;
+ UINT32 ndef_bytes_remaining, ndef_padding = 0;
+ UINT8 flags = 0;
+ UINT8 *p_cur_ndef_src_offset;
+ BT_HDR *p_cmd_buf;
+ UINT8 *p_cmd_start, *p;
+ UINT8 blocks_per_update;
+ UINT32 timeout;
+
+ if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
+ {
+ /* Construct T3T message */
+ p = p_cmd_start = (UINT8 *) (p_cmd_buf + 1) + p_cmd_buf->offset;
+
+ /* Calculate number of ndef bytes remaining to write */
+ ndef_bytes_remaining = p_cb->ndef_msg_len - p_cb->ndef_msg_bytes_sent;
+
+ /* Calculate number of blocks remaining to write */
+ ndef_blocks_remaining = (UINT16) ((ndef_bytes_remaining+15) >> 4); /* ndef blocks remaining (rounded upward) */
+
+ /* Calculate first NDEF block ID for this UPDATE command */
+ first_block_to_write = (UINT16) ((p_cb->ndef_msg_bytes_sent >> 4) + 1);
+
+ /* Calculate max number of blocks per write. */
+ if ((first_block_to_write + RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT) < 0x100)
+ {
+ /* All block-numbers are < 0x100 (i.e. can be specified using one-byte format) */
+ blocks_per_update = RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT;
+ }
+ else
+ {
+ /* Block-numbers are >= 0x100 (i.e. need to be specified using two-byte format) */
+ blocks_per_update = RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_2_BYTE_FORMAT;
+ }
+
+ /* Check if blocks_per_update is bigger than what peer allows */
+ if (blocks_per_update > p_cb->ndef_attrib.nbw)
+ blocks_per_update = p_cb->ndef_attrib.nbw;
+
+ /* Check if remaining blocks can fit into one UPDATE command */
+ if (ndef_blocks_remaining <= blocks_per_update)
+ {
+ /* remaining blocks can fit into one UPDATE command */
+ ndef_blocks_to_write = ndef_blocks_remaining;
+ }
+ else
+ {
+ /* Remaining blocks cannot fit into one UPDATE command */
+ ndef_blocks_to_write = blocks_per_update;
+ }
+
+
+ /* Write to command header for UPDATE */
+
+ /* Add UPDATE opcode to message */
+ UINT8_TO_STREAM (p, T3T_MSG_OPC_UPDATE_CMD);
+
+ /* Add IDm to message */
+ ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
+
+ /* Add Service code list */
+ UINT8_TO_STREAM (p, 1); /* Number of services (only 1 service: NDEF) */
+ UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */
+
+
+ /* Add number of blocks in this UPDATE command */
+ UINT8_TO_STREAM (p, ndef_blocks_to_write); /* Number of blocks to write in this command */
+ timeout = rw_t3t_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) ndef_blocks_to_write * 16);
+
+ if (flags & RW_T3T_FL_PADDING)
+ {
+ /* Add last of the NDEF message */
+ p_cur_ndef_src_offset = &p_cb->ndef_msg[p_cb->ndef_msg_bytes_sent];
+ ARRAY_TO_STREAM (p, p_cur_ndef_src_offset, (int) (16-ndef_padding));
+ p_cb->ndef_msg_bytes_sent += (16-ndef_padding);
+
+ /* Add padding */
+ memset (p, 0, ndef_padding);
+ p+=ndef_padding;
+ }
+
+ /* Calculate length of message */
+ p_cmd_buf->len = (UINT16) (p - p_cmd_start);
+
+ /* Send the T3T message */
+ retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_UPDATE_NDEF, p_cmd_buf, timeout);
+ }
+ else
+ {
+ retval = NFC_STATUS_NO_BUFFERS;
+ }
+
+ return (retval);
+}
+
+
+
+/*****************************************************************************
+**
+** Function rw_t3t_send_next_ndef_check_cmd
+**
+** Description Send command for reading next segment of NDEF message
+**
+** Returns tNFC_STATUS
+**
+*****************************************************************************/
+tNFC_STATUS rw_t3t_send_next_ndef_check_cmd (tRW_T3T_CB *p_cb)
+{
+ tNFC_STATUS retval = NFC_STATUS_OK;
+ UINT16 block_id;
+ UINT16 ndef_blocks_remaining, first_block_to_read, cur_blocks_to_read;
+ UINT32 ndef_bytes_remaining;
+ BT_HDR *p_cmd_buf;
+ UINT8 *p_cmd_start, *p;
+
+ if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
+ {
+ /* Construct T3T message */
+ p = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
+
+ /* Calculate number of ndef bytes remaining to read */
+ ndef_bytes_remaining = p_cb->ndef_attrib.ln - p_cb->ndef_rx_offset;
+
+ /* Calculate number of blocks remaining to read */
+ ndef_blocks_remaining = (UINT16) ((ndef_bytes_remaining+15) >> 4); /* ndef blocks remaining (rounded upward) */
+
+ /* Calculate first NDEF block ID */
+ first_block_to_read = (UINT16) ((p_cb->ndef_rx_offset >> 4) + 1);
+
+ /* Check if remaining blocks can fit into one CHECK command */
+ if (ndef_blocks_remaining <= p_cb->ndef_attrib.nbr)
+ {
+ /* remaining blocks can fit into one CHECK command */
+ cur_blocks_to_read = ndef_blocks_remaining;
+ p_cb->ndef_rx_readlen = ndef_bytes_remaining;
+ p_cb->flags |= RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
+ }
+ else
+ {
+ /* Remaining blocks cannot fit into one CHECK command */
+ cur_blocks_to_read = p_cb->ndef_attrib.nbr; /* Read maximum number of blocks allowed by the peer */
+ p_cb->ndef_rx_readlen = ((UINT32) p_cb->ndef_attrib.nbr * 16);
+ }
+
+ RW_TRACE_DEBUG3 ("rw_t3t_send_next_ndef_check_cmd: bytes_remaining: %i, cur_blocks_to_read: %i, is_final: %i",
+ ndef_bytes_remaining, cur_blocks_to_read, (p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT));
+
+ /* 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) (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 **p, UINT8 num_blocks, tT3T_BLOCK_DESC *p_t3t_blocks)
+{
+ UINT16 i, cur_service_code;
+ UINT8 service_code_idx, num_services = 0;
+ UINT8 *p_msg_num_services;
+ UINT16 service_list[T3T_MSG_SERVICE_LIST_MAX];
+
+ /* Add CHECK or UPDATE opcode to message */
+ UINT8_TO_STREAM ((*p), ((p_cb->cur_cmd == RW_T3T_CMD_CHECK) ? T3T_MSG_OPC_CHECK_CMD:T3T_MSG_OPC_UPDATE_CMD));
+
+ /* Add IDm to message */
+ ARRAY_TO_STREAM ((*p), p_cb->peer_nfcid2, NCI_NFCID2_LEN);
+
+ /* Skip over Number of Services field */
+ p_msg_num_services = (*p); /* pointer to Number of Services offset */
+ (*p)++;
+
+ /* Count number of different services are specified in the list, and add services to Service Code list */
+ for (i = 0; i < num_blocks; i++)
+ {
+ cur_service_code = p_t3t_blocks[i].service_code;
+
+ /* Check if current service_code is already in the service_list */
+ for (service_code_idx=0; service_code_idx<num_services; service_code_idx++)
+ {
+ if (service_list[service_code_idx] == cur_service_code)
+ break;
+ }
+
+ if (service_code_idx == num_services)
+ {
+ /* Service not in the list yet. Add it. */
+ service_list[service_code_idx] = cur_service_code;
+ num_services++;
+
+ /* Add service code to T3T message */
+ UINT16_TO_STREAM ((*p), cur_service_code);
+ }
+ }
+
+ /* Add 'Number of Sservices' to the message */
+ *p_msg_num_services = num_services;
+
+ /* Add 'number of blocks' to the message */
+ UINT8_TO_STREAM ((*p), num_blocks);
+
+ /* Add block descriptors */
+ for (i = 0; i < num_blocks; i++)
+ {
+ cur_service_code = p_t3t_blocks[i].service_code;
+
+ /* Check if current service_code is already in the service_list */
+ for (service_code_idx=0; service_code_idx<num_services; service_code_idx++)
+ {
+ if (service_list[service_code_idx] == cur_service_code)
+ break;
+ }
+
+ /* Add decriptor to T3T message */
+ if (p_t3t_blocks[i].block_number > 0xFF)
+ {
+ UINT8_TO_STREAM ((*p), service_code_idx);
+ UINT16_TO_STREAM ((*p), p_t3t_blocks[i].block_number);
+ }
+ else
+ {
+ service_code_idx |= T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT;
+ UINT8_TO_STREAM ((*p), service_code_idx);
+ UINT8_TO_STREAM ((*p), p_t3t_blocks[i].block_number);
+ }
+ }
+}
+
+/*****************************************************************************
+**
+** Function rw_t3t_send_check_cmd
+**
+** Description Send CHECK command
+**
+** Returns tNFC_STATUS
+**
+*****************************************************************************/
+tNFC_STATUS rw_t3t_send_check_cmd (tRW_T3T_CB *p_cb, UINT8 num_blocks, tT3T_BLOCK_DESC *p_t3t_blocks)
+{
+ BT_HDR *p_cmd_buf;
+ UINT8 *p, *p_cmd_start;
+ tNFC_STATUS retval = NFC_STATUS_OK;
+
+ p_cb->cur_cmd = RW_T3T_CMD_CHECK;
+ if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
+ {
+ /* Construct T3T message */
+ p = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
+ rw_t3t_message_set_block_list (p_cb, &p, num_blocks, p_t3t_blocks);
+
+ /* Calculate length of message */
+ p_cmd_buf->len = (UINT16) (p - p_cmd_start);
+
+ /* Send the T3T message */
+ retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_CHECK, p_cmd_buf, rw_t3t_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 num_blocks, tT3T_BLOCK_DESC *p_t3t_blocks, UINT8 *p_data)
+{
+ BT_HDR *p_cmd_buf;
+ UINT8 *p, *p_cmd_start;
+ tNFC_STATUS retval = NFC_STATUS_OK;
+
+ p_cb->cur_cmd = RW_T3T_CMD_UPDATE;
+ if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
+ {
+ /* Construct T3T message */
+ p = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
+ rw_t3t_message_set_block_list (p_cb, &p, num_blocks, p_t3t_blocks);
+
+ /* Add data blocks to the message */
+ ARRAY_TO_STREAM (p, p_data, num_blocks*16);
+
+ /* Calculate length of message */
+ p_cmd_buf->len = (UINT16) (p - p_cmd_start);
+
+ /* Send the T3T message */
+ retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_UPDATE, p_cmd_buf, rw_t3t_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)
+{
+ BT_HDR *p_cmd_buf;
+ UINT8 *p, *p_cmd_start;
+
+ /* Read Memory Configuration block */
+ if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
+ {
+ /* Construct T3T message */
+ p = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
+
+ /* Add CHECK opcode to message */
+ UINT8_TO_STREAM (p, T3T_MSG_OPC_CHECK_CMD);
+
+ /* Add IDm to message */
+ ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
+
+ /* Add Service code list */
+ UINT8_TO_STREAM (p, 1); /* Number of services (only 1 service: NDEF) */
+ UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RO); /* Service code (little-endian format) */
+
+ /* Number of blocks */
+ UINT8_TO_STREAM (p, 1); /* Number of blocks (only 1 block: 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) (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 len, UINT8 *p_data)
+{
+ BT_HDR *p_cmd_buf;
+ UINT8 *p;
+ tNFC_STATUS retval = NFC_STATUS_OK;
+
+ if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
+ {
+ /* Construct T3T message */
+ p = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
+
+ /* Add data blocks to the message */
+ ARRAY_TO_STREAM (p, p_data, len);
+
+ /* Calculate length of message */
+ p_cmd_buf->len = len;
+
+ /* Send the T3T message */
+ retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_SEND_RAW_FRAME, p_cmd_buf, RW_T3T_RAW_FRAME_CMD_TIMEOUT_TICKS);
+ }
+ else
+ {
+ retval = NFC_STATUS_NO_BUFFERS;
+ }
+
+ return (retval);
+}
+
+
+/*****************************************************************************
+** TAG RESPONSE HANDLERS
+*****************************************************************************/
+
+
+/*****************************************************************************
+**
+** Function rw_t3t_act_handle_ndef_detect_rsp
+**
+** Description Handle response to NDEF detection
+**
+** Returns Nothing
+**
+*****************************************************************************/
+void rw_t3t_act_handle_ndef_detect_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
+{
+ UINT8 *p;
+ UINT32 temp;
+ UINT8 i;
+ UINT16 checksum_calc, checksum_rx;
+ tRW_DETECT_NDEF_DATA evt_data;
+ UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
+
+ evt_data.status = NFC_STATUS_FAILED;
+ evt_data.flags = RW_NDEF_FL_UNKNOWN;
+
+ /* Check if response code is CHECK resp (for reading NDEF attribute block) */
+ if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP)
+ {
+ RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
+ evt_data.status = NFC_STATUS_FAILED;
+ }
+ /* Validate status code and NFCID2 response from tag */
+ else if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */
+ ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) ) /* verify response IDm */
+ {
+ evt_data.status = NFC_STATUS_FAILED;
+ }
+ else
+ {
+ /* Get checksum from received ndef attribute msg */
+ p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA+T3T_MSG_NDEF_ATTR_INFO_SIZE];
+ BE_STREAM_TO_UINT16 (checksum_rx, p);
+
+ /* Calculate checksum - move check for checsum to beginning */
+ checksum_calc = 0;
+ p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA];
+ for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++)
+ {
+ checksum_calc+=p[i];
+ }
+
+ /* Validate checksum */
+ if (checksum_calc != checksum_rx)
+ {
+ p_cb->ndef_attrib.status = NFC_STATUS_FAILED; /* only ok or failed passed to the app. can be boolean*/
+
+ RW_TRACE_ERROR0 ("RW_T3tDetectNDEF checksum failed");
+ }
+ else
+ {
+ p_cb->ndef_attrib.status = NFC_STATUS_OK;
+
+ /* Validate version number */
+ STREAM_TO_UINT8 (p_cb->ndef_attrib.version, p);
+
+ if (T3T_GET_MAJOR_VERSION (T3T_MSG_NDEF_VERSION) < T3T_GET_MAJOR_VERSION (p_cb->ndef_attrib.version))
+ {
+ /* Remote tag's MajorVer is newer than our's. Reject NDEF as per T3TOP RQ_T3T_NDA_024 */
+ RW_TRACE_ERROR2 ("RW_T3tDetectNDEF: incompatible NDEF version. Local=0x%02x, Remote=0x%02x", T3T_MSG_NDEF_VERSION, p_cb->ndef_attrib.version);
+ p_cb->ndef_attrib.status = NFC_STATUS_FAILED;
+ evt_data.status = NFC_STATUS_BAD_RESP;
+ }
+ else
+ {
+ /* Remote tag's MajorVer is equal or older than our's. NDEF is compatible with our version. */
+
+ /* Update NDEF info */
+ STREAM_TO_UINT8 (p_cb->ndef_attrib.nbr, p); /* NBr: number of blocks that can be read using one Check command */
+ STREAM_TO_UINT8 (p_cb->ndef_attrib.nbw, p); /* Nbw: number of blocks that can be written using one Update command */
+ BE_STREAM_TO_UINT16 (p_cb->ndef_attrib.nmaxb, p); /* Nmaxb: maximum number of blocks available for NDEF data */
+ BE_STREAM_TO_UINT32 (temp, p);
+ STREAM_TO_UINT8 (p_cb->ndef_attrib.writef, p); /* WriteFlag: 00h if writing data finished; 0Fh if writing data in progress */
+ STREAM_TO_UINT8 (p_cb->ndef_attrib.rwflag, p); /* RWFlag: 00h NDEF is read-only; 01h if read/write available */
+
+ /* Get length (3-byte, big-endian) */
+ STREAM_TO_UINT8 (temp, p); /* Ln: high-byte */
+ BE_STREAM_TO_UINT16 (p_cb->ndef_attrib.ln, p); /* Ln: lo-word */
+ p_cb->ndef_attrib.ln += (temp << 16);
+
+
+ RW_TRACE_DEBUG1 ("Detected NDEF Ver: 0x%02x", p_cb->ndef_attrib.version);
+ RW_TRACE_DEBUG6 ("Detected NDEF Attributes: Nbr=%i, Nbw=%i, Nmaxb=%i, WriteF=%i, RWFlag=%i, Ln=%i",
+ p_cb->ndef_attrib.nbr,
+ p_cb->ndef_attrib.nbw,
+ p_cb->ndef_attrib.nmaxb,
+ p_cb->ndef_attrib.writef,
+ p_cb->ndef_attrib.rwflag,
+ p_cb->ndef_attrib.ln);
+
+ /* Set data for RW_T3T_NDEF_DETECT_EVT */
+ evt_data.status = p_cb->ndef_attrib.status;
+ evt_data.cur_size = p_cb->ndef_attrib.ln;
+ evt_data.max_size = (UINT32) p_cb->ndef_attrib.nmaxb * 16;
+ evt_data.protocol = NFC_PROTOCOL_T3T;
+ evt_data.flags = (RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATED);
+ if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO)
+ evt_data.flags |= RW_NDEF_FL_READ_ONLY;
+ }
+ }
+ }
+
+ RW_TRACE_DEBUG1 ("RW_T3tDetectNDEF response: %i", evt_data.status);
+
+ p_cb->rw_state = RW_T3T_STATE_IDLE;
+ rw_t3t_update_ndef_flag (&evt_data.flags);
+ /* Notify app of NDEF detection result */
+ (*(rw_cb.p_cback)) (RW_T3T_NDEF_DETECT_EVT, (tRW_DATA *) &evt_data);
+
+ GKI_freebuf (p_msg_rsp);
+}
+
+
+/*****************************************************************************
+**
+** Function rw_t3t_act_handle_check_rsp
+**
+** Description Handle response to CHECK command
+**
+** Returns Nothing
+**
+*****************************************************************************/
+void rw_t3t_act_handle_check_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
+{
+ UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
+ tRW_READ_DATA evt_data;
+ tNFC_STATUS nfc_status = NFC_STATUS_OK;
+
+ /* Validate response from tag */
+ if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */
+ ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) ) /* verify response IDm */
+ {
+ nfc_status = NFC_STATUS_FAILED;
+ GKI_freebuf (p_msg_rsp);
+ }
+ else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP)
+ {
+ RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
+ nfc_status = NFC_STATUS_FAILED;
+ GKI_freebuf (p_msg_rsp);
+ }
+ else
+ {
+ /* Copy incoming data into buffer */
+ p_msg_rsp->offset += T3T_MSG_RSP_OFFSET_CHECK_DATA; /* Skip over t3t header */
+ p_msg_rsp->len -= T3T_MSG_RSP_OFFSET_CHECK_DATA;
+ evt_data.status = NFC_STATUS_OK;
+ evt_data.p_data = p_msg_rsp;
+ (*(rw_cb.p_cback)) (RW_T3T_CHECK_EVT, (tRW_DATA *) &evt_data);
+ }
+
+
+ p_cb->rw_state = RW_T3T_STATE_IDLE;
+
+ (*(rw_cb.p_cback)) (RW_T3T_CHECK_CPLT_EVT, (tRW_DATA *) &nfc_status);
+}
+
+/*****************************************************************************
+**
+** Function rw_t3t_act_handle_update_rsp
+**
+** Description Handle response to UPDATE command
+**
+** Returns Nothing
+**
+*****************************************************************************/
+void rw_t3t_act_handle_update_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
+{
+ UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
+ tRW_READ_DATA evt_data;
+
+ /* Validate response from tag */
+ if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */
+ ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) ) /* verify response IDm */
+ {
+ evt_data.status = NFC_STATUS_FAILED;
+ }
+ else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
+ {
+ RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_UPDATE_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
+ evt_data.status = NFC_STATUS_FAILED;
+ }
+ else
+ {
+ /* Copy incoming data into buffer */
+ evt_data.status = NFC_STATUS_OK;
+ }
+
+ p_cb->rw_state = RW_T3T_STATE_IDLE;
+
+ (*(rw_cb.p_cback)) (RW_T3T_UPDATE_CPLT_EVT, (tRW_DATA *)&evt_data);
+
+ GKI_freebuf (p_msg_rsp);
+}
+
+/*****************************************************************************
+**
+** Function rw_t3t_act_handle_raw_senddata_rsp
+**
+** Description Handle response to NDEF detection
+**
+** Returns Nothing
+**
+*****************************************************************************/
+void rw_t3t_act_handle_raw_senddata_rsp (tRW_T3T_CB *p_cb, tNFC_DATA_CEVT *p_data)
+{
+ tRW_READ_DATA evt_data;
+ BT_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, (tRW_DATA *) &evt_data);
+}
+
+/*****************************************************************************
+**
+** Function rw_t3t_act_handle_check_ndef_rsp
+**
+** Description Handle response to NDEF read segment
+**
+** Returns Nothing
+**
+*****************************************************************************/
+void rw_t3t_act_handle_check_ndef_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
+{
+ BOOLEAN check_complete = TRUE;
+ tNFC_STATUS nfc_status = NFC_STATUS_OK;
+ tRW_READ_DATA read_data;
+ tRW_DATA evt_data;
+ UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
+ UINT8 rsp_num_bytes_rx;
+
+ /* Validate response from tag */
+ if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */
+ ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) /* verify response IDm */
+ ||(p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] != ((p_cb->ndef_rx_readlen+15) >> 4)) ) /* verify length of response */
+ {
+ RW_TRACE_ERROR2 ("Response error: bad status, nfcid2, or invalid len: %i %i", p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS], ((p_cb->ndef_rx_readlen+15)>>4));
+ nfc_status = NFC_STATUS_FAILED;
+ GKI_freebuf (p_msg_rsp);
+ }
+ else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP)
+ {
+ RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
+ nfc_status = NFC_STATUS_FAILED;
+ GKI_freebuf (p_msg_rsp);
+ }
+ else
+ {
+ /* Notify app of NDEF segment received */
+ rsp_num_bytes_rx = p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] * 16; /* Number of bytes received, according to header */
+ p_cb->ndef_rx_offset += p_cb->ndef_rx_readlen;
+ read_data.status = NFC_STATUS_OK;
+ p_msg_rsp->offset += T3T_MSG_RSP_OFFSET_CHECK_DATA; /* Skip over t3t header (point to block data) */
+ p_msg_rsp->len -= T3T_MSG_RSP_OFFSET_CHECK_DATA;
+
+ /* Verify that the bytes received is really the amount indicated in the check-response header */
+ if (rsp_num_bytes_rx > p_msg_rsp->len)
+ {
+ RW_TRACE_ERROR2 ("Response error: CHECK rsp header indicates %i bytes, but only received %i bytes", rsp_num_bytes_rx, p_msg_rsp->len);
+ nfc_status = NFC_STATUS_FAILED;
+ GKI_freebuf (p_msg_rsp);
+ }
+ else
+ {
+ /* If this is the the final block, then set len to reflect only valid bytes (do not include padding to 16-byte boundary) */
+ if ((p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT) && (p_cb->ndef_attrib.ln & 0x000F))
+ {
+ rsp_num_bytes_rx -= (16 - (p_cb->ndef_attrib.ln & 0x000F));
+ }
+
+ p_msg_rsp->len = rsp_num_bytes_rx;
+ read_data.p_data = p_msg_rsp;
+ (*(rw_cb.p_cback)) (RW_T3T_CHECK_EVT, (tRW_DATA *) &read_data);
+
+ /* Send CHECK cmd for next NDEF segment, if needed */
+ if (!(p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT))
+ {
+ if ((nfc_status = rw_t3t_send_next_ndef_check_cmd (p_cb)) == NFC_STATUS_OK)
+ {
+ /* Still getting more segments. Don't send RW_T3T_CHECK_CPLT_EVT yet */
+ check_complete = FALSE;
+ }
+ }
+ }
+ }
+
+ /* Notify app of RW_T3T_CHECK_CPLT_EVT if entire NDEF has been read, or if failure */
+ if (check_complete)
+ {
+ p_cb->rw_state = RW_T3T_STATE_IDLE;
+ evt_data.status = nfc_status;
+ (*(rw_cb.p_cback)) (RW_T3T_CHECK_CPLT_EVT, (tRW_DATA *) &evt_data);
+ }
+}
+
+
+/*****************************************************************************
+**
+** Function rw_t3t_act_handle_update_ndef_rsp
+**
+** Description Handle response to NDEF write segment
+**
+** Returns Nothing
+**
+*****************************************************************************/
+void rw_t3t_act_handle_update_ndef_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
+{
+ BOOLEAN update_complete = TRUE;
+ tNFC_STATUS nfc_status = NFC_STATUS_OK;
+ tRW_DATA evt_data;
+ UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
+
+ /* Check nfcid2 and status of response */
+ if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */
+ ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) ) /* verify response IDm */
+ {
+ nfc_status = NFC_STATUS_FAILED;
+ }
+ /* Validate response opcode */
+ else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
+ {
+ RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_UPDATE_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
+ nfc_status = NFC_STATUS_FAILED;
+ }
+ /* If this is response to final UPDATE, then update NDEF local size */
+ else if (p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT)
+ {
+ /* If successful, update current NDEF size */
+ p_cb->ndef_attrib.ln = p_cb->ndef_msg_len;
+ }
+ /* If any more NDEF bytes to update, then send next UPDATE command */
+ else if (p_cb->ndef_msg_bytes_sent < p_cb->ndef_msg_len)
+ {
+ /* Send UPDATE command for next segment of NDEF */
+ if ((nfc_status = rw_t3t_send_next_ndef_update_cmd (p_cb)) == NFC_STATUS_OK)
+ {
+ /* Wait for update response */
+ update_complete = FALSE;
+ }
+ }
+ /* Otherwise, no more NDEF bytes. Send final UPDATE for Attribute Information block */
+ else
+ {
+ p_cb->flags |= RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
+ if ((nfc_status = rw_t3t_send_update_ndef_attribute_cmd (p_cb, FALSE)) == NFC_STATUS_OK)
+ {
+ /* Wait for update response */
+ update_complete = FALSE;
+ }
+ }
+
+ /* If update is completed, then notify app */
+ if (update_complete)
+ {
+ p_cb->rw_state = RW_T3T_STATE_IDLE;
+ evt_data.status = nfc_status;
+ (*(rw_cb.p_cback)) (RW_T3T_UPDATE_CPLT_EVT, (tRW_DATA *) &evt_data);
+ }
+
+
+ GKI_freebuf (p_msg_rsp);
+
+ return;
+}
+
+
+/*****************************************************************************
+**
+** Function rw_t3t_handle_get_sc_poll_rsp
+**
+** Description Handle POLL response for getting system codes
+**
+** Returns Nothing
+**
+*****************************************************************************/
+static void rw_t3t_handle_get_sc_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf)
+{
+ BT_HDR *p_cmd_buf;
+ UINT8 *p, *p_cmd_start;
+ UINT16 sc;
+ tNFC_STATUS status = NFC_STATUS_FAILED;
+
+ /* If waiting for wildcard POLL */
+ if (p_cb->rw_substate == RW_T3T_GET_SC_SST_POLL_WILDCARD)
+ {
+ /* Get the system code from the response */
+ if ( (nci_status == NCI_STATUS_OK)
+ &&(num_responses > 0)
+ &&(sensf_res_buf_size >= (RW_T3T_SENSF_RES_RD_OFFSET + RW_T3T_SENSF_RES_RD_LEN)) )
+ {
+ p = &p_sensf_res_buf[RW_T3T_SENSF_RES_RD_OFFSET];
+ BE_STREAM_TO_UINT16 (sc, p);
+
+ /* Handle felica lite */
+ if (sc == T3T_SYSTEM_CODE_FELICA_LITE)
+ {
+ RW_TRACE_DEBUG1 ("FeliCa Lite tag detected (system code %04X)", sc);
+ /* Store system code */
+ p_cb->system_codes[p_cb->num_system_codes++] = sc;
+
+ /* Poll for NDEF system code */
+ if ((status = (tNFC_STATUS) nci_snd_t3t_polling (T3T_SYSTEM_CODE_NDEF, 0, 0)) == NCI_STATUS_OK)
+ {
+ p_cb->rw_substate = RW_T3T_GET_SC_SST_POLL_NDEF;
+ p_cb->cur_poll_rc = 0;
+ p_cb->flags |= RW_T3T_FL_W4_GET_SC_POLL_RSP;
+
+ /* start timer for waiting for responses */
+ rw_t3t_start_poll_timer (p_cb);
+ }
+ }
+ else
+ {
+ /* All other types, send REQUEST_SYSTEM_CODE command */
+ if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
+ {
+ p_cb->rw_substate = RW_T3T_GET_SC_SST_REQUEST_SC;
+
+ /* Construct T3T message */
+ p_cmd_start = p = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
+ UINT8_TO_STREAM (p, T3T_MSG_OPC_REQ_SYSTEMCODE_CMD);
+ ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
+
+ /* Fill in length field */
+ p_cmd_buf->len = (UINT16) (p - p_cmd_start);
+
+ /* Send the T3T message */
+ status = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_GET_SYSTEM_CODES, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS);
+ }
+ }
+ }
+
+ /* Error proceeding. Notify upper layer of system codes found so far */
+ if (status != NFC_STATUS_OK)
+ {
+ rw_t3t_handle_get_system_codes_cplt ();
+ }
+ }
+ /* If waiting for NDEF POLL */
+ else if (p_cb->rw_substate == RW_T3T_GET_SC_SST_POLL_NDEF)
+ {
+ /* Validate response for NDEF poll */
+ if ((nci_status == NCI_STATUS_OK) && (num_responses > 0))
+ {
+ /* Tag responded for NDEF poll */
+ p_cb->system_codes[p_cb->num_system_codes++] = T3T_SYSTEM_CODE_NDEF;
+ }
+ rw_t3t_handle_get_system_codes_cplt ();
+ }
+}
+
+/*****************************************************************************
+**
+** Function rw_t3t_handle_ndef_detect_poll_rsp
+**
+** Description Handle POLL response for getting system codes
+**
+** Returns Nothing
+**
+*****************************************************************************/
+static void rw_t3t_handle_ndef_detect_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf)
+{
+ BT_HDR *p_cmd_buf;
+ UINT8 *p, *p_cmd_start;
+ tRW_DATA evt_data;
+
+ /* Validate response for NDEF poll */
+ if ((nci_status == NCI_STATUS_OK) && (num_responses > 0))
+ {
+ /* Tag responded for NDEF poll */
+
+ /* Read NDEF attribute block */
+ if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
+ {
+ /* Construct T3T message */
+ p = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
+
+ /* Add CHECK opcode to message */
+ UINT8_TO_STREAM (p, T3T_MSG_OPC_CHECK_CMD);
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == 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) (p - p_cmd_start);
+
+ /* Send the T3T message */
+ if ((evt_data.status = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_DETECT_NDEF, p_cmd_buf, rw_t3t_check_timeout(1))) == 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_act_handle_get_sc_rsp
+**
+** Description Handle response for getting system codes
+**
+** Returns Nothing
+**
+*****************************************************************************/
+void rw_t3t_act_handle_get_sc_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
+{
+ UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
+ UINT8 *p;
+ UINT16 sc;
+ UINT8 num_sc, i;
+
+ /* Validate response opcode */
+ if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_REQ_SYSTEMCODE_RSP)
+ {
+ RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_REQ_SYSTEMCODE_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
+ }
+ else
+ {
+ /* Point to number of systems parameter */
+ p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMSYS];
+ STREAM_TO_UINT8 (num_sc, p);
+
+ /* Validate maximum */
+ if (num_sc>T3T_MAX_SYSTEM_CODES)
+ {
+ RW_TRACE_DEBUG2 ("Tag's number of systems (%i) exceeds NFA max (%i)", num_sc, T3T_MAX_SYSTEM_CODES);
+ num_sc = T3T_MAX_SYSTEM_CODES;
+ }
+
+ for (i = 0; i < num_sc; i++)
+ {
+ BE_STREAM_TO_UINT16 (sc, p);
+ p_cb->system_codes[p_cb->num_system_codes++] = sc;
+ }
+ }
+ rw_t3t_handle_get_system_codes_cplt ();
+
+ GKI_freebuf (p_msg_rsp);
+}
+
+/*****************************************************************************
+**
+** Function rw_t3t_update_block
+**
+** Description Send UPDATE command for single block
+** (for formatting/configuring read only)
+**
+** Returns tNFC_STATUS
+**
+*****************************************************************************/
+tNFC_STATUS rw_t3t_update_block (tRW_T3T_CB *p_cb, UINT8 block_id, UINT8 *p_block_data)
+{
+ UINT8 *p_dst, *p_cmd_start;
+ BT_HDR *p_cmd_buf;
+ tNFC_STATUS status;
+
+ if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
+ {
+ p_dst = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
+
+ /* Add UPDATE opcode to message */
+ UINT8_TO_STREAM (p_dst, T3T_MSG_OPC_UPDATE_CMD);
+
+ /* Add IDm to message */
+ ARRAY_TO_STREAM (p_dst, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
+
+ /* Add Service code list */
+ UINT8_TO_STREAM (p_dst, 1); /* Number of services (only 1 service: NDEF) */
+ UINT16_TO_STREAM (p_dst, T3T_MSG_NDEF_SC_RW); /* Service code (little-endian format) */
+
+ /* Number of blocks */
+ UINT8_TO_STREAM (p_dst, 1);
+
+ /* Add Block list element for MC */
+ UINT8_TO_STREAM (p_dst, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
+ UINT8_TO_STREAM (p_dst, block_id);
+
+ /* Copy MC data to UPDATE message */
+ ARRAY_TO_STREAM (p_dst, p_block_data, T3T_MSG_BLOCKSIZE);
+
+ /* Calculate length of message */
+ p_cmd_buf->len = (UINT16) (p_dst - p_cmd_start);
+
+ /* Send the T3T message */
+ status = rw_t3t_send_cmd (p_cb, 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 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf)
+{
+ tRW_DATA evt_data;
+
+ evt_data.status = NFC_STATUS_OK;
+
+ /* Validate response for poll response */
+ if ((nci_status == NCI_STATUS_OK) && (num_responses > 0))
+ {
+ /* Tag responded for Felica-Lite poll */
+ /* Get MemoryControl block */
+ RW_TRACE_DEBUG0 ("Felica-Lite tag detected...getting Memory Control block.");
+
+ 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, BT_HDR *p_msg_rsp)
+{
+ UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
+ UINT8 *p_mc;
+ tRW_DATA evt_data;
+
+ evt_data.status = NFC_STATUS_OK;
+
+ /* Check tags's response for reading MemoryControl block */
+ if (p_cb->rw_substate == RW_T3T_FMT_SST_CHECK_MC_BLK)
+ {
+ /* Validate response opcode */
+ if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP)
+ {
+ RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
+ evt_data.status = NFC_STATUS_FAILED;
+ }
+ /* Validate status code and NFCID2 response from tag */
+ else if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) /* verify response status code */
+ ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) ) /* verify response IDm */
+ {
+ evt_data.status = NFC_STATUS_FAILED;
+ }
+ else
+ {
+ /* Check if memory configuration (MC) block to see if SYS_OP=1 (NDEF enabled) */
+ p_mc = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA]; /* Point to MC data of CHECK response */
+
+ if (p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] != 0x01)
+ {
+ /* Tag is not currently enabled for NDEF. Indicate that we need to update the MC block */
+
+ /* Set SYS_OP field to 0x01 (enable NDEF) */
+ p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] = 0x01;
+
+ /* 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 *) rw_t3t_default_attrib_info);
+ }
+ }
+
+ /* If error, notify upper layer */
+ if (evt_data.status != NFC_STATUS_OK)
+ {
+ rw_t3t_format_cplt (evt_data.status);
+ }
+ }
+ else if (p_cb->rw_substate == RW_T3T_FMT_SST_UPDATE_MC_BLK)
+ {
+ /* Validate response opcode */
+ if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
+ ||(p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) )
+
+ {
+ RW_TRACE_ERROR2 ("Response error: rsp_code=%02X, status=%02X", p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE], p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
+ evt_data.status = NFC_STATUS_FAILED;
+ }
+ else
+ {
+ /* SYS_OP=1: ndef already enabled. Just need to update attribute information block */
+ p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB;
+ evt_data.status = rw_t3t_update_block (p_cb, 0, (UINT8 *) rw_t3t_default_attrib_info);
+ }
+
+ /* If error, notify upper layer */
+ if (evt_data.status != NFC_STATUS_OK)
+ {
+ rw_t3t_format_cplt (evt_data.status);
+ }
+ }
+ else if (p_cb->rw_substate == RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB)
+ {
+ /* Validate response opcode */
+ if ( (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
+ ||(p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK) )
+
+ {
+ RW_TRACE_ERROR2 ("Response error: rsp_code=%02X, status=%02X", p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE], p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
+ evt_data.status = NFC_STATUS_FAILED;
+ }
+
+
+ rw_t3t_format_cplt (evt_data.status);
+ }
+
+ GKI_freebuf (p_msg_rsp);
+}
+
+/*****************************************************************************
+**
+** Function rw_t3t_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 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf)
+{
+ tRW_DATA evt_data;
+ UINT8 rw_t3t_ndef_attrib_info[T3T_MSG_BLOCKSIZE];
+ UINT8 *p;
+ UINT8 tempU8;
+ UINT16 checksum, i;
+ UINT32 tempU32 = 0;
+
+ 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) (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 *) 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, BT_HDR *p_msg_rsp)
+{
+ UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
+ UINT8 *p_mc;
+ tRW_DATA evt_data;
+
+ evt_data.status = NFC_STATUS_OK;
+
+ 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 conn_id, tNFC_DATA_CEVT *p_data)
+{
+ tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+ BT_HDR *p_msg = p_data->p_data;
+ BOOLEAN free_msg = FALSE; /* if TRUE, free msg buffer before returning */
+ UINT8 *p, sod;
+
+ /* Stop rsponse timer */
+ nfc_stop_quick_timer (&p_cb->timer);
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+ /* Update rx stats */
+ rw_main_update_rx_stats (p_msg->len);
+#endif /* RW_STATS_INCLUDED */
+
+ /* Check if we are expecting a response */
+ if (p_cb->rw_state != RW_T3T_STATE_COMMAND_PENDING)
+ {
+ /*
+ ** This must be raw frame response
+ ** send raw frame to app with SoD
+ */
+ rw_t3t_act_handle_raw_senddata_rsp (p_cb, p_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 *) (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_GET_SYSTEM_CODES:
+ rw_t3t_act_handle_get_sc_rsp (p_cb, p_msg);
+ break;
+
+ case RW_T3T_CMD_FORMAT:
+ rw_t3t_act_handle_fmt_rsp (p_cb, p_msg);
+ break;
+
+ 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 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
+{
+ tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+ RW_TRACE_DEBUG2 ("rw_t3t_conn_cback: conn_id=%i, evt=0x%02x", conn_id, event);
+
+ /* Only handle NFC_RF_CONN_ID conn_id */
+ if (conn_id != NFC_RF_CONN_ID)
+ {
+ return;
+ }
+
+ switch (event)
+ {
+ case NFC_DEACTIVATE_CEVT:
+ rw_t3t_unselect (NULL);
+ break;
+
+ case NFC_DATA_CEVT: /* check for status in tNFC_CONN */
+ if ( (p_data->data.status == NFC_STATUS_OK)
+ ||(p_data->data.status == NFC_STATUS_CONTINUE) )
+ {
+ rw_t3t_data_cback (conn_id, &(p_data->data));
+ break;
+ }
+ /* Data event with error status...fall through to NFC_ERROR_CEVT case */
+
+
+ case NFC_ERROR_CEVT:
+ nfc_stop_quick_timer (&p_cb->timer);
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+ rw_main_update_trans_error_stats ();
+#endif /* RW_STATS_INCLUDED */
+
+ if (event == NFC_ERROR_CEVT)
+ rw_t3t_process_error (NFC_STATUS_TIMEOUT);
+ else
+ rw_t3t_process_error (p_data->status);
+ break;
+
+ default:
+ break;
+
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function rw_t3t_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 mrti, UINT32 *p_a, UINT32 *p_b)
+{
+ UINT8 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 peer_nfcid2[NCI_RF_F_UID_LEN], UINT8 mrti_check, UINT8 mrti_update)
+{
+ tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+
+ RW_TRACE_API0 ("rw_t3t_select");
+
+ memcpy (p_cb->peer_nfcid2, peer_nfcid2, NCI_NFCID2_LEN); /* Store tag's NFCID2 */
+ p_cb->ndef_attrib.status = NFC_STATUS_NOT_INITIALIZED; /* Indicate that NDEF detection has not been performed yet */
+ p_cb->rw_state = RW_T3T_STATE_IDLE;
+ p_cb->flags = 0;
+ 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)
+ {
+ if ((p_cb->p_cur_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) == NULL)
+ {
+ RW_TRACE_ERROR0 ("rw_t3t_select: unable to allocate buffer for retransmission");
+ p_cb->rw_state = RW_T3T_STATE_NOT_ACTIVATED;
+ return (NFC_STATUS_FAILED);
+ }
+ }
+
+
+ NFC_SetStaticRfCback (rw_t3t_conn_cback);
+
+ return NFC_STATUS_OK;
+}
+
+
+/*******************************************************************************
+**
+** Function rw_t3t_unselect
+**
+** Description Called by NFC manager when a Type3 tag has been de-activated
+**
+** Returns NFC_STATUS_OK
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t3t_unselect (UINT8 peer_nfcid2[])
+{
+ tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+ /* Display stats */
+ rw_main_log_stats ();
+#endif /* RW_STATS_INCLUDED */
+
+ /* Stop t3t timer (if started) */
+ nfc_stop_quick_timer (&p_cb->timer);
+
+ /* Free cmd buf for retransmissions */
+ if (p_cb->p_cur_cmd_buf)
+ {
+ GKI_freebuf (p_cb->p_cur_cmd_buf);
+ p_cb->p_cur_cmd_buf = NULL;
+ }
+
+ p_cb->rw_state = RW_T3T_STATE_NOT_ACTIVATED;
+ NFC_SetStaticRfCback (NULL);
+
+ return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** 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 *p_flag)
+{
+ tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+ UINT8 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 cmd_id)
+{
+ switch (cmd_id)
+ {
+ case RW_T3T_CMD_DETECT_NDEF:
+ return "RW_T3T_CMD_DETECT_NDEF";
+
+ case RW_T3T_CMD_CHECK_NDEF:
+ return "RW_T3T_CMD_CHECK_NDEF";
+
+ case RW_T3T_CMD_UPDATE_NDEF:
+ return "RW_T3T_CMD_UPDATE_NDEF";
+
+ case RW_T3T_CMD_CHECK:
+ return "RW_T3T_CMD_CHECK";
+
+ case RW_T3T_CMD_UPDATE:
+ return "RW_T3T_CMD_UPDATE";
+
+ case RW_T3T_CMD_SEND_RAW_FRAME:
+ return "RW_T3T_CMD_SEND_RAW_FRAME";
+
+ case RW_T3T_CMD_GET_SYSTEM_CODES:
+ return "RW_T3T_CMD_GET_SYSTEM_CODES";
+
+ default:
+ return "Unknown";
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function rw_t3t_state_str
+**
+** Description Converts state_id to command string for logging
+**
+** Returns command string
+**
+*******************************************************************************/
+static char *rw_t3t_state_str (UINT8 state_id)
+{
+ switch (state_id)
+ {
+ case RW_T3T_STATE_NOT_ACTIVATED:
+ return "RW_T3T_STATE_NOT_ACTIVATED";
+
+ case RW_T3T_STATE_IDLE:
+ return "RW_T3T_STATE_IDLE";
+
+ case RW_T3T_STATE_COMMAND_PENDING:
+ return "RW_T3T_STATE_COMMAND_PENDING";
+
+ default:
+ return "Unknown";
+ }
+}
+#endif
+
+/*****************************************************************************
+** Type3 Tag API Functions
+*****************************************************************************/
+
+
+/*****************************************************************************
+**
+** Function RW_T3tDetectNDef
+**
+** Description
+** This function is used to perform NDEF detection on a Type 3 tag, and
+** retrieve the tag's NDEF attribute information (block 0).
+**
+** Before using this API, the application must call RW_SelectTagType to
+** indicate that a Type 3 tag has been activated, and to provide the
+** tag's Manufacture ID (IDm) .
+**
+** Returns
+** NFC_STATUS_OK: ndef detection procedure started
+** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+** NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tDetectNDef (void)
+{
+ tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+ tNFC_STATUS retval = NFC_STATUS_OK;
+
+ RW_TRACE_API0 ("RW_T3tDetectNDef");
+
+ /* Check if we are in valid state to handle this API */
+ if (p_cb->rw_state != RW_T3T_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
+ return (NFC_STATUS_FAILED);
+ }
+
+ if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (T3T_SYSTEM_CODE_NDEF, 0, 0)) == NCI_STATUS_OK)
+ {
+ p_cb->cur_cmd = RW_T3T_CMD_DETECT_NDEF;
+ p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
+ p_cb->cur_poll_rc = 0;
+ p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
+ p_cb->flags |= RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
+
+ /* start timer for waiting for responses */
+ rw_t3t_start_poll_timer (p_cb);
+ }
+
+ return (retval);
+}
+
+
+/*****************************************************************************
+**
+** Function RW_T3tCheckNDef
+**
+** Description
+** Retrieve NDEF contents from a Type3 tag.
+**
+** The RW_T3T_CHECK_EVT event is used to notify the application for each
+** segment of NDEF data received. The RW_T3T_CHECK_CPLT_EVT event is used to
+** notify the application all segments have been received.
+**
+** Before using this API, the RW_T3tDetectNDef function must be called to
+** verify that the tag contains NDEF data, and to retrieve the NDEF
+** attributes.
+**
+** Internally, this command will be separated into multiple Tag 3 Check
+** commands (if necessary) - depending on the tag's Nbr (max number of
+** blocks per read) attribute.
+**
+** Returns
+** NFC_STATUS_OK: check command started
+** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+** NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tCheckNDef (void)
+{
+ tNFC_STATUS retval = NFC_STATUS_OK;
+ tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+
+ RW_TRACE_API0 ("RW_T3tCheckNDef");
+
+ /* Check if we are in valid state to handle this API */
+ if (p_cb->rw_state != RW_T3T_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
+ return (NFC_STATUS_FAILED);
+ }
+ else if (p_cb->ndef_attrib.status != NFC_STATUS_OK) /* NDEF detection not performed yet? */
+ {
+ RW_TRACE_ERROR0 ("Error: NDEF detection not performed yet");
+ return (NFC_STATUS_NOT_INITIALIZED);
+ }
+ else if (p_cb->ndef_attrib.ln == 0)
+ {
+ RW_TRACE_ERROR0 ("Type 3 tag contains empty NDEF message");
+ return (NFC_STATUS_FAILED);
+ }
+
+ /* Check number of blocks needed for this update */
+ p_cb->flags &= ~RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
+ p_cb->ndef_rx_offset = 0;
+ retval = rw_t3t_send_next_ndef_check_cmd (p_cb);
+
+ return (retval);
+}
+
+/*****************************************************************************
+**
+** Function RW_T3tUpdateNDef
+**
+** Description
+** Write NDEF contents to a Type3 tag.
+**
+** The RW_T3T_UPDATE_CPLT_EVT callback event will be used to notify the
+** application of the response.
+**
+** Before using this API, the RW_T3tDetectNDef function must be called to
+** verify that the tag contains NDEF data, and to retrieve the NDEF
+** attributes.
+**
+** Internally, this command will be separated into multiple Tag 3 Update
+** commands (if necessary) - depending on the tag's Nbw (max number of
+** blocks per write) attribute.
+**
+** Returns
+** NFC_STATUS_OK: check command started
+** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+** NFC_STATUS_REFUSED: tag is read-only
+** NFC_STATUS_BUFFER_FULL: len exceeds tag's maximum size
+** NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tUpdateNDef (UINT32 len, UINT8 *p_data)
+{
+ tNFC_STATUS retval = NFC_STATUS_OK;
+ tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+
+ RW_TRACE_API1 ("RW_T3tUpdateNDef (len=%i)", len);
+
+ /* Check if we are in valid state to handle this API */
+ if (p_cb->rw_state != RW_T3T_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
+ return (NFC_STATUS_FAILED);
+ }
+ else if (p_cb->ndef_attrib.status != NFC_STATUS_OK) /* NDEF detection not performed yet? */
+ {
+ RW_TRACE_ERROR0 ("Error: NDEF detection not performed yet");
+ return (NFC_STATUS_NOT_INITIALIZED);
+ }
+ else if (len > (((UINT32)p_cb->ndef_attrib.nmaxb) * 16)) /* Len exceed's tag's NDEF memory? */
+ {
+ return (NFC_STATUS_BUFFER_FULL);
+ }
+ else if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO)/* Tag's NDEF memory is read-only? */
+ {
+ return (NFC_STATUS_REFUSED);
+ }
+
+ /* Check number of blocks needed for this update */
+ p_cb->flags &= ~RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
+ p_cb->ndef_msg_bytes_sent = 0;
+ p_cb->ndef_msg_len = len;
+ p_cb->ndef_msg = p_data;
+
+ /* Send initial UPDATE command for NDEF Attribute Info */
+ retval = rw_t3t_send_update_ndef_attribute_cmd (p_cb, TRUE);
+
+ return (retval);
+}
+
+/*****************************************************************************
+**
+** Function RW_T3tCheck
+**
+** Description
+** Read (non-NDEF) contents from a Type3 tag.
+**
+** The RW_READ_EVT event is used to notify the application for each
+** segment of NDEF data received. The RW_READ_CPLT_EVT event is used to
+** notify the application all segments have been received.
+**
+** Before using this API, the application must call RW_SelectTagType to
+** indicate that a Type 3 tag has been activated, and to provide the
+** tag's Manufacture ID (IDm) .
+**
+** Returns
+** NFC_STATUS_OK: check command started
+** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+** NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tCheck (UINT8 num_blocks, tT3T_BLOCK_DESC *t3t_blocks)
+{
+ tNFC_STATUS retval = NFC_STATUS_OK;
+ tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+
+ RW_TRACE_API1 ("RW_T3tCheck (num_blocks = %i)", num_blocks);
+
+ /* Check if we are in valid state to handle this API */
+ if (p_cb->rw_state != RW_T3T_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
+ return (NFC_STATUS_FAILED);
+ }
+
+ /* Send the CHECK command */
+ retval = rw_t3t_send_check_cmd (p_cb, num_blocks, t3t_blocks);
+
+ return (retval);
+}
+
+/*****************************************************************************
+**
+** Function RW_T3tUpdate
+**
+** Description
+** Write (non-NDEF) contents to a Type3 tag.
+**
+** The RW_WRITE_CPLT_EVT event is used to notify the application all
+** segments have been received.
+**
+** Before using this API, the application must call RW_SelectTagType to
+** indicate that a Type 3 tag has been activated, and to provide the tag's
+** Manufacture ID (IDm) .
+**
+** Returns
+** NFC_STATUS_OK: check command started
+** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+** NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tUpdate (UINT8 num_blocks, tT3T_BLOCK_DESC *t3t_blocks, UINT8 *p_data)
+{
+ tNFC_STATUS retval = NFC_STATUS_OK;
+ tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+
+ RW_TRACE_API1 ("RW_T3tUpdate (num_blocks = %i)", num_blocks);
+
+ /* Check if we are in valid state to handle this API */
+ if (p_cb->rw_state != RW_T3T_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
+ return (NFC_STATUS_FAILED);
+ }
+
+ /* Send the UPDATE command */
+ retval = rw_t3t_send_update_cmd (p_cb, num_blocks, t3t_blocks, p_data);
+
+ return (retval);
+}
+
+/*****************************************************************************
+**
+** Function RW_T3tPresenceCheck
+**
+** Description
+** Check if the tag is still in the field.
+**
+** The RW_T3T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
+** or non-presence.
+**
+** Returns
+** NFC_STATUS_OK, if raw data frame sent
+** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+** NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tPresenceCheck (void)
+{
+ tNFC_STATUS retval = NFC_STATUS_OK;
+ tRW_DATA evt_data;
+ tRW_CB *p_rw_cb = &rw_cb;
+
+ RW_TRACE_API0 ("RW_T3tPresenceCheck");
+
+ /* If RW_SelectTagType was not called (no conn_callback) return failure */
+ if (!(p_rw_cb->p_cback))
+ {
+ retval = NFC_STATUS_FAILED;
+ }
+ /* If we are not activated, then RW_T3T_PRESENCE_CHECK_EVT status=FAIL */
+ else if (p_rw_cb->tcb.t3t.rw_state == RW_T3T_STATE_NOT_ACTIVATED)
+ {
+ evt_data.status = NFC_STATUS_FAILED;
+ (*p_rw_cb->p_cback) (RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
+ }
+ /* If command is pending */
+ else if (p_rw_cb->tcb.t3t.rw_state == RW_T3T_STATE_COMMAND_PENDING)
+ {
+ /* If already performing presence check, return error */
+ if (p_rw_cb->tcb.t3t.flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP)
+ {
+ RW_TRACE_DEBUG0 ("RW_T3tPresenceCheck already in progress");
+ retval = NFC_STATUS_FAILED;
+ }
+ /* If busy with any other command, assume that the tag is present */
+ else
+ {
+ evt_data.status = NFC_STATUS_OK;
+ (*p_rw_cb->p_cback) (RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
+ }
+ }
+ else
+ {
+ /* IDLE state: send POLL command */
+ if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (0xFFFF, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK)
+ {
+ p_rw_cb->tcb.t3t.flags |= RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
+ p_rw_cb->tcb.t3t.rw_state = RW_T3T_STATE_COMMAND_PENDING;
+ p_rw_cb->tcb.t3t.cur_poll_rc = 0;
+
+ /* start timer for waiting for responses */
+ rw_t3t_start_poll_timer (&p_rw_cb->tcb.t3t);
+ }
+ else
+ {
+ RW_TRACE_DEBUG1 ("RW_T3tPresenceCheck error sending NCI_RF_T3T_POLLING cmd (status = 0x%0x)", retval);
+ }
+ }
+
+ return (retval);
+}
+
+/*****************************************************************************
+**
+** Function RW_T3tPoll
+**
+** Description
+** Send POLL command
+**
+** Returns
+** NFC_STATUS_OK, if raw data frame sent
+** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+** NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tPoll (UINT16 system_code, tT3T_POLL_RC rc, UINT8 tsn)
+{
+ tNFC_STATUS retval = NFC_STATUS_OK;
+ tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+
+ RW_TRACE_API0 ("RW_T3tPoll");
+
+ /* Check if we are in valid state to handle this API */
+ if (p_cb->rw_state != RW_T3T_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
+ return (NFC_STATUS_FAILED);
+ }
+
+ if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (system_code, (UINT8) rc, tsn)) == NCI_STATUS_OK)
+ {
+ /* start timer for waiting for responses */
+ p_cb->cur_poll_rc = rc;
+ p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
+ rw_t3t_start_poll_timer (p_cb);
+ }
+
+
+ return (retval);
+}
+
+/*****************************************************************************
+**
+** Function RW_T3tSendRawFrame
+**
+** Description
+** This function is called to send a raw data frame to the peer device.
+** When type 3 tag receives response from peer, the callback function
+** will be called with a RW_T3T_RAW_FRAME_EVT [Table 6].
+**
+** Before using this API, the application must call RW_SelectTagType to
+** indicate that a Type 3 tag has been activated.
+**
+** The raw frame should be a properly formatted Type 3 tag message.
+**
+** Returns
+** NFC_STATUS_OK, if raw data frame sent
+** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+** NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tSendRawFrame (UINT16 len, UINT8 *p_data)
+{
+ tNFC_STATUS retval = NFC_STATUS_OK;
+ tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+
+ RW_TRACE_API1 ("RW_T3tSendRawFrame (len = %i)", len);
+
+ /* Check if we are in valid state to handle this API */
+ if (p_cb->rw_state != RW_T3T_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
+ return (NFC_STATUS_FAILED);
+ }
+
+ /* Send the UPDATE command */
+ retval = rw_t3t_send_raw_frame (p_cb, len ,p_data);
+
+ return (retval);
+}
+
+/*****************************************************************************
+**
+** Function RW_T3tGetSystemCodes
+**
+** Description
+** Get systems codes supported by the activated tag:
+** Poll for wildcard (FFFF):
+** - If felica-lite code then poll for ndef (12fc)
+** - Otherwise send RequestSystmCode command to get
+** system codes.
+**
+** Before using this API, the application must call RW_SelectTagType to
+** indicate that a Type 3 tag has been activated.
+**
+** Returns
+** NFC_STATUS_OK, if raw data frame sent
+** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+** NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tGetSystemCodes (void)
+{
+ tNFC_STATUS retval = NFC_STATUS_OK;
+ tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+
+ RW_TRACE_API0 ("RW_T3tGetSystemCodes");
+
+ /* Check if we are in valid state to handle this API */
+ if (p_cb->rw_state != RW_T3T_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
+ return (NFC_STATUS_FAILED);
+ }
+ else
+ {
+ if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (0xFFFF, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK)
+ {
+ p_cb->cur_cmd = RW_T3T_CMD_GET_SYSTEM_CODES;
+ p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
+ p_cb->cur_poll_rc = T3T_POLL_RC_SC;
+ p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
+ p_cb->rw_substate = RW_T3T_GET_SC_SST_POLL_WILDCARD;
+ p_cb->flags |= RW_T3T_FL_W4_GET_SC_POLL_RSP;
+ p_cb->num_system_codes = 0;
+
+ /* start timer for waiting for responses */
+ rw_t3t_start_poll_timer (p_cb);
+ }
+ }
+
+
+
+ return (retval);
+}
+
+/*****************************************************************************
+**
+** Function RW_T3tFormatNDef
+**
+** Description
+** Format a type-3 tag for NDEF.
+**
+** Only Felica-Lite tags are supported by this API. The
+** RW_T3T_FORMAT_CPLT_EVT is used to notify the status of the operation.
+**
+** Returns
+** NFC_STATUS_OK: ndef detection procedure started
+** NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+** NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tFormatNDef (void)
+{
+ tNFC_STATUS retval = NFC_STATUS_OK;
+ tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+
+ RW_TRACE_API0 ("RW_T3tFormatNDef");
+
+ /* Check if we are in valid state to handle this API */
+ if (p_cb->rw_state != RW_T3T_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
+ return (NFC_STATUS_FAILED);
+ }
+ else
+ {
+ /* Poll tag, to see if Felica-Lite system is supported */
+ if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (T3T_SYSTEM_CODE_FELICA_LITE, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK)
+ {
+ p_cb->cur_cmd = RW_T3T_CMD_FORMAT;
+ p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
+ p_cb->cur_poll_rc = T3T_POLL_RC_SC;
+ p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
+ p_cb->rw_substate = RW_T3T_FMT_SST_POLL_FELICA_LITE;
+ p_cb->flags |= RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
+
+ /* start timer for waiting for responses */
+ rw_t3t_start_poll_timer (p_cb);
+ }
+ }
+
+
+
+ return (retval);
+}
+
+/*****************************************************************************
+**
+** 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 (BOOLEAN 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 */
+ if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (T3T_SYSTEM_CODE_FELICA_LITE, T3T_POLL_RC_SC, 0)) == 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..17a9b76
--- /dev/null
+++ b/src/nfc/tags/rw_t4t.c
@@ -0,0 +1,2711 @@
+/******************************************************************************
+ *
+ * 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"
+
+#if (NFC_INCLUDED == TRUE)
+
+#include "nfc_api.h"
+#include "nfc_int.h"
+#include "rw_api.h"
+#include "rw_int.h"
+#include "tags_int.h"
+#include "gki.h"
+
+/* main state */
+#define RW_T4T_STATE_NOT_ACTIVATED 0x00 /* T4T is not activated */
+#define RW_T4T_STATE_IDLE 0x01 /* waiting for upper layer API */
+#define RW_T4T_STATE_DETECT_NDEF 0x02 /* performing NDEF detection precedure */
+#define RW_T4T_STATE_READ_NDEF 0x03 /* performing read NDEF procedure */
+#define RW_T4T_STATE_UPDATE_NDEF 0x04 /* performing update NDEF procedure */
+#define RW_T4T_STATE_PRESENCE_CHECK 0x05 /* checking presence of tag */
+#define RW_T4T_STATE_SET_READ_ONLY 0x06 /* convert tag to read only */
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#define RW_T4T_STATE_NDEF_FORMAT 0x07 /* performing NDEF format */
+#define RW_T3BT_STATE_GET_PROP_DATA 0x08
+#endif
+/* sub state */
+#define RW_T4T_SUBSTATE_WAIT_SELECT_APP 0x00 /* waiting for response of selecting AID */
+#define RW_T4T_SUBSTATE_WAIT_SELECT_CC 0x01 /* waiting for response of selecting CC */
+#define RW_T4T_SUBSTATE_WAIT_CC_FILE 0x02 /* waiting for response of reading CC */
+#define RW_T4T_SUBSTATE_WAIT_SELECT_NDEF_FILE 0x03 /* waiting for response of selecting NDEF */
+#define RW_T4T_SUBSTATE_WAIT_READ_NLEN 0x04 /* waiting for response of reading NLEN */
+#define RW_T4T_SUBSTATE_WAIT_READ_RESP 0x05 /* waiting for response of reading file */
+#define RW_T4T_SUBSTATE_WAIT_UPDATE_RESP 0x06 /* waiting for response of updating file */
+#define RW_T4T_SUBSTATE_WAIT_UPDATE_NLEN 0x07 /* waiting for response of updating NLEN */
+#define RW_T4T_SUBSTATE_WAIT_UPDATE_CC 0x08 /* waiting for response of updating CC */
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+#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
+#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 state);
+static char *rw_t4t_get_sub_state_name (UINT8 sub_state);
+#endif
+
+static BOOLEAN rw_t4t_send_to_lower (BT_HDR *p_c_apdu);
+static BOOLEAN rw_t4t_select_file (UINT16 file_id);
+static BOOLEAN rw_t4t_read_file (UINT16 offset, UINT16 length, BOOLEAN is_continue);
+static BOOLEAN rw_t4t_update_nlen (UINT16 ndef_len);
+static BOOLEAN rw_t4t_update_file (void);
+static BOOLEAN rw_t4t_update_cc_to_readonly (void);
+static BOOLEAN rw_t4t_select_application (UINT8 version);
+static BOOLEAN rw_t4t_validate_cc_file (void);
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+static BOOLEAN rw_t4t_get_hw_version (void);
+static BOOLEAN rw_t4t_get_sw_version (void);
+static BOOLEAN rw_t4t_create_app (void);
+static BOOLEAN rw_t4t_select_app (void);
+static BOOLEAN rw_t4t_create_ccfile (void);
+static BOOLEAN rw_t4t_create_ndef (void);
+static BOOLEAN rw_t4t_write_cc (void);
+static BOOLEAN rw_t4t_write_ndef (void);
+static BOOLEAN rw_t3bt_get_pupi (void);
+#endif
+static void rw_t4t_handle_error (tNFC_STATUS status, UINT8 sw1, UINT8 sw2);
+static void rw_t4t_sm_detect_ndef (BT_HDR *p_r_apdu);
+static void rw_t4t_sm_read_ndef (BT_HDR *p_r_apdu);
+static void rw_t4t_sm_update_ndef (BT_HDR *p_r_apdu);
+static void rw_t4t_sm_set_readonly (BT_HDR *p_r_apdu);
+static void rw_t4t_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data);
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+static void rw_t4t_sm_ndef_format (BT_HDR *p_r_apdu);
+static void rw_t3Bt_sm_get_card_id(BT_HDR *p_r_apdu);
+#endif
+/*******************************************************************************
+**
+** Function rw_t4t_send_to_lower
+**
+** Description Send C-APDU to lower layer
+**
+** Returns TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN rw_t4t_send_to_lower (BT_HDR *p_c_apdu)
+{
+#if (BT_TRACE_PROTOCOL == TRUE)
+ DispRWT4Tags (p_c_apdu, FALSE);
+#endif
+
+ if (NFC_SendData (NFC_RF_CONN_ID, p_c_apdu) != NFC_STATUS_OK)
+ {
+ RW_TRACE_ERROR0 ("rw_t4t_send_to_lower (): NFC_SendData () failed");
+ return FALSE;
+ }
+
+ nfc_start_quick_timer (&rw_cb.tcb.t4t.timer, NFC_TTYPE_RW_T4T_RESPONSE,
+ (RW_T4T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+
+ return TRUE;
+}
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+/*******************************************************************************
+**
+** Function rw_t4t_get_hw_version
+**
+** Description Send get hw version cmd to peer
+**
+** Returns TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN rw_t4t_get_hw_version (void)
+{
+ BT_HDR *p_c_apdu;
+ UINT8 *p;
+
+ p_c_apdu = (BT_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 *) (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 BOOLEAN rw_t4t_get_sw_version (void)
+{
+ BT_HDR *p_c_apdu;
+ UINT8 *p;
+
+ p_c_apdu = (BT_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 *) (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 BOOLEAN rw_t4t_update_version_details(BT_HDR *p_r_apdu)
+{
+ tRW_T4T_CB *p_t4t = &rw_cb.tcb.t4t;
+ UINT8 *p;
+ UINT16 major_version, minor_version;
+
+ p = (UINT8 *) (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;
+ break;
+ }
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function rw_t4t_get_uid_details
+**
+** Description Send get uid cmd to peer
+**
+** Returns TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN rw_t4t_get_uid_details (void)
+{
+ BT_HDR *p_c_apdu;
+ UINT8 *p;
+
+ p_c_apdu = (BT_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 *) (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 BOOLEAN rw_t4t_create_app (void)
+{
+ tRW_T4T_CB *p_t4t = &rw_cb.tcb.t4t;
+ BT_HDR *p_c_apdu;
+ UINT8 *p;
+ UINT8 df_name[] = {0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01};
+ p_c_apdu = (BT_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 *) (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,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 BOOLEAN rw_t4t_select_app (void)
+{
+ tRW_T4T_CB *p_t4t = &rw_cb.tcb.t4t;
+ BT_HDR *p_c_apdu;
+ UINT8 *p;
+
+ p_c_apdu = (BT_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 *) (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 BOOLEAN rw_t4t_create_ccfile (void)
+{
+ tRW_T4T_CB *p_t4t = &rw_cb.tcb.t4t;
+ BT_HDR *p_c_apdu;
+ UINT8 *p;
+
+ p_c_apdu = (BT_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 *) (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 BOOLEAN rw_t4t_create_ndef (void)
+{
+ tRW_T4T_CB *p_t4t = &rw_cb.tcb.t4t;
+ BT_HDR *p_c_apdu;
+ UINT8 *p;
+
+ p_c_apdu = (BT_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 *) (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 BOOLEAN rw_t4t_write_cc (void)
+{
+ tRW_T4T_CB *p_t4t = &rw_cb.tcb.t4t;
+ BT_HDR *p_c_apdu;
+ UINT8 *p;
+ UINT8 CCFileBytes[] = {0x00,0x0f,0x10,0x00,0x3B,0x00,0x34,0x04,0x06,0xE1,0x04,0x04,0x00,0x00,0x00};
+
+ p_c_apdu = (BT_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 *) (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) 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, 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 BOOLEAN rw_t4t_write_ndef (void)
+{
+ tRW_T4T_CB *p_t4t = &rw_cb.tcb.t4t;
+ BT_HDR *p_c_apdu;
+ UINT8 *p;
+
+ p_c_apdu = (BT_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 *) (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;
+}
+#endif
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+static BOOLEAN rw_t3bt_get_pupi (void)
+{
+ tRW_T4T_CB *p_t4t = &rw_cb.tcb.t4t;
+ BT_HDR *p_c_apdu;
+ UINT8 *p;
+
+ p_c_apdu = (BT_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 *) (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 BOOLEAN rw_t4t_select_file (UINT16 file_id)
+{
+ BT_HDR *p_c_apdu;
+ UINT8 *p;
+
+ RW_TRACE_DEBUG1 ("rw_t4t_select_file (): File ID:0x%04X", file_id);
+
+ p_c_apdu = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+ if (!p_c_apdu)
+ {
+ RW_TRACE_ERROR0 ("rw_t4t_select_file (): Cannot allocate buffer");
+ return FALSE;
+ }
+
+ p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p = (UINT8 *) (p_c_apdu + 1) + p_c_apdu->offset;
+
+ UINT8_TO_BE_STREAM (p, T4T_CMD_CLASS);
+ UINT8_TO_BE_STREAM (p, T4T_CMD_INS_SELECT);
+ UINT8_TO_BE_STREAM (p, T4T_CMD_P1_SELECT_BY_FILE_ID);
+
+ /* if current version mapping is V2.0 */
+ if (rw_cb.tcb.t4t.version == T4T_VERSION_2_0)
+ {
+ UINT8_TO_BE_STREAM (p, T4T_CMD_P2_FIRST_OR_ONLY_0CH);
+ }
+ else /* version 1.0 */
+ {
+ UINT8_TO_BE_STREAM (p, T4T_CMD_P2_FIRST_OR_ONLY_00H);
+ }
+
+ UINT8_TO_BE_STREAM (p, T4T_FILE_ID_SIZE);
+ UINT16_TO_BE_STREAM (p, file_id);
+
+ p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + T4T_FILE_ID_SIZE;
+
+ if (!rw_t4t_send_to_lower (p_c_apdu))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function rw_t4t_read_file
+**
+** Description Send ReadBinary Command to peer
+**
+** Returns TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN rw_t4t_read_file (UINT16 offset, UINT16 length, BOOLEAN is_continue)
+{
+ tRW_T4T_CB *p_t4t = &rw_cb.tcb.t4t;
+ BT_HDR *p_c_apdu;
+ UINT8 *p;
+
+ RW_TRACE_DEBUG3 ("rw_t4t_read_file () offset:%d, length:%d, is_continue:%d, ",
+ offset, length, is_continue);
+
+ p_c_apdu = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+ if (!p_c_apdu)
+ {
+ RW_TRACE_ERROR0 ("rw_t4t_read_file (): Cannot allocate buffer");
+ return FALSE;
+ }
+
+ /* if this is the first reading */
+ if (is_continue == FALSE)
+ {
+ /* initialise starting offset and total length */
+ /* these will be updated when receiving response */
+ p_t4t->rw_offset = offset;
+ p_t4t->rw_length = length;
+ }
+
+ /* adjust reading length if payload is bigger than max size per single command */
+ if (length > p_t4t->max_read_size)
+ {
+ length = (UINT8) (p_t4t->max_read_size);
+ }
+
+ p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p = (UINT8 *) (p_c_apdu + 1) + p_c_apdu->offset;
+
+ UINT8_TO_BE_STREAM (p, (T4T_CMD_CLASS | 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 BOOLEAN rw_t4t_update_nlen (UINT16 ndef_len)
+{
+ BT_HDR *p_c_apdu;
+ UINT8 *p;
+
+ RW_TRACE_DEBUG1 ("rw_t4t_update_nlen () NLEN:%d", ndef_len);
+
+ p_c_apdu = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+ if (!p_c_apdu)
+ {
+ RW_TRACE_ERROR0 ("rw_t4t_update_nlen (): Cannot allocate buffer");
+ return FALSE;
+ }
+
+ p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p = (UINT8 *) (p_c_apdu + 1) + p_c_apdu->offset;
+
+ UINT8_TO_BE_STREAM (p, T4T_CMD_CLASS);
+ UINT8_TO_BE_STREAM (p, T4T_CMD_INS_UPDATE_BINARY);
+ UINT16_TO_BE_STREAM (p, 0x0000); /* offset for NLEN */
+ UINT8_TO_BE_STREAM (p, T4T_FILE_LENGTH_SIZE);
+ UINT16_TO_BE_STREAM (p, ndef_len);
+
+ p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + T4T_FILE_LENGTH_SIZE;
+
+ if (!rw_t4t_send_to_lower (p_c_apdu))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function rw_t4t_update_file
+**
+** Description Send UpdateBinary Command to peer
+**
+** Returns TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN rw_t4t_update_file (void)
+{
+ tRW_T4T_CB *p_t4t = &rw_cb.tcb.t4t;
+ BT_HDR *p_c_apdu;
+ UINT8 *p;
+ UINT16 length;
+
+ RW_TRACE_DEBUG2 ("rw_t4t_update_file () rw_offset:%d, rw_length:%d",
+ p_t4t->rw_offset, p_t4t->rw_length);
+
+ p_c_apdu = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+ if (!p_c_apdu)
+ {
+ RW_TRACE_ERROR0 ("rw_t4t_write_file (): Cannot allocate buffer");
+ return FALSE;
+ }
+
+ /* try to send all of remaining data */
+ length = p_t4t->rw_length;
+
+ /* adjust updating length if payload is bigger than max size per single command */
+ if (length > p_t4t->max_update_size)
+ {
+ length = (UINT8) (p_t4t->max_update_size);
+ }
+
+ p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p = (UINT8 *) (p_c_apdu + 1) + p_c_apdu->offset;
+
+ UINT8_TO_BE_STREAM (p, T4T_CMD_CLASS);
+ UINT8_TO_BE_STREAM (p, T4T_CMD_INS_UPDATE_BINARY);
+ UINT16_TO_BE_STREAM (p, p_t4t->rw_offset);
+ UINT8_TO_BE_STREAM (p, length);
+
+ memcpy (p, p_t4t->p_update_data, length);
+
+ p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + length;
+
+ if (!rw_t4t_send_to_lower (p_c_apdu))
+ {
+ return FALSE;
+ }
+
+ /* adjust offset, length and pointer for remaining data */
+ p_t4t->rw_offset += length;
+ p_t4t->rw_length -= length;
+ p_t4t->p_update_data += length;
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function rw_t4t_update_cc_to_readonly
+**
+** Description Send UpdateBinary Command for changing Write access
+**
+** Returns TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN rw_t4t_update_cc_to_readonly (void)
+{
+ BT_HDR *p_c_apdu;
+ UINT8 *p;
+
+ RW_TRACE_DEBUG0 ("rw_t4t_update_cc_to_readonly (): Remove Write access from CC");
+
+ p_c_apdu = (BT_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 *) (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 BOOLEAN rw_t4t_select_application (UINT8 version)
+{
+ BT_HDR *p_c_apdu;
+ UINT8 *p;
+
+ RW_TRACE_DEBUG1 ("rw_t4t_select_application () version:0x%X", version);
+
+ p_c_apdu = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+ if (!p_c_apdu)
+ {
+ RW_TRACE_ERROR0 ("rw_t4t_select_application (): Cannot allocate buffer");
+ return FALSE;
+ }
+
+ p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p = (UINT8 *) (p_c_apdu + 1) + p_c_apdu->offset;
+
+ UINT8_TO_BE_STREAM (p, T4T_CMD_CLASS);
+ UINT8_TO_BE_STREAM (p, T4T_CMD_INS_SELECT);
+ UINT8_TO_BE_STREAM (p, T4T_CMD_P1_SELECT_BY_NAME);
+ UINT8_TO_BE_STREAM (p, T4T_CMD_P2_FIRST_OR_ONLY_00H);
+
+ if (version == T4T_VERSION_1_0) /* this is for V1.0 */
+ {
+ UINT8_TO_BE_STREAM (p, T4T_V10_NDEF_TAG_AID_LEN);
+
+ memcpy (p, t4t_v10_ndef_tag_aid, T4T_V10_NDEF_TAG_AID_LEN);
+
+ p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + T4T_V10_NDEF_TAG_AID_LEN;
+ }
+ else if (version == T4T_VERSION_2_0) /* this is for V2.0 */
+ {
+ UINT8_TO_BE_STREAM (p, T4T_V20_NDEF_TAG_AID_LEN);
+
+ memcpy (p, t4t_v20_ndef_tag_aid, T4T_V20_NDEF_TAG_AID_LEN);
+ p += T4T_V20_NDEF_TAG_AID_LEN;
+
+ UINT8_TO_BE_STREAM (p, 0x00); /* Le set to 0x00 */
+
+ p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + T4T_V20_NDEF_TAG_AID_LEN + 1;
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ if (!rw_t4t_send_to_lower (p_c_apdu))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function rw_t4t_validate_cc_file
+**
+** Description Validate CC file and mandatory NDEF TLV
+**
+** Returns TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN rw_t4t_validate_cc_file (void)
+{
+ tRW_T4T_CB *p_t4t = &rw_cb.tcb.t4t;
+
+ RW_TRACE_DEBUG0 ("rw_t4t_validate_cc_file ()");
+
+ if (p_t4t->cc_file.cclen < T4T_CC_FILE_MIN_LEN)
+ {
+ RW_TRACE_ERROR1 ("rw_t4t_validate_cc_file (): CCLEN (%d) is too short",
+ p_t4t->cc_file.cclen);
+ return FALSE;
+ }
+
+ if (T4T_GET_MAJOR_VERSION (p_t4t->cc_file.version) != T4T_GET_MAJOR_VERSION (p_t4t->version))
+ {
+ RW_TRACE_ERROR2 ("rw_t4t_validate_cc_file (): Peer version (0x%02X) is matched to ours (0x%02X)",
+ p_t4t->cc_file.version, p_t4t->version);
+ return FALSE;
+ }
+
+ if (p_t4t->cc_file.max_le < 0x000F)
+ {
+ RW_TRACE_ERROR1 ("rw_t4t_validate_cc_file (): MaxLe (%d) is too small",
+ p_t4t->cc_file.max_le);
+ return FALSE;
+ }
+
+ if (p_t4t->cc_file.max_lc < 0x0001)
+ {
+ RW_TRACE_ERROR1 ("rw_t4t_validate_cc_file (): MaxLc (%d) is too small",
+ p_t4t->cc_file.max_lc);
+ return FALSE;
+ }
+
+ if ( (p_t4t->cc_file.ndef_fc.file_id == T4T_CC_FILE_ID)
+ ||(p_t4t->cc_file.ndef_fc.file_id == 0xE102)
+ ||(p_t4t->cc_file.ndef_fc.file_id == 0xE103)
+ ||((p_t4t->cc_file.ndef_fc.file_id == 0x0000) && (p_t4t->cc_file.version == 0x20))
+ ||(p_t4t->cc_file.ndef_fc.file_id == 0x3F00)
+ ||(p_t4t->cc_file.ndef_fc.file_id == 0x3FFF)
+ ||(p_t4t->cc_file.ndef_fc.file_id == 0xFFFF) )
+ {
+ RW_TRACE_ERROR1 ("rw_t4t_validate_cc_file (): File ID (0x%04X) is invalid",
+ p_t4t->cc_file.ndef_fc.file_id);
+ return FALSE;
+ }
+
+ if ( (p_t4t->cc_file.ndef_fc.max_file_size < 0x0005)
+ ||(p_t4t->cc_file.ndef_fc.max_file_size == 0xFFFF) )
+ {
+ RW_TRACE_ERROR1 ("rw_t4t_validate_cc_file (): max_file_size (%d) is reserved",
+ p_t4t->cc_file.ndef_fc.max_file_size);
+ return FALSE;
+ }
+
+ if (p_t4t->cc_file.ndef_fc.read_access != T4T_FC_READ_ACCESS)
+ {
+ RW_TRACE_ERROR1 ("rw_t4t_validate_cc_file (): Read Access (0x%02X) is invalid",
+ p_t4t->cc_file.ndef_fc.read_access);
+ return FALSE;
+ }
+
+ if ( (p_t4t->cc_file.ndef_fc.write_access != T4T_FC_WRITE_ACCESS)
+ &&(p_t4t->cc_file.ndef_fc.write_access != T4T_FC_NO_WRITE_ACCESS) )
+ {
+ RW_TRACE_ERROR1 ("rw_t4t_validate_cc_file (): Write Access (0x%02X) is invalid",
+ p_t4t->cc_file.ndef_fc.write_access);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function rw_t4t_handle_error
+**
+** Description notify error to application and clean up
+**
+** Returns none
+**
+*******************************************************************************/
+static void rw_t4t_handle_error (tNFC_STATUS status, UINT8 sw1, UINT8 sw2)
+{
+ tRW_T4T_CB *p_t4t = &rw_cb.tcb.t4t;
+ tRW_DATA rw_data;
+ tRW_EVENT event;
+
+ RW_TRACE_DEBUG4 ("rw_t4t_handle_error (): status: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;
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ case RW_T4T_STATE_NDEF_FORMAT:
+ event = RW_T4T_NDEF_FORMAT_CPLT_EVT;
+ rw_data.status = NFC_STATUS_FAILED;
+ break;
+ 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;
+ }
+}
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+/*******************************************************************************
+**
+** Function rw_t4t_sm_ndef_format
+**
+** Description State machine for NDEF format procedure
+**
+** Returns none
+**
+*******************************************************************************/
+static void rw_t4t_sm_ndef_format(BT_HDR *p_r_apdu)
+{
+ tRW_T4T_CB *p_t4t = &rw_cb.tcb.t4t;
+ UINT8 *p, type, length;
+ UINT16 status_words, nlen;
+ tRW_DATA rw_data;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ RW_TRACE_DEBUG2 ("rw_t4t_sm_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 *) (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;
+ }
+}
+#endif
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+static void rw_t3Bt_sm_get_card_id(BT_HDR *p_r_apdu)
+{
+ tRW_T4T_CB *p_t4t = &rw_cb.tcb.t4t;
+ UINT8 *p, type, length;
+ UINT16 status_words, nlen;
+ tRW_DATA rw_data;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ RW_TRACE_DEBUG2 ("rw_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 *) (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 rsp_len = p_r_apdu->len - 3;
+ p = (UINT8 *) (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 (BT_HDR *p_r_apdu)
+{
+ tRW_T4T_CB *p_t4t = &rw_cb.tcb.t4t;
+ UINT8 *p, type, length;
+ UINT16 status_words, nlen;
+ tRW_DATA rw_data;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ RW_TRACE_DEBUG2 ("rw_t4t_sm_detect_ndef (): sub_state:%s (%d)",
+ rw_t4t_get_sub_state_name (p_t4t->sub_state), p_t4t->sub_state);
+#else
+ RW_TRACE_DEBUG1 ("rw_t4t_sm_detect_ndef (): sub_state=%d", p_t4t->sub_state);
+#endif
+
+ /* get status words */
+ p = (UINT8 *) (p_r_apdu + 1) + p_r_apdu->offset;
+ p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
+ BE_STREAM_TO_UINT16 (status_words, p);
+
+ if (status_words != T4T_RSP_CMD_CMPLTED)
+ {
+ /* try V1.0 after failing of V2.0 */
+ if ( (p_t4t->sub_state == RW_T4T_SUBSTATE_WAIT_SELECT_APP)
+ &&(p_t4t->version == T4T_VERSION_2_0) )
+ {
+ p_t4t->version = T4T_VERSION_1_0;
+
+ RW_TRACE_DEBUG1 ("rw_t4t_sm_detect_ndef (): retry with version=0x%02X",
+ p_t4t->version);
+
+ if (!rw_t4t_select_application (T4T_VERSION_1_0))
+ {
+ rw_t4t_handle_error (NFC_STATUS_FAILED, 0, 0);
+ }
+ return;
+ }
+
+ p_t4t->ndef_status &= ~ (RW_T4T_NDEF_STATUS_NDEF_DETECTED);
+ rw_t4t_handle_error (NFC_STATUS_CMD_NOT_CMPLTD, *(p-2), *(p-1));
+ return;
+ }
+
+ switch (p_t4t->sub_state)
+ {
+ case RW_T4T_SUBSTATE_WAIT_SELECT_APP:
+
+ /* NDEF Tag application has been selected then select CC file */
+ if (!rw_t4t_select_file (T4T_CC_FILE_ID))
+ {
+ rw_t4t_handle_error (NFC_STATUS_FAILED, 0, 0);
+ }
+ else
+ {
+ p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_CC;
+ }
+ break;
+
+ case RW_T4T_SUBSTATE_WAIT_SELECT_CC:
+
+ /* CC file has been selected then read mandatory part of CC file */
+ if (!rw_t4t_read_file (0x00, T4T_CC_FILE_MIN_LEN, FALSE))
+ {
+ rw_t4t_handle_error (NFC_STATUS_FAILED, 0, 0);
+ }
+ else
+ {
+ p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_CC_FILE;
+ }
+ break;
+
+ case RW_T4T_SUBSTATE_WAIT_CC_FILE:
+
+ /* CC file has been read then validate and select mandatory NDEF file */
+ if (p_r_apdu->len >= T4T_CC_FILE_MIN_LEN + T4T_RSP_STATUS_WORDS_SIZE)
+ {
+ p = (UINT8 *) (p_r_apdu + 1) + p_r_apdu->offset;
+
+ BE_STREAM_TO_UINT16 (p_t4t->cc_file.cclen, p);
+ BE_STREAM_TO_UINT8 (p_t4t->cc_file.version, p);
+ BE_STREAM_TO_UINT16 (p_t4t->cc_file.max_le, p);
+ BE_STREAM_TO_UINT16 (p_t4t->cc_file.max_lc, p);
+
+ BE_STREAM_TO_UINT8 (type, p);
+ BE_STREAM_TO_UINT8 (length, p);
+
+ if ( (type == T4T_NDEF_FILE_CONTROL_TYPE)
+ &&(length == T4T_FILE_CONTROL_LENGTH) )
+ {
+ BE_STREAM_TO_UINT16 (p_t4t->cc_file.ndef_fc.file_id, p);
+ BE_STREAM_TO_UINT16 (p_t4t->cc_file.ndef_fc.max_file_size, p);
+ BE_STREAM_TO_UINT8 (p_t4t->cc_file.ndef_fc.read_access, p);
+ BE_STREAM_TO_UINT8 (p_t4t->cc_file.ndef_fc.write_access, p);
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ RW_TRACE_DEBUG0 ("Capability Container (CC) file");
+ RW_TRACE_DEBUG1 (" CCLEN: 0x%04X", p_t4t->cc_file.cclen);
+ RW_TRACE_DEBUG1 (" Version:0x%02X", p_t4t->cc_file.version);
+ RW_TRACE_DEBUG1 (" MaxLe: 0x%04X", p_t4t->cc_file.max_le);
+ RW_TRACE_DEBUG1 (" MaxLc: 0x%04X", p_t4t->cc_file.max_lc);
+ RW_TRACE_DEBUG0 (" NDEF File Control TLV");
+ RW_TRACE_DEBUG1 (" FileID: 0x%04X", p_t4t->cc_file.ndef_fc.file_id);
+ RW_TRACE_DEBUG1 (" MaxFileSize: 0x%04X", p_t4t->cc_file.ndef_fc.max_file_size);
+ RW_TRACE_DEBUG1 (" ReadAccess: 0x%02X", p_t4t->cc_file.ndef_fc.read_access);
+ RW_TRACE_DEBUG1 (" WriteAccess: 0x%02X", p_t4t->cc_file.ndef_fc.write_access);
+#endif
+
+ if (rw_t4t_validate_cc_file ())
+ {
+ if (!rw_t4t_select_file (p_t4t->cc_file.ndef_fc.file_id))
+ {
+ rw_t4t_handle_error (NFC_STATUS_FAILED, 0, 0);
+ }
+ else
+ {
+ p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_NDEF_FILE;
+ }
+ break;
+ }
+ }
+ }
+
+ /* invalid response or CC file */
+ p_t4t->ndef_status &= ~ (RW_T4T_NDEF_STATUS_NDEF_DETECTED);
+ rw_t4t_handle_error (NFC_STATUS_BAD_RESP, 0, 0);
+ break;
+
+ case RW_T4T_SUBSTATE_WAIT_SELECT_NDEF_FILE:
+
+ /* NDEF file has been selected then read the first 2 bytes (NLEN) */
+ if (!rw_t4t_read_file (0, T4T_FILE_LENGTH_SIZE, FALSE))
+ {
+ rw_t4t_handle_error (NFC_STATUS_FAILED, 0, 0);
+ }
+ else
+ {
+ p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_READ_NLEN;
+ }
+ break;
+
+ case RW_T4T_SUBSTATE_WAIT_READ_NLEN:
+
+ /* NLEN has been read then report upper layer */
+ if (p_r_apdu->len == T4T_FILE_LENGTH_SIZE + T4T_RSP_STATUS_WORDS_SIZE)
+ {
+ /* get length of NDEF */
+ p = (UINT8 *) (p_r_apdu + 1) + p_r_apdu->offset;
+ BE_STREAM_TO_UINT16 (nlen, p);
+
+ if (nlen <= p_t4t->cc_file.ndef_fc.max_file_size - T4T_FILE_LENGTH_SIZE)
+ {
+ p_t4t->ndef_status = RW_T4T_NDEF_STATUS_NDEF_DETECTED;
+
+ if (p_t4t->cc_file.ndef_fc.write_access != T4T_FC_WRITE_ACCESS)
+ {
+ p_t4t->ndef_status |= RW_T4T_NDEF_STATUS_NDEF_READ_ONLY;
+ }
+
+ /* Get max bytes to read per command */
+ if (p_t4t->cc_file.max_le >= RW_T4T_MAX_DATA_PER_READ)
+ {
+ p_t4t->max_read_size = RW_T4T_MAX_DATA_PER_READ;
+ }
+ else
+ {
+ p_t4t->max_read_size = p_t4t->cc_file.max_le;
+ }
+
+ /* Le: valid range is 0x01 to 0xFF */
+ if (p_t4t->max_read_size >= T4T_MAX_LENGTH_LE)
+ {
+ p_t4t->max_read_size = T4T_MAX_LENGTH_LE;
+ }
+
+ /* Get max bytes to update per command */
+ if (p_t4t->cc_file.max_lc >= RW_T4T_MAX_DATA_PER_WRITE)
+ {
+ p_t4t->max_update_size = RW_T4T_MAX_DATA_PER_WRITE;
+ }
+ else
+ {
+ p_t4t->max_update_size = p_t4t->cc_file.max_lc;
+ }
+
+ /* Lc: valid range is 0x01 to 0xFF */
+ if (p_t4t->max_update_size >= T4T_MAX_LENGTH_LC)
+ {
+ p_t4t->max_update_size = T4T_MAX_LENGTH_LC;
+ }
+
+ p_t4t->ndef_length = nlen;
+ p_t4t->state = RW_T4T_STATE_IDLE;
+
+ if (rw_cb.p_cback)
+ {
+ rw_data.ndef.status = NFC_STATUS_OK;
+ rw_data.ndef.protocol = NFC_PROTOCOL_ISO_DEP;
+ rw_data.ndef.max_size = (UINT32) (p_t4t->cc_file.ndef_fc.max_file_size - (UINT16) T4T_FILE_LENGTH_SIZE);
+ rw_data.ndef.cur_size = nlen;
+ rw_data.ndef.flags = RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATED;
+ if (p_t4t->cc_file.ndef_fc.write_access != T4T_FC_WRITE_ACCESS)
+ {
+ rw_data.ndef.flags |= RW_NDEF_FL_READ_ONLY;
+ }
+
+ (*(rw_cb.p_cback)) (RW_T4T_NDEF_DETECT_EVT, &rw_data);
+
+ RW_TRACE_DEBUG0 ("rw_t4t_sm_detect_ndef (): Sent RW_T4T_NDEF_DETECT_EVT");
+ }
+ }
+ else
+ {
+ /* NLEN should be less than max file size */
+ RW_TRACE_ERROR2 ("rw_t4t_sm_detect_ndef (): NLEN (%d) + 2 must be <= max file size (%d)",
+ nlen, p_t4t->cc_file.ndef_fc.max_file_size);
+
+ p_t4t->ndef_status &= ~ (RW_T4T_NDEF_STATUS_NDEF_DETECTED);
+ rw_t4t_handle_error (NFC_STATUS_BAD_RESP, 0, 0);
+ }
+ }
+ else
+ {
+ /* response payload size should be T4T_FILE_LENGTH_SIZE */
+ RW_TRACE_ERROR2 ("rw_t4t_sm_detect_ndef (): Length (%d) of R-APDU must be %d",
+ p_r_apdu->len, T4T_FILE_LENGTH_SIZE + T4T_RSP_STATUS_WORDS_SIZE);
+
+ p_t4t->ndef_status &= ~ (RW_T4T_NDEF_STATUS_NDEF_DETECTED);
+ rw_t4t_handle_error (NFC_STATUS_BAD_RESP, 0, 0);
+ }
+ break;
+
+ default:
+ RW_TRACE_ERROR1 ("rw_t4t_sm_detect_ndef (): unknown sub_state=%d", p_t4t->sub_state);
+ rw_t4t_handle_error (NFC_STATUS_FAILED, 0, 0);
+ break;
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_t4t_sm_read_ndef
+**
+** Description State machine for NDEF read procedure
+**
+** Returns none
+**
+*******************************************************************************/
+static void rw_t4t_sm_read_ndef (BT_HDR *p_r_apdu)
+{
+ tRW_T4T_CB *p_t4t = &rw_cb.tcb.t4t;
+ UINT8 *p;
+ UINT16 status_words;
+ tRW_DATA rw_data;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ RW_TRACE_DEBUG2 ("rw_t4t_sm_read_ndef (): sub_state:%s (%d)",
+ rw_t4t_get_sub_state_name (p_t4t->sub_state), p_t4t->sub_state);
+#else
+ RW_TRACE_DEBUG1 ("rw_t4t_sm_read_ndef (): sub_state=%d", p_t4t->sub_state);
+#endif
+
+ /* get status words */
+ p = (UINT8 *) (p_r_apdu + 1) + p_r_apdu->offset;
+ p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
+ BE_STREAM_TO_UINT16 (status_words, p);
+
+ if (status_words != T4T_RSP_CMD_CMPLTED)
+ {
+ rw_t4t_handle_error (NFC_STATUS_CMD_NOT_CMPLTD, *(p-2), *(p-1));
+ GKI_freebuf (p_r_apdu);
+ return;
+ }
+
+ switch (p_t4t->sub_state)
+ {
+ case RW_T4T_SUBSTATE_WAIT_READ_RESP:
+
+ /* Read partial or complete data */
+ p_r_apdu->len -= T4T_RSP_STATUS_WORDS_SIZE;
+
+ if ((p_r_apdu->len > 0) && (p_r_apdu->len <= p_t4t->rw_length))
+ {
+ p_t4t->rw_length -= p_r_apdu->len;
+ p_t4t->rw_offset += p_r_apdu->len;
+
+ if (rw_cb.p_cback)
+ {
+ rw_data.data.status = NFC_STATUS_OK;
+ rw_data.data.p_data = p_r_apdu;
+
+ /* if need to read more data */
+ if (p_t4t->rw_length > 0)
+ {
+ (*(rw_cb.p_cback)) (RW_T4T_NDEF_READ_EVT, &rw_data);
+
+ if (!rw_t4t_read_file (p_t4t->rw_offset, p_t4t->rw_length, TRUE))
+ {
+ rw_t4t_handle_error (NFC_STATUS_FAILED, 0, 0);
+ }
+ }
+ else
+ {
+ p_t4t->state = RW_T4T_STATE_IDLE;
+
+ (*(rw_cb.p_cback)) (RW_T4T_NDEF_READ_CPLT_EVT, &rw_data);
+
+ RW_TRACE_DEBUG0 ("rw_t4t_sm_read_ndef (): Sent RW_T4T_NDEF_READ_CPLT_EVT");
+
+ }
+
+ p_r_apdu = NULL;
+ }
+ else
+ {
+ p_t4t->rw_length = 0;
+ p_t4t->state = RW_T4T_STATE_IDLE;
+ }
+ }
+ else
+ {
+ RW_TRACE_ERROR2 ("rw_t4t_sm_read_ndef (): invalid payload length (%d), rw_length (%d)",
+ p_r_apdu->len, p_t4t->rw_length);
+ rw_t4t_handle_error (NFC_STATUS_BAD_RESP, 0, 0);
+ }
+ break;
+
+ default:
+ RW_TRACE_ERROR1 ("rw_t4t_sm_read_ndef (): unknown sub_state = %d", p_t4t->sub_state);
+ rw_t4t_handle_error (NFC_STATUS_FAILED, 0, 0);
+ break;
+ }
+
+ if (p_r_apdu)
+ GKI_freebuf (p_r_apdu);
+}
+
+/*******************************************************************************
+**
+** Function rw_t4t_sm_update_ndef
+**
+** Description State machine for NDEF update procedure
+**
+** Returns none
+**
+*******************************************************************************/
+static void rw_t4t_sm_update_ndef (BT_HDR *p_r_apdu)
+{
+ tRW_T4T_CB *p_t4t = &rw_cb.tcb.t4t;
+ UINT8 *p;
+ UINT16 status_words;
+ tRW_DATA rw_data;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ RW_TRACE_DEBUG2 ("rw_t4t_sm_update_ndef (): sub_state:%s (%d)",
+ rw_t4t_get_sub_state_name (p_t4t->sub_state), p_t4t->sub_state);
+#else
+ RW_TRACE_DEBUG1 ("rw_t4t_sm_update_ndef (): sub_state=%d", p_t4t->sub_state);
+#endif
+
+ /* Get status words */
+ p = (UINT8 *) (p_r_apdu + 1) + p_r_apdu->offset;
+ p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
+ BE_STREAM_TO_UINT16 (status_words, p);
+
+ if (status_words != T4T_RSP_CMD_CMPLTED)
+ {
+ rw_t4t_handle_error (NFC_STATUS_CMD_NOT_CMPLTD, *(p-2), *(p-1));
+ return;
+ }
+
+ switch (p_t4t->sub_state)
+ {
+ case RW_T4T_SUBSTATE_WAIT_UPDATE_NLEN:
+
+ /* NLEN has been updated */
+ /* if need to update data */
+ if (p_t4t->p_update_data)
+ {
+ p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_UPDATE_RESP;
+
+ if (!rw_t4t_update_file ())
+ {
+ rw_t4t_handle_error (NFC_STATUS_FAILED, 0, 0);
+ p_t4t->p_update_data = NULL;
+ }
+ }
+ else
+ {
+ p_t4t->state = RW_T4T_STATE_IDLE;
+
+ /* just finished last step of updating (updating NLEN) */
+ if (rw_cb.p_cback)
+ {
+ rw_data.status = NFC_STATUS_OK;
+
+ (*(rw_cb.p_cback)) (RW_T4T_NDEF_UPDATE_CPLT_EVT, &rw_data);
+ RW_TRACE_DEBUG0 ("rw_t4t_sm_update_ndef (): Sent RW_T4T_NDEF_UPDATE_CPLT_EVT");
+ }
+ }
+ break;
+
+ case RW_T4T_SUBSTATE_WAIT_UPDATE_RESP:
+
+ /* if updating is not completed */
+ if (p_t4t->rw_length > 0)
+ {
+ if (!rw_t4t_update_file ())
+ {
+ rw_t4t_handle_error (NFC_STATUS_FAILED, 0, 0);
+ p_t4t->p_update_data = NULL;
+ }
+ }
+ else
+ {
+ p_t4t->p_update_data = NULL;
+
+ /* update NLEN as last step of updating file */
+ if (!rw_t4t_update_nlen (p_t4t->ndef_length))
+ {
+ rw_t4t_handle_error (NFC_STATUS_FAILED, 0, 0);
+ }
+ else
+ {
+ p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_UPDATE_NLEN;
+ }
+ }
+ break;
+
+ default:
+ RW_TRACE_ERROR1 ("rw_t4t_sm_update_ndef (): unknown sub_state = %d", p_t4t->sub_state);
+ rw_t4t_handle_error (NFC_STATUS_FAILED, 0, 0);
+ break;
+ }
+}
+
+/*******************************************************************************
+**
+** Function rw_t4t_sm_set_readonly
+**
+** Description State machine for CC update procedure
+**
+** Returns none
+**
+*******************************************************************************/
+static void rw_t4t_sm_set_readonly (BT_HDR *p_r_apdu)
+{
+ tRW_T4T_CB *p_t4t = &rw_cb.tcb.t4t;
+ UINT8 *p;
+ UINT16 status_words;
+ tRW_DATA rw_data;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ RW_TRACE_DEBUG2 ("rw_t4t_sm_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 *) (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_data_cback
+**
+** Description This callback function receives the data from NFCC.
+**
+** Returns none
+**
+*******************************************************************************/
+static void rw_t4t_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
+{
+ tRW_T4T_CB *p_t4t = &rw_cb.tcb.t4t;
+ BT_HDR *p_r_apdu;
+ tRW_DATA rw_data;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+ UINT8 begin_state = p_t4t->state;
+#endif
+
+ RW_TRACE_DEBUG1 ("rw_t4t_data_cback () event = 0x%X", event);
+ nfc_stop_quick_timer (&p_t4t->timer);
+
+ switch (event)
+ {
+ case NFC_DEACTIVATE_CEVT:
+ NFC_SetStaticRfCback (NULL);
+ p_t4t->state = RW_T4T_STATE_NOT_ACTIVATED;
+ return;
+
+ case NFC_ERROR_CEVT:
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ 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)
+ {
+ rw_t4t_handle_error (rw_data.status, 0, 0);
+ }
+ else
+ {
+ p_t4t->state = RW_T4T_STATE_IDLE;
+ rw_data.status = (tNFC_STATUS) (*(UINT8*) p_data);
+ (*(rw_cb.p_cback)) (RW_T4T_INTF_ERROR_EVT, &rw_data);
+ }
+#else
+ rw_data.status = (tNFC_STATUS) (*(UINT8*) p_data);
+
+ if (p_t4t->state != RW_T4T_STATE_IDLE)
+ {
+ rw_t4t_handle_error (rw_data.status, 0, 0);
+ }
+ else
+ {
+ (*(rw_cb.p_cback)) (RW_T4T_INTF_ERROR_EVT, &rw_data);
+ }
+#endif
+ return;
+
+ case NFC_DATA_CEVT:
+ p_r_apdu = (BT_HDR *) p_data->data.p_data;
+ break;
+
+#if (NFC_NXP_NOT_OPEN_INCLUDED == 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;
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ case RW_T4T_STATE_NDEF_FORMAT:
+ rw_t4t_sm_ndef_format(p_r_apdu);
+ GKI_freebuf (p_r_apdu);
+ break;
+ 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
+}
+
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+/*******************************************************************************
+**
+** 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;
+}
+#endif
+/*******************************************************************************
+**
+** Function rw_t4t_select
+**
+** Description Initialise T4T
+**
+** Returns NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS rw_t4t_select (void)
+{
+ tRW_T4T_CB *p_t4t = &rw_cb.tcb.t4t;
+
+ RW_TRACE_DEBUG0 ("rw_t4t_select ()");
+
+ NFC_SetStaticRfCback (rw_t4t_data_cback);
+
+ p_t4t->state = RW_T4T_STATE_IDLE;
+ p_t4t->version = T4T_MY_VERSION;
+
+ /* set it min of max R-APDU data size before reading CC file */
+ p_t4t->cc_file.max_le = T4T_MIN_MLE;
+
+ /* These will be udated during NDEF detection */
+ p_t4t->max_read_size = T4T_MAX_LENGTH_LE;
+ p_t4t->max_update_size = T4T_MAX_LENGTH_LC;
+
+ return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function RW_T4tDetectNDef
+**
+** Description This function performs NDEF detection procedure
+**
+** RW_T4T_NDEF_DETECT_EVT will be returned
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_FAILED if T4T is busy or other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_T4tDetectNDef (void)
+{
+ RW_TRACE_API0 ("RW_T4tDetectNDef ()");
+
+ if (rw_cb.tcb.t4t.state != RW_T4T_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("RW_T4tDetectNDef ():Unable to start command at state (0x%X)",
+ rw_cb.tcb.t4t.state);
+ return NFC_STATUS_FAILED;
+ }
+
+ if (rw_cb.tcb.t4t.ndef_status & RW_T4T_NDEF_STATUS_NDEF_DETECTED)
+ {
+ /* NDEF Tag application has been selected then select CC file */
+ if (!rw_t4t_select_file (T4T_CC_FILE_ID))
+ {
+ return NFC_STATUS_FAILED;
+ }
+ rw_cb.tcb.t4t.sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_CC;
+ }
+ else
+ {
+ /* Select NDEF Tag Application */
+ if (!rw_t4t_select_application (rw_cb.tcb.t4t.version))
+ {
+ return NFC_STATUS_FAILED;
+ }
+ rw_cb.tcb.t4t.sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_APP;
+ }
+
+ rw_cb.tcb.t4t.state = RW_T4T_STATE_DETECT_NDEF;
+
+ return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function RW_T4tReadNDef
+**
+** Description This function performs NDEF read procedure
+** Note: RW_T4tDetectNDef () must be called before using this
+**
+** The following event will be returned
+** RW_T4T_NDEF_READ_EVT for each segmented NDEF message
+** RW_T4T_NDEF_READ_CPLT_EVT for the last segment or complete NDEF
+** RW_T4T_NDEF_READ_FAIL_EVT for failure
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_FAILED if T4T is busy or other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_T4tReadNDef (void)
+{
+ RW_TRACE_API0 ("RW_T4tReadNDef ()");
+
+ if (rw_cb.tcb.t4t.state != RW_T4T_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("RW_T4tReadNDef ():Unable to start command at state (0x%X)",
+ rw_cb.tcb.t4t.state);
+ return NFC_STATUS_FAILED;
+ }
+
+ /* if NDEF has been detected */
+ if (rw_cb.tcb.t4t.ndef_status & RW_T4T_NDEF_STATUS_NDEF_DETECTED)
+ {
+ /* start reading NDEF */
+ if (!rw_t4t_read_file (T4T_FILE_LENGTH_SIZE, rw_cb.tcb.t4t.ndef_length, FALSE))
+ {
+ return NFC_STATUS_FAILED;
+ }
+
+ rw_cb.tcb.t4t.state = RW_T4T_STATE_READ_NDEF;
+ rw_cb.tcb.t4t.sub_state = RW_T4T_SUBSTATE_WAIT_READ_RESP;
+
+ return NFC_STATUS_OK;
+ }
+ else
+ {
+ RW_TRACE_ERROR0 ("RW_T4tReadNDef ():No NDEF detected");
+ return NFC_STATUS_FAILED;
+ }
+}
+
+/*******************************************************************************
+**
+** Function RW_T4tUpdateNDef
+**
+** Description This function performs NDEF update procedure
+** Note: RW_T4tDetectNDef () must be called before using this
+** Updating data must not be removed until returning event
+**
+** The following event will be returned
+** RW_T4T_NDEF_UPDATE_CPLT_EVT for complete
+** RW_T4T_NDEF_UPDATE_FAIL_EVT for failure
+**
+** Returns NFC_STATUS_OK if success
+** NFC_STATUS_FAILED if T4T is busy or other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_T4tUpdateNDef (UINT16 length, UINT8 *p_data)
+{
+ RW_TRACE_API1 ("RW_T4tUpdateNDef () length:%d", length);
+
+ if (rw_cb.tcb.t4t.state != RW_T4T_STATE_IDLE)
+ {
+ RW_TRACE_ERROR1 ("RW_T4tUpdateNDef ():Unable to start command at state (0x%X)",
+ rw_cb.tcb.t4t.state);
+ return NFC_STATUS_FAILED;
+ }
+
+ /* if NDEF has been detected */
+ if (rw_cb.tcb.t4t.ndef_status & RW_T4T_NDEF_STATUS_NDEF_DETECTED)
+ {
+ /* if read-only */
+ if (rw_cb.tcb.t4t.ndef_status & RW_T4T_NDEF_STATUS_NDEF_READ_ONLY)
+ {
+ RW_TRACE_ERROR0 ("RW_T4tUpdateNDef ():NDEF is read-only");
+ return NFC_STATUS_FAILED;
+ }
+
+ if (rw_cb.tcb.t4t.cc_file.ndef_fc.max_file_size < length + T4T_FILE_LENGTH_SIZE)
+ {
+ RW_TRACE_ERROR2 ("RW_T4tUpdateNDef ():data (%d bytes) plus NLEN is more than max file size (%d)",
+ length, rw_cb.tcb.t4t.cc_file.ndef_fc.max_file_size);
+ return NFC_STATUS_FAILED;
+ }
+
+ /* store NDEF length and data */
+ rw_cb.tcb.t4t.ndef_length = length;
+ rw_cb.tcb.t4t.p_update_data = p_data;
+
+ rw_cb.tcb.t4t.rw_offset = T4T_FILE_LENGTH_SIZE;
+ rw_cb.tcb.t4t.rw_length = length;
+
+ /* set NLEN to 0x0000 for the first step */
+ if (!rw_t4t_update_nlen (0x0000))
+ {
+ return NFC_STATUS_FAILED;
+ }
+
+ rw_cb.tcb.t4t.state = RW_T4T_STATE_UPDATE_NDEF;
+ rw_cb.tcb.t4t.sub_state = RW_T4T_SUBSTATE_WAIT_UPDATE_NLEN;
+
+ return NFC_STATUS_OK;
+ }
+ else
+ {
+ RW_TRACE_ERROR0 ("RW_T4tUpdateNDef ():No NDEF detected");
+ return NFC_STATUS_FAILED;
+ }
+}
+
+/*****************************************************************************
+**
+** Function RW_T4tPresenceCheck
+**
+** Description
+** Check if the tag is still in the field.
+**
+** The RW_T4T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
+** or non-presence.
+** 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 option)
+{
+ tNFC_STATUS retval = NFC_STATUS_OK;
+ tRW_DATA evt_data;
+ BOOLEAN status;
+ BT_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 */
+ if ((p_data = (BT_HDR *) GKI_getbuf (NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE)) != NULL)
+ {
+ p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+ p_data->len = 0;
+ if (NFC_SendData (NFC_RF_CONN_ID, (BT_HDR*) p_data) == 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(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+tNFC_STATUS RW_T3BtGetPupiID(void)
+{
+ BT_HDR *p_c_apdu;
+ UINT8 *p;
+
+ p_c_apdu = (BT_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 *) (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 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 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");
+#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
+ 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");
+ 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
+
+#endif /* (NFC_INCLUDED == TRUE) */
diff --git a/src/nfc/tags/tags_int.c b/src/nfc/tags/tags_int.c
new file mode 100644
index 0000000..f4cfb40
--- /dev/null
+++ b/src/nfc/tags/tags_int.c
@@ -0,0 +1,354 @@
+/******************************************************************************
+ *
+ * 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"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_api.h"
+#include "rw_api.h"
+#include "rw_int.h"
+#include "tags_int.h"
+
+#define T1T_MAX_NUM_OPCODES 9
+#define T1T_STATIC_OPCODES 5
+#define T1T_MAX_TAG_MODELS 2
+
+const tT1T_CMD_RSP_INFO t1t_cmd_rsp_infos[] =
+{
+ /* Note: the order of these commands can not be changed.
+ * If new events are added, add them after T1T_CMD_WRITE_NE8 */
+/* opcode cmd_len, uid_offset, rsp_len */
+ {T1T_CMD_RID, 7, 3, 6},
+ {T1T_CMD_RALL, 7, 3, 122},
+ {T1T_CMD_READ, 7, 3, 2},
+ {T1T_CMD_WRITE_E, 7, 3, 2},
+ {T1T_CMD_WRITE_NE, 7, 3, 2},
+ {T1T_CMD_RSEG, 14, 10, 129},
+ {T1T_CMD_READ8, 14, 10, 9},
+ {T1T_CMD_WRITE_E8, 14, 10, 9},
+ {T1T_CMD_WRITE_NE8, 14, 10, 9}
+};
+
+const tT1T_INIT_TAG t1t_init_content[] =
+{
+/* Tag Name CC3, is dynamic, ltv[0] ltv[1] ltv[2] mtv[0] mtv[1] mtv[2]*/
+ {RW_T1T_IS_TOPAZ96, 0x0E, FALSE, {0, 0, 0}, {0, 0, 0}},
+ {RW_T1T_IS_TOPAZ512,0x3F, TRUE, {0xF2, 0x30, 0x33}, {0xF0, 0x02, 0x03}}
+};
+
+#define T2T_MAX_NUM_OPCODES 3
+#define T2T_MAX_TAG_MODELS 7
+
+const tT2T_CMD_RSP_INFO t2t_cmd_rsp_infos[] =
+{
+ /* Note: the order of these commands can not be changed.
+ * If new events are added, add them after T2T_CMD_SEC_SEL */
+/* opcode cmd_len, rsp_len, nack_rsp_len */
+ {T2T_CMD_READ, 2, 16, 1},
+ {T2T_CMD_WRITE, 6, 1, 1},
+ {T2T_CMD_SEC_SEL, 2, 1, 1}
+};
+
+const tT2T_INIT_TAG t2t_init_content[] =
+{
+/* Tag Name is_multi_v Ver Block Ver No Vbitmask to_calc_cc CC3 OTP BLPB */
+ {TAG_MIFARE_MID, TRUE, T2T_MIFARE_VERSION_BLOCK, T2T_MIFARE_ULTRALIGHT_VER_NO, 0xFFFF, FALSE, 0x06, FALSE, T2T_DEFAULT_LOCK_BLPB},
+ {TAG_MIFARE_MID, TRUE, T2T_MIFARE_VERSION_BLOCK, T2T_MIFARE_ULTRALIGHT_FAMILY_VER_NO, 0xFFFF, TRUE, 0x00, FALSE, T2T_DEFAULT_LOCK_BLPB},
+ {TAG_KOVIO_MID, FALSE, 0x00, 0x00, 0x0000, FALSE, 0x1D, TRUE, 0x04},
+ {TAG_INFINEON_MID, TRUE, T2T_INFINEON_VERSION_BLOCK, T2T_INFINEON_MYD_MOVE_LEAN, 0xFFF0, FALSE, 0x06, FALSE, T2T_DEFAULT_LOCK_BLPB},
+ {TAG_INFINEON_MID, TRUE, T2T_INFINEON_VERSION_BLOCK, T2T_INFINEON_MYD_MOVE, 0xFFF0, FALSE, 0x10, FALSE, T2T_DEFAULT_LOCK_BLPB},
+ {TAG_BRCM_MID, TRUE, T2T_BRCM_VERSION_BLOCK, T2T_BRCM_STATIC_MEM, 0xFFFF, FALSE, 0x06, FALSE, T2T_DEFAULT_LOCK_BLPB},
+ {TAG_BRCM_MID, TRUE, T2T_BRCM_VERSION_BLOCK, T2T_BRCM_DYNAMIC_MEM, 0xFFFF, FALSE, 0x3C, FALSE, T2T_DEFAULT_LOCK_BLPB}
+
+};
+
+const UINT8 t4t_v10_ndef_tag_aid[T4T_V10_NDEF_TAG_AID_LEN] = {0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x00};
+const UINT8 t4t_v20_ndef_tag_aid[T4T_V20_NDEF_TAG_AID_LEN] = {0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01};
+
+#if (BT_TRACE_PROTOCOL == TRUE)
+const char * const t1t_cmd_str[] = {
+ "T1T_RID",
+ "T1T_RALL",
+ "T1T_READ",
+ "T1T_WRITE_E",
+ "T1T_WRITE_NE",
+ "T1T_RSEG",
+ "T1T_READ8",
+ "T1T_WRITE_E8",
+ "T1T_WRITE_NE8"
+};
+
+const char * const t2t_cmd_str[] = {
+ "T2T_CMD_READ",
+ "T2T_CMD_WRITE",
+ "T2T_CMD_SEC_SEL"
+};
+#endif
+
+static unsigned int tags_ones32 (register unsigned int x);
+
+/*******************************************************************************
+**
+** Function t1t_cmd_to_rsp_info
+**
+** Description This function maps the given opcode to tT1T_CMD_RSP_INFO.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+const tT1T_CMD_RSP_INFO * t1t_cmd_to_rsp_info (UINT8 opcode)
+{
+ const tT1T_CMD_RSP_INFO *p_ret = NULL, *p;
+ int xx;
+
+ for (xx = 0, p=&t1t_cmd_rsp_infos[0]; xx<T1T_MAX_NUM_OPCODES; xx++, p++)
+ {
+ if (opcode == p->opcode)
+ {
+ if ((xx < T1T_STATIC_OPCODES) || (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0))
+ p_ret = p;
+ break;
+ }
+ }
+
+ return p_ret;
+}
+
+
+/*******************************************************************************
+**
+** Function t1t_tag_init_data
+**
+** Description This function maps the given opcode to tT1T_INIT_TAG.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+const tT1T_INIT_TAG * t1t_tag_init_data (UINT8 tag_model)
+{
+ const tT1T_INIT_TAG *p_ret = NULL, *p;
+ int xx;
+
+ for (xx = 0, p = &t1t_init_content[0]; xx < T1T_MAX_TAG_MODELS; xx++, p++)
+ {
+ if (tag_model == p->tag_model)
+ {
+ p_ret = p;
+ break;
+ }
+ }
+
+ return p_ret;
+}
+
+/*******************************************************************************
+**
+** Function t2t_tag_init_data
+**
+** Description This function maps the given manufacturer id and version to
+** tT2T_INIT_TAG.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+const tT2T_INIT_TAG * t2t_tag_init_data (UINT8 manufacturer_id, BOOLEAN b_valid_ver, UINT16 version_no)
+{
+ const tT2T_INIT_TAG *p_ret = NULL, *p;
+ int xx;
+
+ for (xx = 0, p = &t2t_init_content[0]; xx < T2T_MAX_TAG_MODELS; xx++, p++)
+ {
+ if (manufacturer_id == p->manufacturer_id)
+ {
+ if ( (!p->b_multi_version)
+ ||(!b_valid_ver)
+ ||(p->version_no == (version_no & p->version_bmask)) )
+ {
+ p_ret = p;
+ break;
+ }
+ }
+ }
+
+ return p_ret;
+}
+
+/*******************************************************************************
+**
+** Function t2t_cmd_to_rsp_info
+**
+** Description This function maps the given opcode to tT2T_CMD_RSP_INFO.
+**
+** Returns tNFC_STATUS
+**
+*******************************************************************************/
+const tT2T_CMD_RSP_INFO * t2t_cmd_to_rsp_info (UINT8 opcode)
+{
+ const tT2T_CMD_RSP_INFO *p_ret = NULL, *p;
+ int xx;
+
+ for (xx = 0, p = &t2t_cmd_rsp_infos[0]; xx < T2T_MAX_NUM_OPCODES; xx++, p++)
+ {
+ if (opcode == p->opcode)
+ {
+ p_ret = p;
+ break;
+ }
+ }
+
+ return p_ret;
+}
+
+/*******************************************************************************
+**
+** Function t1t_info_to_evt
+**
+** Description This function maps the given tT1T_CMD_RSP_INFO to RW/CE event code
+**
+** Returns RW/CE event code
+**
+*******************************************************************************/
+UINT8 t1t_info_to_evt (const tT1T_CMD_RSP_INFO * p_info)
+{
+ return ((UINT8) (p_info - t1t_cmd_rsp_infos) + RW_T1T_FIRST_EVT);
+}
+
+/*******************************************************************************
+**
+** Function t2t_info_to_evt
+**
+** Description This function maps the given tT2T_CMD_RSP_INFO to RW/CE event code
+**
+** Returns RW/CE event code
+**
+*******************************************************************************/
+UINT8 t2t_info_to_evt (const tT2T_CMD_RSP_INFO * p_info)
+{
+ return ((UINT8) (p_info - t2t_cmd_rsp_infos) + RW_T2T_FIRST_EVT);
+}
+
+#if (BT_TRACE_PROTOCOL == TRUE)
+/*******************************************************************************
+**
+** Function t1t_info_to_str
+**
+** Description This function maps the given tT1T_CMD_RSP_INFO to T1T cmd str
+**
+** Returns T1T cmd str
+**
+*******************************************************************************/
+const char * t1t_info_to_str (const tT1T_CMD_RSP_INFO * p_info)
+{
+ int ind = (int) (p_info - t1t_cmd_rsp_infos);
+ if (ind < T1T_MAX_NUM_OPCODES)
+ return (const char *) t1t_cmd_str[ind];
+ else
+ return "";
+}
+
+/*******************************************************************************
+**
+** Function t2t_info_to_str
+**
+** Description This function maps the given tT2T_CMD_RSP_INFO to T2T cmd str
+**
+** Returns T2T cmd str
+**
+*******************************************************************************/
+const char * t2t_info_to_str (const tT2T_CMD_RSP_INFO * p_info)
+{
+ int ind = (int) (p_info - t2t_cmd_rsp_infos);
+ if (ind < T2T_MAX_NUM_OPCODES)
+ return (const char *) t2t_cmd_str[ind];
+ else
+ return "";
+}
+#endif
+
+/*******************************************************************************
+**
+** Function tags_pow
+**
+** Description This function calculates x(base) power of y.
+**
+** Returns int
+**
+*******************************************************************************/
+int tags_pow (int x, int y)
+{
+ int i, ret = 1;
+ for (i = 0; i < y; i++)
+ {
+ ret *= x;
+ }
+ return ret;
+}
+
+/*******************************************************************************
+**
+** Function ones32
+**
+** Description This function returns number of bits set in an unsigned
+** integer variable
+**
+** Returns int
+**
+*******************************************************************************/
+static unsigned int tags_ones32 (register unsigned int x)
+{
+ /* 32-bit recursive reduction using SWAR...
+ but first step is mapping 2-bit values
+ into sum of 2 1-bit values in sneaky way
+ */
+ x -= ((x >> 1) & 0x55555555);
+ x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
+ x = (((x >> 4) + x) & 0x0f0f0f0f);
+ x += (x >> 8);
+ x += (x >> 16);
+ return (x & 0x0000003f);
+}
+
+/*******************************************************************************
+**
+** Function tags_log2
+**
+** Description This function calculates log to the base 2.
+**
+** Returns int
+**
+*******************************************************************************/
+unsigned int tags_log2 (register unsigned int x)
+{
+ x |= (x >> 1);
+ x |= (x >> 2);
+ x |= (x >> 4);
+ x |= (x >> 8);
+ x |= (x >> 16);
+
+ return (tags_ones32 (x) - 1);
+}
+
+#endif /* NFC_INCLUDED == TRUE*/
diff --git a/src/nfca_version.c b/src/nfca_version.c
new file mode 100644
index 0000000..d415d6f
--- /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 nfca_version_string[] = "NFCDROID-AOSP_L_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 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..abdeb07
--- /dev/null
+++ b/src/static-lib-adapt/ProtoDispBluetoothHci.c
@@ -0,0 +1,174 @@
+/******************************************************************************
+ *
+ * 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 *HCIDisp1 (char *p_descr, UINT8 *p_data);
+extern UINT32 ScrProtocolTraceFlag;
+#define HCI_GEN_TRACE (TRACE_CTRL_GENERAL | TRACE_LAYER_HCI | \
+ TRACE_ORG_PROTO_DISP | hci_trace_type)
+static UINT8 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* p_end_hci = NULL;
+static UINT8* HCIDisp1Ext (char *p_descr, UINT8 *p_data, char * p_ext);
+static void disp_sleepmode (UINT8* p);
+static void disp_sleepmode_evt (UINT8* p);
+
+
+///////////////////////////////////////////
+///////////////////////////////////////////
+
+
+UINT8 *HCIDisp1Ext (char *p_descr, UINT8 *p_data, char * p_ext)
+{
+ if (p_data == p_end_hci)
+ return p_data;
+
+ char buff[200];
+
+ sprintf (buff, "%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 * 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* p)
+{
+ UINT8 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 (BT_HDR *p_buf)
+{
+ if (!(ScrProtocolTraceFlag & SCR_PROTO_TRACE_HCI_SUMMARY))
+ return;
+ UINT8 * p = (UINT8 *)(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 (BT_HDR *pBuffer)
+{
+ if (!(ScrProtocolTraceFlag & SCR_PROTO_TRACE_HCI_SUMMARY))
+ return;
+
+ UINT8 *p = (UINT8 *)(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/uamp_api.h b/src/udrv/include/uamp_api.h
new file mode 100644
index 0000000..9eb733c
--- /dev/null
+++ b/src/udrv/include/uamp_api.h
@@ -0,0 +1,168 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * This file contains serial definitions from WIDCOMM's Universal Embedded
+ * Drivers API.
+ *
+ ******************************************************************************/
+#ifndef UAMP_API_H
+#define UAMP_API_H
+
+/*****************************************************************************
+** Constant and Type Definitions
+*****************************************************************************/
+
+/* UAMP identifiers */
+#define UAMP_ID_1 1
+#define UAMP_ID_2 2
+typedef UINT8 tUAMP_ID;
+
+/* UAMP event ids (used by UAMP_CBACK) */
+#define UAMP_EVT_RX_READY 0 /* Data from AMP controller is ready to be read */
+#define UAMP_EVT_CTLR_REMOVED 1 /* Controller removed */
+#define UAMP_EVT_CTLR_READY 2 /* Controller added/ready */
+typedef UINT8 tUAMP_EVT;
+
+
+/* UAMP Channels */
+#define UAMP_CH_HCI_CMD 0 /* HCI Command channel */
+#define UAMP_CH_HCI_EVT 1 /* HCI Event channel */
+#define UAMP_CH_HCI_DATA 2 /* HCI ACL Data channel */
+typedef UINT8 tUAMP_CH;
+
+/* tUAMP_EVT_DATA: union for event-specific data, used by UAMP_CBACK */
+typedef union {
+ tUAMP_CH channel; /* UAMP_EVT_RX_READY: channel for which rx occured */
+} tUAMP_EVT_DATA;
+
+
+
+
+/*****************************************************************************
+**
+** Function: UAMP_CBACK
+**
+** Description: Callback for events. Register callback using UAMP_Init.
+**
+** Parameters amp_id: AMP device identifier that generated the event
+** amp_evt: event id
+** p_amp_evt_data: pointer to event-specific data
+**
+*****************************************************************************/
+typedef void (tUAMP_CBACK)(tUAMP_ID amp_id, tUAMP_EVT amp_evt, tUAMP_EVT_DATA *p_amp_evt_data);
+
+/*****************************************************************************
+** external function declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*****************************************************************************
+**
+** Function: UAMP_Init
+**
+** Description: Initialize UAMP driver
+**
+** Parameters p_cback: Callback function for UAMP event notification
+**
+*****************************************************************************/
+BT_API BOOLEAN UAMP_Init(tUAMP_CBACK *p_cback);
+
+
+/*****************************************************************************
+**
+** Function: UAMP_Open
+**
+** Description: Open connection to local AMP device.
+**
+** Parameters app_id: Application specific AMP identifer. This value
+** will be included in AMP messages sent to the
+** BTU task, to identify source of the message
+**
+*****************************************************************************/
+BT_API BOOLEAN UAMP_Open(tUAMP_ID amp_id);
+
+/*****************************************************************************
+**
+** Function: UAMP_Close
+**
+** Description: Close connection to local AMP device.
+**
+** Parameters app_id: Application specific AMP identifer.
+**
+*****************************************************************************/
+BT_API void UAMP_Close(tUAMP_ID amp_id);
+
+
+/*****************************************************************************
+**
+** Function: UAMP_Write
+**
+** Description: Send buffer to AMP device.
+**
+**
+** Parameters: app_id: AMP identifer.
+** p_buf: pointer to buffer to write
+** num_bytes: number of bytes to write
+** channel: UAMP_CH_HCI_ACL, or UAMP_CH_HCI_CMD
+**
+** Returns: number of bytes written
+**
+*****************************************************************************/
+BT_API UINT16 UAMP_Write(tUAMP_ID amp_id, UINT8 *p_buf, UINT16 num_bytes, tUAMP_CH channel);
+
+
+/*****************************************************************************
+**
+** Function: UAMP_WriteBuf
+**
+** Description: Send GKI buffer to AMP device. Frees GKI buffer when done.
+**
+** Parameters app_amp_id: AMP identifer (BTM_AMP_1, BTM_AMP_2, ...)
+** p_msg: message to send.
+**
+*****************************************************************************/
+BT_API UINT16 UAMP_WriteBuf(tUAMP_ID amp_id, BT_HDR *p_msg);
+
+
+/*****************************************************************************
+**
+** Function: UAMP_Read
+**
+** Description: Read incoming data from AMP. Call after receiving a
+** UAMP_EVT_RX_READY callback event.
+**
+** Parameters: app_id: AMP identifer.
+** p_buf: pointer to buffer for holding incoming AMP data
+** buf_size: size of p_buf
+** channel: UAMP_CH_HCI_ACL, or UAMP_CH_HCI_EVT
+**
+** Returns: number of bytes read
+**
+*****************************************************************************/
+BT_API UINT16 UAMP_Read(tUAMP_ID amp_id, UINT8 *p_buf, UINT16 buf_size, tUAMP_CH channel);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* UAMP_API_H */
diff --git a/src/udrv/include/ucodec.h b/src/udrv/include/ucodec.h
new file mode 100644
index 0000000..6178fdc
--- /dev/null
+++ b/src/udrv/include/ucodec.h
@@ -0,0 +1,385 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2001-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * This file contains codec definitions from Widcomm's Universal Embedded
+ * Drivers API.
+ *
+ ******************************************************************************/
+
+#ifndef UCODEC_H
+#define UCODEC_H
+
+#include "bt_target.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*******************************************************************************
+** Codec APIs
+*******************************************************************************/
+
+/**** Codec IDs ****/
+#define UCODEC_ID_1 0
+#define UCODEC_ID_2 1
+#define UCODEC_ID_3 2
+#define UCODEC_ID_4 3
+#define UCODEC_NUMBER 4
+
+typedef UINT8 tUCODEC_ID;
+
+/**** Status ****/
+#define UCODEC_SUCCESS 0x00
+#define UCODEC_TX_DONE 0x01
+#define UCODEC_RX_READY 0x02
+#define UCODEC_FLOW_CTRL_ON 0x03
+#define UCODEC_FLOW_CTRL_OFF 0x04
+#define UCODEC_OVERFLOW 0x05
+#define UCODEC_UNSUPORTED_CNF 0x06
+#define UCODEC_WRONG_PARAM 0x07
+#define UCODEC_NOT_CONFIGURED 0x08
+#define UCODEC_OUT_OF_MEMORY 0x09
+#define UCODEC_GENERIC_ERROR 0x0a
+#define UCODEC_RECOVERABLE_ERROR 0x0b
+#define UCODEC_UNRECOVERABLE_ERROR 0x0c
+#define UCODEC_LOW_LEVEL_DRIVER_ERROR (0x0d)
+
+typedef UINT8 tUCODEC_STATUS;
+
+/**** Media type ****/
+#define UCODEC_MEDIA_TYPE_AUDIO 0
+#define UCODEC_MEDIA_TYPE_VIDEO 1
+#define UCODEC_MEDIA_TYPE_MULTI 2
+
+typedef UINT8 tUCODEC_MEDIA_TYPE;
+
+/**** Audio Codec type ****/
+#define UCODEC_AUDIO_SBC 0
+#define UCODEC_AUDIO_M12_LAYER1 1 /* layer1 (mp1) */
+#define UCODEC_AUDIO_M12_LAYER2 2 /* layer2 (mp2) */
+#define UCODEC_AUDIO_M12_LAYER3 3 /* layer3 (mp3) */
+#define UCODEC_AUDIO_M24_2LC 4 /* MPEG-2 AAC LC */
+#define UCODEC_AUDIO_M24_4LC 5 /* MPEG-4 AAC LC */
+#define UCODEC_AUDIO_M24_4LTP 6 /* MPEG-4 AAC LTP */
+#define UCODEC_AUDIO_M24_4S 7 /* MPEG-4 AAC scalable */
+#define UCODEC_AUDIO_VOLUME 8 /* Volume settings */
+#define UCODEC_AUDIO_BALANCE 9 /* Balance settings */
+
+typedef UINT8 tUCODEC_AUDIO_FEAT_TYPE;
+
+/**** Video Codec type -> TODO ****/
+/*TBD*/
+
+typedef UINT8 tUCODEC_VIDEO_FEAT_TYPE;
+
+/**** SBC sample frequency ****/
+#define UCODEC_SBC_SMP_FREQ_16 0 /* 16 */
+#define UCODEC_SBC_SMP_FREQ_32 1 /* 23 */
+#define UCODEC_SBC_SMP_FREQ_44 2 /* 44.1 */
+#define UCODEC_SBC_SMP_FREQ_48 3 /* 48 */
+
+typedef UINT8 tUCODEC_SBC_SMP_FREQ;
+
+/**** SBC sample frequency ****/
+#define UCODEC_SBC_SUBBAND_4 4
+#define UCODEC_SBC_SUBBAND_8 8
+
+typedef UINT8 tUCODEC_SBC_SUBBAND;
+/**** Allocation method ****/
+#define UCODEC_SBC_ALLOC_MD_S 0 /* SNR */
+#define UCODEC_SBC_ALLOC_MD_L 1 /* loundess */
+
+typedef UINT8 tUCODEC_SBC_ALLOC_MD;
+
+/**** MPEG sample frequency ****/
+#define UCODEC_M12_SMP_FREQ_16 0 /* 16 */
+#define UCODEC_M12_SMP_FREQ_22 1 /* 22 */
+#define UCODEC_M12_SMP_FREQ_24 2 /* 24 */
+#define UCODEC_M12_SMP_FREQ_32 3 /* 32 */
+#define UCODEC_M12_SMP_FREQ_44 4 /* 44 */
+#define UCODEC_M12_SMP_FREQ_48 5 /* 48 */
+
+typedef UINT8 tUCODEC_M12_SMP_FREQ;
+
+/**** Channel mode ****/
+#define UCODEC_CHN_MONO 0
+#define UCODEC_CHN_DUAL 1
+#define UCODEC_CHN_STEREO 2
+#define UCODEC_CHN_JOINT_STEREO 3
+
+typedef UINT8 tUCODEC_CH_MODE;
+/**** Audio Codec type ****/
+#define UCODEC_M24_SMP_FREQ_8 0 /* 8 */
+#define UCODEC_M24_SMP_FREQ_11 1 /* 11 */
+#define UCODEC_M24_SMP_FREQ_12 2 /* 12 */
+#define UCODEC_M24_SMP_FREQ_16 3 /* 16 */
+#define UCODEC_M24_SMP_FREQ_22 4 /* 22.05 */
+#define UCODEC_M24_SMP_FREQ_24 5 /* 24 */
+#define UCODEC_M24_SMP_FREQ_32 6 /* 32 */
+#define UCODEC_M24_SMP_FREQ_44 7 /* 44.1 */
+#define UCODEC_M24_SMP_FREQ_48 8 /* 48 */
+#define UCODEC_M24_SMP_FREQ_64 9 /* 64 */
+#define UCODEC_M24_SMP_FREQ_88 10 /* 88 */
+#define UCODEC_M24_SMP_FREQ_96 11 /* 96 */
+
+typedef UINT8 tUCODEC_M24_SMP_FREQ;
+
+/**** Codec configuration structure ****/
+typedef struct tUCODEC_CNF_SBC_TAG
+{
+ tUCODEC_SBC_SMP_FREQ SampleFreq;
+ tUCODEC_CH_MODE ChannelMode;
+ UINT16 Offset; /* GKI buffer based offset for UCODEC_ReadBuf */
+ UINT16 MtuSize; /* Max buffer len for UCODEC_ReadBuf*/
+ UINT8 PoolId; /* GKI pool ID for UCODEC_ReadBuf */
+ UINT8 NumBlock; /* Number of block in block unit : 4 blocks 8 blocks 12 blocks 16 blocks are the possible value */
+ UINT8 Subband;
+ tUCODEC_SBC_ALLOC_MD AllocMthd;
+ UINT8 MinBitPool;
+ UINT8 MaxBitPool;
+} tUCODEC_CNF_SBC;
+
+typedef struct tUCODEC_CNF_M12_TAG
+{
+ tUCODEC_CH_MODE ChannelMode; /* Mono, Dual, stereo, joint stereo */
+ tUCODEC_M12_SMP_FREQ SampleFreq; /* Sample freq: 16, 22, 24, 32, 44, 48 */
+ UINT16 BitRate; /* Bit rate in bit per sec */
+ UINT16 Offset; /* GKI buffer based offset for UCODEC_ReadBuf */
+ UINT16 MtuSize; /* Max buffer len for UCODEC_ReadBuf*/
+ UINT8 PoolId; /* GKI pool ID for UCODEC_ReadBuf */
+ BOOLEAN VBR; /* Variable Bit Rate */
+ BOOLEAN CRC_On; /* CRC error detection */
+ BOOLEAN MPF; /* Media payload format */
+} tUCODEC_CNF_M12;
+
+typedef struct tUCODEC_CNF_M24_TAG
+{
+ tUCODEC_M24_SMP_FREQ SampleFreq; /* Sample freq: 8, 11, 12, 16, 22.05, 24, 32, 44.1, 48, 64, 88, 96 */
+ UINT32 BitRate; /* Bit rate */
+ UINT16 Offset; /* GKI buffer based offset for UCODEC_ReadBuf */
+ UINT16 MtuSize; /* Max buffer len for UCODEC_ReadBuf*/
+ UINT8 PoolId; /* GKI pool ID for UCODEC_ReadBuf */
+ UINT8 Chanels; /* 1 or 2 chanels */
+} tUCODEC_CNF_M24;
+
+
+typedef union tUCODEC_CODEC_TYPE_TAG
+{
+ tUCODEC_AUDIO_FEAT_TYPE AudioType;
+ tUCODEC_VIDEO_FEAT_TYPE VideoType;
+} tUCODEC_CODEC_TYPE;
+
+typedef union tUCODEC_FEATURE_TAG
+{
+ /* Add here the audio feature structure */
+ tUCODEC_CNF_SBC SBCConfig;
+ tUCODEC_CNF_M12 M12Config;
+ tUCODEC_CNF_M24 M24Config;
+ UINT8 Volume; /* 0 to mute. 0xFF for the max volume */
+ UINT8 Balance; /* 0->100% right, 255->100% left */
+ /* Add here the video feature structure */
+ /* TBD */
+} tUCODEC_FEATURE;
+
+typedef struct tUCODEC_CNF_TAG
+{
+ tUCODEC_MEDIA_TYPE MediaType;
+ tUCODEC_CODEC_TYPE Type;
+ tUCODEC_FEATURE Feature;
+} tUCODEC_CNF;
+
+typedef struct tUCODEC_BUF_INFO_TAG
+{
+ UINT8 NumOfFrames;
+ UINT32 TimesStamp;
+} tUCODEC_BUF_INFO;
+
+
+/******************************************************************************
+**
+** Function tUCODEC_CBACK_PTR
+**
+** Description This call back report CODEC indication.
+** It report codec error as well as flow onfrol indication.
+**
+** Input : CodecId: Id of the codec that calls this call back.
+** Status: ->UCODEC_FLOW_CTRL_OFF if the Tx Q just
+** went below the low watermark
+** ->UCODEC_RX_READY if data are ready to be
+** read. This olny hapens when the Rx Q was
+** empty before receiving data.
+** ->UCODEC_INTERNAL_ERROR if something went
+** wrong with the driver
+**
+** Output Parameters : None
+**
+** Returns None.
+**
+******************************************************************************/
+typedef void (* tUCODEC_CBACK_PTR)(tUCODEC_ID, tUCODEC_STATUS);
+
+/*******************************************************************************
+** Function Prototypes
+*******************************************************************************/
+
+/******************************************************************************
+**
+** Function UCODEC_Init
+**
+** Description Startup initialisation function. This function is called
+** before any orther function of UCODEC it initialize UCODEC
+** internal structure an the external codec.
+**
+** Input : CodecId: Id of the codec to perform the operation on.
+**
+** Output Parameters : None
+**
+** Returns UCODEC_SUCCESS if The action was performed with sucess.
+** Error code else.
+**
+******************************************************************************/
+BT_API extern tUCODEC_STATUS UCODEC_Init (void *);
+
+/******************************************************************************
+**
+** Function UCODEC_Configure
+**
+** Description Initialise the CODEC for a particular stream.
+**
+**
+** Input : CodecId: Id of the codec to perform the operation on.
+** CbackPrt: Call back pointer for codec feedback.
+** pConfig: Pointer on a codec configuration structure.
+**
+** Output Parameters : None
+**
+** Returns UCODEC_SUCCESS if The action was performed with sucess.
+**
+******************************************************************************/
+BT_API extern tUCODEC_STATUS UCODEC_Configure (tUCODEC_ID, tUCODEC_CBACK_PTR, tUCODEC_CNF *);
+
+/******************************************************************************
+**
+** Function UCODEC_FlushTx
+**
+** Description Fluch Tx buffer Q.
+**
+** Input : CodecId: Id of the codec to perform the operation on.
+**
+** Output Parameters : None
+**
+** Returns UCODEC_SUCCESS if The action was performed with sucess.
+** Error code else.
+**
+******************************************************************************/
+BT_API extern tUCODEC_STATUS UCODEC_FlushTx (tUCODEC_ID);
+
+/******************************************************************************
+**
+** Function UCODEC_FlushRx
+**
+** Description Fluch Rx buffer Q.
+**
+** Input : CodecId: Id of the codec to perform the operation on.
+**
+** Output Parameters : None
+**
+** Returns UCODEC_SUCCESS if The action was performed with sucess.
+** Error code else.
+**
+******************************************************************************/
+BT_API extern tUCODEC_STATUS UCODEC_FlushRx (tUCODEC_ID);
+
+/******************************************************************************
+**
+** Function UCODEC_WriteBuf
+**
+** Description Send a buffer to the codec.
+**
+** Input : CodecId: Id of the codec to perform the operation on.
+** pBuf: Pointer onto the GKI buffer to be send to the CODEC.
+**
+** Output Parameters : None
+**
+** Returns UCODEC_SUCCESS if The action was performed with sucess.
+** UCODEC_FLOW_CTRL_ON if The codec buffer Q had reach a UCODEC_HIGH_WM
+** watermark. The buffer is queued
+** UCODEC_OVERFLOW if The codec buffer Q had reach a critical
+** watermark. The buffer is dropped.
+**
+******************************************************************************/
+BT_API extern tUCODEC_STATUS UCODEC_WriteBuf (tUCODEC_ID, BT_HDR *);
+
+/******************************************************************************
+**
+** Function UCODEC_ReadBuf
+**
+** Description Get a buffer from the codec.
+**
+** Input : CodecId: Id of the codec to perform the operation on.
+**
+** Output Parameters : None
+**
+** Returns Pointer on the GKI buffer. NULL if the Rx Q is empty
+**
+******************************************************************************/
+BT_API extern tUCODEC_STATUS UCODEC_ReadBuf (tUCODEC_ID, BT_HDR **, tUCODEC_BUF_INFO *);
+
+/******************************************************************************
+**
+** Function UCODEC_Close
+**
+** Description This function is called to put the codec in low power mode
+**
+**
+** Input : CodecId: Id of the codec to perform the operation on.
+**
+** Output Parameters : None
+**
+** Returns UCODEC_SUCCESS : The action was performed with sucess.
+** Error code else.
+**
+******************************************************************************/
+BT_API extern tUCODEC_STATUS UCODEC_Close (tUCODEC_ID);
+
+/******************************************************************************
+**
+** Function UCODEC_Open
+**
+** Description This function is called to resume the codec from low power
+** mode after UCODEC_Close had been called. It will put the
+** codec in the state it was before UCODEC_Close being called.
+**
+** Input : CodecId: Id of the codec to perform the operation on.
+**
+** Output Parameters : None
+**
+** Returns UCODEC_SUCCESS : The action was performed with sucess.
+** Error code else.
+**
+******************************************************************************/
+BT_API extern tUCODEC_STATUS UCODEC_Open (tUCODEC_ID);
+
+#ifdef __cplusplus
+};
+#endif
+
+
+#endif /* UCODEC_H */
diff --git a/src/udrv/include/udac.h b/src/udrv/include/udac.h
new file mode 100644
index 0000000..a2d7ab1
--- /dev/null
+++ b/src/udrv/include/udac.h
@@ -0,0 +1,93 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2001-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Definitions for UDAC driver
+ *
+ ******************************************************************************/
+#ifndef UDAC_H
+#define UDAC_H
+
+
+#define UDAC_GAIN_MAX 0x00FFF
+typedef UINT16 tUDAC_GAIN;
+
+/* API functions for DAC driver */
+
+
+/*****************************************************************************
+**
+** Function DAC_Init
+**
+** Description
+** Initialize the DAC subsystem
+**
+** Input parameters
+** Nothing
+**
+** Output parameters
+** Nothing
+**
+** Returns
+** Nothing
+**
+*****************************************************************************/
+void UDAC_Init(void *p_cfg);
+
+
+/*****************************************************************************
+**
+** Function DAC_Read
+**
+** Description
+** Read current DAC gain
+**
+** Input parameters
+** Nothing
+**
+** Output parameters
+** Nothing
+**
+** Returns
+** Current gain setting
+**
+*****************************************************************************/
+tUDAC_GAIN UDAC_Read(void);
+
+
+/*****************************************************************************
+**
+** Function DAC_Set
+**
+** Description
+** Set the DAC gain
+**
+** Input parameters
+** gain Gain setting
+**
+** Output parameters
+** Nothing
+**
+** Returns
+** Nothing
+**
+*****************************************************************************/
+void UDAC_Set(tUDAC_GAIN gain);
+
+#endif /* #ifndef UDAC_H */
diff --git a/src/udrv/include/uipc.h b/src/udrv/include/uipc.h
new file mode 100644
index 0000000..7a29645
--- /dev/null
+++ b/src/udrv/include/uipc.h
@@ -0,0 +1,156 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2007-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * UIPC wrapper interface
+ *
+ ******************************************************************************/
+#ifndef UIPC_H
+#define UIPC_H
+
+#ifndef UDRV_API
+#define UDRV_API
+#endif
+
+
+#define UIPC_CH_ID_ALL 0 /* used to address all the ch id at once */
+#define UIPC_CH_ID_0 1 /* shared mem interface */
+#define UIPC_CH_ID_1 2 /* TCP socket (GPS) */
+#define UIPC_CH_ID_2 3 /* BTIF control socket */
+#define UIPC_CH_ID_3 4 /* BTIF HH */
+#define UIPC_CH_ID_4 5 /* Future usage */
+#define UIPC_CH_ID_5 6 /* Future usage */
+#define UIPC_CH_ID_6 7 /* Future usage */
+#define UIPC_CH_ID_7 8 /* Future usage */
+#define UIPC_CH_ID_8 9 /* Future usage */
+#define UIPC_CH_ID_9 10 /* Future usage */
+#define UIPC_CH_ID_10 11 /* Future usage */
+#define UIPC_CH_ID_11 12 /* Future usage */
+#define UIPC_CH_ID_12 13 /* Future usage */
+#define UIPC_CH_ID_13 14 /* Future usage */
+#define UIPC_CH_ID_14 15 /* Future usage */
+#define UIPC_CH_ID_15 16 /* Future usage */
+#define UIPC_CH_ID_16 17 /* Future usage */
+#define UIPC_CH_ID_17 18 /* Future usage */
+#define UIPC_CH_ID_18 19 /* Future usage */
+#define UIPC_CH_ID_19 20 /* Future usage */
+#define UIPC_CH_ID_20 21 /* Future usage */
+#define UIPC_CH_ID_21 22 /* Future usage */
+#define UIPC_CH_ID_22 23 /* Future usage */
+#define UIPC_CH_ID_23 24 /* Future usage */
+#define UIPC_CH_ID_24 25 /* Future usage */
+
+
+
+#define UIPC_CH_NUM 25
+
+typedef UINT8 tUIPC_CH_ID;
+
+
+typedef void (tUIPC_RCV_CBACK)(BT_HDR *p_msg); /* points to BT_HDR which describes event type and length of data; len contains the number of bytes of entire message (sizeof(BT_HDR) + offset + size of data) */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*******************************************************************************
+**
+** Function UIPC_Init
+**
+** Description Initialize UIPC module
+**
+** Returns void
+**
+*******************************************************************************/
+UDRV_API extern void UIPC_Init(void *);
+
+/*******************************************************************************
+**
+** Function UIPC_Open
+**
+** Description Open UIPC interface
+**
+** Returns void
+**
+*******************************************************************************/
+UDRV_API extern BOOLEAN UIPC_Open(tUIPC_CH_ID ch_id, tUIPC_RCV_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function UIPC_Close
+**
+** Description Close UIPC interface
+**
+** Returns void
+**
+*******************************************************************************/
+UDRV_API extern void UIPC_Close(tUIPC_CH_ID ch_id);
+
+/*******************************************************************************
+**
+** Function UIPC_SendBuf
+**
+** Description Called to transmit a message over UIPC.
+** Message buffer will be freed by UIPC_SendBuf.
+**
+** Returns void
+**
+*******************************************************************************/
+UDRV_API extern BOOLEAN UIPC_SendBuf(tUIPC_CH_ID ch_id, BT_HDR *p_msg);
+
+/*******************************************************************************
+**
+** Function UIPC_Send
+**
+** Description Called to transmit a message over UIPC.
+**
+** Returns void
+**
+*******************************************************************************/
+UDRV_API extern BOOLEAN UIPC_Send(tUIPC_CH_ID ch_id, UINT16 msg_evt, UINT8 *p_buf, UINT16 msglen);
+
+/*******************************************************************************
+**
+** Function UIPC_Read
+**
+** Description Called to read a message from UIPC.
+**
+** Returns void
+**
+*******************************************************************************/
+UDRV_API extern UINT32 UIPC_Read(tUIPC_CH_ID ch_id, UINT16 *p_msg_evt, UINT8 *p_buf, UINT32 len);
+
+/*******************************************************************************
+**
+** Function UIPC_Ioctl
+**
+** Description Called to control UIPC.
+**
+** Returns void
+**
+*******************************************************************************/
+UDRV_API extern BOOLEAN UIPC_Ioctl(tUIPC_CH_ID ch_id, UINT32 request, void *param);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* UIPC_H */
diff --git a/src/udrv/include/unv.h b/src/udrv/include/unv.h
new file mode 100644
index 0000000..7964021
--- /dev/null
+++ b/src/udrv/include/unv.h
@@ -0,0 +1,84 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2002-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * This file contains NV definitions from WIDCOMM's Universal Embedded
+ * Drivers API.
+ *
+ ******************************************************************************/
+
+#ifndef UNV_H
+#define UNV_H
+
+#include "data_types.h"
+
+/*******************************************************************************
+** NV APIs
+*******************************************************************************/
+
+/**** Storage preferences ****/
+#define UNV_BLOCK 1
+#define UNV_BYTE 2
+#define UNV_NOPREF 3
+
+typedef UINT8 tUNV_STORAGE_PREF;
+
+/**** Status ****/
+#define UNV_REINIT (-1)
+#define UNV_WRITELOCKED (-2)
+#define UNV_ERROR (-3)
+
+typedef INT16 tUNV_STATUS;
+
+/* Prototype for function to restore defaults to a block */
+typedef void (tUNV_DEFAULT_FUNC)(void);
+
+/*******************************************************************************
+** Function Prototypes
+*******************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef UDRV_API
+#define UDRV_API
+#endif
+
+UDRV_API extern void UNV_Init(void *);
+UDRV_API extern BOOLEAN UNV_MapBlock(UINT16, tUNV_STORAGE_PREF, UINT16,
+ UINT16, UINT16 *, void *);
+UDRV_API extern BOOLEAN UNV_ReadMap(UINT16, tUNV_STORAGE_PREF *, UINT16 *,
+ UINT16 *, UINT16 *);
+UDRV_API extern BOOLEAN UNV_EraseBlock(UINT16);
+UDRV_API extern void UNV_Default(UINT16);
+UDRV_API extern tUNV_STATUS UNV_Read(UINT16, UINT16, UINT16, UINT16, void *);
+UDRV_API extern tUNV_STATUS UNV_Write(UINT16, UINT16, UINT16, UINT16, void *);
+UDRV_API extern tUNV_STATUS UNV_ReadBlock(UINT16, UINT16, void *);
+UDRV_API extern tUNV_STATUS UNV_WriteBlock(UINT16, void *);
+UDRV_API extern UINT32 UNV_BytesRemaining(void);
+UDRV_API extern void UNV_Consolidate(void);
+UDRV_API extern tUNV_STATUS UNV_ReadPtr(UINT16, UINT16, UINT8 **);
+UDRV_API extern tUNV_STATUS UNV_FreePtr(UINT16, UINT16);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* UNV_H */
diff --git a/src/udrv/include/upio.h b/src/udrv/include/upio.h
new file mode 100644
index 0000000..aa826ef
--- /dev/null
+++ b/src/udrv/include/upio.h
@@ -0,0 +1,372 @@
+/******************************************************************************
+ *
+ * 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 tUPIO_FEATURE;
+
+
+/* Enumeration of UPIO configurations */
+enum
+{
+ UPIO_OUT,
+ UPIO_IN,
+ UPIO_IN_EDGE,
+ UPIO_IN_LEVEL,
+ UPIO_NONE
+};
+typedef UINT8 tUPIO_CONFIG;
+
+
+/* Enumeration of UPIO types */
+enum
+{
+ UPIO_LED, /* LED */
+ UPIO_SWITCH, /* Switch */
+ UPIO_JUMPER, /* Jumper */
+ UPIO_BUTTON, /* Push-button switch */
+ UPIO_GENERAL, /* General purpose I/O */
+
+ UPIO_NUMBER_OF_TYPES
+};
+typedef UINT8 tUPIO_TYPE;
+
+
+/* Enumeration of UPIO states */
+enum
+{
+ UPIO_OFF,
+ UPIO_ON,
+ UPIO_TOGGLE
+};
+typedef UINT8 tUPIO_STATE;
+
+
+enum
+{
+ UPIO_SW_BANK2,
+ UPIO_SW_BANK3
+};
+typedef UINT8 tUPIO_SW_BANK;
+
+/* Jumper masks */
+#define UPIO_JUMPER1 0x00000001
+#define UPIO_JUMPER2 0x00000002
+#define UPIO_JUMPER3 0x00000004
+#define UPIO_JUMPER4 0x00000008
+#define UPIO_JUMPER5 0x00000010
+#define UPIO_JUMPER6 0x00000020
+#define UPIO_JUMPER7 0x00000040
+#define UPIO_JUMPER8 0x00000080
+
+/* General purpose i/o masks */
+#define UPIO_GENERAL1 0x00000001
+#define UPIO_GENERAL2 0x00000002
+#define UPIO_GENERAL3 0x00000004
+#define UPIO_GENERAL4 0x00000008
+#define UPIO_GENERAL5 0x00000010
+#define UPIO_GENERAL6 0x00000020
+#define UPIO_GENERAL7 0x00000040
+#define UPIO_GENERAL8 0x00000080
+#define UPIO_GENERAL9 0x00000100
+#define UPIO_GENERAL10 0x00000200
+#define UPIO_GENERAL11 0x00000400
+#define UPIO_GENERAL12 0x00000800
+#define UPIO_GENERAL13 0x00001000
+#define UPIO_GENERAL14 0x00002000
+#define UPIO_GENERAL15 0x00004000
+#define UPIO_GENERAL16 0x00008000
+#define UPIO_GENERAL17 0x00010000
+#define UPIO_GENERAL18 0x00020000
+#define UPIO_GENERAL19 0x00040000
+#define UPIO_GENERAL20 0x00080000
+#define UPIO_GENERAL21 0x00100000
+#define UPIO_GENERAL22 0x00200000
+#define UPIO_GENERAL23 0x00400000
+#define UPIO_GENERAL24 0x00800000
+#define UPIO_GENERAL25 0x01000000
+#define UPIO_GENERAL26 0x02000000
+#define UPIO_GENERAL27 0x04000000
+#define UPIO_GENERAL28 0x08000000
+#define UPIO_GENERAL29 0x10000000
+#define UPIO_GENERAL30 0x20000000
+#define UPIO_GENERAL31 0x40000000
+#define UPIO_GENERAL32 0x80000000
+
+typedef UINT32 tUPIO;
+
+/* LED masks */
+#define UPIO_LED1 0x00000001
+#define UPIO_LED2 0x00000002
+#define UPIO_LED3 0x00000004
+#define UPIO_LED4 0x00000008
+#define UPIO_LED5 0x00000010
+#define UPIO_LED6 0x00000020
+#define UPIO_LED7 0x00000040
+#define UPIO_LED8 0x00000080
+
+#define UPIO_LED_ALL (UPIO_LED1 | UPIO_LED2 | UPIO_LED3 | UPIO_LED4 | \
+ UPIO_LED5 | UPIO_LED6 | UPIO_LED7 | UPIO_LED8)
+
+
+/* Switch masks */
+#define UPIO_SWITCH1 0x00000001
+#define UPIO_SWITCH2 0x00000002
+#define UPIO_SWITCH3 0x00000004
+#define UPIO_SWITCH4 0x00000008
+#define UPIO_SWITCH5 0x00000010
+#define UPIO_SWITCH6 0x00000020
+#define UPIO_SWITCH7 0x00000040
+#define UPIO_SWITCH8 0x00000080
+#define UPIO_SWITCH9 0x00000100
+#define UPIO_SWITCH10 0x00000200
+#define UPIO_SWITCH11 0x00000400
+#define UPIO_SWITCH12 0x00000800
+#define UPIO_SWITCH13 0x00001000
+#define UPIO_SWITCH14 0x00002000
+#define UPIO_SWITCH15 0x00004000
+#define UPIO_SWITCH16 0x00008000
+
+/* Push button masks */
+#define UPIO_BUTTON1 0x00000001
+#define UPIO_BUTTON2 0x00000002
+#define UPIO_BUTTON3 0x00000004
+#define UPIO_BUTTON4 0x00000008
+#define UPIO_BUTTON5 0x00000010
+#define UPIO_BUTTON6 0x00000020
+#define UPIO_BUTTON7 0x00000040
+#define UPIO_BUTTON8 0x00000080
+
+typedef void (tUPIO_CBACK)(tUPIO_TYPE type, tUPIO pio, tUPIO_STATE state);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* API functions for UPIO driver */
+
+/*****************************************************************************
+**
+** Function UPIO_Init
+**
+** Description
+** Initialize the GPIO service.
+** This function is typically called once upon system startup.
+**
+** Returns nothing
+**
+*****************************************************************************/
+UDRV_API void UPIO_Init(void *p_cfg);
+
+
+/*****************************************************************************
+**
+** Function UPIO_Set
+**
+** Description
+** This function sets one or more GPIO devices to the given state.
+** Multiple GPIOs of the same type can be masked together to set more
+** than one GPIO. This function can only be used on types UPIO_LED and
+** UPIO_GENERAL.
+**
+** Input Parameters:
+** type The type of device.
+** pio Indicates the particular GPIOs.
+** state The desired state.
+**
+** Output Parameter:
+** None.
+**
+** Returns:
+** None.
+**
+*****************************************************************************/
+UDRV_API void UPIO_Set(tUPIO_TYPE type, tUPIO pio, tUPIO_STATE state);
+
+
+/*****************************************************************************
+**
+** Function UPIO_Read
+**
+** Description
+** Read the state of a GPIO. This function can be used for any type of
+** device. Parameter pio can only indicate a single GPIO; multiple GPIOs
+** cannot be masked together.
+**
+** Input Parameters:
+** Type: The type of device.
+** pio: Indicates the particular GUPIO.
+**
+** Output Parameter:
+** None.
+**
+** Returns:
+** State of GPIO (UPIO_ON or UPIO_OFF).
+**
+*****************************************************************************/
+UDRV_API tUPIO_STATE UPIO_Read(tUPIO_TYPE type, tUPIO pio);
+
+
+/*****************************************************************************
+**
+** Function UPIO_Config
+**
+** Description - Configure GPIOs of type UPIO_GENERAL as inputs or outputs
+** - Configure GPIOs to be polled or interrupt driven
+**
+** Currently only support polled GPIOs.
+**
+** Input Parameters:
+** type The type of device.
+** pio Indicates the particular GPIOs.
+** config
+** cback
+**
+** Output Parameter:
+** None.
+**
+** Returns:
+** None.
+**
+*****************************************************************************/
+UDRV_API void UPIO_Config(tUPIO_TYPE type, tUPIO pio, tUPIO_CONFIG config, tUPIO_CBACK *cback);
+
+
+/*****************************************************************************
+**
+** Function UPIO_Feature
+**
+** Description
+** Checks whether a feature of the pio API is supported
+**
+** Input Parameter:
+** feature The feature to check
+**
+** Output Parameter:
+** None.
+**
+** Returns:
+** TRUE if feature is supported, FALSE if it is not.
+**
+*****************************************************************************/
+UDRV_API BOOLEAN UPIO_Feature(tUPIO_FEATURE feature);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ifdef UPIO_H */
diff --git a/src/udrv/include/usb.h b/src/udrv/include/usb.h
new file mode 100644
index 0000000..c9ecda0
--- /dev/null
+++ b/src/udrv/include/usb.h
@@ -0,0 +1,232 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2001-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * This file contains serial definitions from WIDCOMM's Universal Embedded
+ * Drivers API.
+ *
+ ******************************************************************************/
+
+#ifndef USB_H
+#define USB_H
+
+/*******************************************************************************
+** Serial APIs
+*******************************************************************************/
+
+/**** port IDs ****/
+#define USB_PORT_1 0
+#define USB_PORT_2 1
+#define USB_PORT_3 2
+#define USB_PORT_4 3
+
+typedef UINT8 tUSB_PORT;
+
+/**** baud rates ****/
+#define USB_BAUD_300 0
+#define USB_BAUD_600 1
+#define USB_BAUD_1200 2
+#define USB_BAUD_2400 3
+#define USB_BAUD_9600 4
+#define USB_BAUD_19200 5
+#define USB_BAUD_57600 6
+#define USB_BAUD_115200 7
+#define USB_BAUD_230400 8
+#define USB_BAUD_460800 9
+#define USB_BAUD_921600 10
+#define USB_BAUD_AUTO 11
+
+/**** Data Format ****/
+
+/* Stop Bits */
+#define USB_STOPBITS_1 1
+#define USB_STOPBITS_1_5 (1<<1)
+#define USB_STOPBITS_2 (1<<2)
+
+/* Parity Bits */
+#define USB_PARITY_NONE (1<<3)
+#define USB_PARITY_EVEN (1<<4)
+#define USB_PARITY_ODD (1<<5)
+
+/* Data Bits */
+#define USB_DATABITS_5 (1<<6)
+#define USB_DATABITS_6 (1<<7)
+#define USB_DATABITS_7 (1<<8)
+#define USB_DATABITS_8 (1<<9)
+
+
+/**** Flow Control ****/
+#define USB_FC_NONE 0
+#define USB_FC_HW 1
+#define USB_FC_SW 2
+
+/**** Data Buffering Mechanism ****/
+#define USB_BUF_BYTE 0
+#define USB_BUF_GKI 1
+
+/**** Signals ****/
+#define USB_SIG_RTSCTS 1
+#define USB_SIG_DSRDTR (1<<1)
+#define USB_SIG_RI (1<<2)
+#define USB_SIG_CD (1<<3)
+#define USB_SIG_DTE_DEVICE (1<<4)
+
+/**** Errors *****/
+#define USB_ERR_OVERRUN 1
+#define USB_ERR_PARITY (1<<1)
+#define USB_ERR_FRAMING (1<<2)
+#define USB_ERR_BREAK (1<<3)
+
+/**** Serial Operations ****/
+#define USB_OP_FLUSH 0
+#define USB_OP_FLUSH_RX 1
+#define USB_OP_FLUSH_TX 2
+#define USB_OP_BREAK_OFF 3
+#define USB_OP_BREAK_ON 4
+#define USB_OP_BAUD_RD 5
+#define USB_OP_BAUD_WR 6
+#define USB_OP_FMT_RD 7
+#define USB_OP_FMT_WR 8
+#define USB_OP_SIG_RD 9
+#define USB_OP_SIG_WR 10
+#define USB_OP_FC_RD 11
+#define USB_OP_FC_WR 12
+
+typedef UINT8 tUSB_OP;
+
+
+/**** Serial feature types ****/
+#define USB_FEAT_PORT_1 0
+#define USB_FEAT_PORT_2 1
+#define USB_FEAT_PORT_3 2
+#define USB_FEAT_PORT_4 3
+#define USB_FEAT_BAUD_AUTO 4
+#define USB_FEAT_BAUD_300 5
+#define USB_FEAT_BAUD_600 6
+#define USB_FEAT_BAUD_1200 7
+#define USB_FEAT_BAUD_2400 8
+#define USB_FEAT_BAUD_9600 9
+#define USB_FEAT_BAUD_19200 10
+#define USB_FEAT_BAUD_57600 11
+#define USB_FEAT_BAUD_115200 12
+#define USB_FEAT_BAUD_230400 13
+#define USB_FEAT_BAUD_460800 14
+#define USB_FEAT_BAUD_921600 15
+#define USB_FEAT_STOPBITS_1 16
+#define USB_FEAT_STOPBITS_1_5 17
+#define USB_FEAT_STOPBITS_2 18
+#define USB_FEAT_PARITY_NONE 19
+#define USB_FEAT_PARITY_EVEN 20
+#define USB_FEAT_PARITY_ODD 21
+#define USB_FEAT_DATABITS_5 22
+#define USB_FEAT_DATABITS_6 23
+#define USB_FEAT_DATABITS_7 24
+#define USB_FEAT_DATABITS_8 25
+#define USB_FEAT_FC_NONE 26
+#define USB_FEAT_FC_HW 27
+#define USB_FEAT_FC_SW 28
+#define USB_FEAT_BUF_BYTE 29
+#define USB_FEAT_BUF_GKI 30
+#define USB_FEAT_SIG_RTS 31
+#define USB_FEAT_SIG_CTS 32
+#define USB_FEAT_SIG_DSR 33
+#define USB_FEAT_SIG_DTR 34
+#define USB_FEAT_SIG_RI 35
+#define USB_FEAT_SIG_CD 36
+#define USB_FEAT_OP_FLUSH 37
+#define USB_FEAT_OP_FLUSH_RX 38
+#define USB_FEAT_OP_FLUSH_TX 39
+#define USB_FEAT_OP_BREAK 40
+#define USB_FEAT_OP_BAUD_RD 41
+#define USB_FEAT_OP_BAUD_WR 42
+#define USB_FEAT_OP_FMT_RD 43
+#define USB_FEAT_OP_FMT_WR 44
+#define USB_FEAT_OP_SIG_RD 45
+#define USB_FEAT_OP_SIG_WR 46
+#define USB_FEAT_OP_FC_RD 47
+#define USB_FEAT_OP_FC_WR 48
+
+typedef UINT8 tUSB_FEATURE;
+
+
+/**** Event types ****/
+#define USB_RX_READY_EVT 0
+#define USB_TX_DONE_EVT 1
+#define USB_SIG_EVT 2
+#define USB_ERR_EVT 3
+
+typedef UINT8 tUSB_EVT;
+
+
+/* Structure used to configure serial port during open */
+typedef struct
+{
+ UINT16 fmt; /* Data format */
+ UINT8 baud; /* Baud rate */
+ UINT8 fc; /* Flow control */
+ UINT8 buf; /* Data buffering mechanism */
+ UINT8 pool; /* GKI buffer pool for received data */
+ UINT16 size; /* Size of GKI buffer pool */
+ UINT16 offset; /* Offset in GKI buffer pool */
+} tUSB_OPEN_CFG;
+
+/* Union used to pass ioctl arguments */
+typedef union
+{
+ UINT16 fmt;
+ UINT8 baud;
+ UINT8 fc;
+ UINT8 sigs;
+} tUSB_IOCTL_DATA;
+
+
+/* Union to pass event data */
+typedef union
+{
+ UINT8 sigs;
+ UINT8 error;
+} tUSB_EVT_DATA;
+
+/* callback for events */
+typedef void (tUSB_CBACK)(tUSB_PORT, tUSB_EVT, tUSB_EVT_DATA *);
+
+
+/*******************************************************************************
+** Function Prototypes
+*******************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+UDRV_API extern void USB_Init(void *);
+UDRV_API extern void USB_Open(tUSB_PORT, tUSB_OPEN_CFG *, tUSB_CBACK *);
+UDRV_API extern void USB_ReadBuf(tUSB_PORT, BT_HDR **);
+UDRV_API extern UINT16 USB_Read(tUSB_PORT, UINT8 *, UINT16);
+UDRV_API extern BOOLEAN USB_WriteBuf(tUSB_PORT, BT_HDR *);
+UDRV_API extern UINT16 USB_Write(tUSB_PORT, UINT8 *, UINT16);
+UDRV_API extern void USB_Ioctl(tUSB_PORT, tUSB_OP, tUSB_IOCTL_DATA *);
+UDRV_API extern void USB_Close(tUSB_PORT);
+UDRV_API extern BOOLEAN USB_Feature(tUSB_FEATURE);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* USB_H */
diff --git a/src/udrv/include/utimer.h b/src/udrv/include/utimer.h
new file mode 100644
index 0000000..a663ad7
--- /dev/null
+++ b/src/udrv/include/utimer.h
@@ -0,0 +1,98 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2001-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * This file contains timer definitions from WIDCOMM's Universal Embedded
+ * Drivers API.
+ *
+ ******************************************************************************/
+
+#ifndef UTIMER_H
+#define UTIMER_H
+
+/*******************************************************************************
+** Timer APIs
+*******************************************************************************/
+
+/**** Timer IDs ****/
+
+#define UTIMER_ID_1 0
+#define UTIMER_ID_2 1
+#define UTIMER_ID_3 2
+#define UTIMER_ID_4 3
+
+#define UTIMER_NUM_TIMERS 4 /* Number of timers supported */
+
+typedef UINT8 tUTIMER_ID;
+
+/**** Timer types ****/
+
+#define UTIMER_TYPE_PERIODIC 0
+#define UTIMER_TYPE_ONESHOT 1
+
+typedef UINT8 tUTIMER_TYPE;
+
+
+/**** Timer time ****/
+
+typedef UINT32 tUTIMER_TIME;
+
+
+/**** Timer configuration ****/
+
+typedef struct
+{
+ tUTIMER_TIME period;
+ tUTIMER_TYPE type;
+} tUTIMER_CFG;
+
+
+/**** Timer feature types ****/
+#define UTIMER_FEAT_ID_1 0
+#define UTIMER_FEAT_ID_2 1
+#define UTIMER_FEAT_ID_3 2
+#define UTIMER_FEAT_ID_4 3
+#define UTIMER_FEAT_TYPE_PERIODIC 4
+#define UTIMER_FEAT_TYPE_ONESHOT 5
+
+typedef UINT8 tUTIMER_FEATURE;
+
+
+/**** Callback for timer expiration ****/
+typedef void (tUTIMER_CBACK)(tUTIMER_ID);
+
+
+/*******************************************************************************
+** Function Prototypes
+*******************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+UDRV_API extern void UTIMER_Init(void *);
+UDRV_API extern void UTIMER_Start(tUTIMER_ID, tUTIMER_CFG *, tUTIMER_CBACK *);
+UDRV_API extern void UTIMER_Read(tUTIMER_ID, tUTIMER_TIME *);
+UDRV_API extern void UTIMER_Stop(tUTIMER_ID);
+UDRV_API extern BOOLEAN UTIMER_Feature(tUTIMER_FEATURE);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* UTIMER_H */
diff --git a/src/udrv/include/uusb.h b/src/udrv/include/uusb.h
new file mode 100644
index 0000000..7a93920
--- /dev/null
+++ b/src/udrv/include/uusb.h
@@ -0,0 +1,290 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2001-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * This file contains usb definitions from Widcomm's Universal Embedded
+ * Drivers API.
+ *
+ ******************************************************************************/
+
+#ifndef UUSB_H
+#define UUSB_H
+
+#include "bt_target.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*******************************************************************************
+** Codec APIs
+*******************************************************************************/
+
+
+/**** Status ****/
+#define UUSB_SUCCESS 0
+#define UUSB_DRV_INVALID_PARM 1 // Invalid parameter(s) passed to Driver
+#define UUSB_DRV_INVALID_STATE 2 // Driver is not in correct state to accept
+#define UUSB_DRV_UNSUPPORTED_SETUP_REQ 3 // Unsupported SETUP request (use with tUSER_EP0_SETUP_CB)
+#define UUSB_DRV_NO_BUFFER_AVAILABLE 4 // User cannot provide a Buffer (use with CB functions)
+
+typedef UINT8 tUUSB_STATUS;
+
+
+#define UUSB_EP1 0
+#define UUSB_EP2 1
+#define UUSB_EP3 2
+#define UUSB_EP4 3
+#define UUSB_EP5 4
+#define UUSB_EP6 5
+#define UUSB_EP7 6
+
+typedef UINT8 tUUSB_EP_ID;
+
+typedef enum {
+ UUSB_EP_TYPE_CONTROL = 0,
+ UUSB_EP_TYPE_ISOCHRONOUS,
+ UUSB_EP_TYPE_BULK,
+ UUSB_EP_TYPE_INTERRUPT
+} tUUSB_EP_TYPE;
+
+typedef enum {
+ UUSB_DIR_OUT = 0,
+ UUSB_DIR_IN
+} tUUSB_EP_DIRECTION;
+
+typedef struct tUUSB_SETUP_PKTTag
+{
+/* Definition of "USBbmRequestType" */
+#define UUSB_DATA_PHASE_DIR 0x80 /* Mask to get data phase transfer direction */
+#define UUSB_HOST_TO_DEVICE 0x00 /* Data transfer directions */
+#define UUSB_DEVICE_TO_HOST 0x80 /* Data transfer directions */
+/* Types of requests */
+#define UUSB_REQUEST_TYPE 0x60 /* Mask to get request type */
+#define UUSB_STANDARD_REQUEST 0x00 /* Standard request */
+#define UUSB_CLASS_REQUEST 0x20 /* Class request */
+#define UUSB_VENDOR_REQUEST 0x40 /* Vendor request */
+ UINT8 bmRequestType;
+ UINT8 bRequest;
+ UINT16 wValue;
+ UINT16 wIndex;
+ UINT16 wLength;
+} tUUSB_SETUP_PKT;
+
+typedef union
+{
+#define UUSB_HEAD_SIZE (8)
+ UINT8 HeadBytes[UUSB_HEAD_SIZE];
+ tUUSB_SETUP_PKT Setup;
+} tSETUP_OR_HEAD;
+
+typedef struct
+{
+ UINT8 BufSize;
+ UINT8 NumBytesInBuf;
+ tSETUP_OR_HEAD Buf;
+} tUUSB_RX_HEAD;
+
+typedef enum
+{
+ UUSB_EP_DISABLE,
+ UUSB_EP_ENABLE,
+ UUSB_EP_STALL
+} tUUSB_EP_STATE;
+
+typedef UINT8 tEndPoint;
+
+#if 0
+#define UUSB_ATTACHED 0
+#define UUSB_POWERED 1
+#define UUSB_DEFAULT 2
+#define UUSB_ADDRESS 3
+#define UUSB_CONFIGURED 4
+#define UUSB_SUSPENDED 5
+
+typedef UINT8 tUUSB_BUS_STATE;
+#else
+typedef enum
+{
+ UUSB_ATTACHED,
+ UUSB_POWERED,
+ UUSB_DEFAULT,
+ UUSB_ADDRESS,
+ UUSB_CONFIGURED,
+ UUSB_SUSPENDED
+} tUUSB_BUS_STATE;
+#endif
+
+typedef enum _tUUSB_STANDART_REQ
+{
+ UUSB_GET_STATUS = 0,
+ UUSB_CLEAR_FEATURE,
+ UUSB_RESERVED1,
+ UUSB_SET_FEATURE,
+ UUSB_RESERVED2,
+ UUSB_SET_ADDRESS,
+ UUSB_GET_DESCRIPTOR,
+ UUSB_SET_DESCRIPTOR,
+ UUSB_GET_CONFIGURATION,
+ UUSB_SET_CONFIGURATION,
+ UUSB_GET_INTERFACE,
+ UUSB_SET_INTERFACE,
+ UUSB_TOTAL_sREQUEST, /* Total number of Standard request */
+ UUSB_SYNCH_FRAME = 12
+} tUUSB_STANDART_REQ;
+
+
+typedef void (*tUUSB_STATE_CB) (tUUSB_BUS_STATE State);
+typedef void (*tUUSB_PROT_COMPLETE_CB ) (UINT8 *pBuf,UINT16 NumBytesInBuf);
+
+typedef tUUSB_STATUS (*tUUSB_PROT_SETUP_CB ) (UINT8 **ppBuf,UINT16 *pBufSize);
+
+typedef void (*tUUSB_RX_START_CB ) (tUUSB_EP_ID EndPoint,
+ UINT8 **ppBuf,
+ UINT16 *pBufSize);
+
+typedef void (*tUUSB_RX_COMPLETE_CB ) (tUUSB_EP_ID EndPoint,
+ UINT8 *pRxBuf,
+ UINT16 NumBytesInBuf);
+
+typedef void (*tUUSB_TX_COMPLETE_CB ) (tUUSB_EP_ID EndPoint,
+ UINT8 *pRxBuf);
+/*******************************************************************************
+** Function Prototypes
+*******************************************************************************/
+
+/******************************************************************************
+**
+** Function UCODEC_Init
+**
+** Description Startup initialisation function. This function is called
+** before any orther function of UUSB it initialize UUSB
+** internal structure an the external hw.
+**
+** Input :
+**
+** Output Parameters :
+**
+** Returns UUSB_SUCCESS if The action was performed with sucess.
+** Error code else.
+**
+******************************************************************************/
+BT_API extern tUUSB_STATUS UUSB_Init (tUUSB_PROT_SETUP_CB userProtSetupCallBack,
+ tUUSB_PROT_COMPLETE_CB userProtCompleteCallBack,
+ tUUSB_RX_START_CB userRxStartCallBack,
+ tUUSB_STATE_CB userStateCallBack,
+ tUUSB_TX_COMPLETE_CB userTxCompleteCallBack,
+ tUUSB_RX_COMPLETE_CB userRxCompleteCallBack);
+
+
+
+
+/******************************************************************************
+**
+** Function UUSB_Start
+**
+** Description
+**
+**
+**
+**
+**
+** Returns UUSB_SUCCESS if The action was performed with sucess.
+**
+******************************************************************************/
+BT_API extern tUUSB_STATUS UUSB_Start (void);
+
+/******************************************************************************
+**
+** Function UUSB_Stop
+**
+** Description
+**
+**
+**
+**
+** Returns UUSB_SUCCESS if The action was performed with sucess.
+** Error code else.
+**
+******************************************************************************/
+BT_API extern tUUSB_STATUS UUSB_Stop (void);
+
+/******************************************************************************
+**
+** Function UUSB_SetEndPointCnf
+**
+** Description
+**
+**
+** Returns
+**
+******************************************************************************/
+BT_API extern tUUSB_STATUS UUSB_SetEndPointCnf ( BOOLEAN IsIN_EndPoint,
+ tUUSB_EP_ID EndPoint,
+ UINT8 MaxPacketSize,
+ tUUSB_EP_TYPE EndPointType,
+ tUUSB_RX_HEAD *pRxHead,
+ UINT16 RxTimeOut);
+
+
+/******************************************************************************
+**
+** Function UUSB_SetEndPointState
+**
+** Description
+**
+**
+** Returns
+**
+******************************************************************************/
+BT_API extern tUUSB_STATUS UUSB_SetEndPointState (tUUSB_EP_ID EndPoint,
+ tUUSB_EP_STATE EndPointState);
+
+/******************************************************************************
+**
+** Function UUSB_WriteEndPoint
+**
+** Description
+**
+**
+** Returns
+**
+******************************************************************************/
+BT_API extern tUUSB_STATUS UUSB_WriteEndPoint (tUUSB_EP_ID EndPoint,
+ UINT16 Length,
+ UINT8* pBuf);
+
+/******************************************************************************
+**
+** Function UUSB_GenerateRemoteWakeUp
+**
+** Description
+**
+**
+** Returns
+**
+******************************************************************************/
+BT_API extern tUUSB_STATUS UUSB_GenerateRemoteWakeUp (void);
+
+#ifdef __cplusplus
+};
+#endif
+
+
+#endif /* UUSB_H */