This commit is contained in:
Martijn Scheepers
2025-04-24 08:54:12 +02:00
parent 63cc641f47
commit b55318e5a8
20 changed files with 1749 additions and 1623 deletions

View File

@@ -14,6 +14,7 @@ public:
private:
static void credentialNotification(Global::credentialRequest_t *credentialRequest);
static void sendStatusResponse(RP::PDUMessage *message);
static void handleSetParameter(RP::PDUMessage *message);
static void handleIndicationRequest(RP::PDUMessage *message);
static void handleSetMifareKeys(RP::PDUMessage *message);
static void handleGetParameter(RP::PDUMessage *message);

View File

@@ -19,9 +19,6 @@ public:
static bool checkCard(Global::credentialRequest_t *credentialRequest);
private:
// static RC522::DESFire mfrc522;
// static RC522::MFRC522Extended mfrc522;
static bool readACSCard(Global::credentialRequest_t *credentialRequest);
static bool readDesfireCard(Global::credentialRequest_t *credentialRequest);
static bool read14443_4(Global::credentialRequest_t *credentialRequest);

View File

@@ -17,6 +17,11 @@ namespace RC522
class DESFire
{
public:
enum DesfireStatusCodeType : uint8_t
{
WRAPPED_RESPONSE = 0x91,
};
// DESFire Status and Error Codes.
enum DesfireStatusCode : uint8_t
{
@@ -102,6 +107,9 @@ namespace RC522
{
StatusCode mfrc522;
DesfireStatusCode desfire;
//DesfireStatusCodeType sw1;
//DesfireStatusCode sw2;
} StatusCodes;
// A struct used for passing a MIFARE DESFire Version
@@ -175,7 +183,7 @@ namespace RC522
/////////////////////////////////////////////////////////////////////////////////////
// static const char *GetDesfireStatusCodeName(DesfireStatusCode code);
// virtual const char *GetStatusCodeName(RC522::StatusCode code) { return MFRC522::GetStatusCodeName(code); };
static const char *GetStatusCodesName(DESFire::StatusCodes code);
static const char *GetStatusCodesName(RC522::DesfireStatusCode code);
static const char *GetFileTypeName(mifare_desfire_file_types fileType);
static const char *GetCommunicationModeName(mifare_desfire_communication_modes communicationMode);
static bool IsStatusCodesOK(StatusCodes code);
@@ -185,10 +193,11 @@ namespace RC522
/////////////////////////////////////////////////////////////////////////////////////
static void PICC_DumpMifareDesfireMasterKey(mifare_desfire_tag *tag);
static void PICC_DumpMifareDesfireVersion(mifare_desfire_tag *tag, DESFIRE_Version_t *versionInfo);
// static void PICC_DumpMifareDesfireVersion(mifare_desfire_tag *tag, DESFIRE_Version_t *versionInfo);
static void PICC_DumpMifareDesfireVersion(TagInfo *tag, DESFIRE_Version_t *versionInfo);
static void PICC_DumpMifareDesfireApplication(mifare_desfire_tag *tag, mifare_desfire_aid_t *aid);
//static void PICC_DumpMifareDesfireApplication(mifare_desfire_tag *tag, mifare_desfire_aid_t *aid);
static void PICC_DumpMifareDesfireApplication(TagInfo *tag, mifare_desfire_aid_t *aids, uint8_t appCount);
protected:
static StatusCodes DESFIRE_Transceive(TagInfo *tag, PICC_Command cmd, uint8_t *backData, uint8_t *backLen);
@@ -198,7 +207,7 @@ namespace RC522
static StatusCodes DESFIRE_TransceiveWithData_Wrapped(TagInfo *tag, PICC_Command cmd, uint8_t *sendData, uint8_t *sendLen, uint8_t *backData, uint8_t *backLen);
static StatusCodes MIFARE_BlockExchange(mifare_desfire_tag *tag, uint8_t cmd, uint8_t *backData = NULL, uint8_t *backLen = NULL);
static StatusCodes MIFARE_BlockExchangeWithData(mifare_desfire_tag *tag, uint8_t cmd, uint8_t *sendData = NULL, uint8_t *sendLen = NULL, uint8_t *backData = NULL, uint8_t *backLen = NULL);
static StatusCodes MIFARE_BlockExchangeWithData(mifare_desfire_tag *tag, uint8_t cmd, uint8_t *sendData = NULL, uint8_t *sendLen = NULL, uint8_t *backData = NULL, uint8_t *backLen = NULL);
};
}

View File

@@ -10,52 +10,117 @@ namespace RC522
public:
enum class ISO_INSTRUCTION : uint8_t
{
ERASE_BINARY = 0x0E, //or 0F
VERIFY = 0x20, // or 21
MANAGE_CHANNEL = 0x70,
EXTERNAL_AUTHENTICATE = 0x82,
GET_CHALLENGE = 0x84,
INTERNAL_AUTHENTICATE = 0x88,
SELECT_FILE = 0xA4,
READ_BINARY = 0xB0, //or B1
READ_RECORDS = 0xB2, // B3
GET_RESPONSE = 0xC0,
ENVELOPE = 0xC2, //or C3
GET_DATA = 0xCA, //or CB
WRITE_BINARY = 0xD0, //or D1
WRITE_RECORD = 0xD2,
UPDATE_BINARY = 0xD6, //or D7
PUT_DATA = 0xDA,
UPDATE_DATA = 0xDC, //or DD
ACTIVATE_FILE = 0x44,
APPEND_RECORD = 0xE2,
Activate_File = 0x44,
Change_Reference_Data = 0x44,
Create_File = 0xE0,
Deactivate_File = 0xE0,
Delete_File = 0xE4,
Disable_Verification_Requirement = 0x26,
Enable_Verification_Requirement = 0x28,
Erase_Record = 0x0C,
General_Authenticate = 0x86, //or 87
Generate_Asymmetric_Key_Pair = 0x46,
Manage_Security_Environment = 0x22,
Perform_SCQL_Operation = 0x10,
Perform_Security_Operation = 0x2A,
Perform_Transaction_Operation = 0x12,
Reset_Retry_Counter = 0x2C,
Search_Binary = 0xA0, // or A1
Search_Record = 0xA2,
Terminate_Card_Usage = 0xFE,
Terminate_DF = 0xE6,
Terminate_EF = 0xE8,
//Terminate_EF = 0xE8,
//Terminate_EF = 0xE8,
//Terminate_EF = 0xE8,
CHANGE_REFERENCE_DATA = 0x24,
CREATE_FILE = 0xE0,
DEACTIVATE_FILE = 0x04,
DELETE_FILE = 0xE4,
DISABLE_VERIFICATION_REQUIREMENT = 0x26,
ENABLE_VERIFICATION_REQUIREMENT = 0x28,
ENVELOPE = 0xC2, // 0xC3
ERASE_BINARY = 0x0E, // 0x0F
ERASE_RECORDS = 0x0C,
EXTERNAL_AUTHENTICATE = 0x82,
GENERAL_AUTHENTICATE = 0x86, // 0x87
GENERATE_ASYMMETRIC_KEY_PAIR = 0x46,
GET_CHALLENGE = 0x84,
GET_DATA = 0xCA, // 0xCB
GET_RESPONSE = 0xC0,
INTERNAL_AUTHENTICATE = 0x88,
MANAGE_CHANNEL = 0x70,
MANAGE_SECURITY_ENVIRONMENT = 0x22,
PERFORM_SCQL_OPERATION = 0x10,
PERFORM_SECURITY_OPERATION = 0x2A,
PERFORM_TRANSACTION_OPERATION = 0x12,
PERFORM_USER_OPERATION = 0x14,
PUT_DATA = 0xDA, // 0xDB
READ_BINARY = 0xB0, // 0xB1
READ_RECORDS = 0xB2, // 0xB3
RESET_RETRY_COUNTER = 0x2C,
SEARCH_BINARY = 0xA0, // 0xA1
SEARCH_RECORD = 0xA2,
SELECT = 0xA4,
TERMINATE_CARD_USAGE = 0xFE,
TERMINATE_DF = 0xE6,
TERMINATE_EF = 0xE8,
UPDATE_BINARY = 0xD6, // 0xD7
UPDATE_RECORD = 0xDC, // 0xDD
VERIFY = 0x20, // 0x21
WRITE_BINARY = 0xD0, // 0xD1
WRITE_RECORD = 0xD2,
};
static StatusCode ISO_Enable(TagInfo *tag);
static StatusCode ISO_Select(TagInfo *tag);
// enum class ISO_STATUSCODE : uint16_t
// {
// ISO7816_OK = 0x9000,
// // 61 xx
// ISO7816_BYTES_REMAINING_00 = 0x6100, // Response bytes remaining
// // 62 xx
// ISO7816_WARNING_STATE_UNCHANGED = 0x6200, // Warning, card state unchanged
// ISO7816_DATA_CORRUPT = 0x6281, // Returned data may be corrupted
// ISO7816_FILE_EOF = 0x6282, // The end of the file has been reached before the end of reading
// ISO7816_INVALID_DF = 0x6283, // Invalid DF
// ISO7816_INVALID_FILE = 0x6284, // Selected file is not valid
// ISO7816_FILE_TERMINATED = 0x6285, // File is terminated
// // 63 xx
// ISO7816_AUTH_FAILED = 0x6300, // Authentification failed
// ISO7816_FILE_FILLED = 0x6381, // File filled up by the last write
// // 65 xx
// ISO7816_MEMORY_FULL = 0x6501, // Memory failure
// ISO7816_WRITE_MEMORY_ERR = 0x6581, // Write problem / Memory failure / Unknown mode
// // 67 xx
// ISO7816_WRONG_LENGTH = 0x6700, // Wrong length
// // 68 xx
// ISO7816_LOGICAL_CHANNEL_NOT_SUPPORTED = 0x6881, // Card does not support the operation on the specified logical channel
// ISO7816_SECURE_MESSAGING_NOT_SUPPORTED = 0x6882, // Card does not support secure messaging
// ISO7816_LAST_COMMAND_EXPECTED = 0x6883, // Last command in chain expected
// ISO7816_COMMAND_CHAINING_NOT_SUPPORTED = 0x6884, // Command chaining not supported
// // 69 xx
// ISO7816_TRANSACTION_FAIL = 0x6900, // No successful transaction executed during session
// ISO7816_SELECT_FILE_ERR = 0x6981, // Cannot select indicated file, command not compatible with file organization
// ISO7816_SECURITY_STATUS_NOT_SATISFIED = 0x6982, // Security condition not satisfied
// ISO7816_FILE_INVALID = 0x6983, // File invalid
// ISO7816_DATA_INVALID = 0x6984, // Data invalid
// ISO7816_CONDITIONS_NOT_SATISFIED = 0x6985, // Conditions of use not satisfied
// ISO7816_COMMAND_NOT_ALLOWED = 0x6986, // Command not allowed (no current EF)
// ISO7816_SM_DATA_MISSING = 0x6987, // Expected SM data objects missing
// ISO7816_SM_DATA_INCORRECT = 0x6988, // SM data objects incorrect
// ISO7816_APPLET_SELECT_FAILED = 0x6999, // Applet selection failed
// // 6A xx
// ISO7816_INVALID_P1P2 = 0x6A00, // Bytes P1 and/or P2 are invalid
// ISO7816_WRONG_DATA = 0x6A80, // Wrong data
// ISO7816_FUNC_NOT_SUPPORTED = 0x6A81, // Function not supported
// ISO7816_FILE_NOT_FOUND = 0x6A82, // File not found
// ISO7816_RECORD_NOT_FOUND = 0x6A83, // Record not found
// ISO7816_FILE_FULL = 0x6A84, // Not enough memory space in the file
// ISO7816_LC_TLV_CONFLICT = 0x6A85, // LC / TLV conlict
// ISO7816_INCORRECT_P1P2 = 0x6A86, // Incorrect parameters (P1,P2)
// ISO7816_FILE_EXISTS = 0x6A89, // File exists
// ISO7816_NOT_IMPLEMENTED = 0x6AFF, //
// // 6x 00
// ISO7816_WRONG_P1P2 = 0x6B00, // Incorrect parameters (P1,P2)
// ISO7816_CORRECT_LENGTH_00 = 0x6C00, // Correct Expected Length (Le)
// ISO7816_INS_NOT_SUPPORTED = 0x6D00, // INS value not supported
// ISO7816_CLA_NOT_SUPPORTED = 0x6E00, // CLA value not supported
// ISO7816_UNKNOWN = 0x6F00, // No precise diagnosis
// };
// static StatusCode ISO_Enable(TagInfo *tag);
// static StatusCode ISO_Select(TagInfo *tag);
static StatusCode ISO_SelectApplication(TagInfo *tag, uint8_t *aid, uint8_t *aidLen);
static StatusCode ISO_GetData(TagInfo *tag, uint8_t *backData, uint8_t *backLen);
static StatusCode ISO_PutData(TagInfo *tag, uint8_t *data, uint8_t *dataLen);
// static StatusCode MIFARE_Authenticate(PICC_Command command, uint8_t blockAddr, MIFARE_Key *key, Uid *uid);
// static void MIFARE_StopCrypto1();
// static StatusCode MIFARE_NTAG216_AUTH(uint8_t *passWord, uint8_t pACK[]);
@@ -79,9 +144,12 @@ namespace RC522
// static void MIFARE_DumpMifareClassicSectorToSerial(TagInfo *tag, MIFARE_Key *key, uint8_t sector);
// static void MIFARE_DumpMifareUltralightToSerial();
static const char *GetStatusCodesName(ISO7816StatusCode code);
private:
// static StatusCode MIFARE_TwoStepHelper(PICC_Command command, uint8_t blockAddr, int32_t data);
// static StatusCode MIFARE_Transceive(uint8_t *sendData, uint8_t sendLen, bool acceptTimeout = false);
static DESFire::StatusCodes ISO_Transceive(TagInfo *tag, ISO_INSTRUCTION ins, uint8_t *sendData, uint8_t *sendLen, uint8_t *backData, uint8_t *backLen);
static StatusCode ISO_Transceive(TagInfo *tag, ISO_INSTRUCTION ins, uint8_t *backData, uint8_t *backLen);
static StatusCode ISO_Transceive(TagInfo *tag, ISO_INSTRUCTION ins, uint8_t *sendData, uint8_t *sendLen, uint8_t *backData, uint8_t *backLen);
};
}

