Commit 1d36547d authored by Matej Frančeškin's avatar Matej Frančeškin
Browse files

Remove reference to NXP NFC Library. Keep only QtNFC.

parent a97230c7
......@@ -22,7 +22,6 @@ linux {
message("Linux build")
CONFIG += LinuxBuild
DEFINES += __STDC_LIMIT_MACROS
DEFINES += QGC_ENABLE_NFC RW_SUPPORT
DEFINES += QGC_GST_TAISYNC_ENABLED
DEFINES += QGC_GST_MICROHARD_ENABLED
DEFINES += QGC_ENABLE_MAVLINK_INSPECTOR
......
......@@ -147,12 +147,10 @@ contains(DEFINES, QGC_ENABLE_PAIRING) {
} else {
# There is some circular reference settings going on between QGCExternalLibs.pri and gqgroundcontrol.pro.
# So this duplicates some of the enable/disable logic which would normally be in qgroundcontrol.pro.
DEFINES -= QGC_ENABLE_NFC
DEFINES -= QGC_ENABLE_PAIRING
}
} else:WindowsBuild {
#- Pairing is not supported on Windows
DEFINES -= QGC_ENABLE_NFC
DEFINES -= QGC_ENABLE_PAIRING
} else {
LIBS += -lcrypto -lz
......
......@@ -187,18 +187,6 @@ contains (DEFINES, QGC_DISABLE_BLUETOOTH) {
DEFINES += QGC_ENABLE_BLUETOOTH
}
# NFC
contains (DEFINES, QGC_DISABLE_NFC) {
message("Skipping support for NFC (manual override from command line)")
DEFINES -= QGC_ENABLE_NFC
} else:exists(user_config.pri):infile(user_config.pri, DEFINES, QGC_DISABLE_NFC) {
message("Skipping support for NFC (manual override from user_config.pri)")
DEFINES -= QGC_ENABLE_NFC
} else:exists(user_config.pri):infile(user_config.pri, DEFINES, QGC_ENABLE_NFC) {
message("Including support for NFC (manual override from user_config.pri)")
DEFINES += QGC_ENABLE_NFC
}
# QTNFC
contains (DEFINES, QGC_DISABLE_QTNFC) {
message("Skipping support for QTNFC (manual override from command line)")
......@@ -318,14 +306,11 @@ DEFINES+=QGC_DISABLE_PAIRING
# Pairing
contains (DEFINES, QGC_DISABLE_PAIRING) {
message("Skipping support for Pairing")
DEFINES -= QGC_ENABLE_NFC
} else:exists(user_config.pri):infile(user_config.pri, DEFINES, QGC_DISABLE_PAIRING) {
message("Skipping support for Pairing (manual override from user_config.pri)")
DEFINES -= QGC_ENABLE_NFC
} else:AndroidBuild:contains(QT_ARCH, arm64) {
# Haven't figured out how to get 64 bit arm OpenSLL yet which pairing requires
message("Skipping support for Pairing (Missing Android OpenSSL 64 bit support)")
DEFINES -= QGC_ENABLE_NFC
} else {
message("Enabling support for Pairing")
DEFINES += QGC_ENABLE_PAIRING
......@@ -737,37 +722,6 @@ contains (DEFINES, QGC_ENABLE_PAIRING) {
}
}
contains (DEFINES, QGC_ENABLE_PAIRING) {
contains(DEFINES, QGC_ENABLE_NFC) {
HEADERS += \
src/PairingManager/PairingNFC.h \
src/PairingManager/NfcLibrary/inc/Nfc.h \
src/PairingManager/NfcLibrary/inc/Nfc_settings.h \
src/PairingManager/NfcLibrary/NdefLibrary/inc/P2P_NDEF.h \
src/PairingManager/NfcLibrary/NdefLibrary/inc/RW_NDEF.h \
src/PairingManager/NfcLibrary/NdefLibrary/inc/RW_NDEF_T1T.h \
src/PairingManager/NfcLibrary/NdefLibrary/inc/RW_NDEF_T2T.h \
src/PairingManager/NfcLibrary/NdefLibrary/inc/RW_NDEF_T3T.h \
src/PairingManager/NfcLibrary/NdefLibrary/inc/RW_NDEF_T4T.h \
src/PairingManager/NfcLibrary/NdefLibrary/inc/T4T_NDEF_emu.h \
src/PairingManager/NfcLibrary/NxpNci/inc/NxpNci.h \
src/PairingManager/NfcTask/inc/ndef_helper.h \
src/PairingManager/TML/inc/framework_Allocator.h \
src/PairingManager/TML/inc/framework_Interface.h \
src/PairingManager/TML/inc/framework_Map.h \
src/PairingManager/TML/inc/framework_Timer.h \
src/PairingManager/TML/inc/lpcusbsio.h \
src/PairingManager/TML/inc/tml.h \
src/PairingManager/TML/inc/tool.h \
src/PairingManager/TML/inc/framework_Container.h \
src/PairingManager/TML/inc/framework_linux.h \
src/PairingManager/TML/inc/framework_Parcel.h \
src/PairingManager/TML/inc/hidapi.h \
src/PairingManager/TML/inc/lpcusbsio_i2c.h \
src/PairingManager/TML/inc/tml_hid.h
}
}
!NoSerialBuild {
HEADERS += \
src/comm/QGCSerialPortInfo.h \
......@@ -966,36 +920,6 @@ contains (DEFINES, QGC_ENABLE_PAIRING) {
}
}
contains (DEFINES, QGC_ENABLE_PAIRING) {
contains(DEFINES, QGC_ENABLE_NFC) {
SOURCES += \
src/PairingManager/PairingNFC.cc \
src/PairingManager/NfcLibrary/NxpNci/src/NxpNci.c \
src/PairingManager/NfcLibrary/NdefLibrary/src/RW_NDEF_T4T.c \
src/PairingManager/NfcLibrary/NdefLibrary/src/P2P_NDEF.c \
src/PairingManager/NfcLibrary/NdefLibrary/src/RW_NDEF_T3T.c \
src/PairingManager/NfcLibrary/NdefLibrary/src/RW_NDEF.c \
src/PairingManager/NfcLibrary/NdefLibrary/src/RW_NDEF_T1T.c \
src/PairingManager/NfcLibrary/NdefLibrary/src/RW_NDEF_T2T.c \
src/PairingManager/NfcLibrary/NdefLibrary/src/T4T_NDEF_emu.c \
src/PairingManager/TML/src/framework_Map.c \
src/PairingManager/TML/src/framework_log.c \
src/PairingManager/TML/src/framework_Parcel.c \
src/PairingManager/TML/src/framework_sem.c \
src/PairingManager/TML/src/framework_mutex.c \
src/PairingManager/TML/src/hid.c \
src/PairingManager/TML/src/framework_Allocator.c \
src/PairingManager/TML/src/tml_hid.c \
src/PairingManager/TML/src/framework_Container.c \
src/PairingManager/TML/src/framework_thread.c \
src/PairingManager/TML/src/framework_Timer.c \
src/PairingManager/TML/src/lpcusbsio.c \
src/PairingManager/TML/src/tml.c \
src/PairingManager/NfcTask/src/ndef_helper.c
LIBS += -lrt -ludev
}
}
!MobileBuild {
SOURCES += \
src/GPS/Drivers/src/gps_helper.cpp \
......
/*
* Copyright (c), NXP Semiconductors Caen / France
*
* (C)NXP Semiconductors
* All rights are reserved. Reproduction in whole or in part is
* prohibited without the written consent of the copyright owner.
* NXP reserves the right to make changes without notice at any time.
* NXP makes no warranty, expressed, implied or statutory, including but
* not limited to any implied warranty of merchantability or fitness for any
*particular purpose, or that the use will not infringe any third party patent,
* copyright or trademark. NXP must not be liable for any loss or damage
* arising from its use.
*/
#define P2P_NDEF_MAX_NDEF_MESSAGE_SIZE 240
void P2P_NDEF_Reset(void);
void P2P_NDEF_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size);
/*
* Copyright (c), NXP Semiconductors Caen / France
*
* (C)NXP Semiconductors
* All rights are reserved. Reproduction in whole or in part is
* prohibited without the written consent of the copyright owner.
* NXP reserves the right to make changes without notice at any time.
* NXP makes no warranty, expressed, implied or statutory, including but
* not limited to any implied warranty of merchantability or fitness for any
*particular purpose, or that the use will not infringe any third party patent,
* copyright or trademark. NXP must not be liable for any loss or damage
* arising from its use.
*/
#define RW_MAX_NDEF_FILE_SIZE 500
extern unsigned char NdefBuffer[RW_MAX_NDEF_FILE_SIZE];
typedef void RW_NDEF_Callback_t (unsigned char*, unsigned short);
#define RW_NDEF_TYPE_T1T 0x1
#define RW_NDEF_TYPE_T2T 0x2
#define RW_NDEF_TYPE_T3T 0x3
#define RW_NDEF_TYPE_T4T 0x4
extern unsigned char *pRW_NdefMessage;
extern unsigned short RW_NdefMessage_size;
extern RW_NDEF_Callback_t *pRW_NDEF_PullCb;
extern RW_NDEF_Callback_t *pRW_NDEF_PushCb;
void RW_NDEF_Reset(unsigned char type);
void RW_NDEF_Read_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size);
void RW_NDEF_Write_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size);
/*
* Copyright (c), NXP Semiconductors Caen / France
*
* (C)NXP Semiconductors
* All rights are reserved. Reproduction in whole or in part is
* prohibited without the written consent of the copyright owner.
* NXP reserves the right to make changes without notice at any time.
* NXP makes no warranty, expressed, implied or statutory, including but
* not limited to any implied warranty of merchantability or fitness for any
*particular purpose, or that the use will not infringe any third party patent,
* copyright or trademark. NXP must not be liable for any loss or damage
* arising from its use.
*/
void RW_NDEF_T1T_Reset(void);
void RW_NDEF_T1T_Read_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size);
/*
* Copyright (c), NXP Semiconductors Caen / France
*
* (C)NXP Semiconductors
* All rights are reserved. Reproduction in whole or in part is
* prohibited without the written consent of the copyright owner.
* NXP reserves the right to make changes without notice at any time.
* NXP makes no warranty, expressed, implied or statutory, including but
* not limited to any implied warranty of merchantability or fitness for any
*particular purpose, or that the use will not infringe any third party patent,
* copyright or trademark. NXP must not be liable for any loss or damage
* arising from its use.
*/
void RW_NDEF_T2T_Reset(void);
void RW_NDEF_T2T_Read_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size);
void RW_NDEF_T2T_Write_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size);
/*
* Copyright (c), NXP Semiconductors Caen / France
*
* (C)NXP Semiconductors
* All rights are reserved. Reproduction in whole or in part is
* prohibited without the written consent of the copyright owner.
* NXP reserves the right to make changes without notice at any time.
* NXP makes no warranty, expressed, implied or statutory, including but
* not limited to any implied warranty of merchantability or fitness for any
*particular purpose, or that the use will not infringe any third party patent,
* copyright or trademark. NXP must not be liable for any loss or damage
* arising from its use.
*/
void RW_NDEF_T3T_Reset(void);
void RW_NDEF_T3T_SetIDm(unsigned char *pIDm);
void RW_NDEF_T3T_Read_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size);
/*
* Copyright (c), NXP Semiconductors Caen / France
*
* (C)NXP Semiconductors
* All rights are reserved. Reproduction in whole or in part is
* prohibited without the written consent of the copyright owner.
* NXP reserves the right to make changes without notice at any time.
* NXP makes no warranty, expressed, implied or statutory, including but
* not limited to any implied warranty of merchantability or fitness for any
*particular purpose, or that the use will not infringe any third party patent,
* copyright or trademark. NXP must not be liable for any loss or damage
* arising from its use.
*/
void RW_NDEF_T4T_Reset(void);
void RW_NDEF_T4T_Read_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size);
void RW_NDEF_T4T_Write_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size);
/*
* Copyright (c), NXP Semiconductors Caen / France
*
* (C)NXP Semiconductors
* All rights are reserved. Reproduction in whole or in part is
* prohibited without the written consent of the copyright owner.
* NXP reserves the right to make changes without notice at any time.
* NXP makes no warranty, expressed, implied or statutory, including but
* not limited to any implied warranty of merchantability or fitness for any
*particular purpose, or that the use will not infringe any third party patent,
* copyright or trademark. NXP must not be liable for any loss or damage
* arising from its use.
*/
void T4T_NDEF_EMU_Reset(void);
void T4T_NDEF_EMU_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size);
/*
* Copyright (c), NXP Semiconductors Caen / France
*
* (C)NXP Semiconductors
* All rights are reserved. Reproduction in whole or in part is
* prohibited without the written consent of the copyright owner.
* NXP reserves the right to make changes without notice at any time.
* NXP makes no warranty, expressed, implied or statutory, including but
* not limited to any implied warranty of merchantability or fitness for any
*particular purpose, or that the use will not infringe any third party patent,
* copyright or trademark. NXP must not be liable for any loss or damage
* arising from its use.
*/
#ifdef P2P_SUPPORT
#include <TML/inc/tool.h>
#include <NfcLibrary/NdefLibrary/inc/P2P_NDEF.h>
/* Well-known LLCP SAP Values */
#define SAP_SDP 1
#define SAP_SNEP 4
/* SNEP codes */
#define SNEP_VER10 0x10
#define SNEP_PUT 0x2
#define SNEP_SUCCESS 0x81
/* LLCP PDU Types */
#define SYMM 0x0
#define PAX 0x1
#define AGF 0x2
#define UI 0x3
#define CONNECT 0x4
#define DISC 0x5
#define CC 0x6
#define DM 0x7
#define FRMR 0x8
#define SNL 0x9
#define reservedA 0xA
#define reservedB 0xB
#define I 0xC
#define RR 0xD
#define RNR 0xE
#define reservedF 0xF
/* LLCP parameters */
#define VERSION 1
#define MIUX 2
#define WKS 3
#define LTO 4
#define RW 5
#define SN 6
const unsigned char SNEP_PUT_SUCCESS[] = {SNEP_VER10, SNEP_SUCCESS, 0x00, 0x00, 0x00, 0x00};
const unsigned char LLCP_CONNECT_SNEP[] = {0x11, 0x20};
const unsigned char LLCP_I_SNEP_PUT_HEADER[] = {SNEP_VER10, SNEP_PUT, 0x00, 0x00, 0x00, 0x00};
const unsigned char LLCP_SYMM[] = {0x00, 0x00};
unsigned char *pNdefMessage;
unsigned short NdefMessage_size = 0;
/* Defines the number of symmetry exchanges is expected before initiating the NDEF push (to allow a remote phone to beam an NDEF message first) */
#define NDEF_PUSH_DELAY_COUNT 2
/* Defines at which frequency the symmetry is exchange (in ms) */
#define SYMM_FREQ 500
typedef enum
{
Idle,
Initial,
DelayingPush,
SnepClientConnecting,
SnepClientConnected,
NdefMsgSent
} P2P_SnepClient_state_t;
typedef struct
{
unsigned char Dsap;
unsigned char Pdu;
unsigned char Ssap;
unsigned char Version;
unsigned short Miux;
unsigned short Wks;
unsigned char Lto;
unsigned char Rw;
unsigned char Sn[30];
} P2P_NDEF_LlcpHeader_t;
typedef void P2P_NDEF_Callback_t (unsigned char*, unsigned short);
static P2P_SnepClient_state_t eP2P_SnepClient_State = Initial;
static P2P_NDEF_Callback_t *pP2P_NDEF_PushCb = NULL;
static P2P_NDEF_Callback_t *pP2P_NDEF_PullCb = NULL;
static unsigned short P2P_SnepClient_DelayCount = NDEF_PUSH_DELAY_COUNT;
static void ParseLlcp(unsigned char *pBuf, unsigned short BufSize, P2P_NDEF_LlcpHeader_t *pLlcpHeader)
{
uint8_t i = 2;
pLlcpHeader->Dsap = pBuf[0] >> 2;
pLlcpHeader->Pdu = ((pBuf[0] & 3) << 2) + (pBuf[1] >> 6);
pLlcpHeader->Ssap = pBuf[1] & 0x3F;
while(i<BufSize)
{
switch (pBuf[i]){
case VERSION:
pLlcpHeader->Version = pBuf[i+2];
break;
case MIUX:
pLlcpHeader->Miux = (pBuf[i+2] << 8) + pBuf[i+3];
break;
case WKS:
pLlcpHeader->Wks = (pBuf[i+2] << 8) + pBuf[i+3];
break;
case LTO:
pLlcpHeader->Lto = pBuf[i+2];
break;
case RW:
pLlcpHeader->Rw = pBuf[i+2];
break;
case SN:
memcpy(pLlcpHeader->Sn, &pBuf[i+2], pBuf[i+1] < sizeof(pLlcpHeader->Sn) ? pBuf[i+1] : sizeof(pLlcpHeader->Sn));
break;
default:
break;
}
i += pBuf[i+1]+2;
}
}
static void FillLlcp(P2P_NDEF_LlcpHeader_t LlcpHeader, unsigned char *pBuf)
{
pBuf[0] = (LlcpHeader.Ssap << 2) + ((LlcpHeader.Pdu >> 2) & 3);
pBuf[1] = (LlcpHeader.Pdu << 6) + LlcpHeader.Dsap;
}
bool P2P_NDEF_SetMessage(unsigned char *pMessage, unsigned short Message_size, void *pCb)
{
if (Message_size <= P2P_NDEF_MAX_NDEF_MESSAGE_SIZE)
{
pNdefMessage = pMessage;
NdefMessage_size = Message_size;
pP2P_NDEF_PushCb = (P2P_NDEF_Callback_t*) pCb;
return true;
}
else
{
NdefMessage_size = 0;
pP2P_NDEF_PushCb = NULL;
return false;
}
}
void P2P_NDEF_RegisterPullCallback(void *pCb)
{
pP2P_NDEF_PullCb = (P2P_NDEF_Callback_t*) pCb;
}
void P2P_NDEF_Reset(void)
{
if (NdefMessage_size != 0)
{
eP2P_SnepClient_State = Initial;
}
else
{
eP2P_SnepClient_State = Idle;
}
}
void P2P_NDEF_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *pRsp, unsigned short *pRsp_size)
{
P2P_NDEF_LlcpHeader_t LlcpHeader;
/* Initialize answer */
*pRsp_size = 0;
ParseLlcp(pCmd, Cmd_size, &LlcpHeader);
switch (LlcpHeader.Pdu)
{
case CONNECT:
/* Is connection from SNEP Client ? */
if ((LlcpHeader.Dsap == SAP_SNEP) || (memcmp(LlcpHeader.Sn, "urn:nfc:sn:snep", 15) == 0))
{
/* Only accept the connection is application is registered for NDEF reception */
if(pP2P_NDEF_PullCb != NULL)
{
LlcpHeader.Pdu = CC;
FillLlcp(LlcpHeader, pRsp);
*pRsp_size = 2;
}
}
else
{
/* Refuse any other connection request */
LlcpHeader.Pdu = DM;
FillLlcp(LlcpHeader, pRsp);
*pRsp_size = 2;
}
break;
case I:
/* Is SNEP PUT ? */
if ((pCmd[3] == SNEP_VER10) && (pCmd[4] == SNEP_PUT))
{
/* Notify application of the NDEF reception */
if(pP2P_NDEF_PullCb != NULL) pP2P_NDEF_PullCb(&pCmd[9], pCmd[8]);
/* Acknowledge the PUT request */
LlcpHeader.Pdu = I;
FillLlcp(LlcpHeader, pRsp);
pRsp[2] = (pCmd[2] >> 4) + 1; // N(R)
memcpy(&pRsp[3], SNEP_PUT_SUCCESS, sizeof(SNEP_PUT_SUCCESS));
*pRsp_size = 9;
}
break;
case CC:
/* Connection to remote SNEP server completed, send NDEF message inside SNEP PUT request */
eP2P_SnepClient_State = SnepClientConnected;
break;
default:
break;
}
/* No answer was set */
if (*pRsp_size == 0)
{
switch(eP2P_SnepClient_State)
{
case Initial:
if((pP2P_NDEF_PullCb == NULL) || (NDEF_PUSH_DELAY_COUNT == 0))
{
memcpy(pRsp, LLCP_CONNECT_SNEP, sizeof(LLCP_CONNECT_SNEP));
*pRsp_size = sizeof(LLCP_CONNECT_SNEP);
eP2P_SnepClient_State = SnepClientConnecting;
}
else
{
P2P_SnepClient_DelayCount = 1;
eP2P_SnepClient_State = DelayingPush;
/* Wait then send a SYMM */
Sleep (SYMM_FREQ);
memcpy(pRsp, LLCP_SYMM, sizeof(LLCP_SYMM));
*pRsp_size = sizeof(LLCP_SYMM);
}
break;
case DelayingPush:
if(P2P_SnepClient_DelayCount == NDEF_PUSH_DELAY_COUNT)
{
memcpy(pRsp, LLCP_CONNECT_SNEP, sizeof(LLCP_CONNECT_SNEP));
*pRsp_size = sizeof(LLCP_CONNECT_SNEP);
eP2P_SnepClient_State = SnepClientConnecting;
}
else
{
P2P_SnepClient_DelayCount++;
/* Wait then send a SYMM */
Sleep (1000);
memcpy(pRsp, LLCP_SYMM, sizeof(LLCP_SYMM));
*pRsp_size = sizeof(LLCP_SYMM);
}
break;
case SnepClientConnected:
LlcpHeader.Pdu = I;
FillLlcp(LlcpHeader, pRsp);
pRsp[2] = 0; // N(R)
pRsp[3] = SNEP_VER10;
pRsp[4] = SNEP_PUT;
pRsp[5] = 0;
pRsp[6] = 0;
pRsp[7] = 0;
pRsp[8] = (unsigned char) NdefMessage_size;
memcpy(&pRsp[9], pNdefMessage, NdefMessage_size);
*pRsp_size = 9 + NdefMessage_size;
eP2P_SnepClient_State = NdefMsgSent;
/* Notify application of the NDEF push */
if(pP2P_NDEF_PushCb != NULL) pP2P_NDEF_PushCb(pNdefMessage, NdefMessage_size);
break;
default:
/* Wait then send a SYMM */
Sleep (SYMM_FREQ);
memcpy(pRsp, LLCP_SYMM, sizeof(LLCP_SYMM));
*pRsp_size = sizeof(LLCP_SYMM);
break;
}
}
}
#endif
/*
* Copyright (c), NXP Semiconductors Caen / France
*
* (C)NXP Semiconductors
* All rights are reserved. Reproduction in whole or in part is
* prohibited without the written consent of the copyright owner.
* NXP reserves the right to make changes without notice at any time.
* NXP makes no warranty, expressed, implied or statutory, including but
* not limited to any implied warranty of merchantability or fitness for any
*particular purpose, or that the use will not infringe any third party patent,
* copyright or trademark. NXP must not be liable for any loss or damage
* arising from its use.
*/
#ifdef RW_SUPPORT
#ifndef NO_NDEF_SUPPORT
#include <TML/inc/tool.h>
#include <NfcLibrary/NdefLibrary/inc/RW_NDEF.h>
#include <NfcLibrary/NdefLibrary/inc/RW_NDEF_T1T.h>
#include <NfcLibrary/NdefLibrary/inc/RW_NDEF_T2T.h>
#include <NfcLibrary/NdefLibrary/inc/RW_NDEF_T3T.h>
#include <NfcLibrary/NdefLibrary/inc/RW_NDEF_T4T.h>
/* Allocate buffer for NDEF operations */
unsigned char NdefBuffer[RW_MAX_NDEF_FILE_SIZE];
typedef void RW_NDEF_Fct_t (unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size);
unsigned char *pRW_NdefMessage;
unsigned short RW_NdefMessage_size;
RW_NDEF_Callback_t *pRW_NDEF_PullCb;
RW_NDEF_Callback_t *pRW_NDEF_PushCb;
static RW_NDEF_Fct_t *pReadFct = NULL;
static RW_NDEF_Fct_t *pWriteFct = NULL;
bool RW_NDEF_SetMessage(unsigned char *pMessage, unsigned short Message_size, void *pCb)
{
if (Message_size <= RW_MAX_NDEF_FILE_SIZE)
{
pRW_NdefMessage = pMessage;
RW_NdefMessage_size = Message_size;
pRW_NDEF_PushCb = (RW_NDEF_Callback_t*) pCb;
return true;
}
else
{
RW_NdefMessage_size = 0;
pRW_NDEF_PushCb = NULL;
return false;
}
}
void RW_NDEF_RegisterPullCallback(void *pCb)
{
pRW_NDEF_PullCb = (RW_NDEF_Callback_t *) pCb;
}
void RW_NDEF_Reset(unsigned char type)
{
pReadFct = NULL;
pWriteFct = NULL;
switch (type)
{
case RW_NDEF_TYPE_T1T:
RW_NDEF_T1T_Reset();
pReadFct = RW_NDEF_T1T_Read_Next;
break;
case RW_NDEF_TYPE_T2T:
RW_NDEF_T2T_Reset();
pReadFct = RW_NDEF_T2T_Read_Next;
pWriteFct = RW_NDEF_T2T_Write_Next;
break;
case RW_NDEF_TYPE_T3T:
RW_NDEF_T3T_Reset();
pReadFct = RW_NDEF_T3T_Read_Next;
break;
case RW_NDEF_TYPE_T4T:
RW_NDEF_T4T_Reset();
pReadFct = RW_NDEF_T4T_Read_Next;
pWriteFct = RW_NDEF_T4T_Write_Next;
break;
default:
break;
}
}
void RW_NDEF_Read_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size)
{
if (pReadFct != NULL) pReadFct(pCmd, Cmd_size, Rsp, pRsp_size);
}
void RW_NDEF_Write_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *Rsp, unsigned short *pRsp_size)
{
if (pWriteFct != NULL) pWriteFct(pCmd, Cmd_size, Rsp, pRsp_size);
}
#endif
#endif
/*
* Copyright (c), NXP Semiconductors Caen / France
*
* (C)NXP Semiconductors
* All rights are reserved. Reproduction in whole or in part is
* prohibited without the written consent of the copyright owner.
* NXP reserves the right to make changes without notice at any time.
* NXP makes no warranty, expressed, implied or statutory, including but
* not limited to any implied warranty of merchantability or fitness for any
*particular purpose, or that the use will not infringe any third party patent,
* copyright or trademark. NXP must not be liable for any loss or damage
* arising from its use.
*/
#ifdef RW_SUPPORT
#ifndef NO_NDEF_SUPPORT
#include <TML/inc/tool.h>
#include <NfcLibrary/NdefLibrary/inc/RW_NDEF.h>
#define T1T_MAGIC_NUMBER 0xE1
#define T1T_NDEF_TLV 0x03
const unsigned char T1T_RID[] = {0x78,0x00,0x00,0x00,0x00,0x00,0x00};
const unsigned char T1T_RALL[] = {0x00,0x00,0x00};
const unsigned char T1T_READ8[] = {0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
typedef enum
{
Initial,
Getting_ID,
Reading_CardContent,
Reading_NDEF
} RW_NDEF_T1T_state_t;
typedef struct
{
unsigned char HR0;
unsigned char HR1;
unsigned char UID[4];
unsigned char BlkNb;
unsigned short MessagePtr;
unsigned short MessageSize;
unsigned char *pMessage;
} RW_NDEF_T1T_Ndef_t;
static RW_NDEF_T1T_state_t eRW_NDEF_T1T_State = Initial;
static RW_NDEF_T1T_Ndef_t RW_NDEF_T1T_Ndef;
void RW_NDEF_T1T_Reset(void)
{
eRW_NDEF_T1T_State = Initial;
RW_NDEF_T1T_Ndef.pMessage = NdefBuffer;
}
void RW_NDEF_T1T_Read_Next(unsigned char *pRsp, unsigned short Rsp_size, unsigned char *pCmd, unsigned short *pCmd_size)
{
/* By default no further command to be sent */
*pCmd_size = 0;
switch(eRW_NDEF_T1T_State)
{
case Initial:
/* Send T1T_RID */
memcpy (pCmd, T1T_RID, sizeof(T1T_RID));
*pCmd_size = 7;
eRW_NDEF_T1T_State = Getting_ID;
break;
case Getting_ID:
/* Is CC Read and Is Ndef ?*/
if ((Rsp_size == 7) && (pRsp[Rsp_size-1] == 0x00))
{
/* Fill File structure */
RW_NDEF_T1T_Ndef.HR0 = pRsp[0];
RW_NDEF_T1T_Ndef.HR1 = pRsp[1];
memcpy (RW_NDEF_T1T_Ndef.UID, &pRsp[2], sizeof(RW_NDEF_T1T_Ndef.UID));
/* Read full card content */
memcpy (pCmd, T1T_RALL, sizeof(T1T_RALL));
memcpy (&pCmd[3], RW_NDEF_T1T_Ndef.UID, sizeof(RW_NDEF_T1T_Ndef.UID));
*pCmd_size = sizeof(T1T_RALL) + sizeof(RW_NDEF_T1T_Ndef.UID);
eRW_NDEF_T1T_State = Reading_CardContent;
}
break;
case Reading_CardContent:
/* Is Read success ?*/
if ((Rsp_size == 123) && (pRsp[Rsp_size-1] == 0x00))
{
/* Check CC */
if (pRsp[10] == T1T_MAGIC_NUMBER)
{
unsigned char Tmp = 14;
unsigned char data_size;
/* If not NDEF Type skip TLV */
while (pRsp[Tmp] != T1T_NDEF_TLV)
{
Tmp += 2 + pRsp[Tmp+1];
if (Tmp > Rsp_size) return;
}
RW_NDEF_T1T_Ndef.MessageSize = pRsp[Tmp+1];
data_size = (Rsp_size - 1) - 16 - Tmp - 2;
/* If provisioned buffer is not large enough, notify the application and stop reading */
if (RW_NDEF_T1T_Ndef.MessageSize > RW_MAX_NDEF_FILE_SIZE)
{
if(pRW_NDEF_PullCb != NULL) pRW_NDEF_PullCb(NULL, 0);
break;
}
/* Is NDEF read already completed ? */
if(RW_NDEF_T1T_Ndef.MessageSize <= data_size)
{
memcpy(RW_NDEF_T1T_Ndef.pMessage, &pRsp[Tmp+2], RW_NDEF_T1T_Ndef.MessageSize);
/* Notify application of the NDEF reception */
if(pRW_NDEF_PullCb != NULL) pRW_NDEF_PullCb(RW_NDEF_T1T_Ndef.pMessage, RW_NDEF_T1T_Ndef.MessageSize);
}
else
{
RW_NDEF_T1T_Ndef.MessagePtr = data_size;
memcpy (RW_NDEF_T1T_Ndef.pMessage, &pRsp[Tmp+2], RW_NDEF_T1T_Ndef.MessagePtr);
RW_NDEF_T1T_Ndef.BlkNb = 0x10;
/* Read NDEF content */
memcpy (pCmd, T1T_READ8, sizeof(T1T_READ8));
pCmd[1] = RW_NDEF_T1T_Ndef.BlkNb;
memcpy (&pCmd[10], RW_NDEF_T1T_Ndef.UID, sizeof(RW_NDEF_T1T_Ndef.UID));
*pCmd_size = sizeof(T1T_READ8) + sizeof(RW_NDEF_T1T_Ndef.UID);
eRW_NDEF_T1T_State = Reading_NDEF;
}
}
}
break;
case Reading_NDEF:
/* Is Read success ?*/
if ((Rsp_size == 10) && (pRsp[Rsp_size-1] == 0x00))
{
/* Is NDEF read already completed ? */
if ((RW_NDEF_T1T_Ndef.MessageSize - RW_NDEF_T1T_Ndef.MessagePtr) < 8)
{
memcpy (&RW_NDEF_T1T_Ndef.pMessage[RW_NDEF_T1T_Ndef.MessagePtr], &pRsp[1], RW_NDEF_T1T_Ndef.MessageSize - RW_NDEF_T1T_Ndef.MessagePtr);
/* Notify application of the NDEF reception */
if(pRW_NDEF_PullCb != NULL) pRW_NDEF_PullCb(RW_NDEF_T1T_Ndef.pMessage, RW_NDEF_T1T_Ndef.MessageSize);
}
else
{
memcpy (&RW_NDEF_T1T_Ndef.pMessage[RW_NDEF_T1T_Ndef.MessagePtr], &pRsp[1], 8);
RW_NDEF_T1T_Ndef.MessagePtr += 8;
RW_NDEF_T1T_Ndef.BlkNb++;
/* Read NDEF content */
memcpy (pCmd, T1T_READ8, sizeof(T1T_READ8));
pCmd[1] = RW_NDEF_T1T_Ndef.BlkNb;
memcpy (&pCmd[10], RW_NDEF_T1T_Ndef.UID, sizeof(RW_NDEF_T1T_Ndef.UID));
*pCmd_size = sizeof(T1T_READ8) + sizeof(RW_NDEF_T1T_Ndef.UID);
}
}
break;
default:
break;
}
}
#endif
#endif
/*
* Copyright (c), NXP Semiconductors Caen / France
*
* (C)NXP Semiconductors
* All rights are reserved. Reproduction in whole or in part is
* prohibited without the written consent of the copyright owner.
* NXP reserves the right to make changes without notice at any time.
* NXP makes no warranty, expressed, implied or statutory, including but
* not limited to any implied warranty of merchantability or fitness for any
*particular purpose, or that the use will not infringe any third party patent,
* copyright or trademark. NXP must not be liable for any loss or damage
* arising from its use.
*/
#ifdef RW_SUPPORT
#ifndef NO_NDEF_SUPPORT
#include <TML/inc/tool.h>
#include <NfcLibrary/NdefLibrary/inc/RW_NDEF.h>
/* TODO: No support for tag larger than 1024 bytes (requiring SECTOR_SELECT command use) */
#define T2T_MAGIC_NUMBER 0xE1
#define T2T_NDEF_TLV 0x03
typedef enum
{
Initial,
Reading_CC,
Reading_Data,
Reading_NDEF,
Writing_Data
} RW_NDEF_T2T_state_t;
typedef struct
{
unsigned char BlkNb;
unsigned short MessagePtr;
unsigned short MessageSize;
unsigned char *pMessage;
} RW_NDEF_T2T_Ndef_t;
static RW_NDEF_T2T_state_t eRW_NDEF_T2T_State = Initial;
static RW_NDEF_T2T_Ndef_t RW_NDEF_T2T_Ndef;
void RW_NDEF_T2T_Reset(void)
{
eRW_NDEF_T2T_State = Initial;
RW_NDEF_T2T_Ndef.pMessage = NdefBuffer;
}
void RW_NDEF_T2T_Read_Next(unsigned char *pRsp, unsigned short Rsp_size, unsigned char *pCmd, unsigned short *pCmd_size)
{
/* By default no further command to be sent */
*pCmd_size = 0;
switch(eRW_NDEF_T2T_State)
{
case Initial:
/* Read CC */
pCmd[0] = 0x30;
pCmd[1] = 0x03;
*pCmd_size = 2;
eRW_NDEF_T2T_State = Reading_CC;
break;
case Reading_CC:
/* Is CC Read and Is Ndef ?*/
if ((Rsp_size == 17) && (pRsp[Rsp_size-1] == 0x00) && (pRsp[0] == T2T_MAGIC_NUMBER))
{
/* Read First data */
pCmd[0] = 0x30;
pCmd[1] = 0x04;
*pCmd_size = 2;
eRW_NDEF_T2T_State = Reading_Data;
}
break;
case Reading_Data:
/* Is Read success ?*/
if ((Rsp_size == 17) && (pRsp[Rsp_size-1] == 0x00))
{
unsigned char Tmp = 0;
/* If not NDEF Type skip TLV */
while (pRsp[Tmp] != T2T_NDEF_TLV)
{
Tmp += 2 + pRsp[Tmp+1];
if (Tmp > Rsp_size) return;
}
if(pRsp[Tmp+1] == 0xFF)
{
RW_NDEF_T2T_Ndef.MessageSize = (pRsp[Tmp+2] << 8) + pRsp[Tmp+3];
Tmp += 2;
}
else RW_NDEF_T2T_Ndef.MessageSize = pRsp[Tmp+1];
/* If provisioned buffer is not large enough, notify the application and stop reading */
if (RW_NDEF_T2T_Ndef.MessageSize > RW_MAX_NDEF_FILE_SIZE)
{
if(pRW_NDEF_PullCb != NULL) pRW_NDEF_PullCb(NULL, 0);
break;
}
/* Is NDEF read already completed ? */
if (RW_NDEF_T2T_Ndef.MessageSize <= ((Rsp_size-1) - Tmp - 2))
{
memcpy (RW_NDEF_T2T_Ndef.pMessage, &pRsp[Tmp+2], RW_NDEF_T2T_Ndef.MessageSize);
/* Notify application of the NDEF reception */
if(pRW_NDEF_PullCb != NULL) pRW_NDEF_PullCb(RW_NDEF_T2T_Ndef.pMessage, RW_NDEF_T2T_Ndef.MessageSize);
}
else
{
RW_NDEF_T2T_Ndef.MessagePtr = (Rsp_size-1) - Tmp - 2;
memcpy (RW_NDEF_T2T_Ndef.pMessage, &pRsp[Tmp+2], RW_NDEF_T2T_Ndef.MessagePtr);
RW_NDEF_T2T_Ndef.BlkNb = 8;
/* Read NDEF content */
pCmd[0] = 0x30;
pCmd[1] = RW_NDEF_T2T_Ndef.BlkNb;
*pCmd_size = 2;
eRW_NDEF_T2T_State = Reading_NDEF;
}
}
break;
case Reading_NDEF:
/* Is Read success ?*/
if ((Rsp_size == 17) && (pRsp[Rsp_size-1] == 0x00))
{
/* Is NDEF read already completed ? */
if ((RW_NDEF_T2T_Ndef.MessageSize - RW_NDEF_T2T_Ndef.MessagePtr) < 16)
{
memcpy (&RW_NDEF_T2T_Ndef.pMessage[RW_NDEF_T2T_Ndef.MessagePtr], pRsp, RW_NDEF_T2T_Ndef.MessageSize - RW_NDEF_T2T_Ndef.MessagePtr);
/* Notify application of the NDEF reception */
if(pRW_NDEF_PullCb != NULL) pRW_NDEF_PullCb(RW_NDEF_T2T_Ndef.pMessage, RW_NDEF_T2T_Ndef.MessageSize);
}
else
{
memcpy (&RW_NDEF_T2T_Ndef.pMessage[RW_NDEF_T2T_Ndef.MessagePtr], pRsp, 16);
RW_NDEF_T2T_Ndef.MessagePtr += 16;
RW_NDEF_T2T_Ndef.BlkNb += 4;
/* Read NDEF content */
pCmd[0] = 0x30;
pCmd[1] = RW_NDEF_T2T_Ndef.BlkNb;
*pCmd_size = 2;
}
}
break;
default:
break;
}
}
void RW_NDEF_T2T_Write_Next(unsigned char *pRsp, unsigned short Rsp_size, unsigned char *pCmd, unsigned short *pCmd_size)
{
/* By default no further command to be sent */
*pCmd_size = 0;
switch(eRW_NDEF_T2T_State)
{
case Initial:
/* Read CC */
pCmd[0] = 0x30;
pCmd[1] = 0x03;
*pCmd_size = 2;
eRW_NDEF_T2T_State = Reading_CC;
break;
case Reading_CC:
/* Is CC Read, Is Ndef and is R/W ?*/
if ((Rsp_size == 17) && (pRsp[Rsp_size-1] == 0x00) && (pRsp[0] == T2T_MAGIC_NUMBER) && (pRsp[3] == 0x00))
{
/* Is size enough ? */
if (pRsp[2]*8 >= RW_NdefMessage_size)
{
/* Write First data */
pCmd[0] = 0xA2;
pCmd[1] = 0x04;
pCmd[2] = 0x03;
if (RW_NdefMessage_size > 0xFF)
{
pCmd[3] = 0xFF;
pCmd[4] = (RW_NdefMessage_size & 0xFF00) >> 8;
pCmd[5] = RW_NdefMessage_size & 0xFF;
RW_NDEF_T2T_Ndef.MessagePtr = 0;
}
else
{
pCmd[3] = (unsigned char) RW_NdefMessage_size;
memcpy(&pCmd[4], pRW_NdefMessage, 2);
RW_NDEF_T2T_Ndef.MessagePtr = 2;
}
RW_NDEF_T2T_Ndef.BlkNb = 5;
*pCmd_size = 6;
eRW_NDEF_T2T_State = Writing_Data;
}
}
break;
case Writing_Data:
/* Is Write success ?*/
if ((Rsp_size == 2) && (pRsp[Rsp_size-1] == 0x00))
{
/* Is NDEF write already completed ? */
if (RW_NdefMessage_size <= RW_NDEF_T2T_Ndef.MessagePtr)
{
/* Notify application of the NDEF reception */
if(pRW_NDEF_PushCb != NULL) pRW_NDEF_PushCb(pRW_NdefMessage, RW_NdefMessage_size);
}
else
{
/* Write NDEF content */
pCmd[0] = 0xA2;
pCmd[1] = RW_NDEF_T2T_Ndef.BlkNb;
memcpy(&pCmd[2], pRW_NdefMessage+RW_NDEF_T2T_Ndef.MessagePtr, 4);
*pCmd_size = 6;
RW_NDEF_T2T_Ndef.MessagePtr+=4;
RW_NDEF_T2T_Ndef.BlkNb++;
}
}
break;
default:
break;
}
}
#endif
#endif
/*
* Copyright (c), NXP Semiconductors Caen / France
*
* (C)NXP Semiconductors
* All rights are reserved. Reproduction in whole or in part is
* prohibited without the written consent of the copyright owner.
* NXP reserves the right to make changes without notice at any time.
* NXP makes no warranty, expressed, implied or statutory, including but
* not limited to any implied warranty of merchantability or fitness for any
*particular purpose, or that the use will not infringe any third party patent,
* copyright or trademark. NXP must not be liable for any loss or damage
* arising from its use.
*/
#ifdef RW_SUPPORT
#ifndef NO_NDEF_SUPPORT
#include <TML/inc/tool.h>
#include <NfcLibrary/NdefLibrary/inc/RW_NDEF.h>
#define T3T_MAGIC_NUMBER 0xE1
#define T3T_NDEF_TLV 0x03
unsigned char T3T_Check[] = {0x10,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x0B,0x00,0x1,0x80,0x00};
typedef enum
{
Initial,
Getting_AttributeInfo,
Reading_CardContent
} RW_NDEF_T3T_state_t;
typedef struct
{
unsigned char IDm[8];
unsigned char BlkNb;
unsigned short Ptr;
unsigned short Size;
unsigned char *p;
} RW_NDEF_T3T_Ndef_t;
static RW_NDEF_T3T_state_t eRW_NDEF_T3T_State = Initial;
static RW_NDEF_T3T_Ndef_t RW_NDEF_T3T_Ndef;
void RW_NDEF_T3T_Reset(void)
{
eRW_NDEF_T3T_State = Initial;
RW_NDEF_T3T_Ndef.p = NdefBuffer;
}
void RW_NDEF_T3T_SetIDm(unsigned char *pIDm)
{
memcpy(RW_NDEF_T3T_Ndef.IDm, pIDm, sizeof(RW_NDEF_T3T_Ndef.IDm));
memcpy(&T3T_Check[2], pIDm, sizeof(RW_NDEF_T3T_Ndef.IDm));
}
void RW_NDEF_T3T_Read_Next(unsigned char *pRsp, unsigned short Rsp_size, unsigned char *pCmd, unsigned short *pCmd_size)
{
/* By default no further command to be sent */
*pCmd_size = 0;
switch(eRW_NDEF_T3T_State)
{
case Initial:
/* Get AttributeInfo */
memcpy (pCmd, T3T_Check, sizeof(T3T_Check));
*pCmd_size = sizeof(T3T_Check);
eRW_NDEF_T3T_State = Getting_AttributeInfo;
break;
case Getting_AttributeInfo:
/* Is Check success ?*/
if ((pRsp[Rsp_size-1] == 0x00) && (pRsp[1] == 0x07) && (pRsp[10] == 0x00) && (pRsp[11] == 0x00))
{
/* Fill File structure */
RW_NDEF_T3T_Ndef.Size = (pRsp[24] << 16) + (pRsp[25] << 16) + pRsp[26];
/* If provisioned buffer is not large enough, notify the application and stop reading */
if (RW_NDEF_T3T_Ndef.Size > RW_MAX_NDEF_FILE_SIZE)
{
if(pRW_NDEF_PullCb != NULL) pRW_NDEF_PullCb(NULL, 0);
break;
}
RW_NDEF_T3T_Ndef.Ptr = 0;
RW_NDEF_T3T_Ndef.BlkNb = 1;
/* Read first NDEF block */
memcpy (pCmd, T3T_Check, sizeof(T3T_Check));
pCmd[15] = 0x01;
*pCmd_size = sizeof(T3T_Check);
eRW_NDEF_T3T_State = Reading_CardContent;
}
break;
case Reading_CardContent:
/* Is Check success ?*/
if ((pRsp[Rsp_size-1] == 0x00) && (pRsp[1] == 0x07) && (pRsp[10] == 0x00) && (pRsp[11] == 0x00))
{
/* Is NDEF message read completed ?*/
if ((RW_NDEF_T3T_Ndef.Size - RW_NDEF_T3T_Ndef.Ptr) <= 16)
{
memcpy(&RW_NDEF_T3T_Ndef.p[RW_NDEF_T3T_Ndef.Ptr], &pRsp[13], (RW_NDEF_T3T_Ndef.Size - RW_NDEF_T3T_Ndef.Ptr));
/* Notify application of the NDEF reception */
if(pRW_NDEF_PullCb != NULL) pRW_NDEF_PullCb(RW_NDEF_T3T_Ndef.p, RW_NDEF_T3T_Ndef.Size);
}
else
{
memcpy(&RW_NDEF_T3T_Ndef.p[RW_NDEF_T3T_Ndef.Ptr], &pRsp[13], 16);
RW_NDEF_T3T_Ndef.Ptr += 16;
RW_NDEF_T3T_Ndef.BlkNb++;
/* Read next NDEF block */
memcpy (pCmd, T3T_Check, sizeof(T3T_Check));
pCmd[15] = RW_NDEF_T3T_Ndef.BlkNb;
*pCmd_size = sizeof(T3T_Check);
}
}
break;
default:
break;
}
}
#endif
#endif
/*
* Copyright (c), NXP Semiconductors Caen / France
*
* (C)NXP Semiconductors
* All rights are reserved. Reproduction in whole or in part is
* prohibited without the written consent of the copyright owner.
* NXP reserves the right to make changes without notice at any time.
* NXP makes no warranty, expressed, implied or statutory, including but
* not limited to any implied warranty of merchantability or fitness for any
*particular purpose, or that the use will not infringe any third party patent,
* copyright or trademark. NXP must not be liable for any loss or damage
* arising from its use.
*/
#ifdef RW_SUPPORT
#ifndef NO_NDEF_SUPPORT
#include <TML/inc/tool.h>
#include <NfcLibrary/NdefLibrary/inc/RW_NDEF.h>
const unsigned char RW_NDEF_T4T_APP_Select20[] = {0x00,0xA4,0x04,0x00,0x07,0xD2,0x76,0x00,0x00,0x85,0x01,0x01,0x00};
const unsigned char RW_NDEF_T4T_APP_Select10[] = {0x00,0xA4,0x04,0x00,0x07,0xD2,0x76,0x00,0x00,0x85,0x01,0x00};
const unsigned char RW_NDEF_T4T_CC_Select[] = {0x00,0xA4,0x00,0x0C,0x02,0xE1,0x03};
const unsigned char RW_NDEF_T4T_NDEF_Select[] = {0x00,0xA4,0x00,0x0C,0x02,0xE1,0x04};
const unsigned char RW_NDEF_T4T_Read[] = {0x00,0xB0,0x00,0x00,0x0F};
const unsigned char RW_NDEF_T4T_Write[] = {0x00,0xD6,0x00,0x00,0x00};
const unsigned char RW_NDEF_T4T_OK[] = {0x90, 0x00};
#define WRITE_SZ 54
typedef enum
{
Initial,
Selecting_NDEF_Application20,
Selecting_NDEF_Application10,
Selecting_CC,
Reading_CC,
Selecting_NDEF,
Reading_NDEF_Size,
Reading_NDEF,
Writing_NDEF,
Writing_NDEFsize,
Write_NDEFcomplete
} RW_NDEF_T4T_state_t;
typedef struct
{
unsigned char MappingVersion;
unsigned short MLe;
unsigned short MLc;
unsigned char FileID[2];
unsigned short MaxNdefFileSize;
unsigned char RdAccess;
unsigned char WrAccess;
unsigned short MessagePtr;
unsigned short MessageSize;
unsigned char *pMessage;
} RW_NDEF_T4T_Ndef_t;
static RW_NDEF_T4T_state_t eRW_NDEF_T4T_State = Initial;
static RW_NDEF_T4T_Ndef_t RW_NDEF_T4T_Ndef;
void RW_NDEF_T4T_Reset(void)
{
eRW_NDEF_T4T_State = Initial;
RW_NDEF_T4T_Ndef.pMessage = NdefBuffer;
}
void RW_NDEF_T4T_Read_Next(unsigned char *pRsp, unsigned short Rsp_size, unsigned char *pCmd, unsigned short *pCmd_size)
{
/* By default no further command to be sent */
*pCmd_size = 0;
switch(eRW_NDEF_T4T_State)
{
case Initial:
/* Select NDEF Application in version 2.0 */
memcpy(pCmd, RW_NDEF_T4T_APP_Select20, sizeof(RW_NDEF_T4T_APP_Select20));
*pCmd_size = sizeof(RW_NDEF_T4T_APP_Select20);
eRW_NDEF_T4T_State = Selecting_NDEF_Application20;
break;
case Selecting_NDEF_Application20:
/* Is NDEF Application Selected ?*/
if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK)))
{
/* Select CC */
memcpy(pCmd, RW_NDEF_T4T_CC_Select, sizeof(RW_NDEF_T4T_CC_Select));
*pCmd_size = sizeof(RW_NDEF_T4T_CC_Select);
eRW_NDEF_T4T_State = Selecting_CC;
}
else
{
/* Select NDEF Application in version 1.0 */
memcpy(pCmd, RW_NDEF_T4T_APP_Select10, sizeof(RW_NDEF_T4T_APP_Select10));
*pCmd_size = sizeof(RW_NDEF_T4T_APP_Select10);
eRW_NDEF_T4T_State = Selecting_NDEF_Application10;
}
break;
case Selecting_NDEF_Application10:
/* Is NDEF Application Selected ?*/
if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK)))
{
/* Select CC */
memcpy(pCmd, RW_NDEF_T4T_CC_Select, sizeof(RW_NDEF_T4T_CC_Select));
pCmd[3] = 0x00;
*pCmd_size = sizeof(RW_NDEF_T4T_CC_Select);
eRW_NDEF_T4T_State = Selecting_CC;
}
break;
case Selecting_CC:
/* Is CC Selected ?*/
if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK)))
{
/* Read CC */
memcpy(pCmd, RW_NDEF_T4T_Read, sizeof(RW_NDEF_T4T_Read));
*pCmd_size = sizeof(RW_NDEF_T4T_Read);
eRW_NDEF_T4T_State = Reading_CC;
}
break;
case Reading_CC:
/* Is CC Read ?*/
if ((!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) && (Rsp_size == 15 + 2))
{
/* Fill CC structure */
RW_NDEF_T4T_Ndef.MappingVersion = pRsp[2];
RW_NDEF_T4T_Ndef.MLe = (pRsp[3] << 8) + pRsp[4];
RW_NDEF_T4T_Ndef.MLc = (pRsp[5] << 8) + pRsp[6];
RW_NDEF_T4T_Ndef.FileID[0] = pRsp[9];
RW_NDEF_T4T_Ndef.FileID[1] = pRsp[10];
RW_NDEF_T4T_Ndef.MaxNdefFileSize = (pRsp[11] << 8) + pRsp[12];
RW_NDEF_T4T_Ndef.RdAccess = pRsp[13];
RW_NDEF_T4T_Ndef.WrAccess = pRsp[14];
/* Select NDEF */
memcpy(pCmd, RW_NDEF_T4T_NDEF_Select, sizeof(RW_NDEF_T4T_NDEF_Select));
if (RW_NDEF_T4T_Ndef.MappingVersion == 0x10) pCmd[3] = 0x00;
pCmd[5] = RW_NDEF_T4T_Ndef.FileID[0];
pCmd[6] = RW_NDEF_T4T_Ndef.FileID[1];
*pCmd_size = sizeof(RW_NDEF_T4T_NDEF_Select);
eRW_NDEF_T4T_State = Selecting_NDEF;
}
break;
case Selecting_NDEF:
/* Is NDEF Selected ?*/
if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK)))
{
/* Get NDEF file size */
memcpy(pCmd, RW_NDEF_T4T_Read, sizeof(RW_NDEF_T4T_Read));
*pCmd_size = sizeof(RW_NDEF_T4T_Read);
pCmd[4] = 2;
eRW_NDEF_T4T_State = Reading_NDEF_Size;
}
break;
case Reading_NDEF_Size:
/* Is Read Success ?*/
if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK)))
{
RW_NDEF_T4T_Ndef.MessageSize = (pRsp[0] << 8) + pRsp[1];
/* If provisioned buffer is not large enough, notify the application and stop reading */
if (RW_NDEF_T4T_Ndef.MessageSize > RW_MAX_NDEF_FILE_SIZE)
{
if(pRW_NDEF_PullCb != NULL) pRW_NDEF_PullCb(NULL, 0);
break;
}
RW_NDEF_T4T_Ndef.MessagePtr = 0;
/* Read NDEF data */
memcpy(pCmd, RW_NDEF_T4T_Read, sizeof(RW_NDEF_T4T_Read));
pCmd[3] = 2;
pCmd[4] = (RW_NDEF_T4T_Ndef.MessageSize > RW_NDEF_T4T_Ndef.MLe-1) ? RW_NDEF_T4T_Ndef.MLe-1 : (unsigned char) RW_NDEF_T4T_Ndef.MessageSize;
*pCmd_size = sizeof(RW_NDEF_T4T_Read);
eRW_NDEF_T4T_State = Reading_NDEF;
}
break;
case Reading_NDEF:
/* Is Read Success ?*/
//if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK)))
{
memcpy(&RW_NDEF_T4T_Ndef.pMessage[RW_NDEF_T4T_Ndef.MessagePtr], pRsp, Rsp_size - 2);
RW_NDEF_T4T_Ndef.MessagePtr += Rsp_size - 2;
/* Is NDEF message read completed ?*/
if (RW_NDEF_T4T_Ndef.MessagePtr == RW_NDEF_T4T_Ndef.MessageSize)
{
/* Notify application of the NDEF reception */
if(pRW_NDEF_PullCb != NULL) pRW_NDEF_PullCb(RW_NDEF_T4T_Ndef.pMessage, RW_NDEF_T4T_Ndef.MessageSize);
}
else
{
/* Read NDEF data */
memcpy(pCmd, RW_NDEF_T4T_Read, sizeof(RW_NDEF_T4T_Read));
pCmd[3] = RW_NDEF_T4T_Ndef.MessagePtr + 2;
pCmd[4] = ((RW_NDEF_T4T_Ndef.MessageSize - RW_NDEF_T4T_Ndef.MessagePtr) > RW_NDEF_T4T_Ndef.MLe-1) ? RW_NDEF_T4T_Ndef.MLe-1 : (unsigned char) (RW_NDEF_T4T_Ndef.MessageSize - RW_NDEF_T4T_Ndef.MessagePtr);
*pCmd_size = sizeof(RW_NDEF_T4T_Read);
}
}
break;
default:
break;
}
}
void RW_NDEF_T4T_Write_Next(unsigned char *pRsp, unsigned short Rsp_size, unsigned char *pCmd, unsigned short *pCmd_size)
{
/* By default no further command to be sent */
*pCmd_size = 0;
switch(eRW_NDEF_T4T_State)
{
case Initial:
/* Select NDEF Application in version 2.0 */
memcpy(pCmd, RW_NDEF_T4T_APP_Select20, sizeof(RW_NDEF_T4T_APP_Select20));
*pCmd_size = sizeof(RW_NDEF_T4T_APP_Select20);
eRW_NDEF_T4T_State = Selecting_NDEF_Application20;
break;
case Selecting_NDEF_Application20:
/* Is NDEF Application Selected ?*/
if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK)))
{
/* Select CC */
memcpy(pCmd, RW_NDEF_T4T_CC_Select, sizeof(RW_NDEF_T4T_CC_Select));
*pCmd_size = sizeof(RW_NDEF_T4T_CC_Select);
eRW_NDEF_T4T_State = Selecting_CC;
}
else
{
/* Select NDEF Application in version 1.0 */
memcpy(pCmd, RW_NDEF_T4T_APP_Select10, sizeof(RW_NDEF_T4T_APP_Select10));
*pCmd_size = sizeof(RW_NDEF_T4T_APP_Select10);
eRW_NDEF_T4T_State = Selecting_NDEF_Application10;
}
break;
case Selecting_NDEF_Application10:
/* Is NDEF Application Selected ?*/
if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK)))
{
/* Select CC */
memcpy(pCmd, RW_NDEF_T4T_CC_Select, sizeof(RW_NDEF_T4T_CC_Select));
pCmd[3] = 0x00;
*pCmd_size = sizeof(RW_NDEF_T4T_CC_Select);
eRW_NDEF_T4T_State = Selecting_CC;
}
break;
case Selecting_CC:
/* Is CC Selected ?*/
if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK)))
{
/* Read CC */
memcpy(pCmd, RW_NDEF_T4T_Read, sizeof(RW_NDEF_T4T_Read));
*pCmd_size = sizeof(RW_NDEF_T4T_Read);
eRW_NDEF_T4T_State = Reading_CC;
}
break;
case Reading_CC:
/* Is CC Read ?*/
if ((!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK))) && (Rsp_size == 15 + 2))
{
/* Fill CC structure */
RW_NDEF_T4T_Ndef.MappingVersion = pRsp[2];
RW_NDEF_T4T_Ndef.MLe = (pRsp[3] << 8) + pRsp[4];
RW_NDEF_T4T_Ndef.MLc = (pRsp[5] << 8) + pRsp[6];
RW_NDEF_T4T_Ndef.FileID[0] = pRsp[9];
RW_NDEF_T4T_Ndef.FileID[1] = pRsp[10];
RW_NDEF_T4T_Ndef.MaxNdefFileSize = (pRsp[11] << 8) + pRsp[12];
RW_NDEF_T4T_Ndef.RdAccess = pRsp[13];
RW_NDEF_T4T_Ndef.WrAccess = pRsp[14];
/* Select NDEF */
memcpy(pCmd, RW_NDEF_T4T_NDEF_Select, sizeof(RW_NDEF_T4T_NDEF_Select));
if (RW_NDEF_T4T_Ndef.MappingVersion == 0x10) pCmd[3] = 0x00;
pCmd[5] = RW_NDEF_T4T_Ndef.FileID[0];
pCmd[6] = RW_NDEF_T4T_Ndef.FileID[1];
*pCmd_size = sizeof(RW_NDEF_T4T_NDEF_Select);
eRW_NDEF_T4T_State = Selecting_NDEF;
}
break;
case Selecting_NDEF:
/* Is NDEF Selected ?*/
if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK)))
{
/* Clearing NDEF message size*/
memcpy(pCmd, RW_NDEF_T4T_Write, sizeof(RW_NDEF_T4T_Write));
pCmd[4] = 2;
pCmd[5] = 0;
pCmd[6] = 0;
*pCmd_size = sizeof(RW_NDEF_T4T_Write) + 2;
RW_NDEF_T4T_Ndef.MessagePtr = 0;
eRW_NDEF_T4T_State = Writing_NDEF;
}
break;
case Writing_NDEF:
/* Is Write Success ?*/
if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK)))
{
/* Writing NDEF message */
memcpy(pCmd, RW_NDEF_T4T_Write, sizeof(RW_NDEF_T4T_Write));
pCmd[2] = (RW_NDEF_T4T_Ndef.MessagePtr + 2) >> 8;
pCmd[3] = (RW_NDEF_T4T_Ndef.MessagePtr + 2) & 0xFF;
if((RW_NdefMessage_size - RW_NDEF_T4T_Ndef.MessagePtr) < WRITE_SZ)
{
pCmd[4] = (RW_NdefMessage_size - RW_NDEF_T4T_Ndef.MessagePtr);
memcpy(&pCmd[5], pRW_NdefMessage + RW_NDEF_T4T_Ndef.MessagePtr, (RW_NdefMessage_size - RW_NDEF_T4T_Ndef.MessagePtr));
*pCmd_size = sizeof(RW_NDEF_T4T_Write) + (RW_NdefMessage_size - RW_NDEF_T4T_Ndef.MessagePtr);
eRW_NDEF_T4T_State = Writing_NDEFsize;
}
else
{
pCmd[4] = WRITE_SZ;
memcpy(&pCmd[5], pRW_NdefMessage + RW_NDEF_T4T_Ndef.MessagePtr, WRITE_SZ);
*pCmd_size = sizeof(RW_NDEF_T4T_Write) + WRITE_SZ;
RW_NDEF_T4T_Ndef.MessagePtr += WRITE_SZ;
eRW_NDEF_T4T_State = Writing_NDEF;
}
}
break;
case Writing_NDEFsize:
/* Is Write Success ?*/
if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK)))
{
memcpy(pCmd, RW_NDEF_T4T_Write, sizeof(RW_NDEF_T4T_Write));
pCmd[4] = 2;
pCmd[5] = RW_NdefMessage_size >> 8;
pCmd[6] = RW_NdefMessage_size & 0xFF;
*pCmd_size = sizeof(RW_NDEF_T4T_Write) + 2;
eRW_NDEF_T4T_State = Write_NDEFcomplete;
}
break;
case Write_NDEFcomplete:
/* Is Write Success ?*/
if (!memcmp(&pRsp[Rsp_size - 2], RW_NDEF_T4T_OK, sizeof(RW_NDEF_T4T_OK)))
{
/* Notify application of the NDEF reception */
if(pRW_NDEF_PushCb != NULL) pRW_NDEF_PushCb(pRW_NdefMessage, RW_NdefMessage_size);
}
break;
default:
break;
}
}
#endif
#endif
/*
* Copyright (c), NXP Semiconductors Caen / France
*
* (C)NXP Semiconductors
* All rights are reserved. Reproduction in whole or in part is
* prohibited without the written consent of the copyright owner.
* NXP reserves the right to make changes without notice at any time.
* NXP makes no warranty, expressed, implied or statutory, including but
* not limited to any implied warranty of merchantability or fitness for any
*particular purpose, or that the use will not infringe any third party patent,
* copyright or trademark. NXP must not be liable for any loss or damage
* arising from its use.
*/
#ifdef CARDEMU_SUPPORT
#ifndef NO_NDEF_SUPPORT
#include <TML/inc/tool.h>
#include <NfcLibrary/NdefLibrary/inc/T4T_NDEF_emu.h>
const unsigned char T4T_NDEF_EMU_APP_Select[] = {0x00,0xA4,0x04,0x00,0x07,0xD2,0x76,0x00,0x00,0x85,0x01,0x01};
const unsigned char T4T_NDEF_EMU_CC[] = {0x00, 0x0F, 0x20, 0x00, 0xFF, 0x00, 0xFF, 0x04, 0x06, 0xE1, 0x04, 0x00, 0xFF, 0x00, 0xFF};
const unsigned char T4T_NDEF_EMU_CC_Select[] = {0x00,0xA4,0x00,0x0C,0x02,0xE1,0x03};
const unsigned char T4T_NDEF_EMU_NDEF_Select[] = {0x00,0xA4,0x00,0x0C,0x02,0xE1,0x04};
const unsigned char T4T_NDEF_EMU_Read[] = {0x00,0xB0};
const unsigned char T4T_NDEF_EMU_OK[] = {0x90, 0x00};
const unsigned char T4T_NDEF_EMU_NOK[] = {0x6A, 0x82};
unsigned char *pT4T_NdefMessage;
unsigned short T4T_NdefMessage_size = 0;
typedef enum
{
Ready,
NDEF_Application_Selected,
CC_Selected,
NDEF_Selected,
} T4T_NDEF_EMU_state_t;
typedef void T4T_NDEF_EMU_Callback_t (unsigned char*, unsigned short);
static T4T_NDEF_EMU_state_t eT4T_NDEF_EMU_State = Ready;
static T4T_NDEF_EMU_Callback_t *pT4T_NDEF_EMU_PushCb = NULL;
static void T4T_NDEF_EMU_FillRsp (unsigned char *pRsp, unsigned short offset, unsigned char length)
{
if (offset == 0)
{
pRsp[0] = (T4T_NdefMessage_size & 0xFF00) >> 8;
pRsp[1] = (T4T_NdefMessage_size & 0x00FF);
memcpy(&pRsp[2], &pT4T_NdefMessage[0], length-2);
}
else if (offset == 1)
{
pRsp[0] = (T4T_NdefMessage_size & 0x00FF);
memcpy(&pRsp[1], &pT4T_NdefMessage[0], length-1);
}
else
{
memcpy(pRsp, &pT4T_NdefMessage[offset-2], length);
}
/* Did we reached the end of NDEF message ?*/
if ((offset + length) >= (T4T_NdefMessage_size + 2))
{
/* Notify application of the NDEF send */
if(pT4T_NDEF_EMU_PushCb != NULL) pT4T_NDEF_EMU_PushCb(pT4T_NdefMessage, T4T_NdefMessage_size);
}
}
bool T4T_NDEF_EMU_SetMessage(unsigned char *pMessage, unsigned short Message_size, void *pCb)
{
pT4T_NdefMessage = pMessage;
T4T_NdefMessage_size = Message_size;
pT4T_NDEF_EMU_PushCb = (T4T_NDEF_EMU_Callback_t*) pCb;
return true;
}
void T4T_NDEF_EMU_Reset(void)
{
eT4T_NDEF_EMU_State = Ready;
}
void T4T_NDEF_EMU_Next(unsigned char *pCmd, unsigned short Cmd_size, unsigned char *pRsp, unsigned short *pRsp_size)
{
bool eStatus = false;
if (!memcmp(pCmd, T4T_NDEF_EMU_APP_Select, sizeof(T4T_NDEF_EMU_APP_Select)))
{
*pRsp_size = 0;
eStatus = true;
eT4T_NDEF_EMU_State = NDEF_Application_Selected;
}
else if (!memcmp(pCmd, T4T_NDEF_EMU_CC_Select, sizeof(T4T_NDEF_EMU_CC_Select)))
{
if(eT4T_NDEF_EMU_State == NDEF_Application_Selected)
{
*pRsp_size = 0;
eStatus = true;
eT4T_NDEF_EMU_State = CC_Selected;
}
}
else if (!memcmp(pCmd, T4T_NDEF_EMU_NDEF_Select, sizeof(T4T_NDEF_EMU_NDEF_Select)))
{
*pRsp_size = 0;
eStatus = true;
eT4T_NDEF_EMU_State = NDEF_Selected;
}
else if (!memcmp(pCmd, T4T_NDEF_EMU_Read, sizeof(T4T_NDEF_EMU_Read)))
{
if(eT4T_NDEF_EMU_State == CC_Selected)
{
memcpy(pRsp, T4T_NDEF_EMU_CC, sizeof(T4T_NDEF_EMU_CC));
*pRsp_size = sizeof(T4T_NDEF_EMU_CC);
eStatus = true;
}
else if (eT4T_NDEF_EMU_State == NDEF_Selected)
{
unsigned short offset = (pCmd[2] << 8) + pCmd[3];
unsigned char length = pCmd[4];
if(length <= (T4T_NdefMessage_size + offset + 2))
{
T4T_NDEF_EMU_FillRsp(pRsp, offset, length);
*pRsp_size = length;
eStatus = true;
}
}
}
if (eStatus == true)
{
memcpy(&pRsp[*pRsp_size], T4T_NDEF_EMU_OK, sizeof(T4T_NDEF_EMU_OK));
*pRsp_size += sizeof(T4T_NDEF_EMU_OK);
} else
{
memcpy(pRsp, T4T_NDEF_EMU_NOK, sizeof(T4T_NDEF_EMU_NOK));
*pRsp_size = sizeof(T4T_NDEF_EMU_NOK);
T4T_NDEF_EMU_Reset();
}
}
#endif
#endif
/*
* Copyright (c), NXP Semiconductors Caen / France
*
* (C)NXP Semiconductors
* All rights are reserved. Reproduction in whole or in part is
* prohibited without the written consent of the copyright owner.
* NXP reserves the right to make changes without notice at any time.
* NXP makes no warranty, expressed, implied or statutory, including but
* not limited to any implied warranty of merchantability or fitness for any
*particular purpose, or that the use will not infringe any third party patent,
* copyright or trademark. NXP must not be liable for any loss or damage
* arising from its use.
*/
#include <NfcLibrary/inc/Nfc.h>
#ifdef CARDEMU_SUPPORT
#include <NfcLibrary/NdefLibrary/inc/T4T_NDEF_emu.h>
#endif
#ifdef P2P_SUPPORT
#include <NfcLibrary/NdefLibrary/inc/P2P_NDEF.h>
#endif
#ifdef RW_SUPPORT
#include <NfcLibrary/NdefLibrary/inc/RW_NDEF.h>
#include <NfcLibrary/NdefLibrary/inc/RW_NDEF_T3T.h>
#endif
#define NXPNCI_SUCCESS NFC_SUCCESS
#define NXPNCI_ERROR NFC_ERROR
#ifdef NCI_DEBUG
#include <stdio.h>
#define NCI_PRINT(...) {printf(__VA_ARGS__);}
unsigned short debug_loop;
#define NCI_PRINT_LOOP(x,y) {for(debug_loop=0; debug_loop<y; debug_loop++) printf("%.2x ", x[debug_loop]);}
#define NCI_PRINT_BUF(x,y,z) {char tmp[200]; int loop; sprintf(tmp, x); \
for(loop=0;loop<(z<30?z:30);loop++) sprintf(tmp+7+(loop*3), "%.2x ", y[loop]); \
if(loop==30) sprintf(tmp+7+(loop*3), "...\n"); \
else sprintf(tmp+7+(loop*3), "\n"); \
printf(tmp);}
#else
#define NCI_PRINT(...)
#define NCI_PRINT_LOOP(x,y)
#define NCI_PRINT_BUF(x,y,z)
#endif
/*
* Copyright (c), NXP Semiconductors Caen / France
*
* (C)NXP Semiconductors
* All rights are reserved. Reproduction in whole or in part is
* prohibited without the written consent of the copyright owner.
* NXP reserves the right to make changes without notice at any time.
* NXP makes no warranty, expressed, implied or statutory, including but
* not limited to any implied warranty of merchantability or fitness for any
*particular purpose, or that the use will not infringe any third party patent,
* copyright or trademark. NXP must not be liable for any loss or damage
* arising from its use.
*/
#include <TML/inc/tool.h>
#include <TML/inc/tml.h>
#include <NfcLibrary/NxpNci/inc/NxpNci.h>
#include <NfcLibrary/inc/Nfc_settings.h>
#define MAX_NCI_FRAME_SIZE 256
#define MAX(x,y) (x > y ? x : y)
static uint8_t gNfcController_generation = 0;
static uint8_t gNextTag_Protocol = PROT_UNDETERMINED;
static bool NxpNci_CheckDevPres(void)
{
uint8_t NCICoreReset[] = {0x20, 0x00, 0x01, 0x01};
uint8_t Answer[6];
uint16_t NbBytes = 0;
tml_Send(NCICoreReset, sizeof(NCICoreReset), &NbBytes);
NCI_PRINT_BUF("NCI >> ", NCICoreReset, NbBytes);
if (NbBytes != sizeof(NCICoreReset)) return NXPNCI_ERROR;
tml_Receive(Answer, sizeof(Answer), &NbBytes, TIMEOUT_100MS);
if ((NbBytes == 0) || (Answer[0] != 0x40) || (Answer[1] != 0x00)) return NXPNCI_ERROR;
NCI_PRINT_BUF("NCI << ", Answer, NbBytes);
return NXPNCI_SUCCESS;
}
static bool NxpNci_WaitForReception(uint8_t *pRBuff, uint16_t RBuffSize, uint16_t *pBytesread, uint16_t timeout)
{
tml_Receive(pRBuff, RBuffSize, pBytesread, timeout);
if (*pBytesread == 0) return NXPNCI_ERROR;
NCI_PRINT_BUF("NCI << ", pRBuff, *pBytesread);
return NXPNCI_SUCCESS;
}
static bool NxpNci_HostTransceive(uint8_t *pTBuff, uint16_t TbuffLen, uint8_t *pRBuff, uint16_t RBuffSize, uint16_t *pBytesread)
{
tml_Send(pTBuff, TbuffLen, pBytesread);
NCI_PRINT_BUF("NCI >> ", pTBuff, TbuffLen);
if (*pBytesread != TbuffLen) return NXPNCI_ERROR;
tml_Receive(pRBuff, RBuffSize, pBytesread, TIMEOUT_1S);
if (*pBytesread == 0) return NXPNCI_ERROR;
NCI_PRINT_BUF("NCI << ", pRBuff, *pBytesread);
return NXPNCI_SUCCESS;
}
static void NxpNci_FillInterfaceInfo(NxpNci_RfIntf_t* pRfIntf, uint8_t* pBuf)
{
uint8_t i;
switch(pRfIntf->ModeTech)
{
case (MODE_POLL | TECH_PASSIVE_NFCA):
memcpy(pRfIntf->Info.NFC_APP.SensRes, &pBuf[0], 2);
pRfIntf->Info.NFC_APP.NfcIdLen = pBuf[2];
memcpy(pRfIntf->Info.NFC_APP.NfcId, &pBuf[3], pRfIntf->Info.NFC_APP.NfcIdLen);
pRfIntf->Info.NFC_APP.SelResLen = pBuf[3+pBuf[2]];
if(pRfIntf->Info.NFC_APP.SelResLen == 1) pRfIntf->Info.NFC_APP.SelRes[0] = pBuf[3+pBuf[2]+1];
break;
case (MODE_POLL | TECH_PASSIVE_NFCB):
pRfIntf->Info.NFC_BPP.SensResLen = pBuf[0];
memcpy(pRfIntf->Info.NFC_BPP.SensRes, &pBuf[1], pRfIntf->Info.NFC_BPP.SensResLen);
break;
case (MODE_POLL | TECH_PASSIVE_NFCF):
pRfIntf->Info.NFC_FPP.BitRate = pBuf[0];
pRfIntf->Info.NFC_FPP.SensResLen = pBuf[1];
memcpy(pRfIntf->Info.NFC_FPP.SensRes, &pBuf[2], pRfIntf->Info.NFC_FPP.SensResLen);
break;
case (MODE_POLL | TECH_PASSIVE_15693):
pRfIntf->Info.NFC_VPP.AFI = pBuf[0];
pRfIntf->Info.NFC_VPP.DSFID = pBuf[1];
for(i=0; i<8; i++) pRfIntf->Info.NFC_VPP.ID[7-i] = pBuf[2+i];
break;
default:
break;
}
}
#ifdef CARDEMU_SUPPORT
void NxpNci_ProcessCardMode(NxpNci_RfIntf_t RfIntf)
{
uint8_t Answer[MAX_NCI_FRAME_SIZE];
uint16_t AnswerSize;
/* Reset Card emulation state */
T4T_NDEF_EMU_Reset();
while(NxpNci_WaitForReception(Answer, sizeof(Answer), &AnswerSize, TIMEOUT_2S) == NXPNCI_SUCCESS)
{
/* is RF_DEACTIVATE_NTF ? */
if((Answer[0] == 0x61) && (Answer[1] == 0x06))
{
/* Come back to discovery state */
break;
}
/* is DATA_PACKET ? */
else if((Answer[0] == 0x00) && (Answer[1] == 0x00))
{
/* DATA_PACKET */
uint8_t Cmd[MAX_NCI_FRAME_SIZE];
uint16_t CmdSize;
T4T_NDEF_EMU_Next(&Answer[3], Answer[2], &Cmd[3], (unsigned short *) &CmdSize);
Cmd[0] = 0x00;
Cmd[1] = (CmdSize & 0xFF00) >> 8;
Cmd[2] = CmdSize & 0x00FF;
NxpNci_HostTransceive(Cmd, CmdSize+3, Answer, sizeof(Answer), &AnswerSize);
}
}
}
bool NxpNci_CardModeReceive (unsigned char *pData, unsigned char *pDataSize)
{
bool status = NXPNCI_ERROR;
uint8_t Ans[MAX_NCI_FRAME_SIZE];
uint16_t AnsSize;
NxpNci_WaitForReception(Ans, sizeof(Ans), &AnsSize, TIMEOUT_2S);
/* Is data packet ? */
if ((Ans[0] == 0x00) && (Ans[1] == 0x00))
{
*pDataSize = Ans[2];
memcpy(pData, &Ans[3], *pDataSize);
status = NXPNCI_SUCCESS;
}
return status;
}
bool NxpNci_CardModeSend (unsigned char *pData, unsigned char DataSize)
{
bool status;
uint8_t Cmd[MAX_NCI_FRAME_SIZE];
uint8_t Ans[MAX_NCI_FRAME_SIZE];
uint16_t AnsSize;
/* Compute and send DATA_PACKET */
Cmd[0] = 0x00;
Cmd[1] = 0x00;
Cmd[2] = DataSize;
memcpy(&Cmd[3], pData, DataSize);
//status = NxpNci_HostSend(Cmd, DataSize+3);
status = NxpNci_HostTransceive(Cmd, DataSize+3, Ans, sizeof(Ans), &AnsSize);
return status;
}
#endif
#ifdef P2P_SUPPORT
void NxpNci_ProcessP2pMode(NxpNci_RfIntf_t RfIntf)
{
uint8_t Answer[MAX_NCI_FRAME_SIZE];
uint16_t AnswerSize;
bool restart;
uint8_t NCILlcpSymm[] = {0x00, 0x00, 0x02, 0x00, 0x00};
uint8_t NCIRestartDiscovery[] = {0x21, 0x06, 0x01, 0x03};
/* Reset P2P_NDEF state */
P2P_NDEF_Reset();
/* Is Initiator mode ? */
if((RfIntf.ModeTech & MODE_LISTEN) != MODE_LISTEN)
{
/* Initiate communication (SYMM PDU) */
NxpNci_HostTransceive(NCILlcpSymm, sizeof(NCILlcpSymm), Answer, sizeof(Answer), &AnswerSize);
}
/* Get frame from remote peer */
while(NxpNci_WaitForReception(Answer, sizeof(Answer), &AnswerSize, TIMEOUT_2S) == NXPNCI_SUCCESS)
{
/* is DATA_PACKET ? */
if((Answer[0] == 0x00) && (Answer[1] == 0x00))
{
uint8_t Cmd[MAX_NCI_FRAME_SIZE];
uint16_t CmdSize;
P2P_NDEF_Next(&Answer[3], Answer[2], &Cmd[3], (unsigned short *) &CmdSize);
/* Compute DATA_PACKET to answer */
Cmd[0] = 0x00;
Cmd[1] = (CmdSize & 0xFF00) >> 8;
Cmd[2] = CmdSize & 0x00FF;
NxpNci_HostTransceive(Cmd, CmdSize+3, Answer, sizeof(Answer), &AnswerSize);
}
/* is CORE_INTERFACE_ERROR_NTF ?*/
else if ((Answer[0] == 0x60) && (Answer[1] == 0x08))
{
break;
}
/* is RF_DEACTIVATE_NTF ? */
else if((Answer[0] == 0x61) && (Answer[1] == 0x06))
{
/* Come back to discovery state */
break;
}
/* is RF_DISCOVERY_NTF ? */
else if((Answer[0] == 0x61) && ((Answer[1] == 0x05) || (Answer[1] == 0x03)))
{
restart = false;
do{
if((Answer[6] & MODE_LISTEN) != MODE_LISTEN) restart = true;
NxpNci_WaitForReception(Answer, sizeof(Answer), &AnswerSize, TIMEOUT_100MS);
}
while (AnswerSize != 0);
if(restart)
{
NxpNci_HostTransceive(NCIRestartDiscovery, sizeof(NCIRestartDiscovery), Answer, sizeof(Answer), &AnswerSize);
}
}
}
/* Is Initiator mode ? */
if((RfIntf.ModeTech & MODE_LISTEN) != MODE_LISTEN)
{
/* Communication ended, restart discovery loop */
NxpNci_HostTransceive(NCIRestartDiscovery, sizeof(NCIRestartDiscovery), Answer, sizeof(Answer), &AnswerSize);
NxpNci_WaitForReception(Answer, sizeof(Answer), &AnswerSize, TIMEOUT_100MS);
}
}
#endif
#ifdef RW_SUPPORT
bool NxpNci_ReaderTagCmd (unsigned char *pCommand, unsigned char CommandSize, unsigned char *pAnswer, unsigned char *pAnswerSize)
{
bool status = NXPNCI_ERROR;
uint8_t Cmd[MAX_NCI_FRAME_SIZE];
uint8_t Ans[MAX_NCI_FRAME_SIZE];
uint16_t AnsSize;
/* Compute and send DATA_PACKET */
Cmd[0] = 0x00;
Cmd[1] = 0x00;
Cmd[2] = CommandSize;
memcpy(&Cmd[3], pCommand, CommandSize);
NxpNci_HostTransceive(Cmd, CommandSize+3, Ans, sizeof(Ans), &AnsSize);
/* Wait for Answer */
NxpNci_WaitForReception(Ans, sizeof(Ans), &AnsSize, TIMEOUT_1S);
if ((Ans[0] == 0x0) && (Ans[1] == 0x0))
{
status = NXPNCI_SUCCESS;
}
*pAnswerSize = Ans[2];
memcpy(pAnswer, &Ans[3], *pAnswerSize);
return status;
}
#ifndef NO_NDEF_SUPPORT
static bool NxpNci_T3TretrieveIDm (void)
{
uint8_t NCIPollingCmdT3T[] = {0x21, 0x08, 0x04, 0x12, 0xFC, 0x00, 0x01};
uint8_t Answer[MAX_NCI_FRAME_SIZE];
uint16_t AnswerSize;
NxpNci_HostTransceive(NCIPollingCmdT3T, sizeof(NCIPollingCmdT3T), Answer, sizeof(Answer), &AnswerSize);
NxpNci_WaitForReception(Answer, sizeof(Answer), &AnswerSize, TIMEOUT_100MS);
if ((Answer[0] == 0x61) && (Answer[1] == 0x08) && (Answer[3] == 0x00))
{
RW_NDEF_T3T_SetIDm(&Answer[6]);
}
else
{
return NXPNCI_ERROR;
}
return NXPNCI_SUCCESS;
}
static void NxpNci_ReadNdef(NxpNci_RfIntf_t RfIntf)
{
uint8_t Answer[MAX_NCI_FRAME_SIZE];
uint16_t AnswerSize;
uint8_t Cmd[MAX_NCI_FRAME_SIZE];
uint16_t CmdSize = 0;
RW_NDEF_Reset(RfIntf.Protocol);
/* In case of T3T tag, retrieve card IDm for further operation */
if (RfIntf.Protocol == PROT_T3T) NxpNci_T3TretrieveIDm();
while(1)
{
RW_NDEF_Read_Next(&Answer[3], Answer[2], &Cmd[3], (unsigned short *) &CmdSize);
if(CmdSize == 0)
{
/* End of the Read operation */
break;
}
else
{
/* Compute and send DATA_PACKET */
Cmd[0] = 0x00;
Cmd[1] = (CmdSize & 0xFF00) >> 8;
Cmd[2] = CmdSize & 0x00FF;
NxpNci_HostTransceive(Cmd, CmdSize+3, Answer, sizeof(Answer), &AnswerSize);
NxpNci_WaitForReception(Answer, sizeof(Answer), &AnswerSize, TIMEOUT_100MS);
}
}
}
static void NxpNci_WriteNdef(NxpNci_RfIntf_t RfIntf)
{
uint8_t Answer[MAX_NCI_FRAME_SIZE];
uint16_t AnswerSize;
uint8_t Cmd[MAX_NCI_FRAME_SIZE];
uint16_t CmdSize = 0;
RW_NDEF_Reset(RfIntf.Protocol);
/* In case of T3T tag, retrieve card IDm for further operation */
if (RfIntf.Protocol == PROT_T3T) NxpNci_T3TretrieveIDm();
while(1)
{
RW_NDEF_Write_Next(&Answer[3], Answer[2], &Cmd[3], (unsigned short *) &CmdSize);
if(CmdSize == 0)
{
/* End of the Write operation */
break;
}
else
{
/* Compute and send DATA_PACKET */
Cmd[0] = 0x00;
Cmd[1] = (CmdSize & 0xFF00) >> 8;
Cmd[2] = CmdSize & 0x00FF;
NxpNci_HostTransceive(Cmd, CmdSize+3, Answer, sizeof(Answer), &AnswerSize);
NxpNci_WaitForReception(Answer, sizeof(Answer), &AnswerSize, TIMEOUT_2S);
}
}
}
#endif
static void NxpNci_PresenceCheck(NxpNci_RfIntf_t RfIntf)
{
uint8_t Answer[MAX_NCI_FRAME_SIZE];
uint16_t AnswerSize;
uint8_t NCIPresCheckT1T[] = {0x00, 0x00, 0x07, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t NCIPresCheckT2T[] = {0x00, 0x00, 0x02, 0x30, 0x00};
uint8_t NCIPresCheckT3T[] = {0x21, 0x08, 0x04, 0xFF, 0xFF, 0x00, 0x01};
uint8_t NCIPresCheckIsoDep[] = {0x2F, 0x11, 0x00};
uint8_t NCIPresCheckIso15693[] = {0x00, 0x00, 0x03, 0x26, 0x01, 0x00};
uint8_t NCIDeactivate[] = {0x21, 0x06, 0x01, 0x01};
uint8_t NCISelectMIFARE[] = {0x21, 0x04, 0x03, 0x01, 0x80, 0x80};
switch (RfIntf.Protocol) {
case PROT_T1T:
do
{
Sleep(500);
NxpNci_HostTransceive(NCIPresCheckT1T, sizeof(NCIPresCheckT1T), Answer, sizeof(Answer), &AnswerSize);
NxpNci_WaitForReception(Answer, sizeof(Answer), &AnswerSize, TIMEOUT_100MS);
} while ((Answer[0] == 0x00) && (Answer[1] == 0x00));
break;
case PROT_T2T:
do
{
Sleep(500);
NxpNci_HostTransceive(NCIPresCheckT2T, sizeof(NCIPresCheckT2T), Answer, sizeof(Answer), &AnswerSize);
NxpNci_WaitForReception(Answer, sizeof(Answer), &AnswerSize, TIMEOUT_100MS);
} while ((Answer[0] == 0x00) && (Answer[1] == 0x00) && (Answer[2] == 0x11));
break;
case PROT_T3T:
do
{
Sleep(500);
NxpNci_HostTransceive(NCIPresCheckT3T, sizeof(NCIPresCheckT3T), Answer, sizeof(Answer), &AnswerSize);
NxpNci_WaitForReception(Answer, sizeof(Answer), &AnswerSize, TIMEOUT_100MS);
} while ((Answer[0] == 0x61) && (Answer[1] == 0x08) && (Answer[3] == 0x00));
break;
case PROT_ISODEP:
do
{
Sleep(500);
NxpNci_HostTransceive(NCIPresCheckIsoDep, sizeof(NCIPresCheckIsoDep), Answer, sizeof(Answer), &AnswerSize);
NxpNci_WaitForReception(Answer, sizeof(Answer), &AnswerSize, TIMEOUT_100MS);
} while ((Answer[0] == 0x6F) && (Answer[1] == 0x11) && (Answer[2] == 0x01) && (Answer[3] == 0x01));
break;
case PROT_ISO15693:
do
{
Sleep(500);
NxpNci_HostTransceive(NCIPresCheckIso15693, sizeof(NCIPresCheckIso15693), Answer, sizeof(Answer), &AnswerSize);
NxpNci_WaitForReception(Answer, sizeof(Answer), &AnswerSize, TIMEOUT_100MS);
} while ((Answer[0] == 0x00) && (Answer[1] == 0x00));
break;
case PROT_MIFARE:
do
{
Sleep(500);
/* Deactivate target */
NxpNci_HostTransceive(NCIDeactivate, sizeof(NCIDeactivate), Answer, sizeof(Answer), &AnswerSize);
NxpNci_WaitForReception(Answer, sizeof(Answer), &AnswerSize, TIMEOUT_100MS);
/* Reactivate target */
NxpNci_HostTransceive(NCISelectMIFARE, sizeof(NCISelectMIFARE), Answer, sizeof(Answer), &AnswerSize);
NxpNci_WaitForReception(Answer, sizeof(Answer), &AnswerSize, TIMEOUT_100MS);
} while ((Answer[0] == 0x61) && (Answer[1] == 0x05));
break;
default:
/* Nothing to do */
break;
}
}
void NxpNci_ProcessReaderMode(NxpNci_RfIntf_t RfIntf, NxpNci_RW_Operation_t Operation)
{
switch (Operation)
{
#ifndef NO_NDEF_SUPPORT
case READ_NDEF:
NxpNci_ReadNdef(RfIntf);
break;
case WRITE_NDEF:
NxpNci_WriteNdef(RfIntf);
break;
#endif
case PRESENCE_CHECK:
NxpNci_PresenceCheck(RfIntf);
break;
default:
break;
}
}
bool NxpNci_ReaderActivateNext(NxpNci_RfIntf_t *pRfIntf)
{
uint8_t NCIStopDiscovery[] = {0x21, 0x06, 0x01, 0x01};
uint8_t NCIRfDiscoverSelect[] = {0x21, 0x04, 0x03, 0x02, PROT_ISODEP, INTF_ISODEP};
uint8_t Answer[MAX_NCI_FRAME_SIZE];
uint16_t AnswerSize;
bool status = NXPNCI_ERROR;
pRfIntf->MoreTags = false;
if (gNextTag_Protocol == PROT_UNDETERMINED)
{
pRfIntf->Interface = INTF_UNDETERMINED;
pRfIntf->Protocol = PROT_UNDETERMINED;
return NXPNCI_ERROR;
}
/* First disconnect current tag */
NxpNci_HostTransceive(NCIStopDiscovery, sizeof(NCIStopDiscovery), Answer, sizeof(Answer), &AnswerSize);
if((Answer[0] != 0x41) && (Answer[1] != 0x06) && (Answer[3] != 0x00)) return NXPNCI_ERROR;
NxpNci_WaitForReception(Answer, sizeof(Answer), &AnswerSize, TIMEOUT_100MS);
if((Answer[0] != 0x61) && (Answer[1] != 0x06)) return NXPNCI_ERROR;
NCIRfDiscoverSelect[4] = gNextTag_Protocol;
if (gNextTag_Protocol == PROT_ISODEP) NCIRfDiscoverSelect[5] = INTF_ISODEP;
else if (gNextTag_Protocol == PROT_ISODEP) NCIRfDiscoverSelect[5] = INTF_NFCDEP;
else if (gNextTag_Protocol == PROT_MIFARE) NCIRfDiscoverSelect[5] = INTF_TAGCMD;
else NCIRfDiscoverSelect[5] = INTF_FRAME;
NxpNci_HostTransceive(NCIRfDiscoverSelect, sizeof(NCIRfDiscoverSelect), Answer, sizeof(Answer), &AnswerSize);
if ((Answer[0] == 0x41) || (Answer[1] == 0x04) || (Answer[3] == 0x00))
{
NxpNci_WaitForReception(Answer, sizeof(Answer), &AnswerSize, TIMEOUT_100MS);
if ((Answer[0] == 0x61) || (Answer[1] == 0x05))
{
pRfIntf->Interface = Answer[4];
pRfIntf->Protocol = Answer[5];
pRfIntf->ModeTech = Answer[6];
NxpNci_FillInterfaceInfo(pRfIntf, &Answer[10]);
status = NXPNCI_SUCCESS;
}
}
return status;
}
bool NxpNci_ReaderReActivate(NxpNci_RfIntf_t *pRfIntf)
{
uint8_t NCIDeactivate[] = {0x21, 0x06, 0x01, 0x01};
uint8_t NCIActivate[] = {0x21, 0x04, 0x03, 0x01, 0x00, 0x00};
uint8_t Answer[MAX_NCI_FRAME_SIZE];
uint16_t AnswerSize;
/* First de-activate the target */
NxpNci_HostTransceive(NCIDeactivate, sizeof(NCIDeactivate), Answer, sizeof(Answer), &AnswerSize);
NxpNci_WaitForReception(Answer, sizeof(Answer), &AnswerSize, TIMEOUT_100MS);
/* Then re-activate the target */
NCIActivate[4] = pRfIntf->Protocol;
NCIActivate[5] = pRfIntf->Interface;
NxpNci_HostTransceive(NCIActivate, sizeof(NCIActivate), Answer, sizeof(Answer), &AnswerSize);
NxpNci_WaitForReception(Answer, sizeof(Answer), &AnswerSize, TIMEOUT_100MS);
if((Answer[0] != 0x61) || (Answer[1] != 0x05)) return NXPNCI_ERROR;
return NXPNCI_SUCCESS;
}
#endif
bool NxpNci_Connect(void)
{
uint8_t i = 2;
uint8_t NCICoreInit[] = {0x20, 0x01, 0x00};
uint8_t Answer[MAX_NCI_FRAME_SIZE];
uint16_t AnswerSize;
/* Open connection to NXPNCI */
tml_Connect ();
/* Loop until NXPNCI answers */
while(NxpNci_CheckDevPres() != NXPNCI_SUCCESS)
{
if(i-- == 0) return NXPNCI_ERROR;
Sleep(500);
}
NxpNci_HostTransceive(NCICoreInit, sizeof(NCICoreInit), Answer, sizeof(Answer), &AnswerSize);
if ((Answer[0] != 0x40) || (Answer[1] != 0x01) || (Answer[3] != 0x00)) return NXPNCI_ERROR;
/* Retrieve NXP-NCI NFC Controller generation */
if (Answer[17+Answer[8]] == 0x08) gNfcController_generation = 1;
else if (Answer[17+Answer[8]] == 0x10) gNfcController_generation = 2;
return NXPNCI_SUCCESS;
}
bool NxpNci_Disconnect(void)
{
/* Close connection to NXPNCI */
tml_Disconnect ();
return NXPNCI_SUCCESS;
}
bool NxpNci_ConfigureSettings(void)
{
uint8_t Answer[MAX_NCI_FRAME_SIZE];
uint16_t AnswerSize;
uint8_t NCICoreReset[] = {0x20, 0x00, 0x01, 0x00};
uint8_t NCICoreInit[] = {0x20, 0x01, 0x00};
#if (NXP_TVDD_CONF | NXP_RF_CONF)
uint8_t *NxpNci_CONF;
uint16_t NxpNci_CONF_size = 0;
#endif
bool isResetRequired = false;
/* Apply settings according definition of Nfc_settings.h header file */
#if NXP_CORE_CONF
if (sizeof(NxpNci_CORE_CONF) != 0)
{
isResetRequired = true;
NxpNci_HostTransceive(NxpNci_CORE_CONF, sizeof(NxpNci_CORE_CONF), Answer, sizeof(Answer), &AnswerSize);
if ((Answer[0] != 0x40) || (Answer[1] != 0x02) || (Answer[3] != 0x00) || (Answer[4] != 0x00)) return NXPNCI_ERROR;
}
#endif
#if NXP_CORE_CONF_EXTN
if (sizeof(NxpNci_CORE_CONF_EXTN) != 0)
{
isResetRequired = true;
NxpNci_HostTransceive(NxpNci_CORE_CONF_EXTN, sizeof(NxpNci_CORE_CONF_EXTN), Answer, sizeof(Answer), &AnswerSize);
if ((Answer[0] != 0x40) || (Answer[1] != 0x02) || (Answer[3] != 0x00) || (Answer[4] != 0x00)) return NXPNCI_ERROR;
}
#endif
#if NXP_CORE_STANDBY
if (sizeof(NxpNci_CORE_STANDBY) != 0)
{
isResetRequired = true;
NxpNci_HostTransceive(NxpNci_CORE_STANDBY, sizeof(NxpNci_CORE_STANDBY), Answer, sizeof(Answer), &AnswerSize);
if ((Answer[0] != 0x4F) || (Answer[1] != 0x00) || (Answer[3] != 0x00)) return NXPNCI_ERROR;
}
#endif
#if NXP_CLK_CONF
if (sizeof(NxpNci_CLK_CONF) != 0)
{
isResetRequired = true;
NxpNci_HostTransceive(NxpNci_CLK_CONF, sizeof(NxpNci_CLK_CONF), Answer, sizeof(Answer), &AnswerSize);
if ((Answer[0] != 0x40) || (Answer[1] != 0x02) || (Answer[3] != 0x00) || (Answer[4] != 0x00)) return NXPNCI_ERROR;
}
#endif
#if NXP_TVDD_CONF
if(gNfcController_generation == 1)
{
NxpNci_CONF = NxpNci_TVDD_CONF_1stGen;
NxpNci_CONF_size = sizeof(NxpNci_TVDD_CONF_1stGen);
}
else if(gNfcController_generation == 2)
{
NxpNci_CONF = NxpNci_TVDD_CONF_2ndGen;
NxpNci_CONF_size = sizeof(NxpNci_TVDD_CONF_2ndGen);
}
if (NxpNci_CONF_size != 0)
{
isResetRequired = true;
NxpNci_HostTransceive(NxpNci_CONF, NxpNci_CONF_size, Answer, sizeof(Answer), &AnswerSize);
if ((Answer[0] != 0x40) || (Answer[1] != 0x02) || (Answer[3] != 0x00) || (Answer[4] != 0x00)) return NXPNCI_ERROR;
}
#endif
#if NXP_RF_CONF
if(gNfcController_generation == 1)
{
NxpNci_CONF = NxpNci_RF_CONF_1stGen;
NxpNci_CONF_size = sizeof(NxpNci_RF_CONF_1stGen);
}
else if(gNfcController_generation == 2)
{
NxpNci_CONF = NxpNci_RF_CONF_2ndGen;
NxpNci_CONF_size = sizeof(NxpNci_RF_CONF_2ndGen);
}
if (NxpNci_CONF_size != 0)
{
isResetRequired = true;
NxpNci_HostTransceive(NxpNci_CONF, NxpNci_CONF_size, Answer, sizeof(Answer), &AnswerSize);
if ((Answer[0] != 0x40) || (Answer[1] != 0x02) || (Answer[3] != 0x00) || (Answer[4] != 0x00)) return NXPNCI_ERROR;
}
#endif
if(isResetRequired)
{
/* Reset the NFC Controller to insure new settings apply */
NxpNci_HostTransceive(NCICoreReset, sizeof(NCICoreReset), Answer, sizeof(Answer), &AnswerSize);
if ((Answer[0] != 0x40) || (Answer[1] != 0x00) || (Answer[3] != 0x00)) return NXPNCI_ERROR;
NxpNci_HostTransceive(NCICoreInit, sizeof(NCICoreInit), Answer, sizeof(Answer), &AnswerSize);
if ((Answer[0] != 0x40) || (Answer[1] != 0x01) || (Answer[3] != 0x00)) return NXPNCI_ERROR;
}
return NXPNCI_SUCCESS;
}
bool NxpNci_ConfigureMode(unsigned char mode)
{
uint8_t Command[MAX_NCI_FRAME_SIZE];
uint8_t Answer[MAX_NCI_FRAME_SIZE];
uint16_t AnswerSize;
uint8_t Item = 0;
uint8_t NCIDiscoverMap[] = {0x21, 0x00};
#ifdef CARDEMU_SUPPORT
const uint8_t DM_CARDEMU[] = {0x4, 0x2, 0x2};
const uint8_t R_CARDEMU[] = {0x1, 0x3, 0x0, 0x1, 0x4};
#endif
#ifdef P2P_SUPPORT
const uint8_t DM_P2P[] = {0x5, 0x3, 0x3};
const uint8_t R_P2P[] = {0x1, 0x3, 0x0, 0x1, 0x5};
uint8_t NCISetConfig_NFC[] = {0x20, 0x02, 0x1F, 0x02, 0x29, 0x0D, 0x46, 0x66, 0x6D, 0x01, 0x01, 0x11, 0x03, 0x02, 0x00, 0x01, 0x04, 0x01, 0xFA, 0x61, 0x0D, 0x46, 0x66, 0x6D, 0x01, 0x01, 0x11, 0x03, 0x02, 0x00, 0x01, 0x04, 0x01, 0xFA};
#endif
#ifdef RW_SUPPORT
const uint8_t DM_RW[] = {0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x3, 0x1, 0x1, 0x4, 0x1, 0x2, 0x80, 0x01, 0x80};
uint8_t NCIPropAct[] = {0x2F, 0x02, 0x00};
#endif
#if defined P2P_SUPPORT || defined CARDEMU_SUPPORT
uint8_t NCIRouting[] = {0x21, 0x01, 0x07, 0x00, 0x01};
uint8_t NCISetConfig_NFCA_SELRSP[] = {0x20, 0x02, 0x04, 0x01, 0x32, 0x01, 0x00};
#endif
if(mode == 0) return NXPNCI_SUCCESS;
/* Enable Proprietary interface for T4T card presence check procedure */
#ifdef RW_SUPPORT
if (mode == NXPNCI_MODE_RW)
{
NxpNci_HostTransceive(NCIPropAct, sizeof(NCIPropAct), Answer, sizeof(Answer), &AnswerSize);
if ((Answer[0] != 0x4F) || (Answer[1] != 0x02) || (Answer[3] != 0x00)) return NXPNCI_ERROR;
}
#endif
/* Building Discovery Map command */
Item = 0;
#ifdef CARDEMU_SUPPORT
if (mode & NXPNCI_MODE_CARDEMU)
{
memcpy(&Command[4+(3*Item)], DM_CARDEMU, sizeof(DM_CARDEMU));
Item++;
}
#endif
#ifdef P2P_SUPPORT
if (mode & NXPNCI_MODE_P2P)
{
memcpy(&Command[4+(3*Item)], DM_P2P, sizeof(DM_P2P));
Item++;
}
#endif
#ifdef RW_SUPPORT
if (mode & NXPNCI_MODE_RW)
{
memcpy(&Command[4+(3*Item)], DM_RW, sizeof(DM_RW));
Item+=sizeof(DM_RW)/3;
}
#endif
#if defined P2P_SUPPORT || defined CARDEMU_SUPPORT || defined RW_SUPPORT
if (Item != 0)
{
memcpy(Command, NCIDiscoverMap, sizeof(NCIDiscoverMap));
Command[2] = 1 + (Item*3);
Command[3] = Item;
NxpNci_HostTransceive(Command, 3 + Command[2], Answer, sizeof(Answer), &AnswerSize);
if ((Answer[0] != 0x41) || (Answer[1] != 0x00) || (Answer[3] != 0x00)) return NXPNCI_ERROR;
}
#endif
/* Configuring routing */
Item = 0;
#ifdef CARDEMU_SUPPORT
if (mode & NXPNCI_MODE_CARDEMU)
{
memcpy(&Command[5+(5*Item)], R_CARDEMU, sizeof(R_CARDEMU));
Item++;
}
#endif
#ifdef P2P_SUPPORT
if (mode & NXPNCI_MODE_P2P)
{
memcpy(&Command[5+(5*Item)], R_P2P, sizeof(R_P2P));
Item++;
}
#endif
#if defined P2P_SUPPORT || defined CARDEMU_SUPPORT
if (Item != 0)
{
memcpy(Command, NCIRouting, sizeof(NCIRouting));
Command[2] = 2 + (Item*5);
Command[4] = Item;
NxpNci_HostTransceive(Command, 3 + Command[2] , Answer, sizeof(Answer), &AnswerSize);
if ((Answer[0] != 0x41) || (Answer[1] != 0x01) || (Answer[3] != 0x00)) return NXPNCI_ERROR;
}
#endif
/* Setting NFCA SEL_RSP */
#ifdef CARDEMU_SUPPORT
if (mode & NXPNCI_MODE_CARDEMU)
{
NCISetConfig_NFCA_SELRSP[6] += 0x20;
}
#endif
#ifdef P2P_SUPPORT
if (mode & NXPNCI_MODE_P2P)
{
NCISetConfig_NFCA_SELRSP[6] += 0x40;
}
#endif
#if defined P2P_SUPPORT || defined CARDEMU_SUPPORT
if (NCISetConfig_NFCA_SELRSP[6] != 0x00)
{
NxpNci_HostTransceive(NCISetConfig_NFCA_SELRSP, sizeof(NCISetConfig_NFCA_SELRSP), Answer, sizeof(Answer), &AnswerSize);
if ((Answer[0] != 0x40) || (Answer[1] != 0x02) || (Answer[3] != 0x00)) return NXPNCI_ERROR;
}
#endif
/* Setting LLCP support */
#ifdef P2P_SUPPORT
if (mode & NXPNCI_MODE_P2P)
{
NxpNci_HostTransceive(NCISetConfig_NFC, sizeof(NCISetConfig_NFC), Answer, sizeof(Answer), &AnswerSize);
if ((Answer[0] != 0x40) || (Answer[1] != 0x02) || (Answer[3] != 0x00)) return NXPNCI_ERROR;
}
#endif
return NXPNCI_SUCCESS;
}
bool NxpNci_StartDiscovery(unsigned char *pTechTab, unsigned char TechTabSize)
{
uint8_t Buffer[MAX_NCI_FRAME_SIZE];
uint8_t Answer[MAX_NCI_FRAME_SIZE];
uint16_t AnswerSize;
uint8_t i;
Buffer[0] = 0x21;
Buffer[1] = 0x03;
Buffer[2] = (TechTabSize * 2) + 1;
Buffer[3] = TechTabSize;
for (i=0; i<TechTabSize; i++)
{
Buffer[(i*2)+4] = pTechTab[i];
Buffer[(i*2)+5] = 0x01;
}
NxpNci_HostTransceive(Buffer, (TechTabSize * 2) + 4, Answer, sizeof(Answer), &AnswerSize);
if ((Answer[0] != 0x41) || (Answer[1] != 0x03) || (Answer[3] != 0x00)) return NXPNCI_ERROR;
return NXPNCI_SUCCESS;
}
bool NxpNci_StopDiscovery(void)
{
uint8_t NCIStopDiscovery[] = {0x21, 0x06, 0x01, 0x00};
uint8_t Answer[MAX_NCI_FRAME_SIZE];
uint16_t AnswerSize;
NxpNci_HostTransceive(NCIStopDiscovery, sizeof(NCIStopDiscovery), Answer, sizeof(Answer), &AnswerSize);
NxpNci_WaitForReception(Answer, sizeof(Answer), &AnswerSize, TIMEOUT_1S);
return NXPNCI_SUCCESS;
}
bool NxpNci_WaitForDiscoveryNotification(NxpNci_RfIntf_t *pRfIntf)
{
uint8_t NCIRfDiscoverSelect[] = {0x21, 0x04, 0x03, 0x01, PROT_ISODEP, INTF_ISODEP};
uint8_t Answer[MAX_NCI_FRAME_SIZE];
uint16_t AnswerSize;
#ifdef P2P_SUPPORT
uint8_t NCIRestartDiscovery[] = {0x21, 0x06, 0x01, 0x03};
uint8_t saved_NTF[7];
wait:
#endif
do
{
if(NxpNci_WaitForReception(Answer, sizeof(Answer), &AnswerSize, TIMEOUT_INFINITE) == NXPNCI_ERROR) return NXPNCI_ERROR;
}while ((Answer[0] != 0x61) || ((Answer[1] != 0x05) && (Answer[1] != 0x03)));
gNextTag_Protocol = PROT_UNDETERMINED;
/* Is RF_INTF_ACTIVATED_NTF ? */
if (Answer[1] == 0x05)
{
pRfIntf->Interface = Answer[4];
pRfIntf->Protocol = Answer[5];
pRfIntf->ModeTech = Answer[6];
pRfIntf->MoreTags = false;
NxpNci_FillInterfaceInfo(pRfIntf, &Answer[10]);
#ifdef P2P_SUPPORT
/* Verifying if not a P2P device also presenting T4T emulation */
if ((pRfIntf->Interface == INTF_ISODEP) && (pRfIntf->Protocol == PROT_ISODEP) && ((pRfIntf->ModeTech & MODE_LISTEN) != MODE_LISTEN))
{
memcpy(saved_NTF, Answer, sizeof(saved_NTF));
while(1)
{
/* Restart the discovery loop */
NxpNci_HostTransceive(NCIRestartDiscovery, sizeof(NCIRestartDiscovery), Answer, sizeof(Answer), &AnswerSize);
NxpNci_WaitForReception(Answer, sizeof(Answer), &AnswerSize, TIMEOUT_100MS);
/* Wait for discovery */
do NxpNci_WaitForReception(Answer, sizeof(Answer), &AnswerSize, TIMEOUT_1S);
while ((AnswerSize == 4) && (Answer[0] == 0x60) && (Answer[1] == 0x07));
if ((AnswerSize != 0) && (Answer[0] == 0x61) && (Answer[1] == 0x05))
{
/* Is same device detected ? */
if (memcmp(saved_NTF, Answer, sizeof(saved_NTF)) == 0) break;
/* Is P2P detected ? */
if (Answer[5] == PROT_NFCDEP)
{
pRfIntf->Interface = Answer[4];
pRfIntf->Protocol = Answer[5];
pRfIntf->ModeTech = Answer[6];
pRfIntf->MoreTags = false;
NxpNci_FillInterfaceInfo(pRfIntf, &Answer[10]);
break;
}
}
else
{
if (AnswerSize != 0)
{
/* Restart the discovery loop */
NxpNci_HostTransceive(NCIRestartDiscovery, sizeof(NCIRestartDiscovery), Answer, sizeof(Answer), &AnswerSize);
NxpNci_WaitForReception(Answer, sizeof(Answer), &AnswerSize, TIMEOUT_100MS);
}
goto wait;
}
}
}
#endif
}
else /* RF_DISCOVER_NTF */
{
pRfIntf->Interface = INTF_UNDETERMINED;
pRfIntf->Protocol = Answer[4];
pRfIntf->ModeTech = Answer[5];
pRfIntf->MoreTags = true;
/* Get next NTF for further activation */
do {
if(NxpNci_WaitForReception(Answer, sizeof(Answer), &AnswerSize, TIMEOUT_100MS) == NXPNCI_ERROR) return NXPNCI_ERROR;
} while ((Answer[0] != 0x61) || (Answer[1] != 0x03));
gNextTag_Protocol = Answer[4];
/* Remaining NTF ? */
while(Answer[AnswerSize-1] == 0x02) NxpNci_WaitForReception(Answer, sizeof(Answer), &AnswerSize, TIMEOUT_100MS);
/* In case of multiple cards, select the first one */
NCIRfDiscoverSelect[4] = pRfIntf->Protocol;
if (pRfIntf->Protocol == PROT_ISODEP) NCIRfDiscoverSelect[5] = INTF_ISODEP;
else if (pRfIntf->Protocol == PROT_NFCDEP) NCIRfDiscoverSelect[5] = INTF_NFCDEP;
else if (pRfIntf->Protocol == PROT_MIFARE) NCIRfDiscoverSelect[5] = INTF_TAGCMD;
else NCIRfDiscoverSelect[5] = INTF_FRAME;
NxpNci_HostTransceive(NCIRfDiscoverSelect, sizeof(NCIRfDiscoverSelect), Answer, sizeof(Answer), &AnswerSize);
if ((Answer[0] == 0x41) || (Answer[1] == 0x04) || (Answer[3] == 0x00))
{
NxpNci_WaitForReception(Answer, sizeof(Answer), &AnswerSize, TIMEOUT_100MS);
if ((Answer[0] == 0x61) || (Answer[1] == 0x05))
{
pRfIntf->Interface = Answer[4];
pRfIntf->Protocol = Answer[5];
pRfIntf->ModeTech = Answer[6];
NxpNci_FillInterfaceInfo(pRfIntf, &Answer[10]);
}
}
}
/* In case of unknown target align protocol information */
if (pRfIntf->Interface == INTF_UNDETERMINED) pRfIntf->Protocol = PROT_UNDETERMINED;
return NXPNCI_SUCCESS;
}
/*
* Copyright (c), NXP Semiconductors Caen / France
*
* (C)NXP Semiconductors
* All rights are reserved. Reproduction in whole or in part is
* prohibited without the written consent of the copyright owner.
* NXP reserves the right to make changes without notice at any time.
* NXP makes no warranty, expressed, implied or statutory, including but
* not limited to any implied warranty of merchantability or fitness for any
*particular purpose, or that the use will not infringe any third party patent,
* copyright or trademark. NXP must not be liable for any loss or damage
* arising from its use.
*/
/***** NFC dedicated interface ****************************************/
/*
* Status code definition used as API returned values
*/
#define NFC_SUCCESS 0
#define NFC_ERROR 1
/*
* Flag definition used as Interface values
*/
#define INTF_UNDETERMINED 0x0
#define INTF_FRAME 0x1
#define INTF_ISODEP 0x2
#define INTF_NFCDEP 0x3
#define INTF_TAGCMD 0x80
/*
* Flag definition used as Protocol values
*/
#define PROT_UNDETERMINED 0x0
#define PROT_T1T 0x1
#define PROT_T2T 0x2
#define PROT_T3T 0x3
#define PROT_ISODEP 0x4
#define PROT_NFCDEP 0x5
#define PROT_ISO15693 0x6
#define PROT_MIFARE 0x80
/*
* Flag definition used as Mode values
*/
#define MODE_POLL 0x00
#define MODE_LISTEN 0x80
#define MODE_MASK 0xF0
/*
* Flag definition used as Technologies values
*/
#define TECH_PASSIVE_NFCA 0
#define TECH_PASSIVE_NFCB 1
#define TECH_PASSIVE_NFCF 2
#define TECH_ACTIVE_NFCA 3
#define TECH_ACTIVE_NFCF 5
#define TECH_PASSIVE_15693 6
/*
* Flag definition used for NFC library configuration
*/
#define NXPNCI_MODE_CARDEMU (1<<0)
#define NXPNCI_MODE_P2P (1<<1)
#define NXPNCI_MODE_RW (1<<2)
/*
* Definition of operations handled when processing Reader mode
*/
typedef enum
{
#ifndef NO_NDEF_SUPPORT
READ_NDEF,
WRITE_NDEF,
#endif
PRESENCE_CHECK
} NxpNci_RW_Operation_t;
/*
* Definition of discovered remote device properties information
*/
/* POLL passive type A */
typedef struct
{
unsigned char SensRes[2];
unsigned char NfcIdLen;
unsigned char NfcId[10];
unsigned char SelResLen;
unsigned char SelRes[1];
} NxpNci_RfIntf_info_APP_t;
/* POLL passive type B */
typedef struct
{
unsigned char SensResLen;
unsigned char SensRes[12];
} NxpNci_RfIntf_info_BPP_t;
/* POLL passive type F */
typedef struct
{
unsigned char BitRate;
unsigned char SensResLen;
unsigned char SensRes[18];
} NxpNci_RfIntf_info_FPP_t;
/* POLL passive type ISO15693 */
typedef struct
{
unsigned char AFI;
unsigned char DSFID;
unsigned char ID[8];
} NxpNci_RfIntf_info_VPP_t;
typedef union
{
NxpNci_RfIntf_info_APP_t NFC_APP;
NxpNci_RfIntf_info_BPP_t NFC_BPP;
NxpNci_RfIntf_info_FPP_t NFC_FPP;
NxpNci_RfIntf_info_VPP_t NFC_VPP;
} NxpNci_RfIntf_Info_t;
/*
* Definition of discovered remote device properties
*/
typedef struct
{
unsigned char Interface;
unsigned char Protocol;
unsigned char ModeTech;
bool MoreTags;
NxpNci_RfIntf_Info_t Info;
} NxpNci_RfIntf_t;
/**********************************************************************/
/***** NFC dedicated API **********************************************/
/*
* Open connection to the NXP-NCI device
* return NFC_SUCCESS or NFC_ERROR
*/
bool NxpNci_Connect(void);
/*
* Close connection to the NXP-NCI device
* return NFC_SUCCESS or NFC_ERROR
*/
bool NxpNci_Disconnect(void);
/*
* Configure NXP-NCI device settings
* Related settings are defined in Nfc_settings.h header file
* To be called after NxpNci_Connect() and prior to NxpNci_ConfigureMode() APIs
* return NFC_SUCCESS or NFC_ERROR
*/
bool NxpNci_ConfigureSettings(void);
/*
* Configure NXP-NCI device mode
* - mode: specifies which modes to be configured (see NXPNCI_MODE_xxx flags)
* return NFC_SUCCESS or NFC_ERROR
*/
bool NxpNci_ConfigureMode(unsigned char mode);
/*
* Start NFC Discovery loop for remote NFC device detection
* - pTechTab: list of NFC technologies to look for (see TECH_xxx_xxx flags)
* \param TechTabSize: number of items in the list
* return NFC_SUCCESS or NFC_ERROR
*/
bool NxpNci_StartDiscovery(unsigned char *pTechTab, unsigned char TechTabSize);
/*
* Stop NFC Discovery loop
* return NFC_SUCCESS or NFC_ERROR
*/
bool NxpNci_StopDiscovery(void);
/*
* Wait until remote NFC device is discovered
* - pRfIntf: filled with discovered NFC remote device properties
* return NFC_SUCCESS or NFC_ERROR
*/
bool NxpNci_WaitForDiscoveryNotification(NxpNci_RfIntf_t *pRfIntf);
/**********************************************************************/
/***** Reader/writer dedicated APIs ***********************************/
#ifdef RW_SUPPORT
#ifndef NO_NDEF_SUPPORT
/*
* Register NDEF message to be written to remote NFC Tag
* - pMessage: pointer to the NDEF message
* - Message_size: NDEF message size
* - pCb: pointer to function to be called back when tag has been written
* return NFC_SUCCESS or NFC_ERROR
*/
bool RW_NDEF_SetMessage(unsigned char *pMessage, unsigned short Message_size, void *pCb);
/*
* Register function called when NDEF message is read from remote NFC Tag
* - pCb: pointer to function to be called back when NDEF message has been read
*/
void RW_NDEF_RegisterPullCallback(void *pCb);
#endif
/*
* Process the operation identified as parameter with discovered remote NFC tag (function is blocking until the end of the operation)
* - RfIntf: discovered NFC device properties
* - Operation: select operation to be done with the remote NFC tag
* o READ_NDEF: extract NDEF message from the tag, previously registered callback function will be called whenever complete NDEF message is found.
* o WRITE_NDEF: write previously registered NDEF message to the tag
* o PRESENCE_CHECK: perform presence check until tag has been removed (function is blocking until card is removed)
*/
void NxpNci_ProcessReaderMode(NxpNci_RfIntf_t RfIntf, NxpNci_RW_Operation_t Operation);
/*
* Perform RAW transceive operation (send then receive) with the remote tag
* - pCommand: pointer to the command to send
* - CommandSize: command size
* - pAnswer: pointer to buffer for getting the response
* - pAnswerSize: response size
* return NFC_SUCCESS or NFC_ERROR
*/
bool NxpNci_ReaderTagCmd (unsigned char *pCommand, unsigned char CommandSize, unsigned char *pAnswer, unsigned char *pAnswerSize);
/*
* Perform activation of the next tag (in case of multiple tag detection or multi-protocol tag)
* - pRfIntf: filled with discovered NFC remote device properties
* return NFC_SUCCESS or NFC_ERROR
*/
bool NxpNci_ReaderActivateNext(NxpNci_RfIntf_t *pRfIntf);
/*
* Perform deactivation then reactivation of the current tag
* - pRfIntf: filled with discovered NFC remote device properties
* return NFC_SUCCESS or NFC_ERROR
*/
bool NxpNci_ReaderReActivate(NxpNci_RfIntf_t *pRfIntf);
#endif
/**********************************************************************/
/***** Card Emulation dedicated APIs **********************************/
#ifdef CARDEMU_SUPPORT
#ifndef NO_NDEF_SUPPORT
/*
* Register NDEF message to be exposed to remote NFC reader Device
* - pMessage: pointer to the NDEF message
* - Message_size: NDEF message size
* - pCb: pointer to function to be called back when tag has been written
* return NFC_SUCCESS or NFC_ERROR
*/
bool T4T_NDEF_EMU_SetMessage(unsigned char *pMessage, unsigned short Message_size, void *pCb);
#endif
/*
* Expose the previously registered NDEF message to discovered remote NFC reader (function is blocking until the remote reader is lost):
* - RfIntf: discovered NFC device properties
*/
void NxpNci_ProcessCardMode(NxpNci_RfIntf_t RfIntf);
/*
* Perform RAW reception of data from the remote reader
* - pData: pointer to buffer for getting the data
* - pDataSize: received data size
* return NFC_SUCCESS or NFC_ERROR
*/
bool NxpNci_CardModeReceive (unsigned char *pData, unsigned char *pDataSize);
/*
* Perform RAW transmission of data from the remote reader
* - pData: pointer to data to transmit
* - DataSize: size of data to transmit
* return NFC_SUCCESS or NFC_ERROR
*/
bool NxpNci_CardModeSend (unsigned char *pData, unsigned char DataSize);
#endif
/**********************************************************************/
/***** P2P dedicated APIs *********************************************/
#ifdef P2P_SUPPORT
/*
* Register NDEF message to be sent to remote NFC Peer to peer Device
* - pMessage: pointer to the NDEF message
* - Message_size: NDEF message size
* - pCb: pointer to function to be called back when tag has been sent
* return NFC_SUCCESS or NFC_ERROR
*/
bool P2P_NDEF_SetMessage(unsigned char *pMessage, unsigned short Message_size, void *pCb);
/*
* Register function called when NDEF message is received from remote NFC Peer to peer Device
* - pCb: pointer to function to be called back when NDEF message has been received
*/
void P2P_NDEF_RegisterPullCallback(void *pCb);
/* Process P2P operation (function is blocking until the remote peer is lost):
* ¤ SNEP server to allow receiving NDEF message from remote NFC P2P device
* ¤ SNEP client to send previously registered NDEF message
* - RfIntf: discovered NFC device properties
*/
void NxpNci_ProcessP2pMode(NxpNci_RfIntf_t RfIntf);
#endif
/**********************************************************************/
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment