diff --git a/lib/lfrfid/protocols/lfrfid_protocols.c b/lib/lfrfid/protocols/lfrfid_protocols.c index f07218d7f..a8d0ff280 100644 --- a/lib/lfrfid/protocols/lfrfid_protocols.c +++ b/lib/lfrfid/protocols/lfrfid_protocols.c @@ -20,6 +20,8 @@ const ProtocolBase* lfrfid_protocols[] = { [LFRFIDProtocolEM4100] = &protocol_em4100, + [LFRFIDProtocolEM410032] = &protocol_em4100_32, + [LFRFIDProtocolEM410016] = &protocol_em4100_16, [LFRFIDProtocolH10301] = &protocol_h10301, [LFRFIDProtocolIdteck] = &protocol_idteck, [LFRFIDProtocolIndala26] = &protocol_indala26, diff --git a/lib/lfrfid/protocols/lfrfid_protocols.h b/lib/lfrfid/protocols/lfrfid_protocols.h index 0cb7cbc84..64a9fcba2 100644 --- a/lib/lfrfid/protocols/lfrfid_protocols.h +++ b/lib/lfrfid/protocols/lfrfid_protocols.h @@ -9,6 +9,8 @@ typedef enum { typedef enum { LFRFIDProtocolEM4100, + LFRFIDProtocolEM410032, + LFRFIDProtocolEM410016, LFRFIDProtocolH10301, LFRFIDProtocolIdteck, LFRFIDProtocolIndala26, diff --git a/lib/lfrfid/protocols/protocol_em4100.c b/lib/lfrfid/protocols/protocol_em4100.c index 4b720dffd..8dd3b2ce0 100644 --- a/lib/lfrfid/protocols/protocol_em4100.c +++ b/lib/lfrfid/protocols/protocol_em4100.c @@ -24,16 +24,9 @@ typedef uint64_t EM4100DecodedData; #define EM4100_DECODED_DATA_SIZE (5) #define EM4100_ENCODED_DATA_SIZE (sizeof(EM4100DecodedData)) -#define EM4100_CLOCK_PER_BIT (64) - -#define EM_READ_SHORT_TIME (256) -#define EM_READ_LONG_TIME (512) -#define EM_READ_JITTER_TIME (100) - -#define EM_READ_SHORT_TIME_LOW (EM_READ_SHORT_TIME - EM_READ_JITTER_TIME) -#define EM_READ_SHORT_TIME_HIGH (EM_READ_SHORT_TIME + EM_READ_JITTER_TIME) -#define EM_READ_LONG_TIME_LOW (EM_READ_LONG_TIME - EM_READ_JITTER_TIME) -#define EM_READ_LONG_TIME_HIGH (EM_READ_LONG_TIME + EM_READ_JITTER_TIME) +#define EM_READ_SHORT_TIME_BASE (256) +#define EM_READ_LONG_TIME_BASE (512) +#define EM_READ_JITTER_TIME_BASE (100) typedef struct { uint8_t data[EM4100_DECODED_DATA_SIZE]; @@ -43,13 +36,74 @@ typedef struct { bool encoded_polarity; ManchesterState decoder_manchester_state; + uint8_t clock_per_bit; } ProtocolEM4100; +uint16_t protocol_em4100_get_time_divisor(ProtocolEM4100 *proto) { + switch (proto->clock_per_bit) { + case 64: + return 1; + case 32: + return 2; + case 16: + return 4; + default: + return 1; + } +} + +uint32_t protocol_em4100_get_t5577_bitrate(ProtocolEM4100 *proto) { + switch (proto->clock_per_bit) { + case 64: + return LFRFID_T5577_BITRATE_RF_64; + case 32: + return LFRFID_T5577_BITRATE_RF_32; + case 16: + return LFRFID_T5577_BITRATE_RF_16; + default: + return LFRFID_T5577_BITRATE_RF_64; + } +} + +uint16_t protocol_em4100_get_short_time_low(ProtocolEM4100 *proto) { + return EM_READ_SHORT_TIME_BASE / protocol_em4100_get_time_divisor(proto) - EM_READ_JITTER_TIME_BASE / protocol_em4100_get_time_divisor(proto); +} + +uint16_t protocol_em4100_get_short_time_high(ProtocolEM4100 *proto) { + return EM_READ_SHORT_TIME_BASE / protocol_em4100_get_time_divisor(proto) + EM_READ_JITTER_TIME_BASE / protocol_em4100_get_time_divisor(proto); +} + +uint16_t protocol_em4100_get_long_time_low(ProtocolEM4100 *proto) { + return EM_READ_LONG_TIME_BASE / protocol_em4100_get_time_divisor(proto) - EM_READ_JITTER_TIME_BASE / protocol_em4100_get_time_divisor(proto); + +} + +uint16_t protocol_em4100_get_long_time_high(ProtocolEM4100 *proto) { + return EM_READ_LONG_TIME_BASE / protocol_em4100_get_time_divisor(proto) + EM_READ_JITTER_TIME_BASE / protocol_em4100_get_time_divisor(proto); +} + + + ProtocolEM4100* protocol_em4100_alloc(void) { ProtocolEM4100* proto = malloc(sizeof(ProtocolEM4100)); + proto->clock_per_bit = 64; return (void*)proto; }; +ProtocolEM4100* protocol_em4100_16_alloc(void) { + ProtocolEM4100* proto = malloc(sizeof(ProtocolEM4100)); + proto->clock_per_bit = 16; + return (void*)proto; +}; + +ProtocolEM4100* protocol_em4100_32_alloc(void) { + ProtocolEM4100* proto = malloc(sizeof(ProtocolEM4100)); + proto->clock_per_bit = 32; + return (void*)proto; +}; + + + void protocol_em4100_free(ProtocolEM4100* proto) { free(proto); }; @@ -145,13 +199,13 @@ bool protocol_em4100_decoder_feed(ProtocolEM4100* proto, bool level, uint32_t du ManchesterEvent event = ManchesterEventReset; - if(duration > EM_READ_SHORT_TIME_LOW && duration < EM_READ_SHORT_TIME_HIGH) { + if(duration > protocol_em4100_get_short_time_low(proto) && duration < protocol_em4100_get_short_time_high(proto)) { if(!level) { event = ManchesterEventShortHigh; } else { event = ManchesterEventShortLow; } - } else if(duration > EM_READ_LONG_TIME_LOW && duration < EM_READ_LONG_TIME_HIGH) { + } else if(duration > protocol_em4100_get_long_time_low(proto) && duration < protocol_em4100_get_long_time_high(proto)) { if(!level) { event = ManchesterEventLongHigh; } else { @@ -227,7 +281,7 @@ bool protocol_em4100_encoder_start(ProtocolEM4100* proto) { LevelDuration protocol_em4100_encoder_yield(ProtocolEM4100* proto) { bool level = (proto->encoded_data >> (63 - proto->encoded_data_index)) & 1; - uint32_t duration = EM4100_CLOCK_PER_BIT / 2; + uint32_t duration = proto->clock_per_bit / 2; if(proto->encoded_polarity) { proto->encoded_polarity = false; @@ -260,7 +314,7 @@ bool protocol_em4100_write_data(ProtocolEM4100* protocol, void* data) { if(request->write_type == LFRFIDWriteTypeT5577) { request->t5577.block[0] = - (LFRFID_T5577_MODULATION_MANCHESTER | LFRFID_T5577_BITRATE_RF_64 | + (LFRFID_T5577_MODULATION_MANCHESTER | protocol_em4100_get_t5577_bitrate(protocol) | (2 << LFRFID_T5577_MAXBLOCK_SHIFT)); request->t5577.block[1] = protocol->encoded_data; request->t5577.block[2] = protocol->encoded_data >> 32; @@ -273,7 +327,7 @@ bool protocol_em4100_write_data(ProtocolEM4100* protocol, void* data) { void protocol_em4100_render_data(ProtocolEM4100* protocol, FuriString* result) { uint8_t* data = protocol->data; furi_string_printf( - result, "FC: %03u, Card: %05u", data[2], (uint16_t)((data[3] << 8) | (data[4]))); + result, "FC: %03u, Card: %05u (RF/%u)", data[2], (uint16_t)((data[3] << 8) | (data[4])), protocol->clock_per_bit); }; const ProtocolBase protocol_em4100 = { @@ -298,4 +352,53 @@ const ProtocolBase protocol_em4100 = { .render_data = (ProtocolRenderData)protocol_em4100_render_data, .render_brief_data = (ProtocolRenderData)protocol_em4100_render_data, .write_data = (ProtocolWriteData)protocol_em4100_write_data, -}; \ No newline at end of file +}; + + +const ProtocolBase protocol_em4100_32 = { + .name = "EM4100/32", + .manufacturer = "EM-Micro", + .data_size = EM4100_DECODED_DATA_SIZE, + .features = LFRFIDFeatureASK | LFRFIDFeaturePSK, + .validate_count = 3, + .alloc = (ProtocolAlloc)protocol_em4100_32_alloc, + .free = (ProtocolFree)protocol_em4100_free, + .get_data = (ProtocolGetData)protocol_em4100_get_data, + .decoder = + { + .start = (ProtocolDecoderStart)protocol_em4100_decoder_start, + .feed = (ProtocolDecoderFeed)protocol_em4100_decoder_feed, + }, + .encoder = + { + .start = (ProtocolEncoderStart)protocol_em4100_encoder_start, + .yield = (ProtocolEncoderYield)protocol_em4100_encoder_yield, + }, + .render_data = (ProtocolRenderData)protocol_em4100_render_data, + .render_brief_data = (ProtocolRenderData)protocol_em4100_render_data, + .write_data = (ProtocolWriteData)protocol_em4100_write_data, +}; + +const ProtocolBase protocol_em4100_16 = { + .name = "EM4100/16", + .manufacturer = "EM-Micro", + .data_size = EM4100_DECODED_DATA_SIZE, + .features = LFRFIDFeatureASK | LFRFIDFeaturePSK, + .validate_count = 3, + .alloc = (ProtocolAlloc)protocol_em4100_16_alloc, + .free = (ProtocolFree)protocol_em4100_free, + .get_data = (ProtocolGetData)protocol_em4100_get_data, + .decoder = + { + .start = (ProtocolDecoderStart)protocol_em4100_decoder_start, + .feed = (ProtocolDecoderFeed)protocol_em4100_decoder_feed, + }, + .encoder = + { + .start = (ProtocolEncoderStart)protocol_em4100_encoder_start, + .yield = (ProtocolEncoderYield)protocol_em4100_encoder_yield, + }, + .render_data = (ProtocolRenderData)protocol_em4100_render_data, + .render_brief_data = (ProtocolRenderData)protocol_em4100_render_data, + .write_data = (ProtocolWriteData)protocol_em4100_write_data, +}; diff --git a/lib/lfrfid/protocols/protocol_em4100.h b/lib/lfrfid/protocols/protocol_em4100.h index 6e1e25b93..23af66e27 100644 --- a/lib/lfrfid/protocols/protocol_em4100.h +++ b/lib/lfrfid/protocols/protocol_em4100.h @@ -1,4 +1,8 @@ #pragma once #include -extern const ProtocolBase protocol_em4100; \ No newline at end of file +extern const ProtocolBase protocol_em4100; + +extern const ProtocolBase protocol_em4100_32; + +extern const ProtocolBase protocol_em4100_16;