View File

@@ -1,6 +1,7 @@
#pragma once
#include "pico/stdlib.h"
// #include "ISO.h"
namespace RC522
{
@@ -27,6 +28,11 @@ namespace RC522
STATUS_MIFARE_NACK, // A MIFARE PICC responded with NAK.
};
enum DesfireStatusCodeType : uint8_t
{
WRAPPED_RESPONSE = 0x91,
};
// DESFire Status and Error Codes.
enum class DesfireStatusCode : uint8_t
{
@@ -54,6 +60,69 @@ namespace RC522
MF_FILE_INTEGRITY_ERROR = 0xF1 /* unrecoverable error within file */
};
enum class ISO7816StatusCode : uint16_t
{
OK = 0x9000,
// 61 xx
BYTES_REMAINING_00 = 0x6100, // Response bytes remaining
// 62 xx
WARNING_STATE_UNCHANGED = 0x6200, // Warning, card state unchanged
DATA_CORRUPT = 0x6281, // Returned data may be corrupted
FILE_EOF = 0x6282, // The end of the file has been reached before the end of reading
INVALID_DF = 0x6283, // Invalid DF
INVALID_FILE = 0x6284, // Selected file is not valid
FILE_TERMINATED = 0x6285, // File is terminated
// 63 xx
AUTH_FAILED = 0x6300, // Authentification failed
FILE_FILLED = 0x6381, // File filled up by the last write
// 65 xx
MEMORY_FULL = 0x6501, // Memory failure
WRITE_MEMORY_ERR = 0x6581, // Write problem / Memory failure / Unknown mode
// 67 xx
WRONG_LENGTH = 0x6700, // Wrong length
// 68 xx
LOGICAL_CHANNEL_NOT_SUPPORTED = 0x6881, // Card does not support the operation on the specified logical channel
SECURE_MESSAGING_NOT_SUPPORTED = 0x6882, // Card does not support secure messaging
LAST_COMMAND_EXPECTED = 0x6883, // Last command in chain expected
COMMAND_CHAINING_NOT_SUPPORTED = 0x6884, // Command chaining not supported
// 69 xx
TRANSACTION_FAIL = 0x6900, // No successful transaction executed during session
SELECT_FILE_ERR = 0x6981, // Cannot select indicated file, command not compatible with file organization
SECURITY_STATUS_NOT_SATISFIED = 0x6982, // Security condition not satisfied
FILE_INVALID = 0x6983, // File invalid
DATA_INVALID = 0x6984, // Data invalid
CONDITIONS_NOT_SATISFIED = 0x6985, // Conditions of use not satisfied
COMMAND_NOT_ALLOWED = 0x6986, // Command not allowed (no current EF)
SM_DATA_MISSING = 0x6987, // Expected SM data objects missing
SM_DATA_INCORRECT = 0x6988, // SM data objects incorrect
APPLET_SELECT_FAILED = 0x6999, // Applet selection failed
// 6A xx
INVALID_P1P2 = 0x6A00, // Bytes P1 and/or P2 are invalid
WRONG_DATA = 0x6A80, // Wrong data
FUNC_NOT_SUPPORTED = 0x6A81, // Function not supported
FILE_NOT_FOUND = 0x6A82, // File not found
RECORD_NOT_FOUND = 0x6A83, // Record not found
FILE_FULL = 0x6A84, // Not enough memory space in the file
LC_TLV_CONFLICT = 0x6A85, // LC / TLV conlict
INCORRECT_P1P2 = 0x6A86, // Incorrect parameters (P1,P2)
FILE_EXISTS = 0x6A89, // File exists
NOT_IMPLEMENTED = 0x6AFF, //
// 6x 00
WRONG_P1P2 = 0x6B00, // Incorrect parameters (P1,P2)
CORRECT_LENGTH_00 = 0x6C00, // Correct Expected Length (Le)
INS_NOT_SUPPORTED = 0x6D00, // INS value not supported
CLA_NOT_SUPPORTED = 0x6E00, // CLA value not supported
UNKNOWN = 0x6F00, // No precise diagnosis
};
// A struct used for passing a MIFARE Crypto1 key
typedef struct
{
@@ -227,12 +296,28 @@ namespace RC522
};
struct DesfireTag
{
uint8_t selected_application[MIFARE_AID_SIZE];
DesfireStatusCode status;
DesfireStatusCodeType sw1;
DesfireStatusCode sw2;
};
struct ISO7816Tag
{
ISO7816StatusCode status;
};
struct ISO14443Tag
{
uint8_t cid; // Card Identifier field, this byte is used to identify specific tags.
// It contains a 4 bit CID value as well as information on the signal strength between the reader and the tag.
uint8_t pcb; // Protocol Control Byte, this byte is used to transfer format information about each PDU block.
uint8_t nad; // Node Address field, the example firmware does not support the use of NAD.
uint8_t selected_application[MIFARE_AID_SIZE];
ISO7816Tag iso7816;
DesfireTag desfire;
};
enum class UIDSize : uint8_t
@@ -255,16 +340,16 @@ namespace RC522
struct TagInfo
{
PICC_Type piccType;
ATQA atqa; // Answer To Request acc. to ISO/IEC 14443-4
Uid uid; // Unique Identifier, Type A
Ats ats; // Answer To Select acc. to ISO/IEC 14443-4
Uid uid; // Unique Identifier, Type A
Ats ats; // Answer To Select acc. to ISO/IEC 14443-4
// For Block PCB
bool blockNumber;
DesfireTag desfire;
ISO14443Tag iso14443;
StatusCode status;
};
// A struct used for passing PCB Block

View File

@@ -57,204 +57,6 @@ namespace RP
}
};
/*=============================================================================
* Description:
* A UintVar is represented by a variable length pattern.
* The representation uses a sequence of bytes where each byte carries 7 bits.
* All bytes except the last (LSB) has bit 8 (MSb) set to 1 to indicate that there
* are more bytes. The last byte has bit 8 set to 0.
* A UintVar represent integers in the interval [0, 2^32-1],
* so the maximum number of bytes in a UintVar is 5.
*
* Examples:
* | Normal | UintVar | UintVar |
* | Decimal | Binary | Hex |
* |------------------|---MSB---------------------------------LSB----|--MSB-----------------LSB-|
* | max 4294967295 | 10001111 11111111 11111111 11111111 01111111 | 0x8F 0xFF 0xFF 0xFF 0x7F |
* | 4294967167 | 10001111 11111111 11111111 11111110 01111111 | 0x8F 0xFF 0xFF 0xFE 0x7F |
* | 8192 | 11000000 00000000 | 0xC0 0x00 |
* | 1000 | 10000111 01101000 | 0x87 0x68 |
* | 255 | 10000001 01111111 | 0x81 0x7F |
* | 128 | 10000001 00000000 | 0x81 0x00 |
* | 127 | 01111111 | 0x7F |
* | 1 | 00000001 | 0x01 |
* | min 0 | 00000000 | 0x00 |
*
* In your machine, treat a UintVar as a uint32.
*===========================================================================*/
// struct AadpIpUintVar : PDUDataType
// {
// uint32_t value;
// uint8_t numBytes;
// void parseMessage(std::vector<uint8_t> &bytes, uint8_t &idx) override
// {
// // At least one byte is always used
// value = bytes[idx];
// numBytes = 1;
// idx++;
// if (((value & 0x80) != 0))
// {
// uint32_t c;
// value &= 0x7F;
// do
// {
// c = bytes[idx];
// value = (value << 7) + (c & 0x7F);
// ++numBytes;
// idx++;
// } while ((c & 0x80) != 0);
// }
// }
// void createMessage(std::vector<uint8_t> &buff) override
// {
// if (value <= 127)
// {
// buff.push_back(value);
// return;
// }
// std::vector<uint8_t> bytes;
// bool first = true;
// while (first || value > 0)
// {
// uint8_t lower7bits;
// if (first == true)
// lower7bits = (uint8_t)(value & 0x7f);
// else
// lower7bits = (uint8_t)(value | 0x80);
// first = false;
// value >>= 7;
// bytes.push_back(lower7bits);
// if (value <= 127)
// {
// lower7bits = (uint8_t)(value | 128);
// bytes.push_back(lower7bits);
// break;
// }
// }
// std::reverse(bytes.begin(), bytes.end());
// buff.insert(buff.end(), bytes.begin(), bytes.end());
// }
// };
/*=============================================================================
* DataType:
* AadpIpInt16
* previously called Short in documentation.
* (but "Short" might be different sizes depending on machine and compiler)
*
* Description:
* An AadpIpInt16 is a signed integer represented by 2 bytes.
* An AadpIpInt16 represent integers in the interval [-2^15 , 2^15 -1]
* i.e. [-32768, 32767 ]
*===========================================================================*/
// struct AadpIpInt16 : PDUDataType
// {
// int16_t value;
// AadpIpInt16(){}
// AadpIpInt16(int16_t val)
// {
// value = val;
// }
// void parseMessage(std::vector<uint8_t> &bytes, uint8_t &idx) override
// {
// value = (bytes[idx] << 8);
// idx++;
// value = value + bytes[idx];
// idx++;
// }
// void parseMessage(uint8_t bytes[], uint8_t idx){
// value = (bytes[idx] << 8);
// idx++;
// value = value + bytes[idx];
// };
// void createMessage(std::vector<uint8_t> &buff) override
// {
// buff.push_back(value >> 8);
// buff.push_back(value & 0xFF);
// }
// };
/*=============================================================================
* DataType:
* AadpIpGenericId
*
* Description:
* Representation of AADP IP Generic ID.
* It is a lenght prefixed string with up to 15 ASCII characters that can be used for naming
*===========================================================================*/
// struct AadpIpGenericId : PDUDataType
// {
// AadpIpUintVar len;
// std::vector<uint8_t> data{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
// AadpIpGenericId()
// {
// len.value = 6;
// }
// void parseMessage(std::vector<uint8_t> &bytes, uint8_t &idx) override
// {
// len.parseMessage(bytes, idx);
// std::vector<uint8_t>::iterator start = bytes.begin() + idx;
// std::vector<uint8_t>::iterator end = start + len.value;
// data = std::vector<uint8_t>(start, end);
// idx = idx + len.value;
// }
// void createMessage(std::vector<uint8_t> &buff) override
// {
// len.createMessage(buff);
// buff.insert(buff.end(), data.begin(), data.end());
// }
// };
/*=============================================================================
* DataType:
* RPString
*
* Description:
* Representation of RP String.
* a UTF-8 char
*
*===========================================================================*/
struct RPString : PDUDataType
{
uint8_t len;
std::string data;
RPString() {}
RPString(std::string &text)
{
data = text;
len = text.size();
}
void parseMessage(std::vector<uint8_t> &bytes, uint8_t &idx) override
{
len = bytes[idx];
idx++;
std::vector<uint8_t>::iterator start = bytes.begin() + idx;
std::vector<uint8_t>::iterator end = start + len;
data.assign(start, end);
idx = idx + len;
}
void createMessage(std::vector<uint8_t> &buff) override
{
buff.push_back(len);
buff.insert(buff.end(), data.begin(), data.end());
}
};
/*=============================================================================
* DataType:
* AadpIpByteArray
@@ -283,363 +85,4 @@ namespace RP
buff.insert(buff.end(), data.begin(), data.begin() + len);
}
};
/*=============================================================================
* DataType:
* AadpIpBool
*
* Description:
* Representation of AADP IP Booleans.
* 0x00 = false
* 0xFF = true
*===========================================================================*/
// struct AadpIpBool : PDUDataType
// {
// bool value = false;
// AadpIpBool(){}
// AadpIpBool(bool val)
// {
// value = val;
// }
// void parseMessage(std::vector<uint8_t> &bytes, uint8_t &idx) override
// {
// if (bytes[idx] == 0xFF)
// value = true;
// idx++;
// }
// void createMessage(std::vector<uint8_t> &buff) override
// {
// if (value)
// buff.push_back(0xFF);
// else
// buff.push_back(0x00);
// }
// };
/*=============================================================================
* DataType:
* AadpIpDeviceID
*
* Description:
* Representation of AADP IP Device ID.
* Device ID is always 12 bytes
*===========================================================================*/
// struct AadpIpDeviceId : PDUDataType
// {
// std::vector<uint8_t> id{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
// void parseMessage(std::vector<uint8_t> &bytes, uint8_t &idx) override
// {
// std::vector<uint8_t>::iterator start = bytes.begin() + idx;
// std::vector<uint8_t>::iterator end = start + AADP_IP_DEVICE_ID_LEN;
// id.assign(start, end);
// idx = idx + AADP_IP_DEVICE_ID_LEN;
// }
// void createMessage(std::vector<uint8_t> &buff) override
// {
// buff.insert(buff.end(), id.begin(), id.end());
// }
// };
/*=============================================================================
* DataType:
* AadpIpVersion
*
* Description:
* Representation of AADP IP Version.
*===========================================================================*/
// struct AadpIpVersion : PDUDataType
// {
// uint8_t major;
// uint8_t minor;
// uint16_t patch;
// void parseMessage(std::vector<uint8_t> &bytes, uint8_t &idx) override
// {
// major = bytes[idx];
// idx++;
// minor = bytes[idx];
// idx++;
// patch = bytes[idx];
// idx++;
// }
// void createMessage(std::vector<uint8_t> &buff) override
// {
// buff.push_back(major);
// buff.push_back(minor);
// buff.push_back(patch);
// }
// };
/*=============================================================================
* DataType:
* AadpIpCredentialBlock
*
* Description:
* Representation of AADP IP AadpIpCredentialBlock.
*===========================================================================*/
// struct AadpIpCredentialBlock : PDUDataType
// {
// AadpIpCredentialBlockType credentialBlockType; // Defines how to interpret the Data field.
// AadpIpInt16 length; // Number of bytes in credential array
// AadpIpUintVar validBits; // Number of valid bits of last data byte in array
// //uint8_t data[AADP_IP_CREDENTIAL_BLOCK_DATA_MAX_LEN]; // Credential data array
// std::vector<uint8_t> data;
// void parseMessage(std::vector<uint8_t> &bytes, uint8_t &idx) override
// {
// //2 byte enum
// AadpIpInt16 type;
// type.parseMessage(bytes, idx);
// credentialBlockType = static_cast<AadpIpCredentialBlockType>(type.value);
// length.parseMessage(bytes, idx);
// validBits.parseMessage(bytes, idx);
// std::vector<uint8_t>::iterator start = bytes.begin() + idx;
// std::vector<uint8_t>::iterator end = start + length.value;
// data.assign(start, end);
// idx = idx + length.value;
// }
// void createMessage(std::vector<uint8_t> &buff) override
// {
// buff.push_back(static_cast<uint8_t>((static_cast<uint16_t>(credentialBlockType) >> 8))); //block type
// buff.push_back(static_cast<uint8_t>((static_cast<uint16_t>(credentialBlockType) & 0x00FF))); //block type
// length.createMessage(buff);
// buff.push_back(0x08); //valid bits
// buff.insert(buff.end(), std::begin(data), std::begin(data) + length.value);
// }
// };
/*=============================================================================
* DataType:
* AadpIpDeviceGroupInfo
*
* Description:
* Representation of AADP IP AadpIpDeviceGroupInfo.
*===========================================================================*/
// struct AadpIpDeviceGroupInfo : PDUDataType
// {
// AadpIpGenericId deviceGroupId;
// AadpIpString name; // (optional) Name of this device group
// AadpIpString location; // (optional) Location of this device group
// void parseMessage(std::vector<uint8_t> &bytes, uint8_t &idx) override
// {
// deviceGroupId.parseMessage(bytes, idx);
// name.parseMessage(bytes, idx);
// location.parseMessage(bytes, idx);
// }
// void createMessage(std::vector<uint8_t> &buff) override
// {
// deviceGroupId.createMessage(buff);
// name.createMessage(buff);
// location.createMessage(buff);
// }
// };
/*=============================================================================
* DataType:
* AadpIpTime
*
* Description:
* Representation of AADP IP AadpIpTime.
*===========================================================================*/
// struct AadpIpTime : PDUDataType
// {
// AadpIpUintVar timeStamp; // Time is in UTC and seconds since 2000-01-01.
// AadpIpInt16 timeZone; // Time zone is specified in quarters of an hour
// // from UTC/GMT +0.
// // (Stockholm is (UTC +1) -> +4 )
// // (San Francisco is (UTC -7) -> -28)
// void parseMessage(std::vector<uint8_t> &bytes, uint8_t &idx) override
// {
// timeStamp.parseMessage(bytes, idx);
// timeZone.parseMessage(bytes, idx);
// }
// void createMessage(std::vector<uint8_t> &buff) override
// {
// timeStamp.createMessage(buff);
// timeZone.createMessage(buff);
// }
// };
/*=============================================================================
* DataType:
* AadpIpTiming
*
* Description:
* Representation of AADP IP AadpIpTiming.
* The time specified in decimal seconds i.e. 1/10s of seconds.
* This value is only relevant if Mode is TIME.
* The field is either way included in the message.
*===========================================================================*/
// struct AadpIpTiming : PDUDataType
// {
// AadpIpTimingMode mode;
// AadpIpUintVar time;
// void parseMessage(std::vector<uint8_t> &bytes, uint8_t &idx) override
// {
// mode = static_cast<AadpIpTimingMode>(bytes[idx]);
// idx++;
// time.parseMessage(bytes, idx);
// }
// void createMessage(std::vector<uint8_t> &buff) override
// {
// buff.push_back(static_cast<uint8_t>(mode));
// time.createMessage(buff);
// }
// };
/*=============================================================================
* DataType:
* AadpIpDtcId
*
* Description:
* The DtcInfo describes the identity and current status of a DTC.
*
* note:
* AadpIpDtcId is encoded as a UintVar "on the wire"
*===========================================================================*/
// typedef struct
// {
// AadpIpDtcIdCategoryAndType categoryAndType;
// AadpIpDtcIdSource source;
// uint8_t enumAndReserved; // high nibble used as counter if there are more than one thing with same catergory, type and source e.g. LEDs of different colour
// } AadpIpDtcId;
/*=============================================================================
* DataType:
* AadpIpDtcInfo
*
* Description:
* The DtcInfo describes the identity and current status of a DTC.
*===========================================================================*/
// struct AadpIpDtcInfo : PDUDataType
// {
// AadpIpUintVar dtcId; // Encoded as UintVar "on the wire", The diagnostic trouble code. see doc [ ST-001033 Diagnostic Trouble Code Identifiers ] for details
// //AadpIpDtcId dtcId; // Data type AadpIpDtcId is used internally
// AadpIpUintVar time; // Time when DTC was recorded. Time is in seconds since the 1970-01-01.
// AadpIpBool isFailing; // False if test is currently not failing.
// // True if test is currently failing.
// AadpIpBool hasFailed; // False if test has not failed since last clear.
// // True if test has failed at least once since last clear. (test might not be failing right now)
// AadpIpBool testCompleted; // False if test has never been completed
// // True if test has completed at least once.
// void parseMessage(std::vector<uint8_t> &bytes, uint8_t &idx) override
// {
// dtcId.parseMessage(bytes, idx);
// time.parseMessage(bytes, idx);
// isFailing.parseMessage(bytes, idx);
// hasFailed.parseMessage(bytes, idx);
// testCompleted.parseMessage(bytes, idx);
// }
// void createMessage(std::vector<uint8_t> &buff) override
// {
// dtcId.createMessage(buff);
// time.createMessage(buff);
// isFailing.createMessage(buff);
// hasFailed.createMessage(buff);
// testCompleted.createMessage(buff);
// }
// };
/*=============================================================================
* DataType:
* AadpIpDeviceDefinition
*
* Description:
* Representation of AADP IP AadpIpDeviceDefinition.
*===========================================================================*/
// struct AadpIpDeviceDefinition : PDUDataType
// {
// AadpIpDeviceId ownDeviceId;
// AadpIpDeviceId hostDeviceId;
// AadpIpProductClass productClass;
// void parseMessage(std::vector<uint8_t> &bytes, uint8_t &idx) override
// {
// ownDeviceId.parseMessage(bytes, idx);
// hostDeviceId.parseMessage(bytes, idx);
// productClass = static_cast<AadpIpProductClass>(bytes[idx]);
// idx++;
// }
// void createMessage(std::vector<uint8_t> &buff) override
// {
// ownDeviceId.createMessage(buff);
// hostDeviceId.createMessage(buff);
// buff.push_back(static_cast<uint8_t>(productClass));
// }
// };
/*=============================================================================
* DataType:
* AadpIpActivatorInfo
*
* Description:
* Representation of AADP IP AadpIpActivatorInfo.
*===========================================================================*/
// struct AadpIpActivatorInfo : PDUDataType
// {
// AadpIpDeviceId deviceId;
// AadpIpUintVar activatorId;
// AadpIpActivatorState activatorState;
// void parseMessage(std::vector<uint8_t> &bytes, uint8_t &idx) override
// {
// deviceId.parseMessage(bytes, idx);
// activatorId.parseMessage(bytes, idx);
// activatorState = static_cast<AadpIpActivatorState>(bytes[idx]);
// idx++;
// }
// void createMessage(std::vector<uint8_t> &buff) override
// {
// deviceId.createMessage(buff);
// activatorId.createMessage(buff);
// buff.push_back(static_cast<uint8_t>(activatorState));
// }
// };
/*
* Packet Sequence Number is used for two purposes…
* 1. …to keep track of which Notification belongs to which Command. This is necessary because some commands
* (e.g. GetAuditTrail ) can take some time for a device to handle,
* so other messages might be sent between the Command and the Notification
* 2. …to allow for the EAC and device to request resends and keep track of which messages has been received.
* Usage:
* Notifications:
* Spontaneous Notifications has number zero, [0].
* Response Notifications uses the same number as the Command.
* Commands:
* New read sequence can start with any number in range [1, 65 535].
* Not stepping the number means an expected Notification was not received.
* Stepping the number means last Notification was received.
* A step can be one or greater.
* I.e. simultaneous commands to different devices can share the same counter.
*/
// typedef uint16_t AadpIpPacketSequenceNumber;
/*
* note:
* 0xFF FF FF FF (4 294 967 295) = will never expire
* If time must be truncated in device; it shall be to the nearest bigger unit.
* e.g.
* 1 second is truncated to 1 minute.
*/
// typedef AadpIpUintVar AadpIpCredentialExpireLimit;
}
// Header include guard -------------------------------------------------------
}

