Created
January 9, 2020 13:34
-
-
Save z4yx/1f3c0c06076c810ec7da5c8f19575d2e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/**************** from pn53x-internal.h **********/ | |
// Register addresses | |
#define PN53X_REG_Control_switch_rng 0x6106 | |
#define PN53X_REG_CIU_Mode 0x6301 | |
#define PN53X_REG_CIU_TxMode 0x6302 | |
#define PN53X_REG_CIU_RxMode 0x6303 | |
#define PN53X_REG_CIU_TxControl 0x6304 | |
#define PN53X_REG_CIU_TxAuto 0x6305 | |
#define PN53X_REG_CIU_TxSel 0x6306 | |
#define PN53X_REG_CIU_RxSel 0x6307 | |
#define PN53X_REG_CIU_RxThreshold 0x6308 | |
#define PN53X_REG_CIU_Demod 0x6309 | |
#define PN53X_REG_CIU_FelNFC1 0x630A | |
#define PN53X_REG_CIU_FelNFC2 0x630B | |
#define PN53X_REG_CIU_MifNFC 0x630C | |
#define PN53X_REG_CIU_ManualRCV 0x630D | |
#define PN53X_REG_CIU_TypeB 0x630E | |
// #define PN53X_REG_- 0x630F | |
// #define PN53X_REG_- 0x6310 | |
#define PN53X_REG_CIU_CRCResultMSB 0x6311 | |
#define PN53X_REG_CIU_CRCResultLSB 0x6312 | |
#define PN53X_REG_CIU_GsNOFF 0x6313 | |
#define PN53X_REG_CIU_ModWidth 0x6314 | |
#define PN53X_REG_CIU_TxBitPhase 0x6315 | |
#define PN53X_REG_CIU_RFCfg 0x6316 | |
#define PN53X_REG_CIU_GsNOn 0x6317 | |
#define PN53X_REG_CIU_CWGsP 0x6318 | |
#define PN53X_REG_CIU_ModGsP 0x6319 | |
#define PN53X_REG_CIU_TMode 0x631A | |
#define PN53X_REG_CIU_TPrescaler 0x631B | |
#define PN53X_REG_CIU_TReloadVal_hi 0x631C | |
#define PN53X_REG_CIU_TReloadVal_lo 0x631D | |
#define PN53X_REG_CIU_TCounterVal_hi 0x631E | |
#define PN53X_REG_CIU_TCounterVal_lo 0x631F | |
// #define PN53X_REG_- 0x6320 | |
#define PN53X_REG_CIU_TestSel1 0x6321 | |
#define PN53X_REG_CIU_TestSel2 0x6322 | |
#define PN53X_REG_CIU_TestPinEn 0x6323 | |
#define PN53X_REG_CIU_TestPinValue 0x6324 | |
#define PN53X_REG_CIU_TestBus 0x6325 | |
#define PN53X_REG_CIU_AutoTest 0x6326 | |
#define PN53X_REG_CIU_Version 0x6327 | |
#define PN53X_REG_CIU_AnalogTest 0x6328 | |
#define PN53X_REG_CIU_TestDAC1 0x6329 | |
#define PN53X_REG_CIU_TestDAC2 0x632A | |
#define PN53X_REG_CIU_TestADC 0x632B | |
// #define PN53X_REG_- 0x632C | |
// #define PN53X_REG_- 0x632D | |
// #define PN53X_REG_- 0x632E | |
#define PN53X_REG_CIU_RFlevelDet 0x632F | |
#define PN53X_REG_CIU_SIC_CLK_en 0x6330 | |
#define PN53X_REG_CIU_Command 0x6331 | |
#define PN53X_REG_CIU_CommIEn 0x6332 | |
#define PN53X_REG_CIU_DivIEn 0x6333 | |
#define PN53X_REG_CIU_CommIrq 0x6334 | |
#define PN53X_REG_CIU_DivIrq 0x6335 | |
#define PN53X_REG_CIU_Error 0x6336 | |
#define PN53X_REG_CIU_Status1 0x6337 | |
#define PN53X_REG_CIU_Status2 0x6338 | |
#define PN53X_REG_CIU_FIFOData 0x6339 | |
#define PN53X_REG_CIU_FIFOLevel 0x633A | |
#define PN53X_REG_CIU_WaterLevel 0x633B | |
#define PN53X_REG_CIU_Control 0x633C | |
#define PN53X_REG_CIU_BitFraming 0x633D | |
#define PN53X_REG_CIU_Coll 0x633E | |
/**************** end pn53x-internal.h **********/ | |
#include <inttypes.h> | |
#include <signal.h> | |
#include <stddef.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <nfc/nfc-types.h> | |
#include <nfc/nfc.h> | |
int pn53x_read_register(struct nfc_device *pnd, uint16_t ui16RegisterAddress, | |
uint8_t *ui8Value); | |
int pn53x_write_register(struct nfc_device *pnd, | |
const uint16_t ui16RegisterAddress, | |
const uint8_t ui8SymbolMask, const uint8_t ui8Value); | |
static nfc_device *pnd = NULL; | |
static nfc_context *context; | |
//========= | |
#define CRC_A 1 | |
#define CRC_B 2 | |
#define BYTE unsigned char | |
unsigned short UpdateCrc(unsigned char ch, unsigned short *lpwCrc) { | |
ch = (ch ^ (unsigned char)((*lpwCrc) & 0x00FF)); | |
ch = (ch ^ (ch << 4)); | |
*lpwCrc = (*lpwCrc >> 8) ^ ((unsigned short)ch << 8) ^ | |
((unsigned short)ch << 3) ^ ((unsigned short)ch >> 4); | |
return (*lpwCrc); | |
} | |
void ComputeCrc(int CRCType, char *Data, int Length, BYTE *TransmitFirst, | |
BYTE *TransmitSecond) { | |
unsigned char chBlock; | |
unsigned short wCrc; | |
switch (CRCType) { | |
case CRC_A: | |
wCrc = 0x6363; /* ITU-V.41 */ | |
break; | |
case CRC_B: | |
wCrc = 0xFFFF; /* ISO/IEC 13239 (formerly ISO/IEC 3309) */ | |
break; | |
default: | |
return; | |
} | |
do { | |
chBlock = *Data++; | |
UpdateCrc(chBlock, &wCrc); | |
} while (--Length); | |
if (CRCType == CRC_B) | |
wCrc = ~wCrc; /* ISO/IEC 13239 (formerly ISO/IEC 3309) */ | |
*TransmitFirst = (BYTE)(wCrc & 0xFF); | |
*TransmitSecond = (BYTE)((wCrc >> 8) & 0xFF); | |
return; | |
} | |
uint16_t calc_crc_b(BYTE BuffCRC_B[], int len) { | |
int i; | |
// BYTE BuffCRC_B[] = {0x0b,0x00,0x00,0xb0,0x95,0x00,0x0f,}; | |
unsigned short Crc; | |
BYTE First, Second; | |
// printf("CRC-16 reference results ISO/IEC 14443-3\n"); | |
// printf("Crc-16 G(x) = x^16 + x^12 + x^5 + 1\n\n"); | |
// printf("CRC_A of [ "); | |
// for(i=0; i<2; i++) | |
// printf("%02X ",BuffCRC_A[i]); | |
// ComputeCrc(CRC_A, BuffCRC_A, 2, &First, &Second); | |
// printf("] Transmitted: %02X then %02X.\n", First, Second); | |
printf("CRC_B of [ "); | |
for (i = 0; i < len; i++) | |
printf("%02X ", BuffCRC_B[i]); | |
ComputeCrc(CRC_B, BuffCRC_B, len, &First, &Second); | |
printf("] Transmitted: %02X then %02X.\n", First, Second); | |
return ((uint16_t)First << 8) | Second; | |
} | |
//============= | |
int main(int argc, const char *argv[]) { | |
// Display libnfc version | |
const char *acLibnfcVersion = nfc_version(); | |
printf("%s uses libnfc %s\n", argv[0], acLibnfcVersion); | |
nfc_target nt; | |
int res = 0; | |
nfc_init(&context); | |
if (context == NULL) { | |
printf("Unable to init libnfc (malloc)"); | |
exit(EXIT_FAILURE); | |
} | |
pnd = nfc_open(context, NULL); | |
if (pnd == NULL) { | |
printf("%s", "Unable to open NFC device."); | |
nfc_exit(context); | |
exit(EXIT_FAILURE); | |
} | |
if (nfc_initiator_init(pnd) < 0) { | |
nfc_perror(pnd, "nfc_initiator_init"); | |
nfc_close(pnd); | |
nfc_exit(context); | |
exit(EXIT_FAILURE); | |
} | |
printf("NFC reader: %s opened\n", nfc_device_get_name(pnd)); | |
// const uint8_t uiPollNr = 255; | |
// const uint8_t uiPeriod = 1; | |
// const nfc_modulation nmModulations[5] = { | |
// {.nmt = NMT_ISO14443A, .nbr = NBR_106}, | |
// {.nmt = NMT_ISO14443B, .nbr = NBR_106}, | |
// {.nmt = NMT_FELICA, .nbr = NBR_212}, | |
// {.nmt = NMT_FELICA, .nbr = NBR_424}, | |
// {.nmt = NMT_JEWEL, .nbr = NBR_106}, | |
// }; | |
// const size_t szModulations = 1; | |
// for (;;) { | |
// printf("NFC device will poll during %ld ms (%u pollings of %lu ms for " | |
// "%" PRIdPTR " modulations)\n", | |
// (unsigned long)uiPollNr * szModulations * uiPeriod * 150, | |
// uiPollNr, (unsigned long)uiPeriod * 150, szModulations); | |
// if ((res = nfc_initiator_poll_target(pnd, nmModulations, szModulations, | |
// uiPollNr, uiPeriod, &nt)) < 0) { | |
// nfc_perror(pnd, "nfc_initiator_poll_target"); | |
// continue; | |
// // nfc_close(pnd); | |
// // nfc_exit(context); | |
// // exit(EXIT_FAILURE); | |
// } | |
// if (res > 0) { | |
// // print_nfc_target(&nt, verbose); | |
// printf("Waiting for card removing..."); | |
// fflush(stdout); | |
// while (0 == nfc_initiator_target_is_present(pnd, NULL)) { | |
// } | |
// nfc_perror(pnd, "nfc_initiator_target_is_present"); | |
// printf("done.\n"); | |
// } else { | |
// printf("No target found.\n"); | |
// } | |
// } | |
printf("nfc_device_set_property_bool(NP_EASY_FRAMING)=%d\n", | |
nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, false)); | |
// pn512_reg_write(TModeReg, | |
// 0x82); // time slot = 13.56M / (2 * 0x2A5 + 1) = 100us | |
// pn512_reg_write(TPrescalerReg, 0xA5); | |
// pn512_reg_set(ControlReg, 0x10); | |
// pn512_reg_write(RFCfgReg, 0x59); | |
// pn512_reg_set(TxAutoReg, FullASK); | |
// pn512_reg_write(ModeReg, ISO14443aCRC); | |
// pn512_reg_write(TxControlReg, AntennaOn); | |
printf("pn53x_write_register(PN53X_REG_CIU_TMode)=%d\n", | |
pn53x_write_register(pnd, PN53X_REG_CIU_TMode, 0xff, 0x82)); | |
printf("pn53x_write_register(PN53X_REG_CIU_TPrescaler)=%d\n", | |
pn53x_write_register(pnd, PN53X_REG_CIU_TPrescaler, 0xff, 0xA5)); | |
printf("pn53x_write_register(PN53X_REG_CIU_Control)=%d\n", | |
pn53x_write_register(pnd, PN53X_REG_CIU_Control, 0x10, 0x10)); | |
printf("pn53x_write_register(PN53X_REG_CIU_RFCfg)=%d\n", | |
pn53x_write_register(pnd, PN53X_REG_CIU_RFCfg, 0xff, 0x59)); | |
printf("pn53x_write_register(PN53X_REG_CIU_TxAuto)=%d\n", | |
pn53x_write_register(pnd, PN53X_REG_CIU_TxAuto, 1 << 6, 1 << 6)); | |
printf("pn53x_write_register(PN53X_REG_CIU_Mode)=%d\n", | |
pn53x_write_register(pnd, PN53X_REG_CIU_Mode, 0xff, 0x39)); | |
printf("pn53x_write_register(PN53X_REG_CIU_TxControl)=%d\n", | |
pn53x_write_register(pnd, PN53X_REG_CIU_TxControl, 0xff, 0x83)); | |
printf("pn53x_write_register(PN53X_REG_CIU_TxMode)=%d\n", | |
pn53x_write_register(pnd, PN53X_REG_CIU_TxMode, (1 << 7), 0)); | |
printf("pn53x_write_register(PN53X_REG_CIU_RxMode)=%d\n", | |
pn53x_write_register(pnd, PN53X_REG_CIU_RxMode, (1 << 7), 0)); | |
printf("pn53x_write_register(PN53X_REG_CIU_TReloadVal_hi)=%d\n", | |
pn53x_write_register(pnd, PN53X_REG_CIU_TReloadVal_hi, 0xff, 0)); | |
printf("pn53x_write_register(PN53X_REG_CIU_TReloadVal_lo)=%d\n", | |
pn53x_write_register(pnd, PN53X_REG_CIU_TReloadVal_lo, 0xff, 0x32)); | |
printf("pn53x_write_register(PN53X_REG_CIU_BitFraming)=%d\n", | |
pn53x_write_register(pnd, PN53X_REG_CIU_BitFraming, 0xff, 0x7)); | |
uint8_t cmd_atqa[] = {0x26}; | |
uint8_t recv[384]; | |
int sz = nfc_initiator_transceive_bytes(pnd, cmd_atqa, sizeof(cmd_atqa), recv, | |
sizeof(recv), -1); | |
printf("ATQA got %d bytes\n", sz); | |
for (int i = 0; i < sz; ++i) { | |
printf("%02x ", recv[i]); | |
} | |
printf("\n"); | |
if (sz > 0) { | |
printf("pn53x_write_register(PN53X_REG_CIU_BitFraming)=%d\n", | |
pn53x_write_register(pnd, PN53X_REG_CIU_BitFraming, 0xff, 0x0)); | |
uint8_t cmd_select[] = {0x93, 0x20}; | |
uint8_t selectTag[7] = {0x93, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00}; | |
for (uint8_t level = 1, selectCmd = 0x93; level <= 3; | |
++level, selectCmd += 2) { | |
printf("pn53x_write_register(PN53X_REG_CIU_TxMode)=%d\n", | |
pn53x_write_register(pnd, PN53X_REG_CIU_TxMode, (1 << 7), 0)); | |
printf("pn53x_write_register(PN53X_REG_CIU_RxMode)=%d\n", | |
pn53x_write_register(pnd, PN53X_REG_CIU_RxMode, (1 << 7), 0)); | |
cmd_select[0] = selectCmd; | |
sz = nfc_initiator_transceive_bytes(pnd, cmd_select, sizeof(cmd_select), | |
recv, sizeof(recv), -1); | |
printf("SELECT All level %hhu got %d bytes\n", level, sz); | |
for (int i = 0; i < sz; ++i) { | |
printf("%02x ", recv[i]); | |
} | |
printf("\n"); | |
uint8_t ct = recv[0]; | |
printf( | |
"pn53x_write_register(PN53X_REG_CIU_TxMode)=%d\n", | |
pn53x_write_register(pnd, PN53X_REG_CIU_TxMode, (1 << 7), (1 << 7))); | |
printf( | |
"pn53x_write_register(PN53X_REG_CIU_RxMode)=%d\n", | |
pn53x_write_register(pnd, PN53X_REG_CIU_RxMode, (1 << 7), (1 << 7))); | |
selectTag[0] = selectCmd; | |
memcpy(selectTag + 2, recv, 5); | |
sz = nfc_initiator_transceive_bytes(pnd, selectTag, sizeof(selectTag), | |
recv, sizeof(recv), -1); | |
printf("SELECT Tag level %hhu got %d bytes\n", level, sz); | |
for (int i = 0; i < sz; ++i) { | |
printf("%02x ", recv[i]); | |
} | |
printf("\n"); | |
if (sz < 0 || ct != 0x88) | |
break; | |
// if (sz < 0 || (recv[0] & (1 << 2)) == 0) | |
// break; | |
} | |
printf("pn53x_write_register(PN53X_REG_CIU_TxMode)=%d\n", | |
pn53x_write_register(pnd, PN53X_REG_CIU_TxMode, (1 << 7), (1 << 7))); | |
printf("pn53x_write_register(PN53X_REG_CIU_RxMode)=%d\n", | |
pn53x_write_register(pnd, PN53X_REG_CIU_RxMode, (1 << 7), (1 << 7))); | |
} | |
if (sz > 0) { | |
uint8_t rats[2] = {0xE0, 0x50}; | |
sz = nfc_initiator_transceive_bytes(pnd, rats, sizeof(rats), recv, | |
sizeof(recv), -1); | |
printf("RATS got %d bytes\n", sz); | |
for (int i = 0; i < sz; ++i) { | |
printf("%02x ", recv[i]); | |
} | |
printf("\n"); | |
} | |
if(sz>0){ | |
printf("pn53x_write_register(PN53X_REG_CIU_TReloadVal_hi)=%d\n", | |
pn53x_write_register(pnd, PN53X_REG_CIU_TReloadVal_hi, 0xff, 0)); | |
printf("pn53x_write_register(PN53X_REG_CIU_TReloadVal_lo)=%d\n", | |
pn53x_write_register(pnd, PN53X_REG_CIU_TReloadVal_lo, 0xff, 0x32)); | |
uint8_t lv4[] = {0x0A, 0x00, 0x00, 0x01, 0x23, 0x09}; | |
sz = nfc_initiator_transceive_bytes(pnd, lv4, sizeof(lv4), recv, | |
sizeof(recv), -1); | |
printf("APUD1 got %d bytes\n", sz); | |
for (int i = 0; i < sz; ++i) { | |
printf("%02x ", recv[i]); | |
} | |
printf("\n"); | |
lv4[0] ^= 1; | |
sz = nfc_initiator_transceive_bytes(pnd, lv4, sizeof(lv4), recv, | |
sizeof(recv), -1); | |
printf("APUD2 got %d bytes\n", sz); | |
for (int i = 0; i < sz; ++i) { | |
printf("%02x ", recv[i]); | |
} | |
printf("\n"); | |
} | |
// uint8_t cmd_atqb[] = {0x05, 0, 0, 0x71, 0xff}; | |
// uint8_t recv[384]; | |
// int sz = nfc_initiator_transceive_bytes(pnd, cmd_atqb, | |
// sizeof(cmd_atqb), recv, | |
// sizeof(recv), -1); | |
// printf("ATQB got %d bytes\n", sz); | |
// uint8_t cmd_attrib[] = {0x1d, recv[1], recv[2], recv[3], recv[4], 0x00, | |
// 0x08, 0x00, 0x00, 0xf0, 0x1d}; | |
// uint16_t crc = calc_crc_b(cmd_attrib, 9); | |
// cmd_attrib[9] = crc >> 8; | |
// cmd_attrib[10] = crc & 0xff; | |
// sz = nfc_initiator_transceive_bytes(pnd, cmd_attrib, | |
// sizeof(cmd_attrib), recv, | |
// sizeof(recv), -1); | |
// printf("ATTRIB got %d bytes\n", sz); | |
// // uint8_t cmd_cid[] = {0x0a,0x00,0x00,0xb0,0x95,0x00,0x0f,0x88,0x4c}; | |
// uint8_t cmd_cid[] = {0x0b, 0x00, 0x00, 0xb0, 0x95, 0x00, 0x0f, 0x5d, | |
// 0xd3}; sz = nfc_initiator_transceive_bytes(pnd, cmd_cid, | |
// sizeof(cmd_cid), recv, | |
// sizeof(recv), -1); | |
// printf("cid got %d bytes\n", sz); | |
// for (int i = 0; i < sz; ++i) { | |
// printf("%02x,", recv[i]); | |
// } | |
// printf("\n"); | |
// uint8_t cmd_2[] = {0x0b, 0x00, 0x00, 0xa4, 0x04, 0x00, 0x09, 0xa0, | |
// 0x00, | |
// 0x00, 0x00, 0x03, 0x86, 0x98, 0x07, 0x01, 0x6e, | |
// 0x1b}; | |
// sz = nfc_initiator_transceive_bytes(pnd, cmd_2, sizeof(cmd_2), recv, | |
// sizeof(recv), -1); | |
// printf("cmd 2 got %d bytes\n", sz); | |
// uint8_t cmd_sid[] = {0x0b, 0x00, 0x00, 0xb0, 0x96, 0x1c, 0x0a, 0xa5, | |
// 0x57}; sz = nfc_initiator_transceive_bytes(pnd, cmd_sid, | |
// sizeof(cmd_sid), recv, | |
// sizeof(recv), -1); | |
// printf("sid got %d bytes\n", sz); | |
// for (int i = 0; i < sz; ++i) { | |
// printf("%02x,", recv[i]); | |
// } | |
// printf("\n"); | |
nfc_close(pnd); | |
nfc_exit(context); | |
exit(EXIT_SUCCESS); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment