Skip to content

Instantly share code, notes, and snippets.

@z4yx
Created January 9, 2020 13:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save z4yx/1f3c0c06076c810ec7da5c8f19575d2e to your computer and use it in GitHub Desktop.
Save z4yx/1f3c0c06076c810ec7da5c8f19575d2e to your computer and use it in GitHub Desktop.
/**************** 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