View File

@@ -1,40 +1,4 @@
#pragma once
/* The frame boundary octet is 01111110, (7E in hexadecimal notation) */
// #define FRAME_BOUNDARY_OCTET 0x7E
/* A "control escape octet", has the bit sequence '01111101', (7D hexadecimal) */
// #define CONTROL_ESCAPE_OCTET 0x7D
// #define DLE 0x7E
// #define STX 0x02
// #define ETX 0x03
const uint8_t FLAG = 0x7E; // flag byte
const uint8_t ESCAPE = 0x7D; // escape byte
// Version of protocol defined by this suite of files
// #define RP_VERSION_MAJOR 1
// #define RP_VERSION_MINOR 5
// #define RP_VERSION_PATCH 0
// Maximum number of bytes occupied by an AADP IP encoded UintVar.
// #define AADP_IP_UINTVAR_MAX_LEN 5
// Maximum number of characters in an AADP IP String.
// #define AADP_IP_STRING_MAX_CHARS 128
// Maximum number of characters of a Device Id.
// #define AADP_IP_DEVICE_ID_LEN 12
// Maximum number of characters of a Generic Id.
// #define AADP_IP_GENERIC_ID_MAX_CHARS 15
// Maximum number of credential blocks in a CredentialNotification
// #define AADP_IP_MAX_NR_OF_CREDENTIAL_BLOCKS 8
// #define AADP_IP_CREDENTIAL_BLOCK_DATA_MAX_LEN 80
// #define AADP_MANUAL_OPEN_ID 1
// #define AADP_EMERGENCY_INSIDE_ID 10
// #define AADP_EMERGENCY_OUTSIDE_ID 20
const uint8_t ESCAPE = 0x7D; // escape byte

