flipper-zero-tutorials/rfid/t5577/protocol_demo1.c

141 lines
4.9 KiB
C
Raw Normal View History

2024-04-27 16:54:32 +00:00
/**
* @file protocol_demo1.c
* @brief Demo protocol, doesn't do read/emulate, but does write data to the T5577 tag.
* @details This protocol is a demo protocol that doesn't actually do any reading or
* emulating, but does write data to the T5577 tag. This is useful for testing the
* write functionality of the T5577 tag. You can change the data in the write_data
* function to write different data to the T5577 tag.
*
* A sample file looks like (test.rfid):
* Filetype: Flipper RFID key
* Version: 1
* Key type: Demo1
* Data: 42 13
*
* You can also go to 125 kHz RFID, Add Manually, Derek Jamison Demo1, enter the
* data "42 13", click save, choose a name, and click save again. This will create
* the test.rfid file.
*
* For more information, see the youtube video at https://youtu.be/nSCIOz2bVR0
*/
#include <furi.h>
#include <toolbox/protocols/protocol.h>
#include <bit_lib/bit_lib.h>
#include "lfrfid_protocols.h"
#define TAG "Demo1"
#define DEMO1_DECODED_DATA_SIZE (2)
typedef struct {
uint8_t data[DEMO1_DECODED_DATA_SIZE];
uint32_t feed_counter;
} ProtocolDemo1;
ProtocolDemo1* protocol_demo1_alloc(void) {
ProtocolDemo1* protocol = malloc(sizeof(ProtocolDemo1));
return protocol;
};
void protocol_demo1_free(ProtocolDemo1* protocol) {
free(protocol);
};
uint8_t* protocol_demo1_get_data(ProtocolDemo1* protocol) {
return protocol->data;
};
void protocol_demo1_decoder_start(ProtocolDemo1* protocol) {
// This would normally reset the decoder state (clearing encoded_data).
protocol->feed_counter = 0;
};
bool protocol_demo1_decoder_feed(ProtocolDemo1* protocol, bool level, uint32_t duration) {
// Normally, we would decode the data here & see if the data looks like a full packet.
// NOTE: duration is in us.
// When it does, you would return true.
UNUSED(level);
UNUSED(duration);
// Prints "data: [0]:42 [1]:13" to the log for our sample file.
FURI_LOG_D(TAG, "data: [0]:%02x [1]:%02x", protocol->data[0], protocol->data[1]);
if(protocol->data[0] == 0x42) {
protocol->feed_counter++;
}
return protocol->feed_counter % 100 == 99;
};
bool protocol_demo1_encoder_start(ProtocolDemo1* protocol) {
// This would normally reset the encoder state (populating encoded_data).
UNUSED(protocol);
return true;
};
LevelDuration protocol_demo1_encoder_yield(ProtocolDemo1* protocol) {
// This would normally return the next level/duration pair to send.
// Note: duration is in ticks (8us).
UNUSED(protocol);
return level_duration_make(true, 1);
};
void protocol_demo1_render_data(ProtocolDemo1* protocol, FuriString* result) {
// This would normally use protocol->data to populate the result string.
UNUSED(protocol);
furi_string_printf(result, "ATA5577 Maker %02x %02x", protocol->data[0], protocol->data[1]);
}
void protocol_demo1_render_brief_data(ProtocolDemo1* protocol, FuriString* result) {
// This would normally use protocol->data to populate the brief result string.
UNUSED(protocol);
furi_string_printf(result, "T5577 %02x %02x", protocol->data[0], protocol->data[1]);
}
bool protocol_demo1_write_data(ProtocolDemo1* protocol, void* data) {
LFRFIDWriteRequest* request = (LFRFIDWriteRequest*)data;
bool result = false;
protocol_demo1_encoder_start(protocol);
// This would normally write the data to the T5577 using the data
// from the protocol->encoded_data. For this demo, we'll just
// populate the request with some known data.
//
// We use the data from https://youtu.be/5DvIBvXBDX8?t=367
if(request->write_type == LFRFIDWriteTypeT5577) {
request->t5577.block[0] = LFRFID_T5577_MODULATION_FSK2a | LFRFID_T5577_BITRATE_RF_50 |
(3 << LFRFID_T5577_MAXBLOCK_SHIFT);
request->t5577.block[1] = 0x1D555955;
request->t5577.block[2] = 0x5569A599;
request->t5577.block[3] = 0xA96A995A;
request->t5577.blocks_to_write = 4;
result = true;
}
return result;
};
const ProtocolBase protocol_demo1 = {
.name = "Demo1",
.manufacturer = "Derek Jamison",
.data_size = DEMO1_DECODED_DATA_SIZE,
.features = LFRFIDFeatureASK,
.validate_count = 2,
.alloc = (ProtocolAlloc)protocol_demo1_alloc,
.free = (ProtocolFree)protocol_demo1_free,
.get_data = (ProtocolGetData)protocol_demo1_get_data,
.decoder =
{
.start = (ProtocolDecoderStart)protocol_demo1_decoder_start,
.feed = (ProtocolDecoderFeed)protocol_demo1_decoder_feed,
},
.encoder =
{
.start = (ProtocolEncoderStart)protocol_demo1_encoder_start,
.yield = (ProtocolEncoderYield)protocol_demo1_encoder_yield,
},
.render_data = (ProtocolRenderData)protocol_demo1_render_data,
.render_brief_data = (ProtocolRenderData)protocol_demo1_render_brief_data,
.write_data = (ProtocolWriteData)protocol_demo1_write_data,
};