|
|
@@ -44,13 +44,13 @@ UHFWorkerEvent verify_module_connected(UHFWorker* uhf_worker) {
|
|
|
return UHFWorkerEventSuccess;
|
|
|
}
|
|
|
|
|
|
-static uint8_t get_epc_length_in_bits(uint8_t pc) {
|
|
|
+uint8_t get_epc_length_in_bits(uint8_t pc) {
|
|
|
uint8_t epc_length = pc;
|
|
|
epc_length >>= 3;
|
|
|
return (uint8_t)epc_length * 16; // x-words * 16 bits
|
|
|
}
|
|
|
|
|
|
-static bool send_set_select_command(UHFData* selected_tag, UHFBank bank) {
|
|
|
+bool send_set_select_command(UHFData* selected_tag, UHFBank bank) {
|
|
|
bool success = false;
|
|
|
// Set select
|
|
|
UHFData* select_cmd = uhf_data_alloc();
|
|
|
@@ -88,7 +88,7 @@ static bool send_set_select_command(UHFData* selected_tag, UHFBank bank) {
|
|
|
return success;
|
|
|
}
|
|
|
|
|
|
-static bool read_bank(UHFData* read_bank_cmd, UHFData* response_bank, UHFBank bank) {
|
|
|
+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);
|
|
|
@@ -98,6 +98,35 @@ static bool read_bank(UHFData* read_bank_cmd, UHFData* response_bank, UHFBank ba
|
|
|
return response_bank->data[2] == read_bank_cmd->data[2];
|
|
|
}
|
|
|
|
|
|
+bool write_bank(UHFData* write_bank_cmd, UHFBank bank, uint8_t* bank_data, size_t bank_len) {
|
|
|
+ UHFData* rp_data = uhf_data_alloc();
|
|
|
+ write_bank_cmd->end = false;
|
|
|
+ for(size_t i = 0; i < write_bank_cmd->length; i++) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, module_rx_callback, rp_data);
|
|
|
+ for(int i = 5; i < 9; i++) { // no access password for now
|
|
|
+ write_bank_cmd->data[i] = 0;
|
|
|
+ }
|
|
|
+ write_bank_cmd->data[9] = bank;
|
|
|
+ size_t word_len = bank_len / 2;
|
|
|
+ write_bank_cmd->data[13] = word_len;
|
|
|
+ write_bank_cmd->length = 14;
|
|
|
+ write_bank_cmd->start = true;
|
|
|
+ for(size_t i = 0; i < bank_len; i++) {
|
|
|
+ uhf_data_append(write_bank_cmd, bank_data[i]);
|
|
|
+ }
|
|
|
+ uhf_data_append(write_bank_cmd, 00);
|
|
|
+ uhf_data_append(write_bank_cmd, FRAME_END);
|
|
|
+ write_bank_cmd->data[4] = write_bank_cmd->length - 7;
|
|
|
+ write_bank_cmd->data[write_bank_cmd->length - 2] = uhf_data_calculate_checksum(write_bank_cmd);
|
|
|
+ furi_hal_uart_tx(FuriHalUartIdUSART1, write_bank_cmd->data, write_bank_cmd->length);
|
|
|
+ furi_delay_ms(CB_DELAY);
|
|
|
+ bool success = rp_data->data[2] == write_bank_cmd->data[2];
|
|
|
+ uhf_data_free(rp_data);
|
|
|
+ return success;
|
|
|
+}
|
|
|
+
|
|
|
UHFWorkerEvent send_polling_command(UHFWorker* uhf_worker, UHFData* raw_read_data) {
|
|
|
furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, module_rx_callback, raw_read_data);
|
|
|
uhf_data_reset(raw_read_data);
|
|
|
@@ -153,7 +182,6 @@ UHFWorkerEvent read_single_card(UHFWorker* uhf_worker) {
|
|
|
do {
|
|
|
if(read_bank(read_bank_cmd, raw_bank_data, EPC_BANK)) {
|
|
|
uhf_tag_set_epc(uhf_tag, raw_bank_data->data + offset, epc_length + 2);
|
|
|
- FURI_LOG_E("TAG", "epc read");
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
@@ -207,7 +235,37 @@ UHFWorkerEvent read_single_card(UHFWorker* uhf_worker) {
|
|
|
return UHFWorkerEventSuccess;
|
|
|
}
|
|
|
|
|
|
-UHFWorkerEvent write_single_card(UHFWorker* worker) {
|
|
|
+UHFWorkerEvent write_single_card(UHFWorker* uhf_worker) {
|
|
|
+ UHFResponseData* uhf_response_data = uhf_worker->response_data;
|
|
|
+ uhf_response_data_reset(uhf_response_data);
|
|
|
+ UHFData* raw_read_data = uhf_response_data_get_uhf_data(uhf_response_data, 0);
|
|
|
+ furi_hal_uart_set_br(FuriHalUartIdUSART1, DEFAULT_BAUD_RATE);
|
|
|
+
|
|
|
+ send_polling_command(uhf_worker, raw_read_data);
|
|
|
+ // todo : rfu ?
|
|
|
+ UHFTag* uhf_tag = uhf_worker->uhf_tag;
|
|
|
+
|
|
|
+ UHFData* write_bank_cmd = uhf_data_alloc();
|
|
|
+ write_bank_cmd->length = CMD_WRITE_LABEL_DATA_STORAGE.length;
|
|
|
+
|
|
|
+ memcpy(
|
|
|
+ (void*)&write_bank_cmd->data[0],
|
|
|
+ (void*)&CMD_WRITE_LABEL_DATA_STORAGE.cmd[0],
|
|
|
+ write_bank_cmd->length);
|
|
|
+ if(!send_set_select_command(raw_read_data, EPC_BANK)) return UHFWorkerEventFail;
|
|
|
+
|
|
|
+ if(raw_read_data->data[6] & 0x04) {
|
|
|
+ if(!write_bank(write_bank_cmd, USER_BANK, uhf_tag->user, uhf_tag->user_length))
|
|
|
+ return UHFWorkerEventFail;
|
|
|
+ }
|
|
|
+ uint8_t write_data[uhf_tag->epc_length + 2];
|
|
|
+ memcpy(&write_data, &raw_read_data->data[raw_read_data->length - 4], 2);
|
|
|
+ memcpy(&write_data[2], &uhf_tag->epc, uhf_tag->epc_length);
|
|
|
+ write_data[10] = 0xF1;
|
|
|
+ if(!write_bank(write_bank_cmd, EPC_BANK, write_data, uhf_tag->epc_length + 2)) {
|
|
|
+ return UHFWorkerEventFail;
|
|
|
+ }
|
|
|
+ return UHFWorkerEventSuccess;
|
|
|
}
|
|
|
|
|
|
int32_t uhf_worker_task(void* ctx) {
|