View File

@@ -25,17 +25,14 @@ namespace RP
RESTART = 0x09,
};
/*
* See doc. [ ST-001577 Credential data specification ] for details
* */
enum class RPCredentialSourceDetails
{
CREDENTIAL_SOURCE_DETAILS_MIFARE = 0x01,
CREDENTIAL_SOURCE_DETAILS_MIFARE_CLASSIC_1K = 0x02,
CREDENTIAL_SOURCE_DETAILS_MIFARE_CLASSIC_4K = 0x03,
CREDENTIAL_SOURCE_DETAILS_MIFARE_ULTRALIGHT = 0x04,
CREDENTIAL_SOURCE_DETAILS_MIFARE_DESFIRE = 0x05,
CREDENTIAL_SOURCE_DETAILS_MIFARE_PLUS = 0x06,
MIFARE = 0x01,
MIFARE_CLASSIC_1K = 0x02,
MIFARE_CLASSIC_4K = 0x03,
MIFARE_ULTRALIGHT = 0x04,
MIFARE_DESFIRE = 0x05,
MIFARE_PLUS = 0x06,
// CREDENTIAL_SOURCE_DETAILS_ICLASS = 0x0200,
@@ -66,30 +63,13 @@ namespace RP
// CREDENTIAL_SOURCE_DETAILS_STID_BLE = 0x23
};
/*
* See doc. [ ST-001577 Credential data specification ] for details
* */
// enum class AadpIpCredentialBlockType
// {
// UNKNOWN = 0x0000,
// CUSTOM = 0x0010,
// SOURCE_DETAILS = 0x0100,
// MIFARE_UID = 0x0200,
// DYNAMIC_DATA = 0x0201,
// ICLASS_ACCESS_ID = 0x0300,
// ISO14443B_UID = 0x0400,
// ISO15693_UID = 0x0500,
// LEGIC_UID = 0x0600,
// SEOS_CREDENTIAL = 0x0700,
// PICOPASS_SERIAL_NUMBER = 0x0900,
// STID_DATA = 0x0A00
// };
enum class RPParamterType
{
UNKNOWN = 0,
SOFTWAREVERSION = 1,
UNIQUEID = 2,
MIFAREKEY_A = 3,
MIFAREKEY_B = 4,
};
enum class RPStatus
@@ -149,14 +129,14 @@ namespace RP
// EVERYLEDON = 0x39,
};
enum class RpParseErrors
enum class RPParseErrors
{
OK = 0,
NO_DATA = -1,
START_FLAG_MISSING = -2,
END_FLAG_MISSING = -3,
CRC_FAILED = -4,
UNKNOWN_PDU = -5
UNKNOWN_PDU = -5,
DATA_TO_SHORT = -6
};
}

