📄 level3.c
字号:
else
corr >>= 2;
if ((flags & 1) == 1)
pom -= corr;
pom = (19 * (uint32_t)pom) / 16 + 1;
decode_number = flags & 3;
if (decode_number & 2) {
halfDataRate = 288; //high data rates
pulsesPerBit = 8;
} else {
halfDataRate = 288 * 4; //low data rates
pulsesPerBit = 32;
}
maxTGeneral = pom;
maxTwa1ee = write_tag_memory_delay + pom;
}
//--------------------------------------------------------------
//send command and wait
//
void Send(uint8_t len, uint16_t wait_time) {
uint8_t fwd_bit_count;
int i;
forward_ptr = data_buffer;
fwd_bit_count = 0;
for(i=0; i < len; i++)
fwd_bit_count += Prepare_Data( cmd_message[i] );
Compute_Timeouts(cmd_message[0]);
ClearCaptureBuffers();
maxCaptureTimeLow = (uint8_t)maxTGeneral;
maxCaptureTimeHi = maxTGeneral >> 8;
SendForward(fwd_bit_count);
if (wait_time != 0) Wait( wait_time );
}
//--------------------------------------------------------------
// general read function
//
uint8_t GeneralRead(void) {
uint8_t i = UART_MESSAGE_OK;
signed_crc = 0;
if (cmd_message[1] == 0xE2) { //signed operation
//sign the CRC
HWSign( &cmd_message[cmd_message_len-2], &cmd_message[cmd_message_len-2], 16);
if ((cmd_message[0] & 0x40) != 0) {
signed_crc = 1;
}
}
Send( cmd_message_len, STD_WAIT );
maxCaptureTimeLow = (uint8_t)maxTGeneral;
maxCaptureTimeHi = maxTGeneral >> 8;
Capture(2);
if (debug_mode == 0) {
int i;
clean_data_cnt = 0;
if (sof >= 1) {
i = 248 - ExtractData( 248 ); //extract data, max effective size is 248/8 bytes
if (((uint8_t)i >= 33) && (data_buffer[0] != 0)) { //error message found
i = ERR_EM4035_ERROR_MSG;
clean_data_cnt = 4;
if (signed_crc != 0) {
//unsign
HWSign( (uint8_t*)&data_buffer[clean_data_cnt-2], (uint8_t*)&data_buffer[clean_data_cnt-2], 16);
}
} else if ((i-1) < expectedResponseLen) { //no good header found or not enough data
clean_data_cnt = 0;
i = ERR_EM4035_WRONG_LEN;
} else { //clamp data to bytes
i = 0;
clean_data_cnt = expectedResponseLen / 8;
if (signed_crc != 0) {
//unsign
HWSign( (uint8_t*)&data_buffer[clean_data_cnt-2], (uint8_t*)&data_buffer[clean_data_cnt-2], 16);
}
}
} else {
i = ERR_EM4035_NO_SOF;
}
}
return i;
}
//--------------------------------------------------------------
// General Write
uint8_t GeneralWrite(void) {
uint8_t i = UART_MESSAGE_OK;
signed_crc = 0;
if (cmd_message[1] == 0xE3) { //signed operation
//sign the CRC
HWSign( &cmd_message[cmd_message_len-2], &cmd_message[cmd_message_len-2], 16);
if ((cmd_message[0] & 0x40) != 0) {
signed_crc = 1;
}
}
Send( cmd_message_len, 0 );
if ((cmd_message[0] & 0x40) && ((cmd_message[1] == 0x21) ||
(cmd_message[1] == 0x22) || (cmd_message[1] == 0x27))) { //optionFlag = '1'
Wait( write_tag_memory_delay );
SendEOF();
maxCaptureTimeLow = (uint8_t)maxTGeneral;
maxCaptureTimeHi = maxTGeneral >> 8;
} else { //optionFlag = '0'
maxCaptureTimeLow = (uint8_t)maxTwa1ee;
maxCaptureTimeHi = maxTwa1ee >> 8;
}
Capture(2);
if (debug_mode == 0) {
clean_data_cnt = 0;
if (sof >= 1) {
i = 248 - ExtractData( 248 ); //extract data, max effective size is 248/8 bytes
if ((i >= 33) && (data_buffer[0] != 0)) { //error message found
i = ERR_EM4035_ERROR_MSG;
clean_data_cnt = 4;
if (signed_crc != 0) {
//unsign
HWSign( (uint8_t*)&data_buffer[clean_data_cnt-2], (uint8_t*)&data_buffer[clean_data_cnt-2], 16);
}
} else if ((uint8_t)(i-1) < (uint8_t)expectedResponseLen) { //no good header found or not enough data
clean_data_cnt = 0;
i = ERR_EM4035_WRONG_LEN;
} else { //clamp data to bytes
i = 0;
clean_data_cnt = expectedResponseLen / 8;
if (signed_crc != 0) {
//unsign
HWSign( (uint8_t*)&data_buffer[clean_data_cnt-2], (uint8_t*)&data_buffer[clean_data_cnt-2], 16);
}
}
if (clean_data_cnt != 0) {
i = UART_MESSAGE_OK;
}
} else {
i = ERR_EM4035_NO_SOF;
}
}
return i;
}
//--------------------------------------------------------------
// Appends crc to ISO15693 command
void AddCRC( uint8_t where ) {
uint16_t crc = CRC( cmd_message, where );
cmd_message[where++] = crc & 255;
cmd_message[where] = crc >> 8;
}
//--------------------------------------------------------------
//--------------------------------------------------------------
//1TS Inventory
//#define DBG_1TS
#define STACK_LENGTH 8 //stack size
typedef struct {
uint8_t mask_len;
uint8_t value;
uint8_t mask[12];
uint8_t vata[2]; //to keep this structure size being 2^n
} TINVENTORY;
TINVENTORY found[STACK_LENGTH];
int8_t found_ptr;
uint8_t dbg_counter;
//--------------------------------------------------------------
//--------------------------------------------------------------
//--------------------------------------------------------------
// ****************** 1TS inventory version 4 ******************
TINVENTORY search;
int8_t InventoryStep_version4(void) {
uint8_t i, j, k, l;
uint8_t result;
uint16_t crc;
expectedResponseLen = 96;
j = search.mask_len;
//set collision bit
if (j > 0) {
l = 2 + (j - 1) / 8;
for(k = 0xFE, i = 0; i < ((j-1)%8); i++) k <<= 1; //!!!
search.mask[l] = search.mask[l] & (~k);
k = search.value << ((j-1) % 8);
search.mask[l] = search.mask[l] | k;
}
cmd_message[0] = message_flags;
cmd_message[1] = 0x01;
cmd_message[2] = j;
//copy uid as a mask
if (j != 0) {
l = (j - 1) / 8;
Copy( &cmd_message[3], &search.mask[2], l+1 );
j = (j + 7) / 8;
}
//compute CRC
j += 3;
AddCRC( j );
j += 2;
//form & send command & wait
Send( j, STD_WAIT );
//listen for response
maxCaptureTimeLow = (uint8_t)maxTGeneral;
maxCaptureTimeHi = maxTGeneral >> 8;
Capture(2);
clean_data_cnt = 0;
result = 0;
#ifdef DBG_1TS
UDR = j;
while (!(UCSRA & (1<<UDRE)))
{}
for (i=2; i<j; i++) {
UDR = cmd_message[i];
while (!(UCSRA & (1<<UDRE)))
{}
}
UDR = sof;
while (!(UCSRA & (1<<UDRE)))
{}
UDR = capture_cnt;
while (!(UCSRA & (1<<UDRE)))
{}
if (dbg_counter == 2)
SendCaptureData(0x83, 3);
#endif
if ((sof == 0) || (capture_cnt < 8))
return -2;
j = ExtractData( expectedResponseLen ); //find first data bit
#ifdef DBG_1TS
UDR = j;
while (!(UCSRA & (1<<UDRE)))
{}
#endif
Copy( found[found_ptr].mask, data_buffer, 12 ); //always copy data regardless the result
if (j == 0) {
//one valid response received
clean_data_cnt = 12;
crc = CRC(data_buffer, clean_data_cnt);
if (crc == ~0xF0B8) {
//switch to '1' or restart 1 bit position less blindly
if (search.value == 1) {
if (search.mask_len > 0) {
search.mask_len--;
search.value = 0;
}
} else
search.value = 1;
//form Stay Quiet command
cmd_message[0] = (message_flags & 0x03) | 0x20;
cmd_message[1] = 0x02;
Copy( &cmd_message[2], &found[found_ptr].mask[2], 8);
AddCRC( 10 );
//form & send command & wait (10 = arbitrary delay)
Send( 12, 300 );
#if 0
//#ifdef DBG_1TS
for (i=0; i<12; i++) {
UDR = cmd_message[i];
while (!(UCSRA & (1<<UDRE)))
{}
}
#endif
found_ptr++;
if (found_ptr > STACK_LENGTH-1) return ERR_EM4035_BUFFER_OVERFLOW;
return 0;
}
return ERR_EM4035_BAD_CRC;
}
//collision
return 1;
}
//-------------------------------------------------------------------------------------
uint8_t Inventory(void) {
uint8_t timeout = 32;
uint8_t nothing;
uint8_t auxiliary_nothing = 0;
int8_t result;
uint8_t debug_count = 0;
debug_count = 0;
found_ptr = 0;
search.mask_len = 0;
//clear the mask
for(nothing=0; nothing<sizeof(search.mask); nothing++) search.mask[nothing] = 0;
nothing = 0;
while (timeout-- > 0) {
// AddMemo("Step: " + AnsiString(debug_count));
result = InventoryStep_version4();
// AddMemo("Result: " + AnsiString(result));
//current mask tag found
if (result == 0) {
if (search.value == 1) { //slow step back
if (search.mask_len > 0) {
search.mask_len--;
search.value = 0;
}
} else {
search.value = 1;
}
nothing = 0;
auxiliary_nothing = 0;
}
if (result == ERR_EM4035_BUFFER_OVERFLOW) {
break;
}
//current mask collision found
if (result > 0) {
if (search.mask_len < 64) {
search.mask_len++;
search.value = 0;
}
nothing = 0;
auxiliary_nothing = 0;
}
//no response
if (result == -2) {
nothing++;
auxiliary_nothing++;
}
if (auxiliary_nothing >= 7) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -