mirror of
https://github.com/RfidResearchGroup/ChameleonMini.git
synced 2026-05-12 11:20:37 -07:00
Merge pull request #66 from mgp25/proxgrind
NTAG 215 Support + ChamTool update
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
|
||||
.DS_Store
|
||||
*.pyc
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "TITagitstandard.h"
|
||||
#include "Sniff14443A.h"
|
||||
#include "EM4233.h"
|
||||
#include "NTAG215.h"
|
||||
|
||||
/* Function wrappers */
|
||||
INLINE void ApplicationInit(void) {
|
||||
|
||||
@@ -0,0 +1,438 @@
|
||||
/*
|
||||
* NTAG215.c
|
||||
*
|
||||
* Created on: 20.02.2019
|
||||
* Author: Giovanni Cammisa (gcammisa)
|
||||
* Still missing support for:
|
||||
* - The management of both static and dynamic lock bytes
|
||||
* - Bruteforce protection (AUTHLIM COUNTER)
|
||||
* Thanks to skuser for the MifareUltralight code used as a starting point
|
||||
*/
|
||||
|
||||
#include "ISO14443-3A.h"
|
||||
#include "../Codec/ISO14443-2A.h"
|
||||
#include "../Memory.h"
|
||||
#include "NTAG215.h"
|
||||
|
||||
// DEFINE ATQA and SAK
|
||||
#define ATQA_VALUE 0x0044
|
||||
#define SAK_VALUE 0x00
|
||||
|
||||
#define SAK_CL1_VALUE ISO14443A_SAK_INCOMPLETE
|
||||
#define SAK_CL2_VALUE ISO14443A_SAK_COMPLETE_NOT_COMPLIANT
|
||||
|
||||
// ACK and NACK
|
||||
#define ACK_VALUE 0x0A
|
||||
#define ACK_FRAME_SIZE 4 /* Bits */
|
||||
#define NAK_INVALID_ARG 0x00
|
||||
#define NAK_CRC_ERROR 0x01
|
||||
#define NAK_NOT_AUTHED 0x04
|
||||
#define NAK_EEPROM_ERROR 0x05
|
||||
#define NAK_FRAME_SIZE 4
|
||||
|
||||
// DEFINING COMMANDS
|
||||
/* ISO commands */
|
||||
#define CMD_HALT 0x50
|
||||
// NTAG COMMANDS
|
||||
#define CMD_GET_VERSION 0x60
|
||||
#define CMD_READ 0x30
|
||||
#define CMD_FAST_READ 0x3A
|
||||
#define CMD_WRITE 0xA2
|
||||
#define CMD_COMPAT_WRITE 0xA0
|
||||
#define CMD_READ_CNT 0x39
|
||||
#define CMD_PWD_AUTH 0x1B
|
||||
#define CMD_READ_SIG 0x3C
|
||||
|
||||
// MEMORY LAYOUT STUFF, addresses and sizes in bytes
|
||||
// UID stuff
|
||||
#define UID_CL1_ADDRESS 0x00
|
||||
#define UID_CL1_SIZE 3
|
||||
#define UID_BCC1_ADDRESS 0x03
|
||||
#define UID_CL2_ADDRESS 0x04
|
||||
#define UID_CL2_SIZE 4
|
||||
#define UID_BCC2_ADDRESS 0x08
|
||||
// LockBytes stuff
|
||||
#define STATIC_LOCKBYTE_0_ADDRESS 0x0A
|
||||
#define STATIC_LOCKBYTE_1_ADDRESS 0x0B
|
||||
// CONFIG stuff
|
||||
#define CONFIG_AREA_START_ADDRESS NTAG215_PAGE_SIZE * 0x83
|
||||
#define CONFIG_AREA_SIZE 8
|
||||
// CONFIG offsets, relative to config start address
|
||||
#define CONF_AUTH0_OFFSET 0x03
|
||||
#define CONF_ACCESS_OFFSET 0x04
|
||||
#define CONF_PASSWORD_OFFSET 0x08
|
||||
#define CONF_PACK_OFFSET 0x0C
|
||||
|
||||
// WRITE STUFF
|
||||
#define BYTES_PER_WRITE 4
|
||||
#define PAGE_WRITE_MIN 0x02
|
||||
|
||||
// CONFIG masks to check individual needed bits
|
||||
#define CONF_ACCESS_PROT 0x80
|
||||
|
||||
#define VERSION_INFO_LENGTH 8 //8 bytes info lenght + crc
|
||||
|
||||
#define BYTES_PER_READ NTAG215_PAGE_SIZE * 4
|
||||
|
||||
// SIGNATURE Lenght
|
||||
#define SIGNATURE_LENGTH 32
|
||||
|
||||
|
||||
static enum {
|
||||
STATE_HALT,
|
||||
STATE_IDLE,
|
||||
STATE_READY1,
|
||||
STATE_READY2,
|
||||
STATE_ACTIVE
|
||||
} State;
|
||||
|
||||
static bool FromHalt = false;
|
||||
static uint8_t PageCount;
|
||||
static bool ArmedForCompatWrite;
|
||||
static uint8_t CompatWritePageAddress;
|
||||
static bool Authenticated;
|
||||
static uint8_t FirstAuthenticatedPage;
|
||||
static bool ReadAccessProtected;
|
||||
static uint8_t Access;
|
||||
|
||||
|
||||
void NTAG215AppInit(void)
|
||||
{
|
||||
|
||||
State = STATE_IDLE;
|
||||
FromHalt = false;
|
||||
ArmedForCompatWrite = false;
|
||||
Authenticated = false;
|
||||
PageCount = NTAG215_PAGES;
|
||||
|
||||
/* Fetch some of the configuration into RAM */
|
||||
MemoryReadBlock(&FirstAuthenticatedPage, CONFIG_AREA_START_ADDRESS + CONF_AUTH0_OFFSET, 1);
|
||||
MemoryReadBlock(&Access, CONFIG_AREA_START_ADDRESS + CONF_ACCESS_OFFSET, 1);
|
||||
ReadAccessProtected = !!(Access & CONF_ACCESS_PROT);
|
||||
}
|
||||
|
||||
void NTAG215AppReset(void)
|
||||
{
|
||||
State = STATE_IDLE;
|
||||
}
|
||||
|
||||
void NTAG215AppTask(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Verify authentication
|
||||
static bool VerifyAuthentication(uint8_t PageAddress)
|
||||
{
|
||||
/* If authenticated, no verification needed */
|
||||
if (Authenticated) {
|
||||
return true;
|
||||
}
|
||||
/* Otherwise, verify the accessed page is below the limit */
|
||||
return PageAddress < FirstAuthenticatedPage;
|
||||
}
|
||||
|
||||
// Writes a page
|
||||
static uint8_t AppWritePage(uint8_t PageAddress, uint8_t* const Buffer)
|
||||
{
|
||||
if (!ActiveConfiguration.ReadOnly) {
|
||||
MemoryWriteBlock(Buffer, PageAddress * NTAG215_PAGE_SIZE, NTAG215_PAGE_SIZE);
|
||||
} else {
|
||||
/* If the chameleon is in read only mode, it silently
|
||||
* ignores any attempt to write data. */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Basic sketch of the command handling stuff
|
||||
static uint16_t AppProcess(uint8_t* const Buffer, uint16_t ByteCount)
|
||||
{
|
||||
uint8_t Cmd = Buffer[0];
|
||||
|
||||
/* Handle the compatibility write command */
|
||||
if (ArmedForCompatWrite) {
|
||||
ArmedForCompatWrite = false;
|
||||
|
||||
AppWritePage(CompatWritePageAddress, &Buffer[2]);
|
||||
Buffer[0] = ACK_VALUE;
|
||||
return ACK_FRAME_SIZE;
|
||||
}
|
||||
|
||||
switch (Cmd) {
|
||||
case CMD_GET_VERSION: {
|
||||
/* Provide hardcoded version response */ //VERSION RESPONSE FOR NTAG 215
|
||||
Buffer[0] = 0x00;
|
||||
Buffer[1] = 0x04;
|
||||
Buffer[2] = 0x04;
|
||||
Buffer[3] = 0x02;
|
||||
Buffer[4] = 0x01;
|
||||
Buffer[5] = 0x00;
|
||||
Buffer[6] = 0x11;
|
||||
Buffer[7] = 0x03;
|
||||
ISO14443AAppendCRCA(Buffer, VERSION_INFO_LENGTH);
|
||||
return (VERSION_INFO_LENGTH + ISO14443A_CRCA_SIZE) * 8;
|
||||
}
|
||||
|
||||
case CMD_READ: {
|
||||
uint8_t PageAddress = Buffer[1];
|
||||
uint8_t PageLimit;
|
||||
uint8_t Offset;
|
||||
|
||||
PageLimit = PageCount;
|
||||
|
||||
/* if protected and not autenticated, ensure the wraparound is at the first protected page */
|
||||
if (ReadAccessProtected && !Authenticated) {
|
||||
PageLimit = FirstAuthenticatedPage;
|
||||
}
|
||||
else {
|
||||
PageLimit = PageCount;
|
||||
}
|
||||
|
||||
/* Validation */
|
||||
if (PageAddress >= PageLimit) {
|
||||
Buffer[0] = NAK_INVALID_ARG;
|
||||
return NAK_FRAME_SIZE;
|
||||
}
|
||||
/* Read out, emulating the wraparound */
|
||||
for (Offset = 0; Offset < BYTES_PER_READ; Offset += 4) {
|
||||
MemoryReadBlock(&Buffer[Offset], PageAddress * NTAG215_PAGE_SIZE, NTAG215_PAGE_SIZE);
|
||||
PageAddress++;
|
||||
if (PageAddress == PageLimit) { // if arrived ad the last page, start reading from page 0
|
||||
PageAddress = 0;
|
||||
}
|
||||
}
|
||||
ISO14443AAppendCRCA(Buffer, BYTES_PER_READ);
|
||||
return (BYTES_PER_READ + ISO14443A_CRCA_SIZE) * 8;
|
||||
}
|
||||
|
||||
case CMD_FAST_READ: {
|
||||
uint8_t StartPageAddress = Buffer[1];
|
||||
uint8_t EndPageAddress = Buffer[2];
|
||||
/* Validation */
|
||||
if ((StartPageAddress > EndPageAddress) || (StartPageAddress >= PageCount) || (EndPageAddress >= PageCount)) {
|
||||
Buffer[0] = NAK_INVALID_ARG;
|
||||
return NAK_FRAME_SIZE;
|
||||
}
|
||||
|
||||
/* Check authentication only if protection is read&write (instead of only write protection) */
|
||||
if (ReadAccessProtected) {
|
||||
if (!VerifyAuthentication(StartPageAddress) || !VerifyAuthentication(EndPageAddress)) {
|
||||
Buffer[0] = NAK_NOT_AUTHED;
|
||||
return NAK_FRAME_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
ByteCount = (EndPageAddress - StartPageAddress + 1) * NTAG215_PAGE_SIZE;
|
||||
MemoryReadBlock(Buffer, StartPageAddress * NTAG215_PAGE_SIZE, ByteCount);
|
||||
ISO14443AAppendCRCA(Buffer, ByteCount);
|
||||
return (ByteCount + ISO14443A_CRCA_SIZE) * 8;
|
||||
}
|
||||
|
||||
case CMD_PWD_AUTH: {
|
||||
uint8_t Password[4];
|
||||
|
||||
/* For now I don't care about bruteforce protection, so: */
|
||||
/* TODO: IMPLEMENT COUNTER AUTHLIM */
|
||||
|
||||
/* Read and compare the password */
|
||||
MemoryReadBlock(Password, CONFIG_AREA_START_ADDRESS + CONF_PASSWORD_OFFSET, 4);
|
||||
if (Password[0] != Buffer[1] || Password[1] != Buffer[2] || Password[2] != Buffer[3] || Password[3] != Buffer[4]) {
|
||||
Buffer[0] = NAK_NOT_AUTHED;
|
||||
return NAK_FRAME_SIZE;
|
||||
}
|
||||
/* Authenticate the user */
|
||||
//RESET AUTHLIM COUNTER, CURRENTLY NOT IMPLEMENTED
|
||||
Authenticated = 1;
|
||||
/* Send the PACK value back */
|
||||
MemoryReadBlock(Buffer, CONFIG_AREA_START_ADDRESS + CONF_PACK_OFFSET, 2);
|
||||
ISO14443AAppendCRCA(Buffer, 2);
|
||||
return (2 + ISO14443A_CRCA_SIZE) * 8;
|
||||
}
|
||||
|
||||
case CMD_WRITE: {
|
||||
/* This is a write command containing 4 bytes of data that
|
||||
* should be written to the given page address. */
|
||||
uint8_t PageAddress = Buffer[1];
|
||||
/* Validation */
|
||||
if ((PageAddress < PAGE_WRITE_MIN) || (PageAddress >= PageCount)) {
|
||||
Buffer[0] = NAK_INVALID_ARG;
|
||||
return NAK_FRAME_SIZE;
|
||||
}
|
||||
if (!VerifyAuthentication(PageAddress)) {
|
||||
Buffer[0] = NAK_NOT_AUTHED;
|
||||
return NAK_FRAME_SIZE;
|
||||
}
|
||||
AppWritePage(PageAddress, &Buffer[2]);
|
||||
Buffer[0] = ACK_VALUE;
|
||||
return ACK_FRAME_SIZE;
|
||||
}
|
||||
|
||||
case CMD_COMPAT_WRITE: {
|
||||
uint8_t PageAddress = Buffer[1];
|
||||
/* Validation */
|
||||
if ((PageAddress < PAGE_WRITE_MIN) || (PageAddress >= PageCount)) {
|
||||
Buffer[0] = NAK_INVALID_ARG;
|
||||
return NAK_FRAME_SIZE;
|
||||
}
|
||||
if (!VerifyAuthentication(PageAddress)) {
|
||||
Buffer[0] = NAK_NOT_AUTHED;
|
||||
return NAK_FRAME_SIZE;
|
||||
}
|
||||
/* CRC check passed and page-address is within bounds.
|
||||
* Store address and proceed to receiving the data. */
|
||||
CompatWritePageAddress = PageAddress;
|
||||
ArmedForCompatWrite = true; //TODO:IMPLEMENT ARMED COMPAT WRITE
|
||||
Buffer[0] = ACK_VALUE;
|
||||
return ACK_FRAME_SIZE;
|
||||
}
|
||||
|
||||
|
||||
case CMD_READ_SIG: {
|
||||
/* Hardcoded response */
|
||||
memset(Buffer, 0xCA, SIGNATURE_LENGTH);
|
||||
ISO14443AAppendCRCA(Buffer, SIGNATURE_LENGTH);
|
||||
return (SIGNATURE_LENGTH + ISO14443A_CRCA_SIZE) * 8;
|
||||
}
|
||||
|
||||
//PART OF ISO STANDARD, NOT OF NTAG DATASHEET
|
||||
case CMD_HALT: {
|
||||
/* Halts the tag. According to the ISO14443, the second
|
||||
* byte is supposed to be 0. */
|
||||
if (Buffer[1] == 0) {
|
||||
/* According to ISO14443, we must not send anything
|
||||
* in order to acknowledge the HALT command. */
|
||||
State = STATE_HALT;
|
||||
return ISO14443A_APP_NO_RESPONSE;
|
||||
} else {
|
||||
Buffer[0] = NAK_INVALID_ARG;
|
||||
return NAK_FRAME_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
/* Command not handled. Switch to idle. */
|
||||
|
||||
State = STATE_IDLE;
|
||||
return ISO14443A_APP_NO_RESPONSE;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// FINITE STATE MACHINE STUFF, SHOULD BE THE VERY SIMILAR TO Mifare Ultralight
|
||||
uint16_t NTAG215AppProcess(uint8_t* Buffer, uint16_t BitCount)
|
||||
{
|
||||
uint8_t Cmd = Buffer[0];
|
||||
uint16_t ByteCount;
|
||||
|
||||
switch(State) {
|
||||
case STATE_IDLE:
|
||||
case STATE_HALT:
|
||||
FromHalt = State == STATE_HALT;
|
||||
if (ISO14443AWakeUp(Buffer, &BitCount, ATQA_VALUE, FromHalt)) {
|
||||
/* We received a REQA or WUPA command, so wake up. */
|
||||
State = STATE_READY1;
|
||||
return BitCount;
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_READY1:
|
||||
if (ISO14443AWakeUp(Buffer, &BitCount, ATQA_VALUE, FromHalt)) {
|
||||
State = FromHalt ? STATE_HALT : STATE_IDLE;
|
||||
return ISO14443A_APP_NO_RESPONSE;
|
||||
} else if (Cmd == ISO14443A_CMD_SELECT_CL1) {
|
||||
/* Load UID CL1 and perform anticollision. Since
|
||||
* MF Ultralight use a double-sized UID, the first byte
|
||||
* of CL1 has to be the cascade-tag byte. */
|
||||
uint8_t UidCL1[ISO14443A_CL_UID_SIZE] = { [0] = ISO14443A_UID0_CT };
|
||||
|
||||
MemoryReadBlock(&UidCL1[1], UID_CL1_ADDRESS, UID_CL1_SIZE);
|
||||
|
||||
if (ISO14443ASelect(Buffer, &BitCount, UidCL1, SAK_CL1_VALUE)) {
|
||||
/* CL1 stage has ended successfully */
|
||||
State = STATE_READY2;
|
||||
}
|
||||
|
||||
return BitCount;
|
||||
} else {
|
||||
/* Unknown command. Enter halt state */
|
||||
State = STATE_IDLE;
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_READY2:
|
||||
if (ISO14443AWakeUp(Buffer, &BitCount, ATQA_VALUE, FromHalt)) {
|
||||
State = FromHalt ? STATE_HALT : STATE_IDLE;
|
||||
return ISO14443A_APP_NO_RESPONSE;
|
||||
} else if (Cmd == ISO14443A_CMD_SELECT_CL2) {
|
||||
/* Load UID CL2 and perform anticollision */
|
||||
uint8_t UidCL2[ISO14443A_CL_UID_SIZE];
|
||||
|
||||
MemoryReadBlock(UidCL2, UID_CL2_ADDRESS, UID_CL2_SIZE);
|
||||
|
||||
if (ISO14443ASelect(Buffer, &BitCount, UidCL2, SAK_CL2_VALUE)) {
|
||||
/* CL2 stage has ended successfully. This means
|
||||
* our complete UID has been sent to the reader. */
|
||||
State = STATE_ACTIVE;
|
||||
}
|
||||
|
||||
return BitCount;
|
||||
} else {
|
||||
/* Unknown command. Enter halt state */
|
||||
State = STATE_IDLE;
|
||||
}
|
||||
break;
|
||||
|
||||
// Only ACTIVE state, no AUTHENTICATED state, PWD_AUTH is handled in commands.
|
||||
case STATE_ACTIVE:
|
||||
/* Preserve incoming data length */
|
||||
ByteCount = (BitCount + 7) >> 3;
|
||||
if (ISO14443AWakeUp(Buffer, &BitCount, ATQA_VALUE, FromHalt)) {
|
||||
State = FromHalt ? STATE_HALT : STATE_IDLE;
|
||||
return ISO14443A_APP_NO_RESPONSE;
|
||||
}
|
||||
/* At the very least, there should be 3 bytes in the buffer. */
|
||||
if (ByteCount < (1 + ISO14443A_CRCA_SIZE)) {
|
||||
State = STATE_IDLE;
|
||||
return ISO14443A_APP_NO_RESPONSE;
|
||||
}
|
||||
/* All commands here have CRCA appended; verify it right away */
|
||||
ByteCount -= 2;
|
||||
if (!ISO14443ACheckCRCA(Buffer, ByteCount)) {
|
||||
Buffer[0] = NAK_CRC_ERROR;
|
||||
return NAK_FRAME_SIZE;
|
||||
}
|
||||
return AppProcess(Buffer, ByteCount);
|
||||
|
||||
default:
|
||||
/* Unknown state? Should never happen. */
|
||||
break;
|
||||
}
|
||||
|
||||
/* No response has been sent, when we reach here */
|
||||
return ISO14443A_APP_NO_RESPONSE;
|
||||
}
|
||||
|
||||
// HELPER FUNCTIONS
|
||||
void NTAG215GetUid(ConfigurationUidType Uid)
|
||||
{
|
||||
/* Read UID from memory */
|
||||
MemoryReadBlock(&Uid[0], UID_CL1_ADDRESS, UID_CL1_SIZE);
|
||||
MemoryReadBlock(&Uid[UID_CL1_SIZE], UID_CL2_ADDRESS, UID_CL2_SIZE);
|
||||
}
|
||||
|
||||
void NTAG215SetUid(ConfigurationUidType Uid)
|
||||
{
|
||||
/* Calculate check bytes and write everything into memory */
|
||||
uint8_t BCC1 = ISO14443A_UID0_CT ^ Uid[0] ^ Uid[1] ^ Uid[2];
|
||||
uint8_t BCC2 = Uid[3] ^ Uid[4] ^ Uid[5] ^ Uid[6];
|
||||
|
||||
MemoryWriteBlock(&Uid[0], UID_CL1_ADDRESS, UID_CL1_SIZE);
|
||||
MemoryWriteBlock(&BCC1, UID_BCC1_ADDRESS, ISO14443A_CL_BCC_SIZE);
|
||||
MemoryWriteBlock(&Uid[UID_CL1_SIZE], UID_CL2_ADDRESS, UID_CL2_SIZE);
|
||||
MemoryWriteBlock(&BCC2, UID_BCC2_ADDRESS, ISO14443A_CL_BCC_SIZE);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* NTAG215.h
|
||||
*
|
||||
* Created on: 20.02.2019
|
||||
* Author: gcammisa
|
||||
*/
|
||||
|
||||
#ifndef NTAG215_H_
|
||||
#define NTAG215_H_
|
||||
|
||||
#include "Application.h"
|
||||
#include "ISO14443-3A.h"
|
||||
|
||||
#define NTAG215_UID_SIZE ISO14443A_UID_SIZE_DOUBLE // 7 bytes UID
|
||||
#define NTAG215_PAGE_SIZE 4 // bytes per page
|
||||
#define NTAG215_PAGES 135 // 135 pages total, from 0 to 134
|
||||
#define NTAG215_MEM_SIZE ( NTAG215_PAGE_SIZE * NTAG215_PAGES )
|
||||
|
||||
void NTAG215AppInit(void);
|
||||
void NTAG215AppReset(void);
|
||||
void NTAG215AppTask(void);
|
||||
|
||||
uint16_t NTAG215AppProcess(uint8_t* Buffer, uint16_t BitCount);
|
||||
|
||||
void NTAG215GetUid(ConfigurationUidType Uid);
|
||||
void NTAG215SetUid(ConfigurationUidType Uid);
|
||||
#endif
|
||||
@@ -51,6 +51,9 @@ static const MapEntryType PROGMEM ConfigurationMap[] = {
|
||||
#ifdef CONFIG_ISO14443A_READER_SUPPORT
|
||||
{ .Id = CONFIG_ISO14443A_READER, .Text = "ISO14443A_READER" },
|
||||
#endif
|
||||
#ifdef CONFIG_NTAG215_SUPPORT
|
||||
{ .Id = CONFIG_NTAG215, .Text = "NTAG215" },
|
||||
#endif
|
||||
#ifdef CONFIG_VICINITY_SUPPORT
|
||||
{ .Id = CONFIG_VICINITY, .Text = "VICINITY" },
|
||||
#endif
|
||||
@@ -478,6 +481,24 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
|
||||
.TagFamily = TAG_FAMILY_ISO15693
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_NTAG215_SUPPORT
|
||||
[CONFIG_NTAG215] = {
|
||||
.CodecInitFunc = ISO14443ACodecInit,
|
||||
.CodecDeInitFunc = ISO14443ACodecDeInit,
|
||||
.CodecTaskFunc = ISO14443ACodecTask,
|
||||
.ApplicationInitFunc = NTAG215AppInit,
|
||||
.ApplicationResetFunc = NTAG215AppReset,
|
||||
.ApplicationTaskFunc = NTAG215AppTask,
|
||||
.ApplicationTickFunc = ApplicationTickDummy,
|
||||
.ApplicationProcessFunc = NTAG215AppProcess,
|
||||
.ApplicationGetUidFunc = NTAG215GetUid,
|
||||
.ApplicationSetUidFunc = NTAG215SetUid,
|
||||
.UidSize = NTAG215_UID_SIZE,
|
||||
.MemorySize = NTAG215_MEM_SIZE,
|
||||
.ReadOnly = false,
|
||||
.TagFamily = TAG_FAMILY_ISO14443A
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
ConfigurationType ActiveConfiguration;
|
||||
|
||||
@@ -57,6 +57,9 @@ typedef enum {
|
||||
#ifdef CONFIG_ISO14443A_READER_SUPPORT
|
||||
CONFIG_ISO14443A_READER,
|
||||
#endif
|
||||
#ifdef CONFIG_NTAG215_SUPPORT
|
||||
CONFIG_NTAG215,
|
||||
#endif
|
||||
#ifdef CONFIG_VICINITY_SUPPORT
|
||||
CONFIG_VICINITY,
|
||||
#endif
|
||||
|
||||
@@ -17,6 +17,7 @@ SETTINGS += -DCONFIG_MF_CLASSIC_4K_7B_SUPPORT
|
||||
SETTINGS += -DCONFIG_MF_ULTRALIGHT_SUPPORT
|
||||
SETTINGS += -DCONFIG_ISO14443A_SNIFF_SUPPORT
|
||||
SETTINGS += -DCONFIG_ISO14443A_READER_SUPPORT
|
||||
SETTINGS += -DCONFIG_NTAG215_SUPPORT
|
||||
SETTINGS += -DCONFIG_VICINITY_SUPPORT
|
||||
SETTINGS += -DCONFIG_SL2S2002_SUPPORT
|
||||
SETTINGS += -DCONFIG_TITAGITSTANDARD_SUPPORT
|
||||
@@ -113,7 +114,7 @@ SRC += Terminal/Terminal.c Terminal/Commands.c Terminal/XModem.c Termina
|
||||
SRC += Codec/Codec.c Codec/ISO14443-2A.c Codec/Reader14443-2A.c Codec/SniffISO14443-2A.c Codec/Reader14443-ISR.S
|
||||
SRC += Application/MifareUltralight.c Application/MifareClassic.c Application/ISO14443-3A.c Application/Crypto1.c Application/Reader14443A.c Application/Sniff14443A.c Application/CryptoTDEA.S
|
||||
SRC += Codec/ISO15693.c
|
||||
SRC += Application/Vicinity.c Application/Sl2s2002.c Application/TITagitstandard.c Application/ISO15693-A.c Application/EM4233.c
|
||||
SRC += Application/Vicinity.c Application/Sl2s2002.c Application/TITagitstandard.c Application/ISO15693-A.c Application/EM4233.c Application/NTAG215.c
|
||||
SRC += $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS)
|
||||
LUFA_PATH = ../LUFA
|
||||
CC_FLAGS = -flto -DUSE_LUFA_CONFIG_HEADER -DFLASH_DATA_ADDR=$(FLASH_DATA_ADDR) -DFLASH_DATA_SIZE=$(FLASH_DATA_SIZE) -DSPM_HELPER_ADDR=$(SPM_HELPER_ADDR) -DBUILD_DATE=$(BUILD_DATE) -DCOMMIT_ID=\"$(COMMIT_ID)\" $(SETTINGS)
|
||||
|
||||
@@ -28,6 +28,7 @@ class Device:
|
||||
COMMAND_RED_LED = "LEDRED"
|
||||
COMMAND_THRESHOLD = "THRESHOLD"
|
||||
COMMAND_UPGRADE = "upgrade"
|
||||
COMMAND_CLEAR = "CLEAR"
|
||||
|
||||
STATUS_CODE_OK = 100
|
||||
STATUS_CODE_OK_WITH_TEXT = 101
|
||||
@@ -207,6 +208,9 @@ class Device:
|
||||
|
||||
def cmdClearLog(self):
|
||||
return self.execCmd(self.COMMAND_LOG_CLEAR)
|
||||
|
||||
def cmdClear(self):
|
||||
return self.execCmd(self.COMMAND_CLEAR)
|
||||
|
||||
def cmdLogMode(self, newLogMode):
|
||||
return self.getSetCmd(self.COMMAND_LOGMODE, newLogMode)
|
||||
|
||||
@@ -182,6 +182,10 @@ def cmdUpgrade(chameleon, arg):
|
||||
print ("Device changed into Upgrade Mode")
|
||||
exit(0)
|
||||
|
||||
def cmdClear(chameleon, arg):
|
||||
chameleon.cmdClear()
|
||||
return "Slot has been cleared"
|
||||
|
||||
# Custom class for argparse
|
||||
class CmdListAction(argparse.Action):
|
||||
def __init__(self, option_strings, dest, default=False, required=False,
|
||||
@@ -224,6 +228,7 @@ def main():
|
||||
cmdArgGroup.add_argument("-rl", "--rled", dest="rled", action=CmdListAction, metavar="FUNCTION", nargs='?', help="retrieve or set the current red led function")
|
||||
cmdArgGroup.add_argument("-th", "--threshold", dest="threshold", action=CmdListAction, nargs='?', help="retrieve or set the threshold")
|
||||
cmdArgGroup.add_argument("-ug", "--upgrade", dest="upgrade", action=CmdListAction, nargs=0, help="set the micro Controller to upgrade mode")
|
||||
cmdArgGroup.add_argument("-cl", "--clear", dest="clear", action=CmdListAction, nargs=0, help="clear the slot")
|
||||
|
||||
args = argParser.parse_args()
|
||||
|
||||
@@ -258,6 +263,7 @@ def main():
|
||||
"rled" : cmdRedLED,
|
||||
"threshold" : cmdThreshold,
|
||||
"upgrade" : cmdUpgrade,
|
||||
"clear" : cmdClear,
|
||||
}
|
||||
|
||||
if hasattr(args, "cmdList"):
|
||||
|
||||
Reference in New Issue
Block a user