View File

@@ -98,7 +98,7 @@ namespace RP
};
/*
* Message: 2 PollResponse
* Message: 2 StatusResponse
* Direction: To Controller
*/
struct StatusResponse final : PDUMessage
@@ -280,7 +280,7 @@ namespace RP
};
/*
* Message: 9 SetParameterResponse
* Message: 9 GetParameterResponse
* Direction: To Controller
* Answer: none
*/
@@ -372,11 +372,11 @@ namespace RP
return destuffedData;
}
RpParseErrors ParseMessage(std::vector<uint8_t> bytes)
RPParseErrors ParseMessage(std::vector<uint8_t> bytes)
{
idx = 0;
if (bytes.empty())
return RpParseErrors::NO_DATA;
return RPParseErrors::NO_DATA;
// if( bytes.at(0) != FLAG)
// return RpParseErrors::START_FLAG_MISSING;
@@ -391,7 +391,7 @@ namespace RP
if (bytes.back() != crc)
{
// printf("crc failed\r\n");
return RpParseErrors::CRC_FAILED;
return RPParseErrors::CRC_FAILED;
}
bytes = byteDestuffing(bytes);
@@ -430,7 +430,7 @@ namespace RP
break;
default:
return RpParseErrors::UNKNOWN_PDU;
return RPParseErrors::UNKNOWN_PDU;
break;
}
@@ -441,7 +441,7 @@ namespace RP
message->parseMessage(bytes, idx);
return RpParseErrors::OK;
return RPParseErrors::OK;
}
};