Merge remote-tracking branch 'mntm/dev' into kiisu-mntm

This commit is contained in:
WillyJL
2025-08-24 01:54:42 +02:00
13 changed files with 112 additions and 57 deletions
+35 -19
View File
@@ -138,6 +138,30 @@ jobs:
tar czpf "artifacts/flipper-z-any-scripts-${SUFFIX}.tgz" scripts
cp build/core2_firmware.tgz "artifacts/flipper-z-any-core2_firmware-${SUFFIX}.tgz"
- name: "Upload artifacts to update server"
if: ${{ env.SHOULD_UPLOAD == 'true' }}
run: |
curl "${{ secrets.INDEXER_URL }}"/firmware/directory.json > previndex.json
FILES=$(for ARTIFACT in $(find artifacts -maxdepth 1 -not -type d); do echo "-F files=@${ARTIFACT}"; done)
curl --fail -L -H "Token: ${{ secrets.INDEXER_TOKEN }}" \
-F "branch=${BRANCH_NAME}" \
-F "version_token=${COMMIT_SHA}" \
${FILES[@]} \
"${{ secrets.INDEXER_URL }}"/firmware/uploadfiles
- name: "Force deploy website to refresh devbuilds"
if: ${{ env.SHOULD_DEVBUILD == 'true' }}
uses: Codex-/return-dispatch@v2
id: force-deploy
with:
token: ${{ secrets.REPO_DISPATCH_TOKEN }}
ref: dev
repo: v2.momentum-fw.dev
owner: Next-Flip
workflow: force-deploy.yml
workflow_timeout_seconds: 300
workflow_job_steps_retry_seconds: 5
- name: "Calculate DFU sizes"
if: ${{ env.SHOULD_PRCOMMENT == 'true' }}
run: |
@@ -161,25 +185,6 @@ jobs:
echo "FLASH_FREE=$FLASH_FREE" >> $GITHUB_ENV
echo "FLASH_USABLE=$FLASH_USABLE" >> $GITHUB_ENV
- name: "Upload artifacts to update server"
if: ${{ env.SHOULD_UPLOAD == 'true' }}
run: |
curl "${{ secrets.INDEXER_URL }}"/firmware/directory.json > previndex.json
FILES=$(for ARTIFACT in $(find artifacts -maxdepth 1 -not -type d); do echo "-F files=@${ARTIFACT}"; done)
curl --fail -L -H "Token: ${{ secrets.INDEXER_TOKEN }}" \
-F "branch=${BRANCH_NAME}" \
-F "version_token=${COMMIT_SHA}" \
${FILES[@]} \
"${{ secrets.INDEXER_URL }}"/firmware/uploadfiles
- name: "Force deploy website to refresh devbuilds"
if: ${{ env.SHOULD_DEVBUILD == 'true' }}
uses: peter-evans/repository-dispatch@v3
with:
token: ${{ secrets.REPO_DISPATCH_TOKEN }}
repository: Next-Flip/v2.momentum-fw.dev
event-type: force-deploy
- name: "Find previous comment"
if: ${{ env.SHOULD_PRCOMMENT == 'true' }}
uses: peter-evans/find-comment@v3
@@ -203,6 +208,17 @@ jobs:
- Free Flash: `${{ env.FLASH_FREE }}` (`${{ env.FLASH_USABLE }}` usable)
edit-mode: replace
- name: "Wait for deploy (Run ID ${{ steps.force-deploy.outputs.run_id }})"
if: ${{ env.SHOULD_DEVBUILD == 'true' }}
uses: Codex-/await-remote-run@v1
with:
token: ${{ github.token }}
repo: v2.momentum-fw.dev
owner: Next-Flip
run_id: ${{ steps.force-deploy.outputs.run_id }}
run_timeout_seconds: 300
poll_interval_ms: 5000
- name: "Send devbuild webhook"
env:
INDEXER_URL: ${{ secrets.INDEXER_URL }}
+20 -6
View File
@@ -1,7 +1,9 @@
### Added:
- Apps:
- GPIO/ESP: [ESP32] Ghost ESP (by @jaylikesbunda)
- GPIO/GPS: [NMEA] Nearby Files (by @Stichoza)
- NFC: NFC-Eink (by @RebornedBrain)
- RFID: Simultaneous UHF RFID Reader (by @haffnerriley)
- Sub-GHz: Sub Analyzer (by @RocketGod-git)
- SubGHz:
- UL: Roger (static 28 bit) with add manually support (by @xMasterX & @mishamyte)
@@ -11,6 +13,7 @@
- UL: Marantec protocol implement CRC verification display and add manually support (by @xMasterX & @li0ard, original code by @Skorpionm)
- UL: Keeloq Comunello add manually support (by @xMasterX)
- UL: Add variant of 'Add Manually' menu with manual editing for each value (by @MrLego8-9)
- UL: Add ZKTeco 430.5 MHz add manually support (by @xMasterX)
- RFID: Support writing Securakey, Jablotron and FDX-B to EM4305 cards (#434 by @jamisonderek)
- BT Remote: Add Rename Option, simplify Bad KB BLE profile (#439 by @aaronjamt & @WillyJL)
- MNTM Settings:
@@ -23,19 +26,28 @@
### Updated:
- Apps:
- Asteroids: Bugfixes, title screen, Drone Buddy power-up (by @SimplyMinimal)
- Combo Cracker: Allow press and hold to change values, add tutorial (by @TAxelAnderson)
- ESP Flasher: Bump Marauder 1.8.3 (by @justcallmekoko)
- FlipDownloader: Added a new option to download GitHub repositories (by @jblanked)
- Combo Cracker: Allow press and hold to change values, add tutorial (by @TAxelAnderson), support alphabetic combination locks (by @henrygab)
- ESP Flasher: Bump Marauder 1.8.4 (by @justcallmekoko), add C5 support (by @Play2BReal)
- FlipDownloader: Added a new option to download GitHub repositories with dedicated keyboard, add auto updating (by @jblanked)
- FlipSocial: C++ rewrite, comments on feed posts, simpler logic and registration (by @jblanked)
- FlipWiFi: Minor bugfixes (by @jblanked)
- Flipper Blackhat: Add Deauth Broadcast command (by @o7-machinehum)
- KeyCopier: Added Weiser WR3 key format (by @lightos)
- KeyCopier: Added Weiser WR3 key format (by @lightos), added Suzuki SUZ18 key format (by @RIcePatrol)
- Metroflip: Fix unsupported card crash, RENFE Suma 10 support, GEG Connect AID added, Top Up log parsing and animations, 16 new rail lines, support for parsing area codes, saving function for Suica/Japan Rail IC, bugfixes (by @luu176)
- NFC Maker: Support making empty/blank NDEF payloads (by @WillyJL)
- NFC Playlist: Refactor playlist worker, new settings layout, loop setting, controls to move between items (by @acegoal07)
- Passy: Misc memory management bugfixes (by @qistoph)
- Seader: Fix ATS handling (by @NVX), reset SAM on error (by @bettse)
- Sentry Safe: New interface, settings & help page (by @H4ckd4ddy)
- WiFi Marauder: Support for ESP32Marauder 1.8.x (by @justcallmekoko)
- Seos Compatible: Add keys v2 support with per-device encryption (by @bettse)
- Sub-GHz Remote: Add possibility to use custom buttons (by @MrLego8-9)
- Weather Station: Added support for solight TE44 (by @fersingb)
- Weebo: Prevent 0x88 in UID[3] (by @bettse)
- WiFi Marauder: Support for ESP32Marauder 1.8.4 (by @justcallmekoko)
- Sub-GHz:
- UL: Add 868.46 MHz to default subghz freqs list (by @xMasterX)
- UL: Reduce less popular freqs in default hopper preset, make it faster (by @xMasterX)
- UL: Tune Linear (add better EZCode support), Dickert MAHS decoders (by @xMasterX)
- JS: Expose button event type in `gui/widget` button callback (by @WillyJL)
- UL: Docs: Update Sub-GHz DoorHan programming instructions (by @li0ard)
@@ -43,7 +55,9 @@
- CLI: Fix long delay with quick connect/disconnect, qFlipper should connect faster as expected again (by @WillyJL)
- Bad KB: Fix modifier keys with HOLD/RELEASE commands (by @WillyJL)
- Desktop: Fix lock screen hang (#438 by @aaronjamt)
- NFC: Fix incorrect Saflok year formula (#433 by @Eltrick)
- NFC:
- Fix incorrect Saflok year formula (#433 by @Eltrick)
- Fix read crash with unexpectedly large MFC AUTH(0) response, eg with Chameleon Ultra NTAG emualtion (by @WillyJL)
- FBT: Fix redundant decl for apps using an icon disabled in API (by @WillyJL)
### Removed:
@@ -128,6 +128,7 @@ typedef enum {
SetTypeCAMESpace,
SetTypePricenton315,
SetTypePricenton433,
SetTypeZKTeco430,
SetTypeBETT_433,
SetTypeGangQi_433,
SetTypeHollarm_433,
@@ -38,6 +38,16 @@ void subghz_scene_set_type_fill_generation_infos(GenInfo* infos_dest, SetType ty
.data.bits = 24,
.data.te = 400};
break;
case SetTypeZKTeco430:
gen_info = (GenInfo){
.type = GenData,
.mod = "AM650",
.freq = 430500000,
.data.name = SUBGHZ_PROTOCOL_PRINCETON_NAME,
.data.key = (key & 0x00FFFF00) | 0x30, // btn 0x30(UP), 0x03(STOP), 0x0C(DOWN)
.data.bits = 24,
.data.te = 357};
break;
case SetTypeNiceFlo12bit:
gen_info = (GenInfo){
.type = GenData,
@@ -107,7 +107,8 @@ bool subghz_scene_set_counter_on_event(void* context, SceneManagerEvent event) {
subghz->gen_info->keeloq_bft.cnt = __bswap16(subghz->gen_info->keeloq_bft.cnt);
break;
case GenAlutechAt4n:
subghz->gen_info->alutech_at_4n.cnt = __bswap16(subghz->gen_info->alutech_at_4n.cnt);
subghz->gen_info->alutech_at_4n.cnt =
__bswap16(subghz->gen_info->alutech_at_4n.cnt);
break;
case GenSomfyTelis:
subghz->gen_info->somfy_telis.cnt = __bswap16(subghz->gen_info->somfy_telis.cnt);
@@ -44,7 +44,6 @@ bool subghz_scene_set_key_on_event(void* context, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == SubGhzCustomEventByteInputDone) {
if(subghz->gen_info->type == GenData) {
subghz->gen_info->data.key = __bswap64(subghz->gen_info->data.key);
@@ -60,7 +60,6 @@ bool subghz_scene_set_seed_on_event(void* context, SceneManagerEvent event) {
bool generated_protocol = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == SubGhzCustomEventByteInputDone) {
switch(subghz->gen_info->type) {
case GenFaacSLH:
subghz->gen_info->faac_slh.seed = __bswap32(subghz->gen_info->faac_slh.seed);
@@ -95,25 +95,32 @@ bool subghz_scene_set_serial_on_event(void* context, SceneManagerEvent event) {
subghz->gen_info->keeloq.serial = __bswap32(subghz->gen_info->keeloq.serial);
break;
case GenCameAtomo:
subghz->gen_info->came_atomo.serial = __bswap32(subghz->gen_info->came_atomo.serial);
subghz->gen_info->came_atomo.serial =
__bswap32(subghz->gen_info->came_atomo.serial);
break;
case GenKeeloqBFT:
subghz->gen_info->keeloq_bft.serial = __bswap32(subghz->gen_info->keeloq_bft.serial);
subghz->gen_info->keeloq_bft.serial =
__bswap32(subghz->gen_info->keeloq_bft.serial);
break;
case GenAlutechAt4n:
subghz->gen_info->alutech_at_4n.serial = __bswap32(subghz->gen_info->alutech_at_4n.serial);
subghz->gen_info->alutech_at_4n.serial =
__bswap32(subghz->gen_info->alutech_at_4n.serial);
break;
case GenSomfyTelis:
subghz->gen_info->somfy_telis.serial = __bswap32(subghz->gen_info->somfy_telis.serial);
subghz->gen_info->somfy_telis.serial =
__bswap32(subghz->gen_info->somfy_telis.serial);
break;
case GenNiceFlorS:
subghz->gen_info->nice_flor_s.serial = __bswap32(subghz->gen_info->nice_flor_s.serial);
subghz->gen_info->nice_flor_s.serial =
__bswap32(subghz->gen_info->nice_flor_s.serial);
break;
case GenSecPlus2:
subghz->gen_info->sec_plus_2.serial = __bswap32(subghz->gen_info->sec_plus_2.serial);
subghz->gen_info->sec_plus_2.serial =
__bswap32(subghz->gen_info->sec_plus_2.serial);
break;
case GenPhoenixV2:
subghz->gen_info->phoenix_v2.serial = __bswap32(subghz->gen_info->phoenix_v2.serial);
subghz->gen_info->phoenix_v2.serial =
__bswap32(subghz->gen_info->phoenix_v2.serial);
break;
// Not needed for these types
case GenData:
@@ -68,6 +68,7 @@ static const char* submenu_names[SetTypeMAX] = {
[SetTypeCAMESpace] = "KL: CAME Space 433MHz",
[SetTypePricenton315] = "Princeton 315MHz",
[SetTypePricenton433] = "Princeton 433MHz",
[SetTypeZKTeco430] = "ZKTeco 430MHz",
[SetTypeGangQi_433] = "GangQi 433MHz",
[SetTypeHollarm_433] = "Hollarm 433MHz",
[SetTypeReversRB2_433] = "Revers RB2 433MHz",
@@ -42,7 +42,13 @@ static Iso14443_3aError iso14443_3a_poller_standard_frame_exchange(
break;
}
if(bit_buffer_get_capacity_bytes(rx_buffer) <
bit_buffer_get_size_bytes(instance->rx_buffer)) {
ret = Iso14443_3aErrorBufferOverflow;
break;
}
bit_buffer_copy(rx_buffer, instance->rx_buffer);
if(!iso14443_crc_check(Iso14443CrcTypeA, instance->rx_buffer)) {
ret = Iso14443_3aErrorWrongCrc;
break;
+3 -2
View File
@@ -290,8 +290,9 @@ void subghz_protocol_decoder_dickert_mahs_feed(void* context, bool level, uint32
instance->decoder.decode_count_bit = 0;
}
if((!level) && (duration > 10 * subghz_protocol_dickert_mahs_const.te_short)) {
//Found header DICKERT_MAHS
if((!level) && (DURATION_DIFF(duration, subghz_protocol_dickert_mahs_const.te_long * 50) <
subghz_protocol_dickert_mahs_const.te_delta * 70)) {
//Found header DICKERT_MAHS 44k us
instance->decoder.parser_step = DickertMAHSDecoderStepInitial;
}
break;
+19 -19
View File
@@ -18,7 +18,7 @@
static const SubGhzBlockConst subghz_protocol_linear_const = {
.te_short = 500,
.te_long = 1500,
.te_delta = 150,
.te_delta = 350,
.min_count_bit_for_found = 10,
};
@@ -118,32 +118,32 @@ static bool subghz_protocol_encoder_linear_get_upload(SubGhzProtocolEncoderLinea
if(bit_read(instance->generic.data, i - 1)) {
//send bit 1
instance->encoder.upload[index++] =
level_duration_make(true, (uint32_t)subghz_protocol_linear_const.te_short * 3);
level_duration_make(true, (uint32_t)subghz_protocol_linear_const.te_short);
instance->encoder.upload[index++] =
level_duration_make(false, (uint32_t)subghz_protocol_linear_const.te_short);
level_duration_make(false, (uint32_t)subghz_protocol_linear_const.te_long);
} else {
//send bit 0
instance->encoder.upload[index++] =
level_duration_make(true, (uint32_t)subghz_protocol_linear_const.te_short);
level_duration_make(true, (uint32_t)subghz_protocol_linear_const.te_long);
instance->encoder.upload[index++] =
level_duration_make(false, (uint32_t)subghz_protocol_linear_const.te_short * 3);
level_duration_make(false, (uint32_t)subghz_protocol_linear_const.te_short);
}
}
//Send end bit
if(bit_read(instance->generic.data, 0)) {
//send bit 1
instance->encoder.upload[index++] =
level_duration_make(true, (uint32_t)subghz_protocol_linear_const.te_short * 3);
//Send PT_GUARD
level_duration_make(true, (uint32_t)subghz_protocol_linear_const.te_short);
//Send gap
instance->encoder.upload[index++] =
level_duration_make(false, (uint32_t)subghz_protocol_linear_const.te_short * 42);
level_duration_make(false, (uint32_t)subghz_protocol_linear_const.te_short * 44);
} else {
//send bit 0
instance->encoder.upload[index++] =
level_duration_make(true, (uint32_t)subghz_protocol_linear_const.te_short);
//Send PT_GUARD
level_duration_make(true, (uint32_t)subghz_protocol_linear_const.te_long);
//Send gap
instance->encoder.upload[index++] =
level_duration_make(false, (uint32_t)subghz_protocol_linear_const.te_short * 44);
level_duration_make(false, (uint32_t)subghz_protocol_linear_const.te_short * 42);
}
return true;
@@ -225,7 +225,7 @@ void subghz_protocol_decoder_linear_feed(void* context, bool level, uint32_t dur
switch(instance->decoder.parser_step) {
case LinearDecoderStepReset:
if((!level) && (DURATION_DIFF(duration, subghz_protocol_linear_const.te_short * 42) <
subghz_protocol_linear_const.te_delta * 20)) {
subghz_protocol_linear_const.te_delta * 15)) {
//Found header Linear
instance->decoder.decode_data = 0;
instance->decoder.decode_count_bit = 0;
@@ -246,16 +246,16 @@ void subghz_protocol_decoder_linear_feed(void* context, bool level, uint32_t dur
instance->decoder.parser_step = LinearDecoderStepReset;
//checking that the duration matches the guardtime
if(DURATION_DIFF(duration, subghz_protocol_linear_const.te_short * 42) >
subghz_protocol_linear_const.te_delta * 20) {
subghz_protocol_linear_const.te_delta * 15) {
break;
}
if(DURATION_DIFF(instance->decoder.te_last, subghz_protocol_linear_const.te_short) <
subghz_protocol_linear_const.te_delta) {
subghz_protocol_blocks_add_bit(&instance->decoder, 0);
subghz_protocol_blocks_add_bit(&instance->decoder, 1);
} else if(
DURATION_DIFF(instance->decoder.te_last, subghz_protocol_linear_const.te_long) <
subghz_protocol_linear_const.te_delta) {
subghz_protocol_blocks_add_bit(&instance->decoder, 1);
subghz_protocol_blocks_add_bit(&instance->decoder, 0);
}
if(instance->decoder.decode_count_bit ==
subghz_protocol_linear_const.min_count_bit_for_found) {
@@ -275,14 +275,14 @@ void subghz_protocol_decoder_linear_feed(void* context, bool level, uint32_t dur
subghz_protocol_linear_const.te_delta) &&
(DURATION_DIFF(duration, subghz_protocol_linear_const.te_long) <
subghz_protocol_linear_const.te_delta)) {
subghz_protocol_blocks_add_bit(&instance->decoder, 0);
subghz_protocol_blocks_add_bit(&instance->decoder, 1);
instance->decoder.parser_step = LinearDecoderStepSaveDuration;
} else if(
(DURATION_DIFF(instance->decoder.te_last, subghz_protocol_linear_const.te_long) <
subghz_protocol_linear_const.te_delta) &&
(DURATION_DIFF(duration, subghz_protocol_linear_const.te_short) <
subghz_protocol_linear_const.te_delta)) {
subghz_protocol_blocks_add_bit(&instance->decoder, 1);
subghz_protocol_blocks_add_bit(&instance->decoder, 0);
instance->decoder.parser_step = LinearDecoderStepSaveDuration;
} else {
instance->decoder.parser_step = LinearDecoderStepReset;
@@ -333,8 +333,8 @@ void subghz_protocol_decoder_linear_get_string(void* context, FuriString* output
furi_string_cat_printf(
output,
"%s %dbit\r\n"
"Key:0x%08lX\r\n"
"Yek:0x%08lX\r\n"
"Key:0x%03lX\r\n"
"Yek:0x%03lX\r\n"
"DIP:" DIP_PATTERN "\r\n",
instance->generic.protocol_name,
instance->generic.data_count_bit,