1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
};
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
};
- memset(trace, 0x44, TRACE_SIZE);
+ uint8_t *trace = BigBuf_get_addr();
+ uint16_t max_traceLen = BigBuf_max_traceLen();
+ memset(trace, 0x44, max_traceLen);
uint16_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity
uint16_t duration = timestamp_end - timestamp_start;
// Return when trace is full
uint16_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity
uint16_t duration = timestamp_end - timestamp_start;
// Return when trace is full
} else if (Uart.len & 0x0007) { // there are some parity bits to store
Uart.parityBits <<= (8 - (Uart.len&0x0007)); // left align remaining parity bits
Uart.parity[Uart.parityLen++] = Uart.parityBits; // and store them
} else if (Uart.len & 0x0007) { // there are some parity bits to store
Uart.parityBits <<= (8 - (Uart.len&0x0007)); // left align remaining parity bits
Uart.parity[Uart.parityLen++] = Uart.parityBits; // and store them
} else if (Demod.len & 0x0007) { // there are some parity bits to store
Demod.parityBits <<= (8 - (Demod.len&0x0007)); // left align remaining parity bits
Demod.parity[Demod.parityLen++] = Demod.parityBits; // and store them
} else if (Demod.len & 0x0007) { // there are some parity bits to store
Demod.parityBits <<= (8 - (Demod.len&0x0007)); // left align remaining parity bits
Demod.parity[Demod.parityLen++] = Demod.parityBits; // and store them
return TRUE; // we are finished with decoding the raw data sequence
} else { // nothing received. Start over
DemodReset();
return TRUE; // we are finished with decoding the raw data sequence
} else { // nothing received. Start over
DemodReset();
// We won't start recording the frames that we acquire until we trigger;
// a good trigger condition to get started is probably when we see a
// We won't start recording the frames that we acquire until we trigger;
// a good trigger condition to get started is probably when we see a
- // The length of a received command will in most cases be no more than 18 bytes.
- // So 32 should be enough!
- uint8_t *receivedCmd = ((uint8_t *)BigBuf) + RECV_CMD_OFFSET;
- uint8_t *receivedCmdPar = ((uint8_t *)BigBuf) + RECV_CMD_PAR_OFFSET;
+ uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
+ uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE);
- uint8_t *receivedResponse = ((uint8_t *)BigBuf) + RECV_RESP_OFFSET;
- uint8_t *receivedResponsePar = ((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET;
-
- // As we receive stuff, we copy it from receivedCmd or receivedResponse
- // into trace, along with its length and other annotations.
- //uint8_t *trace = (uint8_t *)BigBuf;
+ uint8_t *receivedResponse = BigBuf_malloc(MAX_FRAME_SIZE);
+ uint8_t *receivedResponsePar = BigBuf_malloc(MAX_PARITY_SIZE);
bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_StartTime, uint32_t reader_EndTime, uint8_t *reader_Parity,
uint8_t *tag_data, uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, uint8_t *tag_Parity);
bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_StartTime, uint32_t reader_EndTime, uint8_t *reader_Parity,
uint8_t *tag_data, uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, uint8_t *tag_Parity);
bool prepare_tag_modulation(tag_response_info_t* response_info, size_t max_buffer_size) {
// Example response, answer to MIFARE Classic read block will be 16 bytes + 2 CRC = 18 bytes
// This will need the following byte array for a modulation sequence
bool prepare_tag_modulation(tag_response_info_t* response_info, size_t max_buffer_size) {
// Example response, answer to MIFARE Classic read block will be 16 bytes + 2 CRC = 18 bytes
// This will need the following byte array for a modulation sequence
// Prepare the tag modulation bits from the message
CodeIso14443aAsTag(response_info->response,response_info->response_n);
// Prepare the tag modulation bits from the message
CodeIso14443aAsTag(response_info->response,response_info->response_n);
+
+// "precompile" responses. There are 7 predefined responses with a total of 28 bytes data to transmit.
+// Coded responses need one byte per bit to transfer (data, parity, start, stop, correction)
+// 28 * 8 data bits, 28 * 1 parity bits, 7 start bits, 7 stop bits, 7 correction bits
+// -> need 273 bytes buffer
+#define ALLOCATED_TAG_MODULATION_BUFFER_SIZE 273
+
bool prepare_allocated_tag_modulation(tag_response_info_t* response_info) {
// Retrieve and store the current buffer index
response_info->modulation = free_buffer_pointer;
// Determine the maximum size we can use from our buffer
bool prepare_allocated_tag_modulation(tag_response_info_t* response_info) {
// Retrieve and store the current buffer index
response_info->modulation = free_buffer_pointer;
// Determine the maximum size we can use from our buffer
//-----------------------------------------------------------------------------
void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
{
//-----------------------------------------------------------------------------
void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
{
response2[4] = response2[0] ^ response2[1] ^ response2[2] ^ response2[3];
// Prepare the mandatory SAK (for 4 and 7 byte UID)
response2[4] = response2[0] ^ response2[1] ^ response2[2] ^ response2[3];
// Prepare the mandatory SAK (for 4 and 7 byte UID)
response3[0] = sak;
ComputeCrc14443(CRC_14443_A, response3, 1, &response3[1], &response3[2]);
// Prepare the optional second SAK (for 7 byte UID), drop the cascade bit
response3[0] = sak;
ComputeCrc14443(CRC_14443_A, response3, 1, &response3[1], &response3[2]);
// Prepare the optional second SAK (for 7 byte UID), drop the cascade bit
response3a[0] = sak & 0xFB;
ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]);
response3a[0] = sak & 0xFB;
ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]);
- // Reset the offset pointer of the free buffer
- reset_free_buffer();
-
+ BigBuf_free_keep_EM();
+
+ // allocate buffers:
+ uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
+ uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE);
+ free_buffer_pointer = BigBuf_malloc(ALLOCATED_TAG_MODULATION_BUFFER_SIZE);
+
+ // clear trace
+ iso14a_clear_trace();
+ iso14a_set_tracing(TRUE);
+
// Prepare the responses of the anticollision phase
// there will be not enough time to do this at the moment the reader sends it REQA
for (size_t i=0; i<TAG_RESPONSE_COUNT; i++) {
// Prepare the responses of the anticollision phase
// there will be not enough time to do this at the moment the reader sends it REQA
for (size_t i=0; i<TAG_RESPONSE_COUNT; i++) {
// We need to listen to the high-frequency, peak-detected path.
iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN);
// We need to listen to the high-frequency, peak-detected path.
iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN);
// We already responded, do not send anything with the EmSendCmd14443aRaw() that is called below
p_response = NULL;
} else if(receivedCmd[0] == 0x50) { // Received a HALT
// We already responded, do not send anything with the EmSendCmd14443aRaw() that is called below
p_response = NULL;
} else if(receivedCmd[0] == 0x50) { // Received a HALT
if (tracing) {
LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
}
if (tracing) {
LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
}
// do the tracing for the previous reader request and this tag answer:
uint8_t par[MAX_PARITY_SIZE];
GetParity(p_response->response, p_response->response_n, par);
// do the tracing for the previous reader request and this tag answer:
uint8_t par[MAX_PARITY_SIZE];
GetParity(p_response->response, p_response->response_n, par);
Dbprintf("%x %x %x", happened, happened2, cmdsRecvd);
LED_A_OFF();
Dbprintf("%x %x %x", happened, happened2, cmdsRecvd);
LED_A_OFF();
//-----------------------------------------------------------------------------
static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receivedResponsePar, uint16_t offset)
{
//-----------------------------------------------------------------------------
static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receivedResponsePar, uint16_t offset)
{
// Set FPGA mode to "reader listen mode", no modulation (listen
// only, since we are receiving, not transmitting).
// Set FPGA mode to "reader listen mode", no modulation (listen
// only, since we are receiving, not transmitting).
void ReaderTransmitBitsPar(uint8_t* frame, uint16_t bits, uint8_t *par, uint32_t *timing)
{
void ReaderTransmitBitsPar(uint8_t* frame, uint16_t bits, uint8_t *par, uint32_t *timing)
{
uint8_t sel_all[] = { 0x93,0x20 };
uint8_t sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
uint8_t rats[] = { 0xE0,0x80,0x00,0x00 }; // FSD=256, FSDI=8, CID=0
uint8_t sel_all[] = { 0x93,0x20 };
uint8_t sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
uint8_t rats[] = { 0xE0,0x80,0x00,0x00 }; // FSD=256, FSDI=8, CID=0
- uint8_t *resp = ((uint8_t *)BigBuf) + RECV_RESP_OFFSET;
- uint8_t *resp_par = ((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET;
+ uint8_t resp[MAX_FRAME_SIZE]; // theoretically. A usual RATS will be much smaller
+ uint8_t resp_par[MAX_PARITY_SIZE];
Dbprintf("Multiple tags detected. Collision after Bit %d", Demod.collisionPos);
for (uint16_t i = collision_answer_offset; i < Demod.collisionPos; i++, uid_resp_bits++) { // add valid UID bits before collision point
uint16_t UIDbit = (resp[i/8] >> (i % 8)) & 0x01;
Dbprintf("Multiple tags detected. Collision after Bit %d", Demod.collisionPos);
for (uint16_t i = collision_answer_offset; i < Demod.collisionPos; i++, uid_resp_bits++) { // add valid UID bits before collision point
uint16_t UIDbit = (resp[i/8] >> (i % 8)) & 0x01;
if ((sak & 0x04) /* && uid_resp[0] == 0x88 */) {
// Remove first byte, 0x88 is not an UID byte, it CT, see page 3 of:
// http://www.nxp.com/documents/application_note/AN10927.pdf
if ((sak & 0x04) /* && uid_resp[0] == 0x88 */) {
// Remove first byte, 0x88 is not an UID byte, it CT, see page 3 of:
// http://www.nxp.com/documents/application_note/AN10927.pdf
- // This was earlier:
- //memcpy(uid_resp, uid_resp + 1, 3);
- // But memcpy should not be used for overlapping arrays,
- // and memmove appears to not be available in the arm build.
- // Therefore:
uid_resp[0] = uid_resp[1];
uid_resp[1] = uid_resp[2];
uid_resp[2] = uid_resp[3];
uid_resp[0] = uid_resp[1];
uid_resp[1] = uid_resp[2];
uid_resp[2] = uid_resp[3];
// Request for answer to select
AppendCrc14443a(rats, 2);
// Request for answer to select
AppendCrc14443a(rats, 2);
if(p_hi14a_card) {
memcpy(p_hi14a_card->ats, resp, sizeof(p_hi14a_card->ats));
p_hi14a_card->ats_len = len;
if(p_hi14a_card) {
memcpy(p_hi14a_card->ats, resp, sizeof(p_hi14a_card->ats));
p_hi14a_card->ats_len = len;
uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
static uint8_t mf_nr_ar3;
uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
static uint8_t mf_nr_ar3;
- uint8_t* receivedAnswer = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
- uint8_t* receivedAnswerPar = (((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET);
+ uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
+ uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
- byte_t par_list[8] = {0,0,0,0,0,0,0,0};
- byte_t ks_list[8] = {0,0,0,0,0,0,0,0};
+ byte_t par_list[8] = {0x00};
+ byte_t ks_list[8] = {0x00};
- uint8_t* receivedCmd = get_bigbufptr_recvcmdbuf();
- uint8_t* receivedCmd_par = receivedCmd + MAX_FRAME_SIZE;
- uint8_t* response = get_bigbufptr_recvrespbuf();
- uint8_t* response_par = response + MAX_FRAME_SIZE;
+ uint8_t receivedCmd[MAX_MIFARE_FRAME_SIZE];
+ uint8_t receivedCmd_par[MAX_MIFARE_PARITY_SIZE];
+ uint8_t response[MAX_MIFARE_FRAME_SIZE];
+ uint8_t response_par[MAX_MIFARE_PARITY_SIZE];
uint8_t rATQA[] = {0x04, 0x00}; // Mifare classic 1k 4BUID
uint8_t rUIDBCC1[] = {0xde, 0xad, 0xbe, 0xaf, 0x62};
uint8_t rATQA[] = {0x04, 0x00}; // Mifare classic 1k 4BUID
uint8_t rUIDBCC1[] = {0xde, 0xad, 0xbe, 0xaf, 0x62};
uint32_t ar_nr_responses[] = {0,0,0,0,0,0,0,0};
uint8_t ar_nr_collected = 0;
uint32_t ar_nr_responses[] = {0,0,0,0,0,0,0,0};
uint8_t ar_nr_collected = 0;
// The command (reader -> tag) that we're receiving.
// The length of a received command will in most cases be no more than 18 bytes.
// So 32 should be enough!
// The command (reader -> tag) that we're receiving.
// The length of a received command will in most cases be no more than 18 bytes.
// So 32 should be enough!
- uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
- uint8_t *receivedCmdPar = ((uint8_t *)BigBuf) + RECV_CMD_PAR_OFFSET;
+ uint8_t receivedCmd[MAX_MIFARE_FRAME_SIZE];
+ uint8_t receivedCmdPar[MAX_MIFARE_PARITY_SIZE];
- uint8_t *receivedResponse = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
- uint8_t *receivedResponsePar = ((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET;
+ uint8_t receivedResponse[MAX_MIFARE_FRAME_SIZE];
+ uint8_t receivedResponsePar[MAX_MIFARE_PARITY_SIZE];
// As we receive stuff, we copy it from receivedCmd or receivedResponse
// into trace, along with its length and other annotations.
//uint8_t *trace = (uint8_t *)BigBuf;
// As we receive stuff, we copy it from receivedCmd or receivedResponse
// into trace, along with its length and other annotations.
//uint8_t *trace = (uint8_t *)BigBuf;
- // The DMA buffer, used to stream samples from the FPGA
- uint8_t *dmaBuf = ((uint8_t *)BigBuf) + DMA_BUFFER_OFFSET;
+ // free eventually allocated BigBuf memory
+ BigBuf_free();
+ // allocate the DMA buffer, used to stream samples from the FPGA
+ uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);