|
|
@@ -2,22 +2,7 @@
|
|
|
#include "uhf_cmd.h"
|
|
|
|
|
|
#define CB_DELAY 50
|
|
|
-// // inner functions
|
|
|
-// uint8_t calculate_checksum(UHFData* uhf_data) {
|
|
|
-// // CheckSum8 Modulo 256
|
|
|
-// // Sum of Bytes % 256
|
|
|
-// uint8_t sum_val = 0x00;
|
|
|
-// size_t length = uhf_data->length - 2;
|
|
|
-// for(size_t i = 1; i < length; i++) {
|
|
|
-// sum_val += uhf_data->data[i];
|
|
|
-// }
|
|
|
-// return sum_val % 256;
|
|
|
-// }
|
|
|
-// bool validate_checksum(UHFData* uhf_data) {
|
|
|
-// uint8_t data_checksum = uhf_data->data[uhf_data->length - 2];
|
|
|
-// uint8_t actual_checksum = calculate_checksum(uhf_data);
|
|
|
-// return data_checksum == actual_checksum;
|
|
|
-// }
|
|
|
+
|
|
|
// uart callback functions
|
|
|
void module_rx_callback(UartIrqEvent event, uint8_t data, void* ctx) {
|
|
|
UNUSED(event);
|
|
|
@@ -54,13 +39,71 @@ UHFWorkerEvent verify_module_connected(UHFWorker* uhf_worker) {
|
|
|
}
|
|
|
// verify all data was received correctly
|
|
|
if(!uhf_data_verfiy_checksum(hardware_version) ||
|
|
|
- !uhf_data_verfiy_checksum(software_version) ||
|
|
|
- !uhf_data_verfiy_checksum(manufacturer))
|
|
|
+ !uhf_data_verfiy_checksum(software_version) || !uhf_data_verfiy_checksum(manufacturer))
|
|
|
return UHFWorkerEventFail;
|
|
|
|
|
|
return UHFWorkerEventSuccess;
|
|
|
}
|
|
|
|
|
|
+static bool send_set_select_command(UHFData* selected_tag) {
|
|
|
+ bool success = false;
|
|
|
+ uint16_t pc = 0;
|
|
|
+ uint16_t mask_length_bits = 0xF800;
|
|
|
+ size_t mask_length_word = 2;
|
|
|
+ // Set select
|
|
|
+ UHFData* select_cmd = uhf_data_alloc();
|
|
|
+ select_cmd->length = CMD_SET_SELECT_PARAMETER.length;
|
|
|
+ memcpy((void*)&select_cmd->data, (void*)&CMD_SET_SELECT_PARAMETER.cmd[0], select_cmd->length);
|
|
|
+ pc += selected_tag->data[6];
|
|
|
+ pc <<= 8;
|
|
|
+ pc |= selected_tag->data[7];
|
|
|
+ mask_length_bits &= pc;
|
|
|
+ mask_length_bits >>= 11; // shift right 11 bits to only get 10h-14h
|
|
|
+ // mask length word
|
|
|
+ mask_length_word *= (size_t)(mask_length_bits);
|
|
|
+ // mask length in bits
|
|
|
+ mask_length_bits *= 16;
|
|
|
+ // set select param
|
|
|
+ select_cmd->data[5] = 0x01; // 0x00=rfu, 0x01=epc, 0x10=tid, 0x11=user
|
|
|
+ // set ptr
|
|
|
+ select_cmd->data[9] = 0x20;
|
|
|
+ // set mask length
|
|
|
+ select_cmd->data[10] = mask_length_bits;
|
|
|
+ // set mask starting position
|
|
|
+ select_cmd->length = 11;
|
|
|
+ // set mask
|
|
|
+ FURI_LOG_E("TAG", "Mask length (bits=%d, words=%d)", mask_length_bits, mask_length_word);
|
|
|
+ for(size_t i = 0; i < mask_length_word; i++) {
|
|
|
+ uhf_data_append(select_cmd, selected_tag->data[8 + i]);
|
|
|
+ }
|
|
|
+ uhf_data_append(select_cmd, 0x00); // add checksum section
|
|
|
+ uhf_data_append(select_cmd, FRAME_END); // command end
|
|
|
+ // add checksum
|
|
|
+ select_cmd->data[select_cmd->length - 2] = uhf_data_calculate_checksum(select_cmd);
|
|
|
+
|
|
|
+ UHFData* select_response = uhf_data_alloc();
|
|
|
+ furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, module_rx_callback, select_response);
|
|
|
+ furi_hal_uart_tx(FuriHalUartIdUSART1, select_cmd->data, select_cmd->length);
|
|
|
+ furi_delay_ms(CB_DELAY);
|
|
|
+
|
|
|
+ success = select_response->data[5] != 0x00;
|
|
|
+
|
|
|
+ uhf_data_free(select_cmd);
|
|
|
+ uhf_data_free(select_response);
|
|
|
+
|
|
|
+ return success;
|
|
|
+}
|
|
|
+
|
|
|
+static bool read_bank(UHFData* read_bank_cmd, UHFData* response_bank, UHFBank bank) {
|
|
|
+ furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, module_rx_callback, response_bank);
|
|
|
+ read_bank_cmd->data[9] = bank;
|
|
|
+ read_bank_cmd->data[read_bank_cmd->length - 2] = uhf_data_calculate_checksum(read_bank_cmd);
|
|
|
+ uhf_data_reset(response_bank);
|
|
|
+ furi_hal_uart_tx(FuriHalUartIdUSART1, read_bank_cmd->data, read_bank_cmd->length);
|
|
|
+ furi_delay_ms(CB_DELAY);
|
|
|
+ return response_bank->data[2] == read_bank_cmd->data[2];
|
|
|
+}
|
|
|
+
|
|
|
UHFWorkerEvent read_single_card(UHFWorker* uhf_worker) {
|
|
|
UHFResponseData* uhf_response_data = uhf_worker->response_data;
|
|
|
uhf_response_data_reset(uhf_response_data);
|
|
|
@@ -83,27 +126,8 @@ UHFWorkerEvent read_single_card(UHFWorker* uhf_worker) {
|
|
|
break; // read success
|
|
|
}
|
|
|
}
|
|
|
- // Set select
|
|
|
- UHFData* select_cmd = uhf_data_alloc();
|
|
|
- select_cmd->length = CMD_SET_SELECT_PARAMETER.length;
|
|
|
- memcpy((void*)&select_cmd->data, (void*)&CMD_SET_SELECT_PARAMETER.cmd[0], select_cmd->length);
|
|
|
- // set select param
|
|
|
- select_cmd->data[5] = 0x01; // 0x00=rfu, 0x01=epc, 0x10=tid, 0x11=user
|
|
|
- // set ptr
|
|
|
- select_cmd->data[9] = 0x20;
|
|
|
- // set mask
|
|
|
- for(int i = 0; i < 12; i++) // 96 bits, 12 bytes
|
|
|
- {
|
|
|
- select_cmd->data[12 + i] = raw_read_data->data[8 + i];
|
|
|
- }
|
|
|
- // checksum
|
|
|
- select_cmd->data[select_cmd->length - 2] = uhf_data_calculate_checksum(select_cmd);
|
|
|
- UHFData* select_response = uhf_response_data_add_new_uhf_data(uhf_response_data);
|
|
|
- furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, module_rx_callback, select_response);
|
|
|
- furi_hal_uart_tx(FuriHalUartIdUSART1, select_cmd->data, select_cmd->length);
|
|
|
- furi_delay_ms(CB_DELAY);
|
|
|
|
|
|
- if(select_response->data[5] != 0x00) return UHFWorkerEventFail;
|
|
|
+ if(send_set_select_command(raw_read_data)) return UHFWorkerEventFail;
|
|
|
|
|
|
UHFData* read_bank_cmd = uhf_data_alloc();
|
|
|
read_bank_cmd->length = CMD_READ_LABEL_DATA_STORAGE.length;
|
|
|
@@ -114,66 +138,56 @@ UHFWorkerEvent read_single_card(UHFWorker* uhf_worker) {
|
|
|
|
|
|
// int retry = 10;
|
|
|
// read rfu bank
|
|
|
- UHFData* rfu_bank = select_response;
|
|
|
- furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, module_rx_callback, rfu_bank);
|
|
|
- read_bank_cmd->data[9] = 0x00;
|
|
|
- read_bank_cmd->data[read_bank_cmd->length - 2] = uhf_data_calculate_checksum(read_bank_cmd);
|
|
|
- uhf_data_reset(rfu_bank);
|
|
|
- furi_hal_uart_tx(FuriHalUartIdUSART1, read_bank_cmd->data, read_bank_cmd->length);
|
|
|
- furi_delay_ms(CB_DELAY);
|
|
|
- if(rfu_bank->data[2] != read_bank_cmd->data[2]) {
|
|
|
+ UHFData* rfu_bank = uhf_response_data_add_new_uhf_data(uhf_response_data);
|
|
|
+ if(!read_bank(read_bank_cmd, rfu_bank, RFU_BANK)) {
|
|
|
uhf_data_reset(rfu_bank);
|
|
|
}
|
|
|
|
|
|
// read epc bank
|
|
|
UHFData* epc_bank = uhf_response_data_add_new_uhf_data(uhf_response_data);
|
|
|
- furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, module_rx_callback, epc_bank);
|
|
|
- read_bank_cmd->data[9] = 0x01;
|
|
|
- read_bank_cmd->data[read_bank_cmd->length - 2] = uhf_data_calculate_checksum(read_bank_cmd);
|
|
|
- uhf_data_reset(epc_bank);
|
|
|
- furi_hal_uart_tx(FuriHalUartIdUSART1, read_bank_cmd->data, read_bank_cmd->length);
|
|
|
- furi_delay_ms(CB_DELAY);
|
|
|
- if(epc_bank->data[2] != read_bank_cmd->data[2]) {
|
|
|
+ if(!read_bank(read_bank_cmd, epc_bank, EPC_BANK)) {
|
|
|
uhf_data_reset(epc_bank);
|
|
|
}
|
|
|
|
|
|
// read tid bank
|
|
|
UHFData* tid_bank = uhf_response_data_add_new_uhf_data(uhf_response_data);
|
|
|
- furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, module_rx_callback, tid_bank);
|
|
|
- read_bank_cmd->data[9] = 0x02;
|
|
|
- read_bank_cmd->data[read_bank_cmd->length - 2] = uhf_data_calculate_checksum(read_bank_cmd);
|
|
|
- uhf_data_reset(tid_bank);
|
|
|
- furi_hal_uart_tx(FuriHalUartIdUSART1, read_bank_cmd->data, read_bank_cmd->length);
|
|
|
- furi_delay_ms(CB_DELAY);
|
|
|
- if(tid_bank->data[2] != read_bank_cmd->data[2]) {
|
|
|
+ if(!read_bank(read_bank_cmd, tid_bank, TID_BANK)) {
|
|
|
uhf_data_reset(tid_bank);
|
|
|
}
|
|
|
|
|
|
// read user bank
|
|
|
UHFData* user_bank = uhf_response_data_add_new_uhf_data(uhf_response_data);
|
|
|
- furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, module_rx_callback, user_bank);
|
|
|
- read_bank_cmd->data[9] = 0x03;
|
|
|
- read_bank_cmd->data[read_bank_cmd->length - 2] = uhf_data_calculate_checksum(read_bank_cmd);
|
|
|
- uhf_data_reset(user_bank);
|
|
|
- furi_hal_uart_tx(FuriHalUartIdUSART1, read_bank_cmd->data, read_bank_cmd->length);
|
|
|
- furi_delay_ms(CB_DELAY);
|
|
|
- if(user_bank->data[2] != read_bank_cmd->data[2]) {
|
|
|
+ if(!read_bank(read_bank_cmd, user_bank, USER_BANK)) {
|
|
|
uhf_data_reset(user_bank);
|
|
|
}
|
|
|
-
|
|
|
- // for(int i = 0; i < (int)user_bank->length; i++) {
|
|
|
- // FURI_LOG_E("user_bank", "data[%d]=%02x", i, user_bank->data[i]);
|
|
|
- // }
|
|
|
- // for(int i = 0; i < (int)rfu_bank->length; i++) {
|
|
|
- // FURI_LOG_E("rfu_bank", "data[%d]=%02x", i, rfu_bank->data[i]);
|
|
|
- // }
|
|
|
- // for(int i = 0; i < (int)epc_bank->length; i++) {
|
|
|
- // FURI_LOG_E("epc_bank", "data[%d]=%02x", i, epc_bank->data[i]);
|
|
|
- // }
|
|
|
- // for(int i = 0; i < (int)tid_bank->length; i++) {
|
|
|
- // FURI_LOG_E("tid_bank", "data[%d]=%02x", i, tid_bank->data[i]);
|
|
|
- // }
|
|
|
- uhf_data_free(select_cmd);
|
|
|
+ FuriString* str;
|
|
|
+ str = furi_string_alloc();
|
|
|
+ furi_string_cat(str, "RFU : ");
|
|
|
+ for(int i = 0; i < (int)rfu_bank->length; i++) {
|
|
|
+ furi_string_cat_printf(str, "%02x ", rfu_bank->data[i]);
|
|
|
+ }
|
|
|
+ FURI_LOG_E("TAG", furi_string_get_cstr(str));
|
|
|
+ furi_string_reset(str);
|
|
|
+ furi_string_cat(str, "EPC : ");
|
|
|
+ for(int i = 0; i < (int)epc_bank->length; i++) {
|
|
|
+ furi_string_cat_printf(str, "%02x ", epc_bank->data[i]);
|
|
|
+ }
|
|
|
+ FURI_LOG_E("TAG", furi_string_get_cstr(str));
|
|
|
+ furi_string_reset(str);
|
|
|
+ furi_string_cat(str, "TID : ");
|
|
|
+ for(int i = 0; i < (int)tid_bank->length; i++) {
|
|
|
+ furi_string_cat_printf(str, "%02x ", tid_bank->data[i]);
|
|
|
+ }
|
|
|
+ FURI_LOG_E("TAG", furi_string_get_cstr(str));
|
|
|
+ furi_string_reset(str);
|
|
|
+ furi_string_cat(str, "USER : ");
|
|
|
+ for(int i = 0; i < (int)user_bank->length; i++) {
|
|
|
+ furi_string_cat_printf(str, "%02x ", user_bank->data[i]);
|
|
|
+ }
|
|
|
+ FURI_LOG_E("TAG", furi_string_get_cstr(str));
|
|
|
+ furi_string_reset(str);
|
|
|
+ furi_string_free(str);
|
|
|
+ // uhf_data_free(select);
|
|
|
uhf_data_free(read_bank_cmd);
|
|
|
return UHFWorkerEventSuccess;
|
|
|
}
|