diff --git a/CHANGELOG.md b/CHANGELOG.md
index 30c0c1f7d..3b4d73eb9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,34 +1,12 @@
## Main changes
- Current API: 79.3
-* SubGHz: Jolly Motors support (with add manually) (Thanks @pkooiman !)
-* Power: Auto Power Off Timer (by @Dmitry422 with some fixes by @xMasterX)
-* OFW: **Fix lost BadBLE keystrokes**
-* OFW: **Add the ability to send a signal once via RPC**
-* OFW PR 4070: Infrared: increase max carrier limit (by @skotopes)
-* OFW PR 4025: Increase system stack's reserved memory size (Fix USB UART Bridge Crash) (by @Astrrra)
-* OFW: merged gsurkov/vcp_break_support branch for usb uart bridge (WIP!!!)
+* OFW: LFRFID - **EM4305 support**
* Apps: **Check out more Apps updates and fixes by following** [this link](https://github.com/xMasterX/all-the-plugins/commits/dev)
## Other changes
-* Power & Desktop: Add input events sub check & use event system for auto power off
-* OFW: Rename FuriHalDebuging.md to FuriHalDebugging.md
-* OFW: nfc: Fix MIFARE Plus detection
-* OFW: u2f: Fix leaking message digest contexts
-* OFW: nfc: Fix MFUL PWD_AUTH command creation
-* OFW: Bump cross-spawn in /applications/system/js_app/packages/create-fz-app
-* OFW: **Pipe** (new api funcs)
-* OFW: Fix invalid path errors while deploying SDK by enforcing toolchain to use UTF-8 on initial SDK Extraction
-* OFW: **Added flipper_format_write_empty_line(...)**
-* OFW: Fix skylander ID reading
-* OFW: Work around incorrect serial port handling by the OS
-* OFW: Add winter animations
-* OFW: FBT: Don't lint JS packages
-* OFW: **Loader: Fix BusFault in handling of OOM** (was already included in previous UL release)
-* OFW: **NFC Fix ISO15693 stucking in wrong mode.**
-* OFW: Update `infrared_test.c` reference
-* OFW: **FuriThread stdin**
-* OFW: NFC: Plantain parser Last payment amount fix
-* OFW: NFC clipper: BART station ids for San Lorenzo, Bay Fair
-* OFW: Fix typo for mf_classic_key_cahce_get_next_key() function
+* OFW: Infrared: increase max carrier limit
+* OFW: Ensure that `furi_record_create` is passed a non-NULL data pointer
+* OFW: Update mbedtls & expose AES
+* OFW: Add the Showtime animation
#### Known NFC post-refactor regressions list:
- Mifare Mini clones reading is broken (original mini working fine) (OFW)
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_0.png b/assets/dolphin/external/L1_Showtime_128x64/frame_0.png
new file mode 100755
index 000000000..7eed9a024
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_0.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_1.png b/assets/dolphin/external/L1_Showtime_128x64/frame_1.png
new file mode 100755
index 000000000..827730087
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_1.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_10.png b/assets/dolphin/external/L1_Showtime_128x64/frame_10.png
new file mode 100755
index 000000000..c627bd6f9
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_10.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_11.png b/assets/dolphin/external/L1_Showtime_128x64/frame_11.png
new file mode 100755
index 000000000..0535101be
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_11.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_12.png b/assets/dolphin/external/L1_Showtime_128x64/frame_12.png
new file mode 100755
index 000000000..1284019a8
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_12.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_13.png b/assets/dolphin/external/L1_Showtime_128x64/frame_13.png
new file mode 100755
index 000000000..bc71a08a0
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_13.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_14.png b/assets/dolphin/external/L1_Showtime_128x64/frame_14.png
new file mode 100755
index 000000000..1444ab836
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_14.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_15.png b/assets/dolphin/external/L1_Showtime_128x64/frame_15.png
new file mode 100755
index 000000000..0945008a5
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_15.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_16.png b/assets/dolphin/external/L1_Showtime_128x64/frame_16.png
new file mode 100755
index 000000000..0d1246fc7
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_16.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_17.png b/assets/dolphin/external/L1_Showtime_128x64/frame_17.png
new file mode 100755
index 000000000..4d0b7227f
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_17.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_18.png b/assets/dolphin/external/L1_Showtime_128x64/frame_18.png
new file mode 100755
index 000000000..d53d074e6
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_18.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_19.png b/assets/dolphin/external/L1_Showtime_128x64/frame_19.png
new file mode 100755
index 000000000..0d421d372
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_19.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_2.png b/assets/dolphin/external/L1_Showtime_128x64/frame_2.png
new file mode 100755
index 000000000..a52e051b9
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_2.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_20.png b/assets/dolphin/external/L1_Showtime_128x64/frame_20.png
new file mode 100755
index 000000000..a5962bd2c
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_20.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_21.png b/assets/dolphin/external/L1_Showtime_128x64/frame_21.png
new file mode 100755
index 000000000..5113c1095
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_21.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_22.png b/assets/dolphin/external/L1_Showtime_128x64/frame_22.png
new file mode 100755
index 000000000..88ba06d37
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_22.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_23.png b/assets/dolphin/external/L1_Showtime_128x64/frame_23.png
new file mode 100755
index 000000000..6507bdc6b
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_23.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_24.png b/assets/dolphin/external/L1_Showtime_128x64/frame_24.png
new file mode 100755
index 000000000..5d4360a82
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_24.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_25.png b/assets/dolphin/external/L1_Showtime_128x64/frame_25.png
new file mode 100755
index 000000000..817c78ab5
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_25.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_26.png b/assets/dolphin/external/L1_Showtime_128x64/frame_26.png
new file mode 100755
index 000000000..93f02f48e
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_26.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_27.png b/assets/dolphin/external/L1_Showtime_128x64/frame_27.png
new file mode 100755
index 000000000..2b856cc79
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_27.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_28.png b/assets/dolphin/external/L1_Showtime_128x64/frame_28.png
new file mode 100755
index 000000000..bcf538072
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_28.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_29.png b/assets/dolphin/external/L1_Showtime_128x64/frame_29.png
new file mode 100755
index 000000000..68b32d80c
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_29.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_3.png b/assets/dolphin/external/L1_Showtime_128x64/frame_3.png
new file mode 100755
index 000000000..e7bf65287
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_3.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_30.png b/assets/dolphin/external/L1_Showtime_128x64/frame_30.png
new file mode 100755
index 000000000..4d34f9afb
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_30.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_31.png b/assets/dolphin/external/L1_Showtime_128x64/frame_31.png
new file mode 100755
index 000000000..274a16074
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_31.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_32.png b/assets/dolphin/external/L1_Showtime_128x64/frame_32.png
new file mode 100755
index 000000000..7dbb729ef
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_32.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_33.png b/assets/dolphin/external/L1_Showtime_128x64/frame_33.png
new file mode 100755
index 000000000..3cfbe5a98
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_33.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_34.png b/assets/dolphin/external/L1_Showtime_128x64/frame_34.png
new file mode 100755
index 000000000..4e64d9db3
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_34.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_35.png b/assets/dolphin/external/L1_Showtime_128x64/frame_35.png
new file mode 100755
index 000000000..09fe5c1cd
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_35.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_36.png b/assets/dolphin/external/L1_Showtime_128x64/frame_36.png
new file mode 100755
index 000000000..4139bd8b5
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_36.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_37.png b/assets/dolphin/external/L1_Showtime_128x64/frame_37.png
new file mode 100755
index 000000000..0384fbdae
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_37.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_38.png b/assets/dolphin/external/L1_Showtime_128x64/frame_38.png
new file mode 100755
index 000000000..2632807f9
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_38.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_39.png b/assets/dolphin/external/L1_Showtime_128x64/frame_39.png
new file mode 100755
index 000000000..f257489a1
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_39.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_4.png b/assets/dolphin/external/L1_Showtime_128x64/frame_4.png
new file mode 100755
index 000000000..8a0c1734e
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_4.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_40.png b/assets/dolphin/external/L1_Showtime_128x64/frame_40.png
new file mode 100755
index 000000000..cbcff2c89
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_40.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_41.png b/assets/dolphin/external/L1_Showtime_128x64/frame_41.png
new file mode 100755
index 000000000..4377a91c6
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_41.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_42.png b/assets/dolphin/external/L1_Showtime_128x64/frame_42.png
new file mode 100755
index 000000000..30b446707
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_42.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_43.png b/assets/dolphin/external/L1_Showtime_128x64/frame_43.png
new file mode 100755
index 000000000..10d9579a3
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_43.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_44.png b/assets/dolphin/external/L1_Showtime_128x64/frame_44.png
new file mode 100755
index 000000000..6d9362c51
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_44.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_45.png b/assets/dolphin/external/L1_Showtime_128x64/frame_45.png
new file mode 100755
index 000000000..f834ad6c1
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_45.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_46.png b/assets/dolphin/external/L1_Showtime_128x64/frame_46.png
new file mode 100755
index 000000000..4c799effb
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_46.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_47.png b/assets/dolphin/external/L1_Showtime_128x64/frame_47.png
new file mode 100755
index 000000000..017549d29
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_47.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_48.png b/assets/dolphin/external/L1_Showtime_128x64/frame_48.png
new file mode 100755
index 000000000..28497ac23
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_48.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_49.png b/assets/dolphin/external/L1_Showtime_128x64/frame_49.png
new file mode 100755
index 000000000..5a25c32da
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_49.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_5.png b/assets/dolphin/external/L1_Showtime_128x64/frame_5.png
new file mode 100755
index 000000000..04ad4360c
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_5.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_6.png b/assets/dolphin/external/L1_Showtime_128x64/frame_6.png
new file mode 100755
index 000000000..86bcbf48c
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_6.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_7.png b/assets/dolphin/external/L1_Showtime_128x64/frame_7.png
new file mode 100755
index 000000000..3e2a2c739
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_7.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_8.png b/assets/dolphin/external/L1_Showtime_128x64/frame_8.png
new file mode 100755
index 000000000..d9babe8dc
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_8.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/frame_9.png b/assets/dolphin/external/L1_Showtime_128x64/frame_9.png
new file mode 100755
index 000000000..24dcababb
Binary files /dev/null and b/assets/dolphin/external/L1_Showtime_128x64/frame_9.png differ
diff --git a/assets/dolphin/external/L1_Showtime_128x64/meta.txt b/assets/dolphin/external/L1_Showtime_128x64/meta.txt
new file mode 100755
index 000000000..da24febdc
--- /dev/null
+++ b/assets/dolphin/external/L1_Showtime_128x64/meta.txt
@@ -0,0 +1,23 @@
+Filetype: Flipper Animation
+Version: 1
+
+Width: 128
+Height: 64
+Passive frames: 26
+Active frames: 26
+Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 41 42 43 44 45 46 47 48 49
+Active cycles: 1
+Frame rate: 2
+Duration: 3600
+Active cooldown: 7
+
+Bubble slots: 1
+
+Slot: 0
+X: 69
+Y: 47
+Text: SHOWTIME!
+AlignH: Left
+AlignV: Center
+StartFrame: 41
+EndFrame: 44
diff --git a/assets/dolphin/external/manifest.txt b/assets/dolphin/external/manifest.txt
index 7e8bee083..0ea791ebb 100644
--- a/assets/dolphin/external/manifest.txt
+++ b/assets/dolphin/external/manifest.txt
@@ -216,7 +216,7 @@ Min butthurt: 0
Max butthurt: 14
Min level: 1
Max level: 3
-Weight: 4
+Weight: 3
Name: L1_Sleigh_ride_128x64
Min butthurt: 0
@@ -225,6 +225,14 @@ Min level: 1
Max level: 3
Weight: 4
+Name: L1_Showtime_128x64
+Min butthurt: 0
+Max butthurt: 10
+Min level: 1
+Max level: 3
+Weight: 4
+
+
Name: L1_New_year_128x64
Min butthurt: 0
Max butthurt: 14
diff --git a/furi/core/record.c b/furi/core/record.c
index fa384369a..17c95aa9b 100644
--- a/furi/core/record.c
+++ b/furi/core/record.c
@@ -80,6 +80,7 @@ bool furi_record_exists(const char* name) {
void furi_record_create(const char* name, void* data) {
furi_check(furi_record);
furi_check(name);
+ furi_check(data);
furi_record_lock();
diff --git a/furi/core/record.h b/furi/core/record.h
index a269484f0..1fb20ed6f 100644
--- a/furi/core/record.h
+++ b/furi/core/record.h
@@ -27,7 +27,7 @@ bool furi_record_exists(const char* name);
/** Create record
*
* @param name record name
- * @param data data pointer
+ * @param data data pointer (not NULL)
* @note Thread safe. Create and destroy must be executed from the same
* thread.
*/
diff --git a/lib/lfrfid/lfrfid_worker_modes.c b/lib/lfrfid/lfrfid_worker_modes.c
index d0569b300..645d2bd82 100644
--- a/lib/lfrfid/lfrfid_worker_modes.c
+++ b/lib/lfrfid/lfrfid_worker_modes.c
@@ -510,9 +510,6 @@ static void lfrfid_worker_mode_emulate_process(LFRFIDWorker* worker) {
static void lfrfid_worker_mode_write_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;
@@ -521,63 +518,88 @@ static void lfrfid_worker_mode_write_process(LFRFIDWorker* worker) {
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");
- t5577_write(&request->t5577);
+ while(!lfrfid_worker_check_for_stop(worker)) {
+ FURI_LOG_D(TAG, "Data write");
+ uint16_t skips = 0;
+ for(size_t i = 0; i < LFRFIDWriteTypeMax; i++) {
+ memset(request, 0, sizeof(LFRFIDWriteRequest));
+ LFRFIDWriteType write_type = i;
+ request->write_type = write_type;
- 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);
+ protocol_dict_set_data(worker->protocols, protocol, verify_data, data_size);
- if(state == LFRFIDWorkerReadOK) {
- bool read_success = false;
+ bool can_be_written =
+ protocol_dict_get_write_data(worker->protocols, protocol, request);
- 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) {
+ if(!can_be_written) {
+ skips++;
+ if(skips == LFRFIDWriteTypeMax) {
if(worker->write_cb) {
- worker->write_cb(LFRFIDWorkerWriteOK, worker->cb_ctx);
+ worker->write_cb(LFRFIDWorkerWriteProtocolCannotBeWritten, worker->cb_ctx);
}
break;
- } else {
- unsuccessful_reads++;
+ }
+ continue;
+ }
- if(unsuccessful_reads == LFRFID_WORKER_WRITE_MAX_UNSUCCESSFUL_READS) {
- if(worker->write_cb) {
- worker->write_cb(LFRFIDWorkerWriteFobCannotBeWritten, worker->cb_ctx);
- }
+ memset(read_data, 0, data_size);
+
+ if(request->write_type == LFRFIDWriteTypeT5577) {
+ t5577_write(&request->t5577);
+ } else if(request->write_type == LFRFIDWriteTypeEM4305) {
+ em4305_write(&request->em4305);
+ } else {
+ furi_crash("Unknown write type");
+ }
+ }
+ 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) {
+ 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;
}
+ } 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);
- }
+ 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);
- }
+ lfrfid_worker_delay(worker, LFRFID_WORKER_WRITE_DROP_TIME_MS);
}
free(request);
diff --git a/lib/lfrfid/protocols/lfrfid_protocols.h b/lib/lfrfid/protocols/lfrfid_protocols.h
index 12ac2dddd..9621bc408 100644
--- a/lib/lfrfid/protocols/lfrfid_protocols.h
+++ b/lib/lfrfid/protocols/lfrfid_protocols.h
@@ -1,6 +1,7 @@
#pragma once
#include
#include "../tools/t5577.h"
+#include "../tools/em4305.h"
typedef enum {
LFRFIDFeatureASK = 1 << 0, /** ASK Demodulation */
@@ -31,6 +32,7 @@ typedef enum {
LFRFIDProtocolNexwatch,
LFRFIDProtocolSecurakey,
LFRFIDProtocolGProxII,
+
LFRFIDProtocolMax,
} LFRFIDProtocol;
@@ -38,11 +40,15 @@ extern const ProtocolBase* lfrfid_protocols[];
typedef enum {
LFRFIDWriteTypeT5577,
+ LFRFIDWriteTypeEM4305,
+
+ LFRFIDWriteTypeMax,
} LFRFIDWriteType;
typedef struct {
LFRFIDWriteType write_type;
union {
LFRFIDT5577 t5577;
+ LFRFIDEM4305 em4305;
};
} LFRFIDWriteRequest;
diff --git a/lib/lfrfid/protocols/protocol_electra.c b/lib/lfrfid/protocols/protocol_electra.c
index 25fcdc514..50d82c8f1 100644
--- a/lib/lfrfid/protocols/protocol_electra.c
+++ b/lib/lfrfid/protocols/protocol_electra.c
@@ -407,6 +407,24 @@ bool protocol_electra_write_data(ProtocolElectra* protocol, void* data) {
request->t5577.blocks_to_write = 5;
result = true;
}
+ if(request->write_type == LFRFIDWriteTypeEM4305) {
+ request->em4305.word[4] =
+ (EM4x05_MODULATION_MANCHESTER | EM4x05_SET_BITRATE(64) | (8 << EM4x05_MAXBLOCK_SHIFT));
+ uint64_t encoded_data_reversed = 0;
+ uint64_t encoded_epilogue_reversed = 0;
+ for(uint8_t i = 0; i < 64; i++) {
+ encoded_data_reversed = (encoded_data_reversed << 1) |
+ ((protocol->encoded_base_data >> i) & 1);
+ encoded_epilogue_reversed = (encoded_epilogue_reversed << 1) |
+ ((protocol->encoded_epilogue >> i) & 1);
+ }
+ request->em4305.word[5] = encoded_data_reversed & 0xFFFFFFFF;
+ request->em4305.word[6] = encoded_data_reversed >> 32;
+ request->em4305.word[7] = encoded_epilogue_reversed & 0xFFFFFFFF;
+ request->em4305.word[8] = encoded_epilogue_reversed >> 32;
+ request->em4305.mask = 0x01F0;
+ result = true;
+ }
return result;
}
diff --git a/lib/lfrfid/protocols/protocol_em4100.c b/lib/lfrfid/protocols/protocol_em4100.c
index e68bc0e2e..ed18133dc 100644
--- a/lib/lfrfid/protocols/protocol_em4100.c
+++ b/lib/lfrfid/protocols/protocol_em4100.c
@@ -69,6 +69,19 @@ uint32_t protocol_em4100_get_t5577_bitrate(ProtocolEM4100* proto) {
}
}
+uint32_t protocol_em4100_get_em4305_bitrate(ProtocolEM4100* proto) {
+ switch(proto->clock_per_bit) {
+ case 64:
+ return EM4x05_SET_BITRATE(64);
+ case 32:
+ return EM4x05_SET_BITRATE(32);
+ case 16:
+ return EM4x05_SET_BITRATE(16);
+ default:
+ return EM4x05_SET_BITRATE(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);
@@ -339,6 +352,19 @@ bool protocol_em4100_write_data(ProtocolEM4100* protocol, void* data) {
request->t5577.block[2] = protocol->encoded_data;
request->t5577.blocks_to_write = 3;
result = true;
+ } else if(request->write_type == LFRFIDWriteTypeEM4305) {
+ request->em4305.word[4] =
+ (EM4x05_MODULATION_MANCHESTER | protocol_em4100_get_em4305_bitrate(protocol) |
+ (6 << EM4x05_MAXBLOCK_SHIFT));
+ uint64_t encoded_data_reversed = 0;
+ for(uint8_t i = 0; i < 64; i++) {
+ encoded_data_reversed = (encoded_data_reversed << 1) |
+ ((protocol->encoded_data >> i) & 1);
+ }
+ request->em4305.word[5] = encoded_data_reversed;
+ request->em4305.word[6] = encoded_data_reversed >> 32;
+ request->em4305.mask = 0x70;
+ result = true;
}
return result;
}
diff --git a/lib/lfrfid/protocols/protocol_gallagher.c b/lib/lfrfid/protocols/protocol_gallagher.c
index 9ae0cf80a..bbed99706 100644
--- a/lib/lfrfid/protocols/protocol_gallagher.c
+++ b/lib/lfrfid/protocols/protocol_gallagher.c
@@ -264,6 +264,20 @@ bool protocol_gallagher_write_data(ProtocolGallagher* protocol, void* data) {
request->t5577.block[3] = bit_lib_get_bits_32(protocol->encoded_data, 64, 32);
request->t5577.blocks_to_write = 4;
result = true;
+ } else if(request->write_type == LFRFIDWriteTypeEM4305) {
+ request->em4305.word[4] =
+ (EM4x05_MODULATION_MANCHESTER | EM4x05_SET_BITRATE(32) | (7 << EM4x05_MAXBLOCK_SHIFT));
+ uint32_t encoded_data_reversed[3] = {0};
+ for(uint8_t i = 0; i < (32 * 3); i++) {
+ encoded_data_reversed[i / 32] =
+ (encoded_data_reversed[i / 32] << 1) |
+ (bit_lib_get_bit(protocol->encoded_data, ((32 * 3) - i)) & 1);
+ }
+ request->em4305.word[5] = encoded_data_reversed[2];
+ request->em4305.word[6] = encoded_data_reversed[1];
+ request->em4305.word[7] = encoded_data_reversed[0];
+ request->em4305.mask = 0xF0;
+ result = true;
}
return result;
}
diff --git a/lib/lfrfid/protocols/protocol_viking.c b/lib/lfrfid/protocols/protocol_viking.c
index 78499a415..7e9009fde 100644
--- a/lib/lfrfid/protocols/protocol_viking.c
+++ b/lib/lfrfid/protocols/protocol_viking.c
@@ -171,6 +171,19 @@ bool protocol_viking_write_data(ProtocolViking* protocol, void* data) {
request->t5577.block[2] = bit_lib_get_bits_32(protocol->encoded_data, 32, 32);
request->t5577.blocks_to_write = 3;
result = true;
+ } else if(request->write_type == LFRFIDWriteTypeEM4305) {
+ request->em4305.word[4] =
+ (EM4x05_MODULATION_MANCHESTER | EM4x05_SET_BITRATE(32) | (6 << EM4x05_MAXBLOCK_SHIFT));
+ uint32_t encoded_data_reversed[2] = {0};
+ for(uint8_t i = 0; i < 64; i++) {
+ encoded_data_reversed[i / 32] =
+ (encoded_data_reversed[i / 32] << 1) |
+ (bit_lib_get_bit(protocol->encoded_data, (63 - i)) & 1);
+ }
+ request->em4305.word[5] = encoded_data_reversed[1];
+ request->em4305.word[6] = encoded_data_reversed[0];
+ request->em4305.mask = 0x70;
+ result = true;
}
return result;
}
diff --git a/lib/lfrfid/tools/em4305.c b/lib/lfrfid/tools/em4305.c
new file mode 100644
index 000000000..3b072d38d
--- /dev/null
+++ b/lib/lfrfid/tools/em4305.c
@@ -0,0 +1,152 @@
+#include "em4305.h"
+#include
+#include
+
+#define TAG "EM4305"
+
+#define EM4305_TIMING_1 (32)
+#define EM4305_TIMING_0_OFF (23)
+#define EM4305_TIMING_0_ON (18)
+
+#define EM4305_FIELD_STOP_OFF_CYCLES (55)
+#define EM4305_FIELD_STOP_ON_CYCLES (18)
+
+#define EM4305_TIMING_POWER_CHECK (1480)
+#define EM4305_TIMING_EEPROM_WRITE (9340)
+
+static bool em4305_line_parity(uint8_t data) {
+ uint8_t parity = 0;
+ for(uint8_t i = 0; i < 8; i++) {
+ parity ^= (data >> i) & 1;
+ }
+ return parity;
+}
+
+static uint64_t em4305_prepare_data(uint32_t data) {
+ uint8_t i, j;
+ uint64_t data_with_parity = 0;
+
+ // 4 lines of 8 bits of data
+ // line even parity at bits 8 17 26 35
+ // column even parity at bits 36-43
+ // bit 44 is always 0
+ // final table is 5 lines of 9 bits
+
+ // line parity
+ for(i = 0; i < 4; i++) {
+ for(j = 0; j < 8; j++) {
+ data_with_parity = (data_with_parity << 1) | ((data >> (i * 8 + j)) & 1);
+ }
+ data_with_parity = (data_with_parity << 1) | (uint64_t)em4305_line_parity(data >> (i * 8));
+ }
+
+ // column parity
+ for(i = 0; i < 8; i++) {
+ uint8_t column_parity = 0;
+ for(j = 0; j < 4; j++) {
+ column_parity ^= (data >> (j * 8 + i)) & 1;
+ }
+ data_with_parity = (data_with_parity << 1) | column_parity;
+ }
+
+ // bit 44
+ data_with_parity = (data_with_parity << 1) | 0;
+
+ return data_with_parity;
+}
+
+static void em4305_start(void) {
+ furi_hal_rfid_tim_read_start(125000, 0.5);
+
+ // do not ground the antenna
+ furi_hal_rfid_pin_pull_release();
+}
+
+static void em4305_stop(void) {
+ furi_hal_rfid_tim_read_stop();
+ furi_hal_rfid_pins_reset();
+}
+
+static void em4305_write_bit(bool value) {
+ if(value) {
+ furi_delay_us(EM4305_TIMING_1 * 8);
+ } else {
+ furi_hal_rfid_tim_read_pause();
+ furi_delay_us(EM4305_TIMING_0_OFF * 8);
+ furi_hal_rfid_tim_read_continue();
+ furi_delay_us(EM4305_TIMING_0_ON * 8);
+ }
+}
+
+static void em4305_write_opcode(uint8_t value) {
+ // 3 bit opcode
+ for(uint8_t i = 0; i < 3; i++) {
+ em4305_write_bit((value >> i) & 1);
+ }
+
+ // parity
+ bool parity = 0;
+ for(uint8_t i = 0; i < 3; i++) {
+ parity ^= (value >> i) & 1;
+ }
+ em4305_write_bit(parity);
+}
+
+static void em4305_field_stop() {
+ furi_hal_rfid_tim_read_pause();
+ furi_delay_us(EM4305_FIELD_STOP_OFF_CYCLES * 8);
+ furi_hal_rfid_tim_read_continue();
+ furi_delay_us(EM4305_FIELD_STOP_ON_CYCLES * 8);
+}
+
+static void em4305_write_word(uint8_t address, uint32_t data) {
+ // parity
+ uint64_t data_with_parity = em4305_prepare_data(data);
+
+ // power up the tag
+ furi_delay_us(8000);
+
+ // field stop
+ em4305_field_stop();
+
+ // start bit
+ em4305_write_bit(0);
+
+ // opcode
+ em4305_write_opcode(EM4x05_OPCODE_WRITE);
+
+ // address
+ bool address_parity = 0;
+ for(uint8_t i = 0; i < 4; i++) {
+ em4305_write_bit((address >> (i)) & 1);
+ address_parity ^= (address >> (i)) & 1;
+ }
+ em4305_write_bit(0);
+ em4305_write_bit(0);
+ em4305_write_bit(address_parity);
+
+ // data
+ for(uint8_t i = 0; i < 45; i++) {
+ em4305_write_bit((data_with_parity >> (44 - i)) & 1);
+ }
+
+ // wait for power check and eeprom write
+ furi_delay_us(EM4305_TIMING_POWER_CHECK);
+ furi_delay_us(EM4305_TIMING_EEPROM_WRITE);
+}
+
+void em4305_write(LFRFIDEM4305* data) {
+ furi_check(data);
+
+ em4305_start();
+ FURI_CRITICAL_ENTER();
+
+ for(uint8_t i = 0; i < EM4x05_WORD_COUNT; i++) {
+ if(data->mask & (1 << i)) {
+ em4305_write_word(i, data->word[i]);
+ }
+ }
+
+ FURI_CRITICAL_EXIT();
+ em4305_stop();
+}
diff --git a/lib/lfrfid/tools/em4305.h b/lib/lfrfid/tools/em4305.h
new file mode 100644
index 000000000..0cec00254
--- /dev/null
+++ b/lib/lfrfid/tools/em4305.h
@@ -0,0 +1,61 @@
+#pragma once
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// EM4305/4205 chip config definitions, thanks proxmark3!
+#define EM4x05_GET_BITRATE(x) ((((x) & 0x3F) * 2) + 2)
+// Note: only data rates 8, 16, 32, 40(*) and 64 are supported. (*) only with EM4305 330pF
+#define EM4x05_SET_BITRATE(x) (((x) - 2) / 2)
+#define EM4x05_MODULATION_NRZ (0x00000000)
+#define EM4x05_MODULATION_MANCHESTER (0x00000040)
+#define EM4x05_MODULATION_BIPHASE (0x00000080)
+#define EM4x05_MODULATION_MILLER (0x000000C0) // not supported by all 4x05/4x69 chips
+#define EM4x05_MODULATION_PSK1 (0x00000100) // not supported by all 4x05/4x69 chips
+#define EM4x05_MODULATION_PSK2 (0x00000140) // not supported by all 4x05/4x69 chips
+#define EM4x05_MODULATION_PSK3 (0x00000180) // not supported by all 4x05/4x69 chips
+#define EM4x05_MODULATION_FSK1 (0x00000200) // not supported by all 4x05/4x69 chips
+#define EM4x05_MODULATION_FSK2 (0x00000240) // not supported by all 4x05/4x69 chips
+#define EM4x05_PSK_RF_2 (0)
+#define EM4x05_PSK_RF_4 (0x00000400)
+#define EM4x05_PSK_RF_8 (0x00000800)
+#define EM4x05_MAXBLOCK_SHIFT (14)
+#define EM4x05_FIRST_USER_BLOCK (5)
+#define EM4x05_SET_NUM_BLOCKS(x) \
+ (((x) + 4) << 14) // number of blocks sent during default read mode
+#define EM4x05_GET_NUM_BLOCKS(x) ((((x) >> 14) & 0xF) - 4)
+#define EM4x05_READ_LOGIN_REQ (1 << 18)
+#define EM4x05_READ_HK_LOGIN_REQ (1 << 19)
+#define EM4x05_WRITE_LOGIN_REQ (1 << 20)
+#define EM4x05_WRITE_HK_LOGIN_REQ (1 << 21)
+#define EM4x05_READ_AFTER_WRITE (1 << 22)
+#define EM4x05_DISABLE_ALLOWED (1 << 23)
+#define EM4x05_READER_TALK_FIRST (1 << 24)
+#define EM4x05_INVERT (1 << 25)
+#define EM4x05_PIGEON (1 << 26)
+
+#define EM4x05_WORD_COUNT (16)
+
+#define EM4x05_OPCODE_LOGIN (0b001)
+#define EM4x05_OPCODE_WRITE (0b010)
+#define EM4x05_OPCODE_READ (0b100)
+#define EM4x05_OPCODE_PROTECT (0b110)
+#define EM4x05_OPCODE_DISABLE (0b101)
+
+typedef struct {
+ uint32_t word[EM4x05_WORD_COUNT]; /**< Word data to write */
+ uint16_t mask; /**< Word mask */
+} LFRFIDEM4305;
+
+/** Write EM4305 tag data to tag
+ *
+ * @param data The data to write (mask is taken from that data)
+ */
+void em4305_write(LFRFIDEM4305* data);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/lib/mbedtls b/lib/mbedtls
index edb8fec98..107ea89da 160000
--- a/lib/mbedtls
+++ b/lib/mbedtls
@@ -1 +1 @@
-Subproject commit edb8fec9882084344a314368ac7fd957a187519c
+Subproject commit 107ea89daaefb9867ea9121002fbbdf926780e98
diff --git a/lib/mbedtls.scons b/lib/mbedtls.scons
index 77add7696..759f263af 100644
--- a/lib/mbedtls.scons
+++ b/lib/mbedtls.scons
@@ -6,6 +6,7 @@ env.Append(
"#/lib/mbedtls/include",
],
SDK_HEADERS=[
+ File("mbedtls/include/mbedtls/aes.h"),
File("mbedtls/include/mbedtls/des.h"),
File("mbedtls/include/mbedtls/sha1.h"),
File("mbedtls/include/mbedtls/sha256.h"),
@@ -37,6 +38,7 @@ libenv.AppendUnique(
# sources = libenv.GlobRecursive("*.c*", "mbedtls/library")
# Otherwise, we can just use the files we need:
sources = [
+ File("mbedtls/library/aes.c"),
File("mbedtls/library/bignum.c"),
File("mbedtls/library/bignum_core.c"),
File("mbedtls/library/ecdsa.c"),
diff --git a/scripts/ufbt/project_template/app_template/.github/workflows/build.yml b/scripts/ufbt/project_template/app_template/.github/workflows/build.yml
index 143847c4a..613590d47 100644
--- a/scripts/ufbt/project_template/app_template/.github/workflows/build.yml
+++ b/scripts/ufbt/project_template/app_template/.github/workflows/build.yml
@@ -34,7 +34,7 @@ jobs:
with:
sdk-channel: ${{ matrix.sdk-channel }}
- name: Upload app artifacts
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
# See ufbt action docs for other output variables
name: ${{ github.event.repository.name }}-${{ steps.build-app.outputs.suffix }}
diff --git a/targets/f18/api_symbols.csv b/targets/f18/api_symbols.csv
index 6ce1736d0..8fa65acf0 100644
--- a/targets/f18/api_symbols.csv
+++ b/targets/f18/api_symbols.csv
@@ -1,5 +1,5 @@
entry,status,name,type,params
-Version,+,79.2,,
+Version,+,79.3,,
Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
Header,+,applications/services/cli/cli.h,,
@@ -84,6 +84,7 @@ Header,+,lib/libusb_stm32/inc/usb_hid.h,,
Header,+,lib/libusb_stm32/inc/usb_std.h,,
Header,+,lib/libusb_stm32/inc/usb_tmc.h,,
Header,+,lib/libusb_stm32/inc/usbd_core.h,,
+Header,+,lib/mbedtls/include/mbedtls/aes.h,,
Header,+,lib/mbedtls/include/mbedtls/des.h,,
Header,+,lib/mbedtls/include/mbedtls/ecdh.h,,
Header,+,lib/mbedtls/include/mbedtls/ecdsa.h,,
@@ -1892,6 +1893,21 @@ Function,+,manchester_encoder_advance,_Bool,"ManchesterEncoderState*, const _Boo
Function,+,manchester_encoder_finish,ManchesterEncoderResult,ManchesterEncoderState*
Function,+,manchester_encoder_reset,void,ManchesterEncoderState*
Function,+,maxim_crc8,uint8_t,"const uint8_t*, const uint8_t, const uint8_t"
+Function,-,mbedtls_aes_crypt_cbc,int,"mbedtls_aes_context*, int, size_t, unsigned char[16], const unsigned char*, unsigned char*"
+Function,-,mbedtls_aes_crypt_cfb128,int,"mbedtls_aes_context*, int, size_t, size_t*, unsigned char[16], const unsigned char*, unsigned char*"
+Function,-,mbedtls_aes_crypt_cfb8,int,"mbedtls_aes_context*, int, size_t, unsigned char[16], const unsigned char*, unsigned char*"
+Function,-,mbedtls_aes_crypt_ctr,int,"mbedtls_aes_context*, size_t, size_t*, unsigned char[16], unsigned char[16], const unsigned char*, unsigned char*"
+Function,-,mbedtls_aes_crypt_ecb,int,"mbedtls_aes_context*, int, const unsigned char[16], unsigned char[16]"
+Function,-,mbedtls_aes_crypt_ofb,int,"mbedtls_aes_context*, size_t, size_t*, unsigned char[16], const unsigned char*, unsigned char*"
+Function,-,mbedtls_aes_crypt_xts,int,"mbedtls_aes_xts_context*, int, size_t, const unsigned char[16], const unsigned char*, unsigned char*"
+Function,-,mbedtls_aes_free,void,mbedtls_aes_context*
+Function,-,mbedtls_aes_init,void,mbedtls_aes_context*
+Function,-,mbedtls_aes_setkey_dec,int,"mbedtls_aes_context*, const unsigned char*, unsigned int"
+Function,-,mbedtls_aes_setkey_enc,int,"mbedtls_aes_context*, const unsigned char*, unsigned int"
+Function,-,mbedtls_aes_xts_free,void,mbedtls_aes_xts_context*
+Function,-,mbedtls_aes_xts_init,void,mbedtls_aes_xts_context*
+Function,-,mbedtls_aes_xts_setkey_dec,int,"mbedtls_aes_xts_context*, const unsigned char*, unsigned int"
+Function,-,mbedtls_aes_xts_setkey_enc,int,"mbedtls_aes_xts_context*, const unsigned char*, unsigned int"
Function,-,mbedtls_des3_crypt_cbc,int,"mbedtls_des3_context*, int, size_t, unsigned char[8], const unsigned char*, unsigned char*"
Function,-,mbedtls_des3_crypt_ecb,int,"mbedtls_des3_context*, const unsigned char[8], unsigned char[8]"
Function,-,mbedtls_des3_free,void,mbedtls_des3_context*
@@ -1915,6 +1931,7 @@ Function,-,mbedtls_ecdh_can_do,int,mbedtls_ecp_group_id
Function,-,mbedtls_ecdh_compute_shared,int,"mbedtls_ecp_group*, mbedtls_mpi*, const mbedtls_ecp_point*, const mbedtls_mpi*, int (*)(void*, unsigned char*, size_t), void*"
Function,-,mbedtls_ecdh_free,void,mbedtls_ecdh_context*
Function,-,mbedtls_ecdh_gen_public,int,"mbedtls_ecp_group*, mbedtls_mpi*, mbedtls_ecp_point*, int (*)(void*, unsigned char*, size_t), void*"
+Function,-,mbedtls_ecdh_get_grp_id,mbedtls_ecp_group_id,mbedtls_ecdh_context*
Function,-,mbedtls_ecdh_get_params,int,"mbedtls_ecdh_context*, const mbedtls_ecp_keypair*, mbedtls_ecdh_side"
Function,-,mbedtls_ecdh_init,void,mbedtls_ecdh_context*
Function,-,mbedtls_ecdh_make_params,int,"mbedtls_ecdh_context*, size_t*, unsigned char*, size_t, int (*)(void*, unsigned char*, size_t), void*"
@@ -1955,7 +1972,9 @@ Function,-,mbedtls_ecp_group_init,void,mbedtls_ecp_group*
Function,-,mbedtls_ecp_group_load,int,"mbedtls_ecp_group*, mbedtls_ecp_group_id"
Function,-,mbedtls_ecp_grp_id_list,const mbedtls_ecp_group_id*,
Function,-,mbedtls_ecp_is_zero,int,mbedtls_ecp_point*
+Function,-,mbedtls_ecp_keypair_calc_public,int,"mbedtls_ecp_keypair*, int (*)(void*, unsigned char*, size_t), void*"
Function,-,mbedtls_ecp_keypair_free,void,mbedtls_ecp_keypair*
+Function,-,mbedtls_ecp_keypair_get_group_id,mbedtls_ecp_group_id,const mbedtls_ecp_keypair*
Function,-,mbedtls_ecp_keypair_init,void,mbedtls_ecp_keypair*
Function,-,mbedtls_ecp_mul,int,"mbedtls_ecp_group*, mbedtls_ecp_point*, const mbedtls_mpi*, const mbedtls_ecp_point*, int (*)(void*, unsigned char*, size_t), void*"
Function,-,mbedtls_ecp_mul_restartable,int,"mbedtls_ecp_group*, mbedtls_ecp_point*, const mbedtls_mpi*, const mbedtls_ecp_point*, int (*)(void*, unsigned char*, size_t), void*, mbedtls_ecp_restart_ctx*"
@@ -1968,6 +1987,7 @@ Function,-,mbedtls_ecp_point_read_binary,int,"const mbedtls_ecp_group*, mbedtls_
Function,-,mbedtls_ecp_point_read_string,int,"mbedtls_ecp_point*, int, const char*, const char*"
Function,-,mbedtls_ecp_point_write_binary,int,"const mbedtls_ecp_group*, const mbedtls_ecp_point*, int, size_t*, unsigned char*, size_t"
Function,-,mbedtls_ecp_read_key,int,"mbedtls_ecp_group_id, mbedtls_ecp_keypair*, const unsigned char*, size_t"
+Function,-,mbedtls_ecp_set_public_key,int,"mbedtls_ecp_group_id, mbedtls_ecp_keypair*, const mbedtls_ecp_point*"
Function,-,mbedtls_ecp_set_zero,int,mbedtls_ecp_point*
Function,-,mbedtls_ecp_tls_read_group,int,"mbedtls_ecp_group*, const unsigned char**, size_t"
Function,-,mbedtls_ecp_tls_read_group_id,int,"mbedtls_ecp_group_id*, const unsigned char**, size_t"
@@ -1975,6 +1995,10 @@ Function,-,mbedtls_ecp_tls_read_point,int,"const mbedtls_ecp_group*, mbedtls_ecp
Function,-,mbedtls_ecp_tls_write_group,int,"const mbedtls_ecp_group*, size_t*, unsigned char*, size_t"
Function,-,mbedtls_ecp_tls_write_point,int,"const mbedtls_ecp_group*, const mbedtls_ecp_point*, int, size_t*, unsigned char*, size_t"
Function,-,mbedtls_ecp_write_key,int,"mbedtls_ecp_keypair*, unsigned char*, size_t"
+Function,-,mbedtls_ecp_write_key_ext,int,"const mbedtls_ecp_keypair*, size_t*, unsigned char*, size_t"
+Function,-,mbedtls_ecp_write_public_key,int,"const mbedtls_ecp_keypair*, int, size_t*, unsigned char*, size_t"
+Function,-,mbedtls_internal_aes_decrypt,int,"mbedtls_aes_context*, const unsigned char[16], unsigned char[16]"
+Function,-,mbedtls_internal_aes_encrypt,int,"mbedtls_aes_context*, const unsigned char[16], unsigned char[16]"
Function,-,mbedtls_internal_md5_process,int,"mbedtls_md5_context*, const unsigned char[64]"
Function,-,mbedtls_internal_sha1_process,int,"mbedtls_sha1_context*, const unsigned char[64]"
Function,-,mbedtls_internal_sha256_process,int,"mbedtls_sha256_context*, const unsigned char[64]"
@@ -2303,9 +2327,9 @@ Function,+,pipe_install_as_stdio,void,PipeSide*
Function,+,pipe_receive,size_t,"PipeSide*, void*, size_t, FuriWait"
Function,+,pipe_role,PipeRole,PipeSide*
Function,+,pipe_send,size_t,"PipeSide*, const void*, size_t, FuriWait"
+Function,+,pipe_set_broken_callback,void,"PipeSide*, PipeSideBrokenCallback, FuriEventLoopEvent"
Function,+,pipe_set_callback_context,void,"PipeSide*, void*"
Function,+,pipe_set_data_arrived_callback,void,"PipeSide*, PipeSideDataArrivedCallback, FuriEventLoopEvent"
-Function,+,pipe_set_broken_callback,void,"PipeSide*, PipeSideBrokenCallback, FuriEventLoopEvent"
Function,+,pipe_set_space_freed_callback,void,"PipeSide*, PipeSideSpaceFreedCallback, FuriEventLoopEvent"
Function,+,pipe_spaces_available,size_t,PipeSide*
Function,+,pipe_state,PipeState,PipeSide*
diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv
index 420d7e678..bfb84a0c8 100644
--- a/targets/f7/api_symbols.csv
+++ b/targets/f7/api_symbols.csv
@@ -96,6 +96,7 @@ Header,+,lib/libusb_stm32/inc/usb_hid.h,,
Header,+,lib/libusb_stm32/inc/usb_std.h,,
Header,+,lib/libusb_stm32/inc/usb_tmc.h,,
Header,+,lib/libusb_stm32/inc/usbd_core.h,,
+Header,+,lib/mbedtls/include/mbedtls/aes.h,,
Header,+,lib/mbedtls/include/mbedtls/des.h,,
Header,+,lib/mbedtls/include/mbedtls/ecdh.h,,
Header,+,lib/mbedtls/include/mbedtls/ecdsa.h,,
@@ -1009,6 +1010,7 @@ Function,+,elements_string_fit_width,void,"Canvas*, FuriString*, size_t"
Function,+,elements_text_box,void,"Canvas*, int32_t, int32_t, size_t, size_t, Align, Align, const char*, _Bool"
Function,+,elf_resolve_from_hashtable,_Bool,"const ElfApiInterface*, uint32_t, Elf32_Addr*"
Function,+,elf_symbolname_hash,uint32_t,const char*
+Function,+,em4305_write,void,LFRFIDEM4305*
Function,+,empty_screen_alloc,EmptyScreen*,
Function,+,empty_screen_free,void,EmptyScreen*
Function,+,empty_screen_get_view,View*,EmptyScreen*
@@ -2367,6 +2369,21 @@ Function,+,manchester_encoder_advance,_Bool,"ManchesterEncoderState*, const _Boo
Function,+,manchester_encoder_finish,ManchesterEncoderResult,ManchesterEncoderState*
Function,+,manchester_encoder_reset,void,ManchesterEncoderState*
Function,+,maxim_crc8,uint8_t,"const uint8_t*, const uint8_t, const uint8_t"
+Function,-,mbedtls_aes_crypt_cbc,int,"mbedtls_aes_context*, int, size_t, unsigned char[16], const unsigned char*, unsigned char*"
+Function,-,mbedtls_aes_crypt_cfb128,int,"mbedtls_aes_context*, int, size_t, size_t*, unsigned char[16], const unsigned char*, unsigned char*"
+Function,-,mbedtls_aes_crypt_cfb8,int,"mbedtls_aes_context*, int, size_t, unsigned char[16], const unsigned char*, unsigned char*"
+Function,-,mbedtls_aes_crypt_ctr,int,"mbedtls_aes_context*, size_t, size_t*, unsigned char[16], unsigned char[16], const unsigned char*, unsigned char*"
+Function,-,mbedtls_aes_crypt_ecb,int,"mbedtls_aes_context*, int, const unsigned char[16], unsigned char[16]"
+Function,-,mbedtls_aes_crypt_ofb,int,"mbedtls_aes_context*, size_t, size_t*, unsigned char[16], const unsigned char*, unsigned char*"
+Function,-,mbedtls_aes_crypt_xts,int,"mbedtls_aes_xts_context*, int, size_t, const unsigned char[16], const unsigned char*, unsigned char*"
+Function,-,mbedtls_aes_free,void,mbedtls_aes_context*
+Function,-,mbedtls_aes_init,void,mbedtls_aes_context*
+Function,-,mbedtls_aes_setkey_dec,int,"mbedtls_aes_context*, const unsigned char*, unsigned int"
+Function,-,mbedtls_aes_setkey_enc,int,"mbedtls_aes_context*, const unsigned char*, unsigned int"
+Function,-,mbedtls_aes_xts_free,void,mbedtls_aes_xts_context*
+Function,-,mbedtls_aes_xts_init,void,mbedtls_aes_xts_context*
+Function,-,mbedtls_aes_xts_setkey_dec,int,"mbedtls_aes_xts_context*, const unsigned char*, unsigned int"
+Function,-,mbedtls_aes_xts_setkey_enc,int,"mbedtls_aes_xts_context*, const unsigned char*, unsigned int"
Function,-,mbedtls_des3_crypt_cbc,int,"mbedtls_des3_context*, int, size_t, unsigned char[8], const unsigned char*, unsigned char*"
Function,-,mbedtls_des3_crypt_ecb,int,"mbedtls_des3_context*, const unsigned char[8], unsigned char[8]"
Function,-,mbedtls_des3_free,void,mbedtls_des3_context*
@@ -2390,6 +2407,7 @@ Function,-,mbedtls_ecdh_can_do,int,mbedtls_ecp_group_id
Function,-,mbedtls_ecdh_compute_shared,int,"mbedtls_ecp_group*, mbedtls_mpi*, const mbedtls_ecp_point*, const mbedtls_mpi*, int (*)(void*, unsigned char*, size_t), void*"
Function,-,mbedtls_ecdh_free,void,mbedtls_ecdh_context*
Function,-,mbedtls_ecdh_gen_public,int,"mbedtls_ecp_group*, mbedtls_mpi*, mbedtls_ecp_point*, int (*)(void*, unsigned char*, size_t), void*"
+Function,-,mbedtls_ecdh_get_grp_id,mbedtls_ecp_group_id,mbedtls_ecdh_context*
Function,-,mbedtls_ecdh_get_params,int,"mbedtls_ecdh_context*, const mbedtls_ecp_keypair*, mbedtls_ecdh_side"
Function,-,mbedtls_ecdh_init,void,mbedtls_ecdh_context*
Function,-,mbedtls_ecdh_make_params,int,"mbedtls_ecdh_context*, size_t*, unsigned char*, size_t, int (*)(void*, unsigned char*, size_t), void*"
@@ -2430,7 +2448,9 @@ Function,-,mbedtls_ecp_group_init,void,mbedtls_ecp_group*
Function,-,mbedtls_ecp_group_load,int,"mbedtls_ecp_group*, mbedtls_ecp_group_id"
Function,-,mbedtls_ecp_grp_id_list,const mbedtls_ecp_group_id*,
Function,-,mbedtls_ecp_is_zero,int,mbedtls_ecp_point*
+Function,-,mbedtls_ecp_keypair_calc_public,int,"mbedtls_ecp_keypair*, int (*)(void*, unsigned char*, size_t), void*"
Function,-,mbedtls_ecp_keypair_free,void,mbedtls_ecp_keypair*
+Function,-,mbedtls_ecp_keypair_get_group_id,mbedtls_ecp_group_id,const mbedtls_ecp_keypair*
Function,-,mbedtls_ecp_keypair_init,void,mbedtls_ecp_keypair*
Function,-,mbedtls_ecp_mul,int,"mbedtls_ecp_group*, mbedtls_ecp_point*, const mbedtls_mpi*, const mbedtls_ecp_point*, int (*)(void*, unsigned char*, size_t), void*"
Function,-,mbedtls_ecp_mul_restartable,int,"mbedtls_ecp_group*, mbedtls_ecp_point*, const mbedtls_mpi*, const mbedtls_ecp_point*, int (*)(void*, unsigned char*, size_t), void*, mbedtls_ecp_restart_ctx*"
@@ -2443,6 +2463,7 @@ Function,-,mbedtls_ecp_point_read_binary,int,"const mbedtls_ecp_group*, mbedtls_
Function,-,mbedtls_ecp_point_read_string,int,"mbedtls_ecp_point*, int, const char*, const char*"
Function,-,mbedtls_ecp_point_write_binary,int,"const mbedtls_ecp_group*, const mbedtls_ecp_point*, int, size_t*, unsigned char*, size_t"
Function,-,mbedtls_ecp_read_key,int,"mbedtls_ecp_group_id, mbedtls_ecp_keypair*, const unsigned char*, size_t"
+Function,-,mbedtls_ecp_set_public_key,int,"mbedtls_ecp_group_id, mbedtls_ecp_keypair*, const mbedtls_ecp_point*"
Function,-,mbedtls_ecp_set_zero,int,mbedtls_ecp_point*
Function,-,mbedtls_ecp_tls_read_group,int,"mbedtls_ecp_group*, const unsigned char**, size_t"
Function,-,mbedtls_ecp_tls_read_group_id,int,"mbedtls_ecp_group_id*, const unsigned char**, size_t"
@@ -2450,6 +2471,10 @@ Function,-,mbedtls_ecp_tls_read_point,int,"const mbedtls_ecp_group*, mbedtls_ecp
Function,-,mbedtls_ecp_tls_write_group,int,"const mbedtls_ecp_group*, size_t*, unsigned char*, size_t"
Function,-,mbedtls_ecp_tls_write_point,int,"const mbedtls_ecp_group*, const mbedtls_ecp_point*, int, size_t*, unsigned char*, size_t"
Function,-,mbedtls_ecp_write_key,int,"mbedtls_ecp_keypair*, unsigned char*, size_t"
+Function,-,mbedtls_ecp_write_key_ext,int,"const mbedtls_ecp_keypair*, size_t*, unsigned char*, size_t"
+Function,-,mbedtls_ecp_write_public_key,int,"const mbedtls_ecp_keypair*, int, size_t*, unsigned char*, size_t"
+Function,-,mbedtls_internal_aes_decrypt,int,"mbedtls_aes_context*, const unsigned char[16], unsigned char[16]"
+Function,-,mbedtls_internal_aes_encrypt,int,"mbedtls_aes_context*, const unsigned char[16], unsigned char[16]"
Function,-,mbedtls_internal_md5_process,int,"mbedtls_md5_context*, const unsigned char[64]"
Function,-,mbedtls_internal_sha1_process,int,"mbedtls_sha1_context*, const unsigned char[64]"
Function,-,mbedtls_internal_sha256_process,int,"mbedtls_sha256_context*, const unsigned char[64]"