mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-07-08 23:08:10 -07:00
Merge branch 'dev' of https://github.com/DarkFlippers/unleashed-firmware into dev
This commit is contained in:
@@ -8,12 +8,14 @@ typedef enum {
|
||||
LFRFIDEventStopMode = (1 << 1),
|
||||
LFRFIDEventRead = (1 << 2),
|
||||
LFRFIDEventWrite = (1 << 3),
|
||||
LFRFIDEventEmulate = (1 << 4),
|
||||
LFRFIDEventReadRaw = (1 << 5),
|
||||
LFRFIDEventEmulateRaw = (1 << 6),
|
||||
LFRFIDEventWriteWithPass = (1 << 4),
|
||||
LFRFIDEventEmulate = (1 << 5),
|
||||
LFRFIDEventReadRaw = (1 << 6),
|
||||
LFRFIDEventEmulateRaw = (1 << 7),
|
||||
LFRFIDEventAll =
|
||||
(LFRFIDEventStopThread | LFRFIDEventStopMode | LFRFIDEventRead | LFRFIDEventWrite |
|
||||
LFRFIDEventEmulate | LFRFIDEventReadRaw | LFRFIDEventEmulateRaw),
|
||||
LFRFIDEventWriteWithPass | LFRFIDEventEmulate | LFRFIDEventReadRaw |
|
||||
LFRFIDEventEmulateRaw),
|
||||
} LFRFIDEventType;
|
||||
|
||||
static int32_t lfrfid_worker_thread(void* thread_context);
|
||||
@@ -69,6 +71,18 @@ void lfrfid_worker_write_start(
|
||||
furi_thread_flags_set(furi_thread_get_id(worker->thread), LFRFIDEventWrite);
|
||||
}
|
||||
|
||||
void lfrfid_worker_write_with_pass_start(
|
||||
LFRFIDWorker* worker,
|
||||
LFRFIDProtocol protocol,
|
||||
LFRFIDWorkerWriteCallback callback,
|
||||
void* context) {
|
||||
furi_assert(worker->mode_index == LFRFIDWorkerIdle);
|
||||
worker->protocol = protocol;
|
||||
worker->write_cb = callback;
|
||||
worker->cb_ctx = context;
|
||||
furi_thread_flags_set(furi_thread_get_id(worker->thread), LFRFIDEventWriteWithPass);
|
||||
}
|
||||
|
||||
void lfrfid_worker_emulate_start(LFRFIDWorker* worker, LFRFIDProtocol protocol) {
|
||||
furi_assert(worker->mode_index == LFRFIDWorkerIdle);
|
||||
worker->protocol = protocol;
|
||||
@@ -145,6 +159,7 @@ static int32_t lfrfid_worker_thread(void* thread_context) {
|
||||
// switch mode
|
||||
if(flags & LFRFIDEventRead) worker->mode_index = LFRFIDWorkerRead;
|
||||
if(flags & LFRFIDEventWrite) worker->mode_index = LFRFIDWorkerWrite;
|
||||
if(flags & LFRFIDEventWriteWithPass) worker->mode_index = LFRFIDWorkerWriteWithPass;
|
||||
if(flags & LFRFIDEventEmulate) worker->mode_index = LFRFIDWorkerEmulate;
|
||||
if(flags & LFRFIDEventReadRaw) worker->mode_index = LFRFIDWorkerReadRaw;
|
||||
if(flags & LFRFIDEventEmulateRaw) worker->mode_index = LFRFIDWorkerEmulateRaw;
|
||||
|
||||
@@ -106,6 +106,20 @@ void lfrfid_worker_write_start(
|
||||
LFRFIDWorkerWriteCallback callback,
|
||||
void* context);
|
||||
|
||||
/**
|
||||
* @brief Start write with pass mode
|
||||
*
|
||||
* @param worker
|
||||
* @param protocol
|
||||
* @param callback
|
||||
* @param context
|
||||
*/
|
||||
void lfrfid_worker_write_with_pass_start(
|
||||
LFRFIDWorker* worker,
|
||||
LFRFIDProtocol protocol,
|
||||
LFRFIDWorkerWriteCallback callback,
|
||||
void* context);
|
||||
|
||||
/**
|
||||
* Start emulate mode
|
||||
* @param worker
|
||||
|
||||
@@ -22,6 +22,7 @@ typedef enum {
|
||||
LFRFIDWorkerIdle,
|
||||
LFRFIDWorkerRead,
|
||||
LFRFIDWorkerWrite,
|
||||
LFRFIDWorkerWriteWithPass,
|
||||
LFRFIDWorkerEmulate,
|
||||
LFRFIDWorkerReadRaw,
|
||||
LFRFIDWorkerEmulateRaw,
|
||||
|
||||
@@ -574,6 +574,96 @@ static void lfrfid_worker_mode_write_process(LFRFIDWorker* worker) {
|
||||
free(read_data);
|
||||
}
|
||||
|
||||
static void lfrfid_worker_mode_write_with_pass_process(LFRFIDWorker* worker) {
|
||||
LFRFIDProtocol protocol = worker->protocol;
|
||||
LFRFIDWriteRequest* request = malloc(sizeof(LFRFIDWriteRequest));
|
||||
request->write_type = LFRFIDWriteTypeT5577;
|
||||
|
||||
bool can_be_written = protocol_dict_get_write_data(worker->protocols, protocol, request);
|
||||
|
||||
uint32_t write_start_time = furi_get_tick();
|
||||
bool too_long = false;
|
||||
size_t unsuccessful_reads = 0;
|
||||
|
||||
size_t data_size = protocol_dict_get_data_size(worker->protocols, protocol);
|
||||
uint8_t* verify_data = malloc(data_size);
|
||||
uint8_t* read_data = malloc(data_size);
|
||||
protocol_dict_get_data(worker->protocols, protocol, verify_data, data_size);
|
||||
|
||||
if(can_be_written) {
|
||||
while(!lfrfid_worker_check_for_stop(worker)) {
|
||||
FURI_LOG_D(TAG, "Data write");
|
||||
|
||||
uint8_t size;
|
||||
const uint32_t* password_list = t5577_get_default_passwords(&size);
|
||||
|
||||
uint32_t pass = password_list[rand() % size];
|
||||
|
||||
request->t5577.mask = 0b1111111;
|
||||
request->t5577.block[0] |= 0b10000;
|
||||
request->t5577.block[7] = pass;
|
||||
|
||||
t5577_write_with_mask(&request->t5577, 0, 0);
|
||||
|
||||
ProtocolId read_result = PROTOCOL_NO;
|
||||
LFRFIDWorkerReadState state = lfrfid_worker_read_internal(
|
||||
worker,
|
||||
protocol_dict_get_features(worker->protocols, protocol),
|
||||
LFRFID_WORKER_WRITE_VERIFY_TIME_MS,
|
||||
&read_result);
|
||||
|
||||
if(state == LFRFIDWorkerReadOK) {
|
||||
bool read_success = false;
|
||||
|
||||
if(read_result == protocol) {
|
||||
protocol_dict_get_data(worker->protocols, protocol, read_data, data_size);
|
||||
|
||||
if(memcmp(read_data, verify_data, data_size) == 0) {
|
||||
read_success = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(read_success) {
|
||||
FURI_LOG_D(TAG, "Write with password %08lX success", pass);
|
||||
|
||||
if(worker->write_cb) {
|
||||
worker->write_cb(LFRFIDWorkerWriteOK, worker->cb_ctx);
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
unsuccessful_reads++;
|
||||
|
||||
if(unsuccessful_reads == LFRFID_WORKER_WRITE_MAX_UNSUCCESSFUL_READS) {
|
||||
if(worker->write_cb) {
|
||||
worker->write_cb(LFRFIDWorkerWriteFobCannotBeWritten, worker->cb_ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if(state == LFRFIDWorkerReadExit) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(!too_long &&
|
||||
(furi_get_tick() - write_start_time) > LFRFID_WORKER_WRITE_TOO_LONG_TIME_MS) {
|
||||
too_long = true;
|
||||
if(worker->write_cb) {
|
||||
worker->write_cb(LFRFIDWorkerWriteTooLongToWrite, worker->cb_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
lfrfid_worker_delay(worker, LFRFID_WORKER_WRITE_DROP_TIME_MS);
|
||||
}
|
||||
} else {
|
||||
if(worker->write_cb) {
|
||||
worker->write_cb(LFRFIDWorkerWriteProtocolCannotBeWritten, worker->cb_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
free(request);
|
||||
free(verify_data);
|
||||
free(read_data);
|
||||
}
|
||||
|
||||
/**************************************************************************************************/
|
||||
/******************************************* READ RAW *********************************************/
|
||||
/**************************************************************************************************/
|
||||
@@ -629,6 +719,7 @@ const LFRFIDWorkerModeType lfrfid_worker_modes[] = {
|
||||
[LFRFIDWorkerIdle] = {.process = NULL},
|
||||
[LFRFIDWorkerRead] = {.process = lfrfid_worker_mode_read_process},
|
||||
[LFRFIDWorkerWrite] = {.process = lfrfid_worker_mode_write_process},
|
||||
[LFRFIDWorkerWriteWithPass] = {.process = lfrfid_worker_mode_write_with_pass_process},
|
||||
[LFRFIDWorkerEmulate] = {.process = lfrfid_worker_mode_emulate_process},
|
||||
[LFRFIDWorkerReadRaw] = {.process = lfrfid_worker_mode_read_raw_process},
|
||||
[LFRFIDWorkerEmulateRaw] = {.process = lfrfid_worker_mode_emulate_raw_process},
|
||||
|
||||
@@ -13,6 +13,33 @@
|
||||
#define T5577_OPCODE_PAGE_1 0b11
|
||||
#define T5577_OPCODE_RESET 0b00
|
||||
|
||||
#define T5577_BLOCKS_IN_PAGE_0 8
|
||||
#define T5577_BLOCKS_IN_PAGE_1 4
|
||||
|
||||
//TODO: use .txt file in resources for passwords.
|
||||
const uint32_t default_passwords[] = {
|
||||
0x51243648, 0x000D8787, 0x19920427, 0x50524F58, 0xF9DCEBA0, 0x65857569, 0x05D73B9F, 0x89A69E60,
|
||||
0x314159E0, 0xAA55BBBB, 0xA5B4C3D2, 0x1C0B5848, 0x00434343, 0x444E4752, 0x4E457854, 0x44B44CAE,
|
||||
0x88661858, 0xE9920427, 0x575F4F4B, 0x50520901, 0x20206666, 0x65857569, 0x5469616E, 0x7686962A,
|
||||
0xC0F5009A, 0x07CEE75D, 0xfeedbeef, 0xdeadc0de, 0x00000000, 0x11111111, 0x22222222, 0x33333333,
|
||||
0x44444444, 0x55555555, 0x66666666, 0x77777777, 0x88888888, 0x99999999, 0xAAAAAAAA, 0xBBBBBBBB,
|
||||
0xCCCCCCCC, 0xDDDDDDDD, 0xEEEEEEEE, 0xFFFFFFFF, 0xa0a1a2a3, 0xb0b1b2b3, 0x50415353, 0x00000001,
|
||||
0x00000002, 0x0000000a, 0x0000000b, 0x01020304, 0x02030405, 0x03040506, 0x04050607, 0x05060708,
|
||||
0x06070809, 0x0708090A, 0x08090A0B, 0x090A0B0C, 0x0A0B0C0D, 0x0B0C0D0E, 0x0C0D0E0F, 0x01234567,
|
||||
0x12345678, 0x10000000, 0x20000000, 0x30000000, 0x40000000, 0x50000000, 0x60000000, 0x70000000,
|
||||
0x80000000, 0x90000000, 0xA0000000, 0xB0000000, 0xC0000000, 0xD0000000, 0xE0000000, 0xF0000000,
|
||||
0x10101010, 0x01010101, 0x11223344, 0x22334455, 0x33445566, 0x44556677, 0x55667788, 0x66778899,
|
||||
0x778899AA, 0x8899AABB, 0x99AABBCC, 0xAABBCCDD, 0xBBCCDDEE, 0xCCDDEEFF, 0x0CB7E7FC, 0xFABADA11,
|
||||
0x87654321, 0x12341234, 0x69696969, 0x12121212, 0x12344321, 0x1234ABCD, 0x11112222, 0x13131313,
|
||||
0x10041004, 0x31415926, 0xabcd1234, 0x20002000, 0x19721972, 0xaa55aa55, 0x55aa55aa, 0x4f271149,
|
||||
0x07d7bb0b, 0x9636ef8f, 0xb5f44686, 0x9E3779B9, 0xC6EF3720, 0x7854794A, 0xF1EA5EED, 0x69314718,
|
||||
0x57721566, 0x93C467E3, 0x27182818, 0x50415353};
|
||||
|
||||
const uint32_t* t5577_get_default_passwords(uint8_t* len) {
|
||||
*len = sizeof(default_passwords) / sizeof(uint32_t);
|
||||
return default_passwords;
|
||||
}
|
||||
|
||||
static void t5577_start() {
|
||||
furi_hal_rfid_tim_read_start(125000, 0.5);
|
||||
|
||||
@@ -52,6 +79,7 @@ static void t5577_write_reset() {
|
||||
}
|
||||
|
||||
static void t5577_write_block_pass(
|
||||
uint8_t page,
|
||||
uint8_t block,
|
||||
bool lock_bit,
|
||||
uint32_t data,
|
||||
@@ -62,8 +90,8 @@ static void t5577_write_block_pass(
|
||||
// start gap
|
||||
t5577_write_gap(T5577_TIMING_START_GAP);
|
||||
|
||||
// opcode for page 0
|
||||
t5577_write_opcode(T5577_OPCODE_PAGE_0);
|
||||
// opcode for page
|
||||
t5577_write_opcode((page == 1) ? T5577_OPCODE_PAGE_1 : T5577_OPCODE_PAGE_0);
|
||||
|
||||
// password
|
||||
if(with_pass) {
|
||||
@@ -92,7 +120,7 @@ static void t5577_write_block_pass(
|
||||
}
|
||||
|
||||
static void t5577_write_block_simple(uint8_t block, bool lock_bit, uint32_t data) {
|
||||
t5577_write_block_pass(block, lock_bit, data, false, 0);
|
||||
t5577_write_block_pass(0, block, lock_bit, data, false, 0);
|
||||
}
|
||||
|
||||
void t5577_write(LFRFIDT5577* data) {
|
||||
@@ -110,9 +138,28 @@ void t5577_write_with_pass(LFRFIDT5577* data, uint32_t password) {
|
||||
t5577_start();
|
||||
FURI_CRITICAL_ENTER();
|
||||
for(size_t i = 0; i < data->blocks_to_write; i++) {
|
||||
t5577_write_block_pass(i, false, data->block[i], true, password);
|
||||
t5577_write_block_pass(0, i, false, data->block[i], true, password);
|
||||
}
|
||||
t5577_write_reset();
|
||||
FURI_CRITICAL_EXIT();
|
||||
t5577_stop();
|
||||
}
|
||||
|
||||
void t5577_write_with_mask(LFRFIDT5577* data, uint8_t page, uint32_t password) {
|
||||
t5577_start();
|
||||
FURI_CRITICAL_ENTER();
|
||||
|
||||
uint8_t mask = data->mask;
|
||||
|
||||
size_t pages_total = (page == 0) ? T5577_BLOCKS_IN_PAGE_0 : T5577_BLOCKS_IN_PAGE_1;
|
||||
|
||||
for(size_t i = 0; i < pages_total; i++) {
|
||||
bool need_to_write = mask & 1;
|
||||
mask >>= 1;
|
||||
if(!need_to_write) continue;
|
||||
t5577_write_block_pass(page, i, false, data->block[i], true, password);
|
||||
}
|
||||
t5577_write_reset();
|
||||
FURI_CRITICAL_EXIT();
|
||||
t5577_stop();
|
||||
}
|
||||
@@ -42,8 +42,11 @@ extern "C" {
|
||||
typedef struct {
|
||||
uint32_t block[LFRFID_T5577_BLOCK_COUNT];
|
||||
uint32_t blocks_to_write;
|
||||
uint8_t mask;
|
||||
} LFRFIDT5577;
|
||||
|
||||
const uint32_t* t5577_get_default_passwords(uint8_t* len);
|
||||
|
||||
/**
|
||||
* @brief Write T5577 tag data to tag
|
||||
*
|
||||
@@ -53,6 +56,8 @@ void t5577_write(LFRFIDT5577* data);
|
||||
|
||||
void t5577_write_with_pass(LFRFIDT5577* data, uint32_t password);
|
||||
|
||||
void t5577_write_with_mask(LFRFIDT5577* data, uint8_t page, uint32_t password);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -22,6 +22,7 @@ MfClassicPoller* mf_classic_poller_alloc(Iso14443_3aPoller* iso14443_3a_poller)
|
||||
instance->rx_plain_buffer = bit_buffer_alloc(MF_CLASSIC_MAX_BUFF_SIZE);
|
||||
instance->rx_encrypted_buffer = bit_buffer_alloc(MF_CLASSIC_MAX_BUFF_SIZE);
|
||||
instance->current_type_check = MfClassicType4k;
|
||||
instance->card_state = MfClassicCardStateLost;
|
||||
|
||||
instance->mfc_event.data = &instance->mfc_event_data;
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ struct SubGhzFileEncoderWorker {
|
||||
|
||||
volatile bool worker_running;
|
||||
volatile bool worker_stopping;
|
||||
bool level;
|
||||
bool is_storage_slow;
|
||||
FuriString* str_data;
|
||||
FuriString* file_path;
|
||||
@@ -41,19 +40,8 @@ void subghz_file_encoder_worker_callback_end(
|
||||
void subghz_file_encoder_worker_add_level_duration(
|
||||
SubGhzFileEncoderWorker* instance,
|
||||
int32_t duration) {
|
||||
bool res = true;
|
||||
if(duration < 0 && !instance->level) {
|
||||
res = false;
|
||||
} else if(duration > 0 && instance->level) {
|
||||
res = false;
|
||||
}
|
||||
|
||||
if(res) {
|
||||
instance->level = !instance->level;
|
||||
furi_stream_buffer_send(instance->stream, &duration, sizeof(int32_t), 100);
|
||||
} else {
|
||||
FURI_LOG_E(TAG, "Invalid level in the stream");
|
||||
}
|
||||
size_t ret = furi_stream_buffer_send(instance->stream, &duration, sizeof(int32_t), 100);
|
||||
if(sizeof(int32_t) != ret) FURI_LOG_E(TAG, "Invalid add duration in the stream");
|
||||
}
|
||||
|
||||
bool subghz_file_encoder_worker_data_parse(SubGhzFileEncoderWorker* instance, const char* strStart) {
|
||||
@@ -214,7 +202,6 @@ SubGhzFileEncoderWorker* subghz_file_encoder_worker_alloc() {
|
||||
|
||||
instance->str_data = furi_string_alloc();
|
||||
instance->file_path = furi_string_alloc();
|
||||
instance->level = false;
|
||||
instance->worker_stopping = true;
|
||||
|
||||
return instance;
|
||||
|
||||
Reference in New Issue
Block a user